mirror of
https://github.com/PolarisSS13/Polaris.git
synced 2025-12-29 19:43:16 +00:00
Catwalks and Railings
Added catwalks and railings. Ported from Vorestation who ported them from Eris. Note, catwalks can be placed on plating (as is seen on the vorestation map Tether) and is done so here as well. However it doesn't seem like it is possible to build said catwalks on plating. Did not bother to adjust this at this time. Something to sort in the future. Adjusted SC station dmm to use both the railing and catwalks as well as a couple fixes for the floor tile adjustment in a earlier commit.
This commit is contained in:
82
code/game/objects/structures/catwalk.dm
Normal file
82
code/game/objects/structures/catwalk.dm
Normal file
@@ -0,0 +1,82 @@
|
||||
// Based on catwalk.dm from https://github.com/Endless-Horizon/CEV-Eris
|
||||
/obj/structure/catwalk
|
||||
layer = TURF_LAYER + 0.5
|
||||
icon = 'icons/turf/catwalks.dmi'
|
||||
icon_state = "catwalk"
|
||||
name = "catwalk"
|
||||
desc = "Cats really don't like these things."
|
||||
density = 0
|
||||
anchored = 1.0
|
||||
|
||||
/obj/structure/catwalk/initialize()
|
||||
for(var/obj/structure/catwalk/C in get_turf(src))
|
||||
if(C != src)
|
||||
warning("Duplicate [type] in [loc] ([x], [y], [z])")
|
||||
qdel(C)
|
||||
update_icon()
|
||||
|
||||
/obj/structure/catwalk/Destroy()
|
||||
var/turf/location = loc
|
||||
. = ..()
|
||||
for(var/obj/structure/catwalk/L in orange(location, 1))
|
||||
L.update_icon()
|
||||
|
||||
/obj/structure/catwalk/update_icon()
|
||||
var/connectdir = 0
|
||||
for(var/direction in cardinal)
|
||||
if(locate(/obj/structure/catwalk, get_step(src, direction)))
|
||||
connectdir |= direction
|
||||
|
||||
//Check the diagonal connections for corners, where you have, for example, connections both north and east. In this case it checks for a north-east connection to determine whether to add a corner marker or not.
|
||||
var/diagonalconnect = 0 //1 = NE; 2 = SE; 4 = NW; 8 = SW
|
||||
//NORTHEAST
|
||||
if(connectdir & NORTH && connectdir & EAST)
|
||||
if(locate(/obj/structure/catwalk, get_step(src, NORTHEAST)))
|
||||
diagonalconnect |= 1
|
||||
//SOUTHEAST
|
||||
if(connectdir & SOUTH && connectdir & EAST)
|
||||
if(locate(/obj/structure/catwalk, get_step(src, SOUTHEAST)))
|
||||
diagonalconnect |= 2
|
||||
//NORTHWEST
|
||||
if(connectdir & NORTH && connectdir & WEST)
|
||||
if(locate(/obj/structure/catwalk, get_step(src, NORTHWEST)))
|
||||
diagonalconnect |= 4
|
||||
//SOUTHWEST
|
||||
if(connectdir & SOUTH && connectdir & WEST)
|
||||
if(locate(/obj/structure/catwalk, get_step(src, SOUTHWEST)))
|
||||
diagonalconnect |= 8
|
||||
|
||||
icon_state = "catwalk[connectdir]-[diagonalconnect]"
|
||||
|
||||
|
||||
/obj/structure/catwalk/ex_act(severity)
|
||||
switch(severity)
|
||||
if(1.0)
|
||||
qdel(src)
|
||||
if(2.0)
|
||||
qdel(src)
|
||||
return
|
||||
|
||||
/obj/structure/catwalk/attackby(obj/item/C as obj, mob/user as mob)
|
||||
if (istype(C, /obj/item/weapon/weldingtool))
|
||||
var/obj/item/weapon/weldingtool/WT = C
|
||||
if(WT.isOn())
|
||||
if(WT.remove_fuel(0, user))
|
||||
to_chat(user, "<span class='notice'>Slicing lattice joints ...</span>")
|
||||
new /obj/item/stack/rods(src.loc)
|
||||
new /obj/item/stack/rods(src.loc)
|
||||
new /obj/structure/lattice(src.loc)
|
||||
qdel(src)
|
||||
return ..()
|
||||
|
||||
/obj/structure/catwalk/Crossed()
|
||||
. = ..()
|
||||
if(isliving(usr))
|
||||
playsound(src, pick('sound/effects/footstep/catwalk1.ogg', 'sound/effects/footstep/catwalk2.ogg', 'sound/effects/footstep/catwalk3.ogg', 'sound/effects/footstep/catwalk4.ogg', 'sound/effects/footstep/catwalk5.ogg'), 25, 1)
|
||||
|
||||
/obj/structure/catwalk/CheckExit(atom/movable/O, turf/target)
|
||||
if(O.checkpass(PASSGRILLE))
|
||||
return 1
|
||||
if(target && target.z < src.z)
|
||||
return 0
|
||||
return 1
|
||||
@@ -67,7 +67,18 @@
|
||||
user << "<span class='notice'>Slicing lattice joints ...</span>"
|
||||
new /obj/item/stack/rods(src.loc)
|
||||
qdel(src)
|
||||
|
||||
return
|
||||
// VOREStation Edit - Added Catwalks
|
||||
if (istype(C, /obj/item/stack/rods))
|
||||
var/obj/item/stack/rods/R = C
|
||||
if(R.use(2))
|
||||
user << "<span class='notice'>You start connecting \the [R.name] to \the [src.name] ...</span>"
|
||||
if(do_after(user, 5 SECONDS))
|
||||
src.alpha = 0 // Note: I don't know why this is set, Eris did it, just trusting for now. ~Leshana
|
||||
new /obj/structure/catwalk(src.loc)
|
||||
qdel(src)
|
||||
return
|
||||
// VOREStation Edit End
|
||||
return
|
||||
|
||||
/obj/structure/lattice/proc/updateOverlays()
|
||||
|
||||
319
code/game/objects/structures/railing.dm
Normal file
319
code/game/objects/structures/railing.dm
Normal file
@@ -0,0 +1,319 @@
|
||||
// Based on railing.dmi from https://github.com/Endless-Horizon/CEV-Eris
|
||||
/obj/structure/railing
|
||||
name = "railing"
|
||||
desc = "A standard steel railing. Play stupid games win stupid prizes."
|
||||
icon = 'icons/obj/railing.dmi'
|
||||
density = 1
|
||||
throwpass = 1
|
||||
climbable = 1
|
||||
layer = 3.2 //Just above doors
|
||||
anchored = 1
|
||||
flags = ON_BORDER
|
||||
icon_state = "railing0"
|
||||
var/broken = FALSE
|
||||
var/health = 70
|
||||
var/maxhealth = 70
|
||||
var/check = 0
|
||||
|
||||
/obj/structure/railing/New(loc, constructed = 0)
|
||||
..()
|
||||
// TODO - "constructed" is not passed to us. We need to find a way to do this safely.
|
||||
if (constructed) // player-constructed railings
|
||||
anchored = 0
|
||||
if(climbable)
|
||||
verbs += /obj/structure/proc/climb_on
|
||||
|
||||
/obj/structure/railing/initialize()
|
||||
..()
|
||||
if(src.anchored)
|
||||
update_icon(0)
|
||||
|
||||
/obj/structure/railing/Destroy()
|
||||
var/turf/location = loc
|
||||
. = ..()
|
||||
for(var/obj/structure/railing/R in orange(location, 1))
|
||||
R.update_icon()
|
||||
|
||||
/obj/structure/railing/CanPass(atom/movable/mover, turf/target, height=0, air_group=0)
|
||||
if(!mover)
|
||||
return 1
|
||||
if(istype(mover) && mover.checkpass(PASSTABLE))
|
||||
return 1
|
||||
if(get_dir(loc, target) == dir)
|
||||
return !density
|
||||
else
|
||||
return 1
|
||||
|
||||
/obj/structure/railing/examine(mob/user)
|
||||
. = ..()
|
||||
if(health < maxhealth)
|
||||
switch(health / maxhealth)
|
||||
if(0.0 to 0.5)
|
||||
to_chat(user, "<span class='warning'>It looks severely damaged!</span>")
|
||||
if(0.25 to 0.5)
|
||||
to_chat(user, "<span class='warning'>It looks damaged!</span>")
|
||||
if(0.5 to 1.0)
|
||||
to_chat(user, "<span class='notice'>It has a few scrapes and dents.</span>")
|
||||
|
||||
/obj/structure/railing/proc/take_damage(amount)
|
||||
health -= amount
|
||||
if(health <= 0)
|
||||
visible_message("<span class='warning'>\The [src] breaks down!</span>")
|
||||
playsound(loc, 'sound/effects/grillehit.ogg', 50, 1)
|
||||
new /obj/item/stack/rods(get_turf(usr))
|
||||
qdel(src)
|
||||
|
||||
/obj/structure/railing/proc/NeighborsCheck(var/UpdateNeighbors = 1)
|
||||
check = 0
|
||||
//if (!anchored) return
|
||||
var/Rturn = turn(src.dir, -90)
|
||||
var/Lturn = turn(src.dir, 90)
|
||||
|
||||
for(var/obj/structure/railing/R in src.loc)
|
||||
if ((R.dir == Lturn) && R.anchored)
|
||||
check |= 32
|
||||
if (UpdateNeighbors)
|
||||
R.update_icon(0)
|
||||
if ((R.dir == Rturn) && R.anchored)
|
||||
check |= 2
|
||||
if (UpdateNeighbors)
|
||||
R.update_icon(0)
|
||||
|
||||
for (var/obj/structure/railing/R in get_step(src, Lturn))
|
||||
if ((R.dir == src.dir) && R.anchored)
|
||||
check |= 16
|
||||
if (UpdateNeighbors)
|
||||
R.update_icon(0)
|
||||
for (var/obj/structure/railing/R in get_step(src, Rturn))
|
||||
if ((R.dir == src.dir) && R.anchored)
|
||||
check |= 1
|
||||
if (UpdateNeighbors)
|
||||
R.update_icon(0)
|
||||
|
||||
for (var/obj/structure/railing/R in get_step(src, (Lturn + src.dir)))
|
||||
if ((R.dir == Rturn) && R.anchored)
|
||||
check |= 64
|
||||
if (UpdateNeighbors)
|
||||
R.update_icon(0)
|
||||
for (var/obj/structure/railing/R in get_step(src, (Rturn + src.dir)))
|
||||
if ((R.dir == Lturn) && R.anchored)
|
||||
check |= 4
|
||||
if (UpdateNeighbors)
|
||||
R.update_icon(0)
|
||||
|
||||
/obj/structure/railing/update_icon(var/UpdateNeighgors = 1)
|
||||
NeighborsCheck(UpdateNeighgors)
|
||||
//layer = (dir == SOUTH) ? FLY_LAYER : initial(layer) // Vorestation edit because wtf does this even do
|
||||
overlays.Cut()
|
||||
if (!check || !anchored)//|| !anchored
|
||||
icon_state = "railing0"
|
||||
else
|
||||
icon_state = "railing1"
|
||||
if (check & 32)
|
||||
overlays += image ('icons/obj/railing.dmi', src, "corneroverlay")
|
||||
if ((check & 16) || !(check & 32) || (check & 64))
|
||||
overlays += image ('icons/obj/railing.dmi', src, "frontoverlay_l")
|
||||
if (!(check & 2) || (check & 1) || (check & 4))
|
||||
overlays += image ('icons/obj/railing.dmi', src, "frontoverlay_r")
|
||||
if(check & 4)
|
||||
switch (src.dir)
|
||||
if (NORTH)
|
||||
overlays += image ('icons/obj/railing.dmi', src, "mcorneroverlay", pixel_x = 32)
|
||||
if (SOUTH)
|
||||
overlays += image ('icons/obj/railing.dmi', src, "mcorneroverlay", pixel_x = -32)
|
||||
if (EAST)
|
||||
overlays += image ('icons/obj/railing.dmi', src, "mcorneroverlay", pixel_y = -32)
|
||||
if (WEST)
|
||||
overlays += image ('icons/obj/railing.dmi', src, "mcorneroverlay", pixel_y = 32)
|
||||
|
||||
/obj/structure/railing/verb/rotate()
|
||||
set name = "Rotate Railing Counter-Clockwise"
|
||||
set category = "Object"
|
||||
set src in oview(1)
|
||||
|
||||
if(usr.incapacitated())
|
||||
return 0
|
||||
|
||||
if(anchored)
|
||||
to_chat(usr, "It is fastened to the floor therefore you can't rotate it!")
|
||||
return 0
|
||||
|
||||
set_dir(turn(dir, 90))
|
||||
update_icon()
|
||||
return
|
||||
|
||||
/obj/structure/railing/verb/revrotate()
|
||||
set name = "Rotate Railing Clockwise"
|
||||
set category = "Object"
|
||||
set src in oview(1)
|
||||
|
||||
if(usr.incapacitated())
|
||||
return 0
|
||||
|
||||
if(anchored)
|
||||
to_chat(usr, "It is fastened to the floor therefore you can't rotate it!")
|
||||
return 0
|
||||
|
||||
set_dir(turn(dir, -90))
|
||||
update_icon()
|
||||
return
|
||||
|
||||
/obj/structure/railing/verb/flip() // This will help push railing to remote places, such as open space turfs
|
||||
set name = "Flip Railing"
|
||||
set category = "Object"
|
||||
set src in oview(1)
|
||||
|
||||
if(usr.incapacitated())
|
||||
return 0
|
||||
|
||||
if(anchored)
|
||||
to_chat(usr, "It is fastened to the floor therefore you can't flip it!")
|
||||
return 0
|
||||
|
||||
var/obj/occupied = neighbor_turf_impassable()
|
||||
if(occupied)
|
||||
to_chat(usr, "You can't flip \the [src] because there's \a [occupied] in the way.")
|
||||
return 0
|
||||
|
||||
src.loc = get_step(src, src.dir)
|
||||
set_dir(turn(dir, 180))
|
||||
update_icon()
|
||||
return
|
||||
|
||||
/obj/structure/railing/CheckExit(atom/movable/O as mob|obj, target as turf)
|
||||
if(istype(O) && O.checkpass(PASSTABLE))
|
||||
return 1
|
||||
if(get_dir(O.loc, target) == dir)
|
||||
return 0
|
||||
return 1
|
||||
|
||||
/obj/structure/railing/attackby(obj/item/W as obj, mob/user as mob)
|
||||
// Dismantle
|
||||
if(istype(W, /obj/item/weapon/wrench) && !anchored)
|
||||
playsound(src.loc, 'sound/items/Ratchet.ogg', 50, 1)
|
||||
if(do_after(user, 20, src))
|
||||
user.visible_message("<span class='notice'>\The [user] dismantles \the [src].</span>", "<span class='notice'>You dismantle \the [src].</span>")
|
||||
new /obj/item/stack/material/steel(get_turf(usr), 2)
|
||||
qdel(src)
|
||||
return
|
||||
|
||||
// Repair
|
||||
if(health < maxhealth && istype(W, /obj/item/weapon/weldingtool))
|
||||
var/obj/item/weapon/weldingtool/F = W
|
||||
if(F.welding)
|
||||
playsound(src.loc, 'sound/items/Welder.ogg', 50, 1)
|
||||
if(do_after(user, 20, src))
|
||||
user.visible_message("<span class='notice'>\The [user] repairs some damage to \the [src].</span>", "<span class='notice'>You repair some damage to \the [src].</span>")
|
||||
health = min(health+(maxhealth/5), maxhealth) // 20% repair per application
|
||||
return
|
||||
|
||||
// Install
|
||||
if(istype(W, /obj/item/weapon/screwdriver))
|
||||
user.visible_message(anchored ? "<span class='notice'>\The [user] begins unscrewing \the [src].</span>" : "<span class='notice'>\The [user] begins fasten \the [src].</span>" )
|
||||
playsound(loc, 'sound/items/Screwdriver.ogg', 75, 1)
|
||||
if(do_after(user, 10, src))
|
||||
to_chat(user, (anchored ? "<span class='notice'>You have unfastened \the [src] from the floor.</span>" : "<span class='notice'>You have fastened \the [src] to the floor.</span>"))
|
||||
anchored = !anchored
|
||||
update_icon()
|
||||
return
|
||||
|
||||
// Handle harm intent grabbing/tabling.
|
||||
if(istype(W, /obj/item/weapon/grab) && get_dist(src,user)<2)
|
||||
var/obj/item/weapon/grab/G = W
|
||||
if (istype(G.affecting, /mob/living))
|
||||
var/mob/living/M = G.affecting
|
||||
var/obj/occupied = turf_is_crowded()
|
||||
if(occupied)
|
||||
to_chat(user, "<span class='danger'>There's \a [occupied] in the way.</span>")
|
||||
return
|
||||
if (G.state < 2)
|
||||
if(user.a_intent == I_HURT)
|
||||
if (prob(15)) M.Weaken(5)
|
||||
M.apply_damage(8,def_zone = "head")
|
||||
take_damage(8)
|
||||
visible_message("<span class='danger'>[G.assailant] slams [G.affecting]'s face against \the [src]!</span>")
|
||||
playsound(loc, 'sound/effects/grillehit.ogg', 50, 1)
|
||||
else
|
||||
to_chat(user, "<span class='danger'>You need a better grip to do that!</span>")
|
||||
return
|
||||
else
|
||||
if (get_turf(G.affecting) == get_turf(src))
|
||||
G.affecting.forceMove(get_step(src, src.dir))
|
||||
else
|
||||
G.affecting.forceMove(get_turf(src))
|
||||
G.affecting.Weaken(5)
|
||||
visible_message("<span class='danger'>[G.assailant] throws [G.affecting] over \the [src]!</span>")
|
||||
qdel(W)
|
||||
return
|
||||
|
||||
else
|
||||
playsound(loc, 'sound/effects/grillehit.ogg', 50, 1)
|
||||
take_damage(W.force)
|
||||
|
||||
return ..()
|
||||
|
||||
/obj/structure/railing/ex_act(severity)
|
||||
switch(severity)
|
||||
if(1.0)
|
||||
qdel(src)
|
||||
return
|
||||
if(2.0)
|
||||
qdel(src)
|
||||
return
|
||||
if(3.0)
|
||||
qdel(src)
|
||||
return
|
||||
else
|
||||
return
|
||||
|
||||
// Duplicated from structures.dm, but its a bit different.
|
||||
/obj/structure/railing/do_climb(var/mob/living/user)
|
||||
if(!can_climb(user))
|
||||
return
|
||||
|
||||
usr.visible_message("<span class='warning'>[user] starts climbing onto \the [src]!</span>")
|
||||
climbers |= user
|
||||
|
||||
if(!do_after(user,(issmall(user) ? 20 : 34)))
|
||||
climbers -= user
|
||||
return
|
||||
|
||||
if(!can_climb(user, post_climb_check=1))
|
||||
climbers -= user
|
||||
return
|
||||
|
||||
if(get_turf(user) == get_turf(src))
|
||||
usr.forceMove(get_step(src, src.dir))
|
||||
else
|
||||
usr.forceMove(get_turf(src))
|
||||
|
||||
usr.visible_message("<span class='warning'>[user] climbed over \the [src]!</span>")
|
||||
if(!anchored) take_damage(maxhealth) // Fatboy
|
||||
climbers -= user
|
||||
|
||||
/obj/structure/railing/can_climb(var/mob/living/user, post_climb_check=0)
|
||||
if(!..())
|
||||
return 0
|
||||
|
||||
// Normal can_climb() handles climbing from adjacent turf onto our turf. But railings also allow climbing
|
||||
// from our turf onto an adjacent! If that is the case we need to do checks for that too...
|
||||
if(get_turf(user) == get_turf(src))
|
||||
var/obj/occupied = neighbor_turf_impassable()
|
||||
if(occupied)
|
||||
to_chat(user, "<span class='danger'>You can't climb there, there's \a [occupied] in the way.</span>")
|
||||
return 0
|
||||
return 1
|
||||
|
||||
// TODO - This here might require some investigation
|
||||
/obj/structure/proc/neighbor_turf_impassable()
|
||||
var/turf/T = get_step(src, src.dir)
|
||||
if(!T || !istype(T))
|
||||
return 0
|
||||
if(T.density == 1)
|
||||
return T
|
||||
for(var/obj/O in T.contents)
|
||||
if(istype(O,/obj/structure))
|
||||
var/obj/structure/S = O
|
||||
if(S.climbable) continue
|
||||
if(O && O.density && !(O.flags & ON_BORDER && !(turn(O.dir, 180) & dir)))
|
||||
return O
|
||||
Reference in New Issue
Block a user