Emergency shutters down have pressure/temperature difference overlays.

Based on the emergency shutter from Paradise.
This commit is contained in:
PsiOmega
2014-09-09 14:41:07 +02:00
parent a63f358049
commit ff39ceff9c
4 changed files with 216 additions and 34 deletions

View File

@@ -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

View File

@@ -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)

View File

@@ -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 = "&nbsp;&nbsp;"
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