[MIRROR] Moves atmos checking from Fire Alarms to Fire Locks, Fire Locks now close on their own rather than area-based, a bunch of related stuff. [MDB IGNORE] (#10893)
* Moves atmos checking from Fire Alarms to Fire Locks, Fire Locks now close on their own rather than area-based, a bunch of related stuff. * Weeeee Co-authored-by: zxaber <37497534+zxaber@users.noreply.github.com> Co-authored-by: Gandalf <9026500+Gandalf2k15@users.noreply.github.com>
@@ -1,7 +1,7 @@
|
||||
//A set of defines to be used by the alarm datums
|
||||
///Sent by air alarms, indecates something wrong with thier attached atmosphere
|
||||
#define ALARM_ATMOS "Atmosphere"
|
||||
///Sent by fire alarms when they are toggled
|
||||
///Sent by firelocks when they detect fire, and by fire alarms when a user pulls them
|
||||
#define ALARM_FIRE "Fire"
|
||||
///Sent by apcs when their power starts to fail
|
||||
#define ALARM_POWER "Power"
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
//A set of defines to be sent by fire alarms. The signals are sent to the alarm's area, but are read and used by the firelocks of the area, and are used for mass changes in fire detection.
|
||||
///Sent when a fire alarm is emagged
|
||||
#define FIRE_DETECT_EMAG "fire_detect_emag"
|
||||
///Sent when the fire detection of an area is disabled
|
||||
#define FIRE_DETECT_STOP "fire_detect_stop"
|
||||
///Sent when the fire detection of an area is enabled
|
||||
#define FIRE_DETECT_START "fire_detect_start"
|
||||
///Designates a fire lock should be closed due to HEAT
|
||||
#define FIRELOCK_ALARM_TYPE_HOT "firelock_alarm_type_hot"
|
||||
///Designates a fire lock should be closed due to COLD
|
||||
#define FIRELOCK_ALARM_TYPE_COLD "firelock_alarm_type_cold"
|
||||
///Designates a fire lock should be closed due unknown reasons (IE fire alarm was pulled)
|
||||
#define FIRELOCK_ALARM_TYPE_GENERIC "firelock_alarm_type_generic"
|
||||
@@ -59,15 +59,6 @@
|
||||
///from base of /obj/effect/abstract/liquid_turf/Initialize() (/obj/effect/abstract/liquid_turf/liquids)
|
||||
#define COMSIG_TURF_LIQUIDS_CREATION "turf_liquids_creation"
|
||||
|
||||
// Firealarm signals
|
||||
/// /obj/machinery/firealarm/proc/trigger_effects(manual = FALSE)
|
||||
#define COMSIG_FIREALARM_TRIGGERED_ON "firealarm_triggered_on"
|
||||
#define COMSIG_FIREALARM_TRIGGER_DOORS "firealarm_trigger_doors"
|
||||
/// /obj/machinery/firealarm/proc/untrigger_effects()
|
||||
#define COMSIG_FIREALARM_TRIGGERED_OFF "firealarm_triggered_off"
|
||||
/// /obj/machinery/door/firedoor/proc/trigger_hot()
|
||||
#define COMSIG_FIREDOOR_CLOSED_FIRE "firedoor_closed_fire"
|
||||
|
||||
//when someone casts their fishing rod
|
||||
#define COMSIG_START_FISHING "start_fishing"
|
||||
//when someone pulls back their fishing rod
|
||||
|
||||
@@ -64,6 +64,8 @@
|
||||
mid_length = 18
|
||||
volume = 50
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/datum/looping_sound/oven
|
||||
start_sound = 'sound/machines/oven/oven_loop_start.ogg' //my immersions
|
||||
start_length = 12
|
||||
@@ -98,6 +100,7 @@
|
||||
volume = 85
|
||||
vary = TRUE
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/datum/looping_sound/server
|
||||
mid_sounds = list('sound/machines/tcomms/tcomms_mid1.ogg'=1,'sound/machines/tcomms/tcomms_mid2.ogg'=1,'sound/machines/tcomms/tcomms_mid3.ogg'=1,'sound/machines/tcomms/tcomms_mid4.ogg'=1,\
|
||||
@@ -108,6 +111,8 @@
|
||||
falloff_exponent = 5
|
||||
volume = 50
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/datum/looping_sound/computer
|
||||
start_sound = 'sound/machines/computer/computer_start.ogg'
|
||||
start_length = 7.2 SECONDS
|
||||
@@ -121,6 +126,8 @@
|
||||
extra_range = -12
|
||||
falloff_distance = 1 //Instant falloff after initial tile
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/datum/looping_sound/gravgen
|
||||
mid_sounds = list('sound/machines/gravgen/gravgen_mid1.ogg'=1,'sound/machines/gravgen/gravgen_mid2.ogg'=1,'sound/machines/gravgen/gravgen_mid3.ogg'=1,'sound/machines/gravgen/gravgen_mid4.ogg'=1,)
|
||||
mid_length = 1.8 SECONDS
|
||||
@@ -129,6 +136,15 @@
|
||||
falloff_distance = 5
|
||||
falloff_exponent = 20
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/datum/looping_sound/firealarm
|
||||
mid_sounds = list('sound/machines/FireAlarm.ogg'=1)
|
||||
mid_length = 9.7 SECONDS
|
||||
volume = 75
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/datum/looping_sound/gravgen/kinesis
|
||||
volume = 20
|
||||
falloff_distance = 2
|
||||
|
||||
@@ -17,11 +17,17 @@
|
||||
|
||||
///Do we have an active fire alarm?
|
||||
var/fire = FALSE
|
||||
///How many fire alarm sources do we have?
|
||||
var/triggered_firealarms = 0
|
||||
///A var for whether the area allows for detecting fires/etc. Disabled or enabled at a fire alarm, checked by fire locks.
|
||||
var/fire_detect = TRUE
|
||||
///A list of all fire locks in this area. Used by fire alarm panels when resetting fire locks or activating all in an area
|
||||
var/list/firedoors
|
||||
///A list of firelocks currently active. Used by fire alarms when setting their icons.
|
||||
var/list/active_firelocks
|
||||
///A list of all fire alarms in this area. Used by fire locks and burglar alarms to tell the fire alarm to change its icon.
|
||||
var/list/firealarms
|
||||
///Alarm type to count of sources. Not usable for ^ because we handle fires differently
|
||||
var/list/active_alarms = list()
|
||||
///We use this just for fire alarms, because they're area based right now so one alarm going poof shouldn't prevent you from clearing your alarms listing
|
||||
///We use this just for fire alarms, because they're area based right now so one alarm going poof shouldn't prevent you from clearing your alarms listing. Fire alarms and fire locks will set and clear alarms.
|
||||
var/datum/alarm_handler/alarm_manager
|
||||
|
||||
var/lightswitch = TRUE
|
||||
@@ -65,10 +71,7 @@
|
||||
var/list/ambientsounds
|
||||
flags_1 = CAN_BE_DIRTY_1
|
||||
|
||||
var/list/firedoors
|
||||
var/list/cameras
|
||||
//var/list/firealarms SKYRAT EDIT REMOVAL
|
||||
var/firedoors_last_closed_on = 0
|
||||
|
||||
///Typepath to limit the areas (subtypes included) that atoms in this area can smooth with. Used for shuttles.
|
||||
var/area/area_limited_icon_smoothing
|
||||
@@ -240,84 +243,6 @@ GLOBAL_LIST_EMPTY(teleportlocs)
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
QDEL_NULL(alarm_manager)
|
||||
return ..()
|
||||
/* SKYRAT EDIT REMOVAL
|
||||
/**
|
||||
* Try to close all the firedoors in the area
|
||||
*/
|
||||
/area/proc/ModifyFiredoors(opening)
|
||||
if(firedoors)
|
||||
firedoors_last_closed_on = world.time
|
||||
for(var/FD in firedoors)
|
||||
var/obj/machinery/door/firedoor/D = FD
|
||||
if (D.being_held_open)
|
||||
continue
|
||||
var/cont = !D.welded
|
||||
if(cont && opening) //don't open if adjacent area is on fire
|
||||
for(var/I in D.affecting_areas)
|
||||
var/area/A = I
|
||||
if(A.fire)
|
||||
cont = FALSE
|
||||
break
|
||||
if(cont && D.is_operational)
|
||||
if(D.operating)
|
||||
D.nextstate = opening ? FIREDOOR_OPEN : FIREDOOR_CLOSED
|
||||
else if(!(D.density ^ opening))
|
||||
INVOKE_ASYNC(D, (opening ? /obj/machinery/door/firedoor.proc/open : /obj/machinery/door/firedoor.proc/close))
|
||||
|
||||
/**
|
||||
* Generate a firealarm alert for this area
|
||||
*
|
||||
* Sends to all ai players, alert consoles, drones and alarm monitor programs in the world
|
||||
*
|
||||
* Also starts the area processing on SSobj
|
||||
*/
|
||||
/area/proc/firealert(obj/source)
|
||||
if (!fire)
|
||||
set_fire_alarm_effect()
|
||||
ModifyFiredoors(FALSE)
|
||||
for(var/item in firealarms)
|
||||
var/obj/machinery/firealarm/F = item
|
||||
F.update_appearance()
|
||||
alarm_manager.send_alarm(ALARM_FIRE, source)
|
||||
START_PROCESSING(SSobj, src)
|
||||
|
||||
/**
|
||||
* Reset the firealarm alert for this area
|
||||
*
|
||||
* resets the alert sent to all ai players, alert consoles, drones and alarm monitor programs
|
||||
* in the world
|
||||
*
|
||||
* Also cycles the icons of all firealarms and deregisters the area from processing on SSOBJ
|
||||
*/
|
||||
/area/proc/firereset(obj/source)
|
||||
var/should_reset_alarms = fire
|
||||
if(source)
|
||||
if(istype(source, /obj/machinery/firealarm))
|
||||
var/obj/machinery/firealarm/alarm = source
|
||||
if(alarm.triggered)
|
||||
alarm.triggered = FALSE
|
||||
triggered_firealarms -= 1
|
||||
if(triggered_firealarms > 0)
|
||||
should_reset_alarms = FALSE
|
||||
should_reset_alarms = should_reset_alarms & power_environ //No resetting if there's no power
|
||||
|
||||
if (should_reset_alarms) // if there's a source, make sure there's no fire alarms left
|
||||
unset_fire_alarm_effects()
|
||||
ModifyFiredoors(TRUE)
|
||||
for(var/item in firealarms)
|
||||
var/obj/machinery/firealarm/F = item
|
||||
F.update_appearance()
|
||||
alarm_manager.clear_alarm(ALARM_FIRE, source)
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
|
||||
/**
|
||||
* If 100 ticks has elapsed, toggle all the firedoors closed again
|
||||
*/
|
||||
/area/process()
|
||||
if(!triggered_firealarms)
|
||||
firereset() //If there are no breaches or fires, and this alert was caused by a breach or fire, die
|
||||
if(firedoors_last_closed_on + 100 < world.time) //every 10 seconds
|
||||
ModifyFiredoors(FALSE)
|
||||
|
||||
/**
|
||||
* Close and lock a door passed into this proc
|
||||
@@ -352,15 +277,14 @@ GLOBAL_LIST_EMPTY(teleportlocs)
|
||||
* Updates the fire light on fire alarms in the area and sets all lights to emergency mode
|
||||
*/
|
||||
/area/proc/set_fire_alarm_effect()
|
||||
if(fire)
|
||||
return
|
||||
fire = TRUE
|
||||
if(!triggered_firealarms) //If there aren't any fires/breaches
|
||||
triggered_firealarms = INFINITY //You're not allowed to naturally die
|
||||
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
|
||||
for(var/alarm in firealarms)
|
||||
var/obj/machinery/firealarm/F = alarm
|
||||
F.update_fire_light(fire)
|
||||
for(var/obj/machinery/light/L in src)
|
||||
L.update()
|
||||
for(var/obj/machinery/firealarm/firepanel in firealarms)
|
||||
firepanel.set_status()
|
||||
|
||||
/**
|
||||
* unset the fire alarm visual affects in an area
|
||||
@@ -369,15 +293,12 @@ GLOBAL_LIST_EMPTY(teleportlocs)
|
||||
*/
|
||||
/area/proc/unset_fire_alarm_effects()
|
||||
fire = FALSE
|
||||
triggered_firealarms = 0
|
||||
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
|
||||
for(var/alarm in firealarms)
|
||||
var/obj/machinery/firealarm/F = alarm
|
||||
F.update_fire_light(fire)
|
||||
F.triggered = FALSE
|
||||
for(var/obj/machinery/light/L in src)
|
||||
L.update()
|
||||
*/
|
||||
for(var/obj/machinery/firealarm/firepanel in firealarms)
|
||||
firepanel.set_status()
|
||||
|
||||
/**
|
||||
* Update the icon state of the area
|
||||
*
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
#define CONSTRUCTION_PANEL_OPEN 1 //Maintenance panel is open, still functioning
|
||||
#define CONSTRUCTION_NO_CIRCUIT 2 //Circuit board removed, can safely weld apart
|
||||
#define DEFAULT_STEP_TIME 20 /// default time for each step
|
||||
#define DETECT_COOLDOWN_STEP_TIME 5 SECONDS ///Wait time before we can detect an issue again, after a recent clear.
|
||||
|
||||
/obj/machinery/door/firedoor
|
||||
name = "firelock"
|
||||
desc = "Apply crowbar."
|
||||
icon = 'icons/obj/doors/Doorfireglass.dmi' //ICON OVERRIDEN IN SKYRAT AESTHETICS - SEE MODULE
|
||||
icon = 'icons/obj/doors/Doorfireglass.dmi'
|
||||
icon_state = "door_open"
|
||||
opacity = FALSE
|
||||
density = FALSE
|
||||
@@ -21,16 +22,76 @@
|
||||
assemblytype = /obj/structure/firelock_frame
|
||||
armor = list(MELEE = 10, BULLET = 30, LASER = 20, ENERGY = 20, BOMB = 30, BIO = 100, FIRE = 95, ACID = 70)
|
||||
interaction_flags_machine = INTERACT_MACHINE_WIRES_IF_OPEN | INTERACT_MACHINE_ALLOW_SILICON | INTERACT_MACHINE_OPEN_SILICON | INTERACT_MACHINE_REQUIRES_SILICON | INTERACT_MACHINE_OPEN
|
||||
var/nextstate = null
|
||||
|
||||
COOLDOWN_DECLARE(detect_cooldown)
|
||||
|
||||
///Trick to get the glowing overlay visible from a distance
|
||||
luminosity = 1
|
||||
///X offset for the overlay lights, so that they line up with the thin border firelocks
|
||||
var/light_xoffset = 0
|
||||
///Y offset for the overlay lights, so that they line up with the thin border firelocks
|
||||
var/light_yoffset = 0
|
||||
|
||||
var/boltslocked = TRUE
|
||||
///List of areas we handle. See CalculateAffectingAreas()
|
||||
var/list/affecting_areas
|
||||
///For the few times we affect only the area we're actually in. Set during Init. If we get moved, we don't update, but this is consistant with fire alarms and also kinda funny so call it intentional.
|
||||
var/area/my_area
|
||||
///Tracks if the firelock is being held open by a crowbar. If so, we don't close until they walk away
|
||||
var/being_held_open = FALSE
|
||||
|
||||
///Type of alarm when active. See code/defines/firealarm.dm for the list. This var being null means there is no alarm.
|
||||
var/alarm_type = null
|
||||
///The merger_id and merger_typecache variables are used to make rows of firelocks activate at the same time.
|
||||
var/merger_id = "firelocks"
|
||||
var/static/list/merger_typecache
|
||||
///Overlay object for the warning lights. This and some plane settings allows the lights to glow in the dark.
|
||||
var/mutable_appearance/warn_lights
|
||||
|
||||
///looping sound datum for our fire alarm siren.
|
||||
var/datum/looping_sound/firealarm/soundloop
|
||||
///Keeps track of if we're playing the alarm sound loop (as only one firelock per group should be). Used during power changes.
|
||||
var/is_playing_alarm = FALSE
|
||||
|
||||
var/knock_sound = 'sound/effects/glassknock.ogg'
|
||||
var/bash_sound = 'sound/effects/glassbash.ogg'
|
||||
|
||||
|
||||
/obj/machinery/door/firedoor/Initialize(mapload)
|
||||
. = ..()
|
||||
COOLDOWN_START(src, detect_cooldown, DETECT_COOLDOWN_STEP_TIME)
|
||||
soundloop = new(src, FALSE)
|
||||
AddElement(/datum/element/atmos_sensitive, mapload)
|
||||
CalculateAffectingAreas()
|
||||
my_area = get_area(src)
|
||||
var/static/list/loc_connections = list(
|
||||
COMSIG_TURF_EXPOSE = .proc/check_atmos,
|
||||
)
|
||||
|
||||
AddElement(/datum/element/connect_loc, loc_connections)
|
||||
if(!merger_typecache)
|
||||
merger_typecache = typecacheof(/obj/machinery/door/firedoor)
|
||||
|
||||
check_atmos()
|
||||
|
||||
return INITIALIZE_HINT_LATELOAD
|
||||
|
||||
/obj/machinery/door/firedoor/LateInitialize()
|
||||
. = ..()
|
||||
GetMergeGroup(merger_id, allowed_types = merger_typecache)
|
||||
|
||||
/**
|
||||
* Sets the offset for the warning lights.
|
||||
*
|
||||
* Used for special firelocks with light overlays that don't line up to their sprite.
|
||||
*/
|
||||
/obj/machinery/door/firedoor/proc/adjust_lights_starting_offset()
|
||||
return
|
||||
|
||||
/obj/machinery/door/firedoor/Destroy()
|
||||
remove_from_areas()
|
||||
QDEL_NULL(soundloop)
|
||||
return ..()
|
||||
|
||||
/obj/machinery/door/firedoor/examine(mob/user)
|
||||
. = ..()
|
||||
@@ -39,39 +100,152 @@
|
||||
else if(!welded)
|
||||
. += span_notice("It is closed, but could be <b>pried</b> open.")
|
||||
. += span_notice("Hold the firelock temporarily open by prying it with <i>left-click</i> and standing next to it.")
|
||||
//. += span_notice("Prying by <i>right-clicking</i> the firelock will open it permanently.") SKYRAT EDIT REMOVAL
|
||||
. += span_notice("Prying by <i>right-clicking</i> the firelock will open it permanently.")
|
||||
. += span_notice("Deconstruction would require it to be <b>welded</b> shut.")
|
||||
else if(boltslocked)
|
||||
. += span_notice("It is <i>welded</i> shut. The floor bolts have been locked by <b>screws</b>.")
|
||||
else
|
||||
. += span_notice("The bolt locks have been <i>unscrewed</i>, but the bolts themselves are still <b>wrenched</b> to the floor.")
|
||||
|
||||
/* //SKYRAT EDIT REMOVAL BEGIN
|
||||
/**
|
||||
* Calculates what areas we should worry about.
|
||||
*
|
||||
* This proc builds a list of areas we are in and areas we border
|
||||
* and writes it to affecting_areas.
|
||||
*/
|
||||
/obj/machinery/door/firedoor/proc/CalculateAffectingAreas()
|
||||
var/list/new_affecting_areas = get_adjacent_open_areas(src) | get_area(src)
|
||||
if(compare_list(new_affecting_areas, affecting_areas))
|
||||
return //No changes needed
|
||||
|
||||
remove_from_areas()
|
||||
affecting_areas = get_adjacent_open_areas(src) | get_area(src)
|
||||
for(var/I in affecting_areas)
|
||||
var/area/A = I
|
||||
LAZYADD(A.firedoors, src)
|
||||
*/ //SKYRAT EDIT END
|
||||
affecting_areas = new_affecting_areas
|
||||
for(var/area/place in affecting_areas)
|
||||
LAZYADD(place.firedoors, src)
|
||||
if(alarm_type)
|
||||
if(place == get_area(src))
|
||||
LAZYADD(place.active_firelocks, src) //We only add ourselves to our own area's active firelocks...
|
||||
for(var/obj/machinery/firealarm/fire_panel in place.firealarms)
|
||||
fire_panel.set_status() //...but all adjacent fire alarms are notified
|
||||
|
||||
/obj/machinery/door/firedoor/closed
|
||||
icon_state = "door_closed"
|
||||
density = TRUE
|
||||
|
||||
/* //SKYRAT EDIT REMOVAL BEGIN
|
||||
//see also turf/AfterChange for adjacency shennanigans
|
||||
/**
|
||||
* Removes us from any lists of areas in the affecting_areas list, then clears affecting_areas
|
||||
*
|
||||
* Undoes everything done in the CalculateAffectingAreas() proc, to clean up prior to deletion.
|
||||
* Calls reset() first, in case any alarms need to be cleared first.
|
||||
*/
|
||||
/obj/machinery/door/firedoor/proc/remove_from_areas()
|
||||
if(affecting_areas)
|
||||
for(var/I in affecting_areas)
|
||||
var/area/A = I
|
||||
LAZYREMOVE(A.firedoors, src)
|
||||
if(!affecting_areas)
|
||||
return
|
||||
for(var/area/place in affecting_areas)
|
||||
LAZYREMOVE(place.firedoors, src)
|
||||
LAZYREMOVE(place.active_firelocks, src)
|
||||
if(LAZYLEN(place.active_firelocks)) //if we were the last firelock still active in this particular area
|
||||
continue
|
||||
for(var/obj/machinery/firealarm/fire_panel in place.firealarms)
|
||||
fire_panel.set_status()
|
||||
|
||||
/obj/machinery/door/firedoor/Destroy()
|
||||
remove_from_areas()
|
||||
affecting_areas.Cut()
|
||||
return ..()
|
||||
*/ //SKYRAT EDIT REMOVAL END
|
||||
/obj/machinery/door/firedoor/proc/check_atmos(datum/source)
|
||||
if(!COOLDOWN_FINISHED(src, detect_cooldown))
|
||||
return
|
||||
if(alarm_type)
|
||||
return
|
||||
for(var/area/place in affecting_areas)
|
||||
if(!place.fire_detect) //if any area is set to disable detection
|
||||
return
|
||||
|
||||
var/turf/my_turf = source
|
||||
if(!my_turf)
|
||||
my_turf = get_turf(src)
|
||||
|
||||
var/datum/gas_mixture/environment = my_turf.return_air()
|
||||
var/result
|
||||
|
||||
if(environment?.temperature >= BODYTEMP_HEAT_DAMAGE_LIMIT || environment?.volume > WARNING_HIGH_PRESSURE) //SKYRAT EDIT CHANGE - BETTER LOCKS
|
||||
result = FIRELOCK_ALARM_TYPE_HOT
|
||||
if(environment?.temperature <= BODYTEMP_COLD_DAMAGE_LIMIT || environment?.volume < WARNING_LOW_PRESSURE) //SKYRAT EDIT CHANGE - BETTER LOCKS
|
||||
result = FIRELOCK_ALARM_TYPE_COLD
|
||||
if(!result)
|
||||
return
|
||||
|
||||
start_activation_process(result)
|
||||
|
||||
/**
|
||||
* Begins activation process of us and our neighbors.
|
||||
*
|
||||
* This proc will call activate() on every fire lock (including us) listed
|
||||
* in the merge group datum. Returns without doing anything if our alarm_type
|
||||
* was already set, as that means that we're already active.
|
||||
*
|
||||
* Arguments:
|
||||
* code should be one of three defined alarm types, or can be not supplied. Will dictate the color of the fire alarm lights, and defults to "firelock_alarm_type_generic"
|
||||
*/
|
||||
/obj/machinery/door/firedoor/proc/start_activation_process(code = FIRELOCK_ALARM_TYPE_GENERIC)
|
||||
if(alarm_type)
|
||||
return //We're already active
|
||||
soundloop.start()
|
||||
is_playing_alarm = TRUE
|
||||
var/datum/merger/merge_group = GetMergeGroup(merger_id, merger_typecache)
|
||||
for(var/obj/machinery/door/firedoor/buddylock as anything in merge_group.members)
|
||||
buddylock.activate(code)
|
||||
|
||||
|
||||
/**
|
||||
* Proc that handles activation of the firelock and all this details
|
||||
*
|
||||
* Sets the alarm_type variable based on the single arg, which is in turn
|
||||
* used by several procs to understand the intended state of the fire lock.
|
||||
* Also calls set_status() on all fire alarms in all affected areas, tells
|
||||
* the area the firelock sits in to report the event (AI, alarm consoles, etc)
|
||||
* and finally calls correct_state(), which will handle opening or closing
|
||||
* this fire lock.
|
||||
*/
|
||||
/obj/machinery/door/firedoor/proc/activate(code = FIRELOCK_ALARM_TYPE_GENERIC)
|
||||
SIGNAL_HANDLER
|
||||
if(alarm_type)
|
||||
return //Already active
|
||||
alarm_type = code
|
||||
for(var/area/place in affecting_areas)
|
||||
LAZYADD(place.active_firelocks, src)
|
||||
if(LAZYLEN(place.active_firelocks) == 1) //if we're the first to activate in this particular area
|
||||
for(var/obj/machinery/firealarm/fire_panel in place.firealarms)
|
||||
fire_panel.set_status()
|
||||
if(alarm_type != FIRELOCK_ALARM_TYPE_GENERIC) //Generic alarms tend to activate all firelocks in an area, which otherwise makes the red lighting spread like a virus. Anyway, fire alarms already do this for manual pulls.
|
||||
place.set_fire_alarm_effect() //bathe in red
|
||||
if(place == my_area)
|
||||
place.alarm_manager.send_alarm(ALARM_FIRE, place) //We'll limit our reporting to just the area we're on. If the issue affects bordering areas, they can report it themselves
|
||||
update_icon() //Sets the door lights even if the door doesn't move.
|
||||
correct_state()
|
||||
|
||||
/**
|
||||
* Proc that handles reset steps
|
||||
*
|
||||
* Clears the alarm state and attempts to open the firelock.
|
||||
*/
|
||||
/obj/machinery/door/firedoor/proc/reset()
|
||||
SIGNAL_HANDLER
|
||||
alarm_type = null
|
||||
for(var/area/place in affecting_areas)
|
||||
LAZYREMOVE(place.active_firelocks, src)
|
||||
if(!LAZYLEN(place.active_firelocks)) //if we were the last firelock still active in this particular area
|
||||
for(var/obj/machinery/firealarm/fire_panel in place.firealarms)
|
||||
fire_panel.set_status()
|
||||
place.unset_fire_alarm_effects()
|
||||
COOLDOWN_START(src, detect_cooldown, DETECT_COOLDOWN_STEP_TIME)
|
||||
soundloop.stop()
|
||||
is_playing_alarm = FALSE
|
||||
update_icon() //Sets the door lights even if the door doesn't move.
|
||||
correct_state()
|
||||
|
||||
/obj/machinery/door/firedoor/emag_act(mob/user, obj/item/card/emag/doorjack/digital_crowbar)
|
||||
if(obj_flags & EMAGGED)
|
||||
return
|
||||
if(!isAI(user)) //Skip doorjack-specific code
|
||||
if(!user || digital_crowbar.charges < 1)
|
||||
return
|
||||
digital_crowbar.use_charge(user)
|
||||
obj_flags |= EMAGGED
|
||||
INVOKE_ASYNC(src, .proc/open)
|
||||
|
||||
/obj/machinery/door/firedoor/Bumped(atom/movable/AM)
|
||||
if(panel_open || operating)
|
||||
@@ -85,7 +259,13 @@
|
||||
|
||||
/obj/machinery/door/firedoor/power_change()
|
||||
. = ..()
|
||||
INVOKE_ASYNC(src, .proc/latetoggle)
|
||||
update_icon()
|
||||
correct_state()
|
||||
if(machine_stat & NOPOWER)
|
||||
soundloop.stop()
|
||||
else if(is_playing_alarm)
|
||||
soundloop.start()
|
||||
|
||||
|
||||
/obj/machinery/door/firedoor/attack_hand(mob/living/user, list/modifiers)
|
||||
. = ..()
|
||||
@@ -143,6 +323,7 @@
|
||||
user.visible_message(span_danger("[user] [welded?"welds":"unwelds"] [src]."), span_notice("You [welded ? "weld" : "unweld"] [src]."))
|
||||
log_game("[key_name(user)] [welded ? "welded":"unwelded"] firedoor [src] with [W] at [AREACOORD(src)]")
|
||||
update_appearance()
|
||||
correct_state()
|
||||
|
||||
/// We check for adjacency when using the primary attack.
|
||||
/obj/machinery/door/firedoor/try_to_crowbar(obj/item/acting_object, mob/user)
|
||||
@@ -170,6 +351,8 @@
|
||||
|
||||
if(density)
|
||||
open()
|
||||
if(alarm_type)
|
||||
addtimer(CALLBACK(src, .proc/correct_state), 2 SECONDS, TIMER_UNIQUE)
|
||||
else
|
||||
close()
|
||||
|
||||
@@ -180,7 +363,7 @@
|
||||
if(!QDELETED(user) && Adjacent(user) && isliving(user) && (living_user.body_position == STANDING_UP))
|
||||
return
|
||||
being_held_open = FALSE
|
||||
INVOKE_ASYNC(src, .proc/close)
|
||||
correct_state()
|
||||
UnregisterSignal(user, COMSIG_MOVABLE_MOVED)
|
||||
UnregisterSignal(user, COMSIG_LIVING_SET_BODY_POSITION)
|
||||
UnregisterSignal(user, COMSIG_PARENT_QDELETING)
|
||||
@@ -193,6 +376,8 @@
|
||||
return TRUE
|
||||
if(density)
|
||||
open()
|
||||
if(alarm_type)
|
||||
addtimer(CALLBACK(src, .proc/correct_state), 2 SECONDS, TIMER_UNIQUE)
|
||||
else
|
||||
close()
|
||||
return TRUE
|
||||
@@ -206,6 +391,8 @@
|
||||
to_chat(user, span_warning("[src] refuses to budge!"))
|
||||
return
|
||||
open()
|
||||
if(alarm_type)
|
||||
addtimer(CALLBACK(src, .proc/correct_state), 2 SECONDS, TIMER_UNIQUE)
|
||||
|
||||
/obj/machinery/door/firedoor/do_animate(animation)
|
||||
switch(animation)
|
||||
@@ -214,54 +401,77 @@
|
||||
if("closing")
|
||||
flick("door_closing", src)
|
||||
|
||||
/*SKYRAT EDIT REMOVAL
|
||||
/obj/machinery/door/firedoor/update_icon_state()
|
||||
. = ..()
|
||||
icon_state = "[base_icon_state]_[density ? "closed" : "open"]"
|
||||
*/
|
||||
|
||||
/obj/machinery/door/firedoor/update_overlays()
|
||||
. = ..()
|
||||
if(!welded)
|
||||
if(welded)
|
||||
. += density ? "welded" : "welded_open"
|
||||
if(alarm_type && powered())
|
||||
var/mutable_appearance/hazards
|
||||
hazards = mutable_appearance(icon, "[(obj_flags & EMAGGED) ? "firelock_alarm_type_emag" : alarm_type]")
|
||||
hazards.pixel_x = light_xoffset
|
||||
hazards.pixel_y = light_yoffset
|
||||
. += hazards
|
||||
hazards = emissive_appearance(icon, "[(obj_flags & EMAGGED) ? "firelock_alarm_type_emag" : alarm_type]", alpha = src.alpha)
|
||||
hazards.pixel_x = light_xoffset
|
||||
hazards.pixel_y = light_yoffset
|
||||
. += hazards
|
||||
|
||||
/**
|
||||
* Corrects the current state of the door, based on if alarm_type is set.
|
||||
*
|
||||
* This proc is called after weld and power restore events. Gives the
|
||||
* illusion that the door is constantly attempting to move without actually
|
||||
* having to process it. Timers also call this, so that if alarm_type
|
||||
* changes during the timer, the door doesn't close or open incorrectly.
|
||||
*/
|
||||
/obj/machinery/door/firedoor/proc/correct_state()
|
||||
if(obj_flags & EMAGGED || being_held_open)
|
||||
return //Unmotivated, indifferent, we have no real care what state we're in anymore.
|
||||
if(alarm_type && !density) //We should be closed but we're not
|
||||
INVOKE_ASYNC(src, .proc/close)
|
||||
return
|
||||
if(!alarm_type && density) //We should be open but we're not
|
||||
INVOKE_ASYNC(src, .proc/open)
|
||||
return
|
||||
. += density ? "welded" : "welded_open"
|
||||
|
||||
/obj/machinery/door/firedoor/open()
|
||||
if(welded)
|
||||
return
|
||||
var/alarm = alarm_type
|
||||
. = ..()
|
||||
latetoggle()
|
||||
if(alarm != alarm_type) //Something changed while we were sleeping
|
||||
correct_state() //So we should re-evaluate our state
|
||||
|
||||
/obj/machinery/door/firedoor/close()
|
||||
if(HAS_TRAIT(loc, TRAIT_FIREDOOR_STOP))
|
||||
return
|
||||
var/alarm = alarm_type
|
||||
. = ..()
|
||||
latetoggle()
|
||||
if(alarm != alarm_type) //Something changed while we were sleeping
|
||||
correct_state() //So we should re-evaluate our state
|
||||
|
||||
/obj/machinery/door/firedoor/deconstruct(disassembled = TRUE)
|
||||
if(!(flags_1 & NODECONSTRUCT_1))
|
||||
var/turf/T = get_turf(src)
|
||||
var/turf/targetloc = get_turf(src)
|
||||
if(disassembled || prob(40))
|
||||
var/obj/structure/firelock_frame/F = new assemblytype(T)
|
||||
var/obj/structure/firelock_frame/unbuilt_lock = new assemblytype(targetloc)
|
||||
if(disassembled)
|
||||
F.constructionStep = CONSTRUCTION_PANEL_OPEN
|
||||
unbuilt_lock.constructionStep = CONSTRUCTION_PANEL_OPEN
|
||||
else
|
||||
F.constructionStep = CONSTRUCTION_NO_CIRCUIT
|
||||
F.update_integrity(F.max_integrity * 0.5)
|
||||
F.update_appearance()
|
||||
unbuilt_lock.constructionStep = CONSTRUCTION_NO_CIRCUIT
|
||||
unbuilt_lock.update_integrity(unbuilt_lock.max_integrity * 0.5)
|
||||
unbuilt_lock.update_appearance()
|
||||
else
|
||||
new /obj/item/electronics/firelock (T)
|
||||
new /obj/item/electronics/firelock (targetloc)
|
||||
qdel(src)
|
||||
|
||||
|
||||
/obj/machinery/door/firedoor/proc/latetoggle()
|
||||
if(operating || machine_stat & NOPOWER || !nextstate)
|
||||
return
|
||||
switch(nextstate)
|
||||
if(FIREDOOR_OPEN)
|
||||
nextstate = null
|
||||
open()
|
||||
if(FIREDOOR_CLOSED)
|
||||
nextstate = null
|
||||
close()
|
||||
/obj/machinery/door/firedoor/closed
|
||||
icon_state = "door_closed"
|
||||
density = TRUE
|
||||
|
||||
/obj/machinery/door/firedoor/border_only
|
||||
icon = 'icons/obj/doors/edge_Doorfire.dmi'
|
||||
@@ -281,6 +491,25 @@
|
||||
)
|
||||
|
||||
AddElement(/datum/element/connect_loc, loc_connections)
|
||||
adjust_lights_starting_offset()
|
||||
|
||||
/obj/machinery/door/firedoor/border_only/adjust_lights_starting_offset()
|
||||
light_xoffset = 0
|
||||
light_yoffset = 0
|
||||
switch(dir)
|
||||
if(NORTH)
|
||||
light_yoffset = 2
|
||||
if(SOUTH)
|
||||
light_yoffset = -2
|
||||
if(EAST)
|
||||
light_xoffset = 2
|
||||
if(WEST)
|
||||
light_xoffset = -2
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/door/firedoor/border_only/Moved()
|
||||
. = ..()
|
||||
adjust_lights_starting_offset()
|
||||
|
||||
/obj/machinery/door/firedoor/border_only/CanAllowThrough(atom/movable/mover, border_dir)
|
||||
. = ..()
|
||||
@@ -306,7 +535,7 @@
|
||||
|
||||
/obj/machinery/door/firedoor/heavy
|
||||
name = "heavy firelock"
|
||||
icon = 'icons/obj/doors/Doorfire.dmi' //ICON OVERRIDEN IN SKYRAT AESTHETICS - SEE MODULE
|
||||
icon = 'icons/obj/doors/Doorfire.dmi' //SKYRAT EDIT - ICON OVERRIDEN IN AESTHETICS MODULE
|
||||
glass = FALSE
|
||||
explosion_block = 2
|
||||
assemblytype = /obj/structure/firelock_frame/heavy
|
||||
@@ -321,7 +550,7 @@
|
||||
/obj/structure/firelock_frame
|
||||
name = "firelock frame"
|
||||
desc = "A partially completed firelock."
|
||||
icon = 'icons/obj/doors/Doorfire.dmi' //ICON OVERRIDEN IN SKYRAT AESTHETICS - SEE MODULE
|
||||
icon = 'icons/obj/doors/Doorfire.dmi' //SKYRAT EDIT - ICON OVERRIDEN IN AESTHETICS MODULE
|
||||
icon_state = "frame1"
|
||||
base_icon_state = "frame"
|
||||
anchored = FALSE
|
||||
@@ -343,14 +572,14 @@
|
||||
icon_state = "[base_icon_state][constructionStep]"
|
||||
return ..()
|
||||
|
||||
/obj/structure/firelock_frame/attackby(obj/item/C, mob/user)
|
||||
/obj/structure/firelock_frame/attackby(obj/item/attacking_object, mob/user)
|
||||
switch(constructionStep)
|
||||
if(CONSTRUCTION_PANEL_OPEN)
|
||||
if(C.tool_behaviour == TOOL_CROWBAR)
|
||||
C.play_tool_sound(src)
|
||||
if(attacking_object.tool_behaviour == TOOL_CROWBAR)
|
||||
attacking_object.play_tool_sound(src)
|
||||
user.visible_message(span_notice("[user] begins removing the circuit board from [src]..."), \
|
||||
span_notice("You begin prying out the circuit board from [src]..."))
|
||||
if(!C.use_tool(src, user, DEFAULT_STEP_TIME))
|
||||
if(!attacking_object.use_tool(src, user, DEFAULT_STEP_TIME))
|
||||
return
|
||||
if(constructionStep != CONSTRUCTION_PANEL_OPEN)
|
||||
return
|
||||
@@ -361,14 +590,14 @@
|
||||
constructionStep = CONSTRUCTION_NO_CIRCUIT
|
||||
update_appearance()
|
||||
return
|
||||
if(C.tool_behaviour == TOOL_WRENCH)
|
||||
if(attacking_object.tool_behaviour == TOOL_WRENCH)
|
||||
if(locate(/obj/machinery/door/firedoor) in get_turf(src))
|
||||
to_chat(user, span_warning("There's already a firelock there."))
|
||||
return
|
||||
C.play_tool_sound(src)
|
||||
attacking_object.play_tool_sound(src)
|
||||
user.visible_message(span_notice("[user] starts bolting down [src]..."), \
|
||||
span_notice("You begin bolting [src]..."))
|
||||
if(!C.use_tool(src, user, DEFAULT_STEP_TIME))
|
||||
if(!attacking_object.use_tool(src, user, DEFAULT_STEP_TIME))
|
||||
return
|
||||
if(locate(/obj/machinery/door/firedoor) in get_turf(src))
|
||||
return
|
||||
@@ -381,61 +610,61 @@
|
||||
new /obj/machinery/door/firedoor(get_turf(src))
|
||||
qdel(src)
|
||||
return
|
||||
if(istype(C, /obj/item/stack/sheet/plasteel))
|
||||
var/obj/item/stack/sheet/plasteel/P = C
|
||||
if(istype(attacking_object, /obj/item/stack/sheet/plasteel))
|
||||
var/obj/item/stack/sheet/plasteel/plasteel_sheet = attacking_object
|
||||
if(reinforced)
|
||||
to_chat(user, span_warning("[src] is already reinforced."))
|
||||
return
|
||||
if(P.get_amount() < 2)
|
||||
if(plasteel_sheet.get_amount() < 2)
|
||||
to_chat(user, span_warning("You need more plasteel to reinforce [src]."))
|
||||
return
|
||||
user.visible_message(span_notice("[user] begins reinforcing [src]..."), \
|
||||
span_notice("You begin reinforcing [src]..."))
|
||||
playsound(get_turf(src), 'sound/items/deconstruct.ogg', 50, TRUE)
|
||||
if(do_after(user, DEFAULT_STEP_TIME, target = src))
|
||||
if(constructionStep != CONSTRUCTION_PANEL_OPEN || reinforced || P.get_amount() < 2 || !P)
|
||||
if(constructionStep != CONSTRUCTION_PANEL_OPEN || reinforced || plasteel_sheet.get_amount() < 2 || !plasteel_sheet)
|
||||
return
|
||||
user.visible_message(span_notice("[user] reinforces [src]."), \
|
||||
span_notice("You reinforce [src]."))
|
||||
playsound(get_turf(src), 'sound/items/deconstruct.ogg', 50, TRUE)
|
||||
P.use(2)
|
||||
plasteel_sheet.use(2)
|
||||
reinforced = 1
|
||||
return
|
||||
if(CONSTRUCTION_NO_CIRCUIT)
|
||||
if(istype(C, /obj/item/electronics/firelock))
|
||||
user.visible_message(span_notice("[user] starts adding [C] to [src]..."), \
|
||||
if(istype(attacking_object, /obj/item/electronics/firelock))
|
||||
user.visible_message(span_notice("[user] starts adding [attacking_object] to [src]..."), \
|
||||
span_notice("You begin adding a circuit board to [src]..."))
|
||||
playsound(get_turf(src), 'sound/items/deconstruct.ogg', 50, TRUE)
|
||||
if(!do_after(user, DEFAULT_STEP_TIME, target = src))
|
||||
return
|
||||
if(constructionStep != CONSTRUCTION_NO_CIRCUIT)
|
||||
return
|
||||
qdel(C)
|
||||
qdel(attacking_object)
|
||||
user.visible_message(span_notice("[user] adds a circuit to [src]."), \
|
||||
span_notice("You insert and secure [C]."))
|
||||
span_notice("You insert and secure [attacking_object]."))
|
||||
playsound(get_turf(src), 'sound/items/deconstruct.ogg', 50, TRUE)
|
||||
constructionStep = CONSTRUCTION_PANEL_OPEN
|
||||
return
|
||||
if(C.tool_behaviour == TOOL_WELDER)
|
||||
if(!C.tool_start_check(user, amount=1))
|
||||
if(attacking_object.tool_behaviour == TOOL_WELDER)
|
||||
if(!attacking_object.tool_start_check(user, amount=1))
|
||||
return
|
||||
user.visible_message(span_notice("[user] begins cutting apart [src]'s frame..."), \
|
||||
span_notice("You begin slicing [src] apart..."))
|
||||
|
||||
if(C.use_tool(src, user, DEFAULT_STEP_TIME, volume=50, amount=1))
|
||||
if(attacking_object.use_tool(src, user, DEFAULT_STEP_TIME, volume=50, amount=1))
|
||||
if(constructionStep != CONSTRUCTION_NO_CIRCUIT)
|
||||
return
|
||||
user.visible_message(span_notice("[user] cuts apart [src]!"), \
|
||||
span_notice("You cut [src] into metal."))
|
||||
var/turf/T = get_turf(src)
|
||||
new /obj/item/stack/sheet/iron(T, 3)
|
||||
var/turf/tagetloc = get_turf(src)
|
||||
new /obj/item/stack/sheet/iron(tagetloc, 3)
|
||||
if(reinforced)
|
||||
new /obj/item/stack/sheet/plasteel(T, 2)
|
||||
new /obj/item/stack/sheet/plasteel(tagetloc, 2)
|
||||
qdel(src)
|
||||
return
|
||||
if(istype(C, /obj/item/electroadaptive_pseudocircuit))
|
||||
var/obj/item/electroadaptive_pseudocircuit/P = C
|
||||
if(!P.adapt_circuit(user, DEFAULT_STEP_TIME * 0.5))
|
||||
if(istype(attacking_object, /obj/item/electroadaptive_pseudocircuit))
|
||||
var/obj/item/electroadaptive_pseudocircuit/raspberrypi = attacking_object
|
||||
if(!raspberrypi.adapt_circuit(user, DEFAULT_STEP_TIME * 0.5))
|
||||
return
|
||||
user.visible_message(span_notice("[user] fabricates a circuit and places it into [src]."), \
|
||||
span_notice("You adapt a firelock circuit and slot it into the assembly."))
|
||||
@@ -471,3 +700,4 @@
|
||||
|
||||
#undef CONSTRUCTION_PANEL_OPEN
|
||||
#undef CONSTRUCTION_NO_CIRCUIT
|
||||
#undef DETECT_COOLDOWN_STEP_TIME
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
#define FIREALARM_COOLDOWN 80 //SKYRAT EDIT CHANGE - ORIGINAL: 96 - AESTHETIC // This define is based on the current FireAlarm.ogg, and is placed to match the running time at 9 seconds 600 milliseconds (9.6 seconds)
|
||||
|
||||
/obj/item/electronics/firealarm
|
||||
name = "fire alarm electronics"
|
||||
desc = "A fire alarm circuit. Can handle heat levels up to 40 degrees celsius."
|
||||
@@ -7,7 +5,7 @@
|
||||
/obj/item/wallframe/firealarm
|
||||
name = "fire alarm frame"
|
||||
desc = "Used for building fire alarms."
|
||||
icon = 'icons/obj/monitors.dmi' //ICON OVERRIDEN IN SKYRAT AESTHETICS - SEE MODULE
|
||||
icon = 'icons/obj/monitors.dmi'
|
||||
icon_state = "fire_bitem"
|
||||
result_path = /obj/machinery/firealarm
|
||||
pixel_shift = 26
|
||||
@@ -15,7 +13,7 @@
|
||||
/obj/machinery/firealarm
|
||||
name = "fire alarm"
|
||||
desc = "<i>\"Pull this in case of emergency\"</i>. Thus, keep pulling it forever."
|
||||
icon = 'icons/obj/monitors.dmi' //ICON OVERRIDEN IN SKYRAT AESTHETICS - SEE MODULE
|
||||
icon = 'icons/obj/monitors.dmi'
|
||||
icon_state = "fire0"
|
||||
max_integrity = 250
|
||||
integrity_failure = 0.4
|
||||
@@ -32,15 +30,13 @@
|
||||
|
||||
//Trick to get the glowing overlay visible from a distance
|
||||
luminosity = 1
|
||||
///Buildstate for contruction steps. 2 = complete, 1 = no wires, 0 = circuit gone
|
||||
var/buildstage = 2
|
||||
///Our home area, set in Init. Due to loading step order, this seems to be null very early in the server setup process, which is why some procs use `my_area?` for var or list checks.
|
||||
var/area/my_area = null
|
||||
///looping sound datum for our fire alarm siren.
|
||||
var/datum/looping_sound/firealarm/soundloop
|
||||
|
||||
var/detecting = 1
|
||||
var/buildstage = 2 // 2 = complete, 1 = no wires, 0 = circuit gone
|
||||
COOLDOWN_DECLARE(last_alarm)
|
||||
var/area/myarea = null
|
||||
//Has this firealarm been triggered by its enviroment?
|
||||
var/triggered = FALSE
|
||||
|
||||
/* SKYRAT EDIT REMOVAL
|
||||
/obj/machinery/firealarm/Initialize(mapload, dir, building)
|
||||
. = ..()
|
||||
if(building)
|
||||
@@ -49,18 +45,34 @@
|
||||
if(name == initial(name))
|
||||
name = "[get_area_name(src)] [initial(name)]"
|
||||
update_appearance()
|
||||
myarea = get_area(src)
|
||||
LAZYADD(myarea.firealarms, src)
|
||||
my_area = get_area(src)
|
||||
LAZYADD(my_area.firealarms, src)
|
||||
|
||||
AddElement(/datum/element/atmos_sensitive, mapload)
|
||||
RegisterSignal(SSsecurity_level, COMSIG_SECURITY_LEVEL_CHANGED, .proc/check_security_level)
|
||||
|
||||
soundloop = new(src, FALSE)
|
||||
|
||||
/obj/machinery/firealarm/Destroy()
|
||||
myarea.firereset(src)
|
||||
LAZYREMOVE(myarea.firealarms, src)
|
||||
if(my_area)
|
||||
LAZYREMOVE(my_area.firealarms, src)
|
||||
my_area = null
|
||||
QDEL_NULL(soundloop)
|
||||
return ..()
|
||||
*/
|
||||
|
||||
/**
|
||||
* Sets the sound state, and then calls update_icon()
|
||||
*
|
||||
* This proc exists to be called by areas and firelocks
|
||||
* so that it may update its icon and start or stop playing
|
||||
* the alarm sound based on the state of an area variable.
|
||||
*/
|
||||
/obj/machinery/firealarm/proc/set_status()
|
||||
if( (my_area.fire || LAZYLEN(my_area.active_firelocks)) && !(obj_flags & EMAGGED) )
|
||||
set_light(l_power = 0.8)
|
||||
else
|
||||
soundloop.stop()
|
||||
set_light(l_power = 0)
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/firealarm/update_icon_state()
|
||||
if(panel_open)
|
||||
@@ -87,12 +99,11 @@
|
||||
. += mutable_appearance(icon, "fire_[SEC_LEVEL_GREEN]")
|
||||
. += emissive_appearance(icon, "fire_[SEC_LEVEL_GREEN]", alpha = src.alpha)
|
||||
|
||||
var/area/area = get_area(src)
|
||||
|
||||
if(!detecting || !area.fire)
|
||||
. += "fire_off"
|
||||
. += mutable_appearance(icon, "fire_off")
|
||||
. += emissive_appearance(icon, "fire_off", alpha = src.alpha)
|
||||
if(!(my_area?.fire || LAZYLEN(my_area?.active_firelocks)))
|
||||
if(my_area?.fire_detect) //If this is false, leave the green light missing. A good hint to anyone paying attention.
|
||||
. += "fire_off"
|
||||
. += mutable_appearance(icon, "fire_off")
|
||||
. += emissive_appearance(icon, "fire_off", alpha = src.alpha)
|
||||
else if(obj_flags & EMAGGED)
|
||||
. += "fire_emagged"
|
||||
. += mutable_appearance(icon, "fire_emagged")
|
||||
@@ -102,7 +113,7 @@
|
||||
. += mutable_appearance(icon, "fire_on")
|
||||
. += emissive_appearance(icon, "fire_on", alpha = src.alpha)
|
||||
|
||||
if(!panel_open && detecting && triggered) //It just looks horrible with the panel open
|
||||
if(!panel_open && my_area?.fire_detect && my_area?.fire) //It just looks horrible with the panel open
|
||||
. += "fire_detected"
|
||||
. += mutable_appearance(icon, "fire_detected")
|
||||
. += emissive_appearance(icon, "fire_detected", alpha = src.alpha) //Pain
|
||||
@@ -123,30 +134,9 @@
|
||||
update_appearance()
|
||||
if(user)
|
||||
user.visible_message(span_warning("Sparks fly out of [src]!"),
|
||||
span_notice("You emag [src], disabling its thermal sensors."))
|
||||
span_notice("You override [src], disabling the speaker."))
|
||||
playsound(src, "sparks", 50, TRUE, SHORT_RANGE_SOUND_EXTRARANGE)
|
||||
|
||||
/* SKYRAT EDIT REMOVAL
|
||||
/obj/machinery/firealarm/should_atmos_process(datum/gas_mixture/air, exposed_temperature)
|
||||
return (exposed_temperature > T0C + 200 || exposed_temperature < BODYTEMP_COLD_DAMAGE_LIMIT) && !(obj_flags & EMAGGED) && !machine_stat
|
||||
|
||||
/obj/machinery/firealarm/atmos_expose(datum/gas_mixture/air, exposed_temperature)
|
||||
if(!detecting)
|
||||
return
|
||||
if(!triggered)
|
||||
triggered = TRUE
|
||||
myarea.triggered_firealarms += 1
|
||||
update_appearance()
|
||||
alarm()
|
||||
|
||||
/obj/machinery/firealarm/atmos_end()
|
||||
if(!detecting)
|
||||
return
|
||||
if(triggered)
|
||||
triggered = FALSE
|
||||
myarea.triggered_firealarms -= 1
|
||||
update_appearance()
|
||||
*/
|
||||
set_status()
|
||||
|
||||
/**
|
||||
* Signal handler for checking if we should update fire alarm appearance accordingly to a newly set security level
|
||||
@@ -161,45 +151,69 @@
|
||||
if(is_station_level(z))
|
||||
update_appearance()
|
||||
|
||||
/*SKYRAT EDIT REMOVAL
|
||||
/**
|
||||
* Sounds the fire alarm and closes all firelocks in the area. Also tells the area to color the lights red.
|
||||
*
|
||||
* Arguments:
|
||||
* * mob/user is the user that pulled the alarm.
|
||||
*/
|
||||
/obj/machinery/firealarm/proc/alarm(mob/user)
|
||||
if(!is_operational || !COOLDOWN_FINISHED(src, last_alarm))
|
||||
if(!is_operational)
|
||||
return
|
||||
COOLDOWN_START(src, last_alarm, FIREALARM_COOLDOWN)
|
||||
var/area/area = get_area(src)
|
||||
area.firealert(src)
|
||||
//playsound(loc, 'sound/machines/FireAlarm.ogg', 96) ORIGINAL
|
||||
playsound(loc, alarm_sound, 75) //SKYRAT EDIT CHANGE - AESTHETICS
|
||||
|
||||
if(my_area.fire)
|
||||
return //area alarm already active
|
||||
my_area.alarm_manager.send_alarm(ALARM_FIRE, my_area)
|
||||
my_area.set_fire_alarm_effect()
|
||||
for(var/obj/machinery/door/firedoor/firelock in my_area.firedoors)
|
||||
firelock.activate(FIRELOCK_ALARM_TYPE_GENERIC)
|
||||
if(user)
|
||||
log_game("[user] triggered a fire alarm at [COORD(src)]")
|
||||
soundloop.start() //Manually pulled fire alarms will make the sound, rather than the doors.
|
||||
|
||||
/**
|
||||
* Resets all firelocks in the area. Also tells the area to disable alarm lighting, if it was enabled.
|
||||
*
|
||||
* Arguments:
|
||||
* * mob/user is the user that reset the alarm.
|
||||
*/
|
||||
/obj/machinery/firealarm/proc/reset(mob/user)
|
||||
if(!is_operational)
|
||||
return
|
||||
var/area/area = get_area(src)
|
||||
area.firereset()
|
||||
my_area.unset_fire_alarm_effects()
|
||||
for(var/obj/machinery/door/firedoor/firelock in my_area.firedoors)
|
||||
firelock.reset()
|
||||
my_area.alarm_manager.clear_alarm(ALARM_FIRE, my_area)
|
||||
if(user)
|
||||
log_game("[user] reset a fire alarm at [COORD(src)]")
|
||||
soundloop.stop()
|
||||
|
||||
/obj/machinery/firealarm/attack_hand(mob/user, list/modifiers)
|
||||
if(buildstage != 2)
|
||||
return
|
||||
. = ..()
|
||||
add_fingerprint(user)
|
||||
var/area/area = get_area(src)
|
||||
if(area.fire)
|
||||
reset(user)
|
||||
else
|
||||
alarm(user)
|
||||
*/
|
||||
alarm(user)
|
||||
|
||||
/obj/machinery/firealarm/attack_hand_secondary(mob/user, list/modifiers)
|
||||
if(buildstage != 2)
|
||||
return ..()
|
||||
add_fingerprint(user)
|
||||
reset(user)
|
||||
return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN
|
||||
|
||||
/obj/machinery/firealarm/attack_ai(mob/user)
|
||||
return attack_hand(user)
|
||||
|
||||
/obj/machinery/firealarm/attack_ai_secondary(mob/user)
|
||||
return attack_hand_secondary(user)
|
||||
|
||||
/obj/machinery/firealarm/attack_robot(mob/user)
|
||||
return attack_hand(user)
|
||||
|
||||
/*SKYRAT EDIT REMOVAL
|
||||
/obj/machinery/firealarm/attack_robot_secondary(mob/user)
|
||||
return attack_hand_secondary(user)
|
||||
|
||||
/obj/machinery/firealarm/attackby(obj/item/tool, mob/living/user, params)
|
||||
add_fingerprint(user)
|
||||
|
||||
@@ -227,15 +241,7 @@
|
||||
|
||||
switch(buildstage)
|
||||
if(2)
|
||||
if(tool.tool_behaviour == TOOL_MULTITOOL)
|
||||
detecting = !detecting
|
||||
if (src.detecting)
|
||||
user.visible_message(span_notice("[user] reconnects [src]'s detecting unit!"), span_notice("You reconnect [src]'s detecting unit."))
|
||||
else
|
||||
user.visible_message(span_notice("[user] disconnects [src]'s detecting unit!"), span_notice("You disconnect [src]'s detecting unit."))
|
||||
return
|
||||
|
||||
else if(tool.tool_behaviour == TOOL_WIRECUTTER)
|
||||
if(tool.tool_behaviour == TOOL_WIRECUTTER)
|
||||
buildstage = 1
|
||||
tool.play_tool_sound(src)
|
||||
new /obj/item/stack/cable_coil(user.loc, 5)
|
||||
@@ -302,9 +308,7 @@
|
||||
tool.play_tool_sound(src)
|
||||
qdel(src)
|
||||
return
|
||||
|
||||
return ..()
|
||||
*/
|
||||
|
||||
/obj/machinery/firealarm/rcd_vals(mob/user, obj/item/construction/rcd/the_rcd)
|
||||
if((buildstage == 0) && (the_rcd.upgrade & RCD_UPGRADE_SIMPLE_CIRCUITS))
|
||||
@@ -331,16 +335,12 @@
|
||||
/obj/machinery/firealarm/singularity_pull(S, current_size)
|
||||
if (current_size >= STAGE_FIVE) // If the singulo is strong enough to pull anchored objects, the fire alarm experiences integrity failure
|
||||
deconstruct()
|
||||
..()
|
||||
return ..()
|
||||
|
||||
/* SKYRAT EDIT REMOVAL
|
||||
/obj/machinery/firealarm/atom_break(damage_flag)
|
||||
if(buildstage == 0) //can't break the electronics if there isn't any inside.
|
||||
return
|
||||
. = ..()
|
||||
if(.)
|
||||
LAZYREMOVE(myarea.firealarms, src)
|
||||
*/
|
||||
return ..()
|
||||
|
||||
/obj/machinery/firealarm/deconstruct(disassembled = TRUE)
|
||||
if(!(flags_1 & NODECONSTRUCT_1))
|
||||
@@ -352,18 +352,16 @@
|
||||
new /obj/item/stack/cable_coil(loc, 3)
|
||||
qdel(src)
|
||||
|
||||
/obj/machinery/firealarm/proc/update_fire_light(fire)
|
||||
if(fire == !!light_power)
|
||||
return // do nothing if we're already active
|
||||
if(fire)
|
||||
set_light(l_power = 0.8)
|
||||
else
|
||||
set_light(l_power = 0)
|
||||
|
||||
// Allows users to examine the state of the thermal sensor
|
||||
/obj/machinery/firealarm/examine(mob/user)
|
||||
. = ..()
|
||||
. += "A light on the side indicates the thermal sensor is [detecting ? "enabled" : "disabled"]."
|
||||
if((my_area?.fire || LAZYLEN(my_area?.active_firelocks)))
|
||||
. += "The local area hazard light is flashing."
|
||||
. += "<b>Left-Click</b> to activate all firelocks in this area."
|
||||
. += "<b>Right-Click</b> or <b>Alt-Click</b> to reset firelocks in this area."
|
||||
else
|
||||
. += "The local area thermal detection light is [my_area.fire_detect ? "lit" : "unlit"]."
|
||||
. += "<b>Left-Click</b> to activate all firelocks in this area."
|
||||
|
||||
// Allows Silicons to disable thermal sensor
|
||||
/obj/machinery/firealarm/BorgCtrlClick(mob/living/silicon/robot/user)
|
||||
@@ -376,8 +374,11 @@
|
||||
if(obj_flags & EMAGGED)
|
||||
to_chat(user, span_warning("The control circuitry of [src] appears to be malfunctioning."))
|
||||
return
|
||||
detecting = !detecting
|
||||
to_chat(user, span_notice("You [ detecting ? "enable" : "disable" ] [src]'s detecting unit!"))
|
||||
my_area.fire_detect = !my_area.fire_detect
|
||||
for(var/obj/machinery/firealarm/fire_panel in my_area.firealarms)
|
||||
fire_panel.update_icon()
|
||||
to_chat(user, span_notice("You [ my_area.fire_detect ? "enable" : "disable" ] the local firelock thermal sensors!"))
|
||||
log_game("[user] has [ my_area.fire_detect ? "enabled" : "disabled" ] firelock sensors using [src] at [COORD(src)]")
|
||||
|
||||
MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/firealarm, 26)
|
||||
|
||||
|
||||
@@ -91,7 +91,7 @@ again.
|
||||
/obj/effect/spawner/structure/window/reinforced
|
||||
name = "reinforced window spawner"
|
||||
icon_state = "rwindow_spawner"
|
||||
spawn_list = list(/obj/machinery/door/firedoor/onetile, /obj/structure/grille, /obj/structure/window/reinforced/fulltile) //SKYRAT EDIT CHANGE
|
||||
spawn_list = list(/obj/machinery/door/firedoor, /obj/structure/grille, /obj/structure/window/reinforced/fulltile) //SKYRAT EDIT CHANGE
|
||||
|
||||
/obj/effect/spawner/structure/window/hollow/reinforced
|
||||
name = "hollow reinforced window spawner"
|
||||
|
||||
@@ -61,7 +61,7 @@
|
||||
|
||||
/obj/item/card/emag/Initialize(mapload)
|
||||
. = ..()
|
||||
type_blacklist = list(typesof(/obj/machinery/door/airlock), typesof(/obj/machinery/door/window/)) //list of all typepaths that require a specialized emag to hack.
|
||||
type_blacklist = list(typesof(/obj/machinery/door/airlock), typesof(/obj/machinery/door/window/), typesof(/obj/machinery/door/firedoor)) //list of all typepaths that require a specialized emag to hack.
|
||||
|
||||
/obj/item/card/emag/attack()
|
||||
return
|
||||
@@ -101,7 +101,7 @@
|
||||
|
||||
/obj/item/card/emag/doorjack/Initialize(mapload)
|
||||
. = ..()
|
||||
type_whitelist = list(typesof(/obj/machinery/door/airlock), typesof(/obj/machinery/door/window/)) //list of all acceptable typepaths that this device can affect
|
||||
type_whitelist = list(typesof(/obj/machinery/door/airlock), typesof(/obj/machinery/door/window/), typesof(/obj/machinery/door/firedoor)) //list of all acceptable typepaths that this device can affect
|
||||
|
||||
/obj/item/card/emag/doorjack/proc/use_charge(mob/user)
|
||||
charges --
|
||||
|
||||
@@ -697,11 +697,15 @@ GLOBAL_LIST_INIT(malf_modules, subtypesof(/datum/ai_module))
|
||||
uses = 1
|
||||
|
||||
/datum/action/innate/ai/break_fire_alarms/Activate()
|
||||
for(var/obj/machinery/firealarm/F in GLOB.machines)
|
||||
if(!is_station_level(F.z))
|
||||
for(var/obj/machinery/firealarm/bellman in GLOB.machines)
|
||||
if(!is_station_level(bellman.z))
|
||||
continue
|
||||
F.obj_flags |= EMAGGED
|
||||
F.update_appearance()
|
||||
bellman.obj_flags |= EMAGGED
|
||||
bellman.update_appearance()
|
||||
for(var/obj/machinery/door/firedoor/firelock in GLOB.machines)
|
||||
if(!is_station_level(firelock.z))
|
||||
continue
|
||||
firelock.emag_act(owner_AI, src)
|
||||
to_chat(owner, span_notice("All thermal sensors on the station have been disabled. Fire alerts will no longer be recognized."))
|
||||
owner.playsound_local(owner, 'sound/machines/terminal_off.ogg', 50, 0)
|
||||
|
||||
|
||||
|
Before Width: | Height: | Size: 7.5 KiB After Width: | Height: | Size: 7.8 KiB |
|
Before Width: | Height: | Size: 5.2 KiB After Width: | Height: | Size: 5.3 KiB |
|
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 20 KiB |
@@ -1,199 +1,2 @@
|
||||
/obj/machinery/firealarm
|
||||
icon = 'modular_skyrat/modules/aesthetics/firealarm/icons/firealarm.dmi'
|
||||
var/alarm_sound = 'modular_skyrat/modules/aesthetics/firealarm/sound/alarm_fire.ogg'
|
||||
|
||||
/obj/machinery/firealarm/Initialize(mapload, dir, building)
|
||||
. = ..()
|
||||
if(dir)
|
||||
src.setDir(dir)
|
||||
if(building)
|
||||
buildstage = 0
|
||||
panel_open = TRUE
|
||||
pixel_x = (dir & 3)? 0 : (dir == 4 ? -24 : 24)
|
||||
pixel_y = (dir & 3)? (dir ==1 ? -24 : 24) : 0
|
||||
if(name == initial(name))
|
||||
name = "[get_area_name(src)] [initial(name)]"
|
||||
|
||||
RegisterSignal(SSsecurity_level, COMSIG_SECURITY_LEVEL_CHANGED, .proc/check_security_level)
|
||||
|
||||
gather_objects()
|
||||
|
||||
update_appearance()
|
||||
|
||||
/obj/machinery/firealarm/proc/gather_objects()
|
||||
var/area/my_area = get_area(src)
|
||||
|
||||
for(var/obj/machinery/light/iterating_light in my_area)
|
||||
iterating_light.RegisterSignal(src, COMSIG_FIREALARM_TRIGGERED_ON, /obj/machinery/light.proc/firealarm_on)
|
||||
iterating_light.RegisterSignal(src, COMSIG_FIREALARM_TRIGGERED_OFF, /obj/machinery/light.proc/firealarm_off)
|
||||
|
||||
for(var/obj/machinery/door/firedoor/iterating_firedoor in my_area)
|
||||
iterating_firedoor.RegisterSignal(src, COMSIG_FIREALARM_TRIGGER_DOORS, /obj/machinery/door/firedoor.proc/firealarm_on)
|
||||
iterating_firedoor.RegisterSignal(src, COMSIG_FIREALARM_TRIGGERED_OFF, /obj/machinery/door/firedoor.proc/firealarm_off)
|
||||
|
||||
for(var/obj/machinery/firealarm/iterating_firealarm in my_area)
|
||||
if(iterating_firealarm == src) //Bad infinite loops.
|
||||
continue
|
||||
iterating_firealarm.RegisterSignal(src, COMSIG_FIREALARM_TRIGGERED_ON, .proc/area_alarm_on)
|
||||
iterating_firealarm.RegisterSignal(src, COMSIG_FIREALARM_TRIGGERED_OFF, .proc/area_alarm_off)
|
||||
|
||||
/obj/machinery/firealarm/proc/area_alarm_on()
|
||||
SIGNAL_HANDLER
|
||||
|
||||
triggered = TRUE
|
||||
update_fire_light(TRUE)
|
||||
update_appearance()
|
||||
|
||||
/obj/machinery/firealarm/proc/area_alarm_off()
|
||||
SIGNAL_HANDLER
|
||||
|
||||
triggered = FALSE
|
||||
update_fire_light(FALSE)
|
||||
update_appearance()
|
||||
|
||||
/obj/machinery/firealarm/proc/alarm(mob/user)
|
||||
if(triggered)
|
||||
return
|
||||
triggered = TRUE
|
||||
if(!is_operational || !COOLDOWN_FINISHED(src, last_alarm))
|
||||
return
|
||||
COOLDOWN_START(src, last_alarm, FIREALARM_COOLDOWN)
|
||||
playsound(loc, alarm_sound, 75)
|
||||
if(user)
|
||||
log_game("[user] triggered a fire alarm at [COORD(src)]")
|
||||
trigger_effects()
|
||||
trigger_doors()
|
||||
update_appearance()
|
||||
|
||||
/obj/machinery/firealarm/proc/trigger_doors()
|
||||
SEND_SIGNAL(src, COMSIG_FIREALARM_TRIGGER_DOORS)
|
||||
|
||||
/obj/machinery/firealarm/proc/trigger_effects()
|
||||
SIGNAL_HANDLER
|
||||
SEND_SIGNAL(src, COMSIG_FIREALARM_TRIGGERED_ON)
|
||||
|
||||
/obj/machinery/firealarm/proc/untrigger_effects()
|
||||
SEND_SIGNAL(src, COMSIG_FIREALARM_TRIGGERED_OFF)
|
||||
|
||||
/obj/machinery/firealarm/proc/reset(mob/user)
|
||||
if(!is_operational)
|
||||
return
|
||||
if(user)
|
||||
log_game("[user] reset a fire alarm at [COORD(src)]")
|
||||
triggered = FALSE
|
||||
untrigger_effects()
|
||||
update_appearance()
|
||||
|
||||
/obj/machinery/firealarm/attack_hand(mob/user, list/modifiers)
|
||||
if(buildstage != 2)
|
||||
return ..()
|
||||
add_fingerprint(user)
|
||||
if(triggered)
|
||||
reset(user)
|
||||
else
|
||||
alarm(user, TRUE)
|
||||
|
||||
/obj/machinery/firealarm/attackby(obj/item/tool, mob/living/user, params)
|
||||
add_fingerprint(user)
|
||||
|
||||
if(tool.tool_behaviour == TOOL_SCREWDRIVER && buildstage == 2)
|
||||
tool.play_tool_sound(src)
|
||||
panel_open = !panel_open
|
||||
to_chat(user, span_notice("The wires have been [panel_open ? "exposed" : "unexposed"]."))
|
||||
update_appearance()
|
||||
return
|
||||
|
||||
if(panel_open)
|
||||
|
||||
if(tool.tool_behaviour == TOOL_WELDER && !user.combat_mode)
|
||||
if(atom_integrity < max_integrity)
|
||||
if(!tool.tool_start_check(user, amount=0))
|
||||
return
|
||||
|
||||
to_chat(user, span_notice("You begin repairing [src]..."))
|
||||
if(tool.use_tool(src, user, 40, volume=50))
|
||||
atom_integrity = max_integrity
|
||||
to_chat(user, span_notice("You repair [src]."))
|
||||
else
|
||||
to_chat(user, span_warning("[src] is already in good condition!"))
|
||||
return
|
||||
|
||||
switch(buildstage)
|
||||
if(2)
|
||||
if(tool.tool_behaviour == TOOL_MULTITOOL)
|
||||
detecting = !detecting
|
||||
if (src.detecting)
|
||||
user.visible_message(span_notice("[user] reconnects [src]'s detecting unit!"), span_notice("You reconnect [src]'s detecting unit."))
|
||||
else
|
||||
user.visible_message(span_notice("[user] disconnects [src]'s detecting unit!"), span_notice("You disconnect [src]'s detecting unit."))
|
||||
return
|
||||
|
||||
else if(tool.tool_behaviour == TOOL_WIRECUTTER)
|
||||
buildstage = 1
|
||||
tool.play_tool_sound(src)
|
||||
new /obj/item/stack/cable_coil(user.loc, 5)
|
||||
to_chat(user, span_notice("You cut the wires from \the [src]."))
|
||||
update_appearance()
|
||||
return
|
||||
|
||||
else if(tool.force) //hit and turn it on
|
||||
..()
|
||||
if(!triggered)
|
||||
alarm()
|
||||
return
|
||||
|
||||
if(1)
|
||||
if(istype(tool, /obj/item/stack/cable_coil))
|
||||
var/obj/item/stack/cable_coil/coil = tool
|
||||
if(coil.get_amount() < 5)
|
||||
to_chat(user, span_warning("You need more cable for this!"))
|
||||
else
|
||||
coil.use(5)
|
||||
buildstage = 2
|
||||
to_chat(user, span_notice("You wire \the [src]."))
|
||||
update_appearance()
|
||||
return
|
||||
|
||||
else if(tool.tool_behaviour == TOOL_CROWBAR)
|
||||
user.visible_message(span_notice("[user.name] removes the electronics from [src.name]."), \
|
||||
span_notice("You start prying out the circuit..."))
|
||||
if(tool.use_tool(src, user, 20, volume=50))
|
||||
if(buildstage == 1)
|
||||
if(machine_stat & BROKEN)
|
||||
to_chat(user, span_notice("You remove the destroyed circuit."))
|
||||
set_machine_stat(machine_stat & ~BROKEN)
|
||||
else
|
||||
to_chat(user, span_notice("You pry out the circuit."))
|
||||
new /obj/item/electronics/firealarm(user.loc)
|
||||
buildstage = 0
|
||||
update_appearance()
|
||||
return
|
||||
if(0)
|
||||
if(istype(tool, /obj/item/electronics/firealarm))
|
||||
to_chat(user, span_notice("You insert the circuit."))
|
||||
qdel(tool)
|
||||
buildstage = 1
|
||||
update_appearance()
|
||||
return
|
||||
|
||||
else if(istype(tool, /obj/item/electroadaptive_pseudocircuit))
|
||||
var/obj/item/electroadaptive_pseudocircuit/pseudoc = tool
|
||||
if(!pseudoc.adapt_circuit(user, 15))
|
||||
return
|
||||
user.visible_message(span_notice("[user] fabricates a circuit and places it into [src]."), \
|
||||
span_notice("You adapt a fire alarm circuit and slot it into the assembly."))
|
||||
buildstage = 1
|
||||
update_appearance()
|
||||
return
|
||||
|
||||
else if(tool.tool_behaviour == TOOL_WRENCH)
|
||||
user.visible_message(span_notice("[user] removes the fire alarm assembly from the wall."), \
|
||||
span_notice("You remove the fire alarm assembly from the wall."))
|
||||
var/obj/item/wallframe/firealarm/frame = new /obj/item/wallframe/firealarm()
|
||||
frame.forceMove(user.drop_location())
|
||||
tool.play_tool_sound(src)
|
||||
qdel(src)
|
||||
return
|
||||
|
||||
return ..()
|
||||
|
||||
|
||||
@@ -1,116 +1,9 @@
|
||||
#define FIREDOOR_CLOSE_OVERRIDE_RESET_TIME 3 MINUTES
|
||||
|
||||
/obj/machinery/door/firedoor
|
||||
name = "emergency shutter"
|
||||
desc = "Emergency air-tight shutter, capable of sealing off breached areas. This one has a glass panel. It has a mechanism to open it with just your hands."
|
||||
icon = 'modular_skyrat/modules/aesthetics/firedoor/icons/firedoor_glass.dmi'
|
||||
|
||||
req_access = list(ACCESS_ATMOSPHERICS)
|
||||
|
||||
var/door_open_sound = 'modular_skyrat/modules/aesthetics/firedoor/sound/firedoor_open.ogg'
|
||||
var/door_close_sound = 'modular_skyrat/modules/aesthetics/firedoor/sound/firedoor_open.ogg'
|
||||
var/hot_or_cold = FALSE //True for hot, false for cold
|
||||
|
||||
var/stay_open = FALSE // Do we stay open? Triggered via atmos techs using their ID on it.
|
||||
var/has_hotcold_sprite = TRUE //does it actually have the sprites needed
|
||||
|
||||
/obj/machinery/door/firedoor/heavy
|
||||
name = "heavy emergency shutter"
|
||||
desc = "Emergency air-tight shutter, capable of sealing off breached areas. It has a mechanism to open it with just your hands."
|
||||
icon = 'modular_skyrat/modules/aesthetics/firedoor/icons/firedoor.dmi'
|
||||
|
||||
/obj/structure/firelock_frame
|
||||
icon = 'modular_skyrat/modules/aesthetics/firedoor/icons/firedoor.dmi'
|
||||
|
||||
/obj/machinery/door/firedoor/border_only
|
||||
has_hotcold_sprite = FALSE
|
||||
|
||||
/obj/machinery/door/firedoor/open()
|
||||
playsound(loc, door_open_sound, 90, TRUE)
|
||||
. = ..()
|
||||
|
||||
/obj/machinery/door/firedoor/close()
|
||||
if(stay_open)
|
||||
return
|
||||
playsound(loc, door_close_sound, 90, TRUE)
|
||||
return ..()
|
||||
|
||||
/obj/machinery/door/firedoor/proc/atmos_changed(datum/source, datum/gas_mixture/air, exposed_temperature)
|
||||
if(density)
|
||||
return
|
||||
var/pressure = air.return_pressure()
|
||||
if(exposed_temperature < BODYTEMP_COLD_DAMAGE_LIMIT || pressure < WARNING_LOW_PRESSURE)
|
||||
hot_or_cold = FALSE
|
||||
close()
|
||||
else if(exposed_temperature > BODYTEMP_HEAT_DAMAGE_LIMIT || pressure > WARNING_HIGH_PRESSURE)
|
||||
hot_or_cold = TRUE
|
||||
trigger_hot()
|
||||
close()
|
||||
|
||||
/obj/machinery/door/firedoor/proc/firealarm_on()
|
||||
SIGNAL_HANDLER
|
||||
INVOKE_ASYNC(src, .proc/close)
|
||||
|
||||
/obj/machinery/door/firedoor/proc/firealarm_off()
|
||||
SIGNAL_HANDLER
|
||||
INVOKE_ASYNC(src, .proc/open)
|
||||
|
||||
/obj/machinery/door/firedoor/proc/trigger_hot()
|
||||
SEND_SIGNAL(src, COMSIG_FIREDOOR_CLOSED_FIRE)
|
||||
|
||||
/obj/machinery/door/firedoor/proc/CalculateAffectingAreas()
|
||||
for(var/turf/adjacent_turf in range(1, src))
|
||||
RegisterSignal(adjacent_turf, COMSIG_TURF_EXPOSE, .proc/atmos_changed, override = TRUE)
|
||||
|
||||
var/my_area = get_area(src)
|
||||
|
||||
for(var/obj/machinery/firealarm/iterating_alarm in my_area)
|
||||
iterating_alarm.RegisterSignal(src, COMSIG_FIREDOOR_CLOSED_FIRE, /obj/machinery/firealarm.proc/trigger_effects, override = TRUE) //We trigger the alarms automatically.
|
||||
|
||||
/obj/machinery/door/firedoor/update_icon_state()
|
||||
. = ..()
|
||||
if(density)
|
||||
icon_state = "[base_icon_state]_closed[has_hotcold_sprite ? (hot_or_cold ? "_hot" : "_cold") : ""]"
|
||||
else
|
||||
icon_state = "[base_icon_state]_open"
|
||||
|
||||
/obj/machinery/door/firedoor/onetile/CalculateAffectingAreas()
|
||||
RegisterSignal(loc, COMSIG_TURF_EXPOSE, .proc/atmos_changed, override = TRUE)
|
||||
|
||||
var/my_area = get_area(src)
|
||||
|
||||
for(var/obj/machinery/firealarm/iterating_alarm in my_area)
|
||||
iterating_alarm.RegisterSignal(src, COMSIG_FIREDOOR_CLOSED_FIRE, /obj/machinery/firealarm.proc/trigger_effects, override = TRUE) //We trigger the alarms automatically.
|
||||
|
||||
/obj/machinery/door/firedoor/attackby(obj/item/C, mob/user, params)
|
||||
if(C.GetID())
|
||||
if(allowed(user))
|
||||
toggle_close_override(user)
|
||||
return ..()
|
||||
|
||||
|
||||
/obj/machinery/door/firedoor/CtrlClick(mob/user)
|
||||
if(!user.canUseTopic(src, !issilicon(user)))
|
||||
return
|
||||
toggle_close_override(user)
|
||||
|
||||
/obj/machinery/door/firedoor/proc/toggle_close_override(mob/user)
|
||||
stay_open = !stay_open
|
||||
balloon_alert(user, "close override [stay_open ? "engaged" : "disengaged"]")
|
||||
addtimer(CALLBACK(src, .proc/close_override_reset), FIREDOOR_CLOSE_OVERRIDE_RESET_TIME)
|
||||
|
||||
/obj/machinery/door/firedoor/proc/close_override_reset()
|
||||
stay_open = FALSE
|
||||
|
||||
/obj/machinery/door/firedoor/examine(mob/user)
|
||||
. = ..()
|
||||
if(issilicon(user))
|
||||
. += span_notice("You can override the closing mechanism by Ctrl+Clicking on the firelock.")
|
||||
else
|
||||
. += span_notice("You can override the closing mechanism by swiping your ID on it, providing it has Atmospherics Access.")
|
||||
. += span_notice("It's close override mechanism is [stay_open ? "engaged" : "disengaged"].")
|
||||
|
||||
/obj/effect/spawner/structure/window/reinforced/no_firelock
|
||||
spawn_list = list(/obj/structure/grille, /obj/structure/window/reinforced/fulltile)
|
||||
|
||||
#undef FIREDOOR_CLOSE_OVERRIDE_RESET_TIME
|
||||
|
||||
|
Before Width: | Height: | Size: 3.2 KiB After Width: | Height: | Size: 7.7 KiB |
|
Before Width: | Height: | Size: 6.4 KiB After Width: | Height: | Size: 7.7 KiB |
@@ -71,6 +71,7 @@
|
||||
#include "code\__DEFINES\explosions.dm"
|
||||
#include "code\__DEFINES\exports.dm"
|
||||
#include "code\__DEFINES\fantasy_affixes.dm"
|
||||
#include "code\__DEFINES\firealarm.dm"
|
||||
#include "code\__DEFINES\flags.dm"
|
||||
#include "code\__DEFINES\food.dm"
|
||||
#include "code\__DEFINES\footsteps.dm"
|
||||
|
||||