Files
Aurora.3/code/modules/organs/pain.dm
T
582d213b8d Some Misc Bugfixes (#22225)
This PR fixes a few bugs that were recently reported both by players and
by our new bug monitoring system. An AI agent (specifically Gemini 3)
was used to do some of the code diving process, while the fixes were
tested and verified myself manually. Yes I have actually verified the
fixes in this PR in testing.

The swap to Calculus methods for organ EMP was done by me, no AI. I love
Calculus to much to let a bot do it for me. In particular my fix to
organ EMP was to make it so that EMP damage is handled directly as
"number of fractional seconds the EMP will last", and that they tick
down cleanly per second. I did this because after fixing mechanical
organs not doing ANY EMP effects at all, I tested them and discovered
that the EMP effects were extremely underwhelming. They were like, "Your
screen only briefly filling with static for like 2 ticks", and "your
heart skips a single beat", which was lame and nonthreatening.
Significantly more fun is making the static last for N number of
seconds, and for the Heart to fail to pump for N number of seconds (very
life threatening!)

The new organ EMP handling vars are per-organ rather than a define, so
if we want there to be different EMP times for hearts vs eyes, that's
totally doable. Just make the heart have a larger recovery rate, or the
eyes have a smaller recovery rate.

---------

Signed-off-by: VMSolidus <evilexecutive@gmail.com>
Co-authored-by: Arrow768 <1331699+Arrow768@users.noreply.github.com>
2026-05-03 17:07:44 +00:00

114 lines
4.3 KiB
Plaintext

/mob/proc/flash_pain(var/target)
if(pain)
animate(pain, alpha = target, time = 15, easing = ELASTIC_EASING)
animate(pain, alpha = 0, time = 20)
/mob/var/last_pain_message = ""
/mob/var/next_pain_time = 0
// message is the custom message to be displayed
// power decides how much painkillers will stop the message
// force means it ignores anti-spam timer
/mob/living/carbon/proc/custom_pain(var/message, var/power, var/force, var/obj/item/organ/external/affecting, var/nohalloss)
if(!message || stat || !can_feel_pain() || chem_effects[CE_PAINKILLER] > power)
return 0
power -= chem_effects[CE_PAINKILLER]/2 //Take the edge off.
// Excessive halloss is horrible, just give them enough to make it visible.
if(!nohalloss && power)
if(!affecting)
adjustHalLoss(Ceiling(power/2))
else
affecting.add_pain(Ceiling(power/2))
flash_pain(min(round(2*power)+55, 255))
// Anti message spam checks
if(force || (message != last_pain_message) || (world.time >= next_pain_time))
last_pain_message = message
if(power >= 110)
flash_strong_pain()
to_chat(src, SPAN_DANGER("<font size=3>[message]</font>"))
else if(power >= 70)
to_chat(src, SPAN_DANGER("<font size=3>[message]</font>"))
else if(power >= 40)
to_chat(src, SPAN_DANGER("<font size=2>[message]</font>"))
else if(power >= 10)
to_chat(src, SPAN_DANGER("[message]"))
else
to_chat(src, SPAN_WARNING("[message]"))
var/force_emote = species.get_pain_emote(src, power)
if(force_emote && prob(power))
var/singleton/emote/use_emote = usable_emotes[force_emote]
if(use_emote && !(use_emote.message_type == AUDIBLE_MESSAGE && silent))
emote(force_emote)
next_pain_time = world.time + 5 SECONDS
/mob/living/carbon/human/proc/handle_pain()
if(stat >= DEAD)
return
if(!can_feel_pain())
return
if(world.time < next_pain_time)
return
var/maxdam = 0
var/obj/item/organ/external/damaged_organ = null
for(var/obj/item/organ/external/E in organs)
if(E.status & (ORGAN_DEAD|ORGAN_ROBOT))
continue
var/dam = E.get_damage()
// make the choice of the organ depend on damage,
// but also sometimes use one of the less damaged ones
if(dam > maxdam && (maxdam == 0 || prob(70)) )
damaged_organ = E
maxdam = dam
if(damaged_organ && chem_effects[CE_PAINKILLER] < maxdam)
if(maxdam > 10 && paralysis)
paralysis = max(0, paralysis - round(maxdam / 10))
if(maxdam > 50 && prob(maxdam / 5))
to_chat(src, SPAN_WARNING("A bolt of pain shoots through your body, causing your hands to spasm!"))
drop_item()
var/burning = damaged_organ.burn_dam > damaged_organ.brute_dam
var/msg
switch(maxdam)
if(1 to 10)
msg = "[burning ? species.organ_low_burn_message : species.organ_low_pain_message]"
if(11 to 60)
msg = "[burning ? species.organ_med_burn_message : species.organ_med_pain_message]"
if(61 to INFINITY)
msg = "[burning ? species.organ_high_burn_message : species.organ_high_pain_message]"
msg = replacetext(msg, "%PARTNAME%", damaged_organ.name)
custom_pain(msg, maxdam, prob(30), damaged_organ, TRUE)
// Damage to internal organs hurts a lot.
for(var/obj/item/organ/internal/I in internal_organs)
if(prob(1) && !((I.status & ORGAN_DEAD) || BP_IS_ROBOTIC(I)) && I.damage > 5 && I.parent_organ)
var/obj/item/organ/external/parent = get_organ(I.parent_organ)
if (!parent) continue
var/pain = 10
var/message = I.unknown_pain_location ? "You feel a dull pain in your [parent.name]..." : "You feel a dull pain radiating from your [I.name]..."
if(I.is_bruised())
pain = 25
message = I.unknown_pain_location ? "You feel a stinging pain in your [parent.name]." : "You feel a stinging pain radiating from your [I.name]."
if(I.is_broken())
pain = 50
message = I.unknown_pain_location ? "You feel a sharp pain in your [parent.name]!" : "You feel a sharp pain radiating from your [I.name]!"
src.custom_pain(message, pain, affecting = parent)
if(prob(1))
switch(getToxLoss())
if(5 to 17)
custom_pain("Your body stings slightly.", getToxLoss())
if(17 to 35)
custom_pain("Your body stings.", getToxLoss())
if(35 to 60)
custom_pain("Your body stings strongly.", getToxLoss())
if(60 to 100)
custom_pain("Your whole body hurts badly!", getToxLoss())
if(100 to INFINITY)
custom_pain("Your body aches all over, it's driving you mad!", getToxLoss())