Ports MultiZAS

This commit is contained in:
Anewbe
2017-02-19 16:57:59 -06:00
committed by Leshana
parent b71a67a775
commit cce1fcc1f5
10 changed files with 150 additions and 73 deletions

View File

@@ -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)

View File

@@ -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

View File

@@ -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)

View File

@@ -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)

View File

@@ -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)))

View File

@@ -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

View File

@@ -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)

View File

@@ -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]) (<A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[epicenter.x];Y=[epicenter.y];Z=[epicenter.z]'>JMP</a>)")
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)

View File

@@ -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 << "<span class='danger'>You smash against the wall!</span>"
take_damage(rand(25,75))