diff --git a/code/modules/mob/living/simple_animal/bot/atmosbot.dm b/code/modules/mob/living/simple_animal/bot/atmosbot.dm index 6a42640d86618..e6f9bad4045ef 100644 --- a/code/modules/mob/living/simple_animal/bot/atmosbot.dm +++ b/code/modules/mob/living/simple_animal/bot/atmosbot.dm @@ -313,47 +313,35 @@ to_check_turfs |= adjacent_turf return null -/mob/living/simple_animal/bot/atmosbot/get_controls(mob/user) - var/dat - dat += hack(user) - dat += showpai(user) - dat += "Atmospheric Stabilizer Controls v1.1

" - dat += "Status: [on ? "On" : "Off"]
" - dat += "Maintenance panel panel is [open ? "opened" : "closed"]
" - if(!locked || issilicon(user) || IsAdminGhost(user)) - dat += "Breach Pressure: [breached_pressure]
" - dat += "Temperature Control: [temperature_control?"Enabled":"Disabled"]
" - dat += "Temperature Target: [ideal_temperature]K
" - dat += "Gas Scrubbing Controls
" - for(var/gas_id in gasses) - var/gas_enabled = gasses[gas_id] - dat += "[GLOB.gas_data.names[gas_id]]: [gas_enabled?"Scrubbing":"Not Scrubbing"]
" - dat += "Patrol Station: [auto_patrol ? "Yes" : "No"]
" - return dat - -/mob/living/simple_animal/bot/atmosbot/Topic(href, href_list) - if(..()) - return TRUE - - if(href_list["set_breach_pressure"]) - var/new_breach_pressure = input(usr, "Pressure to scan for breaches at? (0 to 100)", "Breach Pressure") as num - if(!isnum(new_breach_pressure) || new_breach_pressure < 0 || new_breach_pressure > 100) - return - breached_pressure = new_breach_pressure - else if(href_list["toggle_temp_control"]) - temperature_control = temperature_control ? FALSE : TRUE - else if(href_list["toggle_gas"]) - var/gas_id = href_list["toggle_gas"] - for(var/G in gasses) - if("[G]" == gas_id) - gasses[G] = gasses[G] ? FALSE : TRUE - else if(href_list["set_ideal_temperature"]) - var/new_temp = input(usr, "Set Target Temperature ([T0C]K to [T20C + 20]K)", "Target Temperature") as num - if(!isnum(new_temp) || new_temp < T0C || new_temp > T20C + 20) - return - ideal_temperature = new_temp - - update_controls() +/mob/living/simple_animal/bot/atmosbot/ui_data(mob/user) + var/list/data = ..() + if (!locked || issilicon(user) || IsAdminGhost(user)) + data["custom_controls"]["breach_pressure"] = breached_pressure + data["custom_controls"]["temperature_control"] = temperature_control + data["custom_controls"]["ideal_temperature"] = ideal_temperature + data["custom_controls"]["scrub_gasses"] = gasses + return data + +/mob/living/simple_animal/bot/atmosbot/ui_act(action, params) + . = ..() + if(. || (locked && !usr.has_unlimited_silicon_privilege)) + return + switch(action) + if("breach_pressure") + var/adjust_num = round(text2num(params["pressure"])) + adjust_num = clamp(adjust_num, 0, 100) + breached_pressure = adjust_num + if("temperature_control") + temperature_control = !temperature_control + if("ideal_temperature") + var/adjust_num = round(text2num(params["temperature"])) + adjust_num = clamp(adjust_num, T0C, T20C + 20) + ideal_temperature = adjust_num + if("scrub_gasses") + var/id = params["id"] + for(var/gas_id in gasses) + if (gas_id == id) + gasses[id] = !gasses[id] update_icon() /mob/living/simple_animal/bot/atmosbot/update_icon() diff --git a/code/modules/mob/living/simple_animal/bot/bot.dm b/code/modules/mob/living/simple_animal/bot/bot.dm index f4b33a44b3aed..28e3c1d1d760d 100644 --- a/code/modules/mob/living/simple_animal/bot/bot.dm +++ b/code/modules/mob/living/simple_animal/bot/bot.dm @@ -306,18 +306,22 @@ /mob/living/simple_animal/bot/attack_hand(mob/living/carbon/human/H) if(H.a_intent == INTENT_HELP) - interact(H) + ui_interact(H) else return ..() /mob/living/simple_animal/bot/attack_ai(mob/user) if(!topic_denied(user)) - interact(user) + ui_interact(user) else to_chat(user, "[src]'s interface is not responding!") -/mob/living/simple_animal/bot/interact(mob/user) - show_controls(user) +/mob/living/simple_animal/bot/ui_interact(mob/user, datum/tgui/ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "SimpleBot", name) + ui.set_autoupdate(TRUE) + ui.open() /mob/living/simple_animal/bot/proc/togglelock(mob/living/user) if(bot_core.allowed(user) && !open && !emagged) @@ -899,6 +903,79 @@ Pass a positive integer as an argument to override a bot's default speed. D.open() frustration = 0 +/mob/living/simple_animal/bot/ui_data(mob/user) + var/list/data = list() + data["can_hack"] = (issilicon(user) || IsAdminGhost(user)) + data["custom_controls"] = list() + data["emagged"] = emagged + data["locked"] = locked + data["pai"] = list() + data["settings"] = list() + if(!locked || issilicon(user) || IsAdminGhost(user)) + data["pai"]["allow_pai"] = allow_pai + data["pai"]["card_inserted"] = paicard + data["settings"]["airplane_mode"] = !remote_disabled + data["settings"]["maintenance_lock"] = !open + data["settings"]["power"] = on + data["settings"]["booting"] = booting + data["settings"]["patrol_station"] = auto_patrol + return data + +// Actions received from TGUI +/mob/living/simple_animal/bot/ui_act(action, params) + . = ..() + if(.) + return + if(!bot_core.allowed(usr) && !usr.has_unlimited_silicon_privilege) + to_chat(usr, "Access denied.") + return + if(action == "lock") + locked = !locked + if(locked && !(issilicon(usr) || IsAdminGhost(usr))) + return + switch(action) + if("power") + if(bot_core.allowed(usr) || !locked) + if (on) + turn_off() + else + boot_up_sequence() + if("maintenance") + open = !open + if("patrol") + if(!issilicon(usr) && !IsAdminGhost(usr) && !(bot_core.allowed(usr) || !locked)) + return TRUE + auto_patrol = !auto_patrol + bot_reset() + if("airplane") + remote_disabled = !remote_disabled + if("hack") + if(!issilicon(usr) && !IsAdminGhost(usr)) + return TRUE + if(emagged != 2) + emagged = 2 + hacked = TRUE + locked = TRUE + to_chat(usr, "[text_hack]") + message_admins("Safety lock of [ADMIN_LOOKUPFLW(src)] was disabled by [ADMIN_LOOKUPFLW(usr)] in [ADMIN_VERBOSEJMP(src)]") + log_game("Safety lock of [src] was disabled by [key_name(usr)] in [AREACOORD(src)]") + bot_reset() + else if(!hacked) + to_chat(usr, "[text_dehack_fail]") + else + emagged = FALSE + hacked = FALSE + to_chat(usr, "[text_dehack]") + log_game("Safety lock of [src] was re-enabled by [key_name(usr)] in [AREACOORD(src)]") + bot_reset() + if("eject_pai") + if(locked && !(issilicon(usr) || IsAdminGhost(usr))) + return + if(paicard) + to_chat(usr, "You eject [paicard] from [bot_name]") + ejectpai(usr) + //update_controls() + /mob/living/simple_animal/bot/proc/show_controls(mob/M) users |= M var/dat = "" diff --git a/code/modules/mob/living/simple_animal/bot/cleanbot.dm b/code/modules/mob/living/simple_animal/bot/cleanbot.dm index 4ebba0bbabbf7..9d3538e7f328f 100644 --- a/code/modules/mob/living/simple_animal/bot/cleanbot.dm +++ b/code/modules/mob/living/simple_animal/bot/cleanbot.dm @@ -434,39 +434,30 @@ /obj/machinery/bot_core/cleanbot req_one_access = list(ACCESS_JANITOR, ACCESS_ROBOTICS) - -/mob/living/simple_animal/bot/cleanbot/get_controls(mob/user) - var/dat - dat += hack(user) - dat += showpai(user) - // missing bot program name here - dat += "
Status: [on ? "On" : "Off"]" - dat += "
Behaviour controls are [locked ? "locked" : "unlocked"]" - dat += "
Maintenance panel panel is [open ? "opened" : "closed"]" - +/mob/living/simple_animal/bot/cleanbot/ui_data(mob/user) + var/list/data = ..() if(!locked || issilicon(user)|| IsAdminGhost(user)) - dat += "
Clean Blood: [blood ? "Yes" : "No"]" - dat += "
Clean Trash: [trash ? "Yes" : "No"]" - dat += "
Clean Graffiti: [drawn ? "Yes" : "No"]" - dat += "
Exterminate Pests: [pests ? "Yes" : "No"]" - dat += "

Patrol Station: [auto_patrol ? "Yes" : "No"]" - return dat - -/mob/living/simple_animal/bot/cleanbot/Topic(href, href_list) - if(..()) - return 1 - if(href_list["operation"]) - switch(href_list["operation"]) - if("blood") - blood = !blood - if("pests") - pests = !pests - if("trash") - trash = !trash - if("drawn") - drawn = !drawn - get_targets() - update_controls() + data["custom_controls"]["clean_blood"] = blood + data["custom_controls"]["clean_trash"] = trash + data["custom_controls"]["clean_graffiti"] = drawn + data["custom_controls"]["pest_control"] = pests + return data + +/mob/living/simple_animal/bot/cleanbot/ui_act(action, params) + if (..()) + return + if(!(bot_core.allowed(usr) || usr.has_unlimited_silicon_privilege) || locked) + return + switch(action) + if("clean_blood") + blood = !blood + if("clean_trash") + trash = !trash + if("clean_graffiti") + drawn = !drawn + if("pest_control") + pests = !pests + get_targets() /obj/machinery/bot_core/cleanbot/medbay req_one_access = list(ACCESS_JANITOR, ACCESS_ROBOTICS, ACCESS_MEDICAL) diff --git a/code/modules/mob/living/simple_animal/bot/ed209bot.dm b/code/modules/mob/living/simple_animal/bot/ed209bot.dm index 7ee271a9b8640..f23d9838f0fa4 100644 --- a/code/modules/mob/living/simple_animal/bot/ed209bot.dm +++ b/code/modules/mob/living/simple_animal/bot/ed209bot.dm @@ -98,27 +98,18 @@ text_dehack = "You restore [name]'s combat inhibitor." text_dehack_fail = "[name] ignores your attempts to restrict him!" -/mob/living/simple_animal/bot/ed209/get_controls(mob/user) - var/dat - dat += hack(user) - dat += showpai(user) - dat += "Security Unit v2.6 controls
" - dat += "
Status: [on ? "On" : "Off"]" - dat += "
Behaviour controls are [locked ? "locked" : "unlocked"]" - dat += "
Maintenance panel panel is [open ? "opened" : "closed"]" - - if(!locked || issilicon(user)|| IsAdminGhost(user)) +/mob/living/simple_animal/bot/ed209/ui_data(mob/user) + var/list/data = ..() + if (!locked || issilicon(user) || IsAdminGhost(user)) if(!lasercolor) - dat += "
" - dat += "
Arrest Unidentifiable Persons: [idcheck ? "Yes" : "No"]" - dat += "
Arrest for Unauthorized Weapons: [weaponscheck ? "Yes" : "No"]" - dat += "
Arrest for Warrant: [check_records ? "Yes" : "No"]" - dat += "
Operating Mode: [arrest_type ? "Detain" : "Arrest"]" - dat += "
Report Arrests [declare_arrests ? "Yes" : "No"]" - dat += "
Auto Patrol [auto_patrol ? "On" : "Off"]" - return dat - -/mob/living/simple_animal/bot/ed209/Topic(href, href_list) + data["custom_controls"]["check_id"] = idcheck + data["custom_controls"]["check_weapons"] = weaponscheck + data["custom_controls"]["check_warrants"] = check_records + data["custom_controls"]["handcuff_targets"] = !arrest_type + data["custom_controls"]["arrest_alert"] = declare_arrests + return data + +/mob/living/simple_animal/bot/ed209/ui_act(action, params) if(lasercolor && ishuman(usr)) var/mob/living/carbon/human/H = usr if((lasercolor == "b") && (istype(H.wear_suit, /obj/item/clothing/suit/redtag)))//Opposing team cannot operate it @@ -126,24 +117,19 @@ else if((lasercolor == "r") && (istype(H.wear_suit, /obj/item/clothing/suit/bluetag))) return if(..()) - return 1 + return - switch(href_list["operation"]) - if("idcheck") + switch(action) + if("check_id") idcheck = !idcheck - update_controls() - if("weaponscheck") + if("check_weapons") weaponscheck = !weaponscheck - update_controls() - if("ignorerec") + if("check_warrants") check_records = !check_records - update_controls() - if("switchmode") + if("handcuff_targets") arrest_type = !arrest_type - update_controls() - if("declarearrests") + if("arrest_alert") declare_arrests = !declare_arrests - update_controls() /mob/living/simple_animal/bot/ed209/proc/judgment_criteria() var/final = FALSE diff --git a/code/modules/mob/living/simple_animal/bot/firebot.dm b/code/modules/mob/living/simple_animal/bot/firebot.dm index 3dad5161e63a0..3a5498f831ec1 100644 --- a/code/modules/mob/living/simple_animal/bot/firebot.dm +++ b/code/modules/mob/living/simple_animal/bot/firebot.dm @@ -105,22 +105,13 @@ text_dehack = "You detect errors in [name] and reset his programming." text_dehack_fail = "[name] is not responding to reset commands!" -/mob/living/simple_animal/bot/firebot/get_controls(mob/user) - var/dat - dat += hack(user) - dat += showpai(user) - dat += "Mobile Fire Extinguisher v1.0

" - dat += "Status: [on ? "On" : "Off"]
" - dat += "Maintenance panel panel is [open ? "opened" : "closed"]
" - - dat += "Behaviour controls are [locked ? "locked" : "unlocked"]
" +/mob/living/simple_animal/bot/firebot/ui_data(mob/user) + var/list/data = ..() if(!locked || issilicon(user) || IsAdminGhost(user)) - dat += "Extinguish Fires: [extinguish_fires ? "Yes" : "No"]
" - dat += "Extinguish People: [extinguish_people ? "Yes" : "No"]
" - dat += "Patrol Station: [auto_patrol ? "Yes" : "No"]
" - dat += "Stationary Mode: [stationary_mode ? "Yes" : "No"]
" - - return dat + data["custom_controls"]["extinguish_fires"] = extinguish_fires + data["custom_controls"]["extinguish_people"] = extinguish_people + data["custom_controls"]["stationary_mode"] = stationary_mode + return data /mob/living/simple_animal/bot/firebot/on_emag(atom/target, mob/user) ..() @@ -142,19 +133,18 @@ internal_ext.max_water = INFINITY internal_ext.refill() -/mob/living/simple_animal/bot/firebot/Topic(href, href_list) +/mob/living/simple_animal/bot/firebot/ui_act(action, params) if(..()) - return TRUE - - switch(href_list["operation"]) + return + if(!(bot_core.allowed(usr) || usr.has_unlimited_silicon_privilege) || locked) + return + switch(action) if("extinguish_fires") extinguish_fires = !extinguish_fires if("extinguish_people") extinguish_people = !extinguish_people if("stationary_mode") stationary_mode = !stationary_mode - - update_controls() update_icon() /mob/living/simple_animal/bot/firebot/proc/is_burning(atom/target) diff --git a/code/modules/mob/living/simple_animal/bot/floorbot.dm b/code/modules/mob/living/simple_animal/bot/floorbot.dm index e4d3c3819dd22..938ab34e7f422 100644 --- a/code/modules/mob/living/simple_animal/bot/floorbot.dm +++ b/code/modules/mob/living/simple_animal/bot/floorbot.dm @@ -84,35 +84,23 @@ text_dehack = "You detect errors in [name] and reset his programming." text_dehack_fail = "[name] is not responding to reset commands!" -/mob/living/simple_animal/bot/floorbot/get_controls(mob/user) - var/dat - dat += hack(user) - dat += showpai(user) - dat += "Floor Repairer Controls v1.1

" - dat += "Status: [on ? "On" : "Off"]
" - dat += "Maintenance panel panel is [open ? "opened" : "closed"]
" - dat += "Special tiles: " - if(tilestack) - dat += "Loaded \[[tilestack.amount]/[maxtiles]\]
" - else - dat += "None Loaded
" - - dat += "Behaviour controls are [locked ? "locked" : "unlocked"]
" +/mob/living/simple_animal/bot/floorbot/ui_data(mob/user) + var/list/data = ..() if(!locked || issilicon(user) || IsAdminGhost(user)) - dat += "Add tiles to new hull plating: [autotile ? "Yes" : "No"]
" - dat += "Place floor tiles: [placetiles ? "Yes" : "No"]
" - dat += "Replace existing floor tiles with custom tiles: [replacetiles ? "Yes" : "No"]
" - dat += "Repair damaged tiles and platings: [fixfloors ? "Yes" : "No"]
" - dat += "Traction Magnets: [HAS_TRAIT_FROM(src, TRAIT_IMMOBILIZED, BUSY_FLOORBOT_TRAIT) ? "Engaged" : "Disengaged"]
" - dat += "Patrol Station: [auto_patrol ? "Yes" : "No"]
" - var/bmode + data["custom_controls"]["tile_hull"] = autotile + data["custom_controls"]["place_tiles"] = placetiles + data["custom_controls"]["place_custom"] = replacetiles + data["custom_controls"]["repair_damage"] = fixfloors + data["custom_controls"]["traction_magnets"] = HAS_TRAIT_FROM(src, TRAIT_IMMOBILIZED, BUSY_FLOORBOT_TRAIT) + data["custom_controls"]["line_mode"] = FALSE + data["custom_controls"]["tile_stack"] = list( + "tilestack" = tilestack, + "amount" = tilestack?.amount, + "max_amount" = tilestack?.max_amount + ) if(targetdirection) - bmode = dir2text(targetdirection) - else - bmode = "disabled" - dat += "Line Mode : [bmode]
" - - return dat + data["custom_controls"]["line_mode"] = dir2text(targetdirection) + return data /mob/living/simple_animal/bot/floorbot/attackby(obj/item/W , mob/user, params) if(istype(W, /obj/item/stack/tile/iron)) @@ -159,26 +147,26 @@ if(change_icon) update_icon() -/mob/living/simple_animal/bot/floorbot/Topic(href, href_list) - if(..()) - return TRUE +/mob/living/simple_animal/bot/floorbot/ui_act(action, params) + if (..() || (locked && !usr.has_unlimited_silicon_privilege)) + return - switch(href_list["operation"]) - if("replace") + switch(action) + if("place_custom") replacetiles = !replacetiles - if("place") + if("place_tiles") placetiles = !placetiles - if("fix") + if("repair_damage") fixfloors = !fixfloors - if("autotile") + if("tile_hull") autotile = !autotile - if("magnet") + if("traction_magnets") toggle_magnet(!HAS_TRAIT_FROM(src, TRAIT_IMMOBILIZED, BUSY_FLOORBOT_TRAIT), FALSE) - if("eject") + if("eject_tiles") if(tilestack) tilestack.forceMove(drop_location()) - if("linemode") + if("line_mode") var/setdir = input("Select construction direction:") as null|anything in list("north","east","south","west","disable") switch(setdir) if("north") @@ -191,7 +179,6 @@ targetdirection = 8 if("disable") targetdirection = null - update_controls() /mob/living/simple_animal/bot/floorbot/handle_automated_action() if(!..()) diff --git a/code/modules/mob/living/simple_animal/bot/honkbot.dm b/code/modules/mob/living/simple_animal/bot/honkbot.dm index 57112432d06f6..792a297a3007f 100644 --- a/code/modules/mob/living/simple_animal/bot/honkbot.dm +++ b/code/modules/mob/living/simple_animal/bot/honkbot.dm @@ -84,20 +84,6 @@ text_dehack = "You reboot [name] and restore the sound control system." text_dehack_fail = "[name] refuses to accept your authority!" -/mob/living/simple_animal/bot/honkbot/get_controls(mob/user) - var/dat - dat += hack(user) - dat += showpai(user) - dat += "Honkomatic Bike Horn Unit v1.0.7 controls
" - dat += "
Status: [on ? "On" : "Off"]" - dat += "
Behaviour controls are [locked ? "locked" : "unlocked"]" - dat += "
Maintenance panel panel is [open ? "opened" : "closed"]" - - if(!locked || issilicon(user) || IsAdminGhost(user)) - dat += "
" - dat += "
Auto Patrol: [auto_patrol ? "On" : "Off"]" - return dat - /mob/living/simple_animal/bot/honkbot/proc/judgment_criteria() var/final = NONE if(check_records) diff --git a/code/modules/mob/living/simple_animal/bot/medbot.dm b/code/modules/mob/living/simple_animal/bot/medbot.dm index e6dcf1a097850..30cba21274ccd 100644 --- a/code/modules/mob/living/simple_animal/bot/medbot.dm +++ b/code/modules/mob/living/simple_animal/bot/medbot.dm @@ -156,97 +156,70 @@ GLOBAL_VAR(medibot_unique_id_gen) /mob/living/simple_animal/bot/medbot/attack_paw(mob/user) return attack_hand(user) -/mob/living/simple_animal/bot/medbot/get_controls(mob/user) - var/dat - dat += hack(user) - dat += showpai(user) - dat += "Medical Unit Controls v1.1

" - dat += "Status: [on ? "On" : "Off"]
" - dat += "Maintenance panel panel is [open ? "opened" : "closed"]
" - dat += "
Behaviour controls are [locked ? "locked" : "unlocked"]
" +/mob/living/simple_animal/bot/medbot/ui_data(mob/user) + var/list/data = ..() if(!locked || issilicon(user) || IsAdminGhost(user)) - dat += "Beaker: " - if(reagent_glass) - dat += "Loaded \[[reagent_glass.name]: [reagent_glass.reagents.total_volume]/[reagent_glass.reagents.maximum_volume]\]
" - else - dat += "None Loaded
" - dat += "Healing Threshold: " - dat += "-- " - dat += "- " - dat += "[heal_threshold] " - dat += "+ " - dat += "++" - dat += "
" - dat += "Injection Level: " - dat += "- " - dat += "[injection_amount] " - dat += "+ " - dat += "
" - dat += "The speaker switch is [shut_up ? "off" : "on"]. Toggle
" - dat += "Critical Patient Alerts: [declare_crit ? "Yes" : "No"]
" - dat += "Patrol Station: [auto_patrol ? "Yes" : "No"]
" - dat += "Stationary Mode: [stationary_mode ? "Yes" : "No"]
" - dat += "Synthesise Epinephrine: [synth_epi ? "Yes" : "No"]
" - dat += "Search for Technological Advancements
" - - return dat - -/mob/living/simple_animal/bot/medbot/Topic(href, href_list) - if(..()) - return 1 - - if(href_list["adj_threshold"]) - var/adjust_num = text2num(href_list["adj_threshold"]) - heal_threshold += adjust_num - if(heal_threshold < 5) - heal_threshold = 5 - if(heal_threshold > 120) - heal_threshold = 120 - - else if(href_list["adj_inject"]) - var/adjust_num = text2num(href_list["adj_inject"]) - injection_amount += adjust_num - if(injection_amount < 5) - injection_amount = 5 - if(injection_amount > 30) - injection_amount = 30 - - - else if(href_list["eject"] && (!isnull(reagent_glass))) - reagent_glass.forceMove(drop_location()) - reagent_glass = null - update_icon() - - else if(href_list["togglevoice"]) - shut_up = !shut_up - - else if(href_list["critalerts"]) - declare_crit = !declare_crit - - else if(href_list["stationary"]) - stationary_mode = !stationary_mode - path = list() - update_icon() - - else if(href_list["synth_epi"]) - synth_epi = !synth_epi - - else if(href_list["hptech"]) - var/old_eff = efficiency - var/tech_boosters - for(var/i in linked_techweb.researched_designs) - var/datum/design/surgery/healing/D = SSresearch.techweb_design_by_id(i) - if(!istype(D)) - continue - tech_boosters++ - if(tech_boosters) - efficiency = 1+(0.075*tech_boosters) //increase efficiency by 7.5% for every surgery researched - if(old_eff < efficiency) - speak("Surgical research data found! Efficiency increased by [round(efficiency/old_eff*100)]%!") - window_name = "Automatic Medical Unit v[efficiency]" - update_controls() - return - + data["custom_controls"]["container"] = list( + "reagent_glass" = reagent_glass, + "total_volume" = reagent_glass?.reagents.total_volume, + "maximum_volume" = reagent_glass?.reagents.maximum_volume + ) + data["custom_controls"]["heal_threshold"] = heal_threshold + data["custom_controls"]["injection_amount"] = injection_amount + data["custom_controls"]["speaker"] = !shut_up + data["custom_controls"]["crit_alerts"] = declare_crit + data["custom_controls"]["stationary_mode"] = stationary_mode + data["custom_controls"]["synth_epi"] = synth_epi + data["custom_controls"]["sync_tech"] = efficiency + return data + +// Actions received from TGUI +/mob/living/simple_animal/bot/medbot/ui_act(action, params) + . = ..() + if(. || (locked && !usr.has_unlimited_silicon_privilege)) + return + switch(action) + if("eject") + if (!isnull(reagent_glass)) + reagent_glass.forceMove(drop_location()) + reagent_glass = null + update_icon() + if("heal_threshold") + var/adjust_num = round(text2num(params["threshold"])) + heal_threshold = adjust_num + if(heal_threshold < 5) + heal_threshold = 5 + if(heal_threshold > 120) + heal_threshold = 120 + if("injection_amount") + var/adjust_num = round(text2num(params["inject"])) + injection_amount = adjust_num + if(injection_amount < 5) + injection_amount = 5 + if(injection_amount > 30) + injection_amount = 30 + if("speaker") + shut_up = !shut_up + if("crit_alerts") + declare_crit = !declare_crit + if("stationary_mode") + stationary_mode = !stationary_mode + path = list() + if("synth_epi") + synth_epi = !synth_epi + if("sync_tech") + var/old_eff = efficiency + var/tech_boosters + for(var/i in linked_techweb.researched_designs) + var/datum/design/surgery/healing/D = SSresearch.techweb_design_by_id(i) + if(!istype(D)) + continue + tech_boosters++ + if(tech_boosters) + efficiency = 1+(0.075*tech_boosters) //increase efficiency by 7.5% for every surgery researched + if(old_eff < efficiency) + speak("Surgical research data found! Efficiency increased by [round(efficiency/old_eff*100)]%!") + window_name = "Automatic Medical Unit v[efficiency]" /mob/living/simple_animal/bot/medbot/attackby(obj/item/W as obj, mob/user as mob, params) if(istype(W, /obj/item/reagent_containers)) diff --git a/code/modules/mob/living/simple_animal/bot/secbot.dm b/code/modules/mob/living/simple_animal/bot/secbot.dm index 48e00fb1d31f2..df5c683c5a3e7 100644 --- a/code/modules/mob/living/simple_animal/bot/secbot.dm +++ b/code/modules/mob/living/simple_animal/bot/secbot.dm @@ -104,46 +104,32 @@ text_dehack = "You reboot [name] and restore the target identification." text_dehack_fail = "[name] refuses to accept your authority!" -/mob/living/simple_animal/bot/secbot/get_controls(mob/user) - var/dat - dat += hack(user) - dat += showpai(user) - dat += "Securitron v1.6 controls
" - dat += "
Status: [on ? "On" : "Off"]" - dat += "
Behaviour controls are [locked ? "locked" : "unlocked"]" - dat += "
Maintenance panel panel is [open ? "opened" : "closed"]" - +/mob/living/simple_animal/bot/secbot/ui_data(mob/user) + var/list/data = ..() if(!locked || issilicon(user) || IsAdminGhost(user)) - dat += "
" - dat += "
Arrest Unidentifiable Persons: [idcheck ? "Yes" : "No"]" - dat += "
Arrest for Unauthorized Weapons: [weaponscheck ? "Yes" : "No"]" - dat += "
Arrest for Warrant: [check_records ? "Yes" : "No"]" - dat += "
Operating Mode: [arrest_type ? "Detain" : "Arrest"]" - dat += "
Report Arrests [declare_arrests ? "Yes" : "No"]" - dat += "
Auto Patrol: [auto_patrol ? "On" : "Off"]" - return dat - -/mob/living/simple_animal/bot/secbot/Topic(href, href_list) + data["custom_controls"]["check_id"] = idcheck + data["custom_controls"]["check_weapons"] = weaponscheck + data["custom_controls"]["check_warrants"] = check_records + data["custom_controls"]["handcuff_targets"] = !arrest_type + data["custom_controls"]["arrest_alert"] = declare_arrests + return data + +/mob/living/simple_animal/bot/secbot/ui_act(action, params) if(..()) - return TRUE - if(!issilicon(usr) && !IsAdminGhost(usr) && !(bot_core.allowed(usr) || !locked)) - return TRUE - switch(href_list["operation"]) - if("idcheck") + return + if(!(bot_core.allowed(usr) || usr.has_unlimited_silicon_privilege) || locked) + return + switch(action) + if("check_id") idcheck = !idcheck - update_controls() - if("weaponscheck") + if("check_weapons") weaponscheck = !weaponscheck - update_controls() - if("ignorerec") + if("check_warrants") check_records = !check_records - update_controls() - if("switchmode") + if("handcuff_targets") arrest_type = !arrest_type - update_controls() - if("declarearrests") + if("arrest_alert") declare_arrests = !declare_arrests - update_controls() /mob/living/simple_animal/bot/secbot/proc/retaliate(mob/living/carbon/human/H) var/judgment_criteria = judgment_criteria() diff --git a/tgui/packages/tgui/interfaces/SimpleBot.tsx b/tgui/packages/tgui/interfaces/SimpleBot.tsx new file mode 100644 index 0000000000000..5022addced540 --- /dev/null +++ b/tgui/packages/tgui/interfaces/SimpleBot.tsx @@ -0,0 +1,415 @@ +import { multiline } from '../../common/string'; +import { useBackend } from '../backend'; +import { Button, Icon, LabeledControls, NoticeBox, Section, Slider, Stack, Tooltip, Flex } from '../components'; +import { Window } from '../layouts'; +import { getGasLabel } from '../constants'; + +type SimpleBotContext = { + can_hack: number; + locked: number; + emagged: number; + pai: Pai; + settings: Settings; + custom_controls: Controls; +}; + +type Pai = { + allow_pai: number; + card_inserted: number; +}; + +type Settings = { + power: number; + booting: boolean; + airplane_mode: number; + maintenance_lock: number; + patrol_station: number; +}; + +type Controls = { + [Control: string]: [Value: number]; +}; + +export const SimpleBot = (_, context) => { + const { data } = useBackend(context); + const { can_hack, locked } = data; + const access = !locked || can_hack; + + return ( + + + + +
}> + {!access ? Locked! : } +
+
+ {access && ( + +
+ +
+
+ )} +
+
+
+ ); +}; + +/** Creates a lock button at the top of the controls */ +const TabDisplay = (_, context) => { + const { act, data } = useBackend(context); + const { can_hack, locked, pai } = data; + const { allow_pai } = pai; + + return ( + <> + {!!can_hack && } + {!!allow_pai && } + + + ); +}; + +/** If user is a bad silicon, they can press this button to hack the bot */ +const HackButton = (_, context) => { + const { act, data } = useBackend(context); + const { can_hack, emagged } = data; + + return ( + + ); +}; + +/** Creates a button indicating PAI status and offers the eject action */ +const PaiButton = (_, context) => { + const { act, data } = useBackend(context); + const { card_inserted } = data.pai; + + if (!card_inserted) { + return ( + + ); + } else { + return ( + + ); + } +}; + +/** Displays the bot's standard settings: Power, patrol, etc. */ +const SettingsDisplay = (_, context) => { + const { act, data } = useBackend(context); + const { settings } = data; + const { airplane_mode, patrol_station, power, booting, maintenance_lock } = settings; + + const color = power ? 'good' : booting ? 'bad' : 'gray'; + + return ( + + + + act('power')} /> + + + + + act('airplane')} /> + + + + + act('patrol')} /> + + + + + act('maintenance')} /> + + + + ); +}; + +/** Iterates over custom controls. + * Calls the helper to identify which button to use. + */ +const ControlsDisplay = (_, context) => { + const { data } = useBackend(context); + const { custom_controls } = data; + + return ( + + {Object.entries(custom_controls).map((control) => { + if (control[0] === 'scrub_gasses') { + return ; + } + return ( + letter.toUpperCase())}> + + + ); + })} + + ); +}; + +/** Helper function which identifies which button to create. + * Might need some fine tuning if you are using more advanced controls. + */ +const ControlHelper = (props, context) => { + const { act } = useBackend(context); + const { control } = props; + if (control[0] === 'sync_tech') { + /** Control is for sync - this is medbot specific */ + return ; + } else if (control[0] === 'heal_threshold') { + /** Control is a threshold - this is medbot specific */ + return ; + } else if (control[0] === 'injection_amount') { + /** Control is a threshold - this is medbot specific */ + return ; + } else if (control[0] === 'container') { + return ; + } else if (control[0] === 'tile_stack') { + return ; + } else if (control[0] === 'line_mode') { + return ; + } else if (control[0] === 'breach_pressure') { + return ; + } else if (control[0] === 'ideal_temperature') { + return ; + } else if (control[0] === 'scrub_gasses') { + return ; + } else { + /** Control is a boolean of some type */ + return ( + act(control[0])} + /> + ); + } +}; + +/** Small button to sync medbots with research. */ +const MedbotSync = (props, context) => { + const { act } = useBackend(context); + const { control } = props; + const efficiency = Math.round(control[1] * 100); + + return ( + + act('sync_tech')} /> + + ); +}; + +/** Slider button for medbot healing thresholds */ +const MedbotThreshold = (props, context) => { + const { act } = useBackend(context); + const { control } = props; + + return ( + + act(control[0], { threshold: value })} + /> + + ); +}; + +/** Slider button for medbot healing thresholds */ +const MedbotInjectionThreshold = (props, context) => { + const { act } = useBackend(context); + const { control } = props; + + return ( + + act(control[0], { inject: value })} + /> + + ); +}; + +const MedbotBeaker = (props, context) => { + const { act } = useBackend(context); + const { control } = props; + const [reagent_glass, total_volume, maximum_volume] = [ + control[1]['reagent_glass'], + control[1]['total_volume'], + control[1]['maximum_volume'], + ]; + + return ( + + ); +}; + +/** Tile stacks for floorbots - shows number and eject button */ +const FloorbotTiles = (props, context) => { + const { act } = useBackend(context); + const { control } = props; + const [tilestack, amount, max_amount] = [control[1]['tilestack'], control[1]['amount'], control[1]['max_amount']]; + + return ( + + ); +}; + +/** Direction indicator for floorbot when line mode is chosen. */ +const FloorbotLine = (props, context) => { + const { act } = useBackend(context); + const { control } = props; + + return ( + + act('line_mode')} + size={!control[1] ? 2 : 1.5}> + {' '} + {control[1] + ? control[1] + .toString() + .charAt(0) + .toUpperCase() + : ''} + + + ); +}; + +/** Slider button for atmosbot breach pressure detection thresholds */ +const AtmosbotBreachPressure = (props, context) => { + const { act } = useBackend(context); + const { control } = props; + + return ( + + act(control[0], { pressure: value })} + /> + + ); +}; + +/** Slider button for atmosbot target temperature */ +const AtmosbotTargetTemperature = (props, context) => { + const { act } = useBackend(context); + const { control } = props; + const [T0C, T20C] = [273.15, 293.15]; + + return ( + + act(control[0], { temperature: value })} + /> + + ); +}; + +const AtmosbotScrubbedGasses = (props, context) => { + const { act } = useBackend(context); + const { control } = props; + const gasses = Object.entries(control[1]); + + return ( + +
+ {gasses.map((gas) => { + const gas_id = gas[0]; + const enabled = gas[1]; + return ( +
+
+ ); +};