diff --git a/_maps/map_files/MetaStation/MetaStation.dmm b/_maps/map_files/MetaStation/MetaStation.dmm index 95512671dc4..5b223837cfb 100644 --- a/_maps/map_files/MetaStation/MetaStation.dmm +++ b/_maps/map_files/MetaStation/MetaStation.dmm @@ -79128,7 +79128,7 @@ /obj/item/stack/sheet/metal{ amount = 10 }, -/obj/item/radio/electropack, +/obj/item/electropack, /obj/machinery/firealarm{ dir = 4; name = "east bump"; diff --git a/_maps/map_files/RandomRuins/SpaceRuins/blowntcommsat.dmm b/_maps/map_files/RandomRuins/SpaceRuins/blowntcommsat.dmm index 66d9cca01fa..d9aad7e6aec 100644 --- a/_maps/map_files/RandomRuins/SpaceRuins/blowntcommsat.dmm +++ b/_maps/map_files/RandomRuins/SpaceRuins/blowntcommsat.dmm @@ -592,7 +592,7 @@ /area/ruin/space/tcommsat) "bW" = ( /obj/structure/table, -/obj/item/radio/electropack, +/obj/item/electropack, /turf/simulated/floor/plating/airless, /area/ruin/space/tcommsat) "bX" = ( diff --git a/_maps/map_files/cyberiad/cyberiad.dmm b/_maps/map_files/cyberiad/cyberiad.dmm index 3d15aa191b6..011b95eb7e0 100644 --- a/_maps/map_files/cyberiad/cyberiad.dmm +++ b/_maps/map_files/cyberiad/cyberiad.dmm @@ -53090,7 +53090,7 @@ /area/toxins/hallway) "cBC" = ( /obj/structure/table, -/obj/item/radio/electropack, +/obj/item/electropack, /obj/item/assembly/signaler, /obj/structure/cable{ d1 = 4; diff --git a/_maps/map_files/generic/centcomm.dmm b/_maps/map_files/generic/centcomm.dmm index ac5e7b78cf0..1c8f3b7afba 100644 --- a/_maps/map_files/generic/centcomm.dmm +++ b/_maps/map_files/generic/centcomm.dmm @@ -3605,7 +3605,7 @@ /area/syndicate_mothership) "mq" = ( /obj/structure/table, -/obj/item/radio/electropack{ +/obj/item/electropack{ pixel_x = -5 }, /obj/item/assembly/signaler{ diff --git a/code/game/objects/effects/anomalies.dm b/code/game/objects/effects/anomalies.dm index fa9d157a51a..08f35b19337 100644 --- a/code/game/objects/effects/anomalies.dm +++ b/code/game/objects/effects/anomalies.dm @@ -40,7 +40,7 @@ var/frequency = rand(PUBLIC_LOW_FREQ, PUBLIC_HIGH_FREQ) if(ISMULTIPLE(frequency, 2))//signaller frequencies are always uneven! frequency++ - aSignal.set_frequency(frequency) + aSignal.frequency = frequency if(new_lifespan) lifespan = new_lifespan diff --git a/code/game/objects/items/devices/radio/electropack.dm b/code/game/objects/items/devices/radio/electropack.dm index 2316db69295..f8a2dc2671e 100644 --- a/code/game/objects/items/devices/radio/electropack.dm +++ b/code/game/objects/items/devices/radio/electropack.dm @@ -1,43 +1,57 @@ -/obj/item/radio/electropack +/obj/item/electropack name = "electropack" desc = "Dance my monkeys! DANCE!!!" + icon = 'icons/obj/radio.dmi' icon_state = "electropack0" item_state = "electropack" - frequency = AIRLOCK_FREQ flags = CONDUCT slot_flags = SLOT_BACK w_class = WEIGHT_CLASS_HUGE - materials = list(MAT_METAL=10000, MAT_GLASS=2500) - var/code = 2 + materials = list(MAT_METAL = 10000, MAT_GLASS = 2500) + /// The integrated signaler + var/obj/item/assembly/signaler/electropack/integrated_signaler -/obj/item/radio/electropack/attack_hand(mob/user as mob) - if(src == user.back) - to_chat(user, "You need help taking this off!") - return 0 +/obj/item/electropack/Initialize(mapload) . = ..() + integrated_signaler = new /obj/item/assembly/signaler/electropack(src, src) // Loc and the integrated one -/obj/item/radio/electropack/Destroy() - if(istype(src.loc, /obj/item/assembly/shock_kit)) - var/obj/item/assembly/shock_kit/S = src.loc +/obj/item/electropack/Destroy() + integrated_signaler.owning_pack = null + QDEL_NULL(integrated_signaler) + + if(istype(loc, /obj/item/assembly/shock_kit)) + var/obj/item/assembly/shock_kit/S = loc if(S.part1 == src) S.part1 = null + else if(S.part2 == src) S.part2 = null + master = null + return ..() -/obj/item/radio/electropack/attackby(obj/item/W as obj, mob/user as mob, params) +/obj/item/electropack/attack_hand(mob/user) + if(src == user.back) + to_chat(user, "You need help taking this off!") + return FALSE + ..() + +/obj/item/electropack/attack_self(mob/user) + ui_interact(user) + +/obj/item/electropack/attackby(obj/item/W, mob/user, params) + ..() + if(istype(W, /obj/item/clothing/head/helmet)) - if(!b_stat) - to_chat(user, "[src] is not ready to be attached!") - return - var/obj/item/assembly/shock_kit/A = new /obj/item/assembly/shock_kit( user ) + var/obj/item/assembly/shock_kit/A = new /obj/item/assembly/shock_kit(user) A.icon = 'icons/obj/assemblies.dmi' if(!user.unEquip(W)) to_chat(user, "\the [W] is stuck to your hand, you cannot attach it to \the [src]!") return + W.loc = A W.master = A A.part1 = W @@ -53,11 +67,12 @@ A.flags |= NODROP -/obj/item/radio/electropack/receive_signal(datum/signal/signal) - if(!signal || signal.encryption != code) - return +/obj/item/electropack/proc/handle_shock() + if(istype(master, /obj/item/assembly/shock_kit)) + var/obj/item/assembly/shock_kit/SK = master + SK.shock_invoke() - if(isliving(loc) && on) + if(isliving(loc)) var/mob/living/M = loc var/turf/T = M.loc if(istype(T, /turf)) @@ -67,58 +82,80 @@ sleep(50) if(M) M.moved_recently = 0 + to_chat(M, "You feel a sharp shock!") do_sparks(3, 1, M) M.Weaken(10 SECONDS) - if(master) - master.receive_signal() - return - - -/obj/item/radio/electropack/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = TRUE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.inventory_state) +// This should honestly just proxy the UI to the internal signaler +/obj/item/electropack/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = TRUE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.inventory_state) ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) ui = new(user, src, ui_key, "Electropack", name, 360, 150, master_ui, state) ui.open() -/obj/item/radio/electropack/ui_data(mob/user) +/obj/item/electropack/ui_data(mob/user) var/list/data = list() - data["power"] = on - data["frequency"] = frequency - data["code"] = code + data["power"] = integrated_signaler.receiving + data["frequency"] = integrated_signaler.frequency + data["code"] = integrated_signaler.code data["minFrequency"] = PUBLIC_LOW_FREQ data["maxFrequency"] = PUBLIC_HIGH_FREQ return data -/obj/item/radio/electropack/ui_act(action, params) +/obj/item/electropack/ui_act(action, list/params) if(..()) return + . = TRUE + switch(action) if("power") - on = !on + integrated_signaler.receiving = !integrated_signaler.receiving + if("freq") var/value = params["freq"] if(value) - frequency = sanitize_frequency(value) - set_frequency(frequency) + integrated_signaler.frequency = sanitize_frequency(value) else . = FALSE + if("code") var/value = text2num(params["code"]) if(value) value = round(value) - code = clamp(value, 1, 100) + integrated_signaler.code = clamp(value, 1, 100) else . = FALSE + if("reset") if(params["reset"] == "freq") - frequency = initial(frequency) + integrated_signaler.frequency = initial(integrated_signaler.frequency) else if(params["reset"] == "code") - code = initial(code) + integrated_signaler.code = initial(integrated_signaler.code) else . = FALSE + if(.) add_fingerprint(usr) + +// Electropack signaller type +/obj/item/assembly/signaler/electropack + frequency = AIRLOCK_FREQ + code = 2 + receiving = TRUE + + var/obj/item/electropack/owning_pack + +/obj/item/assembly/signaler/electropack/Initialize(mapload, holding_electropack) + . = ..() + owning_pack = holding_electropack + +/obj/item/assembly/signaler/electropack/signal_callback() + if(owning_pack) + owning_pack.handle_shock() + +/obj/item/assembly/signaler/electropack/Destroy() + owning_pack = null + return ..() diff --git a/code/game/objects/structures/crates_lockers/closets/secure/medical.dm b/code/game/objects/structures/crates_lockers/closets/secure/medical.dm index 041665481cd..9caf552bf87 100644 --- a/code/game/objects/structures/crates_lockers/closets/secure/medical.dm +++ b/code/game/objects/structures/crates_lockers/closets/secure/medical.dm @@ -181,9 +181,9 @@ /obj/structure/closet/secure_closet/animal/populate_contents() new /obj/item/assembly/signaler(src) - new /obj/item/radio/electropack(src) - new /obj/item/radio/electropack(src) - new /obj/item/radio/electropack(src) + new /obj/item/electropack(src) + new /obj/item/electropack(src) + new /obj/item/electropack(src) /obj/structure/closet/secure_closet/chemical diff --git a/code/game/objects/structures/crates_lockers/crates.dm b/code/game/objects/structures/crates_lockers/crates.dm index ab0ca19a9a5..68184bb50f0 100644 --- a/code/game/objects/structures/crates_lockers/crates.dm +++ b/code/game/objects/structures/crates_lockers/crates.dm @@ -40,7 +40,7 @@ return FALSE break - if(rigged && locate(/obj/item/radio/electropack) in src) + if(rigged && locate(/obj/item/electropack) in src) if(isliving(usr)) var/mob/living/L = usr if(L.electrocute_act(17, src)) @@ -105,7 +105,7 @@ else to_chat(user, "You need atleast 15 wires to rig [src]!") return TRUE - if(istype(W, /obj/item/radio/electropack)) + if(istype(W, /obj/item/electropack)) if(rigged) if(!user.drop_item()) to_chat(user, "[W] seems to be stuck to your hand!") @@ -140,7 +140,7 @@ update_icon() return else - if(rigged && locate(/obj/item/radio/electropack) in src) + if(rigged && locate(/obj/item/electropack) in src) if(isliving(user)) var/mob/living/L = user if(L.electrocute_act(17, src)) diff --git a/code/game/objects/structures/electricchair.dm b/code/game/objects/structures/electricchair.dm index 27e1e2670bb..5528580fa1e 100644 --- a/code/game/objects/structures/electricchair.dm +++ b/code/game/objects/structures/electricchair.dm @@ -18,9 +18,9 @@ if(isnull(part)) //This e-chair was not custom built part = new(src) var/obj/item/clothing/head/helmet/part1 = new(part) - var/obj/item/radio/electropack/part2 = new(part) - part2.set_frequency(1445) - part2.code = 6 + var/obj/item/electropack/part2 = new(part) + part2.integrated_signaler.frequency = 1445 + part2.integrated_signaler.code = 6 part2.master = part part.part1 = part1 part.part2 = part2 diff --git a/code/modules/assembly/assembly.dm b/code/modules/assembly/assembly.dm index 2e198be45c5..8f548481618 100644 --- a/code/modules/assembly/assembly.dm +++ b/code/modules/assembly/assembly.dm @@ -48,9 +48,6 @@ /obj/item/assembly/proc/holder_movement() //Called when the holder is moved return -/obj/item/assembly/proc/describe() // Called by grenades to describe the state of the trigger (time left, etc) - return "The trigger assembly looks broken!" - /obj/item/assembly/interact(mob/user) //Called when attack_self is called return diff --git a/code/modules/assembly/igniter.dm b/code/modules/assembly/igniter.dm index c18b96672a6..fbc2934606b 100644 --- a/code/modules/assembly/igniter.dm +++ b/code/modules/assembly/igniter.dm @@ -4,10 +4,11 @@ icon_state = "igniter" materials = list(MAT_METAL=500, MAT_GLASS=50) origin_tech = "magnets=1" - var/datum/effect_system/spark_spread/sparks = new /datum/effect_system/spark_spread + var/datum/effect_system/spark_spread/sparks -/obj/item/assembly/igniter/New() - ..() +/obj/item/assembly/igniter/Initialize(mapload) + . = ..() + sparks = new /datum/effect_system/spark_spread sparks.set_up(2, 0, src) sparks.attach(src) @@ -15,32 +16,36 @@ QDEL_NULL(sparks) return ..() - -/obj/item/assembly/igniter/describe() - return "The igniter is [secured ? "secured." : "unsecured."]" +/obj/item/assembly/igniter/examine(mob/user) + . = ..() + . += "The igniter is [secured ? "secured." : "unsecured."]" /obj/item/assembly/igniter/activate() if(!..()) - return FALSE//Cooldown check + return FALSE //Cooldown check + var/turf/location = get_turf(loc) if(location) - location.hotspot_expose(1000,1000) + location.hotspot_expose(1000, 1000) + sparks.start() + if(istype(loc, /obj/item/assembly_holder)) var/locloc = loc.loc if(istype(locloc, /obj/structure/reagent_dispensers/fueltank)) var/obj/structure/reagent_dispensers/fueltank/tank = locloc if(tank) tank.boom(TRUE) // this qdel's `src` + else if(istype(locloc, /obj/item/reagent_containers/glass/beaker)) var/obj/item/reagent_containers/glass/beaker/beakerbomb = locloc if(beakerbomb) beakerbomb.heat_beaker() + return TRUE /obj/item/assembly/igniter/attack_self(mob/user) activate() add_fingerprint(user) - return diff --git a/code/modules/assembly/infrared.dm b/code/modules/assembly/infrared.dm index 694ca59f6ce..1efec94e043 100644 --- a/code/modules/assembly/infrared.dm +++ b/code/modules/assembly/infrared.dm @@ -25,12 +25,9 @@ fire_location = null return ..() -/obj/item/assembly/infra/describe() - return "The assembly is [secured ? "secure" : "not secure"]. The infrared trigger is [on ? "on" : "off"]." - /obj/item/assembly/infra/examine(mob/user) . = ..() - . += describe() + . += "The assembly is [secured ? "secure" : "not secure"]. The infrared trigger is [on ? "on" : "off"]." /obj/item/assembly/infra/activate() if(!..()) diff --git a/code/modules/assembly/mousetrap.dm b/code/modules/assembly/mousetrap.dm index e6168b3b3ae..398eebd714d 100644 --- a/code/modules/assembly/mousetrap.dm +++ b/code/modules/assembly/mousetrap.dm @@ -14,32 +14,32 @@ . += "It looks like it's armed." /obj/item/assembly/mousetrap/activate() - if(..()) - armed = !armed - if(!armed) - if(ishuman(usr)) - var/mob/living/carbon/human/user = usr - if((user.getBrainLoss() >= 60 || HAS_TRAIT(user, TRAIT_CLUMSY)) && prob(50)) - to_chat(user, "Your hand slips, setting off the trigger.") - pulse(0) - update_icon() - if(usr) - playsound(usr.loc, 'sound/weapons/handcuffs.ogg', 30, 1, -3) + if(!..()) + return + + armed = !armed + if(!armed) + if(ishuman(usr)) + var/mob/living/carbon/human/user = usr + if((user.getBrainLoss() >= 60 || HAS_TRAIT(user, TRAIT_CLUMSY)) && prob(50)) + to_chat(user, "Your hand slips, setting off the trigger.") + pulse(0) + + update_icon() + + if(usr) + playsound(usr.loc, 'sound/weapons/handcuffs.ogg', 30, 1, -3) -/obj/item/assembly/mousetrap/describe() - return "The pressure switch is [armed ? "primed" : "safe"]." /obj/item/assembly/mousetrap/update_icon_state() - if(armed) - icon_state = "mousetraparmed" - else - icon_state = "mousetrap" + icon_state = "mousetrap[armed ? "armed": ""]" if(holder) holder.update_icon() /obj/item/assembly/mousetrap/proc/triggered(mob/target, type = "feet") if(!armed) return + var/obj/item/organ/external/affecting = null if(ishuman(target)) var/mob/living/carbon/human/H = target @@ -49,22 +49,27 @@ update_icon() pulse(FALSE) return FALSE + switch(type) if("feet") if(!H.shoes) affecting = H.get_organ(pick("l_leg", "r_leg")) H.Weaken(6 SECONDS) + if("l_hand", "r_hand") if(!H.gloves) affecting = H.get_organ(type) H.Stun(6 SECONDS) + if(affecting) affecting.receive_damage(1, 0) + else if(ismouse(target)) var/mob/living/simple_animal/mouse/M = target visible_message("SPLAT!") M.death() M.splat() + playsound(loc, 'sound/effects/snap.ogg', 50, 1) layer = MOB_LAYER - 0.2 armed = FALSE @@ -79,11 +84,13 @@ var/which_hand = "l_hand" if(!user.hand) which_hand = "r_hand" + triggered(user, which_hand) - user.visible_message("[user] accidentally sets off [src], breaking [user.p_their()] fingers.", \ - "You accidentally trigger [src]!") + user.visible_message("[user] accidentally sets off [src], breaking [user.p_their()] fingers.", "You accidentally trigger [src]!") return + to_chat(user, "You disarm [src].") + armed = !armed update_icon() playsound(user.loc, 'sound/weapons/handcuffs.ogg', 30, 1, -3) @@ -94,9 +101,9 @@ var/which_hand = "l_hand" if(!user.hand) which_hand = "r_hand" + triggered(user, which_hand) - user.visible_message("[user] accidentally sets off [src], breaking [user.p_their()] fingers.", \ - "You accidentally trigger [src]!") + user.visible_message("[user] accidentally sets off [src], breaking [user.p_their()] fingers.", "You accidentally trigger [src]!") return ..() @@ -106,25 +113,28 @@ var/mob/living/carbon/H = AM if(H.m_intent == MOVE_INTENT_RUN) triggered(H) - H.visible_message("[H] accidentally steps on [src].", \ - "You accidentally step on [src]") + H.visible_message("[H] accidentally steps on [src].", "You accidentally step on [src]") + else if(ismouse(AM)) triggered(AM) + else if(AM.density) // For mousetrap grenades, set off by anything heavy triggered(AM) + ..() /obj/item/assembly/mousetrap/on_found(mob/finder) if(armed) - finder.visible_message("[finder] accidentally sets off [src], breaking [finder.p_their()] fingers.", \ - "You accidentally trigger [src]!") + finder.visible_message("[finder] accidentally sets off [src], breaking [finder.p_their()] fingers.", "You accidentally trigger [src]!") triggered(finder, finder.hand ? "l_hand" : "r_hand") return TRUE //end the search! + return FALSE /obj/item/assembly/mousetrap/hitby(atom/movable/AM, skipcatch, hitpush, blocked, datum/thrownthing/throwingdatum) if(!armed) return ..() + visible_message("[src] is triggered by [AM].") triggered(null) @@ -141,5 +151,5 @@ if(usr.stat) return - layer = TURF_LAYER+0.2 + layer = TURF_LAYER + 0.2 to_chat(usr, "You hide [src].") diff --git a/code/modules/assembly/proximity.dm b/code/modules/assembly/proximity.dm index c8213dbab8f..6424e30007a 100644 --- a/code/modules/assembly/proximity.dm +++ b/code/modules/assembly/proximity.dm @@ -17,10 +17,12 @@ . = ..() AddComponent(/datum/component/proximity_monitor, _always_active = TRUE) -/obj/item/assembly/prox_sensor/describe() +/obj/item/assembly/prox_sensor/examine(mob/user) + . = ..() if(timing) - return "The proximity sensor is arming." - return "The proximity sensor is [scanning ? "armed" : "disarmed"]." + . += "The proximity sensor is arming." + else + . += "The proximity sensor is [scanning ? "armed" : "disarmed"]." /obj/item/assembly/prox_sensor/activate() if(!..()) diff --git a/code/modules/assembly/shock_kit.dm b/code/modules/assembly/shock_kit.dm index 692a478ef3a..db38be9a1ea 100644 --- a/code/modules/assembly/shock_kit.dm +++ b/code/modules/assembly/shock_kit.dm @@ -4,7 +4,7 @@ icon = 'icons/obj/assemblies.dmi' icon_state = "shock_kit" var/obj/item/clothing/head/helmet/part1 = null - var/obj/item/radio/electropack/part2 = null + var/obj/item/electropack/part2 = null var/status = FALSE w_class = WEIGHT_CLASS_HUGE flags = CONDUCT @@ -39,8 +39,7 @@ add_fingerprint(user) return -/obj/item/assembly/shock_kit/receive_signal() +/obj/item/assembly/shock_kit/proc/shock_invoke() if(istype(loc, /obj/structure/chair/e_chair)) var/obj/structure/chair/e_chair/C = loc C.shock() - return diff --git a/code/modules/assembly/signaler.dm b/code/modules/assembly/signaler.dm index 8530ff1fe3c..b8993569949 100644 --- a/code/modules/assembly/signaler.dm +++ b/code/modules/assembly/signaler.dm @@ -1,3 +1,5 @@ +GLOBAL_LIST_EMPTY(remote_signalers) + /obj/item/assembly/signaler name = "remote signaling device" desc = "Used to remotely activate devices." @@ -6,147 +8,92 @@ materials = list(MAT_METAL=400, MAT_GLASS=120) origin_tech = "magnets=1;bluespace=1" wires = WIRE_RECEIVE | WIRE_PULSE | WIRE_RADIO_PULSE | WIRE_RADIO_RECEIVE - secured = TRUE - var/receiving = FALSE - bomb_name = "remote-control bomb" - + /// Are we set to receieve a signal? + var/receiving = FALSE + /// Signal code var/code = 30 + /// Signal freqency itself var/frequency = RSD_FREQ - var/delay = 0 - var/datum/radio_frequency/radio_connection - var/airlock_wire = null - -/obj/item/assembly/signaler/New() - ..() - if(SSradio) - set_frequency(frequency) /obj/item/assembly/signaler/Initialize() - ..() - if(SSradio) - set_frequency(frequency) + . = ..() + GLOB.remote_signalers |= src /obj/item/assembly/signaler/Destroy() - if(SSradio) - SSradio.remove_object(src, frequency) - radio_connection = null + GLOB.remote_signalers -= src return ..() -/obj/item/assembly/signaler/describe() - return "[src]'s power light is [receiving ? "on" : "off"]" +/obj/item/assembly/signaler/examine(mob/user) + . = ..() + . += "The power light is [receiving ? "on" : "off"]" +/// Called from activate(), actually invokes the signal on other signallers in the world +/obj/item/assembly/signaler/proc/signal() + for(var/obj/item/assembly/signaler/S as anything in GLOB.remote_signalers) + if(S == src) + continue + if(S.receiving && (S.code == code) && (S.frequency == frequency)) + S.signal_callback() + + var/turf/T = get_turf(src) + GLOB.lastsignalers.Add("[SQLtime()] : [usr.key] used [src] @ location ([T.x],[T.y],[T.z]) : [format_frequency(frequency)]/[code]") + +/obj/item/assembly/signaler/proc/signal_callback() + pulse(1) + visible_message("[bicon(src)] *beep* *beep*") + +// Activation pre-runner, handles cooldown and calls signal(), invoked from ui_act() /obj/item/assembly/signaler/activate() if(cooldown > 0) - return FALSE + return + cooldown = 2 - addtimer(CALLBACK(src, .proc/process_cooldown), 10) + addtimer(CALLBACK(src, .proc/process_cooldown), 1 SECONDS) signal() - return TRUE /obj/item/assembly/signaler/update_icon_state() if(holder) holder.update_icon() -/obj/item/assembly/signaler/interact(mob/user, flag1) - var/t1 = "-------" - var/dat = {" - - "} - if(!flag1) - dat += {" - Send Signal
- Receiver is [receiving?"on":"off"]
- "} - dat += {" - Frequency/Code for signaler:
- Frequency: - - - - - [format_frequency(frequency)] - + - +
+// UI STUFF // - Code: - - - - - [code] - + - +
- [t1] -
- "} - var/datum/browser/popup = new(user, "radio", name, 400, 400) - popup.set_content(dat) - popup.open(0) - onclose(user, "radio") +/obj/item/assembly/signaler/attack_self(mob/user) + ui_interact(user) -/obj/item/assembly/signaler/Topic(href, href_list) - ..() +/obj/item/assembly/signaler/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.deep_inventory_state) + ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) + if(!ui) + ui = new(user, src, ui_key, "RemoteSignaler", name, 300, 200, master_ui, state) + ui.open() - if(HAS_TRAIT(usr, TRAIT_HANDS_BLOCKED)|| usr.stat || usr.restrained() || !in_range(loc, usr)) - usr << browse(null, "window=radio") - onclose(usr, "radio") +/obj/item/assembly/signaler/ui_data(mob/user) + var/list/data = list() + data["on"] = receiving + data["frequency"] = frequency + data["code"] = code + data["minFrequency"] = PUBLIC_LOW_FREQ + data["maxFrequency"] = PUBLIC_HIGH_FREQ + return data + +/obj/item/assembly/signaler/ui_act(action, list/params, datum/tgui/ui, datum/ui_state/state) + if(..()) return - if(href_list["freq"]) - var/new_frequency = (frequency + text2num(href_list["freq"])) - if(new_frequency < RADIO_LOW_FREQ || new_frequency > RADIO_HIGH_FREQ) - new_frequency = sanitize_frequency(new_frequency, RADIO_LOW_FREQ, RADIO_HIGH_FREQ) - set_frequency(new_frequency) + . = TRUE - if(href_list["code"]) - code += text2num(href_list["code"]) - code = round(code) - code = min(100, code) - code = max(1, code) - if(href_list["receive"]) - receiving = !receiving + switch(action) + if("recv_power") + receiving = !receiving - if(href_list["send"]) - spawn( 0 ) - signal() + if("signal") + activate() - if(usr) - attack_self(usr) + if("freq") + frequency = sanitize_frequency(text2num(params["freq"]) * 10) -/obj/item/assembly/signaler/proc/signal() - if(!radio_connection) - return + if("code") + code = clamp(text2num(params["code"]), 1, 100) - var/datum/signal/signal = new - signal.source = src - signal.encryption = code - signal.data["message"] = "ACTIVATE" - radio_connection.post_signal(src, signal) - - var/time = time2text(world.realtime,"hh:mm:ss") - var/turf/T = get_turf(src) - if(usr) - GLOB.lastsignalers.Add("[time] : [usr.key] used [src] @ location ([T.x],[T.y],[T.z]) : [format_frequency(frequency)]/[code]") - -/obj/item/assembly/signaler/receive_signal(datum/signal/signal) - if(!receiving || !signal) - return FALSE - - if(signal.encryption != code) - return FALSE - - if(!(wires & WIRE_RADIO_RECEIVE)) - return FALSE - pulse(1) - - for(var/mob/O in hearers(1, loc)) - O.show_message("[bicon(src)] *beep* *beep*", 3, "*beep* *beep*", 2) - return TRUE - -/obj/item/assembly/signaler/proc/set_frequency(new_frequency) - if(!SSradio) - sleep(20) - if(!SSradio) - return - SSradio.remove_object(src, frequency) - frequency = new_frequency - radio_connection = SSradio.add_object(src, frequency, RADIO_CHAT) diff --git a/code/modules/assembly/timer.dm b/code/modules/assembly/timer.dm index 187423190ae..48c99b16a58 100644 --- a/code/modules/assembly/timer.dm +++ b/code/modules/assembly/timer.dm @@ -14,10 +14,12 @@ var/repeat = FALSE var/set_time = 10 -/obj/item/assembly/timer/describe() +/obj/item/assembly/timer/examine(mob/user) + . = ..() if(timing) - return "The timer is counting down from [time]!" - return "The timer is set for [time] seconds." + . += "The timer is counting down from [time]!" + else + . += "The timer is set for [time] seconds." /obj/item/assembly/timer/activate() if(!..()) diff --git a/code/modules/assembly/voice.dm b/code/modules/assembly/voice.dm index 681599161cf..1424d0090ad 100644 --- a/code/modules/assembly/voice.dm +++ b/code/modules/assembly/voice.dm @@ -10,11 +10,12 @@ bomb_name = "voice-activated bomb" -/obj/item/assembly/voice/describe() +/obj/item/assembly/voice/examine(mob/user) + . = ..() if(recorded || listening) - return "A meter on [src] flickers with every nearby sound." + . += "A meter on it flickers with every nearby sound." else - return "[src] is deactivated." + . += "It is is deactivated." /obj/item/assembly/voice/hear_talk(mob/living/M as mob, list/message_pieces) hear_input(M, multilingual_to_message(message_pieces), 0) @@ -25,12 +26,14 @@ /obj/item/assembly/voice/proc/hear_input(mob/living/M as mob, msg, type) if(!istype(M,/mob/living)) return + if(listening) recorded = msg recorded_type = type listening = FALSE var/turf/T = get_turf(src) //otherwise it won't work in hand T.visible_message("[bicon(src)] beeps, \"Activation message is [type ? "the sound when one [recorded]" : "'[recorded]'."]\"") + else if(findtext(msg, recorded) && type == recorded_type) var/turf/T = get_turf(src) //otherwise it won't work in hand T.visible_message("[bicon(src)] beeps!") @@ -65,8 +68,9 @@ /obj/item/assembly/voice/noise/attack_self(mob/user) return -/obj/item/assembly/voice/noise/describe() - return "[src] does not appear to have any controls." +/obj/item/assembly/voice/noise/examine(mob/user) + . = ..() + . += "It does not appear to have any controls." /obj/item/assembly/voice/noise/hear_talk(mob/living/M as mob, list/message_pieces) return diff --git a/code/modules/mob/living/silicon/pai/pai.dm b/code/modules/mob/living/silicon/pai/pai.dm index f5e2e250803..ba07ba0df5b 100644 --- a/code/modules/mob/living/silicon/pai/pai.dm +++ b/code/modules/mob/living/silicon/pai/pai.dm @@ -65,7 +65,8 @@ /// List of all installed software var/list/datum/pai_software/installed_software = list() - var/obj/item/integrated_radio/signal/sradio // AI's signaller + /// Integrated remote signaler for signalling + var/obj/item/assembly/signaler/integ_signaler var/translator_on = FALSE // keeps track of the translator module var/flashlight_on = FALSE //keeps track of the flashlight module @@ -74,23 +75,27 @@ var/custom_sprite = FALSE var/slowdown = 0 -/mob/living/silicon/pai/New(obj/item/paicard) - loc = paicard - card = paicard +/mob/living/silicon/pai/Initialize(mapload) + . = ..() + + if(istype(loc, /obj/item/paicard)) + card = loc + if(card) faction = card.faction.Copy() - sradio = new(src) + + integ_signaler = new(src) + if(card) if(!card.radio) card.radio = new /obj/item/radio(card) radio = card.radio //Default languages without universal translator software - add_language("Galactic Common", 1) - add_language("Sol Common", 1) - add_language("Tradeband", 1) - add_language("Gutter", 1) - add_language("Trinary", 1) + add_language("Sol Common") + add_language("Tradeband") + add_language("Gutter") + add_language("Trinary") //Verbs for pAI mobile form, chassis and Say flavor text verbs += /mob/living/silicon/pai/proc/choose_chassis @@ -111,7 +116,6 @@ installed_software[PSD.id] = PSD active_software = installed_software["mainmenu"] // Default us to the main menu - ..() /mob/living/silicon/pai/can_unbuckle() return FALSE @@ -177,11 +181,12 @@ M.show_message("A shower of sparks spray from [src]'s inner workings.", 3, "You hear and smell the ozone hiss of electrical sparks being expelled violently.", 2) return death(0) - switch(pick(1,2,3)) + switch(pick(1, 2, 3)) if(1) master = null master_dna = null to_chat(src, "You feel unbound.") + if(2) var/command if(severity == 1) @@ -190,6 +195,7 @@ command = pick("Serve", "Kill", "Love", "Hate", "Disobey", "Devour", "Fool", "Enrage", "Entice", "Observe", "Judge", "Respect", "Disrespect", "Consume", "Educate", "Destroy", "Disgrace", "Amuse", "Entertain", "Ignite", "Glorify", "Memorialize", "Analyze") pai_law0 = "[command] your master." to_chat(src, "Pr1m3 d1r3c71v3 uPd473D.") + if(3) to_chat(src, "You feel an electric surge run through your circuitry and become acutely aware at how lucky you are that you can still feel at all.") @@ -198,20 +204,17 @@ switch(severity) if(1.0) - if(stat != 2) + if(stat != DEAD) adjustBruteLoss(100) adjustFireLoss(100) if(2.0) - if(stat != 2) + if(stat != DEAD) adjustBruteLoss(60) adjustFireLoss(60) if(3.0) - if(stat != 2) + if(stat != DEAD) adjustBruteLoss(30) - return - - // See software.dm for ui_act() /mob/living/silicon/pai/attack_animal(mob/living/simple_animal/M) diff --git a/code/modules/mob/living/silicon/pai/software/pai_apps.dm b/code/modules/mob/living/silicon/pai/software/pai_apps.dm index 2dad56dd4b4..a18a205084f 100644 --- a/code/modules/mob/living/silicon/pai/software/pai_apps.dm +++ b/code/modules/mob/living/silicon/pai/software/pai_apps.dm @@ -257,8 +257,8 @@ /datum/pai_software/signaler/get_app_data(mob/living/silicon/pai/user) var/list/data = list() - data["frequency"] = user.sradio.frequency - data["code"] = user.sradio.code + data["frequency"] = user.integ_signaler.frequency + data["code"] = user.integ_signaler.code data["minFrequency"] = PUBLIC_LOW_FREQ data["maxFrequency"] = PUBLIC_HIGH_FREQ @@ -270,14 +270,14 @@ switch(action) if("signal") - pai_holder.sradio.send_signal("ACTIVATE") + + pai_holder.integ_signaler.activate() if("freq") - var/new_frequency = sanitize_frequency(text2num(params["freq"]) * 10) - pai_holder.sradio.set_frequency(new_frequency) + pai_holder.integ_signaler.frequency = sanitize_frequency(text2num(params["freq"]) * 10) if("code") - pai_holder.sradio.code = clamp(text2num(params["code"]), 1, 100) + pai_holder.integ_signaler.code = clamp(text2num(params["code"]), 1, 100) // Door Jack // /datum/pai_software/door_jack diff --git a/code/modules/pda/cart.dm b/code/modules/pda/cart.dm index 4257ce6bf1e..6e703b39d69 100644 --- a/code/modules/pda/cart.dm +++ b/code/modules/pda/cart.dm @@ -6,6 +6,9 @@ item_state = "electronic" w_class = WEIGHT_CLASS_TINY + /// Integrated signaler for captain, science & generic signaler cartridge + var/obj/item/assembly/signaler/integ_signaler + var/obj/item/integrated_radio/radio = null var/charges = 0 @@ -24,6 +27,7 @@ for(var/A in programs) var/datum/data/pda/P = A P.pda = pda + for(var/A in messenger_plugins) var/datum/data/pda/messenger_plugin/P = A P.pda = pda @@ -32,32 +36,39 @@ name = "Power-ON Cartridge" icon_state = "cart-e" programs = list( - new/datum/data/pda/app/power, - new/datum/data/pda/utility/scanmode/halogen) + new /datum/data/pda/app/power, + new /datum/data/pda/utility/scanmode/halogen + ) /obj/item/cartridge/atmos name = "BreatheDeep Cartridge" icon_state = "cart-a" - programs = list(new/datum/data/pda/utility/scanmode/gas) + programs = list( + new /datum/data/pda/utility/scanmode/gas + ) /obj/item/cartridge/medical name = "Med-U Cartridge" icon_state = "cart-m" programs = list( - new/datum/data/pda/app/crew_records/medical, - new/datum/data/pda/utility/scanmode/medical) + new /datum/data/pda/app/crew_records/medical, + new /datum/data/pda/utility/scanmode/medical + ) /obj/item/cartridge/chemistry name = "ChemWhiz Cartridge" icon_state = "cart-chem" - programs = list(new/datum/data/pda/utility/scanmode/reagent) + programs = list( + new /datum/data/pda/utility/scanmode/reagent + ) /obj/item/cartridge/security name = "R.O.B.U.S.T. Cartridge" icon_state = "cart-s" programs = list( - new/datum/data/pda/app/crew_records/security, - new/datum/data/pda/app/secbot_control) + new /datum/data/pda/app/crew_records/security, + new /datum/data/pda/app/secbot_control + ) /obj/item/cartridge/security/Initialize(mapload) . = ..() @@ -67,70 +78,75 @@ name = "D.E.T.E.C.T. Cartridge" icon_state = "cart-s" programs = list( - new/datum/data/pda/app/crew_records/medical, - new/datum/data/pda/utility/scanmode/medical, - - new/datum/data/pda/app/crew_records/security) + new /datum/data/pda/app/crew_records/medical, + new /datum/data/pda/utility/scanmode/medical, + new /datum/data/pda/app/crew_records/security + ) /obj/item/cartridge/janitor name = "CustodiPRO Cartridge" desc = "The ultimate in clean-room design." icon_state = "cart-j" - programs = list(new/datum/data/pda/app/janitor) + programs = list( + new /datum/data/pda/app/janitor + ) /obj/item/cartridge/lawyer name = "P.R.O.V.E. Cartridge" icon_state = "cart-s" - programs = list(new/datum/data/pda/app/crew_records/security) + programs = list( + new /datum/data/pda/app/crew_records/security + ) /obj/item/cartridge/clown name = "Honkworks 5.0" icon_state = "cart-clown" charges = 5 - programs = list(new/datum/data/pda/utility/honk) - messenger_plugins = list(new/datum/data/pda/messenger_plugin/virus/clown) + programs = list( + new /datum/data/pda/utility/honk + ) + messenger_plugins = list( + new /datum/data/pda/messenger_plugin/virus/clown + ) /obj/item/cartridge/mime name = "Gestur-O 1000" icon_state = "cart-mi" charges = 5 - messenger_plugins = list(new/datum/data/pda/messenger_plugin/virus/mime) - -/* -/obj/item/cartridge/botanist - name = "Green Thumb v4.20" - icon_state = "cart-b" - access_flora = 1 -*/ + messenger_plugins = list( + new /datum/data/pda/messenger_plugin/virus/mime + ) /obj/item/cartridge/signal name = "generic signaler cartridge" desc = "A data cartridge with an integrated radio signaler module." - programs = list(new/datum/data/pda/app/signaller) + programs = list( + new /datum/data/pda/app/signaller + ) /obj/item/cartridge/signal/Initialize(mapload) . = ..() - radio = new /obj/item/integrated_radio/signal(src) + integ_signaler = new /obj/item/assembly/signaler(src) /obj/item/cartridge/signal/toxins name = "Signal Ace 2" desc = "Complete with integrated radio signaler!" icon_state = "cart-tox" programs = list( - new/datum/data/pda/utility/scanmode/gas, - - new/datum/data/pda/utility/scanmode/reagent, - - new/datum/data/pda/app/signaller) + new /datum/data/pda/utility/scanmode/gas, + new /datum/data/pda/utility/scanmode/reagent, + new /datum/data/pda/app/signaller + ) /obj/item/cartridge/quartermaster name = "Space Parts & Space Vendors Cartridge" desc = "Perfect for the Quartermaster on the go!" icon_state = "cart-q" programs = list( - new/datum/data/pda/app/supply, - new/datum/data/pda/app/mule_control) + new /datum/data/pda/app/supply, + new /datum/data/pda/app/mule_control + ) /obj/item/cartridge/quartermaster/Initialize(mapload) . = ..() @@ -139,20 +155,20 @@ /obj/item/cartridge/head name = "Easy-Record DELUXE" icon_state = "cart-h" - programs = list(new/datum/data/pda/app/status_display) + programs = list( + new /datum/data/pda/app/status_display + ) /obj/item/cartridge/hop name = "HumanResources9001" icon_state = "cart-h" programs = list( - new/datum/data/pda/app/crew_records/security, - - new/datum/data/pda/app/janitor, - - new/datum/data/pda/app/supply, - new/datum/data/pda/app/mule_control, - - new/datum/data/pda/app/status_display) + new /datum/data/pda/app/crew_records/security, + new /datum/data/pda/app/janitor, + new /datum/data/pda/app/supply, + new /datum/data/pda/app/mule_control, + new /datum/data/pda/app/status_display + ) /obj/item/cartridge/hop/Initialize(mapload) . = ..() @@ -162,10 +178,10 @@ name = "R.O.B.U.S.T. DELUXE" icon_state = "cart-hos" programs = list( - new/datum/data/pda/app/crew_records/security, - new/datum/data/pda/app/secbot_control, - - new/datum/data/pda/app/status_display) + new /datum/data/pda/app/crew_records/security, + new /datum/data/pda/app/secbot_control, + new /datum/data/pda/app/status_display + ) /obj/item/cartridge/hos/Initialize(mapload) . = ..() @@ -175,99 +191,85 @@ name = "Power-On DELUXE" icon_state = "cart-ce" programs = list( - new/datum/data/pda/app/power, - new/datum/data/pda/utility/scanmode/halogen, - - new/datum/data/pda/utility/scanmode/gas, - - new/datum/data/pda/app/status_display) + new /datum/data/pda/app/power, + new /datum/data/pda/utility/scanmode/halogen, + new /datum/data/pda/utility/scanmode/gas, + new /datum/data/pda/app/status_display + ) /obj/item/cartridge/cmo name = "Med-U DELUXE" icon_state = "cart-cmo" programs = list( - new/datum/data/pda/app/crew_records/medical, - new/datum/data/pda/utility/scanmode/medical, - - new/datum/data/pda/utility/scanmode/reagent, - - new/datum/data/pda/app/status_display) + new /datum/data/pda/app/crew_records/medical, + new /datum/data/pda/utility/scanmode/medical, + new /datum/data/pda/utility/scanmode/reagent, + new /datum/data/pda/app/status_display + ) /obj/item/cartridge/rd name = "Signal Ace DELUXE" icon_state = "cart-rd" programs = list( - new/datum/data/pda/utility/scanmode/gas, - - new/datum/data/pda/utility/scanmode/reagent, - - new/datum/data/pda/app/signaller, - - new/datum/data/pda/app/status_display) + new /datum/data/pda/utility/scanmode/gas, + new /datum/data/pda/utility/scanmode/reagent, + new /datum/data/pda/app/signaller, + new /datum/data/pda/app/status_display + ) /obj/item/cartridge/rd/Initialize(mapload) . = ..() - radio = new /obj/item/integrated_radio/signal(src) + integ_signaler = new /obj/item/assembly/signaler(src) /obj/item/cartridge/captain name = "Value-PAK Cartridge" desc = "Now with 200% more value!" icon_state = "cart-c" programs = list( - new/datum/data/pda/app/power, - new/datum/data/pda/utility/scanmode/halogen, - - new/datum/data/pda/utility/scanmode/gas, - - new/datum/data/pda/app/crew_records/medical, - new/datum/data/pda/utility/scanmode/medical, - - new/datum/data/pda/utility/scanmode/reagent, - - new/datum/data/pda/app/crew_records/security, - new/datum/data/pda/app/secbot_control, - - new/datum/data/pda/app/janitor, - - new/datum/data/pda/app/supply, - - new/datum/data/pda/app/status_display) + new /datum/data/pda/app/power, + new /datum/data/pda/utility/scanmode/halogen, + new /datum/data/pda/utility/scanmode/gas, + new /datum/data/pda/app/crew_records/medical, + new /datum/data/pda/utility/scanmode/medical, + new /datum/data/pda/utility/scanmode/reagent, + new /datum/data/pda/app/crew_records/security, + new /datum/data/pda/app/secbot_control, + new /datum/data/pda/app/janitor, + new /datum/data/pda/app/supply, + new /datum/data/pda/app/status_display, + new /datum/data/pda/app/signaller + ) /obj/item/cartridge/captain/Initialize(mapload) . = ..() radio = new /obj/item/integrated_radio/beepsky(src) + integ_signaler = new /obj/item/assembly/signaler(src) /obj/item/cartridge/supervisor name = "Easy-Record DELUXE" icon_state = "cart-h" programs = list( - new/datum/data/pda/app/crew_records/security, - - new/datum/data/pda/app/status_display) + new /datum/data/pda/app/crew_records/security, + new /datum/data/pda/app/status_display + ) /obj/item/cartridge/centcom name = "Value-PAK Cartridge" desc = "Now with 200% more value!" icon_state = "cart-c" programs = list( - new/datum/data/pda/app/power, - new/datum/data/pda/utility/scanmode/halogen, - - new/datum/data/pda/utility/scanmode/gas, - - new/datum/data/pda/app/crew_records/medical, - new/datum/data/pda/utility/scanmode/medical, - - new/datum/data/pda/utility/scanmode/reagent, - - new/datum/data/pda/app/crew_records/security, - new/datum/data/pda/app/secbot_control, - - new/datum/data/pda/app/janitor, - - new/datum/data/pda/app/supply, - - new/datum/data/pda/app/status_display) + new /datum/data/pda/app/power, + new /datum/data/pda/utility/scanmode/halogen, + new /datum/data/pda/utility/scanmode/gas, + new /datum/data/pda/app/crew_records/medical, + new /datum/data/pda/utility/scanmode/medical, + new /datum/data/pda/utility/scanmode/reagent, + new /datum/data/pda/app/crew_records/security, + new /datum/data/pda/app/secbot_control, + new /datum/data/pda/app/janitor, + new /datum/data/pda/app/supply, + new /datum/data/pda/app/status_display + ) /obj/item/cartridge/centcom/Initialize(mapload) . = ..() @@ -283,7 +285,9 @@ name = "Nuclear Agent Detomatix Cartridge" desc = "The same reliable Detomatix program except with the added ability of remotely toggling your nuclear shuttle airlock from your PDA" var/initial_remote_door_id = "smindicate" //Make sure this matches the syndicate shuttle's shield/door id!! //don't ask about the name, testing. - programs = list(new/datum/data/pda/utility/toggle_door) + programs = list( + new /datum/data/pda/utility/toggle_door + ) /obj/item/cartridge/syndicate/nuclear/Initialize(mapload) . = ..() @@ -296,13 +300,17 @@ icon_state = "cart" charges = 5 var/telecrystals = 0 - messenger_plugins = list(new/datum/data/pda/messenger_plugin/virus/frame) + messenger_plugins = list( + new /datum/data/pda/messenger_plugin/virus/frame + ) /obj/item/cartridge/mob_hunt_game name = "Nano-Mob Hunter GO! Cartridge" desc = "The hit new PDA game that lets you track down and capture your favorite Nano-Mobs living in your world!" icon_state = "cart-eye" - programs = list(new/datum/data/pda/app/mob_hunter_game) + programs = list( + new /datum/data/pda/app/mob_hunter_game + ) /obj/item/cartridge/mob_hunt_game/detailed_examine_antag() if(emagged) @@ -312,11 +320,13 @@ if(istype(O, /obj/item/nanomob_card)) var/obj/item/nanomob_card/card = O var/datum/data/pda/app/mob_hunter_game/my_game = programs[1] + if(my_game.register_capture(card.mob_data)) to_chat(user, "Transfer successful!") qdel(card) else to_chat(user, "Transfer failed. Could not read mob data from card.") + else ..() diff --git a/code/modules/pda/cart_apps.dm b/code/modules/pda/cart_apps.dm index 4606003b49e..dfe163d0871 100644 --- a/code/modules/pda/cart_apps.dm +++ b/code/modules/pda/cart_apps.dm @@ -68,10 +68,10 @@ category = "Utilities" /datum/data/pda/app/signaller/update_ui(mob/user as mob, list/data) - if(pda.cartridge && istype(pda.cartridge.radio, /obj/item/integrated_radio/signal)) - var/obj/item/integrated_radio/signal/R = pda.cartridge.radio - data["frequency"] = R.frequency - data["code"] = R.code + if(pda?.cartridge?.integ_signaler) + var/obj/item/assembly/signaler/S = pda.cartridge.integ_signaler // Simpler access + data["frequency"] = S.frequency + data["code"] = S.code data["minFrequency"] = PUBLIC_LOW_FREQ data["maxFrequency"] = PUBLIC_HIGH_FREQ @@ -84,20 +84,18 @@ if(!pda.silent) playsound(pda, 'sound/machines/terminal_select.ogg', 15, TRUE) - if(pda.cartridge && istype(pda.cartridge.radio, /obj/item/integrated_radio/signal)) - var/obj/item/integrated_radio/signal/R = pda.cartridge.radio + if(pda?.cartridge?.integ_signaler) + var/obj/item/assembly/signaler/S = pda.cartridge.integ_signaler // Simpler access switch(action) if("signal") - spawn(0) - R.send_signal("ACTIVATE") + S.activate() if("freq") - var/new_frequency = sanitize_frequency(text2num(params["freq"]) * 10) - R.set_frequency(new_frequency) + S.frequency = sanitize_frequency(text2num(params["freq"]) * 10) if("code") - R.code = clamp(text2num(params["code"]), 1, 100) + S.code = clamp(text2num(params["code"]), 1, 100) /datum/data/pda/app/power name = "Power Monitor" diff --git a/code/modules/pda/radio.dm b/code/modules/pda/radio.dm index 7a8dc69c2b7..b7068ee07eb 100644 --- a/code/modules/pda/radio.dm +++ b/code/modules/pda/radio.dm @@ -143,54 +143,3 @@ post_signal(control_freq, "command", "autopick", "active", active, "value", 1, s_filter = RADIO_MULEBOT) post_signal(control_freq, "command", "bot_status", "active", active, s_filter = RADIO_MULEBOT) - - - -/* - * Radio Cartridge, essentially a signaler. - */ - - -/obj/item/integrated_radio/signal - var/frequency = RSD_FREQ - var/code = 30.0 - var/last_transmission - var/datum/radio_frequency/radio_connection - -/obj/item/integrated_radio/signal/Destroy() - if(SSradio) - SSradio.remove_object(src, frequency) - radio_connection = null - return ..() - -/obj/item/integrated_radio/signal/Initialize(mapload) - . = ..() - if(!SSradio) - return - if(src.frequency < PUBLIC_LOW_FREQ || src.frequency > PUBLIC_HIGH_FREQ) - src.frequency = sanitize_frequency(src.frequency) - - set_frequency(frequency) - -/obj/item/integrated_radio/signal/proc/set_frequency(new_frequency) - SSradio.remove_object(src, frequency) - frequency = new_frequency - radio_connection = SSradio.add_object(src, frequency) - -/obj/item/integrated_radio/signal/proc/send_signal(message="ACTIVATE") - - if(last_transmission && world.time < (last_transmission + 5)) - return - last_transmission = world.time - - var/time = time2text(world.realtime,"hh:mm:ss") - var/turf/T = get_turf(src) - GLOB.lastsignalers.Add("[time] : [usr.key] used [src] @ location ([T.x],[T.y],[T.z]) : [format_frequency(frequency)]/[code]") - - var/datum/signal/signal = new - signal.source = src - signal.encryption = code - signal.data["message"] = message - - spawn(0) - radio_connection.post_signal(src, signal) diff --git a/code/modules/research/anomaly/anomaly.dm b/code/modules/research/anomaly/anomaly.dm index 5074c94afc8..632f9a74c5b 100644 --- a/code/modules/research/anomaly/anomaly.dm +++ b/code/modules/research/anomaly/anomaly.dm @@ -8,10 +8,10 @@ receiving = TRUE var/anomaly_type = /obj/effect/anomaly -/obj/item/assembly/signaler/anomaly/receive_signal(datum/signal/signal) - if(..()) - for(var/obj/effect/anomaly/A in get_turf(src)) - A.anomalyNeutralize() +/obj/item/assembly/signaler/anomaly/signal_callback() + if(istype(loc, /obj/effect/anomaly)) + var/obj/effect/anomaly/A = loc + A.anomalyNeutralize() /obj/item/assembly/signaler/anomaly/attack_self() return diff --git a/code/modules/research/designs/autolathe_designs.dm b/code/modules/research/designs/autolathe_designs.dm index a189ad40823..fb9a36033d3 100644 --- a/code/modules/research/designs/autolathe_designs.dm +++ b/code/modules/research/designs/autolathe_designs.dm @@ -676,7 +676,7 @@ id = "electropack" build_type = AUTOLATHE materials = list(MAT_METAL = 10000, MAT_GLASS = 2500) - build_path = /obj/item/radio/electropack + build_path = /obj/item/electropack category = list("hacked", "Tools") /datum/design/large_welding_tool diff --git a/tgui/packages/tgui/interfaces/RemoteSignaler.js b/tgui/packages/tgui/interfaces/RemoteSignaler.js new file mode 100644 index 00000000000..79c7c852991 --- /dev/null +++ b/tgui/packages/tgui/interfaces/RemoteSignaler.js @@ -0,0 +1,31 @@ +import { useBackend } from '../backend'; +import { Button, LabeledList, Section } from '../components'; +import { Window } from '../layouts'; +import { Signaler } from './common/Signaler'; + +export const RemoteSignaler = (props, context) => { + const { act, data } = useBackend(context); + + const { on } = data; + + return ( + + +
+ + +
+
+
+ ); +} diff --git a/tgui/packages/tgui/public/tgui.bundle.js b/tgui/packages/tgui/public/tgui.bundle.js index dd1adfc5daf..c6e41b6fcb9 100644 --- a/tgui/packages/tgui/public/tgui.bundle.js +++ b/tgui/packages/tgui/public/tgui.bundle.js @@ -1,5 +1,5 @@ -!function(e){var t={};function n(o){if(t[o])return t[o].exports;var r=t[o]={i:o,l:!1,exports:{}};return e[o].call(r.exports,r,r.exports,n),r.l=!0,r.exports}n.m=e,n.c=t,n.d=function(e,t,o){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:o})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var o=Object.create(null);if(n.r(o),Object.defineProperty(o,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var r in e)n.d(o,r,function(t){return e[t]}.bind(null,r));return o},n.n=function(e){var t=e&&e.__esModule?function(){return e["default"]}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=230)}([function(e,t,n){"use strict";t.__esModule=!0;var o=n(232);Object.keys(o).forEach((function(e){"default"!==e&&"__esModule"!==e&&(e in t&&t[e]===o[e]||(t[e]=o[e]))}))},function(e,t,n){"use strict";t.__esModule=!0,t.useSharedState=t.useLocalState=t.useBackend=t.deleteLocalState=t.backendUpdate=t.backendSetSharedState=t.backendReducer=t.backendDeleteSharedState=void 0;var o=n(31),r=n(45);t.backendUpdate=function(e){return{type:"backend/update",payload:e}};var a=function(e,t){return{type:"backend/setSharedState",payload:{key:e,nextState:t}}};t.backendSetSharedState=a;var c=function(e){return{type:"backend/deleteSharedState",payload:e}};t.backendDeleteSharedState=c;t.backendReducer=function(e,t){var n=t.type,o=t.payload;if("backend/update"===n){var a=Object.assign({},e.config,o.config),c=Object.assign({},e.data,o.static_data,o.data),i=Object.assign({},e.shared);if(o.shared)for(var l=0,d=Object.keys(o.shared);l1?n-1:0),r=1;rn?n:e};t.clamp01=function(e){return e<0?0:e>1?1:e};t.scale=function(e,t,n){return(e-t)/(n-t)};t.round=function(e,t){return!e||isNaN(e)?e:(t|=0,a=(e*=n=Math.pow(10,t))>0|-(e<0),r=Math.abs(e%1)>=.4999999999854481,o=Math.floor(e),r&&(e=o+(a>0)),(r?e:Math.round(e))/n);var n,o,r,a};t.toFixed=function(e,t){return void 0===t&&(t=0),Number(e).toFixed(Math.max(t,0))};var o=function(e,t){return t&&e>=t[0]&&e<=t[1]};t.inRange=o;t.keyOfMatchingRange=function(e,t){for(var n=0,r=Object.keys(t);n0&&(t.style=l),t};t.computeBoxProps=N;var b=function(e){var t=e.textColor||e.color,n=e.backgroundColor;return(0,o.classes)([u(t)&&"color-"+t,u(n)&&"color-bg-"+n])};t.computeBoxClassName=b;var V=function(e){var t=e.as,n=void 0===t?"div":t,o=e.className,c=e.children,l=function(e,t){if(null==e)return{};var n,o,r={},a=Object.keys(e);for(o=0;o=0||(r[n]=e[n]);return r}(e,i);if("function"==typeof c)return c(N(e));var d="string"==typeof o?o+" "+b(l):b(l),u=N(l);return(0,r.createVNode)(a.VNodeFlags.HtmlElement,n,d,c,a.ChildFlags.UnknownChildren,u)};t.Box=V,V.defaultHooks=o.pureComponentHooks},function(e,t,n){"use strict";var o=n(39);e.exports=function(e){return o(e.length)}},function(e,t,n){"use strict";var o=n(5),r=n(12),a=n(47),c=n(129),i=n(127);e.exports=function(e,t,n,l){var d=!!l&&!!l.unsafe,u=!!l&&!!l.enumerable,s=!!l&&!!l.noTargetGet,m=l&&l.name!==undefined?l.name:t;return r(n)&&c(n,m,l),e===o?(u?e[t]=n:i(t,n),e):(d?!s&&e[t]&&(u=!0):delete e[t],u?e[t]=n:a(e,t,n),e)}},function(e,t,n){"use strict";function o(e,t){var n="undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(n)return(n=n.call(e)).next.bind(n);if(Array.isArray(e)||(n=function(e,t){if(!e)return;if("string"==typeof e)return r(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);"Object"===n&&e.constructor&&(n=e.constructor.name);if("Map"===n||"Set"===n)return Array.from(e);if("Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))return r(e,t)}(e))||t&&e&&"number"==typeof e.length){n&&(e=n);var o=0;return function(){return o>=e.length?{done:!0}:{done:!1,value:e[o++]}}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function r(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,o=new Array(t);n",apos:"'"};return e.replace(/
/gi,"\n").replace(/<\/?[a-z0-9-_]+[^>]*>/gi,"").replace(/&(nbsp|amp|quot|lt|gt|apos);/g,(function(e,n){return t[n]})).replace(/&#?([0-9]+);/gi,(function(e,t){var n=parseInt(t,10);return String.fromCharCode(n)})).replace(/&#x?([0-9a-f]+);/gi,(function(e,t){var n=parseInt(t,16);return String.fromCharCode(n)}))};t.buildQueryString=function(e){return Object.keys(e).map((function(t){return encodeURIComponent(t)+"="+encodeURIComponent(e[t])})).join("&")}},function(e,t,n){"use strict";var o=n(58),r=n(7),a=n(84),c=n(18),i=n(22),l=n(90),d=r([].push),u=function(e){var t=1==e,n=2==e,r=3==e,u=4==e,s=6==e,m=7==e,p=5==e||s;return function(f,h,C,N){for(var b,V,g=c(f),v=a(g),y=o(h,C),x=i(v),_=0,k=N||l,L=t?k(f,x):n||m?k(f,0):undefined;x>_;_++)if((p||_ in v)&&(V=y(b=v[_],_,g),e))if(t)L[_]=V;else if(V)switch(e){case 3:return!0;case 5:return b;case 6:return _;case 2:d(L,b)}else switch(e){case 4:return!1;case 7:d(L,b)}return s?-1:r||u?u:L}};e.exports={forEach:u(0),map:u(1),filter:u(2),some:u(3),every:u(4),find:u(5),findIndex:u(6),filterReject:u(7)}},function(e,t,n){"use strict";var o=n(8),r=n(14),a=n(100),c=n(62),i=n(29),l=n(54),d=n(17),u=n(171),s=Object.getOwnPropertyDescriptor;t.f=o?s:function(e,t){if(e=i(e),t=l(t),u)try{return s(e,t)}catch(n){}if(d(e,t))return c(!r(a.f,e,t),e[t])}},function(e,t,n){"use strict";var o=n(5),r=n(12),a=n(70),c=o.TypeError;e.exports=function(e){if(r(e))return e;throw c(a(e)+" is not a function")}},function(e,t,n){"use strict";var o=n(5),r=n(12),a=function(e){return r(e)?e:undefined};e.exports=function(e,t){return arguments.length<2?a(o[e]):o[e]&&o[e][t]}},function(e,t,n){"use strict";var o=n(84),r=n(30);e.exports=function(e){return o(r(e))}},function(e,t,n){"use strict";var o=n(5).TypeError;e.exports=function(e){if(e==undefined)throw o("Can't call method on "+e);return e}},function(e,t,n){"use strict";function o(e,t,n,o,r,a,c){try{var i=e[a](c),l=i.value}catch(d){return void n(d)}i.done?t(l):Promise.resolve(l).then(o,r)}t.__esModule=!0,t.winset=t.winget=t.runCommand=t.callByondAsync=t.callByond=t.IS_IE8=void 0;var r=window.Byond,a=function(){var e=navigator.userAgent.match(/Trident\/(\d+).+?;/i);if(!e)return null;var t=e[1];return t?parseInt(t,10):null}(),c=null!==a&&a<=6;t.IS_IE8=c;var i=function(e,t){void 0===t&&(t={}),r.call(e,t)};t.callByond=i;var l=function(e,t){void 0===t&&(t={}),window.__callbacks__=window.__callbacks__||[];var n=window.__callbacks__.length,o=new Promise((function(e){window.__callbacks__.push(e)}));return r.call(e,Object.assign({},t,{callback:"__callbacks__["+n+"]"})),o};t.callByondAsync=l;t.runCommand=function(e){return i("winset",{command:e})};var d=function(){var e,t=(e=regeneratorRuntime.mark((function n(e,t){var o;return regeneratorRuntime.wrap((function(n){for(;;)switch(n.prev=n.next){case 0:return n.next=2,l("winget",{id:e,property:t});case 2:return o=n.sent,n.abrupt("return",o[t]);case 4:case"end":return n.stop()}}),n)})),function(){var t=this,n=arguments;return new Promise((function(r,a){var c=e.apply(t,n);function i(e){o(c,r,a,i,l,"next",e)}function l(e){o(c,r,a,i,l,"throw",e)}i(undefined)}))});return function(e,n){return t.apply(this,arguments)}}();t.winget=d;t.winset=function(e,t,n){var o;return i("winset",((o={})[e+"."+t]=n,o))}},function(e,t,n){"use strict";t.__esModule=!0,t.zipWith=t.zip=t.uniqBy=t.toKeyedArray=t.toArray=t.sortBy=t.reduce=t.map=t.filter=void 0;t.toArray=function(e){if(Array.isArray(e))return e;if("object"==typeof e){var t=Object.prototype.hasOwnProperty,n=[];for(var o in e)t.call(e,o)&&n.push(e[o]);return n}return[]};t.toKeyedArray=function(e,t){return void 0===t&&(t="key"),o((function(e,n){var o;return Object.assign(((o={})[t]=n,o),e)}))(e)};t.filter=function(e){return function(t){if(null===t&&t===undefined)return t;if(Array.isArray(t)){for(var n=[],o=0;oi)return 1}return 0};t.sortBy=function(){for(var e=arguments.length,t=new Array(e),n=0;n"+l+""}},function(e,t,n){"use strict";var o=n(6);e.exports=function(e){return o((function(){var t=""[e]('"');return t!==t.toLowerCase()||t.split('"').length>3}))}},function(e,t,n){"use strict";var o,r,a,c=n(173),i=n(5),l=n(7),d=n(11),u=n(47),s=n(17),m=n(126),p=n(102),f=n(86),h=i.TypeError,C=i.WeakMap;if(c||m.state){var N=m.state||(m.state=new C),b=l(N.get),V=l(N.has),g=l(N.set);o=function(e,t){if(V(N,e))throw new h("Object already initialized");return t.facade=e,g(N,e,t),t},r=function(e){return b(N,e)||{}},a=function(e){return V(N,e)}}else{var v=p("state");f[v]=!0,o=function(e,t){if(s(e,v))throw new h("Object already initialized");return t.facade=e,u(e,v,t),t},r=function(e){return s(e,v)?e[v]:{}},a=function(e){return s(e,v)}}e.exports={set:o,get:r,has:a,enforce:function(e){return a(e)?r(e):o(e,{})},getterFor:function(e){return function(t){var n;if(!d(t)||(n=r(t)).type!==e)throw h("Incompatible receiver, "+e+" required");return n}}}},function(e,t,n){"use strict";var o=Math.ceil,r=Math.floor;e.exports=function(e){var t=+e;return t!=t||0===t?0:(t>0?r:o)(t)}},function(e,t,n){"use strict";var o=n(38),r=Math.min;e.exports=function(e){return e>0?r(o(e),9007199254740991):0}},function(e,t,n){"use strict";t.__esModule=!0,t.modalRegisterBodyOverride=t.modalOpen=t.modalClose=t.modalAnswer=t.ComplexModal=void 0;var o=n(0),r=n(1),a=n(2),c={};t.modalOpen=function(e,t,n){var o=(0,r.useBackend)(e),a=o.act,c=o.data,i=Object.assign(c.modal?c.modal.args:{},n||{});a("modal_open",{id:t,arguments:JSON.stringify(i)})};t.modalRegisterBodyOverride=function(e,t){c[e]=t};var i=function(e,t,n,o){var a=(0,r.useBackend)(e),c=a.act,i=a.data;if(i.modal){var l=Object.assign(i.modal.args||{},o||{});c("modal_answer",{id:t,answer:n,arguments:JSON.stringify(l)})}};t.modalAnswer=i;var l=function(e,t){(0,(0,r.useBackend)(e).act)("modal_close",{id:t})};t.modalClose=l;t.ComplexModal=function(e,t){var n=(0,r.useBackend)(t).data;if(n.modal){var d,u,s=n.modal,m=s.id,p=s.text,f=s.type,h=(0,o.createComponentVNode)(2,a.Button,{icon:"arrow-left",content:"Cancel",color:"grey",onClick:function(){return l(t)}}),C="auto";if(c[m])u=c[m](n.modal,t);else if("input"===f){var N=n.modal.value;d=function(e){return i(t,m,N)},u=(0,o.createComponentVNode)(2,a.Input,{value:n.modal.value,placeholder:"ENTER to submit",width:"100%",my:"0.5rem",autofocus:!0,onChange:function(e,t){N=t}}),h=(0,o.createComponentVNode)(2,a.Box,{mt:"0.5rem",children:[(0,o.createComponentVNode)(2,a.Button,{icon:"arrow-left",content:"Cancel",color:"grey",onClick:function(){return l(t)}}),(0,o.createComponentVNode)(2,a.Button,{icon:"check",content:"Confirm",color:"good",float:"right",m:"0",onClick:function(){return i(t,m,N)}}),(0,o.createComponentVNode)(2,a.Box,{clear:"both"})]})}else if("choice"===f){var b="object"==typeof n.modal.choices?Object.values(n.modal.choices):n.modal.choices;u=(0,o.createComponentVNode)(2,a.Dropdown,{options:b,selected:n.modal.value,width:"100%",my:"0.5rem",onSelected:function(e){return i(t,m,e)}}),C="initial"}else"bento"===f?u=(0,o.createComponentVNode)(2,a.Flex,{spacingPrecise:"1",wrap:"wrap",my:"0.5rem",maxHeight:"1%",children:n.modal.choices.map((function(e,r){return(0,o.createComponentVNode)(2,a.Flex.Item,{flex:"1 1 auto",children:(0,o.createComponentVNode)(2,a.Button,{selected:r+1===parseInt(n.modal.value,10),onClick:function(){return i(t,m,r+1)},children:(0,o.createVNode)(1,"img",null,null,1,{src:e})})},r)}))}):"boolean"===f&&(h=(0,o.createComponentVNode)(2,a.Box,{mt:"0.5rem",children:[(0,o.createComponentVNode)(2,a.Button,{icon:"times",content:n.modal.no_text,color:"bad",float:"left",mb:"0",onClick:function(){return i(t,m,0)}}),(0,o.createComponentVNode)(2,a.Button,{icon:"check",content:n.modal.yes_text,color:"good",float:"right",m:"0",onClick:function(){return i(t,m,1)}}),(0,o.createComponentVNode)(2,a.Box,{clear:"both"})]}));return(0,o.createComponentVNode)(2,a.Modal,{maxWidth:e.maxWidth||window.innerWidth/2+"px",maxHeight:e.maxHeight||window.innerHeight/2+"px",onEnter:d,mx:"auto",overflowY:C,children:[(0,o.createComponentVNode)(2,a.Box,{display:"inline",children:p}),u,h]})}}},function(e,t,n){"use strict";var o=n(5),r=n(17),a=n(12),c=n(18),i=n(102),l=n(139),d=i("IE_PROTO"),u=o.Object,s=u.prototype;e.exports=l?u.getPrototypeOf:function(e){var t=c(e);if(r(t,d))return t[d];var n=t.constructor;return a(n)&&t instanceof n?n.prototype:t instanceof u?s:null}},function(e,t,n){"use strict";var o=n(7),r=o({}.toString),a=o("".slice);e.exports=function(e){return a(r(e),8,-1)}},function(e,t,n){"use strict";var o=n(7);e.exports=o({}.isPrototypeOf)},function(e,t,n){"use strict";var o=n(83),r=Function.prototype,a=r.apply,c=r.call;e.exports="object"==typeof Reflect&&Reflect.apply||(o?c.bind(a):function(){return c.apply(a,arguments)})},function(e,t,n){"use strict";t.__esModule=!0,t.timeAgo=t.getGasLabel=t.getGasColor=t.UI_UPDATE=t.UI_INTERACTIVE=t.UI_DISABLED=t.UI_CLOSE=t.RADIO_CHANNELS=t.CSS_COLORS=t.COLORS=void 0;t.UI_INTERACTIVE=2;t.UI_UPDATE=1;t.UI_DISABLED=0;t.UI_CLOSE=-1;t.COLORS={department:{command:"#526aff",security:"#CF0000",medical:"#009190",science:"#993399",engineering:"#A66300",supply:"#9F8545",service:"#80A000",centcom:"#78789B",other:"#C38312"},damageType:{oxy:"#3498db",toxin:"#2ecc71",burn:"#e67e22",brute:"#e74c3c"}};t.CSS_COLORS=["black","white","red","orange","yellow","olive","green","teal","blue","violet","purple","pink","brown","grey","good","average","bad","label"];t.RADIO_CHANNELS=[{name:"Syndicate",freq:1213,color:"#a52a2a"},{name:"SyndTeam",freq:1244,color:"#a52a2a"},{name:"Red Team",freq:1215,color:"#ff4444"},{name:"Blue Team",freq:1217,color:"#3434fd"},{name:"Response Team",freq:1345,color:"#2681a5"},{name:"Special Ops",freq:1341,color:"#2681a5"},{name:"Supply",freq:1347,color:"#b88646"},{name:"Service",freq:1349,color:"#6ca729"},{name:"Science",freq:1351,color:"#c68cfa"},{name:"Command",freq:1353,color:"#5177ff"},{name:"Procedure",freq:1339,color:"#F70285"},{name:"Medical",freq:1355,color:"#57b8f0"},{name:"Medical(I)",freq:1485,color:"#57b8f0"},{name:"Engineering",freq:1357,color:"#f37746"},{name:"Security",freq:1359,color:"#dd3535"},{name:"Security(I)",freq:1475,color:"#dd3535"},{name:"AI Private",freq:1343,color:"#d65d95"},{name:"Common",freq:1459,color:"#1ecc43"}];var o=[{id:"o2",name:"Oxygen",label:"O\u2082",color:"blue"},{id:"n2",name:"Nitrogen",label:"N\u2082",color:"red"},{id:"co2",name:"Carbon Dioxide",label:"CO\u2082",color:"grey"},{id:"plasma",name:"Plasma",label:"Plasma",color:"pink"},{id:"water_vapor",name:"Water Vapor",label:"H\u2082O",color:"grey"},{id:"nob",name:"Hyper-noblium",label:"Hyper-nob",color:"teal"},{id:"n2o",name:"Nitrous Oxide",label:"N\u2082O",color:"red"},{id:"no2",name:"Nitryl",label:"NO\u2082",color:"brown"},{id:"tritium",name:"Tritium",label:"Tritium",color:"green"},{id:"bz",name:"BZ",label:"BZ",color:"purple"},{id:"stim",name:"Stimulum",label:"Stimulum",color:"purple"},{id:"pluox",name:"Pluoxium",label:"Pluoxium",color:"blue"},{id:"miasma",name:"Miasma",label:"Miasma",color:"olive"},{id:"hydrogen",name:"Hydrogen",label:"H\u2082",color:"white"},{id:"ab",name:"Agent B",label:"Agent B",color:"purple"}];t.getGasLabel=function(e,t){var n=String(e).toLowerCase(),r=o.find((function(e){return e.id===n||e.name.toLowerCase()===n}));return r&&r.label||t||e};t.getGasColor=function(e){var t=String(e).toLowerCase(),n=o.find((function(e){return e.id===t||e.name.toLowerCase()===t}));return n&&n.color};t.timeAgo=function(e,t){if(e>t)return"in the future";var n=(t/=10)-(e/=10);if(n>3600){var o=Math.round(n/3600);return o+" hour"+(1===o?"":"s")+" ago"}if(n>60){var r=Math.round(n/60);return r+" minute"+(1===r?"":"s")+" ago"}var a=Math.round(n);return a+" second"+(1===a?"":"s")+" ago"}},function(e,t,n){"use strict";var o=n(28);e.exports=o("navigator","userAgent")||""},function(e,t,n){"use strict";var o=n(8),r=n(16),a=n(62);e.exports=o?function(e,t,n){return r.f(e,t,a(1,n))}:function(e,t,n){return e[t]=n,e}},function(e,t,n){"use strict";var o=n(38),r=Math.max,a=Math.min;e.exports=function(e,t){var n=o(e);return n<0?r(n+t,0):a(n,t)}},function(e,t,n){"use strict";var o,r=n(9),a=n(133),c=n(131),i=n(86),l=n(176),d=n(128),u=n(102),s=u("IE_PROTO"),m=function(){},p=function(e){return"