diff --git a/code/ZAS/Airflow.dm b/code/ZAS/Airflow.dm
index 2d1b72b89db..a00900fd35a 100644
--- a/code/ZAS/Airflow.dm
+++ b/code/ZAS/Airflow.dm
@@ -59,11 +59,14 @@ vs_control/var
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 = 95
- airflow_heavy_pressure_NAME = "Airflow - Dense Movement Threshold %"
- airflow_heavy_pressure_DESC = "Percent of 1 Atm. at which items with canisters and closets will move."
- airflow_heaviest_pressure = 100
- airflow_heaviest_pressure_NAME = "Airflow - Mob Stunning Threshold %"
- airflow_heaviest_pressure_DESC = "Percent of 1 Atm. at which mobs will be stunned by airflow."
+ airflow_heavy_pressure_NAME = "Airflow - Mob Movement Threshold %"
+ airflow_heavy_pressure_DESC = "Percent of 1 Atm. at which mobs will move."
+ airflow_dense_pressure = 120
+ 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 = 100
+ 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."
@@ -113,10 +116,15 @@ atom/movable/proc/check_airflow_movable(n)
if(anchored && !ismob(src)) return 0
- if(!istype(src,/obj/item) && n < vsc.airflow_heavy_pressure) return 0
+ if(!istype(src,/obj/item) && n < vsc.airflow_dense_pressure) return 0
return 1
+mob/check_airflow_movable(n)
+ if(n < vsc.airflow_heavy_pressure)
+ return 0
+ return 1
+
mob/dead/observer/check_airflow_movable()
return 0
@@ -172,7 +180,7 @@ proc/Airflow(zone/A,zone/B)
if(M.last_airflow > world.time - vsc.airflow_delay) continue
//Check for knocking people over
- if(ismob(M) && n > vsc.airflow_heaviest_pressure)
+ if(ismob(M) && n > vsc.airflow_stun_pressure)
if(M:nodamage) continue
M:airflow_stun()
@@ -230,7 +238,7 @@ proc/AirflowSpace(zone/A)
if(M.last_airflow > world.time - vsc.airflow_delay) continue
- if(ismob(M) && n > vsc.airflow_medium_pressure)
+ if(ismob(M) && n > vsc.airflow_stun_pressure)
if(M:nodamage) continue
M:airflow_stun()
diff --git a/code/ZAS/Creation.dm b/code/ZAS/Creation.dm
index b283cd56d43..baa83bfe370 100644
--- a/code/ZAS/Creation.dm
+++ b/code/ZAS/Creation.dm
@@ -35,6 +35,7 @@ zone
for(var/turf/simulated/T in contents)
if(T.zone && T.zone == src)
T.zone = null
+ air_master.tiles_to_update |= T
for(var/zone/Z in connected_zones)
if(src in Z.connected_zones)
Z.connected_zones.Remove(src)
diff --git a/code/ZAS/FEA_system.dm b/code/ZAS/FEA_system.dm
index bdac4bacd68..1d78eb69c8e 100644
--- a/code/ZAS/FEA_system.dm
+++ b/code/ZAS/FEA_system.dm
@@ -142,7 +142,7 @@ datum
if(S.CanPass(null, S, 0, 0))
new/zone(S)
- tiles_to_update |= S
+ S.update_air_properties()
world << "\red \b Geometry processed in [time2text(world.timeofday-start_time, "mm:ss")] minutes!"
spawn start()
diff --git a/code/ZAS/FEA_turf_tile.dm b/code/ZAS/FEA_turf_tile.dm
index 177afbc9de1..fa44ba20f73 100644
--- a/code/ZAS/FEA_turf_tile.dm
+++ b/code/ZAS/FEA_turf_tile.dm
@@ -205,7 +205,7 @@ turf
if(!CanPass(null, T, 1.5, 1) && CanPass(src, T, 0, 0)) //Normally would block it, instead lets make a connection to it.
if(zone)
zone.AddSpace(T)
- else if(!CanPass(src, T, 0, 0)) //I block the air, disconnect from it if connected.
+ else if(!CanPass(src, T, 0, 0) || !CanPass(T, src, 0, 0)) //I block the air or it blocks air, disconnect from it if connected.
if(zone && T in zone.space_tiles)
zone.RemoveSpace(T)
else if(zone)
@@ -219,7 +219,7 @@ turf
if(NT && NT.zone && NT.zone == T.zone)
T.zone.rebuild = 1
- else if((!T.CanPass(null, src, 1.5, 1) && T.CanPass(null, src, 0, 0)) || (!CanPass(null, T, 1.5, 1) && CanPass(null, T, 0, 0)))
+ else if(T.CanPass(null, src, 0, 0))
if(T.zone != zone)
ZConnect(src,T)
diff --git a/code/ZAS/Processing.dm b/code/ZAS/Processing.dm
index e741b70f377..fd21d4168f4 100644
--- a/code/ZAS/Processing.dm
+++ b/code/ZAS/Processing.dm
@@ -1,5 +1,4 @@
#define QUANTIZE(variable) (round(variable,0.0001))
-var/explosion_halt = 0
vs_control/var/zone_share_percent = 10
vs_control/var/zone_share_percent_NAME = "Zone Share Percent"
vs_control/var/zone_share_percent_DESC = "Percentage of air difference to move per tick"
@@ -10,67 +9,8 @@ zone/proc/process()
return 0
//Does rebuilding stuff. Not sure if used.
if(rebuild)
-
- //Choose a random turf and regenerate the zone from it.
- var
- turf/simulated/sample = pick(contents)
- list/new_contents
- problem = 0
-
- if(space_tiles)
- del(space_tiles)
-
- contents.Remove(null) //I can't believe this is needed.
-
- if(!contents.len)
- del src
-
- var/list/tried_turfs = list()
- do
- if(sample)
- tried_turfs |= sample
- var/list/turfs_to_consider = contents - tried_turfs
- if(!turfs_to_consider.len)
- break
- sample = pick(turfs_to_consider) //Nor this.
- while(!istype(sample) || !sample.CanPass(null, sample, 1.5, 1))
-
- if(!istype(sample) || !sample.CanPass(null, sample, 1.5, 1)) //Not a single valid turf.
- for(var/turf/simulated/T in contents)
- air_master.tiles_to_update |= T
- del src
-
- new_contents = FloodFill(sample)
-
- for(var/turf/space/S in new_contents)
- if(!space_tiles)
- space_tiles = list()
- space_tiles |= S
-
- //If something isn't carried over, there was a complication.
- for(var/turf/T in contents)
- if(!(T in new_contents))
- problem = 1
- T.zone = null
-
- if(problem)
- //Build some new zones for stuff that wasn't included.
- var/list/turf/simulated/rebuild_turfs = contents - new_contents
- var/list/turf/simulated/reconsider_turfs = list()
- contents = new_contents
- for(var/turf/T in rebuild_turfs)
- if(istype(T,/turf/space))
- air_master.tiles_to_update |= T
- else if(!T.zone && T.CanPass(null, T, 1.5, 1))
- var/zone/Z = new /zone(T)
- Z.air.copy_from(air)
- else
- reconsider_turfs |= T
- for(var/turf/T in reconsider_turfs)
- if(!T.zone)
- var/zone/Z = new /zone(T)
- Z.air.copy_from(air)
rebuild = 0
+ Rebuild() //Shoving this into a proc.
//Sometimes explosions will cause the air to be deleted for some reason.
if(!air)
@@ -272,4 +212,78 @@ zone/proc/connected_zones()
.[Z]++
else
. += Z
- .[Z] = 1
\ No newline at end of file
+ .[Z] = 1
+
+zone/proc/Rebuild()
+ //Choose a random turf and regenerate the zone from it.
+ var
+ turf/simulated/sample = pick(contents)
+ list/new_contents
+ problem = 0
+
+ if(space_tiles)
+ del(space_tiles)
+
+ contents.Remove(null) //I can't believe this is needed.
+
+ if(!contents.len)
+ del src
+
+ var/list/tried_turfs = list()
+ do
+ if(sample)
+ tried_turfs |= sample
+ var/list/turfs_to_consider = contents - tried_turfs
+ if(!turfs_to_consider.len)
+ break
+ sample = pick(turfs_to_consider) //Nor this.
+ while(!istype(sample) || !sample.CanPass(null, sample, 1.5, 1))
+
+ if(!istype(sample) || !sample.CanPass(null, sample, 1.5, 1)) //Not a single valid turf.
+ for(var/turf/simulated/T in contents)
+ air_master.tiles_to_update |= T
+ del src
+
+ new_contents = FloodFill(sample)
+
+ for(var/turf/space/S in new_contents)
+ if(!space_tiles)
+ space_tiles = list()
+ space_tiles |= S
+
+ if(contents.len != new_contents.len)
+ problem = 1
+
+ //If something isn't carried over, there was a complication.
+ for(var/turf/T in contents)
+ if(!(T in new_contents))
+ T.zone = null
+ problem = 1
+
+ for(var/turf/T in new_contents)
+
+ if(problem)
+ //Build some new zones for stuff that wasn't included.
+ var/list/turf/simulated/rebuild_turfs = contents - new_contents
+ var/list/turf/simulated/reconsider_turfs = list()
+ contents = new_contents
+ for(var/turf/T in rebuild_turfs)
+ if(istype(T,/turf/space))
+ air_master.tiles_to_update |= T
+ else if(!T.zone && T.CanPass(null, T, 1.5, 1))
+ var/zone/Z = new /zone(T)
+ Z.air.copy_from(air)
+ else
+ reconsider_turfs |= T
+ for(var/turf/T in reconsider_turfs)
+ if(!T.zone)
+ var/zone/Z = new /zone(T)
+ Z.air.copy_from(air)
+
+ for(var/turf/T in contents)
+ if(T.zone && T.zone != src)
+ T.zone.RemoveTurf(T)
+ T.zone = src
+ else if(!T.zone)
+ T.zone = src
+ air.group_multiplier = contents.len
\ No newline at end of file
diff --git a/code/ZAS/Variable Settings.dm b/code/ZAS/Variable Settings.dm
index c83008d72d3..56dd21a9e21 100644
--- a/code/ZAS/Variable Settings.dm
+++ b/code/ZAS/Variable Settings.dm
@@ -49,9 +49,12 @@ 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]_METHOD" in vars)
+ 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))
@@ -60,6 +63,8 @@ vs_control
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
@@ -91,7 +96,7 @@ vs_control
vars[ch] = vw
if(how == "Toggle")
newvar = (newvar?"ON":"OFF")
- world << "\blue [key_name(user)] changed the setting [ch] to [newvar]."
+ world << "\blue [key_name(user)] changed the setting [display_description] to [newvar]."
//user << "[which] has been changed to [newvar]."
if(ch in plc.settings)
ChangeSettingsDialog(user,plc.settings)
diff --git a/code/game/machinery/computer/cloning.dm b/code/game/machinery/computer/cloning.dm
index d32933dec83..382ab89c367 100644
--- a/code/game/machinery/computer/cloning.dm
+++ b/code/game/machinery/computer/cloning.dm
@@ -185,7 +185,12 @@
if (src.scanner.occupant)
if(scantemp == "Scanner unoccupied") scantemp = "" // Stupid check to remove the text
- dat += "Scan - [src.scanner.occupant]
"
+ // Make sure we can't scan a headless person. It breaks the cloner permanently.
+ var/datum/organ/external/temp = organs["head"]
+ if(temp && !(temp.status & DESTROYED))
+ dat += "Scan - [src.scanner.occupant]
"
+ else
+ dat += "Error: Cannot locate brain for mental indexing. Unable to continue.
"
else
dat += "Scanner unoccupied"
diff --git a/code/game/objects/window.dm b/code/game/objects/window.dm
index f4924f25ec4..85b155de4ef 100644
--- a/code/game/objects/window.dm
+++ b/code/game/objects/window.dm
@@ -322,7 +322,7 @@
/obj/structure/window/Del()
density = 0
- update_nearby_tiles()
+ update_nearby_tiles(need_rebuild=1)
playsound(src, "shatter", 70, 1)
@@ -343,6 +343,14 @@
//This proc has to do with airgroups and atmos, it has nothing to do with smoothwindows, that's update_nearby_tiles().
/obj/structure/window/proc/update_nearby_tiles(need_rebuild)
if(!air_master) return 0
+ if(!dir in cardinal)
+ var/turf/simulated/source = get_turf(src)
+ if(istype(source))
+ air_master.tiles_to_update |= source
+ for(var/dir in cardinal)
+ var/turf/simulated/target = get_step(source,dir)
+ if(istype(target)) air_master.tiles_to_update |= target
+ return 1
var/turf/simulated/source = get_turf(src)
var/turf/simulated/target = get_step(source,dir)
diff --git a/code/modules/mob/living/carbon/give.dm b/code/modules/mob/living/carbon/give.dm
index 167ad789fda..0b8c0614190 100644
--- a/code/modules/mob/living/carbon/give.dm
+++ b/code/modules/mob/living/carbon/give.dm
@@ -23,6 +23,8 @@ mob/living/carbon/verb/give()
if(src.r_hand == null)
switch(alert(src,"[usr] wants to give you \a [I]?",,"Yes","No"))
if("Yes")
+ if(!I)
+ return
if(!check_can_reach(usr,src))
usr << "You need to keep in reaching distance."
src << "[usr.name] moved too far away."
@@ -52,6 +54,8 @@ mob/living/carbon/verb/give()
else if(src.l_hand == null)
switch(alert(src,"[usr] wants to give you \a [I]?",,"Yes","No"))
if("Yes")
+ if(!I)
+ return
if(!check_can_reach(usr,src))
usr << "You need to keep in reaching distance."
src << "[usr.name] moved too far away."
diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm
index 94ba2c3ebbb..ec02dc0bde8 100644
--- a/code/modules/mob/living/carbon/human/human.dm
+++ b/code/modules/mob/living/carbon/human/human.dm
@@ -2722,7 +2722,7 @@ It can still be worn/put on as normal.
check_dna()
for(var/mob/M in view())
- user.visible_message("\blue \The [src] morphs and changes [user.get_gender_form() == MALE ? "his" : user.get_gender_form() == FEMALE ? "her" : "their"] appearance!", "\blue You change your appearance!", "\red Oh, god! What the hell was that? It sounded like flesh getting squished and bone ground into a different shape!")
+ visible_message("\blue \The [src] morphs and changes [get_visible_gender() == MALE ? "his" : get_visible_gender() == FEMALE ? "her" : "their"] appearance!", "\blue You change your appearance!", "\red Oh, god! What the hell was that? It sounded like flesh getting squished and bone ground into a different shape!")
/mob/living/carbon/human/proc/remotesay()
set name = "Project mind"
@@ -2785,4 +2785,4 @@ It can still be worn/put on as normal.
/mob/living/carbon/human/get_visible_gender()
if(wear_suit && wear_suit.flags_inv & HIDEJUMPSUIT && ((head && head.flags_inv & HIDEMASK) || wear_mask))
return NEUTER
- return gender
+ return gender
diff --git a/html/changelog.html b/html/changelog.html
index c0fb3646ee1..18faae2f9de 100644
--- a/html/changelog.html
+++ b/html/changelog.html
@@ -57,6 +57,18 @@ Stuff which is in development and not yet visible to players or just code relate
should be listed in the changelog upon commit though. Thanks. -->
+