Skip to content

Commit

Permalink
Converting damage types to a decl system.
Browse files Browse the repository at this point in the history
Initial coarse conversion of damage types to decls.

Removing adjust/set/get loss procs.

Coarse take_damage/apply_damage/etc proc unification.

Converting older apply_damage() code to new damage handlers.

Replacing species mod getters with damage modifier list/getter.

Disambiguating various damage procs.

Blob damage now uses a shared take_damage() proc on /atom.

Structures now use shared take_damage() proc.

Walls now use shared take_damage proc.

Shields now use shared take_damage proc.

Organs now use shared damage procs.

Mech components now use shared damage proc.

Items and machines use shared damage proc.

Post-rebase compile updates.

Replacing decl paths for damage handlers with old single-word defines.
  • Loading branch information
MistakeNot4892 committed Jan 23, 2024
1 parent f096d40 commit 71c9b15
Show file tree
Hide file tree
Showing 364 changed files with 2,199 additions and 2,344 deletions.
9 changes: 9 additions & 0 deletions code/__defines/damage.dm
Original file line number Diff line number Diff line change
@@ -1,2 +1,11 @@
///The decimal precision for health values. Health will be rounded against this value.
#define HEALTH_ROUNDING 0.01

#define BRUTE /decl/damage_handler/brute
#define BURN /decl/damage_handler/burn
#define TOX /decl/damage_handler/organ
#define CLONE /decl/damage_handler/genetic
#define ELECTROCUTE /decl/damage_handler/electrocute
#define PAIN /decl/damage_handler/pain
#define OXY /decl/damage_handler/suffocation
#define IRRADIATE /decl/damage_handler/radiation
20 changes: 6 additions & 14 deletions code/__defines/damage_organs.dm
Original file line number Diff line number Diff line change
@@ -1,21 +1,13 @@
#define BRUTE "brute"
#define BURN "fire"
#define TOX "tox"
#define OXY "oxy"
#define CLONE "clone"
#define PAIN "pain"
#define ELECTROCUTE "electrocute"

#define CUT "cut"
#define BRUISE "bruise"
#define PIERCE "pierce"
#define LASER "laser"
#define SHATTER "shatter"
#define WOUND_CUT "cut"
#define WOUND_BURN "burn"
#define WOUND_BRUISE "bruise"
#define WOUND_PIERCE "pierce"
#define WOUND_LASER "laser"
#define WOUND_SHATTER "shatter"

#define STUN "stun"
#define WEAKEN "weaken"
#define PARALYZE "paralize"
#define IRRADIATE "irradiate"
#define SLUR "slur"
#define STUTTER "stutter"
#define EYE_BLUR "eye_blur"
Expand Down
4 changes: 0 additions & 4 deletions code/__defines/shields.dm
Original file line number Diff line number Diff line change
@@ -1,7 +1,3 @@
#define SHIELD_DAMTYPE_PHYSICAL 1 // Physical damage - bullets, meteors, various hand objects - aka. BRUTE damtype.
#define SHIELD_DAMTYPE_EM 2 // Electromagnetic damage - Ion weaponry, stun beams, ...
#define SHIELD_DAMTYPE_HEAT 3 // Heat damage - Lasers, fire

#define ENERGY_PER_HP (45 KILOWATTS)// Base amount energy that will be deducted from the generator's internal reserve per 1 HP of damage taken
#define ENERGY_UPKEEP_PER_TILE (4 KILOWATTS) // Base upkeep per tile protected. Multiplied by various enabled shield modes. Without them the field does literally nothing.
#define ENERGY_UPKEEP_IDLE 45 // Base upkeep when idle; modified by other factors.
Expand Down
16 changes: 8 additions & 8 deletions code/_helpers/medical_scans.dm
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
if(!brain || H.stat == DEAD || (H.status_flags & FAKEDEATH))
brain_result = 0
else if(H.stat != DEAD)
brain_result = round(max(0,(1 - brain.damage/brain.max_damage)*100))
brain_result = round(max(0,(1 - brain.organ_damage/brain.max_damage)*100))
else
brain_result = -1
scan["brain_activity"] = brain_result
Expand Down Expand Up @@ -38,12 +38,12 @@
scan["blood_volume"] = H.vessel.total_volume
scan["blood_volume_max"] = H.vessel.maximum_volume
scan["temperature"] = H.bodytemperature
scan["trauma"] = H.getBruteLoss()
scan["burn"] = H.getFireLoss()
scan["toxin"] = H.getToxLoss()
scan["oxygen"] = H.getOxyLoss()
scan["radiation"] = H.radiation
scan["genetic"] = H.getCloneLoss()
scan["trauma"] = H.get_damage(BRUTE)
scan["burn"] = H.get_damage(BURN)
scan["toxin"] = H.get_damage(TOX)
scan["oxygen"] = H.get_damage(OXY)
scan["radiation"] = H.get_damage(IRRADIATE)
scan["genetic"] = H.get_damage(CLONE)
scan["paralysis"] = GET_STATUS(H, STAT_PARA)
scan["immune_system"] = H.get_immunity()
scan["reagents"] = list()
Expand Down Expand Up @@ -78,7 +78,7 @@
O["name"] = I.name
O["is_broken"] = I.is_broken()
O["is_bruised"] = I.is_bruised()
O["is_damaged"] = I.damage > 0
O["is_damaged"] = I.organ_damage > 0
O["scan_results"] = I.get_scan_results(tag)
O["ailments"] = I.has_diagnosable_ailments(scanner = TRUE)
scan["internal_organs"] += list(O)
Expand Down
28 changes: 0 additions & 28 deletions code/controllers/subsystems/initialization/materials.dm
Original file line number Diff line number Diff line change
Expand Up @@ -184,31 +184,3 @@ SUBSYSTEM_DEF(materials)

if(istype(location.owner))
return location.owner.get_rock_color()

// There is a disconnect between legacy damage and armor code. This here helps bridge the gap.
// This could eventually be removed if we used decls for damage types.
/datum/controller/subsystem/materials/proc/get_armor_key(damage_type, damage_flags)
var/key
switch(damage_type)
if(BRUTE)
if(damage_flags & DAM_BULLET)
key = ARMOR_BULLET
else if(damage_flags & DAM_EXPLODE)
key = ARMOR_BOMB
else
key = ARMOR_MELEE
if(BURN)
if(damage_flags & DAM_LASER)
key = ARMOR_LASER
else if(damage_flags & DAM_EXPLODE)
key = ARMOR_BOMB
else
key = ARMOR_ENERGY
if(TOX)
if(damage_flags & DAM_BIO)
key = ARMOR_BIO // Otherwise just not blocked by default.
if(IRRADIATE)
key = ARMOR_RAD
if(ELECTROCUTE)
key = ARMOR_ENERGY
return key
8 changes: 4 additions & 4 deletions code/controllers/subsystems/statistics.dm
Original file line number Diff line number Diff line change
Expand Up @@ -157,10 +157,10 @@ SUBSYSTEM_DEF(statistics)
death.gender = dead.gender
death.time_of_death = time2text(world.realtime, "YYYY-MM-DD hh:mm:ss")
death.coords = "[dead.x], [dead.y], [dead.z]"
death.bruteloss = dead.getBruteLoss()
death.fireloss = dead.getFireLoss()
death.brainloss = dead.getBrainLoss()
death.oxyloss = dead.getOxyLoss()
death.bruteloss = dead.get_damage(BRUTE)
death.fireloss = dead.get_damage(BURN)
death.brainloss = dead.get_brain_damage()
death.oxyloss = dead.get_damage(OXY)
death.using_map_name = global.using_map.full_name
var/obj/effect/overmap/visitable/cell = global.overmap_sectors[num2text(dead.z)]
death.overmap_location_name = cell?.name || "Unknown"
Expand Down
2 changes: 1 addition & 1 deletion code/datums/ai/human.dm
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,6 @@

for(var/obj/item/organ/I in H.get_internal_organs())
if((I.status & ORGAN_DEAD) || BP_IS_PROSTHETIC(I)) continue
if(I.damage > 2) if(prob(2))
if(I.organ_damage > 2) if(prob(2))
var/obj/item/organ/external/parent = GET_EXTERNAL_ORGAN(H, I.parent_organ)
H.custom_emote("clutches [G.his] [parent.name]!")
53 changes: 53 additions & 0 deletions code/datums/damage/_damage_type.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
/decl/damage_handler
abstract_type = /decl/damage_handler
var/name
var/color = COLOR_GUNMETAL
var/applies_to_machinery = FALSE
var/machinery_hit_sound = 'sound/weapons/smash.ogg'
var/blocked_by_ablative = FALSE
var/can_ignite_reagents = FALSE
var/damage_verb = "shatters"
var/allow_modification_in_vv = TRUE
var/usable_with_backstab = FALSE
var/causes_limb_damage = FALSE
var/projectile_damage_divisor = 1
var/projectile_damages_assembly_casing = TRUE
var/barrier_damage_multiplier = 0
var/item_damage_flags = 0
var/category_type
var/expected_type = /mob/living

/decl/damage_handler/validate()
. = ..()
if(!name)
. += "no name set"
if(!category_type)
. += "no category type set"

/decl/damage_handler/proc/set_mob_damage(var/mob/living/target, var/damage, var/skip_update_health = FALSE)
if(!(category_type in target._damage_values))
return FALSE
var/oldval = target._damage_values[category_type]
var/newval = clamp(oldval + damage, 0, target.get_max_health())
if(oldval == newval)
return FALSE
target._damage_values[category_type] = newval
if(!skip_update_health)
target.update_health()
return TRUE

/decl/damage_handler/proc/heal_mob_damage(var/mob/living/target, var/damage, var/skip_update_health = FALSE)
return set_mob_damage(target, target.get_damage(category_type)-damage, skip_update_health = skip_update_health)

/decl/damage_handler/proc/apply_damage_to_mob(var/mob/living/target, var/damage, var/def_zone, var/damage_flags = 0, var/used_weapon, var/silent = FALSE, var/skip_update_health = FALSE)
return set_mob_damage(target, target.get_damage(category_type)+damage, skip_update_health = skip_update_health)

// There is a disconnect between legacy damage and armor code. This here helps bridge the gap.
/decl/damage_handler/proc/get_armor_key(var/damage_flags = 0)
return null

/decl/damage_handler/proc/get_damage_for_mob(var/mob/living/target)
return LAZYACCESS(target._damage_values, category_type) || 0

/decl/damage_handler/proc/damage_limb(var/obj/item/organ/external/organ, var/damage, var/damage_flags = 0, var/used_weapon, var/skip_update_health = FALSE)
return organ?.take_damage(damage, category_type, damage_flags = damage_flags, used_weapon = used_weapon, skip_update_health = skip_update_health)
16 changes: 16 additions & 0 deletions code/datums/damage/damage_brute.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
/decl/damage_handler/brute
name = "brute"
blocked_by_ablative = TRUE
can_ignite_reagents = TRUE // Why?
usable_with_backstab = TRUE
causes_limb_damage = TRUE
projectile_damage_divisor = 2
barrier_damage_multiplier = 0.5
category_type = /decl/damage_handler/brute

/decl/damage_handler/brute/get_armor_key(var/damage_flags)
if(damage_flags & DAM_BULLET)
return ARMOR_BULLET
if(damage_flags & DAM_EXPLODE)
return ARMOR_BOMB
return ARMOR_MELEE
19 changes: 19 additions & 0 deletions code/datums/damage/damage_burn.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/decl/damage_handler/burn
name = "burn"
applies_to_machinery = TRUE
blocked_by_ablative = TRUE
can_ignite_reagents = TRUE
damage_verb = "sizzles"
usable_with_backstab = TRUE
causes_limb_damage = TRUE
projectile_damage_divisor = 1.5
barrier_damage_multiplier = 0.75
item_damage_flags = DAM_LASER
category_type = /decl/damage_handler/burn

/decl/damage_handler/burn/get_armor_key(var/damage_flags)
if(damage_flags & DAM_LASER)
return ARMOR_LASER
if(damage_flags & DAM_EXPLODE)
return ARMOR_BOMB
return ARMOR_ENERGY
21 changes: 21 additions & 0 deletions code/datums/damage/damage_electrocution.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/decl/damage_handler/electrocute
name = "electrocution"
can_ignite_reagents = TRUE
damage_verb = "sparks"
category_type = /decl/damage_handler/electrocute

/decl/damage_handler/electrocute/get_armor_key(var/damage_flags)
return ARMOR_ENERGY

/decl/damage_handler/electrocute/apply_damage_to_mob(var/mob/living/target, var/damage, var/def_zone, var/damage_flags = 0, var/used_weapon, var/silent = FALSE, var/skip_update_health = FALSE)
target.electrocute_act(damage) // todo
return TRUE

/decl/damage_handler/electrocute/set_mob_damage(var/mob/living/target, var/damage, var/skip_update_health = FALSE)
return FALSE

/decl/damage_handler/electrocute/heal_mob_damage(var/mob/living/target, var/damage, var/skip_update_health = FALSE)
return FALSE

/decl/damage_handler/electrocute/get_damage_for_mob(var/mob/living/target)
return 0
9 changes: 9 additions & 0 deletions code/datums/damage/damage_genetic.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
/decl/damage_handler/genetic
name = "genetic"
usable_with_backstab = TRUE
causes_limb_damage = TRUE
category_type = /decl/damage_handler/genetic

/decl/damage_handler/genetic/damage_limb(var/obj/item/organ/external/organ, var/damage, var/damage_flags = 0, used_weapon)
organ.add_genetic_damage(damage)
return TRUE
11 changes: 11 additions & 0 deletions code/datums/damage/damage_organ.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
/decl/damage_handler/organ
name = "organ"
usable_with_backstab = TRUE
category_type = /decl/damage_handler/organ


/decl/damage_handler/organ/get_armor_key(var/damage_flags)
if(damage_flags & DAM_BIO)
return ARMOR_BIO
// Otherwise just not blocked by default.
return null
12 changes: 12 additions & 0 deletions code/datums/damage/damage_pain.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
/decl/damage_handler/pain
name = "pain"
usable_with_backstab = TRUE
causes_limb_damage = TRUE
projectile_damage_divisor = 3
projectile_damages_assembly_casing = FALSE
category_type = /decl/damage_handler/pain


/decl/damage_handler/pain/damage_limb(var/obj/item/organ/external/organ, var/damage, var/damage_flags = 0, used_weapon)
organ.add_pain(damage)
return TRUE
13 changes: 13 additions & 0 deletions code/datums/damage/damage_radiation.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
/decl/damage_handler/radiation
name = "radiation"
category_type = /decl/damage_handler/radiation

/decl/damage_handler/radiation/apply_damage_to_mob(var/mob/living/target, var/damage, var/def_zone, var/damage_flags = 0, var/used_weapon, var/silent = FALSE)
. = ..()
if(. && iscarbon(target) && !target.isSynthetic())
var/mob/living/carbon/target_carbon = target
if(!target_carbon.ignore_rads)
target.take_damage(0.25 * damage * target.get_damage_modifier(category_type), /decl/damage_handler/burn)

/decl/damage_handler/radiation/get_armor_key(var/damage_flags)
return ARMOR_RAD
4 changes: 4 additions & 0 deletions code/datums/damage/damage_suffocation.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
/decl/damage_handler/suffocation
name = "suffocation"
usable_with_backstab = TRUE
category_type = /decl/damage_handler/suffocation
32 changes: 18 additions & 14 deletions code/datums/extensions/armor/ablative.dm
Original file line number Diff line number Diff line change
Expand Up @@ -11,21 +11,25 @@
armor_degradation_coef = _armor_degradation_speed

/datum/extension/armor/ablative/on_blocking(damage, damage_type, damage_flags, armor_pen, blocked)
if(!(damage_type == BRUTE || damage_type == BURN))
if(!armor_degradation_coef)
return
if(armor_degradation_coef)
var/key = SSmaterials.get_armor_key(damage_type, damage_flags)
var/damage_blocked = round(damage * blocked)
if(damage_blocked)
var/new_armor = max(0, get_value(key) - armor_degradation_coef * damage_blocked)
set_value(key, new_armor)
var/mob/M = holder.get_recursive_loc_of_type(/mob)
if(istype(M))
var/list/visible = get_visible_damage()
for(var/k in visible)
if(LAZYACCESS(last_reported_damage, k) != visible[k])
LAZYSET(last_reported_damage, k, visible[k])
to_chat(M, SPAN_WARNING("The [k] armor on your [holder] has [visible[k]] damage now!"))
var/decl/damage_handler/damage_type_data = GET_DECL(damage_type)
if(!damage_type_data.blocked_by_ablative)
return
var/damage_blocked = round(damage * blocked)
if(!damage_blocked)
return
var/key = damage_type_data.get_armor_key(damage_flags)
var/new_armor = max(0, get_value(key) - armor_degradation_coef * damage_blocked)
set_value(key, new_armor)
var/mob/M = holder.get_recursive_loc_of_type(/mob)
if(!istype(M))
return
var/list/visible = get_visible_damage()
for(var/k in visible)
if(LAZYACCESS(last_reported_damage, k) != visible[k])
LAZYSET(last_reported_damage, k, visible[k])
to_chat(M, SPAN_WARNING("The [k] armor on your [holder] has [visible[k]] damage now!"))

/datum/extension/armor/ablative/proc/get_damage()
for(var/key in armor_values)
Expand Down
3 changes: 2 additions & 1 deletion code/datums/extensions/armor/armor.dm
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,8 @@

// A simpler proc used as a helper for above but can also be used externally. Does not modify state.
/datum/extension/armor/proc/get_blocked(damage_type, damage_flags, armor_pen = 0, damage = 5)
var/key = SSmaterials.get_armor_key(damage_type, damage_flags)
var/decl/damage_handler/damage_type_data = GET_DECL(damage_type)
var/key = damage_type_data.get_armor_key(damage_flags)
if(!key)
return 0

Expand Down
Loading

0 comments on commit 71c9b15

Please sign in to comment.