Files
GhomandGitHub 52e7062fa7 You can now kiss that pizza toilet with the chef kiss skillchip to add "love" to its reagents. (#96547)
## About The Pull Request
De-hardcodes food/crafting complexity (the stuff responsible for food
buffs) from food items and gives the var to the edible component, so
that objects crafted with pizza or meat sheets can have it as well.
Renamed TRAIT_FOOD_CHEF_MADE to TRAIT_HANDMADE now that it's also given
to the item when crafted through either the stack recipe UI or crafting
UI.

## Why It's Good For The Game
See title. In all seriousness though, it's more flexible code.

## Changelog

🆑
refactor: Refactored a couple things around food/recipe complexity (what
food buffs depend on). Technically, you can now kiss that pizza toilet,
which you crafted (right?), with the chef kiss skillchip enabled to add
"love" to its reagents.
/🆑
2026-06-19 12:15:00 -06:00

179 lines
6.8 KiB
Plaintext

///It's gross, gets the name of its owner, and is all kinds of fucked up
/datum/material/meat
name = "meat"
desc = "Meat"
id = /datum/material/meat // So the bespoke versions are categorized under this
color = rgb(214, 67, 67)
mat_flags = MATERIAL_BASIC_RECIPES | MATERIAL_CLASS_ORGANIC
mat_properties = list(
MATERIAL_DENSITY = 5,
MATERIAL_HARDNESS = 0,
MATERIAL_FLEXIBILITY = 5,
MATERIAL_REFLECTIVITY = 4,
MATERIAL_ELECTRICAL = 8,
MATERIAL_THERMAL = 4,
MATERIAL_CHEMICAL = 2,
MATERIAL_BEAUTY = -0.3, // EWW
)
sheet_type = /obj/item/stack/sheet/meat
item_sound_override = 'sound/effects/meatslap.ogg'
turf_sound_override = FOOTSTEP_MEAT
texture_layer_icon_state = "meat"
var/list/blood_dna
/datum/material/meat/on_main_applied(atom/source, mat_amount, multiplier)
. = ..()
make_edible(source, mat_amount, multiplier)
ADD_TRAIT(source, TRAIT_ROD_REMOVE_FISHING_DUD, REF(src)) //The rod itself is the bait... sorta.
if(isbodypart(source))
var/obj/item/bodypart/bodypart = source
if(!(bodypart::bodytype & BODYTYPE_ORGANIC))
bodypart.bodytype |= BODYTYPE_ORGANIC
if(isorgan(source))
var/obj/item/organ/organ = source
if(!(organ::organ_flags & ORGAN_ORGANIC))
organ.organ_flags |= ORGAN_ORGANIC
/datum/material/meat/on_applied(atom/source, mat_amount, multiplier, from_slot)
. = ..()
if(IS_EDIBLE(source))
make_edible(source, mat_amount, multiplier)
/datum/material/meat/on_edible_applied(atom/source, datum/component/edible/edible)
source.reagents.convert_reagent(/datum/reagent/consumable/nutriment, /datum/reagent/consumable/nutriment/protein, keep_data = TRUE)
var/datum/reagent/meaty_chem = source.reagents.has_reagent(/datum/reagent/consumable/nutriment/protein)
if(meaty_chem)
LAZYSET(meaty_chem.data, "meat", length(meaty_chem.data) || 1) //adds meatiness to its tastes
source.reagents.convert_reagent(/datum/reagent/consumable/nutriment/fat/oil, /datum/reagent/consumable/nutriment/fat, include_source_subtypes = TRUE, keep_data = TRUE)
meaty_chem = source.reagents.has_reagent(/datum/reagent/consumable/nutriment/fat)
if(meaty_chem)
LAZYSET(meaty_chem.data, "meat", length(meaty_chem.data) || 1) //adds meatiness to its tastes
source.AddComponentFrom(SOURCE_EDIBLE_MEAT_MAT, /datum/component/edible, foodtypes = MEAT)
/datum/material/meat/on_edible_removed(atom/source, datum/component/edible/edible)
source.reagents.convert_reagent(/datum/reagent/consumable/nutriment/protein, /datum/reagent/consumable/nutriment, keep_data = TRUE)
var/datum/reagent/unmeaty_chem = source.reagents.has_reagent(/datum/reagent/consumable/nutriment)
if(unmeaty_chem)
LAZYREMOVE(unmeaty_chem.data, "meat")
source.reagents.convert_reagent(/datum/reagent/consumable/nutriment/fat, /datum/reagent/consumable/nutriment/fat/oil, keep_data = TRUE)
unmeaty_chem = source.reagents.has_reagent(/datum/reagent/consumable/nutriment/fat/oil)
if(unmeaty_chem)
LAZYREMOVE(unmeaty_chem.data, "meat")
//the edible source is removed by on_removed()
/datum/material/meat/proc/make_edible(atom/source, mat_amount, multiplier)
if(source.material_flags & MATERIAL_NO_EDIBILITY)
return
var/protein_count = 3 * (mat_amount / SHEET_MATERIAL_AMOUNT) * multiplier
var/fat_count = 2 * (mat_amount / SHEET_MATERIAL_AMOUNT) * multiplier
source.AddComponentFrom( \
SOURCE_EDIBLE_MEAT_MAT, \
/datum/component/edible, \
initial_reagents = list(/datum/reagent/consumable/nutriment/protein = protein_count, /datum/reagent/consumable/nutriment/fat = fat_count), \
foodtypes = RAW | MEAT, \
eat_time = 3 SECONDS, \
tastes = list("meat" = 1),\
handmade_complexity = /obj/item/food/meat/steak::crafting_complexity)
source.AddComponent(
/datum/component/bloody_spreader,\
blood_left = (protein_count + fat_count) * 0.3 * multiplier,\
blood_dna = blood_dna,\
)
// Turfs can't handle the meaty goodness of blood walk.
if(!ismovable(source))
return
source.AddComponent(
/datum/component/blood_walk,\
blood_type = /obj/effect/decal/cleanable/blood,\
blood_spawn_chance = 35,\
max_blood = (protein_count + fat_count) * 0.3 * multiplier,\
blood_dna_info = blood_dna,\
)
/datum/material/meat/on_removed(atom/source, mat_amount, multiplier, from_slot)
. = ..()
source.RemoveComponentSource(SOURCE_EDIBLE_MEAT_MAT, /datum/component/edible)
qdel(source.GetComponent(/datum/component/blood_walk))
qdel(source.GetComponent(/datum/component/bloody_spreader))
source.RemoveComponentSource(SOURCE_EDIBLE_MEAT_MAT, /datum/component/edible)
/datum/material/meat/on_main_removed(atom/source, mat_amount, multiplier)
. = ..()
REMOVE_TRAIT(source, TRAIT_ROD_REMOVE_FISHING_DUD, REF(src))
if(isbodypart(source))
var/obj/item/bodypart/bodypart = source
if(!(bodypart::bodytype & BODYTYPE_ORGANIC))
bodypart.bodytype &= ~BODYTYPE_ORGANIC
if(isorgan(source))
var/obj/item/organ/organ = source
if(!(organ::organ_flags & ORGAN_ORGANIC))
organ.organ_flags &= ~ORGAN_ORGANIC
/datum/material/meat/mob_meat
init_flags = MATERIAL_INIT_BESPOKE
var/subjectname = ""
var/subjectjob = null
/datum/material/meat/mob_meat/Initialize(_id, mob/living/source)
if(!istype(source))
return FALSE
name = "[source?.name ? "[source.name]'s" : "mystery"] [initial(name)]"
if(source.real_name)
subjectname = source.real_name
else if(source.name)
subjectname = source.name
var/datum/blood_type/blood_type = source.get_bloodtype()
if (blood_type && blood_type.get_color() != BLOOD_COLOR_RED)
var/list/transition_filter = color_transition_filter(blood_type.get_color())
color = transition_filter["color"]
blood_dna = source.get_blood_dna_list()
if(ishuman(source))
var/mob/living/carbon/human/human_source = source
subjectjob = human_source.job
return ..()
/datum/material/meat/species_meat
init_flags = MATERIAL_INIT_BESPOKE
/datum/material/meat/species_meat/Initialize(_id, datum/species/source)
if(!istype(source))
return FALSE
name = "[source?.name || "mystery"] [initial(name)]"
if(source.exotic_bloodtype)
var/datum/blood_type/blood_type = get_blood_type(source.exotic_bloodtype)
if (blood_type && blood_type.get_color() != BLOOD_COLOR_RED)
var/list/transition_filter = color_transition_filter(blood_type.get_color())
color = transition_filter["color"]
blood_dna = list("[blood_type.dna_string]" = blood_type)
return ..()
/datum/material/meat/blood_meat
init_flags = MATERIAL_INIT_BESPOKE
/datum/material/meat/blood_meat/Initialize(_id, datum/reagent/source)
if(!istype(source))
return FALSE
var/list/blood_data = source.data
name = "[blood_data["real_name"] || "mystery"] [initial(name)]"
var/datum/blood_type/blood_type = blood_data["blood_type"]
if(blood_type && blood_type.get_color() != BLOOD_COLOR_RED)
var/list/transition_filter = color_transition_filter(blood_type.get_color())
color = transition_filter["color"]
blood_dna = list("[blood_type.dna_string]" = blood_type)
else
color = source.color
return ..()