Rework firelocks, and update alarm light sprites (#19036)

* when the fix to firelocks is in areas

* Maybe

* Clearer defines

* Removing emissives. I'll explore that again later.

* Revert "Removing emissives. I'll explore that again later."

This reverts commit a5635f5230.

* Brilliance flashed before my eyes (Order of applied overlays matter)

* Figured I'd update the documentation.
This commit is contained in:
Vi3trice
2022-09-25 17:03:12 +01:00
committed by GitHub
parent 5d55358159
commit ff75cf9d92
8 changed files with 113 additions and 76 deletions
+5
View File
@@ -126,3 +126,8 @@
#define AI_DISPLAY_MODE_BLANK 0
#define AI_DISPLAY_MODE_EMOTE 1
#define AI_DISPLAY_MODE_BSOD 2
// Door operations
#define DOOR_OPENING 1
#define DOOR_CLOSING 2
#define DOOR_MALF 3
+1 -1
View File
@@ -1,4 +1,4 @@
/// Produces a mutable appearance glued to the [EMISSIVE_PLANE] dyed to be the [EMISSIVE_COLOR].
/// Produces a mutable appearance glued to the [EMISSIVE_PLANE] dyed to be the [EMISSIVE_COLOR]. Order of application matters: Default generated blockers are overlays, and will block its own emissive underlays. If you want an object to be both a blocker, and have their own emissive, it has to be an overlay instead. Grayscale lightmasks are visible in the BYOND right-click and Examine pane, unless they're covered up by another overlay.
/proc/emissive_appearance(icon, icon_state = "", layer = FLOAT_LAYER, alpha = 255, appearance_flags = NONE)
var/mutable_appearance/appearance = mutable_appearance(icon, icon_state, layer, EMISSIVE_PLANE, alpha, appearance_flags | EMISSIVE_APPEARANCE_FLAGS)
appearance.color = EMISSIVE_COLOR
+54 -38
View File
@@ -146,29 +146,34 @@
return cameras
/area/proc/air_doors_close()
if(!air_doors_activated)
air_doors_activated = TRUE
for(var/obj/machinery/door/firedoor/D in src)
if(!D.welded)
D.activate_alarm()
if(D.operating)
D.nextstate = FD_CLOSED
else if(!D.density)
spawn(0)
D.close()
if(air_doors_activated)
return
air_doors_activated = TRUE
for(var/obj/machinery/door/firedoor/D in src)
if(!D.is_operational())
continue
D.activate_alarm()
if(D.welded)
continue
if(D.operating && D.operating != DOOR_CLOSING)
D.nextstate = FD_CLOSED
else if(!D.density)
INVOKE_ASYNC(D, /obj/machinery/door/firedoor.proc/close)
/area/proc/air_doors_open()
if(air_doors_activated)
air_doors_activated = FALSE
for(var/obj/machinery/door/firedoor/D in src)
if(!D.welded)
D.deactivate_alarm()
if(D.operating)
D.nextstate = OPEN
else if(D.density)
spawn(0)
D.open()
if(!air_doors_activated)
return
air_doors_activated = FALSE
for(var/obj/machinery/door/firedoor/D in src)
if(!D.is_operational())
continue
D.deactivate_alarm()
if(D.welded)
continue
if(D.operating && D.operating != DOOR_OPENING)
D.nextstate = FD_OPEN
else if(D.density)
INVOKE_ASYNC(D, /obj/machinery/door/firedoor.proc/open)
/area/Destroy()
STOP_PROCESSING(SSobj, src)
@@ -229,23 +234,34 @@
* 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
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 ? FD_OPEN : FD_CLOSED
else if(!(D.density ^ opening))
INVOKE_ASYNC(D, (opening ? /obj/machinery/door/firedoor.proc/open : /obj/machinery/door/firedoor.proc/close))
INVOKE_ASYNC(D, (opening ? /obj/machinery/door/firedoor.proc/deactivate_alarm : /obj/machinery/door/firedoor.proc/activate_alarm))
if(!firedoors)
return
firedoors_last_closed_on = world.time
for(var/obj/machinery/door/firedoor/D in firedoors)
if(!D.is_operational())
continue
var/valid = TRUE
if(opening) //don't open if adjacent area is on fire
for(var/I in D.affecting_areas)
var/area/A = I
if(A.fire)
valid = FALSE
break
if(!valid)
continue
// At this point, the area is safe and the door is technically functional.
INVOKE_ASYNC(D, (opening ? /obj/machinery/door/firedoor.proc/deactivate_alarm : /obj/machinery/door/firedoor.proc/activate_alarm))
if(D.welded)
continue // Alarm is toggled, but door stuck
if(D.operating)
if((D.operating == DOOR_OPENING && opening) || (D.operating == DOOR_CLOSING && !opening))
continue
else
D.nextstate = opening ? FD_OPEN : FD_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
+8 -8
View File
@@ -1233,7 +1233,7 @@ GLOBAL_LIST_EMPTY(airlock_emissive_underlays)
if(!density)
return TRUE
SEND_SIGNAL(src, COMSIG_AIRLOCK_OPEN)
operating = TRUE
operating = DOOR_OPENING
update_icon(AIRLOCK_OPENING, 1)
sleep(1)
set_opacity(0)
@@ -1244,7 +1244,7 @@ GLOBAL_LIST_EMPTY(airlock_emissive_underlays)
sleep(1)
layer = OPEN_DOOR_LAYER
update_icon(AIRLOCK_OPEN, 1)
operating = FALSE
operating = NONE
return TRUE
/obj/machinery/door/airlock/close(forced=0, override = 0)
@@ -1274,7 +1274,7 @@ GLOBAL_LIST_EMPTY(airlock_emissive_underlays)
killthis.ex_act(EXPLODE_HEAVY)//Smashin windows
SEND_SIGNAL(src, COMSIG_AIRLOCK_CLOSE)
operating = TRUE
operating = DOOR_CLOSING
update_icon(AIRLOCK_CLOSING, 1)
layer = CLOSED_DOOR_LAYER
if(!override)
@@ -1290,7 +1290,7 @@ GLOBAL_LIST_EMPTY(airlock_emissive_underlays)
update_freelook_sight()
sleep(1)
update_icon(AIRLOCK_CLOSED, 1)
operating = FALSE
operating = NONE
if(safe)
CheckForMobs()
return TRUE
@@ -1326,13 +1326,13 @@ GLOBAL_LIST_EMPTY(airlock_emissive_underlays)
/obj/machinery/door/airlock/emag_act(mob/user)
if(!operating && density && arePowerSystemsOn() && !emagged)
operating = TRUE
operating = DOOR_MALF
update_icon(AIRLOCK_EMAG, 1)
sleep(6)
if(QDELETED(src))
return
electronics = new /obj/item/airlock_electronics/destroyed()
operating = FALSE
operating = NONE
if(!open())
update_icon(AIRLOCK_CLOSED, 1)
emagged = TRUE
@@ -1341,12 +1341,12 @@ GLOBAL_LIST_EMPTY(airlock_emissive_underlays)
/obj/machinery/door/airlock/cmag_act(mob/user)
if(operating || HAS_TRAIT(src, TRAIT_CMAGGED) || !density || !arePowerSystemsOn())
return
operating = TRUE
operating = DOOR_MALF
update_icon(AIRLOCK_EMAG, 1)
sleep(6)
if(QDELETED(src))
return
operating = FALSE
operating = NONE
update_icon(AIRLOCK_CLOSED, 1)
ADD_TRAIT(src, TRAIT_CMAGGED, "clown_emag")
return TRUE
+6 -6
View File
@@ -14,8 +14,8 @@
damage_deflection = 10
var/closingLayer = CLOSED_DOOR_LAYER
var/visible = TRUE
/// Is it currently in the process of opening or closing.
var/operating = FALSE
/// Is it currently in the process of opening, closing or being tampered
var/operating = NONE
var/autoclose = FALSE
/// Whether the door detects things and mobs in its way and reopen or crushes them.
var/safe = TRUE
@@ -383,7 +383,7 @@
if(operating)
return
SEND_SIGNAL(src, COMSIG_DOOR_OPEN)
operating = TRUE
operating = DOOR_OPENING
do_animate("opening")
set_opacity(0)
sleep(5)
@@ -392,7 +392,7 @@
layer = initial(layer)
update_icon()
set_opacity(0)
operating = FALSE
operating = NONE
air_update_turf(1)
update_freelook_sight()
if(autoclose)
@@ -413,7 +413,7 @@
return
SEND_SIGNAL(src, COMSIG_DOOR_CLOSE)
operating = TRUE
operating = DOOR_CLOSING
do_animate("closing")
layer = closingLayer
@@ -423,7 +423,7 @@
update_icon()
if(!glass || polarized_on)
set_opacity(TRUE)
operating = FALSE
operating = NONE
air_update_turf(1)
update_freelook_sight()
if(safe)
+31 -15
View File
@@ -85,8 +85,22 @@
latetoggle()
else
stat |= NOPOWER
adjust_light()
update_icon()
/obj/machinery/door/firedoor/proc/adjust_light()
if(stat & (NOPOWER|BROKEN))
set_light(0)
return
if(active_alarm)
set_light(1, 0.5, COLOR_RED_LIGHT)
else
set_light(1, LIGHTING_MINIMUM_POWER)
/obj/machinery/door/firedoor/extinguish_light()
set_light(0)
update_icon(UPDATE_OVERLAYS)
/obj/machinery/door/firedoor/attack_hand(mob/user)
if(operating || !density)
return
@@ -168,7 +182,7 @@
else
WELDER_WELD_SUCCESS_MESSAGE
welded = !welded
update_icon()
update_icon(UPDATE_OVERLAYS)
/obj/machinery/door/firedoor/try_to_crowbar(obj/item/I, mob/user)
if(welded || operating)
@@ -209,20 +223,23 @@
/obj/machinery/door/firedoor/update_overlays()
. = ..()
if(active_alarm && hasPower())
. += image('icons/obj/doors/doorfire.dmi', "alarmlights")
if(density && welded)
. += "welded"
return
if(welded)
. += "welded_open"
. += "welded[density ? "" : "_open"]"
if(active_alarm && hasPower())
if(light)
. += emissive_appearance('icons/obj/doors/doorfire.dmi', "alarmlights_lightmask")
. += image('icons/obj/doors/doorfire.dmi', "alarmlights")
/obj/machinery/door/firedoor/proc/activate_alarm()
active_alarm = TRUE
adjust_light()
update_icon()
/obj/machinery/door/firedoor/proc/deactivate_alarm()
active_alarm = FALSE
if(!density)
layer = initial(layer)
adjust_light()
update_icon()
/obj/machinery/door/firedoor/open(auto_close = TRUE)
@@ -230,7 +247,8 @@
return
. = ..()
latetoggle(auto_close)
if(active_alarm)
layer = closingLayer // Active firedoors take precedence and remain visible over closed airlocks.
if(auto_close)
autoclose = TRUE
@@ -245,13 +263,11 @@
/obj/machinery/door/firedoor/proc/latetoggle(auto_close = TRUE)
if(operating || !hasPower() || !nextstate)
return
switch(nextstate)
if(FD_OPEN)
nextstate = null
open(auto_close)
if(FD_CLOSED)
nextstate = null
close()
if(nextstate == FD_OPEN)
INVOKE_ASYNC(src, .proc/open, auto_close)
if(nextstate == FD_CLOSED)
INVOKE_ASYNC(src, .proc/close)
nextstate = null
/obj/machinery/door/firedoor/proc/forcetoggle(magic = FALSE, auto_close = TRUE)
if(!magic && (operating || !hasPower()))
+8 -8
View File
@@ -178,7 +178,7 @@
if(emagged)
return 0
if(!operating) //in case of emag
operating = TRUE
operating = DOOR_OPENING
do_animate("opening")
set_opacity(FALSE)
playsound(loc, 'sound/machines/windowdoor.ogg', 100, 1)
@@ -191,7 +191,7 @@
update_freelook_sight()
if(operating) //emag again
operating = FALSE
operating = NONE
return 1
/obj/machinery/door/window/close(forced=0)
@@ -203,7 +203,7 @@
if(forced < 2)
if(emagged)
return 0
operating = TRUE
operating = DOOR_CLOSING
do_animate("closing")
playsound(loc, 'sound/machines/windowdoor.ogg', 100, 1)
icon_state = base_state
@@ -215,7 +215,7 @@
update_freelook_sight()
sleep(10)
operating = FALSE
operating = NONE
return 1
/obj/machinery/door/window/play_attack_sound(damage_amount, damage_type = BRUTE, damage_flag = 0)
@@ -261,12 +261,12 @@
/obj/machinery/door/window/emag_act(mob/user, obj/weapon)
if(!operating && density && !emagged)
emagged = TRUE
operating = TRUE
operating = DOOR_MALF
electronics = new /obj/item/airlock_electronics/destroyed()
flick("[base_state]spark", src)
playsound(src, "sparks", 75, TRUE, SHORT_RANGE_SOUND_EXTRARANGE)
sleep(6)
operating = FALSE
operating = NONE
open(2)
return 1
@@ -274,11 +274,11 @@
if(operating || !density || HAS_TRAIT(src, TRAIT_CMAGGED))
return
ADD_TRAIT(src, TRAIT_CMAGGED, "clown_emag")
operating = TRUE
operating = DOOR_MALF
flick("[base_state]spark", src)
playsound(src, "sparks", 75, TRUE, SHORT_RANGE_SOUND_EXTRARANGE)
sleep(6)
operating = FALSE
operating = NONE
return TRUE
/obj/machinery/door/window/attackby(obj/item/I, mob/living/user, params)
Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.8 KiB

After

Width:  |  Height:  |  Size: 9.4 KiB