Adds an universal object health system. (#21266)

https://www.youtube.com/watch?v=ZpUYjpKg9KY

As per title. The goal is to add health to most objects in the game and
thus allow them to be dynamically destructible, while also avoiding
shitcode like each structure having its own snowflake health update
proc.

---------

Signed-off-by: Matt Atlas <mattiathebest2000@hotmail.it>
Co-authored-by: Matt Atlas <liermattia@gmail.com>
Co-authored-by: SleepyGemmy <99297919+SleepyGemmy@users.noreply.github.com>
This commit is contained in:
Matt Atlas
2026-04-16 23:22:08 +00:00
committed by GitHub
co-authored by Matt Atlas SleepyGemmy
parent 1d2871729f
commit d5931c5ffe
213 changed files with 1448 additions and 1424 deletions
+16 -27
View File
@@ -4,18 +4,13 @@
icon = 'icons/obj/gore_structures.dmi'
anchored = TRUE
density = FALSE
maxhealth = OBJECT_HEALTH_VERY_LOW
var/destroy_message = "THE STRUCTURE collapses in on itself!"
var/maxHealth = 50
var/health = 50
/obj/structure/gore/Initialize(mapload)
. = ..()
health = maxHealth
/obj/structure/gore/get_examine_text(mob/user, distance, is_adjacent, infix, suffix)
. = ..()
if(distance <= 2)
var/health_div = health / maxHealth
var/health_div = health / maxhealth
if(health_div >= 0.9)
. += SPAN_NOTICE("\The [src] appears completely intact.")
else if(health_div >= 0.7)
@@ -25,32 +20,29 @@
else
. += SPAN_WARNING("\The [src] is barely holding itself together!")
/obj/structure/gore/proc/healthcheck()
if(health <= 0)
var/final_message = replacetext(destroy_message, "THE STRUCTURE", "\The [src]")
visible_message(SPAN_WARNING(final_message))
qdel(src)
/obj/structure/gore/on_death(damage, damage_flags, damage_type, armor_penetration, obj/weapon)
var/final_message = replacetext(destroy_message, "THE STRUCTURE", "\The [src]")
visible_message(SPAN_WARNING(final_message))
qdel(src)
/obj/structure/gore/bullet_act(obj/projectile/hitting_projectile, def_zone, piercing_hit)
. = ..()
if(. != BULLET_ACT_HIT)
return .
health -= hitting_projectile.damage
healthcheck()
add_damage(hitting_projectile.damage)
/obj/structure/gore/ex_act(severity)
switch(severity)
if(1.0)
health -= 50
add_damage(50)
if(2.0)
health -= 50
add_damage(50)
if(3.0)
if(prob(50))
health -= 50
add_damage(50)
else
health -= 25
healthcheck()
add_damage(25)
/obj/structure/gore/hitby(atom/movable/hitting_atom, skipcatch, hitpush, blocked, datum/thrownthing/throwingdatum)
. = ..()
@@ -62,21 +54,18 @@
throw_force = O.throwforce
else if(ismob(hitting_atom))
throw_force = 10
health -= throw_force
healthcheck()
add_damage(throw_force)
/obj/structure/gore/attack_generic(mob/user, damage, attack_message, environment_smash, armor_penetration, attack_flags, damage_type)
attack_hand(usr)
/obj/structure/gore/attackby(obj/item/attacking_item, mob/user)
user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN)
user.do_attack_animation(src, attacking_item)
var/force_damage = attacking_item.force
var/damage = attacking_item.force
if(attacking_item.damtype == DAMAGE_BURN)
force_damage *= 1.25
health -= force_damage
damage *= 1.25
. = ..()
add_damage(damage)
playsound(loc, 'sound/effects/attackblob.ogg', 80, TRUE)
healthcheck()
/obj/structure/gore/CanPass(atom/movable/mover, turf/target, height=0, air_group=0)
if(air_group)
+10 -18
View File
@@ -5,18 +5,13 @@
desc = "It's a gruesome pile of thick, sticky flesh shaped like a nest."
icon = 'icons/obj/gore_structures.dmi'
icon_state = "nest"
maxhealth = OBJECT_HEALTH_LOW
var/destroy_message = "THE STRUCTURE collapses in on itself!"
var/maxHealth = 100
var/health = 100
/obj/structure/bed/nest/Initialize(mapload, new_material, new_padding_material)
. = ..()
health = maxHealth
/obj/structure/bed/nest/get_examine_text(mob/user, distance, is_adjacent, infix, suffix)
. = ..()
if(distance <= 2)
var/health_div = health / maxHealth
var/health_div = health / maxhealth
if(health_div >= 0.9)
. += SPAN_NOTICE("\The [src] appears completely intact.")
else if(health_div >= 0.7)
@@ -51,19 +46,16 @@
unbuckle()
/obj/structure/bed/nest/attackby(obj/item/attacking_item, mob/user)
user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN)
user.do_attack_animation(src, attacking_item)
var/force_damage = attacking_item.force
var/damage = attacking_item.force
if(attacking_item.damtype == DAMAGE_BURN)
force_damage *= 1.25
health -= force_damage
damage *= 1.25
. = ..()
add_damage(damage)
playsound(loc, 'sound/effects/attackblob.ogg', 80, TRUE)
healthcheck()
/obj/structure/bed/nest/proc/healthcheck()
if(health <= 0)
var/final_message = replacetext(destroy_message, "THE STRUCTURE", "\The [src]")
visible_message(SPAN_WARNING(final_message))
qdel(src)
/obj/structure/bed/nest/on_death(damage, damage_flags, damage_type, armor_penetration, obj/weapon)
var/final_message = replacetext(destroy_message, "THE STRUCTURE", "\The [src]")
visible_message(SPAN_WARNING(final_message))
qdel(src)
#undef NEST_RESIST_TIME
@@ -4,7 +4,7 @@
name = "bloody tendrils"
desc = "Bloody, pulsating tendrils."
icon_state = "tendril"
maxHealth = 40
maxhealth = OBJECT_HEALTH_VERY_LOW
pass_flags = PASSTABLE | PASSMOB | PASSTRACE | PASSRAILING
var/being_destroyed = FALSE
var/is_node = FALSE
@@ -18,7 +18,7 @@
desc = "Clumped up flesh, pulsating in rhythm with the tendrils that surround it."
icon_state = "tendril_node"
density = TRUE
maxHealth = 150
maxhealth = OBJECT_HEALTH_MEDIUM
light_range = NODERANGE
light_color = LIGHT_COLOR_EMERGENCY
is_node = TRUE
@@ -125,18 +125,16 @@
/obj/structure/gore/tendrils/ex_act(severity)
switch(severity)
if(1.0)
health = 0
add_damage(maxhealth)
if(2.0)
health -= maxHealth / 2
add_damage(maxhealth / 2)
if(3.0)
health -= maxHealth / 5
healthcheck()
add_damage(maxhealth / 5)
/obj/structure/gore/tendrils/fire_act(exposed_temperature, exposed_volume)
. = ..()
if(exposed_temperature > 300 + T0C)
health -= 5
healthcheck()
add_damage(5)
#undef NODERANGE
+5 -6
View File
@@ -2,21 +2,21 @@
name = "flesh floor"
desc = "Looks like the floor was covered by some fleshlike growth."
icon_state = "flesh_floor"
maxHealth = 100
maxhealth = OBJECT_HEALTH_LOW
/obj/structure/gore/wall
name = "flesh wall"
desc = "Chunks of flesh sculpted to form an impassable wall."
icon_state = "flesh_wall"
opacity = TRUE
maxHealth = 200
maxhealth = OBJECT_HEALTH_HIGH
/obj/structure/gore/wall/membrane
name = "flesh membrane"
desc = "Skin and muscle stretched just thin enough to let light pass through."
icon_state = "flesh_membrane"
opacity = FALSE
maxHealth = 120
maxhealth = 120
/obj/structure/gore/wall/Initialize()
. = ..()
@@ -33,8 +33,7 @@
user.do_attack_animation(src, FIST_ATTACK_ANIMATION)
if((user.mutations & HULK))
visible_message(SPAN_DANGER("\The [user] destroys \the [src]!"))
health = 0
add_damage(maxhealth)
else
visible_message(SPAN_DANGER("\The [user] claws at \the [src]!"))
health -= rand(5, 10)
healthcheck()
add_damage(rand(5, 10))