Going back to BS12 ZAS, permanently

This commit is contained in:
ZomgPonies
2013-11-08 09:51:22 -05:00
parent 950011d4d8
commit 0e201cc4a5
33 changed files with 3205 additions and 3019 deletions
@@ -236,144 +236,144 @@ proc/AirflowSpace(zone/A)
if(M) M.GotoAirflowDest(n/10)
//Sometimes shit breaks, and M isn't there after the spawn.
atom/movable
var/tmp/turf/airflow_dest
var/tmp/airflow_speed = 0
var/tmp/airflow_time = 0
var/tmp/last_airflow = 0
proc/GotoAirflowDest(n)
if(!zas_settings.Get(/datum/ZAS_Setting/airflow_push)) return // If not enabled, fuck it.
if(!airflow_dest) return
if(airflow_speed < 0) return
if(last_airflow > world.time - zas_settings.Get(/datum/ZAS_Setting/airflow_delay)) return
if(airflow_speed)
airflow_speed = n/max(get_dist(src,airflow_dest),1)
/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
/atom/movable/proc/GotoAirflowDest(n)
if(!zas_settings.Get(/datum/ZAS_Setting/airflow_push)) return // If not enabled, fuck it.
if(!airflow_dest) return
if(airflow_speed < 0) return
if(last_airflow > world.time - zas_settings.Get(/datum/ZAS_Setting/airflow_delay)) return
if(airflow_speed)
airflow_speed = n/max(get_dist(src,airflow_dest),1)
return
last_airflow = world.time
if(airflow_dest == loc)
step_away(src,loc)
if(ismob(src))
if(src:status_flags & GODMODE)
return
last_airflow = world.time
if(airflow_dest == loc)
step_away(src,loc)
if(ismob(src))
if(src:status_flags & GODMODE)
if(istype(src, /mob/living/carbon/human))
if(src:buckled)
return
if(istype(src, /mob/living/carbon/human))
if(src:buckled)
return
if(src:shoes)
if(istype(src:shoes, /obj/item/clothing/shoes/magboots))
if(src:shoes:magpulse)
return
src << "\red You are sucked away by airflow!"
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 = min(max(n * (9/airflow_falloff),1),9)
var
xo = airflow_dest.x - src.x
yo = airflow_dest.y - src.y
od = 0
if(src:shoes)
if(istype(src:shoes, /obj/item/clothing/shoes/magboots))
if(src:shoes:magpulse)
return
src << "\red You are sucked away by airflow!"
var/airflow_falloff = 9 - ul_FalloffAmount(airflow_dest) //It's a fast falloff calc. Very useful.
if(airflow_falloff < 1)
airflow_dest = null
if(!density)
density = 1
od = 1
while(airflow_speed > 0)
if(airflow_speed <= 0) return
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)
if(od)
density = 0
sleep(1 * tick_multiplier)
else
return
airflow_speed = min(max(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
while(airflow_speed > 0)
if(airflow_speed <= 0) return
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)
if(od)
density = 0
sleep(max(1,10-(airflow_speed+3)) * tick_multiplier)
if(od)
density = 1
if ((!( src.airflow_dest ) || src.loc == src.airflow_dest))
src.airflow_dest = locate(min(max(src.x + xo, 1), world.maxx), min(max(src.y + yo, 1), world.maxy), src.z)
if ((src.x == 1 || src.x == world.maxx || src.y == 1 || src.y == world.maxy))
return
if(!istype(loc, /turf))
return
step_towards(src, src.airflow_dest)
if(ismob(src) && src:client)
src:client:move_delay = world.time + zas_settings.Get(/datum/ZAS_Setting/airflow_mob_slowdown)
airflow_dest = null
airflow_speed = 0
airflow_time = 0
if(od)
density = 0
proc/RepelAirflowDest(n)
if(!zas_settings.Get(/datum/ZAS_Setting/airflow_push)) return // If not enabled, fuck it.
if(!airflow_dest) return
if(airflow_speed < 0) return
if(last_airflow > world.time - zas_settings.Get(/datum/ZAS_Setting/airflow_delay)) return
if(airflow_speed)
airflow_speed = n/max(get_dist(src,airflow_dest),1)
return
if(airflow_dest == loc)
step_away(src,loc)
if(ismob(src))
if(src:status_flags & GODMODE)
return
if(istype(src, /mob/living/carbon/human))
if(src:buckled)
return
if(src:shoes)
if(istype(src:shoes, /obj/item/clothing/shoes/magboots))
if(src:shoes.flags & NOSLIP)
return
src << "\red You are pushed away by airflow!"
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 = min(max(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
while(airflow_speed > 0)
if(airflow_speed <= 0) return
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(1 * tick_multiplier)
else
sleep(max(1,10-(airflow_speed+3)) * tick_multiplier)
if ((!( src.airflow_dest ) || src.loc == src.airflow_dest))
src.airflow_dest = locate(min(max(src.x + xo, 1), world.maxx), min(max(src.y + yo, 1), world.maxy), src.z)
if ((src.x == 1 || src.x == world.maxx || src.y == 1 || src.y == world.maxy))
return
if(!istype(loc, /turf))
return
step_towards(src, src.airflow_dest)
if(ismob(src) && src:client)
src:client:move_delay = world.time + zas_settings.Get(/datum/ZAS_Setting/airflow_mob_slowdown)
airflow_dest = null
airflow_speed = 0
airflow_time = 0
if(od)
density = 0
Bump(atom/A)
if(airflow_speed > 0 && airflow_dest)
airflow_hit(A)
sleep(1 * tick_multiplier)
else
airflow_speed = 0
airflow_time = 0
. = ..()
if(od)
density = 0
sleep(max(1,10-(airflow_speed+3)) * tick_multiplier)
if(od)
density = 1
if ((!( src.airflow_dest ) || src.loc == src.airflow_dest))
src.airflow_dest = locate(min(max(src.x + xo, 1), world.maxx), min(max(src.y + yo, 1), world.maxy), src.z)
if ((src.x == 1 || src.x == world.maxx || src.y == 1 || src.y == world.maxy))
return
if(!istype(loc, /turf))
return
step_towards(src, src.airflow_dest)
if(ismob(src) && src:client)
src:client:move_delay = world.time + 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(!zas_settings.Get(/datum/ZAS_Setting/airflow_push)) return // If not enabled, fuck it.
if(!airflow_dest) return
if(airflow_speed < 0) return
if(last_airflow > world.time - zas_settings.Get(/datum/ZAS_Setting/airflow_delay)) return
if(airflow_speed)
airflow_speed = n/max(get_dist(src,airflow_dest),1)
return
if(airflow_dest == loc)
step_away(src,loc)
if(ismob(src))
if(src:status_flags & GODMODE)
return
if(istype(src, /mob/living/carbon/human))
if(src:buckled)
return
if(src:shoes)
if(istype(src:shoes, /obj/item/clothing/shoes/magboots))
if(src:shoes.flags & NOSLIP)
return
src << "\red You are pushed away by airflow!"
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 = min(max(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
while(airflow_speed > 0)
if(airflow_speed <= 0) return
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(1 * tick_multiplier)
else
sleep(max(1,10-(airflow_speed+3)) * tick_multiplier)
if ((!( src.airflow_dest ) || src.loc == src.airflow_dest))
src.airflow_dest = locate(min(max(src.x + xo, 1), world.maxx), min(max(src.y + yo, 1), world.maxy), src.z)
if ((src.x == 1 || src.x == world.maxx || src.y == 1 || src.y == world.maxy))
return
if(!istype(loc, /turf))
return
step_towards(src, src.airflow_dest)
if(ismob(src) && src:client)
src:client:move_delay = world.time + zas_settings.Get(/datum/ZAS_Setting/airflow_mob_slowdown)
airflow_dest = null
airflow_speed = 0
airflow_time = 0
if(od)
density = 0
/atom/movable/Bump(atom/A)
if(airflow_speed > 0 && airflow_dest)
airflow_hit(A)
else
airflow_speed = 0
airflow_time = 0
. = ..()
atom/movable/proc/airflow_hit(atom/A)
airflow_speed = 0
@@ -429,6 +429,6 @@ zone/proc/movables()
. = list()
for(var/turf/T in contents)
for(var/atom/A in T)
if(istype(A, /obj/effect) || istype(A, /mob/camera))
if(istype(A, /obj/effect) || isobserver(A) || istype(A, /mob/camera))
continue
. += A
File diff suppressed because it is too large Load Diff
@@ -43,148 +43,142 @@ turf/simulated/hotspot_expose(exposed_temperature, exposed_volume, soh)
return igniting
obj
fire
//Icon for fire on turfs.
/obj/fire
//Icon for fire on turfs.
anchored = 1
mouse_opacity = 0
anchored = 1
mouse_opacity = 0
//luminosity = 3
//luminosity = 3
icon = 'icons/effects/fire.dmi'
icon = 'icons/effects/fire.dmi'
icon_state = "1"
layer = TURF_LAYER
var/firelevel = 10000 //Calculated by gas_mixture.calculate_firelevel()
/obj/fire/process()
. = 1
//get location and check if it is in a proper ZAS zone
var/turf/simulated/S = loc
if(!istype(S))
del src
if(!S.zone)
del src
var/datum/gas_mixture/air_contents = S.return_air()
//get liquid fuels on the ground.
var/obj/effect/decal/cleanable/liquid_fuel/liquid = locate() in S
//and the volatile stuff from the air
var/datum/gas/volatile_fuel/fuel = locate() in air_contents.trace_gases
//since the air is processed in fractions, we need to make sure not to have any minuscle residue or
//the amount of moles might get to low for some functions to catch them and thus result in wonky behaviour
if(air_contents.oxygen < 0.001)
air_contents.oxygen = 0
if(air_contents.toxins < 0.001)
air_contents.toxins = 0
if(fuel)
if(fuel.moles < 0.001)
air_contents.trace_gases.Remove(fuel)
//check if there is something to combust
if(!air_contents.check_recombustability(liquid))
//del src
RemoveFire()
//get a firelevel and set the icon
firelevel = air_contents.calculate_firelevel(liquid)
if(firelevel > 6)
icon_state = "3"
SetLuminosity(7)
else if(firelevel > 2.5)
icon_state = "2"
SetLuminosity(5)
else
icon_state = "1"
SetLuminosity(3)
layer = TURF_LAYER
//im not sure how to implement a version that works for every creature so for now monkeys are firesafe
for(var/mob/living/carbon/human/M in loc)
M.FireBurn(firelevel, air_contents.temperature, air_contents.return_pressure() ) //Burn the humans!
for(var/atom/A in loc)
A.fire_act(air_contents, air_contents.temperature, air_contents.return_volume())
//spread
for(var/direction in cardinal)
if(S.air_check_directions&direction) //Grab all valid bordering tiles
var
firelevel = 10000 //Calculated by gas_mixture.calculate_firelevel()
var/turf/simulated/enemy_tile = get_step(S, direction)
process()
. = 1
if(istype(enemy_tile))
var/datum/gas_mixture/acs = enemy_tile.return_air()
var/obj/effect/decal/cleanable/liquid_fuel/liq = locate() in enemy_tile
if(!acs) continue
if(!acs.check_recombustability(liq)) continue
//If extinguisher mist passed over the turf it's trying to spread to, don't spread and
//reduce firelevel.
if(enemy_tile.fire_protection > world.time-30)
firelevel -= 1.5
continue
//get location and check if it is in a proper ZAS zone
var/turf/simulated/S = loc
//Spread the fire.
if(!(locate(/obj/fire) in enemy_tile))
if( prob( 50 + 50 * (firelevel/zas_settings.Get(/datum/ZAS_Setting/fire_firelevel_multiplier)) ) && S.CanPass(null, enemy_tile, 0,0) && enemy_tile.CanPass(null, S, 0,0))
new/obj/fire(enemy_tile,firelevel)
if(!istype(S))
src.gc_del()
if(!S.zone)
src.gc_del()
var/datum/gas_mixture/air_contents = S.return_air()
//get liquid fuels on the ground.
var/obj/effect/decal/cleanable/liquid_fuel/liquid = locate() in S
//and the volatile stuff from the air
var/datum/gas/volatile_fuel/fuel = locate() in air_contents.trace_gases
//since the air is processed in fractions, we need to make sure not to have any minuscle residue or
//the amount of moles might get to low for some functions to catch them and thus result in wonky behaviour
if(air_contents.oxygen < 0.001)
air_contents.oxygen = 0
if(air_contents.toxins < 0.001)
air_contents.toxins = 0
if(fuel)
if(fuel.moles < 0.001)
air_contents.trace_gases.Remove(fuel)
//check if there is something to combust
if(!air_contents.check_recombustability(liquid))
//src.gc_del()
RemoveFire()
//get a firelevel and set the icon
firelevel = air_contents.calculate_firelevel(liquid)
if(firelevel > 6)
icon_state = "3"
SetLuminosity(7)
else if(firelevel > 2.5)
icon_state = "2"
SetLuminosity(5)
else
icon_state = "1"
SetLuminosity(3)
//im not sure how to implement a version that works for every creature so for now monkeys are firesafe
for(var/mob/living/carbon/human/M in loc)
M.FireBurn(firelevel, air_contents.temperature, air_contents.return_pressure() ) //Burn the humans!
for(var/atom/A in loc)
A.fire_act(air_contents, air_contents.temperature, air_contents.return_volume())
//spread
for(var/direction in cardinal)
if(S.air_check_directions&direction) //Grab all valid bordering tiles
var/turf/simulated/enemy_tile = get_step(S, direction)
if(istype(enemy_tile))
var/datum/gas_mixture/acs = enemy_tile.return_air()
var/obj/effect/decal/cleanable/liquid_fuel/liq = locate() in enemy_tile
if(!acs) continue
if(!acs.check_recombustability(liq)) continue
//If extinguisher mist passed over the turf it's trying to spread to, don't spread and
//reduce firelevel.
if(enemy_tile.fire_protection > world.time-30)
firelevel -= 1.5
continue
//Spread the fire.
if(!(locate(/obj/fire) in enemy_tile))
if( prob( 50 + 50 * (firelevel/zas_settings.Get(/datum/ZAS_Setting/fire_firelevel_multiplier)) ) && S.CanPass(null, enemy_tile, 0,0) && enemy_tile.CanPass(null, S, 0,0))
new/obj/fire(enemy_tile,firelevel)
//seperate part of the present gas
//this is done to prevent the fire burning all gases in a single pass
var/datum/gas_mixture/flow = air_contents.remove_ratio(zas_settings.Get(/datum/ZAS_Setting/fire_consumption_rate))
//seperate part of the present gas
//this is done to prevent the fire burning all gases in a single pass
var/datum/gas_mixture/flow = air_contents.remove_ratio(zas_settings.Get(/datum/ZAS_Setting/fire_consumption_rate))
///////////////////////////////// FLOW HAS BEEN CREATED /// DONT DELETE THE FIRE UNTIL IT IS MERGED BACK OR YOU WILL DELETE AIR ///////////////////////////////////////////////
if(flow)
if(flow)
if(flow.check_recombustability(liquid))
//Ensure flow temperature is higher than minimum fire temperatures.
//this creates some energy ex nihilo but is necessary to get a fire started
//lets just pretend this energy comes from the ignition source and dont mention this again
//flow.temperature = max(PLASMA_MINIMUM_BURN_TEMPERATURE+0.1,flow.temperature)
if(flow.check_recombustability(liquid))
//Ensure flow temperature is higher than minimum fire temperatures.
//this creates some energy ex nihilo but is necessary to get a fire started
//lets just pretend this energy comes from the ignition source and dont mention this again
//flow.temperature = max(PLASMA_MINIMUM_BURN_TEMPERATURE+0.1,flow.temperature)
//burn baby burn!
//burn baby burn!
flow.zburn(liquid,1)
//merge the air back
S.assume_air(flow)
flow.zburn(liquid,1)
//merge the air back
S.assume_air(flow)
///////////////////////////////// FLOW HAS BEEN REMERGED /// feel free to delete the fire again from here on /////////////////////////////////////////////////////////////////
///////////////////////////////// FLOW HAS BEEN REMERGED /// feel free to delete the fire again from here on //////////////////////////////////////////////////////////////////
New(newLoc,fl)
..()
/obj/fire/New(newLoc,fl)
..()
if(!istype(loc, /turf))
src.gc_del()
if(!istype(loc, /turf))
del src
dir = pick(cardinal)
SetLuminosity(3)
firelevel = fl
air_master.active_hotspots.Add(src)
dir = pick(cardinal)
SetLuminosity(3)
firelevel = fl
air_master.active_hotspots.Add(src)
Del()
if (istype(loc, /turf/simulated))
SetLuminosity(0)
/obj/fire/Del()
if (istype(loc, /turf/simulated))
SetLuminosity(0)
loc = null
air_master.active_hotspots.Remove(src)
loc = null
air_master.active_hotspots.Remove(src)
..()
..()
proc/RemoveFire()
if (istype(loc, /turf/simulated))
SetLuminosity(0)
loc = null
air_master.active_hotspots.Remove(src)
proc/gc_del()
loc = null
air_master.active_hotspots.Remove(src)
/obj/fire/proc/RemoveFire()
if (istype(loc, /turf/simulated))
SetLuminosity(0)
loc = null
air_master.active_hotspots.Remove(src)
@@ -78,7 +78,7 @@ proc/FloodFill(turf/simulated/start)
proc/ZMerge(zone/A,zone/B)
//Sanity~
if(!istype(A) || !istype(B) || !istype(B.air) || !istype(A.air))
if(!istype(A) || !istype(B))
return
var/new_contents = A.contents + B.contents
@@ -2,22 +2,22 @@ var/image/contamination_overlay = image('icons/effects/contamination.dmi')
obj/var/contaminated = 0
obj/item/proc
can_contaminate()
//Clothing and backpacks can be contaminated.
if(flags & PLASMAGUARD) return 0
else if(istype(src,/obj/item/weapon/storage/backpack)) return 0 //Cannot be washed :(
else if(istype(src,/obj/item/clothing)) return 1
contaminate()
//Do a contamination overlay? Temporary measure to keep contamination less deadly than it was.
if(!contaminated)
contaminated = 1
overlays += contamination_overlay
/obj/item/proc/can_contaminate()
//Clothing and backpacks can be contaminated.
if(flags & PLASMAGUARD) return 0
else if(istype(src,/obj/item/weapon/storage/backpack)) return 0 //Cannot be washed :(
else if(istype(src,/obj/item/clothing)) return 1
decontaminate()
contaminated = 0
overlays -= contamination_overlay
/obj/item/proc/contaminate()
//Do a contamination overlay? Temporary measure to keep contamination less deadly than it was.
if(!contaminated)
contaminated = 1
overlays += contamination_overlay
/obj/item/proc/decontaminate()
contaminated = 0
overlays -= contamination_overlay
/mob/proc/contaminate()
+394
View File
@@ -0,0 +1,394 @@
/atom/var/pressure_resistance = ONE_ATMOSPHERE
/turf/var/zone/zone
/turf/assume_air(datum/gas_mixture/giver) //use this for machines to adjust air
del(giver)
return 0
/turf/return_air()
//Create gas mixture to hold data for passing
var/datum/gas_mixture/GM = new
GM.oxygen = oxygen
GM.carbon_dioxide = carbon_dioxide
GM.nitrogen = nitrogen
GM.toxins = toxins
GM.temperature = temperature
GM.update_values()
return GM
// For new turfs
/turf/proc/copy_air_from(var/turf/T)
oxygen = T.oxygen
carbon_dioxide = T.carbon_dioxide
nitrogen = T.nitrogen
toxins = T.toxins
temperature = T.temperature
/turf/remove_air(amount as num)
var/datum/gas_mixture/GM = new
var/sum = oxygen + carbon_dioxide + nitrogen + toxins
if(sum>0)
GM.oxygen = (oxygen/sum)*amount
GM.carbon_dioxide = (carbon_dioxide/sum)*amount
GM.nitrogen = (nitrogen/sum)*amount
GM.toxins = (toxins/sum)*amount
GM.temperature = temperature
GM.update_values()
return GM
/turf/simulated/var/current_graphic = null
/turf/simulated/var/tmp/datum/gas_mixture/air
/turf/simulated/var/tmp/processing = 1
/turf/simulated/var/tmp/air_check_directions = 0 //Do not modify this, just add turf to air_master.tiles_to_update
/turf/simulated/var/tmp/obj/fire/active_hotspot
/turf/simulated/var/tmp/was_icy=0
/turf/simulated/proc/update_visuals()
overlays = null
var/siding_icon_state = return_siding_icon_state()
if(siding_icon_state)
overlays += image('icons/turf/floors.dmi',siding_icon_state)
// ONLY USED IF ZAS_SETTINGS SAYS SO.
var/datum/gas_mixture/model = return_air()
if(model.graphics & GRAPHICS_COLD)
if(!was_icy)
wet=3 // Custom ice
was_icy=1
var/o=""
//if(is_plating())
// o="snowfloor_s"
//else
if(is_plasteel_floor())
o="snowfloor"
if(o!="")
overlays += image('icons/turf/overlays.dmi',o)
else
if(was_icy)
wet=0
was_icy=0
if(prob(10))
wet = 1
if(wet_overlay)
overlays -= wet_overlay
wet_overlay = null
wet_overlay = image('icons/effects/water.dmi',src,"wet_floor")
overlays += wet_overlay
spawn(800)
if (!istype(src)) return
if(wet >= 2) return
wet = 0
if(wet_overlay)
overlays -= wet_overlay
wet_overlay = null
if(model.graphics & GRAPHICS_PLASMA)
overlays.Add(plmaster)
if(model.graphics & GRAPHICS_N2O)
overlays.Add(slmaster)
//if(model.graphics & GRAPHICS_REAGENTS)
// overlays.Add(slmaster/*rlmaster*/)
/turf/simulated/New()
..()
if(!blocks_air)
air = new
air.oxygen = oxygen
air.carbon_dioxide = carbon_dioxide
air.nitrogen = nitrogen
air.toxins = toxins
air.temperature = temperature
air.update_values()
if(air_master)
air_master.tiles_to_update.Add(src)
else
if(air_master)
for(var/direction in cardinal)
var/turf/simulated/floor/target = get_step(src,direction)
if(istype(target))
air_master.tiles_to_update |= target
/turf/simulated/Del()
if(active_hotspot)
del(active_hotspot)
if(blocks_air)
for(var/direction in list(NORTH, SOUTH, EAST, WEST))
var/turf/simulated/tile = get_step(src,direction)
if(istype(tile) && !tile.blocks_air)
air_master.tiles_to_update.Add(tile)
..()
/turf/simulated/copy_air_from(var/turf/T)
//if(istype(T,/turf/simulated))
// var/turf/simulated/ST=T
// air=ST.air
air=T.return_air()
/turf/simulated/assume_air(datum/gas_mixture/giver)
if(!giver) return 0
if(zone)
zone.air.merge(giver)
return 1
else
return ..()
/turf/simulated/return_air()
if(zone)
return zone.air
else if(air)
return air
else
return ..()
/turf/simulated/remove_air(amount as num)
if(zone)
var/datum/gas_mixture/removed = null
removed = zone.air.remove(amount)
if(zone.air.check_tile_graphic())
update_visuals(zone.air)
return removed
else if(air)
var/datum/gas_mixture/removed = null
removed = air.remove(amount)
if(air.check_tile_graphic())
update_visuals(air)
return removed
else
return ..()
/turf/simulated/proc/update_air_properties()
var/air_directions_archived = air_check_directions
air_check_directions = 0
for(var/direction in cardinal)
if(ZAirPass(get_step(src,direction)))
air_check_directions |= direction
if(!zone && !blocks_air) //No zone, but not a wall.
for(var/direction in DoorDirections) //Check door directions first.
if(air_check_directions&direction)
var/turf/simulated/T = get_step(src,direction)
if(!istype(T))
continue
if(T.zone)
T.zone.AddTurf(src)
break
if(!zone) //Still no zone
for(var/direction in CounterDoorDirections) //Check the others second.
if(air_check_directions&direction)
var/turf/simulated/T = get_step(src,direction)
if(!istype(T))
continue
if(T.zone)
T.zone.AddTurf(src)
break
if(!zone) //No zone found, new zone!
new/zone(src)
if(!zone) //Still no zone, the floodfill determined it is not part of a larger zone. Force a zone on it.
new/zone(list(src))
//Check pass sanity of the connections.
if("\ref[src]" in air_master.turfs_with_connections)
for(var/connection/C in air_master.turfs_with_connections["\ref[src]"])
air_master.connections_to_check |= C
if(zone && !zone.rebuild)
if(zone.air.check_tile_graphic())
update_visuals(zone.air)
for(var/direction in cardinal)
var/turf/T = get_step(src,direction)
if(!istype(T))
continue
//I can connect to air in this direction
if(air_check_directions&direction)
//If either block air, we must look to see if the adjacent turfs need rebuilt.
if(!CanPass(null, T, 0, 0))
//Target blocks air
if(!T.CanPass(null, T, 0, 0))
var/turf/NT = get_step(T, direction)
//If that turf is in my zone still, rebuild.
if(istype(NT,/turf/simulated) && NT in zone.contents)
zone.rebuild = 1
//If that is an unsimulated tile in my zone, see if we need to rebuild or just remove.
else if(istype(NT) && NT in zone.unsimulated_tiles)
var/consider_rebuild = 0
for(var/d in cardinal)
var/turf/UT = get_step(NT,d)
if(istype(UT, /turf/simulated) && UT.zone == zone && UT.CanPass(null, NT, 0, 0)) //If we find a neighboring tile that is in the same zone, check if we need to rebuild
consider_rebuild = 1
break
if(consider_rebuild)
zone.rebuild = 1 //Gotta check if we need to rebuild, dammit
else
zone.RemoveTurf(NT) //Not adjacent to anything, and unsimulated. Goodbye~
//To make a closed connection through closed door.
ZConnect(T, src)
//If I block air.
else if(T.zone && !T.zone.rebuild)
var/turf/NT = get_step(src, reverse_direction(direction))
//If I am splitting a zone, rebuild.
if(istype(NT,/turf/simulated) && (NT in T.zone.contents || (NT.zone && T in NT.zone.contents)))
T.zone.rebuild = 1
//If NT is unsimulated, parse if I should remove it or rebuild.
else if(istype(NT) && NT in T.zone.unsimulated_tiles)
var/consider_rebuild = 0
for(var/d in cardinal)
var/turf/UT = get_step(NT,d)
if(istype(UT, /turf/simulated) && UT.zone == T.zone && UT.CanPass(null, NT, 0, 0)) //If we find a neighboring tile that is in the same zone, check if we need to rebuild
consider_rebuild = 1
break
//Needs rebuilt.
if(consider_rebuild)
T.zone.rebuild = 1
//Not adjacent to anything, and unsimulated. Goodbye~
else
T.zone.RemoveTurf(NT)
else
//Produce connection through open door.
ZConnect(src,T)
//Something like a wall was built, changing the geometry.
else if(air_directions_archived&direction)
var/turf/NT = get_step(T, direction)
//If the tile is in our own zone, and we cannot connect to it, better rebuild.
if(istype(NT,/turf/simulated) && NT in zone.contents)
zone.rebuild = 1
//Parse if we need to remove the tile, or rebuild the zone.
else if(istype(NT) && NT in zone.unsimulated_tiles)
var/consider_rebuild = 0
//Loop through all neighboring turfs to see if we should remove the turf or just rebuild.
for(var/d in cardinal)
var/turf/UT = get_step(NT,d)
//If we find a neighboring tile that is in the same zone, rebuild
if(istype(UT, /turf/simulated) && UT.zone == zone && UT.CanPass(null, NT, 0, 0))
consider_rebuild = 1
break
//The unsimulated turf is adjacent to another one of our zone's turfs,
// better rebuild to be sure we didn't get cut in twain
if(consider_rebuild)
zone.rebuild = 1
//Not adjacent to anything, and unsimulated. Goodbye~
else
zone.RemoveTurf(NT)
if(air_check_directions)
processing = 1
else
processing = 0
return 1
/turf/proc/HasDoor(turf/O)
//Checks for the presence of doors, used for zone spreading and connection.
//A positive numerical argument checks only for closed doors.
//Another turf as an argument checks for windoors between here and there.
for(var/obj/machinery/door/D in src)
if(isnum(O) && O)
if(!D.density) continue
if(istype(D,/obj/machinery/door/window))
if(!istype(O))
continue
if(D.dir == get_dir(D,O))
return 1
else
return 1
/turf/proc/ZCanPass(turf/simulated/T, var/include_space = 0)
//Fairly standard pass checks for turfs, objects and directional windows. Also stops at the edge of space.
if(!istype(T))
return 0
if(!istype(T) && !include_space)
return 0
else
if(T.blocks_air||blocks_air)
return 0
for(var/obj/obstacle in src)
if(istype(obstacle, /obj/machinery/door) && !obstacle:air_properties_vary_with_direction)
continue
if(!obstacle.CanPass(null, T, 1.5, 1))
return 0
for(var/obj/obstacle in T)
if(istype(obstacle, /obj/machinery/door) && !obstacle:air_properties_vary_with_direction)
continue
if(!obstacle.CanPass(null, src, 1.5, 1))
return 0
return 1
/turf/proc/ZAirPass(turf/T)
//Fairly standard pass checks for turfs, objects and directional windows.
if(!istype(T))
return 0
if(T.blocks_air||blocks_air)
return 0
for(var/obj/obstacle in src)
if(istype(obstacle, /obj/machinery/door) && !obstacle:air_properties_vary_with_direction)
continue
if(!obstacle.CanPass(null, T, 0, 0))
return 0
for(var/obj/obstacle in T)
if(istype(obstacle, /obj/machinery/door) && !obstacle:air_properties_vary_with_direction)
continue
if(!obstacle.CanPass(null, src, 0, 0))
return 0
return 1
/*UNUSED
/turf/proc/check_connections()
//Checks for new connections that can be made.
for(var/d in cardinal)
var/turf/simulated/T = get_step(src,d)
if(istype(T) && ( !T.zone || !T.CanPass(0,src,0,0) ) )
continue
if(T.zone != zone)
ZConnect(src,T)
/turf/proc/check_for_space()
//Checks for space around the turf.
for(var/d in cardinal)
var/turf/T = get_step(src,d)
if(istype(T,/turf/space) && T.CanPass(0,src,0,0))
zone.AddSpace(T)
*/
@@ -178,24 +178,28 @@ var/list/CounterDoorDirections = list(SOUTH,EAST) //Which directions doors turfs
//Check the graphic.
progress = "problem with: modifying turf graphics"
air.graphic = 0
air.graphics = 0
if(air.toxins > MOLES_PLASMA_VISIBLE)
air.graphic = 1
else if(air.trace_gases.len)
air.graphics |= GRAPHICS_PLASMA
if(air.trace_gases.len)
var/datum/gas/sleeping_agent = locate(/datum/gas/sleeping_agent) in air.trace_gases
if(sleeping_agent && (sleeping_agent.moles > 1))
air.graphic = 2
air.graphics |= GRAPHICS_N2O
// If configured and cold, maek ice
if(zas_settings.Get(/datum/ZAS_Setting/ice_formation))
if(air.temperature <= TEMPERATURE_ICE_FORMATION && air.return_pressure()>MIN_PRESSURE_ICE_FORMATION)
air.graphics |= GRAPHICS_COLD
progress = "problem with an inbuilt byond function: some conditional checks"
//Only run through the individual turfs if there's reason to.
if(air.graphic != air.graphic_archived || air.temperature > PLASMA_FLASHPOINT)
if(air.graphics != air.graphics_archived || air.temperature > PLASMA_FLASHPOINT)
progress = "problem with: turf/simulated/update_visuals()"
for(var/turf/simulated/S in contents)
//Update overlays.
if(air.graphic != air.graphic_archived)
if(air.graphics != air.graphics_archived)
if(S.HasDoor(1))
S.update_visuals()
else
@@ -212,7 +216,7 @@ var/list/CounterDoorDirections = list(SOUTH,EAST) //Which directions doors turfs
progress = "problem with: calculating air graphic"
//Archive graphic so we can know if it's different.
air.graphic_archived = air.graphic
air.graphics_archived = air.graphics
progress = "problem with: calculating air temp"
@@ -276,7 +280,7 @@ var/list/CounterDoorDirections = list(SOUTH,EAST) //Which directions doors turfs
//Air Movement//
////////////////
var/list/sharing_lookup_table = list(0.03, 0.07, 0.11, 0.15, 0.18, 0.20)
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.
@@ -407,15 +411,15 @@ proc/ShareSpace(datum/gas_mixture/A, list/unsimulated_tiles, dbg_output)
if(sharing_lookup_table.len >= unsimulated_tiles.len) //6 or more interconnecting tiles will max at 42% of air moved per tick.
ratio = sharing_lookup_table[unsimulated_tiles.len]
//We need to adjust it to account for the insulation settings.
ratio *= 1 - zas_settings.Get(/datum/ZAS_Setting/connection_insulation)
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 )
// EXPERIMENTAL: Disable space being cold
// N3X: Made this togglable for Pomf. Comment recovered from older code.
if(!zas_settings.Get(/datum/ZAS_Setting/space_isnt_cold))
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)
@@ -444,6 +448,9 @@ proc/ShareHeat(datum/gas_mixture/A, datum/gas_mixture/B, connecting_tiles)
ratio = sharing_lookup_table[connecting_tiles]
//WOOT WOOT TOUCH THIS AND YOU ARE A RETARD
//We need to adjust it to account for the insulation settings.
ratio *= 1 - zas_settings.Get(/datum/ZAS_Setting/connection_insulation)
A.temperature = max(0, (A.temperature - temp_avg) * (1- (ratio / max(1,A.group_multiplier)) ) + temp_avg )
B.temperature = max(0, (B.temperature - temp_avg) * (1- (ratio / max(1,B.group_multiplier)) ) + temp_avg )
File diff suppressed because it is too large Load Diff
-500
View File
@@ -1,500 +0,0 @@
/*
ZAS Settings System 2.0
Okay, so VariableSettings is a mess of spaghetticode and
is about as flexible as a grandmother covered in
starch.
This is an attempt to fix that by using getters and
setters instead of stupidity. It's a little more difficult
to code with, but dammit, it's better than hackery.
NOTE: plc was merged into the main settings. We can set up
visual groups later.
HOW2GET:
zas_setting.Get(/datum/ZAS_Setting/herp)
HOW2SET:
zas_setting.Set(/datum/ZAS_Setting/herp, "dsfargeg")
*/
var/global/ZAS_Settings/zas_settings = new
#define ZAS_TYPE_UNDEFINED -1
#define ZAS_TYPE_BOOLEAN 0
#define ZAS_TYPE_NUMERIC 1
/**
* ZAS Setting Datum
*
* Stores a single setting.
* @author N3X15 <nexis@7chan.org>
* @package SS13
* @subpackage ZAS
*/
/datum/ZAS_Setting/
var/name="Clown" // Friendly name.
var/desc="Honk"
var/value=null
var/valtype=ZAS_TYPE_UNDEFINED
/datum/ZAS_Setting/fire_consumption_rate
name = "Fire - Air Consumption Ratio"
desc = "Ratio of air removed and combusted per tick."
valtype=ZAS_TYPE_NUMERIC
value = 0.75
/datum/ZAS_Setting/fire_firelevel_multiplier
value = 25
name = "Fire - Firelevel Constant"
desc = "Multiplied by the equation for firelevel, affects mainly the extingiushing of fires."
valtype=ZAS_TYPE_NUMERIC
/datum/ZAS_Setting/fire_fuel_energy_release
value = 550000
name = "Fire - Fuel energy release"
desc = "The energy in joule released when burning one mol of a burnable substance"
valtype=ZAS_TYPE_NUMERIC
/datum/ZAS_Setting/airflow_lightest_pressure
value = 20
name = "Airflow - Small Movement Threshold %"
desc = "Percent of 1 Atm. at which items with the small weight classes will move."
valtype=ZAS_TYPE_NUMERIC
/datum/ZAS_Setting/airflow_light_pressure
value = 35
name = "Airflow - Medium Movement Threshold %"
desc = "Percent of 1 Atm. at which items with the medium weight classes will move."
valtype=ZAS_TYPE_NUMERIC
/datum/ZAS_Setting/airflow_medium_pressure
value = 50
name = "Airflow - Heavy Movement Threshold %"
desc = "Percent of 1 Atm. at which items with the largest weight classes will move."
valtype=ZAS_TYPE_NUMERIC
/datum/ZAS_Setting/airflow_heavy_pressure
value = 65
name = "Airflow - Mob Movement Threshold %"
desc = "Percent of 1 Atm. at which mobs will move."
valtype=ZAS_TYPE_NUMERIC
/datum/ZAS_Setting/airflow_dense_pressure
value = 85
name = "Airflow - Dense Movement Threshold %"
desc = "Percent of 1 Atm. at which items with canisters and closets will move."
valtype=ZAS_TYPE_NUMERIC
/datum/ZAS_Setting/airflow_stun_pressure
value = 60
name = "Airflow - Mob Stunning Threshold %"
desc = "Percent of 1 Atm. at which mobs will be stunned by airflow."
valtype=ZAS_TYPE_NUMERIC
/datum/ZAS_Setting/airflow_stun_cooldown
value = 60
name = "Aiflow Stunning - Cooldown"
desc = "How long, in tenths of a second, to wait before stunning them again."
valtype=ZAS_TYPE_NUMERIC
/datum/ZAS_Setting/airflow_stun
value = 1
name = "Airflow Impact - Stunning"
desc = "How much a mob is stunned when hit by an object."
valtype=ZAS_TYPE_NUMERIC
/datum/ZAS_Setting/airflow_damage
value = 2
name = "Airflow Impact - Damage"
desc = "Damage from airflow impacts."
valtype=ZAS_TYPE_NUMERIC
/datum/ZAS_Setting/airflow_speed_decay
value = 1.5
name = "Airflow Speed Decay"
desc = "How rapidly the speed gained from airflow decays."
valtype=ZAS_TYPE_NUMERIC
/datum/ZAS_Setting/airflow_delay
value = 30
name = "Airflow Retrigger Delay"
desc = "Time in deciseconds before things can be moved by airflow again."
valtype=ZAS_TYPE_NUMERIC
/datum/ZAS_Setting/airflow_mob_slowdown
value = 1
name = "Airflow 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."
valtype=ZAS_TYPE_NUMERIC
// N3X15 - Added back in so we can tweak performance.
/datum/ZAS_Setting/airflow_push
name="Airflow - Push"
value = 0
desc="1=yes please rape my server, 0=no"
valtype=ZAS_TYPE_BOOLEAN
/datum/ZAS_Setting/connection_insulation
value = 0.4
name = "Connections - Insulation"
desc = "How insulative a connection is, in terms of heat transfer. 1 is perfectly insulative, and 0 is perfectly conductive."
valtype=ZAS_TYPE_NUMERIC
/datum/ZAS_Setting/connection_temperature_delta
value = 10
name = "Connections - Temperature Difference"
desc = "The smallest temperature difference which will cause heat to travel through doors."
valtype=ZAS_TYPE_NUMERIC
///////////////////////////////////////
// PLASMA SHIT
///////////////////////////////////////
// ALL CAPS BECAUSE PLASMA IS HARDCORE YO
// And I'm too lazy to fix the refs.
/datum/ZAS_Setting/PLASMA_DMG
name = "Plasma Damage Amount"
desc = "Self Descriptive"
value = 3
valtype=ZAS_TYPE_NUMERIC
/datum/ZAS_Setting/CLOTH_CONTAMINATION
name = "Cloth Contamination"
desc = "If this is on, plasma does damage by getting into cloth."
value = 1
valtype=ZAS_TYPE_BOOLEAN
/datum/ZAS_Setting/PLASMAGUARD_ONLY
name = "PlasmaGuard Only"
desc = "If this is on, only biosuits and spacesuits protect against contamination and ill effects."
value = 0
valtype=ZAS_TYPE_BOOLEAN
/datum/ZAS_Setting/GENETIC_CORRUPTION
name = "Genetic Corruption Chance"
desc = "Chance of genetic corruption as well as toxic damage, X in 10,000."
value = 0
valtype=ZAS_TYPE_BOOLEAN
/datum/ZAS_Setting/SKIN_BURNS
name = "Skin Burns"
desc = "Plasma has an effect similar to mustard gas on the un-suited."
value = 0
valtype=ZAS_TYPE_BOOLEAN
/datum/ZAS_Setting/EYE_BURNS
name = "Eye Burns"
desc = "Plasma burns the eyes of anyone not wearing eye protection."
value = 1
valtype=ZAS_TYPE_BOOLEAN
/datum/ZAS_Setting/CONTAMINATION_LOSS
name = "Contamination Loss"
desc = "How much toxin damage is dealt from contaminated clothing"
value = 0.02 //Per tick? ASK ARYN
valtype=ZAS_TYPE_NUMERIC
/datum/ZAS_Setting/PLASMA_HALLUCINATION
name = "Plasma Hallucination"
desc = "Does being in plasma cause you to hallucinate?"
value = 0
valtype=ZAS_TYPE_BOOLEAN
/datum/ZAS_Setting/N2O_HALLUCINATION
name = "N2O Hallucination"
desc = "Does being in sleeping gas cause you to hallucinate?"
value = 1
valtype=ZAS_TYPE_BOOLEAN
/**
* ZAS Settings
*
* Stores our settings for ZAS in an editable form.
* @author N3X15 <nexis@7chan.org>
* @package SS13
* @subpackage ZAS
*/
/ZAS_Settings
// INTERNAL USE ONLY
var/list/datum/ZAS_Setting/settings = list()
/ZAS_Settings/New()
.=..()
for(var/S in typesof(/datum/ZAS_Setting) - /datum/ZAS_Setting)
var/id=idfrompath("[S]")
//testing("Creating zas_settings\[[id]\] = new [S]")
src.settings[id]=new S
if(fexists("config/ZAS.txt") == 0)
Save()
Load()
/ZAS_Settings/proc/Save()
var/F = file("config/ZAS.txt")
fdel(F)
for(var/id in src.settings)
var/datum/ZAS_Setting/setting = src.settings[id]
F << "# [setting.name]"
F << "# [setting.desc]"
F << "[id] [setting.value]"
F << ""
/ZAS_Settings/proc/Load()
for(var/t in file2list("config/ZAS.txt"))
if(!t) continue
t = trim(t)
if (length(t) == 0)
continue
else if (copytext(t, 1, 2) == "#")
continue
var/pos = findtext(t, " ")
var/name = null
var/value = null
if (pos)
name = copytext(t, 1, pos)
value = copytext(t, pos + 1)
else
name = t
if (!name)
continue
src.SetFromConfig(name,value)
// INTERNAL USE ONLY
/ZAS_Settings/proc/idfrompath(var/str)
return replacetext(str,"/datum/ZAS_Setting/","")
// INTERNAL USE ONLY
/ZAS_Settings/proc/ChangeSetting(var/user,var/id)
var/datum/ZAS_Setting/setting = src.settings[id]
var/displayedValue=""
switch(setting.valtype)
if(ZAS_TYPE_NUMERIC)
setting.value = input(user,"Enter a number:","Settings",setting.value) as num
displayedValue="\"[setting.value]\""
/*
if(ZAS_TYPE_BITFLAG)
var/flag = input(user,"Toggle which bit?","Settings") in bitflags
flag = text2num(flag)
if(newvar & flag)
newvar &= ~flag
else
newvar |= flag
*/
if(ZAS_TYPE_BOOLEAN)
setting.value = !setting.value
displayedValue = (setting.value) ? "ON" : "OFF"
/*
if(ZAS_TYPE_STRING)
setting.value = input(user,"Enter text:","Settings",newvar) as message
*/
else
error("[id] has an invalid typeval.")
return
world << "\blue <b>[key_name(user)] changed ZAS setting <i>[setting.name]</i> to <i>[displayedValue]</i>.</b>"
ChangeSettingsDialog(user)
/**
* Set the value of a setting.
*
* Recommended to use the actual type of the setting rather than the ID, since
* this will allow for the compiler to check the validity of id. Kinda.
*
* @param id Either the typepath of the desired setting, or the string ID of the setting.
* @param value The value that the setting should be set to.
*/
/ZAS_Settings/proc/Set(var/id, var/value)
var/datum/ZAS_Setting/setting = src.settings[idfrompath(id)]
setting.value=value
// INTERNAL USE ONLY
/ZAS_Settings/proc/SetFromConfig(var/id, var/value)
var/datum/ZAS_Setting/setting = src.settings[id]
switch(setting.valtype)
if(ZAS_TYPE_NUMERIC)
setting.value = text2num(value)
/*
if(ZAS_TYPE_BITFLAG)
var/flag = input(user,"Toggle which bit?","Settings") in bitflags
flag = text2num(flag)
if(newvar & flag)
newvar &= ~flag
else
newvar |= flag
*/
if(ZAS_TYPE_BOOLEAN)
setting.value = (value == "1")
/*
if(ZAS_TYPE_STRING)
setting.value = input(user,"Enter text:","Settings",newvar) as message
*/
/**
* Get a setting.
*
* Recommended to use the actual type of the setting rather than the ID, since
* this will allow for the compiler to check the validity of id. Kinda.
*
* @param id Either the typepath of the desired setting, or the string ID of the setting.
* @returns Value of the desired setting
*/
/ZAS_Settings/proc/Get(var/id)
if(ispath(id))
id="[id]"
var/datum/ZAS_Setting/setting = src.settings[idfrompath(id)]
if(!setting || !istype(setting))
world.log << "ZAS_SETTING DEBUG: [id] | [idfrompath(id)]"
return setting.value
/ZAS_Settings/proc/ChangeSettingsDialog(mob/user)
var/dat = {"
<html>
<head>
<title>ZAS Settings 2.0</title>
<style type="text/css">
body,html {
background:#666666;
font-family:sans-serif;
font-size:smaller;
color: #cccccc;
}
a { color: white; }
</style>
</head>
<body>
<h1>ZAS Configuration</h1>
<p><a href="?src=\ref[src];save=1">Save Settings</a> | <a href="?src=\ref[src];load=1">Load Settings</a></p>
<p>Please note that changing these settings can and probably will result in death, destruction and mayhem. <b>Change at your own risk.</b></p>
<dl>"}
for(var/id in src.settings)
var/datum/ZAS_Setting/s = src.settings[id]
dat += "<dt><b>[s.name]</b> = <i>[s.value]</i> <A href='?src=\ref[src];changevar=[id]'>\[Change\]</A></dt>"
dat += "<dd>[s.desc]</i></dd>"
dat += "</dl></body></html>"
user << browse(dat,"window=settings")
/ZAS_Settings/Topic(href,href_list)
if("changevar" in href_list)
ChangeSetting(usr,href_list["changevar"])
if("save" in href_list)
var/sure = input(usr,"Are you sure? This will overwrite your ZAS configuration!","Overwrite ZAS.txt?", "No") in list("Yes","No")
if(sure=="Yes")
Save()
message_admins("[key_name(usr)] saved ZAS settings to disk.")
if("load" in href_list)
var/sure = input(usr,"Are you sure?","Reload ZAS.txt?", "No") in list("Yes","No")
if(sure=="Yes")
Load()
message_admins("[key_name(usr)] reloaded ZAS settings from disk.")
/ZAS_Settings/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")
Set("CLOTH_CONTAMINATION", 1) //If this is on, plasma does damage by getting into cloth.
Set("PLASMAGUARD_ONLY", 0)
Set("GENETIC_CORRUPTION", 0) //Chance of genetic corruption as well as toxic damage, X in 1000.
Set("SKIN_BURNS", 0) //Plasma has an effect similar to mustard gas on the un-suited.
Set("EYE_BURNS", 1) //Plasma burns the eyes of anyone not wearing eye protection.
Set("PLASMA_HALLUCINATION", 0)
Set("CONTAMINATION_LOSS", 0.02)
if("Plasma - Low Hazard")
Set("CLOTH_CONTAMINATION", 0) //If this is on, plasma does damage by getting into cloth.
Set("PLASMAGUARD_ONLY", 0)
Set("GENETIC_CORRUPTION", 0) //Chance of genetic corruption as well as toxic damage, X in 1000
Set("SKIN_BURNS", 0) //Plasma has an effect similar to mustard gas on the un-suited.
Set("EYE_BURNS", 1) //Plasma burns the eyes of anyone not wearing eye protection.
Set("PLASMA_HALLUCINATION", 0)
Set("CONTAMINATION_LOSS", 0.01)
if("Plasma - High Hazard")
Set("CLOTH_CONTAMINATION", 1) //If this is on, plasma does damage by getting into cloth.
Set("PLASMAGUARD_ONLY", 0)
Set("GENETIC_CORRUPTION", 0) //Chance of genetic corruption as well as toxic damage, X in 1000.
Set("SKIN_BURNS", 1) //Plasma has an effect similar to mustard gas on the un-suited.
Set("EYE_BURNS", 1) //Plasma burns the eyes of anyone not wearing eye protection.
Set("PLASMA_HALLUCINATION", 1)
Set("CONTAMINATION_LOSS", 0.05)
if("Plasma - Oh Shit!")
Set("CLOTH_CONTAMINATION", 1) //If this is on, plasma does damage by getting into cloth.
Set("PLASMAGUARD_ONLY", 1)
Set("GENETIC_CORRUPTION", 5) //Chance of genetic corruption as well as toxic damage, X in 1000.
Set("SKIN_BURNS", 1) //Plasma has an effect similar to mustard gas on the un-suited.
Set("EYE_BURNS", 1) //Plasma burns the eyes of anyone not wearing eye protection.
Set("PLASMA_HALLUCINATION", 1)
Set("CONTAMINATION_LOSS", 0.075)
if("ZAS - Normal")
Set("airflow_push", 0)
Set("airflow_lightest_pressure", 20)
Set("airflow_light_pressure", 35)
Set("airflow_medium_pressure", 50)
Set("airflow_heavy_pressure", 65)
Set("airflow_dense_pressure", 85)
Set("airflow_stun_pressure", 60)
Set("airflow_stun_cooldown", 60)
Set("airflow_stun", 1)
Set("airflow_damage", 2)
Set("airflow_speed_decay", 1.5)
Set("airflow_delay", 30)
Set("airflow_mob_slowdown", 1)
if("ZAS - Forgiving")
Set("airflow_push", 0)
Set("airflow_lightest_pressure", 45)
Set("airflow_light_pressure", 60)
Set("airflow_medium_pressure", 120)
Set("airflow_heavy_pressure", 110)
Set("airflow_dense_pressure", 200)
Set("airflow_stun_pressure", 150)
Set("airflow_stun_cooldown", 90)
Set("airflow_stun", 0.15)
Set("airflow_damage", 0.15)
Set("airflow_speed_decay", 1.5)
Set("airflow_delay", 50)
Set("airflow_mob_slowdown", 0)
if("ZAS - Dangerous")
Set("airflow_push", 1)
Set("airflow_lightest_pressure", 15)
Set("airflow_light_pressure", 30)
Set("airflow_medium_pressure", 45)
Set("airflow_heavy_pressure", 55)
Set("airflow_dense_pressure", 70)
Set("airflow_stun_pressure", 50)
Set("airflow_stun_cooldown", 50)
Set("airflow_stun", 2)
Set("airflow_damage", 3)
Set("airflow_speed_decay", 1.2)
Set("airflow_delay", 25)
Set("airflow_mob_slowdown", 2)
if("ZAS - Hellish")
Set("airflow_push", 1)
Set("airflow_lightest_pressure", 20)
Set("airflow_light_pressure", 30)
Set("airflow_medium_pressure", 40)
Set("airflow_heavy_pressure", 50)
Set("airflow_dense_pressure", 60)
Set("airflow_stun_pressure", 40)
Set("airflow_stun_cooldown", 40)
Set("airflow_stun", 3)
Set("airflow_damage", 4)
Set("airflow_speed_decay", 1)
Set("airflow_delay", 20)
Set("airflow_mob_slowdown", 3)
world << "\blue <b>[key_name(usr)] loaded ZAS preset <i>[def]</i></b>"
-356
View File
@@ -1,356 +0,0 @@
atom/var/pressure_resistance = ONE_ATMOSPHERE
turf
var/zone/zone
assume_air(datum/gas_mixture/giver) //use this for machines to adjust air
del(giver)
return 0
return_air()
//Create gas mixture to hold data for passing
var/datum/gas_mixture/GM = new
GM.oxygen = oxygen
GM.carbon_dioxide = carbon_dioxide
GM.nitrogen = nitrogen
GM.toxins = toxins
GM.temperature = temperature
GM.update_values()
return GM
remove_air(amount as num)
var/datum/gas_mixture/GM = new
var/sum = oxygen + carbon_dioxide + nitrogen + toxins
if(sum>0)
GM.oxygen = (oxygen/sum)*amount
GM.carbon_dioxide = (carbon_dioxide/sum)*amount
GM.nitrogen = (nitrogen/sum)*amount
GM.toxins = (toxins/sum)*amount
GM.temperature = temperature
GM.update_values()
return GM
turf
simulated
var/current_graphic = null
var/tmp
datum/gas_mixture/air
processing = 1
air_check_directions = 0 //Do not modify this, just add turf to air_master.tiles_to_update
obj/fire/active_hotspot
proc/update_visuals()
overlays = null
var/siding_icon_state = return_siding_icon_state()
if(siding_icon_state)
overlays += image('icons/turf/floors.dmi',siding_icon_state)
var/datum/gas_mixture/model = return_air()
switch(model.graphic)
if(1)
overlays.Add(plmaster) //TODO: Make invisible plasma an option
if(2)
overlays.Add(slmaster)
New()
..()
if(!blocks_air)
air = new
air.oxygen = oxygen
air.carbon_dioxide = carbon_dioxide
air.nitrogen = nitrogen
air.toxins = toxins
air.temperature = temperature
air.update_values()
if(air_master)
air_master.tiles_to_update.Add(src)
else
if(air_master)
for(var/direction in cardinal)
var/turf/simulated/floor/target = get_step(src,direction)
if(istype(target))
air_master.tiles_to_update |= target
Del()
if(active_hotspot)
del(active_hotspot)
if(blocks_air)
for(var/direction in list(NORTH, SOUTH, EAST, WEST))
var/turf/simulated/tile = get_step(src,direction)
if(istype(tile) && !tile.blocks_air)
air_master.tiles_to_update.Add(tile)
..()
assume_air(datum/gas_mixture/giver)
if(!giver) return 0
if(zone)
zone.air.merge(giver)
return 1
else
return ..()
return_air()
if(zone)
return zone.air
else if(air)
return air
else
return ..()
remove_air(amount as num)
if(zone)
var/datum/gas_mixture/removed = null
removed = zone.air.remove(amount)
return removed
else if(air)
var/datum/gas_mixture/removed = null
removed = air.remove(amount)
if(air.check_tile_graphic())
update_visuals(air)
return removed
else
return ..()
proc/update_air_properties()
. = 1
var/air_directions_archived = air_check_directions
air_check_directions = 0
for(var/direction in cardinal)
if(ZAirPass(get_step(src,direction)))
air_check_directions |= direction
if(!zone && !blocks_air) //No zone, but not a wall.
for(var/direction in DoorDirections) //Check door directions first.
if(air_check_directions&direction)
var/turf/simulated/T = get_step(src,direction)
if(!istype(T))
continue
if(T.zone)
T.zone.AddTurf(src)
break
if(!zone) //Still no zone
for(var/direction in CounterDoorDirections) //Check the others second.
if(air_check_directions&direction)
var/turf/simulated/T = get_step(src,direction)
if(!istype(T))
continue
if(T.zone)
T.zone.AddTurf(src)
break
if(!zone) //No zone found, new zone!
new/zone(src)
if(!zone) //Still no zone, the floodfill determined it is not part of a larger zone. Force a zone on it.
new/zone(list(src))
//Check pass sanity of the connections.
if("\ref[src]" in air_master.turfs_with_connections)
for(var/connection/C in air_master.turfs_with_connections["\ref[src]"])
air_master.connections_to_check |= C
if(zone && !zone.rebuild)
for(var/direction in cardinal)
var/turf/T = get_step(src,direction)
if(!istype(T))
continue
//I can connect to air in this direction
if(air_check_directions&direction)
//If either block air, we must look to see if the adjacent turfs need rebuilt.
if(!CanPass(null, T, 0, 0))
//Target blocks air
if(!T.CanPass(null, T, 0, 0))
var/turf/NT = get_step(T, direction)
//If that turf is in my zone still, rebuild.
if(istype(NT,/turf/simulated) && NT in zone.contents)
zone.rebuild = 1
//If that is an unsimulated tile in my zone, see if we need to rebuild or just remove.
else if(istype(NT) && NT in zone.unsimulated_tiles)
var/consider_rebuild = 0
for(var/d in cardinal)
var/turf/UT = get_step(NT,d)
if(istype(UT, /turf/simulated) && UT.zone == zone && UT.CanPass(null, NT, 0, 0)) //If we find a neighboring tile that is in the same zone, check if we need to rebuild
consider_rebuild = 1
break
if(consider_rebuild)
zone.rebuild = 1 //Gotta check if we need to rebuild, dammit
else
zone.RemoveTurf(NT) //Not adjacent to anything, and unsimulated. Goodbye~
//To make a closed connection through closed door.
ZConnect(T, src)
//If I block air.
else if(T.zone && !T.zone.rebuild)
var/turf/NT = get_step(src, reverse_direction(direction))
//If I am splitting a zone, rebuild.
if(istype(NT,/turf/simulated) && (NT in T.zone.contents || (NT.zone && T in NT.zone.contents)))
T.zone.rebuild = 1
//If NT is unsimulated, parse if I should remove it or rebuild.
else if(istype(NT) && NT in T.zone.unsimulated_tiles)
var/consider_rebuild = 0
for(var/d in cardinal)
var/turf/UT = get_step(NT,d)
if(istype(UT, /turf/simulated) && UT.zone == T.zone && UT.CanPass(null, NT, 0, 0)) //If we find a neighboring tile that is in the same zone, check if we need to rebuild
consider_rebuild = 1
break
//Needs rebuilt.
if(consider_rebuild)
T.zone.rebuild = 1
//Not adjacent to anything, and unsimulated. Goodbye~
else
T.zone.RemoveTurf(NT)
else
//Produce connection through open door.
ZConnect(src,T)
//Something like a wall was built, changing the geometry.
else if(air_directions_archived&direction)
var/turf/NT = get_step(T, direction)
//If the tile is in our own zone, and we cannot connect to it, better rebuild.
if(istype(NT,/turf/simulated) && NT in zone.contents)
zone.rebuild = 1
//Parse if we need to remove the tile, or rebuild the zone.
else if(istype(NT) && NT in zone.unsimulated_tiles)
var/consider_rebuild = 0
//Loop through all neighboring turfs to see if we should remove the turf or just rebuild.
for(var/d in cardinal)
var/turf/UT = get_step(NT,d)
//If we find a neighboring tile that is in the same zone, rebuild
if(istype(UT, /turf/simulated) && UT.zone == zone && UT.CanPass(null, NT, 0, 0))
consider_rebuild = 1
break
//The unsimulated turf is adjacent to another one of our zone's turfs,
// better rebuild to be sure we didn't get cut in twain
if(consider_rebuild && NT.zone)
NT.zone.rebuild = 1
//Not adjacent to anything, and unsimulated. Goodbye~
else
zone.RemoveTurf(NT)
if(air_check_directions)
processing = 1
else
processing = 0
/turf/proc/HasDoor(turf/O)
//Checks for the presence of doors, used for zone spreading and connection.
//A positive numerical argument checks only for closed doors.
//Another turf as an argument checks for windoors between here and there.
for(var/obj/machinery/door/D in src)
if(isnum(O) && O)
if(!D.density) continue
if(istype(D,/obj/machinery/door/window))
if(!istype(O))
continue
if(D.dir == get_dir(D,O))
return 1
else
return 1
turf/proc/ZCanPass(turf/simulated/T, var/include_space = 0)
//Fairly standard pass checks for turfs, objects and directional windows. Also stops at the edge of space.
if(!istype(T))
return 0
if(!istype(T) && !include_space)
return 0
else
if(T.blocks_air||blocks_air)
return 0
for(var/obj/obstacle in src)
if(istype(obstacle, /obj/machinery/door) && !obstacle:air_properties_vary_with_direction)
continue
if(!obstacle.CanPass(null, T, 1.5, 1))
return 0
for(var/obj/obstacle in T)
if(istype(obstacle, /obj/machinery/door) && !obstacle:air_properties_vary_with_direction)
continue
if(!obstacle.CanPass(null, src, 1.5, 1))
return 0
return 1
turf/proc/ZAirPass(turf/T)
//Fairly standard pass checks for turfs, objects and directional windows.
if(!istype(T))
return 0
if(T.blocks_air||blocks_air)
return 0
for(var/obj/obstacle in src)
if(istype(obstacle, /obj/machinery/door) && !obstacle:air_properties_vary_with_direction)
continue
if(!obstacle.CanPass(null, T, 0, 0))
return 0
for(var/obj/obstacle in T)
if(istype(obstacle, /obj/machinery/door) && !obstacle:air_properties_vary_with_direction)
continue
if(!obstacle.CanPass(null, src, 0, 0))
return 0
return 1
/*UNUSED
/turf/proc/check_connections()
//Checks for new connections that can be made.
for(var/d in cardinal)
var/turf/simulated/T = get_step(src,d)
if(istype(T) && ( !T.zone || !T.CanPass(0,src,0,0) ) )
continue
if(T.zone != zone)
ZConnect(src,T)
/turf/proc/check_for_space()
//Checks for space around the turf.
for(var/d in cardinal)
var/turf/T = get_step(src,d)
if(istype(T,/turf/space) && T.CanPass(0,src,0,0))
zone.AddSpace(T)
*/
+84 -98
View File
@@ -52,17 +52,12 @@ mob/var/tmp/last_airflow_stun = 0
mob/proc/airflow_stun()
if(stat == 2)
return 0
if(last_airflow_stun > world.time - zas_settings.Get(/datum/ZAS_Setting/airflow_stun_cooldown)) return 0
if(last_airflow_stun > world.time - vsc.airflow_stun_cooldown) return 0
if(!(status_flags & CANSTUN) && !(status_flags & CANWEAKEN))
src << "\blue You stay upright as the air rushes past you."
return 0
if(zas_settings.Get(/datum/ZAS_Setting/airflow_push))
if(weakened <= 0) src << "\red The sudden rush of air knocks you over!"
weakened = max(weakened,5)
last_airflow_stun = world.time
return
src << "\blue You stay upright as the air rushes past you."
if(weakened <= 0) src << "\red The sudden rush of air knocks you over!"
weakened = max(weakened,5)
last_airflow_stun = world.time
mob/living/silicon/airflow_stun()
@@ -72,34 +67,27 @@ 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
if(last_airflow_stun > world.time - vsc.airflow_stun_cooldown) return 0
if(buckled) return 0
if(shoes)
if(shoes.flags & NOSLIP) return 0
if(!(status_flags & CANSTUN) && !(status_flags & CANWEAKEN))
src << "\blue You stay upright as the air rushes past you."
return 0
if(zas_settings.Get(/datum/ZAS_Setting/airflow_push))
if(weakened <= 0) src << "\red The sudden rush of air knocks you over!"
weakened = max(weakened,rand(1,5))
last_airflow_stun = world.time
return
src << "\blue You stay upright as the air rushes past you."
if(weakened <= 0) src << "\red The sudden rush of air knocks you over!"
weakened = max(weakened,rand(1,5))
last_airflow_stun = world.time
atom/movable/proc/check_airflow_movable(n)
if(!zas_settings.Get(/datum/ZAS_Setting/airflow_push))
return 0
if(anchored && !ismob(src))
return 0
if(!istype(src,/obj/item) && n < zas_settings.Get(/datum/ZAS_Setting/airflow_dense_pressure))
return 0
if(anchored && !ismob(src)) return 0
if(!istype(src,/obj/item) && n < vsc.airflow_dense_pressure) return 0
return 1
mob/check_airflow_movable(n)
if(n < zas_settings.Get(/datum/ZAS_Setting/airflow_heavy_pressure))
if(n < vsc.airflow_heavy_pressure)
return 0
return 1
@@ -114,11 +102,11 @@ 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(n < vsc.airflow_lightest_pressure) return 0
if(3)
if(n < zas_settings.Get(/datum/ZAS_Setting/airflow_light_pressure)) return 0
if(n < vsc.airflow_light_pressure) return 0
if(4,5)
if(n < zas_settings.Get(/datum/ZAS_Setting/airflow_medium_pressure)) return 0
if(n < vsc.airflow_medium_pressure) return 0
//The main airflow code. Called by zone updates.
//Zones A and B are air zones. n represents the amount of air moved.
@@ -128,7 +116,7 @@ proc/Airflow(zone/A, zone/B)
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
if(abs(n) < vsc.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
@@ -153,52 +141,53 @@ proc/Airflow(zone/A, 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)) // 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()
for(var/atom/movable/M in air_sucked)
if(M.check_airflow_movable(n))
if(M.last_airflow > world.time - vsc.airflow_delay) continue
//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
//Check for knocking people over
if(ismob(M) && n > vsc.airflow_stun_pressure)
if(M:status_flags & GODMODE) continue
M:airflow_stun()
//If they're already being tossed, don't do it again.
if(!M.airflow_speed)
if(M.check_airflow_movable(n))
M.airflow_dest = pick(close_turfs) //Pick a random midpoint to fly towards.
//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
spawn M.GotoAirflowDest(abs(n)/5)
//If they're already being tossed, don't do it again.
if(!M.airflow_speed)
//Do it again for the stuff in the other zone, making it fly away.
for(var/atom/movable/M in air_repelled)
M.airflow_dest = pick(close_turfs) //Pick a random midpoint to fly towards.
if(M.last_airflow > world.time - zas_settings.Get(/datum/ZAS_Setting/airflow_delay)) continue
spawn M.GotoAirflowDest(abs(n)/5)
if(ismob(M) && abs(n) > zas_settings.Get(/datum/ZAS_Setting/airflow_medium_pressure))
if(M:status_flags & GODMODE) continue
M:airflow_stun()
//Do it again for the stuff in the other zone, making it fly away.
for(var/atom/movable/M in air_repelled)
if(M.check_airflow_movable(abs(n)))
if(M.last_airflow > world.time - vsc.airflow_delay) continue
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(ismob(M) && abs(n) > vsc.airflow_medium_pressure)
if(M:status_flags & GODMODE) continue
M:airflow_stun()
//If they're already being tossed, don't do it again.
if(!M.airflow_speed)
if(M.check_airflow_movable(abs(n)))
M.airflow_dest = pick(close_turfs) //Pick a random midpoint to fly towards.
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
spawn M.RepelAirflowDest(abs(n)/5)
//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)
@@ -207,34 +196,34 @@ proc/AirflowSpace(zone/A)
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
if(n < vsc.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)) // If enabled
for(var/atom/movable/M in pplz)
if(M.last_airflow > world.time - zas_settings.Get(/datum/ZAS_Setting/airflow_delay)) continue
for(var/atom/movable/M in pplz)
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.last_airflow > world.time - vsc.airflow_delay) continue
if(M.check_airflow_movable(n))
if(ismob(M) && n > vsc.airflow_stun_pressure)
var/mob/O = M
if(O.status_flags & GODMODE) continue
O.airflow_stun()
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(M.check_airflow_movable(n))
//If they're already being tossed, don't do it again.
if(!M.airflow_speed)
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
M.airflow_dest = pick(close_turfs) //Pick a random midpoint to fly towards.
spawn
if(M) M.GotoAirflowDest(n/10)
//Sometimes shit breaks, and M isn't there after the spawn.
//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
if(M) M.GotoAirflowDest(n/10)
//Sometimes shit breaks, and M isn't there after the spawn.
/atom/movable/var/tmp/turf/airflow_dest
@@ -243,10 +232,9 @@ proc/AirflowSpace(zone/A)
/atom/movable/var/tmp/last_airflow = 0
/atom/movable/proc/GotoAirflowDest(n)
if(!zas_settings.Get(/datum/ZAS_Setting/airflow_push)) return // If not enabled, fuck it.
if(!airflow_dest) return
if(airflow_speed < 0) return
if(last_airflow > world.time - zas_settings.Get(/datum/ZAS_Setting/airflow_delay)) return
if(last_airflow > world.time - vsc.airflow_delay) return
if(airflow_speed)
airflow_speed = n/max(get_dist(src,airflow_dest),1)
return
@@ -280,7 +268,7 @@ proc/AirflowSpace(zone/A)
while(airflow_speed > 0)
if(airflow_speed <= 0) return
airflow_speed = min(airflow_speed,15)
airflow_speed -= zas_settings.Get(/datum/ZAS_Setting/airflow_speed_decay)
airflow_speed -= vsc.airflow_speed_decay
if(airflow_speed > 7)
if(airflow_time++ >= airflow_speed - 7)
if(od)
@@ -300,7 +288,7 @@ proc/AirflowSpace(zone/A)
return
step_towards(src, src.airflow_dest)
if(ismob(src) && src:client)
src:client:move_delay = world.time + zas_settings.Get(/datum/ZAS_Setting/airflow_mob_slowdown)
src:client:move_delay = world.time + vsc.airflow_mob_slowdown
airflow_dest = null
airflow_speed = 0
airflow_time = 0
@@ -309,10 +297,9 @@ proc/AirflowSpace(zone/A)
/atom/movable/proc/RepelAirflowDest(n)
if(!zas_settings.Get(/datum/ZAS_Setting/airflow_push)) return // If not enabled, fuck it.
if(!airflow_dest) return
if(airflow_speed < 0) return
if(last_airflow > world.time - zas_settings.Get(/datum/ZAS_Setting/airflow_delay)) return
if(last_airflow > world.time - vsc.airflow_delay) return
if(airflow_speed)
airflow_speed = n/max(get_dist(src,airflow_dest),1)
return
@@ -346,7 +333,7 @@ proc/AirflowSpace(zone/A)
while(airflow_speed > 0)
if(airflow_speed <= 0) return
airflow_speed = min(airflow_speed,15)
airflow_speed -= zas_settings.Get(/datum/ZAS_Setting/airflow_speed_decay)
airflow_speed -= vsc.airflow_speed_decay
if(airflow_speed > 7)
if(airflow_time++ >= airflow_speed - 7)
sleep(1 * tick_multiplier)
@@ -360,7 +347,7 @@ proc/AirflowSpace(zone/A)
return
step_towards(src, src.airflow_dest)
if(ismob(src) && src:client)
src:client:move_delay = world.time + zas_settings.Get(/datum/ZAS_Setting/airflow_mob_slowdown)
src:client:move_delay = world.time + vsc.airflow_mob_slowdown
airflow_dest = null
airflow_speed = 0
airflow_time = 0
@@ -382,14 +369,14 @@ atom/movable/proc/airflow_hit(atom/A)
mob/airflow_hit(atom/A)
for(var/mob/M in hearers(src))
M.show_message("\red <B>\The [src] slams into \a [A]!</B>",1,"\red You hear a loud slam!",2)
//playsound(src.loc, "smash.ogg", 25, 1, -1)
playsound(src.loc, "smash.ogg", 25, 1, -1)
weakened = max(weakened, (istype(A,/obj/item) ? A:w_class : rand(1,5))) //Heheheh
. = ..()
obj/airflow_hit(atom/A)
for(var/mob/M in hearers(src))
M.show_message("\red <B>\The [src] slams into \a [A]!</B>",1,"\red You hear a loud slam!",2)
//playsound(src.loc, "smash.ogg", 25, 1, -1)
playsound(src.loc, "smash.ogg", 25, 1, -1)
. = ..()
obj/item/airflow_hit(atom/A)
@@ -399,13 +386,13 @@ obj/item/airflow_hit(atom/A)
mob/living/carbon/human/airflow_hit(atom/A)
// for(var/mob/M in hearers(src))
// M.show_message("\red <B>[src] slams into [A]!</B>",1,"\red You hear a loud slam!",2)
//playsound(src.loc, "punch", 25, 1, -1)
playsound(src.loc, "punch", 25, 1, -1)
loc:add_blood(src)
if (src.wear_suit)
src.wear_suit.add_blood(src)
if (src.w_uniform)
src.w_uniform.add_blood(src)
var/b_loss = airflow_speed * zas_settings.Get(/datum/ZAS_Setting/airflow_damage)
var/b_loss = airflow_speed * vsc.airflow_damage
var/blocked = run_armor_check("head","melee")
apply_damage(b_loss/3, BRUTE, "head", blocked, 0, "Airflow")
@@ -416,19 +403,18 @@ mob/living/carbon/human/airflow_hit(atom/A)
blocked = run_armor_check("groin","melee")
apply_damage(b_loss/3, BRUTE, "groin", blocked, 0, "Airflow")
if(zas_settings.Get(/datum/ZAS_Setting/airflow_push))
if(airflow_speed > 10)
paralysis += round(airflow_speed * zas_settings.Get(/datum/ZAS_Setting/airflow_stun))
stunned = max(stunned,paralysis + 3)
else
stunned += round(airflow_speed * zas_settings.Get(/datum/ZAS_Setting/airflow_stun)/2)
if(airflow_speed > 10)
paralysis += round(airflow_speed * vsc.airflow_stun)
stunned = max(stunned,paralysis + 3)
else
stunned += round(airflow_speed * vsc.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) || istype(A, /mob/camera))
// if(istype(A, /obj/effect) || istype(A, /mob/aiEye))
if(istype(A, /obj/effect) || istype(A, /mob/camera/aiEye))
continue
. += A
+101 -56
View File
@@ -13,68 +13,62 @@ Indirect connections will not merge the two zones after they reach equilibrium.
var/zone/zone_A
var/zone/zone_B
var/ref_A
var/ref_B
var/indirect = CONNECTION_DIRECT //If the connection is purely indirect, the zones should not join.
var/last_updated //The tick at which this was last updated.
var/no_zone_count = 0
/connection/New(turf/T,turf/O)
. = ..()
A = T
B = O
if(A.zone && B.zone)
if(!A.zone.connections) A.zone.connections = list()
if(!A.zone.connections)
A.zone.connections = list()
A.zone.connections += src
zone_A = A.zone
ref_A = "\ref[A]"
if(!B.zone.connections) B.zone.connections = list()
if(!B.zone.connections)
B.zone.connections = list()
B.zone.connections += src
zone_B = B.zone
ref_B = "\ref[B]"
if(ref_A in air_master.turfs_with_connections)
var/list/connections = air_master.turfs_with_connections[ref_A]
if(A in air_master.turfs_with_connections)
var/list/connections = air_master.turfs_with_connections[A]
connections.Add(src)
else
air_master.turfs_with_connections[ref_A] = list(src)
air_master.turfs_with_connections[A] = list(src)
if(ref_B in air_master.turfs_with_connections)
var/list/connections = air_master.turfs_with_connections[ref_B]
if(B in air_master.turfs_with_connections)
var/list/connections = air_master.turfs_with_connections[B]
connections.Add(src)
else
air_master.turfs_with_connections[ref_B] = list(src)
air_master.turfs_with_connections[B] = list(src)
if(A.CanPass(null, B, 0, 0))
ConnectZones(A.zone, B.zone, 1)
if(A.HasDoor(B) || B.HasDoor(A))
if(!A.CanPass(null, B, 1.5, 1))
indirect = CONNECTION_INDIRECT
ConnectZones(A.zone, B.zone, indirect)
else
ConnectZones(A.zone, B.zone)
indirect = CONNECTION_CLOSED
else
world.log << "Attempted to create connection object for non-zone tiles: [T] ([T.x],[T.y],[T.z]) -> [O] ([O.x],[O.y],[O.z])"
del(src)
SoftDelete()
/connection/Del()
//remove connections from master lists.
if(ref_B in air_master.turfs_with_connections)
var/list/connections = air_master.turfs_with_connections[ref_B]
if(B in air_master.turfs_with_connections)
var/list/connections = air_master.turfs_with_connections[B]
connections.Remove(src)
if(ref_A in air_master.turfs_with_connections)
var/list/connections = air_master.turfs_with_connections[ref_A]
if(A in air_master.turfs_with_connections)
var/list/connections = air_master.turfs_with_connections[A]
connections.Remove(src)
//Remove connection from zones.
@@ -104,13 +98,52 @@ Indirect connections will not merge the two zones after they reach equilibrium.
//Disconnect zones while handling unusual conditions.
// e.g. loss of a zone on a turf
if(A && A.zone && B && B.zone)
DisconnectZones(A.zone, B.zone)
DisconnectZones(zone_A, zone_B)
//Finally, preform actual deletion.
. = ..()
/connection/proc/SoftDelete()
//remove connections from master lists.
if(B in air_master.turfs_with_connections)
var/list/connections = air_master.turfs_with_connections[B]
connections.Remove(src)
if(A in air_master.turfs_with_connections)
var/list/connections = air_master.turfs_with_connections[A]
connections.Remove(src)
//Remove connection from zones.
if(A)
if(A.zone && A.zone.connections)
A.zone.connections.Remove(src)
if(!A.zone.connections.len)
A.zone.connections = null
if(istype(zone_A) && (!A || A.zone != zone_A))
if(zone_A.connections)
zone_A.connections.Remove(src)
if(!zone_A.connections.len)
zone_A.connections = null
if(B)
if(B.zone && B.zone.connections)
B.zone.connections.Remove(src)
if(!B.zone.connections.len)
B.zone.connections = null
if(istype(zone_B) && (!B || B.zone != zone_B))
if(zone_B.connections)
zone_B.connections.Remove(src)
if(!zone_B.connections.len)
zone_B.connections = null
//Disconnect zones while handling unusual conditions.
// e.g. loss of a zone on a turf
DisconnectZones(zone_A, zone_B)
/connection/proc/ConnectZones(var/zone/zone_1, var/zone/zone_2, open = 0)
//Sanity checking
@@ -140,6 +173,18 @@ Indirect connections will not merge the two zones after they reach equilibrium.
zone_2.connected_zones += zone_1
zone_2.connected_zones[zone_1] = 1
if(open == CONNECTION_DIRECT)
if(!zone_1.direct_connections)
zone_1.direct_connections = list(src)
else
zone_1.direct_connections += src
if(!zone_2.direct_connections)
zone_2.direct_connections = list(src)
else
zone_2.direct_connections += src
//Handle closed connections.
else
@@ -163,6 +208,11 @@ Indirect connections will not merge the two zones after they reach equilibrium.
zone_2.closed_connection_zones += zone_1
zone_2.closed_connection_zones[zone_1] = 1
if(zone_1.status == ZONE_SLEEPING)
zone_1.SetStatus(ZONE_ACTIVE)
if(zone_2.status == ZONE_SLEEPING)
zone_2.SetStatus(ZONE_ACTIVE)
/connection/proc/DisconnectZones(var/zone/zone_1, var/zone/zone_2)
//Sanity checking
@@ -193,6 +243,15 @@ Indirect connections will not merge the two zones after they reach equilibrium.
if(!zone_2.connected_zones.len)
zone_2.connected_zones = null
if(indirect == CONNECTION_DIRECT)
zone_1.direct_connections -= src
if(!zone_1.direct_connections.len)
zone_1.direct_connections = null
zone_2.direct_connections -= src
if(!zone_2.direct_connections.len)
zone_2.direct_connections = null
else
//Handle disconnection of closed zones.
if( (zone_1 in zone_2.closed_connection_zones) || (zone_2 in zone_1.closed_connection_zones) )
@@ -222,35 +281,23 @@ Indirect connections will not merge the two zones after they reach equilibrium.
//Check sanity: existance of turfs
if(!A || !B)
del src
SoftDelete()
return
//Check sanity: loss of zone
if(!A.zone || !B.zone)
SoftDelete()
return
//Check sanity: zones are different
if(A.zone == B.zone)
del src
//Check sanity: same turfs as before.
if(ref_A != "\ref[A]" || ref_B != "\ref[B]")
del src
SoftDelete()
return
//Handle zones changing on a turf.
if((A.zone && A.zone != zone_A) || (B.zone && B.zone != zone_B))
Sanitize()
//Manage sudden loss of a turfs zone. (e.g. a wall being built)
if(!A.zone || !B.zone)
no_zone_count++
if(no_zone_count >= 5)
//world.log << "Connection removed: [A] or [B] missing a zone."
del src
return 0
return 1
/connection/proc/CheckPassSanity()
//Sanity check, first.
Cleanup()
if(A.zone && B.zone)
//If no walls are blocking us...
@@ -263,7 +310,7 @@ Indirect connections will not merge the two zones after they reach equilibrium.
//Make and remove connections to let air pass.
if(indirect == CONNECTION_CLOSED)
DisconnectZones(A.zone, B.zone)
ConnectZones(A.zone, B.zone, 1)
ConnectZones(A.zone, B.zone, door_pass + 1)
if(door_pass)
indirect = CONNECTION_DIRECT
@@ -278,7 +325,8 @@ Indirect connections will not merge the two zones after they reach equilibrium.
//If I can no longer pass air, better delete
else
del src
SoftDelete()
return
/connection/proc/Sanitize()
//If the zones change on connected turfs, update it.
@@ -294,9 +342,6 @@ Indirect connections will not merge the two zones after they reach equilibrium.
A = temp
zone_B = B.zone
zone_A = A.zone
var/temp_ref = ref_A
ref_A = ref_B
ref_B = temp_ref
return
//Handle removal of connections from archived zones.
@@ -400,4 +445,4 @@ Indirect connections will not merge the two zones after they reach equilibrium.
#undef CONNECTION_DIRECT
#undef CONNECTION_INDIRECT
#undef CONNECTION_CLOSED
#undef CONNECTION_CLOSED
+95 -4
View File
@@ -1,3 +1,14 @@
client/proc/ZoneTick()
set category = "Debug"
set name = "Process Atmos"
var/result = air_master.Tick()
if(result)
src << "Sucessfully Processed."
else
src << "Failed to process! ([air_master.tick_progress])"
client/proc/Zone_Info(turf/T as null|turf)
set category = "Debug"
@@ -115,8 +126,88 @@ zone/proc/DebugDisplay(client/client)
client.images -= client.zone_debug_images[src]
client.zone_debug_images.Remove(src)
for(var/zone/Z in zones)
if(Z.air == air && Z != src)
var/turf/zloc = pick(Z.contents)
client << "\red Illegal air datum shared by: [zloc.loc.name]"
if(air_master)
for(var/zone/Z in air_master.zones)
if(Z.air == air && Z != src)
var/turf/zloc = pick(Z.contents)
client << "\red Illegal air datum shared by: [zloc.loc.name]"
client/proc/TestZASRebuild()
// var/turf/turf = get_turf(mob)
var/zone/current_zone = mob.loc:zone
if(!current_zone)
src << "There is no zone there!"
return
var/list/current_adjacents = list()
var/list/overlays = list()
var/adjacent_id
var/lowest_id
var/list/identical_ids = list()
var/list/turfs = current_zone.contents.Copy()
var/current_identifier = 1
for(var/turf/simulated/current in turfs)
lowest_id = null
current_adjacents = list()
for(var/direction in cardinal)
var/turf/simulated/adjacent = get_step(current, direction)
if(!current.ZAirPass(adjacent))
continue
if(turfs.Find(adjacent))
current_adjacents += adjacent
adjacent_id = turfs[adjacent]
if(adjacent_id && (!lowest_id || adjacent_id < lowest_id))
lowest_id = adjacent_id
if(!lowest_id)
lowest_id = current_identifier++
identical_ids += lowest_id
overlays += image('icons/misc/debug_rebuild.dmi',, "[lowest_id]")
for(var/turf/simulated/adjacent in current_adjacents)
adjacent_id = turfs[adjacent]
if(adjacent_id != lowest_id)
if(adjacent_id)
adjacent.overlays -= overlays[adjacent_id]
identical_ids[adjacent_id] = lowest_id
turfs[adjacent] = lowest_id
adjacent.overlays += overlays[lowest_id]
sleep(5)
if(turfs[current])
current.overlays -= overlays[turfs[current]]
turfs[current] = lowest_id
current.overlays += overlays[lowest_id]
sleep(5)
var/list/final_arrangement = list()
for(var/turf/simulated/current in turfs)
current_identifier = identical_ids[turfs[current]]
current.overlays -= overlays[turfs[current]]
current.overlays += overlays[current_identifier]
sleep(5)
if( current_identifier > final_arrangement.len )
final_arrangement.len = current_identifier
final_arrangement[current_identifier] = list(current)
else
final_arrangement[current_identifier] += current
//lazy but fast
final_arrangement.Remove(null)
src << "There are [final_arrangement.len] unique segments."
for(var/turf/current in turfs)
current.overlays -= overlays
return final_arrangement
+107 -55
View File
@@ -8,7 +8,7 @@ What are the archived variables for?
#define SPECIFIC_HEAT_AIR 20
#define SPECIFIC_HEAT_CDO 30
#define HEAT_CAPACITY_CALCULATION(oxygen,carbon_dioxide,nitrogen,toxins) \
(carbon_dioxide*SPECIFIC_HEAT_CDO + (oxygen+nitrogen)*SPECIFIC_HEAT_AIR + toxins*SPECIFIC_HEAT_TOXIN)
max(0, carbon_dioxide * SPECIFIC_HEAT_CDO + (oxygen + nitrogen) * SPECIFIC_HEAT_AIR + toxins * SPECIFIC_HEAT_TOXIN)
#define MINIMUM_HEAT_CAPACITY 0.0003
#define QUANTIZE(variable) (round(variable,0.0001))
@@ -17,12 +17,15 @@ What are the archived variables for?
#define TEMPERATURE_ICE_FORMATION 273.15 // 273 kelvin is the freezing point of water.
#define MIN_PRESSURE_ICE_FORMATION 10 // 10kPa should be okay
<<<<<<< HEAD
#define GRAPHICS_PLASMA 1
#define GRAPHICS_N2O 2
#define GRAPHICS_REAGENTS 4 // Not used. Yet.
#define GRAPHICS_COLD 8
=======
>>>>>>> parent of 0227baa... Reverting ZAS back to /vg/ style
/datum/gas/sleeping_agent/specific_heat = 40 //These are used for the "Trace Gases" stuff, but is buggy.
/datum/gas/oxygen_agent_b/specific_heat = 300
@@ -52,7 +55,7 @@ What are the archived variables for?
//Size of the group this gas_mixture is representing.
//=1 for singletons
var/graphics=0
var/graphic
var/list/datum/gas/trace_gases = list() //Seemed to be a good idea that was abandoned
@@ -63,9 +66,11 @@ What are the archived variables for?
var/tmp/temperature_archived
var/tmp/graphics_archived = 0
var/tmp/graphic_archived = 0
var/tmp/fuel_burnt = 0
var/reacting = 0
//FOR THE LOVE OF GOD PLEASE USE THIS PROC
//Call it with negative numbers to remove gases.
@@ -90,7 +95,7 @@ What are the archived variables for?
update_values()
return
//tg seems to like using these a lot
//tg seems to like using these a lot
/datum/gas_mixture/proc/return_temperature()
return temperature
@@ -114,7 +119,7 @@ What are the archived variables for?
var/heat_capacity = HEAT_CAPACITY_CALCULATION(oxygen,carbon_dioxide,nitrogen,toxins)
if(trace_gases && trace_gases.len) //sanity check because somehow the tracegases gets nulled?
if(trace_gases.len)
for(var/datum/gas/trace_gas in trace_gases)
heat_capacity += trace_gas.moles*trace_gas.specific_heat
@@ -198,6 +203,7 @@ What are the archived variables for?
//Inputs: None
//Outputs: 1 if graphic changed, 0 if unchanged
<<<<<<< HEAD
graphics = 0
@@ -208,21 +214,26 @@ What are the archived variables for?
// This ordering will hopefully keep it from sampling random noise every damn tick.
//if(was_icy || (!was_icy && prob(25)))
graphics |= GRAPHICS_COLD
=======
graphic = 0
if(temperature <= TEMPERATURE_ICE_FORMATION && return_pressure()>MIN_PRESSURE_ICE_FORMATION)
// If we're just forming, do a probability check. Otherwise, KEEP IT ON~
// This ordering will hopefully keep it from sampling random noise every damn tick.
//if(was_icy || (!was_icy && prob(25)))
graphic = 3
>>>>>>> parent of 0227baa... Reverting ZAS back to /vg/ style
if(toxins > MOLES_PLASMA_VISIBLE)
graphics |= GRAPHICS_PLASMA
if(length(trace_gases))
graphic = 1
else if(length(trace_gases))
var/datum/gas/sleeping_agent = locate(/datum/gas/sleeping_agent) in trace_gases
if(sleeping_agent && (sleeping_agent.moles > 1))
graphics |= GRAPHICS_N2O
graphic = 2
else
graphic = 0
/*
var/datum/gas/reagent = exact_locate(/datum/gas/reagent,trace_gases)
if(reagent && (reagent.moles > 0.1))
graphics |= GRAPHICS_REAGENTS
*/
return graphics != graphics_archived
return graphic != graphic_archived
/datum/gas_mixture/proc/react(atom/dump_location)
//Purpose: Calculating if it is possible for a fire to occur in the airmix
@@ -230,14 +241,13 @@ What are the archived variables for?
//Inputs: None
//Outputs: If a fire occured
var/reacting = 0 //set to 1 if a notable reaction occured (used by pipe_network)
//set to 1 if a notable reaction occured (used by pipe_network)
if(temperature > FIRE_MINIMUM_TEMPERATURE_TO_EXIST)
if(zburn(null) > 0)
reacting = 1
zburn(null)
return reacting
/*
/datum/gas_mixture/proc/fire()
//Purpose: Calculating any fire reactions.
//Called by: react() (See above)
@@ -246,7 +256,7 @@ What are the archived variables for?
return zburn(null)
/*var/energy_released = 0
var/energy_released = 0
var/old_heat_capacity = heat_capacity()
var/datum/gas/volatile_fuel/fuel_store = locate(/datum/gas/volatile_fuel) in trace_gases
@@ -321,7 +331,7 @@ What are the archived variables for?
temperature_archived = temperature
graphics_archived = graphics
graphic_archived = graphic
return 1
@@ -396,10 +406,6 @@ What are the archived variables for?
//Inputs: How many moles to remove.
//Outputs: Removed air.
// Fix a singuloth problem
if(group_multiplier==0)
return null
var/sum = total_moles()
amount = min(amount,sum) //Can not take more air than tile has!
if(amount <= 0)
@@ -411,7 +417,7 @@ What are the archived variables for?
removed.oxygen = QUANTIZE((oxygen/sum)*amount)
removed.nitrogen = QUANTIZE((nitrogen/sum)*amount)
removed.carbon_dioxide = QUANTIZE((carbon_dioxide/sum)*amount)
removed.toxins = QUANTIZE((toxins/sum)*amount)
removed.toxins = QUANTIZE(((toxins/sum)*amount))
oxygen -= removed.oxygen/group_multiplier
nitrogen -= removed.nitrogen/group_multiplier
@@ -423,8 +429,8 @@ What are the archived variables for?
var/datum/gas/corresponding = new trace_gas.type()
removed.trace_gases += corresponding
corresponding.moles = (trace_gas.moles/sum)*amount
trace_gas.moles -= corresponding.moles/group_multiplier
corresponding.moles = ((trace_gas.moles/sum)*amount)
trace_gas.moles -= (corresponding.moles/group_multiplier)
removed.temperature = temperature
update_values()
@@ -991,6 +997,7 @@ What are the archived variables for?
//Outputs: 1 if can rebuild, 0 if not.
if(!sample) return 0
if((abs(oxygen-sample.oxygen) > MINIMUM_AIR_TO_SUSPEND) && \
((oxygen < (1-MINIMUM_AIR_RATIO_TO_SUSPEND)*sample.oxygen) || (oxygen > (1+MINIMUM_AIR_RATIO_TO_SUSPEND)*sample.oxygen)))
return 0
@@ -998,39 +1005,60 @@ What are the archived variables for?
((nitrogen < (1-MINIMUM_AIR_RATIO_TO_SUSPEND)*sample.nitrogen) || (nitrogen > (1+MINIMUM_AIR_RATIO_TO_SUSPEND)*sample.nitrogen)))
return 0
if((abs(carbon_dioxide-sample.carbon_dioxide) > MINIMUM_AIR_TO_SUSPEND) && \
((carbon_dioxide < (1-MINIMUM_AIR_RATIO_TO_SUSPEND)*sample.carbon_dioxide) || (oxygen > (1+MINIMUM_AIR_RATIO_TO_SUSPEND)*sample.carbon_dioxide)))
((carbon_dioxide < (1-MINIMUM_AIR_RATIO_TO_SUSPEND)*sample.carbon_dioxide) || (carbon_dioxide > (1+MINIMUM_AIR_RATIO_TO_SUSPEND)*sample.carbon_dioxide)))
return 0
if((abs(toxins-sample.toxins) > MINIMUM_AIR_TO_SUSPEND) && \
((toxins < (1-MINIMUM_AIR_RATIO_TO_SUSPEND)*sample.toxins) || (toxins > (1+MINIMUM_AIR_RATIO_TO_SUSPEND)*sample.toxins)))
return 0
if(total_moles() > MINIMUM_AIR_TO_SUSPEND)
if((abs(temperature-sample.temperature) > MINIMUM_TEMPERATURE_DELTA_TO_SUSPEND) && \
((temperature < (1-MINIMUM_TEMPERATURE_RATIO_TO_SUSPEND)*sample.temperature) || (temperature > (1+MINIMUM_TEMPERATURE_RATIO_TO_SUSPEND)*sample.temperature)))
//world << "temp fail [temperature] & [sample.temperature]"
return 0
var/check_moles
if(sample.trace_gases.len)
for(var/datum/gas/trace_gas in sample.trace_gases)
if(trace_gas.moles_archived > MINIMUM_AIR_TO_SUSPEND)
var/datum/gas/corresponding = locate(trace_gas.type) in trace_gases
if(corresponding)
if((abs(trace_gas.moles - corresponding.moles) > MINIMUM_AIR_TO_SUSPEND) && \
((corresponding.moles < (1-MINIMUM_AIR_RATIO_TO_SUSPEND)*trace_gas.moles) || (corresponding.moles > (1+MINIMUM_AIR_RATIO_TO_SUSPEND)*trace_gas.moles)))
return 0
else
return 0
var/datum/gas/corresponding = locate(trace_gas.type) in trace_gases
if(corresponding)
check_moles = corresponding.moles
else
check_moles = 0
if((abs(trace_gas.moles - check_moles) > MINIMUM_AIR_TO_SUSPEND) && \
((check_moles < (1-MINIMUM_AIR_RATIO_TO_SUSPEND)*trace_gas.moles) || (check_moles > (1+MINIMUM_AIR_RATIO_TO_SUSPEND)*trace_gas.moles)))
return 0
if(trace_gases.len)
for(var/datum/gas/trace_gas in trace_gases)
if(trace_gas.moles > MINIMUM_AIR_TO_SUSPEND)
var/datum/gas/corresponding = locate(trace_gas.type) in sample.trace_gases
if(corresponding)
if((abs(trace_gas.moles - corresponding.moles) > MINIMUM_AIR_TO_SUSPEND) && \
((trace_gas.moles < (1-MINIMUM_AIR_RATIO_TO_SUSPEND)*corresponding.moles) || (trace_gas.moles > (1+MINIMUM_AIR_RATIO_TO_SUSPEND)*corresponding.moles)))
return 0
else
return 0
var/datum/gas/corresponding = locate(trace_gas.type) in trace_gases
if(corresponding)
check_moles = corresponding.moles
else
check_moles = 0
if((abs(trace_gas.moles - check_moles) > MINIMUM_AIR_TO_SUSPEND) && \
((trace_gas.moles < (1-MINIMUM_AIR_RATIO_TO_SUSPEND)*check_moles) || (trace_gas.moles > (1+MINIMUM_AIR_RATIO_TO_SUSPEND)*check_moles)))
return 0
return 1
/datum/gas_mixture/proc/add(datum/gas_mixture/right_side)
oxygen += right_side.oxygen
carbon_dioxide += right_side.carbon_dioxide
nitrogen += right_side.nitrogen
toxins += right_side.toxins
if(trace_gases.len || right_side.trace_gases.len)
for(var/datum/gas/trace_gas in right_side.trace_gases)
var/datum/gas/corresponding = locate(trace_gas.type) in trace_gases
if(!corresponding)
corresponding = new trace_gas.type()
trace_gases += corresponding
corresponding.moles += trace_gas.moles
update_values()
return 1
/datum/gas_mixture/proc/subtract(datum/gas_mixture/right_side)
@@ -1039,18 +1067,42 @@ What are the archived variables for?
//Inputs: Gas mix to remove
//Outputs: 1
oxygen -= right_side.oxygen
carbon_dioxide -= right_side.carbon_dioxide
nitrogen -= right_side.nitrogen
toxins -= right_side.toxins
oxygen = max(oxygen - right_side.oxygen)
carbon_dioxide = max(carbon_dioxide - right_side.carbon_dioxide)
nitrogen = max(nitrogen - right_side.nitrogen)
toxins = max(toxins - right_side.toxins)
if((trace_gases.len > 0)||(right_side.trace_gases.len > 0))
if(trace_gases.len || right_side.trace_gases.len)
for(var/datum/gas/trace_gas in right_side.trace_gases)
var/datum/gas/corresponding = locate(trace_gas.type) in trace_gases
if(!corresponding)
corresponding = new trace_gas.type()
trace_gases += corresponding
if(corresponding)
corresponding.moles = max(0, corresponding.moles - trace_gas.moles)
update_values()
return 1
/datum/gas_mixture/proc/multiply(factor)
oxygen *= factor
carbon_dioxide *= factor
nitrogen *= factor
toxins *= factor
if(trace_gases && trace_gases.len)
for(var/datum/gas/trace_gas in trace_gases)
trace_gas.moles *= factor
update_values()
return 1
/datum/gas_mixture/proc/divide(factor)
oxygen /= factor
carbon_dioxide /= factor
nitrogen /= factor
toxins /= factor
if(trace_gases && trace_gases.len)
for(var/datum/gas/trace_gas in trace_gases)
trace_gas.moles /= factor
corresponding.moles -= trace_gas.moles
update_values()
return 1
+183 -48
View File
@@ -50,10 +50,8 @@ Important Procedures
air_master.process()
This first processes the air_master update/rebuild lists then processes all groups and tiles for air calculations
*/
var/kill_air = 0
var/tick_multiplier = 2
atom/proc/CanPass(atom/movable/mover, turf/target, height=1.5, air_group = 0)
@@ -87,17 +85,32 @@ atom/proc/CanPass(atom/movable/mover, turf/target, height=1.5, air_group = 0)
var/datum/controller/air_system/air_master
/datum/controller/air_system/
//Geoemetry lists
/datum/controller/air_system
//Geometry lists
var/list/turfs_with_connections = list()
var/list/active_hotspots = list()
//Special functions lists
var/reconsidering_zones = FALSE
var/list/tiles_to_reconsider_zones = list()
var/list/tiles_to_reconsider_alternate
//Geometry updates lists
var/updating_tiles = FALSE
var/list/tiles_to_update = list()
var/list/tiles_to_update_alternate
var/checking_connections = FALSE
var/list/connections_to_check = list()
var/list/connections_to_check_alternate
var/list/potential_intrazone_connections = list()
//Zone lists
var/list/active_zones = list()
var/list/zones_needing_rebuilt = list()
var/list/zones = list()
var/current_cycle = 0
var/update_delay = 5 //How long between check should it try to process atmos again.
@@ -106,20 +119,7 @@ var/datum/controller/air_system/air_master
var/tick_progress = 0
/* process()
//Call this to process air movements for a cycle
process_rebuild_select_groups()
//Used by process()
//Warning: Do not call this
rebuild_group(datum/air_group)
//Used by process_rebuild_select_groups()
//Warning: Do not call this, add the group to air_master.groups_to_rebuild instead
*/
/datum/controller/air_system/proc/setup()
/datum/controller/air_system/proc/Setup()
//Purpose: Call this at the start to setup air groups geometry
// (Warning: Very processor intensive but only must be done once per round)
//Called by: Gameticker/Master controller
@@ -147,10 +147,11 @@ var/datum/controller/air_system/air_master
Total Simulated Turfs: [simulated_turf_count]
Total Zones: [zones.len]
Total Unsimulated Turfs: [world.maxx*world.maxy*world.maxz - simulated_turf_count]</font>"}
/*
spawn start()
/datum/controller/air_system/proc/start()
// spawn Start()
/datum/controller/air_system/proc/Start()
//Purpose: This is kicked off by the master controller, and controls the processing of all atmosphere.
//Called by: Master controller
//Inputs: None.
@@ -160,62 +161,196 @@ Total Unsimulated Turfs: [world.maxx*world.maxy*world.maxz - simulated_turf_coun
set background = 1
while(1)
if(!kill_air)
current_cycle++
var/success = tick() //Changed so that a runtime does not crash the ticker.
if(!air_processing_killed)
var/success = Tick() //Changed so that a runtime does not crash the ticker.
if(!success) //Runtimed.
failed_ticks++
if(failed_ticks > 20)
world << "<font color='red'><b>ERROR IN ATMOS TICKER. Killing air simulation!</font></b>"
kill_air = 1
air_processing_killed = 1
sleep(max(5,update_delay*tick_multiplier))
*/
/datum/controller/air_system/proc/tick()
/datum/controller/air_system/proc/Tick()
. = 1 //Set the default return value, for runtime detection.
tick_progress = "update_air_properties"
if(tiles_to_update.len) //If there are tiles to update, do so.
current_cycle++
//If there are tiles to update, do so.
tick_progress = "updating turf properties"
if(tiles_to_update.len)
updating_tiles = TRUE
for(var/turf/simulated/T in tiles_to_update)
if(. && T && !T.update_air_properties())
. = 0 //If a runtime occured, make sure we can sense it.
//message_admins("ZASALERT: Unable run turf/simualted/update_air_properties()")
//If a runtime occured, make sure we can sense it.
. = 0
updating_tiles = FALSE
if(.)
tiles_to_update = list()
if(tiles_to_update_alternate)
tiles_to_update = tiles_to_update_alternate
tiles_to_update_alternate = null
else
tiles_to_update = list()
else if(tiles_to_update_alternate)
tiles_to_update |= tiles_to_update_alternate
tiles_to_update_alternate = null
//Rebuild zones.
if(.)
tick_progress = "rebuilding zones"
if(zones_needing_rebuilt.len)
for(var/zone/zone in zones_needing_rebuilt)
zone.Rebuild()
zones_needing_rebuilt = list()
//Check sanity on connection objects.
if(.)
tick_progress = "connections_to_check"
tick_progress = "checking/creating connections"
if(connections_to_check.len)
for(var/connection/C in connections_to_check)
C.CheckPassSanity()
connections_to_check = list()
checking_connections = TRUE
//Ensure tiles still have zones.
if(.)
tick_progress = "tiles_to_reconsider_zones"
if(tiles_to_reconsider_zones.len)
for(var/turf/simulated/T in tiles_to_reconsider_zones)
if(!T.zone)
new /zone(T)
tiles_to_reconsider_zones = list()
for(var/connection/C in connections_to_check)
C.Cleanup()
for(var/turf/simulated/turf_1 in potential_intrazone_connections)
for(var/turf/simulated/turf_2 in potential_intrazone_connections[turf_1])
if(!turf_1.zone || !turf_2.zone)
continue
if(turf_1.zone == turf_2.zone)
continue
var/should_skip = FALSE
if(turf_1 in air_master.turfs_with_connections)
for(var/connection/C in turfs_with_connections[turf_1])
if(C.B == turf_2 || C.A == turf_2)
should_skip = TRUE
break
if(should_skip)
continue
new /connection(turf_1, turf_2)
checking_connections = FALSE
potential_intrazone_connections = list()
if(connections_to_check_alternate)
connections_to_check = connections_to_check_alternate
connections_to_check_alternate = null
else
connections_to_check = list()
//Process zones.
if(.)
tick_progress = "zone/process()"
for(var/zone/Z in zones)
tick_progress = "processing zones"
for(var/zone/Z in active_zones)
if(Z.last_update < current_cycle)
var/output = Z.process()
if(Z)
Z.last_update = current_cycle
if(. && Z && !output)
. = 0
//Ensure tiles still have zones.
if(.)
tick_progress = "reconsidering zones on turfs"
if(tiles_to_reconsider_zones.len)
reconsidering_zones = TRUE
for(var/turf/simulated/T in tiles_to_reconsider_zones)
if(!T.zone)
new /zone(T)
reconsidering_zones = FALSE
if(tiles_to_reconsider_alternate)
tiles_to_reconsider_zones = tiles_to_reconsider_alternate
tiles_to_reconsider_alternate = null
else
tiles_to_reconsider_zones = list()
//Process fires.
if(.)
tick_progress = "active_hotspots (fire)"
tick_progress = "processing fire"
for(var/obj/fire/F in active_hotspots)
if(. && F && !F.process())
. = 0
if(.)
tick_progress = "success"
tick_progress = "success"
/datum/controller/air_system/proc/AddTurfToUpdate(turf/simulated/outdated_turf)
var/list/tiles_to_check = list()
if(istype(outdated_turf))
tiles_to_check |= outdated_turf
if(istype(outdated_turf, /turf))
for(var/direction in cardinal)
var/turf/simulated/adjacent_turf = get_step(outdated_turf, direction)
if(istype(adjacent_turf))
tiles_to_check |= adjacent_turf
if(updating_tiles)
if(!tiles_to_update_alternate)
tiles_to_update_alternate = tiles_to_check
else
tiles_to_update_alternate |= tiles_to_check
else
tiles_to_update |= tiles_to_check
/datum/controller/air_system/proc/AddConnectionToCheck(connection/connection)
if(checking_connections)
if(istype(connection, /list))
if(!connections_to_check_alternate)
connections_to_check_alternate = connection
else if(!connections_to_check_alternate)
connections_to_check_alternate = list()
connections_to_check_alternate |= connection
else
connections_to_check |= connection
/datum/controller/air_system/proc/ReconsiderTileZone(var/turf/simulated/zoneless_turf)
if(zoneless_turf.zone)
return
if(reconsidering_zones)
if(!tiles_to_reconsider_alternate)
tiles_to_reconsider_alternate = list()
tiles_to_reconsider_alternate |= zoneless_turf
else
tiles_to_reconsider_zones |= zoneless_turf
/datum/controller/air_system/proc/AddIntrazoneConnection(var/turf/simulated/A, var/turf/simulated/B)
if(!istype(A) || !istype(B))
return
if(A in potential_intrazone_connections)
if(B in potential_intrazone_connections[A])
return
if (B in potential_intrazone_connections)
if(A in potential_intrazone_connections[B])
return
potential_intrazone_connections[B] += A
else
potential_intrazone_connections[B] = list(A)
+32 -39
View File
@@ -38,9 +38,6 @@ turf/simulated/hotspot_expose(exposed_temperature, exposed_volume, soh)
new /obj/fire(src,1000)
//active_hotspot.just_spawned = (current_cycle < air_master.current_cycle)
//remove just_spawned protection if no longer processing this cell
return igniting
/obj/fire
@@ -128,12 +125,12 @@ turf/simulated/hotspot_expose(exposed_temperature, exposed_volume, soh)
//Spread the fire.
if(!(locate(/obj/fire) in enemy_tile))
if( prob( 50 + 50 * (firelevel/zas_settings.Get(/datum/ZAS_Setting/fire_firelevel_multiplier)) ) && S.CanPass(null, enemy_tile, 0,0) && enemy_tile.CanPass(null, S, 0,0))
if( prob( 50 + 50 * (firelevel/vsc.fire_firelevel_multiplier) ) && S.CanPass(null, enemy_tile, 0,0) && enemy_tile.CanPass(null, S, 0,0))
new/obj/fire(enemy_tile,firelevel)
//seperate part of the present gas
//this is done to prevent the fire burning all gases in a single pass
var/datum/gas_mixture/flow = air_contents.remove_ratio(zas_settings.Get(/datum/ZAS_Setting/fire_consumption_rate))
var/datum/gas_mixture/flow = air_contents.remove_ratio(vsc.fire_consuption_rate)
///////////////////////////////// FLOW HAS BEEN CREATED /// DONT DELETE THE FIRE UNTIL IT IS MERGED BACK OR YOU WILL DELETE AIR ///////////////////////////////////////////////
if(flow)
@@ -225,7 +222,7 @@ datum/gas_mixture/proc/zburn(obj/effect/decal/cleanable/liquid_fuel/liquid, forc
var/total_reactants = total_fuel + total_oxygen
//determine the amount of reactants actually reacting
var/used_reactants_ratio = min( max(total_reactants * firelevel / zas_settings.Get(/datum/ZAS_Setting/fire_firelevel_multiplier), 0.2), total_reactants) / total_reactants
var/used_reactants_ratio = min( max(total_reactants * firelevel / vsc.fire_firelevel_multiplier, 0.2), total_reactants) / total_reactants
//remove and add gasses as calculated
oxygen -= min(oxygen, total_oxygen * used_reactants_ratio )
@@ -246,7 +243,7 @@ datum/gas_mixture/proc/zburn(obj/effect/decal/cleanable/liquid_fuel/liquid, forc
if(liquid.amount <= 0) del liquid
//calculate the energy produced by the reaction and then set the new temperature of the mix
temperature = (starting_energy + zas_settings.Get(/datum/ZAS_Setting/fire_fuel_energy_release) * total_fuel) / heat_capacity()
temperature = (starting_energy + vsc.fire_fuel_energy_release * total_fuel) / heat_capacity()
update_values()
value = total_reactants * used_reactants_ratio
@@ -256,34 +253,31 @@ datum/gas_mixture/proc/check_recombustability(obj/effect/decal/cleanable/liquid_
//this is a copy proc to continue a fire after its been started.
var/datum/gas/volatile_fuel/fuel = locate() in trace_gases
var/value = 0
if(oxygen && (toxins || fuel || liquid))
if(liquid)
value = 1
else if (toxins && !value)
value = 1
else if(fuel && !value)
value = 1
return 1
if (toxins)
return 1
if(fuel)
return 1
return value
return 0
datum/gas_mixture/proc/check_combustability(obj/effect/decal/cleanable/liquid_fuel/liquid)
//this check comes up very often and is thus centralized here to ease adding stuff
var/datum/gas/volatile_fuel/fuel = locate() in trace_gases
var/value = 0
if(oxygen && (toxins || fuel || liquid))
if(liquid)
value = 1
else if (toxins >= 0.7 && !value)
value = 1
else if(fuel && !value)
if(fuel.moles >= 1.4)
value = 1
return 1
if (toxins >= 0.7)
return 1
if(fuel && fuel.moles >= 1.4)
return 1
return value
return 0
datum/gas_mixture/proc/calculate_firelevel(obj/effect/decal/cleanable/liquid_fuel/liquid)
//Calculates the firelevel based on one equation instead of having to do this multiple times in different areas.
@@ -309,31 +303,30 @@ datum/gas_mixture/proc/calculate_firelevel(obj/effect/decal/cleanable/liquid_fue
//slows down the burning when the concentration of the reactants is low
var/dampening_multiplier = total_combustables / (total_combustables + nitrogen + carbon_dioxide)
//calculates how close the mixture of the reactants is to the optimum
var/mix_multiplier = 1 / (1 + (5 * ((oxygen / total_combustables) ^2)))
var/mix_multiplier = 1 / (1 + (5 * ((oxygen / total_combustables) ** 2)))
//toss everything together
firelevel = zas_settings.Get(/datum/ZAS_Setting/fire_firelevel_multiplier) * mix_multiplier * dampening_multiplier
firelevel = vsc.fire_firelevel_multiplier * mix_multiplier * dampening_multiplier
return max( 0, firelevel)
/mob/living/carbon/human/proc/FireBurn(var/firelevel, var/last_temperature, var/pressure)
// mostly using the old proc from Sky until I can think of something better
/mob/living/proc/FireBurn(var/firelevel, var/last_temperature, var/pressure)
var/mx = 5 * firelevel/vsc.fire_firelevel_multiplier * min(pressure / ONE_ATMOSPHERE, 1)
apply_damage(2.5*mx, BURN)
/mob/living/carbon/human/FireBurn(var/firelevel, var/last_temperature, var/pressure)
//Burns mobs due to fire. Respects heat transfer coefficients on various body parts.
//Due to TG reworking how fireprotection works, this is kinda less meaningful.
var
head_exposure = 1
chest_exposure = 1
groin_exposure = 1
legs_exposure = 1
arms_exposure = 1
//determine the multiplier
//minimize this for low-pressure enviroments
var/mx = 5 * firelevel/zas_settings.Get(/datum/ZAS_Setting/fire_firelevel_multiplier) * min(pressure / ONE_ATMOSPHERE, 1)
var/head_exposure = 1
var/chest_exposure = 1
var/groin_exposure = 1
var/legs_exposure = 1
var/arms_exposure = 1
//Get heat transfer coefficients for clothing.
//skytodo: kill anyone who breaks things then orders me to fix them
for(var/obj/item/clothing/C in src)
if(l_hand == C || r_hand == C)
continue
@@ -349,6 +342,8 @@ datum/gas_mixture/proc/calculate_firelevel(obj/effect/decal/cleanable/liquid_fue
legs_exposure = 0
if(C.body_parts_covered & ARMS)
arms_exposure = 0
//minimize this for low-pressure enviroments
var/mx = 5 * firelevel/vsc.fire_firelevel_multiplier * min(pressure / ONE_ATMOSPHERE, 1)
//Always check these damage procs first if fire damage isn't working. They're probably what's wrong.
@@ -359,5 +354,3 @@ datum/gas_mixture/proc/calculate_firelevel(obj/effect/decal/cleanable/liquid_fue
apply_damage(0.6*mx*legs_exposure, BURN, "r_leg", 0, 0, "Fire")
apply_damage(0.4*mx*arms_exposure, BURN, "l_arm", 0, 0, "Fire")
apply_damage(0.4*mx*arms_exposure, BURN, "r_arm", 0, 0, "Fire")
//flash_pain()
+7 -6
View File
@@ -155,16 +155,17 @@ proc/ZConnect(turf/simulated/A,turf/simulated/B)
//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.zone == B.zone)
air_master.AddIntrazoneConnection(A,B)
return
if(A.CanPass(null,B,0,1))
if(A.CanPass(null, B, 1.5, 1) && A.zone.air.compare(B.zone.air))
return ZMerge(A.zone,B.zone)
//Ensure the connection isn't already made.
if("\ref[A]" in air_master.turfs_with_connections)
for(var/connection/C in air_master.turfs_with_connections["\ref[A]"])
C.Cleanup()
if(C && (C.B == B || C.A == B))
if(A in air_master.turfs_with_connections)
for(var/connection/C in air_master.turfs_with_connections[A])
if(C.B == B || C.A == B)
return
//Make the connection.
+46 -8
View File
@@ -1,5 +1,43 @@
var/image/contamination_overlay = image('icons/effects/contamination.dmi')
/pl_control
var/PLASMA_DMG = 3
var/PLASMA_DMG_NAME = "Plasma Damage Amount"
var/PLASMA_DMG_DESC = "Self Descriptive"
var/CLOTH_CONTAMINATION = 1
var/CLOTH_CONTAMINATION_NAME = "Cloth Contamination"
var/CLOTH_CONTAMINATION_DESC = "If this is on, plasma does damage by getting into cloth."
var/PLASMAGUARD_ONLY = 0
var/PLASMAGUARD_ONLY_NAME = "\"PlasmaGuard Only\""
var/PLASMAGUARD_ONLY_DESC = "If this is on, only biosuits and spacesuits protect against contamination and ill effects."
var/GENETIC_CORRUPTION = 0
var/GENETIC_CORRUPTION_NAME = "Genetic Corruption Chance"
var/GENETIC_CORRUPTION_DESC = "Chance of genetic corruption as well as toxic damage, X in 10,000."
var/SKIN_BURNS = 0
var/SKIN_BURNS_DESC = "Plasma has an effect similar to mustard gas on the un-suited."
var/SKIN_BURNS_NAME = "Skin Burns"
var/EYE_BURNS = 1
var/EYE_BURNS_NAME = "Eye Burns"
var/EYE_BURNS_DESC = "Plasma burns the eyes of anyone not wearing eye protection."
var/CONTAMINATION_LOSS = 0.02
var/CONTAMINATION_LOSS_NAME = "Contamination Loss"
var/CONTAMINATION_LOSS_DESC = "How much toxin damage is dealt from contaminated clothing" //Per tick? ASK ARYN
var/PLASMA_HALLUCINATION = 0
var/PLASMA_HALLUCINATION_NAME = "Plasma Hallucination"
var/PLASMA_HALLUCINATION_DESC = "Does being in plasma cause you to hallucinate?"
var/N2O_HALLUCINATION = 1
var/N2O_HALLUCINATION_NAME = "N2O Hallucination"
var/N2O_HALLUCINATION_DESC = "Does being in sleeping gas cause you to hallucinate?"
obj/var/contaminated = 0
@@ -40,21 +78,21 @@ obj/var/contaminated = 0
//Handles all the bad things plasma can do.
//Contamination
if(zas_settings.Get(/datum/ZAS_Setting/CLOTH_CONTAMINATION)) contaminate()
if(vsc.plc.CLOTH_CONTAMINATION) contaminate()
//Anything else requires them to not be dead.
if(stat >= 2)
return
//Burn skin if exposed.
if(zas_settings.Get(/datum/ZAS_Setting/SKIN_BURNS))
if(vsc.plc.SKIN_BURNS)
if(!pl_head_protected() || !pl_suit_protected())
burn_skin(0.75)
if(prob(20)) src << "\red Your skin burns!"
updatehealth()
//Burn eyes if exposed.
if(zas_settings.Get(/datum/ZAS_Setting/EYE_BURNS))
if(vsc.plc.EYE_BURNS)
if(!head)
if(!wear_mask)
burn_eyes()
@@ -70,8 +108,8 @@ obj/var/contaminated = 0
burn_eyes()
//Genetic Corruption
if(zas_settings.Get(/datum/ZAS_Setting/GENETIC_CORRUPTION))
if(rand(1,10000) < zas_settings.Get(/datum/ZAS_Setting/GENETIC_CORRUPTION))
if(vsc.plc.GENETIC_CORRUPTION)
if(rand(1,10000) < vsc.plc.GENETIC_CORRUPTION)
randmutb(src)
src << "\red High levels of toxins cause you to spontaneously mutate."
domutcheck(src,null)
@@ -90,7 +128,7 @@ obj/var/contaminated = 0
/mob/living/carbon/human/proc/pl_head_protected()
//Checks if the head is adequately sealed.
if(head)
if(zas_settings.Get(/datum/ZAS_Setting/PLASMAGUARD_ONLY))
if(vsc.plc.PLASMAGUARD_ONLY)
if(head.flags & PLASMAGUARD)
return 1
else if(head.flags & HEADCOVERSEYES)
@@ -100,7 +138,7 @@ obj/var/contaminated = 0
/mob/living/carbon/human/proc/pl_suit_protected()
//Checks if the suit is adequately sealed.
if(wear_suit)
if(zas_settings.Get(/datum/ZAS_Setting/PLASMAGUARD_ONLY))
if(vsc.plc.PLASMAGUARD_ONLY)
if(wear_suit.flags & PLASMAGUARD) return 1
else
if(wear_suit.flags_inv & HIDEJUMPSUIT) return 1
@@ -116,7 +154,7 @@ obj/var/contaminated = 0
turf/Entered(obj/item/I)
. = ..()
//Items that are in plasma, but not on a mob, can still be contaminated.
if(istype(I) && zas_settings.Get(/datum/ZAS_Setting/CLOTH_CONTAMINATION))
if(istype(I) && vsc.plc.CLOTH_CONTAMINATION)
var/datum/gas_mixture/env = return_air(1)
if(!env)
return
+290 -295
View File
@@ -1,75 +1,71 @@
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.
/vs_control
var/fire_consuption_rate = 0.25
var/fire_consuption_rate_NAME = "Fire - Air Consumption Ratio"
var/fire_consuption_rate_DESC = "Ratio of air removed and combusted per tick."
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."
var/fire_firelevel_multiplier = 25
var/fire_firelevel_multiplier_NAME = "Fire - Firelevel Constant"
var/fire_firelevel_multiplier_DESC = "Multiplied by the equation for firelevel, affects mainly the extingiushing of fires."
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"
var/fire_fuel_energy_release = 397000
var/fire_fuel_energy_release_NAME = "Fire - Fuel energy release"
var/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."
var/IgnitionLevel = 0.5
var/IgnitionLevel_DESC = "Determines point at which fire can ignite"
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."
var/airflow_lightest_pressure = 20
var/airflow_lightest_pressure_NAME = "Airflow - Small Movement Threshold %"
var/airflow_lightest_pressure_DESC = "Percent of 1 Atm. at which items with the small 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."
var/airflow_light_pressure = 35
var/airflow_light_pressure_NAME = "Airflow - Medium Movement Threshold %"
var/airflow_light_pressure_DESC = "Percent of 1 Atm. at which items with the medium 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."
var/airflow_medium_pressure = 50
var/airflow_medium_pressure_NAME = "Airflow - Heavy Movement Threshold %"
var/airflow_medium_pressure_DESC = "Percent of 1 Atm. at which items with the largest weight classes 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."
var/airflow_heavy_pressure = 65
var/airflow_heavy_pressure_NAME = "Airflow - Mob Movement Threshold %"
var/airflow_heavy_pressure_DESC = "Percent of 1 Atm. at which mobs 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."
var/airflow_dense_pressure = 85
var/airflow_dense_pressure_NAME = "Airflow - Dense Movement Threshold %"
var/airflow_dense_pressure_DESC = "Percent of 1 Atm. at which items with canisters and closets will move."
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."
var/airflow_stun_pressure = 60
var/airflow_stun_pressure_NAME = "Airflow - Mob Stunning Threshold %"
var/airflow_stun_pressure_DESC = "Percent of 1 Atm. at which mobs will be stunned by airflow."
airflow_stun = 1
airflow_stun_NAME = "Airflow Impact - Stunning"
airflow_stun_DESC = "How much a mob is stunned when hit by an object."
var/airflow_stun_cooldown = 60
var/airflow_stun_cooldown_NAME = "Aiflow Stunning - Cooldown"
var/airflow_stun_cooldown_DESC = "How long, in tenths of a second, to wait before stunning them again."
airflow_damage = 2
airflow_damage_NAME = "Airflow Impact - Damage"
airflow_damage_DESC = "Damage from airflow impacts."
var/airflow_stun = 1
var/airflow_stun_NAME = "Airflow Impact - Stunning"
var/airflow_stun_DESC = "How much a mob is stunned when hit by an object."
airflow_speed_decay = 1.5
airflow_speed_decay_NAME = "Airflow Speed Decay"
airflow_speed_decay_DESC = "How rapidly the speed gained from airflow decays."
var/airflow_damage = 2
var/airflow_damage_NAME = "Airflow Impact - Damage"
var/airflow_damage_DESC = "Damage from airflow impacts."
airflow_delay = 30
airflow_delay_NAME = "Airflow Retrigger Delay"
airflow_delay_DESC = "Time in deciseconds before things can be moved by airflow again."
var/airflow_speed_decay = 1.5
var/airflow_speed_decay_NAME = "Airflow Speed Decay"
var/airflow_speed_decay_DESC = "How rapidly the speed gained from airflow decays."
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/airflow_delay = 30
var/airflow_delay_NAME = "Airflow Retrigger Delay"
var/airflow_delay_DESC = "Time in deciseconds before things can be moved by airflow again."
var/connection_insulation = 0.4
var/airflow_mob_slowdown = 1
var/airflow_mob_slowdown_NAME = "Airflow Slowdown"
var/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 = 1
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."
@@ -77,264 +73,263 @@ vs_control/var
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()
/vs_control/var/list/settings = list()
/vs_control/var/list/bitflags = list("1","2","4","8","16","32","64","128","256","512","1024")
/vs_control/var/pl_control/plc = new()
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)
/vs_control/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
for(var/V in settings)
if(findtextEx(V,"_RANDOM") || findtextEx(V,"_DESC") || findtextEx(V,"_METHOD"))
settings -= V
settings -= "settings"
settings -= "bitflags"
settings -= "plc"
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)
/vs_control/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/how = "Text"
var/display_description = ch
var/vw_desc = "No Description."
var/vw_name = 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"
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]_NAME" in vars)
display_description = vars["[ch]_NAME"]
if("[ch]_METHOD" in vars)
how = vars["[ch]_METHOD"]
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")
/vs_control/Topic(href,href_list)
if("changevar" in href_list)
ChangeSetting(usr,href_list["changevar"])
/vs_control/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
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
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
vars[ch] = vw
if(how == "Toggle")
newvar = (newvar?"ON":"OFF")
world << "\blue <b>[key_name(user)] changed the setting [display_description] to [newvar].</b>"
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
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")
world << "\blue <b>[key_name(user)] changed the setting [display_description] to [newvar].</b>"
if(ch in plc.settings)
ChangeSettingsDialog(user,plc.settings)
else
ChangeSettingsDialog(user,settings)
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
world << "\blue <b>[key_name(user)] changed the global plasma/ZAS settings to \"[def]\"</b>"
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)
/vs_control/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"]))
var/txt = vars["[V]_RANDOM"]
if(findtextEx(txt,"PROB"))
txt = text2list(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 = text2list(txt,",")
newvalue = pick(txt)
else
newvalue = roll(txt)
newvalue = roll(vars["[V]_RANDOM"])
else
newvalue = vars[V]
vars[V] = newvalue
V = newvalue
/vs_control/proc/ChangePlasma()
for(var/V in plc.settings)
plc.Randomize(V)
/vs_control/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_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_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_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_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
world << "\blue <b>[key_name(user)] changed the global plasma/ZAS settings to \"[def]\"</b>"
/pl_control/var/list/settings = list()
/pl_control/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"
/pl_control/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 = text2list(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 = text2list(txt,",")
newvalue = pick(txt)
else
newvalue = roll(txt)
else
newvalue = vars[V]
vars[V] = newvalue
+81 -100
View File
@@ -20,15 +20,6 @@
return GM
// For new turfs
/turf/proc/copy_air_from(var/turf/T)
oxygen = T.oxygen
carbon_dioxide = T.carbon_dioxide
nitrogen = T.nitrogen
toxins = T.toxins
temperature = T.temperature
/turf/remove_air(amount as num)
var/datum/gas_mixture/GM = new
@@ -45,11 +36,16 @@
return GM
/turf/simulated/var/current_graphic = null
/turf/simulated/var/tmp/datum/gas_mixture/air
/turf/simulated/var/tmp/processing = 1
/turf/simulated/var/tmp/air_check_directions = 0 //Do not modify this, just add turf to air_master.tiles_to_update
/turf/simulated/var/tmp/unsim_check_directions = 0 //See above.
/turf/simulated/var/tmp/obj/fire/active_hotspot
/turf/simulated/var/tmp/was_icy=0
/turf/simulated/proc/update_visuals()
overlays = null
@@ -57,9 +53,8 @@
var/siding_icon_state = return_siding_icon_state()
if(siding_icon_state)
overlays += image('icons/turf/floors.dmi',siding_icon_state)
// ONLY USED IF ZAS_SETTINGS SAYS SO.
var/datum/gas_mixture/model = return_air()
<<<<<<< HEAD
if(model.graphics & GRAPHICS_COLD)
if(!was_icy)
wet=3 // Custom ice
@@ -97,6 +92,47 @@
overlays.Add(slmaster)
//if(model.graphics & GRAPHICS_REAGENTS)
// overlays.Add(slmaster/*rlmaster*/)
=======
switch(model.graphic)
if(1)
overlays.Add(plmaster) //TODO: Make invisible plasma an option
if(2)
overlays.Add(slmaster)
if(3)
if(!was_icy)
wet=3 // Custom ice
was_icy=1
var/o=""
//if(is_plating())
// o="snowfloor_s"
//else
if(is_plasteel_floor())
o="snowfloor"
if(o!="")
overlays += image('icons/turf/overlays.dmi',o)
else
if(was_icy)
wet=0
was_icy=0
if(prob(10))
wet = 1
if(wet_overlay)
overlays -= wet_overlay
wet_overlay = null
wet_overlay = image('icons/effects/water.dmi',src,"wet_floor")
overlays += wet_overlay
spawn(800)
if (!istype(src)) return
if(wet >= 2) return
wet = 0
if(wet_overlay)
overlays -= wet_overlay
wet_overlay = null
>>>>>>> parent of 0227baa... Reverting ZAS back to /vg/ style
/turf/simulated/New()
@@ -133,16 +169,10 @@
air_master.tiles_to_update.Add(tile)
..()
/turf/simulated/copy_air_from(var/turf/T)
//if(istype(T,/turf/simulated))
// var/turf/simulated/ST=T
// air=ST.air
air=T.return_air()
/turf/simulated/assume_air(datum/gas_mixture/giver)
if(!giver) return 0
if(zone)
zone.air.merge(giver)
zone.assume_air(giver)
return 1
else
return ..()
@@ -158,11 +188,8 @@
/turf/simulated/remove_air(amount as num)
if(zone)
var/datum/gas_mixture/removed = null
removed = zone.air.remove(amount)
if(zone.air.check_tile_graphic())
update_visuals(zone.air)
return removed
return zone.remove_air(amount)
else if(air)
var/datum/gas_mixture/removed = null
removed = air.remove(amount)
@@ -178,14 +205,21 @@
var/air_directions_archived = air_check_directions
air_check_directions = 0
var/unsim_directions_archived = unsim_check_directions
unsim_check_directions = 0
for(var/direction in cardinal)
if(ZAirPass(get_step(src,direction)))
air_check_directions |= direction
var/turf/check_turf = get_step(src, direction)
if(ZAirPass(check_turf))
if(istype(check_turf, /turf/simulated))
air_check_directions |= direction
else if(istype(check_turf, /turf/space) || istype(check_turf, /turf/unsimulated))
unsim_check_directions |= direction
if(!zone && !blocks_air) //No zone, but not a wall.
for(var/direction in DoorDirections) //Check door directions first.
if(air_check_directions&direction)
var/turf/simulated/T = get_step(src,direction)
if(air_check_directions & direction)
var/turf/simulated/T = get_step(src, direction)
if(!istype(T))
continue
if(T.zone)
@@ -193,7 +227,7 @@
break
if(!zone) //Still no zone
for(var/direction in CounterDoorDirections) //Check the others second.
if(air_check_directions&direction)
if(air_check_directions & direction)
var/turf/simulated/T = get_step(src,direction)
if(!istype(T))
continue
@@ -206,84 +240,31 @@
new/zone(list(src))
//Check pass sanity of the connections.
if("\ref[src]" in air_master.turfs_with_connections)
for(var/connection/C in air_master.turfs_with_connections["\ref[src]"])
air_master.connections_to_check |= C
if(src in air_master.turfs_with_connections)
air_master.AddConnectionToCheck(air_master.turfs_with_connections[src])
if(zone && CanPass(null, src, 0, 0))
if(zone && !zone.rebuild)
if(zone.air.check_tile_graphic())
update_visuals(zone.air)
for(var/direction in cardinal)
var/turf/T = get_step(src,direction)
if(!istype(T))
continue
//I can connect to air in this direction
if(air_check_directions&direction)
//If either block air, we must look to see if the adjacent turfs need rebuilt.
if(!CanPass(null, T, 0, 0))
//Target blocks air
if(!T.CanPass(null, T, 0, 0))
var/turf/NT = get_step(T, direction)
//If that turf is in my zone still, rebuild.
if(istype(NT,/turf/simulated) && NT in zone.contents)
zone.rebuild = 1
//If that is an unsimulated tile in my zone, see if we need to rebuild or just remove.
else if(istype(NT) && NT in zone.unsimulated_tiles)
var/consider_rebuild = 0
for(var/d in cardinal)
var/turf/UT = get_step(NT,d)
if(istype(UT, /turf/simulated) && UT.zone == zone && UT.CanPass(null, NT, 0, 0)) //If we find a neighboring tile that is in the same zone, check if we need to rebuild
consider_rebuild = 1
break
if(consider_rebuild)
zone.rebuild = 1 //Gotta check if we need to rebuild, dammit
else
zone.RemoveTurf(NT) //Not adjacent to anything, and unsimulated. Goodbye~
//To make a closed connection through closed door.
ZConnect(T, src)
//If I block air.
else if(T.zone && !T.zone.rebuild)
var/turf/NT = get_step(src, reverse_direction(direction))
//If I am splitting a zone, rebuild.
if(istype(NT,/turf/simulated) && (NT in T.zone.contents || (NT.zone && T in NT.zone.contents)))
T.zone.rebuild = 1
//If NT is unsimulated, parse if I should remove it or rebuild.
else if(istype(NT) && NT in T.zone.unsimulated_tiles)
var/consider_rebuild = 0
for(var/d in cardinal)
var/turf/UT = get_step(NT,d)
if(istype(UT, /turf/simulated) && UT.zone == T.zone && UT.CanPass(null, NT, 0, 0)) //If we find a neighboring tile that is in the same zone, check if we need to rebuild
consider_rebuild = 1
break
//Needs rebuilt.
if(consider_rebuild)
T.zone.rebuild = 1
//Not adjacent to anything, and unsimulated. Goodbye~
else
T.zone.RemoveTurf(NT)
else
//Produce connection through open door.
ZConnect(src,T)
//I can connect to air or space in this direction
if((air_check_directions & direction && !(air_directions_archived & direction)) || \
(unsim_check_directions & direction && !(unsim_directions_archived & direction)))
ZConnect(src,T)
zone.ActivateIfNeeded()
if(T.zone) T.zone.ActivateIfNeeded()
//Something like a wall was built, changing the geometry.
else if(air_directions_archived&direction)
else if((!(air_check_directions & direction) && air_directions_archived & direction) || \
(!(unsim_check_directions & direction) && unsim_directions_archived & direction))
var/turf/NT = get_step(T, direction)
//If the tile is in our own zone, and we cannot connect to it, better rebuild.
if(istype(NT,/turf/simulated) && NT in zone.contents)
zone.rebuild = 1
air_master.zones_needing_rebuilt.Add(zone)
//Parse if we need to remove the tile, or rebuild the zone.
else if(istype(NT) && NT in zone.unsimulated_tiles)
@@ -301,7 +282,7 @@
//The unsimulated turf is adjacent to another one of our zone's turfs,
// better rebuild to be sure we didn't get cut in twain
if(consider_rebuild)
zone.rebuild = 1
air_master.zones_needing_rebuilt.Add(zone)
//Not adjacent to anything, and unsimulated. Goodbye~
else
@@ -340,13 +321,13 @@
return 0
for(var/obj/obstacle in src)
if(istype(obstacle, /obj/machinery/door) && !obstacle:air_properties_vary_with_direction)
if(istype(obstacle, /obj/machinery/door) && !(obstacle:air_properties_vary_with_direction))
continue
if(!obstacle.CanPass(null, T, 1.5, 1))
return 0
for(var/obj/obstacle in T)
if(istype(obstacle, /obj/machinery/door) && !obstacle:air_properties_vary_with_direction)
if(istype(obstacle, /obj/machinery/door) && !(obstacle:air_properties_vary_with_direction))
continue
if(!obstacle.CanPass(null, src, 1.5, 1))
return 0
@@ -362,13 +343,13 @@
return 0
for(var/obj/obstacle in src)
if(istype(obstacle, /obj/machinery/door) && !obstacle:air_properties_vary_with_direction)
if(istype(obstacle, /obj/machinery/door) && !(obstacle:air_properties_vary_with_direction))
continue
if(!obstacle.CanPass(null, T, 0, 0))
return 0
for(var/obj/obstacle in T)
if(istype(obstacle, /obj/machinery/door) && !obstacle:air_properties_vary_with_direction)
if(istype(obstacle, /obj/machinery/door) && !(obstacle:air_properties_vary_with_direction))
continue
if(!obstacle.CanPass(null, src, 0, 0))
return 0
+416 -128
View File
@@ -1,18 +1,30 @@
var/list/zones = list()
var/list/DoorDirections = list(NORTH,WEST) //Which directions doors turfs can connect to zones
var/list/CounterDoorDirections = list(SOUTH,EAST) //Which directions doors turfs can connect to zones
/zone
var/dbg_output = 0 //Enables debug output.
var/rebuild = 0 //If 1, zone will be rebuilt on next process. Not sure if used.
var/datum/gas_mixture/air //The air contents of the zone.
var/datum/gas_mixture/archived_air
var/list/contents //All the tiles that are contained in this zone.
var/list/connections // /connection objects which refer to connections with other zones, e.g. through a door.
var/list/connected_zones //Parallels connections, but lists zones to which this one is connected and the number
//of points they're connected at.
var/list/closed_connection_zones //Same as connected_zones, but for zones where the door or whatever is closed.
var/list/unsimulated_tiles // Any space tiles in this list will cause air to flow out.
var/datum/gas_mixture/air_unsim //Overall average of the air in connected unsimualted tiles.
var/unsim_air_needs_update = 0 //Set to 1 on geometry changes, marks air_unsim as needing update.
var/list/connections //connection objects which refer to connections with other zones, e.g. through a door.
var/list/direct_connections //connections which directly connect two zones.
var/list/connected_zones //Parallels connections, but lists zones to which this one is connected and the number
//of points they're connected at.
var/list/closed_connection_zones //Same as connected_zones, but for zones where the door or whatever is closed.
var/last_update = 0
var/last_rebuilt = 0
var/status = ZONE_ACTIVE
var/interactions_with_neighbors = 0
var/interactions_with_unsim = 0
var/progress = "nothing"
@@ -46,34 +58,42 @@ var/list/CounterDoorDirections = list(SOUTH,EAST) //Which directions doors turfs
air.update_values()
//Add this zone to the global list.
zones.Add(src)
if(air_master)
air_master.zones.Add(src)
air_master.active_zones.Add(src)
//LEGACY, DO NOT USE. Use the SoftDelete proc.
//DO NOT USE. Use the SoftDelete proc.
/zone/Del()
//Ensuring the zone list doesn't get clogged with null values.
for(var/turf/simulated/T in contents)
RemoveTurf(T)
air_master.tiles_to_reconsider_zones += T
air_master.ReconsiderTileZone(T)
for(var/zone/Z in connected_zones)
if(src in Z.connected_zones)
Z.connected_zones.Remove(src)
for(var/connection/C in connections)
air_master.connections_to_check += C
zones.Remove(src)
air_master.AddConnectionToCheck(connections)
if(air_master)
air_master.zones.Remove(src)
air_master.active_zones.Remove(src)
air_master.zones_needing_rebuilt.Remove(src)
air = null
. = ..()
//Handles deletion via garbage collection.
//Handles deletion via garbage collection.
/zone/proc/SoftDelete()
zones.Remove(src)
if(air_master)
air_master.zones.Remove(src)
air_master.active_zones.Remove(src)
air_master.zones_needing_rebuilt.Remove(src)
air = null
//Ensuring the zone list doesn't get clogged with null values.
for(var/turf/simulated/T in contents)
RemoveTurf(T)
air_master.tiles_to_reconsider_zones += T
air_master.ReconsiderTileZone(T)
//Removing zone connections and scheduling connection cleanup
for(var/zone/Z in connected_zones)
@@ -81,8 +101,7 @@ var/list/CounterDoorDirections = list(SOUTH,EAST) //Which directions doors turfs
Z.connected_zones.Remove(src)
connected_zones = null
for(var/connection/C in connections)
air_master.connections_to_check += C
air_master.AddConnectionToCheck(connections)
connections = null
return 1
@@ -99,7 +118,9 @@ var/list/CounterDoorDirections = list(SOUTH,EAST) //Which directions doors turfs
contents += T
if(air)
air.group_multiplier++
T.zone = src
else
if(!unsimulated_tiles)
unsimulated_tiles = list()
@@ -108,6 +129,8 @@ var/list/CounterDoorDirections = list(SOUTH,EAST) //Which directions doors turfs
unsimulated_tiles += T
contents -= T
unsim_air_needs_update = 1
/zone/proc/RemoveTurf(turf/T)
//Same, but in reverse.
if(istype(T, /turf/simulated))
@@ -116,13 +139,60 @@ var/list/CounterDoorDirections = list(SOUTH,EAST) //Which directions doors turfs
contents -= T
if(air)
air.group_multiplier--
if(T.zone == src)
T.zone = null
if(!contents.len)
SoftDelete()
else if(unsimulated_tiles)
unsimulated_tiles -= T
if(!unsimulated_tiles.len)
unsimulated_tiles = null
unsim_air_needs_update = 1
//Updates the air_unsim var
/zone/proc/UpdateUnsimAvg()
if(!unsimulated_tiles || !unsimulated_tiles.len) //if we don't have any unsimulated tiles, we can't do much.
return
if(!unsim_air_needs_update && air_unsim) //if air_unsim doesn't exist, we need to create it even if we don't need an update.
return
unsim_air_needs_update = 0
if(!air_unsim)
air_unsim = new /datum/gas_mixture
air_unsim.oxygen = 0
air_unsim.nitrogen = 0
air_unsim.carbon_dioxide = 0
air_unsim.toxins = 0
air_unsim.temperature = 0
var/correction_ratio = max(1, max(max(1, air.group_multiplier) + 3, 1) + unsimulated_tiles.len) / unsimulated_tiles.len
for(var/turf/T in unsimulated_tiles)
if(!istype(T, /turf/simulated))
air_unsim.oxygen += T.oxygen
air_unsim.carbon_dioxide += T.carbon_dioxide
air_unsim.nitrogen += T.nitrogen
air_unsim.toxins += T.toxins
air_unsim.temperature += T.temperature/unsimulated_tiles.len
//These values require adjustment in order to properly represent a room of the specified size.
air_unsim.oxygen *= correction_ratio
air_unsim.carbon_dioxide *= correction_ratio
air_unsim.nitrogen *= correction_ratio
air_unsim.toxins *= correction_ratio
air_unsim.group_multiplier = unsimulated_tiles.len
air_unsim.update_values()
return
//////////////
//PROCESSING//
//////////////
@@ -140,11 +210,6 @@ var/list/CounterDoorDirections = list(SOUTH,EAST) //Which directions doors turfs
progress = "problem with: Rebuild()"
//Does rebuilding stuff.
if(rebuild)
rebuild = 0
Rebuild() //Shoving this into a proc.
if(!contents.len) //If we got soft deleted.
return
@@ -162,15 +227,22 @@ var/list/CounterDoorDirections = list(SOUTH,EAST) //Which directions doors turfs
progress = "problem with: ShareSpace()"
if(unsim_air_needs_update)
unsim_air_needs_update = 0
UpdateUnsimAvg()
if(unsimulated_tiles)
if(locate(/turf/simulated) in unsimulated_tiles)
for(var/turf/simulated/T in unsimulated_tiles)
unsimulated_tiles -= T
if(unsimulated_tiles.len)
var/moved_air = ShareSpace(air,unsimulated_tiles)
var/moved_air = ShareSpace(air, air_unsim)
if(moved_air > zas_settings.Get(/datum/ZAS_Setting/airflow_lightest_pressure))
if(!air.compare(air_unsim))
interactions_with_unsim++
if(moved_air > vsc.airflow_lightest_pressure)
AirflowSpace(src)
else
unsimulated_tiles = null
@@ -178,8 +250,9 @@ var/list/CounterDoorDirections = list(SOUTH,EAST) //Which directions doors turfs
//Check the graphic.
progress = "problem with: modifying turf graphics"
air.graphics = 0
air.graphic = 0
if(air.toxins > MOLES_PLASMA_VISIBLE)
<<<<<<< HEAD
air.graphics |= GRAPHICS_PLASMA
if(air.trace_gases.len)
var/datum/gas/sleeping_agent = locate(/datum/gas/sleeping_agent) in air.trace_gases
@@ -189,17 +262,26 @@ var/list/CounterDoorDirections = list(SOUTH,EAST) //Which directions doors turfs
if(zas_settings.Get(/datum/ZAS_Setting/ice_formation))
if(air.temperature <= TEMPERATURE_ICE_FORMATION && air.return_pressure()>MIN_PRESSURE_ICE_FORMATION)
air.graphics |= GRAPHICS_COLD
=======
air.graphic = 1
if(air.trace_gases.len)
var/datum/gas/sleeping_agent = locate(/datum/gas/sleeping_agent) in air.trace_gases
if(sleeping_agent && (sleeping_agent.moles > 1))
air.graphic = 2
if(air.temperature <= TEMPERATURE_ICE_FORMATION && air.return_pressure()>MIN_PRESSURE_ICE_FORMATION)
air.graphic = 3
>>>>>>> parent of 0227baa... Reverting ZAS back to /vg/ style
progress = "problem with an inbuilt byond function: some conditional checks"
//Only run through the individual turfs if there's reason to.
if(air.graphics != air.graphics_archived || air.temperature > PLASMA_FLASHPOINT)
if(air.graphic != air.graphic_archived || air.temperature > PLASMA_FLASHPOINT)
progress = "problem with: turf/simulated/update_visuals()"
for(var/turf/simulated/S in contents)
//Update overlays.
if(air.graphics != air.graphics_archived)
if(air.graphic != air.graphic_archived)
if(S.HasDoor(1))
S.update_visuals()
else
@@ -216,7 +298,7 @@ var/list/CounterDoorDirections = list(SOUTH,EAST) //Which directions doors turfs
progress = "problem with: calculating air graphic"
//Archive graphic so we can know if it's different.
air.graphics_archived = air.graphics
air.graphic_archived = air.graphic
progress = "problem with: calculating air temp"
@@ -230,17 +312,13 @@ var/list/CounterDoorDirections = list(SOUTH,EAST) //Which directions doors turfs
progress = "problem with: ZMerge(), a couple of misc procs"
for(var/connection/C in connections)
//Check if the connection is valid first.
if(!C.Cleanup())
continue
if(length(direct_connections))
for(var/connection/C in direct_connections)
//Do merging if conditions are met. Specifically, if there's a non-door connection
//to somewhere with space, the zones are merged regardless of equilibrium, to speed
//up spacing in areas with double-plated windows.
if(C && C.A.zone && C.B.zone)
//indirect = 2 is a direct connection.
if( C.indirect == 2 )
//Do merging if conditions are met. Specifically, if there's a non-door connection
//to somewhere with space, the zones are merged regardless of equilibrium, to speed
//up spacing in areas with double-plated windows.
if(C.A.zone && C.B.zone)
if(C.A.zone.air.compare(C.B.zone.air) || unsimulated_tiles)
ZMerge(C.A.zone,C.B.zone)
@@ -252,11 +330,18 @@ var/list/CounterDoorDirections = list(SOUTH,EAST) //Which directions doors turfs
if(Z.last_update > last_update)
continue
//Handle adjacent zones that are sleeping
if(Z.status == ZONE_SLEEPING)
if(air.compare(Z.air))
continue
else
Z.SetStatus(ZONE_ACTIVE)
if(air && Z.air)
//Ensure we're not doing pointless calculations on equilibrium zones.
var/moles_delta = abs(air.total_moles() - Z.air.total_moles())
if(moles_delta > 0.1 || abs(air.temperature - Z.air.temperature) > 0.1)
if(abs(Z.air.return_pressure() - air.return_pressure()) > zas_settings.Get(/datum/ZAS_Setting/airflow_lightest_pressure))
if(!air.compare(Z.air))
if(abs(Z.air.return_pressure() - air.return_pressure()) > vsc.airflow_lightest_pressure)
Airflow(src,Z)
var/unsimulated_boost = 0
if(unsimulated_tiles)
@@ -266,16 +351,116 @@ var/list/CounterDoorDirections = list(SOUTH,EAST) //Which directions doors turfs
unsimulated_boost = max(0, min(3, unsimulated_boost))
ShareRatio( air , Z.air , connected_zones[Z] + unsimulated_boost)
Z.interactions_with_neighbors++
interactions_with_neighbors++
for(var/zone/Z in closed_connection_zones)
//If that zone has already processed, skip it.
if(Z.last_update > last_update)
continue
var/handle_temperature = abs(air.temperature - Z.air.temperature) > vsc.connection_temperature_delta
if(Z.status == ZONE_SLEEPING)
if (handle_temperature)
Z.SetStatus(ZONE_ACTIVE)
else
continue
if(air && Z.air)
if( abs(air.temperature - Z.air.temperature) > zas_settings.Get(/datum/ZAS_Setting/connection_temperature_delta) )
if( handle_temperature )
ShareHeat(air, Z.air, closed_connection_zones[Z])
Z.interactions_with_neighbors++
interactions_with_neighbors++
if(!interactions_with_neighbors && !interactions_with_unsim)
SetStatus(ZONE_SLEEPING)
interactions_with_neighbors = 0
interactions_with_unsim = 0
progress = "all components completed successfully, the problem is not here"
/zone/proc/SetStatus(var/new_status)
if(status == ZONE_SLEEPING && new_status == ZONE_ACTIVE)
air_master.active_zones.Add(src)
status = ZONE_ACTIVE
else if(status == ZONE_ACTIVE && new_status == ZONE_SLEEPING)
air_master.active_zones.Remove(src)
status = ZONE_SLEEPING
if(unsimulated_tiles && unsimulated_tiles.len)
UpdateUnsimAvg()
air.copy_from(air_unsim)
if(!archived_air)
archived_air = new
archived_air.copy_from(air)
/zone/proc/CheckStatus()
return status
/zone/proc/ActivateIfNeeded()
if(status == ZONE_ACTIVE) return
var/difference = 0
if(unsimulated_tiles && unsimulated_tiles.len)
UpdateUnsimAvg()
if(!air.compare(air_unsim))
difference = 1
if(!difference)
for(var/zone/Z in connected_zones) //Check adjacent zones for air difference.
if(!air.compare(Z.air))
difference = 1
break
if(difference) //We have a difference, activate the zone.
SetStatus(ZONE_ACTIVE)
return
/zone/proc/assume_air(var/datum/gas_mixture/giver)
if(status == ZONE_ACTIVE)
return air.merge(giver)
else
if(unsimulated_tiles && unsimulated_tiles.len)
UpdateUnsimAvg()
var/datum/gas_mixture/compare_air = new
compare_air.copy_from(giver)
compare_air.add(air_unsim)
compare_air.divide(air.group_multiplier)
if(air_unsim.compare(compare_air))
return 0
var/result = air.merge(giver)
if(!archived_air.compare(air))
SetStatus(ZONE_ACTIVE)
return result
/zone/proc/remove_air(var/amount)
if(status == ZONE_ACTIVE)
return air.remove(amount)
else
var/result = air.remove(amount)
if(!archived_air.compare(air))
SetStatus(ZONE_ACTIVE)
return result
////////////////
//Air Movement//
////////////////
@@ -337,6 +522,7 @@ proc/ShareRatio(datum/gas_mixture/A, datum/gas_mixture/B, connecting_tiles)
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
@@ -345,6 +531,15 @@ proc/ShareRatio(datum/gas_mixture/A, datum/gas_mixture/B, connecting_tiles)
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()
@@ -353,7 +548,7 @@ proc/ShareRatio(datum/gas_mixture/A, datum/gas_mixture/B, connecting_tiles)
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 || !unsimulated_tiles.len)
if(!unsimulated_tiles)
return 0
var
@@ -366,6 +561,22 @@ proc/ShareSpace(datum/gas_mixture/A, list/unsimulated_tiles, dbg_output)
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
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
@@ -373,21 +584,26 @@ proc/ShareSpace(datum/gas_mixture/A, list/unsimulated_tiles, dbg_output)
// 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)
correction_ratio = share_size / 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
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
unsim_heat_capacity = HEAT_CAPACITY_CALCULATION(unsim_oxygen,unsim_co2,unsim_nitrogen,unsim_plasma)
//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]
@@ -406,20 +622,20 @@ proc/ShareSpace(datum/gas_mixture/A, list/unsimulated_tiles, dbg_output)
co2_avg = (full_co2 + unsim_co2) / (size + share_size)
plasma_avg = (full_plasma + unsim_plasma) / (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 >= unsimulated_tiles.len) //6 or more interconnecting tiles will max at 42% of air moved per tick.
ratio = sharing_lookup_table[unsimulated_tiles.len]
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]
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 )
// EXPERIMENTAL: Disable space being cold
// N3X: Made this togglable for Pomf. Comment recovered from older code.
if(!zas_settings.Get(/datum/ZAS_Setting/space_isnt_cold))
A.temperature = max(TCMB, (A.temperature - temp_avg) * (1 - ratio) + temp_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)
@@ -449,7 +665,7 @@ proc/ShareHeat(datum/gas_mixture/A, datum/gas_mixture/B, connecting_tiles)
//WOOT WOOT TOUCH THIS AND YOU ARE A RETARD
//We need to adjust it to account for the insulation settings.
ratio *= 1 - zas_settings.Get(/datum/ZAS_Setting/connection_insulation)
ratio *= 1 - vsc.connection_insulation
A.temperature = max(0, (A.temperature - temp_avg) * (1- (ratio / max(1,A.group_multiplier)) ) + temp_avg )
B.temperature = max(0, (B.temperature - temp_avg) * (1- (ratio / max(1,B.group_multiplier)) ) + temp_avg )
@@ -458,72 +674,151 @@ proc/ShareHeat(datum/gas_mixture/A, datum/gas_mixture/B, connecting_tiles)
///////////////////
//Zone Rebuilding//
///////////////////
//Used for updating zone geometry when a zone is cut into two parts.
zone/proc/Rebuild()
if(last_rebuilt == air_master.current_cycle)
return
last_rebuilt = air_master.current_cycle
var/list/new_zone_contents = IsolateContents()
if(new_zone_contents.len == 1)
return
var/list/current_contents
var/list/new_zones = list()
contents = new_zone_contents[1]
air.group_multiplier = contents.len
for(var/identifier in 2 to new_zone_contents.len)
current_contents = new_zone_contents[identifier]
var/zone/new_zone = new (current_contents)
new_zone.air.copy_from(air)
new_zones += new_zone
for(var/connection/connection in connections)
connection.Cleanup()
var/turf/simulated/adjacent
for(var/turf/unsimulated in unsimulated_tiles)
for(var/direction in cardinal)
adjacent = get_step(unsimulated, direction)
if(istype(adjacent) && adjacent.CanPass(null, unsimulated, 0, 0))
for(var/zone/zone in new_zones)
if(adjacent in zone)
zone.AddTurf(unsimulated)
//Implements a two-pass connected component labeling algorithm to determine if the zone is, in fact, split.
/zone/proc/IsolateContents()
var/list/current_adjacents = list()
var/adjacent_id
var/lowest_id
var/list/identical_ids = list()
var/list/turfs = contents.Copy()
var/current_identifier = 1
for(var/turf/simulated/current in turfs)
lowest_id = null
current_adjacents = list()
for(var/direction in cardinal)
if( !(current.air_check_directions & direction))
continue
var/turf/simulated/adjacent = get_step(current, direction)
if(adjacent in turfs)
current_adjacents += adjacent
adjacent_id = turfs[adjacent]
if(adjacent_id && (!lowest_id || adjacent_id < lowest_id))
lowest_id = adjacent_id
if(!lowest_id)
lowest_id = current_identifier++
identical_ids += lowest_id
for(var/turf/simulated/adjacent in current_adjacents)
adjacent_id = turfs[adjacent]
if(adjacent_id != lowest_id)
if(adjacent_id)
identical_ids[adjacent_id] = lowest_id
turfs[adjacent] = lowest_id
turfs[current] = lowest_id
var/list/final_arrangement = list()
for(var/turf/simulated/current in turfs)
current_identifier = identical_ids[turfs[current]]
if( current_identifier > final_arrangement.len )
final_arrangement.len = current_identifier
final_arrangement[current_identifier] = list(current)
else
final_arrangement[current_identifier] += current
//lazy but fast
final_arrangement.Remove(null)
return final_arrangement
/*
if(!RequiresRebuild())
return
//Choose a random turf and regenerate the zone from it.
var
turf/simulated/sample = locate() in contents
list/new_contents
problem = 0
var/list/new_contents
var/list/new_unsimulated
//
var/list/turfs_to_consider = contents.Copy()
var/list/turfs_needing_zones = list()
while(!sample || !sample.CanPass(null, sample, 1.5, 1))
if(sample)
turfs_to_consider.Remove(sample)
sample = locate() in turfs_to_consider
if(!sample)
break
var/list/zones_to_check_connections = list(src)
if(!istype(sample) || !sample.CanPass(null, sample, 1.5, 1)) //Not a single valid turf.
for(var/turf/simulated/T in contents)
air_master.tiles_to_update |= T
if(!locate(/turf/simulated/floor) in contents)
for(var/turf/simulated/turf in contents)
air_master.ReconsiderTileZone(turf)
return SoftDelete()
new_contents = FloodFill(sample)
var/turfs_to_ignore = list()
if(direct_connections)
for(var/connection/connection in direct_connections)
if(connection.A.zone != src)
turfs_to_ignore += A
else if(connection.B.zone != src)
turfs_to_ignore += B
var/list/new_unsimulated = ( unsimulated_tiles ? unsimulated_tiles : list() )
new_unsimulated = ( unsimulated_tiles ? unsimulated_tiles : list() )
//Now, we have allocated the new turfs into proper lists, and we can start actually rebuilding.
//If something isn't carried over, it will need a new zone.
for(var/turf/T in contents)
if(!(T in new_contents))
RemoveTurf(T)
turfs_needing_zones += T
//Handle addition of new turfs
for(var/turf/S in new_contents)
if(!istype(S, /turf/simulated))
new_unsimulated |= S
new_contents.Remove(S)
if(contents.len != new_contents.len)
problem = 1
//If something new is added, we need to deal with it seperately.
else if(!(S in contents) && istype(S, /turf/simulated))
if(!(S.zone in zones_to_check_connections))
zones_to_check_connections += S.zone
//If something isn't carried over, there was a complication.
for(var/turf/T in contents)
if(!(T in new_contents))
T.zone = null
problem = 1
S.zone.RemoveTurf(S)
AddTurf(S)
if(problem)
//Build some new zones for stuff that wasn't included.
var/list/turf/simulated/rebuild_turfs = contents - new_contents
var/list/turf/simulated/reconsider_turfs = list()
contents = new_contents
for(var/turf/simulated/T in rebuild_turfs)
if(!T.zone && T.CanPass(null, T, 1.5, 1))
var/zone/Z = new /zone(T)
Z.air.copy_from(air)
else
reconsider_turfs |= T
for(var/turf/simulated/T in reconsider_turfs)
if(!T.zone && T.CanPass(null, T, 1.5, 1))
var/zone/Z = new /zone(T)
Z.air.copy_from(air)
else if(!T in air_master.tiles_to_update)
air_master.tiles_to_update.Add(T)
for(var/turf/simulated/T in contents)
if(T.zone && T.zone != src)
T.zone.RemoveTurf(T)
T.zone = src
else if(!T.zone)
T.zone = src
air.group_multiplier = contents.len
//Handle the addition of new unsimulated tiles.
unsimulated_tiles = null
if(new_unsimulated.len)
@@ -535,20 +830,13 @@ zone/proc/Rebuild()
if(istype(T) && T.zone && S.CanPass(null, T, 0, 0))
T.zone.AddTurf(S)
//UNUSED
/*
zone/proc/connected_zones()
//A legacy proc for getting connected zones.
. = list()
for(var/connection/C in connections)
var/zone/Z
if(C.A.zone == src)
Z = C.B.zone
else
Z = C.A.zone
//Finally, handle the orphaned turfs
for(var/turf/simulated/T in turfs_needing_zones)
if(!T.zone)
zones_to_check_connections += new /zone(T)
for(var/zone/zone in zones_to_check_connections)
for(var/connection/C in zone.connections)
C.Cleanup()*/
if(Z in .)
.[Z]++
else
. += Z
.[Z] = 1*/
+7 -1
View File
@@ -58,7 +58,8 @@ datum/controller/game_controller/proc/setup()
if(!air_master)
air_master = new /datum/controller/air_system()
air_master.setup()
// air_master.setup()
air_master.Setup()
if(!ticker)
ticker = new /datum/controller/gameticker()
@@ -129,7 +130,12 @@ datum/controller/game_controller/proc/process()
last_thing_processed = air_master.type
air_master.current_cycle++
<<<<<<< HEAD
if(!air_master.tick()) //Runtimed.
=======
// if(!air_master.tick()) Runtimed.
if(!air_master.Tick())
>>>>>>> parent of 0227baa... Reverting ZAS back to /vg/ style
air_master.failed_ticks++
if(air_master.failed_ticks > 5)
world << "<font color='red'><b>RUNTIMES IN ATMOS TICKER. Killing air simulation!</font></b>"
+2 -2
View File
@@ -93,8 +93,8 @@
/obj/machinery/door/proc/bumpopen(mob/user as mob)
if(operating) return
//if(user.last_airflow > world.time - vsc.airflow_delay) //Fakkit
if(user.last_airflow > world.time - zas_settings.Get("airflow_delay")) //Fakkit
if(user.last_airflow > world.time - vsc.airflow_delay) //Fakkit
// if(user.last_airflow > world.time - zas_settings.Get("airflow_delay")) //Fakkit
return
src.add_fingerprint(user)
if(!src.requiresID())
+16 -1
View File
@@ -573,7 +573,7 @@ var/list/admin_verbs_mod = list(
for (var/mob/V in hearers(mob.control_object))
V.show_message("<b>[mob.control_object.name]</b> says: \"" + msg + "\"", 2)
feedback_add_details("admin_verb","OT") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/*
/client/proc/kill_air() // -- TLE
set category = "Debug"
set name = "Kill Air"
@@ -587,6 +587,21 @@ var/list/admin_verbs_mod = list(
feedback_add_details("admin_verb","KA") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
log_admin("[key_name(usr)] used 'kill air'.")
message_admins("\blue [key_name_admin(usr)] used 'kill air'.", 1)
*/
/client/proc/kill_air() // -- TLE
set category = "Debug"
set name = "Kill Air"
set desc = "Toggle Air Processing"
if(air_processing_killed)
air_processing_killed = 0
usr << "<b>Enabled air processing.</b>"
else
air_processing_killed = 1
usr << "<b>Disabled air processing.</b>"
feedback_add_details("admin_verb","KA") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
log_admin("[key_name(usr)] used 'kill air'.")
message_admins("\blue [key_name_admin(usr)] used 'kill air'.", 1)
/client/proc/deadmin_self()
set name = "De-admin self"
+5 -5
View File
@@ -2526,13 +2526,13 @@
else if(href_list["vsc"])
if(check_rights(R_ADMIN|R_SERVER))
if(href_list["vsc"] == "airflow")
/* vsc.ChangeSettingsDialog(usr,vsc.settings)
vsc.ChangeSettingsDialog(usr,vsc.settings)
if(href_list["vsc"] == "plasma")
vsc.ChangeSettingsDialog(usr,vsc.plc.settings) */
zas_settings.ChangeSettingsDialog(usr,zas_settings.settings)
vsc.ChangeSettingsDialog(usr,vsc.plc.settings)
// zas_settings.ChangeSettingsDialog(usr,zas_settings.settings)
if(href_list["vsc"] == "default")
//vsc.SetDefault(usr)
zas_settings.SetDefault(usr)
vsc.SetDefault(usr)
// zas_settings.SetDefault(usr)
// player info stuff
if(href_list["add_player_info"])
+2 -2
View File
@@ -876,8 +876,8 @@
var/total_plasmaloss = 0
for(var/obj/item/I in src)
if(I.contaminated)
//total_plasmaloss += vsc.plc.CONTAMINATION_LOSS
total_plasmaloss += zas_settings.Get("CONTAMINATION_LOSS")
total_plasmaloss += vsc.plc.CONTAMINATION_LOSS
// total_plasmaloss += zas_settings.Get("CONTAMINATION_LOSS")
if(status_flags & GODMODE) return 0 //godmode
adjustToxLoss(total_plasmaloss)
+4
View File
@@ -764,3 +764,7 @@ var/list/RESTRICTED_CAMERA_NETWORKS = list( //Those networks can only be accesse
#define MISSING_PROGRAM 8 // Some files try to automatically launch a program. This is that failing.
#define FILE_DRM 16 // Some files want to not be copied/moved. This is them complaining that you tried.
#define NETWORK_FAILURE 32
//Flags for zone sleeping
#define ZONE_ACTIVE 1
#define ZONE_SLEEPING 0