mirror of
https://github.com/CHOMPStation2/CHOMPStation2.git
synced 2025-12-11 18:53:06 +00:00
Emergency shutters down have pressure/temperature difference overlays.
Based on the emergency shutter from Paradise.
This commit is contained in:
@@ -398,4 +398,65 @@ datum/projectile_data
|
||||
var/r = mixOneColor(weights, reds)
|
||||
var/g = mixOneColor(weights, greens)
|
||||
var/b = mixOneColor(weights, blues)
|
||||
return rgb(r,g,b)
|
||||
return rgb(r,g,b)
|
||||
|
||||
/**
|
||||
* Gets the highest and lowest pressures from the tiles in cardinal directions
|
||||
* around us, then checks the difference.
|
||||
*/
|
||||
/proc/getOPressureDifferential(var/turf/loc)
|
||||
var/minp=16777216;
|
||||
var/maxp=0;
|
||||
for(var/dir in cardinal)
|
||||
var/turf/simulated/T=get_turf(get_step(loc,dir))
|
||||
var/cp=0
|
||||
if(T && istype(T) && T.zone)
|
||||
var/datum/gas_mixture/environment = T.return_air()
|
||||
cp = environment.return_pressure()
|
||||
else
|
||||
if(istype(T,/turf/simulated))
|
||||
continue
|
||||
if(cp<minp)minp=cp
|
||||
if(cp>maxp)maxp=cp
|
||||
return abs(minp-maxp)
|
||||
|
||||
/proc/convert_k2c(var/temp)
|
||||
return ((temp - T0C))
|
||||
|
||||
/proc/convert_c2k(var/temp)
|
||||
return ((temp + T0C))
|
||||
|
||||
/proc/getCardinalAirInfo(var/turf/loc, var/list/stats=list("temperature"))
|
||||
var/list/temps = new/list(4)
|
||||
for(var/dir in cardinal)
|
||||
var/direction
|
||||
switch(dir)
|
||||
if(NORTH)
|
||||
direction = 1
|
||||
if(SOUTH)
|
||||
direction = 2
|
||||
if(EAST)
|
||||
direction = 3
|
||||
if(WEST)
|
||||
direction = 4
|
||||
var/turf/simulated/T=get_turf(get_step(loc,dir))
|
||||
var/list/rstats = new /list(stats.len)
|
||||
if(T && istype(T) && T.zone)
|
||||
var/datum/gas_mixture/environment = T.return_air()
|
||||
for(var/i=1;i<=stats.len;i++)
|
||||
if(stats[i] == "pressure")
|
||||
rstats[i] = environment.return_pressure()
|
||||
else
|
||||
rstats[i] = environment.vars[stats[i]]
|
||||
else if(istype(T, /turf/simulated))
|
||||
rstats = null // Exclude zone (wall, door, etc).
|
||||
else if(istype(T, /turf))
|
||||
// Should still work. (/turf/return_air())
|
||||
var/datum/gas_mixture/environment = T.return_air()
|
||||
for(var/i=1;i<=stats.len;i++)
|
||||
if(stats[i] == "pressure")
|
||||
rstats[i] = environment.return_pressure()
|
||||
else
|
||||
rstats[i] = environment.vars[stats[i]]
|
||||
temps[direction] = rstats
|
||||
return temps
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:31
|
||||
#define DOOR_OPEN_LAYER 2.7 //Under all objects if opened. 2.7 due to tables being at 2.6
|
||||
#define DOOR_CLOSED_LAYER 3.1 //Above most items if closed
|
||||
|
||||
/obj/machinery/door
|
||||
name = "Door"
|
||||
@@ -8,7 +10,9 @@
|
||||
anchored = 1
|
||||
opacity = 1
|
||||
density = 1
|
||||
layer = 2.7
|
||||
layer = DOOR_OPEN_LAYER
|
||||
var/open_layer = DOOR_OPEN_LAYER
|
||||
var/closed_layer = DOOR_CLOSED_LAYER
|
||||
|
||||
var/secondsElectrified = 0
|
||||
var/visible = 1
|
||||
@@ -27,11 +31,11 @@
|
||||
/obj/machinery/door/New()
|
||||
. = ..()
|
||||
if(density)
|
||||
layer = 3.1 //Above most items if closed
|
||||
layer = closed_layer
|
||||
explosion_resistance = initial(explosion_resistance)
|
||||
update_heat_protection(get_turf(src))
|
||||
else
|
||||
layer = 2.7 //Under all objects if opened. 2.7 due to tables being at 2.6
|
||||
layer = open_layer
|
||||
explosion_resistance = 0
|
||||
|
||||
|
||||
@@ -226,7 +230,7 @@
|
||||
icon_state = "door0"
|
||||
src.SetOpacity(0)
|
||||
sleep(10)
|
||||
src.layer = 2.7
|
||||
src.layer = open_layer
|
||||
src.density = 0
|
||||
explosion_resistance = 0
|
||||
update_icon()
|
||||
@@ -250,10 +254,10 @@
|
||||
if(operating > 0) return
|
||||
operating = 1
|
||||
|
||||
do_animate("closing")
|
||||
src.density = 1
|
||||
explosion_resistance = initial(explosion_resistance)
|
||||
src.layer = 3.1
|
||||
src.layer = closed_layer
|
||||
do_animate("closing")
|
||||
sleep(10)
|
||||
update_icon()
|
||||
if(visible && !glass)
|
||||
|
||||
@@ -1,5 +1,15 @@
|
||||
/var/const/OPEN = 1
|
||||
/var/const/CLOSED = 2
|
||||
|
||||
#define FIREDOOR_MAX_PRESSURE_DIFF 25 // kPa
|
||||
#define FIREDOOR_MAX_TEMP 50 // <20>C
|
||||
#define FIREDOOR_MIN_TEMP 0
|
||||
|
||||
// Bitflags
|
||||
#define FIREDOOR_ALERT_HOT 1
|
||||
#define FIREDOOR_ALERT_COLD 2
|
||||
// Not used #define FIREDOOR_ALERT_LOWPRESS 4
|
||||
|
||||
/obj/machinery/door/firedoor
|
||||
name = "\improper Emergency Shutter"
|
||||
desc = "Emergency air-tight shutter, capable of sealing off breached areas."
|
||||
@@ -8,17 +18,33 @@
|
||||
req_one_access = list(access_atmospherics, access_engine_equip)
|
||||
opacity = 0
|
||||
density = 0
|
||||
layer = DOOR_OPEN_LAYER - 0.1
|
||||
open_layer = DOOR_OPEN_LAYER - 0.1 // Just below doors when open
|
||||
closed_layer = DOOR_CLOSED_LAYER + 0.1 // Just above doors when closed
|
||||
|
||||
var/blocked = 0
|
||||
var/lockdown = 0 // When the door has detected a problem, it locks.
|
||||
var/pdiff_alert = 0
|
||||
var/pdiff = 0
|
||||
var/nextstate = null
|
||||
var/net_id
|
||||
var/list/areas_added
|
||||
var/list/users_to_open
|
||||
|
||||
var/list/users_to_open = new
|
||||
var/next_process_time = 0
|
||||
|
||||
power_channel = ENVIRON
|
||||
use_power = 1
|
||||
idle_power_usage = 5
|
||||
|
||||
var/list/tile_info[4]
|
||||
var/list/dir_alerts[4] // 4 dirs, bitflags
|
||||
|
||||
// MUST be in same order as FIREDOOR_ALERT_*
|
||||
var/list/ALERT_STATES=list(
|
||||
"hot",
|
||||
"cold"
|
||||
)
|
||||
|
||||
/obj/machinery/door/firedoor/New()
|
||||
. = ..()
|
||||
for(var/obj/machinery/door/firedoor/F in loc)
|
||||
@@ -38,7 +64,6 @@
|
||||
A.all_doors.Add(src)
|
||||
areas_added += A
|
||||
|
||||
|
||||
/obj/machinery/door/firedoor/Del()
|
||||
for(var/area/A in areas_added)
|
||||
A.all_doors.Remove(src)
|
||||
@@ -48,14 +73,47 @@
|
||||
/obj/machinery/door/firedoor/examine()
|
||||
set src in view()
|
||||
. = ..()
|
||||
if( islist(users_to_open) && users_to_open.len)
|
||||
|
||||
if(get_dist(src, usr) > 1 && !isAI(usr))
|
||||
return
|
||||
|
||||
if(pdiff >= FIREDOOR_MAX_PRESSURE_DIFF)
|
||||
usr << "<span class='warning'>WARNING: Current pressure differential is [pdiff]kPa! Opening door may result in injury!</span>"
|
||||
|
||||
usr << "<b>Sensor readings:</b>"
|
||||
for(var/index = 1; index <= tile_info.len; index++)
|
||||
var/o = " "
|
||||
switch(index)
|
||||
if(1)
|
||||
o += "NORTH: "
|
||||
if(2)
|
||||
o += "SOUTH: "
|
||||
if(3)
|
||||
o += "EAST: "
|
||||
if(4)
|
||||
o += "WEST: "
|
||||
if(tile_info[index] == null)
|
||||
o += "<span class='warning'>DATA UNAVAILABLE</span>"
|
||||
usr << o
|
||||
continue
|
||||
var/celsius = convert_k2c(tile_info[index][1])
|
||||
var/pressure = tile_info[index][2]
|
||||
if(dir_alerts[index] & (FIREDOOR_ALERT_HOT|FIREDOOR_ALERT_COLD))
|
||||
o += "<span class='warning'>"
|
||||
else
|
||||
o += "<span style='color:blue'>"
|
||||
o += "[celsius]<5D>C</span> "
|
||||
o += "<span style='color:blue'>"
|
||||
o += "[pressure]kPa</span></li>"
|
||||
usr << o
|
||||
|
||||
if(islist(users_to_open) && users_to_open.len)
|
||||
var/users_to_open_string = users_to_open[1]
|
||||
if(users_to_open.len >= 2)
|
||||
for(var/i = 2 to users_to_open.len)
|
||||
users_to_open_string += ", [users_to_open[i]]"
|
||||
usr << "These people have opened \the [src] during an alert: [users_to_open_string]."
|
||||
|
||||
|
||||
/obj/machinery/door/firedoor/Bumped(atom/AM)
|
||||
if(p_open || operating)
|
||||
return
|
||||
@@ -63,7 +121,7 @@
|
||||
return ..()
|
||||
if(istype(AM, /obj/mecha))
|
||||
var/obj/mecha/mecha = AM
|
||||
if (mecha.occupant)
|
||||
if(mecha.occupant)
|
||||
var/mob/M = mecha.occupant
|
||||
if(world.time - M.last_bumped <= 10) return //Can bump-open one airlock per second. This is to prevent popup message spam.
|
||||
M.last_bumped = world.time
|
||||
@@ -79,12 +137,7 @@
|
||||
user << "<span class='warning'>\The [src] is welded solid!</span>"
|
||||
return
|
||||
|
||||
if(!allowed(user))
|
||||
user << "<span class='warning'>Access denied.</span>"
|
||||
return
|
||||
|
||||
var/alarmed = 0
|
||||
|
||||
var/alarmed = lockdown
|
||||
for(var/area/A in areas_added) //Checks if there are fire alarms in any areas associated with that firedoor
|
||||
if(A.fire || A.air_doors_activated)
|
||||
alarmed = 1
|
||||
@@ -100,9 +153,21 @@
|
||||
user << "\The [src] is not functioning, you'll have to force it open manually."
|
||||
return
|
||||
|
||||
if(alarmed && density && lockdown && !allowed(user))
|
||||
user << "<span class='warning'>Access denied. Please wait for authorities to arrive, or for the alert to clear.</span>"
|
||||
return
|
||||
else
|
||||
user.visible_message("<span class='notice'>\The [src] [density ? "open" : "close"]s for \the [user].</span>",\
|
||||
"\The [src] [density ? "open" : "close"]s.",\
|
||||
"You hear a beep, and a door opening.")
|
||||
|
||||
var/needs_to_close = 0
|
||||
if(density)
|
||||
if(alarmed)
|
||||
// Accountability!
|
||||
users_to_open |= user.name
|
||||
log_admin("[user]([user.ckey]) has opened an alarming emergency shutter.")
|
||||
message_admins("<span class='danger'>[user]([user.ckey]) has opened an alarming emergency shutter.</span>")
|
||||
needs_to_close = 1
|
||||
spawn()
|
||||
open()
|
||||
@@ -128,38 +193,37 @@
|
||||
var/obj/item/weapon/weldingtool/W = C
|
||||
if(W.remove_fuel(0, user))
|
||||
blocked = !blocked
|
||||
user.visible_message("\red \The [user] [blocked ? "welds" : "unwelds"] \the [src] with \a [W].",\
|
||||
user.visible_message("<span class='danger'>\The [user] [blocked ? "welds" : "unwelds"] \the [src] with \a [W].</span>",\
|
||||
"You [blocked ? "weld" : "unweld"] \the [src] with \the [W].",\
|
||||
"You hear something being welded.")
|
||||
update_icon()
|
||||
return
|
||||
|
||||
if(blocked)
|
||||
user << "\red \The [src] is welded solid!"
|
||||
user << "<span class='danger'>\The [src] is welded solid!</span>"
|
||||
return
|
||||
|
||||
|
||||
if( istype(C, /obj/item/weapon/crowbar) || ( istype(C,/obj/item/weapon/twohanded/fireaxe) && C:wielded == 1 ) )
|
||||
if(istype(C, /obj/item/weapon/crowbar) || ( istype(C,/obj/item/weapon/twohanded/fireaxe) && C:wielded == 1))
|
||||
if(operating)
|
||||
return
|
||||
|
||||
if( blocked && istype(C, /obj/item/weapon/crowbar) )
|
||||
user.visible_message("\red \The [user] pries at \the [src] with \a [C], but \the [src] is welded in place!",\
|
||||
if(blocked && istype(C, /obj/item/weapon/crowbar))
|
||||
user.visible_message("<span class='danger'>\The [user] pries at \the [src] with \a [C], but \the [src] is welded in place!</span>",\
|
||||
"You try to pry \the [src] [density ? "open" : "closed"], but it is welded in place!",\
|
||||
"You hear someone struggle and metal straining.")
|
||||
return
|
||||
|
||||
user.visible_message("\red \The [user] starts to force \the [src] [density ? "open" : "closed"] with \a [C]!",\
|
||||
user.visible_message("<span class='danger'>\The [user] starts to force \the [src] [density ? "open" : "closed"] with \a [C]!</span>",\
|
||||
"You start forcing \the [src] [density ? "open" : "closed"] with \the [C]!",\
|
||||
"You hear metal strain.")
|
||||
if(do_after(user,30))
|
||||
if( istype(C, /obj/item/weapon/crowbar) )
|
||||
if( stat & (BROKEN|NOPOWER) || !density)
|
||||
user.visible_message("\red \The [user] forces \the [src] [density ? "open" : "closed"] with \a [C]!",\
|
||||
if(istype(C, /obj/item/weapon/crowbar))
|
||||
if(stat & (BROKEN|NOPOWER) || !density)
|
||||
user.visible_message("<span class='danger'>\The [user] forces \the [src] [density ? "open" : "closed"] with \a [C]!</span>",\
|
||||
"You force \the [src] [density ? "open" : "closed"] with \the [C]!",\
|
||||
"You hear metal strain, and a door [density ? "open" : "close"].")
|
||||
else
|
||||
user.visible_message("\red \The [user] forces \the [ blocked ? "welded" : "" ] [src] [density ? "open" : "closed"] with \a [C]!",\
|
||||
user.visible_message("<span class='danger'>\The [user] forces \the [ blocked ? "welded" : "" ] [src] [density ? "open" : "closed"] with \a [C]!</span>",\
|
||||
"You force \the [ blocked ? "welded" : "" ] [src] [density ? "open" : "closed"] with \the [C]!",\
|
||||
"You hear metal strain and groan, and a door [density ? "opening" : "closing"].")
|
||||
if(density)
|
||||
@@ -170,7 +234,50 @@
|
||||
close()
|
||||
return
|
||||
|
||||
// CHECK PRESSURE
|
||||
/obj/machinery/door/firedoor/process()
|
||||
..()
|
||||
|
||||
if(density && next_process_time <= world.time)
|
||||
next_process_time = world.time + 100 // 10 second delays between process updates
|
||||
var/changed = 0
|
||||
lockdown=0
|
||||
// Pressure alerts
|
||||
pdiff = getOPressureDifferential(src.loc)
|
||||
if(pdiff >= FIREDOOR_MAX_PRESSURE_DIFF)
|
||||
lockdown = 1
|
||||
if(!pdiff_alert)
|
||||
pdiff_alert = 1
|
||||
changed = 1 // update_icon()
|
||||
else
|
||||
if(pdiff_alert)
|
||||
pdiff_alert = 0
|
||||
changed = 1 // update_icon()
|
||||
|
||||
tile_info = getCardinalAirInfo(src.loc,list("temperature","pressure"))
|
||||
var/old_alerts = dir_alerts
|
||||
for(var/index = 1; index <= 4; index++)
|
||||
var/list/tileinfo=tile_info[index]
|
||||
if(tileinfo==null)
|
||||
continue // Bad data.
|
||||
var/celsius = convert_k2c(tileinfo[1])
|
||||
|
||||
var/alerts=0
|
||||
|
||||
// Temperatures
|
||||
if(celsius >= FIREDOOR_MAX_TEMP)
|
||||
alerts |= FIREDOOR_ALERT_HOT
|
||||
lockdown = 1
|
||||
else if(celsius <= FIREDOOR_MIN_TEMP)
|
||||
alerts |= FIREDOOR_ALERT_COLD
|
||||
lockdown = 1
|
||||
|
||||
dir_alerts[index]=alerts
|
||||
|
||||
if(dir_alerts != old_alerts)
|
||||
changed = 1
|
||||
if(changed)
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/door/firedoor/proc/latetoggle()
|
||||
if(operating || !nextstate)
|
||||
@@ -178,6 +285,7 @@
|
||||
switch(nextstate)
|
||||
if(OPEN)
|
||||
nextstate = null
|
||||
|
||||
open()
|
||||
if(CLOSED)
|
||||
nextstate = null
|
||||
@@ -189,15 +297,17 @@
|
||||
return ..()
|
||||
|
||||
/obj/machinery/door/firedoor/open(var/forced = 0)
|
||||
if (!forced)
|
||||
if (stat & (BROKEN|NOPOWER))
|
||||
if(!forced)
|
||||
if(stat & (BROKEN|NOPOWER))
|
||||
return //needs power to open unless it was forced
|
||||
else
|
||||
use_power(360)
|
||||
else
|
||||
log_admin("[usr]([usr.ckey]) has forced open an emergency shutter.")
|
||||
message_admins("<span class='danger'>[usr]([usr.ckey]) has forced open an emergency shutter.</span>")
|
||||
latetoggle()
|
||||
return ..()
|
||||
|
||||
|
||||
/obj/machinery/door/firedoor/do_animate(animation)
|
||||
switch(animation)
|
||||
if("opening")
|
||||
@@ -213,6 +323,14 @@
|
||||
icon_state = "door_closed"
|
||||
if(blocked)
|
||||
overlays += "welded"
|
||||
if(pdiff_alert)
|
||||
overlays += "palert"
|
||||
if(dir_alerts)
|
||||
for(var/d=1;d<=4;d++)
|
||||
var/cdir = cardinal[d]
|
||||
for(var/i=1;i<=ALERT_STATES.len;i++)
|
||||
if(dir_alerts[d] & (1<<(i-1)))
|
||||
overlays += new/icon(icon,"alert_[ALERT_STATES[i]]", dir=cdir)
|
||||
else
|
||||
icon_state = "door_open"
|
||||
if(blocked)
|
||||
@@ -220,7 +338,6 @@
|
||||
return
|
||||
|
||||
|
||||
|
||||
/obj/machinery/door/firedoor/border_only
|
||||
//These are playing merry hell on ZAS. Sorry fellas :(
|
||||
/*
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 2.6 KiB After Width: | Height: | Size: 4.6 KiB |
Reference in New Issue
Block a user