mirror of
https://github.com/CHOMPStation2/CHOMPStation2.git
synced 2025-12-10 18:22:39 +00:00
Now certain weapons can strike faster or slower than usual. No weapons currently do this as this PR just lays the groundwork for that. The click delay can also be modified with traits. The slime agility modifier makes attacks happen 25% sooner. Adds debug test verb to display a weapon's DPS. It's really basic but should be sufficient for future force adjustments I might do in the future.
330 lines
9.7 KiB
Plaintext
330 lines
9.7 KiB
Plaintext
// 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(src))
|
|
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) // 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 (!can_touch(usr) || ismouse(usr))
|
|
return
|
|
|
|
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 (!can_touch(usr) || ismouse(usr))
|
|
return
|
|
|
|
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 (!can_touch(usr) || ismouse(usr))
|
|
return
|
|
|
|
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, W.usesound, 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, F.usesound, 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, W.usesound, 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)
|
|
user.setClickCooldown(user.get_attack_speed(W))
|
|
|
|
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
|