From da31ea158cb7a8d557f8d7d7632abaaf48e7e8f0 Mon Sep 17 00:00:00 2001 From: Ghom <42542238+Ghommie@users.noreply.github.com> Date: Sun, 2 Mar 2025 13:15:08 +0100 Subject: [PATCH] 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 :cl: 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. /:cl: --- .../dcs/{flags.dm => declarations.dm} | 9 ++ code/datums/components/_component.dm | 6 +- code/datums/components/food/edible.dm | 142 ++++++++++-------- code/datums/components/food/golem_food.dm | 2 +- code/datums/elements/food/fried_item.dm | 6 +- code/datums/elements/food/grilled_item.dm | 4 +- code/datums/materials/meat.dm | 21 +-- code/datums/materials/pizza.dm | 23 +-- code/game/objects/items/cigarettes.dm | 4 +- code/game/objects/items/crayons.dm | 7 +- code/game/objects/items/devices/flashlight.dm | 4 +- code/game/objects/items/food/_food.dm | 4 +- code/game/objects/items/food/donuts.dm | 2 +- code/game/objects/items/food/frozen.dm | 2 +- code/game/objects/items/food/misc.dm | 2 +- code/game/objects/items/food/packaged.dm | 2 +- code/game/objects/items/food/sandwichtoast.dm | 2 +- code/game/objects/items/food/snacks.dm | 2 +- code/game/objects/items/food/sweets.dm | 2 +- .../items/stacks/sheets/sheet_types.dm | 6 +- code/game/objects/items/storage/backpack.dm | 3 +- code/modules/cargo/exports/sheets.dm | 2 +- code/modules/cargo/packs/exploration.dm | 2 +- code/modules/clothing/clothing.dm | 2 +- code/modules/fishing/fish/_fish.dm | 10 +- code/modules/hydroponics/grown/banana.dm | 2 +- code/modules/hydroponics/grown/melon.dm | 2 +- .../mob/living/basic/farm_animals/bee/_bee.dm | 4 +- code/modules/surgery/organs/_organ.dm | 4 +- code/modules/unit_tests/fish_unit_tests.dm | 4 +- code/modules/unit_tests/weird_food.dm | 4 +- tgstation.dme | 2 +- 32 files changed, 174 insertions(+), 119 deletions(-) rename code/__DEFINES/dcs/{flags.dm => declarations.dm} (91%) diff --git a/code/__DEFINES/dcs/flags.dm b/code/__DEFINES/dcs/declarations.dm similarity index 91% rename from code/__DEFINES/dcs/flags.dm rename to code/__DEFINES/dcs/declarations.dm index 950a37d3c43..04b31f4e185 100644 --- a/code/__DEFINES/dcs/flags.dm +++ b/code/__DEFINES/dcs/declarations.dm @@ -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" diff --git a/code/datums/components/_component.dm b/code/datums/components/_component.dm index b9e92ca4423..9fc1e13e1b4 100644 --- a/code/datums/components/_component.dm +++ b/code/datums/components/_component.dm @@ -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 diff --git a/code/datums/components/food/edible.dm b/code/datums/components/food/edible.dm index b466f32c99e..8faf32fef56 100644 --- a/code/datums/components/food/edible.dm +++ b/code/datums/components/food/edible.dm @@ -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 diff --git a/code/datums/components/food/golem_food.dm b/code/datums/components/food/golem_food.dm index 136d495b59e..7ba0a72304d 100644 --- a/code/datums/components/food/golem_food.dm +++ b/code/datums/components/food/golem_food.dm @@ -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) diff --git a/code/datums/elements/food/fried_item.dm b/code/datums/elements/food/fried_item.dm index 7f8613a537f..fae3c8b8320 100644 --- a/code/datums/elements/food/fried_item.dm +++ b/code/datums/elements/food/fried_item.dm @@ -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 ..() diff --git a/code/datums/elements/food/grilled_item.dm b/code/datums/elements/food/grilled_item.dm index 6899f47faa4..c97be0490a8 100644 --- a/code/datums/elements/food/grilled_item.dm +++ b/code/datums/elements/food/grilled_item.dm @@ -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 ..() diff --git a/code/datums/materials/meat.dm b/code/datums/materials/meat.dm index 512b97f81be..134449b712a 100644 --- a/code/datums/materials/meat.dm +++ b/code/datums/materials/meat.dm @@ -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 diff --git a/code/datums/materials/pizza.dm b/code/datums/materials/pizza.dm index 1bbaaefa909..9c71f760139 100644 --- a/code/datums/materials/pizza.dm +++ b/code/datums/materials/pizza.dm @@ -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)) diff --git a/code/game/objects/items/cigarettes.dm b/code/game/objects/items/cigarettes.dm index 89bfb8280d7..1acf813b669 100644 --- a/code/game/objects/items/cigarettes.dm +++ b/code/game/objects/items/cigarettes.dm @@ -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,\ diff --git a/code/game/objects/items/crayons.dm b/code/game/objects/items/crayons.dm index eed79837843..7396fbb59ca 100644 --- a/code/game/objects/items/crayons.dm +++ b/code/game/objects/items/crayons.dm @@ -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) diff --git a/code/game/objects/items/devices/flashlight.dm b/code/game/objects/items/devices/flashlight.dm index a52bb057844..335c3a94863 100644 --- a/code/game/objects/items/devices/flashlight.dm +++ b/code/game/objects/items/devices/flashlight.dm @@ -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)),\ diff --git a/code/game/objects/items/food/_food.dm b/code/game/objects/items/food/_food.dm index 0fb85e67589..85f6ae71732 100644 --- a/code/game/objects/items/food/_food.dm +++ b/code/game/objects/items/food/_food.dm @@ -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,\ diff --git a/code/game/objects/items/food/donuts.dm b/code/game/objects/items/food/donuts.dm index cbe3451c9df..5a7c6a87145 100644 --- a/code/game/objects/items/food/donuts.dm +++ b/code/game/objects/items/food/donuts.dm @@ -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) diff --git a/code/game/objects/items/food/frozen.dm b/code/game/objects/items/food/frozen.dm index 27052507bfd..775c4a545e8 100644 --- a/code/game/objects/items/food/frozen.dm +++ b/code/game/objects/items/food/frozen.dm @@ -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() . = ..() diff --git a/code/game/objects/items/food/misc.dm b/code/game/objects/items/food/misc.dm index 24472eb5e7a..46ee44cd544 100644 --- a/code/game/objects/items/food/misc.dm +++ b/code/game/objects/items/food/misc.dm @@ -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) diff --git a/code/game/objects/items/food/packaged.dm b/code/game/objects/items/food/packaged.dm index 0c68d329d97..559e0fa7943 100644 --- a/code/game/objects/items/food/packaged.dm +++ b/code/game/objects/items/food/packaged.dm @@ -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 diff --git a/code/game/objects/items/food/sandwichtoast.dm b/code/game/objects/items/food/sandwichtoast.dm index 47ae8b2c1ab..ebf934b341a 100644 --- a/code/game/objects/items/food/sandwichtoast.dm +++ b/code/game/objects/items/food/sandwichtoast.dm @@ -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. diff --git a/code/game/objects/items/food/snacks.dm b/code/game/objects/items/food/snacks.dm index 06c0deb7cbc..deb222033ba 100644 --- a/code/game/objects/items/food/snacks.dm +++ b/code/game/objects/items/food/snacks.dm @@ -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)) diff --git a/code/game/objects/items/food/sweets.dm b/code/game/objects/items/food/sweets.dm index 62c10675f04..fcd5707f013 100644 --- a/code/game/objects/items/food/sweets.dm +++ b/code/game/objects/items/food/sweets.dm @@ -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)) diff --git a/code/game/objects/items/stacks/sheets/sheet_types.dm b/code/game/objects/items/stacks/sheets/sheet_types.dm index 3b1b0bde6bb..b032d4f60da 100644 --- a/code/game/objects/items/stacks/sheets/sheet_types.dm +++ b/code/game/objects/items/stacks/sheets/sheet_types.dm @@ -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 diff --git a/code/game/objects/items/storage/backpack.dm b/code/game/objects/items/storage/backpack.dm index b52b0c4fd02..f2ed4287c11 100644 --- a/code/game/objects/items/storage/backpack.dm +++ b/code/game/objects/items/storage/backpack.dm @@ -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,\ diff --git a/code/modules/cargo/exports/sheets.dm b/code/modules/cargo/exports/sheets.dm index 324dce084fc..53ca52ab27b 100644 --- a/code/modules/cargo/exports/sheets.dm +++ b/code/modules/cargo/exports/sheets.dm @@ -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 diff --git a/code/modules/cargo/packs/exploration.dm b/code/modules/cargo/packs/exploration.dm index 55b28094de2..17f1ce1cb2c 100644 --- a/code/modules/cargo/packs/exploration.dm +++ b/code/modules/cargo/packs/exploration.dm @@ -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" diff --git a/code/modules/clothing/clothing.dm b/code/modules/clothing/clothing.dm index 1e9608abdb4..0590e4c3779 100644 --- a/code/modules/clothing/clothing.dm +++ b/code/modules/clothing/clothing.dm @@ -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() diff --git a/code/modules/fishing/fish/_fish.dm b/code/modules/fishing/fish/_fish.dm index d98014903d6..1c4169294be 100644 --- a/code/modules/fishing/fish/_fish.dm +++ b/code/modules/fishing/fish/_fish.dm @@ -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() diff --git a/code/modules/hydroponics/grown/banana.dm b/code/modules/hydroponics/grown/banana.dm index 18640cd2828..0a954b15981 100644 --- a/code/modules/hydroponics/grown/banana.dm +++ b/code/modules/hydroponics/grown/banana.dm @@ -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) . = ..() diff --git a/code/modules/hydroponics/grown/melon.dm b/code/modules/hydroponics/grown/melon.dm index 3aca50ae1be..cc633d4912b 100644 --- a/code/modules/hydroponics/grown/melon.dm +++ b/code/modules/hydroponics/grown/melon.dm @@ -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) diff --git a/code/modules/mob/living/basic/farm_animals/bee/_bee.dm b/code/modules/mob/living/basic/farm_animals/bee/_bee.dm index 09bf3a58195..8c93a28d6d4 100644 --- a/code/modules/mob/living/basic/farm_animals/bee/_bee.dm +++ b/code/modules/mob/living/basic/farm_animals/bee/_bee.dm @@ -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)) diff --git a/code/modules/surgery/organs/_organ.dm b/code/modules/surgery/organs/_organ.dm index 1039a3d332d..66c84a8776f 100644 --- a/code/modules/surgery/organs/_organ.dm +++ b/code/modules/surgery/organs/_organ.dm @@ -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,\ diff --git a/code/modules/unit_tests/fish_unit_tests.dm b/code/modules/unit_tests/fish_unit_tests.dm index bdc4c4d2433..62711753eb8 100644 --- a/code/modules/unit_tests/fish_unit_tests.dm +++ b/code/modules/unit_tests/fish_unit_tests.dm @@ -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") diff --git a/code/modules/unit_tests/weird_food.dm b/code/modules/unit_tests/weird_food.dm index 5c97c343adf..a3b3f0fe203 100644 --- a/code/modules/unit_tests/weird_food.dm +++ b/code/modules/unit_tests/weird_food.dm @@ -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 diff --git a/tgstation.dme b/tgstation.dme index da054778db5..449c253857d 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -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"