From 8e177bf01e765a9fae0b6ca043965a4634066d76 Mon Sep 17 00:00:00 2001 From: Letter N <24603524+LetterN@users.noreply.github.com> Date: Fri, 24 Jul 2020 19:58:48 +0800 Subject: [PATCH] another batch - MAJOR: teleportaiton, displaycase (ico port needed), --- code/datums/skills/_check_skills.dm | 10 +- code/game/objects/items/devices/aicard.dm | 20 +- .../items/devices/radio/electropack.dm | 124 ++++++----- .../objects/items/devices/traitordevices.dm | 154 ++++++------- .../objects/items/devices/transfer_valve.dm | 21 +- .../objects/items/implants/implantchair.dm | 11 +- code/game/objects/items/tanks/tanks.dm | 14 +- code/game/objects/items/teleportation.dm | 155 ++++++------- code/game/objects/structures/artstuff.dm | 12 +- code/game/objects/structures/displaycase.dm | 208 ++++++++++++++++++ .../game/objects/structures/tank_dispenser.dm | 15 +- .../antagonists/abductor/machinery/console.dm | 161 +++++++------- .../abductor/machinery/dispenser.dm | 76 +++---- .../abductor/machinery/experiment.dm | 192 +++++++--------- .../changeling/cellular_emporium.dm | 9 +- .../nukeop/equipment/nuclearbomb.dm | 94 ++++---- code/modules/assembly/infrared.dm | 11 +- code/modules/assembly/proximity.dm | 9 +- code/modules/assembly/signaler.dm | 110 +++------ code/modules/assembly/timer.dm | 10 +- 20 files changed, 758 insertions(+), 658 deletions(-) diff --git a/code/datums/skills/_check_skills.dm b/code/datums/skills/_check_skills.dm index 41939dbee3..b40770e073 100644 --- a/code/datums/skills/_check_skills.dm +++ b/code/datums/skills/_check_skills.dm @@ -14,11 +14,13 @@ mind.skill_holder.ui_interact(src) -/datum/skill_holder/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.always_state) - ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) +/datum/skill_panel/ui_state(mob/user) + return GLOB.always_state + +/datum/skill_panel/ui_interact(mob/user, datum/tgui/ui) + ui = SStgui.try_update_ui(user, src, ui) if(!ui) - ui = new(user, src, ui_key, "SkillPanel", "[owner.name]'s Skills", 620, 580, master_ui, state) - ui.set_autoupdate(FALSE) // This UI is only ever opened by one person, and never is updated outside of user input. + ui = new(user, src, "SkillPanel") ui.open() else if(need_static_data_update) update_static_data(user) diff --git a/code/game/objects/items/devices/aicard.dm b/code/game/objects/items/devices/aicard.dm index bfb9348d97..503e2a9473 100644 --- a/code/game/objects/items/devices/aicard.dm +++ b/code/game/objects/items/devices/aicard.dm @@ -54,18 +54,20 @@ name = initial(name) icon_state = initial(icon_state) -/obj/item/aicard/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, \ - datum/tgui/master_ui = null, datum/ui_state/state = GLOB.hands_state) - ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) +/obj/item/aicard/ui_state(mob/user) + return GLOB.hands_state + +/obj/item/aicard/ui_interact(mob/user, datum/tgui/ui) + ui = SStgui.try_update_ui(user, src, ui) if(!ui) - ui = new(user, src, ui_key, "Intellicard", name, 500, 500, master_ui, state) + ui = new(user, src, "Intellicard", name) ui.open() /obj/item/aicard/ui_data() var/list/data = list() if(AI) data["name"] = AI.name - data["laws"] = AI.laws.get_law_list(include_zeroth = 1) + data["laws"] = AI.laws.get_law_list(include_zeroth = TRUE, render_html = FALSE) data["health"] = (AI.health + 100) / 2 data["wireless"] = !AI.control_disabled //todo disabled->enabled data["radio"] = AI.radio_enabled @@ -86,19 +88,19 @@ if(confirm == "Yes" && !..()) flush = TRUE if(AI && AI.loc == src) - to_chat(AI, "Your core files are being wiped!") + to_chat(AI, "Your core files are being wiped!") while(AI.stat != DEAD && flush) - AI.adjustOxyLoss(1) + AI.adjustOxyLoss(5) AI.updatehealth() sleep(5) flush = FALSE . = TRUE if("wireless") AI.control_disabled = !AI.control_disabled - to_chat(AI, "[src]'s wireless port has been [AI.control_disabled ? "disabled" : "enabled"]!") + to_chat(AI, "[src]'s wireless port has been [AI.control_disabled ? "disabled" : "enabled"]!") . = TRUE if("radio") AI.radio_enabled = !AI.radio_enabled - to_chat(AI, "Your Subspace Transceiver has been [AI.radio_enabled ? "enabled" : "disabled"]!") + to_chat(AI, "Your Subspace Transceiver has been [AI.radio_enabled ? "enabled" : "disabled"]!") . = TRUE update_icon() diff --git a/code/game/objects/items/devices/radio/electropack.dm b/code/game/objects/items/devices/radio/electropack.dm index cdb8c09527..42bf1929d6 100644 --- a/code/game/objects/items/devices/radio/electropack.dm +++ b/code/game/objects/items/devices/radio/electropack.dm @@ -29,7 +29,7 @@ /obj/item/electropack/Destroy() SSradio.remove_object(src, frequency) - . = ..() + return ..() //ATTACK HAND IGNORING PARENT RETURN VALUE /obj/item/electropack/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) @@ -40,7 +40,7 @@ return return ..() -/obj/item/electropack/attackby(obj/item/W, mob/living/user, params) +/obj/item/electropack/attackby(obj/item/W, mob/user, params) if(istype(W, /obj/item/clothing/head/helmet)) var/obj/item/assembly/shock_kit/A = new /obj/item/assembly/shock_kit(user) A.icon = 'icons/obj/assemblies.dmi' @@ -60,56 +60,12 @@ else return ..() -/obj/item/electropack/Topic(href, href_list) - var/mob/living/carbon/C = usr - if(usr.stat || usr.restrained() || C.back == src) - return - - if(!usr.canUseTopic(src, BE_CLOSE)) - usr << browse(null, "window=radio") - onclose(usr, "radio") - return - - if(href_list["set"]) - if(href_list["set"] == "freq") - var/new_freq = input(usr, "Input a new receiving frequency", "Electropack Frequency", format_frequency(frequency)) as num|null - if(!usr.canUseTopic(src, BE_CLOSE)) - return - new_freq = unformat_frequency(new_freq) - new_freq = sanitize_frequency(new_freq, TRUE) - set_frequency(new_freq) - - if(href_list["set"] == "code") - var/new_code = input(usr, "Input a new receiving code", "Electropack Code", code) as num|null - if(!usr.canUseTopic(src, BE_CLOSE)) - return - new_code = round(new_code) - new_code = clamp(new_code, 1, 100) - code = new_code - - if(href_list["set"] == "power") - if(!usr.canUseTopic(src, BE_CLOSE)) - return - on = !(on) - icon_state = "electropack[on]" - - if(usr) - attack_self(usr) - - return - -/obj/item/electropack/proc/set_frequency(new_frequency) - SSradio.remove_object(src, frequency) - frequency = new_frequency - SSradio.add_object(src, frequency, RADIO_SIGNALER) - return - /obj/item/electropack/receive_signal(datum/signal/signal) if(!signal || signal.data["code"] != code) return if(isliving(loc) && on) - if(shock_cooldown == TRUE) + if(shock_cooldown) return shock_cooldown = TRUE addtimer(VARSET_CALLBACK(src, shock_cooldown, FALSE), 100) @@ -125,18 +81,59 @@ if(master) master.receive_signal() - return -/obj/item/electropack/ui_interact(mob/user) - if(!ishuman(user)) +/obj/item/electropack/proc/set_frequency(new_frequency) + SSradio.remove_object(src, frequency) + frequency = new_frequency + SSradio.add_object(src, frequency, RADIO_SIGNALER) + +/obj/item/electropack/ui_state(mob/user) + return GLOB.hands_state + +/obj/item/electropack/ui_interact(mob/user, datum/tgui/ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "Electropack", name) + ui.open() + +/obj/item/electropack/ui_data(mob/user) + var/list/data = list() + data["power"] = on + data["frequency"] = frequency + data["code"] = code + data["minFrequency"] = MIN_FREE_FREQ + data["maxFrequency"] = MAX_FREE_FREQ + return data + +/obj/item/electropack/ui_act(action, params) + if(..()) return -/obj/item/electropack/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, \ - datum/tgui/master_ui = null, datum/ui_state/state = GLOB.hands_state) - ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) - if(!ui) - ui = new(user, src, ui_key, "Electropack", name, ui_x, ui_y, master_ui, state) - ui.open() + switch(action) + if("power") + on = !on + icon_state = "electropack[on]" + . = TRUE + if("freq") + var/value = unformat_frequency(params["freq"]) + if(value) + frequency = sanitize_frequency(value, TRUE) + set_frequency(frequency) + . = TRUE + if("code") + var/value = text2num(params["code"]) + if(value) + value = round(value) + code = clamp(value, 1, 100) + . = TRUE + if("reset") + if(params["reset"] == "freq") + frequency = initial(frequency) + . = TRUE + else if(params["reset"] == "code") + code = initial(code) + . = TRUE + /obj/item/electropack/shockcollar name = "shock collar" @@ -146,7 +143,7 @@ icon_state = "shockcollar" item_state = "shockcollar" body_parts_covered = NECK - slot_flags = ITEM_SLOT_NECK | ITEM_SLOT_DENYPOCKET //no more pocket shockers + slot_flags = ITEM_SLOT_NECK //no more pocket shockers. Now done without lazyness w_class = WEIGHT_CLASS_SMALL strip_delay = 60 equip_delay_other = 60 @@ -168,16 +165,18 @@ return return ..() -/obj/item/electropack/shockcollar/receive_signal(datum/signal/signal) +/obj/item/electropack/shockcollar/receive_signal(datum/signal/signal) //we have to override this because of text if(!signal || signal.data["code"] != code) return - if(isliving(loc) && on) + if(isliving(loc) && on) //the "on" arg is currently useless + var/mob/living/L = loc + if(!L.get_item_by_slot(SLOT_NECK)) //**properly** stops pocket shockers + return if(shock_cooldown == TRUE) return shock_cooldown = TRUE addtimer(VARSET_CALLBACK(src, shock_cooldown, FALSE), 100) - var/mob/living/L = loc step(L, pick(GLOB.cardinals)) to_chat(L, "You feel a sharp shock from the collar!") @@ -197,10 +196,13 @@ if(t) tagname = t name = "[initial(name)] - [t]" + return + if(istype(W, /obj/item/clothing/head/helmet)) //lazy method of denying this + return else return ..() -/obj/item/electropack/shockcollar/ui_interact(mob/user) //on_click calls this +/obj/item/electropack/shockcollar/ui_interact(mob/user) //note to src: use tgooey var/dat = {" Frequency/Code for shock collar:
diff --git a/code/game/objects/items/devices/traitordevices.dm b/code/game/objects/items/devices/traitordevices.dm index 4d255fd339..eb444cdb12 100644 --- a/code/game/objects/items/devices/traitordevices.dm +++ b/code/game/objects/items/devices/traitordevices.dm @@ -86,98 +86,102 @@ effective or pretty fucking useless. return if(!used) log_combat(user, M, "irradiated", src) - var/cooldown = GetCooldown() - used = 1 + var/cooldown = get_cooldown() + used = TRUE icon_state = "health1" - handle_cooldown(cooldown) // splits off to handle the cooldown while handling wavelength + addtimer(VARSET_CALLBACK(src, used, FALSE), cooldown) + addtimer(VARSET_CALLBACK(src, icon_state, "health"), cooldown) to_chat(user, "Successfully irradiated [M].") - spawn((wavelength+(intensity*4))*5) - if(M) - if(intensity >= 5) - M.apply_effect(round(intensity/0.075), EFFECT_UNCONSCIOUS) - M.rad_act(intensity*10) + addtimer(CALLBACK(src, .proc/radiation_aftereffect, M), (wavelength+(intensity*4))*5) else to_chat(user, "The radioactive microlaser is still recharging.") -/obj/item/healthanalyzer/rad_laser/proc/handle_cooldown(cooldown) - spawn(cooldown) - used = 0 - icon_state = "health" +/obj/item/healthanalyzer/rad_laser/proc/radiation_aftereffect(mob/living/M) + if(QDELETED(M)) + return + if(intensity >= 5) + M.apply_effect(round(intensity/0.075), EFFECT_UNCONSCIOUS) + M.rad_act(intensity*10) + +/obj/item/healthanalyzer/rad_laser/proc/get_cooldown() + return round(max(10, (stealth*30 + intensity*5 - wavelength/4))) /obj/item/healthanalyzer/rad_laser/attack_self(mob/user) interact(user) -/obj/item/healthanalyzer/rad_laser/proc/GetCooldown() - return round(max(10, (stealth*30 + intensity*5 - wavelength/4))) - /obj/item/healthanalyzer/rad_laser/interact(mob/user) ui_interact(user) -/obj/item/healthanalyzer/rad_laser/ui_interact(mob/user) -/obj/item/healthanalyzer/rad_laser/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, \ - datum/tgui/master_ui = null, datum/ui_state/state = GLOB.hands_state) - ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) +/obj/item/healthanalyzer/rad_laser/ui_state(mob/user) + return GLOB.hands_state + +/obj/item/healthanalyzer/rad_laser/ui_interact(mob/user, datum/tgui/ui) + ui = SStgui.try_update_ui(user, src, ui) if(!ui) - ui = new(user, src, ui_key, "RadioactiveMicrolaser", "Radioactive Microlaser", ui_x, ui_y, master_ui, state) + ui = new(user, src, "RadioactiveMicrolaser") ui.open() - var/dat = "Irradiation: [irradiate ? "On" : "Off"]
" - dat += "Stealth Mode (NOTE: Deactivates automatically while Irradiation is off): [stealth ? "On" : "Off"]
" - dat += "Scan Mode: " - if(!scanmode) - dat += "Scan Health" - else if(scanmode == 1) - dat += "Scan Reagents" - else - dat += "Disabled" - dat += "

" +/obj/item/healthanalyzer/rad_laser/ui_data(mob/user) + var/list/data = list() + data["irradiate"] = irradiate + data["stealth"] = stealth + data["scanmode"] = scanmode + data["intensity"] = intensity + data["wavelength"] = wavelength + data["on_cooldown"] = used + data["cooldown"] = DisplayTimeText(get_cooldown()) + return data - dat += {" - Radiation Intensity: - -- - [intensity] - ++
+/obj/item/healthanalyzer/rad_laser/ui_act(action, params) + if(..()) + return - Radiation Wavelength: - -- - [(wavelength+(intensity*4))] - ++
- Laser Cooldown: [DisplayTimeText(GetCooldown())]
- "} - - var/datum/browser/popup = new(user, "radlaser", "Radioactive Microlaser Interface", 400, 240) - popup.set_content(dat) - popup.open() - -/obj/item/healthanalyzer/rad_laser/Topic(href, href_list) - if(!usr.canUseTopic(src)) - return 1 - - usr.set_machine(src) - if(href_list["rad"]) - irradiate = !irradiate - - else if(href_list["stealthy"]) - stealth = !stealth - - else if(href_list["mode"]) - scanmode += 1 - if(scanmode > 2) - scanmode = 0 - - else if(href_list["radint"]) - var/amount = text2num(href_list["radint"]) - amount += intensity - intensity = max(1,(min(20,amount))) - - else if(href_list["radwav"]) - var/amount = text2num(href_list["radwav"]) - amount += wavelength - wavelength = max(0,(min(120,amount))) - - attack_self(usr) - add_fingerprint(usr) - return + switch(action) + if("irradiate") + irradiate = !irradiate + . = TRUE + if("stealth") + stealth = !stealth + . = TRUE + if("scanmode") + scanmode = !scanmode + . = TRUE + if("radintensity") + var/target = params["target"] + var/adjust = text2num(params["adjust"]) + if(target == "min") + target = 1 + . = TRUE + else if(target == "max") + target = 20 + . = TRUE + else if(adjust) + target = intensity + adjust + . = TRUE + else if(text2num(target) != null) + target = text2num(target) + . = TRUE + if(.) + target = round(target) + intensity = clamp(target, 1, 20) + if("radwavelength") + var/target = params["target"] + var/adjust = text2num(params["adjust"]) + if(target == "min") + target = 0 + . = TRUE + else if(target == "max") + target = 120 + . = TRUE + else if(adjust) + target = wavelength + adjust + . = TRUE + else if(text2num(target) != null) + target = text2num(target) + . = TRUE + if(.) + target = round(target) + wavelength = clamp(target, 0, 120) /obj/item/shadowcloak name = "cloaker belt" diff --git a/code/game/objects/items/devices/transfer_valve.dm b/code/game/objects/items/devices/transfer_valve.dm index ccf9dcd253..7c3a2a2c14 100644 --- a/code/game/objects/items/devices/transfer_valve.dm +++ b/code/game/objects/items/devices/transfer_valve.dm @@ -188,11 +188,10 @@ tank_one.air_contents.merge(temp) tank_two.air_contents.set_volume(tank_two.air_contents.return_volume() - tank_one.air_contents.return_volume()) - /* +/* Exadv1: I know this isn't how it's going to work, but this was just to check it explodes properly when it gets a signal (and it does). - */ - +*/ /obj/item/transfer_valve/proc/toggle_valve() if(!valve_open && tank_one && tank_two) valve_open = TRUE @@ -233,16 +232,20 @@ valve_open = FALSE update_icon() -// this doesn't do anything but the timer etc. expects it to be here -// eventually maybe have it update icon to show state (timer, prox etc.) like old bombs +/* + This doesn't do anything but the timer etc. expects it to be here + eventually maybe have it update icon to show state (timer, prox etc.) like old bombs +*/ /obj/item/transfer_valve/proc/c_state() return -/obj/item/transfer_valve/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, \ - datum/tgui/master_ui = null, datum/ui_state/state = GLOB.hands_state) - ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) +/obj/item/transfer_valve/ui_state(mob/user) + return GLOB.hands_state + +/obj/item/transfer_valve/ui_interact(mob/user, datum/tgui/ui) + ui = SStgui.try_update_ui(user, src, ui) if(!ui) - ui = new(user, src, ui_key, "TransferValve", name, ui_x, ui_y, master_ui, state) + ui = new(user, src, "TransferValve", name) ui.open() /obj/item/transfer_valve/ui_data(mob/user) diff --git a/code/game/objects/items/implants/implantchair.dm b/code/game/objects/items/implants/implantchair.dm index 3ea27c84bb..6d4e85ac13 100644 --- a/code/game/objects/items/implants/implantchair.dm +++ b/code/game/objects/items/implants/implantchair.dm @@ -26,14 +26,15 @@ open_machine() update_icon() +/obj/machinery/implantchair/ui_state(mob/user) + return GLOB.notcontained_state -/obj/machinery/implantchair/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.notcontained_state) - ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) +/obj/machinery/implantchair/ui_interact(mob/user, datum/tgui/ui) + ui = SStgui.try_update_ui(user, src, ui) if(!ui) - ui = new(user, src, ui_key, "implantchair", name, 375, 280, master_ui, state) + ui = new(user, src, "ImplantChair", name) ui.open() - /obj/machinery/implantchair/ui_data() var/list/data = list() data["occupied"] = occupant ? 1 : 0 @@ -191,4 +192,4 @@ brainwash(C, objective) message_admins("[ADMIN_LOOKUPFLW(user)] brainwashed [key_name_admin(C)] with objective '[objective]'.") log_game("[key_name(user)] brainwashed [key_name(C)] with objective '[objective]'.") - return TRUE \ No newline at end of file + return TRUE diff --git a/code/game/objects/items/tanks/tanks.dm b/code/game/objects/items/tanks/tanks.dm index b601e4310e..c438d00845 100644 --- a/code/game/objects/items/tanks/tanks.dm +++ b/code/game/objects/items/tanks/tanks.dm @@ -164,11 +164,13 @@ else . = ..() -/obj/item/tank/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, \ - datum/tgui/master_ui = null, datum/ui_state/state = GLOB.hands_state) - ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) +/obj/item/tank/ui_state(mob/user) + return GLOB.hands_state + +/obj/item/tank/ui_interact(mob/user, datum/tgui/ui) + ui = SStgui.try_update_ui(user, src, ui) if(!ui) - ui = new(user, src, ui_key, "Tank", name, 400, 120, master_ui, state) + ui = new(user, src, "Tank", name) ui.open() /obj/item/tank/ui_data(mob/user) @@ -205,10 +207,6 @@ else if(pressure == "max") pressure = TANK_MAX_RELEASE_PRESSURE . = TRUE - else if(pressure == "input") - pressure = input("New release pressure ([TANK_MIN_RELEASE_PRESSURE]-[TANK_MAX_RELEASE_PRESSURE] kPa):", name, distribute_pressure) as num|null - if(!isnull(pressure) && !..()) - . = TRUE else if(text2num(pressure) != null) pressure = text2num(pressure) . = TRUE diff --git a/code/game/objects/items/teleportation.dm b/code/game/objects/items/teleportation.dm index 881e4d5f1a..939b9e4905 100644 --- a/code/game/objects/items/teleportation.dm +++ b/code/game/objects/items/teleportation.dm @@ -1,4 +1,3 @@ - #define SOURCE_PORTAL 1 #define DESTINATION_PORTAL 2 @@ -25,90 +24,72 @@ throw_speed = 3 throw_range = 7 custom_materials = list(/datum/material/iron=400) + var/tracking_range = 20 -/obj/item/locator/attack_self(mob/user) - user.set_machine(src) - var/dat - if (temp) - dat = "[temp]

Clear" - else - dat = {" -Persistent Signal Locator
-Refresh"} - user << browse(dat, "window=radio") - onclose(user, "radio") - return +/obj/item/locator/ui_interact(mob/user, datum/tgui/ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "BluespaceLocator", name) + ui.open() -/obj/item/locator/Topic(href, href_list) - ..() - if (usr.stat || usr.restrained()) - return - var/turf/current_location = get_turf(usr)//What turf is the user on? - if(!current_location || is_centcom_level(current_location.z))//If turf was not found or they're on CentCom - to_chat(usr, "[src] is malfunctioning.") - return - if(usr.contents.Find(src) || (in_range(src, usr) && isturf(loc))) - usr.set_machine(src) - if (href_list["refresh"]) - temp = "Persistent Signal Locator
" - var/turf/sr = get_turf(src) +/obj/item/locator/ui_data(mob/user) + var/list/data = list() - if (sr) - temp += "Beacon Signals:
" - for(var/obj/item/beacon/W in GLOB.teleportbeacons) - if (!W.renamed) - continue - var/turf/tr = get_turf(W) - if (tr.z == sr.z && tr) - var/direct = max(abs(tr.x - sr.x), abs(tr.y - sr.y)) - if (direct < 5) - direct = "very strong" - else - if (direct < 10) - direct = "strong" - else - if (direct < 20) - direct = "weak" - else - direct = "very weak" - temp += "[W.name]-[dir2text(get_dir(sr, tr))]-[direct]
" + data["trackingrange"] = tracking_range - temp += "Implant Signals:
" - for (var/obj/item/implant/tracking/W in GLOB.tracked_implants) - if (!isliving(W.imp_in)) - continue - var/mob/living/M = W.imp_in - if (M.stat == DEAD) - if (M.timeofdeath + W.lifespan_postmortem < world.time) - continue + // Get our current turf location. + var/turf/sr = get_turf(src) - var/turf/tr = get_turf(M) - if (tr.z == sr.z && tr) - var/direct = max(abs(tr.x - sr.x), abs(tr.y - sr.y)) - if (direct < 20) - if (direct < 5) - direct = "very strong" - else - if (direct < 10) - direct = "strong" - else - direct = "weak" - temp += "[W.imp_in.name]-[dir2text(get_dir(sr, tr))]-[direct]
" + if (sr) + // Check every teleport beacon. + var/list/tele_beacons = list() + for(var/obj/item/beacon/W in GLOB.teleportbeacons) - temp += "You are at \[[sr.x],[sr.y],[sr.z]\] in orbital coordinates.

Refresh
" + // Get the tracking beacon's turf location. + var/turf/tr = get_turf(W) + + // Make sure it's on a turf and that its Z-level matches the tracker's Z-level + if (tr && tr.z == sr.z) + // Get the distance between the beacon's turf and our turf + var/distance = max(abs(tr.x - sr.x), abs(tr.y - sr.y)) + + // If the target is too far away, skip over this beacon. + if(distance > tracking_range) + continue + + var/beacon_name + + if(W.renamed) + beacon_name = W.name + else + var/area/A = get_area(W) + beacon_name = A.name + + var/D = dir2text(get_dir(sr, tr)) + tele_beacons += list(list(name = beacon_name, direction = D, distance = distance)) + + data["telebeacons"] = tele_beacons + + var/list/track_implants = list() + + for (var/obj/item/implant/tracking/W in GLOB.tracked_implants) + if (!W.imp_in || !isliving(W.loc)) + continue else - temp += "Processing Error: Unable to locate orbital position.
" - else - if (href_list["temp"]) - temp = null - if (ismob(src.loc)) - attack_self(src.loc) - else - for(var/mob/M in fov_viewers(1, src)) - if (M.client) - src.attack_self(M) - return + var/mob/living/M = W.loc + if (M.stat == DEAD) + if (M.timeofdeath + W.lifespan_postmortem < world.time) + continue + var/turf/tr = get_turf(W) + var/distance = max(abs(tr.x - sr.x), abs(tr.y - sr.y)) + if(distance > tracking_range) + continue + + var/D = dir2text(get_dir(sr, tr)) + track_implants += list(list(name = W.imp_in.name, direction = D, distance = distance)) + data["trackimplants"] = track_implants + return data /* * Hand-tele @@ -141,14 +122,11 @@ return TRUE return ..() -/obj/item/hand_tele/proc/try_dispel_portal(atom/target, mob/user, delay = 30) - var/datum/beam/B = user.Beam(target, icon_state = "rped_upgrade", maxdistance = 50) - if(is_parent_of_portal(target) && (!delay || do_after(user, delay, target = target))) +/obj/item/hand_tele/proc/try_dispel_portal(atom/target, mob/user) + if(is_parent_of_portal(target)) qdel(target) to_chat(user, "You dispel [target] with \the [src]!") - qdel(B) return TRUE - qdel(B) return FALSE /obj/item/hand_tele/afterattack(atom/target, mob/user) @@ -190,13 +168,8 @@ user.show_message("\The [src] is recharging!") return var/atom/T = L[t1] - var/implantcheckmate = FALSE - if(isliving(T)) - var/mob/living/M = T - if(!locate(/obj/item/implant/tracking) in M.implants) //The user was too slow and let the target mob's tracking implant expire or get removed. - implantcheckmate = TRUE var/area/A = get_area(T) - if(A.noteleport || implantcheckmate) + if(A.noteleport) to_chat(user, "\The [src] is malfunctioning.") return current_location = get_turf(user) //Recheck. @@ -205,10 +178,12 @@ to_chat(user, "\The [src] is malfunctioning.") return user.show_message("Locked In.", MSG_AUDIBLE) - var/list/obj/effect/portal/created = create_portal_pair(current_location, get_teleport_turf(get_turf(T)), src, 300, 1, null, atmos_link_override) + var/list/obj/effect/portal/created = create_portal_pair(current_location, get_teleport_turf(get_turf(T)), 300, 1, null, atmos_link_override) if(!(LAZYLEN(created) == 2)) return - try_move_adjacent(created[1]) + RegisterSignal(created[1], COMSIG_PARENT_QDELETING, .proc/on_portal_destroy) //Gosh darn it kevinz. + RegisterSignal(created[2], COMSIG_PARENT_QDELETING, .proc/on_portal_destroy) + try_move_adjacent(created[1], user.dir) active_portal_pairs[created[1]] = created[2] var/obj/effect/portal/c1 = created[1] var/obj/effect/portal/c2 = created[2] diff --git a/code/game/objects/structures/artstuff.dm b/code/game/objects/structures/artstuff.dm index 827e9a7b0a..c7e013f802 100644 --- a/code/game/objects/structures/artstuff.dm +++ b/code/game/objects/structures/artstuff.dm @@ -75,12 +75,16 @@ . = ..() ui_interact(user) -/obj/item/canvas/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, \ - datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state) +/obj/item/canvas/ui_state(mob/user) + if(finalized) + return GLOB.physical_obscured_state + else + return GLOB.default_state - ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) +/obj/item/canvas/ui_interact(mob/user, datum/tgui/ui) + ui = SStgui.try_update_ui(user, src, ui) if(!ui) - ui = new(user, src, ui_key, "Canvas", name, ui_x, ui_y, master_ui, state) + ui = new(user, src, "Canvas", name) ui.set_autoupdate(FALSE) ui.open() diff --git a/code/game/objects/structures/displaycase.dm b/code/game/objects/structures/displaycase.dm index 4db889b392..d7343df24c 100644 --- a/code/game/objects/structures/displaycase.dm +++ b/code/game/objects/structures/displaycase.dm @@ -347,3 +347,211 @@ name = initial(I.name) icon = initial(I.icon) icon_state = initial(I.icon_state) + +/obj/structure/displaycase/forsale + name = "vend-a-tray" + icon = 'icons/obj/stationobjs.dmi' + icon_state = "laserbox0" + desc = "A display case with an ID-card swiper. Use your ID to purchase the contents." + density = FALSE + max_integrity = 100 + req_access = null + showpiece_type = /obj/item/reagent_containers/food + alert = FALSE //No, we're not calling the fire department because someone stole your cookie. + glass_fix = FALSE //Fixable with tools instead. + ///The price of the item being sold. Altered by grab intent ID use. + var/sale_price = 20 + ///The Account which will receive payment for purchases. Set by the first ID to swipe the tray. + var/datum/bank_account/payments_acc = null + ///We're using the same trick as paper does in order to cache the image, and only load the UI when messed with. + var/list/viewing_ui = list() + +/obj/structure/displaycase/forsale/update_icon() //remind me to fix my shitcode later + var/icon/I + if(open) + I = icon('icons/obj/stationobjs.dmi',"laserboxb0") + else + I = icon('icons/obj/stationobjs.dmi',"laserbox0") + if(!showpiece && !open) + I = icon('icons/obj/stationobjs.dmi',"laserbox_open") + if(broken) + I = icon('icons/obj/stationobjs.dmi',"laserbox_broken") + if(showpiece) + var/icon/S = getFlatIcon(showpiece) + S.Scale(17,17) + I.Blend(S,ICON_UNDERLAY,8,12) + src.icon = I + return + +/obj/structure/displaycase/forsale/ui_interact(mob/user, datum/tgui/ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "Vendatray", name) + ui.set_autoupdate(FALSE) + viewing_ui[user] = ui + ui.open() + +/obj/structure/displaycase/forsale/ui_data(mob/user) + var/list/data = list() + var/register = FALSE + if(payments_acc) + register = TRUE + data["owner_name"] = payments_acc.account_holder + if(showpiece) + data["product_name"] = capitalize(showpiece.name) + var/base64 = icon2base64(icon(showpiece.icon, showpiece.icon_state)) + data["product_icon"] = base64 + data["registered"] = register + data["product_cost"] = sale_price + data["tray_open"] = open + return data + +/obj/structure/displaycase/forsale/ui_act(action, params) + if(..()) + return + var/obj/item/card/id/potential_acc = usr.get_idcard(hand_first = TRUE) + switch(action) + if("Buy") + if(!showpiece) + to_chat(usr, "There's nothing for sale.") + return TRUE + if(broken) + to_chat(usr, "[src] appears to be broken.") + return TRUE + if(!payments_acc) + to_chat(usr, "[src] hasn't been registered yet.") + return TRUE + if(!usr.canUseTopic(src, BE_CLOSE, FALSE, NO_TK)) + return TRUE + if(!potential_acc) + to_chat(usr, "No ID card detected.") + return + var/datum/bank_account/account = potential_acc.registered_account + if(!account) + to_chat(usr, "[potential_acc] has no account registered!") + return + if(!account.has_money(sale_price)) + to_chat(usr, "You do not possess the funds to purchase this.") + return TRUE + else + account.adjust_money(-sale_price) + if(payments_acc) + payments_acc.adjust_money(sale_price) + usr.put_in_hands(showpiece) + to_chat(usr, "You purchase [showpiece] for [sale_price] credits.") + playsound(src, 'sound/effects/cashregister.ogg', 40, TRUE) + icon = 'icons/obj/stationobjs.dmi' + flick("laserbox_vend", src) + showpiece = null + update_icon() + SStgui.update_uis(src) + return TRUE + if("Open") + if(!payments_acc) + to_chat(usr, "[src] hasn't been registered yet.") + return TRUE + if(!potential_acc || !potential_acc.registered_account) + return + if(!check_access(potential_acc)) + playsound(src, 'sound/machines/buzz-sigh.ogg', 50, TRUE) + return + toggle_lock() + SStgui.update_uis(src) + if("Register") + if(payments_acc) + return + if(!potential_acc || !potential_acc.registered_account) + return + if(!check_access(potential_acc)) + playsound(src, 'sound/machines/buzz-sigh.ogg', 50, TRUE) + return + payments_acc = potential_acc.registered_account + playsound(src, 'sound/machines/click.ogg', 20, TRUE) + if("Adjust") + if(!check_access(potential_acc) || potential_acc.registered_account != payments_acc) + playsound(src, 'sound/machines/buzz-sigh.ogg', 50, TRUE) + return + + var/new_price_input = input(usr,"Set the sale price for this vend-a-tray.","new price",0) as num|null + if(isnull(new_price_input) || (payments_acc != potential_acc.registered_account)) + to_chat(usr, "[src] rejects your new price.") + return + if(!usr.canUseTopic(src, BE_CLOSE, FALSE, NO_TK) ) + to_chat(usr, "You need to get closer!") + return + new_price_input = clamp(round(new_price_input, 1), 10, 1000) + sale_price = new_price_input + to_chat(usr, "The cost is now set to [sale_price].") + SStgui.update_uis(src) + return TRUE + . = TRUE +/obj/structure/displaycase/forsale/attackby(obj/item/I, mob/living/user, params) + if(isidcard(I)) + //Card Registration + var/obj/item/card/id/potential_acc = I + if(!potential_acc.registered_account) + to_chat(user, "This ID card has no account registered!") + return + if(payments_acc == potential_acc.registered_account) + playsound(src, 'sound/machines/click.ogg', 20, TRUE) + toggle_lock() + return + if(istype(I, /obj/item/pda)) + return TRUE + SStgui.update_uis(src) + . = ..() + + +/obj/structure/displaycase/forsale/multitool_act(mob/living/user, obj/item/I) + . = ..() + if(obj_integrity <= (integrity_failure * max_integrity)) + to_chat(user, "You start recalibrating [src]'s hover field...") + if(do_after(user, 20, target = src)) + broken = 0 + obj_integrity = max_integrity + update_icon() + return TRUE + +/obj/structure/displaycase/forsale/wrench_act(mob/living/user, obj/item/I) + . = ..() + if(open && user.a_intent == INTENT_HELP ) + if(anchored) + to_chat(user, "You start unsecuring [src]...") + else + to_chat(user, "You start securing [src]...") + if(I.use_tool(src, user, 16, volume=50)) + if(QDELETED(I)) + return + if(anchored) + to_chat(user, "You unsecure [src].") + else + to_chat(user, "You secure [src].") + anchored = !anchored + return + else if(!open && user.a_intent == INTENT_HELP) + to_chat(user, "[src] must be open to move it.") + return + +/obj/structure/displaycase/forsale/emag_act(mob/user) + . = ..() + payments_acc = null + req_access = list() + to_chat(user, "[src]'s card reader fizzles and smokes, and the account owner is reset.") + +/obj/structure/displaycase/forsale/examine(mob/user) + . = ..() + if(showpiece && !open) + . += "[showpiece] is for sale for [sale_price] credits." + if(broken) + . += "[src] is sparking and the hover field generator seems to be overloaded. Use a multitool to fix it." + +/obj/structure/displaycase/forsale/obj_break(damage_flag) + if(!broken && !(flags_1 & NODECONSTRUCT_1)) + broken = TRUE + playsound(src, "shatter", 70, TRUE) + update_icon() + trigger_alarm() //In case it's given an alarm anyway. + +/obj/structure/displaycase/forsale/kitchen + desc = "A display case with an ID-card swiper. Use your ID to purchase the contents. Meant for the bartender and chef." + req_one_access = list(ACCESS_KITCHEN, ACCESS_BAR) diff --git a/code/game/objects/structures/tank_dispenser.dm b/code/game/objects/structures/tank_dispenser.dm index e2298ac6c5..2a441ff0f2 100644 --- a/code/game/objects/structures/tank_dispenser.dm +++ b/code/game/objects/structures/tank_dispenser.dm @@ -67,15 +67,14 @@ to_chat(user, "You put [I] in [src].") update_icon() -/obj/structure/tank_dispenser/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, \ - datum/tgui/master_ui = null, datum/ui_state/state = GLOB.physical_state) - ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) - if(!ui) - ui = new(user, src, ui_key, "TankDispenser", name, 275, 103, master_ui, state) - ui.open() +/obj/structure/tank_dispenser/ui_state(mob/user) + return GLOB.physical_state -/obj/structure/tank_dispenser/attack_robot(mob/user) - ui_interact(user) +/obj/structure/tank_dispenser/ui_interact(mob/user, datum/tgui/ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "TankDispenser", name) + ui.open() /obj/structure/tank_dispenser/ui_data(mob/user) var/list/data = list() diff --git a/code/modules/antagonists/abductor/machinery/console.dm b/code/modules/antagonists/abductor/machinery/console.dm index 9c9715ee43..6e6d05b1ee 100644 --- a/code/modules/antagonists/abductor/machinery/console.dm +++ b/code/modules/antagonists/abductor/machinery/console.dm @@ -24,7 +24,7 @@ var/obj/machinery/computer/camera_advanced/abductor/camera var/list/datum/icon_snapshot/disguises = list() -/obj/machinery/abductor/console/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) +/obj/machinery/abductor/console/attack_hand(mob/user) . = ..() if(.) return @@ -32,93 +32,93 @@ to_chat(user, "You start mashing alien buttons at random!") if(do_after(user,100, target = src)) TeleporterSend() - return - user.set_machine(src) - var/dat = "" - dat += "

Abductsoft 3000

" +/obj/machinery/abductor/console/ui_status(mob/user) + if(!isabductor(user) && !isobserver(user)) + return UI_CLOSE + return ..() + +/obj/machinery/abductor/console/ui_state(mob/user) + return GLOB.physical_state + +/obj/machinery/abductor/console/ui_interact(mob/user, datum/tgui/ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "AbductorConsole", name) + ui.open() + +/obj/machinery/abductor/console/ui_static_data(mob/user) + var/list/data = list() + data["categories"] = list() + for(var/category in possible_gear) + var/list/cat = list( + "name" = category, + "items" = (category == selected_cat ? list() : null)) + for(var/gear in possible_gear[category]) + var/datum/abductor_gear/AG = possible_gear[category][gear] + cat["items"] += list(list( + "name" = AG.name, + "cost" = AG.cost, + "desc" = AG.description, + )) + data["categories"] += list(cat) + return data + +/obj/machinery/abductor/console/ui_data(mob/user) + var/list/data = list() + data["compactMode"] = compact_mode + data["experiment"] = experiment ? TRUE : FALSE if(experiment) - var/points = experiment.points - var/credits = experiment.credits - dat += "Collected Samples : [points]
" - dat += "Gear Credits: [credits]
" - dat += "Transfer data in exchange for supplies:
" - dat += "Advanced Baton (2 Credits)
" - dat += "Mental Interface Device (2 Credits)
" - dat += "Reagent Synthesizer (2 Credits)
" - dat += "Agent Helmet (1 Credit)
" - dat += "Agent Vest (1 Credit)
" - dat += "Radio Silencer (1 Credit)
" - dat += "Science Tool (1 Credit)
" - dat += "Superlingual Matrix (1 Credit)
" - else - dat += "NO EXPERIMENT MACHINE DETECTED
" - + data["points"] = experiment.points + data["credits"] = experiment.credits + data["pad"] = pad ? TRUE : FALSE if(pad) - dat += "Emergency Teleporter System." - dat += "Consider using primary observation console first." - dat += "Activate Teleporter
" - if(gizmo && gizmo.marked) - dat += "Retrieve Mark
" - else - dat += "Retrieve Mark
" - else - dat += "NO TELEPAD DETECTED
" - + data["gizmo"] = gizmo && gizmo.marked ? TRUE : FALSE + data["vest"] = vest ? TRUE : FALSE if(vest) - dat += "

Agent Vest Mode


" - var/mode = vest.mode - if(mode == VEST_STEALTH) - dat += "Combat" - dat += "Stealth" - else - dat += "Combat" - dat += "Stealth" + data["vest_mode"] = vest.mode + data["vest_lock"] = HAS_TRAIT_FROM(vest, TRAIT_NODROP, ABDUCTOR_VEST_TRAIT) + return data - dat+="
" - dat += "Select Agent Vest Disguise
" - dat += "[HAS_TRAIT_FROM(vest, TRAIT_NODROP, ABDUCTOR_VEST_TRAIT) ? "Unlock" : "Lock"] Vest
" - else - dat += "NO AGENT VEST DETECTED" - var/datum/browser/popup = new(user, "computer", "Abductor Console", 400, 500) - popup.set_content(dat) - popup.open() - -/obj/machinery/abductor/console/Topic(href, href_list) - if(..()) +/obj/machinery/abductor/console/ui_act(action, list/params) + . = ..() + if(.) return - usr.set_machine(src) - if(href_list["teleporter_send"]) - TeleporterSend() - else if(href_list["teleporter_retrieve"]) - TeleporterRetrieve() - else if(href_list["flip_vest"]) - FlipVest() - else if(href_list["toggle_vest"]) - if(vest) + switch(action) + if("buy") + var/item_name = params["name"] + var/list/buyable_items = list() + for(var/category in possible_gear) + buyable_items += possible_gear[category] + for(var/key in buyable_items) + var/datum/abductor_gear/AG = buyable_items[key] + if(AG.name == item_name) + Dispense(AG.build_path, AG.cost) + return TRUE + if("teleporter_send") + TeleporterSend() + return TRUE + if("teleporter_retrieve") + TeleporterRetrieve() + return TRUE + if("flip_vest") + FlipVest() + return TRUE + if("toggle_vest") + if(!vest) + return vest.toggle_nodrop() - else if(href_list["select_disguise"]) - SelectDisguise() - else if(href_list["dispense"]) - switch(href_list["dispense"]) - if("baton") - Dispense(/obj/item/abductor/baton,cost=2) - if("helmet") - Dispense(/obj/item/clothing/head/helmet/abductor) - if("silencer") - Dispense(/obj/item/abductor/silencer) - if("tool") - Dispense(/obj/item/abductor/gizmo) - if("vest") - Dispense(/obj/item/clothing/suit/armor/abductor/vest) - if("mind_device") - Dispense(/obj/item/abductor/mind_device,cost=2) - if("chem_dispenser") - Dispense(/obj/item/abductor_machine_beacon/chem_dispenser,cost=2) - if("tongue") - Dispense(/obj/item/organ/tongue/abductor) - updateUsrDialog() + return TRUE + if("select_disguise") + SelectDisguise() + return TRUE + if("select") + selected_cat = params["category"] + return TRUE + if("compact_toggle") + compact_mode = !compact_mode + return TRUE /obj/machinery/abductor/console/proc/TeleporterRetrieve() if(pad && gizmo && gizmo.marked) @@ -159,7 +159,6 @@ pad.teleport_target = location to_chat(user, "Location marked as test subject release point.") - /obj/machinery/abductor/console/Initialize(mapload) ..() return INITIALIZE_HINT_LATELOAD diff --git a/code/modules/antagonists/abductor/machinery/dispenser.dm b/code/modules/antagonists/abductor/machinery/dispenser.dm index ef423b6379..f5bc0946e6 100644 --- a/code/modules/antagonists/abductor/machinery/dispenser.dm +++ b/code/modules/antagonists/abductor/machinery/dispenser.dm @@ -22,41 +22,44 @@ gland_colors[i] = random_color() amounts[i] = rand(1,5) -/obj/machinery/abductor/gland_dispenser/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) +/obj/machinery/abductor/gland_dispenser/ui_status(mob/user) + if(!isabductor(user) && !isobserver(user)) + return UI_CLOSE + return ..() + +/obj/machinery/abductor/gland_dispenser/ui_state(mob/user) + return GLOB.physical_state + +/obj/machinery/abductor/gland_dispenser/ui_interact(mob/user, datum/tgui/ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "GlandDispenser", name) + ui.open() + +/obj/machinery/abductor/gland_dispenser/ui_data(mob/user) + var/list/data = list() + data["glands"] = list() + for(var/gland_number=1,gland_number<=gland_colors.len,gland_number++) + var/list/gland_information = list( + "color" = gland_colors[gland_number], + "amount" = amounts[gland_number], + "id" = gland_number, + ) + data["glands"] += list(gland_information) + return data + +/obj/machinery/abductor/gland_dispenser/ui_act(action, list/params) . = ..() if(.) return - if(!isabductor(user)) - return - user.set_machine(src) - var/box_css = {" - "} - var/dat = "" - var/item_count = 0 - for(var/i=1,i<=gland_colors.len,i++) - item_count++ - var/g_color = gland_colors[i] - var/amount = amounts[i] - dat += "[amount]" - if(item_count == 4) // Four boxes per line - dat +="

" - item_count = 0 - var/datum/browser/popup = new(user, "glands", "Gland Dispenser", 200, 200) - popup.add_head_content(box_css) - popup.set_content(dat) - popup.open() - return + + switch(action) + if("dispense") + var/gland_id = text2num(params["gland_id"]) + if(!gland_id) + return + Dispense(gland_id) + return TRUE /obj/machinery/abductor/gland_dispenser/attackby(obj/item/W, mob/user, params) if(istype(W, /obj/item/organ/heart/gland)) @@ -68,15 +71,6 @@ else return ..() -/obj/machinery/abductor/gland_dispenser/Topic(href, href_list) - if(..()) - return - usr.set_machine(src) - - if(href_list["dispense"]) - Dispense(text2num(href_list["dispense"])) - updateUsrDialog() - /obj/machinery/abductor/gland_dispenser/proc/Dispense(count) if(amounts[count]>0) amounts[count]-- diff --git a/code/modules/antagonists/abductor/machinery/experiment.dm b/code/modules/antagonists/abductor/machinery/experiment.dm index b94912b635..c7eea63cd0 100644 --- a/code/modules/antagonists/abductor/machinery/experiment.dm +++ b/code/modules/antagonists/abductor/machinery/experiment.dm @@ -15,19 +15,13 @@ var/breakout_time = 450 /obj/machinery/abductor/experiment/MouseDrop_T(mob/target, mob/user) - if(user.stat || user.lying || !Adjacent(user) || !target.Adjacent(user) || !ishuman(target)) + var/mob/living/L = user + if(user.stat || (isliving(user) && (!(L.mobility_flags & MOBILITY_STAND) || !(L.mobility_flags & MOBILITY_UI))) || !Adjacent(user) || !target.Adjacent(user) || !ishuman(target)) return if(isabductor(target)) return close_machine(target) -/obj/machinery/abductor/experiment/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) - . = ..() - if(.) - return - - experimentUI(user) - /obj/machinery/abductor/experiment/open_machine() if(!state_open && !panel_open) ..() @@ -51,7 +45,7 @@ user.last_special = world.time + CLICK_CD_BREAKOUT user.visible_message("You see [user] kicking against the door of [src]!", \ "You lean on the back of [src] and start pushing the door open... (this will take about [DisplayTimeText(breakout_time)].)", \ - "You hear a metallic creaking from [src].") + "You hear a metallic creaking from [src].") if(do_after(user,(breakout_time), target = src)) if(!user || user.stat != CONSCIOUS || user.loc != src || state_open) return @@ -59,122 +53,84 @@ "You successfully break out of [src]!") open_machine() -/obj/machinery/abductor/experiment/proc/dissection_icon(mob/living/carbon/human/H) - var/icon/photo = null - var/g = (H.dna.features["body_model"] == FEMALE) ? "f" : "m" - if(H.dna.species.use_skintones) - photo = icon("icon" = 'icons/mob/human.dmi', "icon_state" = "[H.skin_tone]_[g]") - else - photo = icon("icon" = 'icons/mob/human.dmi', "icon_state" = "[H.dna.species.id]_[g]") - photo.Blend("#[H.dna.features["mcolor"]]", ICON_MULTIPLY) +/obj/machinery/abductor/experiment/ui_status(mob/user) + if(user == occupant) + return UI_CLOSE + return ..() - var/icon/eyes - if(EYECOLOR in H.dna.species.species_traits) - eyes = icon("icon" = 'icons/mob/human_face.dmi', "icon_state" = "eyes") - eyes.Blend("#[H.eye_color]", ICON_MULTIPLY) +/obj/machinery/abductor/experiment/ui_state(mob/user) + return GLOB.physical_state - var/datum/sprite_accessory/S - S = GLOB.hair_styles_list[H.hair_style] - if(S && (HAIR in H.dna.species.species_traits)) - var/icon/hair = icon("icon" = S.icon, "icon_state" = "[S.icon_state]") - hair.Blend("#[H.hair_color]", ICON_MULTIPLY) - eyes.Blend(hair, ICON_OVERLAY) +/obj/machinery/abductor/experiment/ui_interact(mob/user, datum/tgui/ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "ProbingConsole", name) + ui.open() - S = GLOB.facial_hair_styles_list[H.facial_hair_style] - if(S && (FACEHAIR in H.dna.species.species_traits)) - var/icon/facial = icon("icon" = S.icon, "icon_state" = "[S.icon_state]") - facial.Blend("#[H.facial_hair_color]", ICON_MULTIPLY) - eyes.Blend(facial, ICON_OVERLAY) - - if(eyes) - photo.Blend(eyes, ICON_OVERLAY) - - var/icon/splat = icon("icon" = 'icons/mob/dam_mob.dmi',"icon_state" = "chest30") - photo.Blend(splat,ICON_OVERLAY) - - return photo - -/obj/machinery/abductor/experiment/proc/experimentUI(mob/user) - var/dat - dat += "

Experiment

" - if(occupant) - var/obj/item/photo/P = new - P.picture = new - P.picture.picture_image = icon(dissection_icon(occupant), dir = SOUTH) - user << browse_rsc(P.picture.picture_image, "dissection_img") - dat += "
" - dat += "" //Avert your eyes - dat += "" - dat += "Probe
" - dat += "Dissect
" - dat += "Analyze
" - dat += "
" - else - dat += "Experiment " - - if(!occupant) - dat += "

Machine Unoccupied

" - else - dat += "

Subject Status :

" - dat += "[occupant.name] => " - var/mob/living/mob_occupant = occupant - switch(mob_occupant.stat) - if(CONSCIOUS) - dat += "Conscious" - if(UNCONSCIOUS) - dat += "Unconscious" - else // DEAD - dat += "Deceased" - dat += "
" - dat += "[flash]" - dat += "
" - dat += "Scan" - dat += "Close" : "open=1'>Open"]" - var/datum/browser/popup = new(user, "experiment", "Probing Console", 300, 300) - popup.set_title_image(user.browse_rsc_icon(icon, icon_state)) - popup.set_content(dat) - popup.open() - -/obj/machinery/abductor/experiment/Topic(href, href_list) - if(..() || usr == occupant) - return - usr.set_machine(src) - if(href_list["refresh"]) - updateUsrDialog() - return - if(href_list["open"]) - open_machine() - return - if(href_list["close"]) - close_machine() - return +/obj/machinery/abductor/experiment/ui_data(mob/user) + var/list/data = list() + data["open"] = state_open + data["feedback"] = flash + data["occupant"] = occupant ? TRUE : FALSE + data["occupant_name"] = null + data["occupant_status"] = null if(occupant) var/mob/living/mob_occupant = occupant - if(mob_occupant.stat != DEAD) - if(href_list["experiment"]) - flash = Experiment(occupant,href_list["experiment"],usr) - updateUsrDialog() - add_fingerprint(usr) + data["occupant_name"] = mob_occupant.name + data["occupant_status"] = mob_occupant.stat + return data -/obj/machinery/abductor/experiment/proc/Experiment(mob/occupant,type,mob/user) +/obj/machinery/abductor/experiment/ui_act(action, list/params) + . = ..() + if(.) + return + + switch(action) + if("door") + if(state_open) + close_machine() + return TRUE + else + open_machine() + return TRUE + if("experiment") + if(!occupant) + return + var/mob/living/mob_occupant = occupant + if(mob_occupant.stat == DEAD) + return + flash = experiment(occupant, params["experiment_type"], usr) + return TRUE + +/** + * experiment: Performs selected experiment on occupant mob, resulting in a point reward on success + * + * Arguments: + * * occupant The mob inside the machine + * * type The type of experiment to be performed + * * user The mob starting the experiment + */ +/obj/machinery/abductor/experiment/proc/experiment(mob/occupant, type, mob/user) LAZYINITLIST(history) var/mob/living/carbon/human/H = occupant var/datum/antagonist/abductor/user_abductor = user.mind.has_antag_datum(/datum/antagonist/abductor) if(!user_abductor) - return "Authorization failure. Contact mothership immidiately." + return "Authorization failure. Contact mothership immediately." var/point_reward = 0 + if(!H) + return "Invalid or missing specimen." if(H in history) - return "Specimen already in database." + return "Specimen already in database." if(H.stat == DEAD) say("Specimen deceased - please provide fresh sample.") - return "Specimen deceased." + return "Specimen deceased." var/obj/item/organ/heart/gland/GlandTest = locate() in H.internal_organs if(!GlandTest) say("Experimental dissection not detected!") - return "No glands detected!" - if(H.mind != null && (H.voluntary_ghosted || (H.ckey != null))) + return "No glands detected!" + if(H.mind != null && H.ckey != null) LAZYINITLIST(abductee_minds) LAZYADD(history, H) LAZYADD(abductee_minds, H.mind) @@ -196,22 +152,27 @@ point_reward++ if(point_reward > 0) open_machine() - SendBack(H) - playsound(src.loc, 'sound/machines/ding.ogg', 50, 1) + send_back(H) + playsound(src.loc, 'sound/machines/ding.ogg', 50, TRUE) points += point_reward credits += point_reward - return "Experiment successful! [point_reward] new data-points collected." + return "Experiment successful! [point_reward] new data-points collected." else - playsound(src.loc, 'sound/machines/buzz-sigh.ogg', 50, 1) - return "Experiment failed! No replacement organ detected." + playsound(src.loc, 'sound/machines/buzz-sigh.ogg', 50, TRUE) + return "Experiment failed! No replacement organ detected." else say("Brain activity nonexistent - disposing sample...") open_machine() - SendBack(H) - return "Specimen braindead - disposed." + send_back(H) + return "Specimen braindead - disposed." - -/obj/machinery/abductor/experiment/proc/SendBack(mob/living/carbon/human/H) +/** + * send_back: Sends a mob back to a selected teleport location if safe + * + * Arguments: + * * H The human mob to be sent back + */ +/obj/machinery/abductor/experiment/proc/send_back(mob/living/carbon/human/H) H.Sleeping(160) H.uncuff() if(console && console.pad && console.pad.teleport_target) @@ -221,7 +182,6 @@ SSjob.SendToLateJoin(H, FALSE) return - /obj/machinery/abductor/experiment/update_icon_state() if(state_open) icon_state = "experiment-open" diff --git a/code/modules/antagonists/changeling/cellular_emporium.dm b/code/modules/antagonists/changeling/cellular_emporium.dm index 6abefeefe7..2538394db7 100644 --- a/code/modules/antagonists/changeling/cellular_emporium.dm +++ b/code/modules/antagonists/changeling/cellular_emporium.dm @@ -13,10 +13,13 @@ changeling = null . = ..() -/datum/cellular_emporium/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.always_state) - ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) +/datum/cellular_emporium/ui_state(mob/user) + return GLOB.always_state + +/datum/cellular_emporium/ui_interact(mob/user, datum/tgui/ui) + ui = SStgui.try_update_ui(user, src, ui) if(!ui) - ui = new(user, src, ui_key, "CellularEmporium", name, 900, 480, master_ui, state) + ui = new(user, src, "CellularEmporium", name) ui.open() /datum/cellular_emporium/ui_data(mob/user) diff --git a/code/modules/antagonists/nukeop/equipment/nuclearbomb.dm b/code/modules/antagonists/nukeop/equipment/nuclearbomb.dm index 5c011b6318..8e780beb0c 100644 --- a/code/modules/antagonists/nukeop/equipment/nuclearbomb.dm +++ b/code/modules/antagonists/nukeop/equipment/nuclearbomb.dm @@ -7,17 +7,13 @@ density = TRUE resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF - ui_x = 350 - ui_y = 442 - var/timer_set = 90 - var/default_timer_set = 90 var/minimum_timer_set = 90 var/maximum_timer_set = 3600 - ui_style = "nanotrasen" var/numeric_input = "" var/ui_mode = NUKEUI_AWAIT_DISK + var/timing = FALSE var/exploding = FALSE var/exploded = FALSE @@ -34,7 +30,6 @@ var/interior = "" var/proper_bomb = TRUE //Please var/obj/effect/countdown/nuclearbomb/countdown - var/nuclear_cooldown //used to stop global spam. /obj/machinery/nuclearbomb/Initialize() . = ..() @@ -77,15 +72,16 @@ /obj/machinery/nuclearbomb/syndicate/get_cinematic_type(off_station) var/datum/game_mode/nuclear/NM = SSticker.mode switch(off_station) - if(FALSE) + if(0) if(istype(NM) && !NM.nuke_team.syndies_escaped()) return CINEMATIC_ANNIHILATION else return CINEMATIC_NUKE_WIN - if(NUKE_MISS_STATION) + if(1) return CINEMATIC_NUKE_MISS - else + if(2) return CINEMATIC_NUKE_FAR + return CINEMATIC_NUKE_FAR /obj/machinery/nuclearbomb/proc/disk_check(obj/item/disk/nuclear/D) if(D.fake) @@ -194,7 +190,7 @@ icon_state = "nuclearbomb_exploding" /obj/machinery/nuclearbomb/update_overlays() - . = ..() + . += ..() update_icon_interior() update_icon_lights() @@ -236,7 +232,7 @@ explode() else var/volume = (get_time_left() <= 20 ? 30 : 5) - playsound(loc, 'sound/items/timer.ogg', volume, 0) + playsound(loc, 'sound/items/timer.ogg', volume, FALSE) /obj/machinery/nuclearbomb/proc/update_ui_mode() if(exploded) @@ -261,17 +257,18 @@ ui_mode = NUKEUI_AWAIT_TIMER - -/obj/machinery/nuclearbomb/ui_interact(mob/user, ui_key="main", datum/tgui/ui=null, force_open=0, datum/tgui/master_ui=null, datum/ui_state/state=GLOB.default_state) - ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) +/obj/machinery/nuclearbomb/ui_interact(mob/user, datum/tgui/ui) + ui = SStgui.try_update_ui(user, src, ui) if(!ui) - ui = new(user, src, ui_key, "NuclearBomb", name, ui_x, ui_y, master_ui, state) + ui = new(user, src, "NuclearBomb", name) ui.open() /obj/machinery/nuclearbomb/ui_data(mob/user) var/list/data = list() data["disk_present"] = auth + var/hidden_code = (ui_mode == NUKEUI_AWAIT_CODE && numeric_input != "ERROR") + var/current_code = "" if(hidden_code) while(length(current_code) < length(numeric_input)) @@ -388,14 +385,13 @@ if("anchor") if(auth && yes_code) playsound(src, 'sound/machines/nuke/general_beep.ogg', 50, FALSE) - set_anchor(usr) + set_anchor() else playsound(src, 'sound/machines/nuke/angry_beep.ogg', 50, FALSE) - -/obj/machinery/nuclearbomb/proc/set_anchor(mob/user) - if((istype(get_area(src), /area/space) || isinspace()) && !anchored) - to_chat(user, "This is not a suitable platform for anchoring [src]!") +/obj/machinery/nuclearbomb/proc/set_anchor() + if(isinspace() && !anchored) + to_chat(usr, "There is nothing to anchor to!") else anchored = !anchored @@ -416,9 +412,6 @@ if(safety) to_chat(usr, "The safety is still on.") return - if(!timing && nuclear_cooldown > world.time) - to_chat(usr, "[src]'s timer protocols are currently on cooldown, please stand by.") - return timing = !timing if(timing) previous_level = NUM2SECLEVEL(GLOB.security_level) @@ -427,12 +420,6 @@ S.switch_mode_to(TRACK_INFILTRATOR) countdown.start() set_security_level("delta") - nuclear_cooldown = world.time + 15 SECONDS - - if(GLOB.war_declared) - var/area/A = get_area(src) - priority_announce("Alert: Unexpected increase in radiation levels near [A.name] ([src.x],[src.y],[src.z]). Please send an authorized radiation specialist to investigate.", "Sensory Nuclear Indexer Telemetry Calculation Helper") - else detonation_timer = null set_security_level(previous_level) @@ -483,12 +470,19 @@ var/off_station = FALSE var/turf/bomb_location = get_turf(src) - if(!bomb_location || !is_station_level(bomb_location.z)) - off_station = NUKE_MISS_STATION + var/area/A = get_area(bomb_location) + + if(bomb_location && is_station_level(bomb_location.z)) + if(istype(A, /area/space)) + off_station = NUKE_NEAR_MISS + if((bomb_location.x < (128-NUKERANGE)) || (bomb_location.x > (128+NUKERANGE)) || (bomb_location.y < (128-NUKERANGE)) || (bomb_location.y > (128+NUKERANGE))) + off_station = NUKE_NEAR_MISS else if(bomb_location.onSyndieBase()) off_station = NUKE_SYNDICATE_BASE + else + off_station = NUKE_MISS_STATION - if(!off_station) + if(off_station < 2) //can only launch when nuke is on syndie base or space SSshuttle.registerHostileEnvironment(src) SSshuttle.lockdown = TRUE @@ -502,13 +496,13 @@ INVOKE_ASYNC(GLOBAL_PROC,.proc/KillEveryoneOnZLevel, z) /obj/machinery/nuclearbomb/proc/get_cinematic_type(off_station) - if(!off_station) + if(off_station < 2) return CINEMATIC_SELFDESTRUCT else return CINEMATIC_SELFDESTRUCT_MISS /obj/machinery/nuclearbomb/beer - name = "Nanotrasen-brand nuclear fission explosive" + name = "\improper Nanotrasen-brand nuclear fission explosive" desc = "One of the more successful achievements of the Nanotrasen Corporate Warfare Division, their nuclear fission explosives are renowned for being cheap to produce and devastatingly effective. Signs explain that though this particular device has been decommissioned, every Nanotrasen station is equipped with an equivalent one, just in case. All Captains carefully guard the disk needed to detonate them - at least, the sign says they do. There seems to be a tap on the back." proper_bomb = FALSE var/obj/structure/reagent_dispensers/beerkeg/keg @@ -521,9 +515,9 @@ /obj/machinery/nuclearbomb/beer/examine(mob/user) . = ..() if(keg.reagents.total_volume) - . += "It has [keg.reagents.total_volume] unit\s left." + to_chat(user, "It has [keg.reagents.total_volume] unit\s left.") else - . += "It's empty." + to_chat(user, "It's empty.") /obj/machinery/nuclearbomb/beer/attackby(obj/item/W, mob/user, params) if(W.is_refillable()) @@ -535,6 +529,8 @@ return ..() /obj/machinery/nuclearbomb/beer/actually_explode() + //Unblock roundend, we're not actually exploding. + SSticker.roundend_check_paused = FALSE var/turf/bomb_location = get_turf(src) if(!bomb_location) disarm() @@ -583,7 +579,7 @@ This is here to make the tiles around the station mininuke change when it's armed. */ -/obj/machinery/nuclearbomb/selfdestruct/set_anchor(mob/user) +/obj/machinery/nuclearbomb/selfdestruct/set_anchor() return /obj/machinery/nuclearbomb/selfdestruct/set_active() @@ -641,18 +637,19 @@ This is here to make the tiles around the station mininuke change when it's arme if(newturf && lastlocation == newturf) if(last_disk_move < world.time - 5000 && prob((world.time - 5000 - last_disk_move)*0.0001)) var/datum/round_event_control/operative/loneop = locate(/datum/round_event_control/operative) in SSevents.control - if(istype(loneop)) + if(istype(loneop) && loneop.occurrences < loneop.max_occurrences) loneop.weight += 1 - if(loneop.weight % 5 == 0) + if(loneop.weight % 5 == 0 && SSticker.totalPlayers > 1) //players count now message_admins("[src] is stationary in [ADMIN_VERBOSEJMP(newturf)]. The weight of Lone Operative is now [loneop.weight].") log_game("[src] is stationary for too long in [loc_name(newturf)], and has increased the weight of the Lone Operative event to [loneop.weight].") + else lastlocation = newturf last_disk_move = world.time var/datum/round_event_control/operative/loneop = locate(/datum/round_event_control/operative) in SSevents.control - if(istype(loneop) && prob(loneop.weight)) + if(istype(loneop) && loneop.occurrences < loneop.max_occurrences && prob(loneop.weight)) loneop.weight = max(loneop.weight - 1, 0) - if(loneop.weight % 5 == 0) + if(loneop.weight % 5 == 0 && SSticker.totalPlayers > 1) message_admins("[src] is on the move (currently in [ADMIN_VERBOSEJMP(newturf)]). The weight of Lone Operative is now [loneop.weight].") log_game("[src] being on the move has reduced the weight of the Lone Operative event to [loneop.weight].") @@ -661,9 +658,18 @@ This is here to make the tiles around the station mininuke change when it's arme if(!fake) return - if(isobserver(user) || HAS_TRAIT(user, TRAIT_DISK_VERIFIER) || (user.mind && HAS_TRAIT(user.mind, TRAIT_DISK_VERIFIER))) + if(isobserver(user) || HAS_TRAIT(user.mind, TRAIT_DISK_VERIFIER)) . += "The serial numbers on [src] are incorrect." +/* + * You can't accidentally eat the nuke disk, bro + */ +/obj/item/disk/nuclear/on_accidental_consumption(mob/living/carbon/M, mob/living/carbon/user, obj/item/source_item, discover_after = TRUE) + M.visible_message("[M] looks like [M.p_theyve()] just bitten into something important.", \ + "Wait, is this the nuke disk?") + + return discover_after + /obj/item/disk/nuclear/attackby(obj/item/I, mob/living/user, params) if(istype(I, /obj/item/claymore/highlander) && !fake) var/obj/item/claymore/highlander/H = I @@ -686,7 +692,7 @@ This is here to make the tiles around the station mininuke change when it's arme /obj/item/disk/nuclear/suicide_act(mob/user) user.visible_message("[user] is going delta! It looks like [user.p_theyre()] trying to commit suicide!") - playsound(src, 'sound/machines/alarm.ogg', 50, -1, 1) + playsound(src, 'sound/machines/alarm.ogg', 50, -1, TRUE) for(var/i in 1 to 100) addtimer(CALLBACK(user, /atom/proc/add_atom_colour, (i % 2)? "#00FF00" : "#FF0000", ADMIN_COLOUR_PRIORITY), i) addtimer(CALLBACK(src, .proc/manual_suicide, user), 101) @@ -694,7 +700,7 @@ This is here to make the tiles around the station mininuke change when it's arme /obj/item/disk/nuclear/proc/manual_suicide(mob/living/user) user.remove_atom_colour(ADMIN_COLOUR_PRIORITY) - user.visible_message("[user] was destroyed by the nuclear blast!") + user.visible_message("[user] is destroyed by the nuclear blast!") user.adjustOxyLoss(200) user.death(0) diff --git a/code/modules/assembly/infrared.dm b/code/modules/assembly/infrared.dm index 8cb6eb66fb..f8a18a041e 100644 --- a/code/modules/assembly/infrared.dm +++ b/code/modules/assembly/infrared.dm @@ -4,8 +4,6 @@ icon_state = "infrared" custom_materials = list(/datum/material/iron=1000, /datum/material/glass=500) is_position_sensitive = TRUE - var/ui_x = 225 - var/ui_y = 110 var/on = FALSE var/visible = FALSE var/maxlength = 8 @@ -134,7 +132,7 @@ . = ..() setDir(t) -/obj/item/assembly/infra/throw_at(atom/target, range, speed, mob/thrower, spin=1, diagonals_first = 0, datum/callback/callback, force, gentle = FALSE) +/obj/item/assembly/infra/throw_at(atom/target, range, speed, mob/thrower, spin=1, diagonals_first = 0, datum/callback/callback, force, gentle = FALSE, quickstart = TRUE) . = ..() olddir = dir @@ -186,11 +184,10 @@ return ..() return UI_CLOSE -/obj/item/assembly/infra/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, \ - datum/tgui/master_ui = null, datum/ui_state/state = GLOB.hands_state) - ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) +/obj/item/assembly/infra/ui_interact(mob/user, datum/tgui/ui) + ui = SStgui.try_update_ui(user, src, ui) if(!ui) - ui = new(user, src, ui_key, "InfraredEmitter", name, ui_x, ui_y, master_ui, state) + ui = new(user, src, "InfraredEmitter", name) ui.open() /obj/item/assembly/infra/ui_data(mob/user) diff --git a/code/modules/assembly/proximity.dm b/code/modules/assembly/proximity.dm index f0d8f28688..60de1b3e87 100644 --- a/code/modules/assembly/proximity.dm +++ b/code/modules/assembly/proximity.dm @@ -4,8 +4,6 @@ icon_state = "prox" custom_materials = list(/datum/material/iron=800, /datum/material/glass=200) attachable = TRUE - var/ui_x = 250 - var/ui_y = 185 var/scanning = FALSE var/timing = FALSE var/time = 10 @@ -113,11 +111,10 @@ return ..() return UI_CLOSE -/obj/item/assembly/prox_sensor/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, \ - datum/tgui/master_ui = null, datum/ui_state/state = GLOB.hands_state) - ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) +/obj/item/assembly/prox_sensor/ui_interact(mob/user, datum/tgui/ui) + ui = SStgui.try_update_ui(user, src, ui) if(!ui) - ui = new(user, src, ui_key, "ProximitySensor", name, ui_x, ui_y, master_ui, state) + ui = new(user, src, "ProximitySensor", name) ui.open() /obj/item/assembly/prox_sensor/ui_data(mob/user) diff --git a/code/modules/assembly/signaler.dm b/code/modules/assembly/signaler.dm index fe548d662d..80d1a8f81a 100644 --- a/code/modules/assembly/signaler.dm +++ b/code/modules/assembly/signaler.dm @@ -8,33 +8,46 @@ custom_materials = list(/datum/material/iron=400, /datum/material/glass=120) wires = WIRE_RECEIVE | WIRE_PULSE | WIRE_RADIO_PULSE | WIRE_RADIO_RECEIVE attachable = TRUE - var/ui_x = 280 - var/ui_y = 132 + var/code = DEFAULT_SIGNALER_CODE var/frequency = FREQ_SIGNALER var/datum/radio_frequency/radio_connection - var/suicider = null + ///Holds the mind that commited suicide. + var/datum/mind/suicider + ///Holds a reference string to the mob, decides how much of a gamer you are. + var/suicide_mob var/hearing_range = 1 /obj/item/assembly/signaler/suicide_act(mob/living/carbon/user) user.visible_message("[user] eats \the [src]! If it is signaled, [user.p_they()] will die!") playsound(src, 'sound/items/eatfood.ogg', 50, TRUE) - user.transferItemToLoc(src, user, TRUE) - suicider = user - return MANUAL_SUICIDE + moveToNullspace() + suicider = user.mind + suicide_mob = REF(user) + return MANUAL_SUICIDE_NONLETHAL -/obj/item/assembly/signaler/proc/manual_suicide(mob/living/carbon/user) - user.visible_message("[user]'s \the [src] receives a signal, killing [user.p_them()] instantly!") +/obj/item/assembly/signaler/proc/manual_suicide(datum/mind/suicidee) + var/mob/living/user = suicidee.current + if(!istype(user)) + return + if(suicide_mob == REF(user)) + user.visible_message("[user]'s [src] receives a signal, killing [user.p_them()] instantly!") + else + user.visible_message("[user]'s [src] receives a signal and [user.p_they()] die[user.p_s()] like a gamer!") user.adjustOxyLoss(200)//it sends an electrical pulse to their heart, killing them. or something. user.death(0) + user.set_suicide(TRUE) + user.suicide_log() + playsound(user, 'sound/machines/triple_beep.ogg', ASSEMBLY_BEEP_VOLUME, TRUE) + qdel(src) /obj/item/assembly/signaler/Initialize() . = ..() set_frequency(frequency) - /obj/item/assembly/signaler/Destroy() SSradio.remove_object(src,frequency) + suicider = null . = ..() /obj/item/assembly/signaler/activate() @@ -53,11 +66,10 @@ return ..() return UI_CLOSE -/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.hands_state) - ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) +/obj/item/assembly/signaler/ui_interact(mob/user, datum/tgui/ui) + ui = SStgui.try_update_ui(user, src, ui) if(!ui) - ui = new(user, src, ui_key, "Signaler", name, ui_x, ui_y, master_ui, state) + ui = new(user, src, "Signaler", name) ui.open() /obj/item/assembly/signaler/ui_data(mob/user) @@ -66,12 +78,12 @@ data["code"] = code data["minFrequency"] = MIN_FREE_FREQ data["maxFrequency"] = MAX_FREE_FREQ - return data /obj/item/assembly/signaler/ui_act(action, params) if(..()) return + switch(action) if("signal") INVOKE_ASYNC(src, .proc/signal) @@ -115,9 +127,6 @@ if(usr) GLOB.lastsignalers.Add("[time] : [usr.key] used [src] @ location ([T.x],[T.y],[T.z]) : [format_frequency(frequency)]/[code]") - - return - /obj/item/assembly/signaler/receive_signal(datum/signal/signal) . = FALSE if(!signal) @@ -128,6 +137,7 @@ return if(suicider) manual_suicide(suicider) + return pulse(TRUE) audible_message("[icon2html(src, hearers(src))] *beep* *beep* *beep*", null, hearing_range) for(var/CHM in get_hearers_in_view(hearing_range, src)) @@ -136,7 +146,6 @@ LM.playsound_local(get_turf(src), 'sound/machines/triple_beep.ogg', ASSEMBLY_BEEP_VOLUME, TRUE) return TRUE - /obj/item/assembly/signaler/proc/set_frequency(new_frequency) SSradio.remove_object(src, frequency) frequency = new_frequency @@ -165,69 +174,8 @@ return return ..(signal) -// Embedded signaller used in anomalies. -/obj/item/assembly/signaler/anomaly - name = "anomaly core" - desc = "The neutralized core of an anomaly. It'd probably be valuable for research." - icon_state = "anomaly core" - item_state = "electronic" - lefthand_file = 'icons/mob/inhands/misc/devices_lefthand.dmi' - righthand_file = 'icons/mob/inhands/misc/devices_righthand.dmi' - resistance_flags = FIRE_PROOF - var/anomaly_type = /obj/effect/anomaly - -/obj/item/assembly/signaler/anomaly/receive_signal(datum/signal/signal) - if(!signal) - return FALSE - if(signal.data["code"] != code) - return FALSE - if(suicider) - manual_suicide(suicider) - for(var/obj/effect/anomaly/A in get_turf(src)) - A.anomalyNeutralize() - return TRUE - -/obj/item/assembly/signaler/anomaly/manual_suicide(mob/living/carbon/user) - user.visible_message("[user]'s [src] is reacting to the radio signal, warping [user.p_their()] body!") - user.suiciding = TRUE - user.suicide_log() - user.gib() - -/obj/item/assembly/signaler/anomaly/attackby(obj/item/I, mob/user, params) - if(I.tool_behaviour == TOOL_ANALYZER) - to_chat(user, "Analyzing... [src]'s stabilized field is fluctuating along frequency [format_frequency(frequency)], code [code].") - ..() - -//Anomaly cores -/obj/item/assembly/signaler/anomaly/pyro - name = "\improper pyroclastic anomaly core" - desc = "The neutralized core of a pyroclastic anomaly. It feels warm to the touch. It'd probably be valuable for research." - icon_state = "pyro core" - anomaly_type = /obj/effect/anomaly/pyro - -/obj/item/assembly/signaler/anomaly/grav - name = "\improper gravitational anomaly core" - desc = "The neutralized core of a gravitational anomaly. It feels much heavier than it looks. It'd probably be valuable for research." - icon_state = "grav core" - anomaly_type = /obj/effect/anomaly/grav - -/obj/item/assembly/signaler/anomaly/flux - name = "\improper flux anomaly core" - desc = "The neutralized core of a flux anomaly. Touching it makes your skin tingle. It'd probably be valuable for research." - icon_state = "flux core" - anomaly_type = /obj/effect/anomaly/flux - -/obj/item/assembly/signaler/anomaly/bluespace - name = "\improper bluespace anomaly core" - desc = "The neutralized core of a bluespace anomaly. It keeps phasing in and out of view. It'd probably be valuable for research." - icon_state = "anomaly core" - anomaly_type = /obj/effect/anomaly/bluespace - -/obj/item/assembly/signaler/anomaly/vortex - name = "\improper vortex anomaly core" - desc = "The neutralized core of a vortex anomaly. It won't sit still, as if some invisible force is acting on it. It'd probably be valuable for research." - icon_state = "vortex core" - anomaly_type = /obj/effect/anomaly/bhole +/obj/item/assembly/signaler/anomaly/attack_self() + return /obj/item/assembly/signaler/cyborg diff --git a/code/modules/assembly/timer.dm b/code/modules/assembly/timer.dm index d0f0e1e593..e06bb22b0b 100644 --- a/code/modules/assembly/timer.dm +++ b/code/modules/assembly/timer.dm @@ -4,8 +4,7 @@ icon_state = "timer" custom_materials = list(/datum/material/iron=500, /datum/material/glass=50) attachable = TRUE - var/ui_x = 275 - var/ui_y = 115 + var/timing = FALSE var/time = 5 var/saved_time = 5 @@ -88,11 +87,10 @@ return ..() return UI_CLOSE -/obj/item/assembly/timer/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, \ - datum/tgui/master_ui = null, datum/ui_state/state = GLOB.hands_state) - ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) +/obj/item/assembly/timer/ui_interact(mob/user, datum/tgui/ui) + ui = SStgui.try_update_ui(user, src, ui) if(!ui) - ui = new(user, src, ui_key, "Timer", name, ui_x, ui_y, master_ui, state) + ui = new(user, src, "Timer", name) ui.open() /obj/item/assembly/timer/ui_data(mob/user)