From f49861e6469621aac31f71cde2b6fd13b0c721a2 Mon Sep 17 00:00:00 2001
From: SkyratBot <59378654+SkyratBot@users.noreply.github.com>
Date: Fri, 8 Oct 2021 16:33:12 +0200
Subject: [PATCH] [MIRROR] Allows emagged and syndicate borgs to self-detonate
[MDB IGNORE] (#8654)
* Allows emagged and syndicate borgs to self-detonate (#61915)
Once upon a time, when borgs could access machines from any distance once the window was open, borgs could self-detonate as a combat strategy. At some point, machine access for borgs was confined to being nearby the device, which removed self-detonation (except when near the console) as a side effect. This PR re-adds the ability for emagged and syndicate borgs by placing a confirm-type button into their RoboTact app (Actions section, under the Status tab).
Stunned or locked borgs cannot self-destruct.
Additionally, logging for borg detonations has been moved out of the robot console and into the borg self_destruct() proc, to avoid duplicate code, and emagged borgs now have their tablet theme and icon changed to syndicate versions.
* Allows emagged and syndicate borgs to self-detonate
Co-authored-by: zxaber <37497534+zxaber@users.noreply.github.com>
---
code/game/machinery/computer/robot.dm | 9 +-----
.../modules/mob/living/silicon/robot/robot.dm | 29 ++++++++++++++++++-
.../mob/living/silicon/robot/robot_model.dm | 1 +
.../file_system/programs/robotact.dm | 9 +++++-
tgui/packages/tgui/interfaces/NtosRobotact.js | 10 +++++++
5 files changed, 48 insertions(+), 10 deletions(-)
diff --git a/code/game/machinery/computer/robot.dm b/code/game/machinery/computer/robot.dm
index 3fc1ac5f0e5..09334f9b17d 100644
--- a/code/game/machinery/computer/robot.dm
+++ b/code/game/machinery/computer/robot.dm
@@ -86,14 +86,7 @@
if(allowed(usr))
var/mob/living/silicon/robot/R = locate(params["ref"]) in GLOB.silicon_mobs
if(can_control(usr, R) && !..())
- var/turf/T = get_turf(R)
- message_admins(span_notice("[ADMIN_LOOKUPFLW(usr)] detonated [key_name_admin(R, R.client)] at [ADMIN_VERBOSEJMP(T)]!"))
- log_game("[key_name(usr)] detonated [key_name(R)]!")
- log_combat(usr, R, "detonated cyborg")
-
- if(R.connected_ai)
- to_chat(R.connected_ai, "
[span_alert("ALERT - Cyborg detonation detected: [R.name]")]
")
- R.self_destruct()
+ R.self_destruct(usr)
else
to_chat(usr, span_danger("Access Denied."))
if("stopbot")
diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm
index 61db3a70b61..43a15b5ce19 100644
--- a/code/modules/mob/living/silicon/robot/robot.dm
+++ b/code/modules/mob/living/silicon/robot/robot.dm
@@ -97,6 +97,25 @@
modularInterface = new /obj/item/modular_computer/tablet/integrated/syndicate(src)
return ..()
+/**
+ * Sets the tablet theme and icon
+ *
+ * These variables are based on if the borg is a syndicate type or is emagged. This gets used in model change code
+ * and also borg emag code.
+ */
+/mob/living/silicon/robot/proc/set_modularInterface_theme()
+ if(istype(model, /obj/item/robot_model/syndicate) || emagged)
+ modularInterface.device_theme = "syndicate"
+ modularInterface.icon_state = "tablet-silicon-syndicate"
+ modularInterface.icon_state_powered = "tablet-silicon-syndicate"
+ modularInterface.icon_state_unpowered = "tablet-silicon-syndicate"
+ else
+ modularInterface.device_theme = "ntos"
+ modularInterface.icon_state = "tablet-silicon"
+ modularInterface.icon_state_powered = "tablet-silicon"
+ modularInterface.icon_state_unpowered = "tablet-silicon"
+ modularInterface.update_icon()
+
//If there's an MMI in the robot, have it ejected when the mob goes away. --NEO
/mob/living/silicon/robot/Destroy()
var/atom/T = drop_location()//To hopefully prevent run time errors.
@@ -335,7 +354,14 @@
add_overlay(head_overlay)
update_fire()
-/mob/living/silicon/robot/proc/self_destruct()
+/mob/living/silicon/robot/proc/self_destruct(mob/usr)
+ var/turf/groundzero = get_turf(src)
+ message_admins(span_notice("[ADMIN_LOOKUPFLW(usr)] detonated [key_name_admin(src, client)] at [ADMIN_VERBOSEJMP(groundzero)]!"))
+ log_game("[key_name(usr)] detonated [key_name(src)]!")
+ log_combat(usr, src, "detonated cyborg")
+ if(connected_ai)
+ to_chat(connected_ai, "
[span_alert("ALERT - Cyborg detonation detected: [name]")]
")
+
if(emagged)
QDEL_NULL(mmi)
explosion(src, devastation_range = 1, heavy_impact_range = 2, light_impact_range = 4, flame_range = 2)
@@ -401,6 +427,7 @@
throw_alert("hacked", /atom/movable/screen/alert/hacked)
else
clear_alert("hacked")
+ set_modularInterface_theme()
/// Special handling for getting hit with a light eater
/mob/living/silicon/robot/proc/on_light_eater(mob/living/silicon/robot/source, datum/light_eater)
diff --git a/code/modules/mob/living/silicon/robot/robot_model.dm b/code/modules/mob/living/silicon/robot/robot_model.dm
index 5223837dc65..f68f1b7c99c 100644
--- a/code/modules/mob/living/silicon/robot/robot_model.dm
+++ b/code/modules/mob/living/silicon/robot/robot_model.dm
@@ -185,6 +185,7 @@
cyborg.update_module_innate()
new_model.rebuild_modules()
cyborg.radio.recalculateChannels()
+ cyborg.set_modularInterface_theme()
INVOKE_ASYNC(new_model, .proc/do_transform_animation)
qdel(src)
diff --git a/code/modules/modular_computers/file_system/programs/robotact.dm b/code/modules/modular_computers/file_system/programs/robotact.dm
index b424f53af33..0a83bc8fdbc 100644
--- a/code/modules/modular_computers/file_system/programs/robotact.dm
+++ b/code/modules/modular_computers/file_system/programs/robotact.dm
@@ -58,8 +58,9 @@
data["printerTonerMax"] = borgo.tonermax //It's a variable, might as well use it
data["thrustersInstalled"] = borgo.ionpulse //If we have a thruster uprade
data["thrustersStatus"] = "[borgo.ionpulse_on?"ACTIVE":"DISABLED"]" //Feedback for thruster status
+ data["selfDestructAble"] = (borgo.emagged || istype(borgo, /mob/living/silicon/robot/model/syndicate/))
- //DEBUG -- Cover, TRUE for locked
+ //Cover, TRUE for locked
data["cover"] = "[borgo.locked? "LOCKED":"UNLOCKED"]"
//Ability to move. FAULT if lockdown wire is cut, DISABLED if borg locked, ENABLED otherwise
data["locomotion"] = "[borgo.wires.is_cut(WIRE_LOCKDOWN)?"FAULT":"[borgo.lockcharge?"DISABLED":"ENABLED"]"]"
@@ -135,6 +136,12 @@
borgo.lamp_intensity = params["ref"]
borgo.toggle_headlamp(FALSE, TRUE)
+ if("selfDestruct")
+ if(borgo.stat || borgo.lockcharge) //No detonation while stunned or locked down
+ return
+ if(borgo.emagged || istype(borgo, /mob/living/silicon/robot/model/syndicate/)) //This option shouldn't even be showing otherwise
+ borgo.self_destruct(borgo)
+
/**
* Forces a full update of the UI, if currently open.
*
diff --git a/tgui/packages/tgui/interfaces/NtosRobotact.js b/tgui/packages/tgui/interfaces/NtosRobotact.js
index c1699400650..bc20ace8a04 100644
--- a/tgui/packages/tgui/interfaces/NtosRobotact.js
+++ b/tgui/packages/tgui/interfaces/NtosRobotact.js
@@ -38,6 +38,7 @@ export const NtosRobotactContent = (props, context) => {
printerTonerMax,
thrustersInstalled,
thrustersStatus,
+ selfDestructAble,
} = data;
const borgName = data.name || [];
const borgType = data.designation || [];
@@ -209,6 +210,15 @@ export const NtosRobotactContent = (props, context) => {
onClick={() => act('toggleThrusters')} />
)}
+ {!!selfDestructAble && (
+
+ act('selfDestruct')} />
+
+ )}
)}