Skip to content
This repository was archived by the owner on May 22, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions code/game/objects/items/implants/implant_misc.dm
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
imp_in.SetParalyzed(0)
imp_in.SetImmobilized(0)
imp_in.adjustStaminaLoss(-75)
imp_in.clear_stamina_regen() // We already cleared our stamina, don't continue healing
imp_in.set_resting(FALSE)
imp_in.update_mobility()

Expand Down
1 change: 1 addition & 0 deletions code/modules/antagonists/changeling/powers/adrenaline.dm
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,5 @@
user.reagents.add_reagent(/datum/reagent/medicine/changelingadrenaline, 10)
user.reagents.add_reagent(/datum/reagent/medicine/changelinghaste, 2) //For a really quick burst of speed
user.adjustStaminaLoss(-75)
user.clear_stamina_regen() // We already cleared our stamina, don't continue healing
return TRUE
Original file line number Diff line number Diff line change
Expand Up @@ -42,12 +42,13 @@
stacks++

user.adjustStaminaLoss(stacks * 1.3) //At first the changeling may regenerate stamina fast enough to nullify fatigue, but it will stack
user.clear_stamina_regen()

if(stacks == 11) //Warning message that the stacks are getting too high
to_chat(user, span_warning("Our legs are really starting to hurt..."))

sleep(4 SECONDS)

//yogs start - removes speed buff when not active
while(!active)
user.remove_movespeed_modifier(MOVESPEED_ID_CHANGELING_MUSCLES)
Expand Down
1 change: 1 addition & 0 deletions code/modules/antagonists/cult/runes.dm
Original file line number Diff line number Diff line change
Expand Up @@ -876,6 +876,7 @@ structure_check() searches for nearby cultist structures required for the invoca
L.take_overall_damage(0, tick_damage*multiplier) //yogs: only burn damage since these like all runes can be placed and activated near freely
if(is_servant_of_ratvar(L))
L.adjustStaminaLoss(tick_damage*multiplier*1.5)
L.clear_stamina_regen()

//Rite of Spectral Manifestation: Summons a ghost on top of the rune as a cultist human with no items. User must stand on the rune at all times, and takes damage for each summoned ghost.
/obj/effect/rune/manifest
Expand Down
11 changes: 10 additions & 1 deletion code/modules/mob/living/carbon/carbon.dm
Original file line number Diff line number Diff line change
Expand Up @@ -638,7 +638,7 @@
sight |= E.sight_flags
if(!isnull(E.lighting_alpha))
lighting_alpha = E.lighting_alpha

for(var/image/I in infra_images)
if(client)
client.images.Remove(I)
Expand Down Expand Up @@ -1334,3 +1334,12 @@
our_splatter.blood_dna_info = get_blood_dna_list()
var/turf/targ = get_ranged_target_turf(src, splatter_direction, splatter_strength)
INVOKE_ASYNC(our_splatter, TYPE_PROC_REF(/obj/effect/decal/cleanable/blood/hitsplatter, fly_towards), targ, splatter_strength)

/**
* Clears dynamic stamina regeneration on all limbs, typically used for continuous buildup like chems.
*
* Make sure it's used AFTER stamina damage is applied.
*/
/mob/living/carbon/clear_stamina_regen()
for(var/obj/item/bodypart/B in bodyparts)
B.stamina_cache = list()
1 change: 1 addition & 0 deletions code/modules/mob/living/carbon/status_procs.dm
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
/mob/living/carbon/proc/enter_stamcrit()
if(!(status_flags & CANKNOCKDOWN) || HAS_TRAIT(src, TRAIT_STUNIMMUNE))
return
clear_stamina_regen() // Can't passively regen out of stamcrit
if(HAS_TRAIT_FROM(src, TRAIT_INCAPACITATED, STAMINA)) //Already in stamcrit
return
if(absorb_stun(0)) //continuous effect, so we don't want it to increment the stuns absorbed.
Expand Down
3 changes: 3 additions & 0 deletions code/modules/mob/living/damage_procs.dm
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,9 @@
/mob/living/proc/setStaminaLoss(amount, updating_health = TRUE, forced = FALSE)
return

/mob/living/proc/clear_stamina_regen()
return

// heal ONE external organ, organ gets randomly selected from damaged ones.
/mob/living/proc/heal_bodypart_damage(brute = 0, burn = 0, stamina = 0, updating_health = TRUE, required_status)
adjustBruteLoss(-brute, FALSE) //zero as argument for no instant health update
Expand Down
2 changes: 2 additions & 0 deletions code/modules/reagents/chemistry/reagents/alcohol_reagents.dm
Original file line number Diff line number Diff line change
Expand Up @@ -1949,6 +1949,7 @@ All effects don't start immediately, but rather get worse over time; the rate is
/datum/reagent/consumable/ethanol/fanciulli/on_mob_metabolize(mob/living/M)
if(M.health > 0)
M.adjustStaminaLoss(20)
M.clear_stamina_regen()
. = TRUE
..()

Expand All @@ -1972,6 +1973,7 @@ All effects don't start immediately, but rather get worse over time; the rate is
/datum/reagent/consumable/ethanol/branca_menta/on_mob_metabolize(mob/living/M)
if(M.health > 0)
M.adjustStaminaLoss(35)
M.clear_stamina_regen()
. = TRUE
..()

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
if(61 to 200) //you really can only go to 120
ooo_youaregettingsleepy = 2
M.adjustStaminaLoss(ooo_youaregettingsleepy * REM)
M.clear_stamina_regen()
..()
. = TRUE

Expand All @@ -55,6 +56,7 @@
to_chat(M,span_warning("You feel more tired than you usually do, perhaps if you rest your eyes for a bit..."))
M.adjustStaminaLoss(-100, TRUE)
M.Sleeping(10 SECONDS)
M.clear_stamina_regen()
..()
. = TRUE

Expand Down Expand Up @@ -156,6 +158,7 @@
/datum/reagent/medicine/c2/tirimol/on_mob_life(mob/living/carbon/human/M)
M.adjustOxyLoss(-3 * REM)
M.adjustStaminaLoss(2 * REM)
M.clear_stamina_regen()
if(drowsycd && COOLDOWN_FINISHED(src, drowsycd))
M.adjust_drowsiness(20 SECONDS)
COOLDOWN_START(src, drowsycd, 45 SECONDS)
Expand Down
1 change: 1 addition & 0 deletions code/modules/reagents/chemistry/reagents/food_reagents.dm
Original file line number Diff line number Diff line change
Expand Up @@ -343,6 +343,7 @@
M.emote("cough")

M.adjustStaminaLoss(3)
M.clear_stamina_regen()
..()

/datum/reagent/consumable/sodiumchloride
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1296,6 +1296,7 @@
if(prob(20))
M.adjustOrganLoss(ORGAN_SLOT_BRAIN, 1*REM, 50)
M.adjustStaminaLoss(2.5*REM, 0)
M.clear_stamina_regen()
..()
return TRUE

Expand Down Expand Up @@ -1436,6 +1437,7 @@
if(41 to 80)
M.adjustOxyLoss(0.1*REM, 0)
M.adjustStaminaLoss(0.1*REM, 0)
M.clear_stamina_regen()
M.adjust_jitter_up_to(1 SECONDS, 20 SECONDS)
M.adjust_stutter_up_to(1 SECONDS, 20 SECONDS)
M.adjust_dizzy(10)
Expand All @@ -1449,10 +1451,12 @@
to_chat(M, "You feel too exhausted to continue!") // at this point you will eventually die unless you get charcoal
M.adjustOxyLoss(0.1*REM, 0)
M.adjustStaminaLoss(0.1*REM, 0)
M.clear_stamina_regen()
if(82 to INFINITY)
M.Sleeping(100, 0, TRUE)
M.adjustOxyLoss(1.5*REM, 0)
M.adjustStaminaLoss(1.5*REM, 0)
M.clear_stamina_regen()
..()
return TRUE

Expand Down Expand Up @@ -1897,4 +1901,3 @@
if(SEND_SIGNAL(M, COMSIG_HAS_NANITES))
SEND_SIGNAL(M, COMSIG_NANITE_ADJUST_VOLUME, nanite_reduction)
return ..()

3 changes: 2 additions & 1 deletion code/modules/reagents/chemistry/reagents/other_reagents.dm
Original file line number Diff line number Diff line change
Expand Up @@ -635,7 +635,7 @@
color = "#5EFF3B" //RGB: 94, 255, 59
race = /datum/species/ethereal
mutationtext = span_danger("The pain subsides. You feel... ecstatic.")

/datum/reagent/mutationtoxin/preternis
name = "Preternis Mutation Toxin"
description = "A metallic precursor toxin."
Expand Down Expand Up @@ -2081,6 +2081,7 @@
var/healthcomp = (100 - M.health) //DOES NOT ACCOUNT FOR ADMINBUS THINGS THAT MAKE YOU HAVE MORE THAN 200/210 HEALTH, OR SOMETHING OTHER THAN A HUMAN PROCESSING THIS.
if(M.getStaminaLoss() < (45 - healthcomp)) //At 50 health you would have 200 - 150 health meaning 50 compensation. 60 - 50 = 10, so would only do 10-19 stamina.)
M.adjustStaminaLoss(10)
M.clear_stamina_regen()
if(prob(30))
to_chat(M, "You should sit down and take a rest...")
..()
Expand Down
7 changes: 6 additions & 1 deletion code/modules/reagents/chemistry/reagents/toxin_reagents.dm
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,7 @@
M.adjust_slurring(3 SECONDS)
if(5 to 8)
M.adjustStaminaLoss(40, 0)
M.clear_stamina_regen()
if(9 to INFINITY)
fakedeath_active = TRUE
M.fakedeath(type)
Expand Down Expand Up @@ -404,6 +405,7 @@

/datum/reagent/toxin/staminatoxin/on_mob_life(mob/living/carbon/M)
M.adjustStaminaLoss(REM * data, 0)
M.clear_stamina_regen()
data = max(data - 1, 3)
..()
. = 1
Expand Down Expand Up @@ -676,6 +678,7 @@
if(current_cycle >= 10)
M.Sleeping(40, 0)
M.adjustStaminaLoss(10*REM, 0)
M.clear_stamina_regen()
..()
return TRUE

Expand Down Expand Up @@ -947,6 +950,7 @@

/datum/reagent/toxin/bonehurtingjuice/on_mob_life(mob/living/carbon/M)
M.adjustStaminaLoss(7.5, 0)
M.clear_stamina_regen()
if(HAS_TRAIT(M, TRAIT_CALCIUM_HEALER))
M.adjustBruteLoss(0.5, 0)
if(prob(20))
Expand Down Expand Up @@ -1004,8 +1008,9 @@

/datum/reagent/toxin/ninjatoxin/on_mob_life(mob/living/carbon/M)
M.adjustStaminaLoss(3)
M.clear_stamina_regen()
..()

/datum/reagent/toxin/mushroom_powder
name = "Mushroom Powder"
description = "Finely ground polypore mushrooms, ready to be steeped in water to make mushroom tea."
Expand Down
7 changes: 5 additions & 2 deletions code/modules/research/nanites/nanite_programs/healing.dm
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
host_mob.update_damage_overlays()
if(C.getStaminaLoss() < 41) //Should just push you into the first slowdown stage before resetting after 10 seconds
C.adjustStaminaLoss(1) //Annoying but not lethal, and won't stop stamina regen if you're over the limit
C.clear_stamina_regen()
if(prob(5))
to_chat(C, "<span class='warning'>Your injuries itch and burn as they heal.")
else
Expand Down Expand Up @@ -185,10 +186,12 @@
host_mob.update_damage_overlays()
if(C.getStaminaLoss() < 80) //Stops after hitting the second slowdown level.
C.adjustStaminaLoss(5) //Hurts a lot more
C.clear_stamina_regen()
else if(C.getBruteLoss() || C.getFireLoss()) //Prevents stamina regen if it's actively healing and you're over the limit.
C.adjustStaminaLoss(0.1)
C.adjustStaminaLoss(0.1)
C.clear_stamina_regen()
if(prob(5))
if(!C.getBruteLoss() && !C.getFireLoss())
if(!C.getBruteLoss() && !C.getFireLoss())
to_chat(C, "<span class='warning'>You feel a searing pain across your body!")//Not actively healing, so nanites will start randomly replacing healthy tissue. Ouch!
else
to_chat(C, "<span class='warning'>Your wounds burn horribly as they heal!")
Expand Down
23 changes: 18 additions & 5 deletions code/modules/surgery/bodyparts/_bodyparts.dm
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#define STAMINA_REGENERATION_COEFFICIENT 0.65 // How effective stamina regeneration is, with 1 being 100%

/obj/item/bodypart
name = "limb"
Expand Down Expand Up @@ -40,6 +41,8 @@
var/max_stamina_damage = 0
var/max_damage = 0

var/stamina_cache = list() // Lists the times that we should clear stamina damage and for how much

var/brute_reduction = 0 //Subtracted to brute damage taken
var/burn_reduction = 0 //Subtracted to burn damage taken

Expand Down Expand Up @@ -201,9 +204,17 @@
return bodypart_organs
//Return TRUE to get whatever mob this is in to update health.
/obj/item/bodypart/proc/on_life(stam_regen)
if(stamina_dam > DAMAGE_PRECISION && stam_regen) //DO NOT update health here, it'll be done in the carbon's life.
heal_damage(0, 0, INFINITY, null, FALSE)
. |= BODYPART_LIFE_UPDATE_HEALTH
if(stamina_dam > DAMAGE_PRECISION) //DO NOT update health here, it'll be done in the carbon's life.
if(stam_regen)
heal_damage(0, 0, INFINITY, null, FALSE)
stamina_cache = list()
. |= BODYPART_LIFE_UPDATE_HEALTH
else
for(var/dam_instance in stamina_cache)
if(world.time > dam_instance["expiration"])
heal_damage(0, 0, dam_instance["amount"] * STAMINA_REGENERATION_COEFFICIENT, null, FALSE)
stamina_cache -= list(dam_instance)
. |= BODYPART_LIFE_UPDATE_HEALTH

//Applies brute and burn damage to the organ. Returns 1 if the damage-icon states changed at all.
//Damage will not exceed max_damage using this proc
Expand Down Expand Up @@ -316,6 +327,8 @@
owner.updatehealth()
if(stamina > DAMAGE_PRECISION)
owner.update_stamina()
if(!HAS_TRAIT_FROM(owner, TRAIT_INCAPACITATED, STAMINA))
stamina_cache += list(list("expiration" = world.time + STAMINA_REGEN_BLOCK_TIME, "amount" = stamina))
owner.stam_regen_start_time = world.time + STAMINA_REGEN_BLOCK_TIME
. = TRUE
return update_bodypart_damage_state() || .
Expand Down Expand Up @@ -382,7 +395,7 @@

if(HAS_TRAIT(owner, TRAIT_EASYDISMEMBER))
damage *= 1.1

// If we have an open surgery site here, wound more easily
for(var/datum/surgery/S in owner.surgeries)
if(S.operated_bodypart == src)
Expand Down Expand Up @@ -465,7 +478,7 @@

if(H?.physiology?.armor?.wound)//if there is any innate wound armor (poly or genetics)
armor_ablation += H.physiology.armor.getRating(WOUND)

var/list/clothing = H.clothingonpart(src)
for(var/c in clothing)
var/obj/item/clothing/C = c
Expand Down
26 changes: 13 additions & 13 deletions yogstation/code/datums/martial/explosive_fist.dm
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@
#define ALMOST_DETONATE_COMBO "PD" //Sets streak to "Q"
#define PRE_DETONATE_COMBO "HH" //Sets streak to "P"

#define LIFEFORCE_TRADE_COMBO "MG"
#define LIFEFORCE_TRADE_COMBO "MG"
#define ALMOST_LIFEFORCE_TRADE_COMBO "LD" //Sets streak to "M"
#define PRE_LIFEFORCE_TRADE_COMBO "DG" //Sets streak to "L"

#define IMMOLATE_COMBO "JG"
#define IMMOLATE_COMBO "JG"
#define ALMOST_IMMOLATE_COMBO "ID" //Sets streak to "J"
#define PRE_IMMOLATE_COMBO "DH" //Sets strak to "I"

Expand Down Expand Up @@ -64,13 +64,13 @@
if(!can_use(A))
return
if(findtext(streak, EXPLOSIVE_DISARM_COMBO))
streak = ""
streak = ""
explosive_disarm(A,D)
return TRUE
if(findtext(streak, DETONATE_COMBO)) // End Detonate Chain
streak = ""
detonate(A,D)
return TRUE
return TRUE
if(findtext(streak, ALMOST_DETONATE_COMBO))
streak = "Q" //Q comes after P
almost_detonate(A,D)
Expand Down Expand Up @@ -163,7 +163,7 @@
D.apply_damage(damage_to_deal + 10, STAMINA, selected_zone, armor_block) //Always does at least 10

D.visible_message(span_danger("[A] activates [D]!"), \
span_userdanger("[A] activates you!"))
span_userdanger("[A] activates you!"))
log_combat(A, D, "activates(Explosive Fist)")
D.adjust_fire_stacks(4)

Expand Down Expand Up @@ -261,11 +261,11 @@
var/obj/item/bodypart/affecting_p = A.get_bodypart(BODY_ZONE_HEAD)
var/brute_block_p = A.run_armor_check(affecting_p, MELEE)
var/burn_block_p = A.run_armor_check(affecting_p, BOMB)
A.apply_damage(5, BRUTE, BODY_ZONE_HEAD, brute_block_p)
A.apply_damage(5, BURN, BODY_ZONE_HEAD, burn_block_p)
A.apply_damage(5, BRUTE, BODY_ZONE_HEAD, brute_block_p)
A.apply_damage(5, BURN, BODY_ZONE_HEAD, burn_block_p)

D.visible_message(span_danger("[A] headbutts [D]!"), \
span_userdanger("[A] headbutts you!"))
span_userdanger("[A] headbutts you!"))
log_combat(A, D, "headbutts(Explosive Fist)")
streak = ""
else
Expand All @@ -274,7 +274,7 @@
if(!(A.pulling == D))
D.grabbedby(A, 1)
D.visible_message(span_danger("[A] violently grabs [D]'s neck!"), \
span_userdanger("[A] violently grabs your neck!"))
span_userdanger("[A] violently grabs your neck!"))
log_combat(A, D, "grabs by the neck(Explosive Fist)")
playsound(get_turf(D), 'sound/weapons/punch1.ogg', 50, TRUE, -1)
streak = ""
Expand Down Expand Up @@ -321,7 +321,7 @@
D.apply_damage(A.get_punchdamagehigh() * 2 + 6, BURN, selected_zone, armor_block) //20 burn (vs bomb armor)

D.visible_message(span_danger("[A] burns [D]!"), \
span_userdanger("[A] burns you!"))
span_userdanger("[A] burns you!"))
log_combat(A, D, "burns(Explosive Fist)")

return TRUE
Expand Down Expand Up @@ -349,9 +349,9 @@
if(A.get_item_by_slot(ITEM_SLOT_HEAD)) //No helmets???
streak = ""
return FALSE
else
else
for(var/mob/living/target in view_or_range(2, A, "range"))
if(target == A)
if(target == A)
continue
target.adjustFireLoss(30)
target.ignite_mob()
Expand All @@ -361,7 +361,7 @@
var/obj/item/bodypart/hed = D.get_bodypart(BODY_ZONE_HEAD)
var/armor_block = D.run_armor_check(hed, BOMB)
D.apply_damage(A.get_punchdamagehigh() + 3, BURN, BODY_ZONE_HEAD, armor_block) //10 burn (vs bomb armor)
D.emote("scream")
D.emote("scream")
D.blur_eyes(4)

A.apply_damage(10, BURN, BODY_ZONE_CHEST, 0) //Take some unblockable damage since you're using your inner flame or something
Expand Down