mirror of
https://github.com/VOREStation/VOREStation.git
synced 2026-05-18 20:59:56 +01:00
84dc5535dc
* These two are easy * !!!runlevel_flags the fact it was global.runlevel_flags.len has me a bit...iffy on this. * !!!json_cache Same as above. used global. * player_list & observer_mob_list * mechas_list * this wasn't even used * surgery_steps * event_triggers * landmarks_list * dead_mob_list * living_mob_list * ai_list * cable_list * cleanbot_reserved_turfs * listening_objects * silicon_mob_list * human_mob_list * Update global_lists.dm * joblist * mob_list * Update global_lists.dm * holomap_markers * mapping_units * mapping_beacons * hair_styles_list * facial_hair_styles_list * Update global_lists.dm * facial_hair_styles_male_list * facial_hair_styles_female_list * body_marking_styles_list * body_marking_nopersist_list * ear_styles_list * hair_styles_male_list * tail_styles_list * wing_styles_list * escape_list & rune_list & endgame_exits these were all really small * endgame_safespawns * stool_cache * emotes_by_key * random_maps & map_count * item_tf_spawnpoints * narsie_list * active_radio_jammers * unused * paikeys * pai_software_by_key & default_pai_software * plant_seed_sprites * magazine_icondata_keys & magazine_icondata_states * unused * ashtray_cache * light_type_cache * HOLIDAY!!! this one was annoying * faction stuff (red?!) * Update preferences_factions.dm * vs edit removal * backbaglist, pdachoicelist, exclude_jobs * item_digestion_blacklist, edible_tech, blacklisted_artifact_effect, selectable_footstep, hexNums, syndicate_access * string_slot_flags and hexdigits->hexNums * possible_changeling_IDs * vr_mob_tf_options * vr_mob_spawner_options * pipe_colors * vr_mob_spawner_options * common_tools * newscaster_standard_feeds * Update periodic_news.dm * changeling_fabricated_clothing * semirandom_mob_spawner_decisions * id_card_states * Update syndicate_ids.dm * overlay_cache & gear_distributed_to * more * radio_channels_by_freq * Update global_lists.dm * proper * default_medbay_channels & default_internal_channels default_internal_channels is weird as it has a mapbased proc() but that proc is never called... * valid_ringtones * move this * possible_plants * more * separate these moves xeno2chemlist from a hook to a new global list. * tube_dir_list * valid_bloodreagents & monitor_states * Junk * valid_bloodtypes * breach_burn_descriptors & burn * more!! appliance_available_recipes seems uber cursed, re-look at later * Appliance code is cursed * wide_chassis & flying_chassis * allows_eye_color * all_tooltip_styles * direction_table * gun_choices * severity_to_string * old event_viruses * description_icons * MOVE_KEY_MAPPINGS * more more * pai & robot modules * Update global_lists.dm * GEOSAMPLES Also swaps a .len to LAZYLEN() * shieldgens * reagent recipies * global ammo types * rad collector * old file and unused global * nif_look_messages * FESH * nifsoft * chamelion * the death of sortAtom * globulins * lazylen that * Update global_lists.dm * LAZY * Theese too * quick fix --------- Co-authored-by: Kashargul <144968721+Kashargul@users.noreply.github.com>
213 lines
6.1 KiB
Plaintext
213 lines
6.1 KiB
Plaintext
//A 'wound' system for space suits.
|
|
//Breaches greatly increase the amount of lost gas and decrease the armour rating of the suit.
|
|
//They can be healed with plastic or metal sheeting.
|
|
|
|
/datum/breach
|
|
var/class = 0 // Size. Lower is smaller. Uses floating point values!
|
|
var/descriptor // 'gaping hole' etc.
|
|
var/damtype = BURN // Punctured or melted
|
|
var/obj/item/clothing/suit/space/holder // Suit containing the list of breaches holding this instance.
|
|
|
|
/obj/item/clothing/suit/space
|
|
|
|
var/can_breach = 1 // Set to 0 to disregard all breaching.
|
|
var/list/breaches = list() // Breach datum container.
|
|
var/resilience = 0.2 // Multiplier that turns damage into breach class. 1 is 100% of damage to breach, 0.1 is 10%. 0.2 -> 50 brute/burn damage to cause 10 breach damage
|
|
var/breach_threshold = 3 // Min damage before a breach is possible. Damage is subtracted by this amount, it determines the "hardness" of the suit.
|
|
var/damage = 0 // Current total damage
|
|
var/brute_damage = 0 // Specifically brute damage.
|
|
var/burn_damage = 0 // Specifically burn damage.
|
|
var/base_name // Used to keep the original name safe while we apply modifiers.
|
|
|
|
/obj/item/clothing/suit/space/Initialize(mapload)
|
|
. = ..()
|
|
base_name = "[name]"
|
|
|
|
/datum/breach/proc/update_descriptor()
|
|
|
|
//Sanity...
|
|
class = between(1, round(class), 5)
|
|
//Apply the correct descriptor.
|
|
if(damtype == BURN)
|
|
descriptor = GLOB.breach_burn_descriptors[class]
|
|
else if(damtype == BRUTE)
|
|
descriptor = GLOB.breach_brute_descriptors[class]
|
|
|
|
//Repair a certain amount of brute or burn damage to the suit.
|
|
/obj/item/clothing/suit/space/proc/repair_breaches(var/damtype, var/amount, var/mob/user)
|
|
|
|
if(!can_breach || !breaches || !breaches.len || !damage)
|
|
to_chat(user, "There are no breaches to repair on \the [src].")
|
|
return
|
|
|
|
var/list/valid_breaches = list()
|
|
|
|
for(var/datum/breach/B in breaches)
|
|
if(B.damtype == damtype)
|
|
valid_breaches += B
|
|
|
|
if(!valid_breaches.len)
|
|
to_chat(user, "There are no breaches to repair on \the [src].")
|
|
return
|
|
|
|
var/amount_left = amount
|
|
for(var/datum/breach/B in valid_breaches)
|
|
if(!amount_left) break
|
|
|
|
if(B.class <= amount_left)
|
|
amount_left -= B.class
|
|
valid_breaches -= B
|
|
breaches -= B
|
|
else
|
|
B.class -= amount_left
|
|
amount_left = 0
|
|
B.update_descriptor()
|
|
|
|
user.visible_message(span_infoplain(span_bold("[user]") + " patches some of the damage on \the [src]."))
|
|
calc_breach_damage()
|
|
|
|
/obj/item/clothing/suit/space/proc/create_breaches(var/damtype, var/amount)
|
|
|
|
amount -= src.breach_threshold
|
|
amount *= src.resilience
|
|
|
|
if(!can_breach || amount <= 0)
|
|
return
|
|
|
|
if(!breaches)
|
|
breaches = list()
|
|
|
|
if(damage > 25) return //We don't need to keep tracking it when it's at 250% pressure loss, really.
|
|
|
|
if(!loc) return
|
|
var/turf/T = get_turf(src)
|
|
if(!T) return
|
|
|
|
//Increase existing breaches.
|
|
for(var/datum/breach/existing in breaches)
|
|
|
|
if(existing.damtype != damtype)
|
|
continue
|
|
|
|
//keep in mind that 10 breach damage == full pressure loss.
|
|
//a breach can have at most 5 breach damage
|
|
if (existing.class < 5)
|
|
var/needs = 5 - existing.class
|
|
if(amount < needs)
|
|
existing.class += amount
|
|
amount = 0
|
|
else
|
|
existing.class = 5
|
|
amount -= needs
|
|
|
|
if(existing.damtype == BRUTE)
|
|
T.visible_message(span_warning("\The [existing.descriptor] on [src] gapes wider!"))
|
|
else if(existing.damtype == BURN)
|
|
T.visible_message(span_warning("\The [existing.descriptor] on [src] widens!"))
|
|
|
|
if (amount)
|
|
//Spawn a new breach.
|
|
var/datum/breach/B = new()
|
|
breaches += B
|
|
|
|
B.class = min(amount,5)
|
|
|
|
B.damtype = damtype
|
|
B.update_descriptor()
|
|
B.holder = src
|
|
|
|
if(B.damtype == BRUTE)
|
|
T.visible_message(span_warning("\A [B.descriptor] opens up on [src]!"))
|
|
else if(B.damtype == BURN)
|
|
T.visible_message(span_warning("\A [B.descriptor] marks the surface of [src]!"))
|
|
|
|
calc_breach_damage()
|
|
|
|
//Calculates the current extent of the damage to the suit.
|
|
/obj/item/clothing/suit/space/proc/calc_breach_damage()
|
|
|
|
damage = 0
|
|
brute_damage = 0
|
|
burn_damage = 0
|
|
|
|
if(!can_breach || !breaches || !breaches.len)
|
|
name = base_name
|
|
return 0
|
|
|
|
for(var/datum/breach/B in breaches)
|
|
if(!B.class)
|
|
src.breaches -= B
|
|
qdel(B)
|
|
else
|
|
damage += B.class
|
|
if(B.damtype == BRUTE)
|
|
brute_damage += B.class
|
|
else if(B.damtype == BURN)
|
|
burn_damage += B.class
|
|
|
|
if(damage >= 3)
|
|
if(brute_damage >= 3 && brute_damage > burn_damage)
|
|
name = "punctured [base_name]"
|
|
else if(burn_damage >= 3 && burn_damage > brute_damage)
|
|
name = "scorched [base_name]"
|
|
else
|
|
name = "damaged [base_name]"
|
|
else
|
|
name = "[base_name]"
|
|
|
|
return damage
|
|
|
|
//Handles repairs (and also upgrades).
|
|
|
|
/obj/item/clothing/suit/space/attackby(obj/item/W as obj, mob/user as mob)
|
|
if(istype(W,/obj/item/stack/material))
|
|
var/repair_power = 0
|
|
switch(W.get_material_name())
|
|
if(MAT_STEEL)
|
|
repair_power = 2
|
|
if(MAT_PLASTIC)
|
|
repair_power = 1
|
|
|
|
if(!repair_power)
|
|
return
|
|
|
|
if(isliving(src.loc))
|
|
to_chat(user, span_warning("How do you intend to patch a hardsuit while someone is wearing it?"))
|
|
return
|
|
|
|
if(!damage || !burn_damage)
|
|
to_chat(user, "There is no surface damage on \the [src] to repair.")
|
|
return
|
|
|
|
var/obj/item/stack/P = W
|
|
var/use_amt = min(P.get_amount(), 3)
|
|
if(use_amt && P.use(use_amt))
|
|
repair_breaches(BURN, use_amt * repair_power, user)
|
|
return
|
|
|
|
else if(W.has_tool_quality(TOOL_WELDER))
|
|
|
|
if(isliving(src.loc))
|
|
to_chat(user, span_red("How do you intend to patch a hardsuit while someone is wearing it?"))
|
|
return
|
|
|
|
if (!damage || ! brute_damage)
|
|
to_chat(user, "There is no structural damage on \the [src] to repair.")
|
|
return
|
|
|
|
var/obj/item/weldingtool/WT = W.get_welder()
|
|
if(!WT.remove_fuel(5))
|
|
to_chat(user, span_red("You need more welding fuel to repair this suit."))
|
|
return
|
|
|
|
repair_breaches(BRUTE, 3, user)
|
|
return
|
|
|
|
..()
|
|
|
|
/obj/item/clothing/suit/space/examine(mob/user)
|
|
. = ..()
|
|
if(can_breach && breaches?.len)
|
|
for(var/datum/breach/B in breaches)
|
|
. += span_red(span_bold("It has \a [B.descriptor]."))
|