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
@@ -4,20 +4,13 @@
anchored = TRUE
density = TRUE
atom_flags = ATOM_FLAG_CHECKS_BORDER
maxhealth = OBJECT_HEALTH_LOW
/// The type of stack the barricade dropped when disassembled if any.
var/stack_type
/// The amount of stack dropped when disassembled at full health
var/stack_amount = 5
/// to specify a non-zero amount of stack to drop when destroyed
var/destroyed_stack_amount
/// Pretty tough. Changes sprites at 300 and 150
var/health = 100
/// Basic code functions
var/maxhealth = 100
/// Used for calculating some stuff related to maxhealth as it constantly changes due to e.g. barbed wire. set to 100 to avoid possible divisions by zero
var/starting_maxhealth = 100
/// How much force an item needs to even damage it at all.
var/force_level_absorption = 5
var/barricade_hitsound
@@ -33,19 +26,17 @@
/obj/structure/barricade/Initialize(mapload, mob/user)
. = ..()
update_icon()
starting_maxhealth = maxhealth
/obj/structure/barricade/condition_hints(mob/user, distance, is_adjacent)
. += ..()
/obj/structure/barricade/get_damage_condition_hints(mob/user, distance, is_adjacent)
switch(damage_state)
if(BARRICADE_DMG_NONE)
. += SPAN_INFO("It appears to be in good shape.")
. = SPAN_INFO("It appears to be in good shape.")
if(BARRICADE_DMG_SLIGHT)
. += SPAN_WARNING("It's slightly damaged, but still very functional.")
. = SPAN_WARNING("It's slightly damaged, but still very functional.")
if(BARRICADE_DMG_MODERATE)
. += SPAN_WARNING("It's quite beat up, but it's holding together.")
. = SPAN_WARNING("It's quite beat up, but it's holding together.")
if(BARRICADE_DMG_HEAVY)
. += SPAN_WARNING("It's crumbling apart, just a few more blows will tear it apart!")
. = SPAN_WARNING("It's crumbling apart, just a few more blows will tear it apart!")
/obj/structure/barricade/mechanics_hints(mob/user, distance, is_adjacent)
. += ..()
@@ -164,7 +155,7 @@
visible_message(SPAN_DANGER("\The [src]'s barbed wire slices into [L]!"))
L.apply_damage((5), DAMAGE_BRUTE, pick(BP_R_HAND, BP_L_HAND), "barbed wire", DAMAGE_FLAG_SHARP|DAMAGE_FLAG_EDGE, 25)
L.do_attack_animation(src)
take_damage(damage)
add_damage(damage)
/obj/structure/barricade/attackby(obj/item/attacking_item, mob/user)
if(istype(attacking_item, /obj/item/stack/barbed_wire))
@@ -181,8 +172,8 @@
user.visible_message(SPAN_NOTICE("[user] sets up [attacking_item.name] on [src]."),
SPAN_NOTICE("You set up [attacking_item.name] on [src]."))
maxhealth += 50
update_health(-50)
set_maxhealth(maxhealth + 50)
add_health(50)
can_wire = FALSE
is_wired = TRUE
climbable = FALSE
@@ -196,12 +187,11 @@
if(do_after(user, 20, src, DO_REPAIR_CONSTRUCT))
if(!is_wired)
return
playsound(src.loc, 'sound/items/Wirecutter.ogg', 25, 1)
user.visible_message(SPAN_NOTICE("[user] removes the barbed wire on [src]."),
SPAN_NOTICE("You remove the barbed wire on [src]."))
maxhealth -= 50
update_health(50)
set_maxhealth(maxhealth - 50)
add_damage(50)
can_wire = TRUE
is_wired = FALSE
climbable = TRUE
@@ -222,7 +212,7 @@
bullet_ping(hitting_projectile)
var/damage_to_take = hitting_projectile.damage * hitting_projectile.anti_materiel_potential
take_damage(damage_to_take)
add_damage(damage_to_take, hitting_projectile.damage_flags(), hitting_projectile.damtype, hitting_projectile.armor_penetration, hitting_projectile)
/obj/structure/barricade/proc/barricade_deconstruct(deconstruct)
if(deconstruct && is_wired)
@@ -232,7 +222,7 @@
if(!deconstruct && destroyed_stack_amount)
stack_amt = destroyed_stack_amount
else
stack_amt = round(stack_amount * (health/starting_maxhealth)) //Get an amount of sheets back equivalent to remaining health. Obviously, fully destroyed means 0
stack_amt = round(stack_amount * (health/initial(maxhealth))) //Get an amount of sheets back equivalent to remaining health. Obviously, fully destroyed means 0
if(stack_amt)
new stack_type (loc, stack_amt)
@@ -242,7 +232,7 @@
for(var/obj/structure/barricade/B in get_step(src,dir)) //discourage double-stacking barricades by removing health from opposing barricade
if(B.dir == REVERSE_DIR(dir))
INVOKE_ASYNC(B, TYPE_PROC_REF(/atom, ex_act), severity, direction)
update_health(round(severity))
add_damage(round(severity))
// This proc is called whenever the cade is moved, so I thought it was appropriate,
// especially since the barricade's direction needs to be handled when moving
@@ -267,26 +257,20 @@
var/message = pick(I.attack_verb)
visible_message(SPAN_DANGER("[L] has [message] the [src]!"))
L.do_attack_animation(src)
take_damage(I.force)
add_damage(I.force, I.damage_flags(), I.damtype, I.armor_penetration, I)
/obj/structure/barricade/proc/take_damage(var/damage)
/obj/structure/barricade/add_damage(damage, damage_flags, damage_type, armor_penetration, obj/weapon)
for(var/obj/structure/barricade/B in get_step(src,dir)) //discourage double-stacking barricades by removing health from opposing barricade
if(B.dir == REVERSE_DIR(dir))
B.update_health(damage)
update_health(damage)
/obj/structure/barricade/proc/update_health(damage, nomessage)
health -= damage
health = clamp(health, 0, maxhealth)
B.add_damage(damage, damage_flags, damage_type, armor_penetration, weapon)
if(..())
update_damage_state()
update_icon()
/obj/structure/barricade/on_death(damage, damage_flags, damage_type, armor_penetration, obj/weapon)
if(!health)
if(!nomessage)
visible_message(SPAN_DANGER("[src] falls apart!"))
visible_message(SPAN_DANGER("[src] falls apart!"))
barricade_deconstruct()
return
update_damage_state()
update_icon()
/obj/structure/barricade/proc/update_damage_state()
var/health_percent = round(health/maxhealth * 100)
@@ -309,7 +293,7 @@
if(WT.use_tool(src, user, 7 SECONDS, volume = 40))
user.visible_message(SPAN_NOTICE("[user] repairs some damage on [src]."),
SPAN_NOTICE("You repair \the [src]."))
update_health(-200)
add_health(200)
return TRUE
@@ -120,7 +120,7 @@
health = BARRICADE_LIQUIDBAG_TRESHOLD_5
maxhealth = BARRICADE_LIQUIDBAG_TRESHOLD_5
maxhealth += 50
update_health(-50)
add_health(50)
stack_amount = 5
can_wire = FALSE
is_wired = TRUE
@@ -109,7 +109,7 @@
/obj/structure/barricade/metal/wired/Initialize(mapload, mob/user)
. = ..()
maxhealth += 50
update_health(-50)
add_health(50)
can_wire = FALSE
is_wired = TRUE
climbable = FALSE
@@ -29,7 +29,7 @@
visible_message(SPAN_NOTICE("[user] begins to repair [src]."))
if(do_after(user, 2 SECONDS, src, DO_REPAIR_CONSTRUCT) && (health < maxhealth))
if(D.use(1))
update_health(-0.5*maxhealth)
add_health(maxhealth*0.5)
update_damage_state()
visible_message(SPAN_NOTICE("[user] haphazardly repairs [src]."))
return
+1
View File
@@ -4,6 +4,7 @@
icon = 'icons/obj/coatrack.dmi'
icon_state = "coatrack"
layer = ABOVE_HUMAN_LAYER
maxhealth = OBJECT_HEALTH_VERY_LOW
var/obj/item/clothing/coat
var/obj/item/clothing/head/hat
/// Custom manual sprite override.
@@ -3,10 +3,13 @@
desc = "It's a basic storage unit."
icon = 'icons/obj/containers/closet.dmi'
icon_state = "generic"
hitsound = 'sound/effects/metalhit.ogg'
density = TRUE
build_amt = 2
slowdown = 2.5
pass_flags_self = PASSSTRUCTURE | LETPASSCLICKS | PASSTRACE
maxhealth = OBJECT_HEALTH_MEDIUM
armor = list(MELEE = ARMOR_MELEE_RESISTANT, BULLET = ARMOR_BALLISTIC_PISTOL, LASER = ARMOR_LASER_KEVLAR)
var/icon_door = null
/// Override to have open overlay use icon different to its base's
@@ -34,7 +37,6 @@
/// Never solid (You can always pass over it)
var/wall_mounted = FALSE
var/health = 100
/// If someone is currently breaking out. mutex
var/breakout = 0
@@ -157,6 +159,10 @@
. = ..()
/obj/structure/closet/on_death(damage, damage_flags, damage_type, armor_penetration, obj/weapon)
dump_contents()
. = ..()
/// Fill lockers with this.
/obj/structure/closet/proc/fill()
return
@@ -318,11 +324,11 @@
/obj/structure/closet/ex_act(severity)
switch(severity)
if(1)
health -= rand(120, 240)
add_damage(rand(120, 240))
if(2)
health -= rand(60, 120)
add_damage(rand(60, 120))
if(3)
health -= rand(30, 60)
add_damage(rand(30, 60))
if(health <= 0)
for (var/atom/movable/A as mob|obj in src)
@@ -525,9 +531,13 @@
playsound(loc, 'sound/weapons/blade.ogg', 50, 1)
else
attack_hand(user)
else
return ..()
else
attack_hand(user)
return
if(attacking_item.force < 10 && user.a_intent != I_HURT)
attack_hand(user)
else
return ..()
// helper procs for callbacks
/obj/structure/closet/proc/is_closed()
@@ -7,7 +7,13 @@
secure = TRUE
opened = FALSE
locked = TRUE
health = 200
health = OBJECT_HEALTH_VERY_HIGH
armor = list(
MELEE = ARMOR_MELEE_RESISTANT,
BULLET = ARMOR_BALLISTIC_MEDIUM,
LASER = ARMOR_LASER_MEDIUM,
ENERGY = ARMOR_ENERGY_RESISTANT,
)
/obj/structure/closet/emp_act(severity)
. = ..()
@@ -243,7 +243,13 @@
locked = TRUE
secure = TRUE
secure_lights = TRUE
health = 200
maxhealth = OBJECT_HEALTH_VERY_HIGH
armor = list(
MELEE = ARMOR_MELEE_RESISTANT,
BULLET = ARMOR_BALLISTIC_MEDIUM,
LASER = ARMOR_LASER_MEDIUM,
ENERGY = ARMOR_ENERGY_RESISTANT,
)
/obj/structure/closet/crate/plastic
name = "plastic crate"
+23 -35
View File
@@ -5,25 +5,25 @@
icon_state = "scattered"
anchored = TRUE
density = FALSE
maxhealth = OBJECT_HEALTH_HIGH
var/singleton/reagent/reagent_id
var/state = 0
var/health = 100
var/mine_rate = 1 // how fast you can mine it
var/obj/machinery/power/crystal_agitator/creator // used to re-add dense turfs to agitation list when destroyed
/obj/structure/reagent_crystal/condition_hints(mob/user, distance, is_adjacent)
. += ..()
var/current_damage = health / initial(health)
/obj/structure/reagent_crystal/get_damage_condition_hints(mob/user, distance, is_adjacent)
var/current_damage = health / maxhealth
switch(current_damage)
if(0 to 0.2)
. += SPAN_DANGER("The crystal is barely holding together!")
. = SPAN_DANGER("The crystal is barely holding together!")
if(0.2 to 0.4)
. += SPAN_WARNING("The crystal has various cracks visible!")
. = SPAN_WARNING("The crystal has various cracks visible!")
if(0.4 to 0.8)
. += SPAN_WARNING("The crystal has scratches and deeper grooves on its surface.")
. = SPAN_WARNING("The crystal has scratches and deeper grooves on its surface.")
if(0.8 to 1)
. += SPAN_NOTICE("The crystal looks structurally sound.")
. = SPAN_NOTICE("The crystal looks structurally sound.")
/obj/structure/reagent_crystal/Initialize(mapload, var/reagent_i = null, var/our_creator = null)
. = ..()
@@ -39,16 +39,15 @@
if(our_creator)
creator = our_creator
/obj/structure/reagent_crystal/proc/take_damage(var/damage)
health -= damage
if(health <= 0)
visible_message(SPAN_WARNING("\The [src] collapses into smaller crystals!"))
harvest()
/obj/structure/reagent_crystal/on_death(damage, damage_flags, damage_type, armor_penetration, obj/weapon)
visible_message(SPAN_WARNING("\The [src] collapses into smaller crystals!"))
new /obj/item/reagent_crystal(get_turf(src), reagent_id, 5)
qdel(src)
/obj/structure/reagent_crystal/attack_hand(mob/user)
if((user.mutations & HULK))
user.visible_message(SPAN_WARNING("\The [user] smashes \the [src] apart!"), SPAN_WARNING("You smash \the [src] apart!"))
harvest()
add_damage(health)
return
return ..()
@@ -75,7 +74,7 @@
user.do_attack_animation(src)
playsound(get_turf(src), 'sound/weapons/smash.ogg', 50)
visible_message(SPAN_WARNING("\The [user] smashes \the [attacking_item] into \the [src]."))
take_damage(attacking_item.force * 4)
add_damage(attacking_item.force * 4)
/obj/structure/reagent_crystal/proc/mine_crystal(var/mob/user, var/time_to_dig, var/use_sound)
if(!user)
@@ -86,46 +85,35 @@
if(do_after(user, time_to_dig * mine_rate, src))
if(!src)
return
harvest()
add_damage(health)
if(use_sound)
playsound(get_turf(src), use_sound, 30, TRUE)
/obj/structure/reagent_crystal/proc/harvest()
new /obj/item/reagent_crystal(get_turf(src), reagent_id, 5)
qdel(src)
/obj/structure/reagent_crystal/ex_act(severity)
switch(severity)
if(1.0)
qdel(src)
return
if(2.0)
if(prob(30))
harvest()
return
add_damage(health)
else
health -= rand(60,180)
add_damage(rand(60,180))
if(3.0)
if(prob(5))
harvest()
return
add_damage(health)
else
health -= rand(40,80)
if(health <= 0)
harvest()
return
add_damage(rand(40,80))
/obj/structure/reagent_crystal/attack_generic(mob/user, damage, attack_message, environment_smash, armor_penetration, attack_flags, damage_type)
if(!damage || !environment_smash)
return FALSE
user.do_attack_animation(src)
visible_message(SPAN_WARNING("\The [user] [attack_message] \the [src]!"))
harvest()
add_damage(health)
return TRUE
/obj/structure/reagent_crystal/proc/become_dense()
var/health_mod = health / initial(health)
var/health_mod = health / maxhealth
var/obj/structure/reagent_crystal/dense/P = new /obj/structure/reagent_crystal/dense(get_turf(src), reagent_id, creator)
P.health *= health_mod
if(creator)
@@ -136,10 +124,10 @@
name = "dense chemical crystal cluster"
desc = "A dense cluster of hardened chemical crystals."
icon_state = "dense"
health = 200
maxhealth = OBJECT_HEALTH_HIGH
mine_rate = 2
/obj/structure/reagent_crystal/dense/harvest()
/obj/structure/reagent_crystal/dense/on_death(damage, damage_flags, damage_type, armor_penetration, obj/weapon)
var/turf/our_turf = get_turf(src)
for(var/i = 0 to 2)
new /obj/item/reagent_crystal(our_turf, reagent_id, 5)
+1 -1
View File
@@ -7,7 +7,7 @@
anchored = TRUE
unacidable = TRUE
req_access = list(ACCESS_CAPTAIN)
var/health = 30
maxhealth = OBJECT_HEALTH_VERY_LOW
var/obj/held_obj
var/open = FALSE
var/destroyed = FALSE
@@ -3,6 +3,7 @@
desc = "A steel window frame."
icon = 'icons/obj/smooth/window/full_window_frame_color.dmi'
icon_state = "window_frame"
maxhealth = OBJECT_HEALTH_MEDIUM
color = COLOR_GRAY20
build_amt = 4
layer = WINDOW_FRAME_LAYER
@@ -10,7 +11,6 @@
density = TRUE
climbable = TRUE
smoothing_flags = SMOOTH_MORE
breakable = TRUE
can_be_unanchored = TRUE
canSmoothWith = list(
/turf/simulated/wall,
@@ -169,6 +169,7 @@
new_grille.shock(user, 70) // You haven't forgotten your precautions, have you?
has_grille_installed = TRUE
return
else return ..()
/obj/structure/window_frame/hitby(atom/movable/hitting_atom, skipcatch, hitpush, blocked, datum/thrownthing/throwingdatum)
. = ..()
@@ -177,6 +178,7 @@
W.hitby(arglist(args))
/obj/structure/window_frame/wood
maxhealth = OBJECT_HEALTH_LOW
color = "#8f5847"
/obj/structure/window_frame/unanchored // Used during in-game construction.
@@ -187,6 +189,7 @@
should_check_mapload = FALSE // No glass.
/obj/structure/window_frame/shuttle
maxhealth = OBJECT_HEALTH_HIGH
icon = 'icons/obj/smooth/window/full_window_frame_color.dmi'
color = null
smoothing_flags = SMOOTH_MORE
+19 -30
View File
@@ -7,8 +7,8 @@
w_class = WEIGHT_CLASS_HUGE
obj_flags = OBJ_FLAG_MOVES_UNSUPPORTED
pass_flags_self = PASSTABLE
maxhealth = OBJECT_HEALTH_HIGH
var/state = 0
var/health = 200
/// How much cover the girder provides against projectiles.
var/cover = 50
build_amt = 2
@@ -16,10 +16,9 @@
var/reinforcing = 0
var/plating = FALSE
/obj/structure/girder/condition_hints(mob/user, distance, is_adjacent)
. += ..()
/obj/structure/girder/get_damage_condition_hints(mob/user, distance, is_adjacent)
var/state
var/current_damage = health / initial(health)
var/current_damage = health / maxhealth
switch(current_damage)
if(0 to 0.2)
state = SPAN_DANGER("The support struts are collapsing!")
@@ -29,7 +28,7 @@
state = SPAN_NOTICE("The support struts are dented, but holding together.")
if(0.8 to 1)
state = SPAN_NOTICE("The support struts look completely intact.")
. += state
. = state
/obj/structure/girder/mechanics_hints(mob/user, distance, is_adjacent)
. += ..()
@@ -68,7 +67,7 @@
name = "displaced girder"
icon_state = "displaced"
anchored = 0
health = 50
maxhealth = OBJECT_HEALTH_VERY_LOW
cover = 25
/obj/structure/girder/bullet_act(obj/projectile/hitting_projectile, def_zone, piercing_hit)
@@ -83,20 +82,18 @@
if(!istype(hitting_projectile, /obj/projectile/beam))
damage *= 0.4 //non beams do reduced damage
take_damage(damage)
add_damage(damage)
return ..()
/obj/structure/girder/proc/take_damage(var/damage)
health -= damage
if(health <= 0)
visible_message(SPAN_WARNING("\The [src] falls apart!"))
dismantle()
/obj/structure/girder/on_death(damage, damage_flags, damage_type, armor_penetration, obj/weapon)
visible_message(SPAN_WARNING("\The [src] falls apart!"))
. = ..()
/obj/structure/girder/proc/reset_girder()
anchored = 1
anchored = TRUE
cover = initial(cover)
health = min(health,initial(health))
set_health(maxhealth)
state = 0
icon_state = initial(icon_state)
reinforcing = 0
@@ -200,7 +197,7 @@
to_chat(user, SPAN_NOTICE("You dislodged the girder!"))
icon_state = "displaced"
anchored = 0
health = 50
set_maxhealth(OBJECT_HEALTH_VERY_LOW, TRUE)
cover = 25
else if(istype(attacking_item, /obj/item/stack/material))
@@ -222,7 +219,7 @@
if(damage_to_deal > weaken && (damage_to_deal > MIN_DAMAGE_TO_HIT))
damage_to_deal -= weaken
visible_message(SPAN_WARNING("[user] strikes \the [src] with \the [attacking_item], [is_sharp(attacking_item) ? "slicing" : "denting"] a support rod!"))
take_damage(damage_to_deal)
add_damage(damage_to_deal)
else
visible_message(SPAN_WARNING("[user] strikes \the [src] with \the [attacking_item], but it bounces off!"))
user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN)
@@ -301,7 +298,7 @@
/obj/structure/girder/proc/reinforce_girder()
cover = reinf_material.hardness
health = 500
set_maxhealth(OBJECT_HEALTH_EXTREMELY_HIGH, TRUE)
state = 2
icon_state = "reinforced"
reinforcing = 0
@@ -316,26 +313,18 @@
/obj/structure/girder/ex_act(severity)
switch(severity)
if(1.0)
if(1)
qdel(src)
return
if(2.0)
if(2)
if (prob(30))
dismantle()
return
else
health -= rand(60,180)
if(3.0)
add_damage(rand(60,180))
if(3)
if (prob(5))
dismantle()
return
else
health -= rand(40,80)
if(health <= 0)
dismantle()
return
add_damage(rand(40,80))
/obj/structure/girder/attack_generic(mob/user, damage, attack_message, environment_smash, armor_penetration, attack_flags, damage_type)
if(!damage || !environment_smash)
+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))
+22 -39
View File
@@ -9,11 +9,15 @@
obj_flags = OBJ_FLAG_CONDUCTABLE | OBJ_FLAG_MOVES_UNSUPPORTED
explosion_resistance = 1
layer = BELOW_WINDOW_LAYER
var/health = 10
maxhealth = OBJECT_HEALTH_FRAGILE
armor = list(
MELEE = ARMOR_MELEE_KNIVES,
LASER = ARMOR_LASER_SMALL,
ENERGY = ARMOR_ENERGY_SMALL
)
var/destroyed = 0
/obj/structure/grille/condition_hints(mob/user, distance, is_adjacent)
. += ..()
/obj/structure/grille/get_damage_condition_hints(mob/user, distance, is_adjacent)
if(health < initial(health))
var/state
var/current_damage = health / initial(health)
@@ -24,7 +28,7 @@
state = SPAN_ALERT("The grille has taken some serious damage.")
if(0.8 to 1)
state = SPAN_NOTICE("The grille is in less than perfect condition.")
. += state
. = state
/obj/structure/grille/mechanics_hints(mob/user, distance, is_adjacent)
. += ..()
@@ -179,8 +183,7 @@
. = BULLET_ACT_HIT
damage = between(0, (damage - hitting_projectile.damage)*(hitting_projectile.damage_type == DAMAGE_BRUTE? 0.4 : 1), 10) //if the bullet passes through then the grille avoids most of the damage
src.health -= damage*0.2
spawn(0) healthcheck() //spawn to make sure we return properly if the grille is deleted
add_damage(damage * 0.2)
/obj/structure/grille/attackby(obj/item/attacking_item, mob/user)
if(attacking_item.tool_behaviour == TOOL_WIRECUTTER)
@@ -262,30 +265,19 @@
user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN)
user.do_attack_animation(src)
playsound(loc, 'sound/effects/grillehit.ogg', 80, 1)
switch(attacking_item.damtype)
if("fire")
health -= attacking_item.force
if("brute")
health -= attacking_item.force * 0.1
healthcheck()
add_damage(attacking_item.force)
..()
return
/obj/structure/grille/on_death(damage, damage_flags, damage_type, armor_penetration, obj/weapon)
if(!destroyed)
density = FALSE
destroyed = TRUE
update_icon()
new /obj/item/stack/rods(get_turf(src))
/obj/structure/grille/proc/healthcheck()
if(health <= 0)
if(!destroyed)
density = 0
destroyed = 1
update_icon()
new /obj/item/stack/rods(get_turf(src))
else
if(health <= -6)
new /obj/item/stack/rods(get_turf(src))
qdel(src)
return
return
else
. = ..()
// shock user with probability prb (if all connections & power are working)
// returns 1 if shocked, 0 otherwise
@@ -314,17 +306,9 @@
/obj/structure/grille/fire_act(exposed_temperature, exposed_volume)
if(!destroyed)
if(exposed_temperature > T0C + 1500)
health -= 1
healthcheck()
add_damage(1)
..()
/obj/structure/grille/attack_generic(mob/user, damage, attack_message, environment_smash, armor_penetration, attack_flags, damage_type)
visible_message(SPAN_DANGER("[user] [attack_verb] the [src]!"))
user.do_attack_animation(src)
health -= damage
spawn(1) healthcheck()
return 1
// Used in mapping to avoid
/obj/structure/grille/broken
destroyed = 1
@@ -333,8 +317,7 @@
/obj/structure/grille/broken/New()
..()
health = rand(-5, -1) //In the destroyed but not utterly threshold.
healthcheck() //Send this to healthcheck just in case we want to do something else with it.
add_damage(rand(-5, -1)) //In the destroyed but not utterly threshold.
/obj/structure/grille/diagonal
icon_state = "grille_diagonal"
@@ -343,7 +326,7 @@
name = "cult grille"
desc = "A matrice built out of an unknown material, with some sort of force field blocking air around it"
icon_state = "grillecult"
health = 40 //Make it strong enough to avoid people breaking in too easily
maxhealth = OBJECT_HEALTH_VERY_LOW //Make it strong enough to avoid people breaking in too easily
appearance_flags = NO_CLIENT_COLOR
/obj/structure/grille/cult/CanPass(atom/movable/mover, turf/target, height = 1.5, air_group = 0)
+1 -1
View File
@@ -6,11 +6,11 @@
density = TRUE
anchored = TRUE
layer = ABOVE_HUMAN_LAYER
maxhealth = OBJECT_HEALTH_MEDIUM
var/toppled = FALSE
var/outside = FALSE
var/already_toppled = FALSE
var/toppling_sound = 'sound/effects/metalhit.ogg'
var/health = 100
/obj/structure/hadii_statue/stone
icon_state = "stone"
+1 -1
View File
@@ -3,8 +3,8 @@
desc = "The central core of the Hivebot Secondary Transmitter Drone - all that remains after the machine's destruction. Perhaps some data as to the threat can be gleaned from this?"
icon = 'icons/obj/structure/hivebot_head.dmi'
icon_state = "hivebot_head"
maxhealth = null
w_class = WEIGHT_CLASS_BULKY
breakable = FALSE
climbable = FALSE
density = FALSE
+3 -1
View File
@@ -47,10 +47,12 @@
anchored = TRUE
atmos_canpass = CANPASS_DENSITY
maxhealth = OBJECT_HEALTH_FRAGILE
var/deflating = FALSE
var/undeploy_path = null
var/torn_path = null
var/health = 15
/obj/structure/inflatable/mechanics_hints(mob/user, distance, is_adjacent)
. += ..()
+18 -21
View File
@@ -13,9 +13,10 @@
obj_flags = OBJ_FLAG_ROTATABLE|OBJ_FLAG_MOVES_UNSUPPORTED
build_amt = 2
maxhealth = OBJECT_HEALTH_EXTREMELY_LOW
var/broken = FALSE
var/health = 70
var/maxhealth = 70
var/neighbor_status = 0
/// If the object shouldn't inherit a material, set this to True.
@@ -25,16 +26,15 @@
can_astar_pass = CANASTARPASS_ALWAYS_PROC
/obj/structure/railing/condition_hints(mob/user, distance, is_adjacent)
. += ..()
/obj/structure/railing/get_damage_condition_hints(mob/user, distance, is_adjacent)
if (health < maxhealth)
switch(health / maxhealth)
if (0.0 to 0.5)
. += SPAN_WARNING("It looks severely damaged!")
. = SPAN_WARNING("It looks severely damaged!")
if (0.25 to 0.5)
. += SPAN_WARNING("It looks damaged!")
. = SPAN_WARNING("It looks damaged!")
if (0.5 to 1.0)
. += SPAN_NOTICE("It has a few scrapes and dents.")
. = SPAN_NOTICE("It has a few scrapes and dents.")
/obj/structure/railing/mechanics_hints(mob/user, distance, is_adjacent)
. += ..()
@@ -88,8 +88,8 @@
name = "[material.display_name] [initial(name)]"
desc = "A simple [material.display_name] railing designed to protect against careless trespass."
maxhealth = round(material.integrity / 5)
health = maxhealth
set_maxhealth(round(material.integrity / 5))
set_health(maxhealth)
color = material.icon_colour
if(material.products_need_process())
@@ -124,13 +124,11 @@
return !density
return TRUE
/obj/structure/railing/proc/take_damage(amount)
health -= amount
if(health <= 0)
visible_message(SPAN_WARNING("\The [src] [material.destruction_desc]!"))
playsound(get_turf(src), 'sound/effects/grillehit.ogg', 50, TRUE)
material.place_shard(get_turf(src))
qdel(src)
/obj/structure/railing/on_death(damage, damage_flags, damage_type, armor_penetration, obj/weapon)
visible_message(SPAN_WARNING("\The [src] [material.destruction_desc]!"))
playsound(get_turf(src), 'sound/effects/grillehit.ogg', 50, TRUE)
material.place_shard(get_turf(src))
qdel(src)
/obj/structure/railing/proc/NeighborsCheck(var/UpdateNeighbors = 1)
neighbor_status = 0
@@ -298,7 +296,7 @@
if(health >= maxhealth)
return
user.visible_message(SPAN_NOTICE("\The [user] repairs some damage to \the [src]."), SPAN_NOTICE("You repair some damage to \the [src]."))
health = min(health + (maxhealth / 5), maxhealth)
add_health(maxhealth * 0.5)
return
// Install
@@ -320,7 +318,7 @@
if(attacking_item.force && (attacking_item.damtype == DAMAGE_BURN || attacking_item.damtype == DAMAGE_BRUTE))
user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN)
visible_message(SPAN_WARNING("\The [src] has been [LAZYLEN(attacking_item.attack_verb) ? pick(attacking_item.attack_verb) : "attacked"] with \the [attacking_item] by \the [user]!"))
take_damage(attacking_item.force)
add_damage(attacking_item.force, attacking_item.damage_flags(), attacking_item.damtype, attacking_item.armor_penetration, attacking_item)
return
. = ..()
@@ -367,7 +365,7 @@
LAZYREMOVE(climbers, user)
if(!anchored || material.is_brittle())
take_damage(maxhealth) // Fatboy
add_damage(maxhealth) // Fatboy
/obj/structure/railing/proc/get_destination_turf(var/mob/user)
. = get_turf(src) // by default, we pop into the turf the railing's on
@@ -394,8 +392,7 @@
icon = 'icons/obj/doors/retractable_railing.dmi'
icon_state = "railing1"
anchored = TRUE
health = 150
maxhealth = 150
maxhealth = OBJECT_HEALTH_MEDIUM
non_material_object = TRUE
can_wrench = FALSE
can_screwdriver = FALSE
+5 -4
View File
@@ -2,18 +2,19 @@
name = "door"
density = 1
anchored = 1
maxhealth = OBJECT_HEALTH_VERY_LOW
icon = 'icons/obj/doors/material_doors.dmi'
icon_state = "metal"
build_amt = 10
var/state = 0 //closed, 1 == open
var/isSwitchingStates = 0
var/oreAmount = 7
var/datum/lock/lock
var/initial_lock_value //for mapping purposes. Basically if this value is set, it sets the lock to this value.
var/health = 100
var/maxhealth = 100
/obj/structure/simple_door/feedback_hints(mob/user, distance, is_adjacent)
. += ..()
@@ -41,8 +42,8 @@
name = "[material.display_name] door"
color = material.icon_colour
maxhealth = max(1,round(material.integrity))
health = maxhealth
set_health(material.integrity)
set_health(maxhealth)
if(initial_lock_value)
locked = initial_lock_value
@@ -252,12 +252,15 @@
update_icon()
/obj/structure/bed/dismantle(obj/item/W, mob/user)
user.visible_message("<b>[user]</b> begins dismantling \the [src].", SPAN_NOTICE("You begin dismantling \the [src]."))
if(W.use_tool(src, user, 20, volume = 50))
user.visible_message("\The [user] dismantles \the [src].", SPAN_NOTICE("You dismantle \the [src]."))
if(padding_material)
padding_material.place_sheet(get_turf(src))
..()
if(user)
user.visible_message("<b>[user]</b> begins dismantling \the [src].", SPAN_NOTICE("You begin dismantling \the [src]."))
if(W.use_tool(src, user, 20, volume = 50))
user.visible_message("\The [user] dismantles \the [src].", SPAN_NOTICE("You dismantle \the [src]."))
else
return FALSE
if(padding_material)
padding_material.place_sheet(get_turf(src))
..()
/obj/structure/bed/Move()
. = ..()
+2 -3
View File
@@ -744,7 +744,7 @@ ABSTRACT_TYPE(/obj/structure/stairs/urban/road_ramp)
icon = 'icons/obj/structure/urban/windows_tall.dmi'
icon_state = "wood"
basestate = "wood"
maxhealth = 60
maxhealth = OBJECT_HEALTH_VERY_LOW
alpha = 255
/obj/structure/window/urban/framed
@@ -791,8 +791,7 @@ ABSTRACT_TYPE(/obj/structure/stairs/urban/road_ramp)
icon = 'icons/obj/structure/urban/building_external.dmi'
icon_state = "wall_half"
//basestate = "wall_half"
health = 200
maxhealth = 200
maxhealth = OBJECT_HEALTH_HIGH
layer = ABOVE_HUMAN_LAYER
/obj/structure/blocker/exterior_wall/red
+37 -88
View File
@@ -17,11 +17,11 @@
anchored = TRUE
atom_flags = ATOM_FLAG_CHECKS_BORDER
obj_flags = OBJ_FLAG_ROTATABLE|OBJ_FLAG_MOVES_UNSUPPORTED
var/hitsound = 'sound/effects/glass_hit.ogg'
var/maxhealth = 14
maxhealth = OBJECT_HEALTH_FRAGILE
hitsound = 'sound/effects/glass_hit.ogg'
var/maximal_heat = T0C + 100 // Maximal heat before this window begins taking damage from fire
var/damage_per_fire_tick = 2 // Amount of damage per fire tick. Regular windows are not fireproof so they might as well break quickly.
var/health
var/ini_dir = null
var/state = 2
var/reinf = FALSE
@@ -34,27 +34,26 @@
atmos_canpass = CANPASS_PROC
/obj/structure/window/condition_hints(mob/user, distance, is_adjacent)
. += ..()
/obj/structure/window/get_damage_condition_hints(mob/user, distance, is_adjacent)
if(health == maxhealth)
. += SPAN_NOTICE("It looks fully intact.")
. = SPAN_NOTICE("It looks fully intact.")
else
var/perc = health / maxhealth
if(perc > 0.75)
. += SPAN_NOTICE("It has a few cracks.")
. = SPAN_NOTICE("It has a few cracks.")
else if(perc > 0.5)
. += SPAN_WARNING("It looks slightly damaged.")
. = SPAN_WARNING("It looks slightly damaged.")
else if(perc > 0.25)
. += SPAN_WARNING("It looks moderately damaged.")
. = SPAN_WARNING("It looks moderately damaged.")
else
. += SPAN_DANGER("It looks heavily damaged.")
. = SPAN_DANGER("It looks heavily damaged.")
if(silicate)
if (silicate < 30)
. += SPAN_NOTICE("It has a thin layer of silicate.")
. = SPAN_NOTICE("It has a thin layer of silicate.")
else if (silicate < 70)
. += SPAN_NOTICE("It is covered in silicate.")
. = SPAN_NOTICE("It is covered in silicate.")
else
. += SPAN_NOTICE("There is a thick layer of silicate covering it.")
. = SPAN_NOTICE("There is a thick layer of silicate covering it.")
/obj/structure/window/proc/update_nearby_icons()
QUEUE_SMOOTH_NEIGHBORS(src)
@@ -65,38 +64,14 @@
layer = ABOVE_HUMAN_LAYER
QUEUE_SMOOTH(src)
/obj/structure/window/proc/take_damage(var/damage = 0, var/sound_effect = 1, message = TRUE)
var/initialhealth = health
if(silicate)
damage = damage * (1 - silicate / 200)
health = max(0, health - damage)
if(health <= 0)
shatter(message)
else
if(sound_effect)
playsound(loc, 'sound/effects/glass_hit.ogg', 100, 1)
if(health < maxhealth / 4 && initialhealth >= maxhealth / 4)
if(message)
visible_message(SPAN_DANGER("[src] looks like it's about to shatter!"))
playsound(loc, SFX_GLASS_CRACK, 100, 1)
else if(health < maxhealth / 2 && initialhealth >= maxhealth / 2)
if(message)
visible_message(SPAN_WARNING("[src] looks seriously damaged!"))
playsound(loc, SFX_GLASS_CRACK, 100, 1)
else if(health < maxhealth * 3/4 && initialhealth >= maxhealth * 3/4)
if(message)
visible_message(SPAN_WARNING("Cracks begin to appear in [src]!"))
playsound(loc, SFX_GLASS_CRACK, 100, 1)
return
/obj/structure/window/on_death(damage, damage_flags, damage_type, armor_penetration, obj/weapon, message)
shatter(message)
/obj/structure/window/proc/apply_silicate(var/amount)
if(health < maxhealth) // Mend the damage.
health = min(health + amount * 3, maxhealth)
add_health(amount * 3)
if(health == maxhealth)
visible_message("[src] looks fully repaired." )
visible_message(SPAN_NOTICE("The silicate fully mends the damage on \the [src]."))
else // Reinforce.
silicate = min(silicate + amount, 100)
updateSilicate()
@@ -145,23 +120,19 @@
if(. != BULLET_ACT_HIT)
return .
take_damage(proj_damage)
return
add_damage(proj_damage)
/obj/structure/window/ex_act(severity)
switch(severity)
if(1)
qdel(src)
return
if(2)
shatter(0)
return
if(3)
if(prob(50))
shatter(0)
return
else
take_damage(rand(10,30), TRUE, FALSE)
add_damage(rand(10,30), TRUE, FALSE)
// This and relevant verbs/procs can probably be removed since full windows are a thing now. -Gem
/obj/structure/window/proc/is_full_window()
@@ -210,7 +181,7 @@
anchored = 0
update_nearby_icons()
step(src, get_dir(hitting_atom, src))
take_damage(tforce)
add_damage(tforce)
/obj/structure/window/attack_hand(var/mob/living/user)
user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN)
@@ -243,7 +214,7 @@
user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN)
if(damage >= 10)
visible_message(SPAN_DANGER("[user] smashes into [src]!"))
take_damage(damage)
add_damage(damage)
else
visible_message(SPAN_NOTICE("\The [user] bonks \the [src] harmlessly."))
playsound(src.loc, 'sound/effects/glass_hit.ogg', 10, 1, -2)
@@ -347,8 +318,7 @@
/obj/structure/window/proc/hit(var/damage, var/sound_effect = 1)
if(reinf)
damage *= 0.5
take_damage(damage)
return
add_damage(damage)
/obj/structure/window/proc/dismantle_window()
if(dir == SOUTHWEST)
@@ -369,8 +339,6 @@
if (start_dir)
set_dir(start_dir)
health = maxhealth
ini_dir = dir
update_nearby_tiles(need_rebuild=1)
@@ -429,7 +397,7 @@
glasstype = /obj/item/stack/material/glass
maximal_heat = T0C + 100
damage_per_fire_tick = 2
maxhealth = 12
maxhealth = OBJECT_HEALTH_FRAGILE
/obj/structure/window/basic/full
name = "glass"
@@ -441,7 +409,7 @@
desc = "It looks rather strong. Might take a few good hits to shatter it."
icon_state = "rwindow"
basestate = "rwindow"
maxhealth = 40
maxhealth = OBJECT_HEALTH_LOW
reinf = TRUE
maximal_heat = T0C + 750
damage_per_fire_tick = 2
@@ -462,7 +430,7 @@
/obj/structure/window/reinforced/tinted/frosted
name = "reinforced frosted glass pane"
desc = "It looks rather strong and frosted over. Looks like it might take a few less hits then a normal reinforced window."
maxhealth = 30
maxhealth = OBJECT_HEALTH_EXTREMELY_LOW
/obj/structure/window/reinforced/polarized
name = "reinforced electrochromic glass pane"
@@ -489,9 +457,6 @@
/obj/structure/window/reinforced/crescent/hitby(atom/movable/hitting_atom, skipcatch, hitpush, blocked, datum/thrownthing/throwingdatum)
return
/obj/structure/window/reinforced/crescent/take_damage()
return
/obj/structure/window/reinforced/crescent/shatter()
return
@@ -536,7 +501,7 @@
glasstype = /obj/item/stack/material/glass/phoronglass
maximal_heat = T0C + 2000
damage_per_fire_tick = 1 // This should last for 80 fire ticks if the window is not damaged at all. The idea is that borosilicate windows have something like ablative layer that protects them for a while.
maxhealth = 40
maxhealth = OBJECT_HEALTH_VERY_LOW
/// Phoron-infused silicate
rad_resistance_modifier = 4
@@ -547,13 +512,13 @@
glasstype = /obj/item/stack/material/glass/phoronrglass
reinf = TRUE
maximal_heat = T0C + 4000
maxhealth = 80
maxhealth = OBJECT_HEALTH_LOW
/obj/structure/window/borosilicate/reinforced/skrell
name = "advanced borosilicate alloy window"
desc = "A window made out of a higly advanced borosilicate alloy. It seems to be extremely strong."
color = GLASS_COLOR_PHORON
maxhealth = 250
maxhealth = OBJECT_HEALTH_HIGH
/********** Shuttle Windows **********/
/obj/structure/window/shuttle
@@ -564,7 +529,7 @@
basestate = "w"
atom_flags = 0
obj_flags = null
maxhealth = 40
maxhealth = OBJECT_HEALTH_VERY_LOW
reinf = TRUE
dir = 5
smoothing_flags = SMOOTH_TRUE
@@ -579,8 +544,7 @@
/obj/structure/window/shuttle/legion
name = "reinforced cockpit window"
icon = 'icons/obj/smooth/shuttle_window_legion.dmi'
health = 160
maxhealth = 160
maxhealth = OBJECT_HEALTH_HIGH
/obj/structure/window/shuttle/palepurple
icon = 'icons/obj/smooth/shuttle_window_palepurple.dmi'
@@ -589,8 +553,7 @@
name = "advanced borosilicate alloy window"
desc = "It looks extremely strong. Might take many good hits to crack it."
icon = 'icons/obj/smooth/skrell_window_purple.dmi'
health = 500
maxhealth = 500
maxhealth = OBJECT_HEALTH_VERY_HIGH
smoothing_flags = SMOOTH_MORE | SMOOTH_DIAGONAL
canSmoothWith = list(
/turf/simulated/wall/shuttle/skrell,
@@ -602,8 +565,7 @@
desc = "It looks extremely strong. Might take many good hits to crack it."
icon = 'icons/turf/smooth/scc_ship/scc_ship_windows.dmi'
icon_state = "map_window"
health = 500
maxhealth = 500
maxhealth = OBJECT_HEALTH_VERY_HIGH
alpha = 255
smoothing_flags = SMOOTH_MORE
canSmoothWith = list(
@@ -629,15 +591,11 @@
/obj/structure/window/shuttle/scc
icon = 'icons/obj/smooth/scc_shuttle_window.dmi'
health = 160
maxhealth = 160
maxhealth = OBJECT_HEALTH_HIGH
/obj/structure/window/shuttle/crescent
desc = "It looks rather strong."
/obj/structure/window/shuttle/crescent/take_damage()
return
//
// Full Windows
//
@@ -647,7 +605,7 @@
atom_flags = 0
obj_flags = null
dir = 5
maxhealth = 28 // Two glass panes worth of health, since that's the minimum you need to break through to get to the other side.
maxhealth = OBJECT_HEALTH_EXTREMELY_LOW
glasstype = /obj/item/stack/material/glass
shardtype = /obj/item/material/shard
full = TRUE
@@ -757,14 +715,12 @@
qdel(src)
return
/obj/structure/window/full/take_damage(var/damage = 0, var/sound_effect = 1)
/obj/structure/window/full/add_damage(damage, damage_flags, damage_type, armor_penetration, obj/weapon, sound_effect = TRUE)
var/initialhealth = health
if(silicate)
damage = damage * (1 - silicate / 200)
health = max(0, health - damage)
if(health <= 0)
shatter()
else
@@ -779,7 +735,6 @@
else if(health < maxhealth * 3/4 && initialhealth >= maxhealth * 3/4)
visible_message(SPAN_WARNING("Cracks begin to appear in [src]!"))
playsound(loc, SFX_GLASS_CRACK, 100, 1)
return
/obj/structure/window/full/dismantle_window()
var/obj/item/stack/material/mats = new glasstype(loc)
@@ -803,7 +758,7 @@
icon = 'icons/obj/smooth/window/full_window.dmi'
icon_state = "window_glass"
basestate = "window_glass"
maxhealth = 80 // Two reinforced panes worth of health, since that's the minimum you need to break through to get to the other side.
maxhealth = OBJECT_HEALTH_LOW
reinf = TRUE
maximal_heat = T0C + 750
glasstype = /obj/item/stack/material/glass/reinforced
@@ -834,9 +789,6 @@
/obj/structure/window/full/reinforced/indestructible/hitby(atom/movable/hitting_atom, skipcatch, hitpush, blocked, datum/thrownthing/throwingdatum)
return
/obj/structure/window/full/reinforced/indestructible/take_damage()
return
/obj/structure/window/full/reinforced/indestructible/shatter()
return
@@ -867,9 +819,6 @@
/obj/structure/window/full/reinforced/polarized/indestructible/hitby(atom/movable/hitting_atom, skipcatch, hitpush, blocked, datum/thrownthing/throwingdatum)
return
/obj/structure/window/full/reinforced/polarized/indestructible/take_damage()
return
/obj/structure/window/full/reinforced/polarized/indestructible/shatter()
return
@@ -898,7 +847,7 @@
basestate = "window_glass"
glasstype = /obj/item/stack/material/glass/phoronglass
shardtype = /obj/item/material/shard/phoron
maxhealth = 80 // Two borosilicate glass panes worth of health, since that's the minimum you need to break through to get to the other side.
maxhealth = OBJECT_HEALTH_LOW
maximal_heat = T0C + 2000
damage_per_fire_tick = 1
@@ -907,7 +856,7 @@
name = "reinforced borosilicate window"
desc = "A borosilicate alloy window, with rods supporting it. It seems to be very strong."
glasstype = /obj/item/stack/material/glass/phoronrglass
maxhealth = 160 // Two reinforced borosilicate glass panes worth of health, since that's the minimum you need to break through to get to the other side.
maxhealth = OBJECT_HEALTH_MEDIUM
reinf = TRUE
maximal_heat = T0C + 4000
rad_resistance_modifier = 4