diff --git a/baystation12.dme b/baystation12.dme
index d5d6d411620..d8248340b5e 100644
--- a/baystation12.dme
+++ b/baystation12.dme
@@ -1411,6 +1411,12 @@
#include "code\modules\mob\new_player\preferences_setup.dm"
#include "code\modules\mob\new_player\skill.dm"
#include "code\modules\mob\new_player\sprite_accessories.dm"
+#include "code\modules\multiz\_stubs.dm"
+#include "code\modules\multiz\basic.dm"
+#include "code\modules\multiz\movement.dm"
+#include "code\modules\multiz\pipes.dm"
+#include "code\modules\multiz\structures.dm"
+#include "code\modules\multiz\turf.dm"
#include "code\modules\nano\_JSON.dm"
#include "code\modules\nano\JSON Reader.dm"
#include "code\modules\nano\JSON Writer.dm"
@@ -1785,13 +1791,6 @@
#include "code\modules\virus2\items_devices.dm"
#include "code\modules\xgm\xgm_gas_data.dm"
#include "code\modules\xgm\xgm_gas_mixture.dm"
-#include "code\TriDimension\controller.dm"
-#include "code\TriDimension\controller_presets.dm"
-#include "code\TriDimension\Movement.dm"
-#include "code\TriDimension\Pipes.dm"
-#include "code\TriDimension\Structures.dm"
-#include "code\TriDimension\Structures_presets.dm"
-#include "code\TriDimension\Turfs.dm"
#include "code\ZAS\_docs.dm"
#include "code\ZAS\Airflow.dm"
#include "code\ZAS\Atom.dm"
diff --git a/code/TriDimension/Movement.dm b/code/TriDimension/Movement.dm
deleted file mode 100644
index 3637184d31a..00000000000
--- a/code/TriDimension/Movement.dm
+++ /dev/null
@@ -1,52 +0,0 @@
-/obj/item/weapon/tank/jetpack/verb/moveup()
- set name = "Move Upwards"
- set category = "Object"
- if(allow_thrust(0.01, usr))
- var/turf/controllerlocation = locate(1, 1, usr.z)
- var/legal = 0
- for(var/obj/effect/landmark/zcontroller/controller in controllerlocation)
- legal = controller.up
- if (controller.up)
- var/turf/T = locate(usr.x, usr.y, controller.up_target)
- if(T && (istype(T, /turf/space) || istype(T, /turf/simulated/floor/open)))
- var/blocked = 0
- for(var/atom/A in T.contents)
- if(A.density)
- blocked = 1
- usr << "You bump into \the [A]."
- break
- if(!blocked)
- usr.Move(T)
- usr << "You move upwards."
- else
- usr << "There is something in your way."
- if (legal == 0)
- usr << "There is nothing of interest in this direction."
- return 1
-
-/obj/item/weapon/tank/jetpack/verb/movedown()
- set name = "Move Downwards"
- set category = "Object"
- if(allow_thrust(0.01, usr))
- var/turf/controllerlocation = locate(1, 1, usr.z)
- var/legal = 0
- for(var/obj/effect/landmark/zcontroller/controller in controllerlocation)
- legal = controller.down
- if (controller.down == 1)
- var/turf/T = locate(usr.x, usr.y, controller.down_target)
- var/turf/S = locate(usr.x, usr.y, usr.z)
- if(T && (istype(S, /turf/space) || istype(S, /turf/simulated/floor/open)))
- var/blocked = 0
- for(var/atom/A in T.contents)
- if(A.density)
- blocked = 1
- usr << "You bump into \the [A]."
- break
- if(!blocked)
- usr.Move(T)
- usr << "You move downwards."
- else
- usr << "You cant move through the floor."
- if (legal == 0)
- usr << "There is nothing of interest in this direction."
- return 1
diff --git a/code/TriDimension/Structures.dm b/code/TriDimension/Structures.dm
deleted file mode 100644
index 99151936f5f..00000000000
--- a/code/TriDimension/Structures.dm
+++ /dev/null
@@ -1,274 +0,0 @@
-///////////////////////////////////////
-//Contents: Ladders, Hatches, Stairs.//
-///////////////////////////////////////
-
-/obj/multiz
- icon = 'icons/obj/structures.dmi'
- density = 0
- opacity = 0
- anchored = 1
-
- CanPass(obj/mover, turf/source, height, airflow)
- return airflow || !density
-
-/obj/multiz/ladder
- icon_state = "ladderdown"
- name = "ladder"
- desc = "A ladder. You climb up and down it."
-
- var/d_state = 1
- var/obj/multiz/target
-
- New()
- . = ..()
-
- proc/connect()
- if(icon_state == "ladderdown") // the upper will connect to the lower
- d_state = 1
- var/turf/controllerlocation = locate(1, 1, z)
- for(var/obj/effect/landmark/zcontroller/controller in controllerlocation)
- if(controller.down)
- var/turf/below = locate(src.x, src.y, controller.down_target)
- for(var/obj/multiz/ladder/L in below)
- if(L.icon_state == "ladderup")
- target = L
- L.target = src
- d_state = 0
- break
- return
-
-/* ex_act(severity)
- switch(severity)
- if(1.0)
- if(icon_state == "ladderup" && prob(10))
- qdel(src)
- if(2.0)
- if(prob(50))
- qdel(src)
- if(3.0)
- qdel(src)
- return*/
-
- Destroy()
- spawn(1)
- if(target && icon_state == "ladderdown")
- qdel(target)
- return ..()
-
- attackby(obj/item/C as obj, mob/user as mob)
- (..)
-
-// construction commented out for balance concerns
-/* if (!target && istype(C, /obj/item/stack/rods))
- var/turf/controllerlocation = locate(1, 1, z)
- var/found = 0
- var/obj/item/stack/rods/S = C
- if(S.amount < 2)
- user << "You dont have enough rods to finish the ladder."
- return
- for(var/obj/effect/landmark/zcontroller/controller in controllerlocation)
- if(controller.down)
- found = 1
- var/turf/below = locate(src.x, src.y, controller.down_target)
- var/blocked = 0
- for(var/atom/A in below.contents)
- if(A.density)
- blocked = 1
- break
- if(!blocked && !istype(below, /turf/simulated/wall))
- var/obj/multiz/ladder/X = new /obj/multiz/ladder(below)
- S.amount = S.amount - 2
- if(S.amount == 0) qdel(S)
- X.icon_state = "ladderup"
- connect()
- user << "You finish the ladder."
- else
- user << "The area below is blocked."
- if(!found)
- user << "You cant build a ladder down there."
- return
-
- else if (icon_state == "ladderdown" && d_state == 0 && istype(C, /obj/item/weapon/wrench))
- user << "You start loosening the anchoring bolts which secure the ladder to the frame."
- playsound(src.loc, 'sound/items/Ratchet.ogg', 100, 1)
-
- sleep(30)
- if(!user || !C) return
-
- src.d_state = 1
- if(target)
- var/obj/item/stack/rods/R = PoolOrNew(/obj/item/stack/rods, target.loc)
- R.amount = 2
- qdel(Target)
-
- user << "You remove the bolts anchoring the ladder."
- return
-
- else if (icon_state == "ladderdown" && d_state == 1 && istype(C, /obj/item/weapon/weldingtool) )
- var/obj/item/weapon/weldingtool/WT = C
- if( WT.remove_fuel(0,user) )
-
- user << "You begin to remove the ladder."
- playsound(src.loc, 'sound/items/Welder.ogg', 100, 1)
-
- sleep(60)
- if(!user || !WT || !WT.isOn()) return
-
- var/obj/item/stack/material/steel/S = new /obj/item/stack/material/steel( src )
- S.amount = 2
- user << "You remove the ladder and close the hole."
- qdel(src)
- else
- user << "You need more welding fuel to complete this task."
- return
-
- else
- src.attack_hand(user)
- return*/
- src.attack_hand(user)
- return
-
- attack_hand(var/mob/M)
- if(!target || !istype(target.loc, /turf))
- M << "The ladder is incomplete and can't be climbed."
- else
- var/turf/T = target.loc
- var/blocked = 0
- for(var/atom/A in T.contents)
- if(A.density)
- blocked = 1
- break
- if(blocked || istype(T, /turf/simulated/wall))
- M << "Something is blocking the ladder."
- else
- M.visible_message("\The [M] climbs [src.icon_state == "ladderup" ? "up" : "down"] \the [src]!", "You climb [src.icon_state == "ladderup" ? "up" : "down"] \the [src]!", "You hear some grunting, and clanging of a metal ladder being used.")
- M.Move(target.loc)
-
-/* hatch
- icon_state = "hatchdown"
- name = "hatch"
- desc = "A hatch. You climb down it, and it will automatically seal against pressure loss behind you."
- top_icon_state = "hatchdown"
- var/top_icon_state_open = "hatchdown-open"
- var/top_icon_state_close = "hatchdown-close"
-
- bottom_icon_state = "ladderup"
-
- var/image/green_overlay
- var/image/red_overlay
-
- var/active = 0
-
- New()
- . = ..()
- red_overlay = image(icon, "red-ladderlight")
- green_overlay = image(icon, "green-ladderlight")
-
- attack_hand(var/mob/M)
-
- if(!target || !istype(target.loc, /turf))
- qdel(src)
-
- if(active)
- M << "That [src] is being used."
- return // It is a tiny airlock, only one at a time.
-
- active = 1
- var/obj/multiz/ladder/hatch/top_hatch = target
- var/obj/multiz/ladder/hatch/bottom_hatch = src
- if(icon_state == top_icon_state)
- top_hatch = src
- bottom_hatch = target
-
- flick(top_icon_state_open, top_hatch)
- bottom_hatch.overlays += green_overlay
-
- spawn(7)
- if(!target || !istype(target.loc, /turf))
- qdel(src)
- if(M.z == z && get_dist(src,M) <= 1)
- var/list/adjacent_to_me = global_adjacent_z_levels["[z]"]
- M.visible_message("\The [M] scurries [target.z == adjacent_to_me["up"] ? "up" : "down"] \the [src]!", "You scramble [target.z == adjacent_to_me["up"] ? "up" : "down"] \the [src]!", "You hear some grunting, and a hatch sealing.")
- M.Move(target.loc)
- flick(top_icon_state_close,top_hatch)
- bottom_hatch.overlays -= green_overlay
- bottom_hatch.overlays += red_overlay
-
- spawn(7)
- top_hatch.icon_state = top_icon_state
- bottom_hatch.overlays -= red_overlay
- active = 0*/
-
-/obj/multiz/stairs
- name = "Stairs"
- desc = "Stairs. You walk up and down them."
- icon_state = "rampbottom"
- var/obj/multiz/stairs/connected
- var/turf/target
- var/turf/target2
- var/suggest_dir // try this dir first when finding stairs; this is the direction to walk *down* the stairs
-
- New()
- ..()
- var/turf/cl= locate(1, 1, src.z)
- for(var/obj/effect/landmark/zcontroller/c in cl)
- if(c.up)
- var/turf/O = locate(src.x, src.y, c.up_target)
- if(istype(O, /turf/space))
- O.ChangeTurf(/turf/simulated/floor/open)
-
- spawn(1)
- var/turf/T
- if(suggest_dir)
- T = get_step(src.loc,suggest_dir)
- find_stair_connection(T, suggest_dir, 1)
- if(!target)
- for(var/dir in cardinal)
- T = get_step(src.loc,dir)
- find_stair_connection(T, dir)
- if(target)
- break
-
- Bumped(var/atom/movable/M)
- if(connected && target && istype(src, /obj/multiz/stairs) && locate(/obj/multiz/stairs) in M.loc)
- var/obj/multiz/stairs/Con = locate(/obj/multiz/stairs) in M.loc
- if(Con == src.connected) //make sure the atom enters from the approriate lower stairs tile
- M.Move(target)
- return
-
- proc/find_stair_connection(var/turf/T, var/dir, var/suggested=0)
- for(var/obj/multiz/stairs/S in T)
- if(S && S.icon_state == "rampbottom" && !S.connected)
- if(!S.suggest_dir || S.suggest_dir == dir) // it doesn't have a suggested direction, or it's the same direction as we're trying, so we connect to it
- initialise_stair_connection(src, S, dir)
- else if(!suggested) // we're trying directions, so it could be a reverse stair (i.e. we're the bottom stair rather than the top)
- var/inv_dir = 0
- switch(dir)
- if(1)
- inv_dir = 2
- if(2)
- inv_dir = 1
- if(4)
- inv_dir = 8
- if(8)
- inv_dir = 4
- if(S.suggest_dir == inv_dir)
- initialise_stair_connection(S, src, inv_dir)
-
- proc/initialise_stair_connection(var/obj/multiz/stairs/top, var/obj/multiz/stairs/bottom, var/dir)
- top.set_dir(dir)
- bottom.set_dir(dir)
- top.connected = bottom
- bottom.connected = top
- top.icon_state = "ramptop"
- top.density = 1
- var/turf/controllerlocation = locate(1, 1, top.z)
- for(var/obj/effect/landmark/zcontroller/controller in controllerlocation)
- if(controller.up)
- var/turf/above = locate(top.x, top.y, controller.up_target)
- if(istype(above,/turf/space) || istype(above,/turf/simulated/floor/open))
- top.target = above
- var/turf/above2 = locate(bottom.x, bottom.y, controller.up_target)
- if(istype(above2, /turf/space) || istype(above,/turf/simulated/floor/open))
- top.target2 = above2
- return
diff --git a/code/TriDimension/Structures_presets.dm b/code/TriDimension/Structures_presets.dm
deleted file mode 100644
index 7a28efe2112..00000000000
--- a/code/TriDimension/Structures_presets.dm
+++ /dev/null
@@ -1,11 +0,0 @@
-/obj/multiz/stairs/north_up
- suggest_dir = SOUTH
-
-/obj/multiz/stairs/south_up
- suggest_dir = NORTH
-
-/obj/multiz/stairs/east_up
- suggest_dir = WEST
-
-/obj/multiz/stairs/west_up
- suggest_dir = EAST
\ No newline at end of file
diff --git a/code/TriDimension/Turfs.dm b/code/TriDimension/Turfs.dm
deleted file mode 100644
index c601e36b992..00000000000
--- a/code/TriDimension/Turfs.dm
+++ /dev/null
@@ -1,128 +0,0 @@
-/turf/simulated/floor/open
- name = "open space"
- density = 0
- icon_state = "black"
- pathweight = 100000 //Seriously, don't try and path over this one numbnuts
- var/icon/darkoverlays = null
- var/turf/floorbelow
- var/list/overlay_references
-
- New()
- ..()
- getbelow()
- return
-
- Enter(var/atom/movable/AM)
- if (..()) //TODO make this check if gravity is active (future use) - Sukasa
- spawn(1)
- // only fall down in defined areas (read: areas with artificial gravitiy)
- if(!floorbelow) //make sure that there is actually something below
- if(!getbelow())
- return
- if(AM)
- var/area/areacheck = get_area(src)
- var/blocked = 0
- var/soft = 0
- for(var/atom/A in floorbelow.contents)
- if(A.density)
- if(istype(A, /obj/structure/window))
- var/obj/structure/window/W = A
- blocked = W.is_fulltile()
- if(blocked)
- break
- else
- blocked = 1
- break
- if(istype(A, /obj/machinery/atmospherics/pipe/zpipe/up) && istype(AM,/obj/item/pipe))
- blocked = 1
- break
- if(istype(A, /obj/structure/disposalpipe/up) && istype(AM,/obj/item/pipe))
- blocked = 1
- break
- if(istype(A, /obj/multiz/stairs))
- soft = 1
- //dont break here, since we still need to be sure that it isnt blocked
-
- if (soft || (!blocked && !(areacheck.name == "Space")))
- AM.Move(floorbelow)
- if (!soft && istype(AM, /mob/living/carbon/human))
- var/mob/living/carbon/human/H = AM
- var/damage = 5
- H.apply_damage(min(rand(-damage,damage),0), BRUTE, "head")
- H.apply_damage(min(rand(-damage,damage),0), BRUTE, "chest")
- H.apply_damage(min(rand(-damage,damage),0), BRUTE, "l_leg")
- H.apply_damage(min(rand(-damage,damage),0), BRUTE, "r_leg")
- H.apply_damage(min(rand(-damage,damage),0), BRUTE, "l_arm")
- H.apply_damage(min(rand(-damage,damage),0), BRUTE, "r_arm")
- H:weakened = max(H:weakened,2)
- H:updatehealth()
- return ..()
-
-/turf/proc/hasbelow()
- var/turf/controllerlocation = locate(1, 1, z)
- for(var/obj/effect/landmark/zcontroller/controller in controllerlocation)
- if(controller.down)
- return 1
- return 0
-
-/turf/simulated/floor/open/proc/getbelow()
- var/turf/controllerlocation = locate(1, 1, z)
- for(var/obj/effect/landmark/zcontroller/controller in controllerlocation)
- // check if there is something to draw below
- if(!controller.down)
- src.ChangeTurf(get_base_turf(src.z))
- return 0
- else
- floorbelow = locate(src.x, src.y, controller.down_target)
- return 1
- return 1
-
-// override to make sure nothing is hidden
-/turf/simulated/floor/open/levelupdate()
- for(var/obj/O in src)
- O.hide(0)
-
-//overwrite the attackby of space to transform it to openspace if necessary
-/turf/space/attackby(obj/item/C as obj, mob/user as mob)
- if (istype(C, /obj/item/stack/cable_coil) && src.hasbelow())
- var/turf/simulated/floor/open/W = src.ChangeTurf(/turf/simulated/floor/open)
- W.attackby(C, user)
- return
- ..()
-
-/turf/simulated/floor/open/ex_act(severity)
- // cant destroy empty space with an ordinary bomb
- return
-
-/turf/simulated/floor/open/attackby(obj/item/C as obj, mob/user as mob)
- (..)
- if (istype(C, /obj/item/stack/cable_coil))
- var/obj/item/stack/cable_coil/cable = C
- cable.turf_place(src, user)
- return
-
- 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 << "Constructing support lattice..."
- playsound(src.loc, '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.loc, 'sound/weapons/Genhit.ogg', 50, 1)
- S.use(1)
- ChangeTurf(/turf/simulated/floor/airless)
- return
- else
- user << "The plating is going to need some support."
- return
diff --git a/code/TriDimension/controller.dm b/code/TriDimension/controller.dm
deleted file mode 100644
index c8b81d0d499..00000000000
--- a/code/TriDimension/controller.dm
+++ /dev/null
@@ -1,189 +0,0 @@
-/obj/effect/landmark/zcontroller
- name = "Z-Level Controller"
- var/initialized = 0 // when set to 1, turfs will report to the controller
- var/up = 0 // 1 allows up movement
- var/up_target = 0 // the Z-level that is above the current one
- var/down = 0 // 1 allows down movement
- var/down_target = 0 // the Z-level that is below the current one
-
- var/list/slow = list()
- var/list/normal = list()
- var/list/fast = list()
-
- var/slow_time
- var/normal_time
- var/fast_time
-
-/obj/effect/landmark/zcontroller/New()
- ..()
- for (var/turf/T in world)
- if (T.z == z)
- fast += T
- slow_time = world.time + 3000
- normal_time = world.time + 600
- fast_time = world.time + 10
-
- processing_objects.Add(src)
-
- initialized = 1
- return 1
-
-/obj/effect/landmark/zcontroller/Destroy()
- processing_objects.Remove(src)
- return ..()
-
-/obj/effect/landmark/zcontroller/process()
- if (world.time > fast_time)
- calc(fast)
- fast_time = world.time + 10
-
- if (world.time > normal_time)
- calc(normal)
- normal_time = world.time + 600
-
-/* if (world.time > slow_time)
- calc(slow)
- slow_time = world.time + 3000 */
- return
-
-/obj/effect/landmark/zcontroller/proc/add(var/list/L, var/I, var/transfer)
- while (L.len)
- var/turf/T = pick(L)
-
- L -= T
- slow -= T
- normal -= T
- fast -= T
-
- if(!T || !istype(T, /turf))
- continue
-
- switch (I)
- if(1) slow += T
- if(2) normal += T
- if(3) fast += T
-
- if(transfer > 0)
- if(up)
- var/turf/controller_up = locate(1, 1, up_target)
- for(var/obj/effect/landmark/zcontroller/c_up in controller_up)
- var/list/temp = list()
- temp += locate(T.x, T.y, up_target)
- c_up.add(temp, I, transfer-1)
-
- if(down)
- var/turf/controller_down = locate(1, 1, down_target)
- for(var/obj/effect/landmark/zcontroller/c_down in controller_down)
- var/list/temp = list()
- temp += locate(T.x, T.y, down_target)
- c_down.add(temp, I, transfer-1)
- return
-
-/turf
- var/list/z_overlays = list()
-
-/turf/New()
- ..()
-
- var/turf/controller = locate(1, 1, z)
- for(var/obj/effect/landmark/zcontroller/c in controller)
- if(c.initialized)
- var/list/turf = list()
- turf += src
- c.add(turf,3,1)
-
-atom/movable/Move() //Hackish
- . = ..()
-
- var/turf/controllerlocation = locate(1, 1, src.z)
- for(var/obj/effect/landmark/zcontroller/controller in controllerlocation)
- if(controller.up || controller.down)
- var/list/temp = list()
- temp += locate(src.x, src.y, src.z)
- controller.add(temp,3,1)
-
-/obj/effect/landmark/zcontroller/proc/calc(var/list/L)
- var/list/slowholder = list()
- var/list/normalholder = list()
- var/list/fastholder = list()
- var/new_list
-
- while(L.len)
- var/turf/T = pick(L)
- new_list = 0
-
- if(!T || !istype(T, /turf))
- L -= T
- continue
-
- T.overlays -= T.z_overlays
- T.z_overlays -= T.z_overlays
-
- if(down && (istype(T, /turf/space) || istype(T, /turf/simulated/floor/open)))
- var/turf/below = locate(T.x, T.y, down_target)
- if(below)
- if(!(istype(below, /turf/space) || istype(below, /turf/simulated/floor/open)))
- var/image/t_img = list()
- new_list = 1
-
- var/image/temp = image(below, dir=below.dir, layer = TURF_LAYER + 0.04)
-
- temp.color = rgb(127,127,127)
- temp.overlays += below.overlays
- t_img += temp
- T.overlays += t_img
- T.z_overlays += t_img
-
- // get objects
- var/image/o_img = list()
- for(var/obj/o in below)
- // ingore objects that have any form of invisibility
- if(o.invisibility) continue
- new_list = 2
- var/image/temp2 = image(o, dir=o.dir, layer = TURF_LAYER+0.05*o.layer)
- temp2.color = rgb(127,127,127)
- temp2.overlays += o.overlays
- o_img += temp2
- // you need to add a list to .overlays or it will not display any because space
- T.overlays += o_img
- T.z_overlays += o_img
-
- // get mobs
- var/image/m_img = list()
- for(var/mob/m in below)
- // ingore mobs that have any form of invisibility
- if(m.invisibility) continue
- // only add this tile to fastprocessing if there is a living mob, not a dead one
- if(istype(m, /mob/living)) new_list = 3
- var/image/temp2 = image(m, dir=m.dir, layer = TURF_LAYER+0.05*m.layer)
- temp2.color = rgb(127,127,127)
- temp2.overlays += m.overlays
- m_img += temp2
- // you need to add a list to .overlays or it will not display any because space
- T.overlays += m_img
- T.z_overlays += m_img
-
- T.overlays -= below.z_overlays
- T.z_overlays -= below.z_overlays
-
- L -= T
-
- if(new_list == 1)
- slowholder += T
- if(new_list == 2)
- normalholder += T
- if(new_list == 3)
- fastholder += T
- for(var/d in cardinal)
- var/turf/mT = get_step(T,d)
- if(!(mT in fastholder))
- fastholder += mT
- for(var/f in cardinal)
- var/turf/nT = get_step(mT,f)
- if(!(nT in fastholder))
- fastholder += nT
-
- add(slowholder,1, 0)
- add(normalholder, 2, 0)
- add(fastholder, 3, 0)
- return
diff --git a/code/TriDimension/controller_presets.dm b/code/TriDimension/controller_presets.dm
deleted file mode 100644
index f775b94e93e..00000000000
--- a/code/TriDimension/controller_presets.dm
+++ /dev/null
@@ -1,37 +0,0 @@
-/obj/effect/landmark/zcontroller/level_1_bottom
- up = 1
- up_target = 2
-
-/obj/effect/landmark/zcontroller/level_2_mid
- up = 1
- up_target = 3
- down = 1
- down_target = 1
-
-/obj/effect/landmark/zcontroller/level_3_mid
- up = 1
- up_target = 4
- down = 1
- down_target = 2
-
-/obj/effect/landmark/zcontroller/level_4_mid
- up = 1
- up_target = 5
- down = 1
- down_target = 3
-
-/obj/effect/landmark/zcontroller/level_2_top
- down = 1
- down_target = 1
-
-/obj/effect/landmark/zcontroller/level_3_top
- down = 1
- down_target = 2
-
-/obj/effect/landmark/zcontroller/level_4_top
- down = 1
- down_target = 3
-
-/obj/effect/landmark/zcontroller/level_5_top
- down = 1
- down_target = 4
\ No newline at end of file
diff --git a/code/ZAS/Atom.dm b/code/ZAS/Atom.dm
index e655295f783..ce69ad71622 100644
--- a/code/ZAS/Atom.dm
+++ b/code/ZAS/Atom.dm
@@ -64,9 +64,9 @@ turf/c_airblock(turf/other)
#ifdef ZLEVELS
if(other.z != src.z)
if(other.z < src.z)
- if(!istype(src, /turf/simulated/floor/open)) return BLOCKED
+ if(!istype(src, /turf/simulated/open)) return BLOCKED
else
- if(!istype(other, /turf/simulated/floor/open)) return BLOCKED
+ if(!istype(other, /turf/simulated/open)) return BLOCKED
#endif
var/result = 0
diff --git a/code/game/gamemodes/gameticker.dm b/code/game/gamemodes/gameticker.dm
index 614d181795d..f74ddff07d2 100644
--- a/code/game/gamemodes/gameticker.dm
+++ b/code/game/gamemodes/gameticker.dm
@@ -153,8 +153,6 @@ var/global/datum/controller/gameticker/ticker
processScheduler.start()
- for(var/obj/multiz/ladder/L in world) L.connect() //Lazy hackfix for ladders. TODO: move this to an actual controller. ~ Z
-
if(config.sql_enabled)
statistic_cycle() // Polls population totals regularly and stores them in an SQL DB -- TLE
diff --git a/code/game/objects/explosion.dm b/code/game/objects/explosion.dm
index 1b32185ace3..b081530e10b 100644
--- a/code/game/objects/explosion.dm
+++ b/code/game/objects/explosion.dm
@@ -1,8 +1,6 @@
//TODO: Flash range does nothing currently
-///// Z-Level Stuff
-proc/explosion(turf/epicenter, devastation_range, heavy_impact_range, light_impact_range, flash_range, adminlog = 1, z_transfer = 1)
-///// Z-Level Stuff
+proc/explosion(turf/epicenter, devastation_range, heavy_impact_range, light_impact_range, flash_range, adminlog = 1, z_transfer = UP|DOWN)
src = null //so we don't abort once src is deleted
spawn(0)
if(config.use_recursive_explosions)
@@ -14,23 +12,19 @@ proc/explosion(turf/epicenter, devastation_range, heavy_impact_range, light_impa
epicenter = get_turf(epicenter)
if(!epicenter) return
-///// Z-Level Stuff
- if(z_transfer && (devastation_range > 0 || heavy_impact_range > 0))
- //transfer the explosion in both directions
- explosion_z_transfer(epicenter, devastation_range, heavy_impact_range, light_impact_range, flash_range)
-///// Z-Level Stuff
+ // 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)
var/max_range = max(devastation_range, heavy_impact_range, light_impact_range, flash_range)
- //playsound(epicenter, 'sound/effects/explosionfar.ogg', 100, 1, round(devastation_range*2,1) )
- //playsound(epicenter, "explosion", 100, 1, round(devastation_range,1) )
-// Play sounds; we want sounds to be different depending on distance so we will manually do it ourselves.
-
-// Stereo users will also hear the direction of the explosion!
-
-// Calculate far explosion sound range. Only allow the sound effect for heavy/devastating explosions.
-
-// 3/7/14 will calculate to 80 + 35
+ // Play sounds; we want sounds to be different depending on distance so we will manually do it ourselves.
+ // Stereo users will also hear the direction of the explosion!
+ // Calculate far explosion sound range. Only allow the sound effect for heavy/devastating explosions.
+ // 3/7/14 will calculate to 80 + 35
var/far_dist = 0
far_dist += heavy_impact_range * 5
far_dist += devastation_range * 20
@@ -62,10 +56,6 @@ proc/explosion(turf/epicenter, devastation_range, heavy_impact_range, light_impa
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/lighting_controller_was_processing = lighting_controller.processing //Pause the lighting updates for a bit
-// lighting_controller.processing = 0
-
-
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
@@ -107,7 +97,6 @@ proc/explosion(turf/epicenter, devastation_range, heavy_impact_range, light_impa
sleep(8)
-// if(!lighting_controller.processing) lighting_controller.processing = lighting_controller_was_processing
if(!powernet_rebuild_was_deferred_already && defer_powernet_rebuild)
makepowernets()
defer_powernet_rebuild = 0
@@ -119,20 +108,3 @@ proc/explosion(turf/epicenter, devastation_range, heavy_impact_range, light_impa
proc/secondaryexplosion(turf/epicenter, range)
for(var/turf/tile in range(range, epicenter))
tile.ex_act(2)
-
-///// Z-Level Stuff
-proc/explosion_z_transfer(turf/epicenter, devastation_range, heavy_impact_range, light_impact_range, flash_range, up = 1, down = 1)
- var/turf/controllerlocation = locate(1, 1, epicenter.z)
- for(var/obj/effect/landmark/zcontroller/controller in controllerlocation)
- if(controller.down)
- //start the child explosion, no admin log and no additional transfers
- explosion(locate(epicenter.x, epicenter.y, controller.down_target), max(devastation_range - 2, 0), max(heavy_impact_range - 2, 0), max(light_impact_range - 2, 0), max(flash_range - 2, 0), 0, 0)
- if(devastation_range - 2 > 0 || heavy_impact_range - 2 > 0) //only transfer further if the explosion is still big enough
- explosion(locate(epicenter.x, epicenter.y, controller.down_target), max(devastation_range - 2, 0), max(heavy_impact_range - 2, 0), max(light_impact_range - 2, 0), max(flash_range - 2, 0), 0, 1)
-
- if(controller.up)
- //start the child explosion, no admin log and no additional transfers
- explosion(locate(epicenter.x, epicenter.y, controller.up_target), max(devastation_range - 2, 0), max(heavy_impact_range - 2, 0), max(light_impact_range - 2, 0), max(flash_range - 2, 0), 0, 0)
- if(devastation_range - 2 > 0 || heavy_impact_range - 2 > 0) //only transfer further if the explosion is still big enough
- explosion(locate(epicenter.x, epicenter.y, controller.up_target), max(devastation_range - 2, 0), max(heavy_impact_range - 2, 0), max(light_impact_range - 2, 0), max(flash_range - 2, 0), 1, 0)
-///// Z-Level Stuff
diff --git a/code/game/objects/structures/lattice.dm b/code/game/objects/structures/lattice.dm
index f69407b0c92..cc87be62fab 100644
--- a/code/game/objects/structures/lattice.dm
+++ b/code/game/objects/structures/lattice.dm
@@ -11,7 +11,7 @@
/obj/structure/lattice/New()
..()
///// Z-Level Stuff
- if(!(istype(src.loc, /turf/space) || istype(src.loc, /turf/simulated/floor/open)))
+ if(!(istype(src.loc, /turf/space) || istype(src.loc, /turf/simulated/open)))
///// Z-Level Stuff
qdel(src)
for(var/obj/structure/lattice/LAT in src.loc)
diff --git a/code/game/turfs/simulated.dm b/code/game/turfs/simulated.dm
index 96f5466684f..e35426e1749 100644
--- a/code/game/turfs/simulated.dm
+++ b/code/game/turfs/simulated.dm
@@ -34,8 +34,7 @@
if (istype(A,/mob/living))
var/mob/living/M = A
if(M.lying)
- ..()
- return
+ return ..()
// Ugly hack :( Should never have multiple plants in the same tile.
var/obj/effect/plant/plant = locate() in contents
diff --git a/code/game/turfs/turf.dm b/code/game/turfs/turf.dm
index 0d44f84914d..2069d06283d 100644
--- a/code/game/turfs/turf.dm
+++ b/code/game/turfs/turf.dm
@@ -75,6 +75,9 @@
if(movement_disabled && usr.ckey != movement_disabled_exception)
usr << "Movement is admin-disabled." //This is to identify lag problems
return
+
+ ..()
+
if (!mover || !isturf(mover.loc))
return 1
diff --git a/code/game/turfs/turf_changing.dm b/code/game/turfs/turf_changing.dm
index 4962ddadb51..f6aabc5ce60 100644
--- a/code/game/turfs/turf_changing.dm
+++ b/code/game/turfs/turf_changing.dm
@@ -14,19 +14,11 @@
if (!N)
return
-///// Z-Level Stuff ///// This makes sure that turfs are not changed to space when one side is part of a zone
+ // This makes sure that turfs are not changed to space when one side is part of a zone
if(N == /turf/space)
- var/turf/controller = locate(1, 1, src.z)
- for(var/obj/effect/landmark/zcontroller/c in controller)
- if(c.down)
- var/turf/below = locate(src.x, src.y, c.down_target)
- if((air_master.has_valid_zone(below) || air_master.has_valid_zone(src)) && !istype(below, /turf/space)) // dont make open space into space, its pointless and makes people drop out of the station
- var/turf/W = src.ChangeTurf(/turf/simulated/floor/open)
- var/list/temp = list()
- temp += W
- c.add(temp,3,1) // report the new open space to the zcontroller
- return W
-///// Z-Level Stuff
+ var/turf/below = GetBelow(src)
+ if(istype(below) && (air_master.has_valid_zone(below) || air_master.has_valid_zone(src)))
+ N = /turf/simulated/open
var/obj/fire/old_fire = fire
var/old_opacity = opacity
@@ -46,11 +38,11 @@
if(S.zone) S.zone.rebuild()
if(ispath(N, /turf/simulated/floor))
- var/turf/simulated/floor/W = new N( locate(src.x, src.y, src.z) )
+ var/turf/simulated/W = new N( locate(src.x, src.y, src.z) )
if(old_fire)
fire = old_fire
- if (istype(W))
+ if (istype(W,/turf/simulated/floor))
W.RemoveLattice()
if(tell_universe)
diff --git a/code/modules/multiz/_stubs.dm b/code/modules/multiz/_stubs.dm
new file mode 100644
index 00000000000..4c6e63cb7e6
--- /dev/null
+++ b/code/modules/multiz/_stubs.dm
@@ -0,0 +1,16 @@
+/obj/effect/landmark/map_data
+ name = "Unknown"
+ desc = "An unknown location."
+ invisibility = 101
+
+ var/height = 1 ///< The number of Z-Levels in the map.
+ var/turf/edge_type ///< What the map edge should be formed with. (null = world.turf)
+
+// 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*().
+HasAbove(var/z)
+HasBelow(var/z)
+// These give either the turf or null.
+GetAbove(var/atom/atom)
+GetBelow(var/atom/atom)
\ No newline at end of file
diff --git a/code/modules/multiz/basic.dm b/code/modules/multiz/basic.dm
new file mode 100644
index 00000000000..e76c6516aa7
--- /dev/null
+++ b/code/modules/multiz/basic.dm
@@ -0,0 +1,35 @@
+// If you add a more comprehensive system, just untick this file.
+// WARNING: Only works for up to 17 z-levels!
+var/z_levels = 0 // Each bit represents a connection between adjacent levels. So the first bit means levels 1 and 2 are connected.
+
+// If the height is more than 1, we mark all contained levels as connected.
+/obj/effect/landmark/map_data/New()
+ 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)
+
+// 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))
+
+proc/HasBelow(var/z)
+ if(z > world.maxz || z > 17 || z < 2)
+ return 0
+ return z_levels & (1 << (z - 2))
+
+// Thankfully, no bitwise magic is needed here.
+proc/GetAbove(var/atom/atom)
+ var/turf/turf = get_turf(atom)
+ if(!turf)
+ return null
+ return HasAbove(turf.z) ? get_step(turf, UP) : null
+
+proc/GetBelow(var/atom/atom)
+ var/turf/turf = get_turf(atom)
+ if(!turf)
+ return null
+ return HasBelow(turf.z) ? get_step(turf, DOWN) : null
diff --git a/code/modules/multiz/disabled.dm b/code/modules/multiz/disabled.dm
new file mode 100644
index 00000000000..b91fb789319
--- /dev/null
+++ b/code/modules/multiz/disabled.dm
@@ -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
\ No newline at end of file
diff --git a/code/modules/multiz/movement.dm b/code/modules/multiz/movement.dm
new file mode 100644
index 00000000000..dd0a93fec11
--- /dev/null
+++ b/code/modules/multiz/movement.dm
@@ -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 << "\The [src] is disabled."
+ return
+
+ var/turf/above = GetAbove(src)
+ if(!istype(above))
+ usr << "There is nothing of interest in this direction."
+ return
+
+ if(!istype(above, /turf/space) && !istype(above, /turf/simulated/open))
+ usr << "You bump against \the [above]."
+ return
+
+ for(var/atom/A in above)
+ if(A.density)
+ usr << "\The [A] blocks you."
+ return
+
+ usr.Move(above)
+ usr << "You move upwards."
+
+/obj/item/weapon/tank/jetpack/verb/movedown()
+ set name = "Move Downwards"
+ set category = "Object"
+
+ . = 1
+ if(!allow_thrust(0.01, usr))
+ usr << "\The [src] is disabled."
+ return
+
+ var/turf/below = GetBelow(src)
+ if(!istype(below))
+ usr << "There is nothing of interest in this direction."
+ return
+
+ if(below.density)
+ usr << "You bump against \the [below]."
+ return
+
+ for(var/atom/A in below)
+ if(A.density)
+ usr << "\The [A] blocks you."
+ return
+
+ usr.Move(below)
+ usr << "You move downwards."
diff --git a/code/TriDimension/Pipes.dm b/code/modules/multiz/pipes.dm
similarity index 85%
rename from code/TriDimension/Pipes.dm
rename to code/modules/multiz/pipes.dm
index 2a4771744e4..85e23b6797f 100644
--- a/code/TriDimension/Pipes.dm
+++ b/code/modules/multiz/pipes.dm
@@ -136,16 +136,13 @@ obj/machinery/atmospherics/pipe/zpipe/up/initialize()
node1 = target
break
- var/turf/controllerlocation = locate(1, 1, src.z)
- for(var/obj/effect/landmark/zcontroller/controller in controllerlocation)
- if(controller.up)
- var/turf/above = locate(src.x, src.y, controller.up_target)
- 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/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
@@ -177,16 +174,13 @@ obj/machinery/atmospherics/pipe/zpipe/down/initialize()
node1 = target
break
- var/turf/controllerlocation = locate(1, 1, src.z)
- for(var/obj/effect/landmark/zcontroller/controller in controllerlocation)
- if(controller.down)
- var/turf/below = locate(src.x, src.y, controller.down_target)
- 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/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
diff --git a/code/modules/multiz/structures.dm b/code/modules/multiz/structures.dm
new file mode 100644
index 00000000000..61e3a7e4871
--- /dev/null
+++ b/code/modules/multiz/structures.dm
@@ -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 << "\The [src] is incomplete and can't be climbed."
+ return
+
+ var/turf/T = target.loc
+ for(var/atom/A in T)
+ if(A.density)
+ M << "\A [A] is blocking \the [src]."
+ return
+
+ M.visible_message("\A [M] climbs [icon_state == "ladderup" ? "up" : "down"] \a [src]!",
+ "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
\ No newline at end of file
diff --git a/code/modules/multiz/turf.dm b/code/modules/multiz/turf.dm
new file mode 100644
index 00000000000..c78807a3286
--- /dev/null
+++ b/code/modules/multiz/turf.dm
@@ -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 << "Constructing support lattice ..."
+ 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 << "The plating is going to need some support."
+ return
\ No newline at end of file
diff --git a/code/modules/power/cable.dm b/code/modules/power/cable.dm
index 7e35d2a9cfd..b5aa43077f9 100644
--- a/code/modules/power/cable.dm
+++ b/code/modules/power/cable.dm
@@ -126,11 +126,10 @@ By design, d1 is the smallest direction and d2 is the highest
return
if(istype(W, /obj/item/weapon/wirecutters))
-///// Z-Level Stuff
- if(src.d1 == 12 || src.d2 == 12)
+ if(d1 == 12 || d2 == 12)
user << "You must cut this cable from above."
return
-///// Z-Level Stuff
+
if(breaker_box)
user << "\red This cable is connected to nearby breaker box. Use breaker box to interact with it."
return
@@ -146,16 +145,13 @@ By design, d1 is the smallest direction and d2 is the highest
for(var/mob/O in viewers(src, null))
O.show_message("[user] cuts the cable.", 1)
-///// Z-Level Stuff
- if(src.d1 == 11 || src.d2 == 11)
- var/turf/controllerlocation = locate(1, 1, z)
- for(var/obj/effect/landmark/zcontroller/controller in controllerlocation)
- if(controller.down)
- var/turf/below = locate(src.x, src.y, controller.down_target)
- for(var/obj/structure/cable/c in below)
- if(c.d1 == 12 || c.d2 == 12)
- qdel(c)
-///// Z-Level Stuff
+ if(d1 == 11 || d2 == 11)
+ var/turf/turf = GetBelow(src)
+ if(turf)
+ for(var/obj/structure/cable/c in turf)
+ if(c.d1 == 12 || c.d2 == 12)
+ qdel(c)
+
investigate_log("was cut by [key_name(usr, usr.client)] in [user.loc.loc]","wires")
qdel(src)
@@ -347,19 +343,20 @@ obj/structure/cable/proc/cableColor(var/colorC)
. = list() // this will be a list of all connected power objects
var/turf/T
-///// Z-Level Stuff
- if (d1 == 11 || d1 == 12)
- var/turf/controllerlocation = locate(1, 1, z)
- for(var/obj/effect/landmark/zcontroller/controller in controllerlocation)
- if(controller.up && d1 == 12)
- T = locate(src.x, src.y, controller.up_target)
- if(T)
- . += power_list(T, src, 11, 1)
- if(controller.down && d1 == 11)
- T = locate(src.x, src.y, controller.down_target)
- if(T)
- . += power_list(T, src, 12, 1)
-///// Z-Level Stuff
+ // Handle z-level connections.
+ if(d1 == 11 || d1 == 12)
+ // Connections below.
+ if(d1 == 11)
+ var/turf/turf = GetBelow(src)
+ if(turf)
+ . += power_list(turf, src, 12, 1)
+
+ // Connections above.
+ if(d1 == 12)
+ var/turf/turf = GetAbove(src)
+ if(turf)
+ . += power_list(turf, src, 11, 1)
+
//get matching cables from the first direction
else if(d1) //if not a node cable
T = get_step(src, d1)
@@ -376,19 +373,22 @@ obj/structure/cable/proc/cableColor(var/colorC)
. += power_list(loc, src, d1, powernetless_only) //get on turf matching cables
-///// Z-Level Stuff
+
+ // Second direction.
+ // Handle z-level connections.
if(d2 == 11 || d2 == 12)
- var/turf/controllerlocation = locate(1, 1, z)
- for(var/obj/effect/landmark/zcontroller/controller in controllerlocation)
- if(controller.up && d2 == 12)
- T = locate(src.x, src.y, controller.up_target)
- if(T)
- . += power_list(T, src, 11, 1)
- if(controller.down && d2 == 11)
- T = locate(src.x, src.y, controller.down_target)
- if(T)
- . += power_list(T, src, 12, 1)
-///// Z-Level Stuff
+ // Connections below.
+ if(d2 == 11)
+ var/turf/turf = GetBelow(src)
+ if(turf)
+ . += power_list(turf, src, 12, 1)
+
+ // Connections above.
+ if(d2 == 12)
+ var/turf/turf = GetAbove(src)
+ if(turf)
+ . += power_list(turf, src, 11, 1)
+
else
//do the same on the second direction (which can't be 0)
T = get_step(src, d2)
@@ -672,15 +672,14 @@ obj/structure/cable/proc/cableColor(var/colorC)
return
///// Z-Level Stuff
// check if the target is open space
- if(istype(F, /turf/simulated/floor/open))
+ if(istype(F, /turf/simulated/open))
for(var/obj/structure/cable/LC in F)
if((LC.d1 == dirn && LC.d2 == 11 ) || ( LC.d2 == dirn && LC.d1 == 11))
user << "There's already a cable at that position."
return
- var/turf/simulated/floor/open/temp = F
var/obj/structure/cable/C = new(F)
- var/obj/structure/cable/D = new(temp.floorbelow)
+ var/obj/structure/cable/D = new(GetBelow(F))
C.cableColor(color)
diff --git a/code/modules/recycling/disposal.dm b/code/modules/recycling/disposal.dm
index dcf58713e61..d764d56e555 100644
--- a/code/modules/recycling/disposal.dm
+++ b/code/modules/recycling/disposal.dm
@@ -985,12 +985,9 @@
var/obj/structure/disposalpipe/P
if(nextdir == 12)
- var/turf/controllerlocation = locate(1, 1, src.z)
- for(var/obj/effect/landmark/zcontroller/controller in controllerlocation)
- if(controller.up)
- T = locate(src.x, src.y, controller.up_target)
+ T = GetAbove(src)
if(!T)
- H.loc = src.loc
+ H.loc = loc
return
else
for(var/obj/structure/disposalpipe/down/F in T)
@@ -1038,10 +1035,7 @@
var/obj/structure/disposalpipe/P
if(nextdir == 11)
- var/turf/controllerlocation = locate(1, 1, src.z)
- for(var/obj/effect/landmark/zcontroller/controller in controllerlocation)
- if(controller.down)
- T = locate(src.x, src.y, controller.down_target)
+ T = GetBelow(src)
if(!T)
H.loc = src.loc
return
diff --git a/icons/obj/structures.dmi b/icons/obj/structures.dmi
index 8312e7ea56f..e5071ac8f04 100644
Binary files a/icons/obj/structures.dmi and b/icons/obj/structures.dmi differ