From 0f781e36a75cc6db33f12e20eff9db7f59120bad Mon Sep 17 00:00:00 2001 From: Neerti Date: Thu, 2 Mar 2017 18:44:57 -0500 Subject: [PATCH] Adds Multi-Z Test Map --- code/datums/observation/turf_changed.dm | 28 +++ code/game/machinery/CableLayer.dm | 6 +- .../mecha/equipment/tools/medical_tools.dm | 4 +- code/game/objects/effects/effect_system.dm | 2 +- code/game/objects/structures/lattice.dm | 5 + code/game/turfs/turf_changing.dm | 9 + code/modules/admin/verbs/buildmode.dm | 9 +- code/modules/multiz/movement.dm | 209 ++++++++++++++--- code/modules/multiz/structures.dm | 213 ++++++++++++------ code/modules/multiz/turf.dm | 130 +++++------ code/modules/power/cable.dm | 161 +++++-------- icons/obj/power_cond_white.dmi | Bin 12329 -> 12337 bytes icons/turf/cliff.dmi | Bin 0 -> 750 bytes icons/turf/space.dmi | Bin 126411 -> 126419 bytes maps/example/example-1.dmm | 73 ++++++ maps/example/example-2.dmm | 69 ++++++ maps/example/example.dm | 14 ++ maps/example/example_defines.dm | 49 ++++ maps/northern_star/northern_star.dm | 2 + polaris.dme | 2 +- 20 files changed, 702 insertions(+), 283 deletions(-) create mode 100644 code/datums/observation/turf_changed.dm create mode 100644 icons/turf/cliff.dmi create mode 100644 maps/example/example-1.dmm create mode 100644 maps/example/example-2.dmm create mode 100644 maps/example/example.dm create mode 100644 maps/example/example_defines.dm diff --git a/code/datums/observation/turf_changed.dm b/code/datums/observation/turf_changed.dm new file mode 100644 index 0000000000..861b409227 --- /dev/null +++ b/code/datums/observation/turf_changed.dm @@ -0,0 +1,28 @@ +// Observer Pattern Implementation: Turf Changed +// Registration type: /turf +// +// Raised when: A turf has been changed using the ChangeTurf proc. +// +// Arguments that the called proc should expect: +// /turf/affected: The turf that has changed +// /old_density: Density before the change +// /new_density: Density after the change +// /old_opacity: Opacity before the change +// /new_opacity: Opacity after the change + +var/decl/observ/turf_changed/turf_changed_event = new() + +/decl/observ/turf_changed + name = "Turf Changed" + expected_type = /turf + +/************************ +* Turf Changed Handling * +************************/ + +/turf/ChangeTurf() + var/old_density = density + var/old_opacity = opacity + . = ..() + if(.) + turf_changed_event.raise_event(src, old_density, density, old_opacity, opacity) \ No newline at end of file diff --git a/code/game/machinery/CableLayer.dm b/code/game/machinery/CableLayer.dm index a5625e9253..2b4eae9a0d 100644 --- a/code/game/machinery/CableLayer.dm +++ b/code/game/machinery/CableLayer.dm @@ -73,7 +73,7 @@ visible_message("A red light flashes on \the [src].") return cable.use(amount) - if(deleted(cable)) + if(deleted(cable)) cable = null return 1 @@ -104,13 +104,13 @@ NC.cableColor("red") NC.d1 = 0 NC.d2 = fdirn - NC.updateicon() + NC.update_icon() var/datum/powernet/PN if(last_piece && last_piece.d2 != M_Dir) last_piece.d1 = min(last_piece.d2, M_Dir) last_piece.d2 = max(last_piece.d2, M_Dir) - last_piece.updateicon() + last_piece.update_icon() PN = last_piece.powernet if(!PN) diff --git a/code/game/mecha/equipment/tools/medical_tools.dm b/code/game/mecha/equipment/tools/medical_tools.dm index fdf4a16b00..ffe30bf3fd 100644 --- a/code/game/mecha/equipment/tools/medical_tools.dm +++ b/code/game/mecha/equipment/tools/medical_tools.dm @@ -348,13 +348,13 @@ NC.cableColor("red") NC.d1 = 0 NC.d2 = fdirn - NC.updateicon() + NC.update_icon() var/datum/powernet/PN if(last_piece && last_piece.d2 != chassis.dir) last_piece.d1 = min(last_piece.d2, chassis.dir) last_piece.d2 = max(last_piece.d2, chassis.dir) - last_piece.updateicon() + last_piece.update_icon() PN = last_piece.powernet if(!PN) diff --git a/code/game/objects/effects/effect_system.dm b/code/game/objects/effects/effect_system.dm index d7e530b761..610746339b 100644 --- a/code/game/objects/effects/effect_system.dm +++ b/code/game/objects/effects/effect_system.dm @@ -333,7 +333,7 @@ steam.start() -- spawns the effect spawn(0) var/turf/T = get_turf(src.holder) if(T != src.oldposition) - if(istype(T, /turf/space)) + if(istype(T, /turf/simulated)) var/obj/effect/effect/ion_trails/I = PoolOrNew(/obj/effect/effect/ion_trails, src.oldposition) src.oldposition = T I.set_dir(src.holder.dir) diff --git a/code/game/objects/structures/lattice.dm b/code/game/objects/structures/lattice.dm index 5d01438614..0eb48e94e0 100644 --- a/code/game/objects/structures/lattice.dm +++ b/code/game/objects/structures/lattice.dm @@ -34,6 +34,11 @@ if(locate(/obj/structure/lattice, get_step(src, dir))) L = locate(/obj/structure/lattice, get_step(src, dir)) L.updateOverlays(src.loc) + if(istype(loc, /turf/simulated/open)) + var/turf/simulated/open/O = loc + spawn(1) + if(O) // If we built a new floor with the lattice, the open turf won't exist anymore. + O.update() // This lattice may be supporting things on top of it. If it's being deleted, they need to fall down. ..() /obj/structure/lattice/ex_act(severity) diff --git a/code/game/turfs/turf_changing.dm b/code/game/turfs/turf_changing.dm index 9b9638d908..7379d2c80b 100644 --- a/code/game/turfs/turf_changing.dm +++ b/code/game/turfs/turf_changing.dm @@ -9,6 +9,13 @@ if(L) qdel(L) +// Called after turf replaces old one +/turf/proc/post_change() + levelupdate() + var/turf/simulated/open/T = GetAbove(src) + if(istype(T)) + T.update_icon() + //Creates a new turf /turf/proc/ChangeTurf(var/turf/N, var/tell_universe=1, var/force_lighting_update = 0) if (!N) @@ -60,6 +67,7 @@ W.levelupdate() W.update_icon(1) + W.post_change() . = W else @@ -83,6 +91,7 @@ W.levelupdate() W.update_icon(1) + W.post_change() . = W lighting_overlay = old_lighting_overlay diff --git a/code/modules/admin/verbs/buildmode.dm b/code/modules/admin/verbs/buildmode.dm index 5a211d960b..9239f6385f 100644 --- a/code/modules/admin/verbs/buildmode.dm +++ b/code/modules/admin/verbs/buildmode.dm @@ -392,11 +392,12 @@ if(holder.buildmode.coordA && holder.buildmode.coordB) user << "Ladder locations set, building ladders." - var/obj/structure/ladder/A = new /obj/structure/ladder(holder.buildmode.coordA) + var/obj/structure/ladder/A = new /obj/structure/ladder/up(holder.buildmode.coordA) var/obj/structure/ladder/B = new /obj/structure/ladder(holder.buildmode.coordB) - A.target = B - B.target = A - B.icon_state = "ladderup" + A.target_up = B + B.target_down = A + A.update_icon() + B.update_icon() holder.buildmode.coordA = null holder.buildmode.coordB = null if(7) // Move into contents diff --git a/code/modules/multiz/movement.dm b/code/modules/multiz/movement.dm index dd0a93fec1..586b624260 100644 --- a/code/modules/multiz/movement.dm +++ b/code/modules/multiz/movement.dm @@ -1,51 +1,194 @@ -/obj/item/weapon/tank/jetpack/verb/moveup() +/mob/verb/up() set name = "Move Upwards" - set category = "Object" + set category = "IC" - . = 1 - if(!allow_thrust(0.01, usr)) - usr << "\The [src] is disabled." + if(zMove(UP)) + to_chat(usr, "You move upwards.") + +/mob/verb/down() + set name = "Move Down" + set category = "IC" + + if(zMove(DOWN)) + to_chat(usr, "You move down.") + +/mob/proc/zMove(direction) + if(eyeobj) + return eyeobj.zMove(direction) + if(!can_ztravel()) + to_chat(usr, "You lack means of travel in that direction.") return - var/turf/above = GetAbove(src) - if(!istype(above)) - usr << "There is nothing of interest in this direction." - return + var/turf/destination = (direction == UP) ? GetAbove(src) : GetBelow(src) - if(!istype(above, /turf/space) && !istype(above, /turf/simulated/open)) - usr << "You bump against \the [above]." - return + if(!destination) + to_chat(usr, "There is nothing of interest in this direction.") + return 0 - for(var/atom/A in above) - if(A.density) - usr << "\The [A] blocks you." - return + var/turf/start = get_turf(src) + if(!start.CanZPass(src, direction)) + to_chat(usr, "\The [start] is in the way.") + return 0 + if(!destination.CanZPass(src, direction)) + to_chat(usr, "\The [destination] blocks your way.") + return 0 - usr.Move(above) - usr << "You move upwards." + var/area/area = get_area(src) + if(direction == UP && area.has_gravity) + var/obj/structure/lattice/lattice = locate() in destination.contents + if(lattice) + var/pull_up_time = max(5 SECONDS + (src.movement_delay() * 10), 1) + to_chat(src, "You grab \the [lattice] and start pulling yourself upward...") + destination.audible_message("You hear something climbing up \the [lattice].") + if(do_after(src, pull_up_time)) + to_chat(src, "You pull yourself up.") + else + to_chat(src, "You gave up on pulling yourself up.") + return 0 + else + to_chat(usr, "Gravity stops you from moving upward.") + return 0 -/obj/item/weapon/tank/jetpack/verb/movedown() - set name = "Move Downwards" - set category = "Object" + for(var/atom/A in destination) + if(!A.CanPass(src, start, 1.5, 0)) + to_chat(usr, "\The [A] blocks you.") + return 0 + Move(destination) + return 1 - . = 1 - if(!allow_thrust(0.01, usr)) - usr << "\The [src] is disabled." +/mob/observer/zMove(direction) + var/turf/destination = (direction == UP) ? GetAbove(src) : GetBelow(src) + if(destination) + forceMove(destination) + else + to_chat(usr, "There is nothing of interest in this direction.") + +/mob/observer/eye/zMove(direction) + var/turf/destination = (direction == UP) ? GetAbove(src) : GetBelow(src) + if(destination) + setLoc(destination) + else + to_chat(usr, "There is nothing of interest in this direction.") + +/mob/proc/can_ztravel() + return 0 + +/mob/observer/can_ztravel() + return 1 + +/mob/living/carbon/human/can_ztravel() + if(incapacitated()) + return 0 + + if(Process_Spacemove()) + return 1 + + if(Check_Shoegrip()) //scaling hull with magboots + for(var/turf/simulated/T in trange(1,src)) + if(T.density) + return 1 + +/mob/living/silicon/robot/can_ztravel() + if(incapacitated() || is_dead()) + return 0 + + if(Process_Spacemove()) //Checks for active jetpack + return 1 + + for(var/turf/simulated/T in trange(1,src)) //Robots get "magboots" + if(T.density) + return 1 + + + + +//FALLING STUFF + +//Holds fall checks that should not be overriden by children +/atom/movable/proc/fall() + if(!isturf(loc)) return var/turf/below = GetBelow(src) - if(!istype(below)) - usr << "There is nothing of interest in this direction." + if(!below) return - if(below.density) - usr << "You bump against \the [below]." + var/turf/T = loc + if(!T.CanZPass(src, DOWN) || !below.CanZPass(src, DOWN)) return + // No gravity in space, apparently. + var/area/area = get_area(src) + if(!area.has_gravity()) + return + + if(throwing) + return + + if(can_fall()) + handle_fall(below) + +//For children to override +/atom/movable/proc/can_fall() + if(anchored) + return FALSE + + if(locate(/obj/structure/lattice, loc)) + return FALSE + + // See if something prevents us from falling. + var/turf/below = GetBelow(src) for(var/atom/A in below) - if(A.density) - usr << "\The [A] blocks you." - return + if(!A.CanPass(src, src.loc)) + return FALSE - usr.Move(below) - usr << "You move downwards." + return TRUE + +/obj/effect/can_fall() + return FALSE + +/obj/effect/decal/cleanable/can_fall() + return TRUE + +/obj/item/pipe/can_fall() + var/turf/simulated/open/below = loc + below = below.below + + . = ..() + + if(anchored) + return FALSE + + if((locate(/obj/structure/disposalpipe/up) in below) || locate(/obj/machinery/atmospherics/pipe/zpipe/up in below)) + return FALSE + +/mob/living/simple_animal/parrot/can_fall() // Poly can fly. + return FALSE + +/mob/living/simple_animal/hostile/carp/can_fall() // So can carp apparently. + return FALSE + +/atom/movable/proc/handle_fall(var/turf/landing) + Move(landing) + if(locate(/obj/structure/stairs) in landing) + return 1 + + if(istype(landing, /turf/simulated/open)) + visible_message("\The [src] falls from the deck above through \the [landing]!", "You hear a whoosh of displaced air.") + else + visible_message("\The [src] falls from the deck above and slams into \the [landing]!", "You hear something slam into the deck.") + +/mob/living/carbon/human/handle_fall(var/turf/landing) + if(..()) + return + to_chat(src, "You fall off and hit \the [landing]!") + playsound(loc, "punch", 25, 1, -1) + var/damage = 20 // Because wounds heal rather quickly, 20 should be enough to discourage jumping off but not be enough to ruin you, at least for the first time. + apply_damage(rand(0, damage), BRUTE, BP_HEAD) + apply_damage(rand(0, damage), BRUTE, BP_TORSO) + apply_damage(rand(0, damage), BRUTE, BP_L_LEG) + apply_damage(rand(0, damage), BRUTE, BP_R_LEG) + apply_damage(rand(0, damage), BRUTE, BP_L_ARM) + apply_damage(rand(0, damage), BRUTE, BP_R_ARM) + Weaken(4) + updatehealth() \ No newline at end of file diff --git a/code/modules/multiz/structures.dm b/code/modules/multiz/structures.dm index 36a606bfcf..5727808276 100644 --- a/code/modules/multiz/structures.dm +++ b/code/modules/multiz/structures.dm @@ -4,54 +4,127 @@ /obj/structure/ladder name = "ladder" - desc = "A ladder. You can climb it up and down." - icon_state = "ladderdown" + desc = "A ladder. You can climb it up and down." + icon_state = "ladder01" icon = 'icons/obj/structures.dmi' density = 0 opacity = 0 anchored = 1 - var/obj/structure/ladder/target + var/allowed_directions = DOWN + var/obj/structure/ladder/target_up + var/obj/structure/ladder/target_down - initialize() - // the upper will connect to the lower - if(icon_state == "ladderup") - return + var/const/climb_time = 2 SECONDS +/obj/structure/ladder/initialize() + // the upper will connect to the lower + if(allowed_directions & DOWN) //we only want to do the top one, as it will initialize the ones before it. for(var/obj/structure/ladder/L in GetBelow(src)) - if(L.icon_state == "ladderup") - target = L - L.target = src + if(L.allowed_directions & UP) + target_down = L + L.target_up = src return + update_icon() - Destroy() - if(target && icon_state == "ladderdown") - qdel(target) - return ..() +/obj/structure/ladder/Destroy() + if(target_down) + target_down.target_up = null + target_down = null + if(target_up) + target_up.target_down = null + target_up = null + return ..() - attackby(obj/item/C as obj, mob/user as mob) - . = ..() - attack_hand(user) +/obj/structure/ladder/attackby(obj/item/C as obj, mob/user as mob) + attack_hand(user) + return + +/obj/structure/ladder/attack_hand(var/mob/M) + if(!M.may_climb_ladders(src)) return - attack_hand(var/mob/M) - if(!target || !istype(target.loc, /turf)) - M << "\The [src] is incomplete and can't be climbed." + var/obj/structure/ladder/target_ladder = getTargetLadder(M) + if(!target_ladder) + return + if(!M.Move(get_turf(src))) + to_chat(M, "You fail to reach \the [src].") + return + + var/direction = target_ladder == target_up ? "up" : "down" + + M.visible_message("\The [M] begins climbing [direction] \the [src]!", + "You begin climbing [direction] \the [src]!", + "You hear the grunting and clanging of a metal ladder being used.") + + target_ladder.audible_message("You hear something coming [direction] \the [src]") + + if(do_after(M, climb_time, src)) + climbLadder(M, target_ladder) + +/obj/structure/ladder/attack_ghost(var/mob/M) + var/target_ladder = getTargetLadder(M) + if(target_ladder) + M.forceMove(get_turf(target_ladder)) + +/obj/structure/ladder/proc/getTargetLadder(var/mob/M) + if((!target_up && !target_down) || (target_up && !istype(target_up.loc, /turf) || (target_down && !istype(target_down.loc,/turf)))) + to_chat(M, "\The [src] is incomplete and can't be climbed.") + return + if(target_down && target_up) + var/direction = alert(M,"Do you want to go up or down?", "Ladder", "Up", "Down", "Cancel") + + if(direction == "Cancel") return - var/turf/T = target.loc - for(var/atom/A in T) - if(A.density) - M << "\A [A] is blocking \the [src]." - return + if(!M.may_climb_ladders(src)) + return + + switch(direction) + if("Up") + return target_up + if("Down") + return target_down + else + return target_down || target_up + +/mob/proc/may_climb_ladders(var/ladder) + if(!Adjacent(ladder)) + to_chat(src, "You need to be next to \the [ladder] to start climbing.") + return FALSE + if(incapacitated()) + to_chat(src, "You are physically unable to climb \the [ladder].") + return FALSE + return TRUE + +/mob/observer/ghost/may_climb_ladders(var/ladder) + return TRUE + +/obj/structure/ladder/proc/climbLadder(var/mob/M, var/target_ladder) + var/turf/T = get_turf(target_ladder) + for(var/atom/A in T) + if(!A.CanPass(M, M.loc, 1.5, 0)) + to_chat(M, "\The [A] is blocking \the [src].") + return FALSE + return M.Move(T) + +/obj/structure/ladder/CanPass(obj/mover, turf/source, height, airflow) + return airflow || !density + +/obj/structure/ladder/update_icon() + icon_state = "ladder[!!(allowed_directions & UP)][!!(allowed_directions & DOWN)]" + +/obj/structure/ladder/up + allowed_directions = UP + icon_state = "ladder10" + +/obj/structure/ladder/updown + allowed_directions = UP|DOWN + icon_state = "ladder11" + + - 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" @@ -61,46 +134,50 @@ opacity = 0 anchored = 1 - initialize() - for(var/turf/turf in locs) - var/turf/simulated/open/above = GetAbove(turf) - if(!above) - warning("Stair created without level above: ([loc.x], [loc.y], [loc.z])") - return qdel(src) - if(!istype(above)) - above.ChangeTurf(/turf/simulated/open) +/obj/structure/stairs/initialize() + for(var/turf/turf in locs) + var/turf/simulated/open/above = GetAbove(turf) + if(!above) + warning("Stair created without level above: ([loc.x], [loc.y], [loc.z])") + return qdel(src) + if(!istype(above)) + above.ChangeTurf(/turf/simulated/open) - Uncross(atom/movable/A) - if(A.dir == dir) - // This is hackish but whatever. - var/turf/target = get_step(GetAbove(A), dir) - var/turf/source = A.loc - if(target.Enter(A, source)) - A.loc = target - target.Entered(A, source) - return 0 - return 1 +/obj/structure/stairs/Uncross(atom/movable/A) + if(A.dir == dir) + // This is hackish but whatever. + var/turf/target = get_step(GetAbove(A), dir) + var/turf/source = A.loc + if(target.Enter(A, source)) + A.loc = target + target.Entered(A, source) + if(isliving(A)) + var/mob/living/L = A + if(L.pulling) + L.pulling.forceMove(target) + return 0 + return 1 - CanPass(obj/mover, turf/source, height, airflow) - return airflow || !density +/obj/structure/stairs/CanPass(obj/mover, turf/source, height, airflow) + return airflow || !density - // type paths to make mapping easier. - north - dir = NORTH - bound_height = 64 - bound_y = -32 - pixel_y = -32 +// type paths to make mapping easier. +/obj/structure/stairs/north + dir = NORTH + bound_height = 64 + bound_y = -32 + pixel_y = -32 - south - dir = SOUTH - bound_height = 64 +/obj/structure/stairs/south + dir = SOUTH + bound_height = 64 - east - dir = EAST - bound_width = 64 - bound_x = -32 - pixel_x = -32 +/obj/structure/stairs/east + dir = EAST + bound_width = 64 + bound_x = -32 + pixel_x = -32 - west - dir = WEST - bound_width = 64 \ No newline at end of file +/obj/structure/stairs/west + dir = WEST + bound_width = 64 \ No newline at end of file diff --git a/code/modules/multiz/turf.dm b/code/modules/multiz/turf.dm index d85a464af2..8389df7112 100644 --- a/code/modules/multiz/turf.dm +++ b/code/modules/multiz/turf.dm @@ -1,87 +1,79 @@ +/turf/proc/CanZPass(atom/A, direction) + if(z == A.z) //moving FROM this turf + return direction == UP //can't go below + else + if(direction == UP) //on a turf below, trying to enter + return 0 + if(direction == DOWN) //on a turf above, trying to enter + return !density + +/turf/simulated/open/CanZPass(atom, direction) + return 1 + +/turf/space/CanZPass(atom, direction) + return 1 + /turf/simulated/open name = "open space" icon = 'icons/turf/space.dmi' - icon_state = "black" - alpha = 16 + icon_state = "" 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/post_change() + ..() + update() /turf/simulated/open/initialize() ..() - below = GetBelow(src) ASSERT(HasBelow(z)) + update() /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 + ..() + mover.fall() - // 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(mover.anchored || 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)) - mover.visible_message("\The [mover] falls from the deck above through \the [below]!", "You hear a whoosh of displaced air.") - else - mover.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, BP_HEAD) - H.apply_damage(rand(0, damage), BRUTE, BP_TORSO) - H.apply_damage(rand(0, damage), BRUTE, BP_L_LEG) - H.apply_damage(rand(0, damage), BRUTE, BP_R_LEG) - H.apply_damage(rand(0, damage), BRUTE, BP_L_ARM) - H.apply_damage(rand(0, damage), BRUTE, BP_R_ARM) - H.weakened = max(H.weakened,2) - H.updatehealth() +/turf/simulated/open/proc/update() + below = GetBelow(src) + turf_changed_event.register(below, src, /turf/simulated/open/update_icon) + var/turf/simulated/T = get_step(src,NORTH) + if(T) + turf_changed_event.register(T, src, /turf/simulated/open/update_icon) + levelupdate() + for(var/atom/movable/A in src) + A.fall() + update_icon() // override to make sure nothing is hidden /turf/simulated/open/levelupdate() for(var/obj/O in src) O.hide(0) +/turf/simulated/open/update_icon() + if(below) + underlays = list(image(icon = below.icon, icon_state = below.icon_state)) + underlays += below.overlays.Copy() + + var/list/noverlays = list() + if(!istype(below,/turf/space)) + noverlays += image(icon =icon, icon_state = "empty", layer = 2.2) + + var/turf/simulated/T = get_step(src,NORTH) + if(istype(T) && !istype(T,/turf/simulated/open)) + noverlays += image(icon ='icons/turf/cliff.dmi', icon_state = "metal", layer = 2.2) + + var/obj/structure/stairs/S = locate() in below + if(S && S.loc == below) + var/image/I = image(icon = S.icon, icon_state = "below", dir = S.dir, layer = 2.2) + I.pixel_x = S.pixel_x + I.pixel_y = S.pixel_y + noverlays += I + + overlays = noverlays + // Straight copy from space. /turf/simulated/open/attackby(obj/item/C as obj, mob/user as mob) if (istype(C, /obj/item/stack/rods)) @@ -108,4 +100,14 @@ return else user << "The plating is going to need some support." - return \ No newline at end of file + + //To lay cable. + if(istype(C, /obj/item/stack/cable_coil)) + var/obj/item/stack/cable_coil/coil = C + coil.turf_place(src, user) + return + return + +//Most things use is_plating to test if there is a cover tile on top (like regular floors) +/turf/simulated/open/is_plating() + return 1 \ No newline at end of file diff --git a/code/modules/power/cable.dm b/code/modules/power/cable.dm index c837f502dd..671d57e04e 100644 --- a/code/modules/power/cable.dm +++ b/code/modules/power/cable.dm @@ -129,12 +129,12 @@ var/list/possible_cable_coil_colours = list( /obj/structure/cable/hide(var/i) if(istype(loc, /turf)) invisibility = i ? 101 : 0 - updateicon() + update_icon() /obj/structure/cable/hides_under_flooring() return 1 -/obj/structure/cable/proc/updateicon() +/obj/structure/cable/update_icon() icon_state = "[d1]-[d2]" alpha = invisibility ? 127 : 255 @@ -635,102 +635,75 @@ obj/structure/cable/proc/cableColor(var/colorC) ////////////////////////////////////////////// // called when cable_coil is clicked on a turf/simulated/floor -/obj/item/stack/cable_coil/proc/turf_place(turf/simulated/floor/F, mob/user) +/obj/item/stack/cable_coil/proc/turf_place(turf/simulated/F, mob/user) if(!isturf(user.loc)) return if(get_amount() < 1) // Out of cable - user << "There is no cable left." + to_chat(user, "There is no cable left.") return if(get_dist(F,user) > 1) // Too far - user << "You can't lay cable at a place that far away." + to_chat(user, "You can't lay cable at a place that far away.") return if(!F.is_plating()) // Ff floor is intact, complain - user << "You can't lay cable there unless the floor tiles are removed." + to_chat(user, "You can't lay cable there unless the floor tiles are removed.") return + var/dirn + if(user.loc == F) + dirn = user.dir // if laying on the tile we're on, lay in the direction we're facing else - var/dirn + dirn = get_dir(F, user) - if(user.loc == F) - dirn = user.dir // if laying on the tile we're on, lay in the direction we're facing - else - dirn = get_dir(F, user) + var/end_dir = 0 + if(istype(F, /turf/simulated/open)) + if(!can_use(2)) + to_chat(user, "You don't have enough cable to do this!") + return + end_dir = DOWN - 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/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 + for(var/obj/structure/cable/LC in F) + if((LC.d1 == dirn && LC.d2 == end_dir ) || ( LC.d2 == dirn && LC.d1 == end_dir)) + to_chat(user, "There's already a cable at that position.") + return - var/obj/structure/cable/C = new(F) - var/obj/structure/cable/D = new(GetBelow(F)) + put_cable(F, user, end_dir, dirn) + if(end_dir == DOWN) + put_cable(GetBelow(F), user, UP, 0) + to_chat(user, "You slide some cable downward.") - C.cableColor(color) +/obj/item/stack/cable_coil/proc/put_cable(turf/simulated/F, mob/user, d1, d2) + if(!istype(F)) + return - C.d1 = 11 - C.d2 = dirn - C.add_fingerprint(user) - C.updateicon() + var/obj/structure/cable/C = new(F) + C.cableColor(color) + C.d1 = d1 + C.d2 = d2 + C.add_fingerprint(user) + C.update_icon() - var/datum/powernet/PN = new() - PN.add_cable(C) + //create a new powernet with the cable, if needed it will be merged later + var/datum/powernet/PN = new() + PN.add_cable(C) - C.mergeConnectedNetworks(C.d2) - C.mergeConnectedNetworksOnTurf() + C.mergeConnectedNetworks(C.d1) //merge the powernets... + C.mergeConnectedNetworks(C.d2) //...in the two new cable directions + C.mergeConnectedNetworksOnTurf() - D.cableColor(color) + if(C.d1 & (C.d1 - 1))// if the cable is layed diagonally, check the others 2 possible directions + C.mergeDiagonalsNetworks(C.d1) - D.d1 = 12 - D.d2 = 0 - D.add_fingerprint(user) - D.updateicon() + if(C.d2 & (C.d2 - 1))// if the cable is layed diagonally, check the others 2 possible directions + C.mergeDiagonalsNetworks(C.d2) - PN.add_cable(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(color) - - //set up the new cable - C.d1 = 0 //it's a O-X node cable - C.d2 = dirn - C.add_fingerprint(user) - C.updateicon() - - //create a new powernet with the cable, if needed it will be merged later - var/datum/powernet/PN = new() - PN.add_cable(C) - - C.mergeConnectedNetworks(C.d2) //merge the powernet with adjacents powernets - C.mergeConnectedNetworksOnTurf() //merge the powernet with on turf powernets - - if(C.d2 & (C.d2 - 1))// if the cable is layed diagonally, check the others 2 possible directions - C.mergeDiagonalsNetworks(C.d2) - - - use(1) - if (C.shock(user, 50)) - if (prob(50)) //fail - new/obj/item/stack/cable_coil(C.loc, 1, C.color) - qdel(C) + use(1) + if (C.shock(user, 50)) + if (prob(50)) //fail + new/obj/item/stack/cable_coil(C.loc, 1, C.color) + qdel(C) // called when cable_coil is click on an installed obj/cable // or click on a turf that already contains a "node" cable @@ -745,10 +718,9 @@ obj/structure/cable/proc/cableColor(var/colorC) return if(get_dist(C, user) > 1) // make sure it's close enough - user << "You can't lay cable at a place that far away." + to_chat(user, "You can't lay cable at a place that far away.") return - if(U == T) //if clicked on the turf we're standing on, try to put a cable in the direction we're facing turf_place(T,user) return @@ -758,7 +730,7 @@ obj/structure/cable/proc/cableColor(var/colorC) // one end of the clicked cable is pointing towards us if(C.d1 == dirn || C.d2 == dirn) if(!U.is_plating()) // can't place a cable if the floor is complete - user << "You can't lay cable there unless the floor tiles are removed." + to_chat(user, "You can't lay cable there unless the floor tiles are removed.") return else // cable is pointing at us, we're standing on an open tile @@ -768,34 +740,9 @@ obj/structure/cable/proc/cableColor(var/colorC) for(var/obj/structure/cable/LC in U) // check to make sure there's not a cable there already if(LC.d1 == fdirn || LC.d2 == fdirn) - user << "There's already a cable at that position." + to_chat(user, "There's already a cable at that position.") return - - var/obj/structure/cable/NC = new(U) - NC.cableColor(color) - - NC.d1 = 0 - NC.d2 = fdirn - NC.add_fingerprint() - NC.updateicon() - - //create a new powernet with the cable, if needed it will be merged later - var/datum/powernet/newPN = new() - newPN.add_cable(NC) - - NC.mergeConnectedNetworks(NC.d2) //merge the powernet with adjacents powernets - NC.mergeConnectedNetworksOnTurf() //merge the powernet with on turf powernets - - if(NC.d2 & (NC.d2 - 1))// if the cable is layed diagonally, check the others 2 possible directions - NC.mergeDiagonalsNetworks(NC.d2) - - use(1) - - if (NC.shock(user, 50)) - if (prob(50)) //fail - new/obj/item/stack/cable_coil(NC.loc, 1, NC.color) - qdel(NC) - + put_cable(U,user,0,fdirn) return // exisiting cable doesn't point at our position, so see if it's a stub @@ -814,7 +761,7 @@ obj/structure/cable/proc/cableColor(var/colorC) if(LC == C) // skip the cable we're interacting with continue if((LC.d1 == nd1 && LC.d2 == nd2) || (LC.d1 == nd2 && LC.d2 == nd1) ) // make sure no cable matches either direction - user << "There's already a cable at that position." + to_chat(user, "There's already a cable at that position.") return @@ -824,7 +771,7 @@ obj/structure/cable/proc/cableColor(var/colorC) C.d2 = nd2 C.add_fingerprint() - C.updateicon() + C.update_icon() C.mergeConnectedNetworks(C.d1) //merge the powernets... diff --git a/icons/obj/power_cond_white.dmi b/icons/obj/power_cond_white.dmi index 8d17183bfa41316444880ffbc9b2d3c2b8e54905..f9f3d9da7a6355a68c681e7b4dd250f2c22a0c5c 100644 GIT binary patch delta 267 zcmV+m0rdWfFDZ*Bkpc$|%tF>1p=5JhY4DF(ZC(9G;E za$`BHRDR{cW9C2DKYRJ?zWTGYr#{?=d71uxrAYj!L-m-h z>nKIsLNyN4_qe_u%X(P{DYB~%x(n5HninY&Lv@=kKf@wLbbrejU?N}=U@~ADz#IXi z^;<}RyaIUz@(Sb?$SaUnB5y#17ZfmjEF@LI)cya0woeC zgJl^k%Vb#t1~p{Rkw9+XFuH-`;G{%Oe!r8dIq8~{A~|Z3=EDZkf6!jKb1Uts4^K|F Rv0^vSj)MRIAhQ|)4=*VRb|nA+ delta 267 zcmV+m0rdW{V5wk`B!B99R9JLGWpiV4X>fFDZ*Bkpc$|%tu?~VT6h&wH6)!Stc+Zx= z(8XX3gZ={vC=6->jsCua3r?P~$w_<8(3{KQcxo@woLl!A=4E<5B#Pe^E_+XX8YRl! zTs98VZA{<8lDafVlufbKjm!FJUL=Zl*>&#j!y-|1%@|-jV1EK&O2AZrsR5(KUr0f` zf_Me-3gQ*SD~MMTZy?M-n1L_@VFtpCgn1zCfwTwG9!Ps49e_{(LIDT`B24M8J<76MI#+I9u$50uOC(nxb|-3L17u||Z0I$Qt% RAOJ~3K~#90?XxNY2QRB&a|Zwb diff --git a/icons/turf/cliff.dmi b/icons/turf/cliff.dmi new file mode 100644 index 0000000000000000000000000000000000000000..40e8885771cbc1657cb8206203e911119991cb38 GIT binary patch literal 750 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE3?yBabR7dy9|C+rTt!4h!otEVEiHAlwQX!{ zBE!RNZEZb0JX~B{oSmJVoIwPLa)QuK4i5JA4j=+V*+Xc1Yiny8AhfmtVh{_=G&eIh zGcyMQAOU28IcCO2KwxYPq(B%*f}jZy1A&Q=kqJ=LL{Cp&AA*4-7;0$)fff*eDKJx8 zOHEx34AeoiIuNKSfq=3y2mxs&Ie9rC0D4eF6o^5DnVFfIx9mHh-x*7S{DK)Ap4~_T zax$wzB1&9Ri<65o3raHc^B5Q^<^+co6qSDe5?t`{>k}<+U9EFx&IfM@HMnT};E~RG zAI*~tMLoScER2JUFB^L)%y~5F$fOX3U`_L_Du(Wz-Nve$S4f;NfAYvj+v|*P>xQYK zF@IwY9AjcIza}Nu^dOQC=m2w17sn8b-nXZ2hc!8fusx8Sz^Y}`#J8fef&Ic7gJ3rS z{>-uo75}$qwk*xQ>3XN+qU-%xH~-J8=RG3%K#AEvbK1{m5e(B4^dsM$S=kWNl(_Sb zWMAqf)^$b)O55x|Hi~~@U3j89DNcafwd$yle#fGK2i-}Y0u>ViBHg+|^ri>8h6zlX zx~gTBsEW7O(yj?C5l16}3)e1tSjGHUI`nAN;&m5=9!njQm{oQ9!ff5kJ-XU?k-3L2 zo!url+xKt>@7+raFTcGRd;H~h>*jfvU*5fSZlT1j=G_Zx{~Nq$vX-*#n}6&|%9~v# zZeM&dcD>{ZKL7c|neWX%=lrl!OfgeEXv4vAm-$hpK-ZGSt|SIw`zP=c(B~De`h>_@y6ik>gTe~ HDWM4fQK%7+ literal 0 HcmV?d00001 diff --git a/icons/turf/space.dmi b/icons/turf/space.dmi index 30d0d1428a533d5de1e02cfa8d5f11a146eade1a..e11f256d8889d8d107c7a6345dc9adfcba1449d8 100644 GIT binary patch delta 16123 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 aIBvDlkAcFEBlAdzKLr^T>2j%epZ^~p{Q~O% diff --git a/maps/example/example-1.dmm b/maps/example/example-1.dmm new file mode 100644 index 0000000000..6c5d1ead2d --- /dev/null +++ b/maps/example/example-1.dmm @@ -0,0 +1,73 @@ +"a" = (/turf/space,/area/space) +"b" = (/turf/simulated/wall,/area/aisat) +"c" = (/obj/machinery/atmospherics/pipe/zpipe/up{tag = "icon-up (EAST)"; icon_state = "up"; dir = 4},/obj/structure/disposalpipe/up,/turf/simulated/floor/plating,/area/aisat) +"d" = (/obj/machinery/atmospherics/pipe/simple/visible{dir = 4},/obj/effect/floor_decal/corner/white/diagonal,/turf/simulated/floor/tiled/dark,/area/aisat) +"e" = (/obj/machinery/atmospherics/pipe/manifold/visible{dir = 1},/obj/effect/floor_decal/corner/white/diagonal,/turf/simulated/floor/tiled/dark,/area/aisat) +"f" = (/obj/machinery/atmospherics/binary/pump/high_power{dir = 8},/obj/effect/floor_decal/corner/white/diagonal,/turf/simulated/floor/tiled/dark,/area/aisat) +"g" = (/obj/machinery/atmospherics/pipe/simple/visible{tag = "icon-intact (SOUTHWEST)"; icon_state = "intact"; dir = 10},/obj/effect/floor_decal/corner/white/diagonal,/turf/simulated/floor/tiled/dark,/area/aisat) +"h" = (/obj/effect/floor_decal/corner/white/diagonal,/turf/simulated/floor/tiled/dark,/area/aisat) +"i" = (/obj/machinery/light{dir = 1},/turf/simulated/floor/tiled/dark,/area/aisat) +"j" = (/obj/structure/disposalpipe/segment,/turf/simulated/floor/plating,/area/aisat) +"k" = (/obj/machinery/atmospherics/pipe/simple/visible,/obj/effect/floor_decal/corner/white/diagonal,/obj/machinery/meter,/turf/simulated/floor/tiled/dark,/area/aisat) +"l" = (/obj/machinery/atmospherics/portables_connector{dir = 4},/obj/effect/floor_decal/corner/white/diagonal,/turf/simulated/floor/tiled/dark,/area/aisat) +"m" = (/obj/machinery/atmospherics/pipe/manifold/visible{tag = "icon-map (EAST)"; icon_state = "map"; dir = 4},/obj/effect/floor_decal/corner/white/diagonal,/obj/machinery/meter,/turf/simulated/floor/tiled/dark,/area/aisat) +"n" = (/turf/simulated/floor/tiled/dark,/area/aisat) +"o" = (/obj/effect/floor_decal/industrial/hatch/yellow,/turf/simulated/floor/tiled/dark,/area/aisat) +"p" = (/obj/machinery/portable_atmospherics/canister/empty,/obj/effect/floor_decal/corner/white/diagonal,/obj/structure/disposalpipe/segment,/turf/simulated/floor/tiled/dark,/area/aisat) +"q" = (/obj/machinery/atmospherics/pipe/simple/visible{tag = "icon-intact (NORTHEAST)"; icon_state = "intact"; dir = 5},/obj/effect/floor_decal/corner/white/diagonal,/turf/simulated/floor/tiled/dark,/area/aisat) +"r" = (/obj/machinery/atmospherics/binary/pump/high_power{tag = "icon-map_off (EAST)"; icon_state = "map_off"; dir = 4},/obj/effect/floor_decal/corner/white/diagonal,/turf/simulated/floor/tiled/dark,/area/aisat) +"s" = (/obj/machinery/atmospherics/pipe/simple/visible{tag = "icon-intact (NORTHWEST)"; icon_state = "intact"; dir = 9},/obj/effect/floor_decal/corner/white/diagonal,/turf/simulated/floor/tiled/dark,/area/aisat) +"t" = (/obj/structure/ladder/up,/turf/simulated/floor/tiled/dark,/area/aisat) +"u" = (/obj/machinery/portable_atmospherics/canister/air,/obj/effect/floor_decal/corner/white/diagonal,/obj/structure/disposalpipe/segment,/turf/simulated/floor/tiled/dark,/area/aisat) +"v" = (/obj/machinery/light,/turf/simulated/floor/tiled/dark,/area/aisat) +"w" = (/obj/machinery/alarm{dir = 4; icon_state = "alarm0"; pixel_x = -22},/obj/machinery/light{icon_state = "tube1"; dir = 8},/obj/machinery/disposal,/obj/structure/disposalpipe/trunk{tag = "icon-pipe-t (NORTH)"; icon_state = "pipe-t"; dir = 1},/turf/simulated/floor/tiled/dark,/area/aisat) +"x" = (/obj/machinery/light{icon_state = "tube1"; dir = 4},/turf/simulated/floor/tiled/dark,/area/aisat) +"y" = (/obj/machinery/light_switch,/turf/simulated/wall,/area/aisat) +"z" = (/obj/machinery/light{icon_state = "tube1"; dir = 8},/turf/simulated/floor/tiled/dark,/area/aisat) +"A" = (/obj/machinery/light{icon_state = "tube1"; dir = 4},/obj/machinery/power/apc{dir = 4; name = "east bump"; pixel_x = 24},/obj/structure/cable/yellow{d2 = 2; icon_state = "0-2"},/turf/simulated/floor/tiled/dark,/area/aisat) +"B" = (/obj/effect/floor_decal/corner/white/diagonal,/obj/structure/table/standard,/obj/item/device/multitool,/turf/simulated/floor/tiled/dark,/area/aisat) +"C" = (/obj/machinery/light{dir = 1},/obj/structure/table/standard,/obj/item/weapon/storage/belt/utility/full,/turf/simulated/floor/tiled/dark,/area/aisat) +"D" = (/obj/effect/floor_decal/corner/white/diagonal,/obj/structure/table/standard,/obj/item/clothing/gloves/yellow,/turf/simulated/floor/tiled/dark,/area/aisat) +"E" = (/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/effect/floor_decal/corner/white/diagonal,/turf/simulated/floor/tiled/dark,/area/aisat) +"F" = (/obj/effect/landmark{name = "JoinLate"},/obj/effect/floor_decal/corner/white/diagonal,/turf/simulated/floor/tiled/dark,/area/aisat) +"G" = (/obj/effect/landmark/start,/turf/simulated/floor/tiled/dark,/area/aisat) +"H" = (/obj/structure/stairs/south,/turf/simulated/floor/tiled/dark,/area/aisat) +"I" = (/obj/effect/floor_decal/sign/a,/turf/simulated/floor/tiled/dark,/area/aisat) +"J" = (/obj/machinery/light,/obj/effect/floor_decal/corner/white/diagonal,/turf/simulated/floor/tiled/dark,/area/aisat) +"K" = (/obj/structure/cable/yellow,/obj/structure/cable/yellow{d1 = 16; d2 = 0; icon_state = "16-0"},/turf/simulated/floor/plating,/area/aisat) +"L" = (/turf/simulated/floor/tiled/red,/area/aisat) + +(1,1,1) = {" +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaabbbbbbbbbbbbbbbaaaaaaaaa +aaaaaaaabcdefghihhhhhhbaaaaaaaaa +aaaaaaaabjhklmhnhhooohbaaaaaaaaa +aaaaaaaabphqrshthhooohbaaaaaaaaa +aaaaaaaabphhhhhnhhooohbaaaaaaaaa +aaaaaaaabuhhhhhnhhhhhhbaaaaaaaaa +aaaaaaaabuhhhhhvhhhhhhbaaaaaaaaa +aaaaaaaabwnnnnxyznnnnAbaaaaaaaaa +aaaaaaaabhhhhhBCDhhhhEbaaaaaaaaa +aaaaaaaabhhFFFhnhhhhhEbaaaaaaaaa +aaaaaaaabhhFFFhGhhhhhEbaaaaaaaaa +aaaaaaaabnbFFFhnhhhhhEbaaaaaaaaa +aaaaaaaabHbhhhhIhhhhhEbaaaaaaaaa +aaaaaaaabbbhJhhnhhJhhKbaaaaaaaaa +aaaaaaaabbbbbLLLLLbbbbbaaaaaaaaa +aaaaaaaaaaaabLLLLLbaaaaaaaaaaaaa +aaaaaaaaaaaabLLLLLbaaaaaaaaaaaaa +aaaaaaaaaaaabLLLLLbaaaaaaaaaaaaa +aaaaaaaaaaaabLLLLLbaaaaaaaaaaaaa +aaaaaaaaaaaabbbbbbbaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +"} diff --git a/maps/example/example-2.dmm b/maps/example/example-2.dmm new file mode 100644 index 0000000000..972beeecfc --- /dev/null +++ b/maps/example/example-2.dmm @@ -0,0 +1,69 @@ +"a" = (/turf/space,/area/space) +"b" = (/obj/effect/landmark/map_data{height = 2; step_x = 0},/turf/space,/area/space) +"c" = (/turf/simulated/wall,/area/aisat_interior) +"d" = (/obj/structure/lattice,/obj/machinery/atmospherics/pipe/zpipe/down{tag = "icon-down (EAST)"; icon_state = "down"; dir = 4},/obj/structure/disposalpipe/down,/turf/simulated/open,/area/aisat_interior) +"e" = (/obj/machinery/atmospherics/pipe/simple/visible{dir = 4},/obj/effect/floor_decal/corner/lime/diagonal,/turf/simulated/floor/tiled/dark,/area/aisat_interior) +"f" = (/obj/machinery/atmospherics/pipe/manifold/visible{dir = 1},/obj/effect/floor_decal/corner/lime/diagonal,/turf/simulated/floor/tiled/dark,/area/aisat_interior) +"g" = (/obj/machinery/atmospherics/binary/pump/high_power{dir = 8},/obj/effect/floor_decal/corner/lime/diagonal,/turf/simulated/floor/tiled/dark,/area/aisat_interior) +"h" = (/obj/machinery/atmospherics/pipe/simple/visible{tag = "icon-intact (SOUTHWEST)"; icon_state = "intact"; dir = 10},/obj/effect/floor_decal/corner/lime/diagonal,/turf/simulated/floor/tiled/dark,/area/aisat_interior) +"i" = (/obj/effect/floor_decal/corner/lime/diagonal,/turf/simulated/floor/tiled/dark,/area/aisat_interior) +"j" = (/obj/machinery/light{dir = 1},/turf/simulated/floor/tiled/dark,/area/aisat_interior) +"k" = (/obj/structure/disposalpipe/segment,/turf/simulated/floor/plating,/area/aisat_interior) +"l" = (/obj/machinery/atmospherics/pipe/simple/visible,/obj/effect/floor_decal/corner/lime/diagonal,/obj/machinery/meter,/turf/simulated/floor/tiled/dark,/area/aisat_interior) +"m" = (/obj/machinery/atmospherics/portables_connector{dir = 4},/obj/effect/floor_decal/corner/lime/diagonal,/turf/simulated/floor/tiled/dark,/area/aisat_interior) +"n" = (/obj/machinery/atmospherics/pipe/manifold/visible{tag = "icon-map (EAST)"; icon_state = "map"; dir = 4},/obj/effect/floor_decal/corner/lime/diagonal,/obj/machinery/meter,/turf/simulated/floor/tiled/dark,/area/aisat_interior) +"o" = (/turf/simulated/floor/tiled/dark,/area/aisat_interior) +"p" = (/turf/simulated/open,/area/aisat_interior) +"q" = (/obj/machinery/portable_atmospherics/canister/empty,/obj/effect/floor_decal/corner/lime/diagonal,/obj/structure/disposalpipe/segment,/turf/simulated/floor/tiled/dark,/area/aisat_interior) +"r" = (/obj/machinery/atmospherics/pipe/simple/visible{tag = "icon-intact (NORTHEAST)"; icon_state = "intact"; dir = 5},/obj/effect/floor_decal/corner/lime/diagonal,/turf/simulated/floor/tiled/dark,/area/aisat_interior) +"s" = (/obj/machinery/atmospherics/binary/pump/high_power{tag = "icon-map_off (EAST)"; icon_state = "map_off"; dir = 4},/obj/effect/floor_decal/corner/lime/diagonal,/turf/simulated/floor/tiled/dark,/area/aisat_interior) +"t" = (/obj/machinery/atmospherics/pipe/simple/visible{tag = "icon-intact (NORTHWEST)"; icon_state = "intact"; dir = 9},/obj/effect/floor_decal/corner/lime/diagonal,/turf/simulated/floor/tiled/dark,/area/aisat_interior) +"u" = (/obj/structure/ladder,/turf/simulated/floor/tiled/dark,/area/aisat_interior) +"v" = (/obj/machinery/portable_atmospherics/canister/air,/obj/effect/floor_decal/corner/lime/diagonal,/obj/structure/disposalpipe/segment,/turf/simulated/floor/tiled/dark,/area/aisat_interior) +"w" = (/obj/machinery/light,/turf/simulated/floor/tiled/dark,/area/aisat_interior) +"x" = (/obj/machinery/alarm{dir = 4; icon_state = "alarm0"; pixel_x = -22},/obj/machinery/light{icon_state = "tube1"; dir = 8},/obj/machinery/disposal,/obj/structure/disposalpipe/trunk{tag = "icon-pipe-t (NORTH)"; icon_state = "pipe-t"; dir = 1},/turf/simulated/floor/tiled/dark,/area/aisat_interior) +"y" = (/obj/machinery/light{icon_state = "tube1"; dir = 4},/turf/simulated/floor/tiled/dark,/area/aisat_interior) +"z" = (/obj/machinery/light_switch,/turf/simulated/wall,/area/aisat_interior) +"A" = (/obj/machinery/power/fractal_reactor,/obj/structure/cable/yellow{d2 = 4; icon_state = "0-4"},/obj/machinery/light{icon_state = "tube1"; dir = 8},/turf/simulated/floor/tiled/dark,/area/aisat_interior) +"B" = (/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/tiled/dark,/area/aisat_interior) +"C" = (/obj/machinery/power/apc{dir = 4; name = "east bump"; pixel_x = 24},/obj/structure/cable/yellow{d2 = 8; icon_state = "0-8"},/obj/structure/cable/yellow{d1 = 2; d2 = 8; icon_state = "2-8"},/obj/machinery/light{icon_state = "tube1"; dir = 4},/turf/simulated/floor/tiled/dark,/area/aisat_interior) +"D" = (/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/effect/floor_decal/corner/lime/diagonal,/turf/simulated/floor/tiled/dark,/area/aisat_interior) +"E" = (/turf/simulated/floor/tiled/red,/area/aisat_interior) +"F" = (/obj/effect/floor_decal/sign/two,/turf/simulated/floor/tiled/dark,/area/aisat_interior) +"G" = (/obj/machinery/light,/obj/effect/floor_decal/corner/lime/diagonal,/turf/simulated/floor/tiled/dark,/area/aisat_interior) +"H" = (/obj/structure/lattice,/obj/structure/cable/yellow{d1 = 32; icon_state = "32-1"},/turf/simulated/open,/area/aisat_interior) + +(1,1,1) = {" +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaabaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaacccccccccccccccaaaaaaaaa +aaaaaaaacdefghijiiiiiicaaaaaaaaa +aaaaaaaackilmnioiipppicaaaaaaaaa +aaaaaaaacqirstiuiipppicaaaaaaaaa +aaaaaaaacqiiiiioiipppicaaaaaaaaa +aaaaaaaacviiiiioiiiiiicaaaaaaaaa +aaaaaaaacviiiiiwiiiiiicaaaaaaaaa +aaaaaaaacxooooyzABBBBCcaaaaaaaaa +aaaaaaaaciiiiiijiiiiiDcaaaaaaaaa +aaaaaaaaciiiiiioiiiiiDcaaaaaaaaa +aaaaaaaaccciiiioiiiiiDcaaaaaaaaa +aaaaaaaacEciiiioiiiiiDcaaaaaaaaa +aaaaaaaacEciiiiFiiiiiDcaaaaaaaaa +aaaaaaaaciiiGiioiiGiiHcaaaaaaaaa +aaaaaaaacccccEEEEEcccccaaaaaaaaa +aaaaaaaaaaaacEEEEEcaaaaaaaaaaaaa +aaaaaaaaaaaacEEEEEcaaaaaaaaaaaaa +aaaaaaaaaaaacEEEEEcaaaaaaaaaaaaa +aaaaaaaaaaaacEEEEEcaaaaaaaaaaaaa +aaaaaaaaaaaacccccccaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +"} diff --git a/maps/example/example.dm b/maps/example/example.dm new file mode 100644 index 0000000000..d5e18ea366 --- /dev/null +++ b/maps/example/example.dm @@ -0,0 +1,14 @@ +#if !defined(USING_MAP_DATUM) + + #include "example-1.dmm" + #include "example-2.dmm" + + #include "example_defines.dm" + + #define USING_MAP_DATUM /datum/map/example + +#elif !defined(MAP_OVERRIDE) + + #warn A map has already been included, ignoring Northern Star + +#endif \ No newline at end of file diff --git a/maps/example/example_defines.dm b/maps/example/example_defines.dm new file mode 100644 index 0000000000..3c7ae5d30e --- /dev/null +++ b/maps/example/example_defines.dm @@ -0,0 +1,49 @@ +#define Z_LEVEL_FIRST_EXAMPLE 1 +#define Z_LEVEL_SECOND_EXAMPLE 2 + +/datum/map/example + name = "Test Map" + full_name = "The Test Map" + path = "example" + + lobby_icon = 'icons/misc/title.dmi' + lobby_screens = list("mockingjay00") + + station_levels = list( + Z_LEVEL_FIRST_EXAMPLE, + Z_LEVEL_SECOND_EXAMPLE + ) + + admin_levels = list() + contact_levels = list( + Z_LEVEL_FIRST_EXAMPLE, + Z_LEVEL_SECOND_EXAMPLE + ) + + player_levels = list( + Z_LEVEL_FIRST_EXAMPLE, + Z_LEVEL_SECOND_EXAMPLE + ) + + sealed_levels = list() + empty_levels = list() + accessible_z_levels = list("1" = 50, "2" = 50) // The defines can't be used here sadly. + base_turf_by_z = list("2" = /turf/simulated/open) + + station_name = "The Funhouse" + station_short = "Funhouse" + dock_name = "the Maximum Fun Chamber" + boss_name = "Mister Fun" + boss_short = "Mr. Fun" + company_name = "Fun Inc." + company_short = "FI" + starsys_name = "Vir" + + shuttle_docked_message = "The scheduled shuttle to the %dock_name% has docked with the station at docks one and two. It will depart in approximately %ETD%." + shuttle_leaving_dock = "The Crew Transfer Shuttle has left the station. Estimate %ETA% until the shuttle docks at %dock_name%." + shuttle_called_message = "A crew transfer to %Dock_name% has been scheduled. The shuttle has been called. Those leaving should procede to docks one and two in approximately %ETA%" + shuttle_recall_message = "The scheduled crew transfer has been cancelled." + emergency_shuttle_docked_message = "The Emergency Shuttle has docked with the station at docks one and two. You have approximately %ETD% to board the Emergency Shuttle." + emergency_shuttle_leaving_dock = "The Emergency Shuttle has left the station. Estimate %ETA% until the shuttle docks at %dock_name%." + emergency_shuttle_called_message = "An emergency evacuation shuttle has been called. It will arrive at docks one and two in approximately %ETA%" + emergency_shuttle_recall_message = "The emergency shuttle has been recalled." \ No newline at end of file diff --git a/maps/northern_star/northern_star.dm b/maps/northern_star/northern_star.dm index 90edaa6c73..2212774657 100644 --- a/maps/northern_star/northern_star.dm +++ b/maps/northern_star/northern_star.dm @@ -6,6 +6,8 @@ #include "polaris-4.dmm" #include "polaris-5.dmm" + #include "northern_star_defines.dm" + #define USING_MAP_DATUM /datum/map/northern_star #elif !defined(MAP_OVERRIDE) diff --git a/polaris.dme b/polaris.dme index e1dbe5ff98..45b45aaa9e 100644 --- a/polaris.dme +++ b/polaris.dme @@ -205,6 +205,7 @@ #include "code\datums\observation\moved.dm" #include "code\datums\observation\observation.dm" #include "code\datums\observation\task_triggered.dm" +#include "code\datums\observation\turf_changed.dm" #include "code\datums\observation\unequipped.dm" #include "code\datums\observation\~cleanup.dm" #include "code\datums\repositories\cameras.dm" @@ -2173,6 +2174,5 @@ #include "interface\interface.dm" #include "interface\skin.dmf" #include "maps\northern_star\northern_star.dm" -#include "maps\northern_star\northern_star_defines.dm" #include "maps\~map_system\maps.dm" // END_INCLUDE