[MIRROR] Cuts the number of apply_damage copypaste procs from 3(.5) to 1, fixing a few bugs along the way [MDB IGNORE] (#24619)

* Cuts the number of `apply_damage` copypaste procs from 3(.5) to 1, fixing a few bugs along the way

* Update _species.dm

* Update damage_procs.dm

* Modular adjustments

* Update mutant_species.dm

* Update mutant_species.dm

---------

Co-authored-by: MrMelbert <51863163+MrMelbert@users.noreply.github.com>
Co-authored-by: Bloop <13398309+vinylspiders@users.noreply.github.com>
This commit is contained in:
SkyratBot
2023-10-28 00:22:32 +02:00
committed by GitHub
parent f4698f05af
commit e7a1ec5ba2
31 changed files with 427 additions and 299 deletions
@@ -90,11 +90,16 @@
///from base of mob/set_invis_see(): (new_invis, old_invis)
#define COMSIG_MOB_SEE_INVIS_CHANGE "mob_see_invis_change"
///from base of /mob/living/proc/apply_damage(): (damage, damagetype, def_zone, blocked, wound_bonus, bare_wound_bonus, sharpness, attack_direction, attacking_item)
/// from /mob/living/proc/apply_damage(): (list/damage_mods, damage, damagetype, def_zone, sharpness, attack_direction, attacking_item)
/// allows you to add multiplicative damage modifiers to the damage mods argument to adjust incoming damage
/// not sent if the apply damage call was forced
#define COMSIG_MOB_APPLY_DAMAGE_MODIFIERS "mob_apply_damage_modifiers"
/// from base of /mob/living/proc/apply_damage(): (damage, damagetype, def_zone, blocked, wound_bonus, bare_wound_bonus, sharpness, attack_direction, attacking_item)
#define COMSIG_MOB_APPLY_DAMAGE "mob_apply_damage"
///from /mob/living/proc/apply_damage(), works like above but after the damage is actually inflicted: (damage, damagetype, def_zone, blocked, wound_bonus, bare_wound_bonus, sharpness, attack_direction, attacking_item)
/// from /mob/living/proc/apply_damage(): (damage, damagetype, def_zone, blocked, wound_bonus, bare_wound_bonus, sharpness, attack_direction, attacking_item)
/// works like above but after the damage is actually inflicted
#define COMSIG_MOB_AFTER_APPLY_DAMAGE "mob_after_apply_damage"
///from base of /mob/living/attack_alien(): (user)
#define COMSIG_MOB_ATTACK_ALIEN "mob_attack_alien"
///from base of /mob/throw_item(): (atom/target)
+4 -1
View File
@@ -91,13 +91,16 @@
detonate()
///Called when you attack a specific body part of the thing this is equipped on. Useful for exploding pants.
/datum/component/explodable/proc/explodable_attack_zone(datum/source, damage, damagetype, def_zone)
/datum/component/explodable/proc/explodable_attack_zone(datum/source, damage, damagetype, def_zone, ...)
SIGNAL_HANDLER
if(!def_zone)
return
if(damagetype != BURN) //Don't bother if it's not fire.
return
if(isbodypart(def_zone))
var/obj/item/bodypart/hitting = def_zone
def_zone = hitting.body_zone
if(!is_hitting_zone(def_zone)) //You didn't hit us! ha!
return
detonate()
+12 -10
View File
@@ -172,25 +172,27 @@
qdel(src)
///If the shooter is hit by an attack, they have a 50% chance to flinch and fire. If it hit the arm holding the trigger, it's an 80% chance to fire instead
/datum/component/gunpoint/proc/flinch(attacker, damage, damagetype, def_zone)
/datum/component/gunpoint/proc/flinch(mob/living/source, damage_amount, damagetype, def_zone, blocked, wound_bonus, bare_wound_bonus, sharpness, attack_direction, attacking_item)
SIGNAL_HANDLER
var/mob/living/shooter = parent
if(attacker == shooter)
return // somehow this wasn't checked for months but no one tried punching themselves to initiate the shot, amazing
if(!attack_direction) // No fliching from yourself
return
var/flinch_chance = 50
var/gun_hand = LEFT_HANDS
var/gun_hand = (source.get_held_index_of_item(weapon) % 2) ? BODY_ZONE_L_ARM : BODY_ZONE_R_ARM
if(shooter.held_items[RIGHT_HANDS] == weapon)
gun_hand = RIGHT_HANDS
if(isbodypart(def_zone))
var/obj/item/bodypart/hitting = def_zone
def_zone = hitting.body_zone
if((def_zone == BODY_ZONE_L_ARM && gun_hand == LEFT_HANDS) || (def_zone == BODY_ZONE_R_ARM && gun_hand == RIGHT_HANDS))
if(def_zone == gun_hand)
flinch_chance = 80
if(prob(flinch_chance))
shooter.visible_message(span_danger("[shooter] flinches!"), \
span_danger("You flinch!"))
source.visible_message(
span_danger("[source] flinches!"),
span_danger("You flinch!"),
)
INVOKE_ASYNC(src, PROC_REF(trigger_reaction))
#undef GUNPOINT_DELAY_STAGE_2
+1 -1
View File
@@ -33,7 +33,7 @@
return
return COMPONENT_INCOMPATIBLE
/datum/component/pinata/proc/damage_inflicted(obj/target, damage, damage_type)
/datum/component/pinata/proc/damage_inflicted(obj/target, damage, damage_type, ...)
SIGNAL_HANDLER
if(damage < minimum_damage || damage_type == STAMINA || damage_type == OXY)
return
+1 -1
View File
@@ -66,7 +66,7 @@
deltimer(regeneration_start_timer)
/// When you take damage, reset the cooldown and start processing
/datum/component/regenerator/proc/on_take_damage(datum/source, damage, damagetype)
/datum/component/regenerator/proc/on_take_damage(datum/source, damage, damagetype, ...)
SIGNAL_HANDLER
if (damagetype in ignore_damage_types)
+1 -1
View File
@@ -456,7 +456,7 @@
// Negative effects
/datum/component/style/proc/on_take_damage()
/datum/component/style/proc/on_take_damage(...)
SIGNAL_HANDLER
point_multiplier = round(max(point_multiplier - 0.3, 1), 0.1)
@@ -34,14 +34,16 @@
/datum/quirk/glass_jaw/proc/punch_out(mob/living/carbon/source, damage, damagetype, def_zone, blocked, wound_bonus, bare_wound_bonus, sharpness, attack_direction, attacking_item)
SIGNAL_HANDLER
if((damagetype != BRUTE) || (def_zone != BODY_ZONE_HEAD))
if(isbodypart(def_zone))
var/obj/item/bodypart/hitting = def_zone
def_zone = hitting.body_zone
if(damagetype != BRUTE || def_zone != BODY_ZONE_HEAD)
return
var/actual_damage = damage - (damage * blocked/100)
//only roll for knockouts at 5 damage or more
if(actual_damage < 5)
if(damage < 5)
return
//blunt items are more likely to knock out, but sharp ones are still capable of doing it
if(prob(CEILING(actual_damage * (sharpness & (SHARP_EDGED|SHARP_POINTY) ? 0.65 : 1), 1)))
if(prob(CEILING(damage * (sharpness & (SHARP_EDGED|SHARP_POINTY) ? 0.65 : 1), 1)))
//don't display the message if little mac is already KO'd
if(!source.IsUnconscious())
source.visible_message(
@@ -56,11 +56,11 @@
greyscale_config = /datum/greyscale_config/mutant_organ
greyscale_colors = ROACH_COLORS
/// Timer ID for resetting the damage resistance applied from attacks from behind
var/defense_timerid
/// Bodypart overlay applied to the chest the heart is in
var/datum/bodypart_overlay/simple/roach_shell/roach_shell
COOLDOWN_DECLARE(harden_effect_cd)
/obj/item/organ/internal/heart/roach/Initialize(mapload)
. = ..()
AddElement(/datum/element/noticable_organ, "has hardened, somewhat translucent skin.")
@@ -78,7 +78,8 @@
var/mob/living/carbon/human/human_owner = organ_owner
RegisterSignal(human_owner, COMSIG_MOB_APPLY_DAMAGE, PROC_REF(modify_damage))
RegisterSignal(human_owner, COMSIG_MOB_APPLY_DAMAGE_MODIFIERS, PROC_REF(modify_damage))
RegisterSignal(human_owner, COMSIG_MOB_AFTER_APPLY_DAMAGE, PROC_REF(do_block_effect))
human_owner.physiology.knockdown_mod *= 3
var/obj/item/bodypart/chest/chest = human_owner.get_bodypart(BODY_ZONE_CHEST)
@@ -92,50 +93,55 @@
var/mob/living/carbon/human/human_owner = organ_owner
UnregisterSignal(human_owner, COMSIG_MOB_APPLY_DAMAGE)
UnregisterSignal(human_owner, list(COMSIG_MOB_APPLY_DAMAGE_MODIFIERS, COMSIG_MOB_AFTER_APPLY_DAMAGE))
human_owner.physiology.knockdown_mod /= 3
if(defense_timerid)
reset_damage(human_owner)
var/obj/item/bodypart/chest/chest = human_owner.get_bodypart(BODY_ZONE_CHEST)
chest.remove_bodypart_overlay(roach_shell)
human_owner.update_body_parts()
/**
* Signal proc for [COMSIG_MOB_APPLY_DAMAGE]
* Signal proc for [COMSIG_MOB_APPLY_DAMAGE_MODIFIERS]
*
* Being hit with brute damage in the back will impart a large damage resistance bonus for a very short period.
* Adds a 0.5 modifier to attacks from the back
*/
/obj/item/organ/internal/heart/roach/proc/modify_damage(datum/source, damage, damagetype, def_zone, blocked, wound_bonus, bare_wound_bonus, sharpness, attack_direction, obj/item/attacking_item)
/obj/item/organ/internal/heart/roach/proc/modify_damage(mob/living/carbon/human/source, list/damage_mods, damage_amount, damagetype, def_zone, sharpness, attack_direction, obj/item/attacking_item)
SIGNAL_HANDLER
if(!ishuman(owner) || !attack_direction || damagetype != BRUTE || owner.stat >= UNCONSCIOUS)
if(!is_blocking(source, damage_amount, damagetype, attack_direction))
return
var/mob/living/carbon/human/human_owner = owner
damage_mods += 0.5
/**
* Signal proc for [COMSIG_MOB_AFTER_APPLY_DAMAGE]
*
* Does a special effect if we blocked damage with our back
*/
/obj/item/organ/internal/heart/roach/proc/do_block_effect(mob/living/carbon/human/source, damage_dealt, damagetype, def_zone, blocked, wound_bonus, bare_wound_bonus, sharpness, attack_direction, obj/item/attacking_item)
SIGNAL_HANDLER
if(!is_blocking(source, damage_dealt, damagetype, attack_direction))
return
if(COOLDOWN_FINISHED(src, harden_effect_cd))
source.visible_message(span_warning("[source]'s back hardens against the blow!"))
playsound(source, 'sound/effects/constructform.ogg', 25, vary = TRUE, extrarange = SHORT_RANGE_SOUND_EXTRARANGE)
COOLDOWN_START(src, harden_effect_cd, 5 SECONDS) // Cooldown resets EVERY time we get hit
/// Checks if the passed mob is in a valid state to be blocking damage with the roach shell
/obj/item/organ/internal/heart/roach/proc/is_blocking(mob/living/carbon/human/blocker, damage_amount, damagetype, attack_direction)
if(damage_amount < 5 || damagetype != BRUTE || !attack_direction)
return
if(!ishuman(blocker) || blocker.stat >= UNCONSCIOUS)
return FALSE
// No tactical spinning
if(human_owner.flags_1 & IS_SPINNING_1)
return
// If we're lying down, or were attacked from the back, we get armor.
var/should_armor_up = (human_owner.body_position == LYING_DOWN) || (human_owner.dir & attack_direction)
if(!should_armor_up)
return
// Take 50% less damage from attack behind us
if(!defense_timerid)
human_owner.physiology.brute_mod /= 2
human_owner.visible_message(span_warning("[human_owner]'s back hardens against the blow!"))
playsound(human_owner, 'sound/effects/constructform.ogg', 25, vary = TRUE, extrarange = SHORT_RANGE_SOUND_EXTRARANGE)
defense_timerid = addtimer(CALLBACK(src, PROC_REF(reset_damage), owner), 5 SECONDS, TIMER_UNIQUE|TIMER_OVERRIDE)
/obj/item/organ/internal/heart/roach/proc/reset_damage(mob/living/carbon/human/human_owner)
defense_timerid = null
if(!QDELETED(human_owner))
human_owner.physiology.brute_mod *= 2
human_owner.visible_message(span_warning("[human_owner]'s back softens again."))
if(blocker.flags_1 & IS_SPINNING_1)
return FALSE
if(blocker.body_position == LYING_DOWN || (blocker.dir & attack_direction))
return TRUE
return FALSE
// Simple overlay so we can add a roach shell to guys with roach hearts
/datum/bodypart_overlay/simple/roach_shell
@@ -112,7 +112,7 @@
living_mob.Paralyze(20)
living_mob.Knockdown(200)
living_mob.soundbang_act(1, 200, 10, 15)
if(living_mob.apply_damages(10, 10))
if(living_mob.apply_damages(brute = 10, burn = 10))
to_chat(living_mob, span_userdanger("The blast from \the [src] bruises and burns you!"))
// only checking if they're on top of the tile, cause being one tile over will be its own punishment
@@ -190,7 +190,7 @@
return ..()
/// When we take fire damage (or... technically also cold damage, we don't differentiate), zap a nearby APC
/datum/status_effect/golem/plasma/proc/on_burned(datum/source, damage, damagetype)
/datum/status_effect/golem/plasma/proc/on_burned(datum/source, damage, damagetype, ...)
SIGNAL_HANDLER
if(damagetype != BURN)
return
@@ -190,7 +190,7 @@
qdel(src)
/// Signal proc for [COMSIG_MOB_APPLY_DAMAGE], being damaged past a threshold will roll a chance to stop the effect
/datum/status_effect/shadow_cloak/proc/on_damaged(datum/source, damage, damagetype)
/datum/status_effect/shadow_cloak/proc/on_damaged(datum/source, damage, damagetype, ...)
SIGNAL_HANDLER
// Stam damage is generally bursty, so we'll half it
@@ -108,7 +108,7 @@
)
/// Transfers damage from the avatar to the old_body
/datum/component/avatar_connection/proc/on_linked_damage(datum/source, damage, damage_type, def_zone, blocked, forced)
/datum/component/avatar_connection/proc/on_linked_damage(datum/source, damage, damage_type, def_zone, blocked, ...)
SIGNAL_HANDLER
var/mob/living/carbon/old_body = old_body_ref?.resolve()
@@ -123,7 +123,7 @@
if(damage > 30 && prob(30))
INVOKE_ASYNC(old_body, TYPE_PROC_REF(/mob/living, emote), "scream")
old_body.apply_damage(damage, damage_type, def_zone, blocked, forced, wound_bonus = CANT_WOUND)
old_body.apply_damage(damage, damage_type, def_zone, blocked, wound_bonus = CANT_WOUND)
if(old_body.stat > SOFT_CRIT) // KO!
full_avatar_disconnect(forced = TRUE)
+4 -4
View File
@@ -58,10 +58,10 @@
"health" = creature.health,
"name" = creature.name,
"pilot" = pilot,
"brute" = creature.get_current_damage_of_type(BRUTE),
"burn" = creature.get_current_damage_of_type(BURN),
"tox" = creature.get_current_damage_of_type(TOX),
"oxy" = creature.get_current_damage_of_type(OXY),
"brute" = creature.getBruteLoss(),
"burn" = creature.getFireLoss(),
"tox" = creature.getToxLoss(),
"oxy" = creature.getOxyLoss(),
))
return hosted_avatars
@@ -141,7 +141,7 @@
return COMPONENT_CLEANED
/// When you take brute damage, schedule an explosion
/datum/status_effect/stacking/brimdust_coating/proc/on_take_damage(datum/source, damage, damagetype)
/datum/status_effect/stacking/brimdust_coating/proc/on_take_damage(datum/source, damage, damagetype, ...)
SIGNAL_HANDLER
if(damagetype != BRUTE)
return
@@ -102,9 +102,7 @@
// Goliaths can summon tentacles more frequently as they take damage, scary.
/mob/living/basic/mining/goliath/apply_damage(damage, damagetype, def_zone, blocked, forced, spread_damage, wound_bonus, bare_wound_bonus, sharpness, attack_direction, attacking_item)
. = ..()
if (!.)
return
if (damage <= 0)
if (. <= 0)
return
if (tentacles.cooldown_time > 1 SECONDS)
tentacles.cooldown_time -= 1 SECONDS
+67 -32
View File
@@ -1,44 +1,79 @@
/mob/living/carbon/apply_damage(damage, damagetype = BRUTE, def_zone = null, blocked = 0, forced = FALSE, spread_damage = FALSE, wound_bonus = 0, bare_wound_bonus = 0, sharpness = NONE, attack_direction = null, attacking_item)
SEND_SIGNAL(src, COMSIG_MOB_APPLY_DAMAGE, damage, damagetype, def_zone)
var/hit_percent = (100-blocked)/100
if(!damage || (!forced && hit_percent <= 0))
return 0
/mob/living/carbon/apply_damage(
damage = 0,
damagetype = BRUTE,
def_zone = null,
blocked = 0,
forced = FALSE,
spread_damage = FALSE,
wound_bonus = 0,
bare_wound_bonus = 0,
sharpness = NONE,
attack_direction = null,
attacking_item,
)
// Spread damage should always have def zone be null
if(spread_damage)
def_zone = null
var/obj/item/bodypart/BP = null
if(!spread_damage)
if(isbodypart(def_zone)) //we specified a bodypart object
BP = def_zone
else
if(!def_zone)
def_zone = get_random_valid_zone(def_zone)
BP = get_bodypart(check_zone(def_zone))
if(!BP)
BP = bodyparts[1]
// Otherwise if def zone is null, we'll get a random bodypart / zone to hit.
// ALso we'll automatically covnert string def zones into bodyparts to pass into parent call.
else if(!isbodypart(def_zone))
var/random_zone = check_zone(def_zone || get_random_valid_zone(def_zone))
def_zone = get_bodypart(random_zone) || bodyparts[1]
. = ..()
// Taking brute or burn to bodyparts gives a damage flash
if(def_zone && (damagetype == BRUTE || damagetype == BURN))
damageoverlaytemp += .
return .
/mob/living/carbon/human/apply_damage(
damage = 0,
damagetype = BRUTE,
def_zone = null,
blocked = 0,
forced = FALSE,
spread_damage = FALSE,
wound_bonus = 0,
bare_wound_bonus = 0,
sharpness = NONE,
attack_direction = null,
attacking_item,
)
// Add relevant DR modifiers into blocked value to pass to parent
blocked += physiology?.damage_resistance
blocked += dna?.species?.damage_modifier
return ..()
/mob/living/carbon/human/get_incoming_damage_modifier(
damage = 0,
damagetype = BRUTE,
def_zone = null,
sharpness = NONE,
attack_direction = null,
attacking_item,
)
var/final_mod = ..()
var/damage_amount = forced ? damage : damage * hit_percent
switch(damagetype)
if(BRUTE)
if(BP)
if(BP.receive_damage(damage_amount, 0, wound_bonus = wound_bonus, bare_wound_bonus = bare_wound_bonus, sharpness = sharpness, attack_direction = attack_direction))
update_damage_overlays()
else //no bodypart, we deal damage with a more general method.
adjustBruteLoss(damage_amount, forced = forced)
final_mod *= physiology.brute_mod
if(BURN)
if(BP)
if(BP.receive_damage(0, damage_amount, wound_bonus = wound_bonus, bare_wound_bonus = bare_wound_bonus, sharpness = sharpness, attack_direction = attack_direction))
update_damage_overlays()
else
adjustFireLoss(damage_amount, forced = forced)
final_mod *= physiology.burn_mod
if(TOX)
adjustToxLoss(damage_amount, forced = forced)
final_mod *= physiology.tox_mod
if(OXY)
adjustOxyLoss(damage_amount, forced = forced)
final_mod *= physiology.oxy_mod
if(CLONE)
adjustCloneLoss(damage_amount, forced = forced)
final_mod *= physiology.clone_mod
if(STAMINA)
adjustStaminaLoss(damage_amount, forced = forced)
SEND_SIGNAL(src, COMSIG_MOB_AFTER_APPLY_DAMAGE, damage, damagetype, def_zone)
return TRUE
final_mod *= physiology.stamina_mod
if(BRAIN)
final_mod *= physiology.brain_mod
return final_mod
//These procs fetch a cumulative total damage from all bodyparts
/mob/living/carbon/getBruteLoss()
@@ -104,10 +104,8 @@ GLOBAL_LIST_EMPTY(features_by_species)
///Replaces default appendix with a different organ.
var/obj/item/organ/internal/appendix/mutantappendix = /obj/item/organ/internal/appendix
/**
* Percentage modifier for overall defense of the race, or less defense, if it's negative
* THIS MODIFIES ALL DAMAGE TYPES.
**/
/// Flat modifier on all damage taken via [apply_damage][/mob/living/proc/apply_damage] (so being punched, shot, etc.)
/// IE: 10 = 10% less damage taken.
var/damage_modifier = 0
///multiplier for damage from cold temperature
var/coldmod = 1
@@ -1072,9 +1070,6 @@ GLOBAL_LIST_EMPTY(features_by_species)
affected.log_message("has started overdosing on [chem.name] at [chem.volume] units.", LOG_GAME)
return SEND_SIGNAL(affected, COMSIG_SPECIES_HANDLE_CHEMICAL, chem, seconds_per_tick, times_fired)
/datum/species/proc/check_species_weakness(obj/item, mob/living/attacker)
return 1 //This is not a boolean, it's the multiplier for the damage that the user takes from the item. The force of the item is multiplied by this value
/**
* Equip the outfit required for life. Replaces items currently worn.
*/
@@ -1306,30 +1301,36 @@ GLOBAL_LIST_EMPTY(features_by_species)
span_userdanger("You block [weapon]!"))
return FALSE
var/hit_area
if(!affecting) //Something went wrong. Maybe the limb is missing?
affecting = human.bodyparts[1]
hit_area = affecting.plaintext_zone
var/def_zone = affecting.body_zone
var/armor_block = human.run_armor_check(affecting, MELEE, span_notice("Your armor has protected your [hit_area]!"), span_warning("Your armor has softened a hit to your [hit_area]!"),weapon.armour_penetration, weak_against_armour = weapon.weak_against_armour)
armor_block = min(ARMOR_MAX_BLOCK, armor_block) //cap damage reduction at 90%
var/Iwound_bonus = weapon.wound_bonus
affecting ||= human.bodyparts[1] //Something went wrong. Maybe the limb is missing?
var/hit_area = affecting.plaintext_zone
var/armor_block = min(human.run_armor_check(
def_zone = affecting,
attack_flag = MELEE,
absorb_text = span_notice("Your armor has protected your [hit_area]!"),
soften_text = span_warning("Your armor has softened a hit to your [hit_area]!"),
armour_penetration = weapon.armour_penetration,
weak_against_armour = weapon.weak_against_armour,
), ARMOR_MAX_BLOCK) //cap damage reduction at 90%
var/modified_wound_bonus = weapon.wound_bonus
// this way, you can't wound with a surgical tool on help intent if they have a surgery active and are lying down, so a misclick with a circular saw on the wrong limb doesn't bleed them dry (they still get hit tho)
if((weapon.item_flags & SURGICAL_TOOL) && !user.combat_mode && human.body_position == LYING_DOWN && (LAZYLEN(human.surgeries) > 0))
Iwound_bonus = CANT_WOUND
var/weakness = check_species_weakness(weapon, user)
modified_wound_bonus = CANT_WOUND
human.send_item_attack_message(weapon, user, hit_area, affecting)
var/damage_dealt = human.apply_damage(
damage = weapon.force,
damagetype = weapon.damtype,
def_zone = affecting,
blocked = armor_block,
wound_bonus = modified_wound_bonus,
bare_wound_bonus = weapon.bare_wound_bonus,
sharpness = weapon.get_sharpness(),
attack_direction = get_dir(user, human),
attacking_item = weapon,
)
var/attack_direction = get_dir(user, human)
apply_damage(weapon.force * weakness, weapon.damtype, def_zone, armor_block, human, wound_bonus = Iwound_bonus, bare_wound_bonus = weapon.bare_wound_bonus, sharpness = weapon.get_sharpness(), attack_direction = attack_direction, attacking_item = weapon)
if(!weapon.force)
if(damage_dealt <= 0)
return FALSE //item force is zero
var/bloody = FALSE
if(weapon.damtype != BRUTE)
@@ -1399,61 +1400,6 @@ GLOBAL_LIST_EMPTY(features_by_species)
return TRUE
/datum/species/proc/apply_damage(damage, damagetype = BRUTE, def_zone = null, blocked, mob/living/carbon/human/H, forced = FALSE, spread_damage = FALSE, wound_bonus = 0, bare_wound_bonus = 0, sharpness = NONE, attack_direction = null, attacking_item)
SEND_SIGNAL(H, COMSIG_MOB_APPLY_DAMAGE, damage, damagetype, def_zone, blocked, wound_bonus, bare_wound_bonus, sharpness, attack_direction, attacking_item)
var/hit_percent = (100-(damage_modifier+blocked))/100
hit_percent = (hit_percent * (100-H.physiology.damage_resistance))/100
if(!damage || (!forced && hit_percent <= 0))
return 0
var/obj/item/bodypart/BP = null
if(!spread_damage)
if(isbodypart(def_zone))
BP = def_zone
else
if(!def_zone)
def_zone = H.get_random_valid_zone(def_zone)
BP = H.get_bodypart(check_zone(def_zone))
if(!BP)
BP = H.bodyparts[1]
switch(damagetype)
if(BRUTE)
H.damageoverlaytemp = 20
var/damage_amount = forced ? damage : damage * hit_percent * H.physiology.brute_mod
if(BP)
if(BP.receive_damage(damage_amount, 0, forced = forced, wound_bonus = wound_bonus, bare_wound_bonus = bare_wound_bonus, sharpness = sharpness, attack_direction = attack_direction, damage_source = attacking_item))
H.update_damage_overlays()
else//no bodypart, we deal damage with a more general method.
H.adjustBruteLoss(damage_amount, forced = forced)
INVOKE_ASYNC(H, TYPE_PROC_REF(/mob/living/carbon/human, adjust_pain), damage_amount) // SKYRAT EDIT ADDITION - ERP Pain
if(BURN)
H.damageoverlaytemp = 20
var/damage_amount = forced ? damage : damage * hit_percent * H.physiology.burn_mod
if(BP)
if(BP.receive_damage(0, damage_amount, forced = forced, wound_bonus = wound_bonus, bare_wound_bonus = bare_wound_bonus, sharpness = sharpness, attack_direction = attack_direction, damage_source = attacking_item))
H.update_damage_overlays()
else
H.adjustFireLoss(damage_amount, forced = forced)
INVOKE_ASYNC(H, TYPE_PROC_REF(/mob/living/carbon/human, adjust_pain), damage_amount) // SKYRAT EDIT ADDITION - ERP Pain
if(TOX)
var/damage_amount = forced ? damage : damage * hit_percent * H.physiology.tox_mod
H.adjustToxLoss(damage_amount, forced = forced)
if(OXY)
var/damage_amount = forced ? damage : damage * hit_percent * H.physiology.oxy_mod
H.adjustOxyLoss(damage_amount, forced = forced)
if(CLONE)
var/damage_amount = forced ? damage : damage * hit_percent * H.physiology.clone_mod
H.adjustCloneLoss(damage_amount, forced = forced)
if(STAMINA)
var/damage_amount = forced ? damage : damage * hit_percent * H.physiology.stamina_mod
H.adjustStaminaLoss(damage_amount, forced = forced)
if(BRAIN)
var/damage_amount = forced ? damage : damage * hit_percent * H.physiology.brain_mod
H.adjustOrganLoss(ORGAN_SLOT_BRAIN, damage_amount)
SEND_SIGNAL(H, COMSIG_MOB_AFTER_APPLY_DAMAGE, damage, damagetype, def_zone, blocked, wound_bonus, bare_wound_bonus, sharpness, attack_direction, attacking_item)
return TRUE
//////////////////////////
// ENVIRONMENT HANDLERS //
//////////////////////////
@@ -1741,11 +1687,12 @@ GLOBAL_LIST_EMPTY(features_by_species)
switch(adjusted_pressure)
// Very high pressure, show an alert and take damage
if(HAZARD_HIGH_PRESSURE to INFINITY)
if(!HAS_TRAIT(H, TRAIT_RESISTHIGHPRESSURE))
H.adjustBruteLoss(min(((adjusted_pressure / HAZARD_HIGH_PRESSURE) - 1) * PRESSURE_DAMAGE_COEFFICIENT, MAX_HIGH_PRESSURE_DAMAGE) * H.physiology.pressure_mod * seconds_per_tick, required_bodytype = BODYTYPE_ORGANIC)
H.throw_alert(ALERT_PRESSURE, /atom/movable/screen/alert/highpressure, 2)
else
if(HAS_TRAIT(H, TRAIT_RESISTHIGHPRESSURE))
H.clear_alert(ALERT_PRESSURE)
else
var/pressure_damage = min(((adjusted_pressure / HAZARD_HIGH_PRESSURE) - 1) * PRESSURE_DAMAGE_COEFFICIENT, MAX_HIGH_PRESSURE_DAMAGE) * H.physiology.pressure_mod * H.physiology.brute_mod * seconds_per_tick
H.adjustBruteLoss(pressure_damage, required_bodytype = BODYTYPE_ORGANIC)
H.throw_alert(ALERT_PRESSURE, /atom/movable/screen/alert/highpressure, 2)
// High pressure, show an alert
if(WARNING_HIGH_PRESSURE to HAZARD_HIGH_PRESSURE)
@@ -1769,7 +1716,8 @@ GLOBAL_LIST_EMPTY(features_by_species)
if(HAS_TRAIT(H, TRAIT_RESISTLOWPRESSURE))
H.clear_alert(ALERT_PRESSURE)
else
H.adjustBruteLoss(LOW_PRESSURE_DAMAGE * H.physiology.pressure_mod * seconds_per_tick, required_bodytype = BODYTYPE_ORGANIC)
var/pressure_damage = LOW_PRESSURE_DAMAGE * H.physiology.pressure_mod * H.physiology.brute_mod * seconds_per_tick
H.adjustBruteLoss(pressure_damage, required_bodytype = BODYTYPE_ORGANIC)
H.throw_alert(ALERT_PRESSURE, /atom/movable/screen/alert/lowpressure, 2)
@@ -1,4 +0,0 @@
/// depending on the species, it will run the corresponding apply_damage code there
/mob/living/carbon/human/apply_damage(damage = 0, damagetype = BRUTE, def_zone = null, blocked = 0, forced = FALSE, spread_damage = FALSE, wound_bonus = 0, bare_wound_bonus = 0, sharpness = NONE, attack_direction = null, attacking_item)
return dna.species.apply_damage(damage, damagetype, def_zone, blocked, src, forced, spread_damage, wound_bonus, bare_wound_bonus, sharpness, attack_direction, attacking_item)
@@ -1,18 +1,33 @@
//Stores several modifiers in a way that isn't cleared by changing species
/datum/physiology
var/brute_mod = 1 // % of brute damage taken from all sources
var/burn_mod = 1 // % of burn damage taken from all sources
var/tox_mod = 1 // % of toxin damage taken from all sources
var/oxy_mod = 1 // % of oxygen damage taken from all sources
var/clone_mod = 1 // % of clone damage taken from all sources
var/stamina_mod = 1 // % of stamina damage taken from all sources
var/brain_mod = 1 // % of brain damage taken from all sources
/// Multiplier to brute damage received.
/// IE: A brute mod of 0.9 = 10% less brute damage.
/// Only applies to damage dealt via [apply_damage][/mob/living/proc/apply_damage] unless factored in manually.
var/brute_mod = 1
/// Multiplier to burn damage received
var/burn_mod = 1
/// Multiplier to toxin damage received
var/tox_mod = 1
/// Multiplier to oxygen damage received
var/oxy_mod = 1
/// Multiplier to clone damage received
var/clone_mod = 1
/// Multiplier to stamina damage received
var/stamina_mod = 1
/// Multiplier to brain damage received
var/brain_mod = 1
var/pressure_mod = 1 // % of brute damage taken from low or high pressure (stacks with brute_mod)
var/heat_mod = 1 // % of burn damage taken from heat (stacks with burn_mod)
var/cold_mod = 1 // % of burn damage taken from cold (stacks with burn_mod)
/// Multiplier to damage taken from high / low pressure exposure, stacking with the brute modifier
var/pressure_mod = 1
/// Multiplier to damage taken from high temperature exposure, stacking with the burn modifier
var/heat_mod = 1
/// Multiplier to damage taken from low temperature exposure, stacking with the toxin modifier
var/cold_mod = 1
var/damage_resistance = 0 // %damage reduction from all sources
/// Flat damage reduction from taking damage
/// Unlike the other modifiers, this is not a multiplier.
/// IE: DR of 10 = 10% less damage.
var/damage_resistance = 0
var/siemens_coeff = 1 // resistance to shocks
@@ -32,10 +32,19 @@
BODY_ZONE_CHEST = /obj/item/bodypart/chest/fly,
)
/datum/species/fly/check_species_weakness(obj/item/weapon, mob/living/attacker)
if(istype(weapon, /obj/item/melee/flyswatter))
return 30 //Flyswatters deal 30x damage to flypeople.
return 1
/datum/species/fly/on_species_gain(mob/living/carbon/human/human_who_gained_species, datum/species/old_species, pref_load)
. = ..()
RegisterSignal(human_who_gained_species, COMSIG_MOB_APPLY_DAMAGE_MODIFIERS, PROC_REF(damage_weakness))
/datum/species/fly/on_species_loss(mob/living/carbon/human/C, datum/species/new_species, pref_load)
. = ..()
UnregisterSignal(C, COMSIG_MOB_APPLY_DAMAGE_MODIFIERS)
/datum/species/fly/proc/damage_weakness(datum/source, list/damage_mods, damage_amount, damagetype, def_zone, sharpness, attack_direction, obj/item/attacking_item)
SIGNAL_HANDLER
if(istype(attacking_item, /obj/item/melee/flyswatter))
damage_mods += 30 // Yes, a 30x damage modifier
/datum/species/fly/get_physical_attributes()
return "These hideous creatures suffer from pesticide immensely, eat waste, and are incredibly vulnerable to bright lights. They do have wings though."
@@ -47,10 +47,19 @@
return randname
/datum/species/moth/check_species_weakness(obj/item/weapon, mob/living/attacker)
if(istype(weapon, /obj/item/melee/flyswatter))
return 10 //flyswatters deal 10x damage to moths
return 1
/datum/species/moth/on_species_gain(mob/living/carbon/human/human_who_gained_species, datum/species/old_species, pref_load)
. = ..()
RegisterSignal(human_who_gained_species, COMSIG_MOB_APPLY_DAMAGE_MODIFIERS, PROC_REF(damage_weakness))
/datum/species/moth/on_species_loss(mob/living/carbon/human/C, datum/species/new_species, pref_load)
. = ..()
UnregisterSignal(C, COMSIG_MOB_APPLY_DAMAGE_MODIFIERS)
/datum/species/moth/proc/damage_weakness(datum/source, list/damage_mods, damage_amount, damagetype, def_zone, sharpness, attack_direction, obj/item/attacking_item)
SIGNAL_HANDLER
if(istype(attacking_item, /obj/item/melee/flyswatter))
damage_mods += 10 // Yes, a 10x damage modifier
/datum/species/moth/randomize_features(mob/living/carbon/human/human_mob)
human_mob.dna.features["moth_markings"] = pick(GLOB.moth_wings_list)
@@ -40,6 +40,11 @@
new_vampire.skin_tone = "albino"
new_vampire.update_body(0)
new_vampire.set_safe_hunger_level()
RegisterSignal(new_vampire, COMSIG_MOB_APPLY_DAMAGE_MODIFIERS, PROC_REF(damage_weakness))
/datum/species/vampire/on_species_loss(mob/living/carbon/human/C, datum/species/new_species, pref_load)
. = ..()
UnregisterSignal(C, COMSIG_MOB_APPLY_DAMAGE_MODIFIERS)
/datum/species/vampire/spec_life(mob/living/carbon/human/vampire, seconds_per_tick, times_fired)
. = ..()
@@ -64,10 +69,11 @@
vampire.adjust_fire_stacks(3 * seconds_per_tick)
vampire.ignite_mob()
/datum/species/vampire/check_species_weakness(obj/item/weapon, mob/living/attacker)
if(istype(weapon, /obj/item/nullrod/whip))
return 2 //Whips deal 2x damage to vampires. Vampire killer.
return 1
/datum/species/vampire/proc/damage_weakness(datum/source, list/damage_mods, damage_amount, damagetype, def_zone, sharpness, attack_direction, obj/item/attacking_item)
SIGNAL_HANDLER
if(istype(attacking_item, /obj/item/nullrod/whip))
damage_mods += 2
/datum/species/vampire/get_physical_attributes()
return "Vampires are afflicted with the Thirst, needing to sate it by draining the blood out of another living creature. However, they do not need to breathe or eat normally. \
+151 -52
View File
@@ -1,58 +1,149 @@
/**
* Applies damage to this mob
* Applies damage to this mob.
*
* Sends [COMSIG_MOB_APPLY_DAMAGE]
*
* Arguuments:
* * damage - amount of damage
* * damagetype - one of [BRUTE], [BURN], [TOX], [OXY], [CLONE], [STAMINA]
* * def_zone - zone that is being hit if any
* * blocked - armor value applied
* * forced - bypass hit percentage
* * spread_damage - used in overrides
* * damage - Amount of damage
* * damagetype - What type of damage to do. one of [BRUTE], [BURN], [TOX], [OXY], [CLONE], [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.
* * bare_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].
*
* Returns TRUE if damage applied
* 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, bare_wound_bonus = 0, sharpness = NONE, attack_direction = null, attacking_item)
SEND_SIGNAL(src, COMSIG_MOB_APPLY_DAMAGE, damage, damagetype, def_zone)
var/hit_percent = (100-blocked)/100
if(!damage || (!forced && hit_percent <= 0))
return FALSE
var/damage_amount = forced ? damage : damage * hit_percent
switch(damagetype)
if(BRUTE)
adjustBruteLoss(damage_amount, forced = forced)
if(BURN)
adjustFireLoss(damage_amount, forced = forced)
if(TOX)
adjustToxLoss(damage_amount, forced = forced)
if(OXY)
adjustOxyLoss(damage_amount, forced = forced)
if(CLONE)
adjustCloneLoss(damage_amount, forced = forced)
if(STAMINA)
adjustStaminaLoss(damage_amount, forced = forced)
SEND_SIGNAL(src, COMSIG_MOB_AFTER_APPLY_DAMAGE, damage, damagetype, def_zone)
return TRUE
/mob/living/proc/apply_damage(
damage = 0,
damagetype = BRUTE,
def_zone = null,
blocked = 0,
forced = FALSE,
spread_damage = FALSE,
wound_bonus = 0,
bare_wound_bonus = 0,
sharpness = NONE,
attack_direction = null,
attacking_item,
)
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)
if(damage_amount <= 0)
return 0
///like [apply_damage][/mob/living/proc/apply_damage] except it always uses the damage procs
/mob/living/proc/apply_damage_type(damage = 0, damagetype = BRUTE)
SEND_SIGNAL(src, COMSIG_MOB_APPLY_DAMAGE, damage_amount, damagetype, def_zone, blocked, wound_bonus, bare_wound_bonus, sharpness, attack_direction, attacking_item)
var/damage_dealt = 0
switch(damagetype)
if(BRUTE)
return adjustBruteLoss(damage)
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,
bare_wound_bonus = bare_wound_bonus,
sharpness = sharpness,
attack_direction = attack_direction,
damage_source = attacking_item,
))
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 = adjustBruteLoss(damage_amount, forced = forced)
INVOKE_ASYNC(src, TYPE_PROC_REF(/mob/living, adjust_pain), damage_amount) // SKYRAT EDIT ADDITION - ERP Pain
if(BURN)
return adjustFireLoss(damage)
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,
bare_wound_bonus = bare_wound_bonus,
sharpness = sharpness,
attack_direction = attack_direction,
damage_source = attacking_item,
))
update_damage_overlays()
damage_dealt = delta - actual_hit.get_damage() // See above
else
damage_dealt = adjustFireLoss(damage_amount, forced = forced)
INVOKE_ASYNC(src, TYPE_PROC_REF(/mob/living, adjust_pain), damage_amount) // SKYRAT EDIT ADDITION - ERP Pain
if(TOX)
return adjustToxLoss(damage)
damage_dealt = adjustToxLoss(damage_amount, forced = forced)
if(OXY)
return adjustOxyLoss(damage)
damage_dealt = adjustOxyLoss(damage_amount, forced = forced)
if(CLONE)
return adjustCloneLoss(damage)
damage_dealt = adjustCloneLoss(damage_amount, forced = forced)
if(STAMINA)
return adjustStaminaLoss(damage)
damage_dealt = adjustStaminaLoss(damage_amount, forced = forced)
if(BRAIN)
damage_dealt = adjustOrganLoss(ORGAN_SLOT_BRAIN, damage_amount)
SEND_SIGNAL(src, COMSIG_MOB_AFTER_APPLY_DAMAGE, damage_dealt, damagetype, def_zone, blocked, wound_bonus, bare_wound_bonus, sharpness, attack_direction, attacking_item)
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)
heal_amount = abs(heal_amount) * -1
switch(damagetype)
if(BRUTE)
return adjustBruteLoss(heal_amount)
if(BURN)
return adjustFireLoss(heal_amount)
if(TOX)
return adjustToxLoss(heal_amount)
if(OXY)
return adjustOxyLoss(heal_amount)
if(CLONE)
return adjustCloneLoss(heal_amount)
if(STAMINA)
return adjustStaminaLoss(heal_amount)
/// 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)
@@ -72,26 +163,34 @@
/mob/living/proc/get_total_damage(precision = DAMAGE_PRECISION)
return round(getBruteLoss() + getFireLoss() + getToxLoss() + getOxyLoss() + getCloneLoss(), precision)
/// applies multiple damages at once via [/mob/living/proc/apply_damage]
/mob/living/proc/apply_damages(brute = 0, burn = 0, tox = 0, oxy = 0, clone = 0, def_zone = null, blocked = FALSE, stamina = 0, brain = 0)
if(blocked >= 100)
return 0
/// 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,
clone = 0,
def_zone = null,
blocked = 0,
stamina = 0,
brain = 0,
)
var/total_damage = 0
if(brute)
apply_damage(brute, BRUTE, def_zone, blocked)
total_damage += apply_damage(brute, BRUTE, def_zone, blocked)
if(burn)
apply_damage(burn, BURN, def_zone, blocked)
total_damage += apply_damage(burn, BURN, def_zone, blocked)
if(tox)
apply_damage(tox, TOX, def_zone, blocked)
total_damage += apply_damage(tox, TOX, def_zone, blocked)
if(oxy)
apply_damage(oxy, OXY, def_zone, blocked)
total_damage += apply_damage(oxy, OXY, def_zone, blocked)
if(clone)
apply_damage(clone, CLONE, def_zone, blocked)
total_damage += apply_damage(clone, CLONE, def_zone, blocked)
if(stamina)
apply_damage(stamina, STAMINA, def_zone, blocked)
total_damage += apply_damage(stamina, STAMINA, def_zone, blocked)
if(brain)
apply_damage(brain, BRAIN, def_zone, blocked)
return 1
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)
@@ -432,11 +531,11 @@
///heal up to amount damage, in a given order
/mob/living/proc/heal_ordered_damage(amount, list/damage_types)
. = FALSE //we'll return the amount of damage healed
. = 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)
. += apply_damage_type(-amount_to_heal, damagetype)
. += heal_damage_type(amount_to_heal, damagetype)
amount -= amount_to_heal //remove what we healed from our current amount
if(!amount)
break
@@ -1,17 +1,3 @@
/mob/living/silicon/apply_damage(damage = 0, damagetype = BRUTE, def_zone = null, blocked = 0, forced = FALSE, spread_damage = FALSE, wound_bonus = 0, bare_wound_bonus = 0, sharpness = NONE, attack_direction = null, attacking_item)
var/hit_percent = (100-blocked)/100
if((!damage || (!forced && hit_percent <= 0)))
return 0
var/damage_amount = forced ? damage : damage * hit_percent
switch(damagetype)
if(BRUTE)
adjustBruteLoss(damage_amount, forced = forced)
if(BURN)
adjustFireLoss(damage_amount, forced = forced)
return 1
/mob/living/silicon/apply_effect(effect = 0,effecttype = EFFECT_STUN, blocked = FALSE)
return FALSE //The only effect that can hit them atm is flashes and they still directly edit so this works for now. (This was written in at least 2016. Help)
@@ -658,10 +658,10 @@
healies *= 1.1
if(bot_cover_flags & BOT_COVER_EMAGGED)
patient.reagents.add_reagent(/datum/reagent/toxin/chloralhydrate, 5)
patient.apply_damage_type((healies*1),treatment_method)
patient.apply_damage((healies * 1), treatment_method, spread_damage = TRUE)
log_combat(src, patient, "pretended to tend wounds on", "internal tools", "([uppertext(treatment_method)]) (EMAGGED)")
else
patient.apply_damage_type((healies*-1),treatment_method) //don't need to check treatment_method since we know by this point that they were actually damaged.
patient.heal_damage_type((healies * 1), treatment_method) //don't need to check treatment_method since we know by this point that they were actually damaged.
log_combat(src, patient, "tended the wounds of", "internal tools", "([uppertext(treatment_method)])")
C.visible_message(span_notice("[src] tends the wounds of [patient]!"), \
"<span class='infoplain'>[span_green("[src] tends your wounds!")]</span>")
@@ -995,7 +995,7 @@
healing_types += CLONE
if(length(healing_types))
owner.apply_damage_type(-heal_amount, damagetype = pick(healing_types))
owner.heal_damage_type(heal_amount, damagetype = pick(healing_types))
owner.adjust_nutrition(3)
drained.apply_damage(heal_amount * DRAIN_DAMAGE_MULTIPLIER, damagetype = BRUTE, spread_damage = TRUE)
@@ -139,7 +139,7 @@
return
///Lets you stop the process with enough brute damage
/obj/item/organ/internal/heart/ethereal/proc/on_take_damage(datum/source, damage, damagetype, def_zone)
/obj/item/organ/internal/heart/ethereal/proc/on_take_damage(datum/source, damage, damagetype, def_zone, ...)
SIGNAL_HANDLER
if(damagetype != BRUTE)
return
@@ -264,7 +264,7 @@
return
var/ratio = (breath.gases[/datum/gas/oxygen][MOLES] / safe_oxygen_max) * 10
breather.apply_damage_type(clamp(ratio, oxy_breath_dam_min, oxy_breath_dam_max), oxy_damage_type)
breather.apply_damage(clamp(ratio, oxy_breath_dam_min, oxy_breath_dam_max), oxy_damage_type, spread_damage = TRUE)
breather.throw_alert(ALERT_TOO_MUCH_OXYGEN, /atom/movable/screen/alert/too_much_oxy)
/// Handles NOT having too much o2. only relevant if safe_oxygen_max has a value
@@ -320,10 +320,10 @@
breather.throw_alert(ALERT_TOO_MUCH_CO2, /atom/movable/screen/alert/too_much_co2)
breather.Unconscious(6 SECONDS)
// Lets hurt em a little, let them know we mean business.
breather.apply_damage_type(3, co2_damage_type)
breather.apply_damage(3, co2_damage_type, spread_damage = TRUE)
// They've been in here 30s now, start to kill them for their own good!
if((world.time - breather.co2overloadtime) > 30 SECONDS)
breather.apply_damage_type(8, co2_damage_type)
breather.apply_damage(8, co2_damage_type, spread_damage = TRUE)
/// Handles NOT having too much co2. only relevant if safe_co2_max has a value
/obj/item/organ/internal/lungs/proc/safe_co2(mob/living/carbon/breather, datum/gas_mixture/breath, old_co2_pp)
@@ -364,7 +364,7 @@
breather.throw_alert(ALERT_TOO_MUCH_PLASMA, /atom/movable/screen/alert/too_much_plas)
var/ratio = (breath.gases[/datum/gas/plasma][MOLES] / safe_plasma_max) * 10
breather.apply_damage_type(clamp(ratio, plas_breath_dam_min, plas_breath_dam_max), plas_damage_type)
breather.apply_damage(clamp(ratio, plas_breath_dam_min, plas_breath_dam_max), plas_damage_type, spread_damage = TRUE)
/// Resets plasma side effects
/obj/item/organ/internal/lungs/proc/safe_plasma(mob/living/carbon/breather, datum/gas_mixture/breath, old_plasma_pp)
@@ -754,11 +754,11 @@
if(!HAS_TRAIT(breather, TRAIT_RESISTCOLD)) // COLD DAMAGE
var/cold_modifier = breather.dna.species.coldmod
if(breath_temperature < cold_level_3_threshold)
breather.apply_damage_type(cold_level_3_damage*cold_modifier, cold_damage_type)
breather.apply_damage(cold_level_3_damage*cold_modifier, cold_damage_type, spread_damage = TRUE)
if(breath_temperature > cold_level_3_threshold && breath_temperature < cold_level_2_threshold)
breather.apply_damage_type(cold_level_2_damage*cold_modifier, cold_damage_type)
breather.apply_damage(cold_level_2_damage*cold_modifier, cold_damage_type, spread_damage = TRUE)
if(breath_temperature > cold_level_2_threshold && breath_temperature < cold_level_1_threshold)
breather.apply_damage_type(cold_level_1_damage*cold_modifier, cold_damage_type)
breather.apply_damage(cold_level_1_damage*cold_modifier, cold_damage_type, spread_damage = TRUE)
if(breath_temperature < cold_level_1_threshold)
if(prob(20))
to_chat(breather, span_warning("You feel [cold_message] in your [name]!"))
@@ -766,11 +766,11 @@
if(!HAS_TRAIT(breather, TRAIT_RESISTHEAT)) // HEAT DAMAGE
var/heat_modifier = breather.dna.species.heatmod
if(breath_temperature > heat_level_1_threshold && breath_temperature < heat_level_2_threshold)
breather.apply_damage_type(heat_level_1_damage*heat_modifier, heat_damage_type)
breather.apply_damage(heat_level_1_damage*heat_modifier, heat_damage_type, spread_damage = TRUE)
if(breath_temperature > heat_level_2_threshold && breath_temperature < heat_level_3_threshold)
breather.apply_damage_type(heat_level_2_damage*heat_modifier, heat_damage_type)
breather.apply_damage(heat_level_2_damage*heat_modifier, heat_damage_type, spread_damage = TRUE)
if(breath_temperature > heat_level_3_threshold)
breather.apply_damage_type(heat_level_3_damage*heat_modifier, heat_damage_type)
breather.apply_damage(heat_level_3_damage*heat_modifier, heat_damage_type, spread_damage = TRUE)
if(breath_temperature > heat_level_1_threshold)
if(prob(20))
to_chat(breather, span_warning("You feel [hot_message] in your [name]!"))
@@ -2,7 +2,10 @@
/// Adds or removes pain, this should be used instead of the modifying the var, due to quirk logic.
/// Makes the human scream and shiver when pain hits the soft limit, provided autoemote is enabled.
/mob/living/carbon/human/proc/adjust_pain(change_amount = 0)
/mob/living/proc/adjust_pain(change_amount = 0)
return
/mob/living/carbon/human/adjust_pain(change_amount = 0)
if(stat >= DEAD || !client?.prefs?.read_preference(/datum/preference/toggle/erp))
return
@@ -74,9 +74,14 @@
/// The cooldown before the mutant can start regenerating
COOLDOWN_DECLARE(regen_cooldown)
/datum/species/mutant/infectious/on_species_gain(mob/living/carbon/C, datum/species/old_species)
/datum/species/mutant/infectious/on_species_gain(mob/living/carbon/human/human_who_gained_species, datum/species/old_species, pref_load)
. = ..()
C.AddComponent(/datum/component/mutant_hands, mutant_hand_path = hands_to_give)
human_who_gained_species.AddComponent(/datum/component/mutant_hands, mutant_hand_path = hands_to_give)
RegisterSignal(human_who_gained_species, COMSIG_MOB_AFTER_APPLY_DAMAGE, PROC_REF(queue_regeneration))
/datum/species/mutant/infectious/on_species_loss(mob/living/carbon/human/human_who_lost_species, datum/species/new_species, pref_load)
. = ..()
UnregisterSignal(human_who_lost_species, COMSIG_MOB_AFTER_APPLY_DAMAGE)
/obj/item/bodypart/leg/left/mutant_zombie/infectious
speed_modifier = 0.5
@@ -137,9 +142,11 @@
/datum/species/mutant/infectious/spec_stun(mob/living/carbon/human/H,amount)
. = min(20, amount)
/datum/species/mutant/infectious/apply_damage(damage, damagetype = BRUTE, def_zone = null, blocked, mob/living/carbon/human/H, forced = FALSE, spread_damage = FALSE, wound_bonus = 0, bare_wound_bonus = 0, sharpness = NONE, attack_direction = null, attacking_item)
. = ..()
if(.)
/// Start the cooldown to regenerate - 5 seconds after taking damage
/datum/species/mutant/infectious/proc/queue_regeneration()
SIGNAL_HANDLER
if(COOLDOWN_FINISHED(src, regen_cooldown))
COOLDOWN_START(src, regen_cooldown, REGENERATION_DELAY)
/datum/species/mutant/infectious/spec_life(mob/living/carbon/carbon_mob, seconds_per_tick, times_fired)
-1
View File
@@ -4732,7 +4732,6 @@
#include "code\modules\mob\living\carbon\alien\special\alien_embryo.dm"
#include "code\modules\mob\living\carbon\alien\special\facehugger.dm"
#include "code\modules\mob\living\carbon\human\_species.dm"
#include "code\modules\mob\living\carbon\human\damage_procs.dm"
#include "code\modules\mob\living\carbon\human\death.dm"
#include "code\modules\mob\living\carbon\human\dummy.dm"
#include "code\modules\mob\living\carbon\human\emote.dm"