diff --git a/code/ZAS/Atom.dm b/code/ZAS/Atom.dm
index ce69ad7162..4961355940 100644
--- a/code/ZAS/Atom.dm
+++ b/code/ZAS/Atom.dm
@@ -57,11 +57,11 @@ turf/c_airblock(turf/other)
#ifdef ZASDBG
ASSERT(isturf(other))
#endif
- if(blocks_air || other.blocks_air)
+ if(((blocks_air & AIR_BLOCKED) || (other.blocks_air & AIR_BLOCKED)))
return BLOCKED
//Z-level handling code. Always block if there isn't an open space.
- #ifdef ZLEVELS
+ #ifdef MULTIZAS
if(other.z != src.z)
if(other.z < src.z)
if(!istype(src, /turf/simulated/open)) return BLOCKED
@@ -69,6 +69,12 @@ turf/c_airblock(turf/other)
if(!istype(other, /turf/simulated/open)) return BLOCKED
#endif
+ if(((blocks_air & ZONE_BLOCKED) || (other.blocks_air & ZONE_BLOCKED)))
+ if(z == other.z)
+ return ZONE_BLOCKED
+ else
+ return AIR_BLOCKED
+
var/result = 0
for(var/atom/movable/M in contents)
result |= M.c_airblock(other)
diff --git a/code/ZAS/ConnectionManager.dm b/code/ZAS/ConnectionManager.dm
index 1c101f4b45..28ef365830 100644
--- a/code/ZAS/ConnectionManager.dm
+++ b/code/ZAS/ConnectionManager.dm
@@ -37,7 +37,7 @@ Class Procs:
/connection_manager/var/connection/E
/connection_manager/var/connection/W
-#ifdef ZLEVELS
+#ifdef MULTIZAS
/connection_manager/var/connection/U
/connection_manager/var/connection/D
#endif
@@ -57,7 +57,7 @@ Class Procs:
if(check(W)) return W
else return null
- #ifdef ZLEVELS
+ #ifdef MULTIZAS
if(UP)
if(check(U)) return U
else return null
@@ -73,7 +73,7 @@ Class Procs:
if(EAST) E = c
if(WEST) W = c
- #ifdef ZLEVELS
+ #ifdef MULTIZAS
if(UP) U = c
if(DOWN) D = c
#endif
@@ -83,7 +83,7 @@ Class Procs:
if(check(S)) S.update()
if(check(E)) E.update()
if(check(W)) W.update()
- #ifdef ZLEVELS
+ #ifdef MULTIZAS
if(check(U)) U.update()
if(check(D)) D.update()
#endif
@@ -93,7 +93,7 @@ Class Procs:
if(check(S)) S.erase()
if(check(E)) E.erase()
if(check(W)) W.erase()
- #ifdef ZLEVELS
+ #ifdef MULTIZAS
if(check(U)) U.erase()
if(check(D)) D.erase()
#endif
diff --git a/code/ZAS/Controller.dm b/code/ZAS/Controller.dm
index cfd6cff414..2469f7a36f 100644
--- a/code/ZAS/Controller.dm
+++ b/code/ZAS/Controller.dm
@@ -158,6 +158,9 @@ Total Unsimulated Turfs: [world.maxx*world.maxy*world.maxz - simulated_turf_coun
//defer updating of self-zone-blocked turfs until after all other turfs have been updated.
//this hopefully ensures that non-self-zone-blocked turfs adjacent to self-zone-blocked ones
//have valid zones when the self-zone-blocked turfs update.
+
+ //This ensures that doorways don't form their own single-turf zones, since doorways are self-zone-blocked and
+ //can merge with an adjacent zone, whereas zones that are formed on adjacent turfs cannot merge with the doorway.
var/list/deferred = list()
for(var/turf/T in updating)
diff --git a/code/ZAS/Diagnostic.dm b/code/ZAS/Diagnostic.dm
index ed94b7d582..10ec2e731b 100644
--- a/code/ZAS/Diagnostic.dm
+++ b/code/ZAS/Diagnostic.dm
@@ -39,6 +39,10 @@ client/proc/Test_ZAS_Connection(var/turf/simulated/T as turf)
"South" = SOUTH,\
"East" = EAST,\
"West" = WEST,\
+ #ifdef MULTIZAS
+ "Up" = UP,\
+ "Down" = DOWN,\
+ #endif
"N/A" = null)
var/direction = input("What direction do you wish to test?","Set direction") as null|anything in direction_list
if(!direction)
diff --git a/code/ZAS/Turf.dm b/code/ZAS/Turf.dm
index 62cad5e469..16122a2eac 100644
--- a/code/ZAS/Turf.dm
+++ b/code/ZAS/Turf.dm
@@ -16,7 +16,7 @@
//dbg(blocked)
return 1
- #ifdef ZLEVELS
+ #ifdef MULTIZAS
for(var/d = 1, d < 64, d *= 2)
#else
for(var/d = 1, d < 16, d *= 2)
@@ -52,34 +52,36 @@
*/
/turf/simulated/proc/can_safely_remove_from_zone()
- #ifdef ZLEVELS
- return 0 //TODO generalize this to multiz.
- #else
-
+
+
if(!zone) return 1
-
+
var/check_dirs = get_zone_neighbours(src)
var/unconnected_dirs = check_dirs
-
- for(var/dir in list(NORTHWEST, NORTHEAST, SOUTHEAST, SOUTHWEST))
-
+ var/to_check = list(NORTHEAST, NORTHWEST, SOUTHEAST, SOUTHWEST)
+ #ifdef MULTIZAS
+ to_check += list(NORTHUP, EASTUP, WESTUP, SOUTHUP, NORTHDOWN, EASTDOWN, WESTDOWN, SOUTHDOWN)
+ #endif
+ for(var/dir in to_check)
//for each pair of "adjacent" cardinals (e.g. NORTH and WEST, but not NORTH and SOUTH)
if((dir & check_dirs) == dir)
//check that they are connected by the corner turf
var/connected_dirs = get_zone_neighbours(get_step(src, dir))
- if(connected_dirs && (dir & turn(connected_dirs, 180)) == dir)
+ if(connected_dirs && (dir & reverse_dir[connected_dirs]) == dir)
unconnected_dirs &= ~dir //they are, so unflag the cardinals in question
-
+
//it is safe to remove src from the zone if all cardinals are connected by corner turfs
return !unconnected_dirs
-
- #endif
//helper for can_safely_remove_from_zone()
/turf/simulated/proc/get_zone_neighbours(turf/simulated/T)
. = 0
if(istype(T) && T.zone)
- for(var/dir in cardinal)
+ var/to_check = cardinal.Copy()
+ #ifdef MULTIZAS
+ to_check += list(UP, DOWN)
+ #endif
+ for(var/dir in to_check)
var/turf/simulated/other = get_step(T, dir)
if(istype(other) && other.zone == T.zone && !(other.c_airblock(T) & AIR_BLOCKED) && get_dist(src, other) <= 1)
. |= dir
@@ -98,7 +100,7 @@
#endif
if(zone)
var/zone/z = zone
-
+
if(can_safely_remove_from_zone()) //Helps normal airlocks avoid rebuilding zones all the time
z.remove(src)
else
@@ -110,7 +112,7 @@
open_directions = 0
var/list/postponed
- #ifdef ZLEVELS
+ #ifdef MULTIZAS
for(var/d = 1, d < 64, d *= 2)
#else
for(var/d = 1, d < 16, d *= 2)
@@ -161,7 +163,7 @@
//Might have assigned a zone, since this happens for each direction.
if(!zone)
- //We do not merge if
+ //We do not merge if
// they are blocking us and we are not blocking them, or if
// we are blocking them and not blocking ourselves - this prevents tiny zones from forming on doorways.
if(((block & ZONE_BLOCKED) && !(r_block & ZONE_BLOCKED)) || ((r_block & ZONE_BLOCKED) && !(s_block & ZONE_BLOCKED)))
diff --git a/code/ZAS/_docs.dm b/code/ZAS/_docs.dm
index 1f652ffaab..4433478e32 100644
--- a/code/ZAS/_docs.dm
+++ b/code/ZAS/_docs.dm
@@ -28,8 +28,7 @@ Notes for people who used ZAS before:
*/
//#define ZASDBG
-//#define ZLEVELS
-
+//#define MULTIZAS
#define AIR_BLOCKED 1
#define ZONE_BLOCKED 2
#define BLOCKED 3
diff --git a/code/__defines/misc.dm b/code/__defines/misc.dm
index f85ac5e7d4..cb32f8faa9 100644
--- a/code/__defines/misc.dm
+++ b/code/__defines/misc.dm
@@ -196,3 +196,13 @@
#define TSC_MORPH "Morpheus"
#define TSC_XION "Xion" // Not really needed but consistancy I guess.
#define TSC_GIL "Gilthari"
+
+//MultiZ directions for ZAS checks.
+#define NORTHUP (NORTH|UP)
+#define EASTUP (EAST|UP)
+#define SOUTHUP (SOUTH|UP)
+#define WESTUP (WEST|UP)
+#define NORTHDOWN (NORTH|DOWN)
+#define EASTDOWN (EAST|DOWN)
+#define SOUTHDOWN (SOUTH|DOWN)
+#define WESTDOWN (WEST|DOWN)
diff --git a/code/game/objects/explosion.dm b/code/game/objects/explosion.dm
index b081530e10..0004a39b1c 100644
--- a/code/game/objects/explosion.dm
+++ b/code/game/objects/explosion.dm
@@ -1,23 +1,26 @@
//TODO: Flash range does nothing currently
-proc/explosion(turf/epicenter, devastation_range, heavy_impact_range, light_impact_range, flash_range, adminlog = 1, z_transfer = UP|DOWN)
+proc/explosion(turf/epicenter, devastation_range, heavy_impact_range, light_impact_range, flash_range, adminlog = 1, z_transfer = UP|DOWN, shaped)
+ var/multi_z_scalar = 0.35
src = null //so we don't abort once src is deleted
spawn(0)
- if(config.use_recursive_explosions)
- var/power = devastation_range * 2 + heavy_impact_range + light_impact_range //The ranges add up, ie light 14 includes both heavy 7 and devestation 3. So this calculation means devestation counts for 4, heavy for 2 and light for 1 power, giving us a cap of 27 power.
- explosion_rec(epicenter, power)
- return
-
var/start = world.timeofday
epicenter = get_turf(epicenter)
if(!epicenter) return
// Handles recursive propagation of explosions.
- if(devastation_range > 2 || heavy_impact_range > 2)
- if(HasAbove(epicenter.z) && z_transfer & UP)
- explosion(GetAbove(epicenter), max(0, devastation_range - 2), max(0, heavy_impact_range - 2), max(0, light_impact_range - 2), max(0, flash_range - 2), 0, UP)
- if(HasBelow(epicenter.z) && z_transfer & DOWN)
- explosion(GetAbove(epicenter), max(0, devastation_range - 2), max(0, heavy_impact_range - 2), max(0, light_impact_range - 2), max(0, flash_range - 2), 0, DOWN)
+ if(z_transfer)
+ var/adj_dev = max(0, (multi_z_scalar * devastation_range) - (shaped ? 2 : 0) )
+ var/adj_heavy = max(0, (multi_z_scalar * heavy_impact_range) - (shaped ? 2 : 0) )
+ var/adj_light = max(0, (multi_z_scalar * light_impact_range) - (shaped ? 2 : 0) )
+ var/adj_flash = max(0, (multi_z_scalar * flash_range) - (shaped ? 2 : 0) )
+
+
+ if(adj_dev > 0 || adj_heavy > 0)
+ if(HasAbove(epicenter.z) && z_transfer & UP)
+ explosion(GetAbove(epicenter), round(adj_dev), round(adj_heavy), round(adj_light), round(adj_flash), 0, UP, shaped)
+ if(HasBelow(epicenter.z) && z_transfer & DOWN)
+ explosion(GetBelow(epicenter), round(adj_dev), round(adj_heavy), round(adj_light), round(adj_flash), 0, DOWN, shaped)
var/max_range = max(devastation_range, heavy_impact_range, light_impact_range, flash_range)
@@ -30,34 +33,22 @@ proc/explosion(turf/epicenter, devastation_range, heavy_impact_range, light_impa
far_dist += devastation_range * 20
var/frequency = get_rand_frequency()
for(var/mob/M in player_list)
- // Double check for client
- if(M && M.client)
+ if(M.z == epicenter.z)
var/turf/M_turf = get_turf(M)
- if(M_turf && M_turf.z == epicenter.z)
- var/dist = get_dist(M_turf, epicenter)
- // If inside the blast radius + world.view - 2
- if(dist <= round(max_range + world.view - 2, 1))
- M.playsound_local(epicenter, get_sfx("explosion"), 100, 1, frequency, falloff = 5) // get_sfx() is so that everyone gets the same sound
+ var/dist = get_dist(M_turf, epicenter)
+ // If inside the blast radius + world.view - 2
+ if(dist <= round(max_range + world.view - 2, 1))
+ M.playsound_local(epicenter, get_sfx("explosion"), 100, 1, frequency, falloff = 5) // get_sfx() is so that everyone gets the same sound
+ else if(dist <= far_dist)
+ var/far_volume = Clamp(far_dist, 30, 50) // Volume is based on explosion size and dist
+ far_volume += (dist <= far_dist * 0.5 ? 50 : 0) // add 50 volume if the mob is pretty close to the explosion
+ M.playsound_local(epicenter, 'sound/effects/explosionfar.ogg', far_volume, 1, frequency, falloff = 5)
- //You hear a far explosion if you're outside the blast radius. Small bombs shouldn't be heard all over the station.
-
- else if(dist <= far_dist)
- var/far_volume = Clamp(far_dist, 30, 50) // Volume is based on explosion size and dist
- far_volume += (dist <= far_dist * 0.5 ? 50 : 0) // add 50 volume if the mob is pretty close to the explosion
- M.playsound_local(epicenter, 'sound/effects/explosionfar.ogg', far_volume, 1, frequency, falloff = 5)
-
- var/close = range(world.view+round(devastation_range,1), epicenter)
- // to all distanced mobs play a different sound
- for(var/mob/M in world) if(M.z == epicenter.z) if(!(M in close))
- // check if the mob can hear
- if(M.ear_deaf <= 0 || !M.ear_deaf) if(!istype(M.loc,/turf/space))
- M << 'sound/effects/explosionfar.ogg'
if(adminlog)
message_admins("Explosion with size ([devastation_range], [heavy_impact_range], [light_impact_range]) in area [epicenter.loc.name] ([epicenter.x],[epicenter.y],[epicenter.z]) (JMP)")
log_game("Explosion with size ([devastation_range], [heavy_impact_range], [light_impact_range]) in area [epicenter.loc.name] ")
var/approximate_intensity = (devastation_range * 3) + (heavy_impact_range * 2) + light_impact_range
- var/powernet_rebuild_was_deferred_already = defer_powernet_rebuild
// Large enough explosion. For performance reasons, powernets will be rebuilt manually
if(!defer_powernet_rebuild && (approximate_intensity > 25))
defer_powernet_rebuild = 1
@@ -70,41 +61,41 @@ proc/explosion(turf/epicenter, devastation_range, heavy_impact_range, light_impa
var/x0 = epicenter.x
var/y0 = epicenter.y
var/z0 = epicenter.z
+ if(config.use_recursive_explosions)
+ var/power = devastation_range * 2 + heavy_impact_range + light_impact_range //The ranges add up, ie light 14 includes both heavy 7 and devestation 3. So this calculation means devestation counts for 4, heavy for 2 and light for 1 power, giving us a cap of 27 power.
+ explosion_rec(epicenter, power, shaped)
+ else
+ for(var/turf/T in trange(max_range, epicenter))
+ var/dist = sqrt((T.x - x0)**2 + (T.y - y0)**2)
- for(var/turf/T in trange(max_range, epicenter))
- var/dist = sqrt((T.x - x0)**2 + (T.y - y0)**2)
+ if(dist < devastation_range) dist = 1
+ else if(dist < heavy_impact_range) dist = 2
+ else if(dist < light_impact_range) dist = 3
+ else continue
- if(dist < devastation_range) dist = 1
- else if(dist < heavy_impact_range) dist = 2
- else if(dist < light_impact_range) dist = 3
- else continue
-
- T.ex_act(dist)
- if(T)
+ T.ex_act(dist)
+ if(!T)
+ T = locate(x0,y0,z0)
for(var/atom_movable in T.contents) //bypass type checking since only atom/movable can be contained by turfs anyway
var/atom/movable/AM = atom_movable
if(AM && AM.simulated) AM.ex_act(dist)
var/took = (world.timeofday-start)/10
//You need to press the DebugGame verb to see these now....they were getting annoying and we've collected a fair bit of data. Just -test- changes to explosion code using this please so we can compare
- if(Debug2) world.log << "## DEBUG: Explosion([x0],[y0],[z0])(d[devastation_range],h[heavy_impact_range],l[light_impact_range]): Took [took] seconds."
+ if(Debug2) world.log << "## DEBUG: Explosion([x0],[y0],[z0])(d[devastation_range],h[heavy_impact_range],l[light_impact_range]): Took [took] seconds."
//Machines which report explosions.
for(var/i,i<=doppler_arrays.len,i++)
var/obj/machinery/doppler_array/Array = doppler_arrays[i]
if(Array)
Array.sense_explosion(x0,y0,z0,devastation_range,heavy_impact_range,light_impact_range,took)
-
sleep(8)
if(!powernet_rebuild_was_deferred_already && defer_powernet_rebuild)
makepowernets()
defer_powernet_rebuild = 0
-
return 1
-
-
proc/secondaryexplosion(turf/epicenter, range)
for(var/turf/tile in range(range, epicenter))
- tile.ex_act(2)
+ tile.ex_act(2)
\ No newline at end of file
diff --git a/code/game/turfs/simulated/wall_attacks.dm b/code/game/turfs/simulated/wall_attacks.dm
index 47620d030a..098782ebdf 100644
--- a/code/game/turfs/simulated/wall_attacks.dm
+++ b/code/game/turfs/simulated/wall_attacks.dm
@@ -1,3 +1,6 @@
+#define ZONE_BLOCKED 2
+#define AIR_BLOCKED 1
+
//Interactions
/turf/simulated/wall/proc/toggle_open(var/mob/user)
@@ -8,7 +11,9 @@
can_open = WALL_OPENING
//flick("[material.icon_base]fwall_opening", src)
density = 0
+ blocks_air = ZONE_BLOCKED
update_icon()
+ update_air()
set_light(0)
src.blocks_air = 0
set_opacity(0)
@@ -18,7 +23,9 @@
can_open = WALL_OPENING
//flick("[material.icon_base]fwall_closing", src)
density = 1
+ blocks_air = AIR_BLOCKED
update_icon()
+ update_air()
set_light(1)
src.blocks_air = 1
set_opacity(1)
@@ -28,6 +35,25 @@
can_open = WALL_CAN_OPEN
update_icon()
+#undef ZONE_BLOCKED
+#undef AIR_BLOCKED
+
+/turf/simulated/wall/proc/update_air()
+ if(!air_master)
+ return
+
+ for(var/turf/simulated/turf in loc)
+ update_thermal(turf)
+ air_master.mark_for_update(turf)
+
+
+/turf/simulated/wall/proc/update_thermal(var/turf/simulated/source)
+ if(istype(source))
+ if(density && opacity)
+ source.thermal_conductivity = WALL_HEAT_TRANSFER_COEFFICIENT
+ else
+ source.thermal_conductivity = initial(source.thermal_conductivity)
+
/turf/simulated/wall/proc/fail_smash(var/mob/user)
user << "You smash against the wall!"
take_damage(rand(25,75))
diff --git a/html/changelogs/Anewbe - MultiZAS.yml b/html/changelogs/Anewbe - MultiZAS.yml
new file mode 100644
index 0000000000..c04097eb3d
--- /dev/null
+++ b/html/changelogs/Anewbe - MultiZAS.yml
@@ -0,0 +1,36 @@
+################################
+# Example Changelog File
+#
+# Note: This file, and files beginning with ".", and files that don't end in ".yml" will not be read. If you change this file, you will look really dumb.
+#
+# Your changelog will be merged with a master changelog. (New stuff added only, and only on the date entry for the day it was merged.)
+# When it is, any changes listed below will disappear.
+#
+# Valid Prefixes:
+# bugfix
+# wip (For works in progress)
+# tweak
+# soundadd
+# sounddel
+# rscadd (general adding of nice things)
+# rscdel (general deleting of nice things)
+# imageadd
+# imagedel
+# maptweak
+# spellcheck (typo fixes)
+# experiment
+#################################
+
+# Your name.
+author: Anewbe
+
+# Optional: Remove this file after generating master changelog. Useful for PR changelogs that won't get used again.
+delete-after: True
+
+# Any changes you've made. See valid prefix list above.
+# INDENT WITH TWO SPACES. NOT TABS. SPACES.
+# SCREW THIS UP AND IT WON'T WORK.
+# Also, all entries are changed into a single [] after a master changelog generation. Just remove the brackets when you add new entries.
+# Please surround your changes in double quotes ("), as certain characters otherwise screws up compiling. The quotes will not show up in the changelog.
+changes:
+ - rscadd: "Ports but does not enable Bay's MultiZAS."
\ No newline at end of file