Do the thing (#1812)

This commit is contained in:
Lohikar
2017-02-20 12:34:24 -05:00
committed by LordFowl
parent 4b7270230c
commit 2945dc9f0d
20 changed files with 467 additions and 233 deletions
+22 -4
View File
@@ -11,25 +11,43 @@ var/z_levels = 0 // Each bit represents a connection between adjacent levels. S
qdel(src)
// The storage of connections between adjacent levels means some bitwise magic is needed.
proc/HasAbove(var/z)
/proc/HasAbove(var/z)
if(z >= world.maxz || z > 16 || z < 1)
return 0
return z_levels & (1 << (z - 1))
proc/HasBelow(var/z)
/proc/HasBelow(var/z)
if(z > world.maxz || z > 17 || z < 2)
return 0
return z_levels & (1 << (z - 2))
// Thankfully, no bitwise magic is needed here.
proc/GetAbove(var/atom/atom)
/proc/GetAbove(var/atom/atom)
var/turf/turf = get_turf(atom)
if(!turf)
return null
return HasAbove(turf.z) ? get_step(turf, UP) : null
proc/GetBelow(var/atom/atom)
/proc/GetBelow(var/atom/atom)
var/turf/turf = get_turf(atom)
if(!turf)
return null
return HasBelow(turf.z) ? get_step(turf, DOWN) : null
/proc/GetConnectedZlevels(z)
. = list(z)
for(var/level = z, HasBelow(level), level--)
. |= level-1
for(var/level = z, HasAbove(level), level++)
. |= level+1
proc/AreConnectedZLevels(var/zA, var/zB)
return zA == zB || (zB in GetConnectedZlevels(zA))
/proc/get_zstep(ref, dir)
if(dir == UP)
. = GetAbove(ref)
else if (dir == DOWN)
. = GetBelow(ref)
else
. = get_step(ref, dir)
+154 -33
View File
@@ -1,51 +1,172 @@
/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 << "<span class='warning'>\The [src] is disabled.</span>"
if(zMove(UP))
to_chat(usr, "<span class='notice'>You move upwards.</span>")
/mob/verb/down()
set name = "Move Down"
set category = "IC"
if(zMove(DOWN))
to_chat(usr, "<span class='notice'>You move down.</span>")
/mob/proc/zMove(direction)
if(eyeobj)
return eyeobj.zMove(direction)
if(!can_ztravel())
to_chat(usr, "<span class='warning'>You lack means of travel in that direction.</span>")
return
var/turf/above = GetAbove(src)
if(!istype(above))
usr << "<span class='notice'>There is nothing of interest in this direction.</span>"
return
var/turf/destination = (direction == UP) ? GetAbove(src) : GetBelow(src)
if(!istype(above, /turf/space) && !istype(above, /turf/simulated/open))
usr << "<span class='warning'>You bump against \the [above].</span>"
return
if(!destination)
to_chat(usr, "<span class='notice'>There is nothing of interest in this direction.</span>")
return 0
for(var/atom/A in above)
if(A.density)
usr << "<span class='warning'>\The [A] blocks you.</span>"
return
var/turf/start = get_turf(src)
if(!start.CanZPass(src, direction))
to_chat(usr, "<span class='warning'>\The [start] is in the way.</span>")
return 0
if(!destination.CanZPass(src, direction))
to_chat(usr, "<span class='warning'>You bump against \the [destination].</span>")
return 0
usr.Move(above)
usr << "<span class='notice'>You move upwards.</span>"
var/area/area = get_area(src)
if(direction == UP && area.has_gravity)
to_chat(usr, "<span class='warning'>Gravity stops you from moving upward.</span>")
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, "<span class='warning'>\The [A] blocks you.</span>")
return 0
Move(destination)
return 1
. = 1
if(!allow_thrust(0.01, usr))
usr << "<span class='warning'>\The [src] is disabled.</span>"
/mob/eye/zMove(direction)
var/turf/destination = (direction == UP) ? GetAbove(src) : GetBelow(src)
if(destination)
forceMove(destination)
else
to_chat(usr, "<span class='notice'>There is nothing of interest in this direction.</span>")
/mob/eye/zMove(direction)
var/turf/destination = (direction == UP) ? GetAbove(src) : GetBelow(src)
if(destination)
setLoc(destination)
else
to_chat(usr, "<span class='notice'>There is nothing of interest in this direction.</span>")
/mob/proc/can_ztravel()
return 0
/mob/observer/can_ztravel()
return 1
/mob/living/carbon/human/can_ztravel()
if(incapacitated())
return 0
if(Allow_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(Allow_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 << "<span class='notice'>There is nothing of interest in this direction.</span>"
if(!below)
return
if(below.density)
usr << "<span class='warning'>You bump against \the [below].</span>"
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 << "<span class='warning'>\The [A] blocks you.</span>"
return
if(!A.CanPass(src, src.loc))
return FALSE
usr.Move(below)
usr << "<span class='notice'>You move downwards.</span>"
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
/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
var/damage = 10
apply_damage(rand(0, damage), BRUTE, "head")
apply_damage(rand(0, damage), BRUTE, "chest")
apply_damage(rand(0, damage), BRUTE, "l_leg")
apply_damage(rand(0, damage), BRUTE, "r_leg")
apply_damage(rand(0, damage), BRUTE, "l_arm")
apply_damage(rand(0, damage), BRUTE, "r_arm")
weakened = max(weakened,2)
updatehealth()
+11 -4
View File
@@ -192,7 +192,6 @@ obj/machinery/atmospherics/pipe/zpipe/up/scrubbers
name = "upwards scrubbers pipe"
desc = "A scrubbers pipe segment to connect upwards."
connect_types = CONNECT_TYPE_SCRUBBER
layer = 2.38
icon_connect_type = "-scrubbers"
color = PIPE_COLOR_RED
@@ -201,7 +200,6 @@ obj/machinery/atmospherics/pipe/zpipe/up/supply
name = "upwards supply pipe"
desc = "A supply pipe segment to connect upwards."
connect_types = CONNECT_TYPE_SUPPLY
layer = 2.39
icon_connect_type = "-supply"
color = PIPE_COLOR_BLUE
@@ -210,7 +208,6 @@ obj/machinery/atmospherics/pipe/zpipe/down/scrubbers
name = "downwards scrubbers pipe"
desc = "A scrubbers pipe segment to connect downwards."
connect_types = CONNECT_TYPE_SCRUBBER
layer = 2.38
icon_connect_type = "-scrubbers"
color = PIPE_COLOR_RED
@@ -219,6 +216,16 @@ obj/machinery/atmospherics/pipe/zpipe/down/supply
name = "downwards supply pipe"
desc = "A supply pipe segment to connect downwards."
connect_types = CONNECT_TYPE_SUPPLY
layer = 2.39
icon_connect_type = "-supply"
color = PIPE_COLOR_BLUE
// Colored misc. pipes
obj/machinery/atmospherics/pipe/zpipe/up/cyan
color = PIPE_COLOR_CYAN
obj/machinery/atmospherics/pipe/zpipe/down/cyan
color = PIPE_COLOR_CYAN
obj/machinery/atmospherics/pipe/zpipe/up/red
color = PIPE_COLOR_RED
obj/machinery/atmospherics/pipe/zpipe/down/red
color = PIPE_COLOR_RED
+100 -31
View File
@@ -4,54 +4,123 @@
/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 << "<span class='notice'>\The [src] is incomplete and can't be climbed.</span>"
var/obj/structure/ladder/target_ladder = getTargetLadder(M)
if(!target_ladder)
return
if(!M.Move(get_turf(src)))
to_chat(M, "<span class='notice'>You fail to reach \the [src].</span>")
return
var/direction = target_ladder == target_up ? "up" : "down"
M.visible_message("<span class='notice'>\The [M] begins climbing [direction] \the [src]!</span>",
"You begin climbing [direction] \the [src]!",
"You hear the grunting and clanging of a metal ladder being used.")
target_ladder.audible_message("<span class='notice'>You hear something coming [direction] \the [src]</span>")
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, "<span class='notice'>\The [src] is incomplete and can't be climbed.</span>")
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 << "<span class='notice'>\A [A] is blocking \the [src].</span>"
return
if(!M.may_climb_ladders(src))
return
M.visible_message("<span class='notice'>\A [M] climbs [icon_state == "ladderup" ? "up" : "down"] \a [src]!</span>",
"You climb [icon_state == "ladderup" ? "up" : "down"] \the [src]!",
"You hear the grunting and clanging of a metal ladder being used.")
M.Move(T)
switch(direction)
if("Up")
return target_up
if("Down")
return target_down
else
return target_down || target_up
CanPass(obj/mover, turf/source, height, airflow)
return airflow || !density
/mob/proc/may_climb_ladders(var/ladder)
if(!Adjacent(ladder))
to_chat(src, "<span class='warning'>You need to be next to \the [ladder] to start climbing.</span>")
return FALSE
if(incapacitated())
to_chat(src, "<span class='warning'>You are physically unable to climb \the [ladder].</span>")
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, "<span class='notice'>\The [A] is blocking \the [src].</span>")
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"
/obj/structure/stairs
name = "Stairs"
+69 -71
View File
@@ -1,88 +1,76 @@
/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
layer = 0
icon_state = ""
plane = PLANE_SPACE_BACKGROUND
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()
..()
update()
/turf/simulated/open/proc/update()
below = GetBelow(src)
ASSERT(HasBelow(z))
levelupdate()
for(var/atom/movable/A in src)
A.fall()
update_icon()
/turf/simulated/open/update_dirt()
return 0
/turf/simulated/open/Entered(var/atom/movable/mover)
// only fall down in defined areas (read: areas with artificial gravitiy)
if(!istype(below)) //make sure that there is actually something below
below = GetBelow(src)
if(!below)
return
// No gravity in space, apparently.
var/area/area = get_area(src)
if(area.name == "Space")
return
// Prevent pipes from falling into the void... if there is a pipe to support it.
if(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, "head")
H.apply_damage(rand(0, damage), BRUTE, "chest")
H.apply_damage(rand(0, damage), BRUTE, "l_leg")
H.apply_damage(rand(0, damage), BRUTE, "r_leg")
H.apply_damage(rand(0, damage), BRUTE, "l_arm")
H.apply_damage(rand(0, damage), BRUTE, "r_arm")
H.weakened = max(H.weakened,2)
H.updatehealth()
..()
mover.fall()
// override to make sure nothing is hidden
/turf/simulated/open/levelupdate()
for(var/obj/O in src)
O.hide(0)
// Straight copy from space.
/turf/simulated/open/update_icon()
if(below)
underlays = list(image(icon = below.icon, icon_state = below.icon_state))
var/list/noverlays = list()
if(!istype(below,/turf/space))
noverlays += image(icon =icon, icon_state = "empty", layer = 2.45)
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.45)
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.45)
I.pixel_x = S.pixel_x
I.pixel_y = S.pixel_y
noverlays += I
overlays = noverlays
/turf/simulated/open/attackby(obj/item/C as obj, mob/user as mob)
if (istype(C, /obj/item/stack/rods))
var/obj/structure/lattice/L = locate(/obj/structure/lattice, src)
@@ -90,12 +78,12 @@
return
var/obj/item/stack/rods/R = C
if (R.use(1))
user << "<span class='notice'>Constructing support lattice ...</span>"
to_chat(user, "<span class='notice'>You lay down the support lattice.</span>")
playsound(src, 'sound/weapons/Genhit.ogg', 50, 1)
ReplaceWithLattice()
new /obj/structure/lattice(locate(src.x, src.y, src.z))
return
if (istype(C, /obj/item/stack/tile/floor))
if (istype(C, /obj/item/stack/tile))
var/obj/structure/lattice/L = locate(/obj/structure/lattice, src)
if(L)
var/obj/item/stack/tile/floor/S = C
@@ -107,5 +95,15 @@
ChangeTurf(/turf/simulated/floor/airless)
return
else
user << "<span class='warning'>The plating is going to need some support.</span>"
return
to_chat(user, "<span class='warning'>The plating is going to need some support.</span>")
//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