Files
Bubberstation/code/game/objects/items/storage/backpack.dm
Ghom 4f6727024d Crafting refactor, implementing materials (#89465)
## About The Pull Request
My original plan was to just implement materials into crafting so that
items would inherit the materials of their components, allowing for some
interesting stuff if the material flags of the item allow it. However to
my dismay crafting is a pile of old tech debt, starting from the old
`del_reqs` and `CheckParts` which still contain lines about old janky
bandaids that are no longer in use nor reachable, up to the
`customizable_reagent_holder` component which has some harddel issues
when your custom food is sliced, and items used in food recipes not
being deleted and instead stored inside the result with no purpose as
well as other inconsistencies like stack recipes that transfer materials
having counterparts in the UI that don't do that.

EDIT: Several things have come up while working on this, so I apologise
that it ended up changing over 100+ files. I managed to atomize some of
the changes, but it's a bit tedious.

EDIT: TLDR because I was told this section is too vague and there's too
much going on. This PR:
- Improves the dated crafting code (not the UI).
- replaced `atom/CheckParts` and `crafting_recipe/on_craft_completion`
with `atom/on_craft_completion`.
- Reqs used in food recipes are now deleted by default and not stored
inside the result (they did nothing).
- Renames the customizable_reagent_holder comp and improves it (No
harddels/ref issues).
- Adds a unit test that tries to craft all recipes to see what's wrong
(it skips some of the much more specific reqs for now).
- In the unit test is also the code to make sure materials of the
crafted item and a non-crafted item of the same type are roughly the
same, so far only applied to food.
- Some mild material/food refactoring around the fact that food item
code has been changed to support materials.

## Why It's Good For The Game
Improving the backbone of the crafting system. Also materials and food
code.

## Changelog

🆑
refactor: Refactored crafting backend. Report possible pesky bugs.
balance: the MEAT backpack (from the MEAT cargo pack) may be a smidge
different because of code standardization.
/🆑
2025-06-01 16:37:43 -07:00

482 lines
17 KiB
Plaintext

/* Backpacks
* Contains:
* Backpack
* Backpack Types
* Satchel Types
*/
/*
* Backpack
*/
/obj/item/storage/backpack
name = "backpack"
desc = "You wear this on your back and put items into it."
icon = 'icons/obj/storage/backpack.dmi'
worn_icon = 'icons/mob/clothing/back/backpack.dmi'
icon_state = "backpack"
inhand_icon_state = "backpack"
lefthand_file = 'icons/mob/inhands/equipment/backpack_lefthand.dmi'
righthand_file = 'icons/mob/inhands/equipment/backpack_righthand.dmi'
w_class = WEIGHT_CLASS_BULKY
slot_flags = ITEM_SLOT_BACK //ERROOOOO
resistance_flags = NONE
max_integrity = 300
storage_type = /datum/storage/backpack
pickup_sound = 'sound/items/handling/backpack/backpack_pickup1.ogg'
drop_sound = 'sound/items/handling/backpack/backpack_drop1.ogg'
equip_sound = 'sound/items/equip/backpack_equip.ogg'
sound_vary = TRUE
/obj/item/storage/backpack/Initialize(mapload)
. = ..()
AddElement(/datum/element/attack_equip)
/*
* Backpack Types
*/
/obj/item/bag_of_holding_inert
name = "inert bag of holding"
desc = "What is currently a just an unwieldy block of metal with a slot ready to accept a bluespace anomaly core."
icon = 'icons/obj/storage/backpack.dmi'
worn_icon = 'icons/mob/clothing/back/backpack.dmi'
icon_state = "bag_of_holding-inert"
inhand_icon_state = "brokenpack"
lefthand_file = 'icons/mob/inhands/equipment/backpack_lefthand.dmi'
righthand_file = 'icons/mob/inhands/equipment/backpack_righthand.dmi'
w_class = WEIGHT_CLASS_BULKY
resistance_flags = FIRE_PROOF
item_flags = NO_MAT_REDEMPTION
/obj/item/bag_of_holding_inert/Initialize(mapload)
. = ..()
var/static/list/recipes = list(/datum/crafting_recipe/boh)
AddElement(/datum/element/slapcrafting, recipes)
/obj/item/storage/backpack/holding
name = "bag of holding"
desc = "A backpack that opens into a localized pocket of bluespace."
icon_state = "bag_of_holding"
inhand_icon_state = "holdingpack"
resistance_flags = FIRE_PROOF
item_flags = NO_MAT_REDEMPTION
armor_type = /datum/armor/backpack_holding
storage_type = /datum/storage/bag_of_holding
pickup_sound = null
drop_sound = null
/datum/armor/backpack_holding
fire = 60
acid = 50
/obj/item/storage/backpack/holding/suicide_act(mob/living/user)
user.visible_message(span_suicide("[user] is jumping into [src]! It looks like [user.p_theyre()] trying to commit suicide."))
user.dropItemToGround(src, TRUE)
user.Stun(100, ignore_canstun = TRUE)
sleep(2 SECONDS)
playsound(src, SFX_RUSTLE, 50, TRUE, -5)
user.suicide_log()
qdel(user)
/obj/item/storage/backpack/santabag
name = "Santa's Gift Bag"
desc = "Space Santa uses this to deliver presents to all the nice children in space in Christmas! Wow, it's pretty big!"
icon_state = "giftbag0"
inhand_icon_state = "giftbag"
w_class = WEIGHT_CLASS_BULKY
storage_type = /datum/storage/backpack/santabag
/obj/item/storage/backpack/santabag/Initialize(mapload)
. = ..()
regenerate_presents()
/obj/item/storage/backpack/santabag/suicide_act(mob/living/user)
user.visible_message(span_suicide("[user] places [src] over [user.p_their()] head and pulls it tight! It looks like [user.p_they()] [user.p_are()]n't in the Christmas spirit..."))
return OXYLOSS
/obj/item/storage/backpack/santabag/proc/regenerate_presents()
addtimer(CALLBACK(src, PROC_REF(regenerate_presents)), 30 SECONDS)
var/mob/user = get(loc, /mob)
if(!istype(user))
return
if(HAS_MIND_TRAIT(user, TRAIT_CANNOT_OPEN_PRESENTS))
var/turf/floor = get_turf(src)
var/obj/item/thing = new /obj/item/gift/anything(floor)
if(!atom_storage.attempt_insert(thing, user, override = TRUE, force = STORAGE_SOFT_LOCKED))
qdel(thing)
/obj/item/storage/backpack/cultpack
name = "trophy rack"
desc = "It's useful for both carrying extra gear and proudly declaring your insanity."
icon_state = "backpack-cult"
inhand_icon_state = "backpack"
alternate_worn_layer = ABOVE_BODY_FRONT_HEAD_LAYER
/obj/item/storage/backpack/clown
name = "Giggles von Honkerton"
desc = "It's a backpack made by Honk! Co."
icon_state = "backpack-clown"
inhand_icon_state = "clownpack"
/obj/item/storage/backpack/explorer
name = "explorer bag"
desc = "A robust backpack for stashing your loot."
icon_state = "backpack-explorer"
inhand_icon_state = "explorerpack"
/obj/item/storage/backpack/mime
name = "Parcel Parceaux"
desc = "A silent backpack made for those silent workers. Silence Co."
icon_state = "backpack-mime"
inhand_icon_state = "mimepack"
/obj/item/storage/backpack/medic
name = "medical backpack"
desc = "It's a backpack especially designed for use in a sterile environment."
icon_state = "backpack-medical"
inhand_icon_state = "medicalpack"
/obj/item/storage/backpack/coroner
name = "coroner backpack"
desc = "It's a backpack especially designed for use in an undead environment."
icon_state = "backpack-coroner"
inhand_icon_state = "coronerpack"
/obj/item/storage/backpack/security
name = "security backpack"
desc = "It's a very robust backpack."
icon_state = "backpack-security"
inhand_icon_state = "securitypack"
/obj/item/storage/backpack/captain
name = "captain's backpack"
desc = "It's a special backpack made exclusively for Nanotrasen officers."
icon_state = "backpack-captain"
inhand_icon_state = "captainpack"
/obj/item/storage/backpack/industrial
name = "industrial backpack"
desc = "It's a tough backpack for the daily grind of station life."
icon_state = "backpack-engineering"
inhand_icon_state = "engiepack"
resistance_flags = FIRE_PROOF
/obj/item/storage/backpack/botany
name = "botany backpack"
desc = "It's a backpack made of all-natural fibers."
icon_state = "backpack-hydroponics"
inhand_icon_state = "botpack"
/obj/item/storage/backpack/chemistry
name = "chemistry backpack"
desc = "A backpack specially designed to repel stains and hazardous liquids."
icon_state = "backpack-chemistry"
inhand_icon_state = "chempack"
/obj/item/storage/backpack/genetics
name = "genetics backpack"
desc = "A bag designed to be super tough, just in case someone hulks out on you."
icon_state = "backpack-genetics"
inhand_icon_state = "genepack"
/obj/item/storage/backpack/science
name = "science backpack"
desc = "A specially designed backpack. It's fire resistant and smells vaguely of plasma."
icon_state = "backpack-science"
inhand_icon_state = "scipack"
/obj/item/storage/backpack/virology
name = "virology backpack"
desc = "A backpack made of hypo-allergenic fibers. It's designed to help prevent the spread of disease. Smells like monkey."
icon_state = "backpack-virology"
inhand_icon_state = "viropack"
/obj/item/storage/backpack/floortile
name = "floortile backpack"
desc = "It's a backpack especially designed for use in floortiles..."
icon_state = "floortile_backpack"
inhand_icon_state = "backpack"
/obj/item/storage/backpack/ert
name = "emergency response team commander backpack"
desc = "A spacious backpack with lots of pockets, worn by the Commander of an Emergency Response Team."
icon_state = "ert_commander"
inhand_icon_state = "securitypack"
resistance_flags = FIRE_PROOF
/obj/item/storage/backpack/ert/security
name = "emergency response team security backpack"
desc = "A spacious backpack with lots of pockets, worn by Security Officers of an Emergency Response Team."
icon_state = "ert_security"
/obj/item/storage/backpack/ert/medical
name = "emergency response team medical backpack"
desc = "A spacious backpack with lots of pockets, worn by Medical Officers of an Emergency Response Team."
icon_state = "ert_medical"
/obj/item/storage/backpack/ert/engineer
name = "emergency response team engineer backpack"
desc = "A spacious backpack with lots of pockets, worn by Engineers of an Emergency Response Team."
icon_state = "ert_engineering"
/obj/item/storage/backpack/ert/janitor
name = "emergency response team janitor backpack"
desc = "A spacious backpack with lots of pockets, worn by Janitors of an Emergency Response Team."
icon_state = "ert_janitor"
/obj/item/storage/backpack/ert/clown
name = "emergency response team clown backpack"
desc = "A spacious backpack with lots of pockets, worn by Clowns of an Emergency Response Team."
icon_state = "ert_clown"
/obj/item/storage/backpack/saddlepack
name = "saddlepack"
desc = "A backpack designed to be saddled on a mount or carried on your back, and switch between the two on the fly. It's quite spacious, at the cost of making you feel like a literal pack mule."
icon = 'icons/obj/storage/ethereal.dmi'
worn_icon = 'icons/mob/clothing/back/ethereal.dmi'
icon_state = "saddlepack"
storage_type = /datum/storage/backpack/saddle
// MEAT MEAT MEAT MEAT MEAT
///This nullifies the force malus from the meat material while not touching other stats.
#define INVERSE_MEAT_STRENTGH (1 / /datum/material/meat::strength_modifier)
/obj/item/storage/backpack/meat
name = "\improper MEAT"
desc = "MEAT MEAT MEAT MEAT MEAT MEAT"
icon_state = "meatmeatmeat"
inhand_icon_state = "meatmeatmeat"
force = 15 * INVERSE_MEAT_STRENTGH
throwforce = 15 * INVERSE_MEAT_STRENTGH
material_flags = MATERIAL_EFFECTS | MATERIAL_AFFECT_STATISTICS
attack_verb_continuous = list("MEATS", "MEAT MEATS")
attack_verb_simple = list("MEAT", "MEAT MEAT")
custom_materials = list(/datum/material/meat = SHEET_MATERIAL_AMOUNT * 15) // MEAT
///Sounds used in the squeak component
var/list/meat_sounds = list('sound/effects/blob/blobattack.ogg' = 1)
///Reagents added to the edible component on top of the meat material, ingested when you EAT the MEAT
var/list/meat_reagents = list(
/datum/reagent/consumable/nutriment/vitamin = 15,
)
///Eating verbs when consuming the MEAT
var/list/eatverbs = list("MEAT", "absorb", "gnaw", "consume")
/obj/item/storage/backpack/meat/Initialize(mapload)
. = ..()
AddComponentFrom(
SOURCE_EDIBLE_INNATE, \
/datum/component/edible,\
initial_reagents = meat_reagents,\
tastes = list("meat" = 1),\
eatverbs = eatverbs,\
)
AddComponent(/datum/component/squeak, meat_sounds)
#undef INVERSE_MEAT_STRENTGH
/*
* Satchel Types
*/
/obj/item/storage/backpack/satchel
name = "satchel"
desc = "A trendy looking satchel."
icon_state = "satchel-norm"
inhand_icon_state = "satchel-norm"
/obj/item/storage/backpack/satchel/leather
name = "leather satchel"
desc = "It's a very fancy satchel made with fine leather."
icon_state = "satchel-leather"
inhand_icon_state = "satchel"
/obj/item/storage/backpack/satchel/leather/withwallet/PopulateContents()
new /obj/item/storage/wallet/random(src)
/obj/item/storage/backpack/satchel/fireproof
resistance_flags = FIRE_PROOF
/obj/item/storage/backpack/satchel/eng
name = "industrial satchel"
desc = "A tough satchel with extra pockets."
icon_state = "satchel-engineering"
inhand_icon_state = "satchel-eng"
resistance_flags = FIRE_PROOF
/obj/item/storage/backpack/satchel/med
name = "medical satchel"
desc = "A sterile satchel used in medical departments."
icon_state = "satchel-medical"
inhand_icon_state = "satchel-med"
/obj/item/storage/backpack/satchel/vir
name = "virologist satchel"
desc = "A sterile satchel with virologist colours."
icon_state = "satchel-virology"
inhand_icon_state = "satchel-vir"
/obj/item/storage/backpack/satchel/chem
name = "chemist satchel"
desc = "A sterile satchel with chemist colours."
icon_state = "satchel-chemistry"
inhand_icon_state = "satchel-chem"
/obj/item/storage/backpack/satchel/coroner
name = "coroner satchel"
desc = "A satchel used to carry whatever's left of human bodies."
icon_state = "satchel-coroner"
inhand_icon_state = "satchel-coroner"
/obj/item/storage/backpack/satchel/gen
name = "geneticist satchel"
desc = "A sterile satchel with geneticist colours."
icon_state = "satchel-genetics"
inhand_icon_state = "satchel-gen"
/obj/item/storage/backpack/satchel/science
name = "scientist satchel"
desc = "Useful for holding research materials."
icon_state = "satchel-science"
inhand_icon_state = "satchel-sci"
/obj/item/storage/backpack/satchel/hyd
name = "botanist satchel"
desc = "A satchel made of all natural fibers."
icon_state = "satchel-hydroponics"
inhand_icon_state = "satchel-hyd"
/obj/item/storage/backpack/satchel/sec
name = "security satchel"
desc = "A robust satchel for security related needs."
icon_state = "satchel-security"
inhand_icon_state = "satchel-sec"
/obj/item/storage/backpack/satchel/explorer
name = "explorer satchel"
desc = "A robust satchel for stashing your loot."
icon_state = "satchel-explorer"
inhand_icon_state = "satchel-explorer"
/obj/item/storage/backpack/satchel/cap
name = "captain's satchel"
desc = "An exclusive satchel for Nanotrasen officers."
icon_state = "satchel-captain"
inhand_icon_state = "satchel-cap"
/obj/item/storage/backpack/satchel/flat
name = "smuggler's satchel"
desc = "A very slim satchel that can easily fit into tight spaces. Its contents cannot be detected by contraband scanners."
icon_state = "satchel-flat"
inhand_icon_state = "satchel-flat"
w_class = WEIGHT_CLASS_NORMAL //Can fit in backpacks itself.
storage_type = /datum/storage/backpack/satchel_flat
/obj/item/storage/backpack/satchel/flat/Initialize(mapload)
. = ..()
AddElement(/datum/element/undertile, TRAIT_T_RAY_VISIBLE, INVISIBILITY_OBSERVER, use_anchor = TRUE)
ADD_TRAIT(src, TRAIT_CONTRABAND_BLOCKER, INNATE_TRAIT)
/obj/item/storage/backpack/satchel/flat/PopulateContents()
for(var/items in 1 to 4)
new /obj/effect/spawner/random/contraband(src)
/obj/item/storage/backpack/satchel/flat/with_tools/PopulateContents()
new /obj/item/stack/tile/iron/base(src)
new /obj/item/crowbar(src)
..()
/obj/item/storage/backpack/satchel/flat/empty/PopulateContents()
return
/// Messenger Bag Types
/obj/item/storage/backpack/messenger
name = "messenger bag"
desc = "A trendy looking messenger bag; sometimes known as a courier bag. Fashionable and portable."
icon_state = "messenger"
inhand_icon_state = "messenger"
icon = 'icons/obj/storage/backpack.dmi'
worn_icon = 'icons/mob/clothing/back/backpack.dmi'
lefthand_file = 'icons/mob/inhands/equipment/backpack_lefthand.dmi'
righthand_file = 'icons/mob/inhands/equipment/backpack_righthand.dmi'
/obj/item/storage/backpack/messenger/eng
name = "industrial messenger bag"
desc = "A tough messenger bag made of advanced treated leather for fireproofing. It also has more pockets than usual."
icon_state = "messenger_engineering"
inhand_icon_state = "messenger_engineering"
resistance_flags = FIRE_PROOF
/obj/item/storage/backpack/messenger/med
name = "medical messenger bag"
desc = "A sterile messenger bag well loved by medics for its portability and sleek profile."
icon_state = "messenger_medical"
inhand_icon_state = "messenger_medical"
/obj/item/storage/backpack/messenger/vir
name = "virologist messenger bag"
desc = "A sterile messenger bag with virologist colours, useful for deploying biohazards in record times."
icon_state = "messenger_virology"
inhand_icon_state = "messenger_virology"
/obj/item/storage/backpack/messenger/chem
name = "chemist messenger bag"
desc = "A sterile messenger bag with chemist colours, good for getting to your alleyway deals on time."
icon_state = "messenger_chemistry"
inhand_icon_state = "messenger_chemistry"
/obj/item/storage/backpack/messenger/coroner
name = "coroner messenger bag"
desc = "A messenger bag used to sneak your way out of graveyards at a good pace."
icon_state = "messenger_coroner"
inhand_icon_state = "messenger_coroner"
/obj/item/storage/backpack/messenger/gen
name = "geneticist messenger bag"
desc = "A sterile messenger bag with geneticist colours, making a remarkably cute accessory for hulks."
icon_state = "messenger_genetics"
inhand_icon_state = "messenger_genetics"
/obj/item/storage/backpack/messenger/science
name = "scientist messenger bag"
desc = "Useful for holding research materials, and for speeding your way to different scan objectives."
icon_state = "messenger_science"
inhand_icon_state = "messenger_science"
/obj/item/storage/backpack/messenger/hyd
name = "botanist messenger bag"
desc = "A messenger bag made of all natural fibers, great for getting to the sesh in time."
icon_state = "messenger_hydroponics"
inhand_icon_state = "messenger_hydroponics"
/obj/item/storage/backpack/messenger/sec
name = "security messenger bag"
desc = "A robust messenger bag for security related needs."
icon_state = "messenger_security"
inhand_icon_state = "messenger_security"
/obj/item/storage/backpack/messenger/explorer
name = "explorer messenger bag"
desc = "A robust messenger bag for stashing your loot, as well as making a remarkably cute accessory for your drakebone armor."
icon_state = "messenger_explorer"
inhand_icon_state = "messenger_explorer"
/obj/item/storage/backpack/messenger/cap
name = "captain's messenger bag"
desc = "An exclusive messenger bag for Nanotrasen officers, made of real whale leather."
icon_state = "messenger_captain"
inhand_icon_state = "messenger_captain"
/obj/item/storage/backpack/messenger/clown
name = "Giggles von Honkerton Jr."
desc = "The latest in storage 'technology' from Honk Co. Hey, how does this fit so much with such a small profile anyway? The wearer will definitely never tell you."
icon_state = "messenger_clown"
inhand_icon_state = "messenger_clown"