* :) * that * move those there * refactor that too * wew * stuff * almost. * sigh * just need speed * stuf * pain * hm * tweaks * that * eh * wack * a * done * that's important * wacky * all that * fixes * typo * that * a * funny * that * that * woo * help im losing my fucking mind * okay * fix
674 lines
26 KiB
Plaintext
674 lines
26 KiB
Plaintext
// YEEHAW GAMERS STAMINA REWORK PROC GETS TO BE FIRST
|
|
// amount = strength
|
|
// updating = update mobility etc etc
|
|
// ignore_castun = same logic as Paralyze() in general
|
|
// override_duration = If this is set, does Paralyze() for this duration.
|
|
// override_stam = If this is set, does this amount of stamina damage.
|
|
// knocktofloor - whether to knock them to the ground
|
|
/mob/living/proc/DefaultCombatKnockdown(amount, updating = TRUE, ignore_canknockdown = FALSE, override_hardstun, override_stamdmg, knocktofloor = TRUE)
|
|
if(!iscarbon(src))
|
|
return Paralyze(amount, updating, ignore_canknockdown)
|
|
if(!ignore_canknockdown && !(status_flags & CANKNOCKDOWN))
|
|
return FALSE
|
|
if(istype(buckled, /obj/vehicle/ridden))
|
|
buckled.unbuckle_mob(src)
|
|
var/drop_items = amount > 80 //80 is cutoff for old item dropping behavior
|
|
var/stamdmg = isnull(override_stamdmg)? (amount * 0.25) : override_stamdmg
|
|
if(knocktofloor)
|
|
KnockToFloor(drop_items, TRUE, updating)
|
|
adjustStaminaLoss(stamdmg)
|
|
if(!isnull(override_hardstun))
|
|
Paralyze(override_hardstun)
|
|
|
|
////////////////////////////// STUN ////////////////////////////////////
|
|
|
|
/mob/living/proc/IsStun() //If we're stunned
|
|
return has_status_effect(STATUS_EFFECT_STUN)
|
|
|
|
/mob/living/proc/AmountStun() //How many deciseconds remain in our stun
|
|
var/datum/status_effect/incapacitating/stun/S = IsStun()
|
|
if(S)
|
|
return S.duration - world.time
|
|
return 0
|
|
|
|
/mob/living/proc/Stun(amount, updating = TRUE, ignore_canstun = FALSE) //Can't go below remaining duration
|
|
if(SEND_SIGNAL(src, COMSIG_LIVING_STATUS_STUN, amount, updating, ignore_canstun) & COMPONENT_NO_STUN)
|
|
return
|
|
if(!ignore_canstun && (!(status_flags & CANSTUN) || HAS_TRAIT(src, TRAIT_STUNIMMUNE)))
|
|
return
|
|
if(absorb_stun(amount, ignore_canstun))
|
|
return
|
|
var/datum/status_effect/incapacitating/stun/S = IsStun()
|
|
if(S)
|
|
S.duration = max(world.time + amount, S.duration)
|
|
else if(amount > 0)
|
|
S = apply_status_effect(STATUS_EFFECT_STUN, amount, updating)
|
|
return S
|
|
|
|
/mob/living/proc/SetStun(amount, updating = TRUE, ignore_canstun = FALSE) //Sets remaining duration
|
|
if(SEND_SIGNAL(src, COMSIG_LIVING_STATUS_STUN, amount, updating, ignore_canstun) & COMPONENT_NO_STUN)
|
|
return
|
|
if(!ignore_canstun && (!(status_flags & CANSTUN) || HAS_TRAIT(src, TRAIT_STUNIMMUNE)))
|
|
return
|
|
var/datum/status_effect/incapacitating/stun/S = IsStun()
|
|
if(amount <= 0)
|
|
if(S)
|
|
qdel(S)
|
|
else
|
|
if(absorb_stun(amount, ignore_canstun))
|
|
return
|
|
if(S)
|
|
S.duration = world.time + amount
|
|
else
|
|
S = apply_status_effect(STATUS_EFFECT_STUN, amount, updating)
|
|
return S
|
|
|
|
/mob/living/proc/AdjustStun(amount, updating = TRUE, ignore_canstun = FALSE) //Adds to remaining duration
|
|
if(SEND_SIGNAL(src, COMSIG_LIVING_STATUS_STUN, amount, updating, ignore_canstun) & COMPONENT_NO_STUN)
|
|
return
|
|
if(!ignore_canstun && (!(status_flags & CANSTUN) || HAS_TRAIT(src, TRAIT_STUNIMMUNE)))
|
|
return
|
|
if(absorb_stun(amount, ignore_canstun))
|
|
return
|
|
var/datum/status_effect/incapacitating/stun/S = IsStun()
|
|
if(S)
|
|
S.duration += amount
|
|
else if(amount > 0)
|
|
S = apply_status_effect(STATUS_EFFECT_STUN, amount, updating)
|
|
return S
|
|
|
|
///////////////////////////////// KNOCKDOWN /////////////////////////////////////
|
|
|
|
/mob/living/proc/IsKnockdown() //If we're knocked down
|
|
return has_status_effect(STATUS_EFFECT_KNOCKDOWN)
|
|
|
|
/mob/living/proc/AmountKnockdown() //How many deciseconds remain in our knockdown
|
|
var/datum/status_effect/incapacitating/knockdown/K = IsKnockdown()
|
|
if(K)
|
|
return K.duration - world.time
|
|
return 0
|
|
|
|
/mob/living/proc/Knockdown(amount, updating = TRUE, ignore_canstun = FALSE) //Can't go below remaining duration
|
|
if(SEND_SIGNAL(src, COMSIG_LIVING_STATUS_KNOCKDOWN, amount, updating, ignore_canstun) & COMPONENT_NO_STUN)
|
|
return
|
|
if(!ignore_canstun && (!(status_flags & CANKNOCKDOWN) || HAS_TRAIT(src, TRAIT_STUNIMMUNE)))
|
|
return
|
|
if(absorb_stun(amount, ignore_canstun))
|
|
return
|
|
var/datum/status_effect/incapacitating/knockdown/K = IsKnockdown()
|
|
if(K)
|
|
K.duration = max(world.time + amount, K.duration)
|
|
else if(amount > 0)
|
|
K = apply_status_effect(STATUS_EFFECT_KNOCKDOWN, amount, updating)
|
|
return K
|
|
|
|
/mob/living/proc/SetKnockdown(amount, updating = TRUE, ignore_canstun = FALSE) //Sets remaining duration
|
|
if(SEND_SIGNAL(src, COMSIG_LIVING_STATUS_KNOCKDOWN, amount, updating, ignore_canstun) & COMPONENT_NO_STUN)
|
|
return
|
|
if(!ignore_canstun && (!(status_flags & CANKNOCKDOWN) || HAS_TRAIT(src, TRAIT_STUNIMMUNE)))
|
|
return
|
|
var/datum/status_effect/incapacitating/knockdown/K = IsKnockdown()
|
|
if(amount <= 0)
|
|
if(K)
|
|
qdel(K)
|
|
else
|
|
if(absorb_stun(amount, ignore_canstun))
|
|
return
|
|
if(K)
|
|
K.duration = world.time + amount
|
|
else
|
|
K = apply_status_effect(STATUS_EFFECT_KNOCKDOWN, amount, updating)
|
|
return K
|
|
|
|
/mob/living/proc/AdjustKnockdown(amount, updating = TRUE, ignore_canstun = FALSE) //Adds to remaining duration
|
|
if(SEND_SIGNAL(src, COMSIG_LIVING_STATUS_KNOCKDOWN, amount, updating, ignore_canstun) & COMPONENT_NO_STUN)
|
|
return
|
|
if(!ignore_canstun && (!(status_flags & CANKNOCKDOWN) || HAS_TRAIT(src, TRAIT_STUNIMMUNE)))
|
|
return
|
|
if(absorb_stun(amount, ignore_canstun))
|
|
return
|
|
var/datum/status_effect/incapacitating/knockdown/K = IsKnockdown()
|
|
if(K)
|
|
K.duration += amount
|
|
else if(amount > 0)
|
|
K = apply_status_effect(STATUS_EFFECT_KNOCKDOWN, amount, updating)
|
|
return K
|
|
|
|
///////////////////////////////// IMMOBILIZED ////////////////////////////////////
|
|
/mob/living/proc/IsImmobilized() //If we're immobilized
|
|
return has_status_effect(STATUS_EFFECT_IMMOBILIZED)
|
|
|
|
/mob/living/proc/AmountImmobilized() //How many deciseconds remain in our Immobilized status effect
|
|
var/datum/status_effect/incapacitating/immobilized/I = IsImmobilized()
|
|
if(I)
|
|
return I.duration - world.time
|
|
return 0
|
|
|
|
/mob/living/proc/Immobilize(amount, updating = TRUE, ignore_canstun = FALSE) //Can't go below remaining duration
|
|
if(SEND_SIGNAL(src, COMSIG_LIVING_STATUS_IMMOBILIZE, amount, updating, ignore_canstun) & COMPONENT_NO_STUN)
|
|
return
|
|
if(!ignore_canstun && (!(status_flags & CANKNOCKDOWN) || HAS_TRAIT(src, TRAIT_STUNIMMUNE)))
|
|
return
|
|
if(absorb_stun(amount, ignore_canstun))
|
|
return
|
|
var/datum/status_effect/incapacitating/immobilized/I = IsImmobilized()
|
|
if(I)
|
|
I.duration = max(world.time + amount, I.duration)
|
|
else if(amount > 0)
|
|
I = apply_status_effect(STATUS_EFFECT_IMMOBILIZED, amount, updating)
|
|
return I
|
|
|
|
/mob/living/proc/SetImmobilized(amount, updating = TRUE, ignore_canstun = FALSE) //Sets remaining duration
|
|
if(SEND_SIGNAL(src, COMSIG_LIVING_STATUS_IMMOBILIZE, amount, updating, ignore_canstun) & COMPONENT_NO_STUN)
|
|
return
|
|
if(!ignore_canstun && (!(status_flags & CANKNOCKDOWN) || HAS_TRAIT(src, TRAIT_STUNIMMUNE)))
|
|
return
|
|
var/datum/status_effect/incapacitating/immobilized/I = IsImmobilized()
|
|
if(amount <= 0)
|
|
if(I)
|
|
qdel(I)
|
|
else
|
|
if(absorb_stun(amount, ignore_canstun))
|
|
return
|
|
if(I)
|
|
I.duration = world.time + amount
|
|
else
|
|
I = apply_status_effect(STATUS_EFFECT_IMMOBILIZED, amount, updating)
|
|
return I
|
|
|
|
/mob/living/proc/AdjustImmobilized(amount, updating = TRUE, ignore_canstun = FALSE) //Adds to remaining duration
|
|
if(SEND_SIGNAL(src, COMSIG_LIVING_STATUS_IMMOBILIZE, amount, updating, ignore_canstun) & COMPONENT_NO_STUN)
|
|
return
|
|
if(!ignore_canstun && (!(status_flags & CANKNOCKDOWN) || HAS_TRAIT(src, TRAIT_STUNIMMUNE)))
|
|
return
|
|
if(absorb_stun(amount, ignore_canstun))
|
|
return
|
|
var/datum/status_effect/incapacitating/immobilized/I = IsImmobilized()
|
|
if(I)
|
|
I.duration += amount
|
|
else if(amount > 0)
|
|
I = apply_status_effect(STATUS_EFFECT_IMMOBILIZED, amount, updating)
|
|
return I
|
|
|
|
///////////////////////////////// PARALYZED //////////////////////////////////
|
|
/mob/living/proc/IsParalyzed() //If we're immobilized
|
|
return has_status_effect(STATUS_EFFECT_PARALYZED)
|
|
|
|
/mob/living/proc/AmountParalyzed() //How many deciseconds remain in our Paralyzed status effect
|
|
var/datum/status_effect/incapacitating/paralyzed/P = IsParalyzed(FALSE)
|
|
if(P)
|
|
return P.duration - world.time
|
|
return 0
|
|
|
|
/mob/living/proc/Paralyze(amount, updating = TRUE, ignore_canstun = FALSE) //Can't go below remaining duration
|
|
if(SEND_SIGNAL(src, COMSIG_LIVING_STATUS_PARALYZE, amount, updating, ignore_canstun) & COMPONENT_NO_STUN)
|
|
return
|
|
if(!ignore_canstun && (!(status_flags & CANKNOCKDOWN) || HAS_TRAIT(src, TRAIT_STUNIMMUNE)))
|
|
return
|
|
if(absorb_stun(amount, ignore_canstun))
|
|
return
|
|
var/datum/status_effect/incapacitating/paralyzed/P = IsParalyzed(FALSE)
|
|
if(P)
|
|
P.duration = max(world.time + amount, P.duration)
|
|
else if(amount > 0)
|
|
P = apply_status_effect(STATUS_EFFECT_PARALYZED, amount, updating)
|
|
return P
|
|
|
|
/mob/living/proc/SetParalyzed(amount, updating = TRUE, ignore_canstun = FALSE) //Sets remaining duration
|
|
if(SEND_SIGNAL(src, COMSIG_LIVING_STATUS_PARALYZE, amount, updating, ignore_canstun) & COMPONENT_NO_STUN)
|
|
return
|
|
if(!ignore_canstun && (!(status_flags & CANKNOCKDOWN) || HAS_TRAIT(src, TRAIT_STUNIMMUNE)))
|
|
return
|
|
var/datum/status_effect/incapacitating/paralyzed/P = IsParalyzed(FALSE)
|
|
if(amount <= 0)
|
|
if(P)
|
|
qdel(P)
|
|
else
|
|
if(absorb_stun(amount, ignore_canstun))
|
|
return
|
|
if(P)
|
|
P.duration = world.time + amount
|
|
else
|
|
P = apply_status_effect(STATUS_EFFECT_PARALYZED, amount, updating)
|
|
return P
|
|
|
|
/mob/living/proc/AdjustParalyzed(amount, updating = TRUE, ignore_canstun = FALSE) //Adds to remaining duration
|
|
if(SEND_SIGNAL(src, COMSIG_LIVING_STATUS_PARALYZE, amount, updating, ignore_canstun) & COMPONENT_NO_STUN)
|
|
return
|
|
if(!ignore_canstun && (!(status_flags & CANKNOCKDOWN) || HAS_TRAIT(src, TRAIT_STUNIMMUNE)))
|
|
return
|
|
if(absorb_stun(amount, ignore_canstun))
|
|
return
|
|
var/datum/status_effect/incapacitating/paralyzed/P = IsParalyzed(FALSE)
|
|
if(P)
|
|
P.duration += amount
|
|
else if(amount > 0)
|
|
P = apply_status_effect(STATUS_EFFECT_PARALYZED, amount, updating)
|
|
return P
|
|
|
|
///////////////////////////////// DAZED ////////////////////////////////////
|
|
/mob/living/proc/IsDazed() //If we're Dazed
|
|
return has_status_effect(STATUS_EFFECT_DAZED)
|
|
|
|
/mob/living/proc/AmountDazed() //How many deciseconds remain in our Dazed status effect
|
|
var/datum/status_effect/incapacitating/dazed/I = IsDazed()
|
|
if(I)
|
|
return I.duration - world.time
|
|
return 0
|
|
|
|
/mob/living/proc/Daze(amount, updating = TRUE, ignore_canstun = FALSE) //Can't go below remaining duration
|
|
if(SEND_SIGNAL(src, COMSIG_LIVING_STATUS_DAZE, amount, updating, ignore_canstun) & COMPONENT_NO_STUN)
|
|
return
|
|
if(!ignore_canstun && (!(status_flags & CANKNOCKDOWN) || HAS_TRAIT(src, TRAIT_STUNIMMUNE)))
|
|
return
|
|
if(absorb_stun(amount, ignore_canstun))
|
|
return
|
|
var/datum/status_effect/incapacitating/dazed/I = IsDazed()
|
|
if(I)
|
|
I.duration = max(world.time + amount, I.duration)
|
|
else if(amount > 0)
|
|
I = apply_status_effect(STATUS_EFFECT_DAZED, amount, updating)
|
|
return I
|
|
|
|
/mob/living/proc/SetDazed(amount, updating = TRUE, ignore_canstun = FALSE) //Sets remaining duration
|
|
if(SEND_SIGNAL(src, COMSIG_LIVING_STATUS_DAZE, amount, updating, ignore_canstun) & COMPONENT_NO_STUN)
|
|
return
|
|
if(!ignore_canstun && (!(status_flags & CANKNOCKDOWN) || HAS_TRAIT(src, TRAIT_STUNIMMUNE)))
|
|
return
|
|
var/datum/status_effect/incapacitating/dazed/I = IsDazed()
|
|
if(amount <= 0)
|
|
if(I)
|
|
qdel(I)
|
|
else
|
|
if(absorb_stun(amount, ignore_canstun))
|
|
return
|
|
if(I)
|
|
I.duration = world.time + amount
|
|
else
|
|
I = apply_status_effect(STATUS_EFFECT_DAZED, amount, updating)
|
|
return I
|
|
|
|
/mob/living/proc/AdjustDazed(amount, updating = TRUE, ignore_canstun = FALSE) //Adds to remaining duration
|
|
if(SEND_SIGNAL(src, COMSIG_LIVING_STATUS_DAZE, amount, updating, ignore_canstun) & COMPONENT_NO_STUN)
|
|
return
|
|
if(!ignore_canstun && (!(status_flags & CANKNOCKDOWN) || HAS_TRAIT(src, TRAIT_STUNIMMUNE)))
|
|
return
|
|
if(absorb_stun(amount, ignore_canstun))
|
|
return
|
|
var/datum/status_effect/incapacitating/dazed/I = IsDazed()
|
|
if(I)
|
|
I.duration += amount
|
|
else if(amount > 0)
|
|
I = apply_status_effect(STATUS_EFFECT_DAZED, amount, updating)
|
|
return I
|
|
|
|
///////////////////////////////// STAGGERED ////////////////////////////////////
|
|
/mob/living/proc/IsStaggered() //If we're Staggered
|
|
return has_status_effect(STATUS_EFFECT_STAGGERED)
|
|
|
|
/mob/living/proc/AmountStaggered() //How many deciseconds remain in our Staggered status effect
|
|
var/datum/status_effect/staggered/I = IsStaggered()
|
|
if(I)
|
|
return I.duration - world.time
|
|
return 0
|
|
|
|
/mob/living/proc/Stagger(amount, updating = TRUE, ignore_canstun = FALSE) //Can't go below remaining duration
|
|
if(SEND_SIGNAL(src, COMSIG_LIVING_STATUS_STAGGER, amount, updating, ignore_canstun) & COMPONENT_NO_STUN)
|
|
return
|
|
if(!ignore_canstun && (!(status_flags & CANKNOCKDOWN) || HAS_TRAIT(src, TRAIT_STUNIMMUNE)))
|
|
return
|
|
if(absorb_stun(amount, ignore_canstun))
|
|
return
|
|
var/datum/status_effect/staggered/I = IsStaggered()
|
|
if(I)
|
|
I.duration = max(world.time + amount, I.duration)
|
|
else if(amount > 0)
|
|
I = apply_status_effect(STATUS_EFFECT_STAGGERED, amount, updating)
|
|
return I
|
|
|
|
/mob/living/proc/SetStaggered(amount, updating = TRUE, ignore_canstun = FALSE) //Sets remaining duration
|
|
if(SEND_SIGNAL(src, COMSIG_LIVING_STATUS_STAGGER, amount, updating, ignore_canstun) & COMPONENT_NO_STUN)
|
|
return
|
|
if(!ignore_canstun && (!(status_flags & CANKNOCKDOWN) || HAS_TRAIT(src, TRAIT_STUNIMMUNE)))
|
|
return
|
|
var/datum/status_effect/staggered/I = IsStaggered()
|
|
if(amount <= 0)
|
|
if(I)
|
|
qdel(I)
|
|
else
|
|
if(absorb_stun(amount, ignore_canstun))
|
|
return
|
|
if(I)
|
|
I.duration = world.time + amount
|
|
else
|
|
I = apply_status_effect(STATUS_EFFECT_STAGGERED, amount, updating)
|
|
return I
|
|
|
|
/mob/living/proc/AdjustStaggered(amount, updating = TRUE, ignore_canstun = FALSE) //Adds to remaining duration
|
|
if(SEND_SIGNAL(src, COMSIG_LIVING_STATUS_STAGGER, amount, updating, ignore_canstun) & COMPONENT_NO_STUN)
|
|
return
|
|
if(!ignore_canstun && (!(status_flags & CANKNOCKDOWN) || HAS_TRAIT(src, TRAIT_STUNIMMUNE)))
|
|
return
|
|
if(absorb_stun(amount, ignore_canstun))
|
|
return
|
|
var/datum/status_effect/staggered/I = IsStaggered()
|
|
if(I)
|
|
I.duration += amount
|
|
else if(amount > 0)
|
|
I = apply_status_effect(STATUS_EFFECT_STAGGERED, amount, updating)
|
|
return I
|
|
|
|
//Blanket
|
|
/mob/living/proc/AllImmobility(amount, updating, ignore_canstun = FALSE)
|
|
Paralyze(amount, FALSE, ignore_canstun)
|
|
Knockdown(amount, FALSE, ignore_canstun)
|
|
Stun(amount, FALSE, ignore_canstun)
|
|
Immobilize(amount, FALSE, ignore_canstun)
|
|
Daze(amount, FALSE, ignore_canstun)
|
|
Stagger(amount, FALSE, ignore_canstun)
|
|
if(updating)
|
|
update_mobility()
|
|
|
|
/mob/living/proc/SetAllImmobility(amount, updating, ignore_canstun = FALSE)
|
|
SetParalyzed(amount, FALSE, ignore_canstun)
|
|
SetKnockdown(amount, FALSE, ignore_canstun)
|
|
SetStun(amount, FALSE, ignore_canstun)
|
|
SetImmobilized(amount, FALSE, ignore_canstun)
|
|
SetDazed(amount, FALSE, ignore_canstun)
|
|
SetStaggered(amount, FALSE, ignore_canstun)
|
|
if(updating)
|
|
update_mobility()
|
|
|
|
/mob/living/proc/AdjustAllImmobility(amount, updating, ignore_canstun = FALSE)
|
|
AdjustParalyzed(amount, FALSE, ignore_canstun)
|
|
AdjustKnockdown(amount, FALSE, ignore_canstun)
|
|
AdjustStun(amount, FALSE, ignore_canstun)
|
|
AdjustImmobilized(amount, FALSE, ignore_canstun)
|
|
AdjustDazed(amount, FALSE, ignore_canstun)
|
|
AdjustStaggered(amount, FALSE, ignore_canstun)
|
|
if(updating)
|
|
update_mobility()
|
|
|
|
/// Makes sure all 5 of the non-knockout immobilizing status effects are lower or equal to amount.
|
|
/mob/living/proc/HealAllImmobilityUpTo(amount, updating, ignore_canstun = FALSE)
|
|
if(AmountStun() > amount)
|
|
SetStun(amount, FALSE, ignore_canstun)
|
|
if(AmountKnockdown() > amount)
|
|
SetKnockdown(amount, FALSE, ignore_canstun)
|
|
if(AmountParalyzed() > amount)
|
|
SetParalyzed(amount, FALSE, ignore_canstun)
|
|
if(AmountImmobilized() > amount)
|
|
SetImmobilized(amount, FALSE, ignore_canstun)
|
|
if(AmountDazed() > amount)
|
|
SetImmobilized(amount, FALSE, ignore_canstun)
|
|
if(AmountStaggered() > amount)
|
|
SetStaggered(amount, FALSE, ignore_canstun)
|
|
if(updating)
|
|
update_mobility()
|
|
|
|
/mob/living/proc/HighestImmobilityAmount()
|
|
return max(AmountStun(), AmountKnockdown(), AmountParalyzed(), AmountImmobilized(), AmountDazed(), AmountStaggered())
|
|
|
|
//////////////////UNCONSCIOUS
|
|
/mob/living/proc/IsUnconscious() //If we're unconscious
|
|
return has_status_effect(STATUS_EFFECT_UNCONSCIOUS)
|
|
|
|
/mob/living/proc/AmountUnconscious() //How many deciseconds remain in our unconsciousness
|
|
var/datum/status_effect/incapacitating/unconscious/U = IsUnconscious()
|
|
if(U)
|
|
return U.duration - world.time
|
|
return 0
|
|
|
|
/mob/living/proc/Unconscious(amount, updating = TRUE, ignore_canstun = FALSE) //Can't go below remaining duration
|
|
if(SEND_SIGNAL(src, COMSIG_LIVING_STATUS_UNCONSCIOUS, amount, updating, ignore_canstun) & COMPONENT_NO_STUN)
|
|
return
|
|
if(((status_flags & CANUNCONSCIOUS) && !HAS_TRAIT(src, TRAIT_STUNIMMUNE)) || ignore_canstun)
|
|
var/datum/status_effect/incapacitating/unconscious/U = IsUnconscious()
|
|
if(U)
|
|
U.duration = max(world.time + amount, U.duration)
|
|
else if(amount > 0)
|
|
U = apply_status_effect(STATUS_EFFECT_UNCONSCIOUS, amount, updating)
|
|
return U
|
|
|
|
/mob/living/proc/SetUnconscious(amount, updating = TRUE, ignore_canstun = FALSE) //Sets remaining duration
|
|
if(SEND_SIGNAL(src, COMSIG_LIVING_STATUS_UNCONSCIOUS, amount, updating, ignore_canstun) & COMPONENT_NO_STUN)
|
|
return
|
|
if(((status_flags & CANUNCONSCIOUS) && !HAS_TRAIT(src, TRAIT_STUNIMMUNE)) || ignore_canstun)
|
|
var/datum/status_effect/incapacitating/unconscious/U = IsUnconscious()
|
|
if(amount <= 0)
|
|
if(U)
|
|
qdel(U)
|
|
else if(U)
|
|
U.duration = world.time + amount
|
|
else
|
|
U = apply_status_effect(STATUS_EFFECT_UNCONSCIOUS, amount, updating)
|
|
return U
|
|
|
|
/mob/living/proc/AdjustUnconscious(amount, updating = TRUE, ignore_canstun = FALSE) //Adds to remaining duration
|
|
if(SEND_SIGNAL(src, COMSIG_LIVING_STATUS_UNCONSCIOUS, amount, updating, ignore_canstun) & COMPONENT_NO_STUN)
|
|
return
|
|
if(((status_flags & CANUNCONSCIOUS) && !HAS_TRAIT(src, TRAIT_STUNIMMUNE)) || ignore_canstun)
|
|
var/datum/status_effect/incapacitating/unconscious/U = IsUnconscious()
|
|
if(U)
|
|
U.duration += amount
|
|
else if(amount > 0)
|
|
U = apply_status_effect(STATUS_EFFECT_UNCONSCIOUS, amount, updating)
|
|
return U
|
|
|
|
/////////////////////////////////// SLEEPING ////////////////////////////////////
|
|
|
|
/mob/living/proc/IsSleeping() //If we're asleep
|
|
return has_status_effect(STATUS_EFFECT_SLEEPING)
|
|
|
|
/mob/living/proc/AmountSleeping() //How many deciseconds remain in our sleep
|
|
var/datum/status_effect/incapacitating/sleeping/S = IsSleeping()
|
|
if(S)
|
|
return S.duration - world.time
|
|
return 0
|
|
|
|
/mob/living/proc/Sleeping(amount, updating = TRUE, ignore_canstun = FALSE) //Can't go below remaining duration
|
|
if(SEND_SIGNAL(src, COMSIG_LIVING_STATUS_SLEEP, amount, updating, ignore_canstun) & COMPONENT_NO_STUN)
|
|
return
|
|
if((!HAS_TRAIT(src, TRAIT_SLEEPIMMUNE)) || ignore_canstun)
|
|
var/datum/status_effect/incapacitating/sleeping/S = IsSleeping()
|
|
if(S)
|
|
S.duration = max(world.time + amount, S.duration)
|
|
else if(amount > 0)
|
|
S = apply_status_effect(STATUS_EFFECT_SLEEPING, amount, updating)
|
|
return S
|
|
|
|
/mob/living/proc/SetSleeping(amount, updating = TRUE, ignore_canstun = FALSE) //Sets remaining duration
|
|
if(SEND_SIGNAL(src, COMSIG_LIVING_STATUS_SLEEP, amount, updating, ignore_canstun) & COMPONENT_NO_STUN)
|
|
return
|
|
if((!HAS_TRAIT(src, TRAIT_SLEEPIMMUNE)) || ignore_canstun)
|
|
var/datum/status_effect/incapacitating/sleeping/S = IsSleeping()
|
|
if(amount <= 0)
|
|
if(S)
|
|
qdel(S)
|
|
else if(S)
|
|
S.duration = world.time + amount
|
|
else
|
|
S = apply_status_effect(STATUS_EFFECT_SLEEPING, amount, updating)
|
|
return S
|
|
|
|
/mob/living/proc/AdjustSleeping(amount, updating = TRUE, ignore_canstun = FALSE) //Adds to remaining duration
|
|
if(SEND_SIGNAL(src, COMSIG_LIVING_STATUS_SLEEP, amount, updating, ignore_canstun) & COMPONENT_NO_STUN)
|
|
return
|
|
if((!HAS_TRAIT(src, TRAIT_SLEEPIMMUNE)) || ignore_canstun)
|
|
var/datum/status_effect/incapacitating/sleeping/S = IsSleeping()
|
|
if(S)
|
|
S.duration += amount
|
|
else if(amount > 0)
|
|
S = apply_status_effect(STATUS_EFFECT_SLEEPING, amount, updating)
|
|
return S
|
|
|
|
///////////////////////////////// OFF BALANCE/SHOVIES ////////////////////////
|
|
/mob/living/proc/ShoveOffBalance(amount)
|
|
var/datum/status_effect/off_balance/B = has_status_effect(STATUS_EFFECT_OFF_BALANCE)
|
|
if(B)
|
|
B.duration = max(world.time + amount, B.duration)
|
|
else if(amount > 0)
|
|
B = apply_status_effect(STATUS_EFFECT_OFF_BALANCE, amount)
|
|
return B
|
|
|
|
///////////////////////////////// FROZEN /////////////////////////////////////
|
|
|
|
/mob/living/proc/IsFrozen()
|
|
return has_status_effect(/datum/status_effect/freon)
|
|
|
|
///////////////////////////////////// STUN ABSORPTION /////////////////////////////////////
|
|
|
|
/mob/living/proc/add_stun_absorption(key, duration, priority, message, self_message, examine_message)
|
|
//adds a stun absorption with a key, a duration in deciseconds, its priority, and the messages it makes when you're stun/examined, if any
|
|
if(!islist(stun_absorption))
|
|
stun_absorption = list()
|
|
if(stun_absorption[key])
|
|
stun_absorption[key]["end_time"] = world.time + duration
|
|
stun_absorption[key]["priority"] = priority
|
|
stun_absorption[key]["stuns_absorbed"] = 0
|
|
else
|
|
stun_absorption[key] = list("end_time" = world.time + duration, "priority" = priority, "stuns_absorbed" = 0, \
|
|
"visible_message" = message, "self_message" = self_message, "examine_message" = examine_message)
|
|
|
|
/mob/living/proc/absorb_stun(amount, ignoring_flag_presence)
|
|
if(amount < 0 || stat || ignoring_flag_presence || !islist(stun_absorption))
|
|
return FALSE
|
|
if(!amount)
|
|
amount = 0
|
|
var/priority_absorb_key
|
|
var/highest_priority
|
|
for(var/i in stun_absorption)
|
|
if(stun_absorption[i]["end_time"] > world.time && (!priority_absorb_key || stun_absorption[i]["priority"] > highest_priority))
|
|
priority_absorb_key = stun_absorption[i]
|
|
highest_priority = priority_absorb_key["priority"]
|
|
if(priority_absorb_key)
|
|
if(amount) //don't spam up the chat for continuous stuns
|
|
if(priority_absorb_key["visible_message"] || priority_absorb_key["self_message"])
|
|
if(priority_absorb_key["visible_message"] && priority_absorb_key["self_message"])
|
|
visible_message("<span class='warning'>[src][priority_absorb_key["visible_message"]]</span>", "<span class='boldwarning'>[priority_absorb_key["self_message"]]</span>")
|
|
else if(priority_absorb_key["visible_message"])
|
|
visible_message("<span class='warning'>[src][priority_absorb_key["visible_message"]]</span>")
|
|
else if(priority_absorb_key["self_message"])
|
|
to_chat(src, "<span class='boldwarning'>[priority_absorb_key["self_message"]]</span>")
|
|
priority_absorb_key["stuns_absorbed"] += amount
|
|
return TRUE
|
|
|
|
/////////////////////////////////// DISABILITIES ////////////////////////////////////
|
|
/mob/living/proc/add_quirk(quirktype, spawn_effects) //separate proc due to the way these ones are handled
|
|
if(HAS_TRAIT(src, quirktype))
|
|
return
|
|
var/datum/quirk/T = quirktype
|
|
var/qname = initial(T.name)
|
|
if(!SSquirks || !SSquirks.quirks[qname])
|
|
return
|
|
new quirktype (src, spawn_effects)
|
|
return TRUE
|
|
|
|
/mob/living/proc/remove_quirk(quirktype)
|
|
for(var/datum/quirk/Q in roundstart_quirks)
|
|
if(Q.type == quirktype)
|
|
qdel(Q)
|
|
return TRUE
|
|
return FALSE
|
|
|
|
/mob/living/proc/has_quirk(quirktype)
|
|
for(var/datum/quirk/Q in roundstart_quirks)
|
|
if(Q.type == quirktype)
|
|
return TRUE
|
|
return FALSE
|
|
|
|
/////////////////////////////////// TRAIT PROCS ////////////////////////////////////
|
|
|
|
/mob/living/proc/cure_blind(source)
|
|
REMOVE_TRAIT(src, TRAIT_BLIND, source)
|
|
if(!HAS_TRAIT(src, TRAIT_BLIND))
|
|
if(eye_blind <= 1) //little hack now that we don't actively check for trait and unconsciousness on update_blindness.
|
|
adjust_blindness(-1)
|
|
|
|
/mob/living/proc/become_blind(source)
|
|
if(!HAS_TRAIT(src, TRAIT_BLIND)) // not blind already, add trait then overlay
|
|
ADD_TRAIT(src, TRAIT_BLIND, source)
|
|
blind_eyes(1)
|
|
else
|
|
ADD_TRAIT(src, TRAIT_BLIND, source)
|
|
|
|
/mob/living/proc/cure_nearsighted(source)
|
|
REMOVE_TRAIT(src, TRAIT_NEARSIGHT, source)
|
|
if(!HAS_TRAIT(src, TRAIT_NEARSIGHT))
|
|
clear_fullscreen("nearsighted")
|
|
|
|
/mob/living/proc/become_nearsighted(source)
|
|
if(!HAS_TRAIT(src, TRAIT_NEARSIGHT))
|
|
overlay_fullscreen("nearsighted", /atom/movable/screen/fullscreen/scaled/impaired, 1)
|
|
ADD_TRAIT(src, TRAIT_NEARSIGHT, source)
|
|
|
|
/mob/living/proc/cure_husk(source)
|
|
REMOVE_TRAIT(src, TRAIT_HUSK, source)
|
|
if(!HAS_TRAIT(src, TRAIT_HUSK))
|
|
REMOVE_TRAIT(src, TRAIT_DISFIGURED, "husk")
|
|
update_body()
|
|
return TRUE
|
|
|
|
/mob/living/proc/become_husk(source)
|
|
if(!HAS_TRAIT(src, TRAIT_HUSK))
|
|
ADD_TRAIT(src, TRAIT_HUSK, source)
|
|
ADD_TRAIT(src, TRAIT_DISFIGURED, "husk")
|
|
update_body()
|
|
else
|
|
ADD_TRAIT(src, TRAIT_HUSK, source)
|
|
|
|
/mob/living/proc/cure_fakedeath(source)
|
|
REMOVE_TRAIT(src, TRAIT_FAKEDEATH, source)
|
|
REMOVE_TRAIT(src, TRAIT_DEATHCOMA, source)
|
|
if(stat != DEAD)
|
|
tod = null
|
|
update_stat()
|
|
|
|
/mob/living/proc/fakedeath(source, silent = FALSE)
|
|
if(stat == DEAD)
|
|
return
|
|
if(!silent)
|
|
emote("deathgasp")
|
|
ADD_TRAIT(src, TRAIT_FAKEDEATH, source)
|
|
ADD_TRAIT(src, TRAIT_DEATHCOMA, source)
|
|
tod = STATION_TIME_TIMESTAMP("hh:mm:ss", world.time)
|
|
update_stat()
|
|
|
|
///Unignores all slowdowns that lack the IGNORE_NOSLOW flag.
|
|
/mob/living/proc/unignore_slowdown(source)
|
|
REMOVE_TRAIT(src, TRAIT_IGNORESLOWDOWN, source)
|
|
update_movespeed()
|
|
|
|
///Ignores all slowdowns that lack the IGNORE_NOSLOW flag.
|
|
/mob/living/proc/ignore_slowdown(source)
|
|
ADD_TRAIT(src, TRAIT_IGNORESLOWDOWN, source)
|
|
update_movespeed()
|
|
|
|
///Ignores specific slowdowns. Accepts a list of slowdowns.
|
|
/mob/living/proc/add_movespeed_mod_immunities(source, slowdown_type, update = TRUE)
|
|
if(islist(slowdown_type))
|
|
for(var/listed_type in slowdown_type)
|
|
if(ispath(listed_type))
|
|
listed_type = "[listed_type]" //Path2String
|
|
LAZYADDASSOC(movespeed_mod_immunities, listed_type, source)
|
|
else
|
|
if(ispath(slowdown_type))
|
|
slowdown_type = "[slowdown_type]" //Path2String
|
|
LAZYADDASSOC(movespeed_mod_immunities, slowdown_type, source)
|
|
if(update)
|
|
update_movespeed()
|
|
|
|
///Unignores specific slowdowns. Accepts a list of slowdowns.
|
|
/mob/living/proc/remove_movespeed_mod_immunities(source, slowdown_type, update = TRUE)
|
|
if(islist(slowdown_type))
|
|
for(var/listed_type in slowdown_type)
|
|
if(ispath(listed_type))
|
|
listed_type = "[listed_type]" //Path2String
|
|
LAZYREMOVEASSOC(movespeed_mod_immunities, listed_type, source)
|
|
else
|
|
if(ispath(slowdown_type))
|
|
slowdown_type = "[slowdown_type]" //Path2String
|
|
LAZYREMOVEASSOC(movespeed_mod_immunities, slowdown_type, source)
|
|
if(update)
|
|
update_movespeed()
|