diff --git a/code/__DEFINES/dcs/signals/signals_food.dm b/code/__DEFINES/dcs/signals/signals_food.dm index a5be9bb7c14..5158d84954a 100644 --- a/code/__DEFINES/dcs/signals/signals_food.dm +++ b/code/__DEFINES/dcs/signals/signals_food.dm @@ -1,24 +1,58 @@ -///called when an item is used as an ingredient: (atom/customized) -#define COMSIG_ITEM_USED_AS_INGREDIENT "item_used_as_ingredient" -///called when an edible ingredient is added: (datum/component/edible/ingredient) -#define COMSIG_EDIBLE_INGREDIENT_ADDED "edible_ingredient_added" //Food -///from Edible component: (mob/living/eater, mob/feeder, bitecount, bitesize) +// Eating stuff +/// From datum/component/edible/proc/TakeBite: (mob/living/eater, mob/feeder, bitecount, bitesize) #define COMSIG_FOOD_EATEN "food_eaten" -///from base of datum/component/edible/on_entered: (mob/crosser, bitecount) +/// From base of datum/component/edible/on_entered: (mob/crosser, bitecount) #define COMSIG_FOOD_CROSSED "food_crossed" - -///from base of Component/edible/On_Consume: (mob/living/eater, mob/living/feeder) +/// From base of Component/edible/On_Consume: (mob/living/eater, mob/living/feeder) #define COMSIG_FOOD_CONSUMED "food_consumed" +/// called when an item is used as an ingredient: (atom/customized) +#define COMSIG_ITEM_USED_AS_INGREDIENT "item_used_as_ingredient" +/// called when an edible ingredient is added: (datum/component/edible/ingredient) +#define COMSIG_FOOD_INGREDIENT_ADDED "edible_ingredient_added" -///from base of Component/edible/on_silver_slime_reaction: (obj/item/source) -#define COMSIG_FOOD_SILVER_SPAWNED "food_silver_spawned" - +// Deep frying foods +/// From obj/item/food/deepfryholder/Initialize #define COMSIG_ITEM_FRIED "item_fried" + /// Return to not burn the item #define COMSIG_FRYING_HANDLED (1<<0) +// Microwaving foods +///called on item when microwaved (): (obj/machinery/microwave/microwave, mob/microwaver) +#define COMSIG_ITEM_MICROWAVE_ACT "microwave_act" + /// Return on success - that is, a microwaved item was produced + #define COMPONENT_MICROWAVE_SUCCESS (1<<0) + /// Returned on "failure" - an item was produced but it was the default fail recipe + #define COMPONENT_MICROWAVE_BAD_RECIPE (1<<1) +///called on item when created through microwaving (): (obj/machinery/microwave/M, cooking_efficiency) +#define COMSIG_ITEM_MICROWAVE_COOKED "microwave_cooked" + +// Grilling foods (griddle, grill, and bonfire) +///Called when an object is placed onto a griddle +#define COMSIG_ITEM_GRILL_PLACED_ON "item_placed_on_griddle" +///Called when an object is grilled ontop of a griddle +#define COMSIG_ITEM_GRILL_PROCESS "item_griddled" + /// Return to not burn the item + #define COMPONENT_HANDLED_GRILLING (1<<0) +///Called when an object is turned into another item through grilling ontop of a griddle +#define COMSIG_ITEM_GRILLED "item_grill_completed" + +// Baking foods (oven) +//Called when an object is inserted into an oven (atom/oven, mob/baker) +#define COMSIG_ITEM_OVEN_PLACED_IN "item_placed_in_oven" +//Called when an object is in an oven +#define COMSIG_ITEM_OVEN_PROCESS "item_baked" + /// Return to not burn the item + #define COMPONENT_HANDLED_BAKING (1<<0) + /// Return if the result of the baking was a good thing + #define COMPONENT_BAKING_GOOD_RESULT (1<<1) + /// Return if the result of the baking was a bad thing / failuire + #define COMPONENT_BAKING_BAD_RESULT (1<<2) +///Called when an object is turned into another item through baking in an oven +#define COMSIG_ITEM_BAKED "item_bake_completed" + //Drink ///from base of obj/item/reagent_containers/cup/attack(): (mob/M, mob/user) diff --git a/code/__DEFINES/dcs/signals/signals_object.dm b/code/__DEFINES/dcs/signals/signals_object.dm index bb307955d9a..5178f935942 100644 --- a/code/__DEFINES/dcs/signals/signals_object.dm +++ b/code/__DEFINES/dcs/signals/signals_object.dm @@ -135,31 +135,13 @@ ///from base of obj/item/hit_reaction(): (list/args) #define COMSIG_ITEM_HIT_REACT "item_hit_react" #define COMPONENT_HIT_REACTION_BLOCK (1<<0) -///called on item when microwaved (): (obj/machinery/microwave/M) -#define COMSIG_ITEM_MICROWAVE_ACT "microwave_act" - #define COMPONENT_SUCCESFUL_MICROWAVE (1<<0) -///called on item when created through microwaving (): (obj/machinery/microwave/M, cooking_efficiency) -#define COMSIG_ITEM_MICROWAVE_COOKED "microwave_cooked" ///from base of item/sharpener/attackby(): (amount, max) #define COMSIG_ITEM_SHARPEN_ACT "sharpen_act" #define COMPONENT_BLOCK_SHARPEN_APPLIED (1<<0) #define COMPONENT_BLOCK_SHARPEN_BLOCKED (1<<1) #define COMPONENT_BLOCK_SHARPEN_ALREADY (1<<2) #define COMPONENT_BLOCK_SHARPEN_MAXED (1<<3) -///Called when an object is grilled ontop of a griddle -#define COMSIG_ITEM_GRILLED "item_griddled" - #define COMPONENT_HANDLED_GRILLING (1<<0) -///Called when an object is turned into another item through grilling ontop of a griddle -#define COMSIG_GRILL_COMPLETED "item_grill_completed" -///Called when an object is meant to be grilled through a grill: (atom/fry_object, grill_time) -#define COMSIG_GRILL_FOOD "item_grill_food" -//Called when an object is in an oven -#define COMSIG_ITEM_BAKED "item_baked" - #define COMPONENT_HANDLED_BAKING (1<<0) - #define COMPONENT_BAKING_GOOD_RESULT (1<<1) - #define COMPONENT_BAKING_BAD_RESULT (1<<2) -///Called when an object is turned into another item through baking in an oven -#define COMSIG_BAKE_COMPLETED "item_bake_completed" + ///Called when an armor plate is successfully applied to an object #define COMSIG_ARMOR_PLATED "armor_plated" ///Called when an item gets recharged by the ammo powerup diff --git a/code/__DEFINES/food.dm b/code/__DEFINES/food.dm index 416043b90ed..c3c5ec315ef 100644 --- a/code/__DEFINES/food.dm +++ b/code/__DEFINES/food.dm @@ -19,6 +19,29 @@ #define BUGS (1<<18) #define GORE (1<<19) +DEFINE_BITFIELD(foodtypes, list( + "MEAT" = MEAT, + "VEGETABLES" = VEGETABLES, + "RAW" = RAW, + "JUNKFOOD" = JUNKFOOD, + "GRAIN" = GRAIN, + "FRUIT" = FRUIT, + "DAIRY" = DAIRY, + "FRIED" = FRIED, + "ALCOHOL" = ALCOHOL, + "SUGAR" = SUGAR, + "GROSS" = GROSS, + "TOXIC" = TOXIC, + "PINEAPPLE" = PINEAPPLE, + "BREAKFAST" = BREAKFAST, + "CLOTH" = CLOTH, + "NUTS" = NUTS, + "SEAFOOD" = SEAFOOD, + "ORANGES" = ORANGES, + "BUGS" = BUGS, + "GORE" = GORE, +)) + /// A list of food type names, in order of their flags #define FOOD_FLAGS list( \ "MEAT", \ @@ -73,14 +96,18 @@ #define DRINK_FANTASTIC 4 #define FOOD_AMAZING 5 +/// Food is "in a container", not in a code sense, but in a literal sense (canned foods) #define FOOD_IN_CONTAINER (1<<0) +/// Finger food can be eaten while walking / running around #define FOOD_FINGER_FOOD (1<<1) -///Is this food item spawned from a silver slime? Prevent it from exporting for profit from cargo and make it taste disgusting -#define FOOD_SILVER_SPAWNED (1<<2) + +DEFINE_BITFIELD(food_types, list( + "FOOD_FINGER_FOOD" = FOOD_FINGER_FOOD, + "FOOD_IN_CONTAINER" = FOOD_IN_CONTAINER, +)) #define STOP_SERVING_BREAKFAST (15 MINUTES) - #define FOOD_MEAT_NORMAL 5 #define FOOD_MEAT_HUMAN 50 #define FOOD_MEAT_MUTANT 100 diff --git a/code/__DEFINES/traits.dm b/code/__DEFINES/traits.dm index 909bfbc2ba1..312c94f3cd1 100644 --- a/code/__DEFINES/traits.dm +++ b/code/__DEFINES/traits.dm @@ -474,6 +474,8 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai #define TRAIT_ENTRAILS_READER "entrails_reader" /// this skillchip trait lets you wash brains in washing machines to heal them #define TRAIT_BRAINWASHING "brainwashing" +/// Allows chef's to chefs kiss their food, to make them with love +#define TRAIT_CHEF_KISS "chefs_kiss" ///Movement type traits for movables. See elements/movetype_handler.dm #define TRAIT_MOVE_GROUND "move_ground" @@ -539,7 +541,12 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai #define TRAIT_NO_STORAGE_INSERT "no_storage_insert" /// Visible on t-ray scanners if the atom/var/level == 1 #define TRAIT_T_RAY_VISIBLE "t-ray-visible" +/// If this item's been grilled #define TRAIT_FOOD_GRILLED "food_grilled" +/// This is a silver slime created item +#define TRAIT_FOOD_SILVER "food_silver" +/// If this item's been made by a chef instead of being map-spawned or admin-spawned or such +#define TRAIT_FOOD_CHEF_MADE "food_made_by_chef" /// The items needs two hands to be carried #define TRAIT_NEEDS_TWO_HANDS "needstwohands" /// Can't be catched when thrown diff --git a/code/datums/components/bakeable.dm b/code/datums/components/bakeable.dm index 71e15e7a938..9481f9f8e5d 100644 --- a/code/datums/components/bakeable.dm +++ b/code/datums/components/bakeable.dm @@ -11,6 +11,8 @@ ///Time spent baking so far var/current_bake_time = 0 + /// REF() to the mob which placed us in an oven + var/who_baked_us /datum/component/bakeable/Initialize(bake_result, required_bake_time, positive_result, use_large_steam_sprite) . = ..() @@ -33,32 +35,42 @@ src.positive_result = positive_result /datum/component/bakeable/RegisterWithParent() - RegisterSignal(parent, COMSIG_ITEM_BAKED, .proc/OnBake) - RegisterSignal(parent, COMSIG_PARENT_EXAMINE, .proc/OnExamine) + RegisterSignal(parent, COMSIG_ITEM_OVEN_PLACED_IN, .proc/on_baking_start) + RegisterSignal(parent, COMSIG_ITEM_OVEN_PROCESS, .proc/on_bake) + RegisterSignal(parent, COMSIG_PARENT_EXAMINE, .proc/on_examine) /datum/component/bakeable/UnregisterFromParent() - . = ..() - UnregisterSignal(parent, list(COMSIG_ITEM_BAKED, COMSIG_PARENT_EXAMINE)) + UnregisterSignal(parent, list(COMSIG_ITEM_OVEN_PLACED_IN, COMSIG_ITEM_OVEN_PROCESS, COMSIG_PARENT_EXAMINE)) -///Ran every time an item is baked by something -/datum/component/bakeable/proc/OnBake(datum/source, atom/used_oven, delta_time = 1) +/// Signal proc for [COMSIG_ITEM_OVEN_PLACED_IN] when baking starts (parent enters an oven) +/datum/component/bakeable/proc/on_baking_start(datum/source, atom/used_oven, mob/baker) SIGNAL_HANDLER - . = COMPONENT_HANDLED_BAKING + if(baker) + who_baked_us = REF(baker) - . |= positive_result ? COMPONENT_BAKING_GOOD_RESULT : COMPONENT_BAKING_BAD_RESULT //Are we baking shit or great food? +///Ran every time an item is baked by something +/datum/component/bakeable/proc/on_bake(datum/source, atom/used_oven, delta_time = 1) + SIGNAL_HANDLER + + // Let our signal know if we're baking something good or ... burning something + var/baking_result = positive_result ? COMPONENT_BAKING_GOOD_RESULT : COMPONENT_BAKING_BAD_RESULT current_bake_time += delta_time * 10 //turn it into ds if(current_bake_time >= required_bake_time) - FinishBaking(used_oven) + finish_baking(used_oven) + + return COMPONENT_HANDLED_BAKING | baking_result ///Ran when an object finished baking -/datum/component/bakeable/proc/FinishBaking(atom/used_oven) +/datum/component/bakeable/proc/finish_baking(atom/used_oven) var/atom/original_object = parent var/obj/item/plate/oven_tray/used_tray = original_object.loc var/atom/baked_result = new bake_result(used_tray) + if(who_baked_us) + ADD_TRAIT(baked_result, TRAIT_FOOD_CHEF_MADE, who_baked_us) if(original_object.custom_materials) baked_result.set_custom_materials(original_object.custom_materials, 1) @@ -71,11 +83,11 @@ used_oven.visible_message(span_notice("You smell something great coming from [used_oven]."), blind_message = span_notice("You smell something great...")) else used_oven.visible_message(span_warning("You smell a burnt smell coming from [used_oven]."), blind_message = span_warning("You smell a burnt smell...")) - SEND_SIGNAL(parent, COMSIG_BAKE_COMPLETED, baked_result) + SEND_SIGNAL(parent, COMSIG_ITEM_BAKED, baked_result) qdel(parent) ///Gives info about the items baking status so you can see if its almost done -/datum/component/bakeable/proc/OnExamine(atom/A, mob/user, list/examine_list) +/datum/component/bakeable/proc/on_examine(atom/source, mob/user, list/examine_list) SIGNAL_HANDLER if(!current_bake_time) //Not baked yet diff --git a/code/datums/components/food/edible.dm b/code/datums/components/food/edible.dm index 9106c6e73eb..5698bcd3448 100644 --- a/code/datums/components/food/edible.dm +++ b/code/datums/components/food/edible.dm @@ -36,15 +36,10 @@ 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 reagents of this food when it is made - var/list/initial_reagents ///The initial volume of the foods reagents - var/volume + var/volume = 50 ///The flavortext for taste (haha get it flavor text) var/list/tastes - ///The type of atom this creates when the object is microwaved. - var/atom/microwaved_type - /datum/component/edible/Initialize( list/initial_reagents, @@ -53,9 +48,8 @@ Behavior that's still missing from this component that original food items had t volume = 50, eat_time = 10, list/tastes, - list/eatverbs = list("bite","chew","nibble","gnaw","gobble","chomp"), + list/eatverbs = list("bite", "chew", "nibble", "gnaw", "gobble", "chomp"), bite_consumption = 2, - microwaved_type, junkiness, datum/callback/after_eat, datum/callback/on_consume, @@ -64,109 +58,177 @@ Behavior that's still missing from this component that original food items had t if(!isatom(parent)) return COMPONENT_INCOMPATIBLE - RegisterSignal(parent, COMSIG_PARENT_EXAMINE, .proc/examine) - RegisterSignal(parent, COMSIG_ATOM_ATTACK_ANIMAL, .proc/UseByAnimal) - RegisterSignal(parent, COMSIG_ATOM_CHECKPARTS, .proc/OnCraft) - RegisterSignal(parent, COMSIG_ATOM_CREATEDBY_PROCESSING, .proc/OnProcessed) - RegisterSignal(parent, COMSIG_ITEM_MICROWAVE_COOKED, .proc/OnMicrowaveCooked) - RegisterSignal(parent, COMSIG_EDIBLE_INGREDIENT_ADDED, .proc/edible_ingredient_added) - RegisterSignal(parent, COMSIG_OOZE_EAT_ATOM, .proc/on_ooze_eat) - - if(!isturf(parent)) - var/static/list/loc_connections = list( - COMSIG_ATOM_ENTERED = .proc/on_entered, - ) - AddComponent(/datum/component/connect_loc_behalf, parent, loc_connections) - else - RegisterSignal(parent, COMSIG_ATOM_ENTERED, .proc/on_entered) - - if(isitem(parent)) - RegisterSignal(parent, COMSIG_ITEM_ATTACK, .proc/UseFromHand) - RegisterSignal(parent, COMSIG_ITEM_FRIED, .proc/OnFried) - RegisterSignal(parent, COMSIG_GRILL_FOOD, .proc/GrillFood) - RegisterSignal(parent, COMSIG_ITEM_MICROWAVE_ACT, .proc/OnMicrowaved) - RegisterSignal(parent, COMSIG_FOOD_SILVER_SPAWNED, .proc/on_silver_slime_reaction) - RegisterSignal(parent, COMSIG_ITEM_USED_AS_INGREDIENT, .proc/used_to_customize) - - var/obj/item/item = parent - if (!item.grind_results) - item.grind_results = list() //If this doesn't already exist, add it as an empty list. This is needed for the grinder to accept it. - - else if(isturf(parent) || isstructure(parent)) - RegisterSignal(parent, COMSIG_ATOM_ATTACK_HAND, .proc/TryToEatIt) - 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.initial_reagents = string_assoc_list(initial_reagents) src.tastes = string_assoc_list(tastes) - src.microwaved_type = microwaved_type src.check_liked = check_liked - var/atom/owner = parent + setup_initial_reagents(initial_reagents) - owner.create_reagents(volume, INJECTABLE) +/datum/component/edible/RegisterWithParent() + RegisterSignal(parent, COMSIG_PARENT_EXAMINE, .proc/examine) + RegisterSignal(parent, COMSIG_ATOM_ATTACK_ANIMAL, .proc/UseByAnimal) + RegisterSignal(parent, COMSIG_ATOM_CHECKPARTS, .proc/OnCraft) + RegisterSignal(parent, COMSIG_ATOM_CREATEDBY_PROCESSING, .proc/OnProcessed) + RegisterSignal(parent, COMSIG_FOOD_INGREDIENT_ADDED, .proc/edible_ingredient_added) + RegisterSignal(parent, COMSIG_OOZE_EAT_ATOM, .proc/on_ooze_eat) - for(var/rid in initial_reagents) - var/amount = initial_reagents[rid] - if(length(tastes) && (rid == /datum/reagent/consumable/nutriment || rid == /datum/reagent/consumable/nutriment/vitamin)) - owner.reagents.add_reagent(rid, amount, tastes.Copy()) - else - owner.reagents.add_reagent(rid, amount) + if(isturf(parent)) + RegisterSignal(parent, COMSIG_ATOM_ENTERED, .proc/on_entered) + else + var/static/list/loc_connections = list(COMSIG_ATOM_ENTERED = .proc/on_entered) + AddComponent(/datum/component/connect_loc_behalf, parent, loc_connections) + + if(isitem(parent)) + RegisterSignal(parent, COMSIG_ITEM_ATTACK, .proc/UseFromHand) + RegisterSignal(parent, COMSIG_ITEM_FRIED, .proc/OnFried) + RegisterSignal(parent, COMSIG_ITEM_USED_AS_INGREDIENT, .proc/used_to_customize) + + var/obj/item/item = parent + if(!item.grind_results) + item.grind_results = list() //If this doesn't already exist, add it as an empty list. This is needed for the grinder to accept it. + + else if(isturf(parent) || isstructure(parent)) + RegisterSignal(parent, COMSIG_ATOM_ATTACK_HAND, .proc/TryToEatIt) + +/datum/component/edible/UnregisterFromParent() + UnregisterSignal(parent, list( + COMSIG_ATOM_ATTACK_ANIMAL, + COMSIG_ATOM_ATTACK_HAND, + COMSIG_ATOM_CHECKPARTS, + COMSIG_ATOM_CREATEDBY_PROCESSING, + COMSIG_ATOM_ENTERED, + COMSIG_FOOD_INGREDIENT_ADDED, + COMSIG_ITEM_ATTACK, + COMSIG_ITEM_FRIED, + COMSIG_ITEM_USED_AS_INGREDIENT, + COMSIG_OOZE_EAT_ATOM, + COMSIG_PARENT_EXAMINE, + )) + + qdel(GetComponent(/datum/component/connect_loc_behalf)) /datum/component/edible/InheritComponent( - datum/component/C, + datum/component/edible/old_comp, i_am_original, list/initial_reagents, food_flags = NONE, foodtypes = NONE, - volume = 50, - eat_time = 10, + volume, + eat_time, list/tastes, - list/eatverbs = list("bite","chew","nibble","gnaw","gobble","chomp"), - bite_consumption = 2, - microwaved_type, + list/eatverbs, + bite_consumption, junkiness, datum/callback/after_eat, datum/callback/on_consume, datum/callback/check_liked, ) - . = ..() - src.bite_consumption = bite_consumption - src.food_flags = food_flags - src.foodtypes = foodtypes - src.eat_time = eat_time - src.eatverbs = eatverbs - src.junkiness = junkiness - src.after_eat = after_eat - src.on_consume = on_consume + + // 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 + + // only edit if we're OG + if(!i_am_original) + 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 + if(islist(cached_verbs)) + // eatverbs becomes a combination of existing verbs and new ones + 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)) + src.on_consume = on_consume + if(!isnull(check_liked)) + src.check_liked = check_liked + + // add newly passed in reagents + setup_initial_reagents(initial_reagents) /datum/component/edible/Destroy(force, silent) QDEL_NULL(after_eat) QDEL_NULL(on_consume) + QDEL_NULL(check_liked) return ..() +/// Sets up the initial reagents of the food. +/datum/component/edible/proc/setup_initial_reagents(list/reagents) + var/atom/owner = parent + if(owner.reagents) + owner.reagents.maximum_volume = volume + else + owner.create_reagents(volume, INJECTABLE) + + for(var/rid in reagents) + var/amount = reagents[rid] + if(length(tastes) && (rid == /datum/reagent/consumable/nutriment || rid == /datum/reagent/consumable/nutriment/vitamin)) + owner.reagents.add_reagent(rid, amount, tastes.Copy()) + else + owner.reagents.add_reagent(rid, amount) + /datum/component/edible/proc/examine(datum/source, mob/user, list/examine_list) SIGNAL_HANDLER - if(microwaved_type) - examine_list += "[parent] could be microwaved into [initial(microwaved_type.name)]!" + if(foodtypes) + var/list/types = bitfield_to_list(foodtypes, FOOD_FLAGS) + examine_list += span_notice("It is [lowertext(english_list(types))].") + + if(HAS_TRAIT_FROM(parent, TRAIT_FOOD_CHEF_MADE, REF(user))) + examine_list += span_green("[parent] was made by you!") if(!(food_flags & FOOD_IN_CONTAINER)) - switch (bitecount) - if (0) - return + switch(bitecount) + if(0) + // pass if(1) - examine_list += "[parent] was bitten by someone!" - if(2,3) - examine_list += "[parent] was bitten [bitecount] times!" + examine_list += span_notice("[parent] was bitten by someone!") + if(2, 3) + examine_list += span_notice("[parent] was bitten [bitecount] times!") else - examine_list += "[parent] was bitten multiple times!" + examine_list += span_notice("[parent] was bitten multiple times!") /datum/component/edible/proc/UseFromHand(obj/item/source, mob/living/M, mob/living/user) SIGNAL_HANDLER @@ -186,29 +248,6 @@ Behavior that's still missing from this component that original food items had t qdel(our_atom) return COMSIG_FRYING_HANDLED -/datum/component/edible/proc/GrillFood(datum/source, atom/fry_object, grill_time) - SIGNAL_HANDLER - - var/atom/this_food = parent - - switch(grill_time) //no 0-20 to prevent spam - if(20 to 30) - this_food.name = "lightly-grilled [this_food.name]" - this_food.desc = "[this_food.desc] It's been lightly grilled." - if(30 to 80) - this_food.name = "grilled [this_food.name]" - this_food.desc = "[this_food.desc] It's been grilled." - foodtypes |= FRIED - if(80 to 100) - this_food.name = "heavily grilled [this_food.name]" - this_food.desc = "[this_food.desc] It's been heavily grilled." - foodtypes |= FRIED - if(100 to INFINITY) //grill marks reach max alpha - this_food.name = "Powerfully Grilled [this_food.name]" - this_food.desc = "A [this_food.name]. Reminds you of your wife, wait, no, it's prettier!" - foodtypes |= FRIED - - ///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) SIGNAL_HANDLER @@ -249,38 +288,6 @@ Behavior that's still missing from this component that original food items had t SSblackbox.record_feedback("tally", "food_made", 1, type) -/datum/component/edible/proc/OnMicrowaved(datum/source, obj/machinery/microwave/used_microwave) - SIGNAL_HANDLER - - var/turf/parent_turf = get_turf(parent) - - if(!microwaved_type) - new /obj/item/food/badrecipe(parent_turf) - qdel(parent) - return - - var/obj/item/result - - result = new microwaved_type(parent_turf) - - var/efficiency = istype(used_microwave) ? used_microwave.efficiency : 1 - - SEND_SIGNAL(result, COMSIG_ITEM_MICROWAVE_COOKED, parent, efficiency) - - SSblackbox.record_feedback("tally", "food_made", 1, result.type) - qdel(parent) - return COMPONENT_SUCCESFUL_MICROWAVE - -///Corrects the reagents on the newly cooked food -/datum/component/edible/proc/OnMicrowaveCooked(datum/source, obj/item/source_item, cooking_efficiency = 1) - SIGNAL_HANDLER - - var/atom/this_food = parent - - this_food.reagents.multiply_reagents(cooking_efficiency * CRAFTED_FOOD_BASE_REAGENT_MODIFIER) - - source_item.reagents?.trans_to(this_food, source_item.reagents.total_volume) - ///Makes sure the thing hasn't been destroyed or fully eaten to prevent eating phantom edibles /datum/component/edible/proc/IsFoodGone(atom/owner, mob/living/feeder) if(QDELETED(owner)|| !(IS_EDIBLE(owner))) @@ -427,9 +434,9 @@ Behavior that's still missing from this component that original food items had t var/fraction = min(bite_consumption / owner.reagents.total_volume, 1) owner.reagents.trans_to(eater, bite_consumption, transfered_by = feeder, methods = INGEST) bitecount++ + checkLiked(fraction, eater) if(!owner.reagents.total_volume) On_Consume(eater, feeder) - checkLiked(fraction, eater) //Invoke our after eat callback if it is valid if(after_eat) @@ -487,7 +494,7 @@ Behavior that's still missing from this component that original food items had t else if(foodtypes & H.dna.species.liked_food) food_taste_reaction = FOOD_LIKED - if(food_flags & FOOD_SILVER_SPAWNED) // it's not real food + if(HAS_TRAIT(parent, TRAIT_FOOD_SILVER)) // it's not real food food_taste_reaction = isjellyperson(H) ? FOOD_LIKED : FOOD_TOXIC switch(food_taste_reaction) @@ -552,23 +559,13 @@ Behavior that's still missing from this component that original food items had t /datum/component/edible/proc/used_to_customize(datum/source, atom/customized) SIGNAL_HANDLER - SEND_SIGNAL(customized, COMSIG_EDIBLE_INGREDIENT_ADDED, src) - -///Adds this flag to the item to make it taste disgusting -/datum/component/edible/proc/on_silver_slime_reaction(obj/item/source) - SIGNAL_HANDLER - food_flags |= FOOD_SILVER_SPAWNED + SEND_SIGNAL(customized, COMSIG_FOOD_INGREDIENT_ADDED, src) ///Response to an edible ingredient being added to parent. /datum/component/edible/proc/edible_ingredient_added(datum/source, datum/component/edible/ingredient) SIGNAL_HANDLER - var/datum/component/edible/E = ingredient - if (LAZYLEN(E.tastes)) - tastes = tastes.Copy() - for (var/t in E.tastes) - tastes[t] += E.tastes[t] - foodtypes |= E.foodtypes + InheritComponent(ingredient, TRUE) /// Response to oozes trying to eat something edible /datum/component/edible/proc/on_ooze_eat(datum/source, mob/eater, edible_flags) diff --git a/code/datums/components/grillable.dm b/code/datums/components/grillable.dm index 352eae811f4..0ca5bf6c6b0 100644 --- a/code/datums/components/grillable.dm +++ b/code/datums/components/grillable.dm @@ -6,15 +6,12 @@ var/required_cook_time = 2 MINUTES ///Is this a positive grill result? var/positive_result = TRUE - ///Time spent cooking so far var/current_cook_time = 0 - - ///Are we currently grilling? - var/currently_grilling = FALSE - ///Do we use the large steam sprite? var/use_large_steam_sprite = FALSE + /// REF() to the mob which placed us on the griddle + var/who_placed_us /datum/component/grillable/Initialize(cook_result, required_cook_time, positive_result, use_large_steam_sprite) . = ..() @@ -26,8 +23,13 @@ src.positive_result = positive_result src.use_large_steam_sprite = use_large_steam_sprite - RegisterSignal(parent, COMSIG_ITEM_GRILLED, .proc/OnGrill) - RegisterSignal(parent, COMSIG_PARENT_EXAMINE, .proc/OnExamine) +/datum/component/grillable/RegisterWithParent() + RegisterSignal(parent, COMSIG_ITEM_GRILL_PLACED_ON, .proc/on_grill_start) + RegisterSignal(parent, COMSIG_ITEM_GRILL_PROCESS, .proc/on_grill) + RegisterSignal(parent, COMSIG_PARENT_EXAMINE, .proc/on_examine) + +/datum/component/grillable/UnregisterFromParent() + UnregisterSignal(parent, list(COMSIG_ITEM_GRILL_PLACED_ON, COMSIG_ITEM_GRILL_PROCESS, COMSIG_PARENT_EXAMINE)) // Inherit the new values passed to the component /datum/component/grillable/InheritComponent(datum/component/grillable/new_comp, original, cook_result, required_cook_time, positive_result, use_large_steam_sprite) @@ -42,60 +44,55 @@ if(use_large_steam_sprite) src.use_large_steam_sprite = use_large_steam_sprite +/// Signal proc for [COMSIG_ITEM_GRILL_PLACED_ON], starts the grilling process. +/datum/component/grillable/proc/on_grill_start(datum/source, mob/griller) + SIGNAL_HANDLER + + if(griller) + who_placed_us = REF(griller) + + RegisterSignal(parent, COMSIG_MOVABLE_MOVED, .proc/on_moved) + RegisterSignal(parent, COMSIG_ATOM_UPDATE_OVERLAYS, .proc/add_grilled_item_overlay) + + var/atom/atom_parent = parent + atom_parent.update_appearance() + ///Ran every time an item is grilled by something -/datum/component/grillable/proc/OnGrill(datum/source, atom/used_grill, delta_time = 1) +/datum/component/grillable/proc/on_grill(datum/source, atom/used_grill, delta_time = 1) SIGNAL_HANDLER . = COMPONENT_HANDLED_GRILLING current_cook_time += delta_time * 10 //turn it into ds if(current_cook_time >= required_cook_time) - FinishGrilling(used_grill) - else if(!currently_grilling) //We havn't started grilling yet - StartGrilling(used_grill) - - -///Ran when an object starts grilling on something -/datum/component/grillable/proc/StartGrilling(atom/grill_source) - currently_grilling = TRUE - RegisterSignal(parent, COMSIG_MOVABLE_MOVED, .proc/OnMoved) - RegisterSignal(parent, COMSIG_ATOM_UPDATE_OVERLAYS, .proc/AddGrilledItemOverlay) - - var/atom/A = parent - A.update_appearance() + finish_grilling(used_grill) ///Ran when an object finished grilling -/datum/component/grillable/proc/FinishGrilling(atom/grill_source) +/datum/component/grillable/proc/finish_grilling(atom/grill_source) var/atom/original_object = parent + var/atom/grilled_result if(isstack(parent)) //Check if its a sheet, for grilling multiple things in a stack - var/obj/item/stack/itemstack = original_object - var/atom/grilled_result = new cook_result(original_object.loc, itemstack.amount) - SEND_SIGNAL(parent, COMSIG_GRILL_COMPLETED, grilled_result) - currently_grilling = FALSE - grill_source.visible_message("[parent] turns into \a [grilled_result]!") - grilled_result.pixel_x = original_object.pixel_x - grilled_result.pixel_y = original_object.pixel_y - qdel(parent) - return + var/obj/item/stack/stack_parent = original_object + grilled_result = new cook_result(original_object.loc, stack_parent.amount) - var/atom/grilled_result = new cook_result(original_object.loc) - - if(original_object.custom_materials) - grilled_result.set_custom_materials(original_object.custom_materials, 1) - - grilled_result.pixel_x = original_object.pixel_x - grilled_result.pixel_y = original_object.pixel_y + else + grilled_result = new cook_result(original_object.loc) + if(original_object.custom_materials) + grilled_result.set_custom_materials(original_object.custom_materials) + SEND_SIGNAL(parent, COMSIG_ITEM_GRILLED, grilled_result) + if(who_placed_us) + ADD_TRAIT(grilled_result, TRAIT_FOOD_CHEF_MADE, who_placed_us) grill_source.visible_message("[parent] turns into \a [grilled_result]!") - SEND_SIGNAL(parent, COMSIG_GRILL_COMPLETED, grilled_result) - currently_grilling = FALSE + grilled_result.pixel_x = original_object.pixel_x + grilled_result.pixel_y = original_object.pixel_y qdel(parent) ///Ran when an object almost finishes grilling -/datum/component/grillable/proc/OnExamine(atom/A, mob/user, list/examine_list) +/datum/component/grillable/proc/on_examine(atom/A, mob/user, list/examine_list) SIGNAL_HANDLER if(!current_cook_time) //Not grilled yet @@ -112,14 +109,14 @@ examine_list += span_danger("[parent] should probably not be cooked for much longer!") ///Ran when an object moves from the grill -/datum/component/grillable/proc/OnMoved(atom/A, atom/OldLoc, Dir, Forced) +/datum/component/grillable/proc/on_moved(atom/source, atom/OldLoc, Dir, Forced) SIGNAL_HANDLER - currently_grilling = FALSE + UnregisterSignal(parent, COMSIG_ATOM_UPDATE_OVERLAYS) UnregisterSignal(parent, COMSIG_MOVABLE_MOVED) - A.update_appearance() + source.update_appearance() -/datum/component/grillable/proc/AddGrilledItemOverlay(datum/source, list/overlays) +/datum/component/grillable/proc/add_grilled_item_overlay(datum/source, list/overlays) SIGNAL_HANDLER overlays += mutable_appearance('icons/effects/steam.dmi', "[use_large_steam_sprite ? "steam_triple" : "steam_single"]", ABOVE_OBJ_LAYER) diff --git a/code/datums/elements/food/grilled_item.dm b/code/datums/elements/food/grilled_item.dm new file mode 100644 index 00000000000..b1386bcb5b4 --- /dev/null +++ b/code/datums/elements/food/grilled_item.dm @@ -0,0 +1,31 @@ +/// Items grilled through the grill. +/datum/element/grilled_item + +/datum/element/grilled_item/Attach(datum/target, grill_time) + . = ..() + if(!isatom(target)) + return ELEMENT_INCOMPATIBLE + + var/atom/this_food = target + + switch(grill_time) //no 0-20 to prevent spam + if(20 to 30) + this_food.name = "lightly-grilled [this_food.name]" + this_food.desc += " It's been lightly grilled." + + if(30 to 80) + this_food.name = "grilled [this_food.name]" + this_food.desc += " It's been grilled." + + if(80 to 100) + this_food.name = "heavily grilled [this_food.name]" + this_food.desc += " It's been heavily grilled." + + if(100 to INFINITY) //grill marks reach max alpha + this_food.name = "Powerfully Grilled [this_food.name]" + this_food.desc = "A [this_food.name]. Reminds you of your wife, wait, no, it's prettier!" + + if(grill_time > 20) + ADD_TRAIT(this_food, TRAIT_FOOD_GRILLED, "boomers") + if(grill_time > 30) + this_food.AddComponent(/datum/component/edible, foodtypes = FRIED) diff --git a/code/datums/elements/food/microwavable.dm b/code/datums/elements/food/microwavable.dm new file mode 100644 index 00000000000..d5868006fb3 --- /dev/null +++ b/code/datums/elements/food/microwavable.dm @@ -0,0 +1,69 @@ +/// Atoms that can be microwaved from one type to another. +/datum/element/microwavable + element_flags = ELEMENT_BESPOKE + id_arg_index = 2 + /// The typepath we default to if we were passed no microwave result + var/atom/default_typepath = /obj/item/food/badrecipe + /// Resulting atom typepath on a completed microwave. + var/atom/result_typepath + +/datum/element/microwavable/Attach(datum/target, microwave_type) + . = ..() + if(!isitem(target)) + return ELEMENT_INCOMPATIBLE + + result_typepath = microwave_type || default_typepath + + RegisterSignal(target, COMSIG_ITEM_MICROWAVE_ACT, .proc/on_microwaved) + + if(!ispath(result_typepath, default_typepath)) + RegisterSignal(target, COMSIG_PARENT_EXAMINE, .proc/on_examine) + +/datum/element/microwavable/Detach(datum/source) + UnregisterSignal(source, list(COMSIG_ITEM_MICROWAVE_ACT, COMSIG_PARENT_EXAMINE)) + return ..() + +/** + * Signal proc for [COMSIG_ITEM_MICROWAVE_ACT]. + * Handles the actual microwaving part. + */ +/datum/element/microwavable/proc/on_microwaved(atom/source, obj/machinery/microwave/used_microwave, mob/microwaver) + SIGNAL_HANDLER + + var/atom/result + var/turf/result_loc = get_turf(used_microwave || source) + if(isstack(source)) + var/obj/item/stack/stack_source = source + result = new result_typepath(result_loc, stack_source.amount) + + else + result = new result_typepath(result_loc) + + var/efficiency = istype(used_microwave) ? used_microwave.efficiency : 1 + SEND_SIGNAL(result, COMSIG_ITEM_MICROWAVE_COOKED, source, efficiency) + + if(IS_EDIBLE(result)) + if(microwaver) + ADD_TRAIT(result, TRAIT_FOOD_CHEF_MADE, REF(microwaver)) + + result.reagents?.multiply_reagents(efficiency * CRAFTED_FOOD_BASE_REAGENT_MODIFIER) + source.reagents?.trans_to(result, source.reagents.total_volume) + + SSblackbox.record_feedback("tally", "food_made", 1, result.type) + + qdel(source) + + var/recipe_result = COMPONENT_MICROWAVE_SUCCESS + if(istype(result, default_typepath)) + recipe_result |= COMPONENT_MICROWAVE_BAD_RECIPE + + return recipe_result + +/** + * Signal proc for [COMSIG_PARENT_EXAMINE]. + * Lets examiners know we can be microwaved if we're not the default mess type + */ +/datum/element/microwavable/proc/on_examine(atom/source, mob/user, list/examine_list) + SIGNAL_HANDLER + + examine_list += span_notice("[source] could be microwaved into \a [initial(result_typepath.name)].") diff --git a/code/datums/materials/meat.dm b/code/datums/materials/meat.dm index a2f2a968a6b..9403021e024 100644 --- a/code/datums/materials/meat.dm +++ b/code/datums/materials/meat.dm @@ -30,7 +30,11 @@ /datum/material/meat/proc/make_edible(atom/source, amount, material_flags) var/nutriment_count = 3 * (amount / MINERAL_MATERIAL_AMOUNT) var/oil_count = 2 * (amount / MINERAL_MATERIAL_AMOUNT) - source.AddComponent(/datum/component/edible, list(/datum/reagent/consumable/nutriment = nutriment_count, /datum/reagent/consumable/cooking_oil = oil_count), null, RAW | MEAT | GROSS, null, 30, list("Fleshy")) + source.AddComponent(/datum/component/edible, \ + initial_reagents = list(/datum/reagent/consumable/nutriment = nutriment_count, /datum/reagent/consumable/cooking_oil = oil_count), \ + foodtypes = RAW | MEAT | GROSS, \ + eat_time = 3 SECONDS, \ + tastes = list("Fleshy")) /datum/material/meat/mob_meat diff --git a/code/datums/materials/pizza.dm b/code/datums/materials/pizza.dm index 35f311dcf50..8350a433cc1 100644 --- a/code/datums/materials/pizza.dm +++ b/code/datums/materials/pizza.dm @@ -28,4 +28,8 @@ /datum/material/pizza/proc/make_edible(atom/source, amount, material_flags) var/nutriment_count = 3 * (amount / MINERAL_MATERIAL_AMOUNT) var/oil_count = 2 * (amount / MINERAL_MATERIAL_AMOUNT) - source.AddComponent(/datum/component/edible, list(/datum/reagent/consumable/nutriment = nutriment_count, /datum/reagent/consumable/cooking_oil = oil_count), null, GRAIN | MEAT | DAIRY | VEGETABLES, null, 30, list("crust", "tomato", "cheese", "meat")) + source.AddComponent(/datum/component/edible, \ + initial_reagents = list(/datum/reagent/consumable/nutriment = nutriment_count, /datum/reagent/consumable/cooking_oil = oil_count), \ + foodtypes = GRAIN | MEAT | DAIRY | VEGETABLES, \ + eat_time = 3 SECONDS, \ + tastes = list("crust", "tomato", "cheese", "meat")) diff --git a/code/datums/mood_events/generic_positive_events.dm b/code/datums/mood_events/generic_positive_events.dm index 9d400e8a1a8..10aca583128 100644 --- a/code/datums/mood_events/generic_positive_events.dm +++ b/code/datums/mood_events/generic_positive_events.dm @@ -278,6 +278,14 @@ mood_change = 10 timeout = 5 MINUTES +/datum/mood_event/love_reagent + description = "This food reminds me of the good ol' days." + mood_change = 5 + +/datum/mood_event/love_reagent/add_effects(duration) + if(isnum(duration)) + timeout = duration + /datum/mood_event/won_52_card_pickup description = "HA! That loser will be picking cards up for a long time!" mood_change = 3 diff --git a/code/game/atoms.dm b/code/game/atoms.dm index f14ed5c3add..1f23358a899 100644 --- a/code/game/atoms.dm +++ b/code/game/atoms.dm @@ -1500,7 +1500,6 @@ if(i > 1) created_atom.pixel_x += rand(-8,8) created_atom.pixel_y += rand(-8,8) - SEND_SIGNAL(created_atom, COMSIG_ATOM_CREATEDBY_PROCESSING, src, chosen_option) created_atom.OnCreatedFromProcessing(user, process_item, chosen_option, src) to_chat(user, span_notice("You manage to create [chosen_option[TOOL_PROCESSING_AMOUNT]] [initial(atom_to_create.gender) == PLURAL ? "[initial(atom_to_create.name)]" : "[initial(atom_to_create.name)]\s"] from [src].")) created_atoms.Add(created_atom) @@ -1512,8 +1511,11 @@ qdel(src) return -/atom/proc/OnCreatedFromProcessing(mob/living/user, obj/item/food, list/chosen_option, atom/original_atom) - return +/atom/proc/OnCreatedFromProcessing(mob/living/user, obj/item/work_tool, list/chosen_option, atom/original_atom) + SHOULD_CALL_PARENT(TRUE) + + SEND_SIGNAL(src, COMSIG_ATOM_CREATEDBY_PROCESSING, original_atom, chosen_option) + ADD_TRAIT(src, TRAIT_FOOD_CHEF_MADE, REF(user)) //! Tool-specific behavior procs. /// diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm index 34dd0ea2535..36655167cdf 100644 --- a/code/game/objects/items.dm +++ b/code/game/objects/items.dm @@ -932,11 +932,11 @@ GLOBAL_DATUM_INIT(fire_overlay, /mutable_appearance, mutable_appearance('icons/e MO.desc = "Looks like this was \an [src] some time ago." ..() -/obj/item/proc/microwave_act(obj/machinery/microwave/M) - if(SEND_SIGNAL(src, COMSIG_ITEM_MICROWAVE_ACT, M) & COMPONENT_SUCCESFUL_MICROWAVE) - return TRUE - if(istype(M) && M.dirty < 100) - M.dirty++ +/obj/item/proc/microwave_act(obj/machinery/microwave/microwave_source, mob/microwaver) + SHOULD_CALL_PARENT(TRUE) + + return SEND_SIGNAL(src, COMSIG_ITEM_MICROWAVE_ACT, microwave_source, microwaver) + /obj/item/proc/grind_requirements(obj/machinery/reagentgrinder/R) //Used to check for extra requirements for grinding an object return TRUE @@ -1481,11 +1481,6 @@ GLOBAL_DATUM_INIT(fire_overlay, /mutable_appearance, mutable_appearance('icons/e /obj/item/proc/set_painting_tool_color(chosen_color) SEND_SIGNAL(src, COMSIG_PAINTING_TOOL_SET_COLOR, chosen_color) -/// Triggered from a silver slime reaction, sends a signal for the listener in component/edible -/obj/item/proc/mark_silver_slime_reaction() - SIGNAL_HANDLER - SEND_SIGNAL(src, COMSIG_FOOD_SILVER_SPAWNED) - /** * Returns null if this object cannot be used to interact with physical writing mediums such as paper. * Returns a list of key attributes for this object interacting with paper otherwise. diff --git a/code/game/objects/items/dice.dm b/code/game/objects/items/dice.dm index 1b1efab695e..62915dfc600 100644 --- a/code/game/objects/items/dice.dm +++ b/code/game/objects/items/dice.dm @@ -242,11 +242,12 @@ . = ..() . += "[icon_state]-[result]" -/obj/item/dice/microwave_act(obj/machinery/microwave/M) +/obj/item/dice/microwave_act(obj/machinery/microwave/microwave_source, mob/microwaver) if(microwave_riggable) rigged = DICE_BASICALLY_RIGGED rigged_value = result - ..(M) + + return ..() | COMPONENT_MICROWAVE_SUCCESS // Die of fate stuff /obj/item/dice/d20/fate diff --git a/code/game/objects/items/food/_food.dm b/code/game/objects/items/food/_food.dm index add02d616bd..b7fae31b073 100644 --- a/code/game/objects/items/food/_food.dm +++ b/code/game/objects/items/food/_food.dm @@ -26,8 +26,6 @@ var/list/eatverbs ///How much reagents per bite var/bite_consumption - ///What you get if you microwave the food. Use baking for raw things, use microwaving for already cooked things - var/microwaved_type ///Type of atom thats spawned after eating this item var/trash_type ///How much junkiness this food has? God I should remove junkiness soon @@ -65,14 +63,9 @@ MakeGrillable() MakeDecompose(mapload) MakeBakeable() + make_microwavable() ADD_TRAIT(src, FISHING_BAIT_TRAIT, INNATE_TRAIT) -/obj/item/food/examine(mob/user) - . = ..() - if(foodtypes) - var/list/types = bitfield_to_list(foodtypes, FOOD_FLAGS) - . += span_notice("It is [lowertext(english_list(types))].") - ///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/MakeEdible() AddComponent(/datum/component/edible,\ @@ -84,7 +77,6 @@ tastes = tastes,\ eatverbs = eatverbs,\ bite_consumption = bite_consumption,\ - microwaved_type = microwaved_type,\ junkiness = junkiness) @@ -104,6 +96,10 @@ AddComponent(/datum/component/bakeable, /obj/item/food/badrecipe, rand(25 SECONDS, 40 SECONDS), FALSE) return +/// This proc handles the microwave component. Overwrite if you want special microwave results. +/// By default, all food is microwavable. However, they will be microwaved into a bad recipe (burnt mess). +/obj/item/food/proc/make_microwavable() + AddElement(/datum/element/microwavable) ///This proc handles trash components, overwrite this if you want the object to spawn trash /obj/item/food/proc/MakeLeaveTrash() @@ -116,8 +112,3 @@ /obj/item/food/proc/MakeDecompose(mapload) if(!preserved_food) AddComponent(/datum/component/decomposition, mapload, decomp_req_handle, decomp_flags = foodtypes, decomp_result = decomp_type, ant_attracting = ant_attracting, custom_time = decomposition_time) - -/obj/item/food/mark_silver_slime_reaction() - //Adds this flag to prevent it from exporting for profit from cargo - food_flags |= FOOD_SILVER_SPAWNED - return ..() diff --git a/code/game/objects/items/food/cake.dm b/code/game/objects/items/food/cake.dm index 3e73ea190ac..6a7e0a28ead 100644 --- a/code/game/objects/items/food/cake.dm +++ b/code/game/objects/items/food/cake.dm @@ -185,9 +185,8 @@ /obj/item/food/cake/birthday/MakeProcessable() AddElement(/datum/element/processable, TOOL_KNIFE, /obj/item/food/cakeslice/birthday, 5, 3 SECONDS, table_required = TRUE) -/obj/item/food/cake/birthday/microwave_act(obj/machinery/microwave/microwave) //super sekrit club - new /obj/item/clothing/head/utility/hardhat/cakehat(get_turf(src)) - qdel(src) +/obj/item/food/cake/birthday/make_microwavable() // super sekrit club + AddElement(/datum/element/microwavable, /obj/item/clothing/head/utility/hardhat/cakehat) /obj/item/food/cakeslice/birthday name = "birthday cake slice" @@ -209,6 +208,9 @@ /obj/item/food/cake/birthday/energy/MakeProcessable() AddElement(/datum/element/processable, TOOL_KNIFE, /obj/item/food/cakeslice/birthday/energy, 5, 3 SECONDS, table_required = TRUE) +/obj/item/food/cake/birthday/energy/make_microwavable() //super sekriter club + AddElement(/datum/element/microwavable, /obj/item/clothing/head/utility/hardhat/cakehat/energycake) + /obj/item/food/cake/birthday/energy/proc/energy_bite(mob/living/user) to_chat(user, "As you eat the cake, you accidentally hurt yourself on the embedded energy sword!") user.apply_damage(30, BRUTE, BODY_ZONE_HEAD) @@ -220,10 +222,6 @@ return energy_bite(target_mob, user) -/obj/item/food/cake/birthday/energy/microwave_act(obj/machinery/microwave/M) //super sekriter club - new /obj/item/clothing/head/utility/hardhat/cakehat/energycake(get_turf(src)) - qdel(src) - /obj/item/food/cakeslice/birthday/energy name = "energy cake slice" desc = "For the traitor on the go." @@ -481,6 +479,12 @@ /obj/item/food/cake/pavlova/MakeProcessable() AddElement(/datum/element/processable, TOOL_KNIFE, /obj/item/food/cakeslice/pavlova, 5, 3 SECONDS, table_required = TRUE) +/obj/item/food/cake/pavlova/nuts + foodtypes = NUTS | FRUIT | SUGAR + +/obj/item/food/cake/pavlova/nuts/MakeProcessable() + AddElement(/datum/element/processable, TOOL_KNIFE, /obj/item/food/cakeslice/pavlova/nuts, 5, 30, table_required = TRUE) + /obj/item/food/cakeslice/pavlova name = "pavlova slice" desc = "A cracked slice of pavlova stacked with berries. You even got it sliced in such a way that more berries ended up on your slice, how delightfully devilish." diff --git a/code/game/objects/items/food/cheese.dm b/code/game/objects/items/food/cheese.dm index 1d3b3145515..3084f4e9c25 100644 --- a/code/game/objects/items/food/cheese.dm +++ b/code/game/objects/items/food/cheese.dm @@ -61,13 +61,15 @@ name = "curd cheese" desc = "Known by many names throughout human cuisine, curd cheese is useful for a wide variety of dishes." icon_state = "curd_cheese" - microwaved_type = /obj/item/food/cheese/cheese_curds food_reagents = list(/datum/reagent/consumable/nutriment/protein = 3, /datum/reagent/consumable/cream = 1) tastes = list("cream" = 1, "cheese" = 1) foodtypes = DAIRY w_class = WEIGHT_CLASS_SMALL rat_heal = 35 +/obj/item/food/curd_cheese/make_microwavable() + AddElement(/datum/element/microwavable, /obj/item/food/cheese/cheese_curds) + /obj/item/food/cheese/cheese_curds name = "cheese curds" desc = "Not to be mistaken for curd cheese. Tasty deep fried." diff --git a/code/game/objects/items/food/deepfried.dm b/code/game/objects/items/food/deepfried.dm index da83bf92aaf..52d75d4878f 100644 --- a/code/game/objects/items/food/deepfried.dm +++ b/code/game/objects/items/food/deepfried.dm @@ -6,17 +6,8 @@ bite_consumption = 2 /obj/item/food/deepfryholder/MakeEdible() - AddComponent(/datum/component/edible,\ - initial_reagents = food_reagents,\ - food_flags = food_flags,\ - foodtypes = foodtypes,\ - volume = max_volume,\ - eat_time = eat_time,\ - tastes = tastes,\ - eatverbs = eatverbs,\ - bite_consumption = bite_consumption,\ - on_consume = CALLBACK(src, .proc/On_Consume)) - + . = ..() + AddComponent(/datum/component/edible, on_consume = CALLBACK(src, .proc/On_Consume)) /obj/item/food/deepfryholder/Initialize(mapload, obj/item/fried) if(!fried) diff --git a/code/game/objects/items/food/donkpocket.dm b/code/game/objects/items/food/donkpocket.dm index 73e9c219afa..c4cd66d18cb 100644 --- a/code/game/objects/items/food/donkpocket.dm +++ b/code/game/objects/items/food/donkpocket.dm @@ -5,27 +5,35 @@ desc = "The food of choice for the seasoned traitor." icon_state = "donkpocket" food_reagents = list(/datum/reagent/consumable/nutriment = 3, /datum/reagent/consumable/nutriment/protein = 2) - microwaved_type = /obj/item/food/donkpocket/warm tastes = list("meat" = 2, "dough" = 2, "laziness" = 1) foodtypes = GRAIN food_flags = FOOD_FINGER_FOOD w_class = WEIGHT_CLASS_SMALL -//donk pockets cook quick... try not to burn them for using an unoptimal tool + /// What type of donk pocket we're warmed into via baking or microwaving. + var/warm_type = /obj/item/food/donkpocket/warm + /// The lower end for how long it takes to bake + var/baking_time_short = 25 SECONDS + /// The upper end for how long it takes to bake + var/baking_time_long = 30 SECONDS + /obj/item/food/donkpocket/MakeBakeable() - AddComponent(/datum/component/bakeable, microwaved_type, rand(25 SECONDS, 30 SECONDS), TRUE, TRUE) + AddComponent(/datum/component/bakeable, warm_type, rand(baking_time_short, baking_time_long), TRUE, TRUE) + +/obj/item/food/donkpocket/make_microwavable() + AddElement(/datum/element/microwavable, warm_type) /obj/item/food/donkpocket/warm name = "warm Donk-pocket" desc = "The heated food of choice for the seasoned traitor." food_reagents = list(/datum/reagent/consumable/nutriment = 3, /datum/reagent/consumable/nutriment/protein = 2, /datum/reagent/medicine/omnizine = 6) - microwaved_type = null tastes = list("meat" = 2, "dough" = 2, "laziness" = 1) foodtypes = GRAIN -///Override for fast-burning food -/obj/item/food/donkpocket/warm/MakeBakeable() - AddComponent(/datum/component/bakeable, /obj/item/food/badrecipe, rand(10 SECONDS, 15 SECONDS), FALSE) + // Warmed donk pockets will burn if you leave them in the oven or microwave. + warm_type = /obj/item/food/badrecipe + baking_time_short = 10 SECONDS + baking_time_long = 15 SECONDS /obj/item/food/dankpocket name = "\improper Dank-pocket" @@ -40,10 +48,11 @@ desc = "The classic snack food, now with a heat-activated spicy flair." icon_state = "donkpocketspicy" food_reagents = list(/datum/reagent/consumable/nutriment = 3, /datum/reagent/consumable/nutriment/protein = 2, /datum/reagent/consumable/capsaicin = 2) - microwaved_type = /obj/item/food/donkpocket/warm/spicy tastes = list("meat" = 2, "dough" = 2, "spice" = 1) foodtypes = GRAIN + warm_type = /obj/item/food/donkpocket/warm/spicy + /obj/item/food/donkpocket/warm/spicy name = "warm Spicy-pocket" desc = "The classic snack food, now maybe a bit too spicy." @@ -57,10 +66,11 @@ desc = "An east-asian take on the classic stationside snack." icon_state = "donkpocketteriyaki" food_reagents = list(/datum/reagent/consumable/nutriment = 3, /datum/reagent/consumable/nutriment/protein = 2, /datum/reagent/consumable/soysauce = 2) - microwaved_type = /obj/item/food/donkpocket/warm/teriyaki tastes = list("meat" = 2, "dough" = 2, "soy sauce" = 2) foodtypes = GRAIN + warm_type = /obj/item/food/donkpocket/warm/teriyaki + /obj/item/food/donkpocket/warm/teriyaki name = "warm Teriyaki-pocket" desc = "An east-asian take on the classic stationside snack, now steamy and warm." @@ -74,10 +84,11 @@ desc = "Delicious, cheesy and surprisingly filling." icon_state = "donkpocketpizza" food_reagents = list(/datum/reagent/consumable/nutriment = 3, /datum/reagent/consumable/nutriment/protein = 2, /datum/reagent/consumable/tomatojuice = 2) - microwaved_type = /obj/item/food/donkpocket/warm/pizza tastes = list("meat" = 2, "dough" = 2, "cheese"= 2) foodtypes = GRAIN + warm_type = /obj/item/food/donkpocket/warm/pizza + /obj/item/food/donkpocket/warm/pizza name = "warm Pizza-pocket" desc = "Delicious, cheesy, and even better when hot." @@ -91,10 +102,11 @@ desc = "The award-winning donk-pocket that won the hearts of clowns and humans alike." icon_state = "donkpocketbanana" food_reagents = list(/datum/reagent/consumable/nutriment = 4, /datum/reagent/consumable/banana = 4) - microwaved_type = /obj/item/food/donkpocket/warm/honk tastes = list("banana" = 2, "dough" = 2, "children's antibiotics" = 1) foodtypes = GRAIN + warm_type = /obj/item/food/donkpocket/warm/honk + /obj/item/food/donkpocket/warm/honk name = "warm Honk-pocket" desc = "The award-winning donk-pocket, now warm and toasty." @@ -108,10 +120,11 @@ desc = "A relentlessly sweet donk-pocket first created for use in Operation Dessert Storm." icon_state = "donkpocketberry" food_reagents = list(/datum/reagent/consumable/nutriment = 4, /datum/reagent/consumable/berryjuice = 3) - microwaved_type = /obj/item/food/donkpocket/warm/berry tastes = list("dough" = 2, "jam" = 2) foodtypes = GRAIN + warm_type = /obj/item/food/donkpocket/warm/berry + /obj/item/food/donkpocket/warm/berry name = "warm Berry-pocket" desc = "A relentlessly sweet donk-pocket, now warm and delicious." @@ -125,10 +138,11 @@ desc = "The choice to use real gondola meat in the recipe is controversial, to say the least." //Only a monster would craft this. icon_state = "donkpocketgondola" food_reagents = list(/datum/reagent/consumable/nutriment = 3, /datum/reagent/consumable/nutriment/protein = 2, /datum/reagent/gondola_mutation_toxin = 5) - microwaved_type = /obj/item/food/donkpocket/warm/gondola tastes = list("meat" = 2, "dough" = 2, "inner peace" = 1) foodtypes = GRAIN + warm_type = /obj/item/food/donkpocket/warm/gondola + /obj/item/food/donkpocket/warm/gondola name = "warm Gondola-pocket" desc = "The choice to use real gondola meat in the recipe is controversial, to say the least." diff --git a/code/game/objects/items/food/donuts.dm b/code/game/objects/items/food/donuts.dm index 1ce9b6e6e76..1e90edd3fd3 100644 --- a/code/game/objects/items/food/donuts.dm +++ b/code/game/objects/items/food/donuts.dm @@ -24,18 +24,8 @@ ///Override for checkliked callback /obj/item/food/donut/MakeEdible() - AddComponent(/datum/component/edible,\ - initial_reagents = food_reagents,\ - food_flags = food_flags,\ - foodtypes = foodtypes,\ - volume = max_volume,\ - eat_time = eat_time,\ - tastes = tastes,\ - eatverbs = eatverbs,\ - bite_consumption = bite_consumption,\ - microwaved_type = microwaved_type,\ - junkiness = junkiness,\ - check_liked = CALLBACK(src, .proc/check_liked)) + . = ..() + AddComponent(/datum/component/edible, check_liked = CALLBACK(src, .proc/check_liked)) /obj/item/food/donut/proc/decorate_donut() if(is_decorated || !decorated_icon) diff --git a/code/game/objects/items/food/egg.dm b/code/game/objects/items/food/egg.dm index 4c3a8e8547f..962276e1bd6 100644 --- a/code/game/objects/items/food/egg.dm +++ b/code/game/objects/items/food/egg.dm @@ -19,7 +19,6 @@ icon_state = "egg" inhand_icon_state = "egg" food_reagents = list(/datum/reagent/consumable/eggyolk = 2, /datum/reagent/consumable/eggwhite = 4) - microwaved_type = /obj/item/food/boiledegg foodtypes = MEAT | RAW w_class = WEIGHT_CLASS_TINY ant_attracting = FALSE @@ -27,12 +26,17 @@ decomp_req_handle = TRUE //so laid eggs can actually become chickens var/static/chick_count = 0 //I copied this from the chicken_count (note the "en" in there) variable from chicken code. +/obj/item/food/egg/make_microwavable() + AddElement(/datum/element/microwavable, /obj/item/food/boiledegg) + /obj/item/food/egg/rotten food_reagents = list(/datum/reagent/consumable/eggrot = 10, /datum/reagent/consumable/mold = 10) - microwaved_type = /obj/item/food/boiledegg/rotten foodtypes = GROSS preserved_food = TRUE +/obj/item/food/egg/rotten/make_microwavable() + AddElement(/datum/element/microwavable, /obj/item/food/boiledegg/rotten) + /obj/item/food/egg/gland desc = "An egg! It looks weird..." diff --git a/code/game/objects/items/food/frozen.dm b/code/game/objects/items/food/frozen.dm index 6743d59f2bb..f74e7a16d01 100644 --- a/code/game/objects/items/food/frozen.dm +++ b/code/game/objects/items/food/frozen.dm @@ -239,19 +239,8 @@ update_icon() // make sure the popsicle overlay is primed so it's not just a stick until you start eating it /obj/item/food/popsicle/MakeEdible() - AddComponent(/datum/component/edible,\ - initial_reagents = food_reagents,\ - food_flags = food_flags,\ - foodtypes = foodtypes,\ - volume = max_volume,\ - eat_time = eat_time,\ - tastes = tastes,\ - eatverbs = eatverbs,\ - bite_consumption = bite_consumption,\ - microwaved_type = microwaved_type,\ - junkiness = junkiness,\ - after_eat = CALLBACK(src, .proc/after_bite)) - + . = ..() + AddComponent(/datum/component/edible, after_eat = CALLBACK(src, .proc/after_bite)) /obj/item/food/popsicle/update_overlays() . = ..() diff --git a/code/game/objects/items/food/meatslab.dm b/code/game/objects/items/food/meatslab.dm index b90f07e4523..1b4fcdcbdc2 100644 --- a/code/game/objects/items/food/meatslab.dm +++ b/code/game/objects/items/food/meatslab.dm @@ -391,11 +391,11 @@ /obj/item/food/meat/steak/Initialize(mapload) . = ..() - RegisterSignal(src, COMSIG_ITEM_MICROWAVE_COOKED, .proc/OnMicrowaveCooked) + RegisterSignal(src, COMSIG_ITEM_MICROWAVE_COOKED, .proc/on_microwave_cooked) - -/obj/item/food/meat/steak/proc/OnMicrowaveCooked(datum/source, obj/item/source_item, cooking_efficiency = 1) +/obj/item/food/meat/steak/proc/on_microwave_cooked(datum/source, atom/source_item, cooking_efficiency = 1) SIGNAL_HANDLER + name = "[source_item.name] steak" /obj/item/food/meat/steak/plain @@ -406,16 +406,18 @@ foodtypes = MEAT | GORE ///Make sure the steak has the correct name -/obj/item/food/meat/steak/plain/human/OnMicrowaveCooked(datum/source, obj/item/source_item, cooking_efficiency = 1) +/obj/item/food/meat/steak/plain/human/on_microwave_cooked(datum/source, atom/source_item, cooking_efficiency = 1) . = ..() - if(istype(source_item, /obj/item/food/meat)) - var/obj/item/food/meat/origin_meat = source_item - subjectname = origin_meat.subjectname - subjectjob = origin_meat.subjectjob - if(subjectname) - name = "[origin_meat.subjectname] meatsteak" - else if(subjectjob) - name = "[origin_meat.subjectjob] meatsteak" + if(!istype(source_item, /obj/item/food/meat)) + return + + var/obj/item/food/meat/origin_meat = source_item + subjectname = origin_meat.subjectname + subjectjob = origin_meat.subjectjob + if(subjectname) + name = "[origin_meat.subjectname] meatsteak" + else if(subjectjob) + name = "[origin_meat.subjectjob] meatsteak" /obj/item/food/meat/steak/killertomato @@ -498,8 +500,8 @@ /obj/item/food/meat/rawcutlet/MakeGrillable() AddComponent(/datum/component/grillable, /obj/item/food/meat/cutlet/plain, rand(35 SECONDS, 50 SECONDS), TRUE, TRUE) -/obj/item/food/meat/rawcutlet/OnCreatedFromProcessing(mob/living/user, obj/item/item, list/chosen_option, atom/original_atom) - ..() +/obj/item/food/meat/rawcutlet/OnCreatedFromProcessing(mob/living/user, obj/item/work_tool, list/chosen_option, atom/original_atom) + . = ..() if(!istype(original_atom, /obj/item/food/meat/slab)) return var/obj/item/food/meat/slab/original_slab = original_atom @@ -602,14 +604,17 @@ /obj/item/food/meat/cutlet/Initialize(mapload) . = ..() - RegisterSignal(src, COMSIG_ITEM_MICROWAVE_COOKED, .proc/OnMicrowaveCooked) + RegisterSignal(src, COMSIG_ITEM_MICROWAVE_COOKED, .proc/on_microwave_cooked) ///This proc handles setting up the correct meat name for the cutlet, this should definitely be changed with the food rework. -/obj/item/food/meat/cutlet/proc/OnMicrowaveCooked(datum/source, atom/source_item, cooking_efficiency) +/obj/item/food/meat/cutlet/proc/on_microwave_cooked(datum/source, atom/source_item, cooking_efficiency) SIGNAL_HANDLER - if(istype(source_item, /obj/item/food/meat/rawcutlet)) - var/obj/item/food/meat/rawcutlet/original_cutlet = source_item - name = "[original_cutlet.meat_type] cutlet" + + if(!istype(source_item, /obj/item/food/meat/rawcutlet)) + return + + var/obj/item/food/meat/rawcutlet/original_cutlet = source_item + name = "[original_cutlet.meat_type] cutlet" /obj/item/food/meat/cutlet/plain @@ -617,14 +622,16 @@ tastes = list("tender meat" = 1) foodtypes = MEAT | GORE -/obj/item/food/meat/cutlet/plain/human/OnMicrowaveCooked(datum/source, atom/source_item, cooking_efficiency) +/obj/item/food/meat/cutlet/plain/human/on_microwave_cooked(datum/source, atom/source_item, cooking_efficiency) . = ..() - if(istype(source_item, /obj/item/food/meat)) - var/obj/item/food/meat/origin_meat = source_item - if(subjectname) - name = "[origin_meat.subjectname] [initial(name)]" - else if(subjectjob) - name = "[origin_meat.subjectjob] [initial(name)]" + if(!istype(source_item, /obj/item/food/meat)) + return + + var/obj/item/food/meat/origin_meat = source_item + if(subjectname) + name = "[origin_meat.subjectname] [initial(name)]" + else if(subjectjob) + name = "[origin_meat.subjectjob] [initial(name)]" /obj/item/food/meat/cutlet/killertomato name = "killer tomato cutlet" diff --git a/code/game/objects/items/food/misc.dm b/code/game/objects/items/food/misc.dm index eb505e0f3bb..6b94d320678 100644 --- a/code/game/objects/items/food/misc.dm +++ b/code/game/objects/items/food/misc.dm @@ -169,7 +169,7 @@ /obj/item/food/badrecipe/Initialize(mapload) . = ..() - RegisterSignal(src, COMSIG_ITEM_GRILLED, .proc/OnGrill) + RegisterSignal(src, COMSIG_ITEM_GRILL_PROCESS, .proc/OnGrill) /obj/item/food/badrecipe/moldy name = "moldy mess" @@ -467,18 +467,8 @@ hallucinate(loc) /obj/item/food/bubblegum/bubblegum/MakeEdible() - AddComponent(/datum/component/edible,\ - initial_reagents = food_reagents,\ - food_flags = food_flags,\ - foodtypes = foodtypes,\ - volume = max_volume,\ - eat_time = eat_time,\ - tastes = tastes,\ - eatverbs = eatverbs,\ - bite_consumption = bite_consumption,\ - microwaved_type = microwaved_type,\ - junkiness = junkiness,\ - on_consume = CALLBACK(src, .proc/OnConsume)) + . = ..() + AddComponent(/datum/component/edible, on_consume = CALLBACK(src, .proc/OnConsume)) /obj/item/food/bubblegum/bubblegum/proc/OnConsume(mob/living/eater, mob/living/feeder) if(iscarbon(eater)) @@ -689,18 +679,8 @@ ///Override for checkliked callback /obj/item/food/rationpack/MakeEdible() - AddComponent(/datum/component/edible,\ - initial_reagents = food_reagents,\ - food_flags = food_flags,\ - foodtypes = foodtypes,\ - volume = max_volume,\ - eat_time = eat_time,\ - tastes = tastes,\ - eatverbs = eatverbs,\ - bite_consumption = bite_consumption,\ - microwaved_type = microwaved_type,\ - junkiness = junkiness,\ - check_liked = CALLBACK(src, .proc/check_liked)) + . = ..() + AddComponent(/datum/component/edible, check_liked = CALLBACK(src, .proc/check_liked)) /obj/item/food/rationpack/proc/check_liked(fraction, mob/mob) //Nobody likes rationpacks. Nobody. return FOOD_DISLIKED @@ -804,12 +784,17 @@ icon_state = "ready_donk" trash_type = /obj/item/trash/ready_donk food_reagents = list(/datum/reagent/consumable/nutriment = 5) - microwaved_type = /obj/item/food/ready_donk/warm tastes = list("food?" = 2, "laziness" = 1) foodtypes = MEAT | JUNKFOOD food_flags = FOOD_FINGER_FOOD w_class = WEIGHT_CLASS_SMALL + /// What type of ready-donk are we warmed into? + var/warm_type = /obj/item/food/ready_donk/warm + +/obj/item/food/ready_donk/make_microwavable() + AddElement(/datum/element/microwavable, warm_type) + /obj/item/food/ready_donk/examine_more(mob/user) . = ..() . += span_notice("You browse the back of the box...") @@ -823,16 +808,19 @@ desc = "A quick Donk-dinner, now with flavour! And it's even hot!" icon_state = "ready_donk_warm" food_reagents = list(/datum/reagent/consumable/nutriment = 5, /datum/reagent/medicine/omnizine = 3) - microwaved_type = null tastes = list("food?" = 2, "laziness" = 1) + // Don't burn your warn ready donks. + warm_type = /obj/item/food/badrecipe + /obj/item/food/ready_donk/mac_n_cheese name = "\improper Ready-Donk: Donk-a-Roni" desc = "Neon-orange mac n' cheese in seconds!" - microwaved_type = /obj/item/food/ready_donk/warm/mac_n_cheese tastes = list("cheesy pasta" = 2, "laziness" = 1) foodtypes = GRAIN | DAIRY | JUNKFOOD + warm_type = /obj/item/food/ready_donk/warm/mac_n_cheese + /obj/item/food/ready_donk/warm/mac_n_cheese name = "warm Ready-Donk: Donk-a-Roni" desc = "Neon-orange mac n' cheese, ready to eat!" @@ -843,10 +831,11 @@ /obj/item/food/ready_donk/donkhiladas name = "\improper Ready-Donk: Donkhiladas" desc = "Donk Co's signature Donkhiladas with Donk sauce, for an 'authentic' taste of Mexico." - microwaved_type = /obj/item/food/ready_donk/warm/donkhiladas tastes = list("enchiladas" = 2, "laziness" = 1) foodtypes = GRAIN | DAIRY | MEAT | VEGETABLES | JUNKFOOD + warm_type = /obj/item/food/ready_donk/warm/donkhiladas + /obj/item/food/ready_donk/warm/donkhiladas name = "warm Ready-Donk: Donkhiladas" desc = "Donk Co's signature Donkhiladas with Donk sauce, served as hot as the Mexican sun." diff --git a/code/game/objects/items/food/salad.dm b/code/game/objects/items/food/salad.dm index 6d8c187bb10..f5ce05407f4 100644 --- a/code/game/objects/items/food/salad.dm +++ b/code/game/objects/items/food/salad.dm @@ -63,11 +63,13 @@ name = "ricebowl" desc = "A bowl of raw rice." icon_state = "ricebowl" - microwaved_type = /obj/item/food/salad/boiledrice food_reagents = list(/datum/reagent/consumable/nutriment = 4) tastes = list("rice" = 1) foodtypes = GRAIN | RAW +/obj/item/food/salad/ricebowl/make_microwavable() + AddElement(/datum/element/microwavable, /obj/item/food/salad/boiledrice) + /obj/item/food/salad/boiledrice name = "boiled rice" desc = "A warm bowl of rice." diff --git a/code/game/objects/items/food/snacks.dm b/code/game/objects/items/food/snacks.dm index acb0ad1eef9..30a4b45e427 100644 --- a/code/game/objects/items/food/snacks.dm +++ b/code/game/objects/items/food/snacks.dm @@ -30,18 +30,8 @@ var/revelation = FALSE /obj/item/food/candy/bronx/MakeEdible() - AddComponent(/datum/component/edible,\ - initial_reagents = food_reagents,\ - food_flags = food_flags,\ - foodtypes = foodtypes,\ - volume = max_volume,\ - eat_time = eat_time,\ - tastes = tastes,\ - eatverbs = eatverbs,\ - bite_consumption = bite_consumption,\ - microwaved_type = microwaved_type,\ - junkiness = junkiness,\ - after_eat = CALLBACK(src, .proc/after_eat)) + . = ..() + AddComponent(/datum/component/edible, after_eat = CALLBACK(src, .proc/after_eat)) /obj/item/food/candy/bronx/proc/after_eat(mob/living/eater) if(ishuman(eater)) diff --git a/code/game/objects/items/food/spaghetti.dm b/code/game/objects/items/food/spaghetti.dm index a02eca5271a..968fcc7a30c 100644 --- a/code/game/objects/items/food/spaghetti.dm +++ b/code/game/objects/items/food/spaghetti.dm @@ -5,21 +5,24 @@ foodtypes = GRAIN venue_value = FOOD_PRICE_CHEAP -/obj/item/food/spaghetti/Initialize(mapload) - . = ..() - if(!microwaved_type) // This isn't cooked, why would you put uncooked spaghetti in your pocket? - var/list/display_message = list( - span_notice("Something wet falls out of their pocket and hits the ground. Is that... [name]?"), - span_warning("Oh shit! All your pocket [name] fell out!")) - AddComponent(/datum/component/spill, display_message, 'sound/effects/splat.ogg', MEMORY_SPAGHETTI_SPILL) +// Why are you putting cooked spaghetti in your pockets? +/obj/item/food/spaghetti/make_microwavable() + var/list/display_message = list( + span_notice("Something wet falls out of their pocket and hits the ground. Is that... [name]?"), + span_warning("Oh shit! All your pocket [name] fell out!")) + AddComponent(/datum/component/spill, display_message, 'sound/effects/splat.ogg', MEMORY_SPAGHETTI_SPILL) + + return ..() /obj/item/food/spaghetti/raw name = "spaghetti" desc = "Now that's a nic'e pasta!" icon_state = "spaghetti" - microwaved_type = /obj/item/food/spaghetti/boiledspaghetti tastes = list("pasta" = 1) +/obj/item/food/spaghetti/raw/make_microwavable() + AddElement(/datum/element/microwavable, /obj/item/food/spaghetti/boiledspaghetti) + /obj/item/food/spaghetti/boiledspaghetti name = "boiled spaghetti" desc = "A plain dish of noodles, this needs more ingredients." diff --git a/code/game/objects/items/hand_items.dm b/code/game/objects/items/hand_items.dm index e65f2cb1fc0..fe997b72eb4 100644 --- a/code/game/objects/items/hand_items.dm +++ b/code/game/objects/items/hand_items.dm @@ -395,6 +395,10 @@ . = ..() if(HAS_TRAIT(user, TRAIT_GARLIC_BREATH)) kiss_type = /obj/projectile/kiss/french + + if(HAS_TRAIT(user, TRAIT_CHEF_KISS)) + kiss_type = /obj/projectile/kiss/chef + var/obj/projectile/blown_kiss = new kiss_type(get_turf(user)) user.visible_message("[user] blows \a [blown_kiss] at [target]!", span_notice("You blow \a [blown_kiss] at [target]!")) @@ -548,3 +552,33 @@ //Phwoar living_target.reagents.add_reagent(/datum/reagent/consumable/garlic, 1) living_target.visible_message("[living_target] has a funny look on [living_target.p_their()] face.", "Wow, that is a strong after taste of garlic!", vision_distance=COMBAT_MESSAGE_RANGE) + +/obj/projectile/kiss/chef + name = "chef's kiss" + +// If our chef's kiss hits a food item, we will improve it with love. +/obj/projectile/kiss/chef/on_hit(atom/target, blocked, pierce_hit) + . = ..() + if(!IS_EDIBLE(target) || !target.reagents) + return + if(!firer || !target.Adjacent(firer)) + return + + // From here on, no message + suppressed = SUPPRESSED_VERY + + if(!HAS_TRAIT_FROM(target, TRAIT_FOOD_CHEF_MADE, REF(firer))) + to_chat(firer, span_warning("Wait a second, you didn't make this [target.name]. How can you claim it as your own?")) + return + if(target.reagents.has_reagent(/datum/reagent/love)) + to_chat(firer, span_warning("You've already blessed [target.name] with your heart and soul.")) + return + + var/amount_nutriment = target.reagents.get_multiple_reagent_amounts(typesof(/datum/reagent/consumable/nutriment)) + if(amount_nutriment <= 0) + to_chat(firer, span_warning("There's not enough nutrition in [target.name] for it to be a proper meal.")) + return + + to_chat(firer, span_green("You deliver a chef's kiss over [target], declaring it perfect.")) + target.visible_message(span_notice("[firer] delivers a chef's kiss over [target]."), ignored_mobs = firer) + target.reagents.add_reagent(/datum/reagent/love, clamp(amount_nutriment / 4, 1, 10)) // clamped to about half of the most dense food I think we have (super bite burger) diff --git a/code/game/objects/items/stacks/medical.dm b/code/game/objects/items/stacks/medical.dm index e373e3194d0..b49895f6fd8 100644 --- a/code/game/objects/items/stacks/medical.dm +++ b/code/game/objects/items/stacks/medical.dm @@ -361,6 +361,9 @@ grind_results = list(/datum/reagent/consumable/aloejuice = 1) merge_type = /obj/item/stack/medical/aloe +/obj/item/stack/medical/aloe/fresh + amount = 2 + /obj/item/stack/medical/bone_gel name = "bone gel" singular_name = "bone gel" diff --git a/code/game/objects/items/stacks/sheets/leather.dm b/code/game/objects/items/stacks/sheets/leather.dm index 7fcbd59ff2f..7edec0aedbc 100644 --- a/code/game/objects/items/stacks/sheets/leather.dm +++ b/code/game/objects/items/stacks/sheets/leather.dm @@ -287,6 +287,12 @@ GLOBAL_LIST_INIT(sinew_recipes, list ( \ //Step two - washing..... it's actually in washing machine code. //Step three - drying +/obj/item/stack/sheet/wethide + +/obj/item/stack/sheet/wethide/Initialize(mapload) + . = ..() + AddElement(/datum/element/microwavable, /obj/item/stack/sheet/leather) + /obj/item/stack/sheet/wethide/should_atmos_process(datum/gas_mixture/air, exposed_temperature) return (exposed_temperature > drying_threshold_temperature) @@ -297,11 +303,6 @@ GLOBAL_LIST_INIT(sinew_recipes, list ( \ wetness = initial(wetness) use(1) -/obj/item/stack/sheet/wethide/microwave_act(obj/machinery/microwave/MW) - ..() - new /obj/item/stack/sheet/leather(drop_location(), amount) - qdel(src) - /obj/item/stack/sheet/animalhide/carp name = "carp scales" desc = "The scaly skin of a space carp. It looks quite beatiful when detached from the foul creature who once wore it." diff --git a/code/game/objects/items/stacks/stack.dm b/code/game/objects/items/stacks/stack.dm index 45a7cc5ea0d..a67054911ac 100644 --- a/code/game/objects/items/stacks/stack.dm +++ b/code/game/objects/items/stacks/stack.dm @@ -705,9 +705,5 @@ fingerprintslast = from.fingerprintslast //TODO bloody overlay -/obj/item/stack/microwave_act(obj/machinery/microwave/M) - if(istype(M) && M.dirty < 100) - M.dirty += amount - #undef STACK_CHECK_CARDINALS #undef STACK_CHECK_ADJACENT diff --git a/code/game/objects/structures/bonfire.dm b/code/game/objects/structures/bonfire.dm index 63dad0a3671..200d10203fb 100644 --- a/code/game/objects/structures/bonfire.dm +++ b/code/game/objects/structures/bonfire.dm @@ -150,7 +150,7 @@ var/obj/burned_object = burn_target if(grill && isitem(burned_object)) var/obj/item/grilled_item = burned_object - SEND_SIGNAL(grilled_item, COMSIG_ITEM_GRILLED, src, delta_time) //Not a big fan, maybe make this use fire_act() in the future. + SEND_SIGNAL(grilled_item, COMSIG_ITEM_GRILL_PROCESS, src, delta_time) //Not a big fan, maybe make this use fire_act() in the future. continue burned_object.fire_act(1000, 250 * delta_time) diff --git a/code/modules/cargo/exports/food_and_drink.dm b/code/modules/cargo/exports/food_and_drink.dm index d4b3b559097..6a8b326dd15 100644 --- a/code/modules/cargo/exports/food_and_drink.dm +++ b/code/modules/cargo/exports/food_and_drink.dm @@ -13,10 +13,10 @@ var/cost_obtained_from_venue_value = FALSE /datum/export/food/get_cost(obj/object, allowed_categories, apply_elastic) - var/obj/item/food/sold_food = object - if(sold_food.food_flags & FOOD_SILVER_SPAWNED) + if(HAS_TRAIT(object, TRAIT_FOOD_SILVER)) return FOOD_PRICE_WORTHLESS + var/obj/item/food/sold_food = object if(!cost_obtained_from_venue_value) cost = sold_food.venue_value cost_obtained_from_venue_value = TRUE diff --git a/code/modules/cargo/packs/exploration.dm b/code/modules/cargo/packs/exploration.dm index 77d85eaf3fa..55b28094de2 100644 --- a/code/modules/cargo/packs/exploration.dm +++ b/code/modules/cargo/packs/exploration.dm @@ -20,13 +20,15 @@ contains = list(/obj/item/food/sandwich = 5) crate_name = "outsourced food crate" -/datum/supply_pack/exploration/catering/fill(obj/structure/closet/crate/C) +/datum/supply_pack/exploration/catering/fill(obj/structure/closet/crate/crate) . = ..() - if(prob(30)) - for(var/obj/item/food/F in C) - F.name = "spoiled [F.name]" - F.foodtypes |= GROSS - F.MakeEdible() + if(!prob(30)) + return + + 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) /datum/supply_pack/exploration/shrubbery name = "Shrubbery Crate" diff --git a/code/modules/clothing/clothing.dm b/code/modules/clothing/clothing.dm index 40cdc141d84..ec14cce5b77 100644 --- a/code/modules/clothing/clothing.dm +++ b/code/modules/clothing/clothing.dm @@ -82,18 +82,8 @@ var/datum/weakref/clothing /obj/item/food/clothing/MakeEdible() - AddComponent(/datum/component/edible,\ - initial_reagents = food_reagents,\ - food_flags = food_flags,\ - foodtypes = foodtypes,\ - volume = max_volume,\ - eat_time = eat_time,\ - tastes = tastes,\ - eatverbs = eatverbs,\ - bite_consumption = bite_consumption,\ - microwaved_type = microwaved_type,\ - junkiness = junkiness,\ - after_eat = CALLBACK(src, .proc/after_eat)) + . = ..() + AddComponent(/datum/component/edible, after_eat = CALLBACK(src, .proc/after_eat)) /obj/item/food/clothing/proc/after_eat(mob/eater) var/obj/item/clothing/resolved_clothing = clothing.resolve() diff --git a/code/modules/clothing/head/tinfoilhat.dm b/code/modules/clothing/head/tinfoilhat.dm index 7865e46b6b0..b651c6885e1 100644 --- a/code/modules/clothing/head/tinfoilhat.dm +++ b/code/modules/clothing/head/tinfoilhat.dm @@ -77,10 +77,13 @@ return return ..() -/obj/item/clothing/head/costume/foilhat/microwave_act(obj/machinery/microwave/M) +/obj/item/clothing/head/costume/foilhat/microwave_act(obj/machinery/microwave/microwave_source, mob/microwaver) . = ..() - if(!warped) - warp_up() + if(warped) + return + + warp_up() + return . | COMPONENT_MICROWAVE_SUCCESS /obj/item/clothing/head/costume/foilhat/proc/call_suicide(datum/source) SIGNAL_HANDLER diff --git a/code/modules/food_and_drinks/machinery/deep_fryer.dm b/code/modules/food_and_drinks/machinery/deep_fryer.dm index 79747f283e8..81659c5181b 100644 --- a/code/modules/food_and_drinks/machinery/deep_fryer.dm +++ b/code/modules/food_and_drinks/machinery/deep_fryer.dm @@ -166,6 +166,7 @@ GLOBAL_LIST_INIT(oilfry_blacklisted_items, typecacheof(list( add_filter("entropic_ray", 10, list("type" = "rays", "size" = 35, "color" = COLOR_VIVID_YELLOW)) addtimer(CALLBACK(src, .proc/blow_up), 5 SECONDS) frying = new /obj/item/food/deepfryholder(src, frying_item) + ADD_TRAIT(frying, TRAIT_FOOD_CHEF_MADE, REF(user)) icon_state = "fryer_on" fry_loop.start() diff --git a/code/modules/food_and_drinks/machinery/griddle.dm b/code/modules/food_and_drinks/machinery/griddle.dm index 4b65b96e75f..f07fbb00a8a 100644 --- a/code/modules/food_and_drinks/machinery/griddle.dm +++ b/code/modules/food_and_drinks/machinery/griddle.dm @@ -96,8 +96,10 @@ griddled_objects += item_to_grill item_to_grill.flags_1 |= IS_ONTOP_1 item_to_grill.vis_flags |= VIS_INHERIT_PLANE + + SEND_SIGNAL(item_to_grill, COMSIG_ITEM_GRILL_PLACED_ON, user) RegisterSignal(item_to_grill, COMSIG_MOVABLE_MOVED, .proc/ItemMoved) - RegisterSignal(item_to_grill, COMSIG_GRILL_COMPLETED, .proc/GrillCompleted) + RegisterSignal(item_to_grill, COMSIG_ITEM_GRILLED, .proc/GrillCompleted) RegisterSignal(item_to_grill, COMSIG_PARENT_QDELETING, .proc/ItemRemovedFromGrill) update_grill_audio() update_appearance() @@ -108,7 +110,7 @@ ungrill.vis_flags &= ~VIS_INHERIT_PLANE griddled_objects -= ungrill vis_contents -= ungrill - UnregisterSignal(ungrill, list(COMSIG_GRILL_COMPLETED, COMSIG_MOVABLE_MOVED, COMSIG_PARENT_QDELETING)) + UnregisterSignal(ungrill, list(COMSIG_ITEM_GRILLED, COMSIG_MOVABLE_MOVED, COMSIG_PARENT_QDELETING)) update_grill_audio() /obj/machinery/griddle/proc/ItemMoved(obj/item/I, atom/OldLoc, Dir, Forced) @@ -153,7 +155,7 @@ ..() for(var/i in griddled_objects) var/obj/item/griddled_item = i - if(SEND_SIGNAL(griddled_item, COMSIG_ITEM_GRILLED, src, delta_time) & COMPONENT_HANDLED_GRILLING) + if(SEND_SIGNAL(griddled_item, COMSIG_ITEM_GRILL_PROCESS, src, delta_time) & COMPONENT_HANDLED_GRILLING) continue griddled_item.fire_act(1000) //Hot hot hot! if(prob(10)) diff --git a/code/modules/food_and_drinks/machinery/grill.dm b/code/modules/food_and_drinks/machinery/grill.dm index a3af9650d44..0bf5994bf33 100644 --- a/code/modules/food_and_drinks/machinery/grill.dm +++ b/code/modules/food_and_drinks/machinery/grill.dm @@ -68,8 +68,7 @@ return else if(!grilled_item && user.transferItemToLoc(I, src)) grilled_item = I - RegisterSignal(grilled_item, COMSIG_GRILL_COMPLETED, .proc/GrillCompleted) - ADD_TRAIT(grilled_item, TRAIT_FOOD_GRILLED, "boomers") + RegisterSignal(grilled_item, COMSIG_ITEM_GRILLED, .proc/GrillCompleted) to_chat(user, span_notice("You put the [grilled_item] on [src].")) update_appearance() grill_loop.start() @@ -89,7 +88,7 @@ smoke.set_up(1, holder = src, location = loc) smoke.start() if(grilled_item) - SEND_SIGNAL(grilled_item, COMSIG_ITEM_GRILLED, src, delta_time) + SEND_SIGNAL(grilled_item, COMSIG_ITEM_GRILL_PROCESS, src, delta_time) grill_time += delta_time grilled_item.reagents.add_reagent(/datum/reagent/consumable/char, 0.5 * delta_time) grill_fuel -= GRILL_FUELUSAGE_ACTIVE * delta_time @@ -136,8 +135,8 @@ /obj/machinery/grill/proc/finish_grill() if(grilled_item) - SEND_SIGNAL(grilled_item, COMSIG_GRILL_FOOD, grilled_item, grill_time) - UnregisterSignal(grilled_item, COMSIG_GRILL_COMPLETED) + grilled_item.AddElement(/datum/element/grilled_item, grill_time) + UnregisterSignal(grilled_item, COMSIG_ITEM_GRILLED) grill_time = 0 grill_loop.stop() diff --git a/code/modules/food_and_drinks/machinery/microwave.dm b/code/modules/food_and_drinks/machinery/microwave.dm index 37c027fcd06..eb81bc81599 100644 --- a/code/modules/food_and_drinks/machinery/microwave.dm +++ b/code/modules/food_and_drinks/machinery/microwave.dm @@ -1,4 +1,18 @@ -//Microwaving doesn't use recipes, instead it calls the microwave_act of the objects. For food, this creates something based on the food's cooked_type +// Microwaving doesn't use recipes, instead it calls the microwave_act of the objects. +// For food, this creates something based on the food's cooked_type + +/// Values based on microwave success +#define MICROWAVE_NORMAL 0 +#define MICROWAVE_MUCK 1 +#define MICROWAVE_PRE 2 + +/// Values for how broken the microwave is +#define NOT_BROKEN 0 +#define KINDA_BROKEN 1 +#define REALLY_BROKEN 2 + +/// The max amount of dirtiness a microwave can be +#define MAX_MICROWAVE_DIRTINESS 100 /obj/machinery/microwave name = "microwave oven" @@ -14,9 +28,11 @@ light_power = 3 var/wire_disabled = FALSE // is its internal wire cut? var/operating = FALSE - var/dirty = 0 // 0 to 100 // Does it need cleaning? + /// How dirty is it? + var/dirty = 0 var/dirty_anim_playing = FALSE - var/broken = 0 // 0, 1 or 2 // How broken is it??? + /// How broken is it? NOT_BROKEN, KINDA_BROKEN, REALLY_BROKEN + var/broken = NOT_BROKEN var/open = FALSE var/max_n_of_items = 10 var/efficiency = 0 @@ -126,7 +142,7 @@ . = ..() // All of these will use a full icon state instead - if (panel_open || dirty == 100 || broken || dirty_anim_playing) + if (panel_open || dirty == MAX_MICROWAVE_DIRTINESS || broken || dirty_anim_playing) return . var/ingredient_count = 0 @@ -184,7 +200,7 @@ icon_state = "mwb" else if (dirty_anim_playing) icon_state = "mwbloody1" - else if (dirty == 100) + else if (dirty == MAX_MICROWAVE_DIRTINESS) icon_state = open ? "mwbloodyo" : "mwbloody" else if(operating) icon_state = "back_on" @@ -199,7 +215,7 @@ /obj/machinery/microwave/wrench_act(mob/living/user, obj/item/tool) . = ..() - if(dirty >= 100) + if(dirty >= MAX_MICROWAVE_DIRTINESS) return FALSE if(default_unfasten_wrench(user, tool)) update_appearance() @@ -215,7 +231,7 @@ /obj/machinery/microwave/screwdriver_act(mob/living/user, obj/item/tool) if(operating) return - if(dirty >= 100) + if(dirty >= MAX_MICROWAVE_DIRTINESS) return if(default_deconstruction_screwdriver(user, icon_state, icon_state, tool)) update_appearance() @@ -229,17 +245,17 @@ wires.interact(user) return TRUE - if(broken > 0) - if(broken == 2 && O.tool_behaviour == TOOL_WIRECUTTER) // If it's broken and they're using a TOOL_WIRECUTTER + if(broken > NOT_BROKEN) + if(broken == REALLY_BROKEN && O.tool_behaviour == TOOL_WIRECUTTER) // If it's broken and they're using a TOOL_WIRECUTTER user.visible_message(span_notice("[user] starts to fix part of \the [src]."), span_notice("You start to fix part of \the [src]...")) if(O.use_tool(src, user, 20)) user.visible_message(span_notice("[user] fixes part of \the [src]."), span_notice("You fix part of \the [src].")) - broken = 1 // Fix it a bit - else if(broken == 1 && O.tool_behaviour == TOOL_WELDER) // If it's broken and they're doing the wrench + broken = KINDA_BROKEN // Fix it a bit + else if(broken == KINDA_BROKEN && O.tool_behaviour == TOOL_WELDER) // If it's broken and they're doing the wrench user.visible_message(span_notice("[user] starts to fix part of \the [src]."), span_notice("You start to fix part of \the [src]...")) if(O.use_tool(src, user, 20)) user.visible_message(span_notice("[user] fixes \the [src]."), span_notice("You fix \the [src].")) - broken = 0 + broken = NOT_BROKEN update_appearance() return FALSE //to use some fuel else @@ -271,7 +287,7 @@ update_appearance() return TRUE - if(dirty == 100) // The microwave is all dirty so can't be used! + if(dirty >= MAX_MICROWAVE_DIRTINESS) // The microwave is all dirty so can't be used! to_chat(user, span_warning("\The [src] is dirty!")) return TRUE @@ -337,7 +353,7 @@ if("eject") eject() if("use") - cook() + cook(user) if("examine") examine(user) @@ -349,10 +365,10 @@ playsound(loc, 'sound/machines/click.ogg', 15, TRUE, -3) -/obj/machinery/microwave/proc/cook() +/obj/machinery/microwave/proc/cook(mob/cooker) if(machine_stat & (NOPOWER|BROKEN)) return - if(operating || broken > 0 || panel_open || !anchored || dirty == 100) + if(operating || broken > 0 || panel_open || !anchored || dirty >= MAX_MICROWAVE_DIRTINESS) return if(wire_disabled) @@ -363,14 +379,19 @@ if(prob(max((5 / efficiency) - 5, dirty * 5))) //a clean unupgraded microwave has no risk of failure muck() return - for(var/obj/O in ingredients) - if(istype(O, /obj/item/food) || istype(O, /obj/item/grown)) - continue - if(prob(min(dirty * 5, 100))) - start_can_fail() - return - break - start() + + // How many items are we cooking that aren't already food items + var/non_food_ingedients = length(ingredients) + for(var/atom/movable/potential_fooditem as anything in ingredients) + if(IS_EDIBLE(potential_fooditem)) + non_food_ingedients-- + + // If we're cooking non-food items we can fail randomly + if(length(non_food_ingedients) && prob(min(dirty * 5, 100))) + start_can_fail(cooker) + return + + start(cooker) /obj/machinery/microwave/proc/wzhzhzh() visible_message(span_notice("\The [src] turns on."), null, span_hear("You hear a microwave humming.")) @@ -386,17 +407,13 @@ s.set_up(2, 1, src) s.start() -#define MICROWAVE_NORMAL 0 -#define MICROWAVE_MUCK 1 -#define MICROWAVE_PRE 2 - -/obj/machinery/microwave/proc/start() +/obj/machinery/microwave/proc/start(mob/cooker) wzhzhzh() - loop(MICROWAVE_NORMAL, 10) + loop(MICROWAVE_NORMAL, 10, cooker = cooker) -/obj/machinery/microwave/proc/start_can_fail() +/obj/machinery/microwave/proc/start_can_fail(mob/cooker) wzhzhzh() - loop(MICROWAVE_PRE, 4) + loop(MICROWAVE_PRE, 4, cooker = cooker) /obj/machinery/microwave/proc/muck() wzhzhzh() @@ -405,7 +422,7 @@ update_appearance() loop(MICROWAVE_MUCK, 4) -/obj/machinery/microwave/proc/loop(type, time, wait = max(12 - 2 * efficiency, 2)) // standard wait is 10 +/obj/machinery/microwave/proc/loop(type, time, wait = max(12 - 2 * efficiency, 2), mob/cooker) // standard wait is 10 if((machine_stat & BROKEN) && type == MICROWAVE_PRE) pre_fail() return @@ -413,15 +430,15 @@ if(!time || !length(ingredients)) switch(type) if(MICROWAVE_NORMAL) - loop_finish() + loop_finish(cooker) if(MICROWAVE_MUCK) muck_finish() if(MICROWAVE_PRE) - pre_success() + pre_success(cooker) return time-- use_power(active_power_usage) - addtimer(CALLBACK(src, .proc/loop, type, time, wait), wait) + addtimer(CALLBACK(src, .proc/loop, type, time, wait, cooker), wait) /obj/machinery/microwave/power_change() . = ..() @@ -429,39 +446,45 @@ pre_fail() eject() -/obj/machinery/microwave/proc/loop_finish() +/obj/machinery/microwave/proc/loop_finish(mob/cooker) operating = FALSE - var/metal = 0 - for(var/obj/item/O in ingredients) - O.microwave_act(src) - if(LAZYLEN(O.custom_materials)) - if(O.custom_materials[GET_MATERIAL_REF(/datum/material/iron)]) - metal += O.custom_materials[GET_MATERIAL_REF(/datum/material/iron)] + var/metal_amount = 0 + for(var/obj/item/cooked_item in ingredients) + var/sigreturn = cooked_item.microwave_act(src, cooker) + if(sigreturn & COMPONENT_MICROWAVE_SUCCESS) + if(isstack(cooked_item)) + var/obj/item/stack/cooked_stack = cooked_item + dirty += cooked_stack.amount + else + dirty++ - if(metal) + metal_amount += (cooked_item.custom_materials?[GET_MATERIAL_REF(/datum/material/iron)] || 0) + + if(metal_amount) spark() - broken = 2 - if(prob(max(metal / 2, 33))) + broken = REALLY_BROKEN + if(prob(max(metal_amount / 2, 33))) explosion(src, heavy_impact_range = 1, light_impact_range = 2) + else dump_inventory_contents() after_finish_loop() /obj/machinery/microwave/proc/pre_fail() - broken = 2 + broken = REALLY_BROKEN operating = FALSE spark() after_finish_loop() -/obj/machinery/microwave/proc/pre_success() - loop(MICROWAVE_NORMAL, 10) +/obj/machinery/microwave/proc/pre_success(mob/cooker) + loop(MICROWAVE_NORMAL, 10, cooker = cooker) /obj/machinery/microwave/proc/muck_finish() visible_message(span_warning("\The [src] gets covered in muck!")) - dirty = 100 + dirty = MAX_MICROWAVE_DIRTINESS dirty_anim_playing = FALSE operating = FALSE @@ -507,3 +530,10 @@ #undef MICROWAVE_NORMAL #undef MICROWAVE_MUCK #undef MICROWAVE_PRE + + +#undef NOT_BROKEN +#undef KINDA_BROKEN +#undef REALLY_BROKEN + +#undef MAX_MICROWAVE_DIRTINESS diff --git a/code/modules/food_and_drinks/machinery/oven.dm b/code/modules/food_and_drinks/machinery/oven.dm index 13f8895187e..f94fb11f017 100644 --- a/code/modules/food_and_drinks/machinery/oven.dm +++ b/code/modules/food_and_drinks/machinery/oven.dm @@ -66,7 +66,7 @@ var/worst_cooked_food_state = 0 for(var/obj/item/baked_item in used_tray.contents) - var/signal_result = SEND_SIGNAL(baked_item, COMSIG_ITEM_BAKED, src, delta_time) + var/signal_result = SEND_SIGNAL(baked_item, COMSIG_ITEM_OVEN_PROCESS, src, delta_time) if(signal_result & COMPONENT_HANDLED_BAKING) //This means something responded to us baking! if(signal_result & COMPONENT_BAKING_GOOD_RESULT && worst_cooked_food_state < OVEN_SMOKE_STATE_GOOD) @@ -89,12 +89,12 @@ if(open && !used_tray && istype(I, /obj/item/plate/oven_tray)) if(user.transferItemToLoc(I, src, silent = FALSE)) to_chat(user, span_notice("You put [I] in [src].")) - add_tray_to_oven(I) + add_tray_to_oven(I, user) else return ..() ///Adds a tray to the oven, making sure the shit can get baked. -/obj/machinery/oven/proc/add_tray_to_oven(obj/item/plate/oven_tray) +/obj/machinery/oven/proc/add_tray_to_oven(obj/item/plate/oven_tray, mob/baker) used_tray = oven_tray if(!open) @@ -105,13 +105,14 @@ oven_tray.pixel_y = OVEN_TRAY_Y_OFFSET oven_tray.pixel_x = OVEN_TRAY_X_OFFSET - RegisterSignal(used_tray, COMSIG_MOVABLE_MOVED, .proc/ItemMoved) + RegisterSignal(used_tray, COMSIG_MOVABLE_MOVED, .proc/on_tray_moved) update_baking_audio() update_appearance() ///Called when the tray is moved out of the oven in some way -/obj/machinery/oven/proc/ItemMoved(obj/item/oven_tray, atom/OldLoc, Dir, Forced) +/obj/machinery/oven/proc/on_tray_moved(obj/item/oven_tray, atom/OldLoc, Dir, Forced) SIGNAL_HANDLER + tray_removed_from_oven(oven_tray) /obj/machinery/oven/proc/tray_removed_from_oven(obj/item/oven_tray) @@ -139,6 +140,11 @@ if(used_tray) begin_processing() used_tray.vis_flags |= VIS_HIDE + + // yeah yeah i figure you don't need connect loc for just baking trays + for(var/obj/item/baked_item in used_tray.contents) + SEND_SIGNAL(baked_item, COMSIG_ITEM_OVEN_PLACED_IN, src, user) + update_appearance() update_baking_audio() return TRUE diff --git a/code/modules/food_and_drinks/recipes/food_mixtures.dm b/code/modules/food_and_drinks/recipes/food_mixtures.dm index 5f014d08056..5c0d6fe09db 100644 --- a/code/modules/food_and_drinks/recipes/food_mixtures.dm +++ b/code/modules/food_and_drinks/recipes/food_mixtures.dm @@ -2,6 +2,9 @@ var/real_parts category = CAT_FOOD +/datum/crafting_recipe/food/on_craft_completion(mob/user, atom/result) + ADD_TRAIT(result, TRAIT_FOOD_CHEF_MADE, REF(user)) + /datum/crafting_recipe/food/New() real_parts = parts.Copy() parts |= reqs diff --git a/code/modules/food_and_drinks/recipes/tablecraft/recipes_cake.dm b/code/modules/food_and_drinks/recipes/tablecraft/recipes_cake.dm index 140a3ce037a..c967e50f959 100644 --- a/code/modules/food_and_drinks/recipes/tablecraft/recipes_cake.dm +++ b/code/modules/food_and_drinks/recipes/tablecraft/recipes_cake.dm @@ -170,13 +170,9 @@ /datum/reagent/consumable/korta_milk = 10, /obj/item/food/grown/berries = 5 ) - result = /obj/item/food/cake/pavlova + result = /obj/item/food/cake/pavlova/nuts subcategory = CAT_CAKE -/datum/crafting_recipe/food/pavlovakorta/on_craft_completion(mob/user, obj/item/food/cake/pavlova/result) - result.foodtypes = NUTS | FRUIT | SUGAR - result.AddElement(/datum/element/processable, TOOL_KNIFE, /obj/item/food/cakeslice/pavlova/nuts, 5, 30) - /datum/crafting_recipe/food/bscvcake name = "blackberry and strawberry vanilla cake" reqs = list( diff --git a/code/modules/hydroponics/grown.dm b/code/modules/hydroponics/grown.dm index 237431d7043..822b4afa387 100644 --- a/code/modules/hydroponics/grown.dm +++ b/code/modules/hydroponics/grown.dm @@ -79,19 +79,6 @@ QDEL_NULL(seed) return ..() -/obj/item/food/grown/MakeEdible() - AddComponent(/datum/component/edible,\ - initial_reagents = food_reagents,\ - food_flags = food_flags,\ - foodtypes = foodtypes,\ - volume = max_volume,\ - eat_time = eat_time,\ - tastes = tastes,\ - eatverbs = eatverbs,\ - bite_consumption = bite_consumption,\ - microwaved_type = microwaved_type,\ - junkiness = junkiness) - /obj/item/food/grown/proc/make_dryable() AddElement(/datum/element/dryable, type) diff --git a/code/modules/hydroponics/grown/aloe.dm b/code/modules/hydroponics/grown/aloe.dm index e87e25afd4d..e2ea530f547 100644 --- a/code/modules/hydroponics/grown/aloe.dm +++ b/code/modules/hydroponics/grown/aloe.dm @@ -26,6 +26,5 @@ juice_results = list(/datum/reagent/consumable/aloejuice = 0) distill_reagent = /datum/reagent/consumable/ethanol/tequila -/obj/item/food/grown/aloe/microwave_act(obj/machinery/microwave/M) - new /obj/item/stack/medical/aloe(drop_location(), 2) - qdel(src) +/obj/item/food/grown/aloe/make_microwavable() + AddElement(/datum/element/microwavable, /obj/item/stack/medical/aloe/fresh) diff --git a/code/modules/hydroponics/grown/corn.dm b/code/modules/hydroponics/grown/corn.dm index d363e8d1106..7babd36c010 100644 --- a/code/modules/hydroponics/grown/corn.dm +++ b/code/modules/hydroponics/grown/corn.dm @@ -21,7 +21,6 @@ name = "ear of corn" desc = "Needs some butter!" icon_state = "corn" - microwaved_type = /obj/item/food/popcorn trash_type = /obj/item/grown/corncob bite_consumption_mod = 2 foodtypes = VEGETABLES @@ -33,6 +32,9 @@ /obj/item/food/grown/corn/MakeBakeable() AddComponent(/datum/component/bakeable, /obj/item/food/oven_baked_corn, rand(15 SECONDS, 25 SECONDS), TRUE, TRUE) +/obj/item/food/grown/corn/make_microwavable() + AddElement(/datum/element/microwavable, /obj/item/food/popcorn) + /obj/item/grown/corncob name = "corn cob" desc = "A reminder of meals gone by." diff --git a/code/modules/hydroponics/grown/melon.dm b/code/modules/hydroponics/grown/melon.dm index 2c646b1750b..eb9dbd60d43 100644 --- a/code/modules/hydroponics/grown/melon.dm +++ b/code/modules/hydroponics/grown/melon.dm @@ -69,18 +69,8 @@ return //No drying /obj/item/food/grown/holymelon/MakeEdible() - AddComponent(/datum/component/edible, \ - initial_reagents = food_reagents, \ - food_flags = food_flags, \ - foodtypes = foodtypes, \ - volume = max_volume, \ - eat_time = eat_time, \ - tastes = tastes, \ - eatverbs = eatverbs,\ - bite_consumption = bite_consumption, \ - microwaved_type = microwaved_type, \ - junkiness = junkiness, \ - check_liked = CALLBACK(src, .proc/check_holyness)) + . = ..() + AddComponent(/datum/component/edible, check_liked = CALLBACK(src, .proc/check_holyness)) /* * Callback to be used with the edible component. diff --git a/code/modules/hydroponics/grown/onion.dm b/code/modules/hydroponics/grown/onion.dm index 1b909621de5..b1d0922bac5 100644 --- a/code/modules/hydroponics/grown/onion.dm +++ b/code/modules/hydroponics/grown/onion.dm @@ -64,7 +64,9 @@ food_reagents = list(/datum/reagent/consumable/nutriment = 5, /datum/reagent/consumable/nutriment/vitamin = 2) gender = PLURAL w_class = WEIGHT_CLASS_TINY - microwaved_type = /obj/item/food/onionrings + +/obj/item/food/onion_slice/make_microwavable() + AddElement(/datum/element/microwavable, /obj/item/food/onionrings) /obj/item/food/onion_slice/red name = "red onion slices" diff --git a/code/modules/hydroponics/growninedible.dm b/code/modules/hydroponics/growninedible.dm index b61e817acbc..418ddf8c8c0 100644 --- a/code/modules/hydroponics/growninedible.dm +++ b/code/modules/hydroponics/growninedible.dm @@ -44,9 +44,6 @@ return TRUE return FALSE -/obj/item/grown/microwave_act(obj/machinery/microwave/M) - return - /obj/item/grown/on_grind() . = ..() for(var/i in 1 to grind_results.len) diff --git a/code/modules/library/skill_learning/skillchip.dm b/code/modules/library/skill_learning/skillchip.dm index 88a668a8028..3255b9271e6 100644 --- a/code/modules/library/skill_learning/skillchip.dm +++ b/code/modules/library/skill_learning/skillchip.dm @@ -468,4 +468,13 @@ user.adjustOrganLoss(ORGAN_SLOT_BRAIN, 20) . = ..() +/obj/item/skillchip/chefs_kiss + name = "K1SS skillchip" + auto_traits = list(TRAIT_CHEF_KISS) + skill_name = "Chef's Kiss" + skill_description = "Allows you to kiss food you've created to make them with love." + skill_icon = "cookie" + activate_message = span_notice("You recall learning from your grandmother how they baked their cookies with love.") + deactivate_message = span_notice("You forget all memories imparted upon you by your grandmother. Were they even your real grandma?") + #undef SKILLCHIP_CATEGORY_GENERAL diff --git a/code/modules/mod/modules/modules_service.dm b/code/modules/mod/modules/modules_service.dm index c2747afa698..e4ddb5d611e 100644 --- a/code/modules/mod/modules/modules_service.dm +++ b/code/modules/mod/modules/modules_service.dm @@ -46,7 +46,7 @@ spark_effect.set_up(2, 1, mod.wearer) spark_effect.start() mod.wearer.Beam(target,icon_state="lightning[rand(1,12)]", time = 5) - if(microwave_target.microwave_act()) + if(microwave_target.microwave_act(microwaver = mod.wearer) & COMPONENT_MICROWAVE_SUCCESS) playsound(src, 'sound/machines/microwave/microwave-end.ogg', 50, FALSE) else balloon_alert(mod.wearer, "can't be microwaved!") diff --git a/code/modules/reagents/chemistry/holder.dm b/code/modules/reagents/chemistry/holder.dm index 78c2e481c0c..b38ff691ec2 100644 --- a/code/modules/reagents/chemistry/holder.dm +++ b/code/modules/reagents/chemistry/holder.dm @@ -1277,6 +1277,13 @@ return round(cached_reagent.volume, CHEMICAL_QUANTISATION_LEVEL) return 0 +/datum/reagents/proc/get_multiple_reagent_amounts(list/reagents) + var/list/cached_reagents = reagent_list + for(var/datum/reagent/cached_reagent as anything in cached_reagents) + if(cached_reagent.type in reagents) + return round(cached_reagent.volume, CHEMICAL_QUANTISATION_LEVEL) + return 0 + /// Get the purity of this reagent /datum/reagents/proc/get_reagent_purity(reagent) var/list/cached_reagents = reagent_list diff --git a/code/modules/reagents/chemistry/reagents/other_reagents.dm b/code/modules/reagents/chemistry/reagents/other_reagents.dm index c0ff71ba968..a75096f6923 100644 --- a/code/modules/reagents/chemistry/reagents/other_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/other_reagents.dm @@ -2812,3 +2812,39 @@ mytray.adjust_plant_health(round(chems.get_reagent_amount(src.type) * 1)) if(myseed) myseed.adjust_potency(round(chems.get_reagent_amount(src.type) * 0.5)) + +// I made this food....with love. +// Reagent added to food by chef's with a chef's kiss. Makes people happy. +/datum/reagent/love + name = "Love" + description = "This food's been made... with love." + color = "#ff7edd" + taste_description = "love" + taste_mult = 10 + overdose_threshold = 50 // too much love is a bad thing + +/datum/reagent/love/expose_mob(mob/living/exposed_mob, methods, reac_volume, show_message, touch_protection) + . = ..() + // A syringe is not grandma's cooking + if(methods & ~INGEST) + exposed_mob.reagents.del_reagent(type) + +/datum/reagent/love/on_mob_metabolize(mob/living/metabolizer) + . = ..() + metabolizer.add_mood_event(name, /datum/mood_event/love_reagent) + +/datum/reagent/love/on_mob_delete(mob/living/deleted_from) + . = ..() + // When we exit the system we'll leave the moodlet based on the amount we had + var/duration_of_moodlet = current_cycle * 20 SECONDS + deleted_from.clear_mood_event(name) + deleted_from.add_mood_event(name, /datum/mood_event/love_reagent, duration_of_moodlet) + +/datum/reagent/love/overdose_process(mob/living/metabolizer, delta_time, times_fired) + var/mob/living/carbon/carbon_metabolizer = metabolizer + if(!istype(carbon_metabolizer) || !carbon_metabolizer.can_heartattack() || carbon_metabolizer.undergoing_cardiac_arrest()) + metabolizer.reagents.del_reagent(type) + return + + if(DT_PROB(10, delta_time)) + carbon_metabolizer.set_heartattack(TRUE) diff --git a/code/modules/reagents/chemistry/recipes/slime_extracts.dm b/code/modules/reagents/chemistry/recipes/slime_extracts.dm index e4215dc002b..293f8396046 100644 --- a/code/modules/reagents/chemistry/recipes/slime_extracts.dm +++ b/code/modules/reagents/chemistry/recipes/slime_extracts.dm @@ -147,9 +147,7 @@ for(var/i in 1 to 4 + rand(1,2)) var/chosen = getbork() var/obj/item/food_item = new chosen(T) - if(istype(food_item, /obj/item/food)) - var/obj/item/food/foody = food_item - foody.mark_silver_slime_reaction() + ADD_TRAIT(food_item, TRAIT_FOOD_SILVER, INNATE_TRAIT) if(prob(5))//Fry it! var/obj/item/food/deepfryholder/fried fried = new(T, food_item) diff --git a/code/modules/reagents/reagent_containers.dm b/code/modules/reagents/reagent_containers.dm index 33e136af130..7b6711c1c71 100644 --- a/code/modules/reagents/reagent_containers.dm +++ b/code/modules/reagents/reagent_containers.dm @@ -206,9 +206,9 @@ reagents.clear_reagents() -/obj/item/reagent_containers/microwave_act(obj/machinery/microwave/M) +/obj/item/reagent_containers/microwave_act(obj/machinery/microwave/microwave_source, mob/microwaver) reagents.expose_temperature(1000) - ..() + return ..() | COMPONENT_MICROWAVE_SUCCESS /obj/item/reagent_containers/fire_act(temperature, volume) reagents.expose_temperature(temperature) diff --git a/code/modules/research/xenobiology/crossbreeding/_status_effects.dm b/code/modules/research/xenobiology/crossbreeding/_status_effects.dm index 14d8e74566d..d3b79793b9f 100644 --- a/code/modules/research/xenobiology/crossbreeding/_status_effects.dm +++ b/code/modules/research/xenobiology/crossbreeding/_status_effects.dm @@ -613,7 +613,7 @@ /datum/status_effect/stabilized/darkpurple/tick() var/obj/item/item = owner.get_active_held_item() if(item) - if(IS_EDIBLE(item) && item.microwave_act()) + if(IS_EDIBLE(item) && (item.microwave_act(microwaver = owner) & COMPONENT_MICROWAVE_SUCCESS)) to_chat(owner, span_warning("[linked_extract] flares up brightly, and your hands alone are enough cook [item]!")) else item.attackby(fire, owner) diff --git a/code/modules/research/xenobiology/crossbreeding/burning.dm b/code/modules/research/xenobiology/crossbreeding/burning.dm index 0f653993a2d..66139bfa31b 100644 --- a/code/modules/research/xenobiology/crossbreeding/burning.dm +++ b/code/modules/research/xenobiology/crossbreeding/burning.dm @@ -141,7 +141,7 @@ Burning extracts: var/path = get_random_food() var/obj/item/food/food = new path(pick(turfs)) food.reagents.add_reagent(/datum/reagent/toxin/slimejelly,5) //Oh god it burns - food.mark_silver_slime_reaction() + ADD_TRAIT(food, TRAIT_FOOD_SILVER, INNATE_TRAIT) if(prob(50)) food.desc += " It smells strange..." user.visible_message(span_danger("[src] produces a few pieces of food!")) diff --git a/code/modules/research/xenobiology/crossbreeding/industrial.dm b/code/modules/research/xenobiology/crossbreeding/industrial.dm index 40ea6179706..710cf90dd71 100644 --- a/code/modules/research/xenobiology/crossbreeding/industrial.dm +++ b/code/modules/research/xenobiology/crossbreeding/industrial.dm @@ -120,9 +120,7 @@ Industrial extracts: ..() /obj/item/slimecross/industrial/silver/do_after_spawn(obj/item/spawned) - if(istype(spawned, /obj/item/food)) - var/obj/item/food/food_object = spawned - food_object.mark_silver_slime_reaction() + ADD_TRAIT(spawned, TRAIT_FOOD_SILVER, INNATE_TRAIT) /obj/item/slimecross/industrial/bluespace colour = "bluespace" diff --git a/code/modules/research/xenobiology/xenobiology.dm b/code/modules/research/xenobiology/xenobiology.dm index 859cdf98bc2..0bcf046b501 100644 --- a/code/modules/research/xenobiology/xenobiology.dm +++ b/code/modules/research/xenobiology/xenobiology.dm @@ -156,7 +156,7 @@ if(SLIME_ACTIVATE_MINOR) var/food_type = get_random_food() var/obj/item/food/food_item = new food_type - food_item.mark_silver_slime_reaction() + ADD_TRAIT(food_item, TRAIT_FOOD_SILVER, INNATE_TRAIT) if(!user.put_in_active_hand(food_item)) food_item.forceMove(user.drop_location()) playsound(user, 'sound/effects/splat.ogg', 50, TRUE) diff --git a/code/modules/vending/drinnerware.dm b/code/modules/vending/drinnerware.dm index c6d1477166c..073f2aabf4f 100644 --- a/code/modules/vending/drinnerware.dm +++ b/code/modules/vending/drinnerware.dm @@ -19,6 +19,7 @@ /obj/item/kitchen/rollingpin = 2, /obj/item/knife/kitchen = 2, /obj/item/book/granter/crafting_recipe/cooking_sweets_101 = 2, + /obj/item/skillchip/chefs_kiss = 2, /obj/item/plate/small = 5, /obj/item/plate = 10, /obj/item/plate/large = 5, diff --git a/tgstation.dme b/tgstation.dme index 74a4a19ff6c..a820a9bd97a 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -1096,6 +1096,8 @@ #include "code\datums\elements\decals\blood.dm" #include "code\datums\elements\food\dunkable.dm" #include "code\datums\elements\food\food_trash.dm" +#include "code\datums\elements\food\grilled_item.dm" +#include "code\datums\elements\food\microwavable.dm" #include "code\datums\elements\food\processable.dm" #include "code\datums\elements\food\venue_price.dm" #include "code\datums\elements\screentips\contextual_screentip_bare_hands.dm"