mirror of
https://github.com/Aurorastation/Aurora.3.git
synced 2026-08-22 20:43:10 +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
@@ -6,7 +6,7 @@
|
||||
anchored = TRUE
|
||||
density = FALSE
|
||||
mouse_opacity = MOUSE_OPACITY_ICON
|
||||
var/health = 15
|
||||
maxhealth = OBJECT_HEALTH_FRAGILE
|
||||
|
||||
//similar to weeds, but only barfed out by nurses manually
|
||||
/obj/effect/spider/ex_act(severity)
|
||||
@@ -34,27 +34,20 @@
|
||||
user.do_attack_animation(src)
|
||||
playsound(loc, attacking_item.hitsound, 50, 1, -1)
|
||||
|
||||
health -= damage
|
||||
healthcheck()
|
||||
add_damage(damage)
|
||||
|
||||
/obj/effect/spider/bullet_act(obj/projectile/hitting_projectile, def_zone, piercing_hit)
|
||||
. = ..()
|
||||
if(. != BULLET_ACT_HIT)
|
||||
return .
|
||||
|
||||
health -= hitting_projectile.get_structure_damage()
|
||||
healthcheck()
|
||||
|
||||
/obj/effect/spider/proc/healthcheck()
|
||||
if(health <= 0)
|
||||
qdel(src)
|
||||
add_damage(hitting_projectile.get_structure_damage())
|
||||
|
||||
/obj/effect/spider/fire_act(exposed_temperature, exposed_volume)
|
||||
. = ..()
|
||||
|
||||
if(exposed_temperature > 300 + T0C)
|
||||
health -= 5
|
||||
healthcheck()
|
||||
add_damage(5)
|
||||
|
||||
/obj/effect/spider/stickyweb
|
||||
icon_state = "stickyweb1"
|
||||
@@ -89,7 +82,7 @@
|
||||
name = "egg cluster"
|
||||
desc = "They seem to pulse slightly with an inner life."
|
||||
icon_state = "eggs"
|
||||
health = 10
|
||||
maxhealth = OBJECT_HEALTH_FRAGILE
|
||||
var/amount_grown = 0
|
||||
|
||||
/obj/effect/spider/eggcluster/Initialize(var/mapload, var/atom/parent)
|
||||
@@ -119,11 +112,6 @@
|
||||
new /obj/effect/spider/spiderling(src.loc, src, 0.75)
|
||||
qdel(src)
|
||||
|
||||
/obj/effect/spider/eggcluster/proc/take_damage(var/damage)
|
||||
health -= damage
|
||||
if(health <= 0)
|
||||
qdel(src)
|
||||
|
||||
/obj/effect/spider/spiderling
|
||||
name = "greimorian larva"
|
||||
desc = "A small, agile alien creature. It oozes some disgusting slime."
|
||||
@@ -133,7 +121,7 @@
|
||||
icon_state = "spiderling"
|
||||
anchored = FALSE
|
||||
layer = OPEN_DOOR_LAYER // 2.7
|
||||
health = 3
|
||||
maxhealth = 3
|
||||
var/last_itch = 0
|
||||
/// % chance that the spiderling will eventually turn into a fully-grown greimorian.
|
||||
var/can_mature_chance = 50
|
||||
@@ -185,10 +173,6 @@
|
||||
new /obj/effect/decal/cleanable/spiderling_remains(loc)
|
||||
qdel(src)
|
||||
|
||||
/obj/effect/spider/spiderling/healthcheck()
|
||||
if(health <= 0)
|
||||
die()
|
||||
|
||||
/obj/effect/spider/spiderling/process()
|
||||
if(travelling_in_vent)
|
||||
if(istype(src.loc, /turf))
|
||||
@@ -291,11 +275,10 @@
|
||||
name = "cocoon"
|
||||
desc = "Something wrapped in silky greimorian web"
|
||||
icon_state = "cocoon1"
|
||||
health = 60
|
||||
maxhealth = OBJECT_HEALTH_VERY_LOW
|
||||
|
||||
/obj/effect/spider/cocoon/Initialize()
|
||||
. = ..()
|
||||
|
||||
icon_state = pick("cocoon1","cocoon2","cocoon3")
|
||||
|
||||
/obj/effect/spider/cocoon/Destroy()
|
||||
|
||||
@@ -4,6 +4,8 @@
|
||||
w_class = WEIGHT_CLASS_NORMAL
|
||||
light_system = MOVABLE_LIGHT
|
||||
blocks_emissive = EMISSIVE_BLOCK_GENERIC
|
||||
/// Generic hit sound
|
||||
hitsound = SFX_SWING_HIT
|
||||
|
||||
/// This saves our blood splatter overlay, which will be processed not to go over the edges of the sprite
|
||||
var/image/blood_overlay
|
||||
@@ -11,13 +13,9 @@
|
||||
var/randpixel = 6
|
||||
var/abstract = 0
|
||||
var/r_speed = 1.0
|
||||
var/health
|
||||
var/burn_point
|
||||
var/burning
|
||||
|
||||
/// Generic hit sound
|
||||
var/hitsound = SFX_SWING_HIT
|
||||
|
||||
var/storage_cost
|
||||
|
||||
var/storage_slot_sort_by_name = FALSE
|
||||
@@ -151,10 +149,6 @@
|
||||
/// Sound uses when dropping the item, or when its thrown.
|
||||
var/drop_sound = SFX_DROP
|
||||
|
||||
var/list/armor
|
||||
/// How fast armor will degrade, multiplier to blocked damage to get armor damage value.
|
||||
var/armor_degradation_speed
|
||||
|
||||
//Item_state definition moved to /obj
|
||||
//var/item_state = null // Used to specify the item state for the on-mob overlays.
|
||||
|
||||
@@ -245,11 +239,6 @@
|
||||
|
||||
/obj/item/Initialize(mapload, ...)
|
||||
. = ..()
|
||||
if(islist(armor))
|
||||
for(var/type in armor)
|
||||
if(armor[type])
|
||||
AddComponent(/datum/component/armor, armor)
|
||||
break
|
||||
if(item_flags & ITEM_FLAG_HELD_MAP_TEXT)
|
||||
set_initial_maptext()
|
||||
check_maptext()
|
||||
@@ -345,7 +334,7 @@
|
||||
|
||||
. = ..(user, distance, is_adjacent, "It is a [size] item.", get_extended = get_extended)
|
||||
var/datum/component/armor/armor_component = GetComponent(/datum/component/armor)
|
||||
if(armor_component)
|
||||
if(armor_component && !armor_component.hidden)
|
||||
. += FONT_SMALL(SPAN_NOTICE("\[?\] This item has armor values. <a href='byond://?src=[REF(src)];examine_armor=1'>\[Show Armor Values\]</a>"))
|
||||
|
||||
/obj/item/Topic(href, href_list)
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
icon_state = "box"
|
||||
item_state = "box"
|
||||
contained_sprite = TRUE
|
||||
maxhealth = OBJECT_HEALTH_EXTREMELY_LOW
|
||||
color = COLOR_CARDBOARD
|
||||
var/label = "label"
|
||||
var/illustration = "writing"
|
||||
@@ -39,19 +40,17 @@
|
||||
///Boolean, if set, can be crushed into a trash item when empty
|
||||
var/trash = null
|
||||
|
||||
var/maxHealth = 20 //health is already defined
|
||||
use_sound = 'sound/items/storage/box.ogg'
|
||||
drop_sound = 'sound/items/drop/cardboardbox.ogg'
|
||||
pickup_sound = 'sound/items/pickup/cardboardbox.ogg'
|
||||
var/chewable = TRUE
|
||||
|
||||
/obj/item/storage/box/condition_hints(mob/user, distance, is_adjacent)
|
||||
. += ..()
|
||||
if (health < maxHealth)
|
||||
if (health >= (maxHealth * 0.5))
|
||||
. += SPAN_WARNING("It is slightly torn.")
|
||||
/obj/item/storage/box/get_damage_condition_hints(mob/user, distance, is_adjacent)
|
||||
if (health < maxhealth)
|
||||
if (health >= (maxhealth * 0.5))
|
||||
. = SPAN_WARNING("It is slightly torn.")
|
||||
else
|
||||
. += SPAN_DANGER("It is full of tears and holes.")
|
||||
. = SPAN_DANGER("It is full of tears and holes.")
|
||||
|
||||
/obj/item/storage/box/mechanics_hints(mob/user, distance, is_adjacent)
|
||||
. += ..()
|
||||
@@ -74,7 +73,8 @@
|
||||
|
||||
/obj/item/storage/box/Initialize()
|
||||
. = ..()
|
||||
health = maxHealth
|
||||
if(illustration)
|
||||
AddOverlays(illustration)
|
||||
update_icon()
|
||||
|
||||
/obj/item/storage/box/proc/damage(var/severity)
|
||||
|
||||
@@ -556,7 +556,6 @@
|
||||
/obj/item/reagent_containers/food/snacks/truffle/random
|
||||
)
|
||||
starts_with = list(/obj/item/reagent_containers/food/snacks/truffle/random = 8)
|
||||
maxHealth = 40
|
||||
|
||||
/obj/item/storage/box/fancy/chocolate_box/fill()
|
||||
for(var/i=1; i <= storage_slots; i++)
|
||||
|
||||
@@ -44,7 +44,8 @@
|
||||
anchored = TRUE
|
||||
mouse_opacity = MOUSE_OPACITY_ICON
|
||||
|
||||
var/health = 50
|
||||
maxhealth = OBJECT_HEALTH_VERY_LOW
|
||||
|
||||
var/mob/living/affecting = null //Who it is currently affecting, if anyone.
|
||||
|
||||
/obj/effect/energy_net/Initialize()
|
||||
|
||||
+58
-22
@@ -4,64 +4,76 @@
|
||||
|
||||
/// Used to store information about the contents of the object.
|
||||
var/list/matter
|
||||
/// Whether the object can be recycled (eaten) by something like the Autolathe
|
||||
/// Whether the object can be recycled (eaten) by something like the Autolathe.
|
||||
var/recyclable = FALSE
|
||||
/// Size of the object.
|
||||
var/w_class
|
||||
/// Used by R&D to determine what research bonuses it grants.
|
||||
var/list/origin_tech = null
|
||||
/// Universal "unacidabliness" var, here so you can use it in any obj.
|
||||
var/unacidable = FALSE
|
||||
/// Universal "unacidabliness" var, here so you can use it in any obj. As xeno acid is gone, this is now only used for chemistry acid.
|
||||
var/unacidable = 0
|
||||
|
||||
/// Special flags such as whether or not this object can be rotated.
|
||||
var/obj_flags
|
||||
/// Integer. Used for varied damage and item volume calculations.
|
||||
var/throwforce = 1
|
||||
/// Used in attackby() to say how something was attacked "[x] has been [z.attack_verb] by [y] with [z]"
|
||||
/// Used in attackby() to say how something was attacked "[x] has been [z.attack_verb] by [y] with [z]".
|
||||
var/list/attack_verb
|
||||
/// Whether this object cuts.
|
||||
var/sharp = FALSE
|
||||
/// Whether this object is more likely to dismember its poor foes.
|
||||
/// Whether this object creates CUT wounds.
|
||||
var/sharp = 0
|
||||
/// Whether this object is more likely to dismember.
|
||||
var/edge = FALSE
|
||||
/// If we have a user using us, this will be set on. We will check if the user has stopped using us, and thus stop updating and LAGGING EVERYTHING!
|
||||
var/in_use = FALSE
|
||||
/// Type of damage this object deals.
|
||||
var/in_use = 0
|
||||
/// The type of damage this object deals.
|
||||
var/damtype = DAMAGE_BRUTE
|
||||
/// The damage this object deals.
|
||||
var/force = 0
|
||||
/// The armour penetration this object has.
|
||||
var/armor_penetration = 0
|
||||
/// Makes an object not able to slice things.
|
||||
/// To make it not able to slice things. Used for curtains, flaps, pumpkins... why aren't you just using edge?
|
||||
var/noslice = FALSE
|
||||
/// The armor of this object, turned into an armor component.
|
||||
var/list/armor
|
||||
/// Set to TRUE when shocked by the tesla ball, to not repeatedly shock the object.
|
||||
var/being_shocked = FALSE
|
||||
|
||||
var/being_shocked = 0
|
||||
|
||||
/// If set, this holds the 3-letter shortname of a species, used for species-specific worn icons.
|
||||
/// The slot the object will equip to.
|
||||
var/equip_slot = 0
|
||||
/// If set, this holds the 3-letter shortname of a species, used for species-specific worn icons
|
||||
var/icon_species_tag = ""
|
||||
/// If TRUE, this item will automatically change its species tag to match the wearer's species, given the wearer's species is listed in icon_supported_species_tags.
|
||||
var/icon_auto_adapt = FALSE
|
||||
/// If 1, this item will automatically change its species tag to match the wearer's species. Requires that the wearer's species is listed in icon_supported_species_tags.
|
||||
var/icon_auto_adapt = 0
|
||||
|
||||
/**
|
||||
* A list of strings used with icon_auto_adapt, a list of species which have differing appearances for this item,
|
||||
* based on the specie short name
|
||||
* based on the species short name
|
||||
*/
|
||||
var/list/icon_supported_species_tags
|
||||
|
||||
/// If `TRUE`, will use the `icon_species_tag` var for rendering this item in the left/right hand.
|
||||
var/icon_species_in_hand = FALSE
|
||||
|
||||
var/equip_slot = 0
|
||||
/// Played when the item is used, for example tools.
|
||||
///Played when the item is used, for example tools
|
||||
var/usesound
|
||||
|
||||
/// The speed of the tool. This is generally a divisor.
|
||||
var/toolspeed = 1
|
||||
|
||||
/// The sound this tool makes in surgery.
|
||||
var/surgerysound
|
||||
|
||||
/* START BUCKLING VARS */
|
||||
/// A list of things that can buckle to this atom.
|
||||
var/list/can_buckle
|
||||
/// If the buckled atom can move, and thus face directions.
|
||||
var/buckle_movable = 0
|
||||
/// The direction forced on a buckled atom.
|
||||
var/buckle_dir = 0
|
||||
var/buckle_lying = -1 //bed-like behavior, forces mob.lying = buckle_lying if != -1
|
||||
var/buckle_require_restraints = 0 //require people to be handcuffed before being able to buckle. eg: pipes
|
||||
/// Causes bed-like behavior, forces mob.lying = buckle_lying if != -1.
|
||||
var/buckle_lying = -1
|
||||
/// Require people to be handcuffed before being able to buckle. eg: pipes.
|
||||
var/buckle_require_restraints = 0
|
||||
/// The atom buckled to us.
|
||||
var/atom/movable/buckled = null
|
||||
/**
|
||||
* Stores the original layer of a buckled atom.
|
||||
@@ -71,11 +83,14 @@
|
||||
* Used in `/unbuckle()` to restore the original layer.
|
||||
*/
|
||||
var/buckled_original_layer = null
|
||||
var/buckle_delay = 0 //How much extra time to buckle someone to this object.
|
||||
/// How much extra time to buckle someone to this object.
|
||||
var/buckle_delay = 0
|
||||
/* END BUCKLING VARS */
|
||||
|
||||
/* START ACCESS VARS */
|
||||
/// Required access.
|
||||
var/list/req_access
|
||||
/// Only require one of these accesses.
|
||||
var/list/req_one_access
|
||||
/* END ACCESS VARS */
|
||||
|
||||
@@ -93,6 +108,20 @@
|
||||
var/persistant_objects_expiration_time_days = PERSISTENT_DEFAULT_EXPIRATION_DAYS
|
||||
/* END PERSISTENCE VARS */
|
||||
|
||||
/obj/Initialize(mapload, ...)
|
||||
. = ..()
|
||||
if(maxhealth)
|
||||
if(!health)
|
||||
// Allows you to set dynamic health states on initialize.
|
||||
health = maxhealth
|
||||
if(islist(armor))
|
||||
for(var/type in armor)
|
||||
if(armor[type])
|
||||
AddComponent(/datum/component/armor, armor)
|
||||
break
|
||||
else if(should_use_health)
|
||||
AddComponent(/datum/component/armor, GLOB.default_object_armor, TRUE)
|
||||
|
||||
/obj/Destroy()
|
||||
if(persistent_objects_track_active) // Prevent hard deletion of references in the persistence register by removing it preemptively
|
||||
SSpersistence.objectsDeregisterTrack(src)
|
||||
@@ -127,6 +156,8 @@
|
||||
/mob/proc/CanUseObjTopic()
|
||||
return 1
|
||||
|
||||
|
||||
|
||||
/obj/proc/CouldUseTopic(var/mob/user)
|
||||
user.AddTopicPrint(src)
|
||||
|
||||
@@ -169,6 +200,11 @@
|
||||
if(loc)
|
||||
return loc.return_air()
|
||||
|
||||
/obj/condition_hints(mob/user, distance, is_adjacent)
|
||||
. += ..()
|
||||
if(health < maxhealth)
|
||||
. += get_damage_condition_hints(user, distance, is_adjacent)
|
||||
|
||||
/obj/proc/updateUsrDialog()
|
||||
if(in_use)
|
||||
var/is_in_use = 0
|
||||
|
||||
@@ -4,10 +4,10 @@
|
||||
layer = STRUCTURE_LAYER
|
||||
blocks_emissive = EMISSIVE_BLOCK_GENERIC
|
||||
pass_flags_self = PASSSTRUCTURE
|
||||
should_use_health = TRUE
|
||||
|
||||
var/material_alteration = MATERIAL_ALTERATION_ALL // Overrides for material shit. Set them manually if you don't want colors etc. See wood chairs/office chairs.
|
||||
var/climbable
|
||||
var/breakable
|
||||
var/parts
|
||||
var/list/climbers
|
||||
var/list/footstep_sound //footstep sounds when stepped on
|
||||
@@ -40,15 +40,23 @@
|
||||
material = null
|
||||
return ..()
|
||||
|
||||
/obj/structure/attackby(obj/item/attacking_item, mob/user, params)
|
||||
. = ..()
|
||||
if(user?.a_intent == I_HURT && maxhealth)
|
||||
user.do_attack_animation(src)
|
||||
user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN)
|
||||
add_damage(attacking_item.force, attacking_item.damage_flags(), attacking_item.damtype, attacking_item.armor_penetration, attacking_item)
|
||||
if(hitsound)
|
||||
playsound(user, hitsound, attacking_item.get_clamped_volume())
|
||||
|
||||
/obj/structure/attack_hand(mob/living/user)
|
||||
if(breakable)
|
||||
if((user.mutations & HULK) && !(user.isSynthetic()) && !(isvaurca(user)))
|
||||
user.say(pick(";RAAAAAAAARGH!", ";HNNNNNNNNNGGGGGGH!", ";GWAAAAAAAARRRHHH!", "NNNNNNNNGGGGGGGGHH!", ";AAAAAAARRRGH!" ))
|
||||
attack_generic(user,1,"smashes")
|
||||
else if(istype(user,/mob/living/carbon/human))
|
||||
var/mob/living/carbon/human/H = user
|
||||
if(H.species.can_shred(user))
|
||||
attack_generic(user,1,"slices")
|
||||
if((user.mutations & HULK) && !(user.isSynthetic()) && !(isvaurca(user)))
|
||||
user.say(pick("RAAAAAAAARGH!!!", "HNNNNNNNNNGGGGGGH!!!", "GWAAAAAAAARRRHHH!!!", "NNNNNNNNGGGGGGGGHH!!!", "AAAAAAARRRGH!!!" ))
|
||||
attack_generic(user, 25, "smashes")
|
||||
else if(istype(user,/mob/living/carbon/human))
|
||||
var/mob/living/carbon/human/H = user
|
||||
if(H.species.can_shred(user))
|
||||
attack_generic(user, 25, "slices")
|
||||
|
||||
if(LAZYLEN(climbers) && !(user in climbers))
|
||||
user.visible_message(SPAN_WARNING("[user] shakes \the [src]."), \
|
||||
@@ -75,6 +83,8 @@
|
||||
dismantle_material = SSmaterials.get_material_by_name(DEFAULT_WALL_MATERIAL) //if there is no defined material, it will use steel
|
||||
else
|
||||
dismantle_material = get_material()
|
||||
if(should_use_health && health <= 0)
|
||||
build_amt /= rand(2, 4) //if the structure is destroyed by damage, it will yield less materials
|
||||
for(var/i = 1 to build_amt)
|
||||
dismantle_material.place_sheet(loc)
|
||||
qdel(src)
|
||||
@@ -227,13 +237,8 @@
|
||||
return 0
|
||||
return 1
|
||||
|
||||
/obj/structure/attack_generic(mob/user, damage, attack_message, environment_smash, armor_penetration, attack_flags, damage_type)
|
||||
if(!breakable || !damage || !environment_smash)
|
||||
return 0
|
||||
visible_message(SPAN_DANGER("[user] [attack_verb] the [src] apart!"))
|
||||
user.do_attack_animation(src)
|
||||
qdel(src)
|
||||
return 1
|
||||
/obj/structure/on_death(damage, damage_flags, damage_type, armor_penetration, obj/weapon)
|
||||
dismantle()
|
||||
|
||||
/obj/structure/get_material()
|
||||
return material
|
||||
|
||||
@@ -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