mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-07-11 16:14:08 +01:00
00ccf0c6b5
# Conflicts: # .github/CODEOWNERS # .github/workflows/compile_changelogs.yml # .github/workflows/stale.yml # SQL/database_changelog.md # _maps/map_files/CatwalkStation/CatwalkStation_2023.dmm # code/__DEFINES/atom_hud.dm # code/__DEFINES/inventory.dm # code/__DEFINES/mobs.dm # code/__DEFINES/species_clothing_paths.dm # code/__DEFINES/subsystems.dm # code/__DEFINES/surgery.dm # code/__HELPERS/global_lists.dm # code/_globalvars/lists/maintenance_loot.dm # code/_globalvars/traits/_traits.dm # code/controllers/subsystem/minor_mapping.dm # code/controllers/subsystem/processing/quirks.dm # code/controllers/subsystem/shuttle.dm # code/datums/components/palette.dm # code/datums/components/surgery_initiator.dm # code/datums/diseases/advance/advance.dm # code/datums/hud.dm # code/datums/mood.dm # code/datums/mutations/chameleon.dm # code/datums/quirks/negative_quirks/nyctophobia.dm # code/datums/status_effects/debuffs/debuffs.dm # code/datums/status_effects/debuffs/drunk.dm # code/datums/status_effects/debuffs/slime/slime_leech.dm # code/datums/weather/weather.dm # code/game/data_huds.dm # code/game/objects/items.dm # code/game/objects/items/devices/scanners/health_analyzer.dm # code/game/objects/items/frog_statue.dm # code/game/objects/items/rcd/RLD.dm # code/game/objects/items/robot/items/hypo.dm # code/game/objects/items/stacks/medical.dm # code/game/objects/items/stacks/wrap.dm # code/game/objects/items/storage/garment.dm # code/game/objects/items/tools/medical/defib.dm # code/game/objects/items/weaponry.dm # code/game/objects/items/weaponry/melee/misc.dm # code/game/objects/structures/crates_lockers/closets/secure/security.dm # code/game/objects/structures/curtains.dm # code/game/objects/structures/dresser.dm # code/game/objects/structures/girders.dm # code/game/objects/structures/maintenance.dm # code/game/objects/structures/mirror.dm # code/modules/admin/greyscale_modify_menu.dm # code/modules/admin/verbs/light_debug.dm # code/modules/antagonists/ashwalker/ashwalker.dm # code/modules/antagonists/heretic/knowledge/starting_lore.dm # code/modules/antagonists/ninja/ninjaDrainAct.dm # code/modules/art/paintings.dm # code/modules/client/preferences.dm # code/modules/client/verbs/ooc.dm # code/modules/clothing/head/wig.dm # code/modules/events/disease_outbreak.dm # code/modules/holodeck/holo_effect.dm # code/modules/jobs/job_types/head_of_security.dm # code/modules/jobs/job_types/security_officer.dm # code/modules/library/skill_learning/generic_skillchips/point.dm # code/modules/mining/lavaland/ash_flora.dm # code/modules/mining/lavaland/mining_loot/megafauna/ash_drake.dm # code/modules/mob/dead/new_player/new_player.dm # code/modules/mob/living/basic/guardian/guardian.dm # code/modules/mob/living/basic/space_fauna/space_dragon/space_dragon.dm # code/modules/mob/living/carbon/carbon.dm # code/modules/mob/living/carbon/human/human.dm # code/modules/mob/living/carbon/human/human_defines.dm # code/modules/mob/living/carbon/life.dm # code/modules/mob/living/living.dm # code/modules/mob/living/living_defines.dm # code/modules/mob/mob.dm # code/modules/mob_spawn/ghost_roles/mining_roles.dm # code/modules/mod/mod_control.dm # code/modules/mod/modules/modules_general.dm # code/modules/modular_computers/computers/item/computer_ui.dm # code/modules/paperwork/paper.dm # code/modules/paperwork/paperbin.dm # code/modules/power/lighting/light.dm # code/modules/projectiles/guns/energy/kinetic_accelerator.dm # code/modules/projectiles/projectile.dm # code/modules/reagents/chemistry/reagents/drinks/alcohol_reagents.dm # code/modules/reagents/chemistry/reagents/food_reagents.dm # code/modules/reagents/chemistry/reagents/other_reagents.dm # code/modules/reagents/chemistry/reagents/pyrotechnic_reagents.dm # code/modules/research/xenobiology/crossbreeding/_clothing.dm # code/modules/research/xenobiology/crossbreeding/prismatic.dm # code/modules/surgery/advanced/brainwashing.dm # code/modules/surgery/advanced/lobotomy.dm # code/modules/surgery/amputation.dm # code/modules/surgery/blood_filter.dm # code/modules/surgery/bodyparts/_bodyparts.dm # code/modules/surgery/brain_surgery.dm # code/modules/surgery/cavity_implant.dm # code/modules/surgery/coronary_bypass.dm # code/modules/surgery/gastrectomy.dm # code/modules/surgery/healing.dm # code/modules/surgery/limb_augmentation.dm # code/modules/surgery/organ_manipulation.dm # code/modules/surgery/revival.dm # code/modules/surgery/sleeper_protocol.dm # code/modules/surgery/surgery_helpers.dm # code/modules/surgery/surgery_step.dm # code/modules/unit_tests/_unit_tests.dm # code/modules/unit_tests/designs.dm # code/modules/unit_tests/icon_state_worn.dm # code/modules/unit_tests/screenshots/screenshot_antag_icons_cultist.png # code/modules/unit_tests/screenshots/screenshot_antag_icons_headrevolutionary.png # code/modules/unit_tests/screenshots/screenshot_antag_icons_provocateur.png # code/modules/unit_tests/screenshots/screenshot_husk_body.png # code/modules/unit_tests/screenshots/screenshot_husk_body_missing_limbs.png # icons/map_icons/clothing/head/_head.dmi # icons/map_icons/clothing/shoes.dmi # icons/map_icons/items/_item.dmi # icons/mob/huds/hud.dmi # icons/mob/inhands/64x64_lefthand.dmi # icons/mob/inhands/64x64_righthand.dmi # icons/obj/machines/computer.dmi # tgui/packages/tgui/interfaces/OperatingComputer.jsx # tgui/packages/tgui/interfaces/PreferencesMenu/CharacterPreferences/MainPage.tsx # tgui/packages/tgui/interfaces/PreferencesMenu/types.ts # tgui/packages/tgui/interfaces/SurgeryInitiator.tsx # tools/icon_cutter/check.py
551 lines
19 KiB
Plaintext
551 lines
19 KiB
Plaintext
|
|
/**
|
|
* Applies damage to this mob.
|
|
*
|
|
* Sends [COMSIG_MOB_APPLY_DAMAGE]
|
|
*
|
|
* Arguuments:
|
|
* * damage - Amount of damage
|
|
* * damagetype - What type of damage to do. one of [BRUTE], [BURN], [TOX], [OXY], [STAMINA], [BRAIN].
|
|
* * def_zone - What body zone is being hit. Or a reference to what bodypart is being hit.
|
|
* * blocked - Percent modifier to damage. 100 = 100% less damage dealt, 50% = 50% less damage dealt.
|
|
* * forced - "Force" exactly the damage dealt. This means it skips damage modifier from blocked.
|
|
* * spread_damage - For carbons, spreads the damage across all bodyparts rather than just the targeted zone.
|
|
* * wound_bonus - Bonus modifier for wound chance.
|
|
* * exposed_wound_bonus - Bonus modifier for wound chance on bare skin.
|
|
* * sharpness - Sharpness of the weapon.
|
|
* * attack_direction - Direction of the attack from the attacker to [src].
|
|
* * attacking_item - Item that is attacking [src].
|
|
* * wound_clothing - If this should cause damage to clothing.
|
|
*
|
|
* Returns the amount of damage dealt.
|
|
*/
|
|
/mob/living/proc/apply_damage(
|
|
damage = 0,
|
|
damagetype = BRUTE,
|
|
def_zone = null,
|
|
blocked = 0,
|
|
forced = FALSE,
|
|
spread_damage = FALSE,
|
|
wound_bonus = 0,
|
|
exposed_wound_bonus = 0,
|
|
sharpness = NONE,
|
|
attack_direction = null,
|
|
attacking_item,
|
|
wound_clothing = TRUE,
|
|
)
|
|
SHOULD_CALL_PARENT(TRUE)
|
|
var/damage_amount = damage
|
|
if(!forced)
|
|
damage_amount *= ((100 - blocked) / 100)
|
|
damage_amount *= get_incoming_damage_modifier(damage_amount, damagetype, def_zone, sharpness, attack_direction, attacking_item)
|
|
|
|
SEND_SIGNAL(src, COMSIG_MOB_ALWAYS_APPLY_DAMAGE, damage_amount, damagetype, def_zone, blocked, wound_bonus, exposed_wound_bonus, sharpness, attack_direction, attacking_item, wound_clothing) // BUBBER ADDITION: FLAT DAMAGE MODIFIERS
|
|
|
|
if(damage_amount <= 0)
|
|
return 0
|
|
|
|
SEND_SIGNAL(src, COMSIG_MOB_APPLY_DAMAGE, damage_amount, damagetype, def_zone, blocked, wound_bonus, exposed_wound_bonus, sharpness, attack_direction, attacking_item, wound_clothing)
|
|
|
|
var/damage_dealt = 0
|
|
switch(damagetype)
|
|
if(BRUTE)
|
|
if(isbodypart(def_zone))
|
|
var/obj/item/bodypart/actual_hit = def_zone
|
|
var/delta = actual_hit.get_damage()
|
|
if(actual_hit.receive_damage(
|
|
brute = damage_amount,
|
|
burn = 0,
|
|
forced = forced,
|
|
wound_bonus = wound_bonus,
|
|
exposed_wound_bonus = exposed_wound_bonus,
|
|
sharpness = sharpness,
|
|
attack_direction = attack_direction,
|
|
damage_source = attacking_item,
|
|
wound_clothing = wound_clothing,
|
|
))
|
|
update_damage_overlays()
|
|
damage_dealt = actual_hit.get_damage() - delta // Unfortunately bodypart receive_damage doesn't return damage dealt so we do it manually
|
|
else
|
|
damage_dealt = -1 * adjust_brute_loss(damage_amount, forced = forced)
|
|
INVOKE_ASYNC(src, TYPE_PROC_REF(/mob/living, adjust_pain), damage_amount) // SKYRAT EDIT ADDITION - ERP Pain
|
|
if(BURN)
|
|
if(isbodypart(def_zone))
|
|
var/obj/item/bodypart/actual_hit = def_zone
|
|
var/delta = actual_hit.get_damage()
|
|
if(actual_hit.receive_damage(
|
|
brute = 0,
|
|
burn = damage_amount,
|
|
forced = forced,
|
|
wound_bonus = wound_bonus,
|
|
exposed_wound_bonus = exposed_wound_bonus,
|
|
sharpness = sharpness,
|
|
attack_direction = attack_direction,
|
|
damage_source = attacking_item,
|
|
wound_clothing = wound_clothing,
|
|
))
|
|
update_damage_overlays()
|
|
damage_dealt = actual_hit.get_damage() - delta // See above
|
|
else
|
|
damage_dealt = -1 * adjust_fire_loss(damage_amount, forced = forced)
|
|
INVOKE_ASYNC(src, TYPE_PROC_REF(/mob/living, adjust_pain), damage_amount) // SKYRAT EDIT ADDITION - ERP Pain
|
|
if(TOX)
|
|
damage_dealt = -1 * adjust_tox_loss(damage_amount, forced = forced)
|
|
if(OXY)
|
|
damage_dealt = -1 * adjust_oxy_loss(damage_amount, forced = forced)
|
|
if(STAMINA)
|
|
damage_dealt = -1 * adjust_stamina_loss(damage_amount, forced = forced)
|
|
if(BRAIN)
|
|
damage_dealt = -1 * adjust_organ_loss(ORGAN_SLOT_BRAIN, damage_amount)
|
|
|
|
SEND_SIGNAL(src, COMSIG_MOB_AFTER_APPLY_DAMAGE, damage_dealt, damagetype, def_zone, blocked, wound_bonus, exposed_wound_bonus, sharpness, attack_direction, attacking_item, wound_clothing)
|
|
return damage_dealt
|
|
|
|
/**
|
|
* Used in tandem with [/mob/living/proc/apply_damage] to calculate modifier applied into incoming damage
|
|
*/
|
|
/mob/living/proc/get_incoming_damage_modifier(
|
|
damage = 0,
|
|
damagetype = BRUTE,
|
|
def_zone = null,
|
|
sharpness = NONE,
|
|
attack_direction = null,
|
|
attacking_item,
|
|
)
|
|
SHOULD_CALL_PARENT(TRUE)
|
|
SHOULD_BE_PURE(TRUE)
|
|
|
|
var/list/damage_mods = list()
|
|
SEND_SIGNAL(src, COMSIG_MOB_APPLY_DAMAGE_MODIFIERS, damage_mods, damage, damagetype, def_zone, sharpness, attack_direction, attacking_item)
|
|
|
|
var/final_mod = 1
|
|
for(var/new_mod in damage_mods)
|
|
final_mod *= new_mod
|
|
return final_mod
|
|
|
|
/**
|
|
* Simply a wrapper for calling mob adjustXLoss() procs to heal a certain damage type,
|
|
* when you don't know what damage type you're healing exactly.
|
|
*/
|
|
/mob/living/proc/heal_damage_type(heal_amount = 0, damagetype = BRUTE, update_health = TRUE)
|
|
heal_amount = abs(heal_amount) * -1
|
|
|
|
switch(damagetype)
|
|
if(BRUTE)
|
|
return adjust_brute_loss(heal_amount, update_health)
|
|
if(BURN)
|
|
return adjust_fire_loss(heal_amount, update_health)
|
|
if(TOX)
|
|
return adjust_tox_loss(heal_amount, update_health)
|
|
if(OXY)
|
|
return adjust_oxy_loss(heal_amount, update_health)
|
|
if(STAMINA)
|
|
return adjust_stamina_loss(heal_amount, update_health)
|
|
|
|
/// return the damage amount for the type given
|
|
/**
|
|
* Simply a wrapper for calling mob getXLoss() procs to get a certain damage type,
|
|
* when you don't know what damage type you're getting exactly.
|
|
*/
|
|
/mob/living/proc/get_current_damage_of_type(damagetype = BRUTE)
|
|
switch(damagetype)
|
|
if(BRUTE)
|
|
return get_brute_loss()
|
|
if(BURN)
|
|
return get_fire_loss()
|
|
if(TOX)
|
|
return get_tox_loss()
|
|
if(OXY)
|
|
return get_oxy_loss()
|
|
if(STAMINA)
|
|
return get_stamina_loss()
|
|
|
|
/// return the total damage of all types which update your health
|
|
/mob/living/proc/get_total_damage(precision = DAMAGE_PRECISION)
|
|
return round(get_brute_loss() + get_fire_loss() + get_tox_loss() + get_oxy_loss(), precision)
|
|
|
|
/// Applies multiple damages at once via [apply_damage][/mob/living/proc/apply_damage]
|
|
/mob/living/proc/apply_damages(
|
|
brute = 0,
|
|
burn = 0,
|
|
tox = 0,
|
|
oxy = 0,
|
|
def_zone = null,
|
|
blocked = 0,
|
|
stamina = 0,
|
|
brain = 0,
|
|
)
|
|
var/total_damage = 0
|
|
if(brute)
|
|
total_damage += apply_damage(brute, BRUTE, def_zone, blocked)
|
|
if(burn)
|
|
total_damage += apply_damage(burn, BURN, def_zone, blocked)
|
|
if(tox)
|
|
total_damage += apply_damage(tox, TOX, def_zone, blocked)
|
|
if(oxy)
|
|
total_damage += apply_damage(oxy, OXY, def_zone, blocked)
|
|
if(stamina)
|
|
total_damage += apply_damage(stamina, STAMINA, def_zone, blocked)
|
|
if(brain)
|
|
total_damage += apply_damage(brain, BRAIN, def_zone, blocked)
|
|
return total_damage
|
|
|
|
/// applies various common status effects or common hardcoded mob effects
|
|
/mob/living/proc/apply_effect(effect = 0,effecttype = EFFECT_STUN, blocked = 0)
|
|
var/hit_percent = (100-blocked)/100
|
|
if(!effect || (hit_percent <= 0))
|
|
return FALSE
|
|
switch(effecttype)
|
|
if(EFFECT_STUN)
|
|
Stun(effect * hit_percent)
|
|
if(EFFECT_KNOCKDOWN)
|
|
Knockdown(effect * hit_percent)
|
|
if(EFFECT_PARALYZE)
|
|
Paralyze(effect * hit_percent)
|
|
if(EFFECT_IMMOBILIZE)
|
|
Immobilize(effect * hit_percent)
|
|
if(EFFECT_UNCONSCIOUS)
|
|
Unconscious(effect * hit_percent)
|
|
|
|
return TRUE
|
|
|
|
/**
|
|
* Applies multiple effects at once via [/mob/living/proc/apply_effect]
|
|
*
|
|
* Pretty much only used for projectiles applying effects on hit,
|
|
* don't use this for anything else please just cause the effects directly
|
|
*/
|
|
/mob/living/proc/apply_effects(
|
|
stun = 0,
|
|
knockdown = 0,
|
|
unconscious = 0,
|
|
slur = 0 SECONDS, // Speech impediment, not technically an effect
|
|
stutter = 0 SECONDS, // Ditto
|
|
eyeblur = 0 SECONDS,
|
|
drowsy = 0 SECONDS,
|
|
blocked = 0, // This one's not an effect, don't be confused - it's block chance
|
|
stamina = 0, // This one's a damage type, and not an effect
|
|
jitter = 0 SECONDS,
|
|
paralyze = 0,
|
|
immobilize = 0,
|
|
)
|
|
|
|
if(blocked >= 100)
|
|
return FALSE
|
|
|
|
if(stun)
|
|
apply_effect(stun, EFFECT_STUN, blocked)
|
|
if(knockdown)
|
|
apply_effect(knockdown, EFFECT_KNOCKDOWN, blocked)
|
|
if(unconscious)
|
|
apply_effect(unconscious, EFFECT_UNCONSCIOUS, blocked)
|
|
if(paralyze)
|
|
apply_effect(paralyze, EFFECT_PARALYZE, blocked)
|
|
if(immobilize)
|
|
apply_effect(immobilize, EFFECT_IMMOBILIZE, blocked)
|
|
|
|
if(stamina)
|
|
apply_damage(stamina, STAMINA, null, blocked)
|
|
|
|
if(drowsy)
|
|
adjust_drowsiness(drowsy)
|
|
if(eyeblur)
|
|
adjust_eye_blur_up_to(eyeblur, eyeblur)
|
|
if(jitter && !check_stun_immunity(CANSTUN))
|
|
adjust_jitter(jitter)
|
|
if(slur)
|
|
adjust_slurring(slur)
|
|
if(stutter)
|
|
adjust_stutter(stutter)
|
|
|
|
return TRUE
|
|
|
|
/// Returns a multiplier to apply to a specific kind of damage
|
|
/mob/living/proc/get_damage_mod(damage_type)
|
|
switch(damage_type)
|
|
if (OXY)
|
|
return HAS_TRAIT(src, TRAIT_NOBREATH) ? 0 : 1
|
|
if (TOX)
|
|
if (HAS_TRAIT(src, TRAIT_TOXINLOVER))
|
|
return -1
|
|
return HAS_TRAIT(src, TRAIT_TOXIMMUNE) ? 0 : 1
|
|
return 1
|
|
|
|
/mob/living/proc/get_brute_loss()
|
|
return bruteloss
|
|
|
|
/mob/living/proc/can_adjust_brute_loss(amount, forced, required_bodytype)
|
|
if(!forced && HAS_TRAIT(src, TRAIT_GODMODE))
|
|
return FALSE
|
|
if(SEND_SIGNAL(src, COMSIG_LIVING_ADJUST_BRUTE_DAMAGE, BRUTE, amount, forced) & COMPONENT_IGNORE_CHANGE)
|
|
return FALSE
|
|
return TRUE
|
|
|
|
/mob/living/proc/adjust_brute_loss(amount, updating_health = TRUE, forced = FALSE, required_bodytype = ALL)
|
|
if (!can_adjust_brute_loss(amount, forced, required_bodytype))
|
|
return 0
|
|
. = bruteloss
|
|
bruteloss = clamp((bruteloss + (amount * CONFIG_GET(number/damage_multiplier))), 0, maxHealth * 2)
|
|
. -= bruteloss
|
|
if(!.) // no change, no need to update
|
|
return 0
|
|
if(updating_health)
|
|
updatehealth()
|
|
|
|
|
|
/mob/living/proc/set_brute_loss(amount, updating_health = TRUE, forced = FALSE, required_bodytype = ALL)
|
|
if(!forced && HAS_TRAIT(src, TRAIT_GODMODE))
|
|
return FALSE
|
|
. = bruteloss
|
|
bruteloss = amount
|
|
|
|
if(!.) // no change, no need to update
|
|
return FALSE
|
|
if(updating_health)
|
|
updatehealth()
|
|
. -= bruteloss
|
|
|
|
/mob/living/proc/get_oxy_loss()
|
|
return oxyloss
|
|
|
|
/mob/living/proc/can_adjust_oxy_loss(amount, forced, required_biotype, required_respiration_type)
|
|
if(!forced)
|
|
if(HAS_TRAIT(src, TRAIT_GODMODE))
|
|
return FALSE
|
|
if (required_respiration_type)
|
|
var/obj/item/organ/lungs/affected_lungs = get_organ_slot(ORGAN_SLOT_LUNGS)
|
|
if(isnull(affected_lungs))
|
|
if(!(mob_respiration_type & required_respiration_type)) // if the mob has no lungs, use mob_respiration_type
|
|
return FALSE
|
|
else
|
|
if(!(affected_lungs.respiration_type & required_respiration_type)) // otherwise use the lungs' respiration_type
|
|
return FALSE
|
|
if(SEND_SIGNAL(src, COMSIG_LIVING_ADJUST_OXY_DAMAGE, OXY, amount, forced) & COMPONENT_IGNORE_CHANGE)
|
|
return FALSE
|
|
return TRUE
|
|
|
|
/mob/living/proc/adjust_oxy_loss(amount, updating_health = TRUE, forced = FALSE, required_biotype = ALL, required_respiration_type = ALL)
|
|
if(!can_adjust_oxy_loss(amount, forced, required_biotype, required_respiration_type))
|
|
return 0
|
|
. = oxyloss
|
|
oxyloss = clamp((oxyloss + (amount * CONFIG_GET(number/damage_multiplier))), 0, maxHealth * 2)
|
|
. -= oxyloss
|
|
if(!.) // no change, no need to update
|
|
return FALSE
|
|
if(updating_health)
|
|
updatehealth()
|
|
|
|
/mob/living/proc/set_oxy_loss(amount, updating_health = TRUE, forced = FALSE, required_biotype = ALL, required_respiration_type = ALL)
|
|
if(!forced)
|
|
if(HAS_TRAIT(src, TRAIT_GODMODE))
|
|
return FALSE
|
|
|
|
var/obj/item/organ/lungs/affected_lungs = get_organ_slot(ORGAN_SLOT_LUNGS)
|
|
if(isnull(affected_lungs))
|
|
if(!(mob_respiration_type & required_respiration_type))
|
|
return FALSE
|
|
else
|
|
if(!(affected_lungs.respiration_type & required_respiration_type))
|
|
return FALSE
|
|
. = oxyloss
|
|
oxyloss = amount
|
|
. -= oxyloss
|
|
if(!.) // no change, no need to update
|
|
return FALSE
|
|
if(updating_health)
|
|
updatehealth()
|
|
|
|
/mob/living/proc/get_tox_loss()
|
|
return toxloss
|
|
|
|
/mob/living/proc/can_adjust_tox_loss(amount, forced, required_biotype = ALL)
|
|
if(!forced && (HAS_TRAIT(src, TRAIT_GODMODE) || !(mob_biotypes & required_biotype)))
|
|
return FALSE
|
|
if(SEND_SIGNAL(src, COMSIG_LIVING_ADJUST_TOX_DAMAGE, TOX, amount, forced) & COMPONENT_IGNORE_CHANGE)
|
|
return FALSE
|
|
return TRUE
|
|
|
|
/mob/living/proc/adjust_tox_loss(amount, updating_health = TRUE, forced = FALSE, required_biotype = ALL)
|
|
if(!can_adjust_tox_loss(amount, forced, required_biotype))
|
|
return 0
|
|
|
|
if(!forced && HAS_TRAIT(src, TRAIT_TOXINLOVER)) //damage becomes healing and healing becomes damage
|
|
amount = -amount
|
|
if(HAS_TRAIT(src, TRAIT_TOXIMMUNE)) //Prevents toxin damage, but not healing
|
|
amount = min(amount, 0)
|
|
if(amount > 0)
|
|
adjust_blood_volume(-5 * amount)
|
|
else
|
|
adjust_blood_volume(-amount)
|
|
|
|
else if(!forced && HAS_TRAIT(src, TRAIT_TOXIMMUNE)) //Prevents toxin damage, but not healing
|
|
amount = min(amount, 0)
|
|
|
|
. = toxloss
|
|
toxloss = clamp((toxloss + (amount * CONFIG_GET(number/damage_multiplier))), 0, maxHealth * 2)
|
|
. -= toxloss
|
|
|
|
if(!.) // no change, no need to update
|
|
return FALSE
|
|
|
|
if(updating_health)
|
|
updatehealth()
|
|
|
|
|
|
/mob/living/proc/set_tox_loss(amount, updating_health = TRUE, forced = FALSE, required_biotype = ALL)
|
|
if(!forced && HAS_TRAIT(src, TRAIT_GODMODE))
|
|
return FALSE
|
|
if(!forced && !(mob_biotypes & required_biotype))
|
|
return FALSE
|
|
. = toxloss
|
|
toxloss = amount
|
|
. -= toxloss
|
|
if(!.) // no change, no need to update
|
|
return FALSE
|
|
if(updating_health)
|
|
updatehealth()
|
|
|
|
/mob/living/proc/get_fire_loss()
|
|
return fireloss
|
|
|
|
/mob/living/proc/can_adjust_fire_loss(amount, forced, required_bodytype)
|
|
if(!forced && HAS_TRAIT(src, TRAIT_GODMODE))
|
|
return FALSE
|
|
if(SEND_SIGNAL(src, COMSIG_LIVING_ADJUST_BURN_DAMAGE, BURN, amount, forced) & COMPONENT_IGNORE_CHANGE)
|
|
return FALSE
|
|
return TRUE
|
|
|
|
/mob/living/proc/adjust_fire_loss(amount, updating_health = TRUE, forced = FALSE, required_bodytype = ALL)
|
|
if(!can_adjust_fire_loss(amount, forced, required_bodytype))
|
|
return 0
|
|
. = fireloss
|
|
fireloss = clamp((fireloss + (amount * CONFIG_GET(number/damage_multiplier))), 0, maxHealth * 2)
|
|
. -= fireloss
|
|
if(. == 0) // no change, no need to update
|
|
return
|
|
if(updating_health)
|
|
updatehealth()
|
|
|
|
/mob/living/proc/set_fire_loss(amount, updating_health = TRUE, forced = FALSE, required_bodytype = ALL)
|
|
if(!forced && HAS_TRAIT(src, TRAIT_GODMODE))
|
|
return 0
|
|
. = fireloss
|
|
fireloss = amount
|
|
. -= fireloss
|
|
if(. == 0) // no change, no need to update
|
|
return 0
|
|
if(updating_health)
|
|
updatehealth()
|
|
|
|
/mob/living/proc/adjust_organ_loss(slot, amount, maximum, required_organ_flag)
|
|
return
|
|
|
|
/mob/living/proc/set_organ_loss(slot, amount, maximum, required_organ_flag)
|
|
return
|
|
|
|
/mob/living/proc/get_organ_loss(slot, required_organ_flag)
|
|
return
|
|
|
|
/mob/living/proc/get_stamina_loss()
|
|
return staminaloss
|
|
|
|
/mob/living/proc/can_adjust_stamina_loss(amount, forced, required_biotype = ALL)
|
|
if(!forced && (!(mob_biotypes & required_biotype) || HAS_TRAIT(src, TRAIT_GODMODE)))
|
|
return FALSE
|
|
if(SEND_SIGNAL(src, COMSIG_LIVING_ADJUST_STAMINA_DAMAGE, STAMINA, amount, forced) & COMPONENT_IGNORE_CHANGE)
|
|
return FALSE
|
|
return TRUE
|
|
|
|
/mob/living/proc/adjust_stamina_loss(amount, updating_stamina = TRUE, forced = FALSE, required_biotype = ALL)
|
|
if(!can_adjust_stamina_loss(amount, forced, required_biotype))
|
|
return 0
|
|
var/old_amount = staminaloss
|
|
staminaloss = clamp((staminaloss + (amount * CONFIG_GET(number/damage_multiplier))), 0, max_stamina)
|
|
var/delta = old_amount - staminaloss
|
|
if(delta <= 0)
|
|
// need to check for stamcrit AFTER canadjust but BEFORE early return here
|
|
received_stamina_damage(staminaloss, -1 * delta)
|
|
if(delta == 0) // no change, no need to update
|
|
return 0
|
|
if(updating_stamina)
|
|
updatehealth()
|
|
return delta
|
|
|
|
/mob/living/proc/set_stamina_loss(amount, updating_stamina = TRUE, forced = FALSE, required_biotype = ALL)
|
|
if(!forced && HAS_TRAIT(src, TRAIT_GODMODE))
|
|
return 0
|
|
if(!forced && !(mob_biotypes & required_biotype))
|
|
return 0
|
|
var/old_amount = staminaloss
|
|
staminaloss = amount
|
|
var/delta = old_amount - staminaloss
|
|
if(delta <= 0 && amount >= DAMAGE_PRECISION)
|
|
received_stamina_damage(staminaloss, -1 * delta, amount)
|
|
if(delta == 0) // no change, no need to update
|
|
return 0
|
|
if(updating_stamina)
|
|
updatehealth()
|
|
return delta
|
|
|
|
/// The mob has received stamina damage
|
|
///
|
|
/// - current_level: The mob's current stamina damage amount (to save unnecessary get_stamina_loss() calls)
|
|
/// - amount_actual: The amount of stamina damage received, in actuality
|
|
/// For example, if you are taking 50 stamina damage but are at 90, you would actually only receive 30 stamina damage (due to the cap)
|
|
/// - amount: The amount of stamina damage received, raw
|
|
/mob/living/proc/received_stamina_damage(current_level, amount_actual, amount)
|
|
addtimer(CALLBACK(src, PROC_REF(set_stamina_loss), 0, TRUE, TRUE), stamina_regen_time, TIMER_UNIQUE|TIMER_OVERRIDE)
|
|
|
|
/**
|
|
* heal ONE external organ, organ gets randomly selected from damaged ones.
|
|
*
|
|
* returns the net change in damage
|
|
*/
|
|
/mob/living/proc/heal_bodypart_damage(brute = 0, burn = 0, updating_health = TRUE, required_bodytype = NONE, target_zone = null)
|
|
. = (adjust_brute_loss(-abs(brute), updating_health = FALSE) + adjust_fire_loss(-abs(burn), updating_health = FALSE))
|
|
if(!.) // no change, no need to update
|
|
return FALSE
|
|
if(updating_health)
|
|
updatehealth()
|
|
|
|
/// damage ONE external organ, organ gets randomly selected from damaged ones.
|
|
/mob/living/proc/take_bodypart_damage(brute = 0, burn = 0, updating_health = TRUE, required_bodytype, check_armor = FALSE, wound_bonus = 0, exposed_wound_bonus = 0, sharpness = NONE)
|
|
. = (adjust_brute_loss(abs(brute), updating_health = FALSE) + adjust_fire_loss(abs(burn), updating_health = FALSE))
|
|
if(!.) // no change, no need to update
|
|
return FALSE
|
|
if(updating_health)
|
|
updatehealth()
|
|
|
|
/// heal MANY bodyparts, in random order. note: stamina arg nonfunctional for carbon mobs
|
|
/mob/living/proc/heal_overall_damage(brute = 0, burn = 0, stamina = 0, required_bodytype, updating_health = TRUE, forced = FALSE)
|
|
. = (adjust_brute_loss(-abs(brute), updating_health = FALSE, forced = forced) + \
|
|
adjust_fire_loss(-abs(burn), updating_health = FALSE, forced = forced) + \
|
|
adjust_stamina_loss(-abs(stamina), updating_stamina = FALSE, forced = forced))
|
|
if(!.) // no change, no need to update
|
|
return FALSE
|
|
if(updating_health)
|
|
updatehealth()
|
|
|
|
/// damage MANY bodyparts, in random order. note: stamina arg nonfunctional for carbon mobs
|
|
/mob/living/proc/take_overall_damage(brute = 0, burn = 0, stamina = 0, updating_health = TRUE, forced = FALSE, required_bodytype)
|
|
. = (adjust_brute_loss(abs(brute), updating_health = FALSE, forced = forced) + \
|
|
adjust_fire_loss(abs(burn), updating_health = FALSE, forced = forced) + \
|
|
adjust_stamina_loss(abs(stamina), updating_stamina = FALSE, forced = forced))
|
|
if(!.) // no change, no need to update
|
|
return FALSE
|
|
if(updating_health)
|
|
updatehealth()
|
|
|
|
///heal up to amount damage, in a given order
|
|
/mob/living/proc/heal_ordered_damage(amount, list/damage_types, update_health = TRUE)
|
|
. = 0 //we'll return the amount of damage healed
|
|
for(var/damagetype in damage_types)
|
|
var/amount_to_heal = min(abs(amount), get_current_damage_of_type(damagetype)) //heal only up to the amount of damage we have
|
|
if(amount_to_heal)
|
|
. += heal_damage_type(amount_to_heal, damagetype, FALSE)
|
|
amount -= amount_to_heal //remove what we healed from our current amount
|
|
if(!amount)
|
|
break
|
|
if(. && update_health)
|
|
updatehealth()
|