Z-Level Falling (#7469)

Falling down a Z-Level without rolling now has a chance to dislocate the limb you land on.
This commit is contained in:
Geeves
2019-12-16 21:15:03 +02:00
committed by Erki
parent f014fddf01
commit 8516a4fbe4
2 changed files with 89 additions and 31 deletions
+83 -31
View File
@@ -40,18 +40,18 @@
// Check if we can actually travel a Z-level.
if (!can_ztravel(direction))
to_chat(src, "<span class='warning'>You lack means of travel in that direction.</span>")
to_chat(src, span("warning", "You lack means of travel in that direction."))
return FALSE
var/turf/destination = (direction == UP) ? GetAbove(src) : GetBelow(src)
if(!destination)
to_chat(src, "<span class='notice'>There is nothing of interest in this direction.</span>")
to_chat(src, span("notice", "There is nothing of interest in this direction."))
return FALSE
var/turf/start = get_turf(src)
if(!start.CanZPass(src, direction))
to_chat(src, "<span class='warning'>\The [start] is in the way.</span>")
to_chat(src, span("warning", "\The [start] is in the way."))
return FALSE
if(!destination.CanZPass(src, direction))
@@ -63,13 +63,13 @@
// If we want to move up,but the current area has gravity. Invoke CanAvoidGravity()
// to check if this move is possible.
if(direction == UP && area.has_gravity() && !CanAvoidGravity())
to_chat(src, "<span class='warning'>Gravity stops you from moving upward.</span>")
to_chat(src, span("warning", "Gravity stops you from moving upward."))
return FALSE
// Check for blocking atoms at the destination.
for (var/atom/A in destination)
if (!A.CanPass(src, start, 1.5, 0))
to_chat(src, "<span class='warning'>\The [A] blocks you.</span>")
to_chat(src, span("warning", "\The [A] blocks you."))
return FALSE
// Actually move.
@@ -98,21 +98,21 @@
if(destination)
setLoc(destination)
else
to_chat(owner, "<span class='notice'>There is nothing of interest in this direction.</span>")
to_chat(owner, span("notice", "There is nothing of interest in this direction."))
/mob/abstract/observer/zMove(direction)
var/turf/destination = (direction == UP) ? GetAbove(src) : GetBelow(src)
if(destination)
forceMove(destination)
else
to_chat(src, "<span class='notice'>There is nothing of interest in this direction.</span>")
to_chat(src, span("notice", "There is nothing of interest in this direction."))
/mob/living/carbon/human/bst/zMove(direction)
var/turf/destination = (direction == UP) ? GetAbove(src) : GetBelow(src)
if(destination)
forceMove(destination)
else
to_chat(src, "<span class='notice'>There is nothing of interest in this direction.</span>")
to_chat(src, span("notice", "There is nothing of interest in this direction."))
/**
* An initial check for Z-level travel. Called relatively early in mob/proc/zMove.
@@ -154,16 +154,16 @@
return
if(destination.density)
to_chat(src, "<span class='notice'>There is something obstructing your destination!</span>")
to_chat(src, span("notice", "There is something obstructing your destination!"))
return
for(var/obj/O in destination)
if(O.density)
to_chat(src, "<span class='notice'>There is something obstructing your destination!</span>")
to_chat(src, span("notice", "There is something obstructing your destination!"))
return
visible_message("<span class='notice'>The [src] begins to climb [(direction == UP) ? "upwards" : "downwards"].</span>",
"<span class='notice'>You begin to climb [(direction == UP) ? "upwards" : "downwards"].</span>")
visible_message(span("notice", "The [src] begins to climb [(direction == UP) ? "upwards" : "downwards"]."),
span("notice", "You begin to climb [(direction == UP) ? "upwards" : "downwards"]."))
var/climb_chance = 50
var/climb_speed = 45 SECONDS
var/will_succeed = FALSE
@@ -193,13 +193,13 @@
if(do_after(src, climb_speed, extra_checks = CALLBACK(src, .proc/climb_check, will_succeed, climb_chance, climb_speed, direction, destination)))
if(will_succeed)
visible_message("<span class='noticed'>\The [src] climbs [(direction == UP) ? "upwards" : "downwards"].</span>",
"<span class='noticed'>You climb [(direction == UP) ? "upwards" : "downwards"].</span>")
visible_message(span("notice", "\The [src] climbs [(direction == UP) ? "upwards" : "downwards"]."),
span("notice", "You climb [(direction == UP) ? "upwards" : "downwards"]."))
forceMove(destination)
return
else
visible_message("<span class='warning'>\The [src] slips and falls as they climb [(direction == UP) ? "upwards" : "downwards"]!</span>",
"<span class='danger'>You slip and fall as you climb [(direction == UP) ? "upwards" : "downwards"]!</span>")
visible_message(span("warning", "\The [src] slips and falls as they climb [(direction == UP) ? "upwards" : "downwards"]!"),
span("danger", "You slip and fall as you climb [(direction == UP) ? "upwards" : "downwards"]!"))
if(direction == DOWN)
Move(destination)
fall_impact(1, damage_mod = min(1, max(0.2, ((100-climb_chance)/100) - 0.2)))
@@ -208,8 +208,8 @@
if((last_special < world.time) && !success) //if you will succeed you can't fail
last_special = world.time + speed/10
if(prob(100 - climb_chance)) //The worse you are the sooner you'll fail.
visible_message("<span class='warning'>\The [src] slips and falls as they climb [(direction == UP) ? "upwards" : "downwards"]!</span>",
"<span class='danger'>You slip and fall as you climb [(direction == UP) ? "upwards" : "downwards"]!</span>")
visible_message(span("warning", "\The [src] slips and falls as they climb [(direction == UP) ? "upwards" : "downwards"]!"),
span("danger", "You slip and fall as you climb [(direction == UP) ? "upwards" : "downwards"]!"))
if(direction == DOWN)
Move(destination)
fall_impact(1, damage_mod = min(1, max(0.2, ((100-climb_chance)/100) - 0.2)))
@@ -379,12 +379,12 @@
/mob/living/heavy_vehicle/fall_through()
var/obj/structure/lattice/L = locate() in loc
if (L)
visible_message("<span class='danger'>\The [src] crushes \the [L] with its weight!</span>")
visible_message(span("danger", "\The [src] crushes \the [L] with its weight!"))
qdel(L)
var/obj/structure/stairs/S = locate() in loc
if (S)
visible_message("<span class='danger'>\The [src] crushes \the [S] with its weight!</span>")
visible_message(span("danger", "\The [src] crushes \the [S] with its weight!"))
qdel(S)
/**
* Invoked when an atom has landed on a tile through which they can no longer fall.
@@ -451,8 +451,8 @@
if (istype(rig))
for (var/obj/item/rig_module/actuators/A in rig.installed_modules)
if (A.active && rig.check_power_cost(src, 10, A, 0))
visible_message("<span class='notice'>\The [src] lands flawlessly with \his [rig].</span>",
"<span class='notice'>You hear an electric <i>*whirr*</i> right after the slam!</span>")
visible_message(span("notice", "\The [src] lands flawlessly with \his [rig]."),
span("notice", "You hear an electric <i>*whirr*</i> right after the slam!"))
return FALSE
var/combat_roll = 1
@@ -460,8 +460,8 @@
combat_roll = 0.7 //If you're sleeping, you take less damage because your body is less rigid. It's science 'n shit.
if(!sleeping)
combat_roll = 0.2 //Combat roll!
visible_message("<span class='notice'>\The [src] tucks into a roll as they hit \the [loc]!</span>",
"<span class='notice'>You tuck into a roll as you hit \the [loc], minimizing damage!</span>")
visible_message(span("notice", "\The [src] tucks into a roll as they hit \the [loc]!"),
span("notice", "You tuck into a roll as you hit \the [loc], minimizing damage!"))
var/z_velocity = 5*(levels_fallen**2)
var/damage = (((40 * species.fall_mod) + z_velocity) + rand(-20,20)) * combat_roll * damage_mod
@@ -486,8 +486,30 @@
if(prob(50))
apply_damage(groin_damage, BRUTE, BP_GROIN)
visible_message("<span class='warning'>\The [src] falls and lands directly on their legs!</span>",
"<span class='danger'>You land on your feet, and the impact brings you to your knees.</span>")
visible_message(span("warning", "\The [src] falls and lands directly on their legs!"),
span("danger", "You land on your feet, and the impact brings you to your knees."))
if(prob(20))
var/obj/item/organ/external/l_foot = get_organ("l_foot")
var/obj/item/organ/external/r_foot = get_organ("r_foot")
if(prob(50) && l_foot)
fall_message("left ankle", "bends unnaturally")
l_foot.dislocate(TRUE)
else if(r_foot)
fall_message("right ankle", "bends unnaturally")
r_foot.dislocate(TRUE)
else if(prob(15))
var/obj/item/organ/external/l_leg = get_organ("l_leg")
var/obj/item/organ/external/r_leg = get_organ("r_leg")
if(prob(50) && l_leg)
fall_message("left knee", "caves in")
l_leg.dislocate(TRUE)
else if(r_leg)
fall_message("right knee", "caves in")
l_leg.dislocate(TRUE)
limb_damage = left_damage + right_damage + leftf_damage + rightf_damage + groin_damage
@@ -507,14 +529,40 @@
limb_damage = left_damage + right_damage + lefth_damage + righth_damage
visible_message("<span class='warning'>\The [src] falls and lands arms first!</span>",
"<span class='danger'>You brace your fall with your arms, hitting \the [loc] with a loud thud.</span>", "You hear a thud!")
visible_message(span("warning", "\The [src] falls and lands arms first!"),
span("danger", "You brace your fall with your arms, hitting \the [loc] with a loud thud."), "You hear a thud!")
if(prob(20))
var/obj/item/organ/external/l_hand = get_organ("l_hand")
var/obj/item/organ/external/r_hand = get_organ("r_hand")
if(prob(50) && l_hand)
fall_message("left wrist", "bends unnaturally")
l_hand.dislocate(TRUE)
else if(r_hand)
fall_message("right wrist", "bends unnaturally")
r_hand.dislocate(TRUE)
else if(prob(15))
var/obj/item/organ/external/l_arm = get_organ("l_arm")
var/obj/item/organ/external/r_arm = get_organ("r_arm")
if(prob(50) && l_arm)
fall_message("left elbow", "caves in")
l_arm.dislocate(TRUE)
else if(r_arm)
fall_message("right elbow", "caves in")
r_arm.dislocate(TRUE)
else if(prob(30) && combat_roll >= 1)//landed on their head
apply_damage(limb_damage, BRUTE, BP_HEAD)
visible_message("<span class='warning'>\The [src] falls and lands on their face!</span>",
"<span class='danger'>With a loud thud, you land on your head. Hard.</span>", "You hear a thud!")
var/obj/item/organ/external/head = get_organ("head")
if(prob(20) && head)
fall_message("jaw", "cracks loose")
head.dislocate(TRUE)
else
limb_damage = 0
if(combat_roll >= 0.5)
@@ -548,6 +596,10 @@
return TRUE
/mob/living/carbon/human/proc/fall_message(var/location, var/descriptor)
visible_message(span("warning", "There's a sickening popping noise as [src]'s [location] [descriptor]!"),
span("danger", "Grueling pain shoots through your mind as your [location] [descriptor]!"))
/mob/living/carbon/human/proc/post_fall_death_check()
if (stat == DEAD)
SSfeedback.IncrementSimpleStat("openturf_human_deaths")
@@ -647,8 +699,8 @@
else
L.apply_damage(damage, BRUTE)
L.visible_message("<span class='danger'>\The [L] had \the [src] fall onto \him!</span>",
"<span class='danger'>You had \the [src] fall onto you and strike you!</span>")
L.visible_message(span("danger", "\The [L] had \the [src] fall onto \him!"),
span("danger", "You had \the [src] fall onto you and strike you!"))
admin_attack_log((ismob(src) ? src : null), L, "fell onto", "was fallen on by", "fell ontop of")
@@ -660,7 +712,7 @@
. = ..()
if (.)
to_chat(src, "<span class='danger'>You fell ontop of \the [.]!</span>")
to_chat(src, span("danger", "You fell ontop of \the [.]!"))
/**
* Helper proc for customizing which attributes should be used in fall damage