diff --git a/code/modules/mob/living/silicon/pai/software.dm b/code/modules/mob/living/silicon/pai/software.dm index 342e8d7f5c8..1cd5d394913 100644 --- a/code/modules/mob/living/silicon/pai/software.dm +++ b/code/modules/mob/living/silicon/pai/software.dm @@ -42,26 +42,24 @@ var/global/list/default_pai_software = list() set name = "Software Interface" ui_interact(src) + tgui_interact(src) -/mob/living/silicon/pai/ui_interact(mob/user, ui_key = "main", datum/nanoui/ui = null, force_open = 1) - if(user != src) - if(ui) ui.set_status(STATUS_CLOSE, 0) - return +/mob/living/silicon/pai/tgui_state(mob/user) + return GLOB.tgui_self_state - if(ui_key != "main") - var/datum/pai_software/S = software[ui_key] - if(S && !S.toggle) - S.on_ui_interact(src, ui, force_open) - else - if(ui) ui.set_status(STATUS_CLOSE, 0) - return - - var/data[0] +/mob/living/silicon/pai/tgui_interact(mob/user, datum/tgui/ui, datum/tgui/parent_ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "pAIInterface", "pAI Software Interface") + ui.open() +/mob/living/silicon/pai/tgui_data(mob/user, datum/tgui/ui, datum/tgui_state/state) + var/list/data = ..() + // Software we have bought - var/bought_software[0] + var/list/bought_software = list() // Software we have not bought - var/not_bought_software[0] + var/list/not_bought_software = list() for(var/key in pai_software_by_key) var/datum/pai_software/S = pai_software_by_key[key] @@ -70,63 +68,52 @@ var/global/list/default_pai_software = list() software_data["id"] = S.id if(key in software) software_data["on"] = S.is_active(src) - bought_software[++bought_software.len] = software_data + bought_software.Add(list(software_data)) else software_data["ram"] = S.ram_cost - not_bought_software[++not_bought_software.len] = software_data + not_bought_software.Add(list(software_data)) data["bought"] = bought_software data["not_bought"] = not_bought_software data["available_ram"] = ram // Emotions - var/emotions[0] + var/list/emotions = list() for(var/name in pai_emotions) - var/emote[0] + var/list/emote = list() emote["name"] = name emote["id"] = pai_emotions[name] - emotions[++emotions.len] = emote + emotions.Add(list(emote)) data["emotions"] = emotions data["current_emotion"] = card.current_emotion - ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) - if (!ui) - ui = new(user, src, ui_key, "pai_interface.tmpl", "pAI Software Interface", 450, 600) - ui.set_initial_data(data) - ui.open() - ui.set_auto_update(1) + return data -/mob/living/silicon/pai/Topic(href, href_list) - . = ..() - if(.) return +/mob/living/silicon/pai/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state) + if(..()) + return TRUE - if(href_list["software"]) - var/soft = href_list["software"] - var/datum/pai_software/S = software[soft] - if(S.toggle) - S.toggle(src) - else - ui_interact(src, ui_key = soft) - S.tgui_interact(src) - return 1 + switch(action) + if("software") + var/soft = params["software"] + var/datum/pai_software/S = software[soft] + if(S.toggle) + S.toggle(src) + else + S.tgui_interact(src, parent_ui = ui) + return TRUE - else if(href_list["stopic"]) - var/soft = href_list["stopic"] - var/datum/pai_software/S = software[soft] - if(S) - return S.Topic(href, href_list) + if("purchase") + var/soft = params["purchase"] + var/datum/pai_software/S = pai_software_by_key[soft] + if(S && (ram >= S.ram_cost)) + ram -= S.ram_cost + software[S.id] = S + return TRUE - else if(href_list["purchase"]) - var/soft = href_list["purchase"] - var/datum/pai_software/S = pai_software_by_key[soft] - if(S && (ram >= S.ram_cost)) - ram -= S.ram_cost - software[S.id] = S - return 1 - - else if(href_list["image"]) - var/img = text2num(href_list["image"]) - if(1 <= img && img <= (pai_emotions.len)) - card.setEmotion(img) - return 1 + if("image") + var/img = text2num(params["image"]) + if(1 <= img && img <= (pai_emotions.len)) + card.setEmotion(img) + return TRUE diff --git a/code/modules/mob/living/silicon/pai/software_modules.dm b/code/modules/mob/living/silicon/pai/software_modules.dm index c543c913885..e518e74a4a2 100644 --- a/code/modules/mob/living/silicon/pai/software_modules.dm +++ b/code/modules/mob/living/silicon/pai/software_modules.dm @@ -12,9 +12,6 @@ // Whether pAIs should automatically receive this module at no cost var/default = 0 -/datum/pai_software/proc/on_ui_interact(mob/living/silicon/pai/user, datum/nanoui/ui=null, force_open=1) - return - /datum/pai_software/proc/toggle(mob/living/silicon/pai/user) return @@ -36,30 +33,33 @@ toggle = 0 default = 1 -/datum/pai_software/directives/on_ui_interact(mob/living/silicon/pai/user, datum/nanoui/ui=null, force_open=1) - var/data[0] +/datum/pai_software/directives/tgui_interact(mob/user, datum/tgui/ui, datum/tgui/parent_ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "pAIDirectives", name, parent_ui) + ui.open() + +/datum/pai_software/directives/tgui_data(mob/living/silicon/pai/user, datum/tgui/ui, datum/tgui_state/state) + var/list/data = list() data["master"] = user.master data["dna"] = user.master_dna data["prime"] = user.pai_law0 data["supplemental"] = user.pai_laws - ui = SSnanoui.try_update_ui(user, user, id, ui, data, force_open) - if(!ui) - // Don't copy-paste this unless you're making a pAI software module! - ui = new(user, user, id, "pai_directives.tmpl", "pAI Directives", 450, 600) - ui.set_initial_data(data) - ui.open() - ui.set_auto_update(1) + return data -/datum/pai_software/directives/Topic(href, href_list) +/datum/pai_software/directives/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state) var/mob/living/silicon/pai/P = usr - if(!istype(P)) return + if(!istype(P)) + return TRUE + if(..()) + return TRUE - if(href_list["getdna"]) + if(action == "getdna") var/mob/living/M = P.loc - var/count = 0 + var/count = 0 // Find the carrier while(!istype(M, /mob/living)) if(!M || !M.loc || count > 6) @@ -73,7 +73,7 @@ var/datum/gender/TM = gender_datums[M.get_visible_gender()] var/answer = input(M, "[P] is requesting a DNA sample from you. Will you allow it to confirm your identity?", "[P] Check DNA", "No") in list("Yes", "No") if(answer == "Yes") - var/turf/T = get_turf_or_move(P.loc) + var/turf/T = get_turf(P.loc) for (var/mob/v in viewers(T)) v.show_message("[M] presses [TM.his] thumb against [P].", 3, "[P] makes a sharp clicking sound as it extracts DNA material from [M].", 2) var/datum/dna/dna = M.dna @@ -84,7 +84,7 @@ to_chat(P, "DNA does not match stored Master DNA.") else to_chat(P, "[M] does not seem like [TM.he] is going to provide a DNA sample willingly.") - return 1 + return TRUE /datum/pai_software/radio_config name = "Radio Configuration" @@ -130,15 +130,21 @@ id = "med_records" toggle = 0 -/datum/pai_software/med_records/on_ui_interact(mob/living/silicon/pai/user, datum/nanoui/ui=null, force_open=1) - var/data[0] +/datum/pai_software/med_records/tgui_interact(mob/user, datum/tgui/ui, datum/tgui/parent_ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "pAIMedrecords", name, parent_ui) + ui.open() - var/records[0] +/datum/pai_software/med_records/tgui_data(mob/living/silicon/pai/user, datum/tgui/ui, datum/tgui_state/state) + var/list/data = ..() + + var/list/records = list() for(var/datum/data/record/general in sortRecord(data_core.general)) - var/record[0] + var/list/record = list() record["name"] = general.fields["name"] record["ref"] = "\ref[general]" - records[++records.len] = record + records.Add(list(record)) data["records"] = records @@ -148,20 +154,16 @@ data["medical"] = M ? M.fields : null data["could_not_find"] = user.medical_cannotfind - ui = SSnanoui.try_update_ui(user, user, id, ui, data, force_open) - if(!ui) - // Don't copy-paste this unless you're making a pAI software module! - ui = new(user, user, id, "pai_medrecords.tmpl", "Medical Records", 450, 600) - ui.set_initial_data(data) - ui.open() - ui.set_auto_update(1) + return data -/datum/pai_software/med_records/Topic(href, href_list) +/datum/pai_software/med_records/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state) + . = ..() var/mob/living/silicon/pai/P = usr - if(!istype(P)) return + if(!istype(P)) + return - if(href_list["select"]) - var/datum/data/record/record = locate(href_list["select"]) + if(action == "select") + var/datum/data/record/record = locate(params["select"]) if(record) var/datum/data/record/R = record var/datum/data/record/M = null @@ -184,15 +186,21 @@ id = "sec_records" toggle = 0 -/datum/pai_software/sec_records/on_ui_interact(mob/living/silicon/pai/user, datum/nanoui/ui=null, force_open=1) - var/data[0] +/datum/pai_software/sec_records/tgui_interact(mob/user, datum/tgui/ui, datum/tgui/parent_ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "pAISecrecords", name, parent_ui) + ui.open() - var/records[0] +/datum/pai_software/sec_records/tgui_data(mob/living/silicon/pai/user, datum/tgui/ui, datum/tgui_state/state) + var/list/data = ..() + + var/list/records = list() for(var/datum/data/record/general in sortRecord(data_core.general)) - var/record[0] + var/list/record = list() record["name"] = general.fields["name"] record["ref"] = "\ref[general]" - records[++records.len] = record + records.Add(list(record)) data["records"] = records @@ -202,20 +210,16 @@ data["security"] = S ? S.fields : null data["could_not_find"] = user.security_cannotfind - ui = SSnanoui.try_update_ui(user, user, id, ui, data, force_open) - if(!ui) - // Don't copy-paste this unless you're making a pAI software module! - ui = new(user, user, id, "pai_secrecords.tmpl", "Security Records", 450, 600) - ui.set_initial_data(data) - ui.open() - ui.set_auto_update(1) + return data -/datum/pai_software/sec_records/Topic(href, href_list) +/datum/pai_software/sec_records/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state) + . = ..() var/mob/living/silicon/pai/P = usr - if(!istype(P)) return + if(!istype(P)) + return - if(href_list["select"]) - var/datum/data/record/record = locate(href_list["select"]) + if(action == "select") + var/datum/data/record/record = locate(params["select"]) if(record) var/datum/data/record/R = record var/datum/data/record/S = null @@ -234,7 +238,7 @@ P.securityActive1 = null P.securityActive2 = null P.security_cannotfind = 1 - return 1 + return TRUE /datum/pai_software/door_jack name = "Door Jack" @@ -242,8 +246,14 @@ id = "door_jack" toggle = 0 -/datum/pai_software/door_jack/on_ui_interact(mob/living/silicon/pai/user, datum/nanoui/ui=null, force_open=1) - var/data[0] +/datum/pai_software/door_jack/tgui_interact(mob/user, datum/tgui/ui, datum/tgui/parent_ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "pAIDoorjack", "Door Jack", parent_ui) + ui.open() + +/datum/pai_software/door_jack/tgui_data(mob/living/silicon/pai/user, datum/tgui/ui, datum/tgui_state/state) + var/list/data = ..() data["cable"] = user.cable != null data["machine"] = user.cable && (user.cable.machine != null) @@ -252,37 +262,33 @@ data["progress_b"] = user.hackprogress % 10 data["aborted"] = user.hack_aborted - ui = SSnanoui.try_update_ui(user, user, id, ui, data, force_open) - if(!ui) - // Don't copy-paste this unless you're making a pAI software module! - ui = new(user, user, id, "pai_doorjack.tmpl", "Door Jack", 300, 150) - ui.set_initial_data(data) - ui.open() - ui.set_auto_update(1) + return data -/datum/pai_software/door_jack/Topic(href, href_list) +/datum/pai_software/door_jack/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state) var/mob/living/silicon/pai/P = usr - if(!istype(P)) return + if(!istype(P) || ..()) + return TRUE - if(href_list["jack"]) - if(P.cable && P.cable.machine) - P.hackdoor = P.cable.machine - P.hackloop() - return 1 - else if(href_list["cancel"]) - P.hackdoor = null - return 1 - else if(href_list["cable"]) - var/turf/T = get_turf_or_move(P.loc) - P.hack_aborted = 0 - P.cable = new /obj/item/weapon/pai_cable(T) - for(var/mob/M in viewers(T)) - M.show_message("A port on [P] opens to reveal [P.cable], which promptly falls to the floor.", 3, - "You hear the soft click of something light and hard falling to the ground.", 2) - return 1 + switch(action) + if("jack") + if(P.cable && P.cable.machine) + P.hackdoor = P.cable.machine + P.hackloop() + return 1 + if("cancel") + P.hackdoor = null + return 1 + if("cable") + var/turf/T = get_turf(P) + P.hack_aborted = 0 + P.cable = new /obj/item/weapon/pai_cable(T) + for(var/mob/M in viewers(T)) + M.show_message("A port on [P] opens to reveal [P.cable], which promptly falls to the floor.", 3, + "You hear the soft click of something light and hard falling to the ground.", 2) + return 1 /mob/living/silicon/pai/proc/hackloop() - var/turf/T = get_turf_or_move(src.loc) + var/turf/T = get_turf(src) for(var/mob/living/silicon/ai/AI in player_list) if(T.loc) to_chat(AI, "Network Alert: Brute-force encryption crack in progress in [T.loc].") @@ -316,40 +322,51 @@ id = "atmos_sense" toggle = 0 -/datum/pai_software/atmosphere_sensor/on_ui_interact(mob/living/silicon/pai/user, datum/nanoui/ui=null, force_open=1) - var/data[0] - - var/turf/T = get_turf_or_move(user.loc) - if(!T) - data["reading"] = 0 - data["pressure"] = 0 - data["temperature"] = 0 - data["temperatureC"] = 0 - data["gas"] = list() - else - var/datum/gas_mixture/env = T.return_air() - data["reading"] = 1 - var/pres = env.return_pressure() * 10 - data["pressure"] = "[round(pres/10)].[pres%10]" - data["temperature"] = round(env.temperature) - data["temperatureC"] = round(env.temperature-T0C) - - var/t_moles = env.total_moles - var/gases[0] - for(var/g in env.gas) - var/gas[0] - gas["name"] = gas_data.name[g] - gas["percent"] = round((env.gas[g] / t_moles) * 100) - gases[++gases.len] = gas - data["gas"] = gases - - ui = SSnanoui.try_update_ui(user, user, id, ui, data, force_open) +/datum/pai_software/atmosphere_sensor/tgui_interact(mob/user, datum/tgui/ui, datum/tgui/parent_ui) + ui = SStgui.try_update_ui(user, src, ui) if(!ui) - // Don't copy-paste this unless you're making a pAI software module! - ui = new(user, user, id, "pai_atmosphere.tmpl", "Atmosphere Sensor", 350, 300) - ui.set_initial_data(data) + ui = new(user, src, "pAIAtmos", name, parent_ui) ui.open() +/datum/pai_software/atmosphere_sensor/tgui_data(mob/user, datum/tgui/ui, datum/tgui_state/state) + var/list/data = ..() + + var/list/results = list() + var/turf/T = get_turf(user) + if(!isnull(T)) + var/datum/gas_mixture/environment = T.return_air() + var/pressure = environment.return_pressure() + var/total_moles = environment.total_moles + if (total_moles) + var/o2_level = environment.gas["oxygen"]/total_moles + var/n2_level = environment.gas["nitrogen"]/total_moles + var/co2_level = environment.gas["carbon_dioxide"]/total_moles + var/phoron_level = environment.gas["phoron"]/total_moles + var/unknown_level = 1-(o2_level+n2_level+co2_level+phoron_level) + + // entry is what the element is describing + // Type identifies which unit or other special characters to use + // Val is the information reported + // Bad_high/_low are the values outside of which the entry reports as dangerous + // Poor_high/_low are the values outside of which the entry reports as unideal + // Values were extracted from the template itself + results = list( + list("entry" = "Pressure", "units" = "kPa", "val" = "[round(pressure,0.1)]", "bad_high" = 120, "poor_high" = 110, "poor_low" = 95, "bad_low" = 80), + list("entry" = "Temperature", "units" = "°C", "val" = "[round(environment.temperature-T0C,0.1)]", "bad_high" = 35, "poor_high" = 25, "poor_low" = 15, "bad_low" = 5), + list("entry" = "Oxygen", "units" = "kPa", "val" = "[round(o2_level*100,0.1)]", "bad_high" = 140, "poor_high" = 135, "poor_low" = 19, "bad_low" = 17), + list("entry" = "Nitrogen", "units" = "kPa", "val" = "[round(n2_level*100,0.1)]", "bad_high" = 105, "poor_high" = 85, "poor_low" = 50, "bad_low" = 40), + list("entry" = "Carbon Dioxide", "units" = "kPa", "val" = "[round(co2_level*100,0.1)]", "bad_high" = 10, "poor_high" = 5, "poor_low" = 0, "bad_low" = 0), + list("entry" = "Phoron", "units" = "kPa", "val" = "[round(phoron_level*100,0.01)]", "bad_high" = 0.5, "poor_high" = 0, "poor_low" = 0, "bad_low" = 0), + list("entry" = "Other", "units" = "kPa", "val" = "[round(unknown_level, 0.01)]", "bad_high" = 1, "poor_high" = 0.5, "poor_low" = 0, "bad_low" = 0) + ) + + if(isnull(results)) + results = list(list("entry" = "pressure", "units" = "kPa", "val" = "0", "bad_high" = 120, "poor_high" = 110, "poor_low" = 95, "bad_low" = 80)) + + data["aircontents"] = results + + return data + /datum/pai_software/sec_hud name = "Security HUD" ram_cost = 20 @@ -406,44 +423,54 @@ return user.translator_on /datum/pai_software/signaller - name = "Remote Signaller" + name = "Remote Signaler" ram_cost = 5 id = "signaller" toggle = 0 -/datum/pai_software/signaller/on_ui_interact(mob/living/silicon/pai/user, datum/nanoui/ui=null, force_open=1) - var/data[0] - - data["frequency"] = format_frequency(user.sradio.frequency) - data["code"] = user.sradio.code - - ui = SSnanoui.try_update_ui(user, user, id, ui, data, force_open) +/datum/pai_software/signaller/tgui_interact(mob/user, datum/tgui/ui, datum/tgui/parent_ui) + ui = SStgui.try_update_ui(user, src, ui) if(!ui) - // Don't copy-paste this unless you're making a pAI software module! - ui = new(user, user, id, "pai_signaller.tmpl", "Signaller", 320, 150) - ui.set_initial_data(data) + ui = new(user, src, "Signaler", "Signaler", parent_ui) ui.open() -/datum/pai_software/signaller/Topic(href, href_list) - var/mob/living/silicon/pai/P = usr - if(!istype(P)) return +/datum/pai_software/signaller/tgui_data(mob/living/silicon/pai/user, datum/tgui/ui, datum/tgui_state/state) + var/list/data = ..() + + var/obj/item/radio/integrated/signal/R = user.sradio - if(href_list["send"]) - P.sradio.send_signal("ACTIVATE") - for(var/mob/O in hearers(1, P.loc)) - O.show_message("[bicon(P)] *beep* *beep*", 3, "*beep* *beep*", 2) - return 1 + data["frequency"] = R.frequency + data["minFrequency"] = RADIO_LOW_FREQ + data["maxFrequency"] = RADIO_HIGH_FREQ + data["code"] = R.code - else if(href_list["freq"]) - var/new_frequency = (P.sradio.frequency + text2num(href_list["freq"])) - if(new_frequency < PUBLIC_LOW_FREQ || new_frequency > PUBLIC_HIGH_FREQ) - new_frequency = sanitize_frequency(new_frequency) - P.sradio.set_frequency(new_frequency) - return 1 + return data - else if(href_list["code"]) - P.sradio.code += text2num(href_list["code"]) - P.sradio.code = round(P.sradio.code) - P.sradio.code = min(100, P.sradio.code) - P.sradio.code = max(1, P.sradio.code) - return 1 +/datum/pai_software/signaller/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state) + if(..()) + return TRUE + + var/mob/living/silicon/pai/user = usr + if(istype(user)) + var/obj/item/radio/integrated/signal/R = user.sradio + + switch(action) + if("signal") + spawn(0) + R.send_signal("ACTIVATE") + for(var/mob/O in hearers(1, R.loc)) + O.show_message("[bicon(R)] *beep* *beep*", 3, "*beep* *beep*", 2) + if("freq") + var/frequency = unformat_frequency(params["freq"]) + frequency = sanitize_frequency(frequency, RADIO_LOW_FREQ, RADIO_HIGH_FREQ) + R.set_frequency(frequency) + . = TRUE + if("code") + R.code = clamp(round(text2num(params["code"])), 1, 100) + . = TRUE + if("reset") + if(params["reset"] == "freq") + R.set_frequency(initial(R.frequency)) + else + R.code = initial(R.code) + . = TRUE diff --git a/code/modules/resleeving/infomorph.dm b/code/modules/resleeving/infomorph.dm index 248444f1dff..87f622f6faa 100644 --- a/code/modules/resleeving/infomorph.dm +++ b/code/modules/resleeving/infomorph.dm @@ -463,94 +463,81 @@ var/global/list/default_infomorph_software = list() set category = "Card Commands" set name = "Software Interface" - ui_interact(src) + tgui_interact(src) -/mob/living/silicon/infomorph/ui_interact(mob/user, ui_key = "main", datum/nanoui/ui = null, force_open = 1, key_state = self_state) - if(user != src) - if(ui) ui.set_status(STATUS_CLOSE, 0) - return +/mob/living/silicon/infomorph/tgui_state(mob/user) + return GLOB.tgui_self_state - if(ui_key != "main") - var/datum/infomorph_software/S = software[ui_key] - if(S && !S.toggle) - S.on_ui_interact(src, ui, force_open) - else - if(ui) ui.set_status(STATUS_CLOSE, 0) - return - - var/data[0] +/mob/living/silicon/infomorph/tgui_interact(mob/user, datum/tgui/ui, datum/tgui/parent_ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "pAIInterface", "Card Software Interface") + ui.open() +/mob/living/silicon/infomorph/tgui_data(mob/user, datum/tgui/ui, datum/tgui_state/state) + var/list/data = ..() + // Software we have bought - var/bought_software[0] + var/list/bought_software = list() // Software we have not bought - var/not_bought_software[0] + var/list/not_bought_software = list() for(var/key in infomorph_software_by_key) var/datum/infomorph_software/S = infomorph_software_by_key[key] - var/software_data[0] + var/list/software_data = list() software_data["name"] = S.name software_data["id"] = S.id if(key in software) software_data["on"] = S.is_active(src) - bought_software[++bought_software.len] = software_data + bought_software.Add(list(software_data)) else software_data["ram"] = S.ram_cost - not_bought_software[++not_bought_software.len] = software_data + not_bought_software.Add(list(software_data)) data["bought"] = bought_software data["not_bought"] = not_bought_software data["available_ram"] = ram // Emotions - var/emotions[0] + var/list/emotions = list() for(var/name in infomorph_emotions) - var/emote[0] + var/list/emote = list() emote["name"] = name emote["id"] = infomorph_emotions[name] - emotions[++emotions.len] = emote + emotions.Add(list(emote)) data["emotions"] = emotions data["current_emotion"] = card.current_emotion - ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open, key_state) - if (!ui) - ui = new(user, src, ui_key, "pai_interface.tmpl", "Card Software Interface", 450, 600, state = key_state) - ui.set_initial_data(data) - ui.open() - ui.set_auto_update(1) + return data -/mob/living/silicon/infomorph/Topic(href, href_list) - . = ..() - if(.) return +/mob/living/silicon/infomorph/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state) + if(..()) + return TRUE - if(href_list["software"]) - var/soft = href_list["software"] - var/datum/infomorph_software/S = software[soft] - if(S.toggle) - S.toggle(src) - else - ui_interact(src, ui_key = soft) - return 1 + switch(action) + if("software") + var/soft = params["software"] + var/datum/infomorph_software/S = software[soft] + if(S.toggle) + S.toggle(src) + else + S.tgui_interact(src, parent_ui = ui) + return TRUE - else if(href_list["stopic"]) - var/soft = href_list["stopic"] - var/datum/infomorph_software/S = software[soft] - if(S) - return S.Topic(href, href_list) + if("purchase") + var/soft = params["purchase"] + var/datum/infomorph_software/S = infomorph_software_by_key[soft] + if(S && (ram >= S.ram_cost)) + ram -= S.ram_cost + software[S.id] = S + return TRUE - else if(href_list["purchase"]) - var/soft = href_list["purchase"] - var/datum/infomorph_software/S = infomorph_software_by_key[soft] - if(S && (ram >= S.ram_cost)) - ram -= S.ram_cost - software[S.id] = S - return 1 - - else if(href_list["image"]) - var/img = href_list["image"] - if(img) - card.setEmotion(img) - return 1 + if("image") + var/img = text2num(params["image"]) + if(img) + card.setEmotion(img) + return TRUE /mob/living/silicon/infomorph/examine(mob/user) . = ..(user, infix = ", personal AI") diff --git a/code/modules/resleeving/infomorph_software.dm b/code/modules/resleeving/infomorph_software.dm index 2d2439b614a..67a2bd47f93 100644 --- a/code/modules/resleeving/infomorph_software.dm +++ b/code/modules/resleeving/infomorph_software.dm @@ -12,35 +12,38 @@ // Whether pAIs should automatically receive this module at no cost var/default = 0 - proc/on_ui_interact(mob/living/silicon/infomorph/user, datum/nanoui/ui=null, force_open=1) - return +/datum/infomorph_software/tgui_state(mob/user) + return GLOB.tgui_always_state - proc/toggle(mob/living/silicon/infomorph/user) - return +/datum/infomorph_software/tgui_status(mob/user) + if(!istype(user, /mob/living/silicon/infomorph)) + return STATUS_CLOSE + return ..() - proc/is_active(mob/living/silicon/infomorph/user) - return 0 +/datum/infomorph_software/proc/toggle(mob/living/silicon/infomorph/user) + return + +/datum/infomorph_software/proc/is_active(mob/living/silicon/infomorph/user) + return 0 /datum/infomorph_software/crew_manifest name = "Crew Manifest" - ram_cost = 15 + ram_cost = 5 id = "manifest" toggle = 0 - on_ui_interact(mob/living/silicon/infomorph/user, datum/nanoui/ui=null, force_open=1) +/datum/infomorph_software/crew_manifest/tgui_interact(mob/user, datum/tgui/ui, datum/tgui/parent_ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "CrewManifest", name, parent_ui) + ui.open() + +/datum/infomorph_software/crew_manifest/tgui_data(mob/user, datum/tgui/ui, datum/tgui_state/state) + var/list/data = ..() + if(data_core) data_core.get_manifest_list() - - var/data[0] - // This is dumb, but NanoUI breaks if it has no data to send - data["manifest"] = PDA_Manifest - - ui = SSnanoui.try_update_ui(user, user, id, ui, data, force_open) - if(!ui) - // Don't copy-paste this unless you're making a pAI software module! - ui = new(user, user, id, "pai_manifest.tmpl", "Crew Manifest", 450, 600) - ui.set_initial_data(data) - ui.open() - ui.set_auto_update(1) + data["manifest"] = PDA_Manifest + return data /datum/infomorph_software/med_records name = "Medical Records" @@ -48,53 +51,55 @@ id = "med_records" toggle = 0 - on_ui_interact(mob/living/silicon/infomorph/user, datum/nanoui/ui=null, force_open=1) - var/data[0] +/datum/infomorph_software/med_records/tgui_interact(mob/user, datum/tgui/ui, datum/tgui/parent_ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "pAIMedrecords", name, parent_ui) + ui.open() - var/records[0] - for(var/datum/data/record/general in sortRecord(data_core.general)) - var/record[0] - record["name"] = general.fields["name"] - record["ref"] = "\ref[general]" - records[++records.len] = record +/datum/infomorph_software/med_records/tgui_data(mob/living/silicon/infomorph/user, datum/tgui/ui, datum/tgui_state/state) + var/list/data = ..() + + var/list/records = list() + for(var/datum/data/record/general in sortRecord(data_core.general)) + var/list/record = list() + record["name"] = general.fields["name"] + record["ref"] = "\ref[general]" + records.Add(list(record)) - data["records"] = records + data["records"] = records - var/datum/data/record/G = user.medicalActive1 - var/datum/data/record/M = user.medicalActive2 - data["general"] = G ? G.fields : null - data["medical"] = M ? M.fields : null - data["could_not_find"] = user.medical_cannotfind + var/datum/data/record/G = user.medicalActive1 + var/datum/data/record/M = user.medicalActive2 + data["general"] = G ? G.fields : null + data["medical"] = M ? M.fields : null + data["could_not_find"] = user.medical_cannotfind - ui = SSnanoui.try_update_ui(user, user, id, ui, data, force_open) - if(!ui) - // Don't copy-paste this unless you're making a pAI software module! - ui = new(user, user, id, "pai_medrecords.tmpl", "Medical Records", 450, 600) - ui.set_initial_data(data) - ui.open() - ui.set_auto_update(1) + return data - Topic(href, href_list) - var/mob/living/silicon/infomorph/P = usr - if(!istype(P)) return +/datum/infomorph_software/med_records/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state) + . = ..() + var/mob/living/silicon/infomorph/P = usr + if(!istype(P)) + return - if(href_list["select"]) - var/datum/data/record/record = locate(href_list["select"]) - if(record) - var/datum/data/record/R = record - var/datum/data/record/M = null - if (!( data_core.general.Find(R) )) - P.medical_cannotfind = 1 - else - P.medical_cannotfind = 0 - for(var/datum/data/record/E in data_core.medical) - if ((E.fields["name"] == R.fields["name"] || E.fields["id"] == R.fields["id"])) - M = E - P.medicalActive1 = R - P.medicalActive2 = M - else + if(action == "select") + var/datum/data/record/record = locate(params["select"]) + if(record) + var/datum/data/record/R = record + var/datum/data/record/M = null + if (!( data_core.general.Find(R) )) P.medical_cannotfind = 1 - return 1 + else + P.medical_cannotfind = 0 + for(var/datum/data/record/E in data_core.medical) + if ((E.fields["name"] == R.fields["name"] || E.fields["id"] == R.fields["id"])) + M = E + P.medicalActive1 = R + P.medicalActive2 = M + else + P.medical_cannotfind = 1 + return 1 /datum/infomorph_software/sec_records name = "Security Records" @@ -102,57 +107,59 @@ id = "sec_records" toggle = 0 - on_ui_interact(mob/living/silicon/infomorph/user, datum/nanoui/ui=null, force_open=1) - var/data[0] +/datum/infomorph_software/sec_records/tgui_interact(mob/user, datum/tgui/ui, datum/tgui/parent_ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "pAISecrecords", name, parent_ui) + ui.open() - var/records[0] - for(var/datum/data/record/general in sortRecord(data_core.general)) - var/record[0] - record["name"] = general.fields["name"] - record["ref"] = "\ref[general]" - records[++records.len] = record +/datum/infomorph_software/sec_records/tgui_data(mob/living/silicon/infomorph/user, datum/tgui/ui, datum/tgui_state/state) + var/list/data = ..() + + var/list/records = list() + for(var/datum/data/record/general in sortRecord(data_core.general)) + var/list/record = list() + record["name"] = general.fields["name"] + record["ref"] = "\ref[general]" + records.Add(list(record)) - data["records"] = records + data["records"] = records - var/datum/data/record/G = user.securityActive1 - var/datum/data/record/S = user.securityActive2 - data["general"] = G ? G.fields : null - data["security"] = S ? S.fields : null - data["could_not_find"] = user.security_cannotfind + var/datum/data/record/G = user.securityActive1 + var/datum/data/record/S = user.securityActive2 + data["general"] = G ? G.fields : null + data["security"] = S ? S.fields : null + data["could_not_find"] = user.security_cannotfind - ui = SSnanoui.try_update_ui(user, user, id, ui, data, force_open) - if(!ui) - // Don't copy-paste this unless you're making a pAI software module! - ui = new(user, user, id, "pai_secrecords.tmpl", "Security Records", 450, 600) - ui.set_initial_data(data) - ui.open() - ui.set_auto_update(1) + return data - Topic(href, href_list) - var/mob/living/silicon/infomorph/P = usr - if(!istype(P)) return +/datum/infomorph_software/sec_records/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state) + . = ..() + var/mob/living/silicon/infomorph/P = usr + if(!istype(P)) + return - if(href_list["select"]) - var/datum/data/record/record = locate(href_list["select"]) - if(record) - var/datum/data/record/R = record - var/datum/data/record/S = null - if (!( data_core.general.Find(R) )) - P.securityActive1 = null - P.securityActive2 = null - P.security_cannotfind = 1 - else - P.security_cannotfind = 0 - for(var/datum/data/record/E in data_core.security) - if ((E.fields["name"] == R.fields["name"] || E.fields["id"] == R.fields["id"])) - S = E - P.securityActive1 = R - P.securityActive2 = S - else + if(action == "select") + var/datum/data/record/record = locate(params["select"]) + if(record) + var/datum/data/record/R = record + var/datum/data/record/S = null + if (!( data_core.general.Find(R) )) P.securityActive1 = null P.securityActive2 = null P.security_cannotfind = 1 - return 1 + else + P.security_cannotfind = 0 + for(var/datum/data/record/E in data_core.security) + if ((E.fields["name"] == R.fields["name"] || E.fields["id"] == R.fields["id"])) + S = E + P.securityActive1 = R + P.securityActive2 = S + else + P.securityActive1 = null + P.securityActive2 = null + P.security_cannotfind = 1 + return TRUE /datum/infomorph_software/door_jack name = "Door Jack" @@ -160,44 +167,45 @@ id = "door_jack" toggle = 0 - on_ui_interact(mob/living/silicon/infomorph/user, datum/nanoui/ui=null, force_open=1) - var/data[0] +/datum/infomorph_software/door_jack/tgui_interact(mob/user, datum/tgui/ui, datum/tgui/parent_ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "pAIDoorjack", "Door Jack", parent_ui) + ui.open() - data["cable"] = user.cable != null - data["machine"] = user.cable && (user.cable.machine != null) - data["inprogress"] = user.hackdoor != null - data["progress_a"] = round(user.hackprogress) - data["progress_b"] = user.hackprogress % 10 - data["aborted"] = user.hack_aborted +/datum/infomorph_software/door_jack/tgui_data(mob/living/silicon/infomorph/user, datum/tgui/ui, datum/tgui_state/state) + var/list/data = ..() - ui = SSnanoui.try_update_ui(user, user, id, ui, data, force_open) - if(!ui) - // Don't copy-paste this unless you're making a pAI software module! - ui = new(user, user, id, "pai_doorjack.tmpl", "Door Jack", 300, 150) - ui.set_initial_data(data) - ui.open() - ui.set_auto_update(1) + data["cable"] = user.cable != null + data["machine"] = user.cable && (user.cable.machine != null) + data["inprogress"] = user.hackdoor != null + data["progress_a"] = round(user.hackprogress / 10) + data["progress_b"] = user.hackprogress % 10 + data["aborted"] = user.hack_aborted - Topic(href, href_list) - var/mob/living/silicon/infomorph/P = usr - if(!istype(P)) return + return data - if(href_list["jack"]) +/datum/infomorph_software/door_jack/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state) + var/mob/living/silicon/infomorph/P = usr + if(!istype(P) || ..()) + return TRUE + + switch(action) + if("jack") if(P.cable && P.cable.machine) P.hackdoor = P.cable.machine P.hackloop() return 1 - else if(href_list["cancel"]) + if("cancel") P.hackdoor = null return 1 - else if(href_list["cable"]) + if("cable") var/turf/T = get_turf(P) P.hack_aborted = 0 P.cable = new /obj/item/weapon/pai_cable(T) - if(ishuman(P.card.loc)) - var/mob/living/carbon/human/H = P.card.loc - H.put_in_any_hand_if_possible(P.cable) - T.visible_message("A port on \the [P] opens to reveal \the [P.cable].") + for(var/mob/M in viewers(T)) + M.show_message("A port on [P] opens to reveal [P.cable], which promptly falls to the floor.", 3, + "You hear the soft click of something light and hard falling to the ground.", 2) return 1 /mob/living/silicon/infomorph/proc/hackloop() @@ -239,43 +247,54 @@ /datum/infomorph_software/atmosphere_sensor name = "Atmosphere Sensor" - ram_cost = 15 + ram_cost = 5 id = "atmos_sense" toggle = 0 - on_ui_interact(mob/living/silicon/infomorph/user, datum/nanoui/ui=null, force_open=1) - var/data[0] +/datum/infomorph_software/atmosphere_sensor/tgui_interact(mob/user, datum/tgui/ui, datum/tgui/parent_ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "pAIAtmos", name, parent_ui) + ui.open() - var/turf/T = get_turf_or_move(user.loc) - if(!T) - data["reading"] = 0 - data["pressure"] = 0 - data["temperature"] = 0 - data["temperatureC"] = 0 - data["gas"] = list() - else - var/datum/gas_mixture/env = T.return_air() - data["reading"] = 1 - var/pres = env.return_pressure() * 10 - data["pressure"] = "[round(pres/10)].[pres%10]" - data["temperature"] = round(env.temperature) - data["temperatureC"] = round(env.temperature-T0C) +/datum/infomorph_software/atmosphere_sensor/tgui_data(mob/user, datum/tgui/ui, datum/tgui_state/state) + var/list/data = ..() - var/t_moles = env.total_moles - var/gases[0] - for(var/g in env.gas) - var/gas[0] - gas["name"] = gas_data.name[g] - gas["percent"] = round((env.gas[g] / t_moles) * 100) - gases[++gases.len] = gas - data["gas"] = gases + var/list/results = list() + var/turf/T = get_turf(user) + if(!isnull(T)) + var/datum/gas_mixture/environment = T.return_air() + var/pressure = environment.return_pressure() + var/total_moles = environment.total_moles + if (total_moles) + var/o2_level = environment.gas["oxygen"]/total_moles + var/n2_level = environment.gas["nitrogen"]/total_moles + var/co2_level = environment.gas["carbon_dioxide"]/total_moles + var/phoron_level = environment.gas["phoron"]/total_moles + var/unknown_level = 1-(o2_level+n2_level+co2_level+phoron_level) - ui = SSnanoui.try_update_ui(user, user, id, ui, data, force_open) - if(!ui) - // Don't copy-paste this unless you're making a pAI software module! - ui = new(user, user, id, "pai_atmosphere.tmpl", "Atmosphere Sensor", 350, 300) - ui.set_initial_data(data) - ui.open() + // entry is what the element is describing + // Type identifies which unit or other special characters to use + // Val is the information reported + // Bad_high/_low are the values outside of which the entry reports as dangerous + // Poor_high/_low are the values outside of which the entry reports as unideal + // Values were extracted from the template itself + results = list( + list("entry" = "Pressure", "units" = "kPa", "val" = "[round(pressure,0.1)]", "bad_high" = 120, "poor_high" = 110, "poor_low" = 95, "bad_low" = 80), + list("entry" = "Temperature", "units" = "°C", "val" = "[round(environment.temperature-T0C,0.1)]", "bad_high" = 35, "poor_high" = 25, "poor_low" = 15, "bad_low" = 5), + list("entry" = "Oxygen", "units" = "kPa", "val" = "[round(o2_level*100,0.1)]", "bad_high" = 140, "poor_high" = 135, "poor_low" = 19, "bad_low" = 17), + list("entry" = "Nitrogen", "units" = "kPa", "val" = "[round(n2_level*100,0.1)]", "bad_high" = 105, "poor_high" = 85, "poor_low" = 50, "bad_low" = 40), + list("entry" = "Carbon Dioxide", "units" = "kPa", "val" = "[round(co2_level*100,0.1)]", "bad_high" = 10, "poor_high" = 5, "poor_low" = 0, "bad_low" = 0), + list("entry" = "Phoron", "units" = "kPa", "val" = "[round(phoron_level*100,0.01)]", "bad_high" = 0.5, "poor_high" = 0, "poor_low" = 0, "bad_low" = 0), + list("entry" = "Other", "units" = "kPa", "val" = "[round(unknown_level, 0.01)]", "bad_high" = 1, "poor_high" = 0.5, "poor_low" = 0, "bad_low" = 0) + ) + + if(isnull(results)) + results = list(list("entry" = "pressure", "units" = "kPa", "val" = "0", "bad_high" = 120, "poor_high" = 110, "poor_low" = 95, "bad_low" = 80)) + + data["aircontents"] = results + + return data /datum/infomorph_software/ar_hud name = "AR HUD" @@ -302,45 +321,56 @@ is_active(mob/living/silicon/infomorph/user) return user.translator.listening + /datum/infomorph_software/signaller - name = "Remote Signaller" - ram_cost = 15 + name = "Remote Signaler" + ram_cost = 5 id = "signaller" toggle = 0 - on_ui_interact(mob/living/silicon/infomorph/user, datum/nanoui/ui=null, force_open=1) - var/data[0] +/datum/infomorph_software/signaller/tgui_interact(mob/user, datum/tgui/ui, datum/tgui/parent_ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "Signaler", "Signaler", parent_ui) + ui.open() - data["frequency"] = format_frequency(user.sradio.frequency) - data["code"] = user.sradio.code +/datum/infomorph_software/signaller/tgui_data(mob/living/silicon/infomorph/user, datum/tgui/ui, datum/tgui_state/state) + var/list/data = ..() + + var/obj/item/radio/integrated/signal/R = user.sradio - ui = SSnanoui.try_update_ui(user, user, id, ui, data, force_open) - if(!ui) - // Don't copy-paste this unless you're making a pAI software module! - ui = new(user, user, id, "pai_signaller.tmpl", "Signaller", 320, 150) - ui.set_initial_data(data) - ui.open() + data["frequency"] = R.frequency + data["minFrequency"] = RADIO_LOW_FREQ + data["maxFrequency"] = RADIO_HIGH_FREQ + data["code"] = R.code - Topic(href, href_list) - var/mob/living/silicon/infomorph/P = usr - if(!istype(P)) return + return data - if(href_list["send"]) - P.sradio.send_signal("ACTIVATE") - for(var/mob/O in hearers(1, P.loc)) - O.show_message("[bicon(P)] *beep* *beep*", 3, "*beep* *beep*", 2) - return 1 +/datum/infomorph_software/signaller/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state) + if(..()) + return TRUE - else if(href_list["freq"]) - var/new_frequency = (P.sradio.frequency + text2num(href_list["freq"])) - if(new_frequency < PUBLIC_LOW_FREQ || new_frequency > PUBLIC_HIGH_FREQ) - new_frequency = sanitize_frequency(new_frequency) - P.sradio.set_frequency(new_frequency) - return 1 + var/mob/living/silicon/infomorph/user = usr + if(istype(user)) + var/obj/item/radio/integrated/signal/R = user.sradio - else if(href_list["code"]) - P.sradio.code += text2num(href_list["code"]) - P.sradio.code = round(P.sradio.code) - P.sradio.code = min(100, P.sradio.code) - P.sradio.code = max(1, P.sradio.code) - return 1 + switch(action) + if("signal") + spawn(0) + R.send_signal("ACTIVATE") + for(var/mob/O in hearers(1, R.loc)) + O.show_message("[bicon(R)] *beep* *beep*", 3, "*beep* *beep*", 2) + if("freq") + var/frequency = unformat_frequency(params["freq"]) + frequency = sanitize_frequency(frequency, RADIO_LOW_FREQ, RADIO_HIGH_FREQ) + R.set_frequency(frequency) + . = TRUE + if("code") + R.code = clamp(round(text2num(params["code"])), 1, 100) + . = TRUE + if("reset") + if(params["reset"] == "freq") + R.set_frequency(initial(R.frequency)) + else + R.code = initial(R.code) + . = TRUE diff --git a/code/modules/resleeving/sleevecard.dm b/code/modules/resleeving/sleevecard.dm index 7da45bbdb1c..1fc6b8decaf 100644 --- a/code/modules/resleeving/sleevecard.dm +++ b/code/modules/resleeving/sleevecard.dm @@ -1,6 +1,9 @@ /obj/item/device/radio/sleevecard canhear_range = 0 +/obj/item/device/radio/sleevecard/tgui_state(mob/user) + return GLOB.tgui_always_state + /obj/item/device/sleevecard name = "sleevecard" desc = "This KHI-upgraded pAI module has enough capacity to run a whole mind of human-level intelligence." diff --git a/code/modules/tgui/tgui.dm b/code/modules/tgui/tgui.dm index 2f928ae6fa5..eb128a129bd 100644 --- a/code/modules/tgui/tgui.dm +++ b/code/modules/tgui/tgui.dm @@ -114,7 +114,6 @@ closing = TRUE for(var/datum/tgui/child in children) child.close(can_be_suspended, logout) - children.Cut() // If we don't have window_id, open proc did not have the opportunity // to finish, therefore it's safe to skip this whole block. if(window) @@ -126,6 +125,8 @@ src_object.tgui_close(user) SStgui.on_close(src) state = null + if(parent_ui) + parent_ui.children -= src parent_ui = null qdel(src) diff --git a/nano/templates/pai_atmosphere.tmpl b/nano/templates/pai_atmosphere.tmpl deleted file mode 100644 index b1a0b0404b8..00000000000 --- a/nano/templates/pai_atmosphere.tmpl +++ /dev/null @@ -1,36 +0,0 @@ - - -{{if data.reading}} -