diff --git a/code/modules/mob/living/simple_animal/_damage_coeff.dm b/code/modules/mob/living/simple_animal/_damage_coeff.dm new file mode 100644 index 000000000000..22bd67b462c1 --- /dev/null +++ b/code/modules/mob/living/simple_animal/_damage_coeff.dm @@ -0,0 +1,96 @@ +#define DAMCOEFFID "damage_coeff-[red]-[white]-[black]-[pale]-[brute]-[burn]-[tox]-[clone]-[stamina]-[oxy]" + +/proc/getDamCoeff(red = 1, white = 1, black = 1, pale = 1, brute = 1, burn = 1, tox = 1, clone = 1, stamina = 1, oxy = 1) + . = locate(DAMCOEFFID) + if(!.) + . = new /datum/dam_coeff(red, white, black, pale, brute, burn, tox, clone, stamina, oxy) + +/proc/makeDamCoeff(list/dc = list()) + var/brute = 1 + var/burn = 1 + var/tox = 1 + var/clone = 1 + var/stamina = 1 + var/oxy = 1 + var/red = 1 + var/white = 1 + var/black = 1 + var/pale = 1 + for(var/I in dc) + switch(I) + if(BRUTE) + brute = dc[I] + if(BURN) + burn = dc[I] + if(TOX) + tox = dc[I] + if(CLONE) + clone = dc[I] + if(STAMINA) + stamina = dc[I] + if(OXY) + oxy = dc[I] + if(RED_DAMAGE) + red = dc[I] + if(WHITE_DAMAGE) + white = dc[I] + if(BLACK_DAMAGE) + black = dc[I] + if(PALE_DAMAGE) + pale = dc[I] + return getDamCoeff(red, white, black, pale, brute, burn, tox, clone, stamina, oxy) + +/datum/dam_coeff + datum_flags = DF_USE_TAG + var/brute + var/burn + var/tox + var/clone + var/stamina + var/oxy + var/red + var/white + var/black + var/pale + +/datum/dam_coeff/New(red = 1, white = 1, black = 1, pale = 1, brute = 1, burn = 1, tox = 1, clone = 1, stamina = 1, oxy = 1) + src.red = red + src.white = white + src.black = black + src.pale = pale + src.brute = brute + src.burn = burn + src.tox = tox + src.clone = clone + src.stamina = stamina + src.oxy = oxy + tag = DAMCOEFFID + +/datum/dam_coeff/proc/modifyCoeff(red = 0, white = 0, black = 0, pale = 0, brute = 0, burn = 0, tox = 0, clone = 0, stamina = 0, oxy = 0) + return getDamCoeff(src.red+red, src.white+white, src.black+black, src.pale+pale, src.brute+brute, src.burn+burn, src.tox+tox, src.clone+clone, src.stamina+stamina, src.oxy+oxy) + +/datum/dam_coeff/proc/setCoeff(red, white, black, pale, brute, burn, tox, clone, stamina, oxy) + return getDamCoeff((isnull(red) ? src.red : red),\ + (isnull(white) ? src.white : white),\ + (isnull(black) ? src.black : black),\ + (isnull(pale) ? src.pale : pale),\ + (isnull(brute) ? src.brute : brute),\ + (isnull(burn) ? src.burn : burn),\ + (isnull(tox) ? src.tox : clone),\ + (isnull(clone) ? src.clone : clone),\ + (isnull(stamina) ? src.stamina : stamina),\ + (isnull(oxy) ? src.oxy : oxy)) + +/datum/dam_coeff/proc/getCoeff(coeff) + return vars[coeff] + +/datum/dam_coeff/proc/getList() + return list(RED_DAMAGE = red, WHITE_DAMAGE = white, BLACK_DAMAGE = black, PALE_DAMAGE = pale, BRUTE = brute, BURN = burn, TOX = tox, CLONE = clone, STAMINA = stamina, OXY = oxy) + +/datum/dam_coeff/vv_edit_var(var_name, var_value) + if (var_name == NAMEOF(src, tag)) + return FALSE + . = ..() + tag = DAMCOEFFID // update tag in case damage_coeff values were edited + +#undef DAMCOEFFID diff --git a/code/modules/mob/living/simple_animal/damage_coeff_helper.dm b/code/modules/mob/living/simple_animal/damage_coeff_helper.dm index ec7eee589fc0..2298fe22c1ee 100644 --- a/code/modules/mob/living/simple_animal/damage_coeff_helper.dm +++ b/code/modules/mob/living/simple_animal/damage_coeff_helper.dm @@ -86,7 +86,29 @@ * * TRUE if value was successfully changed. */ /mob/living/simple_animal/proc/ChangeResistance(resistance, value, update = TRUE) - unmodified_damage_coeff[resistance] = value + switch(resistance) + if(BRUTE) + unmodified_damage_coeff_datum = unmodified_damage_coeff_datum.setCoeff(brute = value) + if(BURN) + unmodified_damage_coeff_datum = unmodified_damage_coeff_datum.setCoeff(burn = value) + if(TOX) + unmodified_damage_coeff_datum = unmodified_damage_coeff_datum.setCoeff(tox = value) + if(CLONE) + unmodified_damage_coeff_datum = unmodified_damage_coeff_datum.setCoeff(clone = value) + if(STAMINA) + unmodified_damage_coeff_datum = unmodified_damage_coeff_datum.setCoeff(stamina = value) + if(OXY) + unmodified_damage_coeff_datum = unmodified_damage_coeff_datum.setCoeff(oxy = value) + if(RED_DAMAGE) + unmodified_damage_coeff_datum = unmodified_damage_coeff_datum.setCoeff(red = value) + if(WHITE_DAMAGE) + unmodified_damage_coeff_datum = unmodified_damage_coeff_datum.setCoeff(white = value) + if(BLACK_DAMAGE) + unmodified_damage_coeff_datum = unmodified_damage_coeff_datum.setCoeff(black = value) + if(PALE_DAMAGE) + unmodified_damage_coeff_datum = unmodified_damage_coeff_datum.setCoeff(pale = value) + else + return FALSE if(update) UpdateResistances() return TRUE @@ -95,19 +117,19 @@ * Updates all of a mob's resistances to be based on their base value with modifiers added. */ /mob/living/simple_animal/proc/UpdateResistances() - damage_coeff = unmodified_damage_coeff.Copy() // Reset resistances + var/list/cached_resistances = unmodified_damage_coeff_datum.getList() // Reset resistances for(var/datum/dc_change/D in damage_mods) // Check our multiplicative mods if(D.additive) continue if(islist(D.damage_type)) for(var/dam_type in D.damage_type) - if(damage_coeff[dam_type] <= 0) // Immunity / Healing is not modified + if(cached_resistances[dam_type] <= 0) // Immunity / Healing is not modified continue - damage_coeff[dam_type] *= D.potency + cached_resistances[dam_type] *= D.potency else - if(damage_coeff[D.damage_type] <= 0) // Immunity / Healing is not modified + if(cached_resistances[D.damage_type] <= 0) // Immunity / Healing is not modified continue - damage_coeff[D.damage_type] *= D.potency + cached_resistances[D.damage_type] *= D.potency for(var/datum/dc_change/D in damage_mods) // Then include additive modifiers if(!D.additive) continue @@ -115,12 +137,26 @@ for(var/dam_type in D.damage_type) if(damage_coeff[dam_type] <= 0) // Immunity / Healing is not modified continue - damage_coeff[dam_type] += D.potency + cached_resistances[dam_type] += D.potency else if(damage_coeff[D.damage_type] <= 0) // Immunity / Healing is not modified continue - damage_coeff[D.damage_type] += D.potency + cached_resistances[D.damage_type] += D.potency + + for(var/I in cached_resistances) + cached_resistances[I] = round(cached_resistances[I], 0.1) // Minimizes damage_coeff datums created due to rampant decimals. + damage_coeff_datum = damage_coeff_datum.setCoeff( + cached_resistances[RED_DAMAGE],\ + cached_resistances[WHITE_DAMAGE],\ + cached_resistances[BLACK_DAMAGE],\ + cached_resistances[PALE_DAMAGE],\ + cached_resistances[BRUTE],\ + cached_resistances[BURN],\ + cached_resistances[TOX],\ + cached_resistances[CLONE],\ + cached_resistances[STAMINA],\ + cached_resistances[OXY]) /** * Give it a dc_change modifier path and it will check aganist that. If it exists in the list, it will be returned. diff --git a/code/modules/mob/living/simple_animal/damage_procs.dm b/code/modules/mob/living/simple_animal/damage_procs.dm index baf4dca53243..be7bfb70cda6 100644 --- a/code/modules/mob/living/simple_animal/damage_procs.dm +++ b/code/modules/mob/living/simple_animal/damage_procs.dm @@ -22,60 +22,60 @@ /mob/living/simple_animal/adjustBruteLoss(amount, updating_health = TRUE, forced = FALSE) if(forced) . = adjustHealth(amount * CONFIG_GET(number/damage_multiplier), updating_health, forced) - else if(damage_coeff[BRUTE]) - . = adjustHealth(amount * damage_coeff[BRUTE] * CONFIG_GET(number/damage_multiplier), updating_health, forced) + else + . = adjustHealth(amount * damage_coeff_datum.brute * CONFIG_GET(number/damage_multiplier), updating_health, forced) /mob/living/simple_animal/adjustFireLoss(amount, updating_health = TRUE, forced = FALSE) if(forced) . = adjustHealth(amount * CONFIG_GET(number/damage_multiplier), updating_health, forced) - else if(damage_coeff[BURN]) - . = adjustHealth(amount * damage_coeff[BURN] * CONFIG_GET(number/damage_multiplier), updating_health, forced) + else + . = adjustHealth(amount * damage_coeff_datum.burn * CONFIG_GET(number/damage_multiplier), updating_health, forced) /mob/living/simple_animal/adjustOxyLoss(amount, updating_health = TRUE, forced = FALSE) if(forced) . = adjustHealth(amount * CONFIG_GET(number/damage_multiplier), updating_health, forced) - else if(damage_coeff[OXY]) - . = adjustHealth(amount * damage_coeff[OXY] * CONFIG_GET(number/damage_multiplier), updating_health, forced) + else + . = adjustHealth(amount * damage_coeff_datum.oxy * CONFIG_GET(number/damage_multiplier), updating_health, forced) /mob/living/simple_animal/adjustToxLoss(amount, updating_health = TRUE, forced = FALSE) if(forced) . = adjustHealth(amount * CONFIG_GET(number/damage_multiplier), updating_health, forced) - else if(damage_coeff[TOX]) - . = adjustHealth(amount * damage_coeff[TOX] * CONFIG_GET(number/damage_multiplier), updating_health, forced) + else + . = adjustHealth(amount * damage_coeff_datum.tox * CONFIG_GET(number/damage_multiplier), updating_health, forced) /mob/living/simple_animal/adjustCloneLoss(amount, updating_health = TRUE, forced = FALSE) if(forced) . = adjustHealth(amount * CONFIG_GET(number/damage_multiplier), updating_health, forced) - else if(damage_coeff[CLONE]) - . = adjustHealth(amount * damage_coeff[CLONE] * CONFIG_GET(number/damage_multiplier), updating_health, forced) + else + . = adjustHealth(amount * damage_coeff_datum.clone * CONFIG_GET(number/damage_multiplier), updating_health, forced) /mob/living/simple_animal/adjustStaminaLoss(amount, updating_health = FALSE, forced = FALSE) if(forced) staminaloss = max(0, min(max_staminaloss, staminaloss + amount)) else - staminaloss = max(0, min(max_staminaloss, staminaloss + (amount * damage_coeff[STAMINA]))) + staminaloss = max(0, min(max_staminaloss, staminaloss + (amount * damage_coeff_datum.stamina))) update_stamina() /mob/living/simple_animal/adjustRedLoss(amount, updating_health = TRUE, forced = FALSE) if(forced) . = adjustHealth(amount * CONFIG_GET(number/damage_multiplier), updating_health, forced) - else if(damage_coeff[RED_DAMAGE]) - . = adjustHealth(amount * damage_coeff[RED_DAMAGE] * CONFIG_GET(number/damage_multiplier), updating_health, forced) + else + . = adjustHealth(amount * damage_coeff_datum.red * CONFIG_GET(number/damage_multiplier), updating_health, forced) /mob/living/simple_animal/adjustWhiteLoss(amount, updating_health = TRUE, forced = FALSE, white_healable = FALSE) if(forced) . = adjustHealth(amount * CONFIG_GET(number/damage_multiplier), updating_health, forced) - else if(damage_coeff[WHITE_DAMAGE]) - . = adjustHealth(amount * damage_coeff[WHITE_DAMAGE] * CONFIG_GET(number/damage_multiplier), updating_health, forced) + else + . = adjustHealth(amount * damage_coeff_datum.white * CONFIG_GET(number/damage_multiplier), updating_health, forced) /mob/living/simple_animal/adjustBlackLoss(amount, updating_health = TRUE, forced = FALSE, white_healable = FALSE) if(forced) . = adjustHealth(amount * CONFIG_GET(number/damage_multiplier), updating_health, forced) - else if(damage_coeff[BLACK_DAMAGE]) - . = adjustHealth(amount * damage_coeff[BLACK_DAMAGE] * CONFIG_GET(number/damage_multiplier), updating_health, forced) + else + . = adjustHealth(amount * damage_coeff_datum.black * CONFIG_GET(number/damage_multiplier), updating_health, forced) /mob/living/simple_animal/adjustPaleLoss(amount, updating_health = TRUE, forced = FALSE) if(forced) . = adjustHealth(amount * CONFIG_GET(number/damage_multiplier), updating_health, forced) - else if(damage_coeff[PALE_DAMAGE]) - . = adjustHealth(amount * damage_coeff[PALE_DAMAGE] * CONFIG_GET(number/damage_multiplier), updating_health, forced) + else + . = adjustHealth(amount * damage_coeff_datum.pale * CONFIG_GET(number/damage_multiplier), updating_health, forced) diff --git a/code/modules/mob/living/simple_animal/simple_animal.dm b/code/modules/mob/living/simple_animal/simple_animal.dm index 6493d6694af3..bc44a18e9b3b 100644 --- a/code/modules/mob/living/simple_animal/simple_animal.dm +++ b/code/modules/mob/living/simple_animal/simple_animal.dm @@ -82,11 +82,13 @@ var/armour_penetration = 0 ///Damage type of a simple mob's melee attack, should it do damage. var/melee_damage_type = RED_DAMAGE - /// 1 for full damage , 0 for none , -1 for 1:1 heal from that source. + /// 1 for full damage , 0 for none , -1 for 1:1 heal from that source., Modifying this variable post-Initialize is pointless. var/list/damage_coeff = list(BRUTE = 1, RED_DAMAGE = 1, WHITE_DAMAGE = 1, BLACK_DAMAGE = 1, PALE_DAMAGE = 1) - /// A copy of the original damage_coeff, what the base resistances of a simple animal should be before modifiers. - var/list/unmodified_damage_coeff = list() - /// The datum modifiers to + /// The datum that stores the damage_coeff post Initialize() + var/datum/dam_coeff/damage_coeff_datum + /// The unmodified values for the dam_coeff datum + var/datum/dam_coeff/unmodified_damage_coeff_datum + /// The list of all modifiers to the current DC datum var/list/damage_mods = list() ///Attacking verb in present continuous tense. var/attack_verb_continuous = "attacks" @@ -202,8 +204,13 @@ emote_see = string_list(emote_hear) if(atmos_requirements) atmos_requirements = string_assoc_list(atmos_requirements) - if(damage_coeff) + if(LAZYLEN(damage_coeff)) damage_coeff = string_assoc_list(damage_coeff) + damage_coeff_datum = makeDamCoeff(damage_coeff) + unmodified_damage_coeff_datum = makeDamCoeff(damage_coeff) + else + damage_coeff_datum = getDamCoeff() + unmodified_damage_coeff_datum = getDamCoeff() if(footstep_type) AddComponent(/datum/component/footstep, footstep_type) if(!unsuitable_cold_damage) @@ -211,7 +218,6 @@ if(!unsuitable_heat_damage) unsuitable_heat_damage = unsuitable_atmos_damage - unmodified_damage_coeff = damage_coeff.Copy() /mob/living/simple_animal/Life() . = ..() diff --git a/lobotomy-corp13.dme b/lobotomy-corp13.dme index 39d553332ce0..6b540d98b1b4 100644 --- a/lobotomy-corp13.dme +++ b/lobotomy-corp13.dme @@ -2668,6 +2668,7 @@ #include "code\modules\mob\living\silicon\robot\robot_modules.dm" #include "code\modules\mob\living\silicon\robot\robot_movement.dm" #include "code\modules\mob\living\silicon\robot\robot_say.dm" +#include "code\modules\mob\living\simple_animal\_damage_coeff.dm" #include "code\modules\mob\living\simple_animal\animal_defense.dm" #include "code\modules\mob\living\simple_animal\constructs.dm" #include "code\modules\mob\living\simple_animal\corpse.dm"