mirror of
https://github.com/CHOMPstation/CHOMPstation.git
synced 2026-07-18 18:42:59 +01:00
Ported Eris's "railings"
* Railings are an ON_BORDER object that looks like a railing; you can throw and reach across it, but it stops you from falling into holes or whatever. * Mobs can climb over them (or throw other mobs over them!) * They are construtable/deconstructable. * Smoothly auto-joining sprites to look like a railing. * Changes from Eris: Converted << to to_chat(), Desnowflaked some code, Fixed being able to climb over when windows are in the way.
This commit is contained in:
@@ -0,0 +1,318 @@
|
||||
// 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()
|
||||
for(var/obj/structure/railing/R in oview(src, 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)
|
||||
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.")
|
||||
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