Fixes some atom health bugs (#22312)

## About PR
- Fixes #22260
- Fixes #22304
- Fixes #22234

Additionally changes some health values for:

- Canisters, `50` -> `100`. Takes 5 crowbar hits to break instead of 3,
these shouldn't break so easily
- Railings, `30` -> `75`. 3 crowbars instead of 1
- Reinforced girders, `600` -> `300`. Still takes a lot of crowbars
before breaking, barebone girders shouldn't compete reinforced walls
This commit is contained in:
Kano
2026-04-23 00:34:59 +00:00
committed by GitHub
parent 44bb1d5c82
commit 3d5f69f548
11 changed files with 120 additions and 169 deletions
+36 -88
View File
@@ -1,9 +1,3 @@
//
// Glass
//
#define FULL_REINFORCED_WINDOW_DAMAGE_FORCE 8
#define REINFORCED_WINDOW_DAMAGE_FORCE 8
/obj/structure/window
name = "glass pane"
desc = "A glass pane."
@@ -177,10 +171,6 @@
tforce = I.throwforce
if(reinf)
tforce *= 0.25
if(health - tforce <= 7 && !reinf)
anchored = 0
update_nearby_icons()
step(src, get_dir(hitting_atom, src))
add_damage(tforce)
/obj/structure/window/attack_hand(var/mob/living/user)
@@ -229,66 +219,66 @@
/obj/structure/window/attackby(obj/item/attacking_item, mob/user)
if(!istype(attacking_item) || istype(attacking_item, /obj/item/flag))
return
// Slamming someone against the window interaction
if(istype(attacking_item, /obj/item/grab) && get_dist(src,user)<2)
var/obj/item/grab/G = attacking_item
if(istype(G.affecting,/mob/living))
if(istype(G.affecting, /mob/living))
grab_smash_attack(G, DAMAGE_BRUTE)
return
if(attacking_item.item_flags & ITEM_FLAG_NO_BLUDGEON)
return
if(handle_construction(attacking_item, user))
return
. = ..()
/obj/structure/window/proc/handle_construction(obj/item/attacking_item, mob/user)
// Screwdriver
if(attacking_item.tool_behaviour == TOOL_SCREWDRIVER && user.a_intent != I_HURT)
if(reinf && state >= 1)
state = 3 - state
update_nearby_icons()
attacking_item.play_tool_sound(get_turf(src), 75)
to_chat(user, (state == 1 ? SPAN_NOTICE("You have unfastened the window from the frame.") : SPAN_NOTICE("You have fastened the window to the frame.")))
else if(reinf && state == 0)
anchored = !anchored
update_icon()
update_nearby_icons()
attacking_item.play_tool_sound(get_turf(src), 75)
to_chat(user, (anchored ? SPAN_NOTICE("You have fastened the frame to the floor.") : SPAN_NOTICE("You have unfastened the frame from the floor.")))
else if(!reinf)
else
anchored = !anchored
update_nearby_icons()
attacking_item.play_tool_sound(get_turf(src), 75)
to_chat(user, (anchored ? SPAN_NOTICE("You have fastened the window to the floor.") : SPAN_NOTICE("You have unfastened the window.")))
update_icon()
update_nearby_icons()
return TRUE
// Crowbar
else if(attacking_item.tool_behaviour == TOOL_CROWBAR && reinf && state <= 1 && user.a_intent != I_HURT)
state = 1 - state
attacking_item.play_tool_sound(get_turf(src), 75)
to_chat(user, (state ? SPAN_NOTICE("You have pried the window into the frame.") : SPAN_NOTICE("You have pried the window out of the frame.")))
return TRUE
// Wrench
else if(attacking_item.tool_behaviour == TOOL_WRENCH && !anchored && (!state || !reinf) && user.a_intent != I_HURT)
if(!glasstype)
to_chat(user, SPAN_NOTICE("You're not sure how to dismantle \the [src] properly."))
else
visible_message(SPAN_NOTICE("[user] dismantles \the [src]."))
dismantle_window()
else
user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN)
if(attacking_item.damtype == DAMAGE_BRUTE || attacking_item.damtype == DAMAGE_BURN)
if(reinf)
user.do_attack_animation(src)
if(attacking_item.force >= REINFORCED_WINDOW_DAMAGE_FORCE)
user.visible_message(SPAN_DANGER("\The [user] forcefully strikes \the [src] with \the [attacking_item]!"))
playsound(src, hitsound, attacking_item.get_clamped_volume(), 1)
hit(attacking_item.force)
else
user.visible_message(SPAN_WARNING("[user] hits \the [src] with \the [attacking_item], but it glances off, doing no damage."))
playsound(src, hitsound, attacking_item.get_clamped_volume(), 1)
else
user.do_attack_animation(src)
hit(attacking_item.force)
if(health <= 7)
anchored = 0
update_nearby_icons()
step(src, get_dir(user, src))
else
playsound(src, hitsound, 10, 1)
return
return TRUE
return FALSE
/obj/structure/window/proc/grab_smash_attack(obj/item/grab/G, var/damtype = DAMAGE_BRUTE)
var/mob/living/M = G.affecting
@@ -645,64 +635,46 @@
WF.has_glass_installed = FALSE
return ..()
/obj/structure/window/full/attackby(obj/item/attacking_item, mob/user)
if(!istype(attacking_item) || istype(attacking_item, /obj/item/flag))
return
if(istype(attacking_item, /obj/item/grab) && get_dist(src,user)<2)
var/obj/item/grab/G = attacking_item
if(istype(G.affecting,/mob/living))
grab_smash_attack(G, DAMAGE_BRUTE)
return
if(attacking_item.item_flags & ITEM_FLAG_NO_BLUDGEON)
return
/obj/structure/window/full/handle_construction(obj/item/attacking_item, mob/user)
if(attacking_item.tool_behaviour == TOOL_SCREWDRIVER && user.a_intent != I_HURT)
if(state == 2)
if(attacking_item.use_tool(src, user, 2 SECONDS, volume = 50))
to_chat(user, SPAN_NOTICE("You have unfastened the glass from the window frame."))
state--
update_nearby_icons()
return TRUE
else if(state == 1)
if(attacking_item.use_tool(src, user, 2 SECONDS, volume = 50))
to_chat(user, SPAN_NOTICE("You have fastened the glass to the window frame."))
state++
update_nearby_icons()
return TRUE
else if(attacking_item.tool_behaviour == TOOL_CROWBAR && user.a_intent != I_HURT)
if(state == 1)
if(attacking_item.use_tool(src, user, 2 SECONDS, volume = 50))
to_chat(user, SPAN_NOTICE("You pry the glass out of the window frame."))
state--
update_nearby_icons()
return TRUE
else if(state == 0)
if(attacking_item.use_tool(src, user, 2 SECONDS, volume = 50))
to_chat(user, SPAN_NOTICE("You pry the glass into the window frame."))
state++
update_nearby_icons()
return TRUE
else if(attacking_item.tool_behaviour == TOOL_WRENCH && user.a_intent != I_HURT)
if(state == 0)
user.visible_message(SPAN_DANGER("\The [user] is dismantling \the [src]!"))
if(attacking_item.use_tool(src, user, 2 SECONDS, volume = 50))
to_chat(user, SPAN_NOTICE("You undo the safety bolts and remove the glass from \the [src]."))
dismantle_window()
else
user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN)
if(attacking_item.damtype == DAMAGE_BRUTE || attacking_item.damtype == DAMAGE_BURN)
if(reinf)
user.do_attack_animation(src)
if(attacking_item.force >= FULL_REINFORCED_WINDOW_DAMAGE_FORCE)
user.visible_message(SPAN_DANGER("\The [user] forcefully strikes \the [src] with \the [attacking_item]!"))
playsound(src, hitsound, attacking_item.get_clamped_volume(), 1)
hit(attacking_item.force)
else
user.visible_message(SPAN_WARNING("[user] hits \the [src] with \the [attacking_item], but it glances off, doing no damage."))
playsound(src, hitsound, attacking_item.get_clamped_volume(), 1)
else
user.do_attack_animation(src)
hit(attacking_item.force)
else
playsound(src, hitsound, 10, 1)
return
return TRUE
return FALSE
/obj/structure/window/full/shatter(var/display_message = 1)
playsound(src, SFX_BREAK_GLASS, 70, 1)
@@ -716,27 +688,6 @@
qdel(src)
return
/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)
if(health <= 0)
shatter()
else
if(sound_effect)
playsound(loc, 'sound/effects/glass_hit.ogg', 100, 1)
if(health < maxhealth / 4 && initialhealth >= maxhealth / 4)
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)
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)
visible_message(SPAN_WARNING("Cracks begin to appear in [src]!"))
playsound(loc, SFX_GLASS_CRACK, 100, 1)
/obj/structure/window/full/dismantle_window()
var/obj/item/stack/material/mats = new glasstype(loc)
mats.amount = 4
@@ -861,6 +812,3 @@
reinf = TRUE
maximal_heat = T0C + 4000
rad_resistance_modifier = 4
#undef FULL_REINFORCED_WINDOW_DAMAGE_FORCE
#undef REINFORCED_WINDOW_DAMAGE_FORCE