Alt-click lock toggle functionality, APC SFX upgrade (#21310)

Updated objects whose behavior when an ID was used on them was strictly
toggling lock/unlock status to use Alt-click functionality, with
associated pop-up messages for the clicking player. Mechanics hints for
all affected objects updated.

Fixed APC sprite's status lights for each power channel (general messy
alignment).

Updated APC sprite's lock status light to be brighter/clearer for better
visual feedback of lock status.

Added a lot of nice clicky beepy sounds to APCs. They all came from here
on TG, and they seem oooooold so I wasn't able to find credit. [So,
credit to TG for sounds/machines/terminal sounds until we track down an
actual
name!](https://github.com/tgstation/tgstation/tree/master/sound/machines/terminal)

Updated dmdocs as I passed by them.
This commit is contained in:
Batrachophreno
2025-10-03 15:56:32 +00:00
committed by GitHub
parent 41dedf13aa
commit f06bdc8b3c
34 changed files with 387 additions and 201 deletions
+6 -3
View File
@@ -40,9 +40,12 @@
var/blood_color
var/last_bumped = 0
var/pass_flags = 0
var/germ_level = GERM_LEVEL_AMBIENT // The higher the germ level, the more germ on the atom.
var/simulated = 1 // Filter for actions. Used by lighting overlays.
var/fluorescent // Shows up under a UV light.
/// The higher the germ level, the more germ on the atom.
var/germ_level = GERM_LEVEL_AMBIENT
/// Filter for actions. Used by lighting overlays.
var/simulated = 1
/// Shows up under a UV light.
var/fluorescent
var/explosion_resistance
+21 -12
View File
@@ -1064,18 +1064,6 @@ pixel_x = 10;
update_icon()
return TRUE
if (attacking_item.GetID())// trying to unlock the interface with an ID card
if(stat & (NOPOWER|BROKEN))
to_chat(user, SPAN_NOTICE("Nothing happens."))
return TRUE
else
if(allowed(usr) && !wires.is_cut(WIRE_IDSCAN))
locked = !locked
to_chat(user, SPAN_NOTICE("You [ locked ? "lock" : "unlock"] the Air Alarm interface."))
else
to_chat(user, SPAN_WARNING("Access denied."))
return TRUE
if(1)
if(attacking_item.iscoil())
var/obj/item/stack/cable_coil/C = attacking_item
@@ -1116,6 +1104,27 @@ pixel_x = 10;
return ..()
/obj/machinery/alarm/AltClick(mob/user)
if(Adjacent(user))
if(stat & (NOPOWER|BROKEN))
to_chat(user, SPAN_NOTICE("Nothing happens."))
return TRUE
else if(allowed(user))
locked = !locked
if(locked)
playsound(src, 'sound/machines/terminal/terminal_button03.ogg', 35, FALSE)
else
playsound(src, 'sound/machines/terminal/terminal_button01.ogg', 35, FALSE)
balloon_alert(user, locked ? "locked" : "unlocked")
updateUsrDialog()
else
to_chat(user, SPAN_NOTICE("Access denied."))
playsound(src, 'sound/machines/terminal/terminal_error.ogg', 25, FALSE)
balloon_alert(user, "access denied!")
return TRUE
/obj/machinery/alarm/power_change()
..()
queue_icon_update()
@@ -7,18 +7,21 @@
matter = list(DEFAULT_WALL_MATERIAL = 50, MATERIAL_GLASS = 50)
req_access = list(ACCESS_ENGINE)
var/secure = FALSE //if set, then wires will be randomized and bolts will drop if the door is broken
/// If set, then wires will be randomized and bolts will drop if the door is broken
var/secure = FALSE
var/list/conf_access
var/one_access = FALSE //if set to TRUE, door would receive req_one_access instead of req_access
/// If set to TRUE, door would receive req_one_access instead of req_access
var/one_access = FALSE
var/last_configurator
var/locked = TRUE
var/is_installed = FALSE // no double-spending
/// No double-spending
var/is_installed = FALSE
var/unres_dir = null
/obj/item/airlock_electronics/mechanics_hints(mob/user, distance, is_adjacent)
. += ..()
. += "Access control can be configured by using your ID on the circuitboard to unlock it, then using the circuitboard on yourself."
. += "ALT-click the [src] to lock or unlock it (if you have the appropriate ID access)."
. += "Once unlocked, use the airlock electronics on yourself to program different access rights."
. += "You can copy the settings from one circuitboard to another by clicking the source board with the target board. Be mindful of directional access settings!"
/obj/item/airlock_electronics/attack_self(mob/user)
@@ -131,18 +134,25 @@
src.last_configurator = A.last_configurator
to_chat(user, SPAN_NOTICE("Configuration settings copied successfully."))
return TRUE
else if(attacking_item.GetID())
var/obj/item/card/id/I = attacking_item.GetID()
if(check_access(I))
locked = !locked
last_configurator = I.registered_name
to_chat(user, SPAN_NOTICE("You swipe your ID over \the [src], [locked ? "locking" : "unlocking"] it."))
else
to_chat(user, SPAN_WARNING("Access denied."))
return TRUE
else
return ..()
/obj/item/airlock_electronics/AltClick(mob/user)
if(Adjacent(user))
add_fingerprint(user)
if(allowed(user))
locked = !locked
if(locked)
playsound(src, 'sound/machines/terminal/terminal_button03.ogg', 35, FALSE)
else
playsound(src, 'sound/machines/terminal/terminal_button01.ogg', 35, FALSE)
balloon_alert(user, locked ? "locked" : "unlocked")
else
to_chat(user, SPAN_WARNING("Access denied."))
playsound(src, 'sound/machines/terminal/terminal_error.ogg', 25, FALSE)
balloon_alert(user, "access denied!")
return
/obj/item/airlock_electronics/secure
name = "secure airlock electronics"
desc = "Designed to be somewhat more resistant to hacking than standard electronics."
+31 -13
View File
@@ -7,19 +7,30 @@
icon_state = null
name = "navigation beacon"
desc = "A radio beacon used for bot navigation."
level = 1 // underfloor
// underfloor
level = 1
layer = ABOVE_WIRE_LAYER
anchored = 1
var/open = 0 // true if cover is open
var/locked = 1 // true if controls are locked
var/freq = BEACONS_FREQ // radio frequency
var/location = "" // location response text
var/list/codes // assoc. list of transponder codes
var/codes_txt = "" // codes as set on map: "tag1;tag2" or "tag1=value;tag2=value"
/// true if cover is open
var/open = FALSE
/// true if controls are locked
var/locked = TRUE
/// radio frequency
var/freq = BEACONS_FREQ
/// location response text
var/location = ""
/// assoc. list of transponder codes
var/list/codes
/// codes as set on map: "tag1;tag2" or "tag1=value;tag2=value"
var/codes_txt = ""
req_one_access = list(ACCESS_ENGINE, ACCESS_ROBOTICS)
/obj/machinery/navbeacon/mechanics_hints(mob/user, distance, is_adjacent)
. += ..()
. += "ALT-click the [src] to lock or unlock it (if you have the appropriate ID access)."
/obj/machinery/navbeacon/Initialize(mapload)
. = ..()
@@ -149,17 +160,24 @@
hide(!T.is_plating())
else if (attacking_item.GetID())
/obj/machinery/navbeacon/AltClick(mob/user)
if(Adjacent(user))
if(open)
if (src.allowed(user))
src.locked = !src.locked
to_chat(user, "Controls are now [src.locked ? "locked." : "unlocked."]")
add_fingerprint(user)
if(allowed(user))
locked = !locked
if(locked)
playsound(src, 'sound/machines/terminal/terminal_button03.ogg', 35, FALSE)
else
playsound(src, 'sound/machines/terminal/terminal_button01.ogg', 35, FALSE)
balloon_alert(user, locked ? "locked" : "unlocked")
else
to_chat(user, SPAN_WARNING("Access denied."))
updateDialog()
playsound(src, 'sound/machines/terminal/terminal_error.ogg', 25, FALSE)
balloon_alert(user, "access denied!")
else
to_chat(user, "You must open the cover first!")
return TRUE
return
/obj/machinery/navbeacon/attack_ai(var/mob/user)
if(!ai_can_interact(user))
+104 -62
View File
@@ -15,65 +15,95 @@
anchored = 1
density = 0
idle_power_usage = 50 //when inactive, this turret takes up constant 50 Equipment power
active_power_usage = 300 //when active, this turret takes up constant 300 Equipment power
power_channel = AREA_USAGE_EQUIP //drains power from the EQUIPMENT channel
/// when inactive, this turret takes up constant 50 Equipment power
idle_power_usage = 50
/// when active, this turret takes up constant 300 Equipment power
active_power_usage = 300
/// drains power from the EQUIPMENT channel
power_channel = AREA_USAGE_EQUIP
req_one_access = list(ACCESS_SECURITY, ACCESS_HEADS)
light_range = 3
light_power = 2
var/raised = 0 //if the turret cover is "open" and the turret is raised
var/raising= 0 //if the turret is currently opening or closing its cover
var/health = 80 //the turret's health
var/maxhealth = 80 //turrets maximal health.
var/auto_repair = 0 //if 1 the turret slowly repairs itself.
var/locked = 1 //if the turret's behaviour control access is locked
var/controllock = 0 //if the turret responds to control panels
var/obj/item/gun/energy/installation = /obj/item/gun/energy/gun //the type of weapon installed
var/gun_charge = 0 //the charge of the gun inserted
var/reqpower = 500 //holder for power needed
var/lethal_icon = 0 //holder for the icon_state. 1 for lethal sprite, null for stun sprite.
var/egun = 1 //holder to handle certain guns switching modes
var/sprite_set = "carbine" //set of gun sprites the turret will use
var/cover_set = 0 //set of cover sprites the turret will use
/// if the turret cover is "open" and the turret is raised
var/raised = 0
/// if the turret is currently opening or closing its cover
var/raising= 0
/// the turret's health
var/health = 80
/// turrets maximal health.
var/maxhealth = 80
/// if 1 the turret slowly repairs itself.
var/auto_repair = 0
/// if the turret's behaviour control access is locked
var/locked = 1
/// if the turret responds to control panels
var/controllock = 0
/// the type of weapon installed
var/obj/item/gun/energy/installation = /obj/item/gun/energy/gun
/// the charge of the gun inserted
var/gun_charge = 0
/// holder for power needed
var/reqpower = 500
/// holder for the icon_state. 1 for lethal sprite, null for stun sprite.
var/lethal_icon = 0
/// holder to handle certain guns switching modes
var/egun = 1
/// set of gun sprites the turret will use
var/sprite_set = "carbine"
/// set of cover sprites the turret will use
var/cover_set = 0
var/name_override = FALSE
var/last_fired = 0 //1: if the turret is cooling down from a shot, 0: turret is ready to fire
var/shot_delay = 15 //1.5 seconds between each shot
var/check_arrest = 1 //checks if the perp is set to arrest
var/check_records = 1 //checks if a security record exists at all
var/check_weapons = 0 //checks if it can shoot people that have a weapon they aren't authorized to have
var/check_access = 1 //if this is active, the turret shoots everything that does not meet the access requirements
var/check_wildlife = 1 //checks if it can shoot at simple animals or anything that passes issmall
var/check_synth = 0 //if active, will shoot at anything not an AI or cyborg
var/target_borgs = FALSE//if active, will shoot at borgs
var/ailock = 0 // AI cannot use this
var/immobile = FALSE // If TRUE, the turret cannot be detached from the ground with a wrench.
var/no_salvage = FALSE // If TRUE, the turret cannot be salvaged for parts when broken.
var/attacked = 0 //if set to 1, the turret gets pissed off and shoots at people nearby (unless they have sec access!)
var/enabled = 1 //determines if the turret is on
var/lethal = 0 //whether in lethal or stun mode
/// 1: if the turret is cooling down from a shot, 0: turret is ready to fire
var/last_fired = 0
/// 1.5 seconds between each shot
var/shot_delay = 15
/// checks if the perp is set to arrest
var/check_arrest = 1
/// checks if a security record exists at all
var/check_records = 1
/// checks if it can shoot people that have a weapon they aren't authorized to have
var/check_weapons = 0
/// if this is active, the turret shoots everything that does not meet the access requirements
var/check_access = 1
/// checks if it can shoot at simple animals or anything that passes issmall
var/check_wildlife = 1
/// if active, will shoot at anything not an AI or cyborg
var/check_synth = 0
/// if active, will shoot at borgs
var/target_borgs = FALSE
/// AI cannot use this
var/ailock = 0
/// If TRUE, the turret cannot be detached from the ground with a wrench.
var/immobile = FALSE
/// If TRUE, the turret cannot be salvaged for parts when broken.
var/no_salvage = FALSE
/// if set to 1, the turret gets pissed off and shoots at people nearby (unless they have sec access!)
var/attacked = 0
/// determines if the turret is on
var/enabled = 1
/// whether in lethal or stun mode
var/lethal = 0
var/disabled = 0
var/projectile =/obj/projectile/beam/stun //holder for stun (main) mode beam
var/eprojectile = /obj/projectile/beam //holder for lethal (secondary) mode beam
var/shot_sound = 'sound/weapons/Taser.ogg' //what sound should play when the turret fires
var/eshot_sound = 'sound/weapons/laser1.ogg' //what sound should play when the lethal turret fires
var/datum/effect_system/sparks/spark_system //the spark system, used for generating... sparks?
/// holder for stun (main) mode beam
var/projectile =/obj/projectile/beam/stun
/// holder for lethal (secondary) mode beam
var/eprojectile = /obj/projectile/beam
/// what sound should play when the turret fires
var/shot_sound = 'sound/weapons/Taser.ogg'
/// what sound should play when the lethal turret fires
var/eshot_sound = 'sound/weapons/laser1.ogg'
/// the spark system, used for generating... sparks?
var/datum/effect_system/sparks/spark_system
var/wrenching = 0
var/last_target //last target fired at, prevents turrets from erratically firing at all valid targets in range
var/list/targets = list() //list of primary targets
var/list/secondarytargets = list() //targets that are least important
/// last target fired at, prevents turrets from erratically firing at all valid targets in range
var/last_target
/// list of primary targets
var/list/targets = list()
/// targets that are least important
var/list/secondarytargets = list()
var/resetting
var/fast_processing = FALSE
@@ -92,9 +122,14 @@
else
. += "\The [src] is in perfect condition."
/obj/machinery/porta_turret/mechanics_hints(mob/user, distance, is_adjacent)
. += ..()
. += "ALT-click the [src] to lock or unlock it (if you have the appropriate ID access)."
/obj/machinery/porta_turret/assembly_hints(mob/user, distance, is_adjacent)
. += ..()
. += "It [anchored ? "is" : "could be"] anchored to the floor with some <b>bolts</b>."
if(!immobile)
. += "It [anchored ? "is" : "could be"] anchored to the floor with some <b>bolts</b>."
/obj/machinery/porta_turret/crescent
enabled = FALSE
@@ -110,7 +145,8 @@
no_salvage = TRUE
req_one_access = list(ACCESS_CENT_SPECOPS, ACCESS_CENT_GENERAL)
var/admin_emag_override = FALSE // Set to true to allow emagging of this turret.
/// Set to true to allow emagging of this turret.
var/admin_emag_override = FALSE
/obj/machinery/porta_turret/crescent/emag_act()
if (admin_emag_override)
@@ -376,16 +412,6 @@
wrenching = 0
return TRUE
else if(attacking_item.GetID())
//Behavior lock/unlock mangement
if(allowed(user))
locked = !locked
to_chat(user, SPAN_NOTICE("Controls are now [locked ? "locked" : "unlocked"]."))
updateUsrDialog()
else
to_chat(user, SPAN_NOTICE("Access denied."))
return TRUE
else if(attacking_item.iswelder())
var/obj/item/weldingtool/WT = attacking_item
if (!WT.welding)
@@ -416,6 +442,22 @@
addtimer(CALLBACK(src, PROC_REF(reset_attacked)), 1 SECONDS, TIMER_UNIQUE | TIMER_OVERRIDE)
return ..()
/obj/machinery/porta_turret/AltClick(mob/user)
if(Adjacent(user))
if(allowed(user))
locked = !locked
if(locked)
playsound(src, 'sound/machines/terminal/terminal_button03.ogg', 35, FALSE)
else
playsound(src, 'sound/machines/terminal/terminal_button01.ogg', 35, FALSE)
balloon_alert(user, locked ? "locked" : "unlocked")
updateUsrDialog()
else
to_chat(user, SPAN_NOTICE("Access denied."))
playsound(src, 'sound/machines/terminal/terminal_error.ogg', 25, FALSE)
balloon_alert(user, "access denied!")
return TRUE
/obj/machinery/porta_turret/proc/reset_attacked()
attacked = FALSE
+42 -19
View File
@@ -36,21 +36,27 @@
req_access = list(ACCESS_CAPTAIN, ACCESS_HEADS)
z_flags = ZMM_MANGLE_PLANES
var/active = FALSE // PLEASE HOLD.
var/safeties = TRUE // The cycler won't start with a living thing inside it unless safeties are off.
var/irradiating = 0 // If this is > 0, the cycler is decontaminating whatever is inside it.
var/radiation_level = 2 // 1 is removing germs, 2 is removing blood, 3 is removing phoron.
var/model_text = "" // Some flavour text for the topic box.
var/locked = TRUE // If locked, nothing can be taken from or added to the cycler.
var/can_repair // If set, the cycler can repair voidsuits.
/// PLEASE HOLD.
var/active = FALSE
/// The cycler won't start with a living thing inside it unless safeties are off.
var/safeties = TRUE
/// If this is > 0, the cycler is decontaminating whatever is inside it.
var/irradiating = 0
/// 1 is removing germs, 2 is removing blood, 3 is removing phoron.
var/radiation_level = 2
/// Some flavour text for the topic box.
var/model_text = ""
/// If locked, nothing can be taken from or added to the cycler.
var/locked = TRUE
/// If set, the cycler can repair voidsuits.
var/can_repair
var/electrified = FALSE
//Will it change the suit name to "refitted [x]" on refit
/// Will it change the suit name to "refitted [x]" on refit
var/rename_on_refit = TRUE
//Departments that the cycler can paint suits to look like.
/// Departments that the cycler can paint suits to look like.
var/list/departments = list("Engineering", "Mining", "Medical", "Security", "Atmos")
//Species that the suits can be configured to fit.
/// Species that the suits can be configured to fit.
var/list/species = list(BODYTYPE_HUMAN, BODYTYPE_SKRELL, BODYTYPE_UNATHI, BODYTYPE_TAJARA, BODYTYPE_IPC)
var/target_department
@@ -64,6 +70,10 @@
var/datum/wires/suit_storage_unit/wires
/obj/machinery/suit_cycler/mechanics_hints(mob/user, distance, is_adjacent)
. += ..()
. += "ALT-click the [src] to lock or unlock it (if you have the appropriate ID access)."
/obj/machinery/suit_cycler/Initialize(mapload, d = 0, populate_parts = TRUE)
. = ..()
@@ -193,14 +203,6 @@
if(src.shock(user, 100))
return
if(attacking_item.GetID())
if(allowed(user))
locked = !locked
to_chat(user, SPAN_NOTICE("You [locked ? "" : "un"]lock \the [src]."))
else
to_chat(user, SPAN_WARNING("Access denied."))
return
//Other interface stuff.
if(istype(attacking_item, /obj/item/grab))
var/obj/item/grab/G = attacking_item
@@ -242,6 +244,7 @@
updateUsrDialog()
update_icon()
return
else if(attacking_item.isscrewdriver())
panel_open = !panel_open
to_chat(user, SPAN_NOTICE("You [panel_open ? "open" : "close"] the maintenance panel."))
@@ -256,6 +259,26 @@
..()
/obj/machinery/suit_cycler/AltClick(mob/user)
if(Adjacent(user))
add_fingerprint(user)
if(electrified != 0)
if(src.shock(user, 100))
return
if(allowed(user))
locked = !locked
if(locked)
playsound(src, 'sound/machines/terminal/terminal_button03.ogg', 35, FALSE)
else
playsound(src, 'sound/machines/terminal/terminal_button01.ogg', 35, FALSE)
balloon_alert(user, locked ? "locked" : "unlocked")
else
to_chat(user, SPAN_WARNING("Access denied."))
playsound(src, 'sound/machines/terminal/terminal_error.ogg', 25, FALSE)
balloon_alert(user, "access denied!")
return
/obj/machinery/suit_cycler/emag_act(var/remaining_charges, mob/user)
if(emagged)
to_chat(user, SPAN_WARNING("The cycler has already been subverted."))
+39 -22
View File
@@ -18,19 +18,32 @@
var/enabled = 0
var/lethal = 0
var/locked = 1
var/egun = 1 //if the control panel can switch lethal and stun modes
var/area/control_area //can be area name, path or nothing.
/// if the control panel can switch lethal and stun modes
var/egun = 1
/// can be area name, path or nothing.
var/area/control_area
var/check_arrest = 1 //checks if the perp is set to arrest
var/check_records = 1 //checks if a security record exists at all
var/check_weapons = 0 //checks if it can shoot people that have a weapon they aren't authorized to have
var/check_access = 1 //if this is active, the turret shoots everything that does not meet the access requirements
var/check_wildlife = 1 //checks if it can shoot at simple animals or anything that passes issmall
var/check_synth = 0 //if active, will shoot at anything not an AI or cyborg
var/target_borgs = FALSE//if active, will shoot at borgs
var/ailock = 0 //Silicons cannot use this
/// checks if the perp is set to arrest
var/check_arrest = 1
/// checks if a security record exists at all
var/check_records = 1
/// checks if it can shoot people that have a weapon they aren't authorized to have
var/check_weapons = 0
/// if this is active, the turret shoots everything that does not meet the access requirements
var/check_access = 1
/// checks if it can shoot at simple animals or anything that passes issmall
var/check_wildlife = 1
/// if active, will shoot at anything not an AI or cyborg
var/check_synth = 0
/// if active, will shoot at borgs
var/target_borgs = FALSE
/// Silicons cannot use this
var/ailock = 0
req_access = list(ACCESS_AI_UPLOAD)
/obj/machinery/turretid/mechanics_hints(mob/user, distance, is_adjacent)
. += ..()
. += "ALT-click the [src] to lock or unlock it (if you have the appropriate ID access)."
/obj/machinery/turretid/stun
enabled = 1
@@ -94,19 +107,23 @@
return ..()
/obj/machinery/turretid/attackby(obj/item/attacking_item, mob/user)
if(stat & BROKEN)
return
if(attacking_item.GetID())
if(src.allowed(usr))
if(emagged)
to_chat(user, SPAN_NOTICE("The turret control is unresponsive."))
/obj/machinery/turretid/AltClick(mob/user)
if(Adjacent(user))
add_fingerprint(user)
if(emagged)
to_chat(user, SPAN_NOTICE("The turret control is unresponsive."))
else if(allowed(user))
locked = !locked
if(locked)
playsound(src, 'sound/machines/terminal/terminal_button03.ogg', 35, FALSE)
else
locked = !locked
to_chat(user, SPAN_NOTICE("You [ locked ? "lock" : "unlock"] the panel."))
return TRUE
return ..()
playsound(src, 'sound/machines/terminal/terminal_button01.ogg', 35, FALSE)
balloon_alert(user, locked ? "locked" : "unlocked")
else
to_chat(user, SPAN_WARNING("Access denied."))
playsound(src, 'sound/machines/terminal/terminal_error.ogg', 25, FALSE)
balloon_alert(user, "access denied!")
return
/obj/machinery/turretid/emag_act(var/remaining_charges, var/mob/user)
if(!emagged)
+5 -4
View File
@@ -21,8 +21,10 @@
/obj/item/holomenu/mechanics_hints(mob/user, distance, is_adjacent)
. += ..()
. += "If you have bar or kitchen access, you can swipe your ID on this to root it in place, then you can click on it with an empty hand to adjust its text."
. += "Alt-clicking it will toggle its border."
. += "If you have Bar, Kitchen, or Hydroponics access, you can swipe your ID on this to anchor it in place."
. += "You can enter text manually by clicking it with an empty hand, or you can use a paper on the [src] to transfer its written contents."
. += "ALT-click the [src] to toggle its border."
. += "CTRL-click the [src] to toggle RAVE MODE."
/obj/item/holomenu/Initialize()
. = ..()
@@ -140,8 +142,7 @@
/obj/item/holomenu/holodeck/mechanics_hints(mob/user, distance, is_adjacent)
. += ..()
. += "If you have bar or kitchen access, you can click on this with paper in hand to display text, or you can click on it with an empty hand to adjust its text."
. += "Alt-clicking it will toggle its border."
. += "Note that holodecks do not support RAVE MODE."
/obj/item/holomenu/holodeck/attack_hand(mob/user)
var/new_text = sanitize(input(user, "Enter new text for the hologram to display.", "Hologram Display", html2pencode(menu_text, TRUE)) as null|message)
+37 -22
View File
@@ -147,7 +147,8 @@ ABSTRACT_TYPE(/obj/machinery/power/apc)
/obj/machinery/power/apc/mechanics_hints(mob/user, distance, is_adjacent)
. += ..()
. += "An APC (Area Power Controller) regulates and supplies backup power for the area they are in."
. += "Their power channels are divided into 'environmental' (items that manipulate airflow and temperature), 'lighting' (lights), and 'equipment' (everything else that consumes power)."
. += "ALT-click the [src] to lock or unlock it (if you have the appropriate ID access)."
. += "APC power channels are divided into 'environmental' (items that manipulate airflow and temperature), 'lighting' (lights), and 'equipment' (everything else that consumes power)."
. += "Power consumption and backup power cell charge can be seen from the interface; further controls (turning a specific channel on, off or automatic, \
toggling the APC's ability to charge the backup cell, or toggling power for the entire area via master breaker) first requires the interface to be unlocked \
with an ID with Engineering access or by one of the ship's robots or AI."
@@ -373,7 +374,7 @@ ABSTRACT_TYPE(/obj/machinery/power/apc)
if(update & 2)
ClearOverlays()
if(!(stat & (BROKEN|MAINT)) && update_state & UPDATE_ALLGOOD)
AddOverlays(status_overlays_lock[locked+coverlocked+1])
AddOverlays(status_overlays_lock[locked+1])
AddOverlays(status_overlays_charging[charging+1])
AddOverlays(emissive_appearance(icon, "apc-cover-0"))
AddOverlays(emissive_appearance(icon, "apc-charge-0"))
@@ -585,26 +586,6 @@ ABSTRACT_TYPE(/obj/machinery/power/apc)
to_chat(user, "The wires have been [panel_open ? "exposed" : "unexposed"]")
update_icon()
// ID CARD: Attempt to unlock the interface if you have sufficient access.
else if (attacking_item.GetID())
if(emagged)
to_chat(user, "The interface is broken.")
else if(opened != COVER_CLOSED)
to_chat(user, "You must close the cover to swipe an ID card.")
else if(panel_open)
to_chat(user, "You must close the wiring panel to swipe an ID card.")
else if(stat & (BROKEN|MAINT))
to_chat(user, "Nothing happens.")
else if(hacker)
to_chat(user, SPAN_WARNING("Access denied."))
else
if(allowed(usr) && !isWireCut(WIRE_IDSCAN))
locked = !locked
to_chat(user, "You [ locked ? "lock" : "unlock"] the APC interface.")
update_icon()
else
to_chat(user, SPAN_WARNING("Access denied."))
// CABLE COIL: Install the power terminal (wire stuff on the floor in front of the APC).
else if (attacking_item.iscoil() && !terminal && opened != COVER_CLOSED && has_electronics != HAS_ELECTRONICS_SECURED)
var/turf/T = loc
@@ -798,6 +779,33 @@ ABSTRACT_TYPE(/obj/machinery/power/apc)
SPAN_DANGER("You hit the [name] with your [attacking_item.name]!"), \
"You hear a loud metallic bang")
/obj/machinery/power/apc/AltClick(mob/user)
if(Adjacent(user) || issilicon(user))
add_fingerprint(user)
if(emagged)
to_chat(user, "The interface is broken.")
else if(opened != COVER_CLOSED)
to_chat(user, "You must close the cover to swipe an ID card.")
else if(panel_open)
to_chat(user, "You must close the wiring panel to swipe an ID card.")
else if(stat & (BROKEN|MAINT))
to_chat(user, "Nothing happens.")
else if(hacker)
to_chat(user, SPAN_WARNING("Access denied."))
else
if(allowed(usr) && !isWireCut(WIRE_IDSCAN))
locked = !locked
if(locked)
playsound(src, 'sound/machines/terminal/terminal_button03.ogg', 35, FALSE)
else
playsound(src, 'sound/machines/terminal/terminal_button01.ogg', 35, FALSE)
balloon_alert(user, locked ? "locked" : "unlocked")
update_icon()
else
to_chat(user, SPAN_WARNING("Access denied."))
playsound(src, 'sound/machines/terminal/terminal_error.ogg', 25, FALSE)
balloon_alert(user, "access denied!")
/obj/machinery/power/apc/emag_act(var/remaining_charges, var/mob/user)
if(emagged && !infected)
to_chat(user, SPAN_WARNING("You start sliding your cryptographic device into the charging slot. This will take a few seconds..."))
@@ -957,10 +965,12 @@ ABSTRACT_TYPE(/obj/machinery/power/apc)
area.power_light = (lighting > 1)
area.power_equip = (equipment > 1)
area.power_environ = (environ > 1)
else
area.power_light = FALSE
area.power_equip = FALSE
area.power_environ = FALSE
playsound(src.loc, 'sound/machines/terminal/terminal_off.ogg', 50, FALSE)
area.power_change()
/obj/machinery/power/apc/proc/isWireCut(var/wireIndex)
@@ -1070,6 +1080,7 @@ ABSTRACT_TYPE(/obj/machinery/power/apc)
if("Environment")
environ = setsubsystem(val)
intent_message(BUTTON_FLICK, 5)
playsound(src, 'sound/machines/terminal/terminal_select.ogg', 18, TRUE)
update_icon()
update()
. = TRUE
@@ -1090,6 +1101,10 @@ ABSTRACT_TYPE(/obj/machinery/power/apc)
/obj/machinery/power/apc/proc/toggle_breaker()
operating = !operating
if(operating)
playsound(src, 'sound/machines/terminal/terminal_on.ogg', 35, FALSE)
else
playsound(src, 'sound/machines/terminal/terminal_off.ogg', 35, FALSE)
update()
update_icon()
intent_message(BUTTON_FLICK)
+19 -10
View File
@@ -14,9 +14,10 @@
req_access = list(ACCESS_ENGINE_EQUIP)
obj_flags = OBJ_FLAG_ROTATABLE | OBJ_FLAG_SIGNALER
var/id
use_power = POWER_USE_OFF //uses powernet power, not APC power
active_power_usage = 30000 //30 kW laser. I guess that means 30 kJ per shot.
/// uses powernet power, not APC power
use_power = POWER_USE_OFF
/// 30 kW laser. I guess that means 30 kJ per shot.
active_power_usage = 30000
var/active = FALSE
var/powered = FALSE
@@ -29,8 +30,8 @@
var/shot_counter = 0
var/state = EMITTER_LOOSE
var/locked = FALSE
var/special_emitter = FALSE // special emitters notify admins if something happens to them, to prevent grief
/// special emitters notify admins if something happens to them, to prevent grief
var/special_emitter = FALSE
var/_wifi_id
var/datum/wifi/receiver/button/emitter/wifi_receiver
@@ -40,7 +41,7 @@
/obj/machinery/power/emitter/mechanics_hints(mob/user, distance, is_adjacent)
. += ..()
. += "Standing next to \the [src] and examining it will let you see how many shots it has fired since last being turned on."
. += "Using an Engineering ID on \the [src] will toggle its control locks."
. += "ALT-click the [src] to lock or unlock it (if you have the appropriate ID access)."
. += "You can attach a signaler to \the [src] to remotely toggle it on and off (so long as its controls are not locked)."
/obj/machinery/power/emitter/assembly_hints(mob/user, distance, is_adjacent)
@@ -248,23 +249,31 @@
else
to_chat(user, SPAN_WARNING("You need more welding fuel to complete this task."))
return
..()
return
if(attacking_item.GetID())
/obj/machinery/power/emitter/AltClick(mob/user)
if(Adjacent(user))
add_fingerprint(user)
if(emagged)
to_chat(user, SPAN_WARNING("The lock seems to be broken."))
return
if(allowed(user))
if(active)
locked = !locked
to_chat(user, SPAN_NOTICE("The controls are now [locked ? "locked." : "unlocked."]"))
if(locked)
playsound(src, 'sound/machines/terminal/terminal_button03.ogg', 35, FALSE)
else
playsound(src, 'sound/machines/terminal/terminal_button01.ogg', 35, FALSE)
balloon_alert(user, locked ? "locked" : "unlocked")
else
locked = FALSE //just in case it somehow gets locked
to_chat(user, SPAN_WARNING("The controls can only be locked when \the [src] is online."))
else
to_chat(user, SPAN_WARNING("Access denied."))
playsound(src, 'sound/machines/terminal/terminal_error.ogg', 25, FALSE)
balloon_alert(user, "access denied!")
return
..()
return
/obj/machinery/power/emitter/emag_act(remaining_charges, mob/user)
if(!emagged)
+28 -15
View File
@@ -155,15 +155,20 @@
req_access = list(ACCESS_ENGINE)
var/health = 100
var/active = FALSE
var/malfunction = FALSE //Malfunction causes parts of the shield to slowly dissapate
// Malfunction causes parts of the shield to slowly dissapate
var/malfunction = FALSE
var/list/deployed_shields = list()
var/list/regenerating = list()
var/is_open = FALSE //Whether or not the wires are exposed
panel_open = FALSE
var/locked = FALSE
var/check_delay = 60 //periodically recheck if we need to rebuild a shield
use_power = POWER_USE_OFF
idle_power_usage = 0
/obj/machinery/shieldgen/mechanics_hints(mob/user, distance, is_adjacent)
. += ..()
. += "ALT-click the [src] to lock or unlock it (if you have the appropriate ID access)."
/obj/machinery/shieldgen/Destroy()
collapse_shields()
return ..()
@@ -289,7 +294,7 @@
if(locked)
to_chat(user, SPAN_WARNING("The machine is locked!"))
return
if(is_open)
if(panel_open)
to_chat(user, SPAN_WARNING("The panel must be closed before operating this machine."))
return
@@ -317,14 +322,14 @@
/obj/machinery/shieldgen/attackby(obj/item/attacking_item, mob/user)
if(attacking_item.isscrewdriver())
attacking_item.play_tool_sound(get_turf(src), 50)
if(is_open)
if(panel_open)
to_chat(user, SPAN_NOTICE("You close the panel."))
is_open = FALSE
panel_open = FALSE
else
to_chat(user, SPAN_NOTICE("You open the panel and expose the wiring."))
is_open = TRUE
panel_open = TRUE
else if(attacking_item.iscoil() && malfunction && is_open)
else if(attacking_item.iscoil() && malfunction && panel_open)
var/obj/item/stack/cable_coil/coil = attacking_item
to_chat(user, SPAN_NOTICE("You begin to replace the wires."))
//if(do_after(user, min(60, round( ((maxhealth/health)*10)+(malfunction*10) ))) //Take longer to repair heavier damage
@@ -352,17 +357,25 @@
to_chat(user, SPAN_NOTICE("You secure the [src] to the floor!"))
anchored = TRUE
else if(attacking_item.GetID())
if(src.allowed(user))
src.locked = !src.locked
to_chat(user, "The controls are now [src.locked ? "locked." : "unlocked."]")
else
to_chat(user, SPAN_WARNING("Access denied."))
else
..()
/obj/machinery/shieldgen/AltClick(mob/user)
if(Adjacent(user))
add_fingerprint(user)
if(allowed(user))
locked = !locked
if(locked)
playsound(src, 'sound/machines/terminal/terminal_button03.ogg', 35, FALSE)
else
playsound(src, 'sound/machines/terminal/terminal_button01.ogg', 35, FALSE)
balloon_alert(user, locked ? "locked" : "unlocked")
else
to_chat(user, SPAN_WARNING("Access denied."))
playsound(src, 'sound/machines/terminal/terminal_error.ogg', 25, FALSE)
balloon_alert(user, "access denied!")
return
/obj/machinery/shieldgen/update_icon()
if(active && !(stat & NOPOWER))
+16 -5
View File
@@ -23,7 +23,12 @@
///How much power is drawn from powernet. Increase this to allow the generator to sustain longer shields, at the cost of more power draw.
var/power_draw = 30 KILO WATTS
var/max_stored_power = 50 KILO WATTS
use_power = POWER_USE_OFF //Draws directly from power net. Does not use APC power.
/// Draws directly from power net. Does not use APC power.
use_power = POWER_USE_OFF
/obj/machinery/shieldwallgen/mechanics_hints(mob/user, distance, is_adjacent)
. += ..()
. += "ALT-click the [src] to lock or unlock it (if you have the appropriate ID access)."
/obj/machinery/shieldwallgen/update_icon()
if(power_state >= POWER_STARTING)
@@ -156,17 +161,23 @@
var/self_msg = wrenched ? "You secure the external reinforcing bolts to the floor." : "You unsecure the external reinforcing bolts."
user.visible_message(others_msg, SPAN_NOTICE(self_msg), SPAN_NOTICE("You hear a ratcheting noise."))
return
return ..()
if(attacking_item.GetID())
/obj/machinery/shieldwallgen/AltClick(mob/user)
if(Adjacent(user))
add_fingerprint(user)
if(allowed(user))
locked = !locked
var/msg = "The controls are now [locked ? "locked" : "unlocked"]."
to_chat(user, SPAN_NOTICE(msg))
if(locked)
playsound(src, 'sound/machines/terminal/terminal_button03.ogg', 35, FALSE)
else
playsound(src, 'sound/machines/terminal/terminal_button01.ogg', 35, FALSE)
balloon_alert(user, locked ? "locked" : "unlocked")
else
to_chat(user, SPAN_WARNING("Access denied."))
playsound(src, 'sound/machines/terminal/terminal_error.ogg', 25, FALSE)
balloon_alert(user, "access denied!")
return
return ..()
/obj/machinery/shieldwallgen/proc/alldir_cleanup()
for(var/dir in list(NORTH, SOUTH, EAST, WEST))
+15
View File
@@ -0,0 +1,15 @@
# Your name.
author: Batrachophrenoboocosmomachia
# Optional: Remove this file after generating master changelog. Useful for PR changelogs that won't get used again.
delete-after: True
# Any changes you've made. See valid prefix list above.
# INDENT WITH TWO SPACES. NOT TABS. SPACES.
# SCREW THIS UP AND IT WON'T WORK.
# Also, this gets changed to [] after reading. Just remove the brackets when you add new shit.
# Please surround your changes in double quotes ("). It works without them, but if you use certain characters it screws up compiling. The quotes will not show up in the changelog.
changes:
- qol: "Many objects, which required you to have an ID in-hand to toggle lock statuses for, now instead check for equipped IDs on alt-click."
- rscadd: "Added new SFX to APCs, Air Alarms, and other devices."
- bugfix: "APC status lights now accurately reflect lock/unlock status and channel settings."
Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.9 KiB

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.