Fixes multi-z things.

This commit is contained in:
Joseph Heinemeyer
2015-08-30 15:43:32 -07:00
committed by SkyMarshal
parent 772c320303
commit 8c61c3ab6f
17 changed files with 251 additions and 655 deletions

View File

@@ -9,8 +9,8 @@
// FOR THE LOVE OF GOD USE THESE. DO NOT FUCKING SPAGHETTIFY THIS.
// Use the Has*() functions if you ONLY need to check.
// If you need to do something, use Get*().
proc/HasAbove(var/z)
proc/HasBelow(var/z)
HasAbove(var/z)
HasBelow(var/z)
// These give either the turf or null.
proc/GetAbove(var/turf/turf)
proc/GetBelow(var/turf/turf)
GetAbove(var/atom/atom)
GetBelow(var/atom/atom)

View File

@@ -4,28 +4,32 @@ var/z_levels = 0 // Each bit represents a connection between adjacent levels. S
// If the height is more than 1, we mark all contained levels as connected.
/obj/effect/landmark/map_data/New()
for(var/i = z - 1 to height - 2)
z_levels |= 1 << i
del src
ASSERT(height <= z)
// Due to the offsets of how connections are stored v.s. how z-levels are indexed, some magic number silliness happened.
for(var/i = (z - height) to (z - 2))
z_levels |= (1 << i)
qdel(src)
HasAbove(z)
if(z > world.maxz || z > 17 || z < 2)
// The storage of connections between adjacent levels means some bitwise magic is needed.
proc/HasAbove(var/z)
if(z >= world.maxz || z > 16 || z < 1)
return 0
return z_levels & (1 << (z - 1))
HasBelow(z)
if(z >= world.maxz || z > 16 || z < 1)
proc/HasBelow(var/z)
if(z > world.maxz || z > 17 || z < 2)
return 0
return z_levels & (1 << z)
return z_levels & (1 << (z - 2))
GetAbove(var/atom/thing)
var/turf/turf = get_turf(thing)
if(!istype(turf))
// Thankfully, no bitwise magic is needed here.
proc/GetAbove(var/atom/atom)
var/turf/turf = get_turf(atom)
if(!turf)
return null
return HasBelow(turf.z) ? locate(turf.z, turf.y, turf.z - 1) : null
return HasAbove(turf.z) ? get_step(turf, UP) : null
GetBelow(var/atom/thing)
var/turf/turf = get_turf(thing)
if(!istype(turf))
proc/GetBelow(var/atom/atom)
var/turf/turf = get_turf(atom)
if(!turf)
return null
return HasBelow(turf.z) ? locate(turf.z, turf.y, turf.z + 1) : null
return HasBelow(turf.z) ? get_step(turf, DOWN) : null

View File

@@ -0,0 +1,10 @@
proc/HasAbove(var/z)
return 0
proc/HasBelow(var/z)
return 0
// These give either the turf or null.
proc/GetAbove(var/turf/turf)
return null
proc/GetBelow(var/turf/turf)
return null

View File

@@ -0,0 +1,51 @@
/obj/item/weapon/tank/jetpack/verb/moveup()
set name = "Move Upwards"
set category = "Object"
. = 1
if(!allow_thrust(0.01, usr))
usr << "<span class='warning'>\The [src] is disabled.</span>"
return
var/turf/above = GetAbove(src)
if(!istype(above))
usr << "<span class='notice'>There is nothing of interest in this direction.</span>"
return
if(!istype(above, /turf/space) && !istype(above, /turf/simulated/open))
usr << "<span class='warning'>You bump against \the [above].</span>"
return
for(var/atom/A in above)
if(A.density)
usr << "<span class='warning'>\The [A] blocks you.</span>"
return
usr.Move(above)
usr << "<span class='notice'>You move upwards.</span>"
/obj/item/weapon/tank/jetpack/verb/movedown()
set name = "Move Downwards"
set category = "Object"
. = 1
if(!allow_thrust(0.01, usr))
usr << "<span class='warning'>\The [src] is disabled.</span>"
return
var/turf/below = GetBelow(src)
if(!istype(below))
usr << "<span class='notice'>There is nothing of interest in this direction.</span>"
return
if(below.density)
usr << "<span class='warning'>You bump against \the [below].</span>"
return
for(var/atom/A in below)
if(A.density)
usr << "<span class='warning'>\The [A] blocks you.</span>"
return
usr.Move(below)
usr << "<span class='notice'>You move downwards.</span>"

View File

@@ -0,0 +1,227 @@
////////////////////////////
// parent class for pipes //
////////////////////////////
obj/machinery/atmospherics/pipe/zpipe
icon = 'icons/obj/structures.dmi'
icon_state = "up"
name = "upwards pipe"
desc = "A pipe segment to connect upwards."
volume = 70
dir = SOUTH
initialize_directions = SOUTH
var/obj/machinery/atmospherics/node1 //connection on the same Z
var/obj/machinery/atmospherics/node2 //connection on the other Z
var/minimum_temperature_difference = 300
var/thermal_conductivity = 0 //WALL_HEAT_TRANSFER_COEFFICIENT No
var/maximum_pressure = 70*ONE_ATMOSPHERE
var/fatigue_pressure = 55*ONE_ATMOSPHERE
alert_pressure = 55*ONE_ATMOSPHERE
level = 1
obj/machinery/atmospherics/pipe/zpipe/New()
..()
switch(dir)
if(SOUTH)
initialize_directions = SOUTH
if(NORTH)
initialize_directions = NORTH
if(WEST)
initialize_directions = WEST
if(EAST)
initialize_directions = EAST
if(NORTHEAST)
initialize_directions = NORTH
if(NORTHWEST)
initialize_directions = WEST
if(SOUTHEAST)
initialize_directions = EAST
if(SOUTHWEST)
initialize_directions = SOUTH
/obj/machinery/atmospherics/pipe/zpipe/hide(var/i)
if(istype(loc, /turf/simulated))
invisibility = i ? 101 : 0
update_icon()
obj/machinery/atmospherics/pipe/up/process()
if(!parent) //This should cut back on the overhead calling build_network thousands of times per cycle
..()
else
. = PROCESS_KILL
obj/machinery/atmospherics/pipe/zpipe/check_pressure(pressure)
var/datum/gas_mixture/environment = loc.return_air()
var/pressure_difference = pressure - environment.return_pressure()
if(pressure_difference > maximum_pressure)
burst()
else if(pressure_difference > fatigue_pressure)
//TODO: leak to turf, doing pfshhhhh
if(prob(5))
burst()
else return 1
obj/machinery/atmospherics/pipe/zpipe/proc/burst()
src.visible_message("<span class='warning'>\The [src] bursts!</span>");
playsound(src.loc, 'sound/effects/bang.ogg', 25, 1)
var/datum/effect/effect/system/smoke_spread/smoke = new
smoke.set_up(1,0, src.loc, 0)
smoke.start()
qdel(src) // NOT qdel.
obj/machinery/atmospherics/pipe/zpipe/proc/normalize_dir()
if(dir==3)
set_dir(1)
else if(dir==12)
set_dir(4)
obj/machinery/atmospherics/pipe/zpipe/Destroy()
if(node1)
node1.disconnect(src)
if(node2)
node2.disconnect(src)
..()
obj/machinery/atmospherics/pipe/zpipe/pipeline_expansion()
return list(node1, node2)
obj/machinery/atmospherics/pipe/zpipe/update_icon()
return
obj/machinery/atmospherics/pipe/zpipe/disconnect(obj/machinery/atmospherics/reference)
if(reference == node1)
if(istype(node1, /obj/machinery/atmospherics/pipe))
qdel(parent)
node1 = null
if(reference == node2)
if(istype(node2, /obj/machinery/atmospherics/pipe))
qdel(parent)
node2 = null
return null
/////////////////////////
// the elusive up pipe //
/////////////////////////
obj/machinery/atmospherics/pipe/zpipe/up
icon = 'icons/obj/structures.dmi'
icon_state = "up"
name = "upwards pipe"
desc = "A pipe segment to connect upwards."
obj/machinery/atmospherics/pipe/zpipe/up/initialize()
normalize_dir()
var/node1_dir
for(var/direction in cardinal)
if(direction&initialize_directions)
if (!node1_dir)
node1_dir = direction
for(var/obj/machinery/atmospherics/target in get_step(src,node1_dir))
if(target.initialize_directions & get_dir(target,src))
if (check_connect_types(target,src))
node1 = target
break
var/turf/above = GetAbove(src)
if(above)
for(var/obj/machinery/atmospherics/target in above)
if(target.initialize_directions && istype(target, /obj/machinery/atmospherics/pipe/zpipe/down))
if (check_connect_types(target,src))
node2 = target
break
var/turf/T = src.loc // hide if turf is not intact
hide(!T.is_plating())
///////////////////////
// and the down pipe //
///////////////////////
obj/machinery/atmospherics/pipe/zpipe/down
icon = 'icons/obj/structures.dmi'
icon_state = "down"
name = "downwards pipe"
desc = "A pipe segment to connect downwards."
obj/machinery/atmospherics/pipe/zpipe/down/initialize()
normalize_dir()
var/node1_dir
for(var/direction in cardinal)
if(direction&initialize_directions)
if (!node1_dir)
node1_dir = direction
for(var/obj/machinery/atmospherics/target in get_step(src,node1_dir))
if(target.initialize_directions & get_dir(target,src))
if (check_connect_types(target,src))
node1 = target
break
var/turf/below = GetBelow(src)
if(below)
for(var/obj/machinery/atmospherics/target in below)
if(target.initialize_directions && istype(target, /obj/machinery/atmospherics/pipe/zpipe/up))
if (check_connect_types(target,src))
node2 = target
break
var/turf/T = src.loc // hide if turf is not intact
hide(!T.is_plating())
///////////////////////
// supply/scrubbers //
///////////////////////
obj/machinery/atmospherics/pipe/zpipe/up/scrubbers
icon_state = "up-scrubbers"
name = "upwards scrubbers pipe"
desc = "A scrubbers pipe segment to connect upwards."
connect_types = CONNECT_TYPE_SCRUBBER
layer = 2.38
icon_connect_type = "-scrubbers"
color = PIPE_COLOR_RED
obj/machinery/atmospherics/pipe/zpipe/up/supply
icon_state = "up-supply"
name = "upwards supply pipe"
desc = "A supply pipe segment to connect upwards."
connect_types = CONNECT_TYPE_SUPPLY
layer = 2.39
icon_connect_type = "-supply"
color = PIPE_COLOR_BLUE
obj/machinery/atmospherics/pipe/zpipe/down/scrubbers
icon_state = "down-scrubbers"
name = "downwards scrubbers pipe"
desc = "A scrubbers pipe segment to connect downwards."
connect_types = CONNECT_TYPE_SCRUBBER
layer = 2.38
icon_connect_type = "-scrubbers"
color = PIPE_COLOR_RED
obj/machinery/atmospherics/pipe/zpipe/down/supply
icon_state = "down-supply"
name = "downwards supply pipe"
desc = "A supply pipe segment to connect downwards."
connect_types = CONNECT_TYPE_SUPPLY
layer = 2.39
icon_connect_type = "-supply"
color = PIPE_COLOR_BLUE

View File

@@ -0,0 +1,86 @@
//////////////////////////////
//Contents: Ladders, Stairs.//
//////////////////////////////
/obj/structure/ladder
name = "ladder"
desc = "A ladder. You can climb it up and down."
icon_state = "ladderdown"
icon = 'icons/obj/structures.dmi'
density = 0
opacity = 0
anchored = 1
var/obj/structure/ladder/target
initialize()
// the upper will connect to the lower
if(icon_state == "ladderup")
return
for(var/obj/structure/ladder/L in GetBelow(src))
if(L.icon_state == "ladderup")
target = L
L.target = src
return
Destroy()
if(target && icon_state == "ladderdown")
qdel(target)
return ..()
attackby(obj/item/C as obj, mob/user as mob)
. = ..()
attack_hand(user)
return
attack_hand(var/mob/M)
if(!target || !istype(target.loc, /turf))
M << "<span class='notice'>\The [src] is incomplete and can't be climbed.</span>"
return
var/turf/T = target.loc
for(var/atom/A in T)
if(A.density)
M << "<span class='notice'>\A [A] is blocking \the [src].</span>"
return
M.visible_message("<span class='notice'>\A [M] climbs [icon_state == "ladderup" ? "up" : "down"] \a [src]!</span>",
"You climb [icon_state == "ladderup" ? "up" : "down"] \the [src]!",
"You hear the grunting and clanging of a metal ladder being used.")
M.Move(T)
CanPass(obj/mover, turf/source, height, airflow)
return airflow || !density
/obj/structure/stairs
name = "Stairs"
desc = "Stairs. You walk up and down them."
icon_state = "rampbottom"
icon = 'icons/obj/structures.dmi'
density = 0
opacity = 0
anchored = 1
var/obj/structure/stairs/connected
New()
..()
var/turf/above = GetAbove(src)
if(istype(above, /turf/space))
above.ChangeTurf(/turf/simulated/open)
initialize()
var/updown = icon_state == "rampbottom" ? UP : DOWN
var/turf/T = get_step(src, dir | updown)
connected = locate() in T
ASSERT(connected)
Uncross(var/atom/movable/M)
if(connected && M.dir == dir)
M.loc = connected.loc
return 1
CanPass(obj/mover, turf/source, height, airflow)
return airflow || !density

111
code/modules/multiz/turf.dm Normal file
View File

@@ -0,0 +1,111 @@
/turf/simulated/open
name = "open space"
icon = 'icons/turf/space.dmi'
icon_state = "black"
alpha = 16
layer = 0
density = 0
pathweight = 100000 //Seriously, don't try and path over this one numbnuts
var/turf/below
var/list/underlay_references
var/global/overlay_map = list()
/turf/simulated/open/New()
. = ..()
ASSERT(HasBelow(z))
below = GetBelow(src)
/turf/simulated/open/Entered(var/atom/movable/mover)
// only fall down in defined areas (read: areas with artificial gravitiy)
if(!istype(below)) //make sure that there is actually something below
below = GetBelow(src)
if(!below)
return
// No gravity in space, apparently.
var/area/area = get_area(src)
if(area.name == "Space")
return
// Prevent pipes from falling into the void... if there is a pipe to support it.
if(istype(mover, /obj/item/pipe) && \
(locate(/obj/structure/disposalpipe/up) in below) || \
locate(/obj/machinery/atmospherics/pipe/zpipe/up in below))
return
// See if something prevents us from falling.
var/soft = 0
for(var/atom/A in below)
if(A.density)
if(!istype(A, /obj/structure/window))
return
else
var/obj/structure/window/W = A
if(W.is_fulltile())
return
// Dont break here, since we still need to be sure that it isnt blocked
if(istype(A, /obj/structure/stairs))
soft = 1
// We've made sure we can move, now.
mover.Move(below)
if(!soft)
if(!istype(mover, /mob))
if(istype(below, /turf/simulated/open))
below.visible_message("\The [mover] falls from the deck above through \the [below]!", "You hear a whoosh of displaced air.")
else
below.visible_message("\The [mover] falls from the deck above and slams into \the [below]!", "You hear something slam into the deck.")
else
var/mob/M = mover
if(istype(below, /turf/simulated/open))
below.visible_message("\The [mover] falls from the deck above through \the [below]!", "You hear a soft whoosh.[M.stat ? "" : ".. and some screaming."]")
else
M.visible_message("\The [mover] falls from the deck above and slams into \the [below]!", "You land on \the [below].", "You hear a soft whoosh and a crunch")
// Handle people getting hurt, it's funny!
if (istype(mover, /mob/living/carbon/human))
var/mob/living/carbon/human/H = mover
var/damage = 5
H.apply_damage(rand(0, damage), BRUTE, "head")
H.apply_damage(rand(0, damage), BRUTE, "chest")
H.apply_damage(rand(0, damage), BRUTE, "l_leg")
H.apply_damage(rand(0, damage), BRUTE, "r_leg")
H.apply_damage(rand(0, damage), BRUTE, "l_arm")
H.apply_damage(rand(0, damage), BRUTE, "r_arm")
H.weakened = max(H.weakened,2)
H.updatehealth()
// override to make sure nothing is hidden
/turf/simulated/open/levelupdate()
for(var/obj/O in src)
O.hide(0)
// Straight copy from space.
/turf/simulated/open/attackby(obj/item/C as obj, mob/user as mob)
if (istype(C, /obj/item/stack/rods))
var/obj/structure/lattice/L = locate(/obj/structure/lattice, src)
if(L)
return
var/obj/item/stack/rods/R = C
if (R.use(1))
user << "<span class='notice'>Constructing support lattice ...</span>"
playsound(src, 'sound/weapons/Genhit.ogg', 50, 1)
ReplaceWithLattice()
return
if (istype(C, /obj/item/stack/tile/floor))
var/obj/structure/lattice/L = locate(/obj/structure/lattice, src)
if(L)
var/obj/item/stack/tile/floor/S = C
if (S.get_amount() < 1)
return
qdel(L)
playsound(src, 'sound/weapons/Genhit.ogg', 50, 1)
S.use(1)
ChangeTurf(/turf/simulated/floor/airless)
return
else
user << "<span class='warning'>The plating is going to need some support.</span>"
return