Files
Aurora.3/code/game/objects/structures/machinery/controlhub.dm
T
Batrachophreno 4ecb0bc21c Repath obj/machinery to obj/structure/machinery [MDB Ignore] (#22500)
Repaths obj/machinery to obj/structure/machinery. **Note for
reviewers:** the only meaningful changed code exists within
**code/game/objects/structures.dm** and
**code/game/objects/structures/_machinery.dm**, largely concerning
damage procs. With the exception of moving airlock defines to their own
file, ALL OTHER CHANGES ARE STRICTLY PATH CHANGES.

Objects, _categorically_, are largely divided between those you can hold
in your hand/inventory and those you can't. Machinery objects are
already subtypes of Structures behaviorally, this PR just makes their
pathing reflect that, and allows for future work (tool actions, more
health/destruction functionality) to be developed without unnecessary
code duplication.

I have tested this PR by loading up the Horizon and dismantling various
machines and structures with tools, shooting guns of various types
throughout the ship, and detonating a bunch of explosions throughout the
ship.
2026-05-26 19:35:48 +00:00

260 lines
8.2 KiB
Plaintext

ABSTRACT_TYPE(/obj/structure/machinery/controlhub)
/obj/structure/machinery/controlhub
name = "control hub"
desc = "A control interface that can manage multiple systems from a single point."
icon = 'icons/obj/modular_computers/modular_telescreen.dmi'
anchored = TRUE
density = FALSE
opacity = FALSE
idle_power_usage = 10
active_power_usage = 50
power_channel = AREA_USAGE_ENVIRON
/// associative list of control configurations. key is control name, value is list("type", "id", optional "functions")
var/list/controls
/// maximum range in tiles for finding machinery to control
var/range = 16
/// associative list tracking toggle states for controls. key is control name, value is boolean
var/list/control_states
/// stores the initial icon_state set by subtype
var/initial_icon_state
/*
* INITIALIZATION & POWER
*/
/obj/structure/machinery/controlhub/Initialize()
. = ..()
control_states = list()
initial_icon_state = icon_state
update_icon()
/obj/structure/machinery/controlhub/update_icon()
ClearOverlays()
if(stat & BROKEN)
icon_state = "broken"
else if(stat & NOPOWER)
icon_state = "standby"
else
icon_state = initial_icon_state
/obj/structure/machinery/controlhub/power_change()
..()
update_icon()
/*
* INTERACTION
*/
/obj/structure/machinery/controlhub/attack_hand(mob/user)
if(..())
return TRUE
if(stat & BROKEN)
to_chat(user, SPAN_WARNING("\The [src]'s screen is shattered!"))
return TRUE
if(stat & NOPOWER)
to_chat(user, SPAN_WARNING("\The [src] is not responding."))
return TRUE
if(!allowed(user))
to_chat(user, SPAN_WARNING("Access denied."))
return TRUE
if(!length(controls))
to_chat(user, SPAN_WARNING("\The [src] has no configured controls."))
return TRUE
var/list/choices = list()
for(var/control_name in controls)
var/list/control_data = controls[control_name]
var/button_type
switch(control_data["type"])
if("holosign", "windowtint")
button_type = /obj/structure/machinery/button/switch
if("blast_door")
button_type = /obj/structure/machinery/button/remote/blast_door
if("airlock")
button_type = /obj/structure/machinery/button/remote/airlock
if("flasher", "igniter", "emitter", "mass_driver")
button_type = /obj/structure/machinery/button
choices[control_name] = image(icon = initial(button_type:icon), icon_state = initial(button_type:icon_state))
var/chosen_control = show_radial_menu(user, src, choices, require_near = !issilicon(user), radius = 42, tooltips = TRUE)
if(!chosen_control || stat & (BROKEN|NOPOWER))
return TRUE
use_power_oneoff(active_power_usage)
playsound(src, 'sound/machines/holoclick.ogg', 100, FALSE)
flick(initial_icon_state, src)
var/list/control_data = controls[chosen_control]
if(!control_data)
return TRUE
if(!issilicon(user))
user.visible_message(SPAN_NOTICE("\The [user] presses the [chosen_control] button."))
activate_control(chosen_control, control_data)
return TRUE
/obj/structure/machinery/controlhub/proc/activate_control(control_name, list/control_data)
var/control_id = control_data["id"]
switch(control_data["type"])
if("windowtint")
toggle_windowtint(control_id)
if("holosign")
toggle_holosign(control_id)
if("blast_door")
toggle_blast_doors(control_id)
if("airlock")
toggle_airlock(control_name, control_id, control_data["functions"])
if("flasher")
trigger_flasher(control_id)
if("igniter")
trigger_igniter(control_id)
if("emitter")
trigger_emitter(control_id)
if("mass_driver")
trigger_mass_driver(control_id)
/*
* MACHINERY FINDING HELPERS
*/
/obj/structure/machinery/controlhub/proc/find_machinery_by_id(machinery_type, target_id)
. = list()
for(var/obj/structure/machinery/machinery as anything in SSmachinery.machinery)
if(istype(machinery, machinery_type) && machinery:id == target_id)
. += machinery
/obj/structure/machinery/controlhub/proc/find_airlocks_by_id(target_id)
. = list()
for(var/obj/structure/machinery/door/airlock/airlock as anything in SSmachinery.machinery)
if(airlock.id_tag == target_id)
. += airlock
/*
* CONTROL FUNCTIONS
*/
/// toggles the tint on all polarized windows with matching ID within range
/obj/structure/machinery/controlhub/proc/toggle_windowtint(window_id)
for(var/obj/structure/window/window in range(src, range))
if((istype(window, /obj/structure/window/reinforced/polarized) || istype(window, /obj/structure/window/full/reinforced/polarized)) && (window:id == window_id || !window:id))
window:toggle()
/obj/structure/machinery/controlhub/proc/toggle_holosign(holosign_id)
for(var/obj/structure/machinery/holosign/holosign in find_machinery_by_id(/obj/structure/machinery/holosign, holosign_id))
INVOKE_ASYNC(holosign, TYPE_PROC_REF(/obj/structure/machinery/holosign, toggle))
/// toggles blast doors with matching ID based on first door's state
/obj/structure/machinery/controlhub/proc/toggle_blast_doors(door_id)
var/open_doors
for(var/obj/structure/machinery/door/blast/door in find_machinery_by_id(/obj/structure/machinery/door/blast, door_id))
if(isnull(open_doors))
open_doors = door.density
if(open_doors)
door.open()
else
door.close()
/// controls airlocks with matching ID. special_functions bitflags: 1=open/close, 2=ID scan, 4=bolt, 8=electrify, 16=safeties
/obj/structure/machinery/controlhub/proc/toggle_airlock(control_name, airlock_id, special_functions = 1)
if(isnull(control_states[control_name]))
control_states[control_name] = FALSE
control_states[control_name] = !control_states[control_name]
for(var/obj/structure/machinery/door/airlock/airlock in SSmachinery.machinery)
if(airlock.id_tag != airlock_id)
continue
if(special_functions & 1)
if(airlock.density)
airlock.open()
else
airlock.close()
return
if(control_states[control_name])
if(special_functions & 2)
airlock.set_idscan(FALSE)
if(special_functions & 4)
airlock.lock()
if(special_functions & 8)
airlock.electrify(-1)
if(special_functions & 16)
airlock.set_safeties(FALSE)
else
if(special_functions & 2)
airlock.set_idscan(TRUE)
if(special_functions & 4)
airlock.unlock()
if(special_functions & 8)
airlock.electrify(0)
if(special_functions & 16)
airlock.set_safeties(TRUE)
/obj/structure/machinery/controlhub/proc/trigger_flasher(flasher_id)
for(var/obj/structure/machinery/flasher/flasher in find_machinery_by_id(/obj/structure/machinery/flasher, flasher_id))
flasher.flash()
/obj/structure/machinery/controlhub/proc/trigger_igniter(igniter_id)
for(var/obj/structure/machinery/sparker/sparker in find_machinery_by_id(/obj/structure/machinery/sparker, igniter_id))
INVOKE_ASYNC(sparker, TYPE_PROC_REF(/obj/structure/machinery/sparker, ignite))
for(var/obj/structure/machinery/igniter/igniter in find_machinery_by_id(/obj/structure/machinery/igniter, igniter_id))
igniter.ignite()
/obj/structure/machinery/controlhub/proc/trigger_emitter(emitter_id)
for(var/obj/structure/machinery/power/emitter/emitter in find_machinery_by_id(/obj/structure/machinery/power/emitter, emitter_id))
emitter.activate()
/// opens blast door, triggers mass driver, then closes blast door
/obj/structure/machinery/controlhub/proc/trigger_mass_driver(driver_id)
var/list/obj/structure/machinery/door/blast/blast_doors = list()
for(var/obj/structure/machinery/door/blast/door in find_machinery_by_id(/obj/structure/machinery/door/blast, driver_id))
blast_doors += door
INVOKE_ASYNC(door, TYPE_PROC_REF(/obj/structure/machinery/door/blast, open))
sleep(2 SECONDS)
for(var/obj/structure/machinery/mass_driver/driver in find_machinery_by_id(/obj/structure/machinery/mass_driver, driver_id))
driver.drive()
sleep(5 SECONDS)
for(var/obj/structure/machinery/door/blast/door in blast_doors)
INVOKE_ASYNC(door, TYPE_PROC_REF(/obj/structure/machinery/door/blast, close))
/*
* SUBTYPES
*/
/obj/structure/machinery/controlhub/bar
name = "bar control hub"
icon_state = "holocontrol"
req_access = list(ACCESS_BAR)
controls = list(
"counter shutters" = list("type" = "blast_door", "id" = "bar_shutter"),
"holosign" = list("type" = "holosign", "id" = "bar"),
"maintenance shutters" = list("type" = "blast_door", "id" = "bar_maint"),
"safety shutters" = list("type" = "blast_door", "id" = "bar_viewing_shutters"),
"window tint" = list("type" = "windowtint", "id" = "bar_fore")
)