The edible component now uses DUPE_SOURCE mode (#89687)

## About The Pull Request
The edible component now uses DUPE_SOURCE mode, which is needed to avoid
conflicts between sources. This includes some other tidbits from my
refactor like renaming dcs/flags.dm to ds/declarations.dm (in virtue of
the fact it doesn't only contain flags anymore even before this PR),
meat materials giving protein and fat reagents to affected atoms instead
of generic nutriment and oil, and the pizza material no longer
containing meat, because margherita pizza, which the material is
extracted from, doesn't contain meat either. The pepperonis were
magically conjured space bs.

## Why It's Good For The Game
There are multiple sources of the edible component and we don't want
issues with that. Also atomizing stuff from my refactor.

## Changelog

🆑
balance: objects made out of meat are no longer classified as gross food
on top of being raw and meaty, and actually contain protein and fat
instead of standard nutriment and oil.
balance: the pizza material stacks, crafted with margherita pizza and
rollig pin mind you, no longer magically contain pepperoni.
/🆑
This commit is contained in:
Ghom
2025-03-02 13:15:08 +01:00
committed by GitHub
parent fc25b55500
commit da31ea158c
32 changed files with 174 additions and 119 deletions
@@ -78,3 +78,12 @@
#define CUSTOM_INGREDIENT_ICON_STACK 3
#define CUSTOM_INGREDIENT_ICON_LINE 4
#define CUSTOM_INGREDIENT_ICON_STACKPLUSTOP 5
//declarations for various sources of the edible component.
//The standard source of the edible component which is not expected to e removable
#define SOURCE_EDIBLE_INNATE "innate"
#define SOURCE_EDIBLE_FRIED "fried"
#define SOURCE_EDIBLE_GRILLED "grilled"
#define SOURCE_EDIBLE_MEAT_MAT "meat"
#define SOURCE_EDIBLE_PIZZA_MAT "pizza"
+5 -1
View File
@@ -356,7 +356,7 @@
old_component.InheritComponent(new_component, TRUE)
if(COMPONENT_DUPE_SOURCES)
if(source in old_component.sources)
if((source in old_component.sources) && !old_component.allow_source_update(source))
return old_component // source already registered, no work to do
if(old_component.on_source_add(arglist(list(source) + raw_args.Copy(2))) == COMPONENT_INCOMPATIBLE)
@@ -480,3 +480,7 @@
*/
/datum/component/ui_host()
return parent
///Whether the component is allowed to call on_source_add() on a source that's already present
/datum/component/proc/allow_source_update(source)
return FALSE
+79 -63
View File
@@ -10,10 +10,12 @@ Behavior that's still missing from this component that original food items had t
Misc:
Something for cakes (You can store things inside)
*/
#define DEFAULT_EDIBLE_VOLUME 50
/datum/component/edible
dupe_mode = COMPONENT_DUPE_UNIQUE_PASSARGS
dupe_mode = COMPONENT_DUPE_SOURCES
///Amount of reagents taken per bite
var/bite_consumption = 2
///Amount of bites taken so far
@@ -23,7 +25,7 @@ Behavior that's still missing from this component that original food items had t
///Bitfield of the types of this food
var/foodtypes = NONE
///Amount of seconds it takes to eat this food
var/eat_time = 30
var/eat_time = 3 SECONDS
///Defines how much it lowers someones satiety (Need to eat, essentialy)
var/junkiness = 0
///Message to send when eating
@@ -36,16 +38,18 @@ Behavior that's still missing from this component that original food items had t
var/datum/callback/check_liked
///Last time we checked for food likes
var/last_check_time
///The initial volume of the foods reagents
var/volume = 50
///The flavortext for taste (haha get it flavor text)
var/list/tastes
///Assoc list of sources and their foodtypes
var/list/foodtypes_by_source = list()
///Assoc list of sources and their food flags
var/list/food_flags_by_source = list()
///Assoc list of sources and their junkiness
var/list/junkiness_by_source = list()
/datum/component/edible/Initialize(
list/initial_reagents,
food_flags = NONE,
foodtypes = NONE,
volume = 50,
volume = DEFAULT_EDIBLE_VOLUME,
eat_time = 1 SECONDS,
list/tastes,
list/eatverbs = list("bite", "chew", "nibble", "gnaw", "gobble", "chomp"),
@@ -59,19 +63,15 @@ Behavior that's still missing from this component that original food items had t
if(!isatom(parent))
return COMPONENT_INCOMPATIBLE
// If these args are not explicitly stated when initializing the component
// Use the defaults provided in this proc definition, so we don't have to worry
// about these being null. We cannot rely on on_add_source() for this lest these
// end up being unwantedly overriden by other sources.
src.bite_consumption = bite_consumption
src.food_flags = food_flags
src.foodtypes = foodtypes
src.volume = volume
src.eat_time = eat_time
src.eatverbs = string_list(eatverbs)
src.junkiness = junkiness
src.after_eat = after_eat
src.on_consume = on_consume
src.tastes = string_assoc_list(tastes)
src.check_liked = check_liked
setup_initial_reagents(initial_reagents, reagent_purity)
/datum/component/edible/RegisterWithParent()
RegisterSignal(parent, COMSIG_ATOM_EXAMINE, PROC_REF(examine))
@@ -79,7 +79,7 @@ Behavior that's still missing from this component that original food items had t
RegisterSignal(parent, COMSIG_ATOM_CHECKPARTS, PROC_REF(OnCraft))
RegisterSignal(parent, COMSIG_OOZE_EAT_ATOM, PROC_REF(on_ooze_eat))
RegisterSignal(parent, COMSIG_FOOD_INGREDIENT_ADDED, PROC_REF(edible_ingredient_added))
RegisterSignal(parent, COMSIG_ATOM_CREATEDBY_PROCESSING, PROC_REF(OnProcessed))
RegisterSignal(parent, COMSIG_ATOM_CREATEDBY_PROCESSING, PROC_REF(created_by_processing))
if(isturf(parent))
RegisterSignal(parent, COMSIG_ATOM_ENTERED, PROC_REF(on_entered))
@@ -120,12 +120,14 @@ Behavior that's still missing from this component that original food items had t
if(foodtypes & GORE)
REMOVE_TRAIT(parent, TRAIT_VALID_DNA_INFUSION, REF(src))
/datum/component/edible/InheritComponent(
datum/component/edible/old_comp,
i_am_original,
/datum/component/edible/allow_source_update(source)
return source == SOURCE_EDIBLE_INNATE
/datum/component/edible/on_source_add(
source,
list/initial_reagents,
food_flags = NONE,
foodtypes = NONE,
food_flags,
foodtypes,
volume,
eat_time,
list/tastes,
@@ -135,26 +137,39 @@ Behavior that's still missing from this component that original food items had t
datum/callback/after_eat,
datum/callback/on_consume,
datum/callback/check_liked,
reagent_purity = 0.5,
)
. = ..()
// If we got passed an old comp, take only the values that will not override our current ones
if(old_comp)
food_flags = old_comp.food_flags
foodtypes = old_comp.foodtypes
tastes = old_comp.tastes
eatverbs = old_comp.eatverbs
var/recalculate = FALSE
if(!isnull(foodtypes))
if(foodtypes_by_source[source]) //foodtypes being overriden
recalculate = TRUE
foodtypes_by_source[source] = foodtypes
if(!isnull(food_flags))
if(food_flags_by_source[source]) //food_flags being overriden
recalculate = TRUE
food_flags_by_source[source] = food_flags
if(!isnull(junkiness))
src.junkiness += junkiness - junkiness_by_source[source]
junkiness_by_source[source] = junkiness
if(foodtypes & GORE)
ADD_TRAIT(parent, TRAIT_VALID_DNA_INFUSION, REF(src))
if(recalculate)
recalculate_food_flags()
else
// nothing is being removed
src.food_flags |= food_flags
src.foodtypes |= foodtypes
if(foodtypes & GORE)
ADD_TRAIT(parent, TRAIT_VALID_DNA_INFUSION, REF(src))
// only edit if we're OG
if(!i_am_original)
// add newly passed in reagents
setup_initial_reagents(initial_reagents, reagent_purity, tastes, volume)
//Only the innate source is allowed to change the following vars if there are a plurality of sources.
if(source != SOURCE_EDIBLE_INNATE && length(sources) > 1)
return
// add food flags and types
src.food_flags |= food_flags
src.foodtypes |= foodtypes
// add all new eatverbs to the list
if(islist(eatverbs))
var/list/cached_verbs = src.eatverbs
@@ -163,29 +178,11 @@ Behavior that's still missing from this component that original food items had t
src.eatverbs = string_list(cached_verbs | eatverbs)
else
src.eatverbs = string_list(eatverbs)
// add all new tastes to the tastes
if(islist(tastes))
var/list/cached_tastes = src.tastes
if(islist(cached_tastes))
// tastes becomes a combination of existing tastes and new ones
var/list/mixed_tastes = cached_tastes.Copy()
for(var/new_taste in tastes)
mixed_tastes[new_taste] += tastes[new_taste]
src.tastes = string_assoc_list(mixed_tastes)
else
src.tastes = string_assoc_list(tastes)
// just set these directly
if(!isnull(bite_consumption))
src.bite_consumption = bite_consumption
if(!isnull(volume))
src.volume = volume
if(!isnull(eat_time))
src.eat_time = eat_time
if(!isnull(junkiness))
src.junkiness = junkiness
if(!isnull(after_eat))
src.after_eat = after_eat
if(!isnull(on_consume))
@@ -193,8 +190,25 @@ Behavior that's still missing from this component that original food items had t
if(!isnull(check_liked))
src.check_liked = check_liked
// add newly passed in reagents
setup_initial_reagents(initial_reagents)
/datum/component/edible/on_source_remove(source)
//rebuild the foodtypes and food_flags bitfields without the removed source
foodtypes_by_source -= source
food_flags_by_source -= source
junkiness -= junkiness_by_source[source]
junkiness_by_source -= source
recalculate_food_flags()
return ..()
/datum/component/edible/proc/recalculate_food_flags()
foodtypes = NONE
food_flags = NONE
for(var/source_key in foodtypes_by_source)
foodtypes |= foodtypes_by_source[source_key]
food_flags |= food_flags_by_source[source_key]
if(foodtypes & GORE)
ADD_TRAIT(parent, TRAIT_VALID_DNA_INFUSION, REF(src))
else
REMOVE_TRAIT(parent, TRAIT_VALID_DNA_INFUSION, REF(src))
/datum/component/edible/Destroy(force)
after_eat = null
@@ -203,12 +217,12 @@ Behavior that's still missing from this component that original food items had t
return ..()
/// Sets up the initial reagents of the food.
/datum/component/edible/proc/setup_initial_reagents(list/reagents, reagent_purity)
/datum/component/edible/proc/setup_initial_reagents(list/reagents, reagent_purity, list/tastes, volume)
var/atom/owner = parent
if(owner.reagents)
if(!owner.reagents)
owner.create_reagents(volume || DEFAULT_EDIBLE_VOLUME, INJECTABLE)
else if(volume > owner.reagents.maximum_volume)
owner.reagents.maximum_volume = volume
else
owner.create_reagents(volume, INJECTABLE)
for(var/rid in reagents)
var/amount = reagents[rid]
@@ -299,7 +313,7 @@ Behavior that's still missing from this component that original food items had t
return TryToEat(user, user)
///Called when food is created through processing (Usually this means it was sliced). We use this to pass the OG items reagents.
/datum/component/edible/proc/OnProcessed(datum/source, atom/original_atom, list/chosen_processing_option)
/datum/component/edible/proc/created_by_processing(datum/source, atom/original_atom, list/chosen_processing_option)
SIGNAL_HANDLER
if(!original_atom.reagents)
@@ -308,9 +322,9 @@ Behavior that's still missing from this component that original food items had t
var/atom/this_food = parent
//Make sure we have a reagent container large enough to fit the original atom's reagents.
volume = max(volume, ROUND_UP(original_atom.reagents.maximum_volume / chosen_processing_option[TOOL_PROCESSING_AMOUNT]))
var/volume = ROUND_UP(original_atom.reagents.maximum_volume / chosen_processing_option[TOOL_PROCESSING_AMOUNT])
this_food.create_reagents(volume)
this_food.create_reagents(volume, this_food.reagents?.flags)
original_atom.reagents.copy_to(this_food, original_atom.reagents.total_volume / chosen_processing_option[TOOL_PROCESSING_AMOUNT], 1)
if(original_atom.name != initial(original_atom.name))
@@ -726,3 +740,5 @@ Behavior that's still missing from this component that original food items had t
playsound(get_turf(eater),'sound/items/eatfood.ogg', rand(30,50), TRUE)
qdel(food)
return COMPONENT_ATOM_EATEN
#undef DEFAULT_EDIBLE_VOLUME
+1 -1
View File
@@ -108,7 +108,7 @@
/obj/item/food/golem_food/make_edible()
. = ..()
AddComponent(/datum/component/edible, after_eat = CALLBACK(src, PROC_REF(took_bite)), volume = INFINITY)
AddComponentFrom(SOURCE_EDIBLE_INNATE, /datum/component/edible, after_eat = CALLBACK(src, PROC_REF(took_bite)), volume = INFINITY)
/// Called when someone bites this food, subtract one charge from our material stack
/obj/item/food/golem_food/proc/took_bite(mob/eater)
+3 -3
View File
@@ -43,13 +43,13 @@
ADD_TRAIT(this_food, TRAIT_FOOD_FRIED, ELEMENT_TRAIT(type))
// Already edible items will inherent these parameters
// Otherwise, we will become edible.
this_food.AddComponent( \
this_food.AddComponentFrom( \
SOURCE_EDIBLE_FRIED, \
/datum/component/edible, \
bite_consumption = 2, \
food_flags = FOOD_FINGER_FOOD, \
junkiness = 10, \
foodtypes = FRIED, \
volume = this_food.reagents?.maximum_volume, \
)
SEND_SIGNAL(this_food, COMSIG_ITEM_FRIED, fry_time)
@@ -59,5 +59,5 @@
source.name = initial(source.name)
source.desc = initial(source.desc)
REMOVE_TRAIT(source, TRAIT_FOOD_FRIED, ELEMENT_TRAIT(type))
qdel(source.GetComponent(/datum/component/edible)) // Don't care if it was initially edible
source.RemoveComponentSource(SOURCE_EDIBLE_FRIED, /datum/component/edible)
return ..()
+2 -2
View File
@@ -26,7 +26,7 @@
this_food.desc = "A [this_food.name]. Reminds you of your wife, wait, no, it's prettier!"
if(grill_time > 30 SECONDS && isnull(this_food.GetComponent(/datum/component/edible)))
this_food.AddComponent(/datum/component/edible, foodtypes = FRIED)
this_food.AddComponentFrom(SOURCE_EDIBLE_GRILLED, /datum/component/edible, foodtypes = FRIED)
SEND_SIGNAL(this_food, COMSIG_ITEM_BARBEQUE_GRILLED, grill_time)
ADD_TRAIT(this_food, TRAIT_FOOD_BBQ_GRILLED, ELEMENT_TRAIT(type))
@@ -34,6 +34,6 @@
/datum/element/grilled_item/Detach(atom/source, ...)
source.name = initial(source.name)
source.desc = initial(source.desc)
qdel(source.GetComponent(/datum/component/edible)) // Don't care if it was initially edible
source.RemoveComponentSource(SOURCE_EDIBLE_GRILLED, /datum/component/edible)
REMOVE_TRAIT(src, TRAIT_FOOD_BBQ_GRILLED, ELEMENT_TRAIT(type))
return ..()
+12 -9
View File
@@ -38,17 +38,20 @@
make_edible(source, mat_amount, multiplier)
/datum/material/meat/proc/make_edible(atom/source, mat_amount, multiplier)
var/nutriment_count = 3 * (mat_amount / SHEET_MATERIAL_AMOUNT)
var/oil_count = 2 * (mat_amount / SHEET_MATERIAL_AMOUNT)
source.AddComponent(/datum/component/edible, \
initial_reagents = list(/datum/reagent/consumable/nutriment = nutriment_count, /datum/reagent/consumable/nutriment/fat/oil = oil_count), \
foodtypes = RAW | MEAT | GROSS, \
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("Meaty"))
tastes = list("meat"))
source.AddComponent(
/datum/component/bloody_spreader,\
blood_left = (nutriment_count + oil_count) * 0.3 * multiplier,\
blood_left = (protein_count + fat_count) * 0.3,\
blood_dna = list("meaty DNA" = "MT-"),\
diseases = null,\
)
@@ -61,17 +64,17 @@
/datum/component/blood_walk,\
blood_type = /obj/effect/decal/cleanable/blood,\
blood_spawn_chance = 35,\
max_blood = (nutriment_count + oil_count) * 0.3 * multiplier,\
max_blood = (protein_count + fat_count) * 0.3,\
)
/datum/material/meat/on_removed(atom/source, mat_amount, multiplier)
. = ..()
source.RemoveComponentSource(SOURCE_EDIBLE_MEAT_MAT, /datum/component/edible)
qdel(source.GetComponent(/datum/component/blood_walk))
qdel(source.GetComponent(/datum/component/bloody_spreader))
/datum/material/meat/on_main_removed(atom/source, mat_amount, multiplier)
. = ..()
qdel(source.GetComponent(/datum/component/edible))
REMOVE_TRAIT(source, TRAIT_ROD_REMOVE_FISHING_DUD, REF(src))
/datum/material/meat/mob_meat
+14 -9
View File
@@ -28,24 +28,29 @@
/datum/material/pizza/on_main_applied(atom/source, mat_amount, multiplier)
. = ..()
if(!IS_EDIBLE(source))
make_edible(source, mat_amount)
make_edible(source, mat_amount, multiplier)
ADD_TRAIT(source, TRAIT_ROD_REMOVE_FISHING_DUD, REF(src)) //the fishing rod itself is the bait... sorta.
/datum/material/pizza/on_applied(atom/source, mat_amount, multiplier)
. = ..()
if(IS_EDIBLE(source))
make_edible(source, mat_amount)
make_edible(source, mat_amount, multiplier)
/datum/material/pizza/proc/make_edible(atom/source, mat_amount)
var/nutriment_count = 3 * (mat_amount / SHEET_MATERIAL_AMOUNT)
var/oil_count = 2 * (mat_amount / SHEET_MATERIAL_AMOUNT)
source.AddComponent(/datum/component/edible, \
/datum/material/pizza/proc/make_edible(atom/source, mat_amount, multiplier)
var/nutriment_count = 3 * (mat_amount / SHEET_MATERIAL_AMOUNT) * multiplier
var/oil_count = 2 * (mat_amount / SHEET_MATERIAL_AMOUNT) * multiplier
source.AddComponentFrom(
SOURCE_EDIBLE_PIZZA_MAT, \
/datum/component/edible, \
initial_reagents = list(/datum/reagent/consumable/nutriment = nutriment_count, /datum/reagent/consumable/nutriment/fat/oil = oil_count), \
foodtypes = GRAIN | MEAT | DAIRY | VEGETABLES, \
foodtypes = GRAIN | DAIRY | VEGETABLES, \
eat_time = 3 SECONDS, \
tastes = list("crust", "tomato", "cheese", "meat"))
tastes = list("crust", "tomato", "cheese"))
/datum/material/pizza/on_removed(atom/source, mat_amount, multiplier)
. = ..()
source.RemoveComponentSource(SOURCE_EDIBLE_PIZZA_MAT, /datum/component/edible)
/datum/material/pizza/on_main_removed(atom/source, mat_amount, multiplier)
. = ..()
qdel(source.GetComponent(/datum/component/edible))
REMOVE_TRAIT(source, TRAIT_ROD_REMOVE_FISHING_DUD, REF(src))
+3 -1
View File
@@ -238,7 +238,9 @@ CIGARETTE PACKETS ARE IN FANCY.DM
inhand_icon_state = inhand_icon_off
// "It is called a cigarette"
AddComponent(/datum/component/edible,\
AddComponentFrom(
SOURCE_EDIBLE_INNATE,\
/datum/component/edible,\
initial_reagents = list_reagents,\
food_flags = FOOD_NO_EXAMINE,\
foodtypes = JUNKFOOD,\
+6 -1
View File
@@ -218,7 +218,12 @@
refill()
if(edible)
AddComponent(/datum/component/edible, bite_consumption = reagents.total_volume / (charges_left / 5), after_eat = CALLBACK(src, PROC_REF(after_eat)))
AddComponentFrom(
SOURCE_EDIBLE_INNATE, \
/datum/component/edible, \
bite_consumption = reagents.total_volume / (charges_left / 5), \
after_eat = CALLBACK(src, PROC_REF(after_eat)), \
)
/// Used for edible component to reduce charges_left on bite.
/obj/item/toy/crayon/proc/after_eat(mob/user)
@@ -801,7 +801,9 @@
reagents.add_reagent(fuel_type, max_fuel)
. = ..()
set_light_color(color)
AddComponent(/datum/component/edible,\
AddComponentFrom(
SOURCE_EDIBLE_INNATE,\
/datum/component/edible,\
food_flags = FOOD_NO_EXAMINE,\
volume = reagents.total_volume,\
bite_consumption = round(reagents.total_volume / (rand(20, 30) * 0.1)),\
+3 -1
View File
@@ -72,7 +72,9 @@
///This proc adds the edible component, overwrite this if you for some reason want to change some specific args like callbacks.
/obj/item/food/proc/make_edible()
AddComponent(/datum/component/edible,\
AddComponentFrom(
SOURCE_EDIBLE_INNATE,\
/datum/component/edible,\
initial_reagents = food_reagents,\
food_flags = food_flags,\
foodtypes = foodtypes,\
+1 -1
View File
@@ -27,7 +27,7 @@
///Override for checkliked callback
/obj/item/food/donut/make_edible()
. = ..()
AddComponent(/datum/component/edible, check_liked = CALLBACK(src, PROC_REF(check_liked)))
AddComponentFrom(SOURCE_EDIBLE_INNATE, /datum/component/edible, check_liked = CALLBACK(src, PROC_REF(check_liked)))
/obj/item/food/donut/proc/decorate_donut()
if(is_decorated || !decorated_icon)
+1 -1
View File
@@ -349,7 +349,7 @@
/obj/item/food/popsicle/make_edible()
. = ..()
AddComponent(/datum/component/edible, after_eat = CALLBACK(src, PROC_REF(after_bite)))
AddComponentFrom(SOURCE_EDIBLE_INNATE, /datum/component/edible, after_eat = CALLBACK(src, PROC_REF(after_bite)))
/obj/item/food/popsicle/update_overlays()
. = ..()
+1 -1
View File
@@ -616,7 +616,7 @@
/obj/item/food/pickle/make_edible()
. = ..()
AddComponent(/datum/component/edible, check_liked = CALLBACK(src, PROC_REF(check_liked)))
AddComponentFrom(SOURCE_EDIBLE_INNATE, /datum/component/edible, check_liked = CALLBACK(src, PROC_REF(check_liked)))
/obj/item/food/pickle/proc/check_liked(mob/living/carbon/human/consumer)
var/obj/item/organ/liver/liver = consumer.get_organ_slot(ORGAN_SLOT_LIVER)
+1 -1
View File
@@ -372,7 +372,7 @@
///Override for checkliked callback
/obj/item/food/rationpack/make_edible()
. = ..()
AddComponent(/datum/component/edible, check_liked = CALLBACK(src, PROC_REF(check_liked)))
AddComponentFrom(SOURCE_EDIBLE_INNATE, /datum/component/edible, check_liked = CALLBACK(src, PROC_REF(check_liked)))
/obj/item/food/rationpack/proc/check_liked(mob/mob) //Nobody likes rationpacks. Nobody.
return FOOD_DISLIKED
@@ -277,7 +277,7 @@
// Override for after_eat and check_liked callbacks.
/obj/item/food/sandwich/death/make_edible()
. = ..()
AddComponent(/datum/component/edible, after_eat = CALLBACK(src, PROC_REF(after_eat)), check_liked = CALLBACK(src, PROC_REF(check_liked)))
AddComponentFrom(SOURCE_EDIBLE_INNATE, /datum/component/edible, after_eat = CALLBACK(src, PROC_REF(after_eat)), check_liked = CALLBACK(src, PROC_REF(check_liked)))
/**
* Callback to be used with the edible component.
+1 -1
View File
@@ -39,7 +39,7 @@
/obj/item/food/candy/bronx/make_edible()
. = ..()
AddComponent(/datum/component/edible, on_consume = CALLBACK(src, PROC_REF(on_consume)))
AddComponentFrom(SOURCE_EDIBLE_INNATE, /datum/component/edible, on_consume = CALLBACK(src, PROC_REF(on_consume)))
/obj/item/food/candy/bronx/proc/on_consume(mob/living/eater)
if(ishuman(eater))
+1 -1
View File
@@ -242,7 +242,7 @@
/obj/item/food/bubblegum/bubblegum/make_edible()
. = ..()
AddComponent(/datum/component/edible, on_consume = CALLBACK(src, PROC_REF(OnConsume)))
AddComponentFrom(SOURCE_EDIBLE_INNATE, /datum/component/edible, on_consume = CALLBACK(src, PROC_REF(OnConsume)))
/obj/item/food/bubblegum/bubblegum/proc/OnConsume(mob/living/eater, mob/living/feeder)
if(iscarbon(eater))
@@ -929,9 +929,9 @@ new /datum/stack_recipe("paper frame door", /obj/structure/mineral_door/paperfra
amount = 5
/obj/item/stack/sheet/pizza
name = "pepperoni sheetzzas"
desc = "It's a delicious pepperoni sheetzza!"
singular_name = "pepperoni sheetzza"
name = "sheet pizza"
desc = "It's a deliciously rectangular sheet of pizza!"
singular_name = "sheet pizza"
icon_state = "sheet-pizza"
mats_per_unit = list(/datum/material/pizza = SHEET_MATERIAL_AMOUNT)
merge_type = /obj/item/stack/sheet/pizza
+2 -1
View File
@@ -271,7 +271,8 @@
/obj/item/storage/backpack/meat/Initialize(mapload)
. = ..()
AddComponent(
AddComponentFrom(
SOURCE_EDIBLE_INNATE, \
/datum/component/edible,\
initial_reagents = meat_reagents,\
foodtypes = foodtypes,\
+1 -1
View File
@@ -119,7 +119,7 @@
/datum/export/stack/pizza
cost = CARGO_CRATE_VALUE * 0.06
unit_name = "of sheetza"
unit_name = "of sheet pizza"
export_types = list(/obj/item/stack/sheet/pizza)
/datum/export/stack/meat
+1 -1
View File
@@ -28,7 +28,7 @@
for(var/obj/item/food/food_item in crate)
// makes all of our items GROSS
food_item.name = "spoiled [food_item.name]"
food_item.AddComponent(/datum/component/edible, foodtypes = GROSS)
food_item.AddComponentFrom(SOURCE_EDIBLE_INNATE, /datum/component/edible, foodtypes = GROSS)
/datum/supply_pack/exploration/shrubbery
name = "Shrubbery Crate"
+1 -1
View File
@@ -94,7 +94,7 @@
/obj/item/food/clothing/make_edible()
. = ..()
AddComponent(/datum/component/edible, after_eat = CALLBACK(src, PROC_REF(after_eat)))
AddComponentFrom(SOURCE_EDIBLE_INNATE, /datum/component/edible, after_eat = CALLBACK(src, PROC_REF(after_eat)))
/obj/item/food/clothing/proc/after_eat(mob/eater)
var/obj/item/clothing/resolved_clothing = clothing.resolve()
+6 -4
View File
@@ -299,7 +299,9 @@
create_reagents(INFINITY) //We'll set this to the total volume of the reagents right after generate_fish_reagents() is over
generate_fish_reagents(bites_to_finish)
reagents.maximum_volume = round(reagents.total_volume * 1.25) //make some meager space for condiments.
AddComponent(/datum/component/edible, \
AddComponentFrom(
SOURCE_EDIBLE_INNATE, \
/datum/component/edible, \
food_flags = FOOD_NO_EXAMINE|FOOD_NO_BITECOUNT, \
foodtypes = foodtypes, \
volume = reagents.total_volume, \
@@ -340,8 +342,8 @@
if(protein)
reagents.multiply(2, /datum/reagent/consumable/nutriment/protein)
var/datum/component/edible/edible = GetComponent(/datum/component/edible)
edible.foodtypes &= ~(RAW|GORE)
//Remove the raw and gore foodtypes from the edible component
AddComponentFrom(SOURCE_EDIBLE_INNATE, /datum/component/edible, foodtypes = get_food_types() & ~(RAW|GORE))
if(cooking_time >= FISH_SAFE_COOKING_DURATION)
well_cooked()
@@ -435,7 +437,7 @@
var/bites_to_finish = weight / FISH_WEIGHT_BITE_DIVISOR
///updates how many units of reagent one bite takes if edible.
if(IS_EDIBLE(src))
AddComponent(/datum/component/edible, bite_consumption = reagents.maximum_volume / bites_to_finish)
AddComponentFrom(SOURCE_EDIBLE_INNATE, /datum/component/edible, bite_consumption = reagents.maximum_volume / bites_to_finish)
///Grinding a fish replaces some the protein it has with blood and gibs. You ain't getting a clean smoothie out of it.
/obj/item/fish/on_grind()
+1 -1
View File
@@ -30,7 +30,7 @@
/obj/item/food/grown/banana/make_edible()
. = ..()
AddComponent(/datum/component/edible, check_liked = CALLBACK(src, PROC_REF(check_liked)))
AddComponentFrom(SOURCE_EDIBLE_INNATE, /datum/component/edible, check_liked = CALLBACK(src, PROC_REF(check_liked)))
/obj/item/food/grown/banana/Initialize(mapload)
. = ..()
+1 -1
View File
@@ -107,7 +107,7 @@
/obj/item/food/grown/holymelon/make_edible()
. = ..()
AddComponent(/datum/component/edible, check_liked = CALLBACK(src, PROC_REF(check_holyness)))
AddComponentFrom(SOURCE_EDIBLE_INNATE, /datum/component/edible, check_liked = CALLBACK(src, PROC_REF(check_holyness)))
/obj/item/food/grown/holymelon/attackby(obj/item/I, mob/user, params)
@@ -79,7 +79,7 @@
var/list/reee = list(/datum/reagent/consumable/nutriment/vitamin = 5)
if(beegent)
reee[beegent.type] = 5
holder.AddComponent(/datum/component/edible, reee, null, BEE_FOODGROUPS, 10, 0, list("bee"), null, 10)
holder.AddComponentFrom(SOURCE_EDIBLE_INNATE, /datum/component/edible, reee, null, BEE_FOODGROUPS, 10, 0, list("bee"), null, 10)
picker.visible_message(span_warning("[picker] scoops up [src]!"))
picker.put_in_hands(holder)
@@ -313,7 +313,7 @@
/obj/item/trash/bee/Initialize(mapload, mob/living/basic/bee/dead_bee)
. = ..()
AddComponent(/datum/component/edible, list(/datum/reagent/consumable/nutriment/vitamin = 5), null, BEE_FOODGROUPS, 10, 0, list("bee"), null, 10)
AddComponentFrom(SOURCE_EDIBLE_INNATE, /datum/component/edible, list(/datum/reagent/consumable/nutriment/vitamin = 5), null, BEE_FOODGROUPS, 10, 0, list("bee"), null, 10)
AddElement(/datum/element/swabable, CELL_LINE_TABLE_QUEEN_BEE, CELL_VIRUS_TABLE_GENERIC_MOB, 1, 5)
RegisterSignal(src, COMSIG_ATOM_ON_LAZARUS_INJECTOR, PROC_REF(use_lazarus))
if(isnull(dead_bee))
+3 -1
View File
@@ -76,7 +76,9 @@ INITIALIZE_IMMEDIATE(/obj/item/organ)
/obj/item/organ/Initialize(mapload)
. = ..()
if(organ_flags & ORGAN_EDIBLE)
AddComponent(/datum/component/edible,\
AddComponentFrom(
SOURCE_EDIBLE_INNATE, \
/datum/component/edible,\
initial_reagents = food_reagents,\
foodtypes = foodtype_flags,\
volume = reagent_vol,\
+2 -2
View File
@@ -471,7 +471,6 @@
TEST_ASSERT(edible, "Fish is not edible")
edible.eat_time = 0
TEST_ASSERT(fish.GetComponent(/datum/component/infective), "Fish doesn't have the infective component")
var/bite_size = edible.bite_consumption
var/mob/living/carbon/human/consistent/gourmet = allocate(/mob/living/carbon/human/consistent)
@@ -496,9 +495,10 @@
TEST_ASSERT(!fish.bites_amount, "bites_amount wasn't reset after the fish revived")
fish.update_size_and_weight(fish.size, FISH_WEIGHT_BITE_DIVISOR)
var/bite_size = edible.bite_consumption
fish.AddElement(/datum/element/fried_item, FISH_SAFE_COOKING_DURATION)
TEST_ASSERT_EQUAL(fish.status, FISH_DEAD, "The fish didn't die after being cooked")
TEST_ASSERT(bite_size < edible.bite_consumption, "The bite_consumption value hasn't increased after being cooked (it removes blood but doubles protein). Value: [bite_size]")
TEST_ASSERT(bite_size < edible.bite_consumption, "The bite_consumption value hasn't increased after being cooked (it removes blood but doubles protein). Old: [bite_size]. New: [edible.bite_consumption]")
TEST_ASSERT(!(edible.foodtypes & (RAW|GORE)), "Fish still has the GORE and/or RAW foodtypes flags after being cooked")
TEST_ASSERT(!fish.GetComponent(/datum/component/infective), "Fish still has the infective component after being cooked for long enough")
+3 -1
View File
@@ -14,8 +14,10 @@
var/times_to_bite = round(light_snack.max_integrity / MOTH_EATING_CLOTHING_DAMAGE) + 1
for (var/i in 1 to times_to_bite)
TEST_ASSERT(!QDELETED(light_snack), "Moth finished eating clothes faster than expected.")
var/old_integrity = light_snack.get_integrity()
light_snack.attack(gourmet, gourmet)
TEST_ASSERT(QDELETED(light_snack), "Moth failed to finish eating clothing.")
TEST_ASSERT(light_snack.get_integrity() < old_integrity, "Clothing didn't take damage when bitten by moth.")
TEST_ASSERT(QDELETED(light_snack), "Moth failed to finish eating clothing. Integrity left: [light_snack.get_integrity()]")
/// Unit test to ensure that golems can eat rocks successfully
/datum/unit_test/golem_food
+1 -1
View File
@@ -294,7 +294,7 @@
#include "code\__DEFINES\construction\material.dm"
#include "code\__DEFINES\construction\rcd.dm"
#include "code\__DEFINES\construction\structures.dm"
#include "code\__DEFINES\dcs\flags.dm"
#include "code\__DEFINES\dcs\declarations.dm"
#include "code\__DEFINES\dcs\helpers.dm"
#include "code\__DEFINES\dcs\signals\mapping.dm"
#include "code\__DEFINES\dcs\signals\signals_action.dm"