mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2025-12-10 01:34:01 +00:00
* Refactors armor into dedicated subtypes * start * most tg things * pain (#18584) * shit * non-mod changes * compile Co-authored-by: John Doe <gamingskeleton3@gmail.com> * #18291 * compile fix * ??? Co-authored-by: Zephyr <12817816+ZephyrTFA@users.noreply.github.com> Co-authored-by: John Doe <gamingskeleton3@gmail.com> Co-authored-by: Zonespace <41448081+Zonespace27@users.noreply.github.com>
234 lines
6.7 KiB
Plaintext
234 lines
6.7 KiB
Plaintext
/// Assosciative list of type -> armor. Used to ensure we always hold a reference to default armor datums
|
|
GLOBAL_LIST_INIT(armor_by_type, generate_armor_type_cache())
|
|
|
|
/proc/generate_armor_type_cache()
|
|
var/list/armor_cache = list()
|
|
for(var/datum/armor/armor_type as anything in subtypesof(/datum/armor))
|
|
armor_type = new armor_type
|
|
armor_cache[armor_type.type] = armor_type
|
|
armor_type.GenerateTag()
|
|
return armor_cache
|
|
|
|
/**
|
|
* Gets an armor type datum using the given type by formatting it into the expected datum tag
|
|
*/
|
|
/proc/get_armor_by_type(armor_type)
|
|
var/armor = locate(replacetext("[armor_type]", "/", "-"))
|
|
if(armor)
|
|
return armor
|
|
if(armor_type == /datum/armor)
|
|
CRASH("Attempted to get the base armor type, you probably meant to use /datum/armor/none")
|
|
CRASH("Attempted to get an armor type that did not exist! '[armor_type]'")
|
|
|
|
/**
|
|
* The armor datum holds information about different types of armor that an atom can have.
|
|
* It also contains logic and helpers for calculating damage and effective damage
|
|
*/
|
|
/datum/armor
|
|
VAR_PROTECTED/acid = 0
|
|
VAR_PROTECTED/bio = 0
|
|
VAR_PROTECTED/bomb = 0
|
|
VAR_PROTECTED/bullet = 0
|
|
VAR_PROTECTED/consume = 0
|
|
VAR_PROTECTED/energy = 0
|
|
VAR_PROTECTED/laser = 0
|
|
VAR_PROTECTED/fire = 0
|
|
VAR_PROTECTED/melee = 0
|
|
VAR_PROTECTED/wound = 0
|
|
|
|
/// A version of armor with no protections
|
|
/datum/armor/none
|
|
|
|
/// A version of armor that cannot be modified and will always return itself when attempted to be modified
|
|
/datum/armor/immune
|
|
|
|
/datum/armor/Destroy(force, ...)
|
|
if(!force && tag)
|
|
return QDEL_HINT_LETMELIVE
|
|
|
|
// something really wants us gone
|
|
datum_flags &= ~DF_USE_TAG
|
|
tag = null
|
|
return ..()
|
|
|
|
/datum/armor/GenerateTag()
|
|
..()
|
|
tag = replacetext("[type]", "/", "-")
|
|
|
|
/datum/armor/vv_edit_var(var_name, var_value)
|
|
return FALSE
|
|
|
|
/datum/armor/can_vv_mark()
|
|
return FALSE
|
|
|
|
/datum/armor/vv_get_dropdown()
|
|
return list("", "MUST MODIFY ARMOR VALUES ON THE PARENT ATOM")
|
|
|
|
/datum/armor/CanProcCall(procname)
|
|
return FALSE
|
|
|
|
/// Generate a brand new armor datum with the modifiers given, if ARMOR_ALL is specified only that modifier is used
|
|
/datum/armor/proc/generate_new_with_modifiers(list/modifiers)
|
|
var/datum/armor/new_armor = new
|
|
|
|
var/all_keys = ARMOR_LIST_ALL()
|
|
if(ARMOR_ALL in modifiers)
|
|
var/modifier_all = modifiers[ARMOR_ALL]
|
|
if(!modifier_all)
|
|
return src
|
|
for(var/mod in all_keys)
|
|
new_armor.vars[mod] = vars[mod] + modifier_all
|
|
return new_armor
|
|
|
|
for(var/modifier in modifiers)
|
|
if(modifier in all_keys)
|
|
new_armor.vars[modifier] = vars[modifier] + modifiers[modifier]
|
|
else
|
|
stack_trace("Attempt to call generate_new_with_modifiers with illegal modifier '[modifier]'! Ignoring it")
|
|
return new_armor
|
|
|
|
/datum/armor/immune/generate_new_with_modifiers(list/modifiers)
|
|
return src
|
|
|
|
/// Generate a brand new armor datum with the multiplier given, if ARMOR_ALL is specified only that modifer is used
|
|
/datum/armor/proc/generate_new_with_multipliers(list/multipliers)
|
|
var/datum/armor/new_armor = new
|
|
|
|
var/all_keys = ARMOR_LIST_ALL()
|
|
if(ARMOR_ALL in multipliers)
|
|
var/multiplier_all = multipliers[ARMOR_ALL]
|
|
if(!multiplier_all)
|
|
return src
|
|
for(var/multiplier in all_keys)
|
|
new_armor.vars[multiplier] = vars[multiplier] * multiplier_all
|
|
return new_armor
|
|
|
|
for(var/multiplier in multipliers)
|
|
if(multiplier in all_keys)
|
|
new_armor.vars[multiplier] = vars[multiplier] * multipliers[multiplier]
|
|
else
|
|
stack_trace("Attempt to call generate_new_with_multipliers with illegal multiplier '[multiplier]'! Ignoring it")
|
|
return new_armor
|
|
|
|
/datum/armor/immune/generate_new_with_multipliers(list/multipliers)
|
|
return src
|
|
|
|
/// Generate a brand new armor datum with the values given, if a value is not present it carries over
|
|
/datum/armor/proc/generate_new_with_specific(list/values)
|
|
var/datum/armor/new_armor = new
|
|
|
|
var/all_keys = ARMOR_LIST_ALL()
|
|
if(ARMOR_ALL in values)
|
|
var/value_all = values[ARMOR_ALL]
|
|
if(!value_all)
|
|
return src
|
|
for(var/mod in all_keys)
|
|
new_armor.vars[mod] = value_all
|
|
return new_armor
|
|
|
|
for(var/value in values)
|
|
if(value in all_keys)
|
|
new_armor.vars[value] = values[value]
|
|
else
|
|
stack_trace("Attempt to call generate_new_with_specific with illegal value '[value]'! Ignoring it")
|
|
return new_armor
|
|
|
|
/datum/armor/immune/generate_new_with_specific(list/values)
|
|
return src
|
|
|
|
/// Gets the rating of armor for the specified rating
|
|
/datum/armor/proc/get_rating(rating)
|
|
// its not that I dont trust coders, its just that I don't trust coders
|
|
if(!(rating in ARMOR_LIST_ALL()))
|
|
CRASH("Attempted to get a rating '[rating]' that doesnt exist")
|
|
return vars[rating]
|
|
|
|
/datum/armor/immune/get_rating(rating)
|
|
return 100
|
|
|
|
/// Converts all the ratings of the armor into a list, optionally inversed
|
|
/datum/armor/proc/get_rating_list(inverse = FALSE)
|
|
var/ratings = list()
|
|
for(var/rating in ARMOR_LIST_ALL())
|
|
var/value = vars[rating]
|
|
if(inverse)
|
|
value *= -1
|
|
ratings[rating] = value
|
|
return ratings
|
|
|
|
/datum/armor/immune/get_rating_list(inverse)
|
|
var/ratings = ..() // get all ratings
|
|
for(var/rating in ratings)
|
|
ratings[rating] = 100 // and set them to 100
|
|
return ratings
|
|
|
|
/// Returns a new armor datum with the given armor added onto this one
|
|
/datum/armor/proc/add_other_armor(datum/armor/other)
|
|
if(ispath(other))
|
|
other = get_armor_by_type(other)
|
|
return generate_new_with_modifiers(other.get_rating_list())
|
|
|
|
/datum/armor/immune/add_other_armor(datum/armor/other)
|
|
return src
|
|
|
|
/// Returns a new armor datum with the given armor removed from this one
|
|
/datum/armor/proc/subtract_other_armor(datum/armor/other)
|
|
if(ispath(other))
|
|
other = get_armor_by_type(other)
|
|
return generate_new_with_modifiers(other.get_rating_list(inverse = TRUE))
|
|
|
|
/datum/armor/immune/subtract_other_armor(datum/armor/other)
|
|
return src
|
|
|
|
/// Checks if any of the armor values are non-zero, so this technically also counts negative armor!
|
|
/datum/armor/proc/has_any_armor()
|
|
for(var/rating as anything in ARMOR_LIST_ALL())
|
|
if(vars[rating])
|
|
return TRUE
|
|
return FALSE
|
|
|
|
/datum/armor/immune/has_any_armor()
|
|
return TRUE
|
|
|
|
/**
|
|
* Rounds armor_value down to the nearest 10, divides it by 10 and then converts it to Roman numerals.
|
|
*
|
|
* Arguments:
|
|
* * armor_value - Number we're converting
|
|
*/
|
|
/proc/armor_to_protection_class(armor_value)
|
|
if (armor_value < 0)
|
|
. = "-"
|
|
. += "\Roman[round(abs(armor_value), 10) / 10]"
|
|
return .
|
|
|
|
/**
|
|
* Returns the client readable name of an armor type
|
|
*
|
|
* Arguments:
|
|
* * armor_type - The type to convert
|
|
*/
|
|
/proc/armor_to_protection_name(armor_type)
|
|
switch(armor_type)
|
|
if(ACID)
|
|
return "ACID"
|
|
if(BIO)
|
|
return "BIOHAZARD"
|
|
if(BOMB)
|
|
return "EXPLOSIVE"
|
|
if(BULLET)
|
|
return "BULLET"
|
|
if(CONSUME)
|
|
return "CONSUMING"
|
|
if(ENERGY)
|
|
return "ENERGY"
|
|
if(FIRE)
|
|
return "FIRE"
|
|
if(LASER)
|
|
return "LASER"
|
|
if(MELEE)
|
|
return "MELEE"
|
|
if(WOUND)
|
|
return "WOUNDING"
|
|
CRASH("Unknown armor type '[armor_type]'")
|