mirror of
https://github.com/Aurorastation/Aurora.3.git
synced 2026-08-23 04:51:32 +01:00
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:
co-authored by
Matt Atlas
SleepyGemmy
parent
1d2871729f
commit
d5931c5ffe
@@ -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
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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)
|
||||
. += ..()
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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()
|
||||
. = ..()
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user