Skip to content

Commit

Permalink
Adds reinforcing clothes with durathread (#3141)
Browse files Browse the repository at this point in the history
* Adds reinforcing clothes with durathread

* Blacklist shaft miner jumpsuit and already durathread shit

* avoid tm conflicts
  • Loading branch information
Absolucy authored Sep 8, 2024
1 parent d0a8d2a commit ebcce87
Show file tree
Hide file tree
Showing 5 changed files with 130 additions and 9 deletions.
29 changes: 21 additions & 8 deletions code/datums/armor/_armor.dm
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
/// 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()
/proc/generate_armor_type_cache() as /list
RETURN_TYPE(/list)
var/list/armor_cache = list()
for(var/datum/armor/armor_type as anything in subtypesof(/datum/armor))
armor_type = new armor_type
Expand All @@ -12,7 +13,8 @@ GLOBAL_LIST_INIT(armor_by_type, generate_armor_type_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)
/proc/get_armor_by_type(armor_type) as /datum/armor
RETURN_TYPE(/datum/armor)
var/armor = locate(replacetext("[armor_type]", "/", "-"))
if(armor)
return armor
Expand Down Expand Up @@ -68,7 +70,8 @@ GLOBAL_LIST_INIT(armor_by_type, generate_armor_type_cache())
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)
/datum/armor/proc/generate_new_with_modifiers(list/modifiers) as /datum/armor
RETURN_TYPE(/datum/armor)
var/datum/armor/new_armor = new

var/all_keys = ARMOR_LIST_ALL()
Expand All @@ -88,10 +91,12 @@ GLOBAL_LIST_INIT(armor_by_type, generate_armor_type_cache())
return new_armor

/datum/armor/immune/generate_new_with_modifiers(list/modifiers)
RETURN_TYPE(/datum/armor)
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)
/datum/armor/proc/generate_new_with_multipliers(list/multipliers) as /datum/armor
RETURN_TYPE(/datum/armor)
var/datum/armor/new_armor = new

var/all_keys = ARMOR_LIST_ALL()
Expand All @@ -111,10 +116,12 @@ GLOBAL_LIST_INIT(armor_by_type, generate_armor_type_cache())
return new_armor

/datum/armor/immune/generate_new_with_multipliers(list/multipliers)
RETURN_TYPE(/datum/armor)
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)
/datum/armor/proc/generate_new_with_specific(list/values) as /datum/armor
RETURN_TYPE(/datum/armor)
var/datum/armor/new_armor = new

var/all_keys = ARMOR_LIST_ALL()
Expand All @@ -134,10 +141,11 @@ GLOBAL_LIST_INIT(armor_by_type, generate_armor_type_cache())
return new_armor

/datum/armor/immune/generate_new_with_specific(list/values)
RETURN_TYPE(/datum/armor)
return src

/// Gets the rating of armor for the specified rating
/datum/armor/proc/get_rating(rating)
/datum/armor/proc/get_rating(rating) as num
// 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")
Expand All @@ -157,27 +165,32 @@ GLOBAL_LIST_INIT(armor_by_type, generate_armor_type_cache())
return ratings

/datum/armor/immune/get_rating_list(inverse)
RETURN_TYPE(/list)
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)
/datum/armor/proc/add_other_armor(datum/armor/other) as /datum/armor
RETURN_TYPE(/datum/armor)
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_TYPE(/datum/armor)
return src

/// Returns a new armor datum with the given armor removed from this one
/datum/armor/proc/subtract_other_armor(datum/armor/other)
/datum/armor/proc/subtract_other_armor(datum/armor/other) as /datum/armor
RETURN_TYPE(/datum/armor)
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_TYPE(/datum/armor)
return src

/// Checks if any of the armor values are non-zero, so this technically also counts negative armor!
Expand Down
2 changes: 1 addition & 1 deletion code/datums/armor/_atom_armor.dm
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/// Get the atom's armor reference
/atom/proc/get_armor()
/atom/proc/get_armor() as /datum/armor
RETURN_TYPE(/datum/armor)
return (armor ||= get_armor_by_type(armor_type))

Expand Down
18 changes: 18 additions & 0 deletions monkestation/code/datums/armor/_armor.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/datum/armor/proc/combine_max_armor(datum/armor/other) as /datum/armor
RETURN_TYPE(/datum/armor)
if(!other)
return src
var/list/ratings = get_rating_list()
for(var/rating in ratings)
ratings[rating] = max(ratings[rating], other.get_rating(rating))
return generate_new_with_specific(ratings)

/datum/armor/proc/operator~=(datum/armor/other)
if(ispath(other, /datum/armor))
other = get_armor_by_type(other)
if(!istype(other, /datum/armor))
return FALSE
for(var/rating in ARMOR_LIST_ALL())
if(vars[rating] != other.vars[rating])
return FALSE
return TRUE
88 changes: 88 additions & 0 deletions monkestation/code/modules/clothing/durathread_weave.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
/// A durathread weave has been used on this item.
#define TRAIT_DURATHREAD_INFUSED "durathread_infused"
#define DOAFTER_SOURCE_DURATHREAD_WEAVE "doafter_durathread_weave"

GLOBAL_LIST_INIT(durathread_weave_blacklist, typecacheof(list(
/obj/item/clothing/gloves/mod,
/obj/item/clothing/head/beanie/durathread,
/obj/item/clothing/head/beret/durathread,
/obj/item/clothing/head/costume/crown,
/obj/item/clothing/head/helmet/durathread,
/obj/item/clothing/head/helmet/space,
/obj/item/clothing/head/hooded/ablative,
/obj/item/clothing/head/mod,
/obj/item/clothing/head/utility,
/obj/item/clothing/mask/bandana/durathread,
/obj/item/clothing/shoes/magboots,
/obj/item/clothing/shoes/mod,
/obj/item/clothing/shoes/sandal,
/obj/item/clothing/suit/armor,
/obj/item/clothing/suit/chaplainsuit/armor,
/obj/item/clothing/suit/hooded/ablative,
/obj/item/clothing/suit/mod,
/obj/item/clothing/suit/space,
/obj/item/clothing/under/misc/durathread,
/obj/item/clothing/under/rank/cargo/miner,
)))

/obj/item/stack/sheet/durathread/examine(mob/user)
. = ..()
. += span_info("You can click on a piece of clothing, with an active welder in your offhand, in order to reinforce it!")

/obj/item/stack/sheet/durathread/afterattack(obj/item/clothing/clothing, mob/living/user, proximity)
. = ..()
if(. || !isliving(user) || !proximity)
return
. |= AFTERATTACK_PROCESSED_ITEM
var/obj/item/welder
for(var/obj/item/thingy in user.held_items)
if(thingy.tool_behaviour == TOOL_WELDER)
welder = thingy
break
if(QDELETED(welder))
to_chat(user, span_warning("You need to have a welder in your hands in order to reinforce clothing with durathread!"))
return
else if(!isclothing(clothing) || QDELING(clothing))
to_chat(user, span_warning("You can only reinforce clothing with durathread!"))
return
else if(is_type_in_typecache(clothing, GLOB.durathread_weave_blacklist))
to_chat(user, span_warning("You cannot reinforce [clothing] with durathread!"))
return
else if(HAS_TRAIT(clothing, TRAIT_DURATHREAD_INFUSED))
to_chat(user, span_warning("[clothing] already has durathread reinforcement!"))
return
else if(amount < 5)
to_chat(user, span_warning("You need at least 5 durathread to reinforce [src]!"))
return
to_chat(user, span_info("You begin to reinforce [clothing] with [src]..."))
if(!welder.use_tool(clothing, user, 10 SECONDS, 5, extra_checks = CALLBACK(src, PROC_REF(has_enough)), interaction_key = DOAFTER_SOURCE_DURATHREAD_WEAVE))
to_chat(user, span_warning("You fail to reinforce [clothing]!"))
return
var/datum/armor/clothing_armor = clothing.get_armor()
var/datum/armor/reinforced_armor = clothing_armor?.combine_max_armor(get_armor_by_type(/datum/armor/durathread_weave))
if(isnull(reinforced_armor))
CRASH("Got null armor when trying to reinforce clothing with durathread.")
else if(reinforced_armor ~= clothing_armor) // the armor was already as good as or better than the durathread reinforcement
to_chat(user, span_warning("[clothing] cannot be further reinforced!"))
return
if(!use(5))
to_chat(user, span_warning("You need at least 5 durathread to reinforce [src]!"))
return
to_chat(user, span_info("You reinforce [clothing] with durathread!"))
clothing.set_armor(reinforced_armor)
clothing.name = "durathread-reinforced [clothing.name]"
ADD_TRAIT(clothing, TRAIT_DURATHREAD_INFUSED, CLOTHING_TRAIT)

/obj/item/stack/sheet/durathread/proc/has_enough()
return amount >= 5

/datum/armor/durathread_weave
melee = 20
bullet = 10
laser = 30
energy = 30
fire = 35
acid = 35
wound = 20

#undef DOAFTER_SOURCE_DURATHREAD_WEAVE
2 changes: 2 additions & 0 deletions tgstation.dme
Original file line number Diff line number Diff line change
Expand Up @@ -5808,6 +5808,7 @@
#include "monkestation\code\datums\ai_laws\laws_monke.dm"
#include "monkestation\code\datums\announcers\dagoth.dm"
#include "monkestation\code\datums\announcers\duke.dm"
#include "monkestation\code\datums\armor\_armor.dm"
#include "monkestation\code\datums\brain_damage\magic.dm"
#include "monkestation\code\datums\brain_damage\phobia.dm"
#include "monkestation\code\datums\changelog\changelog.dm"
Expand Down Expand Up @@ -6706,6 +6707,7 @@
#include "monkestation\code\modules\client\preferences\species_features\simians.dm"
#include "monkestation\code\modules\client\verbs\deadchat.dm"
#include "monkestation\code\modules\client\verbs\looc.dm"
#include "monkestation\code\modules\clothing\durathread_weave.dm"
#include "monkestation\code\modules\clothing\accessories\accessories.dm"
#include "monkestation\code\modules\clothing\costumes\gnome.dm"
#include "monkestation\code\modules\clothing\costumes\henchmen.dm"
Expand Down

0 comments on commit ebcce87

Please # to comment.