diff --git a/code/modules/integrated_electronics/subtypes/input.dm b/code/modules/integrated_electronics/subtypes/input.dm index e8981ed68523..fa6b066e95c7 100644 --- a/code/modules/integrated_electronics/subtypes/input.dm +++ b/code/modules/integrated_electronics/subtypes/input.dm @@ -849,11 +849,11 @@ The first activation pin is always pulsed when the circuit hears someone talk, while the second one \ is only triggered if it hears someone speaking a language other than Galactic Common." icon_state = "recorder" - complexity = 8 + complexity = 4 //cuts complexity in half, you'll need to use a ref to string for the name inputs = list() flags_1 = CONDUCT_1 | HEAR_1 outputs = list( - "speaker" = IC_PINTYPE_STRING, + "speaker" = IC_PINTYPE_REF, "message" = IC_PINTYPE_STRING ) activators = list("on message received" = IC_PINTYPE_PULSE_OUT, "on translation" = IC_PINTYPE_PULSE_OUT) @@ -867,7 +867,7 @@ if(raw_message) if(message_langs != get_selected_language()) translated = TRUE - set_pin_data(IC_OUTPUT, 1, speaker.GetVoice()) + set_pin_data(IC_OUTPUT, 1, speaker) set_pin_data(IC_OUTPUT, 2, raw_message) push_data() diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index f028ffc1c9ba..ef8d0f326cc1 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -370,10 +370,19 @@ mob/visible_message(message, self_message, blind_message, vision_distance = DEFA var/msg = "[src] makes eye contact with you." addtimer(CALLBACK(GLOBAL_PROC, .proc/to_chat, examined_mob, msg), 3) -//same as above -//note: ghosts can point, this is intended -//visible_message will handle invisibility properly -//overridden here and in /mob/dead/observer for different point span classes and sanity checks +/** + * Point at an atom + * + * mob verbs are faster than object verbs. See + * [this byond forum post](https://secure.byond.com/forum/?post=1326139&page=2#comment8198716) + * for why this isn't atom/verb/pointed() + * + * note: ghosts can point, this is intended + * + * visible_message will handle invisibility properly + * + * overridden here and in /mob/dead/observer for different point span classes and sanity checks + */ /mob/verb/pointed(atom/A as mob|obj|turf in fov_view()) set name = "Point To" set category = "Object" @@ -383,12 +392,15 @@ mob/visible_message(message, self_message, blind_message, vision_distance = DEFA if(istype(A, /obj/effect/temp_visual/point)) return FALSE - var/tile = get_turf(A) + var/turf/tile = get_turf(A) if (!tile) return FALSE - new /obj/effect/temp_visual/point(A,invisibility) + var/turf/our_tile = get_turf(src) + var/obj/visual = new /obj/effect/temp_visual/point(our_tile, invisibility) + animate(visual, pixel_x = (tile.x - our_tile.x) * world.icon_size + A.pixel_x, pixel_y = (tile.y - our_tile.y) * world.icon_size + A.pixel_y, time = 1.7, easing = EASE_OUT) SEND_SIGNAL(src, COMSIG_MOB_POINTED, A) + return TRUE /mob/proc/can_resist() diff --git a/sandcode/code/_globalvars/lists/misc.dm b/sandcode/code/_globalvars/lists/misc.dm new file mode 100644 index 000000000000..e2265f339d29 --- /dev/null +++ b/sandcode/code/_globalvars/lists/misc.dm @@ -0,0 +1 @@ +GLOBAL_VAR_INIT(remote_control, TRUE) diff --git a/sandcode/code/_globalvars/lists/objects.dm b/sandcode/code/_globalvars/lists/objects.dm new file mode 100644 index 000000000000..dd737fbe73e9 --- /dev/null +++ b/sandcode/code/_globalvars/lists/objects.dm @@ -0,0 +1,2 @@ +GLOBAL_LIST_EMPTY(ic_jammers) +GLOBAL_LIST_EMPTY(ic_speakers) diff --git a/sandcode/code/game/machinery/computer/arcade/tetris.dm b/sandcode/code/game/machinery/computer/arcade/tetris.dm index 4551314216f9..8bf9c0ac7834 100644 --- a/sandcode/code/game/machinery/computer/arcade/tetris.dm +++ b/sandcode/code/game/machinery/computer/arcade/tetris.dm @@ -33,8 +33,8 @@ return if(user.client) - var/datum/asset/simple/C = new/datum/asset/simple/tetris() - SSassets.transport.send_assets(user.client, C.assets) + var/datum/asset/assets = get_asset_datum(/datum/asset/simple/tetris) + assets.send(user) var/dat = {" diff --git a/sandcode/code/game/machinery/telecomms/machine_interactions.dm b/sandcode/code/game/machinery/telecomms/machine_interactions.dm new file mode 100644 index 000000000000..ed24093d15b8 --- /dev/null +++ b/sandcode/code/game/machinery/telecomms/machine_interactions.dm @@ -0,0 +1,10 @@ +// Additional Options for certain machines. Use this when you want to add an option to a specific machine. +// Example of how to use below. + +/obj/machinery/telecomms/proc/Options_Menu() + return "" + +// The topic for Additional Options. Use this for checking href links for your specific option. +// Example of how to use below. +/obj/machinery/telecomms/proc/Options_Topic(href, href_list) + return diff --git a/sandcode/code/game/machinery/telecomms/machines/receiver.dm b/sandcode/code/game/machinery/telecomms/machines/receiver.dm new file mode 100644 index 000000000000..f1f313d3a27c --- /dev/null +++ b/sandcode/code/game/machinery/telecomms/machines/receiver.dm @@ -0,0 +1,46 @@ +//Code for the interceptor circuit +/obj/machinery/telecomms/receiver/Options_Menu() + var/dat = "
Remote control: [GLOB.remote_control ? "ENABLED" : "DISABLED"]" + dat += "
Broadcasting signals: " + for(var/i in GLOB.ic_speakers) + var/obj/item/integrated_circuit/I = i + var/obj/item/O = I.get_object() + if(get_area(O)) //if it isn't in nullspace, can happen due to printer newing all possible circuits to fetch list data + dat += "
[O.name] = [O.x], [O.y], [O.z], [get_area(O)]" + dat += "

Circuit jammer signals: " + for(var/i in GLOB.ic_jammers) + var/obj/item/integrated_circuit/I = i + var/obj/item/O = I.get_object() + if(get_area(O)) //if it isn't in nullspace, can happen due to printer newing all possible circuits to fetch list data + dat += "
[O.name] = [O.x], [O.y], [O.z], [get_area(O)]" + return dat + +/obj/machinery/telecomms/receiver/Options_Topic(href, href_list) + if(href_list["toggle_remote_control"]) + GLOB.remote_control = !GLOB.remote_control + +/obj/machinery/telecomms/receiver/receive_signal(datum/signal/signal) + if(LAZYLEN(GLOB.ic_jammers) && GLOB.remote_control) + for(var/i in GLOB.ic_jammers) + var/obj/item/integrated_circuit/input/tcomm_interceptor/T = i + var/obj/item/O = T.get_object() + if(is_station_level(O.z)&& (!istype(get_area(O), /area/space))) + if(!istype(signal.source, /obj/item/radio/headset/integrated)) + signal.data["reject"] = TRUE + break + ..() + +//makeshift receiver used for the circuit, so that we don't +//have to edit radio.dm and other shit +/obj/machinery/telecomms/receiver/circuit + idle_power_usage = 0 + var/obj/item/integrated_circuit/input/tcomm_interceptor/holder + +/obj/machinery/telecomms/receiver/circuit/receive_signal(datum/signal/signal) + if(!holder.get_pin_data(IC_INPUT, 1)) + return + if(!signal) + return + holder.receive_signal(signal) + +// End diff --git a/sandcode/code/modules/integrated_electronics/subtypes/input.dm b/sandcode/code/modules/integrated_electronics/subtypes/input.dm new file mode 100644 index 000000000000..c867f905602a --- /dev/null +++ b/sandcode/code/modules/integrated_electronics/subtypes/input.dm @@ -0,0 +1,88 @@ +//Interceptor +//Intercepts a telecomms signal, aka a radio message (;halp getting griff) +//Inputs: +//On (Boolean): If on, the circuit intercepts radio signals. Otherwise it does not. This doesn't affect no pass! +//No pass (Boolean): Decides if the signal will be silently intercepted +// (false) or also blocked from being sent on the radio (true) +//Outputs: +//Source: name of the mob +//Job: job of the mob +//content: the actual message +//spans: a list of spans, there's not much info about this but stuff like robots will have "robot" span +/obj/item/integrated_circuit/input/tcomm_interceptor + name = "telecommunication interceptor" + desc = "This circuit allows for telecomms signals \ + to be fetched prior to being broadcasted." + extended_desc = "Similar \ + to the old NTSL system of realtime signal modification, \ + the circuit connects to telecomms and fetches data \ + for each signal, which can be sent normally or blocked, \ + for cases such as other circuits modifying certain data. \ + Beware, this cannot stop signals from unreachable areas, such \ + as space or zlevels other than station's one." + complexity = 30 + cooldown_per_use = 0.1 + w_class = WEIGHT_CLASS_SMALL + inputs = list( + "intercept" = IC_PINTYPE_BOOLEAN, + "no pass" = IC_PINTYPE_BOOLEAN + ) + outputs = list( + "source" = IC_PINTYPE_STRING, + "job" = IC_PINTYPE_STRING, + "content" = IC_PINTYPE_STRING, + "spans" = IC_PINTYPE_LIST, + "frequency" = IC_PINTYPE_NUMBER + ) + activators = list( + "on intercept" = IC_PINTYPE_PULSE_OUT + ) + power_draw_idle = 0 + spawn_flags = IC_SPAWN_RESEARCH + var/obj/machinery/telecomms/receiver/circuit/receiver + var/list/freq_blacklist = list(FREQ_CENTCOM,FREQ_SYNDICATE,FREQ_CTF_RED,FREQ_CTF_BLUE) + +/obj/item/integrated_circuit/input/tcomm_interceptor/Initialize() + . = ..() + receiver = new(src) + receiver.holder = src + +/obj/item/integrated_circuit/input/tcomm_interceptor/Destroy() + qdel(receiver) + GLOB.ic_jammers -= src + ..() + +/obj/item/integrated_circuit/input/tcomm_interceptor/receive_signal(datum/signal/signal) + if((signal.transmission_method == TRANSMISSION_SUBSPACE) && get_pin_data(IC_INPUT, 1)) + if(signal.frequency in freq_blacklist) + return + set_pin_data(IC_OUTPUT, 1, signal.data["name"]) + set_pin_data(IC_OUTPUT, 2, signal.data["job"]) + set_pin_data(IC_OUTPUT, 3, signal.data["message"]) + set_pin_data(IC_OUTPUT, 4, signal.data["spans"]) + set_pin_data(IC_OUTPUT, 5, signal.frequency) + push_data() + activate_pin(1) + +/obj/item/integrated_circuit/input/tcomm_interceptor/on_data_written() + if(get_pin_data(IC_INPUT, 2)) + GLOB.ic_jammers |= src + if(get_pin_data(IC_INPUT, 1)) + power_draw_idle = 200 + else + power_draw_idle = 100 + else + GLOB.ic_jammers -= src + if(get_pin_data(IC_INPUT, 1)) + power_draw_idle = 100 + else + power_draw_idle = 0 + +/obj/item/integrated_circuit/input/tcomm_interceptor/power_fail() + set_pin_data(IC_INPUT, 1, 0) + set_pin_data(IC_INPUT, 2, 0) + +/obj/item/integrated_circuit/input/tcomm_interceptor/disconnect_all() + set_pin_data(IC_INPUT, 1, 0) + set_pin_data(IC_INPUT, 2, 0) + ..() diff --git a/sandcode/code/modules/integrated_electronics/subtypes/manipulation.dm b/sandcode/code/modules/integrated_electronics/subtypes/manipulation.dm new file mode 100644 index 000000000000..936d66df2268 --- /dev/null +++ b/sandcode/code/modules/integrated_electronics/subtypes/manipulation.dm @@ -0,0 +1,50 @@ +/obj/item/integrated_circuit/manipulation/activator + name = "activator" + desc = "Circuit which can activate things remotely!" + icon_state = "pull_claw" + extended_desc = "This circuit needs a reference to a thing to activate, it also needs to know who is activating said item." + w_class = WEIGHT_CLASS_SMALL + size = 3 + cooldown_per_use = 1 + complexity = 10 + inputs = list("target" = IC_PINTYPE_REF, "person" = IC_PINTYPE_REF) + activators = list("pulse in" = IC_PINTYPE_PULSE_IN,"pulse out" = IC_PINTYPE_PULSE_OUT) + spawn_flags = IC_SPAWN_RESEARCH + power_draw_per_use = 50 + ext_cooldown = 1 + +/obj/item/integrated_circuit/manipulation/activator/do_work(ord) + var/obj/acting_object = get_pin_data_as_type(IC_INPUT, 1, /obj/) + var/mob/person = get_pin_data_as_type(IC_INPUT, 2, /mob/) + acting_object.interact(person) + activate_pin(1) + + +/obj/item/integrated_circuit/manipulation/advactivator + name = "advactivator" + desc = "Circuit which can UI elements remotely!" + icon_state = "pull_claw" + extended_desc = "This circuit needs a reference to a to activate, as well as action and parems to pass! Use mode 1 for lists or 0 for single values." + w_class = WEIGHT_CLASS_SMALL + size = 3 + cooldown_per_use = 1 + complexity = 10 + + //inputs = list("target" = IC_PINTYPE_REF, "action" = IC_PINTYPE_STRING, "params" = IC_PINTYPE_STRING) + inputs = list("target" = IC_PINTYPE_REF, "action" = IC_PINTYPE_STRING, "mode" = IC_PINTYPE_NUMBER, "params" = IC_PINTYPE_STRING, "listparams" = IC_PINTYPE_LIST) + activators = list("pulse in" = IC_PINTYPE_PULSE_IN,"pulse out" = IC_PINTYPE_PULSE_OUT) + spawn_flags = IC_SPAWN_RESEARCH + power_draw_per_use = 50 + ext_cooldown = 1 + var/max_grab = GRAB_PASSIVE + +/obj/item/integrated_circuit/manipulation/advactivator/do_work(ord) + var/obj/acting_object = get_pin_data_as_type(IC_INPUT, 1, /obj/) + var/action = get_pin_data(IC_INPUT, 2) + var/mode = get_pin_data(IC_INPUT, 3) + var/params = get_pin_data(IC_INPUT, 4) + if(mode == 1) + params = get_pin_data(IC_INPUT, 5) + + acting_object.ui_act(action, params) + activate_pin(1) diff --git a/sandcode/code/modules/integrated_electronics/subtypes/output.dm b/sandcode/code/modules/integrated_electronics/subtypes/output.dm index 84ef309ee144..85a99c056af3 100644 --- a/sandcode/code/modules/integrated_electronics/subtypes/output.dm +++ b/sandcode/code/modules/integrated_electronics/subtypes/output.dm @@ -24,9 +24,11 @@ . = ..() radio = new(src) radio.frequency = FREQ_COMMON + GLOB.ic_speakers += src /obj/item/integrated_circuit/output/text_to_radio/Destroy() qdel(radio) + GLOB.ic_speakers -= src ..() /obj/item/integrated_circuit/output/text_to_radio/on_data_written() @@ -79,3 +81,41 @@ to_chat(user, "There are no encryption keys to remove from the mechanism.") /obj/item/radio/headset/integrated + +//sandstorm original - pointer +/obj/item/integrated_circuit/output/pointer + name = "pointer circuit" + desc = "Takes a reference and points to it upon activation." + extended_desc = "This machine points at something for everyone to see." + icon_state = "pull_claw" + complexity = 2 + inputs = list("target" = IC_PINTYPE_REF) + activators = list("point" = IC_PINTYPE_PULSE_IN, "on pointed" = IC_PINTYPE_PULSE_OUT, "on failure" = IC_PINTYPE_PULSE_OUT) + spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH + power_draw_per_use = 10 + cooldown_per_use = 0.1 + +/obj/item/integrated_circuit/output/pointer/do_work() + if(!get_pin_data(IC_INPUT, 1)) + activate_pin(3) + return + else + assembly.point(get_pin_data(IC_INPUT, 1)) + activate_pin(2) + +/obj/item/electronic_assembly/proc/point(atom/A as mob|obj|turf in view()) + if(!src || !(A in view(src.loc))) + return FALSE + if(istype(A, /obj/effect/temp_visual/point)) + return FALSE + + var/turf/tile = get_turf(A) + if(!tile) + return FALSE + + var/turf/our_tile = get_turf(src) + var/obj/visual = new /obj/effect/temp_visual/point(our_tile, invisibility) + animate(visual, pixel_x = (tile.x - our_tile.x) * world.icon_size + A.pixel_x, pixel_y = (tile.y - our_tile.y) * world.icon_size + A.pixel_y, time = 1.7, easing = EASE_OUT) + SEND_SIGNAL(src, COMSIG_MOB_POINTED, A) + + return TRUE diff --git a/tgstation.dme b/tgstation.dme index 7d30d694b0ce..36cf9853c572 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -3614,6 +3614,8 @@ #include "sandcode\code\__DEFINES\status_effects.dm" #include "sandcode\code\__DEFINES\traits.dm" #include "sandcode\code\__DEFINES\wires.dm" +#include "sandcode\code\_globalvars\lists\misc.dm" +#include "sandcode\code\_globalvars\lists\objects.dm" #include "sandcode\code\_onclick\hud\screen_objects.dm" #include "sandcode\code\datums\action.dm" #include "sandcode\code\datums\ai_laws.dm" @@ -3645,6 +3647,8 @@ #include "sandcode\code\game\machinery\posialert.dm" #include "sandcode\code\game\machinery\computer\arcade\tetris.dm" #include "sandcode\code\game\machinery\pipe\construction.dm" +#include "sandcode\code\game\machinery\telecomms\machine_interactions.dm" +#include "sandcode\code\game\machinery\telecomms\machines\receiver.dm" #include "sandcode\code\game\mecha\mecha_construction_paths.dm" #include "sandcode\code\game\mecha\mecha_parts.dm" #include "sandcode\code\game\objects\effects\contraband.dm" @@ -3684,6 +3688,8 @@ #include "sandcode\code\modules\crafting\recipes\recipes_misc.dm" #include "sandcode\code\modules\hydroponics\grown\misc.dm" #include "sandcode\code\modules\integrated_electronics\core\assemblies.dm" +#include "sandcode\code\modules\integrated_electronics\subtypes\input.dm" +#include "sandcode\code\modules\integrated_electronics\subtypes\manipulation.dm" #include "sandcode\code\modules\integrated_electronics\subtypes\output.dm" #include "sandcode\code\modules\keybindings\keybind\carbon.dm" #include "sandcode\code\modules\language\dragon.dm" diff --git a/tgui/src/interfaces/tetris/tetris.js b/tgui/src/interfaces/tetris/tetris.js index 965c4cab1580..0abb6a8614ef 100644 --- a/tgui/src/interfaces/tetris/tetris.js +++ b/tgui/src/interfaces/tetris/tetris.js @@ -5,17 +5,17 @@ Delay=new Array(828,620,464,348,260,196,148,112,84,64,48,36,27); Fld = new Array(MaxX); for (i=0; i < MaxX; i++) { Fld[i]=new Array(MaxY); -} +} RFld=new Array(MaxY); Pic= new Array(8); for (i=0; i<8; i++) -{ Pic[i] = new Image(); - Pic[i].src = "tetris_"+i+".gif"; +{ Pic[i] = new Image(); + Pic[i].src = "tetris_"+i+".gif"; } PrePic= new Array(8); for (i=0; i<8; i++) -{ PrePic[i] = new Image(); - PrePic[i].src = "tetrisp"+i+".gif"; +{ PrePic[i] = new Image(); + PrePic[i].src = "tetrisp"+i+".gif"; } PatternX=new Array(7); PatternY=new Array(7); @@ -53,7 +53,7 @@ function KeyDown(whichkey) if (whichkey == 65461) Down(); if (whichkey == 65462) Right(); if (whichkey == 65464) Rotate(); -} +} function Pause() { IsOver=true; alert("Click OK to continue!"); @@ -108,15 +108,15 @@ function Go() for (nn=0; nn<4; nn++) { Fld[PosX[nn]][PosY[nn]]=Col+1; document.images[PosX[nn]+MaxX*PosY[nn]].src = Pic[Col+1].src; - } + } } else { for (nn=0; nn<4; nn++) Fld[PosX[nn]][PosY[nn]]=0; - if (CanShift(0,1)) + if (CanShift(0,1)) { for (nn=0; nn<4; nn++) Fld[PosX[nn]][PosY[nn]]=Col+1; - Shift(0,1); + Shift(0,1); } else { for (nn=0; nn<4; nn++) @@ -139,7 +139,7 @@ function CanShift(xx, yy) if (PosY[nn]+yy>=MaxY) return(false); if (Fld[PosX[nn]+xx][PosY[nn]+yy]>0) return(false); } - return(true); + return(true); } function GetFld(xx, yy) { if (xx<0) return(-1); @@ -158,7 +158,7 @@ function Rotate() { for (nn=0; nn<4; nn++) Fld[PosX[nn]][PosY[nn]]=Col+1; return; - } + } for (nn=0; nn<4; nn++) document.images[PosX[nn]+MaxX*PosY[nn]].src = Pic[0].src; if (Col==0) @@ -191,11 +191,11 @@ function Rotate() PosX[0]=PosX[1]-nn; nn=PosY[1]-PosY[2]; PosY[2]=PosY[1]+(PosX[1]-PosX[2]); - PosX[2]=PosX[1]-nn; + PosX[2]=PosX[1]-nn; nn=PosY[1]-PosY[3]; PosY[3]=PosY[1]+(PosX[1]-PosX[3]); - PosX[3]=PosX[1]-nn; - } + PosX[3]=PosX[1]-nn; + } for (nn=0; nn<4; nn++) document.images[PosX[nn]+MaxX*PosY[nn]].src = Pic[Col+1].src; } @@ -203,19 +203,19 @@ function CanRotate() { var ii, jj, iim, jjm, dd=3; if (Col==3) return(false); if (Col==0) - { iim=PosX[2]-2; + { iim=PosX[2]-2; jjm=PosY[2]-1; dd=4; } else - { iim=PosX[1]-1; + { iim=PosX[1]-1; jjm=PosY[1]-1; } for (ii=iim; ii