mirror of
https://github.com/vgstation-coders/vgstation13.git
synced 2025-12-09 16:14:13 +00:00
More ZAS updating (#15922)
* Clean up the diff * Some new defines * Guess I missed that * Remove the flipped * Move direct * More SSair stuff * Tidier * Unsimulated edge tick * Removes useless shit * Remove additional garbage * Dusting * More unticked files * I missed another, apparently * Yet another * Wow, an actual change! Sort of * god damn it * Oh, that was commented out * These are actually very slightly different * bad * More readable * Does nothing * Roughly mimics old behavior * Unnecessary * Equivalent * This makes sense above, but not here * *shrug * Missed these * Destroy AirflowCanMove() * Some cleanup * Unification * Bools * Actually it SHOULD be like this * Alright that would have been too hardcore * Update doc * Oops * I have OCD * Cleanup * Fuck group_multiplier * This was all unused * Also unused * Add some stuff * Move stuff * Add nothing * Remove old * Unused * Move * Some new procs * I touched it bitch * Compiles, probably * Air no longer flows nonsensically * Probably makes compare() work * [Another synonym for cleaner] * Potentially done * Last thing I know of * Oh yeah this too
This commit is contained in:
committed by
Pieter-Jan Briers
parent
bed4665115
commit
fa5183d5da
@@ -35,6 +35,9 @@
|
||||
#define MINIMUM_TEMPERATURE_DELTA_TO_SUSPEND 4 //Minimum temperature difference before group processing is suspended
|
||||
#define MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER 0.5 //Minimum temperature difference before the gas temperatures are just set to be equal
|
||||
|
||||
#define MINIMUM_PRESSURE_DELTA_TO_SUSPEND 0.1 //The minimum pressure difference required for groups to remain separate (unless they meet other conditions). Chosen arbitrarily.
|
||||
#define MINIMUM_PRESSURE_RATIO_TO_SUSPEND 0.05 //Minimum RELATIVE difference in pressure for groups to stay separate (unless they meet other conditions). Also chosen arbitrarily.
|
||||
|
||||
#define MINIMUM_TEMPERATURE_FOR_SUPERCONDUCTION T20C+10
|
||||
#define MINIMUM_TEMPERATURE_START_SUPERCONDUCTION T20C+200
|
||||
|
||||
|
||||
@@ -12,10 +12,19 @@
|
||||
#define R_IDEAL_GAS_EQUATION 8.314 //kPa*L/(K*mol)
|
||||
#define ONE_ATMOSPHERE 101.325 //kPa
|
||||
|
||||
// Radiation constants.
|
||||
#define STEFAN_BOLTZMANN_CONSTANT 5.6704e-8 // W/(m^2*K^4).
|
||||
#define COSMIC_RADIATION_TEMPERATURE 3.15 // K.
|
||||
#define AVERAGE_SOLAR_RADIATION 200 // W/m^2. Kind of arbitrary. Really this should depend on the sun position much like solars.
|
||||
#define RADIATOR_OPTIMUM_PRESSURE 3771 // kPa at 20 C. This should be higher as gases aren't great conductors until they are dense. Used the critical pressure for air.
|
||||
#define GAS_CRITICAL_TEMPERATURE 132.65 // K. The critical point temperature for air.
|
||||
|
||||
#define T0C 273.15 // 0degC
|
||||
#define T20C 293.15 // 20degC
|
||||
#define TCMB 2.73 // -270.42degC
|
||||
|
||||
#define QUANTIZE(variable) (round(variable, 0.0001))
|
||||
|
||||
#define INFINITY 1e31 //closer than enough
|
||||
|
||||
#define SPEED_OF_LIGHT 3e8 //not exact but hey!
|
||||
|
||||
@@ -137,36 +137,13 @@
|
||||
return network
|
||||
|
||||
/datum/pipeline/proc/mingle_with_turf(turf/simulated/target, mingle_volume)
|
||||
var/datum/gas_mixture/air_sample = air.remove_ratio(mingle_volume/air.volume)
|
||||
air_sample.volume = mingle_volume
|
||||
var/datum/gas_mixture/air_sample = air.remove_volume(mingle_volume)
|
||||
|
||||
if(istype(target) && target.zone)
|
||||
//Have to consider preservation of group statuses
|
||||
var/datum/gas_mixture/turf_copy = new
|
||||
var/datum/gas_mixture/turf_air = target.return_air()
|
||||
|
||||
turf_copy.copy_from(target.zone.air)
|
||||
turf_copy.volume = target.zone.air.volume //Copy a good representation of the turf from parent group
|
||||
equalize_gases(list(air_sample, turf_air))
|
||||
air.merge(air_sample)
|
||||
|
||||
equalize_gases(list(air_sample, turf_copy))
|
||||
air.merge(air_sample)
|
||||
|
||||
turf_copy.subtract(target.zone.air)
|
||||
|
||||
target.zone.air.merge(turf_copy)
|
||||
|
||||
else
|
||||
var/datum/gas_mixture/turf_air = target.return_air()
|
||||
|
||||
equalize_gases(list(air_sample, turf_air))
|
||||
air.merge(air_sample)
|
||||
//turf_air already modified by equalize_gases()
|
||||
|
||||
/*
|
||||
if(istype(target) && !target.processing)
|
||||
if(target.air)
|
||||
if(target.air.check_tile_graphic())
|
||||
target.update_visuals(target.air)
|
||||
*/
|
||||
if(network)
|
||||
network.update = 1
|
||||
|
||||
@@ -214,7 +191,7 @@
|
||||
air.temperature += self_temperature_delta
|
||||
|
||||
if(modeled_location.zone)
|
||||
modeled_location.zone.air.temperature += sharer_temperature_delta/modeled_location.zone.air.group_multiplier
|
||||
modeled_location.zone.air.temperature += sharer_temperature_delta
|
||||
else
|
||||
modeled_location.air.temperature += sharer_temperature_delta
|
||||
|
||||
|
||||
@@ -32,282 +32,143 @@ atom/movable/airflow_hit(atom/A)
|
||||
|
||||
AUTOMATIC PROCS:
|
||||
|
||||
Airflow(zone/A, zone/B)
|
||||
Causes objects to fly along a pressure gradient.
|
||||
Called by zone updates. A and B are two connected zones.
|
||||
|
||||
AirflowSpace(zone/A)
|
||||
Causes objects to fly into space.
|
||||
Called by zone updates. A is a zone connected to space.
|
||||
|
||||
atom/movable/GotoAirflowDest(n)
|
||||
atom/movable/RepelAirflowDest(n)
|
||||
Called by main airflow procs to cause the object to fly to or away from destination at speed n.
|
||||
Called by main airflow procs to cause the object to fly to (n > 0) or away from (n < 0) destination at speed scaled by abs(n).
|
||||
Probably shouldn't call this directly unless you know what you're
|
||||
doing and have set airflow_dest. airflow_hit() will be called if the object collides with an obstacle.
|
||||
|
||||
*/
|
||||
|
||||
mob/var/tmp/last_airflow_stun = 0
|
||||
mob/proc/airflow_stun()
|
||||
if(stat == 2 || (flags & INVULNERABLE))
|
||||
return 0
|
||||
if(last_airflow_stun > world.time - zas_settings.Get(/datum/ZAS_Setting/airflow_stun_cooldown))
|
||||
return 0
|
||||
/mob/var/tmp/last_airflow_stun = 0
|
||||
/mob/proc/airflow_stun()
|
||||
if(isDead() || (flags & INVULNERABLE) || (status_flags & GODMODE))
|
||||
return FALSE
|
||||
if(world.time < last_airflow_stun + zas_settings.Get(/datum/ZAS_Setting/airflow_stun_cooldown))
|
||||
return FALSE
|
||||
// if(!zas_settings.Get(/datum/ZAS_Setting/airflow_push) || !(M_HARDCORE in mutations)) //This block was added in the original XGM PR, but, again, I don't want to bundle balance with system.
|
||||
// return FALSE
|
||||
// if(locked_to)
|
||||
// to_chat(src, "<span class='notice'>Air suddenly rushes past you!</span>")
|
||||
// return FALSE
|
||||
if(!(status_flags & CANSTUN) && !(status_flags & CANKNOCKDOWN))
|
||||
to_chat(src, "<span class='notice'>You stay upright as the air rushes past you.</span>")
|
||||
return 0
|
||||
|
||||
return FALSE
|
||||
if(knockdown <= 0)
|
||||
to_chat(src, "<span class='warning'>The sudden rush of air knocks you over!</span>")
|
||||
SetKnockdown(5)
|
||||
last_airflow_stun = world.time
|
||||
|
||||
/mob/living/silicon/airflow_stun()
|
||||
return
|
||||
|
||||
mob/living/silicon/airflow_stun()
|
||||
/mob/living/carbon/slime/airflow_stun()
|
||||
return
|
||||
|
||||
mob/living/carbon/metroid/airflow_stun()
|
||||
return
|
||||
|
||||
mob/living/carbon/human/airflow_stun()
|
||||
if(last_airflow_stun > world.time - zas_settings.Get(/datum/ZAS_Setting/airflow_stun_cooldown))
|
||||
return 0
|
||||
/mob/living/carbon/human/airflow_stun()
|
||||
if(world.time < last_airflow_stun + zas_settings.Get(/datum/ZAS_Setting/airflow_stun_cooldown))
|
||||
return FALSE
|
||||
if(locked_to || (flags & INVULNERABLE))
|
||||
return 0
|
||||
return FALSE
|
||||
if(shoes)
|
||||
if(CheckSlip() < 1)
|
||||
return 0
|
||||
return FALSE
|
||||
if(!(status_flags & CANSTUN) && !(status_flags & CANKNOCKDOWN))
|
||||
to_chat(src, "<span class='notice'>You stay upright as the air rushes past you.</span>")
|
||||
return 0
|
||||
return FALSE
|
||||
|
||||
if(knockdown <= 0)
|
||||
to_chat(src, "<span class='warning'>The sudden rush of air knocks you over!</span>")
|
||||
SetKnockdown(rand(1,5))
|
||||
last_airflow_stun = world.time
|
||||
return
|
||||
|
||||
atom/movable/proc/check_airflow_movable(n)
|
||||
if(anchored && !ismob(src))
|
||||
return 0
|
||||
if(!istype(src,/obj/item) && n < zas_settings.Get(/datum/ZAS_Setting/airflow_dense_pressure))
|
||||
return 0
|
||||
/atom/movable/proc/check_airflow_movable(n)
|
||||
return (!anchored && n >= zas_settings.Get(/datum/ZAS_Setting/airflow_dense_pressure))
|
||||
|
||||
return 1
|
||||
/mob/check_airflow_movable(n)
|
||||
// if(M_HARDCORE in mutations)
|
||||
// return TRUE //It really is hardcore //TOO hardcore, probably
|
||||
|
||||
mob/check_airflow_movable(n)
|
||||
if(n < zas_settings.Get(/datum/ZAS_Setting/airflow_heavy_pressure))
|
||||
return 0
|
||||
return 1
|
||||
return FALSE
|
||||
if(status_flags & GODMODE || (flags & INVULNERABLE))
|
||||
return FALSE
|
||||
if(locked_to)
|
||||
return FALSE
|
||||
if(CheckSlip() < 0)
|
||||
return FALSE
|
||||
|
||||
mob/dead/observer/check_airflow_movable()
|
||||
return 0
|
||||
if (grabbed_by.len)
|
||||
return FALSE
|
||||
|
||||
mob/living/silicon/check_airflow_movable()
|
||||
return 0
|
||||
return TRUE
|
||||
|
||||
mob/virtualhearer/check_airflow_movable()
|
||||
return 0
|
||||
/mob/living/carbon/human/check_airflow_movable(n)
|
||||
if(reagents.has_reagent(MEDCORES))
|
||||
return FALSE
|
||||
return ..()
|
||||
|
||||
/mob/dead/observer/check_airflow_movable()
|
||||
return FALSE
|
||||
|
||||
obj/item/check_airflow_movable(n)
|
||||
. = ..()
|
||||
switch(w_class)
|
||||
if(2)
|
||||
if(n < zas_settings.Get(/datum/ZAS_Setting/airflow_lightest_pressure))
|
||||
return 0
|
||||
if(3)
|
||||
if(n < zas_settings.Get(/datum/ZAS_Setting/airflow_light_pressure))
|
||||
return 0
|
||||
if(4,5)
|
||||
if(n < zas_settings.Get(/datum/ZAS_Setting/airflow_medium_pressure))
|
||||
return 0
|
||||
/mob/living/silicon/check_airflow_movable()
|
||||
return FALSE
|
||||
|
||||
/*
|
||||
//The main airflow code. Called by zone updates.
|
||||
//Zones A and B are air zones. n represents the amount of air moved.
|
||||
/mob/virtualhearer/check_airflow_movable()
|
||||
return FALSE
|
||||
|
||||
proc/Airflow(zone/A, zone/B)
|
||||
set background = 1
|
||||
var/n = B.air.return_pressure() - A.air.return_pressure()
|
||||
|
||||
//Don't go any further if n is lower than the lowest value needed for airflow.
|
||||
if(abs(n) < zas_settings.Get(/datum/ZAS_Setting/airflow_lightest_pressure))
|
||||
return
|
||||
|
||||
//These turfs are the midway point between A and B, and will be the destination point for thrown objects.
|
||||
var/list/connection/connections_A = A.connections
|
||||
var/list/turf/connected_turfs = list()
|
||||
for(var/connection/C in connections_A) //Grab the turf that is in the zone we are flowing to (determined by n)
|
||||
if( ( A == C.A.zone || A == C.zone_A ) && ( B == C.B.zone || B == C.zone_B ) )
|
||||
if(n < 0)
|
||||
connected_turfs |= C.B
|
||||
else
|
||||
connected_turfs |= C.A
|
||||
else if( ( A == C.B.zone || A == C.zone_B ) && ( B == C.A.zone || B == C.zone_A ) )
|
||||
if(n < 0)
|
||||
connected_turfs |= C.A
|
||||
else
|
||||
connected_turfs |= C.B
|
||||
|
||||
//Get lists of things that can be thrown across the room for each zone (assumes air is moving from zone B to zone A)
|
||||
spawn()
|
||||
var/list/air_sucked = B.movables()
|
||||
var/list/air_repelled = A.movables()
|
||||
if(n < 0)
|
||||
//air is moving from zone A to zone B
|
||||
var/list/temporary_pplz = air_sucked
|
||||
air_sucked = air_repelled
|
||||
air_repelled = temporary_pplz
|
||||
|
||||
if(zas_settings.Get(/datum/ZAS_Setting/airflow_push) || 1) // If enabled
|
||||
for(var/atom/movable/M in air_sucked)
|
||||
if(M.last_airflow > world.time - zas_settings.Get(/datum/ZAS_Setting/airflow_delay))
|
||||
continue
|
||||
|
||||
//Check for knocking people over
|
||||
if(ismob(M) && n > zas_settings.Get(/datum/ZAS_Setting/airflow_stun_pressure))
|
||||
if(M:status_flags & GODMODE)
|
||||
continue
|
||||
M:airflow_stun()
|
||||
|
||||
if(M.check_airflow_movable(n))
|
||||
|
||||
//Check for things that are in range of the midpoint turfs.
|
||||
var/list/close_turfs = list()
|
||||
for(var/turf/U in connected_turfs)
|
||||
if(M in range(U))
|
||||
close_turfs += U
|
||||
if(!close_turfs.len)
|
||||
continue
|
||||
|
||||
//If they're already being tossed, don't do it again.
|
||||
if(!M.airflow_speed)
|
||||
|
||||
M.airflow_dest = pick(close_turfs) //Pick a random midpoint to fly towards.
|
||||
|
||||
M.GotoAirflowDest(abs(n)/5)
|
||||
|
||||
//Do it again for the stuff in the other zone, making it fly away.
|
||||
for(var/atom/movable/M in air_repelled)
|
||||
|
||||
if(M.last_airflow > world.time - zas_settings.Get(/datum/ZAS_Setting/airflow_delay))
|
||||
continue
|
||||
|
||||
if(ismob(M) && abs(n) > zas_settings.Get(/datum/ZAS_Setting/airflow_medium_pressure))
|
||||
if(M:status_flags & GODMODE)
|
||||
continue
|
||||
M:airflow_stun()
|
||||
|
||||
if(M.check_airflow_movable(abs(n)))
|
||||
|
||||
var/list/close_turfs = list()
|
||||
for(var/turf/U in connected_turfs)
|
||||
if(M in range(U))
|
||||
close_turfs += U
|
||||
if(!close_turfs.len)
|
||||
continue
|
||||
|
||||
//If they're already being tossed, don't do it again.
|
||||
if(!M.airflow_speed)
|
||||
|
||||
M.airflow_dest = pick(close_turfs) //Pick a random midpoint to fly towards.
|
||||
|
||||
spawn M.RepelAirflowDest(abs(n)/5)
|
||||
|
||||
proc/AirflowSpace(zone/A)
|
||||
spawn()
|
||||
//The space version of the Airflow(A,B,n) proc.
|
||||
|
||||
var/n = A.air.return_pressure()
|
||||
//Here, n is determined by only the pressure in the room.
|
||||
|
||||
if(n < zas_settings.Get(/datum/ZAS_Setting/airflow_lightest_pressure))
|
||||
return
|
||||
|
||||
var/list/connected_turfs = A.unsimulated_tiles //The midpoints are now all the space connections.
|
||||
var/list/pplz = A.movables() //We only need to worry about things in the zone, not things in space.
|
||||
|
||||
if(zas_settings.Get(/datum/ZAS_Setting/airflow_push) || 1) // If enabled
|
||||
for(var/atom/movable/M in pplz)
|
||||
if(M.last_airflow > world.time - zas_settings.Get(/datum/ZAS_Setting/airflow_delay))
|
||||
continue
|
||||
|
||||
if(ismob(M) && n > zas_settings.Get(/datum/ZAS_Setting/airflow_stun_pressure))
|
||||
var/mob/O = M
|
||||
if(O.status_flags & GODMODE)
|
||||
continue
|
||||
O.airflow_stun()
|
||||
|
||||
if(M.check_airflow_movable(n))
|
||||
|
||||
var/list/close_turfs = list()
|
||||
for(var/turf/U in connected_turfs)
|
||||
if(M in range(U))
|
||||
close_turfs += U
|
||||
if(!close_turfs.len)
|
||||
continue
|
||||
|
||||
//If they're already being tossed, don't do it again.
|
||||
if(!M.airflow_speed)
|
||||
|
||||
M.airflow_dest = pick(close_turfs) //Pick a random midpoint to fly towards.
|
||||
M.GotoAirflowDest(n/10)
|
||||
//Sometimes shit breaks, and M isn't there after the spawn.
|
||||
*/
|
||||
/obj/item/check_airflow_movable(n)
|
||||
if(anchored)
|
||||
return FALSE
|
||||
switch(w_class) //Note that switch() evaluates the FIRST matching case, so the case that executes for a given w_class is the one for which it is the UPPER bound.
|
||||
if(0 to W_CLASS_TINY)
|
||||
return TRUE
|
||||
if(W_CLASS_TINY to W_CLASS_SMALL)
|
||||
return (n >= zas_settings.Get(/datum/ZAS_Setting/airflow_lightest_pressure))
|
||||
if(W_CLASS_SMALL to W_CLASS_MEDIUM)
|
||||
return (n >= zas_settings.Get(/datum/ZAS_Setting/airflow_light_pressure))
|
||||
if(W_CLASS_MEDIUM to INFINITY)
|
||||
return (n >= zas_settings.Get(/datum/ZAS_Setting/airflow_medium_pressure))
|
||||
|
||||
/atom/movable/var/tmp/turf/airflow_dest
|
||||
/atom/movable/var/tmp/airflow_speed = 0
|
||||
/atom/movable/var/tmp/airflow_time = 0
|
||||
/atom/movable/var/tmp/last_airflow = 0
|
||||
|
||||
// Mainly for bustanuts.
|
||||
|
||||
/atom/movable/proc/AirflowCanPush()
|
||||
return 1
|
||||
|
||||
/mob/AirflowCanPush()
|
||||
return 1
|
||||
|
||||
/mob/living/carbon/human/AirflowCanPush()
|
||||
if(reagents.has_reagent(MEDCORES))
|
||||
return 0
|
||||
return ..()
|
||||
|
||||
/atom/movable/proc/GotoAirflowDest(n)
|
||||
last_airflow = world.time
|
||||
if(pulledby)
|
||||
if(!airflow_dest || pulledby)
|
||||
return
|
||||
if(world.time < last_airflow + zas_settings.Get(/datum/ZAS_Setting/airflow_delay))
|
||||
return
|
||||
if(airflow_dest == loc)
|
||||
return
|
||||
if(ismob(src))
|
||||
var/mob/M = src
|
||||
if(M.status_flags & GODMODE || (flags & INVULNERABLE))
|
||||
return
|
||||
if(M.grabbed_by.len)
|
||||
return
|
||||
if(istype(src, /mob/living/carbon/human))
|
||||
var/mob/living/carbon/human/H = src
|
||||
if(H.locked_to)
|
||||
return
|
||||
if(H.shoes)
|
||||
if(H.CheckSlip() < 0)
|
||||
return
|
||||
to_chat(src, "<SPAN CLASS='warning'>You are sucked away by airflow!</SPAN>")
|
||||
var/airflow_falloff = 9 - ul_FalloffAmount(airflow_dest) //It's a fast falloff calc. Very useful.
|
||||
to_chat(src, "<span class='warning'>You are sucked away by airflow!</span>")
|
||||
|
||||
var/xo = airflow_dest.x - x
|
||||
var/yo = airflow_dest.y - y
|
||||
|
||||
var/airflow_falloff = 9 - sqrt(xo ** 2 + yo ** 2)
|
||||
|
||||
if(airflow_falloff < 1)
|
||||
airflow_dest = null
|
||||
return
|
||||
|
||||
if(n < 0)
|
||||
n *= -2 //Back when GotoAirflowDest() and RepelAirflowDest() were separate procs, the latter was called with differential/5 rather than differential/10. This is to maintain consistency.
|
||||
xo *= -1
|
||||
yo *= -1
|
||||
|
||||
airflow_speed = Clamp(n * (9 / airflow_falloff), 1, 9)
|
||||
var
|
||||
xo = airflow_dest.x - src.x
|
||||
yo = airflow_dest.y - src.y
|
||||
od = 0
|
||||
|
||||
airflow_dest = null
|
||||
|
||||
var/od = FALSE
|
||||
if(!density)
|
||||
density = 1
|
||||
od = 1
|
||||
density = TRUE
|
||||
od = TRUE
|
||||
|
||||
last_airflow = world.time
|
||||
|
||||
spawn(0)
|
||||
while(airflow_speed > 0 && Process_Spacemove(1))
|
||||
airflow_speed = min(airflow_speed,15)
|
||||
@@ -315,14 +176,14 @@ proc/AirflowSpace(zone/A)
|
||||
if(airflow_speed > 7)
|
||||
if(airflow_time++ >= airflow_speed - 7)
|
||||
if(od)
|
||||
density = 0
|
||||
density = FALSE
|
||||
sleep(tick_multiplier)
|
||||
else
|
||||
if(od)
|
||||
density = 0
|
||||
density = FALSE
|
||||
sleep(max(1,10-(airflow_speed+3)) * tick_multiplier)
|
||||
if(od)
|
||||
density = 1
|
||||
density = TRUE
|
||||
if ((!( src.airflow_dest ) || src.loc == src.airflow_dest))
|
||||
airflow_dest = locate(Clamp(x + xo, 1, world.maxx), Clamp(y + yo, 1, world.maxy), z)
|
||||
if ((src.x == 1 || src.x == world.maxx || src.y == 1 || src.y == world.maxy))
|
||||
@@ -330,73 +191,14 @@ proc/AirflowSpace(zone/A)
|
||||
if(!isturf(loc))
|
||||
break
|
||||
step_towards(src, src.airflow_dest)
|
||||
if(ismob(src) && src:client)
|
||||
var/mob/M = src
|
||||
var/mob/M = src
|
||||
if(istype(M) && M.client)
|
||||
M.delayNextMove(zas_settings.Get(/datum/ZAS_Setting/airflow_mob_slowdown))
|
||||
airflow_dest = null
|
||||
airflow_speed = 0
|
||||
airflow_time = 0
|
||||
if(od)
|
||||
density = 0
|
||||
|
||||
|
||||
/atom/movable/proc/RepelAirflowDest(n)
|
||||
if(pulledby)
|
||||
return
|
||||
if(airflow_dest == loc)
|
||||
step_away(src,loc)
|
||||
if(ismob(src))
|
||||
var/mob/M = src
|
||||
if(M.status_flags & GODMODE || (flags & INVULNERABLE))
|
||||
return
|
||||
if(M.grabbed_by.len)
|
||||
return
|
||||
if(istype(src, /mob/living/carbon/human))
|
||||
var/mob/living/carbon/human/H = src
|
||||
if(H.locked_to)
|
||||
return
|
||||
if(H.shoes)
|
||||
if(H.CheckSlip() < 0)
|
||||
return
|
||||
to_chat(src, "<SPAN CLASS='warning'>You are pushed away by airflow!</SPAN>")
|
||||
last_airflow = world.time
|
||||
var/airflow_falloff = 9 - ul_FalloffAmount(airflow_dest) //It's a fast falloff calc. Very useful.
|
||||
if(airflow_falloff < 1)
|
||||
airflow_dest = null
|
||||
return
|
||||
airflow_speed = Clamp(n * (9 / airflow_falloff), 1, 9)
|
||||
var
|
||||
xo = -(airflow_dest.x - src.x)
|
||||
yo = -(airflow_dest.y - src.y)
|
||||
od = 0
|
||||
airflow_dest = null
|
||||
if(!density)
|
||||
density = 1
|
||||
od = 1
|
||||
spawn(0)
|
||||
while(airflow_speed > 0)
|
||||
airflow_speed = min(airflow_speed,15)
|
||||
airflow_speed -= zas_settings.Get(/datum/ZAS_Setting/airflow_speed_decay)
|
||||
if(airflow_speed > 7)
|
||||
if(airflow_time++ >= airflow_speed - 7)
|
||||
sleep(tick_multiplier)
|
||||
else
|
||||
sleep(max(1,10-(airflow_speed+3)) * tick_multiplier)
|
||||
if ((!( src.airflow_dest ) || src.loc == src.airflow_dest))
|
||||
airflow_dest = locate(Clamp(x + xo, 1, world.maxx), Clamp(y + yo, 1, world.maxy), z)
|
||||
if ((src.x == 1 || src.x == world.maxx || src.y == 1 || src.y == world.maxy))
|
||||
break
|
||||
if (!isturf(loc))
|
||||
break
|
||||
step_towards(src, src.airflow_dest)
|
||||
if(ismob(src) && src:client)
|
||||
var/mob/M = src
|
||||
M.delayNextMove(zas_settings.Get(/datum/ZAS_Setting/airflow_mob_slowdown))
|
||||
airflow_dest = null
|
||||
airflow_speed = 0
|
||||
airflow_time = 0
|
||||
if(od)
|
||||
density = 0
|
||||
density = FALSE
|
||||
|
||||
/atom/movable/to_bump(atom/Obstacle)
|
||||
if(airflow_speed > 0 && airflow_dest)
|
||||
@@ -407,17 +209,15 @@ proc/AirflowSpace(zone/A)
|
||||
. = ..()
|
||||
sound_override = 0
|
||||
|
||||
atom/movable/proc/airflow_hit(atom/A)
|
||||
/atom/movable/proc/airflow_hit(atom/A)
|
||||
airflow_speed = 0
|
||||
airflow_dest = null
|
||||
|
||||
mob/airflow_hit(atom/A)
|
||||
/mob/airflow_hit(atom/A)
|
||||
if(size == SIZE_TINY)
|
||||
return //Slamming into a mouse/roach doesn't make much sense
|
||||
|
||||
if(!sound_override)
|
||||
for(var/mob/M in hearers(src))
|
||||
M.show_message("<span class='danger'>\The [src] slams into \a [A]!</span>",1,"<span class='warning'>You hear a loud slam!</span>",2)
|
||||
visible_message(message = "<span class='danger'>\The [src] slams into \a [A]!</span>", blind_message = "<span class='danger'>You hear a loud slam!</span>")
|
||||
//playsound(get_turf(src), "smash.ogg", 25, 1, -1)
|
||||
if(istype(A,/obj/item))
|
||||
var/obj/item/item = A
|
||||
@@ -426,40 +226,17 @@ mob/airflow_hit(atom/A)
|
||||
SetKnockdown(rand(1,5))
|
||||
. = ..()
|
||||
|
||||
obj/airflow_hit(atom/A)
|
||||
/obj/airflow_hit(atom/A)
|
||||
if(!sound_override)
|
||||
for(var/mob/M in hearers(src))
|
||||
M.show_message("<span class='danger'>\The [src] slams into \a [A]!</span>",1,"<span class='warning'>You hear a loud slam!</span>",2)
|
||||
visible_message(message = "<span class='danger'>\The [src] slams into \a [A]!</span>", blind_message = "<span class='warning'>You hear a loud slam!</span>")
|
||||
//playsound(get_turf(src), "smash.ogg", 25, 1, -1)
|
||||
. = ..()
|
||||
|
||||
obj/item/airflow_hit(atom/A)
|
||||
/obj/item/airflow_hit(atom/A)
|
||||
airflow_speed = 0
|
||||
airflow_dest = null
|
||||
|
||||
mob/living/carbon/human/airflow_hit(atom/A)
|
||||
// for(var/mob/M in hearers(src))
|
||||
// M.show_message("<span class='danger'>[src] slams into [A]!</span>",1,"<span class='warning'>You hear a loud slam!</span>",2)
|
||||
//playsound(get_turf(src), "punch", 25, 1, -1)
|
||||
|
||||
|
||||
/*See this? This is how you DON'T handle armor values for protection
|
||||
if(prob(33))
|
||||
loc:add_blood(src)
|
||||
bloody_body(src)
|
||||
|
||||
var/b_loss = airflow_speed * zas_settings.Get(/datum/ZAS_Setting/airflow_damage)
|
||||
|
||||
var/blocked = run_armor_check(LIMB_HEAD,"melee")
|
||||
apply_damage(b_loss/3, BRUTE, LIMB_HEAD, blocked, 0, used_weapon = "Airflow")
|
||||
|
||||
blocked = run_armor_check(LIMB_CHEST,"melee")
|
||||
apply_damage(b_loss/3, BRUTE, LIMB_CHEST, blocked, 0, used_weapon = "Airflow")
|
||||
|
||||
blocked = run_armor_check(LIMB_GROIN,"melee")
|
||||
apply_damage(b_loss/3, BRUTE, LIMB_GROIN, blocked, 0, used_weapon = "Airflow")
|
||||
*/
|
||||
|
||||
/mob/living/carbon/human/airflow_hit(atom/A)
|
||||
var/b_loss = airflow_speed * zas_settings.Get(/datum/ZAS_Setting/airflow_damage)
|
||||
|
||||
for(var/i in contents)
|
||||
@@ -483,19 +260,11 @@ mob/living/carbon/human/airflow_hit(atom/A)
|
||||
T.add_blood(src)
|
||||
bloody_body(src)
|
||||
|
||||
if(zas_settings.Get(/datum/ZAS_Setting/airflow_push) || AirflowCanPush())
|
||||
if(zas_settings.Get(/datum/ZAS_Setting/airflow_push) || (M_HARDCORE in mutations))
|
||||
if(airflow_speed > 10)
|
||||
paralysis += round(airflow_speed * zas_settings.Get(/datum/ZAS_Setting/airflow_stun))
|
||||
stunned = max(stunned,paralysis + 3)
|
||||
Paralyse(round(airflow_speed * zas_settings.Get(/datum/ZAS_Setting/airflow_stun)))
|
||||
Stun(paralysis + 3)
|
||||
else
|
||||
stunned += round(airflow_speed * zas_settings.Get(/datum/ZAS_Setting/airflow_stun)/2)
|
||||
Stun(round(airflow_speed * zas_settings.Get(/datum/ZAS_Setting/airflow_stun)/2))
|
||||
|
||||
. = ..()
|
||||
|
||||
zone/proc/movables()
|
||||
. = list()
|
||||
for(var/turf/T in contents)
|
||||
for(var/atom/A in T)
|
||||
if(istype(A, /obj/effect) || isobserver(A) || isAIEye(A))
|
||||
continue
|
||||
. += A
|
||||
|
||||
@@ -1,141 +1,101 @@
|
||||
/*
|
||||
|
||||
Overview:
|
||||
These are what handle gas transfers between zones and into space.
|
||||
They are found in a zone's edges list and in SSair.edges.
|
||||
Each edge updates every air tick due to their role in gas transfer.
|
||||
They come in two flavors, /connection_edge/zone and /connection_edge/unsimulated.
|
||||
As the type names might suggest, they handle inter-zone and spacelike connections respectively.
|
||||
|
||||
Class Vars:
|
||||
|
||||
A - This always holds a zone. In unsimulated edges, it holds the only zone.
|
||||
|
||||
connecting_turfs - This holds a list of connected turfs, mainly for the sake of airflow.
|
||||
|
||||
coefficent - This is a marker for how many connections are on this edge. Used to determine the ratio of flow.
|
||||
|
||||
connection_edge/zone
|
||||
|
||||
B - This holds the second zone with which the first zone equalizes.
|
||||
|
||||
direct - This counts the number of direct (i.e. with no doors) connections on this edge.
|
||||
Any value of this is sufficient to make the zones mergeable.
|
||||
|
||||
connection_edge/unsimulated
|
||||
|
||||
B - This holds an unsimulated turf which has the gas values this edge is mimicing.
|
||||
|
||||
air - Retrieved from B on creation and used as an argument for the legacy ShareSpace() proc.
|
||||
|
||||
Class Procs:
|
||||
|
||||
add_connection(connection/c)
|
||||
Adds a connection to this edge. Usually increments the coefficient and adds a turf to connecting_turfs.
|
||||
|
||||
remove_connection(connection/c)
|
||||
Removes a connection from this edge. This works even if c is not in the edge, so be careful.
|
||||
If the coefficient reaches zero as a result, the edge is erased.
|
||||
|
||||
contains_zone(zone/Z)
|
||||
Returns true if either A or B is equal to Z. Unsimulated connections return true only on A.
|
||||
|
||||
erase()
|
||||
Removes this connection from processing and zone edge lists.
|
||||
|
||||
tick()
|
||||
Called every air tick on edges in the processing list. Equalizes gas.
|
||||
|
||||
flow(list/movable, differential, repelled)
|
||||
Airflow proc causing all objects in movable to be checked against a pressure differential.
|
||||
If repelled is true, the objects move away from any turf in connecting_turfs, otherwise they approach.
|
||||
A check against vsc.lightest_airflow_pressure should generally be performed before calling this.
|
||||
|
||||
get_connected_zone(zone/from)
|
||||
Helper proc that allows getting the other zone of an edge given one of them.
|
||||
Only on /connection_edge/zone, otherwise use A.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
/connection_edge/var/zone/A
|
||||
/connection_edge
|
||||
var/zone/A
|
||||
|
||||
/connection_edge/var/list/connecting_turfs = list()
|
||||
var/list/connecting_turfs = list()
|
||||
var/direct = 0
|
||||
var/sleeping = 1
|
||||
|
||||
/connection_edge/var/coefficient = 0
|
||||
var/coefficient = 0
|
||||
|
||||
/connection_edge/New()
|
||||
CRASH("Cannot make connection edge without specifications.")
|
||||
|
||||
/connection_edge/proc/add_connection(connection/c)
|
||||
coefficient++
|
||||
// to_chat(world, "Connection added: [type] Coefficient: [coefficient]")
|
||||
if(c.direct())
|
||||
direct++
|
||||
|
||||
/connection_edge/proc/remove_connection(connection/c)
|
||||
// to_chat(world, "Connection removed: [type] Coefficient: [coefficient-1]")
|
||||
coefficient--
|
||||
if(coefficient <= 0)
|
||||
erase()
|
||||
if(c.direct())
|
||||
direct--
|
||||
|
||||
/connection_edge/proc/contains_zone(zone/Z)
|
||||
|
||||
/connection_edge/proc/erase()
|
||||
SSair.remove_edge(src)
|
||||
// to_chat(world, "[type] Erased.")
|
||||
|
||||
/connection_edge/proc/tick()
|
||||
|
||||
/connection_edge/proc/flow(list/movable, differential, repelled, flipped = 0)
|
||||
//Flipped tells us if we are going from A to B or from B to A.
|
||||
/connection_edge/proc/recheck()
|
||||
|
||||
/connection_edge/proc/flow(list/blown, differential)
|
||||
if(!zas_settings.Get(/datum/ZAS_Setting/airflow_push))
|
||||
return
|
||||
for(var/atom/movable/M in movable)
|
||||
if(!M.AirflowCanPush())
|
||||
continue
|
||||
//If they're already being tossed, don't do it again.
|
||||
if(M.last_airflow > world.time - zas_settings.Get(/datum/ZAS_Setting/airflow_delay))
|
||||
continue
|
||||
if(M.airflow_speed)
|
||||
continue
|
||||
|
||||
for(var/atom/movable/AM in blown)
|
||||
//Check for knocking people over
|
||||
if(ismob(M) && differential > zas_settings.Get(/datum/ZAS_Setting/airflow_stun_pressure))
|
||||
if(M:status_flags & GODMODE)
|
||||
continue
|
||||
M:airflow_stun()
|
||||
if(ismob(AM) && differential > zas_settings.Get(/datum/ZAS_Setting/airflow_stun_pressure))
|
||||
var/mob/M = AM
|
||||
M.airflow_stun()
|
||||
|
||||
if(M.check_airflow_movable(differential))
|
||||
if(AM.check_airflow_movable(differential))
|
||||
//Check for things that are in range of the midpoint turfs.
|
||||
var/list/close_turfs = list()
|
||||
for(var/turf/U in connecting_turfs)
|
||||
if(get_dist(M,U) < world.view)
|
||||
if(get_dist(AM,U) < world.view)
|
||||
close_turfs += U
|
||||
if(!close_turfs.len)
|
||||
continue
|
||||
|
||||
M.airflow_dest = pick(close_turfs) //Pick a random midpoint to fly towards.
|
||||
AM.airflow_dest = pick(close_turfs) //Pick a random midpoint to fly towards.
|
||||
|
||||
if(M)
|
||||
if(repelled)
|
||||
if(flipped)
|
||||
if(!(M.loc in src:A.contents))
|
||||
continue
|
||||
else if(!(M.loc in src:B.contents))
|
||||
continue
|
||||
M.RepelAirflowDest(differential/5)
|
||||
else
|
||||
if(flipped)
|
||||
if(!(M.loc in src:B.contents))
|
||||
continue
|
||||
else if(!(M.loc in src:A.contents))
|
||||
continue
|
||||
M.GotoAirflowDest(differential/10)
|
||||
AM.GotoAirflowDest(differential/10)
|
||||
|
||||
|
||||
|
||||
|
||||
/connection_edge/zone/var/zone/B
|
||||
/connection_edge/zone/var/direct = 0
|
||||
/connection_edge/zone
|
||||
var/zone/B
|
||||
|
||||
/connection_edge/zone/New(zone/A, zone/B)
|
||||
|
||||
@@ -144,18 +104,13 @@ Class Procs:
|
||||
A.edges.Add(src)
|
||||
B.edges.Add(src)
|
||||
//id = edge_id(A,B)
|
||||
// to_chat(world, "New edge between [A] and [B]")
|
||||
|
||||
/connection_edge/zone/add_connection(connection/c)
|
||||
. = ..()
|
||||
connecting_turfs.Add(c.A)
|
||||
if(c.direct())
|
||||
direct++
|
||||
|
||||
/connection_edge/zone/remove_connection(connection/c)
|
||||
connecting_turfs.Remove(c.A)
|
||||
if(c.direct())
|
||||
direct--
|
||||
. = ..()
|
||||
|
||||
/connection_edge/zone/contains_zone(zone/Z)
|
||||
@@ -170,38 +125,29 @@ Class Procs:
|
||||
if(A.invalid || B.invalid)
|
||||
erase()
|
||||
return
|
||||
// to_chat(world, "[id]: Tick [SSair.current_cycle]: \...")
|
||||
if(direct)
|
||||
if(SSair.equivalent_pressure(A, B))
|
||||
// to_chat(world, "merged.")
|
||||
erase()
|
||||
SSair.merge(A, B)
|
||||
// to_chat(world, "zones merged.")
|
||||
return
|
||||
|
||||
//SSair.equalize(A, B)
|
||||
ShareRatio(A.air,B.air,coefficient)
|
||||
SSair.mark_zone_update(A)
|
||||
SSair.mark_zone_update(B)
|
||||
// to_chat(world, "equalized.")
|
||||
var/equiv = A.air.share_tiles(B.air, coefficient)
|
||||
|
||||
var/differential = A.air.return_pressure() - B.air.return_pressure()
|
||||
if(abs(differential) < zas_settings.Get(/datum/ZAS_Setting/airflow_lightest_pressure))
|
||||
return
|
||||
if(abs(differential) >= zas_settings.Get(/datum/ZAS_Setting/airflow_lightest_pressure))
|
||||
flow(A.contents, differential)
|
||||
flow(B.contents, -differential)
|
||||
|
||||
var/list/attracted
|
||||
var/list/repelled
|
||||
var/flipped = 0
|
||||
if(differential > 0)
|
||||
attracted = A.movables()
|
||||
repelled = B.movables()
|
||||
else
|
||||
flipped = 1
|
||||
attracted = B.movables()
|
||||
repelled = A.movables()
|
||||
if(equiv)
|
||||
if(direct)
|
||||
erase()
|
||||
SSair.merge(A, B)
|
||||
return
|
||||
else
|
||||
SSair.mark_edge_sleeping(src)
|
||||
equalize_gases(A.get_equalized_zone_air())
|
||||
|
||||
flow(attracted, abs(differential), 0, flipped)
|
||||
flow(repelled, abs(differential), 1, flipped)
|
||||
SSair.mark_zone_update(A)
|
||||
SSair.mark_zone_update(B)
|
||||
|
||||
/connection_edge/zone/recheck()
|
||||
if(!A.air.compare(B.air))
|
||||
SSair.mark_edge_active(src)
|
||||
|
||||
//Helper proc to get connections for a zone.
|
||||
/connection_edge/zone/proc/get_connected_zone(zone/from)
|
||||
@@ -210,8 +156,9 @@ Class Procs:
|
||||
else
|
||||
return A
|
||||
|
||||
/connection_edge/unsimulated/var/turf/B
|
||||
/connection_edge/unsimulated/var/datum/gas_mixture/air
|
||||
/connection_edge/unsimulated
|
||||
var/turf/B
|
||||
var/datum/gas_mixture/air
|
||||
|
||||
/connection_edge/unsimulated/New(zone/A, turf/B)
|
||||
src.A = A
|
||||
@@ -219,16 +166,13 @@ Class Procs:
|
||||
A.edges.Add(src)
|
||||
air = B.return_air()
|
||||
//id = 52*A.id
|
||||
// to_chat(world, "New edge from [A] to [B].")
|
||||
|
||||
/connection_edge/unsimulated/add_connection(connection/c)
|
||||
. = ..()
|
||||
connecting_turfs.Add(c.B)
|
||||
air.group_multiplier = coefficient
|
||||
|
||||
/connection_edge/unsimulated/remove_connection(connection/c)
|
||||
connecting_turfs.Remove(c.B)
|
||||
air.group_multiplier = coefficient
|
||||
. = ..()
|
||||
|
||||
/connection_edge/unsimulated/erase()
|
||||
@@ -242,219 +186,31 @@ Class Procs:
|
||||
if(A.invalid)
|
||||
erase()
|
||||
return
|
||||
// to_chat(world, "[id]: Tick [SSair.current_cycle]: To [B]!")
|
||||
//A.air.mimic(B, coefficient)
|
||||
ShareSpace(A.air,air,dbg_out)
|
||||
SSair.mark_zone_update(A)
|
||||
|
||||
var/equiv = A.air.share_space(air, coefficient)
|
||||
|
||||
var/differential = A.air.return_pressure() - air.return_pressure()
|
||||
if(abs(differential) < zas_settings.Get(/datum/ZAS_Setting/airflow_lightest_pressure))
|
||||
return
|
||||
if(abs(differential) >= zas_settings.Get(/datum/ZAS_Setting/airflow_lightest_pressure))
|
||||
flow(A.contents, abs(differential), differential < 0)
|
||||
|
||||
var/list/attracted = A.movables()
|
||||
flow(attracted, abs(differential), differential < 0)
|
||||
if(equiv)
|
||||
A.air.copy_from(air)
|
||||
SSair.mark_edge_sleeping(src)
|
||||
|
||||
var/list/sharing_lookup_table = list(0.30, 0.40, 0.48, 0.54, 0.60, 0.66)
|
||||
|
||||
proc/ShareRatio(datum/gas_mixture/A, datum/gas_mixture/B, connecting_tiles)
|
||||
//Shares a specific ratio of gas between mixtures using simple weighted averages.
|
||||
var
|
||||
//WOOT WOOT TOUCH THIS AND YOU ARE A RETARD
|
||||
ratio = sharing_lookup_table[6]
|
||||
//WOOT WOOT TOUCH THIS AND YOU ARE A RETARD
|
||||
|
||||
size = max(1,A.group_multiplier)
|
||||
share_size = max(1,B.group_multiplier)
|
||||
|
||||
full_oxy = A.oxygen * size
|
||||
full_nitro = A.nitrogen * size
|
||||
full_co2 = A.carbon_dioxide * size
|
||||
full_plasma = A.toxins * size
|
||||
|
||||
full_heat_capacity = A.heat_capacity() * size
|
||||
|
||||
s_full_oxy = B.oxygen * share_size
|
||||
s_full_nitro = B.nitrogen * share_size
|
||||
s_full_co2 = B.carbon_dioxide * share_size
|
||||
s_full_plasma = B.toxins * share_size
|
||||
|
||||
s_full_heat_capacity = B.heat_capacity() * share_size
|
||||
|
||||
oxy_avg = (full_oxy + s_full_oxy) / (size + share_size)
|
||||
nit_avg = (full_nitro + s_full_nitro) / (size + share_size)
|
||||
co2_avg = (full_co2 + s_full_co2) / (size + share_size)
|
||||
plasma_avg = (full_plasma + s_full_plasma) / (size + share_size)
|
||||
|
||||
temp_avg = (A.temperature * full_heat_capacity + B.temperature * s_full_heat_capacity) / (full_heat_capacity + s_full_heat_capacity)
|
||||
|
||||
//WOOT WOOT TOUCH THIS AND YOU ARE A RETARD
|
||||
if(connecting_tiles && sharing_lookup_table.len >= connecting_tiles) //6 or more interconnecting tiles will max at 42% of air moved per tick.
|
||||
ratio = sharing_lookup_table[connecting_tiles]
|
||||
//WOOT WOOT TOUCH THIS AND YOU ARE A RETARD
|
||||
|
||||
A.oxygen = max(0, (A.oxygen - oxy_avg) * (1-ratio) + oxy_avg )
|
||||
A.nitrogen = max(0, (A.nitrogen - nit_avg) * (1-ratio) + nit_avg )
|
||||
A.carbon_dioxide = max(0, (A.carbon_dioxide - co2_avg) * (1-ratio) + co2_avg )
|
||||
A.toxins = max(0, (A.toxins - plasma_avg) * (1-ratio) + plasma_avg )
|
||||
|
||||
A.temperature = max(0, (A.temperature - temp_avg) * (1-ratio) + temp_avg )
|
||||
|
||||
B.oxygen = max(0, (B.oxygen - oxy_avg) * (1-ratio) + oxy_avg )
|
||||
B.nitrogen = max(0, (B.nitrogen - nit_avg) * (1-ratio) + nit_avg )
|
||||
B.carbon_dioxide = max(0, (B.carbon_dioxide - co2_avg) * (1-ratio) + co2_avg )
|
||||
B.toxins = max(0, (B.toxins - plasma_avg) * (1-ratio) + plasma_avg )
|
||||
|
||||
B.temperature = max(0, (B.temperature - temp_avg) * (1-ratio) + temp_avg )
|
||||
|
||||
for(var/datum/gas/G in A.trace_gases)
|
||||
var/datum/gas/H = locate(G.type) in B.trace_gases
|
||||
if(H)
|
||||
var/G_avg = (G.moles*size + H.moles*share_size) / (size+share_size)
|
||||
G.moles = (G.moles - G_avg) * (1-ratio) + G_avg
|
||||
|
||||
H.moles = (H.moles - G_avg) * (1-ratio) + G_avg
|
||||
else
|
||||
H = new G.type
|
||||
B.trace_gases += H
|
||||
var/G_avg = (G.moles*size) / (size+share_size)
|
||||
G.moles = (G.moles - G_avg) * (1-ratio) + G_avg
|
||||
H.moles = (H.moles - G_avg) * (1-ratio) + G_avg
|
||||
|
||||
for(var/datum/gas/G in B.trace_gases)
|
||||
var/datum/gas/H = locate(G.type) in A.trace_gases
|
||||
if(!H)
|
||||
H = new G.type
|
||||
A.trace_gases += H
|
||||
var/G_avg = (G.moles*size) / (size+share_size)
|
||||
G.moles = (G.moles - G_avg) * (1-ratio) + G_avg
|
||||
H.moles = (H.moles - G_avg) * (1-ratio) + G_avg
|
||||
|
||||
A.update_values()
|
||||
B.update_values()
|
||||
|
||||
if(A.compare(B))
|
||||
return 1
|
||||
else
|
||||
return 0
|
||||
|
||||
proc/ShareSpace(datum/gas_mixture/A, list/unsimulated_tiles, dbg_output)
|
||||
//A modified version of ShareRatio for spacing gas at the same rate as if it were going into a large airless room.
|
||||
if(!unsimulated_tiles)
|
||||
return 0
|
||||
|
||||
var
|
||||
unsim_oxygen = 0
|
||||
unsim_nitrogen = 0
|
||||
unsim_co2 = 0
|
||||
unsim_plasma = 0
|
||||
unsim_heat_capacity = 0
|
||||
unsim_temperature = 0
|
||||
|
||||
size = max(1,A.group_multiplier)
|
||||
|
||||
var/tileslen
|
||||
var/share_size
|
||||
|
||||
if(istype(unsimulated_tiles, /datum/gas_mixture))
|
||||
var/datum/gas_mixture/avg_unsim = unsimulated_tiles
|
||||
unsim_oxygen = avg_unsim.oxygen
|
||||
unsim_co2 = avg_unsim.carbon_dioxide
|
||||
unsim_nitrogen = avg_unsim.nitrogen
|
||||
unsim_plasma = avg_unsim.toxins
|
||||
unsim_temperature = avg_unsim.temperature
|
||||
share_size = max(1, max(size + 3, 1) + avg_unsim.group_multiplier)
|
||||
tileslen = avg_unsim.group_multiplier
|
||||
|
||||
if(dbg_output)
|
||||
to_chat(world, "O2: [unsim_oxygen] N2: [unsim_nitrogen] Size: [share_size] Tiles: [tileslen]")
|
||||
|
||||
else if(istype(unsimulated_tiles, /list))
|
||||
if(!unsimulated_tiles.len)
|
||||
return 0
|
||||
// We use the same size for the potentially single space tile
|
||||
// as we use for the entire room. Why is this?
|
||||
// Short answer: We do not want larger rooms to depressurize more
|
||||
// slowly than small rooms, preserving our good old "hollywood-style"
|
||||
// oh-shit effect when large rooms get breached, but still having small
|
||||
// rooms remain pressurized for long enough to make escape possible.
|
||||
share_size = max(1, max(size + 3, 1) + unsimulated_tiles.len)
|
||||
var/correction_ratio = share_size / unsimulated_tiles.len
|
||||
|
||||
for(var/turf/T in unsimulated_tiles)
|
||||
unsim_oxygen += T.oxygen
|
||||
unsim_co2 += T.carbon_dioxide
|
||||
unsim_nitrogen += T.nitrogen
|
||||
unsim_plasma += T.toxins
|
||||
unsim_temperature += T.temperature/unsimulated_tiles.len
|
||||
|
||||
//These values require adjustment in order to properly represent a room of the specified size.
|
||||
unsim_oxygen *= correction_ratio
|
||||
unsim_co2 *= correction_ratio
|
||||
unsim_nitrogen *= correction_ratio
|
||||
unsim_plasma *= correction_ratio
|
||||
tileslen = unsimulated_tiles.len
|
||||
|
||||
else //invalid input type
|
||||
return 0
|
||||
|
||||
unsim_heat_capacity = HEAT_CAPACITY_CALCULATION(unsim_oxygen, unsim_co2, unsim_nitrogen, unsim_plasma)
|
||||
|
||||
var
|
||||
ratio = sharing_lookup_table[6]
|
||||
|
||||
old_pressure = A.return_pressure()
|
||||
|
||||
full_oxy = A.oxygen * size
|
||||
full_nitro = A.nitrogen * size
|
||||
full_co2 = A.carbon_dioxide * size
|
||||
full_plasma = A.toxins * size
|
||||
|
||||
full_heat_capacity = A.heat_capacity() * size
|
||||
|
||||
oxy_avg = (full_oxy + unsim_oxygen*share_size) / (size + share_size)
|
||||
nit_avg = (full_nitro + unsim_nitrogen*share_size) / (size + share_size)
|
||||
co2_avg = (full_co2 + unsim_co2*share_size) / (size + share_size)
|
||||
plasma_avg = (full_plasma + unsim_plasma*share_size) / (size + share_size)
|
||||
|
||||
temp_avg = 0
|
||||
|
||||
if((full_heat_capacity + unsim_heat_capacity) > 0)
|
||||
temp_avg = (A.temperature * full_heat_capacity + unsim_temperature * unsim_heat_capacity) / (full_heat_capacity + unsim_heat_capacity)
|
||||
|
||||
if(sharing_lookup_table.len >= tileslen) //6 or more interconnecting tiles will max at 42% of air moved per tick.
|
||||
ratio = sharing_lookup_table[tileslen]
|
||||
|
||||
if(dbg_output)
|
||||
to_chat(world, "Ratio: [ratio]")
|
||||
to_chat(world, "Avg O2: [oxy_avg] N2: [nit_avg]")
|
||||
|
||||
A.oxygen = max(0, (A.oxygen - oxy_avg) * (1 - ratio) + oxy_avg )
|
||||
A.nitrogen = max(0, (A.nitrogen - nit_avg) * (1 - ratio) + nit_avg )
|
||||
A.carbon_dioxide = max(0, (A.carbon_dioxide - co2_avg) * (1 - ratio) + co2_avg )
|
||||
A.toxins = max(0, (A.toxins - plasma_avg) * (1 - ratio) + plasma_avg )
|
||||
|
||||
A.temperature = max(TCMB, (A.temperature - temp_avg) * (1 - ratio) + temp_avg )
|
||||
|
||||
for(var/datum/gas/G in A.trace_gases)
|
||||
var/G_avg = (G.moles * size) / (size + share_size)
|
||||
G.moles = (G.moles - G_avg) * (1 - ratio) + G_avg
|
||||
|
||||
A.update_values()
|
||||
|
||||
if(dbg_output)
|
||||
to_chat(world, "Result: [abs(old_pressure - A.return_pressure())] kPa")
|
||||
|
||||
return abs(old_pressure - A.return_pressure())
|
||||
SSair.mark_zone_update(A)
|
||||
|
||||
/connection_edge/unsimulated/recheck()
|
||||
if(!A.air.compare(air))
|
||||
SSair.mark_edge_active(src)
|
||||
|
||||
proc/ShareHeat(datum/gas_mixture/A, datum/gas_mixture/B, connecting_tiles)
|
||||
//This implements a simplistic version of the Stefan-Boltzmann law.
|
||||
var/energy_delta = ((A.temperature - B.temperature) ** 4) * 5.6704e-8 * connecting_tiles * 2.5
|
||||
var/maximum_energy_delta = max(0, min(A.temperature * A.heat_capacity() * A.group_multiplier, B.temperature * B.heat_capacity() * B.group_multiplier))
|
||||
var/energy_delta = ((A.temperature - B.temperature) ** 4) * STEFAN_BOLTZMANN_CONSTANT * connecting_tiles * 2.5
|
||||
var/maximum_energy_delta = max(0, min(A.temperature * A.heat_capacity(), B.temperature * B.heat_capacity()))
|
||||
if(maximum_energy_delta > abs(energy_delta))
|
||||
if(energy_delta < 0)
|
||||
maximum_energy_delta *= -1
|
||||
energy_delta = maximum_energy_delta
|
||||
|
||||
A.temperature -= energy_delta / (A.heat_capacity() * A.group_multiplier)
|
||||
B.temperature += energy_delta / (B.heat_capacity() * B.group_multiplier)
|
||||
A.temperature -= energy_delta / A.heat_capacity()
|
||||
B.temperature += energy_delta / B.heat_capacity()
|
||||
|
||||
@@ -101,7 +101,6 @@ client/proc/Test_ZAS_Connection(var/turf/simulated/T as turf)
|
||||
to_chat(client, "Pressure: [air.return_pressure()] KPa")
|
||||
to_chat(client, "")
|
||||
to_chat(client, "Unsimulated Zone(space/catwalk) Tiles: [length(unsimulated_tiles)]")
|
||||
to_chat(client, "Movable Objects: [length(movables())]")
|
||||
to_chat(client, "<u>Connections: [length(connections)]</u>")
|
||||
|
||||
for(var/connection/C in connections)
|
||||
|
||||
@@ -1,176 +0,0 @@
|
||||
//Global Functions
|
||||
//Contents: FloodFill, ZMerge, ZConnect
|
||||
|
||||
//Floods outward from an initial turf to fill everywhere it's zone would reach.
|
||||
proc/FloodFill(turf/simulated/start)
|
||||
|
||||
|
||||
if(!istype(start))
|
||||
return list()
|
||||
|
||||
//The list of tiles waiting to be evaulated.
|
||||
var/list/open = list(start)
|
||||
//The list of tiles which have been evaulated.
|
||||
var/list/closed = list()
|
||||
|
||||
//Loop through the turfs in the open list in order to find which adjacent turfs should be added to the zone.
|
||||
while(open.len)
|
||||
var/turf/simulated/T = pick(open)
|
||||
|
||||
//sanity!
|
||||
if(!istype(T) || iscatwalk(T))
|
||||
open -= T
|
||||
continue
|
||||
|
||||
//Check all cardinal directions
|
||||
for(var/d in cardinal)
|
||||
var/turf/simulated/O = get_step(T,d)
|
||||
|
||||
//Ensure the turf is of proper type, that it is not in either list, and that air can reach it.
|
||||
if(istype(O) && !iscatwalk(O) && !(O in open) && !(O in closed) && O.ZCanPass(T))
|
||||
|
||||
//Handle connections from a tile with a door.
|
||||
if(T.HasDoor())
|
||||
//If they both have doors, then they are not able to connect period.
|
||||
if(O.HasDoor())
|
||||
continue
|
||||
|
||||
//Connect first to north and west
|
||||
if(d == NORTH || d == WEST)
|
||||
open += O
|
||||
|
||||
//If that fails, and north/west cannot be connected to, see if west or south can be connected instead.
|
||||
else
|
||||
var/turf/simulated/W = get_step(O, WEST)
|
||||
var/turf/simulated/N = get_step(O, NORTH)
|
||||
|
||||
if(!O.ZCanPass(N) && !O.ZCanPass(W) )
|
||||
//If it cannot connect either to the north or west, connect it!
|
||||
open += O
|
||||
|
||||
//If no doors are involved, add it immediately.
|
||||
else if(!O.HasDoor())
|
||||
open += O
|
||||
|
||||
//Handle connecting to a tile with a door.
|
||||
else
|
||||
if(d == SOUTH || d == EAST)
|
||||
//doors prefer connecting to zones to the north or west
|
||||
closed += O
|
||||
|
||||
else
|
||||
//see if we need to force an attempted connection
|
||||
//(there are no potentially viable zones to the north/west of the door)
|
||||
var/turf/simulated/W = get_step(O, WEST)
|
||||
var/turf/simulated/N = get_step(O, NORTH)
|
||||
|
||||
if( !O.ZCanPass(N) && !O.ZCanPass(W) )
|
||||
//If it cannot connect either to the north or west, connect it!
|
||||
closed += O
|
||||
|
||||
//This tile is now evaluated, and can be moved to the list of evaluated tiles.
|
||||
open -= T
|
||||
closed += T
|
||||
|
||||
return closed
|
||||
|
||||
|
||||
//Procedure to merge two zones together.
|
||||
proc/ZMerge(zone/A,zone/B)
|
||||
|
||||
|
||||
//Sanity~
|
||||
if(!istype(A) || !istype(B))
|
||||
return
|
||||
|
||||
var/new_contents = A.contents + B.contents
|
||||
|
||||
//Set all the zone vars.
|
||||
for(var/turf/simulated/T in B.contents)
|
||||
T.zone = A
|
||||
|
||||
if(istype(A.air) && istype(B.air))
|
||||
//Merges two zones so that they are one.
|
||||
var/a_size = A.air.group_multiplier
|
||||
var/b_size = B.air.group_multiplier
|
||||
var/c_size = a_size + b_size
|
||||
|
||||
//Set air multipliers to one so air represents gas per tile.
|
||||
A.air.group_multiplier = 1
|
||||
B.air.group_multiplier = 1
|
||||
|
||||
//Remove some air proportional to the size of this zone.
|
||||
A.air.remove_ratio(a_size/c_size)
|
||||
B.air.remove_ratio(b_size/c_size)
|
||||
|
||||
//Merge the gases and set the multiplier to the sum of the old ones.
|
||||
A.air.merge(B.air)
|
||||
A.air.group_multiplier = c_size
|
||||
|
||||
//I hate when the air datum somehow disappears.
|
||||
// Try to make it sorta work anyways. Fakit
|
||||
else if(istype(B.air))
|
||||
A.air = B.air
|
||||
A.air.group_multiplier = A.contents.len
|
||||
|
||||
else if(istype(A.air))
|
||||
A.air.group_multiplier = A.contents.len
|
||||
|
||||
//Doublefakit.
|
||||
else
|
||||
A.air = new
|
||||
|
||||
//Check for connections to merge into the new zone.
|
||||
for(var/connection/C in B.connections)
|
||||
//The Cleanup proc will delete the connection if the zones are the same.
|
||||
// It will also set the zone variables correctly.
|
||||
C.Cleanup()
|
||||
|
||||
//Add space tiles.
|
||||
if(A.unsimulated_tiles && B.unsimulated_tiles)
|
||||
A.unsimulated_tiles |= B.unsimulated_tiles
|
||||
else if (B.unsimulated_tiles)
|
||||
A.unsimulated_tiles = B.unsimulated_tiles
|
||||
|
||||
//Add contents.
|
||||
A.contents = new_contents
|
||||
|
||||
//Remove the "B" zone, finally.
|
||||
B.SoftDelete()
|
||||
|
||||
|
||||
//Connects two zones by forming a connection object representing turfs A and B.
|
||||
proc/ZConnect(turf/simulated/A,turf/simulated/B)
|
||||
|
||||
|
||||
//Make sure that if it's space, it gets added to unsimulated_tiles instead.
|
||||
if(!istype(B) || iscatwalk(B))
|
||||
if(A.zone)
|
||||
A.zone.AddTurf(B)
|
||||
return
|
||||
if(!istype(A) || iscatwalk(A))
|
||||
if(B.zone)
|
||||
B.zone.AddTurf(A)
|
||||
return
|
||||
|
||||
if(!istype(A) || !istype(B))
|
||||
return
|
||||
|
||||
//Make some preliminary checks to see if the connection is valid.
|
||||
if(!A.zone || !B.zone)
|
||||
return
|
||||
if(A.zone == B.zone)
|
||||
return
|
||||
|
||||
if(A.CanPass(null,B,0,1))
|
||||
return ZMerge(A.zone,B.zone)
|
||||
|
||||
//Ensure the connection isn't already made.
|
||||
if("\ref[A]" in SSair.turfs_with_connections)
|
||||
for(var/connection/C in SSair.turfs_with_connections["\ref[A]"])
|
||||
C.Cleanup()
|
||||
if(C && (C.B == B || C.A == B))
|
||||
return
|
||||
|
||||
//Make the connection.
|
||||
new /connection(A,B)
|
||||
@@ -248,8 +248,6 @@
|
||||
SSair.mark_zone_update(zone)
|
||||
return zone.air
|
||||
else
|
||||
if(!air)
|
||||
make_air()
|
||||
c_copy_air()
|
||||
return air
|
||||
else
|
||||
@@ -261,15 +259,13 @@
|
||||
air = new/datum/gas_mixture
|
||||
air.temperature = temperature
|
||||
air.adjust(oxygen, carbon_dioxide, nitrogen, toxins)
|
||||
air.group_multiplier = 1
|
||||
air.volume = CELL_VOLUME
|
||||
|
||||
/turf/simulated/proc/c_copy_air()
|
||||
if(!air)
|
||||
air = new/datum/gas_mixture
|
||||
air.copy_from(zone.air)
|
||||
air.group_multiplier = 1
|
||||
|
||||
|
||||
/turf/attack_hand(mob/user as mob)
|
||||
user.Move_Pulled(src)
|
||||
user.Move_Pulled(src)
|
||||
|
||||
@@ -1,345 +0,0 @@
|
||||
var/global/vs_control/vsc = new
|
||||
|
||||
// Whoever made this fucking thing: I hate you so much.
|
||||
vs_control/var
|
||||
// N3X15 - Added back in so we can tweak performance.
|
||||
airflow_push = 0
|
||||
airflow_push_NAME="Airflow - Push shit around"
|
||||
airflow_push_DESC="1=yes please rape my server, 0=no"
|
||||
airflow_push_METHOD="Toggle" // See ChangeSettings(). I'd rather not let people break this.
|
||||
|
||||
fire_consuption_rate = 0.75
|
||||
fire_consuption_rate_NAME = "Fire - Air Consumption Ratio"
|
||||
fire_consuption_rate_DESC = "Ratio of air removed and combusted per tick."
|
||||
|
||||
fire_firelevel_multiplier = 25
|
||||
fire_firelevel_multiplier_NAME = "Fire - Firelevel Constant"
|
||||
fire_firelevel_multiplier_DESC = "Multiplied by the equation for firelevel, affects mainly the extingiushing of fires."
|
||||
|
||||
fire_fuel_energy_release = 550000
|
||||
fire_fuel_energy_release_NAME = "Fire - Fuel energy release"
|
||||
fire_fuel_energy_release_DESC = "The energy in joule released when burning one mol of a burnable substance"
|
||||
|
||||
|
||||
airflow_lightest_pressure = 20
|
||||
airflow_lightest_pressure_NAME = "Airflow - Small Movement Threshold %"
|
||||
airflow_lightest_pressure_DESC = "Percent of 1 Atm. at which items with the small weight classes will move."
|
||||
|
||||
airflow_light_pressure = 35
|
||||
airflow_light_pressure_NAME = "Airflow - Medium Movement Threshold %"
|
||||
airflow_light_pressure_DESC = "Percent of 1 Atm. at which items with the medium weight classes will move."
|
||||
|
||||
airflow_medium_pressure = 50
|
||||
airflow_medium_pressure_NAME = "Airflow - Heavy Movement Threshold %"
|
||||
airflow_medium_pressure_DESC = "Percent of 1 Atm. at which items with the largest weight classes will move."
|
||||
|
||||
airflow_heavy_pressure = 65
|
||||
airflow_heavy_pressure_NAME = "Airflow - Mob Movement Threshold %"
|
||||
airflow_heavy_pressure_DESC = "Percent of 1 Atm. at which mobs will move."
|
||||
|
||||
airflow_dense_pressure = 85
|
||||
airflow_dense_pressure_NAME = "Airflow - Dense Movement Threshold %"
|
||||
airflow_dense_pressure_DESC = "Percent of 1 Atm. at which items with canisters and closets will move."
|
||||
|
||||
airflow_stun_pressure = 60
|
||||
airflow_stun_pressure_NAME = "Airflow - Mob Stunning Threshold %"
|
||||
airflow_stun_pressure_DESC = "Percent of 1 Atm. at which mobs will be stunned by airflow."
|
||||
|
||||
airflow_stun_cooldown = 60
|
||||
airflow_stun_cooldown_NAME = "Aiflow Stunning - Cooldown"
|
||||
airflow_stun_cooldown_DESC = "How long, in tenths of a second, to wait before stunning them again."
|
||||
|
||||
airflow_stun = 1
|
||||
airflow_stun_NAME = "Airflow Impact - Stunning"
|
||||
airflow_stun_DESC = "How much a mob is stunned when hit by an object."
|
||||
|
||||
airflow_damage = 2
|
||||
airflow_damage_NAME = "Airflow Impact - Damage"
|
||||
airflow_damage_DESC = "Damage from airflow impacts."
|
||||
|
||||
airflow_speed_decay = 1.5
|
||||
airflow_speed_decay_NAME = "Airflow Speed Decay"
|
||||
airflow_speed_decay_DESC = "How rapidly the speed gained from airflow decays."
|
||||
|
||||
airflow_delay = 30
|
||||
airflow_delay_NAME = "Airflow Retrigger Delay"
|
||||
airflow_delay_DESC = "Time in deciseconds before things can be moved by airflow again."
|
||||
|
||||
airflow_mob_slowdown = 1
|
||||
airflow_mob_slowdown_NAME = "Airflow Slowdown"
|
||||
airflow_mob_slowdown_DESC = "Time in tenths of a second to add as a delay to each movement by a mob if they are fighting the pull of the airflow."
|
||||
|
||||
var/connection_insulation = 0.4
|
||||
var/connection_insulation_NAME = "Connections - Insulation"
|
||||
var/connection_insulation_DESC = "How insulative a connection is, in terms of heat transfer. 1 is perfectly insulative, and 0 is perfectly conductive."
|
||||
|
||||
var/connection_temperature_delta = 10
|
||||
var/connection_temperature_delta_NAME = "Connections - Temperature Difference"
|
||||
var/connection_temperature_delta_DESC = "The smallest temperature difference which will cause heat to travel through doors."
|
||||
|
||||
vs_control
|
||||
var
|
||||
list/settings = list()
|
||||
list/bitflags = list("1","2","4","8","16","32","64","128","256","512","1024") // Oh jesus why. Learn to shift bits, you idiots.
|
||||
pl_control/plc = new()
|
||||
|
||||
New()
|
||||
. = ..()
|
||||
settings = vars.Copy()
|
||||
|
||||
var/datum/D = new() //Ensure only unique vars are put through by making a datum and removing all common vars.
|
||||
for(var/V in D.vars)
|
||||
settings -= V
|
||||
|
||||
for(var/V in settings)
|
||||
if(findtextEx(V,"_RANDOM") || findtextEx(V,"_DESC") || findtextEx(V,"_METHOD"))
|
||||
settings -= V
|
||||
|
||||
settings -= "settings"
|
||||
settings -= "bitflags"
|
||||
settings -= "plc"
|
||||
|
||||
proc/ChangeSettingsDialog(mob/user,list/L)
|
||||
//var/which = input(user,"Choose a setting:") in L
|
||||
var/dat = ""
|
||||
for(var/ch in L)
|
||||
if(findtextEx(ch,"_RANDOM") || findtextEx(ch,"_DESC") || findtextEx(ch,"_METHOD") || findtextEx(ch,"_NAME"))
|
||||
continue
|
||||
var/vw
|
||||
var/vw_desc = "No Description."
|
||||
var/vw_name = ch
|
||||
if(ch in plc.settings)
|
||||
vw = plc.vars[ch]
|
||||
if("[ch]_DESC" in plc.vars)
|
||||
vw_desc = plc.vars["[ch]_DESC"]
|
||||
if("[ch]_NAME" in plc.vars)
|
||||
vw_name = plc.vars["[ch]_NAME"]
|
||||
else
|
||||
vw = vars[ch]
|
||||
if("[ch]_DESC" in vars)
|
||||
vw_desc = vars["[ch]_DESC"]
|
||||
if("[ch]_NAME" in vars)
|
||||
vw_name = vars["[ch]_NAME"]
|
||||
dat += "<b>[vw_name] = [vw]</b> <A href='?src=\ref[src];changevar=[ch]'>\[Change\]</A><br>"
|
||||
dat += "<i>[vw_desc]</i><br><br>"
|
||||
user << browse(dat,"window=settings")
|
||||
Topic(href,href_list)
|
||||
if("changevar" in href_list)
|
||||
ChangeSetting(usr,href_list["changevar"])
|
||||
proc/ChangeSetting(mob/user,ch)
|
||||
var/vw
|
||||
var/how = "Text"
|
||||
var/display_description = ch
|
||||
if(ch in plc.settings)
|
||||
vw = plc.vars[ch]
|
||||
if("[ch]_NAME" in plc.vars)
|
||||
display_description = plc.vars["[ch]_NAME"]
|
||||
if("[ch]_METHOD" in plc.vars)
|
||||
how = plc.vars["[ch]_METHOD"]
|
||||
else
|
||||
if(isnum(vw))
|
||||
how = "Numeric"
|
||||
else
|
||||
how = "Text"
|
||||
else
|
||||
vw = vars[ch]
|
||||
if("[ch]_NAME" in vars)
|
||||
display_description = vars["[ch]_NAME"]
|
||||
if("[ch]_METHOD" in vars)
|
||||
how = vars["[ch]_METHOD"]
|
||||
else
|
||||
if(isnum(vw))
|
||||
how = "Numeric"
|
||||
else
|
||||
how = "Text"
|
||||
var/newvar = vw
|
||||
switch(how)
|
||||
if("Numeric")
|
||||
newvar = input(user,"Enter a number:","Settings",newvar) as num
|
||||
if("Bit Flag")
|
||||
var/flag = input(user,"Toggle which bit?","Settings") in bitflags
|
||||
flag = text2num(flag)
|
||||
if(newvar & flag)
|
||||
newvar &= ~flag
|
||||
else
|
||||
newvar |= flag
|
||||
if("Toggle")
|
||||
newvar = !newvar
|
||||
if("Text")
|
||||
newvar = input(user,"Enter a string:","Settings",newvar) as text
|
||||
if("Long Text")
|
||||
newvar = input(user,"Enter text:","Settings",newvar) as message
|
||||
vw = newvar
|
||||
if(ch in plc.settings)
|
||||
plc.vars[ch] = vw
|
||||
else
|
||||
vars[ch] = vw
|
||||
if(how == "Toggle")
|
||||
newvar = (newvar?"ON":"OFF")
|
||||
to_chat(world, "<span class='notice'><b>[key_name(user)] changed the setting [display_description] to [newvar].</b></span>")
|
||||
if(ch in plc.settings)
|
||||
ChangeSettingsDialog(user,plc.settings)
|
||||
else
|
||||
ChangeSettingsDialog(user,settings)
|
||||
proc/RandomizeWithProbability()
|
||||
for(var/V in settings)
|
||||
var/newvalue
|
||||
if("[V]_RANDOM" in vars)
|
||||
if(isnum(vars["[V]_RANDOM"]))
|
||||
newvalue = prob(vars["[V]_RANDOM"])
|
||||
else if(istext(vars["[V]_RANDOM"]))
|
||||
newvalue = roll(vars["[V]_RANDOM"])
|
||||
else
|
||||
newvalue = vars[V]
|
||||
V = newvalue
|
||||
|
||||
proc/ChangePlasma()
|
||||
for(var/V in plc.settings)
|
||||
plc.Randomize(V)
|
||||
|
||||
proc/SetDefault(var/mob/user)
|
||||
var/list/setting_choices = list("Plasma - Standard", "Plasma - Low Hazard", "Plasma - High Hazard", "Plasma - Oh Shit!",\
|
||||
"ZAS - Normal", "ZAS - Forgiving", "ZAS - Dangerous", "ZAS - Hellish")
|
||||
var/def = input(user, "Which of these presets should be used?") as null|anything in setting_choices
|
||||
if(!def)
|
||||
return
|
||||
switch(def)
|
||||
if("Plasma - Standard")
|
||||
plc.CLOTH_CONTAMINATION = 1 //If this is on, plasma does damage by getting into cloth.
|
||||
plc.PLASMAGUARD_ONLY = 0
|
||||
plc.GENETIC_CORRUPTION = 0 //Chance of genetic corruption as well as toxic damage, X in 1000.
|
||||
plc.SKIN_BURNS = 0 //Plasma has an effect similar to mustard gas on the un-suited.
|
||||
plc.EYE_BURNS = 1 //Plasma burns the eyes of anyone not wearing eye protection.
|
||||
plc.PLASMA_HALLUCINATION = 0
|
||||
plc.CONTAMINATION_LOSS = 0.02
|
||||
|
||||
if("Plasma - Low Hazard")
|
||||
plc.CLOTH_CONTAMINATION = 0 //If this is on, plasma does damage by getting into cloth.
|
||||
plc.PLASMAGUARD_ONLY = 0
|
||||
plc.GENETIC_CORRUPTION = 0 //Chance of genetic corruption as well as toxic damage, X in 1000
|
||||
plc.SKIN_BURNS = 0 //Plasma has an effect similar to mustard gas on the un-suited.
|
||||
plc.EYE_BURNS = 1 //Plasma burns the eyes of anyone not wearing eye protection.
|
||||
plc.PLASMA_HALLUCINATION = 0
|
||||
plc.CONTAMINATION_LOSS = 0.01
|
||||
|
||||
if("Plasma - High Hazard")
|
||||
plc.CLOTH_CONTAMINATION = 1 //If this is on, plasma does damage by getting into cloth.
|
||||
plc.PLASMAGUARD_ONLY = 0
|
||||
plc.GENETIC_CORRUPTION = 0 //Chance of genetic corruption as well as toxic damage, X in 1000.
|
||||
plc.SKIN_BURNS = 1 //Plasma has an effect similar to mustard gas on the un-suited.
|
||||
plc.EYE_BURNS = 1 //Plasma burns the eyes of anyone not wearing eye protection.
|
||||
plc.PLASMA_HALLUCINATION = 1
|
||||
plc.CONTAMINATION_LOSS = 0.05
|
||||
|
||||
if("Plasma - Oh Shit!")
|
||||
plc.CLOTH_CONTAMINATION = 1 //If this is on, plasma does damage by getting into cloth.
|
||||
plc.PLASMAGUARD_ONLY = 1
|
||||
plc.GENETIC_CORRUPTION = 5 //Chance of genetic corruption as well as toxic damage, X in 1000.
|
||||
plc.SKIN_BURNS = 1 //Plasma has an effect similar to mustard gas on the un-suited.
|
||||
plc.EYE_BURNS = 1 //Plasma burns the eyes of anyone not wearing eye protection.
|
||||
plc.PLASMA_HALLUCINATION = 1
|
||||
plc.CONTAMINATION_LOSS = 0.075
|
||||
|
||||
if("ZAS - Normal")
|
||||
airflow_push=0
|
||||
airflow_lightest_pressure = 20
|
||||
airflow_light_pressure = 35
|
||||
airflow_medium_pressure = 50
|
||||
airflow_heavy_pressure = 65
|
||||
airflow_dense_pressure = 85
|
||||
airflow_stun_pressure = 60
|
||||
airflow_stun_cooldown = 60
|
||||
airflow_stun = 1
|
||||
airflow_damage = 2
|
||||
airflow_speed_decay = 1.5
|
||||
airflow_delay = 30
|
||||
airflow_mob_slowdown = 1
|
||||
|
||||
if("ZAS - Forgiving")
|
||||
airflow_push=0
|
||||
airflow_lightest_pressure = 45
|
||||
airflow_light_pressure = 60
|
||||
airflow_medium_pressure = 120
|
||||
airflow_heavy_pressure = 110
|
||||
airflow_dense_pressure = 200
|
||||
airflow_stun_pressure = 150
|
||||
airflow_stun_cooldown = 90
|
||||
airflow_stun = 0.15
|
||||
airflow_damage = 0.15
|
||||
airflow_speed_decay = 1.5
|
||||
airflow_delay = 50
|
||||
airflow_mob_slowdown = 0
|
||||
|
||||
if("ZAS - Dangerous")
|
||||
airflow_push=1
|
||||
airflow_lightest_pressure = 15
|
||||
airflow_light_pressure = 30
|
||||
airflow_medium_pressure = 45
|
||||
airflow_heavy_pressure = 55
|
||||
airflow_dense_pressure = 70
|
||||
airflow_stun_pressure = 50
|
||||
airflow_stun_cooldown = 50
|
||||
airflow_stun = 2
|
||||
airflow_damage = 3
|
||||
airflow_speed_decay = 1.2
|
||||
airflow_delay = 25
|
||||
airflow_mob_slowdown = 2
|
||||
|
||||
if("ZAS - Hellish")
|
||||
airflow_push=1
|
||||
airflow_lightest_pressure = 20
|
||||
airflow_light_pressure = 30
|
||||
airflow_medium_pressure = 40
|
||||
airflow_heavy_pressure = 50
|
||||
airflow_dense_pressure = 60
|
||||
airflow_stun_pressure = 40
|
||||
airflow_stun_cooldown = 40
|
||||
airflow_stun = 3
|
||||
airflow_damage = 4
|
||||
airflow_speed_decay = 1
|
||||
airflow_delay = 20
|
||||
airflow_mob_slowdown = 3
|
||||
|
||||
|
||||
to_chat(world, "<span class='notice'><b>[key_name(user)] changed the global plasma/ZAS settings to \"[def]\"</b></span>")
|
||||
|
||||
pl_control
|
||||
var/list/settings = list()
|
||||
New()
|
||||
. = ..()
|
||||
settings = vars.Copy()
|
||||
|
||||
var/datum/D = new() //Ensure only unique vars are put through by making a datum and removing all common vars.
|
||||
for(var/V in D.vars)
|
||||
settings -= V
|
||||
|
||||
for(var/V in settings)
|
||||
if(findtextEx(V,"_RANDOM") || findtextEx(V,"_DESC"))
|
||||
settings -= V
|
||||
|
||||
settings -= "settings"
|
||||
proc/Randomize(V)
|
||||
var/newvalue
|
||||
if("[V]_RANDOM" in vars)
|
||||
if(isnum(vars["[V]_RANDOM"]))
|
||||
newvalue = prob(vars["[V]_RANDOM"])
|
||||
else if(istext(vars["[V]_RANDOM"]))
|
||||
var/txt = vars["[V]_RANDOM"]
|
||||
if(findtextEx(txt,"PROB"))
|
||||
txt = splittext(txt,"/")
|
||||
txt[1] = replacetext(txt[1],"PROB","")
|
||||
var/p = text2num(txt[1])
|
||||
var/r = txt[2]
|
||||
if(prob(p))
|
||||
newvalue = roll(r)
|
||||
else
|
||||
newvalue = vars[V]
|
||||
else if(findtextEx(txt,"PICK"))
|
||||
txt = replacetext(txt,"PICK","")
|
||||
txt = splittext(txt,",")
|
||||
newvalue = pick(txt)
|
||||
else
|
||||
newvalue = roll(txt)
|
||||
else
|
||||
newvalue = vars[V]
|
||||
vars[V] = newvalue
|
||||
@@ -28,11 +28,8 @@ Class Procs:
|
||||
rebuild()
|
||||
Invalidates the zone and marks all its former tiles for updates.
|
||||
|
||||
add_tile_air(turf/simulated/T)
|
||||
Adds the air contained in T.air to the zone's air supply. Called when adding a turf.
|
||||
|
||||
tick()
|
||||
Called only when the gas content is changed. Archives values and changes gas graphics.
|
||||
Called only when the gas content is changed. Changes gas graphics.
|
||||
|
||||
dbg_data(mob/M)
|
||||
Sends M a printout of important figures for the zone.
|
||||
@@ -51,8 +48,7 @@ Class Procs:
|
||||
/zone/New()
|
||||
SSair.add_zone(src)
|
||||
air.temperature = TCMB
|
||||
air.group_multiplier = 1
|
||||
air.volume = CELL_VOLUME
|
||||
air.volume = 0
|
||||
|
||||
/zone/proc/add(turf/simulated/T)
|
||||
#ifdef ZASDBG
|
||||
@@ -62,7 +58,8 @@ Class Procs:
|
||||
#endif
|
||||
|
||||
var/datum/gas_mixture/turf_air = T.return_air()
|
||||
add_tile_air(turf_air)
|
||||
air.volume += turf_air.volume
|
||||
air.merge(turf_air)
|
||||
T.zone = src
|
||||
contents.Add(T)
|
||||
T.set_graphic(air.graphics)
|
||||
@@ -74,12 +71,14 @@ Class Procs:
|
||||
ASSERT(T.zone == src)
|
||||
soft_assert(T in contents, "Lists are weird broseph")
|
||||
#endif
|
||||
contents.Remove(T)
|
||||
|
||||
T.zone = null
|
||||
var/datum/gas_mixture/turf_air = T.return_air()
|
||||
air.volume -= turf_air.volume
|
||||
air.divide(1 + turf_air.volume / air.volume)
|
||||
contents.Remove(T)
|
||||
T.set_graphic(0)
|
||||
if(contents.len)
|
||||
air.group_multiplier = contents.len
|
||||
else
|
||||
if(!contents.len)
|
||||
c_invalidate()
|
||||
|
||||
/zone/proc/c_merge(zone/into)
|
||||
@@ -113,26 +112,36 @@ Class Procs:
|
||||
T.needs_air_update = 0 //Reset the marker so that it will be added to the list.
|
||||
SSair.mark_for_update(T)
|
||||
|
||||
/zone/proc/add_tile_air(datum/gas_mixture/tile_air)
|
||||
//air.volume += CELL_VOLUME
|
||||
air.group_multiplier = 1
|
||||
air.multiply(contents.len)
|
||||
air.merge(tile_air)
|
||||
air.divide(contents.len+1)
|
||||
air.group_multiplier = contents.len+1
|
||||
//Gets a list of the gas_mixtures of all zones connected to this one through arbitrarily many sleeping edges.
|
||||
//This is to cut down somewhat on differentials across open doors.
|
||||
//Yes, recursion is slow, but this will generally not be called very often, and will rarely have to recurse more than a few levels deep.
|
||||
//That said, feel free to optimize it if you want.
|
||||
//
|
||||
//At the top level, just call it with no arg. The arg generally is for internal use.
|
||||
/zone/proc/get_equalized_zone_air(list/found = list())
|
||||
found += air
|
||||
. = found //I want to minimize the call stack left over after the recursive call. Honestly the implicit return is probably the same as an explicit one, but I'd rather play it safe.
|
||||
for(var/connection_edge/zone/E in edges)
|
||||
if(E.sleeping)
|
||||
var/zone/Z = E.get_connected_zone(src)
|
||||
if(!(Z.air in found))
|
||||
Z.get_equalized_zone_air(found)
|
||||
|
||||
/zone/proc/tick()
|
||||
air.archive()
|
||||
if(air.check_tile_graphic())
|
||||
for(var/turf/simulated/T in contents)
|
||||
T.set_graphic(air.graphics)
|
||||
|
||||
for(var/connection_edge/E in edges)
|
||||
if(E.sleeping)
|
||||
E.recheck()
|
||||
|
||||
/zone/proc/dbg_data(mob/M)
|
||||
to_chat(M, name)
|
||||
to_chat(M, "O2: [air.oxygen] N2: [air.nitrogen] CO2: [air.carbon_dioxide] P: [air.toxins]")
|
||||
to_chat(M, "P: [air.return_pressure()] kPa V: [air.volume]L T: [air.temperature]<5D>K ([air.temperature - T0C]<5D>C)")
|
||||
to_chat(M, "O2 per N2: [(air.nitrogen ? air.oxygen/air.nitrogen : "N/A")] Moles: [air.total_moles]")
|
||||
to_chat(M, "Simulated: [contents.len] ([air.group_multiplier])")
|
||||
to_chat(M, "Simulated: [contents.len] ([air.volume / CELL_VOLUME])")
|
||||
// to_chat(M, "Unsimulated: [unsimulated_contents.len]")
|
||||
// to_chat(M, "Edges: [edges.len]")
|
||||
if(invalid)
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -144,8 +144,6 @@ Class Procs:
|
||||
simulated_turf_count++
|
||||
S.update_air_properties()
|
||||
|
||||
processing_parts[SSAIR_EDGES] = edges //A temporary hack to make edges actually work before the later PR to add edge sleeping, etc.
|
||||
|
||||
to_chat(world, {"<span class='info'>Total Simulated Turfs: [simulated_turf_count]
|
||||
Total Zones: [zones.len]
|
||||
Total Edges: [edges.len]
|
||||
@@ -353,33 +351,31 @@ Total Unsimulated Turfs: [world.maxx*world.maxy*world.maxz - simulated_turf_coun
|
||||
Z.needs_update = 1
|
||||
|
||||
|
||||
//The following is for a system update coming in a later PR.
|
||||
/datum/subsystem/air/proc/mark_edge_sleeping(connection_edge/E)
|
||||
#ifdef ZASDBG
|
||||
ASSERT(istype(E))
|
||||
#endif
|
||||
if(E.sleeping)
|
||||
return
|
||||
processing_parts[SSAIR_EDGES] -= E
|
||||
E.sleeping = 1
|
||||
|
||||
///datum/subsystem/air/proc/mark_edge_sleeping(connection_edge/E)
|
||||
// #ifdef ZASDBG
|
||||
// ASSERT(istype(E))
|
||||
// #endif
|
||||
// if(E.sleeping)
|
||||
// return
|
||||
// processing_parts[SSAIR_EDGES] -= E
|
||||
// E.sleeping = 1
|
||||
//
|
||||
//
|
||||
///datum/subsystem/air/proc/mark_edge_active(connection_edge/E)
|
||||
// #ifdef ZASDBG
|
||||
// ASSERT(istype(E))
|
||||
// #endif
|
||||
// if(!E.sleeping)
|
||||
// return
|
||||
// processing_parts[SSAIR_EDGES] |= E
|
||||
// E.sleeping = 0
|
||||
// #ifdef ZASDBG
|
||||
// if(istype(E, /connection_edge/zone/))
|
||||
// var/connection_edge/zone/ZE = E
|
||||
// world << "ZASDBG: Active edge! Areas: [get_area(pick(ZE.A.contents))] / [get_area(pick(ZE.B.contents))]"
|
||||
// else
|
||||
// world << "ZASDBG: Active edge! Area: [get_area(pick(E.A.contents))]"
|
||||
// #endif
|
||||
|
||||
/datum/subsystem/air/proc/mark_edge_active(connection_edge/E)
|
||||
#ifdef ZASDBG
|
||||
ASSERT(istype(E))
|
||||
#endif
|
||||
if(!E.sleeping)
|
||||
return
|
||||
processing_parts[SSAIR_EDGES] |= E
|
||||
E.sleeping = 0
|
||||
#ifdef ZASDBG
|
||||
if(istype(E, /connection_edge/zone/))
|
||||
var/connection_edge/zone/ZE = E
|
||||
world << "ZASDBG: Active edge! Areas: [get_area(pick(ZE.A.contents))] / [get_area(pick(ZE.B.contents))]"
|
||||
else
|
||||
world << "ZASDBG: Active edge! Area: [get_area(pick(E.A.contents))]"
|
||||
#endif
|
||||
|
||||
|
||||
/datum/subsystem/air/proc/equivalent_pressure(zone/A, zone/B)
|
||||
@@ -394,7 +390,7 @@ Total Unsimulated Turfs: [world.maxx*world.maxy*world.maxz - simulated_turf_coun
|
||||
return edge
|
||||
var/connection_edge/edge = new/connection_edge/zone(A,B)
|
||||
edges.Add(edge)
|
||||
// edge.recheck()
|
||||
edge.recheck()
|
||||
return edge
|
||||
else
|
||||
for(var/connection_edge/unsimulated/edge in A.edges)
|
||||
@@ -402,7 +398,7 @@ Total Unsimulated Turfs: [world.maxx*world.maxy*world.maxz - simulated_turf_coun
|
||||
return edge
|
||||
var/connection_edge/edge = new/connection_edge/unsimulated(A,B)
|
||||
edges.Add(edge)
|
||||
// edge.recheck()
|
||||
edge.recheck()
|
||||
return edge
|
||||
|
||||
|
||||
@@ -422,8 +418,8 @@ Total Unsimulated Turfs: [world.maxx*world.maxy*world.maxz - simulated_turf_coun
|
||||
|
||||
/datum/subsystem/air/proc/remove_edge(connection_edge/E)
|
||||
edges.Remove(E)
|
||||
// if(!E.sleeping)
|
||||
// processing_parts[SSAIR_EDGES] -= E
|
||||
if(!E.sleeping)
|
||||
processing_parts[SSAIR_EDGES] -= E
|
||||
|
||||
|
||||
/datum/subsystem/air/proc/add_hotspot(var/obj/effect/fire/H)
|
||||
|
||||
@@ -23,7 +23,8 @@
|
||||
/obj/machinery/atmospherics/miner/New()
|
||||
..()
|
||||
air_contents = new
|
||||
air_contents.volume=1000
|
||||
air_contents.volume = 1000
|
||||
pumping.volume = 1000 //Same as above so copying works correctly
|
||||
air_contents.temperature = T20C
|
||||
AddAir()
|
||||
air_contents.update_values()
|
||||
|
||||
@@ -26,4 +26,4 @@
|
||||
// if (!my_air.compare(conn_air))
|
||||
// myturf.reset_delay()
|
||||
// zturf_conn.reset_delay()
|
||||
my_air.share(conn_air)
|
||||
my_air.share_tiles(conn_air, 1)
|
||||
|
||||
@@ -349,13 +349,13 @@ Subject's pulse: ??? BPM"})
|
||||
var/unknown_concentration = 1 - (o2_concentration + n2_concentration + co2_concentration + plasma_concentration)
|
||||
|
||||
if(n2_concentration > 0.01)
|
||||
message += "<br>[human_standard && abs(n2_concentration - N2STANDARD) > 20 ? "<span class='bad'>" : "<span class='notice'>"] Nitrogen: [round(scanned.nitrogen, 0.1)] mol, [round(n2_concentration*100)]%</span>"
|
||||
message += "<br>[human_standard && abs(n2_concentration - N2STANDARD) > 20 ? "<span class='bad'>" : "<span class='notice'>"] Nitrogen: [round(scanned.nitrogen / scanned.volume * CELL_VOLUME, 0.1)] mol, [round(n2_concentration*100)]%</span>"
|
||||
if(o2_concentration > 0.01)
|
||||
message += "<br>[human_standard && abs(o2_concentration - O2STANDARD) > 2 ? "<span class='bad'>" : "<span class='notice'>"] Oxygen: [round(scanned.oxygen, 0.1)] mol, [round(o2_concentration*100)]%</span>"
|
||||
message += "<br>[human_standard && abs(o2_concentration - O2STANDARD) > 2 ? "<span class='bad'>" : "<span class='notice'>"] Oxygen: [round(scanned.oxygen / scanned.volume * CELL_VOLUME, 0.1)] mol, [round(o2_concentration*100)]%</span>"
|
||||
if(co2_concentration > 0.01)
|
||||
message += "<br>[human_standard ? "<span class='bad'>" : "<span class='notice'>"] CO2: [round(scanned.carbon_dioxide, 0.1)] mol, [round(co2_concentration*100)]%</span>"
|
||||
message += "<br>[human_standard ? "<span class='bad'>" : "<span class='notice'>"] CO2: [round(scanned.carbon_dioxide / scanned.volume * CELL_VOLUME, 0.1)] mol, [round(co2_concentration*100)]%</span>"
|
||||
if(plasma_concentration > 0.01)
|
||||
message += "<br>[human_standard ? "<span class='bad'>" : "<span class='notice'>"] Plasma: [round(scanned.toxins, 0.1)] mol, [round(plasma_concentration*100)]%</span>"
|
||||
message += "<br>[human_standard ? "<span class='bad'>" : "<span class='notice'>"] Plasma: [round(scanned.toxins / scanned.volume * CELL_VOLUME, 0.1)] mol, [round(plasma_concentration*100)]%</span>"
|
||||
if(unknown_concentration > 0.01)
|
||||
message += "<br><span class='notice'>Unknown: [round(unknown_concentration*100)]%</span>"
|
||||
|
||||
|
||||
@@ -623,42 +623,43 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
|
||||
|
||||
var/pressure = environment.return_pressure()
|
||||
var/total_moles = environment.total_moles()
|
||||
var/tiles = environment.return_volume() / CELL_VOLUME
|
||||
|
||||
to_chat(src, "<span class='notice'><B>Results:</B></span>")
|
||||
if(abs(pressure - ONE_ATMOSPHERE) < 10)
|
||||
to_chat(src, "<span class='notice'>Pressure: [round(pressure,0.1)] kPa</span>")
|
||||
to_chat(src, "<span class='notice'>Pressure: [round(pressure, 0.1)] kPa</span>")
|
||||
else
|
||||
to_chat(src, "<span class='warning'>Pressure: [round(pressure,0.1)] kPa</span>")
|
||||
to_chat(src, "<span class='warning'>Pressure: [round(pressure, 0.1)] kPa</span>")
|
||||
if(total_moles)
|
||||
var/o2_concentration = environment.oxygen/total_moles
|
||||
var/n2_concentration = environment.nitrogen/total_moles
|
||||
var/co2_concentration = environment.carbon_dioxide/total_moles
|
||||
var/plasma_concentration = environment.toxins/total_moles
|
||||
var/o2_concentration = environment.oxygen / total_moles
|
||||
var/n2_concentration = environment.nitrogen / total_moles
|
||||
var/co2_concentration = environment.carbon_dioxide / total_moles
|
||||
var/plasma_concentration = environment.toxins / total_moles
|
||||
|
||||
var/unknown_concentration = 1-(o2_concentration+n2_concentration+co2_concentration+plasma_concentration)
|
||||
var/unknown_concentration = 1 - (o2_concentration + n2_concentration + co2_concentration + plasma_concentration)
|
||||
if(abs(n2_concentration - N2STANDARD) < 20)
|
||||
to_chat(src, "<span class='notice'>Nitrogen: [round(n2_concentration*100)]% ([round(environment.nitrogen,0.01)] moles)</span>")
|
||||
to_chat(src, "<span class='notice'>Nitrogen: [round(n2_concentration * 100)]% ([round(environment.nitrogen / tiles, 0.01)] moles)</span>")
|
||||
else
|
||||
to_chat(src, "<span class='warning'>Nitrogen: [round(n2_concentration*100)]% ([round(environment.nitrogen,0.01)] moles)</span>")
|
||||
to_chat(src, "<span class='warning'>Nitrogen: [round(n2_concentration * 100)]% ([round(environment.nitrogen / tiles, 0.01)] moles)</span>")
|
||||
|
||||
if(abs(o2_concentration - O2STANDARD) < 2)
|
||||
to_chat(src, "<span class='notice'>Oxygen: [round(o2_concentration*100)]% ([round(environment.oxygen,0.01)] moles)</span>")
|
||||
to_chat(src, "<span class='notice'>Oxygen: [round(o2_concentration * 100)]% ([round(environment.oxygen / tiles, 0.01)] moles)</span>")
|
||||
else
|
||||
to_chat(src, "<span class='warning'>Oxygen: [round(o2_concentration*100)]% ([round(environment.oxygen,0.01)] moles)</span>")
|
||||
to_chat(src, "<span class='warning'>Oxygen: [round(o2_concentration * 100)]% ([round(environment.oxygen / tiles, 0.01)] moles)</span>")
|
||||
|
||||
if(co2_concentration > 0.01)
|
||||
to_chat(src, "<span class='warning'>CO2: [round(co2_concentration*100)]% ([round(environment.carbon_dioxide,0.01)] moles)</span>")
|
||||
to_chat(src, "<span class='warning'>CO2: [round(co2_concentration * 100)]% ([round(environment.carbon_dioxide / tiles, 0.01)] moles)</span>")
|
||||
else
|
||||
to_chat(src, "<span class='notice'>CO2: [round(co2_concentration*100)]% ([round(environment.carbon_dioxide,0.01)] moles)</span>")
|
||||
to_chat(src, "<span class='notice'>CO2: [round(co2_concentration * 100)]% ([round(environment.carbon_dioxide / tiles, 0.01)] moles)</span>")
|
||||
|
||||
if(plasma_concentration > 0.01)
|
||||
to_chat(src, "<span class='warning'>Plasma: [round(plasma_concentration*100)]% ([round(environment.toxins,0.01)] moles)</span>")
|
||||
to_chat(src, "<span class='warning'>Plasma: [round(plasma_concentration * 100)]% ([round(environment.toxins / tiles, 0.01)] moles)</span>")
|
||||
|
||||
if(unknown_concentration > 0.01)
|
||||
to_chat(src, "<span class='warning'>Unknown: [round(unknown_concentration*100)]% ([round(unknown_concentration*total_moles,0.01)] moles)</span>")
|
||||
to_chat(src, "<span class='warning'>Unknown: [round(unknown_concentration * 100)]% ([round(unknown_concentration * total_moles / tiles, 0.01)] moles)</span>")
|
||||
|
||||
to_chat(src, "<span class='notice'>Temperature: [round(environment.temperature-T0C,0.1)]°C</span>")
|
||||
to_chat(src, "<span class='notice'>Heat Capacity: [round(environment.heat_capacity(),0.1)]</span>")
|
||||
to_chat(src, "<span class='notice'>Temperature: [round(environment.temperature - T0C, 0.1)]°C</span>")
|
||||
to_chat(src, "<span class='notice'>Heat Capacity: [round(environment.heat_capacity(), 0.1)]</span>")
|
||||
|
||||
|
||||
/mob/dead/observer/verb/toggle_darkness()
|
||||
|
||||
Reference in New Issue
Block a user