mirror of
https://github.com/vgstation-coders/vgstation13.git
synced 2025-12-10 18:32:03 +00:00
* multi-z look up verb * now updates instantly * tidies this up too * updates syntax * dynamically updates these verbs --------- Co-authored-by: SECBATON-GRIFFON <kanef9x@protonmail.com> Co-authored-by: SECBATON-GRIFFON <>
131 lines
4.7 KiB
Plaintext
131 lines
4.7 KiB
Plaintext
#define OPENSPACE_PLANE_START -23
|
|
#define OPENSPACE_PLANE_END -8
|
|
#define OPENSPACE_PLANE -25
|
|
#define OVER_OPENSPACE_PLANE -7
|
|
|
|
/turf/proc/is_space()
|
|
return 0
|
|
|
|
/turf/space/is_space()
|
|
return 1
|
|
|
|
// Called after turf replaces old one
|
|
/turf/proc/post_change()
|
|
levelupdate()
|
|
var/turf/simulated/open/T = GetAbove(src)
|
|
if(istype(T))
|
|
T.update_icon()
|
|
|
|
|
|
/proc/is_on_same_plane_or_station(var/z1, var/z2)
|
|
if(z1 == z2)
|
|
return 1
|
|
if((z1 in map.zLevels) && (z2 in map.zLevels))
|
|
return 1
|
|
return 0
|
|
|
|
// BEGIN /VG/ CODE
|
|
|
|
// Helper for the below
|
|
/proc/get_zs_away(atom/Loc1,atom/Loc2)
|
|
if(Loc1.z == Loc2.z)
|
|
return 0 // Nip this in the bud to save performance maybe
|
|
if(!(HasAbove(Loc1.z) && HasBelow(Loc1.z)) || !(HasAbove(Loc2.z) && HasBelow(Loc2.z)) || !AreConnectedZLevels(Loc1.z, Loc2.z))
|
|
return INFINITY // Redundant to below but sanity checking and performance
|
|
|
|
var/dist_above = 0
|
|
var/dist_below = 0
|
|
var/above_found = FALSE // Using booleans to see how we handle this later, don't want us hitting the ceiling and pulling a short distance when it wasn't found
|
|
var/below_found = FALSE
|
|
|
|
for(var/level = Loc1.z, HasBelow(level), level = map.zLevels[level].z_below)
|
|
if(level == Loc2.z)
|
|
below_found = TRUE
|
|
break
|
|
dist_below++
|
|
if(map.zLevels[level].z_below == Loc1.z) // If we end up where we started, get out of the infinite loop (called after value is upped)
|
|
break
|
|
|
|
for(var/level = Loc1.z, HasAbove(level), level = map.zLevels[level].z_above)
|
|
if(level == Loc2.z)
|
|
above_found = TRUE
|
|
break
|
|
dist_above++
|
|
if(map.zLevels[level].z_above == Loc1.z)
|
|
break
|
|
|
|
if(above_found && below_found)
|
|
return min(dist_above,dist_below) // Get minimum of each if found above AND below
|
|
else if(above_found)
|
|
return dist_above // Otherwise as normal
|
|
else if(below_found)
|
|
return dist_below
|
|
return INFINITY // Yeah, redundant
|
|
|
|
/**
|
|
* Z-Distance functions
|
|
*
|
|
* Because vanilla get_dist() only gets the max value of either x or y and not z for some reason, thanks BYOND!
|
|
*
|
|
* Euclidean follows suit for the proper formula
|
|
*/
|
|
/proc/get_z_dist(atom/Loc1, atom/Loc2)
|
|
var/dx = abs(Loc1.x - Loc2.x)
|
|
var/dy = abs(Loc1.y - Loc2.y)
|
|
var/dz = get_zs_away(Loc1,Loc2)
|
|
|
|
return max(dx,dy,dz)
|
|
|
|
/proc/get_z_dist_euclidian(atom/Loc1, atom/Loc2)
|
|
var/dx = Loc1.x - Loc2.x
|
|
var/dy = Loc1.y - Loc2.y
|
|
var/dz = get_zs_away(Loc1,Loc2)
|
|
|
|
return sqrt(dx**2 + dy**2 + dz**2)
|
|
|
|
/**
|
|
* Get Distance, Squared
|
|
*
|
|
* Because sqrt is slow, this returns the z distance squared, which skips the sqrt step.
|
|
*
|
|
* Use to compare distances. Used in component mobs.
|
|
*/
|
|
/proc/get_z_dist_squared(var/atom/a, var/atom/b)
|
|
|
|
return ((b.x-a.x)**2) + ((b.y-a.y)**2) + ((get_zs_away(a,b))**2)
|
|
|
|
/proc/multi_z_spiral_block(var/turf/epicenter,var/max_range,var/draw_red=0,var/cube=1)
|
|
var/turf/upturf = epicenter
|
|
var/turf/downturf = epicenter
|
|
. = spiral_block(epicenter,max_range,draw_red)
|
|
for(var/i = 1, i < max_range, i++)
|
|
if(HasAbove(upturf.z))
|
|
upturf = GetAbove(upturf)
|
|
log_debug("Spiralling block of size [cube ? max_range : i + (max_range - i)] in [upturf.loc.name] ([upturf.x],[upturf.y],[upturf.z])")
|
|
. += spiral_block(upturf, cube ? max_range : max_range - i, draw_red)
|
|
if(HasBelow(downturf.z))
|
|
downturf = GetBelow(downturf)
|
|
log_debug("Spiralling block of size [cube ? max_range : i + (max_range - i)] in [downturf.loc.name] ([downturf.x],[downturf.y],[downturf.z])")
|
|
. += spiral_block(downturf, cube ? max_range : max_range - i, draw_red)
|
|
|
|
/client/proc/check_multi_z_spiral()
|
|
set name = "Check Multi-Z Spiral Block"
|
|
set category = "Debug"
|
|
|
|
var/turf/epicenter = get_turf(usr)
|
|
var/max_range = input("Set the max range") as num
|
|
var/shape_txt = alert("What shape?","Spiral Block", "Cube","Octahedron")
|
|
var/shape = shape_txt == "Cube" ? 1 : 0
|
|
multi_z_spiral_block(epicenter,max_range,shape)
|
|
|
|
// Halves above and below, as per suggestion by deity on how to handle multi-z explosions
|
|
/proc/explosion_destroy_multi_z(turf/epicenter, turf/offcenter, const/devastation_range, const/heavy_impact_range, const/light_impact_range, const/flash_range, var/explosion_time, var/mob/whodunnit)
|
|
if(HasAbove(offcenter.z) && (devastation_range >= 1 || heavy_impact_range >= 1 || light_impact_range >= 1 || flash_range >= 1))
|
|
var/turf/upcenter = GetAbove(offcenter)
|
|
if(upcenter.z > epicenter.z)
|
|
explosion_destroy(epicenter, upcenter, devastation_range, heavy_impact_range, light_impact_range, flash_range, explosion_time, whodunnit)
|
|
if(HasBelow(offcenter.z) && (devastation_range >= 1 || heavy_impact_range >= 1 || light_impact_range >= 1 || flash_range >= 1))
|
|
var/turf/downcenter = GetBelow(offcenter)
|
|
if(downcenter.z < epicenter.z)
|
|
explosion_destroy(epicenter, downcenter, devastation_range, heavy_impact_range, light_impact_range, flash_range, explosion_time, whodunnit)
|