diff --git a/baystation12.dme b/baystation12.dme index b1f4bfbe2d6..0a7b3a47959 100644 --- a/baystation12.dme +++ b/baystation12.dme @@ -1277,6 +1277,11 @@ #include "code\modules\virus2\helpers.dm" #include "code\modules\virus2\isolator.dm" #include "code\modules\virus2\items_devices.dm" +#include "code\TriDimension\controler.dm" +#include "code\TriDimension\Movement.dm" +#include "code\TriDimension\Pipes.dm" +#include "code\TriDimension\Structures.dm" +#include "code\TriDimension\Turfs.dm" #include "code\WorkInProgress\autopsy.dm" #include "code\WorkInProgress\buildmode.dm" #include "code\WorkInProgress\explosion_particles.dm" diff --git a/code/TriDimension/Movement.dm b/code/TriDimension/Movement.dm index dfb529df5b1..c8cc6cba1ce 100644 --- a/code/TriDimension/Movement.dm +++ b/code/TriDimension/Movement.dm @@ -1,49 +1,52 @@ -var/maxZ = 6 -var/minZ = 2 - -// Maybe it's best to have this hardcoded for whatever we'd add to the map, in order to avoid exploits -// (such as mining base => admin station) -// Note that this assumes the ship's top is at z=1 and bottom at z=4 -/obj/item/weapon/tank/jetpack/proc/move_z(cardinal, mob/user as mob) - if (user.z > 1) - user << "\red There is nothing of interest in that direction." - return - if(allow_thrust(0.01, user)) - switch(cardinal) - if (UP) // Going up! - if(user.z > maxZ) // If we aren't at the very top of the ship - var/turf/T = locate(user.x, user.y, user.z - 1) - // You can only jetpack up if there's space above, and you're sitting on either hull (on the exterior), or space - //if(T && istype(T, /turf/space) && (istype(user.loc, /turf/space) || istype(user.loc, /turf/space/*/hull*/))) - //check through turf contents to make sure there's nothing blocking the way - if(T && istype(T, /turf/space)) - var/blocked = 0 - for(var/atom/A in T.contents) - if(T.density) - blocked = 1 - user << "\red You bump into [T.name]." - break - if(!blocked) - user.Move(T) - else - user << "\red You bump into the ship's plating." +/obj/item/weapon/tank/jetpack/verb/moveup() + set name = "Move Upwards" + set category = "Object" + if(allow_thrust(0.01, usr)) + var/turf/controlerlocation = locate(1, 1, usr.z) + var/legal = 0 + for(var/obj/effect/landmark/zcontroler/controler in controlerlocation) + legal = controler.up + if (controler.up) + var/turf/T = locate(usr.x, usr.y, controler.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 << "\red You bump into [A.name]." + break + if(!blocked) + usr.Move(T) + usr << "You move upwards." else - user << "\red The ship's gravity well keeps you in orbit!" // Assuming the ship starts on z level 1, you don't want to go past it + usr << "\red There is something in your way." + if (legal == 0) + usr << "There is nothing of interest in this direction." + return 1 - if (DOWN) // Going down! - if (user.z < 1) // If we aren't at the very bottom of the ship, or out in space - var/turf/T = locate(user.x, user.y, user.z + 1) - // You can only jetpack down if you're sitting on space and there's space down below, or hull - if(T && (istype(T, /turf/space) || istype(T, /turf/space/*/hull*/)) && istype(user.loc, /turf/space)) - var/blocked = 0 - for(var/atom/A in T.contents) - if(T.density) - blocked = 1 - user << "\red You bump into [T.name]." - break - if(!blocked) - user.Move(T) - else - user << "\red You bump into the ship's plating." +/obj/item/weapon/tank/jetpack/verb/movedown() + set name = "Move Downwards" + set category = "Object" + if(allow_thrust(0.01, usr)) + var/turf/controlerlocation = locate(1, 1, usr.z) + var/legal = 0 + for(var/obj/effect/landmark/zcontroler/controler in controlerlocation) + legal = controler.down + if (controler.down == 1) + var/turf/T = locate(usr.x, usr.y, controler.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 << "\red You bump into [A.name]." + break + if(!blocked) + usr.Move(T) + usr << "You move downwards." else - user << "\red The ship's gravity well keeps you in orbit!" \ No newline at end of file + usr << "\red 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/Pipes.dm b/code/TriDimension/Pipes.dm index e69de29bb2d..779e2e49088 100644 --- a/code/TriDimension/Pipes.dm +++ b/code/TriDimension/Pipes.dm @@ -0,0 +1,191 @@ +//////////////////////////// +// parent class for pipes // +//////////////////////////// +obj/machinery/atmospherics/pipe/zpipe + icon = 'code/TriDimension/multiz_pipe.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 + initialize() + + +obj/machinery/atmospherics/pipe/zpipe/hide(var/i) + if(level == 1 && 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("\red \bold [src] bursts!"); + 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() + del(src) + +obj/machinery/atmospherics/pipe/zpipe/proc/normalize_dir() + if(dir==3) + dir = 1 + else if(dir==12) + dir = 4 + +obj/machinery/atmospherics/pipe/zpipe/Del() + 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)) + del(parent) + node1 = null + + if(reference == node2) + if(istype(node2, /obj/machinery/atmospherics/pipe)) + del(parent) + node2 = null + + return null +///////////////////////// +// the elusive up pipe // +///////////////////////// +obj/machinery/atmospherics/pipe/zpipe/up + icon = 'code/TriDimension/multiz_pipe.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)) + node1 = target + break + + var/turf/controlerlocation = locate(1, 1, src.z) + for(var/obj/effect/landmark/zcontroler/controler in controlerlocation) + if(controler.up) + var/turf/above = locate(src.x, src.y, controler.up_target) + if(above) + for(var/obj/machinery/atmospherics/target in above) + if(target.initialize_directions && istype(target, /obj/machinery/atmospherics/pipe/zpipe/down)) + node2 = target + break + + + var/turf/T = src.loc // hide if turf is not intact + hide(T.intact) + +/////////////////////// +// and the down pipe // +/////////////////////// + +obj/machinery/atmospherics/pipe/zpipe/down + icon = 'code/TriDimension/multiz_pipe.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)) + node1 = target + break + + var/turf/controlerlocation = locate(1, 1, src.z) + for(var/obj/effect/landmark/zcontroler/controler in controlerlocation) + if(controler.down) + var/turf/below = locate(src.x, src.y, controler.down_target) + if(below) + for(var/obj/machinery/atmospherics/target in below) + if(target.initialize_directions && istype(target, /obj/machinery/atmospherics/pipe/zpipe/up)) + node2 = target + break + + + var/turf/T = src.loc // hide if turf is not intact + hide(T.intact) \ No newline at end of file diff --git a/code/TriDimension/Structures.dm b/code/TriDimension/Structures.dm index 85e499f7ad4..4da4de449ee 100644 --- a/code/TriDimension/Structures.dm +++ b/code/TriDimension/Structures.dm @@ -7,7 +7,6 @@ density = 0 opacity = 0 anchored = 1 - var/obj/multiz/target CanPass(obj/mover, turf/source, height, airflow) return airflow || !density @@ -17,62 +16,137 @@ name = "ladder" desc = "A Ladder. You climb up and down it." - var/top_icon_state = "ladderdown" - var/bottom_icon_state = "ladderup" + var/d_state = 1 + var/obj/multiz/target New() . = ..() - spawn(1) //Allow map to load - if(z in levels_3d) - if(!target) - var/list/adjacent_to_me = global_adjacent_z_levels["[z]"] - if("up" in adjacent_to_me) - target = locate() in locate(x,y,adjacent_to_me["up"]) - if(istype(target)) - icon_state = bottom_icon_state - else if("down" in adjacent_to_me) - target = locate() in locate(x,y,adjacent_to_me["down"]) - if(istype(target)) - icon_state = top_icon_state - else - del src - else - del src - else if("down" in adjacent_to_me) - target = locate() in locate(x,y,adjacent_to_me["down"]) - if(istype(target)) - icon_state = bottom_icon_state - else - del src - else - del src - if(target) - target.icon_state = ( icon_state == top_icon_state ? bottom_icon_state : top_icon_state) - target.target = src - else - del src + connect() + + proc/connect() + if(icon_state == "ladderdown") // the upper will connect to the lower + d_state = 1 + var/turf/controlerlocation = locate(1, 1, z) + for(var/obj/effect/landmark/zcontroler/controler in controlerlocation) + if(controler.down) + var/turf/below = locate(src.x, src.y, controler.down_target) + for(var/obj/multiz/ladder/L in below) + target = L + L.target = src + d_state = 0 + break + return + +/* ex_act(severity) + switch(severity) + if(1.0) + if(icon_state == "ladderup" && prob(10)) + Del() + if(2.0) + if(prob(50)) + Del() + if(3.0) + Del() + return*/ Del() spawn(1) - if(target) + if(target && icon_state == "ladderdown") del target return ..() attack_paw(var/mob/M) return attack_hand(M) - attackby(var/W, var/mob/M) - return attack_hand(M) + 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/controlerlocation = 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/zcontroler/controler in controlerlocation) + if(controler.down) + found = 1 + var/turf/below = locate(src.x, src.y, controler.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) S.Del() + 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 = new /obj/item/stack/rods(target.loc) + R.amount = 2 + target.Del() + + 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/sheet/metal/S = new /obj/item/stack/sheet/metal( src ) + S.amount = 2 + user << "You remove the ladder and close the hole." + Del() + 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)) - del src - var/list/adjacent_to_me = global_adjacent_z_levels["[z]"] - M.visible_message("\blue \The [M] climbs [target.z == adjacent_to_me["up"] ? "up" : "down"] \the [src]!", "You climb [target.z == adjacent_to_me["up"] ? "up" : "down"] \the [src]!", "You hear some grunting, and clanging of a metal ladder being used.") - M.Move(target.loc) + M << "The ladder is incomplete and cant 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("\blue \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 +/* hatch icon_state = "hatchdown" name = "hatch" desc = "A hatch. You climb down it, and it will automatically seal against pressure loss behind you." @@ -125,81 +199,48 @@ spawn(7) top_hatch.icon_state = top_icon_state bottom_hatch.overlays -= red_overlay - active = 0 + active = 0*/ /obj/multiz/stairs name = "Stairs" desc = "Stairs. You walk up and down them." - icon_state = "ramptop" - var/top_icon_state = "ramptop" - var/bottom_icon_state = "rampbottom" + icon_state = "rampbottom" + var/obj/multiz/stairs/connected + var/turf/target - active - density = 1 + New() + ..() + var/turf/cl= locate(1, 1, src.z) + for(var/obj/effect/landmark/zcontroler/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) - - New() - . = ..() - spawn(1) - if(z in levels_3d) - if(!target) - var/list/adjacent_to_me = global_adjacent_z_levels["[z]"] - if("up" in adjacent_to_me) - target = locate() in locate(x,y,adjacent_to_me["up"]) - if(istype(target)) - icon_state = bottom_icon_state - else if("down" in adjacent_to_me) - target = locate() in locate(x,y,adjacent_to_me["down"]) - if(istype(target)) - icon_state = top_icon_state - else - del src - else - del src - else if("down" in adjacent_to_me) - target = locate() in locate(x,y,adjacent_to_me["down"]) - if(istype(target)) - icon_state = bottom_icon_state - else - del src - else - del src - if(target) - target.icon_state = ( icon_state == top_icon_state ? bottom_icon_state : top_icon_state) - target.target = src - var/obj/multiz/stairs/lead_in = locate() in get_step(src, reverse_direction(dir)) - if(lead_in) - lead_in.icon_state = ( icon_state == top_icon_state ? bottom_icon_state : top_icon_state) - else - del src - - - Del() - spawn(1) + spawn(1) + for(var/dir in cardinal) + var/turf/T = get_step(src.loc,dir) + for(var/obj/multiz/stairs/S in T) + if(S && S.icon_state == "rampbottom" && !S.connected) + S.dir = dir + src.dir = dir + S.connected = src + src.connected = S + src.icon_state = "ramptop" + src.density = 1 + var/turf/controlerlocation = locate(1, 1, src.z) + for(var/obj/effect/landmark/zcontroler/controler in controlerlocation) + if(controler.up) + var/turf/above = locate(src.x, src.y, controler.up_target) + if(istype(above,/turf/space) || istype(above,/turf/simulated/floor/open)) + src.target = above + break if(target) - del target - return ..() - + break Bumped(var/atom/movable/M) - if(target.z > z && istype(src, /obj/multiz/stairs/active) && !locate(/obj/multiz/stairs) in M.loc) - return //If on bottom, only let them go up stairs if they've moved to the entry tile first. - //If it's the top, they can fall down just fine. - - if(!target || !istype(target.loc, /turf)) - del src - - if(ismob(M) && M:client) - M:client.moving = 1 - M.Move(target.loc) - if (ismob(M) && M:client) - M:client.moving = 0 - - Click() - if(!istype(usr,/mob/dead/observer)) - return ..() - if(!target || !istype(target.loc, /turf)) - del src - usr.client.moving = 1 - usr.Move(target.loc) - usr.client.moving = 0 \ No newline at end of file + 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 diff --git a/code/TriDimension/Turfs.dm b/code/TriDimension/Turfs.dm index 1e49e4dc80e..2f99b6fd415 100644 --- a/code/TriDimension/Turfs.dm +++ b/code/TriDimension/Turfs.dm @@ -1,27 +1,3 @@ -atom/movable/var/list/adjacent_z_levels -atom/movable/var/archived_z_level - -atom/movable/Move() //Hackish - - if(adjacent_z_levels && adjacent_z_levels["up"]) - var/turf/above_me = locate(x,y,adjacent_z_levels["up"]) - if(istype(above_me, /turf/simulated/floor/open)) - above_me:RemoveImage(src) - - . = ..() - - if(archived_z_level != z) - archived_z_level = z - if(z in levels_3d) - adjacent_z_levels = global_adjacent_z_levels["[z]"] - else - adjacent_z_levels = null - - if(adjacent_z_levels && adjacent_z_levels["up"]) - var/turf/above_me = locate(x,y,adjacent_z_levels["up"]) - if(istype(above_me, /turf/simulated/floor/open)) - above_me:AddImage(src) - /turf/simulated/floor/open name = "open space" intact = 0 @@ -31,66 +7,109 @@ atom/movable/Move() //Hackish var/icon/darkoverlays = null var/turf/floorbelow var/list/overlay_references - mouse_opacity = 2 New() ..() - spawn(1) - if(!(z in levels_3d)) - ReplaceWithSpace() - var/list/adjacent_to_me = global_adjacent_z_levels["[z]"] - if(!("down" in adjacent_to_me)) - ReplaceWithSpace() - - floorbelow = locate(x, y, adjacent_to_me["down"]) - if(floorbelow) - if(!istype(floorbelow,/turf)) - del src - else if(floorbelow.density) - ReplaceWithPlating() - else - set_up() - else - ReplaceWithSpace() - + 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) - AM.Move(floorbelow) - if (istype(AM, /mob/living/carbon/human)) - var/mob/living/carbon/human/H = AM - var/damage = rand(5,15) - H.apply_damage(2*damage, BRUTE, "head") - H.apply_damage(2*damage, BRUTE, "chest") - H.apply_damage(0.5*damage, BRUTE, "l_leg") - H.apply_damage(0.5*damage, BRUTE, "r_leg") - H.apply_damage(0.5*damage, BRUTE, "l_arm") - H.apply_damage(0.5*damage, BRUTE, "r_arm") - H:weakened = max(H:weakened,2) - H:updatehealth() + var/area/areacheck = get_area(src) + var/blocked = 0 + var/soft = 0 + for(var/atom/A in floorbelow.contents) + if(A.density) + 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 ..() - attackby() - return //nothing +/turf/simulated/floor/open/proc/getbelow() + var/turf/controlerlocation = locate(1, 1, z) + for(var/obj/effect/landmark/zcontroler/controler in controlerlocation) + // check if there is something to draw below + if(!controler.down) + src.ChangeTurf(/turf/space) + return 0 + else + floorbelow = locate(src.x, src.y, controler.down_target) + return 1 + return 1 - proc/set_up() //Update the overlays to make the openspace turf show what's down a level - if(!overlay_references) - overlay_references = list() - if(!floorbelow) return - overlays += floorbelow - for(var/obj/o in floorbelow) - var/image/o_img = image(o, dir=o.dir, layer = TURF_LAYER+0.05*o.layer) - overlays += o_img - overlay_references[o] = o_img +// override to make sure nothing is hidden +/turf/simulated/floor/open/levelupdate() + for(var/obj/O in src) + if(O.level == 1) + O.hide(0) - proc/AddImage(var/atom/movable/o) - var/o_img = image(o, dir=o.dir, layer = TURF_LAYER+0.05*o.layer) - overlays += o_img - overlay_references[o] = o_img +//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/weapon/cable_coil)) + var/turf/simulated/floor/open/W = src.ChangeTurf(/turf/simulated/floor/open) + W.attackby(C, user) + return + ..() - proc/RemoveImage(var/atom/movable/o) - var/o_img = overlay_references[o] - overlays -= o_img - overlay_references -= o \ No newline at end of file +/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/weapon/cable_coil)) + var/obj/item/weapon/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 + user << "\blue Constructing support lattice ..." + playsound(src.loc, 'sound/weapons/Genhit.ogg', 50, 1) + ReplaceWithLattice() + R.use(1) + return + + if (istype(C, /obj/item/stack/tile/plasteel)) + var/obj/structure/lattice/L = locate(/obj/structure/lattice, src) + if(L) + var/obj/item/stack/tile/plasteel/S = C + del(L) + playsound(src.loc, 'sound/weapons/Genhit.ogg', 50, 1) + S.build(src) + S.use(1) + return + else + user << "\red The plating is going to need some support." + return diff --git a/code/TriDimension/controler.dm b/code/TriDimension/controler.dm new file mode 100644 index 00000000000..59915797385 --- /dev/null +++ b/code/TriDimension/controler.dm @@ -0,0 +1,263 @@ +/obj/effect/landmark/zcontroler + name = "Z-Level Controler" + var/initialized = 0 // when set to 1, turfs will report to the controler + 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/zcontroler/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/zcontroler/Del() + processing_objects.Remove(src) + return + +/obj/effect/landmark/zcontroler/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/zcontroler/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/controler_up = locate(1, 1, up_target) + for(var/obj/effect/landmark/zcontroler/c_up in controler_up) + var/list/temp = list() + temp += locate(T.x, T.y, up_target) + c_up.add(temp, I, transfer-1) + + if(down) + var/turf/controler_down = locate(1, 1, down_target) + for(var/obj/effect/landmark/zcontroler/c_down in controler_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/controler = locate(1, 1, z) + for(var/obj/effect/landmark/zcontroler/c in controler) + if(c.initialized) + var/list/turf = list() + turf += src + c.add(turf,3,1) + +/turf/space/New() + ..() + + var/turf/controler = locate(1, 1, z) + for(var/obj/effect/landmark/zcontroler/c in controler) + if(c.initialized) + var/list/turf = list() + turf += src + c.add(turf,3,1) + +atom/movable/Move() //Hackish + . = ..() + + var/turf/controlerlocation = locate(1, 1, src.z) + for(var/obj/effect/landmark/zcontroler/controler in controlerlocation) + if(controler.up || controler.down) + var/list/temp = list() + temp += locate(src.x, src.y, src.z) + controler.add(temp,3,1) + +/obj/effect/landmark/zcontroler/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 + + // this is sadly impossible to use right now + // the overlay is always opaque to mouseclicks and thus prevents interactions with everything except the turf + /*if(up) + var/turf/above = locate(T.x, T.y, up_target) + if(above) + var/eligeable = 0 + for(var/d in cardinal) + var/turf/mT = get_step(above,d) + if(istype(mT, /turf/space) || istype(mT, /turf/simulated/floor/open)) + eligeable = 1 + /*if(mT.opacity == 0) + for(var/f in cardinal) + var/turf/nT = get_step(mT,f) + if(istype(nT, /turf/space) || istype(nT, /turf/simulated/floor/open)) + eligeable = 1*/ + if(istype(above, /turf/space) || istype(above, /turf/simulated/floor/open)) eligeable = 1 + if(eligeable == 1) + if(!(istype(above, /turf/space) || istype(above, /turf/simulated/floor/open))) + var/image/t_img = list() + if(new_list < 1) new_list = 1 + + above.overlays -= above.z_overlays + var/image/temp = image(above, dir=above.dir, layer = 5 + 0.04) + above.overlays += above.z_overlays + + temp.alpha = 100 + temp.overlays += above.overlays + temp.overlays -= above.z_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 above) + // ingore objects that have any form of invisibility + if(o.invisibility) continue + if(new_list < 2) new_list = 2 + var/image/temp2 = image(o, dir=o.dir, layer = 5+0.05*o.layer) + temp2.alpha = 100 + 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 above) + // 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) new_list = 3 + var/image/temp2 = image(m, dir=m.dir, layer = 5+0.05*m.layer) + temp2.alpha = 100 + 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 -= above.z_overlays + T.z_overlays -= above.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/ZAS/Functions.dm b/code/ZAS/Functions.dm index 3037e13f412..4cefd09b74c 100644 --- a/code/ZAS/Functions.dm +++ b/code/ZAS/Functions.dm @@ -11,6 +11,12 @@ proc/FloodFill(turf/simulated/start) var/list/open = list(start) //The list of tiles which have been evaulated. var/list/closed = list() +/////// Z-Level stuff + //List of all space tiles bordering the zone + var/list/list_space = list() + //List of all Z-Levels of the zone where it borders space + var/list/z_space = list() +/////// Z-Level stuff //Loop through the turfs in the open list in order to find which adjacent turfs should be added to the zone. while(open.len) @@ -67,10 +73,75 @@ proc/FloodFill(turf/simulated/start) //If it cannot connect either to the north or west, connect it! closed += O +/////// Z-Level stuff + if(istype(O,/turf/space)) + if(!(O in list_space)) + list_space += O + if(!(O.z in z_space)) + z_space += O.z + + // handle Z-level connections + var/turf/controlerlocation = locate(1, 1, T.z) + for(var/obj/effect/landmark/zcontroler/controler in controlerlocation) + // connect upwards + if(controler.up) + var/turf/above_me = locate(T.x, T.y, controler.up_target) + // add the turf above this + if(istype(above_me, /turf/simulated/floor/open) && !(above_me in open) && !(above_me in closed)) + open += above_me + + if(istype(above_me,/turf/space)) + if(!(above_me in list_space)) + list_space += above_me + if(!(above_me.z in z_space)) + z_space += above_me.z + // connect downwards + if(controler.down && istype(T, /turf/simulated/floor/open)) + var/turf/below_me = locate(T.x, T.y, controler.down_target) + // add the turf below this + if(!(below_me in open) && !(below_me in closed)) + open += below_me +/////// Z-Level stuff + //This tile is now evaluated, and can be moved to the list of evaluated tiles. open -= T closed += T +/////// Z-Level stuff + // once the zone is done, check if there is space that needs to be changed to open space + if(!open.len) + var/list/temp = list() + while(list_space.len) + var/turf/S = pick(list_space) + //check if the zone has any space borders below the evaluated space tile + //if there is some, we dont need to make open_space since the zone can vent and the zone above can vent + //through the evaluated tile + //if there is none, the zone can connect upwards to either vent from there or connect with the zone there + //also check if the turf below the space is actually part of this zone to prevent the edge tiles from transforming + var/turf/controlerloc = locate(1, 1, S.z) + for(var/obj/effect/landmark/zcontroler/controler in controlerloc) + if(controler.down) + var/turf/below = locate(S.x, S.y, controler.down_target) + if(!((S.z - 1) in z_space) && below in closed) + open += S.ChangeTurf(/turf/simulated/floor/open) + list_space -= S + else + list_space -= S + temp += S + else + list_space -= S + temp += S + // make sure the turf is removed from the list + list_space -= S + z_space -= z_space + while(temp.len) + var/turf/S = pick(temp) + if(!(S.z in z_space)) + z_space += S.z + list_space += S + temp -= S +/////// Z-Level stuff + return closed diff --git a/code/ZAS/ZAS_Zones.dm b/code/ZAS/ZAS_Zones.dm index 1d92062e25d..f6a3327ff23 100644 --- a/code/ZAS/ZAS_Zones.dm +++ b/code/ZAS/ZAS_Zones.dm @@ -151,6 +151,13 @@ var/list/CounterDoorDirections = list(SOUTH,EAST) //Which directions doors turfs air.group_multiplier++ T.zone = src + +///// Z-Level Stuff + // also add the tile below it if its open space + if(istype(T, /turf/simulated/floor/open)) + var/turf/simulated/floor/open/T2 = T + src.AddTurf(T2.floorbelow) +///// Z-Level Stuff else if(!unsimulated_tiles) @@ -773,6 +780,32 @@ zone/proc/Rebuild() if(adjacent_id && (!lowest_id || adjacent_id < lowest_id)) lowest_id = adjacent_id +/////// Z-Level stuff + var/turf/controlerlocation = locate(1, 1, current.z) + for(var/obj/effect/landmark/zcontroler/controler in controlerlocation) + // upwards + if(controler.up) + var/turf/simulated/adjacent = locate(current.x, current.y, controler.up_target) + + if(adjacent in turfs && istype(adjacent, /turf/simulated/floor/open)) + current_adjacents += adjacent + adjacent_id = turfs[adjacent] + + if(adjacent_id && (!lowest_id || adjacent_id < lowest_id)) + lowest_id = adjacent_id + + // downwards + if(controler.down && istype(current, /turf/simulated/floor/open)) + var/turf/simulated/adjacent = locate(current.x, current.y, controler.down_target) + + if(adjacent in turfs) + current_adjacents += adjacent + adjacent_id = turfs[adjacent] + + if(adjacent_id && (!lowest_id || adjacent_id < lowest_id)) + lowest_id = adjacent_id +/////// Z-Level stuff + if(!lowest_id) lowest_id = current_identifier++ identical_ids += lowest_id diff --git a/code/game/machinery/pipe/construction.dm b/code/game/machinery/pipe/construction.dm index 1babba054e6..72aa31ccee0 100644 --- a/code/game/machinery/pipe/construction.dm +++ b/code/game/machinery/pipe/construction.dm @@ -23,6 +23,10 @@ Buildable meters #define PIPE_MTVALVE 18 #define PIPE_MANIFOLD4W 19 #define PIPE_CAP 20 +///// Z-Level stuff +#define PIPE_UP 21 +#define PIPE_DOWN 22 +///// Z-Level stuff /obj/item/pipe name = "pipe" @@ -84,6 +88,12 @@ Buildable meters src.pipe_type = PIPE_MANIFOLD4W else if(istype(make_from, /obj/machinery/atmospherics/pipe/cap)) src.pipe_type = PIPE_CAP +///// Z-Level stuff + else if(istype(make_from, /obj/machinery/atmospherics/pipe/zpipe/up)) + src.pipe_type = PIPE_UP + else if(istype(make_from, /obj/machinery/atmospherics/pipe/zpipe/down)) + src.pipe_type = PIPE_DOWN +///// Z-Level stuff else src.pipe_type = pipe_type src.dir = dir @@ -117,6 +127,10 @@ Buildable meters "t-valve", \ "4-way manifold", \ "pipe cap", \ +///// Z-Level stuff + "pipe up", \ + "pipe down", \ +///// Z-Level stuff ) name = nlist[pipe_type+1] + " fitting" var/list/islist = list( \ @@ -141,6 +155,10 @@ Buildable meters "mtvalve", \ "manifold4w", \ "cap", \ +///// Z-Level stuff + "cap", \ + "cap", \ +///// Z-Level stuff ) icon_state = islist[pipe_type + 1] @@ -213,6 +231,10 @@ Buildable meters return dir|flip|cw if(PIPE_CAP) return flip +///// Z-Level stuff + if(PIPE_UP,PIPE_DOWN) + return dir +///// Z-Level stuff return 0 /obj/item/pipe/proc/get_pdir() //endpoints for regular pipes @@ -348,7 +370,7 @@ Buildable meters if (M.node3) M.node3.initialize() M.node3.build_network() - + if(PIPE_MANIFOLD4W) //4-way manifold var/obj/machinery/atmospherics/pipe/manifold4w/M = new( src.loc ) M.dir = dir @@ -515,7 +537,7 @@ Buildable meters if (P.node2) P.node2.initialize() P.node2.build_network() - + if(PIPE_MTVALVE) //manual t-valve var/obj/machinery/atmospherics/tvalve/V = new(src.loc) V.dir = dir @@ -535,7 +557,7 @@ Buildable meters if (V.node3) V.node3.initialize() V.node3.build_network() - + if(PIPE_CAP) var/obj/machinery/atmospherics/pipe/cap/C = new(src.loc) C.dir = dir @@ -593,6 +615,40 @@ Buildable meters if (C.node) C.node.initialize() C.node.build_network() +///// Z-Level stuff + if(PIPE_UP) //volume pump + var/obj/machinery/atmospherics/pipe/zpipe/up/P = new(src.loc) + P.dir = dir + P.initialize_directions = pipe_dir + if (pipename) + P.name = pipename + var/turf/T = P.loc + P.level = T.intact ? 2 : 1 + P.initialize() + P.build_network() + if (P.node1) + P.node1.initialize() + P.node1.build_network() + if (P.node2) + P.node2.initialize() + P.node2.build_network() + if(PIPE_DOWN) //volume pump + var/obj/machinery/atmospherics/pipe/zpipe/down/P = new(src.loc) + P.dir = dir + P.initialize_directions = pipe_dir + if (pipename) + P.name = pipename + var/turf/T = P.loc + P.level = T.intact ? 2 : 1 + P.initialize() + P.build_network() + if (P.node1) + P.node1.initialize() + P.node1.build_network() + if (P.node2) + P.node2.initialize() + P.node2.build_network() +///// Z-Level stuff playsound(src.loc, 'sound/items/Ratchet.ogg', 50, 1) user.visible_message( \ @@ -649,4 +705,4 @@ Buildable meters #undef PIPE_VOLUME_PUMP #undef PIPE_OUTLET_INJECT #undef PIPE_MTVALVE -//#undef PIPE_MANIFOLD4W \ No newline at end of file +//#undef PIPE_MANIFOLD4W diff --git a/code/game/machinery/pipe/pipe_dispenser.dm b/code/game/machinery/pipe/pipe_dispenser.dm index e883d4d07d1..bf6233f4d47 100644 --- a/code/game/machinery/pipe/pipe_dispenser.dm +++ b/code/game/machinery/pipe/pipe_dispenser.dm @@ -13,6 +13,7 @@ /obj/machinery/pipedispenser/attack_hand(user as mob) if(..()) return +///// Z-Level stuff var/dat = {" Regular pipes:
Pipe
@@ -22,6 +23,8 @@ Pipe Cap
4-Way Manifold
Manual T-Valve
+upward Pipe
+downward Pipe
Devices:
Connector
Unary Vent
@@ -42,6 +45,7 @@ Bent Pipe
"} +///// Z-Level stuff //What number the make points to is in the define # at the top of construction.dm in same folder user << browse("[src][dat]", "window=pipedispenser") @@ -143,6 +147,7 @@ Nah if(..()) return +///// Z-Level stuff var/dat = {"Disposal Pipes

Pipe
Bent Pipe
@@ -152,7 +157,10 @@ Nah Bin
Outlet
Chute
+Upwards
+Downwards
"} +///// Z-Level stuff user << browse("[src][dat]", "window=pipedispenser") return @@ -192,6 +200,12 @@ Nah if(7) C.ptype = 8 C.density = 1 +///// Z-Level stuff + if(21) + C.ptype = 11 + if(22) + C.ptype = 12 +///// Z-Level stuff C.add_fingerprint(usr) C.update() wait = 1 @@ -203,7 +217,7 @@ Nah /obj/machinery/pipedispenser/orderable anchored = 0 unwrenched = 1 - + /obj/machinery/pipedispenser/disposal/orderable anchored = 0 - unwrenched = 1 \ No newline at end of file + unwrenched = 1 diff --git a/code/game/objects/explosion.dm b/code/game/objects/explosion.dm index 5ba97f90053..be5ff1ef428 100644 --- a/code/game/objects/explosion.dm +++ b/code/game/objects/explosion.dm @@ -6,21 +6,9 @@ if(dx>=dy) return dx + (0.5*dy) //The longest side add half the shortest side approximates the hypotenuse else return dy + (0.5*dx) - -proc/trange(var/Dist=0,var/turf/Center=null)//alternative to range (ONLY processes turfs and thus less intensive) - if(Center==null) return - - //var/x1=((Center.x-Dist)<1 ? 1 : Center.x-Dist) - //var/y1=((Center.y-Dist)<1 ? 1 : Center.y-Dist) - //var/x2=((Center.x+Dist)>world.maxx ? world.maxx : Center.x+Dist) - //var/y2=((Center.y+Dist)>world.maxy ? world.maxy : Center.y+Dist) - - var/turf/x1y1 = locate(((Center.x-Dist)<1 ? 1 : Center.x-Dist),((Center.y-Dist)<1 ? 1 : Center.y-Dist),Center.z) - var/turf/x2y2 = locate(((Center.x+Dist)>world.maxx ? world.maxx : Center.x+Dist),((Center.y+Dist)>world.maxy ? world.maxy : Center.y+Dist),Center.z) - return block(x1y1,x2y2) - - -proc/explosion(turf/epicenter, devastation_range, heavy_impact_range, light_impact_range, flash_range, adminlog = 1) +///// 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 src = null //so we don't abort once src is deleted spawn(0) if(config.use_recursive_explosions) @@ -28,6 +16,12 @@ proc/explosion(turf/epicenter, devastation_range, heavy_impact_range, light_impa explosion_rec(epicenter, power) 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 + var/start = world.timeofday epicenter = get_turf(epicenter) if(!epicenter) return @@ -61,7 +55,7 @@ proc/explosion(turf/epicenter, devastation_range, heavy_impact_range, light_impa var/y0 = epicenter.y var/z0 = epicenter.z - for(var/turf/T in trange(max(devastation_range, heavy_impact_range, light_impact_range), epicenter)) + for(var/turf/T in range(epicenter, max(devastation_range, heavy_impact_range, light_impact_range))) var/dist = cheap_pythag(T.x - x0,T.y - y0) if(dist < devastation_range) dist = 1 @@ -98,4 +92,21 @@ 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) \ No newline at end of file + 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/controlerlocation = locate(1, 1, epicenter.z) + for(var/obj/effect/landmark/zcontroler/controler in controlerlocation) + if(controler.down) + //start the child explosion, no admin log and no additional transfers + explosion(locate(epicenter.x, epicenter.y, controler.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, controler.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(controler.up) + //start the child explosion, no admin log and no additional transfers + explosion(locate(epicenter.x, epicenter.y, controler.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, controler.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 12ce9e0b5ff..672011cef9b 100644 --- a/code/game/objects/structures/lattice.dm +++ b/code/game/objects/structures/lattice.dm @@ -10,7 +10,9 @@ /obj/structure/lattice/New() ..() - if(!(istype(src.loc, /turf/space))) +///// Z-Level Stuff + if(!(istype(src.loc, /turf/space) || istype(src.loc, /turf/simulated/floor/open))) +///// Z-Level Stuff del(src) for(var/obj/structure/lattice/LAT in src.loc) if(LAT != src) @@ -80,4 +82,4 @@ dir_sum += direction icon_state = "lattice[dir_sum]" - return \ No newline at end of file + return diff --git a/code/game/turfs/turf.dm b/code/game/turfs/turf.dm index 3a4c6b40b4c..85108e8688f 100644 --- a/code/game/turfs/turf.dm +++ b/code/game/turfs/turf.dm @@ -200,6 +200,20 @@ if (!N) return +///// Z-Level Stuff ///// This makes sure that turfs are not changed to space when one side is part of a zone + if(N == /turf/space) + var/turf/controler = locate(1, 1, src.z) + for(var/obj/effect/landmark/zcontroler/c in controler) + if(c.down) + var/turf/below = locate(src.x, src.y, c.down_target) + if((below.zone || zone) && !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 zcontroler + return W +///// Z-Level Stuff + var/old_lumcount = lighting_lumcount - initial(lighting_lumcount) if(ispath(N, /turf/simulated/floor)) @@ -337,4 +351,4 @@ if(!t.density) if(!LinkBlocked(src, t) && !TurfBlockedNonWindow(t)) L.Add(t) - return L \ No newline at end of file + return L diff --git a/code/modules/power/cable.dm b/code/modules/power/cable.dm index bbcbdb9c9d9..36289dabaac 100644 --- a/code/modules/power/cable.dm +++ b/code/modules/power/cable.dm @@ -28,7 +28,6 @@ /obj/structure/cable/New() ..() - // ensure d1 & d2 reflect the icon_state for entering and exiting cable var/dash = findtext(icon_state, "-") @@ -37,6 +36,7 @@ d2 = text2num( copytext( icon_state, dash+1 ) ) + var/turf/T = src.loc // hide if turf is not intact if(level==1) hide(T.intact) @@ -78,6 +78,12 @@ if(istype(W, /obj/item/weapon/wirecutters)) +///// Z-Level Stuff + if(src.d1 == 12 || src.d2 == 12) + user << "\red You must cut this cable from above." + return +///// Z-Level Stuff + // if(power_switch) // user << "\red This piece of cable is tied to a power switch. Flip the switch to remove it." // return @@ -93,6 +99,17 @@ for(var/mob/O in viewers(src, null)) O.show_message("\red [user] cuts the cable.", 1) +///// Z-Level Stuff + if(src.d1 == 11 || src.d2 == 11) + var/turf/controlerlocation = locate(1, 1, z) + for(var/obj/effect/landmark/zcontroler/controler in controlerlocation) + if(controler.down) + var/turf/below = locate(src.x, src.y, controler.down_target) + for(var/obj/structure/cable/c in below) + if(c.d1 == 12 || c.d2 == 12) + c.Del() +///// Z-Level Stuff + del(src) return // not needed, but for clarity @@ -287,33 +304,75 @@ else dirn = get_dir(F, user) - for(var/obj/structure/cable/LC in F) - if((LC.d1 == dirn && LC.d2 == 0 ) || ( LC.d2 == dirn && LC.d1 == 0)) - user << "There's already a cable at that position." - return +///// Z-Level Stuff + // check if the target is open space + if(istype(F, /turf/simulated/floor/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/obj/structure/cable/C = new(F) + var/turf/simulated/floor/open/temp = F + var/obj/structure/cable/C = new(F) + var/obj/structure/cable/D = new(temp.floorbelow) - C.cableColor(item_color) + C.cableColor("red") - C.d1 = 0 - C.d2 = dirn - C.add_fingerprint(user) - C.updateicon() + C.d1 = 11 + C.d2 = dirn + C.add_fingerprint(user) + C.updateicon() - C.powernet = new() - powernets += C.powernet - C.powernet.cables += C + C.powernet = new() + powernets += C.powernet + C.powernet.cables += C - C.mergeConnectedNetworks(C.d2) - C.mergeConnectedNetworksOnTurf() + C.mergeConnectedNetworks(C.d2) + C.mergeConnectedNetworksOnTurf() + + D.cableColor("red") + + D.d1 = 12 + D.d2 = 0 + D.add_fingerprint(user) + D.updateicon() + + D.powernet = C.powernet + D.powernet.cables += D + + D.mergeConnectedNetworksOnTurf() + + // do the normal stuff + else +///// Z-Level Stuff + + for(var/obj/structure/cable/LC in F) + if((LC.d1 == dirn && LC.d2 == 0 ) || ( LC.d2 == dirn && LC.d1 == 0)) + user << "There's already a cable at that position." + return + + var/obj/structure/cable/C = new(F) + + C.cableColor(item_color) + + C.d1 = 0 + C.d2 = dirn + C.add_fingerprint(user) + C.updateicon() + + C.powernet = new() + powernets += C.powernet + C.powernet.cables += C + + C.mergeConnectedNetworks(C.d2) + C.mergeConnectedNetworksOnTurf() - use(1) - if (C.shock(user, 50)) - if (prob(50)) //fail - new/obj/item/weapon/cable_coil(C.loc, 1, C.cable_color) - del(C) + use(1) + if (C.shock(user, 50)) + if (prob(50)) //fail + new/obj/item/weapon/cable_coil(C.loc, 1, C.cable_color) + del(C) //src.laying = 1 //last = C @@ -328,6 +387,12 @@ var/turf/T = C.loc +///// Z-Level Stuff + if(C.d1 == 12 || C.d2 == 12) + turf_place(T,user) + return +///// Z-Level Stuff + if(!isturf(T) || T.intact) // sanity checks, also stop use interacting with T-scanner revealed cable return diff --git a/code/modules/power/power.dm b/code/modules/power/power.dm index 986f81d6c84..3e1a8fce269 100644 --- a/code/modules/power/power.dm +++ b/code/modules/power/power.dm @@ -112,7 +112,17 @@ // if unmarked==1, only return those with no powernet /proc/power_list(var/turf/T, var/source, var/d, var/unmarked=0) . = list() - var/fdir = (!d)? 0 : turn(d, 180) // the opposite direction to d (or 0 if d==0) + var/fdir = (!d)? 0 : turn(d, 180) + // the opposite direction to d (or 0 if d==0) +///// Z-Level Stuff + var/Zdir + if(d==11) + Zdir = 11 + else if (d==12) + Zdir = 12 + else + Zdir = 999 +///// Z-Level Stuff // world.log << "d=[d] fdir=[fdir]" for(var/AM in T) if(AM == source) continue //we don't want to return source @@ -129,7 +139,9 @@ var/obj/structure/cable/C = AM if(!unmarked || !C.powernet) - if(C.d1 == fdir || C.d2 == fdir) +///// Z-Level Stuff + if(C.d1 == fdir || C.d2 == fdir || C.d1 == Zdir || C.d2 == Zdir) +///// Z-Level Stuff . += C else if(C.d1 == turn(C.d2, 180)) . += C @@ -140,11 +152,40 @@ . = list() // this will be a list of all connected power objects var/turf/T = loc - if(d1) T = get_step(src, d1) - if(T) . += power_list(T, src, d1, 1) +///// Z-Level Stuff + if(d1) + if(d1 <= 10) + T = get_step(src, d1) + if(T) + . += power_list(T, src, d1, 1) + else if (d1 == 11 || d1 == 12) + var/turf/controlerlocation = locate(1, 1, z) + for(var/obj/effect/landmark/zcontroler/controler in controlerlocation) + if(controler.up && d1 == 12) + T = locate(src.x, src.y, controler.up_target) + if(T) + . += power_list(T, src, 11, 1) + if(controler.down && d1 == 11) + T = locate(src.x, src.y, controler.down_target) + if(T) + . += power_list(T, src, 12, 1) - T = get_step(src, d2) - if(T) . += power_list(T, src, d2, 1) + if(d2 == 11 || d2 == 12) + var/turf/controlerlocation = locate(1, 1, z) + for(var/obj/effect/landmark/zcontroler/controler in controlerlocation) + if(controler.up && d2 == 12) + T = locate(src.x, src.y, controler.up_target) + if(T) + . += power_list(T, src, 11, 1) + if(controler.down && d2 == 11) + T = locate(src.x, src.y, controler.down_target) + if(T) + . += power_list(T, src, 12, 1) + else + T = get_step(src, d2) + if(T) + . += power_list(T, src, d2, 1) +///// Z-Level Stuff return . diff --git a/code/modules/recycling/disposal-construction.dm b/code/modules/recycling/disposal-construction.dm index 9bf34ff6c02..d6e30c6656b 100644 --- a/code/modules/recycling/disposal-construction.dm +++ b/code/modules/recycling/disposal-construction.dm @@ -65,9 +65,19 @@ if(10) base_state = "pipe-j2s" dpdir = dir | left | flip +///// Z-Level stuff + if(11) + base_state = "pipe-u" + dpdir = dir + if(12) + base_state = "pipe-d" + dpdir = dir +///// Z-Level stuff - if(ptype<6 || ptype>8) +///// Z-Level stuff + if(ptype<6 || ptype>8 && !(ptype==11 || ptype==12)) +///// Z-Level stuff icon_state = "con[base_state]" else icon_state = base_state @@ -139,6 +149,12 @@ return /obj/machinery/disposal/deliveryChute if(9,10) return /obj/structure/disposalpipe/sortjunction +///// Z-Level stuff + if(11) + return /obj/structure/disposalpipe/up + if(12) + return /obj/structure/disposalpipe/down +///// Z-Level stuff return diff --git a/code/modules/recycling/disposal.dm b/code/modules/recycling/disposal.dm index 04eff0de6ea..69b9a7dae47 100644 --- a/code/modules/recycling/disposal.dm +++ b/code/modules/recycling/disposal.dm @@ -873,6 +873,12 @@ C.ptype = 9 if("pipe-j2s") C.ptype = 10 +///// Z-Level stuff + if("pipe-u") + C.ptype = 11 + if("pipe-d") + C.ptype = 12 +///// Z-Level stuff src.transfer_fingerprints_to(C) C.dir = dir C.density = 0 @@ -900,8 +906,113 @@ update() return +///// Z-Level stuff +/obj/structure/disposalpipe/up + icon_state = "pipe-u" + New() + ..() + dpdir = dir + update() + return + nextdir(var/fromdir) + var/nextdir + if(fromdir == 11) + nextdir = dir + else + nextdir = 12 + return nextdir + + transfer(var/obj/structure/disposalholder/H) + var/nextdir = nextdir(H.dir) + H.dir = nextdir + + var/turf/T + var/obj/structure/disposalpipe/P + + if(nextdir == 12) + var/turf/controlerlocation = locate(1, 1, src.z) + for(var/obj/effect/landmark/zcontroler/controler in controlerlocation) + if(controler.up) + T = locate(src.x, src.y, controler.up_target) + if(!T) + H.loc = src.loc + return + else + for(var/obj/structure/disposalpipe/down/F in T) + P = F + + else + T = get_step(src.loc, H.dir) + P = H.findpipe(T) + + if(P) + // find other holder in next loc, if inactive merge it with current + var/obj/structure/disposalholder/H2 = locate() in P + if(H2 && !H2.active) + H.merge(H2) + + H.loc = P + else // if wasn't a pipe, then set loc to turf + H.loc = T + return null + + return P + +/obj/structure/disposalpipe/down + icon_state = "pipe-d" + + New() + ..() + dpdir = dir + update() + return + + nextdir(var/fromdir) + var/nextdir + if(fromdir == 12) + nextdir = dir + else + nextdir = 11 + return nextdir + + transfer(var/obj/structure/disposalholder/H) + var/nextdir = nextdir(H.dir) + H.dir = nextdir + + var/turf/T + var/obj/structure/disposalpipe/P + + if(nextdir == 11) + var/turf/controlerlocation = locate(1, 1, src.z) + for(var/obj/effect/landmark/zcontroler/controler in controlerlocation) + if(controler.down) + T = locate(src.x, src.y, controler.down_target) + if(!T) + H.loc = src.loc + return + else + for(var/obj/structure/disposalpipe/up/F in T) + P = F + + else + T = get_step(src.loc, H.dir) + P = H.findpipe(T) + + if(P) + // find other holder in next loc, if inactive merge it with current + var/obj/structure/disposalholder/H2 = locate() in P + if(H2 && !H2.active) + H.merge(H2) + + H.loc = P + else // if wasn't a pipe, then set loc to turf + H.loc = T + return null + + return P +///// Z-Level stuff //a three-way junction with dir being the dominant direction /obj/structure/disposalpipe/junction diff --git a/icons/obj/pipes/disposal.dmi b/icons/obj/pipes/disposal.dmi index 709344a6782..d96b98c8e08 100644 Binary files a/icons/obj/pipes/disposal.dmi and b/icons/obj/pipes/disposal.dmi differ diff --git a/icons/obj/power_cond_red.dmi b/icons/obj/power_cond_red.dmi index 962936479ae..459e99336ef 100644 Binary files a/icons/obj/power_cond_red.dmi and b/icons/obj/power_cond_red.dmi differ