From d2498dac0094789ad74928149e348b229d4f8918 Mon Sep 17 00:00:00 2001
From: Gristlebee <56049844+Gristlebee@users.noreply.github.com>
Date: Tue, 28 May 2024 15:12:01 -0700
Subject: [PATCH] Blastdoor and Atmos Holofield ID multitool syncing (#3004)
## About The Pull Request
Multitools can be used on a button with it's panel open to add a blast
door or holofield controller to it's buffer.
The ID can be copied onto a blast door the same way as changing it
normally with a multitool. For holofields, you need to have the access
mode on unlocked and it's panel closed.
Adds holofield controllers to the autolathe.
Changes all the span classes to span macros
## Why It's Good For The Game
When you have a roundstart blast door break or holofield break for
whatever reason, it's almost impossible to replace and properly resync
without ripping out the rest of the blastdoors or the other holofield.
This should make reconstruction more convienent.
Also being able to make and use your own holofield controller adds a
more intuitive way to rig up player made holofields, as currently you
have to use signallers on the activation wire.
## Changelog
:cl:
add: Autolathe can print holofield controllers.
add: You can sync blastdoors and holofields to a controller in a button
with a multitool
code: span macros for blast doors, buttons and holofields
/:cl:
---------
Signed-off-by: Gristlebee <56049844+Gristlebee@users.noreply.github.com>
Co-authored-by: FalloutFalcon <86381784+FalloutFalcon@users.noreply.github.com>
---
code/game/machinery/buttons.dm | 26 +++--
code/game/machinery/doors/poddoor.dm | 34 +++---
code/game/machinery/shieldgen.dm | 109 ++++++++++--------
.../research/designs/autolathe_designs.dm | 8 ++
4 files changed, 106 insertions(+), 71 deletions(-)
diff --git a/code/game/machinery/buttons.dm b/code/game/machinery/buttons.dm
index b10dba436e0d..f6c004ddca71 100644
--- a/code/game/machinery/buttons.dm
+++ b/code/game/machinery/buttons.dm
@@ -68,34 +68,40 @@
default_deconstruction_screwdriver(user, "button-open", "[skin]",W)
update_appearance()
else
- to_chat(user, "Maintenance Access Denied.")
+ to_chat(user, span_alert("Maintenance Access Denied."))
flick("[skin]-denied", src)
return
if(panel_open)
if(!device && istype(W, /obj/item/assembly))
if(!user.transferItemToLoc(W, src))
- to_chat(user, "\The [W] is stuck to you!")
+ to_chat(user, span_warning("\The [W] is stuck to you!"))
return
device = W
- to_chat(user, "You add [W] to the button.")
+ to_chat(user, span_notice("You add [W] to the button."))
if(!board && istype(W, /obj/item/electronics/airlock))
if(!user.transferItemToLoc(W, src))
- to_chat(user, "\The [W] is stuck to you!")
+ to_chat(user, span_warning("\The [W] is stuck to you!"))
return
board = W
if(board.one_access)
req_one_access = board.accesses
else
req_access = board.accesses
- to_chat(user, "You add [W] to the button.")
+ to_chat(user, span_notice("You add [W] to the button."))
+
+ if(device && W.tool_behaviour == TOOL_MULTITOOL)
+ var/obj/item/multitool/multi = W
+ if(istype(device, /obj/item/assembly/control))
+ multi.buffer = device
+ to_chat(user, span_notice("You copy the [device] to your multitool's buffer."))
if(!device && !board && W.tool_behaviour == TOOL_WRENCH)
- to_chat(user, "You start unsecuring the button frame...")
+ to_chat(user, span_notice("You start unsecuring the button frame..."))
W.play_tool_sound(src)
if(W.use_tool(src, user, 40))
- to_chat(user, "You unsecure the button frame.")
+ to_chat(user, span_notice("You unsecure the button frame."))
transfer_fingerprints_to(new /obj/item/wallframe/button(get_turf(src)))
playsound(loc, 'sound/items/deconstruct.ogg', 50, TRUE)
qdel(src)
@@ -153,14 +159,14 @@
req_one_access = list()
board = null
update_appearance()
- to_chat(user, "You remove electronics from the button frame.")
+ to_chat(user, span_notice("You remove electronics from the button frame."))
else
if(skin == "doorctrl")
skin = "launcher"
else
skin = "doorctrl"
- to_chat(user, "You change the button frame's front panel.")
+ to_chat(user, span_notice("You change the button frame's front panel."))
return
if((machine_stat & (NOPOWER|BROKEN)))
@@ -170,7 +176,7 @@
return
if(!allowed(user))
- to_chat(user, "Access Denied.")
+ to_chat(user, span_alert("Access Denied."))
flick("[skin]-denied", src)
return
diff --git a/code/game/machinery/doors/poddoor.dm b/code/game/machinery/doors/poddoor.dm
index 4e846c26f14a..ce705c71e434 100644
--- a/code/game/machinery/doors/poddoor.dm
+++ b/code/game/machinery/doors/poddoor.dm
@@ -23,26 +23,32 @@
/obj/machinery/door/poddoor/attackby(obj/item/W, mob/user, params)
. = ..()
if((resistance_flags & INDESTRUCTIBLE) && W.tool_behaviour == TOOL_SCREWDRIVER) // This makes it so ERT members cannot cheese by opening their blast doors.
- to_chat(user, "You can't find the panel!")
+ to_chat(user, span_warning("You can't find the panel!"))
return
if(W.tool_behaviour == TOOL_SCREWDRIVER)
if(density)
- to_chat(user, "You need to open [src] to access the maintenance panel!")
+ to_chat(user, span_warning("You need to open [src] to access the maintenance panel"))
return
else if(default_deconstruction_screwdriver(user, icon_state, icon_state, W))
- to_chat(user, "You [panel_open ? "open" : "close"] the maintenance hatch of [src].")
+ to_chat(user, span_notice("You [panel_open ? "open" : "close"] the maintenance hatch of [src]."))
return TRUE
if(panel_open && !density)
if(W.tool_behaviour == TOOL_MULTITOOL)
- var/change_id = input("Set [src]'s ID. It must be a number between 1 and 100.", "ID", id) as num|null
- if(change_id)
- id = clamp(round(change_id, 1), 1, 100)
- to_chat(user, "You change the ID to [id].")
+ var/obj/item/multitool/multi = W
+ if (istype(multi.buffer,/obj/item/assembly/control))
+ var/obj/item/assembly/control/controller = multi.buffer
+ id = controller.id
+ to_chat(user, span_notice("You copy the ID in your multitool's buffer into the [src]."))
+ else
+ var/change_id = input("Set [src]'s ID. It must be a number between 1 and 100.", "ID", id) as num|null
+ if(change_id)
+ id = clamp(round(change_id, 1), 1, 100)
+ to_chat(user, span_notice("You change the ID to [id]."))
if(W.tool_behaviour == TOOL_CROWBAR)
- to_chat(user, "You start to remove the airlock electronics.")
+ to_chat(user, span_notice("You start to remove the airlock electronics."))
if(!(machine_stat & NOPOWER))
do_sparks(5, TRUE, src)
electrocute_mob(user, get_area(src), src, 1, TRUE) //fuck this fella
@@ -52,9 +58,9 @@
/obj/machinery/door/poddoor/examine(mob/user)
. = ..()
- . += "The maintenance panel is [panel_open ? "opened" : "closed"]."
+ . += span_notice("The maintenance panel is [panel_open ? "opened" : "closed"].")
if(panel_open)
- . += "The airlock electronics are exposed and could be pried out."
+ . += span_notice("The airlock electronics are exposed and could be pried out.")
/obj/machinery/door/poddoor/deconstruct(disassembled = TRUE, mob/user)
if(!(flags_1 & NODECONSTRUCT_1))
@@ -142,9 +148,9 @@
/obj/machinery/door/poddoor/attack_alien(mob/living/carbon/alien/humanoid/user)
if(density & !(resistance_flags & INDESTRUCTIBLE))
add_fingerprint(user)
- user.visible_message("[user] begins prying open [src].",\
- "You begin digging your claws into [src] with all your might!",\
- "You hear groaning metal...")
+ user.visible_message(span_warning("[user] begins prying open [src]."),\
+ span_noticealien("You begin digging your claws into [src] with all your might"),\
+ span_warning("You hear groaning metal..."))
playsound(src, 'sound/machines/creaking.ogg', 100, TRUE)
var/time_to_open = 5 SECONDS
@@ -153,7 +159,7 @@
if(do_after(user, time_to_open, TRUE, src))
if(density && !open(TRUE)) //The airlock is still closed, but something prevented it opening. (Another player noticed and bolted/welded the airlock in time!)
- to_chat(user, "Despite your efforts, [src] managed to resist your attempts to open it!")
+ to_chat(user, span_warning("Despite your efforts, [src] managed to resist your attempts to open it!"))
else
return ..()
diff --git a/code/game/machinery/shieldgen.dm b/code/game/machinery/shieldgen.dm
index 9f2f56e2e1ce..df865aee82e5 100644
--- a/code/game/machinery/shieldgen.dm
+++ b/code/game/machinery/shieldgen.dm
@@ -122,25 +122,23 @@
if(.)
return
if(locked && !issilicon(user))
- to_chat(user, "The machine is locked, you are unable to use it!")
+ to_chat(user, span_notice("The machine is locked, you are unable to use it!"))
return
if(panel_open)
- to_chat(user, "The panel must be closed before operating this machine!")
+ to_chat(user, span_warning("The panel must be closed before operating this machine!"))
return
if (active)
- user.visible_message("[user] deactivated \the [src].", \
- "You deactivate \the [src].", \
- "You hear heavy droning fade out.")
+ user.visible_message(span_notice("[user] deactivated \the [src]."), span_notice("You deactivate \the [src]."), span_hear("You hear heavy droning fade out"))
shields_down()
else
if(anchored)
- user.visible_message("[user] activated \the [src].", \
- "You activate \the [src].", \
- "You hear heavy droning.")
+ user.visible_message(span_notice("[user] activated \the [src]."), \
+ span_notice("You activate \the [src]."), \
+ span_hear("You hear heavy droning."))
shields_up()
else
- to_chat(user, "The device must first be secured to the floor!")
+ to_chat(user, span_warning("The device must first be secured to the floor!"))
return
/obj/machinery/shieldgen/attackby(obj/item/W, mob/user, params)
@@ -148,60 +146,60 @@
W.play_tool_sound(src, 100)
panel_open = !panel_open
if(panel_open)
- to_chat(user, "You open the panel and expose the wiring.")
+ to_chat(user, span_notice("You open the panel and expose the wiring."))
else
- to_chat(user, "You close the panel.")
+ to_chat(user, span_notice("You close the panel."))
else if(istype(W, /obj/item/stack/cable_coil) && (machine_stat & BROKEN) && panel_open)
var/obj/item/stack/cable_coil/coil = W
if (coil.get_amount() < 1)
- to_chat(user, "You need one length of cable to repair [src]!")
+ to_chat(user, span_warning("You need one length of cable to repair [src]!"))
return
- to_chat(user, "You begin to replace the wires...")
+ to_chat(user, span_notice("You begin to replace the wires..."))
if(do_after(user, 30, target = src))
if(coil.get_amount() < 1)
return
coil.use(1)
obj_integrity = max_integrity
set_machine_stat(machine_stat & ~BROKEN)
- to_chat(user, "You repair \the [src].")
+ to_chat(user, span_notice("You repair \the [src]."))
update_appearance()
else if(W.tool_behaviour == TOOL_WRENCH)
if(locked)
- to_chat(user, "The bolts are covered! Unlocking this would retract the covers.")
+ to_chat(user, span_warning("The bolts are covered! Unlocking this would retract the covers."))
return
if(!anchored && !isinspace())
W.play_tool_sound(src, 100)
- to_chat(user, "You secure \the [src] to the floor!")
+ to_chat(user, span_notice("You secure \the [src] to the floor!"))
set_anchored(TRUE)
else if(anchored)
W.play_tool_sound(src, 100)
- to_chat(user, "You unsecure \the [src] from the floor!")
+ to_chat(user, span_notice("You unsecure \the [src] from the floor!"))
if(active)
- to_chat(user, "\The [src] shuts off!")
+ to_chat(user, span_notice("\The [src] shuts off!"))
shields_down()
set_anchored(FALSE)
else if(W.GetID())
if(allowed(user) && !(obj_flags & EMAGGED))
locked = !locked
- to_chat(user, "You [locked ? "lock" : "unlock"] the controls.")
+ to_chat(user, span_notice("You [locked ? "lock" : "unlock"] the controls."))
else if(obj_flags & EMAGGED)
- to_chat(user, "Error, access controller damaged!")
+ to_chat(user, span_danger("Error, access controller damaged!"))
else
- to_chat(user, "Access denied.")
+ to_chat(user, span_danger("Access denied."))
else
return ..()
/obj/machinery/shieldgen/emag_act(mob/user)
if(obj_flags & EMAGGED)
- to_chat(user, "The access controller is damaged!")
+ to_chat(user, span_warning("The access controller is damaged!"))
return
obj_flags |= EMAGGED
locked = FALSE
playsound(src, "sparks", 100, TRUE, SHORT_RANGE_SOUND_EXTRARANGE)
- to_chat(user, "You short out the access controller.")
+ to_chat(user, span_warning("You short out the access controller."))
/obj/machinery/shieldgen/update_icon_state()
icon_state = "shield[active ? "on" : "off"][(machine_stat & BROKEN) ? "br" : null]"
@@ -275,9 +273,7 @@
if(!active_power_usage || surplus() >= active_power_usage)
add_load(active_power_usage)
else
- visible_message("The [src.name] shuts down due to lack of power!", \
- "If this message is ever seen, something is wrong.",
- "You hear heavy droning fade out.")
+ visible_message(span_danger("The [src.name] shuts down due to lack of power!"), "If this message is ever seen, something is wrong.",span_hear("You hear heavy droning fade out."))
active = FALSE
log_game("[src] deactivated due to lack of power at [AREACOORD(src)]")
for(var/direction in GLOB.cardinals)
@@ -348,7 +344,7 @@
/obj/machinery/power/shieldwallgen/can_be_unfasten_wrench(mob/user, silent)
if(active)
if(!silent)
- to_chat(user, "Turn off the shield generator first!")
+ to_chat(user, span_warning("Turn off the shield generator first!"))
return FAILED_UNFASTEN
return ..()
@@ -388,11 +384,11 @@
if(item.GetID())
if(allowed(user) && !(obj_flags & EMAGGED))
locked = !locked
- to_chat(user, "You [src.locked ? "lock" : "unlock"] the controls.")
+ to_chat(user, span_notice("You [src.locked ? "lock" : "unlock"] the controls."))
else if(obj_flags & EMAGGED)
- to_chat(user, "Error, access controller damaged!")
+ to_chat(user, span_danger("Error, access controller damaged!"))
else
- to_chat(user, "Access denied.")
+ to_chat(user, span_danger("Access denied."))
else
add_fingerprint(user)
@@ -406,25 +402,23 @@
shock(user,50)
return
if(!anchored)
- to_chat(user, "\The [src] needs to be firmly secured to the floor first!")
+ to_chat(user, span_warning("\The [src] needs to be firmly secured to the floor first!"))
return
if(locked && !issilicon(user))
- to_chat(user, "The controls are locked!")
+ to_chat(user, span_warning("The controls are locked!"))
return
if(!powernet)
- to_chat(user, "\The [src] needs to be powered by a wire!")
+ to_chat(user, span_warning("\The [src] needs to be powered by a wire!"))
return
if(active)
- user.visible_message("[user] turned \the [src] off.", \
- "You turn off \the [src].", \
- "You hear heavy droning fade out.")
+ user.visible_message(span_notice("[user] turned \the [src] off."), \
+ span_notice("You turn off \the [src]."), \
+ span_hear("You hear heavy droning fade out."))
active = FALSE
log_game("[src] was deactivated by [key_name(user)] at [AREACOORD(src)]")
else
- user.visible_message("[user] turned \the [src] on.", \
- "You turn on \the [src].", \
- "You hear heavy droning.")
+ user.visible_message(span_notice("[user] turned \the [src] on."), span_notice("ou turn on \the [src]."), span_hear("ou hear heavy droning."))
active = ACTIVE_SETUPFIELDS
log_game("[src] was activated by [key_name(user)] at [AREACOORD(src)]")
add_fingerprint(user)
@@ -435,28 +429,28 @@
if(!powernet)
return
if(active)
- visible_message("The [src.name] hums as it powers down.", \
+ visible_message(span_notice("The [src.name] hums as it powers down."), \
"If this message is ever seen, something is wrong.", \
- "You hear heavy droning fade out.")
+ span_notice("You hear heavy droning fade out."))
playsound(src, 'sound/machines/synth_no.ogg', 50, TRUE, frequency = 6120)
active = FALSE
log_game("[src] was deactivated by wire pulse at [AREACOORD(src)]")
else
- visible_message("The [src.name] beeps as it powers up.", \
+ visible_message(span_notice("The [src.name] beeps as it powers up."), \
"If this message is ever seen, something is wrong.", \
- "You hear heavy droning.")
+ span_notice("You hear heavy droning."))
playsound(src, 'sound/machines/synth_yes.ogg', 50, TRUE, frequency = 6120)
active = ACTIVE_SETUPFIELDS
log_game("[src] was activated by wire pulse at [AREACOORD(src)]")
/obj/machinery/power/shieldwallgen/emag_act(mob/user)
if(obj_flags & EMAGGED)
- to_chat(user, "The access controller is damaged!")
+ to_chat(user, span_warning("The access controller is damaged!"))
return
obj_flags |= EMAGGED
locked = FALSE
playsound(src, "sparks", 100, TRUE, SHORT_RANGE_SOUND_EXTRARANGE)
- to_chat(user, "You short out the access controller.")
+ to_chat(user, span_warning("You short out the access controller."))
/obj/machinery/power/shieldwallgen/proc/shock(mob/user, prb)
if(machine_stat & (BROKEN|NOPOWER)) // unpowered, no shock
@@ -511,10 +505,31 @@
/obj/machinery/power/shieldwallgen/atmos/proc/can_be_rotated(mob/user, rotation_type)
if (anchored)
- to_chat(user, "It is fastened to the floor!")
+ to_chat(user, span_warning("It is fastened to the floor!"))
return FALSE
return TRUE
+/obj/machinery/power/shieldwallgen/atmos/attacked_by(obj/item/I, mob/living/user)
+ if(I.tool_behaviour == TOOL_MULTITOOL)
+ var/obj/item/multitool/multi = I
+ if(!panel_open && !locked)
+ if(istype(multi.buffer,/obj/item/assembly/control/shieldwallgen))
+ var/obj/item/assembly/control/shieldwallgen/controller = multi.buffer
+ to_chat(user, span_notice("You copy the ID in your multitool's buffer to the [src]."))
+ id = controller.id
+ return TRUE
+
+ else
+ to_chat(user, span_warning("The controls are locked!"))
+ return
+
+ return ..()
+
+/obj/machinery/power/shieldwallgen/atmos/multitool_act(mob/living/user, obj/item/I)
+ . = ..()
+
+
+
/// Same as in the normal shieldwallgen, but with the shieldwalls replaced with atmos shieldwalls
/obj/machinery/power/shieldwallgen/atmos/setup_field(direction)
if(!direction)
@@ -586,7 +601,7 @@
setDir(get_dir(gen_primary, gen_secondary))
if(hardshield == TRUE)
for(var/mob/living/victim in get_turf(src))
- visible_message("\The [src] is suddenly occupying the same space as \the [victim]!")
+ visible_message(span_danger("\The [src] is suddenly occupying the same space as \the [victim]!"))
victim.gib()
/obj/machinery/shieldwall/Destroy()
diff --git a/code/modules/research/designs/autolathe_designs.dm b/code/modules/research/designs/autolathe_designs.dm
index 8a0c572015db..e39d48e5cc77 100644
--- a/code/modules/research/designs/autolathe_designs.dm
+++ b/code/modules/research/designs/autolathe_designs.dm
@@ -1191,6 +1191,14 @@
build_path = /obj/item/assembly/control
category = list("initial","Misc")
+/datum/design/holofield_control
+ name = "Holofield Controller"
+ id = "holofield"
+ build_type = AUTOLATHE
+ materials = list(/datum/material/iron = 100, /datum/material/glass = 50)
+ build_path = /obj/item/assembly/control/shieldwallgen
+ category = list("initial","Misc")
+
/datum/design/trashbag
name="Trash Bag"
id="trashbag"