diff --git a/README.md b/README.md
index 661c7de6fde..67e5156428c 100644
--- a/README.md
+++ b/README.md
@@ -11,7 +11,7 @@ Click [here](https://github.com/Baystation12/Baystation12/archive/master.zip) to
The more complicated and easier to update method is using git. You'll need to download git or some client from [here](http://git-scm.com/). When that's installed, right click in any folder and click on "Git Bash". When that opens, type in:
- git clone git@github.com:Baystation12/Baystation12.git
+ git clone https://github.com/Baystation12/Baystation12.git
(hint: hold down ctrl and press insert to paste into git bash)
diff --git a/baystation12.dme b/baystation12.dme
index 802413560a2..9348f106ce0 100644
--- a/baystation12.dme
+++ b/baystation12.dme
@@ -216,8 +216,6 @@
#include "code\game\gamemodes\setupgame.dm"
#include "code\game\gamemodes\autotraitor\autotraitor.dm"
#include "code\game\gamemodes\blob\blob.dm"
-#include "code\game\gamemodes\blob\blob_finish.dm"
-#include "code\game\gamemodes\blob\blob_report.dm"
#include "code\game\gamemodes\blob\theblob.dm"
#include "code\game\gamemodes\blob\blobs\core.dm"
#include "code\game\gamemodes\blob\blobs\factory.dm"
@@ -248,6 +246,7 @@
#include "code\game\gamemodes\events\holidays\Holidays.dm"
#include "code\game\gamemodes\events\holidays\Other.dm"
#include "code\game\gamemodes\extended\extended.dm"
+#include "code\game\gamemodes\heist\heist.dm"
#include "code\game\gamemodes\malfunction\Malf_Modules.dm"
#include "code\game\gamemodes\malfunction\malfunction.dm"
#include "code\game\gamemodes\meteor\meteor.dm"
@@ -313,6 +312,7 @@
#include "code\game\machinery\newscaster.dm"
#include "code\game\machinery\OpTable.dm"
#include "code\game\machinery\overview.dm"
+#include "code\game\machinery\podmen.dm"
#include "code\game\machinery\portable_turret.dm"
#include "code\game\machinery\recharger.dm"
#include "code\game\machinery\rechargestation.dm"
@@ -375,10 +375,12 @@
#include "code\game\machinery\computer\robot.dm"
#include "code\game\machinery\computer\security.dm"
#include "code\game\machinery\computer\shuttle.dm"
+#include "code\game\machinery\computer\skills.dm"
#include "code\game\machinery\computer\specops_shuttle.dm"
#include "code\game\machinery\computer\station_alert.dm"
#include "code\game\machinery\computer\syndicate_shuttle.dm"
#include "code\game\machinery\computer\syndicate_specops_shuttle.dm"
+#include "code\game\machinery\computer\vox_shuttle.dm"
#include "code\game\machinery\doors\airlock.dm"
#include "code\game\machinery\doors\airlock_electronics.dm"
#include "code\game\machinery\doors\alarmlock.dm"
@@ -486,6 +488,7 @@
#include "code\game\objects\items\devices\lightreplacer.dm"
#include "code\game\objects\items\devices\multitool.dm"
#include "code\game\objects\items\devices\paicard.dm"
+#include "code\game\objects\items\devices\pipe_painter.dm"
#include "code\game\objects\items\devices\powersink.dm"
#include "code\game\objects\items\devices\scanners.dm"
#include "code\game\objects\items\devices\taperecorder.dm"
@@ -846,6 +849,7 @@
#include "code\modules\mob\death.dm"
#include "code\modules\mob\emote.dm"
#include "code\modules\mob\inventory.dm"
+#include "code\modules\mob\language.dm"
#include "code\modules\mob\login.dm"
#include "code\modules\mob\logout.dm"
#include "code\modules\mob\mob.dm"
@@ -876,6 +880,7 @@
#include "code\modules\mob\living\carbon\carbon_defines.dm"
#include "code\modules\mob\living\carbon\give.dm"
#include "code\modules\mob\living\carbon\shock.dm"
+#include "code\modules\mob\living\carbon\species.dm"
#include "code\modules\mob\living\carbon\alien\alien.dm"
#include "code\modules\mob\living\carbon\alien\death.dm"
#include "code\modules\mob\living\carbon\alien\login.dm"
@@ -1321,7 +1326,6 @@
#include "code\WorkInProgress\Cael_Aislinn\Supermatter\ZeroPointLaser.dm"
#include "code\WorkInProgress\Chinsky\ashtray.dm"
#include "code\WorkInProgress\Cib\MedicalSideEffects.dm"
-#include "code\WorkInProgress\kilakk\responseteam.dm"
#include "code\WorkInProgress\Mini\ATM.dm"
#include "code\WorkInProgress\Mini\atmos_control.dm"
#include "code\WorkInProgress\Ported\policetape.dm"
diff --git a/code/ATMOSPHERICS/pipes.dm b/code/ATMOSPHERICS/pipes.dm
index c9e763e8390..5baffbcb615 100644
--- a/code/ATMOSPHERICS/pipes.dm
+++ b/code/ATMOSPHERICS/pipes.dm
@@ -527,7 +527,7 @@ obj/machinery/atmospherics/pipe
var/build_killswitch = 1
var/obj/machinery/atmospherics/node1
- New()
+ New()
initialize_directions = dir
..()
@@ -722,7 +722,7 @@ obj/machinery/atmospherics/pipe
icon_state = "manifold_[connected]_[unconnected]"
- if(!connected)
+ if(!connected)
del(src)
return
@@ -951,7 +951,7 @@ obj/machinery/atmospherics/pipe
return
initialize()
-
+
for(var/obj/machinery/atmospherics/target in get_step(src,1))
if(target.initialize_directions & 2)
node1 = target
@@ -1028,7 +1028,7 @@ obj/machinery/atmospherics/pipe
manifold4w/general/hidden
level = 1
icon_state = "manifold4w-f"
-
+
cap
name = "pipe endcap"
desc = "An endcap for pipes"
@@ -1117,28 +1117,9 @@ obj/machinery/atmospherics/pipe/attackby(var/obj/item/weapon/W as obj, var/mob/u
if (istype(src, /obj/machinery/atmospherics/pipe/vent))
return ..()
- // ===== Handle paints =====
- if(istype(W, /obj/item/weapon/reagent_containers/glass/paint/red))
- src.color = "red"
- user << "\red You paint the pipe red."
- update_icon()
+ if(istype(W,/obj/item/device/pipe_painter))
return 1
- if(istype(W, /obj/item/weapon/reagent_containers/glass/paint/blue))
- src.color = "blue"
- user << "\red You paint the pipe blue."
- update_icon()
- return 1
- if(istype(W, /obj/item/weapon/reagent_containers/glass/paint/green))
- src.color = "green"
- user << "\red You paint the pipe green."
- update_icon()
- return 1
- if(istype(W, /obj/item/weapon/reagent_containers/glass/paint/yellow))
- src.color = "yellow"
- user << "\red You paint the pipe yellow."
- update_icon()
- return 1
-
+
if (!istype(W, /obj/item/weapon/wrench))
return ..()
var/turf/T = src.loc
diff --git a/code/WorkInProgress/Cael_Aislinn/Economy/EFTPOS.dm b/code/WorkInProgress/Cael_Aislinn/Economy/EFTPOS.dm
index f3160a3f8a5..7a00499be4f 100644
--- a/code/WorkInProgress/Cael_Aislinn/Economy/EFTPOS.dm
+++ b/code/WorkInProgress/Cael_Aislinn/Economy/EFTPOS.dm
@@ -70,7 +70,7 @@
D.name = "small parcel - 'EFTPOS access code'"
/obj/item/device/eftpos/proc/reconnect_database()
- for(var/obj/machinery/account_database/DB in machines)
+ for(var/obj/machinery/account_database/DB in world) //Hotfix until someone finds out why it isn't in 'machines'
if(DB.z == src.z)
linked_db = DB
break
diff --git a/code/WorkInProgress/Mini/ATM.dm b/code/WorkInProgress/Mini/ATM.dm
index a7c0544591b..97b056a2ca6 100644
--- a/code/WorkInProgress/Mini/ATM.dm
+++ b/code/WorkInProgress/Mini/ATM.dm
@@ -70,7 +70,7 @@ log transactions
break
/obj/machinery/atm/proc/reconnect_database()
- for(var/obj/machinery/account_database/DB in machines)
+ for(var/obj/machinery/account_database/DB in world) //Hotfix until someone finds out why it isn't in 'machines'
if( DB.z == src.z && !(DB.stat & NOPOWER) && DB.activated )
linked_db = DB
break
diff --git a/code/WorkInProgress/kilakk/responseteam.dm b/code/WorkInProgress/kilakk/responseteam.dm
index bf237d60420..6faafad342f 100644
--- a/code/WorkInProgress/kilakk/responseteam.dm
+++ b/code/WorkInProgress/kilakk/responseteam.dm
@@ -119,6 +119,7 @@ var/global/admin_emergency_team = 0 // Used for admin-spawned response teams
break
spawn(0)
+
switch(alert(new_member, "You are an Emergency Response Team member! Are you a boy or a girl?",,"Male","Female"))
if("Male")
new_member.gender = MALE
@@ -130,9 +131,12 @@ var/global/admin_emergency_team = 0 // Used for admin-spawned response teams
if(!new_name)
new_member.real_name = "Agent [pick("Red","Yellow","Orange","Silver","Gold", "Pink", "Purple", "Rainbow")]" // Choose a "random" agent name
new_member.name = usr.real_name
+ new_member.mind.name = usr.real_name
+
else
new_member.real_name = new_name
new_member.name = new_name
+ new_member.mind.name = new_name
// -- CHANGE APPEARANCE --
var/new_tone = input(new_member, "Please select your new skin tone: 1-220 (1=albino, 35=caucasian, 150=black, 220='very' black)", "Character Generation") as num
@@ -179,9 +183,10 @@ var/global/admin_emergency_team = 0 // Used for admin-spawned response teams
new_member.update_hair(1)
new_member.mind_initialize()
+
new_member.mind.assigned_role = "Emergency Response Team"
new_member.mind.special_role = "Emergency Response Team"
- ticker.mode.traitors += new_member.mind // ERTs will show up at the end of the round on the "traitor" list
+ ticker.mode.traitors |= new_member.mind // ERTs will show up at the end of the round on the "traitor" list
// Join message
new_member << "\blue You are the Emergency Response Team[!leader_selected?"!":" Leader!"] \nAs a response team [!leader_selected?"member":"leader"] you answer directly to [!leader_selected?"your team leader.":"Central Command."] \nYou have been deployed by NanoTrasen Central Command in Tau Ceti to resolve a Code Red alert aboard [station_name()], and have been provided with the following instructions and information regarding your mission: \red [situation]"
@@ -223,7 +228,7 @@ var/global/admin_emergency_team = 0 // Used for admin-spawned response teams
// Put stuff into their backpacks
equip_to_slot_or_del(new /obj/item/weapon/storage/box/engineer(src), slot_in_backpack)
- equip_to_slot_or_del(new /obj/item/weapon/storage/firstaid(src), slot_in_backpack) // Not sure about this
+ // equip_to_slot_or_del(new /obj/item/weapon/storage/firstaid/regular(src), slot_in_backpack) // Regular medkit
// Loyalty implants
var/obj/item/weapon/implant/loyalty/L = new/obj/item/weapon/implant/loyalty(src)
@@ -245,5 +250,7 @@ var/global/admin_emergency_team = 0 // Used for admin-spawned response teams
E.registered_name = real_name
equip_to_slot_or_del(E, slot_wear_id)
+ update_icons()
+
return 1
diff --git a/code/ZAS/Airflow.dm b/code/ZAS/Airflow.dm
index a2506bb2d92..894dc92c72b 100644
--- a/code/ZAS/Airflow.dm
+++ b/code/ZAS/Airflow.dm
@@ -225,142 +225,142 @@ 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(!airflow_dest) return
- if(airflow_speed < 0) return
- if(last_airflow > world.time - vsc.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(!airflow_dest) return
+ if(airflow_speed < 0) return
+ if(last_airflow > world.time - vsc.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 -= vsc.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 -= vsc.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 + vsc.airflow_mob_slowdown
- airflow_dest = null
- airflow_speed = 0
- airflow_time = 0
- if(od)
- density = 0
-
-
- proc/RepelAirflowDest(n)
- if(!airflow_dest) return
- if(airflow_speed < 0) return
- if(last_airflow > world.time - vsc.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(src:shoes.type == /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 -= vsc.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 + vsc.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 + vsc.airflow_mob_slowdown
+ airflow_dest = null
+ airflow_speed = 0
+ airflow_time = 0
+ if(od)
+ density = 0
+
+
+/atom/movable/proc/RepelAirflowDest(n)
+ if(!airflow_dest) return
+ if(airflow_speed < 0) return
+ if(last_airflow > world.time - vsc.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 -= vsc.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 + vsc.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
diff --git a/code/ZAS/Connection.dm b/code/ZAS/Connection.dm
index f9697207c60..8a919d50435 100644
--- a/code/ZAS/Connection.dm
+++ b/code/ZAS/Connection.dm
@@ -6,393 +6,396 @@ Indirect connections will not merge the two zones after they reach equilibrium.
#define CONNECTION_INDIRECT 1
#define CONNECTION_CLOSED 0
+/connection
+ var/turf/simulated/A
+ var/turf/simulated/B
-connection
- var
- turf/simulated //The turfs involved in the connection.
- A
- B
- zone
- zone_A
- zone_B
- ref_A
- ref_B
- indirect = CONNECTION_DIRECT //If the connection is purely indirect, the zones should not join.
- last_updated //The tick at which this was last updated.
- no_zone_count = 0
+ 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
- New(turf/T,turf/O)
- A = T
- B = O
- if(A.zone && B.zone)
- 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()
- B.zone.connections += src
- zone_B = B.zone
- ref_B = "\ref[B]"
+/connection/New(turf/T,turf/O)
+ A = T
+ B = O
+ if(A.zone && B.zone)
+ if(!A.zone.connections) A.zone.connections = list()
+ A.zone.connections += src
+ zone_A = A.zone
+ ref_A = "\ref[A]"
- if(ref_A in air_master.turfs_with_connections)
- var/list/connections = air_master.turfs_with_connections[ref_A]
- connections.Add(src)
- else
- air_master.turfs_with_connections[ref_A] = list(src)
-
- if(ref_B in air_master.turfs_with_connections)
- var/list/connections = air_master.turfs_with_connections[ref_B]
- connections.Add(src)
- else
- air_master.turfs_with_connections[ref_B] = list(src)
-
- if(A.CanPass(null, B, 0, 0))
-
- ConnectZones(A.zone, B.zone, 1)
-
- if(A.HasDoor(B) || B.HasDoor(A))
- indirect = CONNECTION_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)
-
-
- 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]
- connections.Remove(src)
+ 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]
- connections.Remove(src)
+ connections.Add(src)
+ else
+ air_master.turfs_with_connections[ref_A] = list(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(ref_B in air_master.turfs_with_connections)
+ var/list/connections = air_master.turfs_with_connections[ref_B]
+ connections.Add(src)
+ else
+ air_master.turfs_with_connections[ref_B] = list(src)
- if(istype(zone_A) && (!A || A.zone != zone_A))
+ if(A.CanPass(null, B, 0, 0))
+
+ ConnectZones(A.zone, B.zone, 1)
+
+ if(A.HasDoor(B) || B.HasDoor(A))
+ indirect = CONNECTION_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)
+
+
+/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]
+ connections.Remove(src)
+
+ if(ref_A in air_master.turfs_with_connections)
+ var/list/connections = air_master.turfs_with_connections[ref_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
+ if(A && A.zone && B && B.zone)
+ DisconnectZones(A.zone, B.zone)
+
+ //Finally, preform actual deletion.
+ . = ..()
+
+
+/connection/proc/ConnectZones(var/zone/zone_1, var/zone/zone_2, open = 0)
+
+ //Sanity checking
+ if(!istype(zone_1) || !istype(zone_2))
+ return
+
+ //Handle zones connecting indirectly/directly.
+ if(open)
+
+ //Create the lists if necessary.
+ if(!zone_1.connected_zones)
+ zone_1.connected_zones = list()
+
+ if(!zone_2.connected_zones)
+ zone_2.connected_zones = list()
+
+ //Increase the number of connections between zones.
+ if(zone_2 in zone_1.connected_zones)
+ zone_1.connected_zones[zone_2]++
+ else
+ zone_1.connected_zones += zone_2
+ zone_1.connected_zones[zone_2] = 1
+
+ if(zone_1 in zone_2.connected_zones)
+ zone_2.connected_zones[zone_1]++
+ else
+ zone_2.connected_zones += zone_1
+ zone_2.connected_zones[zone_1] = 1
+
+ //Handle closed connections.
+ else
+
+ //Create the lists
+ if(!zone_1.closed_connection_zones)
+ zone_1.closed_connection_zones = list()
+
+ if(!zone_2.closed_connection_zones)
+ zone_2.closed_connection_zones = list()
+
+ //Increment the connections.
+ if(zone_2 in zone_1.closed_connection_zones)
+ zone_1.closed_connection_zones[zone_2]++
+ else
+ zone_1.closed_connection_zones += zone_2
+ zone_1.closed_connection_zones[zone_2] = 1
+
+ if(zone_1 in zone_2.closed_connection_zones)
+ zone_2.closed_connection_zones[zone_1]++
+ else
+ zone_2.closed_connection_zones += zone_1
+ zone_2.closed_connection_zones[zone_1] = 1
+
+
+/connection/proc/DisconnectZones(var/zone/zone_1, var/zone/zone_2)
+ //Sanity checking
+ if(!istype(zone_1) || !istype(zone_2))
+ return
+
+ if(indirect != CONNECTION_CLOSED)
+ //Handle disconnection of indirectly or directly connected zones.
+ if( (zone_1 in zone_2.connected_zones) || (zone_2 in zone_1.connected_zones) )
+
+ //If there are more than one connection, decrement the number of connections
+ //Otherwise, remove all connections between the zones.
+ if(zone_2 in zone_1.connected_zones)
+ if(zone_1.connected_zones[zone_2] > 1)
+ zone_1.connected_zones[zone_2]--
+ else
+ zone_1.connected_zones -= zone_2
+ //remove the list if it is empty
+ if(!zone_1.connected_zones.len)
+ zone_1.connected_zones = null
+
+ //Then do the same for the other zone.
+ if(zone_1 in zone_2.connected_zones)
+ if(zone_2.connected_zones[zone_1] > 1)
+ zone_2.connected_zones[zone_1]--
+ else
+ zone_2.connected_zones -= zone_1
+ if(!zone_2.connected_zones.len)
+ zone_2.connected_zones = null
+
+ else
+ //Handle disconnection of closed zones.
+ if( (zone_1 in zone_2.closed_connection_zones) || (zone_2 in zone_1.closed_connection_zones) )
+
+ //If there are more than one connection, decrement the number of connections
+ //Otherwise, remove all connections between the zones.
+ if(zone_2 in zone_1.closed_connection_zones)
+ if(zone_1.closed_connection_zones[zone_2] > 1)
+ zone_1.closed_connection_zones[zone_2]--
+ else
+ zone_1.closed_connection_zones -= zone_2
+ //remove the list if it is empty
+ if(!zone_1.closed_connection_zones.len)
+ zone_1.closed_connection_zones = null
+
+ //Then do the same for the other zone.
+ if(zone_1 in zone_2.closed_connection_zones)
+ if(zone_2.closed_connection_zones[zone_1] > 1)
+ zone_2.closed_connection_zones[zone_1]--
+ else
+ zone_2.closed_connection_zones -= zone_1
+ if(!zone_2.closed_connection_zones.len)
+ zone_2.closed_connection_zones = null
+
+
+/connection/proc/Cleanup()
+
+ //Check sanity: existance of turfs
+ if(!A || !B)
+ del src
+
+ //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
+
+ //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...
+ if(A.ZAirPass(B))
+ //...we check to see if there is a door in the way...
+ var/door_pass = A.CanPass(null,B,1.5,1)
+ //...and if it is opened.
+ if(door_pass || A.CanPass(null,B,0,0))
+
+ //Make and remove connections to let air pass.
+ if(indirect == CONNECTION_CLOSED)
+ DisconnectZones(A.zone, B.zone)
+ ConnectZones(A.zone, B.zone, 1)
+
+ if(door_pass)
+ indirect = CONNECTION_DIRECT
+ else if(!door_pass)
+ indirect = CONNECTION_INDIRECT
+
+ //The door is instead closed.
+ else if(indirect > CONNECTION_CLOSED)
+ DisconnectZones(A.zone, B.zone)
+ indirect = CONNECTION_CLOSED
+ ConnectZones(A.zone, B.zone)
+
+ //If I can no longer pass air, better delete
+ else
+ del src
+
+/connection/proc/Sanitize()
+ //If the zones change on connected turfs, update it.
+
+ //Both zones changed (wat)
+ if(A.zone && A.zone != zone_A && B.zone && B.zone != zone_B)
+
+ //If the zones have gotten swapped
+ // (do not ask me how, I am just being anal retentive about sanity)
+ if(A.zone == zone_B && B.zone == zone_A)
+ var/turf/temp = B
+ B = A
+ 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.
+ if(zone_A && zone_A.connections)
+ zone_A.connections.Remove(src)
+ if(!zone_A.connections.len)
+ zone_A.connections = null
+
+ if(zone_B && zone_B.connections)
+ zone_B.connections.Remove(src)
+ if(!zone_B.connections.len)
+ zone_B.connections = null
+
+ if(A.zone)
+ if(!A.zone.connections)
+ A.zone.connections = list()
+ A.zone.connections |= src
+
+ if(B.zone)
+ if(!B.zone.connections)
+ B.zone.connections = list()
+ B.zone.connections |= src
+
+ //If either zone is null, we disconnect the archived ones after cleaning up the connections.
+ if(!A.zone || !B.zone)
+ if(zone_A && zone_B)
+ DisconnectZones(zone_B, zone_A)
+
+ if(!A.zone)
+ zone_A = A.zone
+
+ if(!B.zone)
+ zone_B = B.zone
+ return
+
+ //Handle diconnection and reconnection of zones.
+ if(zone_A && zone_B)
+ DisconnectZones(zone_A, zone_B)
+ ConnectZones(A.zone, B.zone, indirect)
+
+ //resetting values of archived values.
+ zone_B = B.zone
+ zone_A = A.zone
+
+ //The "A" zone changed.
+ else if(A.zone && A.zone != zone_A)
+
+ //Handle connection cleanup
+ if(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(A.zone)
+ if(!A.zone.connections)
+ A.zone.connections = list()
+ A.zone.connections |= src
- if(istype(zone_B) && (!B || B.zone != zone_B))
+ //If the "A" zone is null, we disconnect the archived ones after cleaning up the connections.
+ if(!A.zone)
+ if(zone_A && zone_B)
+ DisconnectZones(zone_A, zone_B)
+ zone_A = A.zone
+ return
+
+ //Handle diconnection and reconnection of zones.
+ if(zone_A && zone_B)
+ DisconnectZones(zone_A, zone_B)
+ ConnectZones(A.zone, B.zone, indirect)
+ zone_A = A.zone
+
+ //The "B" zone changed.
+ else if(B.zone && B.zone != zone_B)
+
+ //Handle connection cleanup
+ if(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
- if(A && A.zone && B && B.zone)
- DisconnectZones(A.zone, B.zone)
+ if(B.zone)
+ if(!B.zone.connections)
+ B.zone.connections = list()
+ B.zone.connections |= src
- //Finally, preform actual deletion.
- . = ..()
-
-
- proc/ConnectZones(var/zone/zone_1, var/zone/zone_2, open = 0)
-
- //Sanity checking
- if(!istype(zone_1) || !istype(zone_2))
- return
-
- //Handle zones connecting indirectly/directly.
- if(open)
-
- //Create the lists if necessary.
- if(!zone_1.connected_zones)
- zone_1.connected_zones = list()
-
- if(!zone_2.connected_zones)
- zone_2.connected_zones = list()
-
- //Increase the number of connections between zones.
- if(zone_2 in zone_1.connected_zones)
- zone_1.connected_zones[zone_2]++
- else
- zone_1.connected_zones += zone_2
- zone_1.connected_zones[zone_2] = 1
-
- if(zone_1 in zone_2.connected_zones)
- zone_2.connected_zones[zone_1]++
- else
- zone_2.connected_zones += zone_1
- zone_2.connected_zones[zone_1] = 1
-
- //Handle closed connections.
- else
-
- //Create the lists
- if(!zone_1.closed_connection_zones)
- zone_1.closed_connection_zones = list()
-
- if(!zone_2.closed_connection_zones)
- zone_2.closed_connection_zones = list()
-
- //Increment the connections.
- if(zone_2 in zone_1.closed_connection_zones)
- zone_1.closed_connection_zones[zone_2]++
- else
- zone_1.closed_connection_zones += zone_2
- zone_1.closed_connection_zones[zone_2] = 1
-
- if(zone_1 in zone_2.closed_connection_zones)
- zone_2.closed_connection_zones[zone_1]++
- else
- zone_2.closed_connection_zones += zone_1
- zone_2.closed_connection_zones[zone_1] = 1
-
-
- proc/DisconnectZones(var/zone/zone_1, var/zone/zone_2)
-
- //Sanity checking
- if(!istype(zone_1) || !istype(zone_2))
- return
-
- if(indirect != CONNECTION_CLOSED)
- //Handle disconnection of indirectly or directly connected zones.
- if( (zone_1 in zone_2.connected_zones) || (zone_2 in zone_1.connected_zones) )
-
- //If there are more than one connection, decrement the number of connections
- //Otherwise, remove all connections between the zones.
- if(zone_2 in zone_1.connected_zones)
- if(zone_1.connected_zones[zone_2] > 1)
- zone_1.connected_zones[zone_2]--
- else
- zone_1.connected_zones -= zone_2
- //remove the list if it is empty
- if(!zone_1.connected_zones.len)
- zone_1.connected_zones = null
-
- //Then do the same for the other zone.
- if(zone_1 in zone_2.connected_zones)
- if(zone_2.connected_zones[zone_1] > 1)
- zone_2.connected_zones[zone_1]--
- else
- zone_2.connected_zones -= zone_1
- if(!zone_2.connected_zones.len)
- zone_2.connected_zones = null
-
- else
- //Handle disconnection of closed zones.
- if( (zone_1 in zone_2.closed_connection_zones) || (zone_2 in zone_1.closed_connection_zones) )
-
- //If there are more than one connection, decrement the number of connections
- //Otherwise, remove all connections between the zones.
- if(zone_2 in zone_1.closed_connection_zones)
- if(zone_1.closed_connection_zones[zone_2] > 1)
- zone_1.closed_connection_zones[zone_2]--
- else
- zone_1.closed_connection_zones -= zone_2
- //remove the list if it is empty
- if(!zone_1.closed_connection_zones.len)
- zone_1.closed_connection_zones = null
-
- //Then do the same for the other zone.
- if(zone_1 in zone_2.closed_connection_zones)
- if(zone_2.closed_connection_zones[zone_1] > 1)
- zone_2.closed_connection_zones[zone_1]--
- else
- zone_2.closed_connection_zones -= zone_1
- if(!zone_2.closed_connection_zones.len)
- zone_2.closed_connection_zones = null
-
-
- proc/Cleanup()
-
- //Check sanity: existance of turfs
- if(!A || !B)
- del src
-
- //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
-
- //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
-
-
- proc/CheckPassSanity()
- //Sanity check, first.
- Cleanup()
-
- if(A.zone && B.zone)
-
- //If no walls are blocking us...
- if(A.ZAirPass(B))
- //...we check to see if there is a door in the way...
- var/door_pass = A.CanPass(null,B,1.5,1)
- //...and if it is opened.
- if(door_pass || A.CanPass(null,B,0,0))
-
- //Make and remove connections to let air pass.
- if(indirect == CONNECTION_CLOSED)
- DisconnectZones(A.zone, B.zone)
- ConnectZones(A.zone, B.zone, 1)
-
- if(door_pass)
- indirect = CONNECTION_DIRECT
- else if(!door_pass)
- indirect = CONNECTION_INDIRECT
-
- //The door is instead closed.
- else if(indirect > CONNECTION_CLOSED)
- DisconnectZones(A.zone, B.zone)
- indirect = CONNECTION_CLOSED
- ConnectZones(A.zone, B.zone)
-
- //If I can no longer pass air, better delete
- else
- del src
-
- proc/Sanitize()
- //If the zones change on connected turfs, update it.
-
- //Both zones changed (wat)
- if(A.zone && A.zone != zone_A && B.zone && B.zone != zone_B)
-
- //If the zones have gotten swapped
- // (do not ask me how, I am just being anal retentive about sanity)
- if(A.zone == zone_B && B.zone == zone_A)
- var/turf/temp = B
- B = A
- 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.
- if(zone_A && zone_A.connections)
- zone_A.connections.Remove(src)
- if(!zone_A.connections.len)
- zone_A.connections = null
-
- if(zone_B && zone_B.connections)
- zone_B.connections.Remove(src)
- if(!zone_B.connections.len)
- zone_B.connections = null
-
- if(A.zone)
- if(!A.zone.connections)
- A.zone.connections = list()
- A.zone.connections |= src
-
- if(B.zone)
- if(!B.zone.connections)
- B.zone.connections = list()
- B.zone.connections |= src
-
- //If either zone is null, we disconnect the archived ones after cleaning up the connections.
- if(!A.zone || !B.zone)
- if(zone_A && zone_B)
- DisconnectZones(zone_B, zone_A)
-
- if(!A.zone)
- zone_A = A.zone
-
- if(!B.zone)
- zone_B = B.zone
- return
-
- //Handle diconnection and reconnection of zones.
+ //If the "B" zone is null, we disconnect the archived ones after cleaning up the connections.
+ if(!B.zone)
if(zone_A && zone_B)
DisconnectZones(zone_A, zone_B)
- ConnectZones(A.zone, B.zone, indirect)
-
- //resetting values of archived values.
zone_B = B.zone
- zone_A = A.zone
+ return
- //The "A" zone changed.
- else if(A.zone && A.zone != zone_A)
-
- //Handle connection cleanup
- if(zone_A)
- if(zone_A.connections)
- zone_A.connections.Remove(src)
- if(!zone_A.connections.len)
- zone_A.connections = null
-
- if(A.zone)
- if(!A.zone.connections)
- A.zone.connections = list()
- A.zone.connections |= src
-
- //If the "A" zone is null, we disconnect the archived ones after cleaning up the connections.
- if(!A.zone)
- if(zone_A && zone_B)
- DisconnectZones(zone_A, zone_B)
- zone_A = A.zone
- return
-
- //Handle diconnection and reconnection of zones.
- if(zone_A && zone_B)
- DisconnectZones(zone_A, zone_B)
- ConnectZones(A.zone, B.zone, indirect)
-
- //The "B" zone changed.
- else if(B.zone && B.zone != zone_B)
-
- //Handle connection cleanup
- if(zone_B)
- if(zone_B.connections)
- zone_B.connections.Remove(src)
- if(!zone_B.connections.len)
- zone_B.connections = null
-
- if(B.zone)
- if(!B.zone.connections)
- B.zone.connections = list()
- B.zone.connections |= src
-
- //If the "B" zone is null, we disconnect the archived ones after cleaning up the connections.
- if(!B.zone)
- if(zone_A && zone_B)
- DisconnectZones(zone_A, zone_B)
- zone_B = B.zone
- return
-
- //Handle diconnection and reconnection of zones.
- if(zone_A && zone_B)
- DisconnectZones(zone_A, zone_B)
- ConnectZones(A.zone, B.zone, indirect)
+ //Handle diconnection and reconnection of zones.
+ if(zone_A && zone_B)
+ DisconnectZones(zone_A, zone_B)
+ ConnectZones(A.zone, B.zone, indirect)
+ zone_B = B.zone
#undef CONNECTION_DIRECT
diff --git a/code/ZAS/Debug.dm b/code/ZAS/Debug.dm
index b3f069a5540..807208a5a3e 100644
--- a/code/ZAS/Debug.dm
+++ b/code/ZAS/Debug.dm
@@ -8,7 +8,8 @@ client/proc/Zone_Info(turf/T as null|turf)
mob << "No zone here."
else
if(zone_debug_images)
- images -= zone_debug_images
+ for(var/zone in zone_debug_images)
+ images -= zone_debug_images[zone]
zone_debug_images = null
client/var/list/zone_debug_images
@@ -23,12 +24,12 @@ client/proc/Test_ZAS_Connection(var/turf/simulated/T as turf)
"South" = SOUTH,\
"East" = EAST,\
"West" = WEST,\
- "None" = null)
+ "N/A" = null)
var/direction = input("What direction do you wish to test?","Set direction") as null|anything in direction_list
if(!direction)
return
- if(direction == "None")
+ if(direction == "N/A")
if(T.CanPass(null, T, 0,0))
mob << "The turf can pass air! :D"
else
@@ -55,61 +56,67 @@ client/proc/Test_ZAS_Connection(var/turf/simulated/T as turf)
mob << "Both turfs can connect! :)"
-zone/proc
- DebugDisplay(client/client)
- if(!istype(client))
- return
+zone/proc/DebugDisplay(client/client)
+ if(!istype(client))
+ return
- if(!dbg_output)
- dbg_output = 1 //Don't want to be spammed when someone investigates a zone...
+ if(!dbg_output)
+ dbg_output = 1 //Don't want to be spammed when someone investigates a zone...
- if(!client.zone_debug_images)
- client.zone_debug_images = list()
- for(var/turf/T in contents)
- client.zone_debug_images += image('debug_group.dmi', T)
+ if(!client.zone_debug_images)
+ client.zone_debug_images = list()
- for(var/turf/space/S in unsimulated_tiles)
- client.zone_debug_images += image('debug_space.dmi', S)
+ var/list/current_zone_images = list()
- client << "Zone Air Contents"
- client << "Oxygen: [air.oxygen]"
- client << "Nitrogen: [air.nitrogen]"
- client << "Plasma: [air.toxins]"
- client << "Carbon Dioxide: [air.carbon_dioxide]"
- client << "Temperature: [air.temperature] K"
- client << "Heat Energy: [air.temperature * air.heat_capacity()] J"
- client << "Pressure: [air.return_pressure()] KPa"
- client << ""
- client << "Space Tiles: [length(unsimulated_tiles)]"
- client << "Movable Objects: [length(movables())]"
- client << "Connections: [length(connections)]"
+ for(var/turf/T in contents)
+ current_zone_images += image('debug_group.dmi', T, null, TURF_LAYER)
- for(var/connection/C in connections)
- client << "\ref[C] [C.A] --> [C.B] [(C.indirect?"Open":"Closed")]"
- client.zone_debug_images += image('debug_connect.dmi', C.A)
- client.zone_debug_images += image('debug_connect.dmi', C.B)
+ for(var/turf/space/S in unsimulated_tiles)
+ current_zone_images += image('debug_space.dmi', S, null, TURF_LAYER)
- client << "Connected Zones:"
- for(var/zone/zone in connected_zones)
- client << "\ref[zone] [zone] - [connected_zones[zone]] (Connected)"
+ client << "Zone Air Contents"
+ client << "Oxygen: [air.oxygen]"
+ client << "Nitrogen: [air.nitrogen]"
+ client << "Plasma: [air.toxins]"
+ client << "Carbon Dioxide: [air.carbon_dioxide]"
+ client << "Temperature: [air.temperature] K"
+ client << "Heat Energy: [air.temperature * air.heat_capacity()] J"
+ client << "Pressure: [air.return_pressure()] KPa"
+ client << ""
+ client << "Space Tiles: [length(unsimulated_tiles)]"
+ client << "Movable Objects: [length(movables())]"
+ client << "Connections: [length(connections)]"
- for(var/zone/zone in closed_connection_zones)
- client << "\ref[zone] [zone] - [closed_connection_zones[zone]] (Unconnected)"
+ for(var/connection/C in connections)
+ client << "\ref[C] [C.A] --> [C.B] [(C.indirect?"Open":"Closed")]"
+ current_zone_images += image('debug_connect.dmi', C.A, null, TURF_LAYER)
+ current_zone_images += image('debug_connect.dmi', C.B, null, TURF_LAYER)
- for(var/C in connections)
- if(!istype(C,/connection))
- client << "[C] (Not Connection!)"
+ client << "Connected Zones:"
+ for(var/zone/zone in connected_zones)
+ client << "\ref[zone] [zone] - [connected_zones[zone]] (Connected)"
- client.images += client.zone_debug_images
+ for(var/zone/zone in closed_connection_zones)
+ client << "\ref[zone] [zone] - [closed_connection_zones[zone]] (Unconnected)"
- else
- dbg_output = 0
+ for(var/C in connections)
+ if(!istype(C,/connection))
+ client << "[C] (Not Connection!)"
- client.images -= client.zone_debug_images
- client.zone_debug_images = null
+ if(!client.zone_debug_images)
+ client.zone_debug_images = list()
+ client.zone_debug_images[src] = current_zone_images
- 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]"
+ client.images += client.zone_debug_images[src]
+
+ else
+ dbg_output = 0
+
+ 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]"
diff --git a/code/ZAS/FEA_gas_mixture.dm b/code/ZAS/FEA_gas_mixture.dm
index a4104ab01c7..8b7ab992c93 100644
--- a/code/ZAS/FEA_gas_mixture.dm
+++ b/code/ZAS/FEA_gas_mixture.dm
@@ -14,141 +14,135 @@ What are the archived variables for?
#define QUANTIZE(variable) (round(variable,0.0001))
#define TRANSFER_FRACTION 5 //What fraction (1/#) of the air difference to try and transfer
-datum
- gas //These are used for the "Trace Gases" stuff, but is buggy.
- sleeping_agent
- specific_heat = 40
+/datum/gas/sleeping_agent/specific_heat = 40 //These are used for the "Trace Gases" stuff, but is buggy.
- oxygen_agent_b
- specific_heat = 300
+/datum/gas/oxygen_agent_b/specific_heat = 300
- volatile_fuel
- specific_heat = 30
+/datum/gas/volatile_fuel/specific_heat = 30
- var
- moles = 0
- specific_heat = 0
+/datum/gas
+ var/moles = 0
- moles_archived = 0
+ var/specific_heat = 0
- gas_mixture
- var //Holds the "moles" of each of the four gases.
- oxygen = 0
- carbon_dioxide = 0
- nitrogen = 0
- toxins = 0
- total_moles = 0 //Updated when a reaction occurs.
+ var/moles_archived = 0
- volume = CELL_VOLUME
+/datum/gas_mixture/
+ var/oxygen = 0 //Holds the "moles" of each of the four gases.
+ var/carbon_dioxide = 0
+ var/nitrogen = 0
+ var/toxins = 0
- temperature = 0 //in Kelvin, use calculate_temperature() to modify
+ var/total_moles = 0 //Updated when a reaction occurs.
- group_multiplier = 1
+ var/volume = CELL_VOLUME
+
+ var/temperature = 0 //in Kelvin, use calculate_temperature() to modify
+
+ var/group_multiplier = 1
//Size of the group this gas_mixture is representing.
//=1 for singletons
- graphic
+ var/graphic
- list/datum/gas/trace_gases = list() //Seemed to be a good idea that was abandoned
+ var/list/datum/gas/trace_gases = list() //Seemed to be a good idea that was abandoned
- tmp //These are variables for use with the archived data
- oxygen_archived
- carbon_dioxide_archived
- nitrogen_archived
- toxins_archived
+ var/tmp/oxygen_archived //These are variables for use with the archived data
+ var/tmp/carbon_dioxide_archived
+ var/tmp/nitrogen_archived
+ var/tmp/toxins_archived
- temperature_archived
+ var/tmp/temperature_archived
- graphic_archived = 0
- fuel_burnt = 0
+ var/tmp/graphic_archived = 0
+ var/tmp/fuel_burnt = 0
//FOR THE LOVE OF GOD PLEASE USE THIS PROC
//Call it with negative numbers to remove gases.
- proc/adjust(o2 = 0, co2 = 0, n2 = 0, tx = 0, list/datum/gas/traces = list())
- //Purpose: Adjusting the gases within a airmix
- //Called by: Nothing, yet!
- //Inputs: The values of the gases to adjust
- //Outputs: null
+/datum/gas_mixture/proc/adjust(o2 = 0, co2 = 0, n2 = 0, tx = 0, list/datum/gas/traces = list())
+ //Purpose: Adjusting the gases within a airmix
+ //Called by: Nothing, yet!
+ //Inputs: The values of the gases to adjust
+ //Outputs: null
- oxygen = max(0, oxygen + o2)
- carbon_dioxide = max(0, carbon_dioxide + co2)
- nitrogen = max(0, nitrogen + n2)
- toxins = max(0, toxins + tx)
+ oxygen = max(0, oxygen + o2)
+ carbon_dioxide = max(0, carbon_dioxide + co2)
+ nitrogen = max(0, nitrogen + n2)
+ toxins = max(0, toxins + tx)
- //handle trace gasses
- for(var/datum/gas/G in traces)
- var/datum/gas/T = locate(G.type) in trace_gases
- if(T)
- T.moles = max(G.moles + T.moles, 0)
- else if(G.moles > 0)
- trace_gases |= G
- update_values()
- return
+ //handle trace gasses
+ for(var/datum/gas/G in traces)
+ var/datum/gas/T = locate(G.type) in trace_gases
+ if(T)
+ T.moles = max(G.moles + T.moles, 0)
+ else if(G.moles > 0)
+ trace_gases |= G
+ update_values()
+ return
//tg seems to like using these a lot
- proc/return_temperature()
- return temperature
+/datum/gas_mixture/proc/return_temperature()
+ return temperature
- proc/return_volume()
- return max(0, volume)
+/datum/gas_mixture/proc/return_volume()
+ return max(0, volume)
- proc/thermal_energy()
- return temperature*heat_capacity()
+/datum/gas_mixture/proc/thermal_energy()
+ return temperature*heat_capacity()
///////////////////////////////
//PV=nRT - related procedures//
///////////////////////////////
+/datum/gas_mixture/proc/heat_capacity()
+ //Purpose: Returning the heat capacity of the gas mix
+ //Called by: UNKNOWN
+ //Inputs: None
+ //Outputs: Heat capacity
- proc/heat_capacity()
- //Purpose: Returning the heat capacity of the gas mix
- //Called by: UNKNOWN
- //Inputs: None
- //Outputs: Heat capacity
+ var/heat_capacity = HEAT_CAPACITY_CALCULATION(oxygen,carbon_dioxide,nitrogen,toxins)
- var/heat_capacity = HEAT_CAPACITY_CALCULATION(oxygen,carbon_dioxide,nitrogen,toxins)
+ if(trace_gases.len)
+ for(var/datum/gas/trace_gas in trace_gases)
+ heat_capacity += trace_gas.moles*trace_gas.specific_heat
- if(trace_gases.len)
- for(var/datum/gas/trace_gas in trace_gases)
- heat_capacity += trace_gas.moles*trace_gas.specific_heat
+ return max(MINIMUM_HEAT_CAPACITY,heat_capacity)
- return max(MINIMUM_HEAT_CAPACITY,heat_capacity)
+/datum/gas_mixture/proc/heat_capacity_archived()
+ //Purpose: Returning the archived heat capacity of the gas mix
+ //Called by: UNKNOWN
+ //Inputs: None
+ //Outputs: Archived heat capacity
- proc/heat_capacity_archived()
- //Purpose: Returning the archived heat capacity of the gas mix
- //Called by: UNKNOWN
- //Inputs: None
- //Outputs: Archived heat capacity
+ var/heat_capacity_archived = HEAT_CAPACITY_CALCULATION(oxygen_archived,carbon_dioxide_archived,nitrogen_archived,toxins_archived)
- var/heat_capacity_archived = HEAT_CAPACITY_CALCULATION(oxygen_archived,carbon_dioxide_archived,nitrogen_archived,toxins_archived)
+ if(trace_gases.len)
+ for(var/datum/gas/trace_gas in trace_gases)
+ heat_capacity_archived += trace_gas.moles_archived*trace_gas.specific_heat
- if(trace_gases.len)
- for(var/datum/gas/trace_gas in trace_gases)
- heat_capacity_archived += trace_gas.moles_archived*trace_gas.specific_heat
+ return max(MINIMUM_HEAT_CAPACITY,heat_capacity_archived)
- return max(MINIMUM_HEAT_CAPACITY,heat_capacity_archived)
+/datum/gas_mixture/proc/total_moles()
+ return total_moles
+ /*var/moles = oxygen + carbon_dioxide + nitrogen + toxins
- proc/total_moles()
- return total_moles
- /*var/moles = oxygen + carbon_dioxide + nitrogen + toxins
+ if(trace_gases.len)
+ for(var/datum/gas/trace_gas in trace_gases)
+ moles += trace_gas.moles
+ return moles*/
- if(trace_gases.len)
- for(var/datum/gas/trace_gas in trace_gases)
- moles += trace_gas.moles
- return moles*/
+/datum/gas_mixture/proc/return_pressure()
+ //Purpose: Calculating Current Pressure
+ //Called by:
+ //Inputs: None
+ //Outputs: Gas pressure.
- proc/return_pressure()
- //Purpose: Calculating Current Pressure
- //Called by:
- //Inputs: None
- //Outputs: Gas pressure.
-
- if(volume>0)
- return total_moles()*R_IDEAL_GAS_EQUATION*temperature/volume
- return 0
+ if(volume>0)
+ return total_moles()*R_IDEAL_GAS_EQUATION*temperature/volume
+ return 0
// proc/return_temperature()
//Purpose:
@@ -171,868 +165,865 @@ datum
// return temperature*heat_capacity()
- proc/update_values()
- //Purpose: Calculating and storing values which were normally called CONSTANTLY
- //Called by: Anything that changes values within a gas mix.
- //Inputs: None
- //Outputs: None
+/datum/gas_mixture/proc/update_values()
+ //Purpose: Calculating and storing values which were normally called CONSTANTLY
+ //Called by: Anything that changes values within a gas mix.
+ //Inputs: None
+ //Outputs: None
- total_moles = oxygen + carbon_dioxide + nitrogen + toxins
+ total_moles = oxygen + carbon_dioxide + nitrogen + toxins
- if(trace_gases.len)
- for(var/datum/gas/trace_gas in trace_gases)
- total_moles += trace_gas.moles
+ if(trace_gases.len)
+ for(var/datum/gas/trace_gas in trace_gases)
+ total_moles += trace_gas.moles
- return
+ return
////////////////////////////////////////////
//Procedures used for very specific events//
////////////////////////////////////////////
+/datum/gas_mixture/proc/check_tile_graphic()
+ //Purpose: Calculating the graphic for a tile
+ //Called by: Turfs updating
+ //Inputs: None
+ //Outputs: 1 if graphic changed, 0 if unchanged
- proc/check_tile_graphic()
- //Purpose: Calculating the graphic for a tile
- //Called by: Turfs updating
- //Inputs: None
- //Outputs: 1 if graphic changed, 0 if unchanged
-
+ graphic = 0
+ if(toxins > MOLES_PLASMA_VISIBLE)
+ 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))
+ graphic = 2
+ else
graphic = 0
- if(toxins > MOLES_PLASMA_VISIBLE)
- 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))
- graphic = 2
- else
- graphic = 0
- return graphic != graphic_archived
+ return graphic != graphic_archived
- proc/react(atom/dump_location)
- //Purpose: Calculating if it is possible for a fire to occur in the airmix
- //Called by: Air mixes updating?
- //Inputs: None
- //Outputs: If a fire occured
+/datum/gas_mixture/proc/react(atom/dump_location)
+ //Purpose: Calculating if it is possible for a fire to occur in the airmix
+ //Called by: Air mixes updating?
+ //Inputs: None
+ //Outputs: If a fire occured
- var/reacting = 0 //set to 1 if a notable reaction occured (used by pipe_network)
+ var/reacting = 0 //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
+ if(temperature > FIRE_MINIMUM_TEMPERATURE_TO_EXIST)
+ if(zburn(null) > 0)
+ reacting = 1
- return reacting
+ return reacting
- proc/fire()
- //Purpose: Calculating any fire reactions.
- //Called by: react() (See above)
- //Inputs: None
- //Outputs: How much fuel burned
+/datum/gas_mixture/proc/fire()
+ //Purpose: Calculating any fire reactions.
+ //Called by: react() (See above)
+ //Inputs: None
+ //Outputs: How much fuel burned
- return zburn(null)
+ return zburn(null)
- /*var/energy_released = 0
- var/old_heat_capacity = heat_capacity()
+ /*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
- if(fuel_store) //General volatile gas burn
- var/burned_fuel = 0
+ var/datum/gas/volatile_fuel/fuel_store = locate(/datum/gas/volatile_fuel) in trace_gases
+ if(fuel_store) //General volatile gas burn
+ var/burned_fuel = 0
- if(oxygen < fuel_store.moles)
- burned_fuel = oxygen
- fuel_store.moles -= burned_fuel
- oxygen = 0
- else
- burned_fuel = fuel_store.moles
- oxygen -= fuel_store.moles
- del(fuel_store)
+ if(oxygen < fuel_store.moles)
+ burned_fuel = oxygen
+ fuel_store.moles -= burned_fuel
+ oxygen = 0
+ else
+ burned_fuel = fuel_store.moles
+ oxygen -= fuel_store.moles
+ del(fuel_store)
- energy_released += FIRE_CARBON_ENERGY_RELEASED * burned_fuel
- carbon_dioxide += burned_fuel
- fuel_burnt += burned_fuel
+ energy_released += FIRE_CARBON_ENERGY_RELEASED * burned_fuel
+ carbon_dioxide += burned_fuel
+ fuel_burnt += burned_fuel
- //Handle plasma burning
- if(toxins > MINIMUM_HEAT_CAPACITY)
- var/plasma_burn_rate = 0
- var/oxygen_burn_rate = 0
- //more plasma released at higher temperatures
- var/temperature_scale
- if(temperature > PLASMA_UPPER_TEMPERATURE)
- temperature_scale = 1
- else
- temperature_scale = (temperature-PLASMA_MINIMUM_BURN_TEMPERATURE)/(PLASMA_UPPER_TEMPERATURE-PLASMA_MINIMUM_BURN_TEMPERATURE)
- if(temperature_scale > 0)
- oxygen_burn_rate = 1.4 - temperature_scale
- if(oxygen > toxins*PLASMA_OXYGEN_FULLBURN)
- plasma_burn_rate = (toxins*temperature_scale)/4
- else
- plasma_burn_rate = (temperature_scale*(oxygen/PLASMA_OXYGEN_FULLBURN))/4
- if(plasma_burn_rate > MINIMUM_HEAT_CAPACITY)
- toxins -= plasma_burn_rate
- oxygen -= plasma_burn_rate*oxygen_burn_rate
- carbon_dioxide += plasma_burn_rate
+ //Handle plasma burning
+ if(toxins > MINIMUM_HEAT_CAPACITY)
+ var/plasma_burn_rate = 0
+ var/oxygen_burn_rate = 0
+ //more plasma released at higher temperatures
+ var/temperature_scale
+ if(temperature > PLASMA_UPPER_TEMPERATURE)
+ temperature_scale = 1
+ else
+ temperature_scale = (temperature-PLASMA_MINIMUM_BURN_TEMPERATURE)/(PLASMA_UPPER_TEMPERATURE-PLASMA_MINIMUM_BURN_TEMPERATURE)
+ if(temperature_scale > 0)
+ oxygen_burn_rate = 1.4 - temperature_scale
+ if(oxygen > toxins*PLASMA_OXYGEN_FULLBURN)
+ plasma_burn_rate = (toxins*temperature_scale)/4
+ else
+ plasma_burn_rate = (temperature_scale*(oxygen/PLASMA_OXYGEN_FULLBURN))/4
+ if(plasma_burn_rate > MINIMUM_HEAT_CAPACITY)
+ toxins -= plasma_burn_rate
+ oxygen -= plasma_burn_rate*oxygen_burn_rate
+ carbon_dioxide += plasma_burn_rate
- energy_released += FIRE_PLASMA_ENERGY_RELEASED * (plasma_burn_rate)
+ energy_released += FIRE_PLASMA_ENERGY_RELEASED * (plasma_burn_rate)
- fuel_burnt += (plasma_burn_rate)*(1+oxygen_burn_rate)
+ fuel_burnt += (plasma_burn_rate)*(1+oxygen_burn_rate)
- if(energy_released > 0)
- var/new_heat_capacity = heat_capacity()
- if(new_heat_capacity > MINIMUM_HEAT_CAPACITY)
- temperature = (temperature*old_heat_capacity + energy_released)/new_heat_capacity
- update_values()
+ if(energy_released > 0)
+ var/new_heat_capacity = heat_capacity()
+ if(new_heat_capacity > MINIMUM_HEAT_CAPACITY)
+ temperature = (temperature*old_heat_capacity + energy_released)/new_heat_capacity
+ update_values()
- return fuel_burnt*/
+ return fuel_burnt*/
//////////////////////////////////////////////
//Procs for general gas spread calculations.//
//////////////////////////////////////////////
- proc/archive()
- //Purpose: Archives the current gas values
- //Called by: UNKNOWN
- //Inputs: None
- //Outputs: 1
+/datum/gas_mixture/proc/archive()
+ //Purpose: Archives the current gas values
+ //Called by: UNKNOWN
+ //Inputs: None
+ //Outputs: 1
- oxygen_archived = oxygen
- carbon_dioxide_archived = carbon_dioxide
- nitrogen_archived = nitrogen
- toxins_archived = toxins
+ oxygen_archived = oxygen
+ carbon_dioxide_archived = carbon_dioxide
+ nitrogen_archived = nitrogen
+ toxins_archived = toxins
- if(trace_gases.len)
- for(var/datum/gas/trace_gas in trace_gases)
- trace_gas.moles_archived = trace_gas.moles
+ if(trace_gases.len)
+ for(var/datum/gas/trace_gas in trace_gases)
+ trace_gas.moles_archived = trace_gas.moles
- temperature_archived = temperature
+ temperature_archived = temperature
- graphic_archived = graphic
+ graphic_archived = graphic
- return 1
+ return 1
- proc/check_then_merge(datum/gas_mixture/giver)
- //Purpose: Similar to merge(...) but first checks to see if the amount of air assumed is small enough
- // that group processing is still accurate for source (aborts if not)
- //Called by: airgroups/machinery expelling air, ?
- //Inputs: The gas to try and merge
- //Outputs: 1 on successful merge. 0 otherwise.
+/datum/gas_mixture/proc/check_then_merge(datum/gas_mixture/giver)
+ //Purpose: Similar to merge(...) but first checks to see if the amount of air assumed is small enough
+ // that group processing is still accurate for source (aborts if not)
+ //Called by: airgroups/machinery expelling air, ?
+ //Inputs: The gas to try and merge
+ //Outputs: 1 on successful merge. 0 otherwise.
- if(!giver)
- return 0
- if(((giver.oxygen > MINIMUM_AIR_TO_SUSPEND) && (giver.oxygen >= oxygen*MINIMUM_AIR_RATIO_TO_SUSPEND)) \
- || ((giver.carbon_dioxide > MINIMUM_AIR_TO_SUSPEND) && (giver.carbon_dioxide >= carbon_dioxide*MINIMUM_AIR_RATIO_TO_SUSPEND)) \
- || ((giver.nitrogen > MINIMUM_AIR_TO_SUSPEND) && (giver.nitrogen >= nitrogen*MINIMUM_AIR_RATIO_TO_SUSPEND)) \
- || ((giver.toxins > MINIMUM_AIR_TO_SUSPEND) && (giver.toxins >= toxins*MINIMUM_AIR_RATIO_TO_SUSPEND)))
- return 0
- if(abs(giver.temperature - temperature) > MINIMUM_TEMPERATURE_DELTA_TO_SUSPEND)
+ if(!giver)
+ return 0
+ if(((giver.oxygen > MINIMUM_AIR_TO_SUSPEND) && (giver.oxygen >= oxygen*MINIMUM_AIR_RATIO_TO_SUSPEND)) \
+ || ((giver.carbon_dioxide > MINIMUM_AIR_TO_SUSPEND) && (giver.carbon_dioxide >= carbon_dioxide*MINIMUM_AIR_RATIO_TO_SUSPEND)) \
+ || ((giver.nitrogen > MINIMUM_AIR_TO_SUSPEND) && (giver.nitrogen >= nitrogen*MINIMUM_AIR_RATIO_TO_SUSPEND)) \
+ || ((giver.toxins > MINIMUM_AIR_TO_SUSPEND) && (giver.toxins >= toxins*MINIMUM_AIR_RATIO_TO_SUSPEND)))
+ return 0
+ if(abs(giver.temperature - temperature) > MINIMUM_TEMPERATURE_DELTA_TO_SUSPEND)
+ return 0
+
+ if(giver.trace_gases.len)
+ for(var/datum/gas/trace_gas in giver.trace_gases)
+ var/datum/gas/corresponding = locate(trace_gas.type) in trace_gases
+ if((trace_gas.moles > MINIMUM_AIR_TO_SUSPEND) && (!corresponding || (trace_gas.moles >= corresponding.moles*MINIMUM_AIR_RATIO_TO_SUSPEND)))
return 0
- if(giver.trace_gases.len)
- for(var/datum/gas/trace_gas in giver.trace_gases)
- var/datum/gas/corresponding = locate(trace_gas.type) in trace_gases
- if((trace_gas.moles > MINIMUM_AIR_TO_SUSPEND) && (!corresponding || (trace_gas.moles >= corresponding.moles*MINIMUM_AIR_RATIO_TO_SUSPEND)))
+ return merge(giver)
+
+/datum/gas_mixture/proc/merge(datum/gas_mixture/giver)
+ //Purpose: Merges all air from giver into self. Deletes giver.
+ //Called by: Machinery expelling air, check_then_merge, ?
+ //Inputs: The gas to merge.
+ //Outputs: 1
+
+ if(!giver)
+ return 0
+
+ if(abs(temperature-giver.temperature)>MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER)
+ var/self_heat_capacity = heat_capacity()*group_multiplier
+ var/giver_heat_capacity = giver.heat_capacity()*giver.group_multiplier
+ var/combined_heat_capacity = giver_heat_capacity + self_heat_capacity
+ if(combined_heat_capacity != 0)
+ temperature = (giver.temperature*giver_heat_capacity + temperature*self_heat_capacity)/combined_heat_capacity
+
+ if((group_multiplier>1)||(giver.group_multiplier>1))
+ oxygen += giver.oxygen*giver.group_multiplier/group_multiplier
+ carbon_dioxide += giver.carbon_dioxide*giver.group_multiplier/group_multiplier
+ nitrogen += giver.nitrogen*giver.group_multiplier/group_multiplier
+ toxins += giver.toxins*giver.group_multiplier/group_multiplier
+ else
+ oxygen += giver.oxygen
+ carbon_dioxide += giver.carbon_dioxide
+ nitrogen += giver.nitrogen
+ toxins += giver.toxins
+
+ if(giver.trace_gases.len)
+ for(var/datum/gas/trace_gas in giver.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*giver.group_multiplier/group_multiplier
+ update_values()
+
+ // Let the garbage collector handle it, faster according to /tg/ testers
+ //del(giver)
+ return 1
+
+/datum/gas_mixture/proc/remove(amount)
+ //Purpose: Removes a certain number of moles from the air.
+ //Called by: ?
+ //Inputs: How many moles to remove.
+ //Outputs: Removed air.
+
+ var/sum = total_moles()
+ amount = min(amount,sum) //Can not take more air than tile has!
+ if(amount <= 0)
+ return null
+
+ var/datum/gas_mixture/removed = new
+
+
+ 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)
+
+ oxygen -= removed.oxygen/group_multiplier
+ nitrogen -= removed.nitrogen/group_multiplier
+ carbon_dioxide -= removed.carbon_dioxide/group_multiplier
+ toxins -= removed.toxins/group_multiplier
+
+ if(trace_gases.len)
+ for(var/datum/gas/trace_gas in trace_gases)
+ 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
+
+ removed.temperature = temperature
+ update_values()
+ removed.update_values()
+
+ return removed
+
+/datum/gas_mixture/proc/remove_ratio(ratio)
+ //Purpose: Removes a certain ratio of the air.
+ //Called by: ?
+ //Inputs: Percentage to remove.
+ //Outputs: Removed air.
+
+ if(ratio <= 0)
+ return null
+
+ ratio = min(ratio, 1)
+
+ var/datum/gas_mixture/removed = new
+
+ removed.oxygen = QUANTIZE(oxygen*ratio)
+ removed.nitrogen = QUANTIZE(nitrogen*ratio)
+ removed.carbon_dioxide = QUANTIZE(carbon_dioxide*ratio)
+ removed.toxins = QUANTIZE(toxins*ratio)
+
+ oxygen -= removed.oxygen/group_multiplier
+ nitrogen -= removed.nitrogen/group_multiplier
+ carbon_dioxide -= removed.carbon_dioxide/group_multiplier
+ toxins -= removed.toxins/group_multiplier
+
+ if(trace_gases.len)
+ for(var/datum/gas/trace_gas in trace_gases)
+ var/datum/gas/corresponding = new trace_gas.type()
+ removed.trace_gases += corresponding
+
+ corresponding.moles = trace_gas.moles*ratio
+ trace_gas.moles -= corresponding.moles/group_multiplier
+
+ removed.temperature = temperature
+ update_values()
+ removed.update_values()
+
+ return removed
+
+/datum/gas_mixture/proc/check_then_remove(amount)
+ //Purpose: Similar to remove(...) but first checks to see if the amount of air removed is small enough
+ // that group processing is still accurate for source (aborts if not)
+ //Called by: ?
+ //Inputs: Number of moles to remove
+ //Outputs: Removed air or 0 if it can remove air or not.
+
+ amount = min(amount,total_moles()) //Can not take more air than tile has!
+
+ if((amount > MINIMUM_AIR_RATIO_TO_SUSPEND) && (amount > total_moles()*MINIMUM_AIR_RATIO_TO_SUSPEND))
+ return 0
+
+ return remove(amount)
+
+/datum/gas_mixture/proc/copy_from(datum/gas_mixture/sample)
+ //Purpose: Duplicates the sample air mixture.
+ //Called by: airgroups splitting, ?
+ //Inputs: Gas to copy
+ //Outputs: 1
+
+ oxygen = sample.oxygen
+ carbon_dioxide = sample.carbon_dioxide
+ nitrogen = sample.nitrogen
+ toxins = sample.toxins
+ total_moles = sample.total_moles()
+
+ trace_gases.len=null
+ if(sample.trace_gases.len > 0)
+ for(var/datum/gas/trace_gas in sample.trace_gases)
+ var/datum/gas/corresponding = new trace_gas.type()
+ trace_gases += corresponding
+
+ corresponding.moles = trace_gas.moles
+
+ temperature = sample.temperature
+
+ return 1
+
+/datum/gas_mixture/proc/check_gas_mixture(datum/gas_mixture/sharer)
+ //Purpose: Telling if one or both airgroups needs to disable group processing.
+ //Called by: Airgroups sharing air, checking if group processing needs disabled.
+ //Inputs: Gas to compare from other airgroup
+ //Outputs: 0 if the self-check failed (local airgroup breaks?)
+ // then -1 if sharer-check failed (sharing airgroup breaks?)
+ // then 1 if both checks pass (share succesful?)
+ if(!istype(sharer))
+ return
+
+ var/delta_oxygen = QUANTIZE(oxygen_archived - sharer.oxygen_archived)/TRANSFER_FRACTION
+ var/delta_carbon_dioxide = QUANTIZE(carbon_dioxide_archived - sharer.carbon_dioxide_archived)/TRANSFER_FRACTION
+ var/delta_nitrogen = QUANTIZE(nitrogen_archived - sharer.nitrogen_archived)/TRANSFER_FRACTION
+ var/delta_toxins = QUANTIZE(toxins_archived - sharer.toxins_archived)/TRANSFER_FRACTION
+
+ var/delta_temperature = (temperature_archived - sharer.temperature_archived)
+
+ if(((abs(delta_oxygen) > MINIMUM_AIR_TO_SUSPEND) && (abs(delta_oxygen) >= oxygen_archived*MINIMUM_AIR_RATIO_TO_SUSPEND)) \
+ || ((abs(delta_carbon_dioxide) > MINIMUM_AIR_TO_SUSPEND) && (abs(delta_carbon_dioxide) >= carbon_dioxide_archived*MINIMUM_AIR_RATIO_TO_SUSPEND)) \
+ || ((abs(delta_nitrogen) > MINIMUM_AIR_TO_SUSPEND) && (abs(delta_nitrogen) >= nitrogen_archived*MINIMUM_AIR_RATIO_TO_SUSPEND)) \
+ || ((abs(delta_toxins) > MINIMUM_AIR_TO_SUSPEND) && (abs(delta_toxins) >= toxins_archived*MINIMUM_AIR_RATIO_TO_SUSPEND)))
+ return 0
+
+ if(abs(delta_temperature) > MINIMUM_TEMPERATURE_DELTA_TO_SUSPEND)
+ return 0
+
+ if(sharer.trace_gases.len)
+ for(var/datum/gas/trace_gas in sharer.trace_gases)
+ if(trace_gas.moles_archived > MINIMUM_AIR_TO_SUSPEND*4)
+ var/datum/gas/corresponding = locate(trace_gas.type) in trace_gases
+ if(corresponding)
+ if(trace_gas.moles_archived >= corresponding.moles_archived*MINIMUM_AIR_RATIO_TO_SUSPEND*4)
return 0
-
- return merge(giver)
-
- proc/merge(datum/gas_mixture/giver)
- //Purpose: Merges all air from giver into self. Deletes giver.
- //Called by: Machinery expelling air, check_then_merge, ?
- //Inputs: The gas to merge.
- //Outputs: 1
-
- if(!giver)
- return 0
-
- if(abs(temperature-giver.temperature)>MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER)
- var/self_heat_capacity = heat_capacity()*group_multiplier
- var/giver_heat_capacity = giver.heat_capacity()*giver.group_multiplier
- var/combined_heat_capacity = giver_heat_capacity + self_heat_capacity
- if(combined_heat_capacity != 0)
- temperature = (giver.temperature*giver_heat_capacity + temperature*self_heat_capacity)/combined_heat_capacity
-
- if((group_multiplier>1)||(giver.group_multiplier>1))
- oxygen += giver.oxygen*giver.group_multiplier/group_multiplier
- carbon_dioxide += giver.carbon_dioxide*giver.group_multiplier/group_multiplier
- nitrogen += giver.nitrogen*giver.group_multiplier/group_multiplier
- toxins += giver.toxins*giver.group_multiplier/group_multiplier
- else
- oxygen += giver.oxygen
- carbon_dioxide += giver.carbon_dioxide
- nitrogen += giver.nitrogen
- toxins += giver.toxins
-
- if(giver.trace_gases.len)
- for(var/datum/gas/trace_gas in giver.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*giver.group_multiplier/group_multiplier
- update_values()
-
- // Let the garbage collector handle it, faster according to /tg/ testers
- //del(giver)
- return 1
-
- proc/remove(amount)
- //Purpose: Removes a certain number of moles from the air.
- //Called by: ?
- //Inputs: How many moles to remove.
- //Outputs: Removed air.
-
- var/sum = total_moles()
- amount = min(amount,sum) //Can not take more air than tile has!
- if(amount <= 0)
- return null
-
- var/datum/gas_mixture/removed = new
-
-
- 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)
-
- oxygen -= removed.oxygen/group_multiplier
- nitrogen -= removed.nitrogen/group_multiplier
- carbon_dioxide -= removed.carbon_dioxide/group_multiplier
- toxins -= removed.toxins/group_multiplier
-
- if(trace_gases.len)
- for(var/datum/gas/trace_gas in trace_gases)
- 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
-
- removed.temperature = temperature
- update_values()
- removed.update_values()
-
- return removed
-
- proc/remove_ratio(ratio)
- //Purpose: Removes a certain ratio of the air.
- //Called by: ?
- //Inputs: Percentage to remove.
- //Outputs: Removed air.
-
- if(ratio <= 0)
- return null
-
- ratio = min(ratio, 1)
-
- var/datum/gas_mixture/removed = new
-
- removed.oxygen = QUANTIZE(oxygen*ratio)
- removed.nitrogen = QUANTIZE(nitrogen*ratio)
- removed.carbon_dioxide = QUANTIZE(carbon_dioxide*ratio)
- removed.toxins = QUANTIZE(toxins*ratio)
-
- oxygen -= removed.oxygen/group_multiplier
- nitrogen -= removed.nitrogen/group_multiplier
- carbon_dioxide -= removed.carbon_dioxide/group_multiplier
- toxins -= removed.toxins/group_multiplier
-
- if(trace_gases.len)
- for(var/datum/gas/trace_gas in trace_gases)
- var/datum/gas/corresponding = new trace_gas.type()
- removed.trace_gases += corresponding
-
- corresponding.moles = trace_gas.moles*ratio
- trace_gas.moles -= corresponding.moles/group_multiplier
-
- removed.temperature = temperature
- update_values()
- removed.update_values()
-
- return removed
-
- proc/check_then_remove(amount)
- //Purpose: Similar to remove(...) but first checks to see if the amount of air removed is small enough
- // that group processing is still accurate for source (aborts if not)
- //Called by: ?
- //Inputs: Number of moles to remove
- //Outputs: Removed air or 0 if it can remove air or not.
-
- amount = min(amount,total_moles()) //Can not take more air than tile has!
-
- if((amount > MINIMUM_AIR_RATIO_TO_SUSPEND) && (amount > total_moles()*MINIMUM_AIR_RATIO_TO_SUSPEND))
- return 0
-
- return remove(amount)
-
- proc/copy_from(datum/gas_mixture/sample)
- //Purpose: Duplicates the sample air mixture.
- //Called by: airgroups splitting, ?
- //Inputs: Gas to copy
- //Outputs: 1
-
- oxygen = sample.oxygen
- carbon_dioxide = sample.carbon_dioxide
- nitrogen = sample.nitrogen
- toxins = sample.toxins
- total_moles = sample.total_moles()
-
- trace_gases.len=null
- if(sample.trace_gases.len > 0)
- for(var/datum/gas/trace_gas in sample.trace_gases)
- var/datum/gas/corresponding = new trace_gas.type()
- trace_gases += corresponding
-
- corresponding.moles = trace_gas.moles
-
- temperature = sample.temperature
-
- return 1
-
- proc/check_gas_mixture(datum/gas_mixture/sharer)
- //Purpose: Telling if one or both airgroups needs to disable group processing.
- //Called by: Airgroups sharing air, checking if group processing needs disabled.
- //Inputs: Gas to compare from other airgroup
- //Outputs: 0 if the self-check failed (local airgroup breaks?)
- // then -1 if sharer-check failed (sharing airgroup breaks?)
- // then 1 if both checks pass (share succesful?)
- if(!istype(sharer))
- return
-
- var/delta_oxygen = QUANTIZE(oxygen_archived - sharer.oxygen_archived)/TRANSFER_FRACTION
- var/delta_carbon_dioxide = QUANTIZE(carbon_dioxide_archived - sharer.carbon_dioxide_archived)/TRANSFER_FRACTION
- var/delta_nitrogen = QUANTIZE(nitrogen_archived - sharer.nitrogen_archived)/TRANSFER_FRACTION
- var/delta_toxins = QUANTIZE(toxins_archived - sharer.toxins_archived)/TRANSFER_FRACTION
-
- var/delta_temperature = (temperature_archived - sharer.temperature_archived)
-
- if(((abs(delta_oxygen) > MINIMUM_AIR_TO_SUSPEND) && (abs(delta_oxygen) >= oxygen_archived*MINIMUM_AIR_RATIO_TO_SUSPEND)) \
- || ((abs(delta_carbon_dioxide) > MINIMUM_AIR_TO_SUSPEND) && (abs(delta_carbon_dioxide) >= carbon_dioxide_archived*MINIMUM_AIR_RATIO_TO_SUSPEND)) \
- || ((abs(delta_nitrogen) > MINIMUM_AIR_TO_SUSPEND) && (abs(delta_nitrogen) >= nitrogen_archived*MINIMUM_AIR_RATIO_TO_SUSPEND)) \
- || ((abs(delta_toxins) > MINIMUM_AIR_TO_SUSPEND) && (abs(delta_toxins) >= toxins_archived*MINIMUM_AIR_RATIO_TO_SUSPEND)))
- return 0
-
- if(abs(delta_temperature) > MINIMUM_TEMPERATURE_DELTA_TO_SUSPEND)
- return 0
-
- if(sharer.trace_gases.len)
- for(var/datum/gas/trace_gas in sharer.trace_gases)
- if(trace_gas.moles_archived > MINIMUM_AIR_TO_SUSPEND*4)
- var/datum/gas/corresponding = locate(trace_gas.type) in trace_gases
- if(corresponding)
- if(trace_gas.moles_archived >= corresponding.moles_archived*MINIMUM_AIR_RATIO_TO_SUSPEND*4)
- return 0
- else
- return 0
-
- if(trace_gases.len)
- for(var/datum/gas/trace_gas in trace_gases)
- if(trace_gas.moles_archived > MINIMUM_AIR_TO_SUSPEND*4)
- if(!locate(trace_gas.type) in sharer.trace_gases)
- return 0
-
- if(((abs(delta_oxygen) > MINIMUM_AIR_TO_SUSPEND) && (abs(delta_oxygen) >= sharer.oxygen_archived*MINIMUM_AIR_RATIO_TO_SUSPEND)) \
- || ((abs(delta_carbon_dioxide) > MINIMUM_AIR_TO_SUSPEND) && (abs(delta_carbon_dioxide) >= sharer.carbon_dioxide_archived*MINIMUM_AIR_RATIO_TO_SUSPEND)) \
- || ((abs(delta_nitrogen) > MINIMUM_AIR_TO_SUSPEND) && (abs(delta_nitrogen) >= sharer.nitrogen_archived*MINIMUM_AIR_RATIO_TO_SUSPEND)) \
- || ((abs(delta_toxins) > MINIMUM_AIR_TO_SUSPEND) && (abs(delta_toxins) >= sharer.toxins_archived*MINIMUM_AIR_RATIO_TO_SUSPEND)))
- return -1
-
- if(trace_gases.len)
- for(var/datum/gas/trace_gas in trace_gases)
- if(trace_gas.moles_archived > MINIMUM_AIR_TO_SUSPEND*4)
- var/datum/gas/corresponding = locate(trace_gas.type) in sharer.trace_gases
- if(corresponding)
- if(trace_gas.moles_archived >= corresponding.moles_archived*MINIMUM_AIR_RATIO_TO_SUSPEND*4)
- return -1
- else
- return -1
-
- return 1
-
- proc/check_turf(turf/model)
- //Purpose: Used to compare the gases in an unsimulated turf with the gas in a simulated one.
- //Called by: Sharing air (mimicing) with adjacent unsimulated turfs
- //Inputs: Unsimulated turf
- //Outputs: 1 if safe to mimic, 0 if needs to break airgroup.
-
- var/delta_oxygen = (oxygen_archived - model.oxygen)/TRANSFER_FRACTION
- var/delta_carbon_dioxide = (carbon_dioxide_archived - model.carbon_dioxide)/TRANSFER_FRACTION
- var/delta_nitrogen = (nitrogen_archived - model.nitrogen)/TRANSFER_FRACTION
- var/delta_toxins = (toxins_archived - model.toxins)/TRANSFER_FRACTION
-
- var/delta_temperature = (temperature_archived - model.temperature)
-
- if(((abs(delta_oxygen) > MINIMUM_AIR_TO_SUSPEND) && (abs(delta_oxygen) >= oxygen_archived*MINIMUM_AIR_RATIO_TO_SUSPEND)) \
- || ((abs(delta_carbon_dioxide) > MINIMUM_AIR_TO_SUSPEND) && (abs(delta_carbon_dioxide) >= carbon_dioxide_archived*MINIMUM_AIR_RATIO_TO_SUSPEND)) \
- || ((abs(delta_nitrogen) > MINIMUM_AIR_TO_SUSPEND) && (abs(delta_nitrogen) >= nitrogen_archived*MINIMUM_AIR_RATIO_TO_SUSPEND)) \
- || ((abs(delta_toxins) > MINIMUM_AIR_TO_SUSPEND) && (abs(delta_toxins) >= toxins_archived*MINIMUM_AIR_RATIO_TO_SUSPEND)))
- return 0
- if(abs(delta_temperature) > MINIMUM_TEMPERATURE_DELTA_TO_SUSPEND)
- return 0
-
- if(trace_gases.len)
- for(var/datum/gas/trace_gas in trace_gases)
- if(trace_gas.moles_archived > MINIMUM_AIR_TO_SUSPEND*4)
- return 0
-
- return 1
-
- proc/share(datum/gas_mixture/sharer)
- //Purpose: Used to transfer gas from a more pressurised tile to a less presurised tile
- // (Two directional, if the other tile is more pressurised, air travels to current tile)
- //Called by: Sharing air with adjacent simulated turfs
- //Inputs: Air datum to share with
- //Outputs: Amount of gas exchanged (Negative if lost air, positive if gained.)
-
-
- if(!istype(sharer))
- return
-
- var/delta_oxygen = QUANTIZE(oxygen_archived - sharer.oxygen_archived)/TRANSFER_FRACTION
- var/delta_carbon_dioxide = QUANTIZE(carbon_dioxide_archived - sharer.carbon_dioxide_archived)/TRANSFER_FRACTION
- var/delta_nitrogen = QUANTIZE(nitrogen_archived - sharer.nitrogen_archived)/TRANSFER_FRACTION
- var/delta_toxins = QUANTIZE(toxins_archived - sharer.toxins_archived)/TRANSFER_FRACTION
-
- var/delta_temperature = (temperature_archived - sharer.temperature_archived)
-
- var/old_self_heat_capacity = 0
- var/old_sharer_heat_capacity = 0
-
- var/heat_self_to_sharer = 0
- var/heat_capacity_self_to_sharer = 0
- var/heat_sharer_to_self = 0
- var/heat_capacity_sharer_to_self = 0
-
- if(abs(delta_temperature) > MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER)
-
- var/delta_air = delta_oxygen+delta_nitrogen
- if(delta_air)
- var/air_heat_capacity = SPECIFIC_HEAT_AIR*delta_air
- if(delta_air > 0)
- heat_self_to_sharer += air_heat_capacity*temperature_archived
- heat_capacity_self_to_sharer += air_heat_capacity
- else
- heat_sharer_to_self -= air_heat_capacity*sharer.temperature_archived
- heat_capacity_sharer_to_self -= air_heat_capacity
-
- if(delta_carbon_dioxide)
- var/carbon_dioxide_heat_capacity = SPECIFIC_HEAT_CDO*delta_carbon_dioxide
- if(delta_carbon_dioxide > 0)
- heat_self_to_sharer += carbon_dioxide_heat_capacity*temperature_archived
- heat_capacity_self_to_sharer += carbon_dioxide_heat_capacity
- else
- heat_sharer_to_self -= carbon_dioxide_heat_capacity*sharer.temperature_archived
- heat_capacity_sharer_to_self -= carbon_dioxide_heat_capacity
-
- if(delta_toxins)
- var/toxins_heat_capacity = SPECIFIC_HEAT_TOXIN*delta_toxins
- if(delta_toxins > 0)
- heat_self_to_sharer += toxins_heat_capacity*temperature_archived
- heat_capacity_self_to_sharer += toxins_heat_capacity
- else
- heat_sharer_to_self -= toxins_heat_capacity*sharer.temperature_archived
- heat_capacity_sharer_to_self -= toxins_heat_capacity
-
- old_self_heat_capacity = heat_capacity()*group_multiplier
- old_sharer_heat_capacity = sharer.heat_capacity()*sharer.group_multiplier
-
- oxygen -= delta_oxygen/group_multiplier
- sharer.oxygen += delta_oxygen/sharer.group_multiplier
-
- carbon_dioxide -= delta_carbon_dioxide/group_multiplier
- sharer.carbon_dioxide += delta_carbon_dioxide/sharer.group_multiplier
-
- nitrogen -= delta_nitrogen/group_multiplier
- sharer.nitrogen += delta_nitrogen/sharer.group_multiplier
-
- toxins -= delta_toxins/group_multiplier
- sharer.toxins += delta_toxins/sharer.group_multiplier
-
- var/moved_moles = (delta_oxygen + delta_carbon_dioxide + delta_nitrogen + delta_toxins)
-
- var/list/trace_types_considered = list()
-
- if(trace_gases.len)
- for(var/datum/gas/trace_gas in trace_gases)
-
- var/datum/gas/corresponding = locate(trace_gas.type) in sharer.trace_gases
- var/delta = 0
-
- if(corresponding)
- delta = QUANTIZE(trace_gas.moles_archived - corresponding.moles_archived)/TRANSFER_FRACTION
- else
- corresponding = new trace_gas.type()
- sharer.trace_gases += corresponding
-
- delta = trace_gas.moles_archived/TRANSFER_FRACTION
-
- trace_gas.moles -= delta/group_multiplier
- corresponding.moles += delta/sharer.group_multiplier
-
- if(delta)
- var/individual_heat_capacity = trace_gas.specific_heat*delta
- if(delta > 0)
- heat_self_to_sharer += individual_heat_capacity*temperature_archived
- heat_capacity_self_to_sharer += individual_heat_capacity
- else
- heat_sharer_to_self -= individual_heat_capacity*sharer.temperature_archived
- heat_capacity_sharer_to_self -= individual_heat_capacity
-
- moved_moles += delta
-
- trace_types_considered += trace_gas.type
-
-
- if(sharer.trace_gases.len)
- for(var/datum/gas/trace_gas in sharer.trace_gases)
- if(trace_gas.type in trace_types_considered) continue
- else
- var/datum/gas/corresponding
- var/delta = 0
-
- corresponding = new trace_gas.type()
- trace_gases += corresponding
-
- delta = trace_gas.moles_archived/TRANSFER_FRACTION
-
- trace_gas.moles -= delta/sharer.group_multiplier
- corresponding.moles += delta/group_multiplier
-
- //Guaranteed transfer from sharer to self
- var/individual_heat_capacity = trace_gas.specific_heat*delta
- heat_sharer_to_self += individual_heat_capacity*sharer.temperature_archived
- heat_capacity_sharer_to_self += individual_heat_capacity
-
- moved_moles += -delta
- update_values()
- sharer.update_values()
-
- if(abs(delta_temperature) > MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER)
- var/new_self_heat_capacity = old_self_heat_capacity + heat_capacity_sharer_to_self - heat_capacity_self_to_sharer
- var/new_sharer_heat_capacity = old_sharer_heat_capacity + heat_capacity_self_to_sharer - heat_capacity_sharer_to_self
-
- if(new_self_heat_capacity > MINIMUM_HEAT_CAPACITY)
- temperature = (old_self_heat_capacity*temperature - heat_capacity_self_to_sharer*temperature_archived + heat_capacity_sharer_to_self*sharer.temperature_archived)/new_self_heat_capacity
-
- if(new_sharer_heat_capacity > MINIMUM_HEAT_CAPACITY)
- sharer.temperature = (old_sharer_heat_capacity*sharer.temperature-heat_capacity_sharer_to_self*sharer.temperature_archived + heat_capacity_self_to_sharer*temperature_archived)/new_sharer_heat_capacity
-
- if(abs(old_sharer_heat_capacity) > MINIMUM_HEAT_CAPACITY)
- if(abs(new_sharer_heat_capacity/old_sharer_heat_capacity - 1) < 0.10) // <10% change in sharer heat capacity
- temperature_share(sharer, OPEN_HEAT_TRANSFER_COEFFICIENT)
-
- if((delta_temperature > MINIMUM_TEMPERATURE_TO_MOVE) || abs(moved_moles) > MINIMUM_MOLES_DELTA_TO_MOVE)
- var/delta_pressure = temperature_archived*(total_moles() + moved_moles) - sharer.temperature_archived*(sharer.total_moles() - moved_moles)
- return delta_pressure*R_IDEAL_GAS_EQUATION/volume
-
- else
- return 0
-
- proc/mimic(turf/model, border_multiplier)
- //Purpose: Used transfer gas from a more pressurised tile to a less presurised unsimulated tile.
- //Called by: "sharing" from unsimulated to simulated turfs.
- //Inputs: Unsimulated turf, Multiplier for gas transfer (optional)
- //Outputs: Amount of gas exchanged
-
- var/delta_oxygen = QUANTIZE(oxygen_archived - model.oxygen)/TRANSFER_FRACTION
- var/delta_carbon_dioxide = QUANTIZE(carbon_dioxide_archived - model.carbon_dioxide)/TRANSFER_FRACTION
- var/delta_nitrogen = QUANTIZE(nitrogen_archived - model.nitrogen)/TRANSFER_FRACTION
- var/delta_toxins = QUANTIZE(toxins_archived - model.toxins)/TRANSFER_FRACTION
-
- var/delta_temperature = (temperature_archived - model.temperature)
-
- var/heat_transferred = 0
- var/old_self_heat_capacity = 0
- var/heat_capacity_transferred = 0
-
- if(abs(delta_temperature) > MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER)
-
- var/delta_air = delta_oxygen+delta_nitrogen
- if(delta_air)
- var/air_heat_capacity = SPECIFIC_HEAT_AIR*delta_air
- heat_transferred -= air_heat_capacity*model.temperature
- heat_capacity_transferred -= air_heat_capacity
-
- if(delta_carbon_dioxide)
- var/carbon_dioxide_heat_capacity = SPECIFIC_HEAT_CDO*delta_carbon_dioxide
- heat_transferred -= carbon_dioxide_heat_capacity*model.temperature
- heat_capacity_transferred -= carbon_dioxide_heat_capacity
-
- if(delta_toxins)
- var/toxins_heat_capacity = SPECIFIC_HEAT_TOXIN*delta_toxins
- heat_transferred -= toxins_heat_capacity*model.temperature
- heat_capacity_transferred -= toxins_heat_capacity
-
- old_self_heat_capacity = heat_capacity()*group_multiplier
-
- if(border_multiplier)
- oxygen -= delta_oxygen*border_multiplier/group_multiplier
- carbon_dioxide -= delta_carbon_dioxide*border_multiplier/group_multiplier
- nitrogen -= delta_nitrogen*border_multiplier/group_multiplier
- toxins -= delta_toxins*border_multiplier/group_multiplier
- else
- oxygen -= delta_oxygen/group_multiplier
- carbon_dioxide -= delta_carbon_dioxide/group_multiplier
- nitrogen -= delta_nitrogen/group_multiplier
- toxins -= delta_toxins/group_multiplier
-
- var/moved_moles = (delta_oxygen + delta_carbon_dioxide + delta_nitrogen + delta_toxins)
-
- if(trace_gases.len)
- for(var/datum/gas/trace_gas in trace_gases)
- var/delta = 0
-
- delta = trace_gas.moles_archived/TRANSFER_FRACTION
-
- if(border_multiplier)
- trace_gas.moles -= delta*border_multiplier/group_multiplier
- else
- trace_gas.moles -= delta/group_multiplier
-
- var/heat_cap_transferred = delta*trace_gas.specific_heat
- heat_transferred += heat_cap_transferred*temperature_archived
- heat_capacity_transferred += heat_cap_transferred
- moved_moles += delta
- update_values()
-
- if(abs(delta_temperature) > MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER)
- var/new_self_heat_capacity = old_self_heat_capacity - heat_capacity_transferred
- if(new_self_heat_capacity > MINIMUM_HEAT_CAPACITY)
- if(border_multiplier)
- temperature = (old_self_heat_capacity*temperature - heat_capacity_transferred*border_multiplier*temperature_archived)/new_self_heat_capacity
- else
- temperature = (old_self_heat_capacity*temperature - heat_capacity_transferred*border_multiplier*temperature_archived)/new_self_heat_capacity
-
- temperature_mimic(model, model.thermal_conductivity, border_multiplier)
-
- if((delta_temperature > MINIMUM_TEMPERATURE_TO_MOVE) || abs(moved_moles) > MINIMUM_MOLES_DELTA_TO_MOVE)
- var/delta_pressure = temperature_archived*(total_moles() + moved_moles) - model.temperature*(model.oxygen+model.carbon_dioxide+model.nitrogen+model.toxins)
- return delta_pressure*R_IDEAL_GAS_EQUATION/volume
- else
- return 0
-
- proc/check_both_then_temperature_share(datum/gas_mixture/sharer, conduction_coefficient)
- var/delta_temperature = (temperature_archived - sharer.temperature_archived)
-
- var/self_heat_capacity = heat_capacity_archived()
- var/sharer_heat_capacity = sharer.heat_capacity_archived()
-
- var/self_temperature_delta = 0
- var/sharer_temperature_delta = 0
-
- if((sharer_heat_capacity > MINIMUM_HEAT_CAPACITY) && (self_heat_capacity > MINIMUM_HEAT_CAPACITY))
- var/heat = conduction_coefficient*delta_temperature* \
- (self_heat_capacity*sharer_heat_capacity/(self_heat_capacity+sharer_heat_capacity))
-
- self_temperature_delta = -heat/(self_heat_capacity*group_multiplier)
- sharer_temperature_delta = heat/(sharer_heat_capacity*sharer.group_multiplier)
- else
- return 1
-
- if((abs(self_temperature_delta) > MINIMUM_TEMPERATURE_DELTA_TO_SUSPEND) \
- && (abs(self_temperature_delta) > MINIMUM_TEMPERATURE_RATIO_TO_SUSPEND*temperature_archived))
- return 0
-
- if((abs(sharer_temperature_delta) > MINIMUM_TEMPERATURE_DELTA_TO_SUSPEND) \
- && (abs(sharer_temperature_delta) > MINIMUM_TEMPERATURE_RATIO_TO_SUSPEND*sharer.temperature_archived))
- return -1
-
- temperature += self_temperature_delta
- sharer.temperature += sharer_temperature_delta
-
- return 1
- //Logic integrated from: temperature_share(sharer, conduction_coefficient) for efficiency
-
- proc/check_me_then_temperature_share(datum/gas_mixture/sharer, conduction_coefficient)
- var/delta_temperature = (temperature_archived - sharer.temperature_archived)
-
- var/self_heat_capacity = heat_capacity_archived()
- var/sharer_heat_capacity = sharer.heat_capacity_archived()
-
- var/self_temperature_delta = 0
- var/sharer_temperature_delta = 0
-
- if((sharer_heat_capacity > MINIMUM_HEAT_CAPACITY) && (self_heat_capacity > MINIMUM_HEAT_CAPACITY))
- var/heat = conduction_coefficient*delta_temperature* \
- (self_heat_capacity*sharer_heat_capacity/(self_heat_capacity+sharer_heat_capacity))
-
- self_temperature_delta = -heat/(self_heat_capacity*group_multiplier)
- sharer_temperature_delta = heat/(sharer_heat_capacity*sharer.group_multiplier)
- else
- return 1
-
- if((abs(self_temperature_delta) > MINIMUM_TEMPERATURE_DELTA_TO_SUSPEND) \
- && (abs(self_temperature_delta) > MINIMUM_TEMPERATURE_RATIO_TO_SUSPEND*temperature_archived))
- return 0
-
- temperature += self_temperature_delta
- sharer.temperature += sharer_temperature_delta
-
- return 1
- //Logic integrated from: temperature_share(sharer, conduction_coefficient) for efficiency
-
- proc/check_me_then_temperature_turf_share(turf/simulated/sharer, conduction_coefficient)
- var/delta_temperature = (temperature_archived - sharer.temperature)
-
- var/self_temperature_delta = 0
- var/sharer_temperature_delta = 0
-
- if(abs(delta_temperature) > MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER)
- var/self_heat_capacity = heat_capacity_archived()
-
- if((sharer.heat_capacity > MINIMUM_HEAT_CAPACITY) && (self_heat_capacity > MINIMUM_HEAT_CAPACITY))
- var/heat = conduction_coefficient*delta_temperature* \
- (self_heat_capacity*sharer.heat_capacity/(self_heat_capacity+sharer.heat_capacity))
-
- self_temperature_delta = -heat/(self_heat_capacity*group_multiplier)
- sharer_temperature_delta = heat/sharer.heat_capacity
- else
- return 1
-
- if((abs(self_temperature_delta) > MINIMUM_TEMPERATURE_DELTA_TO_SUSPEND) \
- && (abs(self_temperature_delta) > MINIMUM_TEMPERATURE_RATIO_TO_SUSPEND*temperature_archived))
- return 0
-
- temperature += self_temperature_delta
- sharer.temperature += sharer_temperature_delta
-
- return 1
- //Logic integrated from: temperature_turf_share(sharer, conduction_coefficient) for efficiency
-
- proc/check_me_then_temperature_mimic(turf/model, conduction_coefficient)
- var/delta_temperature = (temperature_archived - model.temperature)
- var/self_temperature_delta = 0
-
- if(abs(delta_temperature) > MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER)
- var/self_heat_capacity = heat_capacity_archived()
-
- if((model.heat_capacity > MINIMUM_HEAT_CAPACITY) && (self_heat_capacity > MINIMUM_HEAT_CAPACITY))
- var/heat = conduction_coefficient*delta_temperature* \
- (self_heat_capacity*model.heat_capacity/(self_heat_capacity+model.heat_capacity))
-
- self_temperature_delta = -heat/(self_heat_capacity*group_multiplier)
-
- if((abs(self_temperature_delta) > MINIMUM_TEMPERATURE_DELTA_TO_SUSPEND) \
- && (abs(self_temperature_delta) > MINIMUM_TEMPERATURE_RATIO_TO_SUSPEND*temperature_archived))
- return 0
-
- temperature += self_temperature_delta
-
- return 1
- //Logic integrated from: temperature_mimic(model, conduction_coefficient) for efficiency
-
- proc/temperature_share(datum/gas_mixture/sharer, conduction_coefficient)
-
- var/delta_temperature = (temperature_archived - sharer.temperature_archived)
- if(abs(delta_temperature) > MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER)
- var/self_heat_capacity = heat_capacity_archived()
- var/sharer_heat_capacity = sharer.heat_capacity_archived()
- if(!group_multiplier)
- message_admins("Error! The gas mixture (ref \ref[src]) has no group multiplier!")
- return
-
- if((sharer_heat_capacity > MINIMUM_HEAT_CAPACITY) && (self_heat_capacity > MINIMUM_HEAT_CAPACITY))
- var/heat = conduction_coefficient*delta_temperature* \
- (self_heat_capacity*sharer_heat_capacity/(self_heat_capacity+sharer_heat_capacity))
-
- temperature -= heat/(self_heat_capacity*group_multiplier)
- sharer.temperature += heat/(sharer_heat_capacity*sharer.group_multiplier)
-
- proc/temperature_mimic(turf/model, conduction_coefficient, border_multiplier)
- var/delta_temperature = (temperature - model.temperature)
- if(abs(delta_temperature) > MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER)
- var/self_heat_capacity = heat_capacity()//_archived()
- if(!group_multiplier)
- message_admins("Error! The gas mixture (ref \ref[src]) has no group multiplier!")
- return
-
- if((model.heat_capacity > MINIMUM_HEAT_CAPACITY) && (self_heat_capacity > MINIMUM_HEAT_CAPACITY))
- var/heat = conduction_coefficient*delta_temperature* \
- (self_heat_capacity*model.heat_capacity/(self_heat_capacity+model.heat_capacity))
-
- if(border_multiplier)
- temperature -= heat*border_multiplier/(self_heat_capacity*group_multiplier)
- else
- temperature -= heat/(self_heat_capacity*group_multiplier)
-
- proc/temperature_turf_share(turf/simulated/sharer, conduction_coefficient)
- var/delta_temperature = (temperature_archived - sharer.temperature)
- if(abs(delta_temperature) > MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER)
- var/self_heat_capacity = heat_capacity()
-
- if((sharer.heat_capacity > MINIMUM_HEAT_CAPACITY) && (self_heat_capacity > MINIMUM_HEAT_CAPACITY))
- var/heat = conduction_coefficient*delta_temperature* \
- (self_heat_capacity*sharer.heat_capacity/(self_heat_capacity+sharer.heat_capacity))
-
- temperature -= heat/(self_heat_capacity*group_multiplier)
- sharer.temperature += heat/sharer.heat_capacity
-
- proc/compare(datum/gas_mixture/sample)
- //Purpose: Compares sample to self to see if within acceptable ranges that group processing may be enabled
- //Called by: Airgroups trying to rebuild
- //Inputs: Gas mix to compare
- //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
- if((abs(nitrogen-sample.nitrogen) > MINIMUM_AIR_TO_SUSPEND) && \
- ((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)))
- 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]"
+ else
return 0
- 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
+ if(trace_gases.len)
+ for(var/datum/gas/trace_gas in trace_gases)
+ if(trace_gas.moles_archived > MINIMUM_AIR_TO_SUSPEND*4)
+ if(!locate(trace_gas.type) in sharer.trace_gases)
+ 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
- return 1
+ if(((abs(delta_oxygen) > MINIMUM_AIR_TO_SUSPEND) && (abs(delta_oxygen) >= sharer.oxygen_archived*MINIMUM_AIR_RATIO_TO_SUSPEND)) \
+ || ((abs(delta_carbon_dioxide) > MINIMUM_AIR_TO_SUSPEND) && (abs(delta_carbon_dioxide) >= sharer.carbon_dioxide_archived*MINIMUM_AIR_RATIO_TO_SUSPEND)) \
+ || ((abs(delta_nitrogen) > MINIMUM_AIR_TO_SUSPEND) && (abs(delta_nitrogen) >= sharer.nitrogen_archived*MINIMUM_AIR_RATIO_TO_SUSPEND)) \
+ || ((abs(delta_toxins) > MINIMUM_AIR_TO_SUSPEND) && (abs(delta_toxins) >= sharer.toxins_archived*MINIMUM_AIR_RATIO_TO_SUSPEND)))
+ return -1
+
+ if(trace_gases.len)
+ for(var/datum/gas/trace_gas in trace_gases)
+ if(trace_gas.moles_archived > MINIMUM_AIR_TO_SUSPEND*4)
+ var/datum/gas/corresponding = locate(trace_gas.type) in sharer.trace_gases
+ if(corresponding)
+ if(trace_gas.moles_archived >= corresponding.moles_archived*MINIMUM_AIR_RATIO_TO_SUSPEND*4)
+ return -1
+ else
+ return -1
+
+ return 1
+
+/datum/gas_mixture/proc/check_turf(turf/model)
+ //Purpose: Used to compare the gases in an unsimulated turf with the gas in a simulated one.
+ //Called by: Sharing air (mimicing) with adjacent unsimulated turfs
+ //Inputs: Unsimulated turf
+ //Outputs: 1 if safe to mimic, 0 if needs to break airgroup.
+
+ var/delta_oxygen = (oxygen_archived - model.oxygen)/TRANSFER_FRACTION
+ var/delta_carbon_dioxide = (carbon_dioxide_archived - model.carbon_dioxide)/TRANSFER_FRACTION
+ var/delta_nitrogen = (nitrogen_archived - model.nitrogen)/TRANSFER_FRACTION
+ var/delta_toxins = (toxins_archived - model.toxins)/TRANSFER_FRACTION
+
+ var/delta_temperature = (temperature_archived - model.temperature)
+
+ if(((abs(delta_oxygen) > MINIMUM_AIR_TO_SUSPEND) && (abs(delta_oxygen) >= oxygen_archived*MINIMUM_AIR_RATIO_TO_SUSPEND)) \
+ || ((abs(delta_carbon_dioxide) > MINIMUM_AIR_TO_SUSPEND) && (abs(delta_carbon_dioxide) >= carbon_dioxide_archived*MINIMUM_AIR_RATIO_TO_SUSPEND)) \
+ || ((abs(delta_nitrogen) > MINIMUM_AIR_TO_SUSPEND) && (abs(delta_nitrogen) >= nitrogen_archived*MINIMUM_AIR_RATIO_TO_SUSPEND)) \
+ || ((abs(delta_toxins) > MINIMUM_AIR_TO_SUSPEND) && (abs(delta_toxins) >= toxins_archived*MINIMUM_AIR_RATIO_TO_SUSPEND)))
+ return 0
+ if(abs(delta_temperature) > MINIMUM_TEMPERATURE_DELTA_TO_SUSPEND)
+ return 0
+
+ if(trace_gases.len)
+ for(var/datum/gas/trace_gas in trace_gases)
+ if(trace_gas.moles_archived > MINIMUM_AIR_TO_SUSPEND*4)
+ return 0
+
+ return 1
+
+/datum/gas_mixture/proc/share(datum/gas_mixture/sharer)
+ //Purpose: Used to transfer gas from a more pressurised tile to a less presurised tile
+ // (Two directional, if the other tile is more pressurised, air travels to current tile)
+ //Called by: Sharing air with adjacent simulated turfs
+ //Inputs: Air datum to share with
+ //Outputs: Amount of gas exchanged (Negative if lost air, positive if gained.)
- proc/subtract(datum/gas_mixture/right_side)
- //Purpose: Subtracts right_side from air_mixture. Used to help turfs mingle
- //Called by: Pipelines ending in a break (or something)
- //Inputs: Gas mix to remove
- //Outputs: 1
+ if(!istype(sharer))
+ return
- oxygen -= right_side.oxygen
- carbon_dioxide -= right_side.carbon_dioxide
- nitrogen -= right_side.nitrogen
- toxins -= right_side.toxins
+ var/delta_oxygen = QUANTIZE(oxygen_archived - sharer.oxygen_archived)/TRANSFER_FRACTION
+ var/delta_carbon_dioxide = QUANTIZE(carbon_dioxide_archived - sharer.carbon_dioxide_archived)/TRANSFER_FRACTION
+ var/delta_nitrogen = QUANTIZE(nitrogen_archived - sharer.nitrogen_archived)/TRANSFER_FRACTION
+ var/delta_toxins = QUANTIZE(toxins_archived - sharer.toxins_archived)/TRANSFER_FRACTION
- if((trace_gases.len > 0)||(right_side.trace_gases.len > 0))
- 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
+ var/delta_temperature = (temperature_archived - sharer.temperature_archived)
- corresponding.moles -= trace_gas.moles
- update_values()
- return 1
\ No newline at end of file
+ var/old_self_heat_capacity = 0
+ var/old_sharer_heat_capacity = 0
+
+ var/heat_self_to_sharer = 0
+ var/heat_capacity_self_to_sharer = 0
+ var/heat_sharer_to_self = 0
+ var/heat_capacity_sharer_to_self = 0
+
+ if(abs(delta_temperature) > MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER)
+
+ var/delta_air = delta_oxygen+delta_nitrogen
+ if(delta_air)
+ var/air_heat_capacity = SPECIFIC_HEAT_AIR*delta_air
+ if(delta_air > 0)
+ heat_self_to_sharer += air_heat_capacity*temperature_archived
+ heat_capacity_self_to_sharer += air_heat_capacity
+ else
+ heat_sharer_to_self -= air_heat_capacity*sharer.temperature_archived
+ heat_capacity_sharer_to_self -= air_heat_capacity
+
+ if(delta_carbon_dioxide)
+ var/carbon_dioxide_heat_capacity = SPECIFIC_HEAT_CDO*delta_carbon_dioxide
+ if(delta_carbon_dioxide > 0)
+ heat_self_to_sharer += carbon_dioxide_heat_capacity*temperature_archived
+ heat_capacity_self_to_sharer += carbon_dioxide_heat_capacity
+ else
+ heat_sharer_to_self -= carbon_dioxide_heat_capacity*sharer.temperature_archived
+ heat_capacity_sharer_to_self -= carbon_dioxide_heat_capacity
+
+ if(delta_toxins)
+ var/toxins_heat_capacity = SPECIFIC_HEAT_TOXIN*delta_toxins
+ if(delta_toxins > 0)
+ heat_self_to_sharer += toxins_heat_capacity*temperature_archived
+ heat_capacity_self_to_sharer += toxins_heat_capacity
+ else
+ heat_sharer_to_self -= toxins_heat_capacity*sharer.temperature_archived
+ heat_capacity_sharer_to_self -= toxins_heat_capacity
+
+ old_self_heat_capacity = heat_capacity()*group_multiplier
+ old_sharer_heat_capacity = sharer.heat_capacity()*sharer.group_multiplier
+
+ oxygen -= delta_oxygen/group_multiplier
+ sharer.oxygen += delta_oxygen/sharer.group_multiplier
+
+ carbon_dioxide -= delta_carbon_dioxide/group_multiplier
+ sharer.carbon_dioxide += delta_carbon_dioxide/sharer.group_multiplier
+
+ nitrogen -= delta_nitrogen/group_multiplier
+ sharer.nitrogen += delta_nitrogen/sharer.group_multiplier
+
+ toxins -= delta_toxins/group_multiplier
+ sharer.toxins += delta_toxins/sharer.group_multiplier
+
+ var/moved_moles = (delta_oxygen + delta_carbon_dioxide + delta_nitrogen + delta_toxins)
+
+ var/list/trace_types_considered = list()
+
+ if(trace_gases.len)
+ for(var/datum/gas/trace_gas in trace_gases)
+
+ var/datum/gas/corresponding = locate(trace_gas.type) in sharer.trace_gases
+ var/delta = 0
+
+ if(corresponding)
+ delta = QUANTIZE(trace_gas.moles_archived - corresponding.moles_archived)/TRANSFER_FRACTION
+ else
+ corresponding = new trace_gas.type()
+ sharer.trace_gases += corresponding
+
+ delta = trace_gas.moles_archived/TRANSFER_FRACTION
+
+ trace_gas.moles -= delta/group_multiplier
+ corresponding.moles += delta/sharer.group_multiplier
+
+ if(delta)
+ var/individual_heat_capacity = trace_gas.specific_heat*delta
+ if(delta > 0)
+ heat_self_to_sharer += individual_heat_capacity*temperature_archived
+ heat_capacity_self_to_sharer += individual_heat_capacity
+ else
+ heat_sharer_to_self -= individual_heat_capacity*sharer.temperature_archived
+ heat_capacity_sharer_to_self -= individual_heat_capacity
+
+ moved_moles += delta
+
+ trace_types_considered += trace_gas.type
+
+
+ if(sharer.trace_gases.len)
+ for(var/datum/gas/trace_gas in sharer.trace_gases)
+ if(trace_gas.type in trace_types_considered) continue
+ else
+ var/datum/gas/corresponding
+ var/delta = 0
+
+ corresponding = new trace_gas.type()
+ trace_gases += corresponding
+
+ delta = trace_gas.moles_archived/TRANSFER_FRACTION
+
+ trace_gas.moles -= delta/sharer.group_multiplier
+ corresponding.moles += delta/group_multiplier
+
+ //Guaranteed transfer from sharer to self
+ var/individual_heat_capacity = trace_gas.specific_heat*delta
+ heat_sharer_to_self += individual_heat_capacity*sharer.temperature_archived
+ heat_capacity_sharer_to_self += individual_heat_capacity
+
+ moved_moles += -delta
+ update_values()
+ sharer.update_values()
+
+ if(abs(delta_temperature) > MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER)
+ var/new_self_heat_capacity = old_self_heat_capacity + heat_capacity_sharer_to_self - heat_capacity_self_to_sharer
+ var/new_sharer_heat_capacity = old_sharer_heat_capacity + heat_capacity_self_to_sharer - heat_capacity_sharer_to_self
+
+ if(new_self_heat_capacity > MINIMUM_HEAT_CAPACITY)
+ temperature = (old_self_heat_capacity*temperature - heat_capacity_self_to_sharer*temperature_archived + heat_capacity_sharer_to_self*sharer.temperature_archived)/new_self_heat_capacity
+
+ if(new_sharer_heat_capacity > MINIMUM_HEAT_CAPACITY)
+ sharer.temperature = (old_sharer_heat_capacity*sharer.temperature-heat_capacity_sharer_to_self*sharer.temperature_archived + heat_capacity_self_to_sharer*temperature_archived)/new_sharer_heat_capacity
+
+ if(abs(old_sharer_heat_capacity) > MINIMUM_HEAT_CAPACITY)
+ if(abs(new_sharer_heat_capacity/old_sharer_heat_capacity - 1) < 0.10) // <10% change in sharer heat capacity
+ temperature_share(sharer, OPEN_HEAT_TRANSFER_COEFFICIENT)
+
+ if((delta_temperature > MINIMUM_TEMPERATURE_TO_MOVE) || abs(moved_moles) > MINIMUM_MOLES_DELTA_TO_MOVE)
+ var/delta_pressure = temperature_archived*(total_moles() + moved_moles) - sharer.temperature_archived*(sharer.total_moles() - moved_moles)
+ return delta_pressure*R_IDEAL_GAS_EQUATION/volume
+
+ else
+ return 0
+
+/datum/gas_mixture/proc/mimic(turf/model, border_multiplier)
+ //Purpose: Used transfer gas from a more pressurised tile to a less presurised unsimulated tile.
+ //Called by: "sharing" from unsimulated to simulated turfs.
+ //Inputs: Unsimulated turf, Multiplier for gas transfer (optional)
+ //Outputs: Amount of gas exchanged
+
+ var/delta_oxygen = QUANTIZE(oxygen_archived - model.oxygen)/TRANSFER_FRACTION
+ var/delta_carbon_dioxide = QUANTIZE(carbon_dioxide_archived - model.carbon_dioxide)/TRANSFER_FRACTION
+ var/delta_nitrogen = QUANTIZE(nitrogen_archived - model.nitrogen)/TRANSFER_FRACTION
+ var/delta_toxins = QUANTIZE(toxins_archived - model.toxins)/TRANSFER_FRACTION
+
+ var/delta_temperature = (temperature_archived - model.temperature)
+
+ var/heat_transferred = 0
+ var/old_self_heat_capacity = 0
+ var/heat_capacity_transferred = 0
+
+ if(abs(delta_temperature) > MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER)
+
+ var/delta_air = delta_oxygen+delta_nitrogen
+ if(delta_air)
+ var/air_heat_capacity = SPECIFIC_HEAT_AIR*delta_air
+ heat_transferred -= air_heat_capacity*model.temperature
+ heat_capacity_transferred -= air_heat_capacity
+
+ if(delta_carbon_dioxide)
+ var/carbon_dioxide_heat_capacity = SPECIFIC_HEAT_CDO*delta_carbon_dioxide
+ heat_transferred -= carbon_dioxide_heat_capacity*model.temperature
+ heat_capacity_transferred -= carbon_dioxide_heat_capacity
+
+ if(delta_toxins)
+ var/toxins_heat_capacity = SPECIFIC_HEAT_TOXIN*delta_toxins
+ heat_transferred -= toxins_heat_capacity*model.temperature
+ heat_capacity_transferred -= toxins_heat_capacity
+
+ old_self_heat_capacity = heat_capacity()*group_multiplier
+
+ if(border_multiplier)
+ oxygen -= delta_oxygen*border_multiplier/group_multiplier
+ carbon_dioxide -= delta_carbon_dioxide*border_multiplier/group_multiplier
+ nitrogen -= delta_nitrogen*border_multiplier/group_multiplier
+ toxins -= delta_toxins*border_multiplier/group_multiplier
+ else
+ oxygen -= delta_oxygen/group_multiplier
+ carbon_dioxide -= delta_carbon_dioxide/group_multiplier
+ nitrogen -= delta_nitrogen/group_multiplier
+ toxins -= delta_toxins/group_multiplier
+
+ var/moved_moles = (delta_oxygen + delta_carbon_dioxide + delta_nitrogen + delta_toxins)
+
+ if(trace_gases.len)
+ for(var/datum/gas/trace_gas in trace_gases)
+ var/delta = 0
+
+ delta = trace_gas.moles_archived/TRANSFER_FRACTION
+
+ if(border_multiplier)
+ trace_gas.moles -= delta*border_multiplier/group_multiplier
+ else
+ trace_gas.moles -= delta/group_multiplier
+
+ var/heat_cap_transferred = delta*trace_gas.specific_heat
+ heat_transferred += heat_cap_transferred*temperature_archived
+ heat_capacity_transferred += heat_cap_transferred
+ moved_moles += delta
+ update_values()
+
+ if(abs(delta_temperature) > MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER)
+ var/new_self_heat_capacity = old_self_heat_capacity - heat_capacity_transferred
+ if(new_self_heat_capacity > MINIMUM_HEAT_CAPACITY)
+ if(border_multiplier)
+ temperature = (old_self_heat_capacity*temperature - heat_capacity_transferred*border_multiplier*temperature_archived)/new_self_heat_capacity
+ else
+ temperature = (old_self_heat_capacity*temperature - heat_capacity_transferred*border_multiplier*temperature_archived)/new_self_heat_capacity
+
+ temperature_mimic(model, model.thermal_conductivity, border_multiplier)
+
+ if((delta_temperature > MINIMUM_TEMPERATURE_TO_MOVE) || abs(moved_moles) > MINIMUM_MOLES_DELTA_TO_MOVE)
+ var/delta_pressure = temperature_archived*(total_moles() + moved_moles) - model.temperature*(model.oxygen+model.carbon_dioxide+model.nitrogen+model.toxins)
+ return delta_pressure*R_IDEAL_GAS_EQUATION/volume
+ else
+ return 0
+
+/datum/gas_mixture/proc/check_both_then_temperature_share(datum/gas_mixture/sharer, conduction_coefficient)
+ var/delta_temperature = (temperature_archived - sharer.temperature_archived)
+
+ var/self_heat_capacity = heat_capacity_archived()
+ var/sharer_heat_capacity = sharer.heat_capacity_archived()
+
+ var/self_temperature_delta = 0
+ var/sharer_temperature_delta = 0
+
+ if((sharer_heat_capacity > MINIMUM_HEAT_CAPACITY) && (self_heat_capacity > MINIMUM_HEAT_CAPACITY))
+ var/heat = conduction_coefficient*delta_temperature* \
+ (self_heat_capacity*sharer_heat_capacity/(self_heat_capacity+sharer_heat_capacity))
+
+ self_temperature_delta = -heat/(self_heat_capacity*group_multiplier)
+ sharer_temperature_delta = heat/(sharer_heat_capacity*sharer.group_multiplier)
+ else
+ return 1
+
+ if((abs(self_temperature_delta) > MINIMUM_TEMPERATURE_DELTA_TO_SUSPEND) \
+ && (abs(self_temperature_delta) > MINIMUM_TEMPERATURE_RATIO_TO_SUSPEND*temperature_archived))
+ return 0
+
+ if((abs(sharer_temperature_delta) > MINIMUM_TEMPERATURE_DELTA_TO_SUSPEND) \
+ && (abs(sharer_temperature_delta) > MINIMUM_TEMPERATURE_RATIO_TO_SUSPEND*sharer.temperature_archived))
+ return -1
+
+ temperature += self_temperature_delta
+ sharer.temperature += sharer_temperature_delta
+
+ return 1
+ //Logic integrated from: temperature_share(sharer, conduction_coefficient) for efficiency
+
+/datum/gas_mixture/proc/check_me_then_temperature_share(datum/gas_mixture/sharer, conduction_coefficient)
+ var/delta_temperature = (temperature_archived - sharer.temperature_archived)
+
+ var/self_heat_capacity = heat_capacity_archived()
+ var/sharer_heat_capacity = sharer.heat_capacity_archived()
+
+ var/self_temperature_delta = 0
+ var/sharer_temperature_delta = 0
+
+ if((sharer_heat_capacity > MINIMUM_HEAT_CAPACITY) && (self_heat_capacity > MINIMUM_HEAT_CAPACITY))
+ var/heat = conduction_coefficient*delta_temperature* \
+ (self_heat_capacity*sharer_heat_capacity/(self_heat_capacity+sharer_heat_capacity))
+
+ self_temperature_delta = -heat/(self_heat_capacity*group_multiplier)
+ sharer_temperature_delta = heat/(sharer_heat_capacity*sharer.group_multiplier)
+ else
+ return 1
+
+ if((abs(self_temperature_delta) > MINIMUM_TEMPERATURE_DELTA_TO_SUSPEND) \
+ && (abs(self_temperature_delta) > MINIMUM_TEMPERATURE_RATIO_TO_SUSPEND*temperature_archived))
+ return 0
+
+ temperature += self_temperature_delta
+ sharer.temperature += sharer_temperature_delta
+
+ return 1
+ //Logic integrated from: temperature_share(sharer, conduction_coefficient) for efficiency
+
+/datum/gas_mixture/proc/check_me_then_temperature_turf_share(turf/simulated/sharer, conduction_coefficient)
+ var/delta_temperature = (temperature_archived - sharer.temperature)
+
+ var/self_temperature_delta = 0
+ var/sharer_temperature_delta = 0
+
+ if(abs(delta_temperature) > MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER)
+ var/self_heat_capacity = heat_capacity_archived()
+
+ if((sharer.heat_capacity > MINIMUM_HEAT_CAPACITY) && (self_heat_capacity > MINIMUM_HEAT_CAPACITY))
+ var/heat = conduction_coefficient*delta_temperature* \
+ (self_heat_capacity*sharer.heat_capacity/(self_heat_capacity+sharer.heat_capacity))
+
+ self_temperature_delta = -heat/(self_heat_capacity*group_multiplier)
+ sharer_temperature_delta = heat/sharer.heat_capacity
+ else
+ return 1
+
+ if((abs(self_temperature_delta) > MINIMUM_TEMPERATURE_DELTA_TO_SUSPEND) \
+ && (abs(self_temperature_delta) > MINIMUM_TEMPERATURE_RATIO_TO_SUSPEND*temperature_archived))
+ return 0
+
+ temperature += self_temperature_delta
+ sharer.temperature += sharer_temperature_delta
+
+ return 1
+ //Logic integrated from: temperature_turf_share(sharer, conduction_coefficient) for efficiency
+
+/datum/gas_mixture/proc/check_me_then_temperature_mimic(turf/model, conduction_coefficient)
+ var/delta_temperature = (temperature_archived - model.temperature)
+ var/self_temperature_delta = 0
+
+ if(abs(delta_temperature) > MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER)
+ var/self_heat_capacity = heat_capacity_archived()
+
+ if((model.heat_capacity > MINIMUM_HEAT_CAPACITY) && (self_heat_capacity > MINIMUM_HEAT_CAPACITY))
+ var/heat = conduction_coefficient*delta_temperature* \
+ (self_heat_capacity*model.heat_capacity/(self_heat_capacity+model.heat_capacity))
+
+ self_temperature_delta = -heat/(self_heat_capacity*group_multiplier)
+
+ if((abs(self_temperature_delta) > MINIMUM_TEMPERATURE_DELTA_TO_SUSPEND) \
+ && (abs(self_temperature_delta) > MINIMUM_TEMPERATURE_RATIO_TO_SUSPEND*temperature_archived))
+ return 0
+
+ temperature += self_temperature_delta
+
+ return 1
+ //Logic integrated from: temperature_mimic(model, conduction_coefficient) for efficiency
+
+/datum/gas_mixture/proc/temperature_share(datum/gas_mixture/sharer, conduction_coefficient)
+ var/delta_temperature = (temperature_archived - sharer.temperature_archived)
+ if(abs(delta_temperature) > MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER)
+ var/self_heat_capacity = heat_capacity_archived()
+ var/sharer_heat_capacity = sharer.heat_capacity_archived()
+ if(!group_multiplier)
+ message_admins("Error! The gas mixture (ref \ref[src]) has no group multiplier!")
+ return
+
+ if((sharer_heat_capacity > MINIMUM_HEAT_CAPACITY) && (self_heat_capacity > MINIMUM_HEAT_CAPACITY))
+ var/heat = conduction_coefficient*delta_temperature* \
+ (self_heat_capacity*sharer_heat_capacity/(self_heat_capacity+sharer_heat_capacity))
+
+ temperature -= heat/(self_heat_capacity*group_multiplier)
+ sharer.temperature += heat/(sharer_heat_capacity*sharer.group_multiplier)
+
+/datum/gas_mixture/proc/temperature_mimic(turf/model, conduction_coefficient, border_multiplier)
+ var/delta_temperature = (temperature - model.temperature)
+ if(abs(delta_temperature) > MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER)
+ var/self_heat_capacity = heat_capacity()//_archived()
+ if(!group_multiplier)
+ message_admins("Error! The gas mixture (ref \ref[src]) has no group multiplier!")
+ return
+
+ if((model.heat_capacity > MINIMUM_HEAT_CAPACITY) && (self_heat_capacity > MINIMUM_HEAT_CAPACITY))
+ var/heat = conduction_coefficient*delta_temperature* \
+ (self_heat_capacity*model.heat_capacity/(self_heat_capacity+model.heat_capacity))
+
+ if(border_multiplier)
+ temperature -= heat*border_multiplier/(self_heat_capacity*group_multiplier)
+ else
+ temperature -= heat/(self_heat_capacity*group_multiplier)
+
+/datum/gas_mixture/proc/temperature_turf_share(turf/simulated/sharer, conduction_coefficient)
+ var/delta_temperature = (temperature_archived - sharer.temperature)
+ if(abs(delta_temperature) > MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER)
+ var/self_heat_capacity = heat_capacity()
+
+ if((sharer.heat_capacity > MINIMUM_HEAT_CAPACITY) && (self_heat_capacity > MINIMUM_HEAT_CAPACITY))
+ var/heat = conduction_coefficient*delta_temperature* \
+ (self_heat_capacity*sharer.heat_capacity/(self_heat_capacity+sharer.heat_capacity))
+
+ temperature -= heat/(self_heat_capacity*group_multiplier)
+ sharer.temperature += heat/sharer.heat_capacity
+
+/datum/gas_mixture/proc/compare(datum/gas_mixture/sample)
+ //Purpose: Compares sample to self to see if within acceptable ranges that group processing may be enabled
+ //Called by: Airgroups trying to rebuild
+ //Inputs: Gas mix to compare
+ //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
+ if((abs(nitrogen-sample.nitrogen) > MINIMUM_AIR_TO_SUSPEND) && \
+ ((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)))
+ 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
+
+ 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
+
+ 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
+ return 1
+
+/datum/gas_mixture/proc/subtract(datum/gas_mixture/right_side)
+ //Purpose: Subtracts right_side from air_mixture. Used to help turfs mingle
+ //Called by: Pipelines ending in a break (or something)
+ //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
+
+ if((trace_gases.len > 0)||(right_side.trace_gases.len > 0))
+ 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
\ No newline at end of file
diff --git a/code/ZAS/FEA_system.dm b/code/ZAS/FEA_system.dm
index 94b7c5cf6d1..c2a33ad99db 100644
--- a/code/ZAS/FEA_system.dm
+++ b/code/ZAS/FEA_system.dm
@@ -64,49 +64,46 @@ atom/proc/CanPass(atom/movable/mover, turf/target, height=1.5, air_group = 0)
return (!density || !height || air_group)
-turf
- CanPass(atom/movable/mover, turf/target, height=1.5,air_group=0)
- if(!target) return 0
+/turf/CanPass(atom/movable/mover, turf/target, height=1.5,air_group=0)
+ if(!target) return 0
- if(istype(mover)) // turf/Enter(...) will perform more advanced checks
- return !density
+ if(istype(mover)) // turf/Enter(...) will perform more advanced checks
+ return !density
- else // Now, doing more detailed checks for air movement and air group formation
- if(target.blocks_air||blocks_air)
+ else // Now, doing more detailed checks for air movement and air group formation
+ if(target.blocks_air||blocks_air)
+ return 0
+
+ for(var/obj/obstacle in src)
+ if(!obstacle.CanPass(mover, target, height, air_group))
return 0
-
- for(var/obj/obstacle in src)
- if(!obstacle.CanPass(mover, target, height, air_group))
+ if(target != src)
+ for(var/obj/obstacle in target)
+ if(!obstacle.CanPass(mover, src, height, air_group))
return 0
- if(target != src)
- for(var/obj/obstacle in target)
- if(!obstacle.CanPass(mover, src, height, air_group))
- return 0
- return 1
+ return 1
-var/global/datum/controller/air_system/air_master
+var/datum/controller/air_system/air_master
-datum
- controller
- air_system
- //Geoemetry lists
- var/list/turfs_with_connections = list()
- var/list/active_hotspots = list()
+/datum/controller/air_system/
+ //Geoemetry lists
+ var/list/turfs_with_connections = list()
+ var/list/active_hotspots = list()
- //Special functions lists
- var/list/tiles_to_reconsider_zones = list()
+ //Special functions lists
+ var/list/tiles_to_reconsider_zones = list()
- //Geometry updates lists
- var/list/tiles_to_update = list()
- var/list/connections_to_check = list()
+ //Geometry updates lists
+ var/list/tiles_to_update = list()
+ var/list/connections_to_check = list()
- var/current_cycle = 0
- var/update_delay = 5 //How long between check should it try to process atmos again.
- var/failed_ticks = 0 //How many ticks have runtimed?
+ var/current_cycle = 0
+ var/update_delay = 5 //How long between check should it try to process atmos again.
+ var/failed_ticks = 0 //How many ticks have runtimed?
- var/tick_progress = 0
+ var/tick_progress = 0
/* process()
@@ -122,97 +119,103 @@ datum
*/
- 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
- //Inputs: None.
- //Outputs: None.
+/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
+ //Inputs: None.
+ //Outputs: None.
- set background = 1
- world << "\red \b Processing Geometry..."
- sleep(-1)
+ set background = 1
+ world << "\red \b Processing Geometry..."
+ sleep(-1)
- var/start_time = world.timeofday
+ var/start_time = world.timeofday
- var/simulated_turf_count = 0
+ var/simulated_turf_count = 0
- for(var/turf/simulated/S in world)
- simulated_turf_count++
- if(!S.zone && !S.blocks_air)
- if(S.CanPass(null, S, 0, 0))
- new/zone(S)
+ for(var/turf/simulated/S in world)
+ simulated_turf_count++
+ if(!S.zone && !S.blocks_air)
+ if(S.CanPass(null, S, 0, 0))
+ new/zone(S)
- for(var/turf/simulated/S in world)
- S.update_air_properties()
+ for(var/turf/simulated/S in world)
+ S.update_air_properties()
- world << {"Geometry initialized in [round(0.1*(world.timeofday-start_time),0.1)] seconds.
- Total Simulated Turfs: [simulated_turf_count]
- Total Zones: [zones.len]
- Total Unsimulated Turfs: [world.maxx*world.maxy*world.maxz - simulated_turf_count]"}
- /*
- spawn start()
+ world << {"Geometry initialized in [round(0.1*(world.timeofday-start_time),0.1)] seconds.
+Total Simulated Turfs: [simulated_turf_count]
+Total Zones: [zones.len]
+Total Unsimulated Turfs: [world.maxx*world.maxy*world.maxz - simulated_turf_count]"}
+ /*
+ spawn start()
- proc/start()
- //Purpose: This is kicked off by the master controller, and controls the processing of all atmosphere.
- //Called by: Master controller
- //Inputs: None.
- //Outputs: None.
+/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.
+ //Outputs: None.
- set background = 1
+ set background = 1
- while(1)
- if(!kill_air)
- current_cycle++
- var/success = tick() //Changed so that a runtime does not crash the ticker.
- if(!success) //Runtimed.
- failed_ticks++
- if(failed_ticks > 20)
- world << "ERROR IN ATMOS TICKER. Killing air simulation!"
- kill_air = 1
- sleep(max(5,update_delay*tick_multiplier))
- */
+ while(1)
+ if(!kill_air)
+ current_cycle++
+ var/success = tick() //Changed so that a runtime does not crash the ticker.
+ if(!success) //Runtimed.
+ failed_ticks++
+ if(failed_ticks > 20)
+ world << "ERROR IN ATMOS TICKER. Killing air simulation!"
+ kill_air = 1
+ sleep(max(5,update_delay*tick_multiplier))
+ */
- proc/tick()
- . = 1 //Set the default return value, for runtime detection.
+/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.
- 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()")
- tiles_to_update = list()
+ tick_progress = "update_air_properties"
+ if(tiles_to_update.len) //If there are tiles to update, do so.
+ 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(.)
+ tiles_to_update = list()
- //Check sanity on connection objects.
- tick_progress = "connections_to_check"
- if(connections_to_check.len)
- for(var/connection/C in connections_to_check)
- C.CheckPassSanity()
- connections_to_check = list()
+ //Check sanity on connection objects.
+ if(.)
+ tick_progress = "connections_to_check"
+ if(connections_to_check.len)
+ for(var/connection/C in connections_to_check)
+ C.CheckPassSanity()
+ connections_to_check = list()
- //Ensure tiles still have zones.
- 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()
+ //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()
- //Process zones.
- tick_progress = "zone/process()"
- for(var/zone/Z in zones)
- if(Z.last_update < current_cycle)
- var/output = Z.process()
- if(Z)
- Z.last_update = current_cycle
- if(. && Z && !output)
- . = 0
- //Process fires.
- tick_progress = "active_hotspots (fire)"
- for(var/obj/fire/F in active_hotspots)
- if(. && F && !F.process())
- . = 0
+ //Process zones.
+ if(.)
+ tick_progress = "zone/process()"
+ for(var/zone/Z in zones)
+ if(Z.last_update < current_cycle)
+ var/output = Z.process()
+ if(Z)
+ Z.last_update = current_cycle
+ if(. && Z && !output)
+ . = 0
+ //Process fires.
+ if(.)
+ tick_progress = "active_hotspots (fire)"
+ for(var/obj/fire/F in active_hotspots)
+ if(. && F && !F.process())
+ . = 0
- tick_progress = "success"
\ No newline at end of file
+ if(.)
+ tick_progress = "success"
\ No newline at end of file
diff --git a/code/ZAS/Fire.dm b/code/ZAS/Fire.dm
index 023d60acf08..8973b3794b2 100644
--- a/code/ZAS/Fire.dm
+++ b/code/ZAS/Fire.dm
@@ -30,7 +30,7 @@ turf/simulated/hotspot_expose(exposed_temperature, exposed_volume, soh)
var/igniting = 0
var/obj/effect/decal/cleanable/liquid_fuel/liquid = locate() in src
-
+
if(air_contents.check_combustability(liquid))
igniting = 1
@@ -43,132 +43,130 @@ 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 = 'fire.dmi'
+ icon = '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/floor/S = loc
+ if(!S.zone)
+ del src
+
+ if(!istype(S))
+ 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_combustability(liquid))
+ del src
+
+ //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!
- var
- firelevel = 10000 //Calculated by gas_mixture.calculate_firelevel()
- process()
- . = 1
-
- //get location and check if it is in a proper ZAS zone
- var/turf/simulated/floor/S = loc
- if(!S.zone)
- del src
-
- if(!istype(S))
- 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_combustability(liquid))
- del src
-
- //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!
+ //spread!
+ for(var/direction in cardinal)
+ if(S.air_check_directions&direction) //Grab all valid bordering tiles
-
- //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)
- var/turf/simulated/enemy_tile = get_step(S, direction)
+ if(istype(enemy_tile))
+ //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
- if(istype(enemy_tile))
- //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/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(vsc.fire_consuption_rate)
- //Spread the fire.
- if(!(locate(/obj/fire) in enemy_tile))
- 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(vsc.fire_consuption_rate)
-
///////////////////////////////// FLOW HAS BEEN CREATED /// DONT DELETE THE FIRE UNTIL IT IS MERGED BACK OR YOU WILL DELETE AIR ///////////////////////////////////////////////
-
- if(flow)
- if(flow.check_combustability(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!
- flow.zburn(liquid,1)
-
- //merge the air back
- S.assume_air(flow)
+
+ if(flow)
+ if(flow.check_combustability(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!
+ 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 //////////////////////////////////////////////////////////////////
-
- New(newLoc,fl)
- ..()
- if(!istype(loc, /turf))
- del src
+/obj/fire/New(newLoc,fl)
+ ..()
- dir = pick(cardinal)
- SetLuminosity(3)
- firelevel = fl
- air_master.active_hotspots.Add(src)
+ if(!istype(loc, /turf))
+ del 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)
- ..()
+ ..()
@@ -180,13 +178,13 @@ turf/simulated/apply_fire_protection()
datum/gas_mixture/proc/zburn(obj/effect/decal/cleanable/liquid_fuel/liquid,force_burn)
var/value = 0
-
+
if((temperature > PLASMA_MINIMUM_BURN_TEMPERATURE || force_burn) && check_combustability(liquid) )
- var/total_fuel = 0
+ var/total_fuel = 0
var/datum/gas/volatile_fuel/fuel = locate() in trace_gases
total_fuel += toxins
-
+
if(fuel)
//Volatile Fuel
total_fuel += fuel.moles
@@ -207,7 +205,7 @@ datum/gas_mixture/proc/zburn(obj/effect/decal/cleanable/liquid_fuel/liquid,force
//determine the amount of oxygen used
var/total_oxygen = min(oxygen, 2 * total_fuel)
-
+
//determine the amount of fuel actually used
var/used_fuel_ratio = min(oxygen / 2 , total_fuel) / total_fuel
total_fuel = total_fuel * used_fuel_ratio
@@ -234,31 +232,31 @@ datum/gas_mixture/proc/zburn(obj/effect/decal/cleanable/liquid_fuel/liquid,force
//calculate the energy produced by the reaction and then set the new temperature of the mix
temperature = (starting_energy + vsc.fire_fuel_energy_release * total_fuel) / heat_capacity()
-
+
update_values()
value = total_reactants * used_reactants_ratio
return value
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/datum/gas/volatile_fuel/fuel = locate() in trace_gases
var/value = 0
-
+
if(oxygen && (toxins || fuel || liquid))
value = 1
-
+
return value
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.
-
+
var/datum/gas/volatile_fuel/fuel = locate() in trace_gases
var/total_fuel = 0
var/firelevel = 0
-
+
if(check_combustability(liquid))
-
+
total_fuel += toxins
if(liquid)
@@ -268,16 +266,16 @@ datum/gas_mixture/proc/calculate_firelevel(obj/effect/decal/cleanable/liquid_fue
total_fuel += fuel.moles
var/total_combustables = (total_fuel + oxygen)
-
+
if(total_fuel > 0 && oxygen > 0)
-
+
//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)))
//toss everything together
firelevel = vsc.fire_firelevel_multiplier * mix_multiplier * dampening_multiplier
-
+
return max( 0, firelevel)
diff --git a/code/ZAS/Plasma.dm b/code/ZAS/Plasma.dm
index 3196d93db92..9f0e95f6617 100644
--- a/code/ZAS/Plasma.dm
+++ b/code/ZAS/Plasma.dm
@@ -1,61 +1,61 @@
var/image/contamination_overlay = image('icons/effects/contamination.dmi')
-pl_control/var
- PLASMA_DMG = 3
- PLASMA_DMG_NAME = "Plasma Damage Amount"
- PLASMA_DMG_DESC = "Self Descriptive"
+/pl_control
+ var/PLASMA_DMG = 3
+ var/PLASMA_DMG_NAME = "Plasma Damage Amount"
+ var/PLASMA_DMG_DESC = "Self Descriptive"
- CLOTH_CONTAMINATION = 1
- CLOTH_CONTAMINATION_NAME = "Cloth Contamination"
- CLOTH_CONTAMINATION_DESC = "If this is on, plasma does damage by getting into cloth."
+ 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."
- PLASMAGUARD_ONLY = 0
- PLASMAGUARD_ONLY_NAME = "\"PlasmaGuard Only\""
- PLASMAGUARD_ONLY_DESC = "If this is on, only biosuits and spacesuits protect against contamination and ill effects."
+ 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."
- GENETIC_CORRUPTION = 0
- GENETIC_CORRUPTION_NAME = "Genetic Corruption Chance"
- GENETIC_CORRUPTION_DESC = "Chance of genetic corruption as well as toxic damage, X in 10,000."
+ 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."
- SKIN_BURNS = 0
- SKIN_BURNS_DESC = "Plasma has an effect similar to mustard gas on the un-suited."
- SKIN_BURNS_NAME = "Skin Burns"
+ 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"
- EYE_BURNS = 1
- EYE_BURNS_NAME = "Eye Burns"
- EYE_BURNS_DESC = "Plasma burns the eyes of anyone not wearing eye protection."
+ var/EYE_BURNS = 1
+ var/EYE_BURNS_NAME = "Eye Burns"
+ var/EYE_BURNS_DESC = "Plasma burns the eyes of anyone not wearing eye protection."
- CONTAMINATION_LOSS = 0.02
- CONTAMINATION_LOSS_NAME = "Contamination Loss"
- CONTAMINATION_LOSS_DESC = "How much toxin damage is dealt from contaminated clothing" //Per tick? ASK ARYN
+ 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
- PLASMA_HALLUCINATION = 0
- PLASMA_HALLUCINATION_NAME = "Plasma Hallucination"
- PLASMA_HALLUCINATION_DESC = "Does being in plasma cause you to hallucinate?"
+ var/PLASMA_HALLUCINATION = 0
+ var/PLASMA_HALLUCINATION_NAME = "Plasma Hallucination"
+ var/PLASMA_HALLUCINATION_DESC = "Does being in plasma cause you to hallucinate?"
- N2O_HALLUCINATION = 1
- N2O_HALLUCINATION_NAME = "N2O Hallucination"
- N2O_HALLUCINATION_DESC = "Does being in sleeping gas 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
-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()
diff --git a/code/ZAS/Variable Settings.dm b/code/ZAS/Variable Settings.dm
index dd22765e99c..80e243e3c58 100644
--- a/code/ZAS/Variable Settings.dm
+++ b/code/ZAS/Variable Settings.dm
@@ -1,322 +1,332 @@
var/global/vs_control/vsc = new
-vs_control/var
- fire_consuption_rate = 0.25
- fire_consuption_rate_NAME = "Fire - Air Consumption Ratio"
- fire_consuption_rate_DESC = "Ratio of air removed and combusted per tick."
+/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_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."
+ 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_fuel_energy_release = 397000
- fire_fuel_energy_release_NAME = "Fire - Fuel energy release"
- fire_fuel_energy_release_DESC = "The energy in joule released when burning one mol of a burnable substance"
-
-
- airflow_lightest_pressure = 20
- airflow_lightest_pressure_NAME = "Airflow - Small Movement Threshold %"
- airflow_lightest_pressure_DESC = "Percent of 1 Atm. at which items with the small weight classes will move."
-
- airflow_light_pressure = 35
- airflow_light_pressure_NAME = "Airflow - Medium Movement Threshold %"
- airflow_light_pressure_DESC = "Percent of 1 Atm. at which items with the medium weight classes will move."
-
- airflow_medium_pressure = 50
- airflow_medium_pressure_NAME = "Airflow - Heavy Movement Threshold %"
- airflow_medium_pressure_DESC = "Percent of 1 Atm. at which items with the largest weight classes will move."
-
- airflow_heavy_pressure = 65
- airflow_heavy_pressure_NAME = "Airflow - Mob Movement Threshold %"
- airflow_heavy_pressure_DESC = "Percent of 1 Atm. at which mobs will move."
-
- airflow_dense_pressure = 85
- airflow_dense_pressure_NAME = "Airflow - Dense Movement Threshold %"
- airflow_dense_pressure_DESC = "Percent of 1 Atm. at which items with canisters and closets will move."
-
- airflow_stun_pressure = 60
- airflow_stun_pressure_NAME = "Airflow - Mob Stunning Threshold %"
- airflow_stun_pressure_DESC = "Percent of 1 Atm. at which mobs will be stunned by airflow."
-
- airflow_stun_cooldown = 60
- airflow_stun_cooldown_NAME = "Aiflow Stunning - Cooldown"
- airflow_stun_cooldown_DESC = "How long, in tenths of a second, to wait before stunning them again."
-
- airflow_stun = 1
- airflow_stun_NAME = "Airflow Impact - Stunning"
- airflow_stun_DESC = "How much a mob is stunned when hit by an object."
-
- airflow_damage = 2
- airflow_damage_NAME = "Airflow Impact - Damage"
- airflow_damage_DESC = "Damage from airflow impacts."
-
- airflow_speed_decay = 1.5
- airflow_speed_decay_NAME = "Airflow Speed Decay"
- airflow_speed_decay_DESC = "How rapidly the speed gained from airflow decays."
-
- airflow_delay = 30
- airflow_delay_NAME = "Airflow Retrigger Delay"
- airflow_delay_DESC = "Time in deciseconds before things can be moved by airflow again."
-
- airflow_mob_slowdown = 1
- airflow_mob_slowdown_NAME = "Airflow Slowdown"
- airflow_mob_slowdown_DESC = "Time in tenths of a second to add as a delay to each movement by a mob if they are fighting the pull of the airflow."
+ var/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"
-vs_control
- var
- list/settings = list()
- list/bitflags = list("1","2","4","8","16","32","64","128","256","512","1024")
- pl_control/plc = new()
+ 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."
- New()
- . = ..()
- settings = vars.Copy()
+ 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."
- 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)
+ 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."
+
+ 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."
+
+ 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."
+
+ 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."
+
+ 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."
+
+ 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."
+
+ var/airflow_damage = 2
+ var/airflow_damage_NAME = "Airflow Impact - Damage"
+ var/airflow_damage_DESC = "Damage from airflow impacts."
+
+ 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."
+
+ 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/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 = 0.4
+ var/connection_insulation_NAME = "Connections - Insulation"
+ var/connection_insulation_DESC = "How insulative a connection is, in terms of heat transfer. 1 is perfectly insulative, and 0 is perfectly conductive."
+
+ var/connection_temperature_delta = 10
+ var/connection_temperature_delta_NAME = "Connections - Temperature Difference"
+ var/connection_temperature_delta_DESC = "The smallest temperature difference which will cause heat to travel through doors."
+
+
+/vs_control/var/list/settings = list()
+/vs_control/var/list/bitflags = list("1","2","4","8","16","32","64","128","256","512","1024")
+/vs_control/var/pl_control/plc = new()
+
+/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 += "[vw_name] = [vw] \[Change\] "}
+ dat += text("Search Records
"
- dat += "[vw_desc]
"
- 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 += "[vw_name] = [vw] \[Change\]
"
+ dat += "[vw_desc]
"
+ 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 [key_name(user)] changed the setting [display_description] to [newvar]."
- 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 [key_name(user)] changed the setting [display_description] to [newvar]."
+ 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_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 [key_name(user)] changed the global plasma/ZAS settings to \"[def]\""
-
-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 [key_name(user)] changed the global plasma/ZAS settings to \"[def]\""
+
+/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
diff --git a/code/ZAS/ZAS_Turfs.dm b/code/ZAS/ZAS_Turfs.dm
index 2ed0478aba6..0070a19c5d2 100644
--- a/code/ZAS/ZAS_Turfs.dm
+++ b/code/ZAS/ZAS_Turfs.dm
@@ -1,278 +1,266 @@
-atom/var/pressure_resistance = ONE_ATMOSPHERE
-turf
+/atom/var/pressure_resistance = ONE_ATMOSPHERE
- var/zone/zone
+/turf/var/zone/zone
- assume_air(datum/gas_mixture/giver) //use this for machines to adjust air
- del(giver)
- return 0
+/turf/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
+/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.oxygen = oxygen
+ GM.carbon_dioxide = carbon_dioxide
+ GM.nitrogen = nitrogen
+ GM.toxins = toxins
- GM.temperature = temperature
- GM.update_values()
+ GM.temperature = temperature
+ GM.update_values()
- return GM
+ return GM
- remove_air(amount as num)
- var/datum/gas_mixture/GM = new
+/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
+ 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()
+ GM.temperature = temperature
+ GM.update_values()
- return GM
+ return GM
-turf
- simulated
+/turf/simulated/var/current_graphic = null
- var/current_graphic = null
+/turf/simulated/var/tmp/datum/gas_mixture/air
- var/tmp
- datum/gas_mixture/air
+/turf/simulated/var/tmp/processing = 1
- processing = 1
+/turf/simulated/var/tmp/air_check_directions = 0 //Do not modify this, just add turf to air_master.tiles_to_update
- 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
- obj/fire/active_hotspot
+/turf/simulated/proc/update_visuals()
+ overlays = null
+ var/siding_icon_state = return_siding_icon_state()
+ if(siding_icon_state)
+ overlays += image('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)
- proc/update_visuals()
- overlays = null
+/turf/simulated/New()
+ ..()
- var/siding_icon_state = return_siding_icon_state()
- if(siding_icon_state)
- overlays += image('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)
+ 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()
- 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()
- var/air_directions_archived = air_check_directions
- air_check_directions = 0
+ if(air_master)
+ air_master.tiles_to_update.Add(src)
+ else
+ if(air_master)
for(var/direction in cardinal)
- if(ZAirPass(get_step(src,direction)))
- air_check_directions |= direction
+ var/turf/simulated/floor/target = get_step(src,direction)
+ if(istype(target))
+ air_master.tiles_to_update |= target
- 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))
+/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)
+ ..()
- //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
+/turf/simulated/assume_air(datum/gas_mixture/giver)
+ if(!giver) return 0
+ if(zone)
+ zone.air.merge(giver)
+ return 1
+ else
+ return ..()
- if(zone && !zone.rebuild)
- for(var/direction in cardinal)
- var/turf/T = get_step(src,direction)
+/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)
+ 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))
- //I can connect to air in this direction
- if(air_check_directions&direction)
+ //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 either block air, we must look to see if the adjacent turfs need rebuilt.
- if(!CanPass(null, T, 0, 0))
+ if(zone && !zone.rebuild)
+ for(var/direction in cardinal)
+ var/turf/T = get_step(src,direction)
+ if(!istype(T))
+ continue
- //Target blocks air
- if(!T.CanPass(null, T, 0, 0))
- var/turf/NT = get_step(T, direction)
+ //I can connect to air in this direction
+ if(air_check_directions&direction)
- //If that turf is in my zone still, rebuild.
- if(istype(NT,/turf/simulated) && NT in zone.contents)
- zone.rebuild = 1
+ //If either block air, we must look to see if the adjacent turfs need rebuilt.
+ if(!CanPass(null, T, 0, 0))
- //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)
+ //Target blocks air
+ if(!T.CanPass(null, T, 0, 0))
var/turf/NT = get_step(T, direction)
- //If the tile is in our own zone, and we cannot connect to it, better rebuild.
+ //If that turf is in my zone still, 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.
+ //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
-
- //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(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~
- //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))
+ //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
- //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
+ //Needs rebuilt.
if(consider_rebuild)
- zone.rebuild = 1
+ T.zone.rebuild = 1
//Not adjacent to anything, and unsimulated. Goodbye~
else
- zone.RemoveTurf(NT)
+ T.zone.RemoveTurf(NT)
- if(air_check_directions)
- processing = 1
- else
- processing = 0
- return 1
+ 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.
@@ -289,7 +277,7 @@ turf
else
return 1
-turf/proc/ZCanPass(turf/simulated/T, var/include_space = 0)
+/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
@@ -314,7 +302,7 @@ turf/proc/ZCanPass(turf/simulated/T, var/include_space = 0)
return 1
-turf/proc/ZAirPass(turf/T)
+/turf/proc/ZAirPass(turf/T)
//Fairly standard pass checks for turfs, objects and directional windows.
if(!istype(T))
return 0
@@ -336,7 +324,6 @@ turf/proc/ZAirPass(turf/T)
return 1
-
/*UNUSED
/turf/proc/check_connections()
//Checks for new connections that can be made.
diff --git a/code/ZAS/ZAS_Zones.dm b/code/ZAS/ZAS_Zones.dm
index 2f5d564b3b4..bc432289821 100644
--- a/code/ZAS/ZAS_Zones.dm
+++ b/code/ZAS/ZAS_Zones.dm
@@ -2,129 +2,126 @@ 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.
- rebuild = 0 //If 1, zone will be rebuilt on next process. Not sure if used.
- datum/gas_mixture/air //The air contents of the zone.
- list/contents //All the tiles that are contained in this zone.
- list/connections // /connection objects which refer to connections with other zones, e.g. through a door.
- list/connected_zones //Parallels connections, but lists zones to which this one is connected and the number
+/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/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.
- list/closed_connection_zones //Same as connected_zones, but for zones where the door or whatever is closed.
- list/unsimulated_tiles // Any space tiles in this list will cause air to flow out.
- last_update = 0
- progress = "nothing"
-
- // To make sure you're not spammed to death by airflow sound effects
- tmp/playsound_cooldown = 0
+ 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/last_update = 0
+ var/progress = "nothing"
//CREATION AND DELETION
- New(turf/start)
- . = ..()
- //Get the turfs that are part of the zone using a floodfill method
- if(istype(start,/list))
- contents = start
- else
- contents = FloodFill(start)
+/zone/New(turf/start)
+ . = ..()
+ //Get the turfs that are part of the zone using a floodfill method
+ if(istype(start,/list))
+ contents = start
+ else
+ contents = FloodFill(start)
- //Change all the zone vars of the turfs, check for space to be added to unsimulated_tiles.
- for(var/turf/T in contents)
- if(T.zone && T.zone != src)
- T.zone.RemoveTurf(T)
- T.zone = src
- if(!istype(T,/turf/simulated))
- AddTurf(T)
+ //Change all the zone vars of the turfs, check for space to be added to unsimulated_tiles.
+ for(var/turf/T in contents)
+ if(T.zone && T.zone != src)
+ T.zone.RemoveTurf(T)
+ T.zone = src
+ if(!istype(T,/turf/simulated))
+ AddTurf(T)
- //Generate the gas_mixture for use in txhis zone by using the average of the gases
- //defined at startup.
- air = new
- var/members = contents.len
- for(var/turf/simulated/T in contents)
- air.oxygen += T.oxygen / members
- air.nitrogen += T.nitrogen / members
- air.carbon_dioxide += T.carbon_dioxide / members
- air.toxins += T.toxins / members
- air.temperature += T.temperature / members
- air.group_multiplier = contents.len
- air.update_values()
+ //Generate the gas_mixture for use in txhis zone by using the average of the gases
+ //defined at startup.
+ air = new
+ air.group_multiplier = contents.len
+ for(var/turf/simulated/T in contents)
+ air.oxygen += T.oxygen / air.group_multiplier
+ air.nitrogen += T.nitrogen / air.group_multiplier
+ air.carbon_dioxide += T.carbon_dioxide / air.group_multiplier
+ air.toxins += T.toxins / air.group_multiplier
+ air.temperature += T.temperature / air.group_multiplier
+ air.update_values()
- //Add this zone to the global list.
- zones.Add(src)
+ //Add this zone to the global list.
+ zones.Add(src)
//LEGACY, DO NOT USE. Use the SoftDelete proc.
- 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
- 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 = null
- . = ..()
+/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
+ 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 = null
+ . = ..()
//Handles deletion via garbage collection.
- proc/SoftDelete()
- zones.Remove(src)
- air = null
+/zone/proc/SoftDelete()
+ zones.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
+ //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
- //Removing zone connections and scheduling connection cleanup
- 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
+ //Removing zone connections and scheduling connection cleanup
+ for(var/zone/Z in connected_zones)
+ if(src in Z.connected_zones)
+ Z.connected_zones.Remove(src)
+ connected_zones = null
- return 1
+ for(var/connection/C in connections)
+ air_master.connections_to_check += C
+ connections = null
+
+ return 1
//ZONE MANAGEMENT FUNCTIONS
- proc/AddTurf(turf/T)
- //Adds the turf to contents, increases the size of the zone, and sets the zone var.
- if(istype(T, /turf/simulated))
- if(T in contents)
- return
- if(T.zone)
- T.zone.RemoveTurf(T)
- contents += T
- if(air)
- air.group_multiplier++
- T.zone = src
- else
- if(!unsimulated_tiles)
- unsimulated_tiles = list()
- else if(T in unsimulated_tiles)
- return
- unsimulated_tiles += T
- contents -= T
+/zone/proc/AddTurf(turf/T)
+ //Adds the turf to contents, increases the size of the zone, and sets the zone var.
+ if(istype(T, /turf/simulated))
+ if(T in contents)
+ return
+ if(T.zone)
+ T.zone.RemoveTurf(T)
+ contents += T
+ if(air)
+ air.group_multiplier++
+ T.zone = src
+ else
+ if(!unsimulated_tiles)
+ unsimulated_tiles = list()
+ else if(T in unsimulated_tiles)
+ return
+ unsimulated_tiles += T
+ contents -= T
- proc/RemoveTurf(turf/T)
- //Same, but in reverse.
- if(istype(T, /turf/simulated))
- if(!(T in contents))
- return
- contents -= T
- if(air)
- air.group_multiplier--
- if(T.zone == src)
- T.zone = null
- else if(unsimulated_tiles)
- unsimulated_tiles -= T
- if(!unsimulated_tiles.len)
- unsimulated_tiles = null
+/zone/proc/RemoveTurf(turf/T)
+ //Same, but in reverse.
+ if(istype(T, /turf/simulated))
+ if(!(T in contents))
+ return
+ contents -= T
+ if(air)
+ air.group_multiplier--
+ if(T.zone == src)
+ T.zone = null
+ else if(unsimulated_tiles)
+ unsimulated_tiles -= T
+ if(!unsimulated_tiles.len)
+ unsimulated_tiles = null
//////////////
//PROCESSING//
@@ -132,7 +129,7 @@ zone
#define QUANTIZE(variable) (round(variable,0.0001))
-zone/proc/process()
+/zone/proc/process()
. = 1
progress = "problem with: SoftDelete()"
@@ -151,7 +148,7 @@ zone/proc/process()
if(!contents.len) //If we got soft deleted.
return
- progress = "problem with: air.adjust()"
+ progress = "problem with: air regeneration"
//Sometimes explosions will cause the air to be deleted for some reason.
if(!air)
@@ -162,36 +159,23 @@ zone/proc/process()
air.total_moles()
world.log << "Air object lost in zone. Regenerating."
- progress = "problem with: ShareSpace()"
+ progress = "problem with: ShareSpace()"
if(unsimulated_tiles)
if(locate(/turf/simulated) in unsimulated_tiles)
for(var/turf/simulated/T in unsimulated_tiles)
- RemoveTurf(T)
- if(unsimulated_tiles)
+ unsimulated_tiles -= T
+
+ if(unsimulated_tiles.len)
var/moved_air = ShareSpace(air,unsimulated_tiles)
- // Only play a sound effect every once in a while
- if(playsound_cooldown <= world.time)
- // Play a nice sound effect at one of the bordering turfs
-
- playsound_cooldown = world.time + rand(30, 70)
-
- var/turf/random_border = pick(contents)
- play_wind_sound(random_border, abs(moved_air))
-
if(moved_air > vsc.airflow_lightest_pressure)
AirflowSpace(src)
-
- progress = "problem with: air.react()"
-
- //React the air here.
- //Handled by fire, no need for this.
-// air.react(null,0)
+ else
+ unsimulated_tiles = null
//Check the graphic.
-
progress = "problem with: modifying turf graphics"
air.graphic = 0
@@ -246,12 +230,13 @@ zone/proc/process()
//Check if the connection is valid first.
if(!C.Cleanup())
continue
+
//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 )
+ if( C.indirect == 2 )
if(C.A.zone.air.compare(C.B.zone.air) || unsimulated_tiles)
ZMerge(C.A.zone,C.B.zone)
@@ -259,18 +244,13 @@ zone/proc/process()
//Share some
for(var/zone/Z in connected_zones)
+ //If that zone has already processed, skip it.
+ if(Z.last_update > last_update)
+ continue
+
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)
- // Only play a sound effect every once in a while
- if(playsound_cooldown <= world.time)
- // Play a nice sound effect at one of the bordering turfs
-
- playsound_cooldown = world.time + rand(30, 70)
-
- var/turf/random_border = pick(contents)
- play_wind_sound(random_border, abs(moles_delta))
if(moles_delta > 0.1 || abs(air.temperature - Z.air.temperature) > 0.1)
if(abs(Z.air.return_pressure() - air.return_pressure()) > vsc.airflow_lightest_pressure)
Airflow(src,Z)
@@ -283,8 +263,11 @@ zone/proc/process()
ShareRatio( air , Z.air , connected_zones[Z] + unsimulated_boost)
for(var/zone/Z in closed_connection_zones)
+ //If that zone has already processed, skip it.
+ if(Z.last_update > last_update)
+ continue
if(air && Z.air)
- if( abs(air.temperature - Z.air.temperature) > 10 )
+ if( abs(air.temperature - Z.air.temperature) > vsc.connection_temperature_delta )
ShareHeat(air, Z.air, closed_connection_zones[Z])
progress = "all components completed successfully, the problem is not here"
@@ -293,7 +276,7 @@ zone/proc/process()
//Air Movement//
////////////////
-var/list/sharing_lookup_table = list(0.15, 0.20, 0.24, 0.27, 0.30, 0.33)
+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.
@@ -423,7 +406,9 @@ 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]
- ratio *= 2
+
+ //We need to adjust it to account for the insulation settings.
+ ratio *= 1 - vsc.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 )
@@ -543,22 +528,6 @@ zone/proc/Rebuild()
if(istype(T) && T.zone && S.CanPass(null, T, 0, 0))
T.zone.AddTurf(S)
-
-proc/play_wind_sound(var/turf/random_border, var/n)
- if(random_border)
- var/windsound = 'sound/effects/wind/wind_2_1.ogg'
- switch(n)
- if(31 to 40)
- windsound = pick('sound/effects/wind/wind_2_1.ogg', 'sound/effects/wind/wind_2_2.ogg')
- if(41 to 50)
- windsound = pick('sound/effects/wind/wind_3_1.ogg')
- if(51 to 60)
- windsound = pick('sound/effects/wind/wind_4_1.ogg', 'sound/effects/wind/wind_4_2.ogg')
- if(61 to 1000000)
- windsound = pick('sound/effects/wind/wind_5_1.ogg')
-
- playsound(random_border, windsound, 50, 1, 1)
-
//UNUSED
/*
zone/proc/connected_zones()
diff --git a/code/controllers/master_controller.dm b/code/controllers/master_controller.dm
index c22bf1e2dd8..22a905a2070 100644
--- a/code/controllers/master_controller.dm
+++ b/code/controllers/master_controller.dm
@@ -132,12 +132,12 @@ datum/controller/game_controller/proc/process()
//src.set_debug_state("Air Master")
air_master.current_cycle++
- var/success = air_master.tick() //Changed so that a runtime does not crash the ticker.
- if(!success) //Runtimed.
+ if(!air_master.tick()) //Runtimed.
air_master.failed_ticks++
if(air_master.failed_ticks > 5)
world << "RUNTIMES IN ATMOS TICKER. Killing air simulation!"
- message_admins("ZASALERT: unable run [air_master.tick_progress], tell someone about this!")
+ world.log << "### ZAS SHUTDOWN"
+ message_admins("ZASALERT: unable to run [air_master.tick_progress], shutting down!")
log_admin("ZASALERT: unable run zone/process() -- [air_master.tick_progress]")
air_processing_killed = 1
air_master.failed_ticks = 0
diff --git a/code/datums/datacore.dm b/code/datums/datacore.dm
index 904761eba83..76cab54fd93 100644
--- a/code/datums/datacore.dm
+++ b/code/datums/datacore.dm
@@ -58,6 +58,10 @@
G.fields["sex"] = H.gender
G.fields["species"] = H.get_species()
G.fields["photo"] = get_id_photo(H)
+ if(H.gen_record && !jobban_isbanned(H, "Records"))
+ G.fields["notes"] = H.gen_record
+ else
+ G.fields["notes"] = "No notes found."
general += G
//Medical Record
diff --git a/code/datums/datumvars.dm b/code/datums/datumvars.dm
index 81abf92546a..cafc1c58cd3 100644
--- a/code/datums/datumvars.dm
+++ b/code/datums/datumvars.dm
@@ -256,9 +256,12 @@ client
body += ""
body += ""
+ body += ""
+ body += ""
if(ishuman(D))
body += ""
body += ""
+ body += ""
body += ""
body += ""
body += ""
@@ -743,6 +746,63 @@ client
H.dna.mutantrace = new_mutantrace
H.update_mutantrace()
+ else if(href_list["setspecies"])
+ if(!check_rights(R_SPAWN)) return
+
+ var/mob/living/carbon/human/H = locate(href_list["setspecies"])
+ if(!istype(H))
+ usr << "This can only be done to instances of type /mob/living/carbon/human"
+ return
+
+ var/datum/species/new_species = input("Please choose a new species.","Species",null) as null|anything in (typesof(/datum/species)-/datum/species)
+
+ if(!H)
+ usr << "Mob doesn't exist anymore"
+ return
+
+ if(H.set_species(new new_species))
+ usr << "Set species of [H] to [H.species]."
+ else
+ usr << "Failed! Something went wrong."
+
+ else if(href_list["addlanguage"])
+ if(!check_rights(R_SPAWN)) return
+
+ var/mob/H = locate(href_list["addlanguage"])
+ if(!istype(H))
+ usr << "This can only be done to instances of type /mob"
+ return
+
+ var/datum/language/new_language = input("Please choose a language to add.","Language",null) as null|anything in (typesof(/datum/language)-/datum/language)
+
+ if(!H)
+ usr << "Mob doesn't exist anymore"
+ return
+
+ if(H.add_language(new new_language))
+ usr << "Added [new_language] to [H]."
+ else
+ usr << "Mob already knows that language."
+
+ else if(href_list["remlanguage"])
+ if(!check_rights(R_SPAWN)) return
+
+ var/mob/H = locate(href_list["remlanguage"])
+ if(!istype(H))
+ usr << "This can only be done to instances of type /mob"
+ return
+
+ var/datum/language/rem_language = input("Please choose a language to remove.","Language",null) as null|anything in H.languages
+
+ if(!H)
+ usr << "Mob doesn't exist anymore"
+ return
+
+ if(H.remove_language(rem_language))
+ usr << "Removed [rem_language] from [H]."
+ else
+ usr << "Mob doesn't know that language."
+
else if(href_list["regenerateicons"])
if(!check_rights(0)) return
diff --git a/code/datums/supplypacks.dm b/code/datums/supplypacks.dm
index 57ddf7817e5..b3b03e6ac26 100755
--- a/code/datums/supplypacks.dm
+++ b/code/datums/supplypacks.dm
@@ -356,10 +356,12 @@ var/list/all_supply_groups = list("Operations","Security","Hospitality","Enginee
/obj/item/weapon/storage/firstaid/fire,
/obj/item/weapon/storage/firstaid/toxin,
/obj/item/weapon/storage/firstaid/o2,
+ /obj/item/weapon/storage/firstaid/adv,
/obj/item/weapon/reagent_containers/glass/bottle/antitoxin,
/obj/item/weapon/reagent_containers/glass/bottle/inaprovaline,
/obj/item/weapon/reagent_containers/glass/bottle/stoxin,
- /obj/item/weapon/storage/box/syringes)
+ /obj/item/weapon/storage/box/syringes,
+ /obj/item/weapon/storage/box/autoinjectors)
cost = 10
containertype = /obj/structure/closet/crate/medical
containername = "Medical crate"
diff --git a/code/defines/obj.dm b/code/defines/obj.dm
index 661f4c43b38..a4ef521d9d7 100644
--- a/code/defines/obj.dm
+++ b/code/defines/obj.dm
@@ -51,7 +51,7 @@
//This list tracks characters spawned in the world and cannot be modified in-game. Currently referenced by respawn_character().
var/locked[] = list()
- proc/get_manifest(monochrome)
+ proc/get_manifest(monochrome, OOC)
var/list/heads = new()
var/list/sec = new()
var/list/eng = new()
@@ -80,7 +80,15 @@
var/name = t.fields["name"]
var/rank = t.fields["rank"]
var/real_rank = t.fields["real_rank"]
- isactive[name] = t.fields["p_stat"]
+ if(OOC)
+ var/active = 0
+ for(var/mob/M in player_list)
+ if(M.real_name == name && M.client && M.client.inactivity <= 10 * 60 * 10)
+ active = 1
+ break
+ isactive[name] = active ? "Active" : "Inactive"
+ else
+ isactive[name] = t.fields["p_stat"]
//world << "[name]: [rank]"
diff --git a/code/defines/obj/hydro.dm b/code/defines/obj/hydro.dm
index 9e26cb48fdb..bfea9a3b22b 100644
--- a/code/defines/obj/hydro.dm
+++ b/code/defines/obj/hydro.dm
@@ -81,30 +81,6 @@
plant_type = 2
growthstages = 3
-/obj/item/seeds/replicapod
- name = "pack of replica pod seeds"
- desc = "These seeds grow into replica pods. They say these are used to harvest humans."
- icon_state = "seed-replicapod"
- mypath = "/obj/item/seeds/replicapod"
- species = "replicapod"
- plantname = "Replica Pod"
- productname = "/mob/living/carbon/human" //verrry special -- Urist
- lifespan = 50 //no idea what those do
- endurance = 8
- maturation = 10
- production = 10
- yield = 1 //seeds if there isn't a dna inside
- oneharvest = 1
- potency = 30
- plant_type = 0
- growthstages = 6
- var/ui = null //for storing the guy
- var/se = null
- var/ckey = null
- var/realName = null
- var/datum/mind/mind = null
- gender = MALE
-
/obj/item/seeds/grapeseed
name = "pack of grape seeds"
desc = "These seeds grow into grape vines."
diff --git a/code/game/area/Space Station 13 areas.dm b/code/game/area/Space Station 13 areas.dm
index 049d7f0cd70..fd034fbf5ae 100755
--- a/code/game/area/Space Station 13 areas.dm
+++ b/code/game/area/Space Station 13 areas.dm
@@ -309,6 +309,11 @@ proc/process_ghost_teleport_locs()
/area/shuttle/research/outpost
icon_state = "shuttle"
+/area/shuttle/vox/station
+ name = "\improper Vox Skipjack"
+ icon_state = "yellow"
+ requires_power = 0
+
/area/airtunnel1/ // referenced in airtunnel.dm:759
/area/dummy/ // Referenced in engine.dm:261
@@ -489,10 +494,29 @@ proc/process_ghost_teleport_locs()
icon_state = "yellow"
requires_power = 0
+/area/vox_station/transit
+ name = "\improper hyperspace"
+ icon_state = "shuttle"
+/area/vox_station/southwest_solars
+ name = "\improper aft port solars"
+ icon_state = "southwest"
+/area/vox_station/northwest_solars
+ name = "\improper fore port solars"
+ icon_state = "northwest"
+/area/vox_station/northeast_solars
+ name = "\improper fore starboard solars"
+ icon_state = "northeast"
+/area/vox_station/southeast_solars
+ name = "\improper aft starboard solars"
+ icon_state = "southeast"
+
+/area/vox_station/mining
+ name = "\improper nearby mining asteroid"
+ icon_state = "north"
//PRISON
/area/prison
diff --git a/code/game/area/areas.dm b/code/game/area/areas.dm
index c0921cd54a1..1c9d5373300 100644
--- a/code/game/area/areas.dm
+++ b/code/game/area/areas.dm
@@ -47,6 +47,10 @@
var/list/cameras = list()
for (var/obj/machinery/camera/C in src)
cameras += C
+ if(state == 1)
+ C.network.Remove("Power Alarms")
+ else
+ C.network.Add("Power Alarms")
for (var/mob/living/silicon/aiPlayer in player_list)
if(aiPlayer.z == source.z)
if (state == 1)
@@ -73,11 +77,15 @@
//updateicon()
for(var/obj/machinery/camera/C in RA)
cameras += C
+ C.network.Add("Atmosphere Alarms")
for(var/mob/living/silicon/aiPlayer in player_list)
aiPlayer.triggerAlarm("Atmosphere", src, cameras, src)
for(var/obj/machinery/computer/station_alert/a in machines)
a.triggerAlarm("Atmosphere", src, cameras, src)
else if (atmosalm == 2)
+ for(var/area/RA in related)
+ for(var/obj/machinery/camera/C in RA)
+ C.network.Remove("Atmosphere Alarms")
for(var/mob/living/silicon/aiPlayer in player_list)
aiPlayer.cancelAlarm("Atmosphere", src, src)
for(var/obj/machinery/computer/station_alert/a in machines)
@@ -101,8 +109,10 @@
spawn()
D.close()
var/list/cameras = list()
- for (var/obj/machinery/camera/C in src)
- cameras += C
+ for(var/area/RA in related)
+ for (var/obj/machinery/camera/C in RA)
+ cameras.Add(C)
+ C.network.Add("Fire Alarms")
for (var/mob/living/silicon/ai/aiPlayer in player_list)
aiPlayer.triggerAlarm("Fire", src, cameras, src)
for (var/obj/machinery/computer/station_alert/a in machines)
@@ -120,6 +130,9 @@
else if(D.density)
spawn(0)
D.open()
+ for(var/area/RA in related)
+ for (var/obj/machinery/camera/C in RA)
+ C.network.Remove("Fire Alarms")
for (var/mob/living/silicon/ai/aiPlayer in player_list)
aiPlayer.cancelAlarm("Fire", src, src)
for (var/obj/machinery/computer/station_alert/a in machines)
diff --git a/code/game/atoms.dm b/code/game/atoms.dm
index 784ba44c188..d160e662e84 100644
--- a/code/game/atoms.dm
+++ b/code/game/atoms.dm
@@ -490,7 +490,7 @@ its easier to just keep the beam vertical.
var/using_new_click_proc = 0 //TODO ERRORAGE (This is temporary, while the DblClickNew() proc is being tested)
-/atom/proc/DblClickNew()
+/*/atom/proc/DblClickNew()
if(!usr) return
// TODO DOOHL: Intergrate params to new proc. Saved for another time because var/valid_place is a fucking brainfuck
@@ -792,7 +792,7 @@ var/using_new_click_proc = 0 //TODO ERRORAGE (This is temporary, while the DblCl
if (in_range)
if ( !animal.restrained() )
- attack_animal(animal)
+ attack_animal(animal)*/
/atom/DblClick(location, control, params) //TODO: DEFERRED: REWRITE
if(!usr) return
@@ -943,9 +943,9 @@ var/using_new_click_proc = 0 //TODO ERRORAGE (This is temporary, while the DblCl
// ------- ( CAN USE ITEM OR HAS 1 SECOND USE DELAY ) AND NOT CLICKING ON SCREEN -------
- if (usr.next_move < world.time)
- usr.prev_move = usr.next_move
- usr.next_move = world.time + 10
+ if (usr.last_click + usr.click_delay < world.time)
+ usr.last_click = world.time
+ usr.click_delay = 0
else
// ------- ALREADY USED ONE ITEM WITH USE DELAY IN THE PREVIOUS SECOND -------
return
@@ -1109,10 +1109,9 @@ var/using_new_click_proc = 0 //TODO ERRORAGE (This is temporary, while the DblCl
// ------- ITEM INACESSIBLE OR CLICKING ON SCREEN -------
if (istype(src, /obj/screen))
// ------- IT'S THE HUD YOU'RE CLICKING ON -------
- usr.prev_move = usr.next_move
- usr:lastDblClick = world.time + 2
- if (usr.next_move < world.time)
- usr.next_move = world.time + 2
+ usr.delay_click(2)
+ if (usr.last_click + usr.click_delay < world.time)
+ usr.last_click = world.time
else
return
@@ -1144,7 +1143,7 @@ var/using_new_click_proc = 0 //TODO ERRORAGE (This is temporary, while the DblCl
src.hand_al(usr, usr.hand)
else
// ------- YOU ARE CLICKING ON AN OBJECT THAT'S INACCESSIBLE TO YOU AND IS NOT YOUR HUD -------
- if((LASER in usr:mutations) && usr:a_intent == "hurt" && world.time >= usr.next_move)
+ if((LASER in usr:mutations) && usr:a_intent == "hurt" && usr.last_click + usr.click_delay < world.time)
// ------- YOU HAVE THE LASER MUTATION, YOUR INTENT SET TO HURT AND IT'S BEEN MORE THAN A DECISECOND SINCE YOU LAS TATTACKED -------
var/turf/T = get_turf(usr)
@@ -1169,7 +1168,7 @@ var/using_new_click_proc = 0 //TODO ERRORAGE (This is temporary, while the DblCl
spawn( 1 )
A.process()
- usr.next_move = world.time + 6
+ usr.delay_click(6)
return
/atom/proc/ShiftClick(var/mob/M as mob)
diff --git a/code/game/communications.dm b/code/game/communications.dm
index 94d53f6bf52..32d8ca69348 100644
--- a/code/game/communications.dm
+++ b/code/game/communications.dm
@@ -74,7 +74,6 @@ Radio:
1359 - Security
1441 - death squad
1443 - Confession Intercom
-1349 - Miners
1347 - Cargo techs
Devices:
@@ -110,10 +109,21 @@ var/list/radiochannels = list(
"Supply" = 1347,
)
//depenging helpers
-var/list/DEPT_FREQS = list(1351,1355,1357,1359,1213, 1443, 1441,1347)
+var/list/DEPT_FREQS = list(1351, 1355, 1357, 1359, 1213, 1443, 1441, 1347)
+
+// central command channels, i.e deathsquid & response teams
+var/list/CENT_FREQS = list(1441, 1443)
+
var/const/COMM_FREQ = 1353 //command, colored gold in chat window
var/const/SYND_FREQ = 1213
+// department channels
+var/const/SEC_FREQ = 1359
+var/const/ENG_FREQ = 1357
+var/const/SCI_FREQ = 1351
+var/const/MED_FREQ = 1355
+var/const/SUP_FREQ = 1347
+
#define TRANSMISSION_WIRE 0
#define TRANSMISSION_RADIO 1
diff --git a/code/game/gamemodes/blob/blob.dm b/code/game/gamemodes/blob/blob.dm
index 7cca20dfac0..e53053764b2 100644
--- a/code/game/gamemodes/blob/blob.dm
+++ b/code/game/gamemodes/blob/blob.dm
@@ -6,7 +6,7 @@ var/list/blob_cores = list()
var/list/blob_nodes = list()
-/datum/game_mode/blob
+/*/datum/game_mode/blob
name = "blob"
config_tag = "blob"
required_players = 0
@@ -130,3 +130,4 @@ var/list/blob_nodes = list()
stage = 3
return
+*/
\ No newline at end of file
diff --git a/code/game/gamemodes/cult/runes.dm b/code/game/gamemodes/cult/runes.dm
index 9366cd00523..e73cfeb9422 100644
--- a/code/game/gamemodes/cult/runes.dm
+++ b/code/game/gamemodes/cult/runes.dm
@@ -389,7 +389,7 @@ var/list/sacrificed = list()
var/chose_name = 0
for(var/obj/item/weapon/paper/P in this_rune.loc)
if(P.info)
- D.real_name = copytext(P.info, 1, MAX_NAME_LEN)
+ D.real_name = copytext(P.info, findtext(P.info,">")+1, findtext(P.info,"<",2) )
chose_name = 1
break
if(!chose_name)
diff --git a/code/game/gamemodes/game_mode.dm b/code/game/gamemodes/game_mode.dm
index 85fdca943e9..bb627fd3bcf 100644
--- a/code/game/gamemodes/game_mode.dm
+++ b/code/game/gamemodes/game_mode.dm
@@ -278,6 +278,7 @@ Implants;
if(BE_REV) roletext="revolutionary"
if(BE_CULTIST) roletext="cultist"
if(BE_NINJA) roletext="ninja"
+ if(BE_RAIDER) roletext="raider"
// Assemble a list of active players without jobbans.
for(var/mob/new_player/player in player_list)
diff --git a/code/game/gamemodes/heist/heist.dm b/code/game/gamemodes/heist/heist.dm
new file mode 100644
index 00000000000..fa4299c3c1b
--- /dev/null
+++ b/code/game/gamemodes/heist/heist.dm
@@ -0,0 +1,252 @@
+/*
+VOX HEIST ROUNDTYPE
+*/
+
+#define MAX_VOX_KILLS 10 //Number of kills during the round before the Inviolate is broken.
+ //Would be nice to use vox-specific kills but is currently not feasible.
+
+var/global/vox_kills = 0 //Used to check the Inviolate.
+
+/datum/game_mode/heist
+ name = "heist"
+ config_tag = "heist"
+ required_players = 15
+ required_players_secret = 25
+ required_enemies = 4
+ recommended_enemies = 6
+
+ var/const/waittime_l = 600 //lower bound on time before intercept arrives (in tenths of seconds)
+ var/const/waittime_h = 1800 //upper bound on time before intercept arrives (in tenths of seconds)
+
+ var/list/raid_objectives = list() //Raid objectives.
+ var/list/datum/mind/raiders = list() //Antags.
+ var/list/obj/cortical_stacks = list() //Stacks for 'leave nobody behind' objective.
+
+/datum/game_mode/heist/announce()
+ world << "The current game mode is - Heist!"
+ world << "An unidentified bluespace signature has slipped past the Icarus and is approaching [station_name()]!"
+ world << "Whoever they are, they're likely up to no good. Protect the crew and station resources against this dastardly threat!"
+ world << "Raiders: Loot [station_name()] for anything and everything you need."
+ world << "Personnel: Repel the raiders and their low, low prices and/or crossbows."
+
+/datum/game_mode/heist/can_start()
+
+ if(!..())
+ return 0
+
+ var/list/candidates = get_players_for_role(BE_RAIDER)
+ var/raider_num = 0
+
+ //Check that we have enough vox.
+ if(candidates.len < required_enemies)
+ return 0
+ else if(candidates.len < recommended_enemies)
+ raider_num = candidates.len
+ else
+ raider_num = recommended_enemies
+
+ //Grab candidates randomly until we have enough.
+ while(raider_num > 0)
+ var/datum/mind/new_raider = pick(candidates)
+ raiders += new_raider
+ candidates -= new_raider
+ raider_num--
+
+ for(var/datum/mind/raider in raiders)
+ raider.assigned_role = "MODE"
+ raider.special_role = "Vox Raider"
+ return 1
+
+/datum/game_mode/heist/pre_setup()
+ return 1
+
+/datum/game_mode/heist/post_setup()
+
+ //Build a list of spawn points.
+ var/list/turf/raider_spawn = list()
+
+ for(var/obj/effect/landmark/L in landmarks_list)
+ if(L.name == "voxstart")
+ raider_spawn += get_turf(L)
+ del(L)
+ continue
+
+ //Generate objectives for the group.
+ raid_objectives = forge_vox_objectives()
+
+ var/index = 1
+
+ //Spawn the vox!
+ for(var/datum/mind/raider in raiders)
+
+ if(index > raider_spawn.len)
+ index = 1
+
+ raider.current.loc = raider_spawn[index]
+ index++
+
+ var/sounds = rand(2,8)
+ var/i = 0
+ var/newname = ""
+
+ while(i<=sounds)
+ i++
+ newname += pick(list("ti","hi","ki","ya","ta","ha","ka","ya","chi","cha","kah"))
+
+ var/mob/living/carbon/human/vox = raider.current
+
+ vox.languages += new /datum/language/vox
+ vox.real_name = capitalize(newname)
+ vox.name = vox.real_name
+ vox.age = rand(12,20)
+ vox.set_species(new /datum/species/vox)
+ vox.dna.mutantrace = "vox"
+ vox.h_style = "Short Vox Quills"
+ vox.equip_vox_raider()
+ vox.regenerate_icons()
+
+ raider.objectives = raid_objectives
+ greet_vox(raider)
+
+ spawn (rand(waittime_l, waittime_h))
+ send_intercept()
+
+/datum/game_mode/heist/proc/is_raider_crew_safe()
+
+ if(cortical_stacks.len == 0)
+ return 0
+
+ for(var/obj/stack in cortical_stacks)
+ if (get_area(stack) != locate(/area/shuttle/vox/station))
+ return 0
+ return 1
+
+/datum/game_mode/heist/proc/is_raider_crew_alive()
+
+ for(var/datum/mind/raider in raiders)
+ if(raider.current)
+ if(istype(raider.current,/mob/living/carbon/human) && raider.current.stat != 2)
+ return 1
+ return 0
+
+/datum/game_mode/heist/proc/forge_vox_objectives()
+
+
+ //Commented out for testing.
+ /* var/i = 1
+ var/max_objectives = pick(2,2,2,3,3)
+ var/list/objs = list()
+ while(i<= max_objectives)
+ var/list/goals = list("kidnap","loot","salvage")
+ var/goal = pick(goals)
+ var/datum/objective/heist/O
+
+ if(goal == "kidnap")
+ goals -= "kidnap"
+ O = new /datum/objective/heist/kidnap()
+ else if(goal == "loot")
+ O = new /datum/objective/heist/loot()
+ else
+ O = new /datum/objective/heist/salvage()
+ O.choose_target()
+ objs += O
+
+ i++
+
+ //-All- vox raids have these two objectives. Failing them loses the game.
+ objs += new /datum/objective/heist/inviolate_crew
+ objs += new /datum/objective/heist/inviolate_death */
+
+ raid_objectives += new /datum/objective/heist/kidnap
+ raid_objectives += new /datum/objective/heist/loot
+ raid_objectives += new /datum/objective/heist/salvage
+ raid_objectives += new /datum/objective/heist/inviolate_crew
+ raid_objectives += new /datum/objective/heist/inviolate_death
+
+ for(var/datum/objective/heist/O in raid_objectives)
+ O.choose_target()
+
+ return raid_objectives
+
+/datum/game_mode/heist/proc/greet_vox(var/datum/mind/raider)
+ raider.current << "\blue You are a Vox Raider, fresh from the Shoal!"
+ raider.current << "\blue The Vox are a race of cunning, sharp-eyed nomadic raiders and traders endemic to Tau Ceti and much of the unexplored galaxy. You and the crew have come to the Exodus for plunder, trade or both."
+ raider.current << "\blue Vox are cowardly and will flee from larger groups, but corner one or find them en masse and they are vicious."
+ raider.current << "\blue Use :V to voxtalk, :H to talk on your encrypted channel, and don't forget to turn on your nitrogen internals!"
+ var/obj_count = 1
+ for(var/datum/objective/objective in raider.objectives)
+ raider.current << "Objective #[obj_count]: [objective.explanation_text]"
+ obj_count++
+
+
+/datum/game_mode/heist/declare_completion()
+
+ //No objectives, go straight to the feedback.
+ if(!(raid_objectives.len)) return ..()
+
+ var/win_type = "Major"
+ var/win_group = "Crew"
+ var/win_msg = ""
+
+ var/success = raid_objectives.len
+
+ //Decrease success for failed objectives.
+ for(var/datum/objective/O in raid_objectives)
+ if(!(O.check_completion())) success--
+
+ //Set result by objectives.
+ if(success == raid_objectives.len)
+ win_type = "Major"
+ win_group = "Vox"
+ else if(success > 2)
+ win_type = "Minor"
+ win_group = "Vox"
+ else
+ win_type = "Minor"
+ win_group = "Crew"
+
+ //Now we modify that result by the state of the vox crew.
+ if(!is_raider_crew_alive())
+
+ win_type = "Major"
+ win_group = "Crew"
+ win_msg += "The Vox Raiders have been wiped out!"
+
+ else if(!is_raider_crew_safe())
+
+ if(win_group == "Crew" && win_type == "Minor")
+ win_type = "Major"
+
+ win_group = "Crew"
+ win_msg += "The Vox Raiders have left someone behind!"
+
+ else
+
+ if(win_group == "Vox")
+ if(win_type == "Minor")
+
+ win_type = "Major"
+ win_msg += "The Vox Raiders escaped the station!"
+ else
+ win_msg += "The Vox Raiders were repelled!"
+
+ world << "\red [win_type] [win_group] victory!"
+ world << "[win_msg]"
+ feedback_set_details("round_end_result","heist - [win_type] [win_group]")
+
+ var/count = 1
+ for(var/datum/objective/objective in raid_objectives)
+ if(objective.check_completion())
+ world << "
Objective #[count]: [objective.explanation_text] Success!"
+ feedback_add_details("traitor_objective","[objective.type]|SUCCESS")
+ else
+ world << "
Objective #[count]: [objective.explanation_text] Fail."
+ feedback_add_details("traitor_objective","[objective.type]|FAIL")
+ count++
+
+ ..()
+
+/datum/game_mode/heist/check_finished()
+ if (!(is_raider_crew_alive()) || (vox_shuttle_location && (vox_shuttle_location == "start")))
+ return 1
+ return ..()
\ No newline at end of file
diff --git a/code/game/gamemodes/nuclear/nuclearbomb.dm b/code/game/gamemodes/nuclear/nuclearbomb.dm
index 9d6e12c2223..7480555d694 100644
--- a/code/game/gamemodes/nuclear/nuclearbomb.dm
+++ b/code/game/gamemodes/nuclear/nuclearbomb.dm
@@ -15,6 +15,8 @@ var/bomb_set
var/yes_code = 0.0
var/safety = 1.0
var/obj/item/weapon/disk/nuclear/auth = null
+ var/removal_stage = 0 // 0 is no removal, 1 is covers removed, 2 is covers open,
+ // 3 is sealant open, 4 is unwrenched, 5 is removed from bolts.
flags = FPRINT
use_power = 0
@@ -33,14 +35,83 @@ var/bomb_set
src.attack_hand(M)
return
-/obj/machinery/nuclearbomb/attackby(obj/item/weapon/I as obj, mob/user as mob)
+/obj/machinery/nuclearbomb/attackby(obj/item/weapon/O as obj, mob/user as mob)
if (src.extended)
- if (istype(I, /obj/item/weapon/disk/nuclear))
+ if (istype(O, /obj/item/weapon/disk/nuclear))
usr.drop_item()
- I.loc = src
- src.auth = I
+ O.loc = src
+ src.auth = O
src.add_fingerprint(user)
return
+
+ if (src.anchored)
+ switch(removal_stage)
+ if(0)
+ if(istype(O,/obj/item/weapon/weldingtool))
+
+ var/obj/item/weapon/weldingtool/WT = O
+ if(!WT.isOn()) return
+ if (WT.get_fuel() < 5) // uses up 5 fuel.
+ user << "\red You need more fuel to complete this task."
+ return
+
+ user.visible_message("[user] starts cutting loose the anchoring bolt covers on [src].", "You start cutting loose the anchoring bolt covers with [O]...")
+
+ if(do_after(user,40))
+ if(!src || !user || !WT.remove_fuel(5, user)) return
+ user.visible_message("[user] cuts through the bolt covers on [src].", "You cut through the bolt cover.")
+ removal_stage = 1
+ return
+
+ if(1)
+ if(istype(O,/obj/item/weapon/crowbar))
+ user.visible_message("[user] starts forcing open the bolt covers on [src].", "You start forcing open the anchoring bolt covers with [O]...")
+
+ if(do_after(user,15))
+ if(!src || !user) return
+ user.visible_message("[user] forces open the bolt covers on [src].", "You force open the bolt covers.")
+ removal_stage = 2
+ return
+
+ if(2)
+ if(istype(O,/obj/item/weapon/weldingtool))
+
+ var/obj/item/weapon/weldingtool/WT = O
+ if(!WT.isOn()) return
+ if (WT.get_fuel() < 5) // uses up 5 fuel.
+ user << "\red You need more fuel to complete this task."
+ return
+
+ user.visible_message("[user] starts cutting apart the anchoring system sealant on [src].", "You start cutting apart the anchoring system's sealant with [O]...")
+
+ if(do_after(user,40))
+ if(!src || !user || !WT.remove_fuel(5, user)) return
+ user.visible_message("[user] cuts apart the anchoring system sealant on [src].", "You cut apart the anchoring system's sealant.")
+ removal_stage = 3
+ return
+
+ if(3)
+ if(istype(O,/obj/item/weapon/wrench))
+
+ user.visible_message("[user] begins unwrenching the anchoring bolts on [src].", "You begin unwrenching the anchoring bolts...")
+
+ if(do_after(user,50))
+ if(!src || !user) return
+ user.visible_message("[user] unwrenches the anchoring bolts on [src].", "You unwrench the anchoring bolts.")
+ removal_stage = 4
+ return
+
+ if(4)
+ if(istype(O,/obj/item/weapon/crowbar))
+
+ user.visible_message("[user] begins lifting [src] off of the anchors.", "You begin lifting the device off the anchors...")
+
+ if(do_after(user,80))
+ if(!src || !user) return
+ user.visible_message("[user] crowbars [src] off of the anchors. It can now be moved.", "You jam the crowbar under the nuclear device and lift it off its anchors. You can now move it!")
+ anchored = 0
+ removal_stage = 5
+ return
..()
/obj/machinery/nuclearbomb/attack_paw(mob/user as mob)
@@ -69,7 +140,11 @@ var/bomb_set
user << browse(dat, "window=nuclearbomb;size=300x400")
onclose(user, "nuclearbomb")
else if (src.deployable)
- src.anchored = 1
+ if(removal_stage < 5)
+ src.anchored = 1
+ visible_message("\red With a steely snap, bolts slide out of [src] and anchor it to the flooring!")
+ else
+ visible_message("\red \The [src] makes a highly unpleasant crunching noise. It looks like the anchoring bolts have been cut.")
flick("nuclearbombc", src)
src.icon_state = "nuclearbomb1"
src.extended = 1
@@ -81,8 +156,10 @@ var/bomb_set
set src in oview(1)
if (src.deployable)
+ usr << "\red You close several panels to make [src] undeployable."
src.deployable = 0
else
+ usr << "\red You adjust some panels to make [src] deployable."
src.deployable = 1
/obj/machinery/nuclearbomb/Topic(href, href_list)
@@ -148,7 +225,18 @@ var/bomb_set
src.timing = 0
bomb_set = 0
if (href_list["anchor"])
+
+ if(removal_stage == 5)
+ src.anchored = 0
+ visible_message("\red \The [src] makes a highly unpleasant crunching noise. It looks like the anchoring bolts have been cut.")
+ return
+
src.anchored = !( src.anchored )
+ if(src.anchored)
+ visible_message("\red With a steely snap, bolts slide out of [src] and anchor it to the flooring.")
+ else
+ visible_message("\red The anchoring bolts slide back into the depths of [src].")
+
src.add_fingerprint(usr)
for(var/mob/M in viewers(1, src))
if ((M.client && M.machine == src))
diff --git a/code/game/gamemodes/objective.dm b/code/game/gamemodes/objective.dm
index 1b3552408c5..3d154485133 100644
--- a/code/game/gamemodes/objective.dm
+++ b/code/game/gamemodes/objective.dm
@@ -742,3 +742,173 @@ datum/objective/absorb
/*-------ENDOF CULTIST------*/
*/
+
+//Vox heist objectives.
+
+datum/objective/heist
+ proc/choose_target()
+ return
+
+datum/objective/heist/kidnap
+ choose_target()
+ var/list/roles = list("Chief Engineer","Research Director","Roboticist","Chemist","Station Engineer")
+ var/list/possible_targets = list()
+ var/list/priority_targets = list()
+
+ for(var/datum/mind/possible_target in ticker.minds)
+ if(possible_target != owner && ishuman(possible_target.current) && (possible_target.current.stat != 2) && (possible_target.assigned_role != "MODE"))
+ possible_targets += possible_target
+ for(var/role in roles)
+ if(possible_target.assigned_role == role)
+ priority_targets += possible_target
+ continue
+
+ if(priority_targets.len > 0)
+ target = pick(priority_targets)
+ else if(possible_targets.len > 0)
+ target = pick(possible_targets)
+
+ if(target && target.current)
+ explanation_text = "The Shoal has a need for [target.current.real_name], the [target.assigned_role]. Take them alive."
+ else
+ explanation_text = "Free Objective"
+ return target
+
+ check_completion()
+ if(target && target.current)
+ if (target.current.stat == 2)
+ return 0 // They're dead. Fail.
+ //if (!target.current.restrained())
+ // return 0 // They're loose. Close but no cigar.
+
+ var/area/shuttle/vox/station/A = locate()
+ for(var/mob/living/carbon/human/M in A)
+ if(target.current == M)
+ return 1 //They're restrained on the shuttle. Success.
+ else
+ return 0
+
+datum/objective/heist/loot
+
+ choose_target()
+ var/loot = "an object"
+ switch(rand(1,8))
+ if(1)
+ target = /obj/structure/particle_accelerator
+ target_amount = 6
+ loot = "a complete particle accelerator"
+ if(2)
+ target = /obj/machinery/the_singularitygen
+ target_amount = 1
+ loot = "a gravitational generator"
+ if(3)
+ target = /obj/machinery/power/emitter
+ target_amount = 4
+ loot = "four emitters"
+ if(4)
+ target = /obj/machinery/nuclearbomb
+ target_amount = 1
+ loot = "a nuclear bomb"
+ if(5)
+ target = /obj/item/weapon/gun
+ target_amount = 6
+ loot = "six guns"
+ if(6)
+ target = /obj/item/weapon/gun/energy
+ target_amount = 4
+ loot = "four energy guns"
+ if(7)
+ target = /obj/item/weapon/gun/energy/laser
+ target_amount = 2
+ loot = "two laser guns"
+ if(8)
+ target = /obj/item/weapon/gun/energy/ionrifle
+ target_amount = 1
+ loot = "an ion gun"
+
+ explanation_text = "We are lacking in hardware. Steal [loot]."
+
+ check_completion()
+
+ var/total_amount = 0
+
+ for(var/obj/O in locate(/area/shuttle/vox/station))
+ if(istype(O,target)) total_amount++
+ if(total_amount >= target_amount) return 1
+
+ var/datum/game_mode/heist/H = ticker.mode
+ for(var/datum/mind/raider in H.raiders)
+ if(raider.current)
+ for(var/obj/O in raider.current.get_contents())
+ if(istype(O,target)) total_amount++
+ if(total_amount >= target_amount) return 1
+
+ return 0
+
+datum/objective/heist/salvage
+
+ choose_target()
+ switch(rand(1,8))
+ if(1)
+ target = "metal"
+ target_amount = 300
+ if(2)
+ target = "glass"
+ target_amount = 200
+ if(3)
+ target = "plasteel"
+ target_amount = 100
+ if(4)
+ target = "plasma"
+ target_amount = 100
+ if(5)
+ target = "silver"
+ target_amount = 50
+ if(6)
+ target = "gold"
+ target_amount = 20
+ if(7)
+ target = "uranium"
+ target_amount = 20
+ if(8)
+ target = "diamond"
+ target_amount = 20
+
+ explanation_text = "Ransack the station and escape with [target_amount] [target]."
+
+ check_completion()
+
+ var/total_amount = 0
+
+ for(var/obj/item/O in locate(/area/shuttle/vox/station))
+ if(istype(O,/obj/item/stack/sheet))
+ if(O.name == target)
+ var/obj/item/stack/sheet/S = O
+ total_amount += S.amount
+
+ var/datum/game_mode/heist/H = ticker.mode
+ for(var/datum/mind/raider in H.raiders)
+ if(raider.current)
+ for(var/obj/item/O in raider.current.get_contents())
+ if(istype(O,/obj/item/stack/sheet))
+ if(O.name == target)
+ var/obj/item/stack/sheet/S = O
+ total_amount += S.amount
+
+ if(total_amount >= target_amount) return 1
+ return 0
+
+
+datum/objective/heist/inviolate_crew
+ explanation_text = "Do not leave any Vox behind, alive or dead."
+
+ check_completion()
+ var/datum/game_mode/heist/H = ticker.mode
+ if(H.is_raider_crew_safe()) return 1
+ return 0
+
+datum/objective/heist/inviolate_death
+ explanation_text = "Follow the Inviolate. Minimise death and loss of resources."
+ check_completion()
+ if(vox_kills>5) return 0
+ return 1
\ No newline at end of file
diff --git a/code/game/jobs/job/medical.dm b/code/game/jobs/job/medical.dm
index cacd825d017..22dd096bcca 100644
--- a/code/game/jobs/job/medical.dm
+++ b/code/game/jobs/job/medical.dm
@@ -28,7 +28,7 @@
H.equip_to_slot_or_del(new /obj/item/clothing/shoes/brown(H), slot_shoes)
H.equip_to_slot_or_del(new /obj/item/device/pda/heads/cmo(H), slot_belt)
H.equip_to_slot_or_del(new /obj/item/clothing/suit/storage/labcoat/cmo(H), slot_wear_suit)
- H.equip_to_slot_or_del(new /obj/item/weapon/storage/firstaid/regular(H), slot_l_hand)
+ H.equip_to_slot_or_del(new /obj/item/weapon/storage/firstaid/adv(H), slot_l_hand)
H.equip_to_slot_or_del(new /obj/item/device/flashlight/pen(H), slot_s_store)
if(H.backbag == 1)
H.equip_to_slot_or_del(new /obj/item/weapon/storage/box/survival(H), slot_r_hand)
@@ -88,7 +88,7 @@
H.equip_to_slot_or_del(new /obj/item/clothing/suit/storage/labcoat(H), slot_wear_suit)
H.equip_to_slot_or_del(new /obj/item/clothing/shoes/white(H), slot_shoes)
H.equip_to_slot_or_del(new /obj/item/device/pda/medical(H), slot_belt)
- H.equip_to_slot_or_del(new /obj/item/weapon/storage/firstaid/regular(H), slot_l_hand)
+ H.equip_to_slot_or_del(new /obj/item/weapon/storage/firstaid/adv(H), slot_l_hand)
H.equip_to_slot_or_del(new /obj/item/device/flashlight/pen(H), slot_s_store)
if(H.backbag == 1)
H.equip_to_slot_or_del(new /obj/item/weapon/storage/box/survival(H), slot_r_hand)
diff --git a/code/game/machinery/OpTable.dm b/code/game/machinery/OpTable.dm
index 69519c585d1..7078d9df906 100644
--- a/code/game/machinery/OpTable.dm
+++ b/code/game/machinery/OpTable.dm
@@ -18,6 +18,7 @@
for(dir in list(NORTH,EAST,SOUTH,WEST))
computer = locate(/obj/machinery/computer/operating, get_step(src, dir))
if (computer)
+ computer.table = src
break
// spawn(100) //Wont the MC just call this process() before and at the 10 second mark anyway?
// process()
diff --git a/code/game/machinery/Sleeper.dm b/code/game/machinery/Sleeper.dm
index 9f9ff56f780..a4158218a1e 100644
--- a/code/game/machinery/Sleeper.dm
+++ b/code/game/machinery/Sleeper.dm
@@ -70,12 +70,14 @@
dat += text("[]\t-Burn Severity %: []
", (occupant.getFireLoss() < 60 ? "" : ""), occupant.getFireLoss())
dat += text("
Paralysis Summary %: [] ([] seconds left!)
", occupant.paralysis, round(occupant.paralysis / 4))
if(occupant.reagents)
- dat += text("Inaprovaline units: [] units
", occupant.reagents.get_reagent_amount("inaprovaline"))
- dat += text("Soporific: [] units
", occupant.reagents.get_reagent_amount("stoxin"))
- dat += text("Dermaline: [] units
", occupant.reagents.get_reagent_amount("dermaline"))
- dat += text("Bicaridine: [] units
", occupant.reagents.get_reagent_amount("bicaridine"))
- dat += text("Dexalin: [] units
", occupant.reagents.get_reagent_amount("dexalin"))
- dat += text("
Refresh meter readings each second
Inject Inaprovaline
Inject Soporific
Inject Dermaline
Inject Bicaridine
Inject Dexalin", src, src, src, src, src, src)
+ for(var/chemical in connected.available_chemicals)
+ dat += "[connected.available_chemicals[chemical]]: [occupant.reagents.get_reagent_amount(chemical)] units
"
+ dat += "
Refresh meter readings each second
"
+ for(var/chemical in connected.available_chemicals)
+ dat += "Inject [connected.available_chemicals[chemical]]: "
+ for(var/amount in connected.amounts)
+ dat += "[amount] units "
+ dat += "
"
else
dat += "The sleeper is empty."
dat += text("
Close", user)
@@ -88,27 +90,15 @@
return
if ((usr.contents.Find(src) || ((get_dist(src, usr) <= 1) && istype(src.loc, /turf))) || (istype(usr, /mob/living/silicon/ai)))
usr.set_machine(src)
- if (src.connected)
- if (src.connected.occupant)
- if(src.connected.occupant.health > 0)
- if (href_list["inap"])
- src.connected.inject_inap(usr)
- if (href_list["stox"])
- src.connected.inject_stox(usr)
- if (href_list["derm"])
- src.connected.inject_dermaline(usr)
- if (href_list["bic"])
- src.connected.inject_bicaridine(usr)
- if (href_list["dex"])
- src.connected.inject_dexalin(usr)
- else
- if(src.connected.occupant.health > -100)
- if (href_list["inap"])
- src.connected.inject_inap(usr)
- if (href_list["stox"] || href_list["derm"] || href_list["bic"] || href_list["dex"])
- usr << "\red \b this person is not in good enough condition for sleepers to be effective! Use another means of treatment, such as cryogenics!"
- else
+ if (href_list["chemical"])
+ if (src.connected)
+ if (src.connected.occupant)
+ if (src.connected.occupant.stat == DEAD)
usr << "\red \b This person has no life for to preserve anymore. Take them to a department capable of reanimating them."
+ else if(src.connected.occupant.health > 0 || href_list["chemical"] == "inaprovaline")
+ src.connected.inject_chemical(usr,href_list["chemical"],text2num(href_list["amount"]))
+ else
+ usr << "\red \b This person is not in good enough condition for sleepers to be effective! Use another means of treatment, such as cryogenics!"
if (href_list["refresh"])
src.updateUsrDialog()
src.add_fingerprint(usr)
@@ -142,6 +132,8 @@
anchored = 1
var/orient = "LEFT" // "RIGHT" changes the dir suffix to "-r"
var/mob/living/occupant = null
+ var/available_chemicals = list("inaprovaline" = "Inaprovaline", "stoxin" = "Soporific", "dermaline" = "Dermaline", "bicaridine" = "Bicaridine", "dexalin" = "Dexalin")
+ var/amounts = list(10, 20)
New()
@@ -275,53 +267,13 @@
return
- proc/inject_inap(mob/living/user as mob)
+ proc/inject_chemical(mob/living/user as mob, chemical, amount)
if(src.occupant && src.occupant.reagents)
- if(src.occupant.reagents.get_reagent_amount("inaprovaline") + 30 <= 60)
- src.occupant.reagents.add_reagent("inaprovaline", 30)
- user << text("Occupant now has [] units of Inaprovaline in his/her bloodstream.", src.occupant.reagents.get_reagent_amount("inaprovaline"))
- else
- user << "There's no occupant in the sleeper or the subject rejects the chemicals!"
- return
-
-
- proc/inject_stox(mob/living/user as mob)
- if(src.occupant && src.occupant.reagents)
- if(src.occupant.reagents.get_reagent_amount("stoxin") + 20 <= 40)
- src.occupant.reagents.add_reagent("stoxin", 20)
- user << text("Occupant now has [] units of soporifics in his/her bloodstream.", src.occupant.reagents.get_reagent_amount("stoxin"))
- else
- user << "There's no occupant in the sleeper or the subject rejects the chemicals!"
- return
-
-
- proc/inject_dermaline(mob/living/user as mob)
- if(src.occupant && src.occupant.reagents)
- if(src.occupant.reagents.get_reagent_amount("dermaline") + 20 <= 40)
- src.occupant.reagents.add_reagent("dermaline", 20)
- user << text("Occupant now has [] units of Dermaline in his/her bloodstream.", src.occupant.reagents.get_reagent_amount("dermaline"))
- else
- user << "There's no occupant in the sleeper or the subject rejects the chemicals!"
- return
-
-
- proc/inject_bicaridine(mob/living/user as mob)
- if(src.occupant && src.occupant.reagents)
- if(src.occupant.reagents.get_reagent_amount("bicaridine") + 10 <= 20)
- src.occupant.reagents.add_reagent("bicaridine", 10)
- user << text("Occupant now has [] units of Bicaridine in his/her bloodstream.", src.occupant.reagents.get_reagent_amount("bicaridine"))
- else
- user << "There's no occupant in the sleeper or the subject rejects the chemicals!"
- return
-
-
- proc/inject_dexalin(mob/living/user as mob)
- if(src.occupant && src.occupant.reagents)
- if(src.occupant.reagents.get_reagent_amount("dexalin") + 20 <= 40)
- src.occupant.reagents.add_reagent("dexalin", 20)
- user << text("Occupant now has [] units of Dexalin in his/her bloodstream.", src.occupant.reagents.get_reagent_amount("dexalin"))
- else
- user << "There's no occupant in the sleeper or the subject rejects the chemicals!"
+ if(src.occupant.reagents.get_reagent_amount(chemical) + amount <= 40)
+ src.occupant.reagents.add_reagent(chemical, amount)
+ user << "Occupant now has [src.occupant.reagents.get_reagent_amount(chemical)] units of [available_chemicals[chemical]] in his/her bloodstream."
+ return
+ user << "There's no occupant in the sleeper or the subject rejects the chemicals!"
return
@@ -398,4 +350,4 @@
del(O)
src.add_fingerprint(usr)
return
- return
+ return
\ No newline at end of file
diff --git a/code/game/machinery/alarm.dm b/code/game/machinery/alarm.dm
index ec48cf76cc4..ea2456cf977 100644
--- a/code/game/machinery/alarm.dm
+++ b/code/game/machinery/alarm.dm
@@ -1479,8 +1479,7 @@ FIRE ALARM
A = A.loc
if (!( istype(A, /area) ))
return
- for(var/area/RA in A.related)
- RA.firereset()
+ A.firereset()
update_icon()
return
@@ -1491,8 +1490,7 @@ FIRE ALARM
A = A.loc
if (!( istype(A, /area) ))
return
- for(var/area/RA in A.related)
- RA.firealert()
+ A.firealert()
update_icon()
//playsound(src.loc, 'sound/ambience/signal.ogg', 75, 0)
return
diff --git a/code/game/machinery/bots/cleanbot.dm b/code/game/machinery/bots/cleanbot.dm
index 47b27ac54bd..d0345f60905 100644
--- a/code/game/machinery/bots/cleanbot.dm
+++ b/code/game/machinery/bots/cleanbot.dm
@@ -233,7 +233,8 @@ text("[src.oddbutton ? "Yes" : "No"
if(target && path.len == 0)
spawn(0)
if(!src || !target) return
- src.path = AStar(src.loc, src.target.loc, /turf/proc/AdjacentTurfs, /turf/proc/Distance, 0, 30)
+ src.path = AStar(src.loc, src.target.loc, /turf/proc/CardinalTurfsWithAccess, /turf/proc/Distance, 0, 30, id=botcard)
+ if (!path) path = list()
if(src.path.len == 0)
src.oldtarget = src.target
src.target = null
diff --git a/code/game/machinery/bots/ed209bot.dm b/code/game/machinery/bots/ed209bot.dm
index 5e5ae744068..d71a43c083e 100644
--- a/code/game/machinery/bots/ed209bot.dm
+++ b/code/game/machinery/bots/ed209bot.dm
@@ -615,6 +615,7 @@ Auto Patrol: []"},
// given an optional turf to avoid
/obj/machinery/bot/ed209/proc/calc_path(var/turf/avoid = null)
src.path = AStar(src.loc, patrol_target, /turf/proc/CardinalTurfsWithAccess, /turf/proc/Distance, 0, 120, id=botcard, exclude=avoid)
+ if (!src.path) src.path = list()
// look for a criminal in view of the bot
diff --git a/code/game/machinery/bots/floorbot.dm b/code/game/machinery/bots/floorbot.dm
index bb984a1787b..69fc5afd3f3 100644
--- a/code/game/machinery/bots/floorbot.dm
+++ b/code/game/machinery/bots/floorbot.dm
@@ -241,9 +241,10 @@
if(src.target && (src.target != null) && src.path.len == 0)
spawn(0)
if(!istype(src.target, /turf/))
- src.path = AStar(src.loc, src.target.loc, /turf/proc/AdjacentTurfsSpace, /turf/proc/Distance, 0, 30)
+ src.path = AStar(src.loc, src.target.loc, /turf/proc/AdjacentTurfsSpace, /turf/proc/Distance, 0, 30, id=botcard)
else
- src.path = AStar(src.loc, src.target, /turf/proc/AdjacentTurfsSpace, /turf/proc/Distance, 0, 30)
+ src.path = AStar(src.loc, src.target, /turf/proc/AdjacentTurfsSpace, /turf/proc/Distance, 0, 30, id=botcard)
+ if (!src.path) src.path = list()
if(src.path.len == 0)
src.oldtarget = src.target
src.target = null
diff --git a/code/game/machinery/camera/camera_assembly.dm b/code/game/machinery/camera/camera_assembly.dm
index c67a5a77b19..d5408d33308 100644
--- a/code/game/machinery/camera/camera_assembly.dm
+++ b/code/game/machinery/camera/camera_assembly.dm
@@ -87,6 +87,9 @@
usr << "No network found please hang up and try your call again."
return
+ var/temptag = "[get_area(src)] ([rand(1, 999)])"
+ input = strip_html(input(usr, "How would you like to name the camera?", "Set Camera Name", temptag))
+
state = 4
var/obj/machinery/camera/C = new(src.loc)
src.loc = C
@@ -94,9 +97,12 @@
C.auto_turn()
- C.network = tempnetwork
+ C.network = uniquelist(tempnetwork)
+ tempnetwork = difflist(C.network,RESTRICTED_CAMERA_NETWORKS)
+ if(!tempnetwork.len)//Camera isn't on any open network - remove its chunk from AI visibility.
+ cameranet.removeCamera(C)
- C.c_tag = "[get_area_name(src)] ([rand(1, 999)]"
+ C.c_tag = input
for(var/i = 5; i >= 0; i -= 1)
var/direct = input(user, "Direction?", "Assembling Camera", null) in list("LEAVE IT", "NORTH", "EAST", "SOUTH", "WEST" )
diff --git a/code/game/machinery/cloning.dm b/code/game/machinery/cloning.dm
index 124239dc82b..fd66d0c2c32 100644
--- a/code/game/machinery/cloning.dm
+++ b/code/game/machinery/cloning.dm
@@ -116,7 +116,7 @@
//Clonepod
//Start growing a human clone in the pod!
-/obj/machinery/clonepod/proc/growclone(var/ckey, var/clonename, var/ui, var/se, var/mindref, var/mrace)
+/obj/machinery/clonepod/proc/growclone(var/ckey, var/clonename, var/ui, var/se, var/mindref, var/datum/species/mrace)
if(mess || attempting)
return 0
var/datum/mind/clonemind = locate(mindref)
@@ -191,13 +191,11 @@
randmutb(H) //Sometimes the clones come out wrong.
H.f_style = "Shaved"
- if(mrace == "none") //no more xenos losing ears/tentacles
+ if(mrace.name == "Human") //no more xenos losing ears/tentacles
H.h_style = pick("Bedhead", "Bedhead 2", "Bedhead 3")
- if(H.dna)
- H.dna.mutantrace = mrace
- H.update_mutantrace()
- H.update_mutantrace_languages()
+ H.species = mrace
+ H.update_mutantrace()
H.suiciding = 0
src.attempting = 0
return 1
diff --git a/code/game/machinery/computer/Operating.dm b/code/game/machinery/computer/Operating.dm
index accd7b7a683..f1a1f02db70 100644
--- a/code/game/machinery/computer/Operating.dm
+++ b/code/game/machinery/computer/Operating.dm
@@ -13,7 +13,8 @@
..()
for(dir in list(NORTH,EAST,SOUTH,WEST))
table = locate(/obj/machinery/optable, get_step(src, dir))
- if (!isnull(table))
+ if (table)
+ table.computer = src
break
/obj/machinery/computer/operating/attack_ai(mob/user)
diff --git a/code/game/machinery/computer/buildandrepair.dm b/code/game/machinery/computer/buildandrepair.dm
index 2081a640d8e..7dca0ae01fb 100644
--- a/code/game/machinery/computer/buildandrepair.dm
+++ b/code/game/machinery/computer/buildandrepair.dm
@@ -37,6 +37,10 @@
/obj/item/weapon/circuitboard/security
name = "Circuit board (Security)"
build_path = "/obj/machinery/computer/security"
+ var/network = list("SS13")
+ req_access = list(access_security)
+ var/locked = 1
+ var/emagged = 0
/obj/item/weapon/circuitboard/aicore
name = "Circuit board (AI core)"
origin_tech = "programming=4;biotech=2"
@@ -80,6 +84,9 @@
/obj/item/weapon/circuitboard/secure_data
name = "Circuit board (Security Records)"
build_path = "/obj/machinery/computer/secure_data"
+/obj/item/weapon/circuitboard/skills
+ name = "Circuit board (Employment Records)"
+ build_path = "/obj/machinery/computer/skills"
/obj/item/weapon/circuitboard/stationalert
name = "Circuit board (Station Alerts)"
build_path = "/obj/machinery/computer/station_alert"
@@ -166,10 +173,6 @@
name = "Circuit board (Operating Computer)"
build_path = "/obj/machinery/computer/operating"
origin_tech = "programming=2;biotech=2"
-/obj/item/weapon/circuitboard/mining
- name = "Circuit board (Outpost Status Display)"
- build_path = "/obj/machinery/computer/security/mining"
- origin_tech = "programming=2"
/obj/item/weapon/circuitboard/comm_monitor
name = "Circuit board (Telecommunications Monitor)"
build_path = "/obj/machinery/computer/telecomms/monitor"
@@ -238,6 +241,40 @@
user << "DERP! BUG! Report this (And what you were doing to cause it) to Agouri"
return
+/obj/item/weapon/circuitboard/security/attackby(obj/item/I as obj, mob/user as mob)
+ if(istype(I,/obj/item/weapon/card/emag))
+ if(emagged)
+ user << "Circuit lock is already removed."
+ return
+ user << "\blue You override the circuit lock and open controls."
+ emagged = 1
+ locked = 0
+ else if(istype(I,/obj/item/weapon/card/id))
+ if(emagged)
+ user << "\red Circuit lock does not respond."
+ return
+ if(check_access(I))
+ locked = !locked
+ user << "\blue You [locked ? "" : "un"]lock the circuit controls."
+ else
+ user << "\red Access denied."
+ else if(istype(I,/obj/item/device/multitool))
+ if(locked)
+ user << "\red Circuit controls are locked."
+ return
+ var/existing_networks = dd_list2text(network,",")
+ var/input = strip_html(input(usr, "Which networks would you like to connect this camera console circuit to? Seperate networks with a comma. No Spaces!\nFor example: SS13,Security,Secret ", "Multitool-Circuitboard interface", existing_networks))
+ if(!input)
+ usr << "No input found please hang up and try your call again."
+ return
+ var/list/tempnetwork = text2list(input, ",")
+ tempnetwork = difflist(tempnetwork,RESTRICTED_CAMERA_NETWORKS,1)
+ if(tempnetwork.len < 1)
+ usr << "No network found please hang up and try your call again."
+ return
+ network = tempnetwork
+ return
+
/obj/item/weapon/circuitboard/rdconsole/attackby(obj/item/I as obj, mob/user as mob)
if(istype(I,/obj/item/weapon/screwdriver))
if(src.build_path == "/obj/machinery/computer/rdconsole/core")
@@ -353,4 +390,8 @@
var/obj/machinery/computer/supplycomp/SC = B
var/obj/item/weapon/circuitboard/supplycomp/C = circuit
SC.can_order_contraband = C.contraband_enabled
- del(src)
+ if(istype(circuit,/obj/item/weapon/circuitboard/security))
+ var/obj/machinery/computer/security/C = B
+ var/obj/item/weapon/circuitboard/security/CB = circuit
+ C.network = CB.network
+ del(src)
\ No newline at end of file
diff --git a/code/game/machinery/computer/camera.dm b/code/game/machinery/computer/camera.dm
index 0e4caf97c3f..aeec294fa40 100644
--- a/code/game/machinery/computer/camera.dm
+++ b/code/game/machinery/computer/camera.dm
@@ -5,7 +5,6 @@
name = "Security Cameras"
desc = "Used to access the various cameras on the station."
icon_state = "cameras"
- circuit = "/obj/item/weapon/circuitboard/security"
var/obj/machinery/camera/current = null
var/last_pic = 1.0
var/list/network = list("SS13")
@@ -78,7 +77,38 @@
attack_hand(user)
return
-
+ attackby(I as obj, user as mob)
+ if(istype(I, /obj/item/weapon/screwdriver))
+ playsound(loc, 'sound/items/Screwdriver.ogg', 50, 1)
+ if(do_after(user, 20))
+ if (stat & BROKEN)
+ user << "\blue The broken glass falls out."
+ var/obj/structure/computerframe/CF = new /obj/structure/computerframe(loc)
+ new /obj/item/weapon/shard(loc)
+ var/obj/item/weapon/circuitboard/security/CB = new /obj/item/weapon/circuitboard/security(CF)
+ CB.network = network
+ for (var/obj/C in src)
+ C.loc = loc
+ CF.circuit = CB
+ CF.state = 3
+ CF.icon_state = "3"
+ CF.anchored = 1
+ del(src)
+ else
+ user << "\blue You disconnect the monitor."
+ var/obj/structure/computerframe/CF = new /obj/structure/computerframe( loc )
+ var/obj/item/weapon/circuitboard/security/CB = new /obj/item/weapon/circuitboard/security(CF)
+ CB.network = network
+ for (var/obj/C in src)
+ C.loc = loc
+ CF.circuit = CB
+ CF.state = 4
+ CF.icon_state = "4"
+ CF.anchored = 1
+ del(src)
+ else
+ attack_hand(user)
+ return
/obj/machinery/computer/security/telescreen
name = "Telescreen"
@@ -87,7 +117,6 @@
icon_state = "telescreen"
network = list("thunder")
density = 0
- circuit = null
/obj/machinery/computer/security/telescreen/update_icon()
icon_state = initial(icon_state)
@@ -100,10 +129,6 @@
desc = "Damn, they better have /tg/thechannel on these things."
icon = 'icons/obj/status_display.dmi'
icon_state = "entertainment"
- network = list("thunder")
- density = 0
- circuit = null
-
/obj/machinery/computer/security/wooden_tv
name = "Security Cameras"
@@ -116,4 +141,9 @@
desc = "Used to access the various cameras on the outpost."
icon_state = "miningcameras"
network = list("MINE")
- circuit = "/obj/item/weapon/circuitboard/mining"
+
+/obj/machinery/computer/security/engineering
+ name = "Engineering Cameras"
+ desc = "Used to monitor fires and breaches."
+ icon_state = "engineeringcameras"
+ network = list("Power Alarms","Atmosphere Alarms","Fire Alarms")
\ No newline at end of file
diff --git a/code/game/machinery/computer/cloning.dm b/code/game/machinery/computer/cloning.dm
index edb4882cd2b..e29097a0308 100644
--- a/code/game/machinery/computer/cloning.dm
+++ b/code/game/machinery/computer/cloning.dm
@@ -443,10 +443,7 @@
subject.dna.check_integrity()
var/datum/data/record/R = new /datum/data/record( )
- if(subject.dna)
- R.fields["mrace"] = subject.dna.mutantrace
- else
- R.fields["mrace"] = null
+ R.fields["mrace"] = subject.species
R.fields["ckey"] = subject.ckey
R.fields["name"] = subject.real_name
R.fields["id"] = copytext(md5(subject.real_name), 2, 6)
diff --git a/code/game/machinery/computer/skills.dm b/code/game/machinery/computer/skills.dm
new file mode 100644
index 00000000000..7613d711ce6
--- /dev/null
+++ b/code/game/machinery/computer/skills.dm
@@ -0,0 +1,419 @@
+//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:31
+
+/obj/machinery/computer/skills//TODO:SANITY
+ name = "Employment Records"
+ desc = "Used to view personnel's employment records"
+ icon_state = "medlaptop"
+ req_one_access = list(access_heads)
+ circuit = "/obj/item/weapon/circuitboard/skills"
+ var/obj/item/weapon/card/id/scan = null
+ var/authenticated = null
+ var/rank = null
+ var/screen = null
+ var/datum/data/record/active1 = null
+ var/a_id = null
+ var/temp = null
+ var/printing = null
+ var/can_change_id = 0
+ var/list/Perp
+ var/tempname = null
+ //Sorting Variables
+ var/sortBy = "name"
+ var/order = 1 // -1 = Descending - 1 = Ascending
+
+
+/obj/machinery/computer/skills/attackby(obj/item/O as obj, user as mob)
+ if(istype(O, /obj/item/weapon/card/id) && !scan)
+ usr.drop_item()
+ O.loc = src
+ scan = O
+ user << "You insert [O]."
+ ..()
+
+/obj/machinery/computer/skills/attack_ai(mob/user as mob)
+ return attack_hand(user)
+
+/obj/machinery/computer/skills/attack_paw(mob/user as mob)
+ return attack_hand(user)
+
+//Someone needs to break down the dat += into chunks instead of long ass lines.
+/obj/machinery/computer/skills/attack_hand(mob/user as mob)
+ if(..())
+ return
+ if (src.z > 6)
+ user << "\red Unable to establish a connection: \black You're too far away from the station!"
+ return
+ var/dat
+
+ if (temp)
+ dat = text("[]
Clear Screen", temp, src)
+ else
+ dat = text("Confirm Identity: []
", src, (scan ? text("[]", scan.name) : "----------"))
+ if (authenticated)
+ switch(screen)
+ if(1.0)
+ dat += {"
+
", src)
+ dat += text("New Record
", src)
+ dat += {"
+
+
+
+
+Records:
+
+
+ "}
+ if(!isnull(data_core.general))
+ for(var/datum/data/record/R in sortRecord(data_core.general, sortBy, order))
+ for(var/datum/data/record/E in data_core.security)
+ var/background
+ dat += text("Name
+ID
+Rank
+Fingerprints
+[] ", background, src, R, R.fields["name"])
+ dat += text("[] ", R.fields["id"])
+ dat += text("[] ", R.fields["rank"])
+ dat += text("[] ", R.fields["fingerprint"])
+ dat += "
"
+ dat += text("Record Maintenance
", src)
+ dat += text("{Log Out}",src)
+ if(2.0)
+ dat += "Records Maintenance
"
+ dat += "
Delete All Records
Back"
+ if(3.0)
+ dat += "
| \
+ Name: [active1.fields["name"]] \ + ID: [active1.fields["id"]] \n \ + Sex: [active1.fields["sex"]] \n \ + Age: [active1.fields["age"]] \n \ + Rank: [active1.fields["rank"]] \n \ + Fingerprint: [active1.fields["fingerprint"]] \n \ + Physical Status: [active1.fields["p_stat"]] \n \ + Mental Status: [active1.fields["m_stat"]] \n \ + Employment/skills summary: [active1.fields["notes"]] | \
+ Photo: \
+ ![]() |
| Search Results for '[]': | ", tempname) + dat += {" +
|---|
| Name | +ID | +Rank | +Fingerprints | +|
|---|---|---|---|---|
| [] | ", background, src, R, R.fields["name"]) + dat += text("[] | ", R.fields["id"]) + dat += text("[] | ", R.fields["rank"]) + dat += text("[] | ", R.fields["fingerprint"]) + dat += text("[] |