mirror of
https://github.com/VOREStation/VOREStation.git
synced 2026-05-17 20:30:46 +01:00
557ad96746
* Heavy Landing Added a new heavy landing trait (and hard fall var to other mobs) that cause the mob to take more damage, get weakened for longer and create some damage to the floor tiles (50% chance). Can not be taken with soft landing. Be the fatty you always meant to be. * Changed to a defined trait thing * Update code/modules/mob/living/carbon/human/species/species.dm Co-authored-by: Guti <32563288+TheCaramelion@users.noreply.github.com> * Update code/modules/multiz/movement.dm Co-authored-by: Guti <32563288+TheCaramelion@users.noreply.github.com> * Update code/modules/multiz/movement.dm Co-authored-by: Guti <32563288+TheCaramelion@users.noreply.github.com> --------- Co-authored-by: Guti <32563288+TheCaramelion@users.noreply.github.com> Co-authored-by: Cameron Lennox <killer65311@gmail.com>
319 lines
15 KiB
Plaintext
319 lines
15 KiB
Plaintext
|
|
/mob/living/handle_fall(var/turf/landing)
|
|
var/mob/living/drop_mob = locate(/mob/living, landing)
|
|
|
|
if(locate(/obj/structure/stairs) in landing)
|
|
for(var/atom/A in landing)
|
|
if(!A.CanPass(src, src.loc))
|
|
return FALSE
|
|
Move(landing)
|
|
if(isliving(src))
|
|
var/mob/living/L = src
|
|
if(L.pulling)
|
|
L.pulling.forceMove(landing)
|
|
return TRUE
|
|
|
|
for(var/obj/O in loc)
|
|
if(!O.CanFallThru(src, landing))
|
|
return TRUE
|
|
|
|
if(SEND_SIGNAL(src, COMSIG_LIVING_FALLING_DOWN, landing, drop_mob) & COMSIG_CANCEL_FALL)
|
|
return
|
|
|
|
if(drop_mob && drop_mob != src)
|
|
///Varible to tell if we take damage or not for falling.
|
|
var/safe_fall = FALSE
|
|
if(drop_mob.softfall || (isanimal(drop_mob) && drop_mob.mob_size <= MOB_SMALL))
|
|
safe_fall = TRUE
|
|
|
|
if(ishuman(drop_mob))
|
|
var/mob/living/carbon/human/H = drop_mob
|
|
if(H.species.soft_landing)
|
|
safe_fall = TRUE
|
|
|
|
forceMove(get_turf(drop_mob))
|
|
if(!safe_fall)
|
|
drop_mob.Weaken(8)
|
|
Weaken(8)
|
|
playsound(src, "punch", 25, 1, -1)
|
|
var/tdamage
|
|
for(var/i = 1 to 5) //Twice as less damage because cushioned fall, but both get damaged.
|
|
tdamage = rand(0, 5)
|
|
if(HAS_TRAIT(drop_mob, TRAIT_HEAVY_LANDING))
|
|
tdamage = tdamage * 1.5
|
|
drop_mob.adjustBruteLoss(tdamage)
|
|
adjustBruteLoss(tdamage)
|
|
drop_mob.updatehealth()
|
|
updatehealth()
|
|
if(HAS_TRAIT(drop_mob, TRAIT_HEAVY_LANDING))
|
|
drop_mob.visible_message(span_danger("\The [drop_mob] crashes down onto \the [src]!"))
|
|
else
|
|
drop_mob.visible_message(span_danger("\The [drop_mob] falls onto \the [src]!"))
|
|
else
|
|
drop_mob.visible_message(span_notice("\The [drop_mob] safely brushes past \the [src] as they land."))
|
|
|
|
// Then call parent to have us actually fall
|
|
return ..()
|
|
/mob/CheckFall(var/atom/movable/falling_atom)
|
|
return falling_atom.fall_impact(src)
|
|
|
|
/mob/observer/dead/CheckFall()
|
|
return
|
|
|
|
/mob/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 1
|
|
|
|
/turf/simulated/proc/climb_wall()
|
|
set name = "Climb Wall"
|
|
set desc = "Using nature's gifts or technology, scale that wall!"
|
|
set category = "Object"
|
|
set src in oview(1)
|
|
|
|
if(!isliving(usr)) return //Why would ghosts want to climb?
|
|
var/mob/living/L = usr
|
|
var/climbing_delay_min = L.climbing_delay
|
|
var/fall_chance = 0
|
|
var/drop_our_held = FALSE
|
|
var/nutrition_cost = 50 //Climbing up is harder!
|
|
|
|
//Checking if there's any point trying to climb
|
|
var/turf/above_wall = GetAbove(src)
|
|
if(L.nutrition <= nutrition_cost)
|
|
to_chat(L, span_warning("You [L.isSynthetic() ? "lack the energy" : "are too hungry"] for such strenous activities!"))
|
|
return
|
|
if(!above_wall) //No multiZ
|
|
to_chat(L, span_notice("There's nothing interesting over this cliff!"))
|
|
return
|
|
var/turf/above_mob = GetAbove(L) //Making sure we got headroom
|
|
if(!above_mob.CanZPass(L, UP))
|
|
to_chat(L, span_warning("\The [above_mob] blocks your way."))
|
|
return
|
|
if(above_wall.density) //We check density rather than type since some walls dont have a floor on top.
|
|
to_chat(L, span_warning("\The [above_wall] blocks your way."))
|
|
return
|
|
if(LAZYLEN(above_wall.contents) > 30) //We avoid checking the contents if it's too cluttered to avoid issues
|
|
to_chat(L, span_warning("\The [above_wall] is too cluttered to climb onto!"))
|
|
return
|
|
for(var/atom/A in above_wall.contents)
|
|
if(A.density)
|
|
to_chat(L, span_warning("\The [A.name] blocks your way!"))
|
|
return
|
|
|
|
//human mobs got species and can wear special equipment
|
|
//We give them some snowflake treatment as a consequence
|
|
if(ishuman(L))
|
|
var/permit_human = FALSE
|
|
var/mob/living/carbon/human/H = L
|
|
if(H.species.climbing_delay < H.climbing_delay)
|
|
climbing_delay_min = H.species.climbing_delay
|
|
var/list/gear = list(H.head, H.wear_mask, H.wear_suit, H.w_uniform,
|
|
H.gloves, H.shoes, H.belt, H.get_active_hand(), H.get_inactive_hand())
|
|
if(H.can_climb || H.species.can_climb)
|
|
permit_human = TRUE
|
|
for(var/obj/item/I in gear)
|
|
if(I.rock_climbing)
|
|
permit_human = TRUE
|
|
if(I.climbing_delay > climbing_delay_min)
|
|
climbing_delay_min = I.climbing_delay //We get the maximum possible speedup out of worn equipment
|
|
if(!permit_human)
|
|
var/sure = tgui_alert(H,"Are you sure you want to try without tools? It's VERY LIKELY \
|
|
you will fall and get hurt. More agile species might have better luck", "Second Thoughts", list("Bring it!", "Stay grounded"))
|
|
if(sure || sure == "Stay grounded") return
|
|
fall_chance = clamp(100 - H.species.agility, 40, 90) //This should be 80 for most species. Traceur would reduce to 10%, so clamping higher
|
|
//If not a human mob, must be simple or silicon. They got a var stored on their mob we can check
|
|
else if(!L.can_climb)
|
|
var/sure = tgui_alert(L,"Are you sure you want to try without tools? It's VERY LIKELY \
|
|
you will fall and get hurt. More agile species might have better luck", "Second Thoughts", list("Bring it!", "Stay grounded"))
|
|
if(!sure || sure == "Stay grounded") return
|
|
if(isrobot(L))
|
|
fall_chance = 80 // Robots get no mercy
|
|
else
|
|
fall_chance = 55 //Simple mobs do.
|
|
climbing_delay_min = 2
|
|
//Catslugs are a snowflake case because of references.
|
|
if(istype(L, /mob/living/simple_mob/vore/alienanimals/catslug))
|
|
var/obj/O = L.get_active_hand()
|
|
if(istype(O, /obj/item/material/twohanded/spear))
|
|
var/choice = tgui_alert(L, "Use your spear to climb faster? This will drop and break it!", "Scug Tactics", list("Yes!", "No"))
|
|
if(choice == "Yes!")
|
|
drop_our_held = TRUE
|
|
climbing_delay_min = 0.75
|
|
|
|
//We proceed with the actual climbing!
|
|
// ################### CLIMB TIME BELOW: #############################
|
|
// Climb time is 3.75 for scugs with spears (spear is dropped)
|
|
// Climb time is 5 for Master climbers, Vassilians, Well-geared humans
|
|
// Climb time is 9 for Tajara and Professional Climbers
|
|
// Climb time is 17.5 Seconds for amateur climbers
|
|
// Climb time is 20 seconds for scugs without a spear
|
|
// Climb time is 30 for gearless untrained people
|
|
var/climb_time = (5 * climbing_delay_min) SECONDS
|
|
if(fall_chance)
|
|
to_chat(L, span_warning("You begin climbing over \The [src]. Getting a grip is exceedingly difficult..."))
|
|
climb_time += 20 SECONDS
|
|
else
|
|
to_chat(L, span_notice("You begin climbing above \The [src]! "))
|
|
if(climbing_delay_min > 1.25)
|
|
climb_time += 10 SECONDS
|
|
if(climbing_delay_min > 1.0)
|
|
climb_time += 2.5 SECONDS
|
|
if(L.nutrition >= 100 && L.nutrition <= 200)
|
|
to_chat(L, span_notice("Climbing while [L.isSynthetic() ? "low on power" : "hungry"] slows you down"))
|
|
climb_time += 1 SECONDS
|
|
else if(L.nutrition >= nutrition_cost && L.nutrition <= 100)
|
|
to_chat(L, span_danger("You [L.isSynthetic() ? "lack enough power" : "are too hungry"] to climb safely!"))
|
|
climb_time +=3 SECONDS
|
|
if(fall_chance < 30)
|
|
fall_chance = 30
|
|
L.visible_message(message = span_infoplain(span_bold("[L]") + " begins to climb up on " + span_bold("\The [src]")), self_message = span_infoplain("You begin to clumb up on " + span_bold("\The [src]")), \
|
|
blind_message = span_infoplain("You hear the sounds of climbing!"), runemessage = "Tap Tap")
|
|
var/oops_time = world.time
|
|
var/grace_time = 4 SECONDS
|
|
to_chat(L, span_warning("If you get interrupted after [(grace_time / (1 SECOND))] seconds of climbing, you will fall and hurt yourself, beware!"))
|
|
if(do_after(L, climb_time, target = src))
|
|
if(prob(fall_chance))
|
|
L.forceMove(above_mob)
|
|
L.visible_message(message = span_infoplain(span_bold("[L]") + " falls off " + span_bold("\The [src]")), self_message = span_danger("You slipped off " + span_bold("\The [src]")), \
|
|
blind_message = span_infoplain("you hear a loud thud!"), runemessage = "CRASH!")
|
|
else
|
|
if(drop_our_held)
|
|
L.drop_item(get_turf(L))
|
|
L.forceMove(above_wall)
|
|
L.visible_message(message = span_infoplain(span_bold("[L]") + " climbed up on " + span_bold("\The [src]")), \
|
|
self_message = span_notice("You successfully scaled " + span_bold("\The [src]")), \
|
|
blind_message = span_infoplain("The sounds of climbing cease."), runemessage = "Tap Tap")
|
|
L.adjust_nutrition(-nutrition_cost)
|
|
else if(world.time > (oops_time + grace_time))
|
|
L.forceMove(above_mob)
|
|
L.visible_message(message = span_infoplain(span_bold("[L]") + " falls off " + span_bold("\The [src]")), self_message = span_danger("You slipped off " + span_bold("\The [src]")), \
|
|
blind_message = span_infoplain("you hear a loud thud!"), runemessage = "CRASH!")
|
|
|
|
/mob/living/verb/climb_down()
|
|
set name = "Climb down wall"
|
|
set desc = "attempt to climb down the wall you are standing on, in direction you're looking"
|
|
set category = "IC.Game"
|
|
|
|
var/fall_chance = 0 //Increased if we can't actually climb
|
|
var/turf/our_turf = get_turf(src) //floor we're standing on
|
|
var/climbing_delay_min = src.climbing_delay //We take the lowest climbing delay between mob, species and gear.
|
|
var/nutrition_cost = 25 //Descending is easier!
|
|
|
|
|
|
//Check if we can even try to climb
|
|
if(nutrition <= nutrition_cost)
|
|
to_chat(src, span_warning("You [isSynthetic() ? "lack the energy" : "are too hungry"] for such strenous activities!"))
|
|
return
|
|
var/turf/below_wall = GetBelow(our_turf)
|
|
if(!below_wall) //No multiZ
|
|
to_chat(src, span_notice("There's nothing interesting below us!"))
|
|
return
|
|
if(!istype(below_wall,/turf/simulated)) //Our var is on simulated turfs, we must enforce this
|
|
to_chat(src, span_notice("There's nothing useful to grab onto!"))
|
|
return
|
|
var/turf/simulated/climbing_surface = below_wall
|
|
if(!climbing_surface.density) //passable turfs make no sense to climb
|
|
to_chat(src, span_notice("There's nothing climbable below us!"))
|
|
return
|
|
var/turf/front_of_us = get_step(src, dir) //We get the spot we are facing
|
|
if(!front_of_us.CanZPass(src, DOWN)) //Makes sure where we're climbing isnt blocked by a tile or there's a wall below it.
|
|
to_chat(src, span_notice("\The [front_of_us] blocks your way in this direction!"))
|
|
return
|
|
var/turf/destination = GetBelow(front_of_us)
|
|
if(isopenspace(destination)) //We don't allow descending more than 1 Z at a time
|
|
to_chat(src, span_notice("You're too high up to climb down from here! Find a more gentle descent!"))
|
|
return
|
|
|
|
//Determining whether we should be able to climb safely and how fast
|
|
if(ishuman(src))
|
|
var/permit_human = FALSE
|
|
var/mob/living/carbon/human/H = src
|
|
if(H.species.climbing_delay < H.climbing_delay)
|
|
climbing_delay_min = H.species.climbing_delay
|
|
var/list/gear = list(H.head, H.wear_mask, H.wear_suit, H.w_uniform,
|
|
H.gloves, H.shoes, H.belt, H.get_active_hand(), H.get_inactive_hand())
|
|
if(H.can_climb || H.species.can_climb)
|
|
permit_human = TRUE
|
|
for(var/obj/item/I in gear)
|
|
if(I.rock_climbing)
|
|
permit_human = TRUE
|
|
if(I.climbing_delay > climbing_delay_min)
|
|
climbing_delay_min = I.climbing_delay //We get the maximum possible speedup out of worn equipment
|
|
if(!permit_human)
|
|
var/sure = tgui_alert(H,"Are you sure you want to try without tools? It's VERY LIKELY \
|
|
you will fall and get hurt. More agile species might have better luck", "Second Thoughts", list("Bring it!", "Stay grounded"))
|
|
if(!sure || sure == "Stay grounded") return
|
|
fall_chance = clamp(100 - H.species.agility, 40, 90) //This should be 80 for most species. Traceur would reduce to 10%, so clamping higher
|
|
//If not a human mob, must be simple or silicon. They got a var stored on their mob we can check
|
|
else if(!src.can_climb)
|
|
var/sure = tgui_alert(src,"Are you sure you want to try without tools? It's VERY LIKELY \
|
|
you will fall and get hurt. More agile species might have better luck", "Second Thoughts", list("Bring it!", "Stay grounded"))
|
|
if(!sure || sure == "Stay grounded") return
|
|
if(isrobot(src))
|
|
fall_chance = 80 // Robots get no mercy
|
|
else
|
|
fall_chance = 55 //Simple mobs do.
|
|
climbing_delay_min = 2
|
|
//This time, scugs get no snowflake treatment. We're climbing DOWN, not up!
|
|
|
|
//We proceed with the actual climbing!
|
|
// ################### CLIMB TIME BELOW: #############################
|
|
// Climb time is 3.75 for scugs with spears (spear is dropped)
|
|
// Climb time is 5 for Master climbers, Vassilians, Well-geared humans
|
|
// Climb time is 9 for Tajara and Professional Climbers
|
|
// Climb time is 17.5 Seconds for amateur climbers
|
|
// Climb time is 20 seconds for scugs without a spear
|
|
// Climb time is 30 for gearless untrained people
|
|
var/climb_time = (5 * climbing_delay_min) SECONDS
|
|
if(fall_chance)
|
|
to_chat(src, span_warning("You begin climbing down along \The [below_wall]. Getting a grip is exceedingly difficult..."))
|
|
climb_time += 20 SECONDS
|
|
else
|
|
to_chat(src, span_notice("You begin climbing down \The [below_wall]! "))
|
|
if(climbing_delay_min > 1.25)
|
|
climb_time += 10 SECONDS
|
|
if(climbing_delay_min > 1.0)
|
|
climb_time += 2.5 SECONDS
|
|
if(nutrition >= 100 && nutrition <= 200) //Values are 50 lower than the warning icon appearing
|
|
to_chat(src, span_notice("Climbing while [isSynthetic() ? "low on power" : "hungry"] slows you down"))
|
|
climb_time += 1 SECONDS
|
|
else if(nutrition >= nutrition_cost && nutrition <= 100)
|
|
to_chat(src, span_danger("You [isSynthetic() ? "lack enough power" : "are too hungry"] to climb safely!"))
|
|
climb_time +=3 SECONDS
|
|
if(fall_chance < 30)
|
|
fall_chance = 30
|
|
|
|
if(!climbing_surface.climbable)
|
|
to_chat(src, span_danger("\The [climbing_surface] is not suitable for climbing! Even for a master climber, this is risky!"))
|
|
if(fall_chance < 75 )
|
|
fall_chance = 75
|
|
src.visible_message(message = span_infoplain(span_bold("[src]") + " climb down " + span_bold("\The [below_wall]")), \
|
|
self_message = span_infoplain("You begin to descend " + span_bold("\The [below_wall]")), \
|
|
blind_message = span_infoplain("You hear the sounds of climbing!"), runemessage = "Tap Tap")
|
|
below_wall.audible_message(message = span_infoplain("You hear something climbing up " + span_bold("\The [below_wall]")), runemessage= "Tap Tap")
|
|
var/oops_time = world.time
|
|
var/grace_time = 3 SECONDS
|
|
to_chat(src, span_warning("If you get interrupted after [(grace_time / (1 SECOND))] seconds of climbing, you will fall and hurt yourself, beware!"))
|
|
if(do_after(src, climb_time, target = src))
|
|
if(prob(fall_chance))
|
|
src.forceMove(front_of_us)
|
|
src.visible_message(message = span_infoplain(span_bold("[src]") + " falls off " + span_bold("\The [below_wall]")), \
|
|
self_message = span_danger("You slipped off " + span_bold("\The [below_wall]")), \
|
|
blind_message = span_infoplain("you hear a loud thud!"), runemessage = "CRASH!")
|
|
else
|
|
src.forceMove(destination)
|
|
src.visible_message(message = span_infoplain(span_bold("[src]") + " climbed down on " + span_bold("\The [below_wall]")), \
|
|
self_message = span_notice("You successfully descended " + span_bold("\The [below_wall]")), \
|
|
blind_message = span_infoplain("The sounds of climbing cease."), runemessage = "Tap Tap")
|
|
adjust_nutrition(-nutrition_cost)
|
|
else if(world.time > (oops_time + grace_time))
|
|
src.forceMove(front_of_us)
|
|
src.visible_message(message = span_infoplain(span_bold("[src]") + " falls off " + span_bold("\The [below_wall]")), \
|
|
self_message = span_danger("You slipped off " + span_bold("\The [below_wall]")), \
|
|
blind_message = span_infoplain("you hear a loud thud!"), runemessage = "CRASH!")
|