mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-07-20 20:45:28 +01:00
[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:
@@ -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)
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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. \
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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"
|
||||
|
||||
Reference in New Issue
Block a user