diff --git a/_maps/RandomRuins/BeachRuins/beach_ancient_ruin.dmm b/_maps/RandomRuins/BeachRuins/beach_ancient_ruin.dmm
index be52f6a67f46..77df46175bc6 100644
--- a/_maps/RandomRuins/BeachRuins/beach_ancient_ruin.dmm
+++ b/_maps/RandomRuins/BeachRuins/beach_ancient_ruin.dmm
@@ -606,7 +606,7 @@
/area/ruin/beach/complex)
"kK" = (
/obj/structure/closet/crate/bin,
-/obj/item/reagent_containers/food/snacks/breadslice/moldy,
+/obj/item/food/breadslice/moldy,
/obj/effect/decal/cleanable/dirt/dust,
/turf/open/floor/concrete/slab_4,
/area/ruin/beach/complex)
diff --git a/_maps/RandomRuins/BeachRuins/beach_treasure_cove.dmm b/_maps/RandomRuins/BeachRuins/beach_treasure_cove.dmm
index 6e70a81ace49..becd88ae56fd 100644
--- a/_maps/RandomRuins/BeachRuins/beach_treasure_cove.dmm
+++ b/_maps/RandomRuins/BeachRuins/beach_treasure_cove.dmm
@@ -240,7 +240,7 @@
},
/obj/structure/table/wood/reinforced,
/obj/effect/decal/cleanable/dirt/dust,
-/obj/item/reagent_containers/food/snacks/breadslice/moldy{
+/obj/item/food/breadslice/moldy{
pixel_x = 3;
pixel_y = 6
},
diff --git a/_maps/RandomRuins/JungleRuins/jungle_paradise.dmm b/_maps/RandomRuins/JungleRuins/jungle_paradise.dmm
index 9457e639c5ce..86e2ac4e5477 100644
--- a/_maps/RandomRuins/JungleRuins/jungle_paradise.dmm
+++ b/_maps/RandomRuins/JungleRuins/jungle_paradise.dmm
@@ -5381,7 +5381,7 @@
"Ih" = (
/obj/structure/table/wood,
/obj/machinery/light/directional/south,
-/obj/item/reagent_containers/food/snacks/breadslice/moldy{
+/obj/item/food/breadslice/moldy{
pixel_x = -8
},
/obj/item/reagent_containers/food/snacks/grown/berries/poison{
@@ -7509,7 +7509,7 @@
},
/obj/effect/mob_spawn/human/corpse/nanotrasensoldier,
/obj/effect/decal/cleanable/vomit/old,
-/obj/item/reagent_containers/food/snacks/breadslice/moldy{
+/obj/item/food/breadslice/moldy{
pixel_x = -4;
pixel_y = 16
},
diff --git a/_maps/RandomRuins/LavaRuins/lavaland_crashed_starwalker.dmm b/_maps/RandomRuins/LavaRuins/lavaland_crashed_starwalker.dmm
index 138b1e9d31ed..935a852fac76 100644
--- a/_maps/RandomRuins/LavaRuins/lavaland_crashed_starwalker.dmm
+++ b/_maps/RandomRuins/LavaRuins/lavaland_crashed_starwalker.dmm
@@ -721,7 +721,7 @@
/obj/structure/cable/green{
icon_state = "1-4"
},
-/obj/item/reagent_containers/food/snacks/breadslice/moldy{
+/obj/item/food/breadslice/moldy{
pixel_x = 5
},
/turf/open/floor/pod,
diff --git a/_maps/RandomRuins/LavaRuins/lavaland_surface_biodome_winter.dmm b/_maps/RandomRuins/LavaRuins/lavaland_surface_biodome_winter.dmm
index a4b07632face..6415f9e79293 100644
--- a/_maps/RandomRuins/LavaRuins/lavaland_surface_biodome_winter.dmm
+++ b/_maps/RandomRuins/LavaRuins/lavaland_surface_biodome_winter.dmm
@@ -829,7 +829,7 @@
/area/ruin/unpowered/winter_biodome)
"kb" = (
/obj/structure/table/wood,
-/obj/item/reagent_containers/food/snacks/breadslice/plain,
+/obj/item/food/breadslice/plain,
/obj/item/reagent_containers/food/snacks/grown/cabbage,
/turf/open/floor/wood,
/area/ruin/unpowered/winter_biodome/cabin)
@@ -1006,8 +1006,8 @@
"oR" = (
/obj/effect/turf_decal/corner/opaque/solgovblue/diagonal,
/obj/structure/closet/secure_closet/freezer,
-/obj/item/reagent_containers/food/snacks/store/bread/plain,
-/obj/item/reagent_containers/food/snacks/store/bread/plain,
+/obj/item/food/bread/plain,
+/obj/item/food/bread/plain,
/obj/item/reagent_containers/food/snacks/grown/cabbage,
/obj/item/reagent_containers/food/snacks/grown/cabbage,
/obj/effect/decal/cleanable/dirt/dust,
diff --git a/_maps/RandomRuins/RockRuins/rockplanet_distillery.dmm b/_maps/RandomRuins/RockRuins/rockplanet_distillery.dmm
index 0c592a0ac3b4..df70f94b314b 100644
--- a/_maps/RandomRuins/RockRuins/rockplanet_distillery.dmm
+++ b/_maps/RandomRuins/RockRuins/rockplanet_distillery.dmm
@@ -3431,7 +3431,7 @@
/obj/effect/decal/cleanable/dirt/dust,
/obj/structure/closet/secure_closet/freezer/wall/directional/east,
/obj/item/reagent_containers/food/snacks/chips,
-/obj/item/reagent_containers/food/snacks/butterdog,
+/obj/item/food/butterdog,
/obj/item/reagent_containers/food/snacks/chips{
pixel_x = 2
},
diff --git a/_maps/RandomRuins/SpaceRuins/onehalf.dmm b/_maps/RandomRuins/SpaceRuins/onehalf.dmm
index 85f087ec38a9..0ee697760b25 100644
--- a/_maps/RandomRuins/SpaceRuins/onehalf.dmm
+++ b/_maps/RandomRuins/SpaceRuins/onehalf.dmm
@@ -2034,12 +2034,6 @@
},
/turf/open/space,
/area/space/nearstation)
-"Ra" = (
-/obj/structure/frame/computer{
- dir = 8
- },
-/turf/open/floor/plasteel,
-/area/ruin/space/has_grav/onehalf)
"Rv" = (
/obj/effect/turf_decal/siding/wood,
/turf/open/floor/wood/airless{
@@ -3328,7 +3322,7 @@ UM
cp
ZX
Gv
-Ra
+Gv
cU
YE
bU
diff --git a/_maps/RandomRuins/SpaceRuins/power_puzzle.dmm b/_maps/RandomRuins/SpaceRuins/power_puzzle.dmm
index b76ae63a86e7..3d05cfb13d35 100644
--- a/_maps/RandomRuins/SpaceRuins/power_puzzle.dmm
+++ b/_maps/RandomRuins/SpaceRuins/power_puzzle.dmm
@@ -1739,7 +1739,7 @@
/area/ruin/space/has_grav/powerpuzzle/secure)
"sc" = (
/obj/effect/mob_spawn/human/corpse/cargo_tech,
-/obj/item/reagent_containers/food/snacks/cakeslice/birthday,
+/obj/item/food/cakeslice/birthday,
/obj/effect/decal/cleanable/confetti,
/obj/machinery/light/small/broken/directional/east,
/obj/structure/toilet,
diff --git a/_maps/RandomRuins/SpaceRuins/spacemall.dmm b/_maps/RandomRuins/SpaceRuins/spacemall.dmm
index 0f5d01fb7de8..eb48bcae1626 100644
--- a/_maps/RandomRuins/SpaceRuins/spacemall.dmm
+++ b/_maps/RandomRuins/SpaceRuins/spacemall.dmm
@@ -3606,7 +3606,7 @@
/area/ruin/space/has_grav/spacemall/shop)
"nS" = (
/obj/effect/turf_decal/corner/transparent/black/diagonal,
-/obj/item/reagent_containers/food/snacks/store/bread/spidermeat,
+/obj/item/food/bread/spidermeat,
/obj/structure/table,
/turf/open/floor/plasteel/white,
/area/ruin/space/has_grav/spacemall/dorms)
@@ -6776,7 +6776,7 @@
dir = 8
},
/obj/item/trash/plate,
-/obj/item/reagent_containers/food/snacks/breadslice/moldy{
+/obj/item/food/breadslice/moldy{
pixel_y = 6
},
/obj/item/reagent_containers/food/snacks/spiderling{
diff --git a/_maps/map_files/generic/CentCom.dmm b/_maps/map_files/generic/CentCom.dmm
index ff8c37d19e96..2f531a149ffe 100644
--- a/_maps/map_files/generic/CentCom.dmm
+++ b/_maps/map_files/generic/CentCom.dmm
@@ -3043,10 +3043,6 @@
/obj/structure/table/wood,
/turf/open/floor/plasteel,
/area/wizard_station)
-"aEX" = (
-/obj/structure/table/wood,
-/turf/open/floor/plasteel,
-/area/wizard_station)
"aEY" = (
/obj/structure/table/wood,
/obj/item/bikehorn/golden{
@@ -11574,8 +11570,8 @@
/obj/item/reagent_containers/food/snacks/meat/slab/xeno,
/obj/item/reagent_containers/food/snacks/meat/slab/xeno,
/obj/item/reagent_containers/food/snacks/meat/slab/xeno,
-/obj/item/reagent_containers/food/snacks/spaghetti,
-/obj/item/reagent_containers/food/snacks/spaghetti,
+/obj/item/food/spaghetti/raw,
+/obj/item/food/spaghetti/raw,
/obj/item/reagent_containers/food/snacks/meat/rawcutlet,
/obj/item/reagent_containers/food/snacks/meat/rawcutlet,
/obj/item/reagent_containers/food/snacks/meat/rawcutlet,
@@ -23766,7 +23762,7 @@ auE
aEc
auE
aAx
-aEX
+aEW
aqZ
aqZ
aGr
diff --git a/_maps/outpost/nanotrasen_asteroid.dmm b/_maps/outpost/nanotrasen_asteroid.dmm
index 816befea0002..08f1322e7c60 100644
--- a/_maps/outpost/nanotrasen_asteroid.dmm
+++ b/_maps/outpost/nanotrasen_asteroid.dmm
@@ -125,7 +125,7 @@
/area/outpost/maintenance/fore)
"aE" = (
/obj/structure/table/wood,
-/obj/item/reagent_containers/food/snacks/cakeslice/birthday{
+/obj/item/food/cakeslice/birthday{
pixel_x = -3;
pixel_y = -5
},
diff --git a/_maps/shuttles/independent/independent_lagoon.dmm b/_maps/shuttles/independent/independent_lagoon.dmm
index 77b0d605e91b..248ee9240efd 100644
--- a/_maps/shuttles/independent/independent_lagoon.dmm
+++ b/_maps/shuttles/independent/independent_lagoon.dmm
@@ -2069,7 +2069,7 @@
pixel_y = 1
},
/obj/item/toy/cards/deck,
-/obj/item/reagent_containers/food/snacks/butterbiscuit{
+/obj/item/food/butterbiscuit{
pixel_x = 6;
pixel_y = 6
},
diff --git a/_maps/shuttles/independent/independent_tranquility.dmm b/_maps/shuttles/independent/independent_tranquility.dmm
index 08738bbe821f..641a74a202ef 100644
--- a/_maps/shuttles/independent/independent_tranquility.dmm
+++ b/_maps/shuttles/independent/independent_tranquility.dmm
@@ -2735,7 +2735,7 @@
/area/ship/crew/crewtwo)
"wA" = (
/obj/structure/table,
-/obj/item/reagent_containers/food/snacks/cakeslice/lime,
+/obj/item/food/cakeslice/lime,
/obj/item/kitchen/fork/plastic{
pixel_x = -11
},
@@ -3515,7 +3515,7 @@
/area/ship/crew/hydroponics)
"CH" = (
/obj/structure/table/wood,
-/obj/item/reagent_containers/food/snacks/garlicbread,
+/obj/item/food/garlicbread,
/obj/item/reagent_containers/food/snacks/grown/citrus/orange{
pixel_x = -8;
pixel_y = 7
@@ -6032,11 +6032,11 @@
pixel_x = -11;
pixel_y = 11
},
-/obj/item/reagent_containers/food/snacks/store/bread/banana{
+/obj/item/food/bread/banana{
pixel_x = 14;
pixel_y = 1
},
-/obj/item/reagent_containers/food/snacks/breadslice/banana,
+/obj/item/food/breadslice/banana,
/turf/open/floor/plasteel,
/area/ship/crew/cryo)
"Vg" = (
diff --git a/_maps/shuttles/solgov/solgov_inkwell.dmm b/_maps/shuttles/solgov/solgov_inkwell.dmm
index 86781cc2e251..cb683d981ab0 100644
--- a/_maps/shuttles/solgov/solgov_inkwell.dmm
+++ b/_maps/shuttles/solgov/solgov_inkwell.dmm
@@ -1848,10 +1848,10 @@
/area/ship/crew/canteen/kitchen)
"mz" = (
/obj/structure/closet/crate,
-/obj/item/reagent_containers/food/snacks/store/bread/plain,
-/obj/item/reagent_containers/food/snacks/store/bread/plain,
-/obj/item/reagent_containers/food/snacks/store/bread/plain,
-/obj/item/reagent_containers/food/snacks/store/bread/plain,
+/obj/item/food/bread/plain,
+/obj/item/food/bread/plain,
+/obj/item/food/bread/plain,
+/obj/item/food/bread/plain,
/obj/item/reagent_containers/food/drinks/waterbottle/large,
/obj/item/reagent_containers/food/drinks/waterbottle/large,
/obj/item/reagent_containers/food/drinks/waterbottle/large,
diff --git a/_maps/shuttles/solgov/solgov_paracelsus.dmm b/_maps/shuttles/solgov/solgov_paracelsus.dmm
index 1235af6da913..4700c74ee7b0 100644
--- a/_maps/shuttles/solgov/solgov_paracelsus.dmm
+++ b/_maps/shuttles/solgov/solgov_paracelsus.dmm
@@ -731,10 +731,10 @@
/area/ship/hallway/starboard)
"hh" = (
/obj/structure/closet/crate,
-/obj/item/reagent_containers/food/snacks/store/bread/plain,
-/obj/item/reagent_containers/food/snacks/store/bread/plain,
-/obj/item/reagent_containers/food/snacks/store/bread/plain,
-/obj/item/reagent_containers/food/snacks/store/bread/plain,
+/obj/item/food/bread/plain,
+/obj/item/food/bread/plain,
+/obj/item/food/bread/plain,
+/obj/item/food/bread/plain,
/obj/item/reagent_containers/food/drinks/waterbottle/large,
/obj/item/reagent_containers/food/drinks/waterbottle/large,
/obj/item/reagent_containers/food/drinks/waterbottle/large,
diff --git a/_maps/shuttles/syndicate/syndicate_panacea.dmm b/_maps/shuttles/syndicate/syndicate_panacea.dmm
index 702798048e53..4fdcc0741037 100644
--- a/_maps/shuttles/syndicate/syndicate_panacea.dmm
+++ b/_maps/shuttles/syndicate/syndicate_panacea.dmm
@@ -6072,7 +6072,7 @@
/area/ship/external/dark)
"JJ" = (
/obj/structure/table/wood,
-/obj/item/reagent_containers/food/snacks/store/cake/lemon{
+/obj/item/food/cake/lemon{
pixel_y = 5
},
/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer4{
diff --git a/code/__DEFINES/dcs/signals.dm b/code/__DEFINES/dcs/signals/signals.dm
similarity index 84%
rename from code/__DEFINES/dcs/signals.dm
rename to code/__DEFINES/dcs/signals/signals.dm
index d0038cf5277e..5552a60890d8 100644
--- a/code/__DEFINES/dcs/signals.dm
+++ b/code/__DEFINES/dcs/signals/signals.dm
@@ -158,6 +158,9 @@
///from internal loop in atom/movable/proc/CanReach(): (list/next)
#define COMSIG_ATOM_CANREACH "atom_can_reach"
#define COMPONENT_BLOCK_REACH 1
+///for when an atom has been created through processing (atom/original_atom, list/chosen_processing_option)
+#define COMSIG_ATOM_CREATEDBY_PROCESSING "atom_createdby_processing"
+
///from base of atom/screwdriver_act(): (mob/living/user, obj/item/I)
#define COMSIG_ATOM_SCREWDRIVER_ACT "atom_screwdriver_act"
///from base of atom/wrench_act(): (mob/living/user, obj/item/I)
@@ -172,7 +175,11 @@
#define COMSIG_ATOM_CROWBAR_ACT "atom_crowbar_act"
///from base of atom/analyser_act(): (mob/living/user, obj/item/I)
#define COMSIG_ATOM_ANALYSER_ACT "atom_analyser_act"
+
+///for any tool behaviors: (mob/living/user, obj/item/I, list/recipes)
+#define COMSIG_ATOM_TOOL_ACT(tooltype) "tool_act_[tooltype]"
#define COMPONENT_BLOCK_TOOL_ATTACK (1<<0)
+
///called when teleporting into a protected turf: (channel, turf/origin)
#define COMSIG_ATOM_INTERCEPT_TELEPORT "intercept_teleport"
#define COMPONENT_BLOCK_TELEPORT (1<<0)
@@ -182,6 +189,12 @@
#define COMSIG_ATOM_ORBIT_BEGIN "atom_orbit_begin"
///called when an atom stops orbiting another atom: (atom)
#define COMSIG_ATOM_ORBIT_STOP "atom_orbit_stop"
+/* Attack signals. They should share the returned flags, to standardize the attack chain. */
+/// tool_act -> pre_attack -> target.attackby (item.attack) -> afterattack
+ ///Ends the attack chain. If sent early might cause posterior attacks not to happen.
+ #define COMPONENT_CANCEL_ATTACK_CHAIN (1<<0)
+ ///Skips the specific attack step, continuing for the next one to happen.
+ #define COMPONENT_SKIP_ATTACK (1<<1)
///from base of atom/attack_ghost(): (mob/dead/observer/ghost)
#define COMSIG_ATOM_ATTACK_GHOST "atom_attack_ghost"
///from base of atom/attack_hand(): (mob/user)
@@ -498,84 +511,6 @@
#define COMSIG_HOSTILE_ATTACKINGTARGET "hostile_attackingtarget"
#define COMPONENT_HOSTILE_NO_ATTACK 1
-// /obj signals
-
-///from base of obj/deconstruct(): (disassembled)
-#define COMSIG_OBJ_DECONSTRUCT "obj_deconstruct"
-///from base of code/game/machinery
-#define COMSIG_OBJ_DEFAULT_UNFASTEN_WRENCH "obj_default_unfasten_wrench"
-///from base of /turf/proc/levelupdate(). (intact) true to hide and false to unhide
-#define COMSIG_OBJ_HIDE "obj_hide"
-
-// /obj/machinery signals
-
-///from /obj/machinery/obj_break(damage_flag): (damage_flag)
-#define COMSIG_MACHINERY_BROKEN "machinery_broken"
-///from base power_change() when power is lost
-#define COMSIG_MACHINERY_POWER_LOST "machinery_power_lost"
-///from base power_change() when power is restored
-#define COMSIG_MACHINERY_POWER_RESTORED "machinery_power_restored"
-
-// /obj/machinery/power/supermatter_crystal signals
-/// from /obj/machinery/power/supermatter_crystal/process_atmos(); when the SM delam reaches the point of sounding alarms
-#define COMSIG_SUPERMATTER_DELAM_START_ALARM "sm_delam_start_alarm"
-/// from /obj/machinery/power/supermatter_crystal/process_atmos(); when the SM sounds an audible alarm
-#define COMSIG_SUPERMATTER_DELAM_ALARM "sm_delam_alarm"
-
-// /obj/item signals
-#define COMSIG_ITEM_ATTACK "item_attack" //from base of obj/item/attack(): (/mob/living/target, /mob/living/user)
-#define COMSIG_ITEM_ATTACK_SELF "item_attack_self" //from base of obj/item/attack_self(): (/mob)
- #define COMPONENT_NO_INTERACT 1
-#define COMSIG_ITEM_ATTACK_OBJ "item_attack_obj" //from base of obj/item/attack_obj(): (/obj, /mob)
- #define COMPONENT_NO_ATTACK_OBJ 1
-#define COMSIG_ITEM_PRE_ATTACK "item_pre_attack" //from base of obj/item/pre_attack(): (atom/target, mob/user, params)
- #define COMPONENT_NO_ATTACK 1
-#define COMSIG_ITEM_AFTERATTACK "item_afterattack" //from base of obj/item/afterattack(): (atom/target, mob/user, params)
-#define COMSIG_ITEM_ATTACK_QDELETED "item_attack_qdeleted" //from base of obj/item/attack_qdeleted(): (atom/target, mob/user, params)
-#define COMSIG_ITEM_EQUIPPED "item_equip" //from base of obj/item/equipped(): (/mob/equipper, slot)
-#define COMSIG_ITEM_DROPPED "item_drop" //from base of obj/item/dropped(): (mob/user)
-#define COMSIG_ITEM_PICKUP "item_pickup" //from base of obj/item/pickup(): (/mob/taker)
-#define COMSIG_ITEM_ATTACK_ZONE "item_attack_zone" //from base of mob/living/carbon/attacked_by(): (mob/living/carbon/target, mob/living/user, hit_zone)
-#define COMSIG_ITEM_IMBUE_SOUL "item_imbue_soul" //return a truthy value to prevent ensouling, checked in /obj/effect/proc_holder/spell/targeted/lichdom/cast(): (mob/user)
-#define COMSIG_ITEM_MARK_RETRIEVAL "item_mark_retrieval" //called before marking an object for retrieval, checked in /obj/effect/proc_holder/spell/targeted/summonitem/cast() : (mob/user)
- #define COMPONENT_BLOCK_MARK_RETRIEVAL 1
-#define COMSIG_ITEM_HIT_REACT "item_hit_react" //from base of obj/item/hit_reaction(): (list/args)
-#define COMSIG_ITEM_WEARERCROSSED "wearer_crossed" //called on item when crossed by something (): (/atom/movable, mob/living/crossed)
-#define COMSIG_ITEM_MICROWAVE_ACT "microwave_act" //called on item when microwaved (): (obj/machinery/microwave/M)
-#define COMSIG_ITEM_SHARPEN_ACT "sharpen_act" //from base of item/sharpener/attackby(): (amount, max)
- #define COMPONENT_BLOCK_SHARPEN_APPLIED 1
- #define COMPONENT_BLOCK_SHARPEN_BLOCKED 2
- #define COMPONENT_BLOCK_SHARPEN_ALREADY 4
- #define COMPONENT_BLOCK_SHARPEN_MAXED 8
-#define COMSIG_TOOL_IN_USE "tool_in_use" ///from base of [/obj/item/proc/tool_check_callback]: (mob/living/user)
-#define COMSIG_TOOL_START_USE "tool_start_use" ///from base of [/obj/item/proc/tool_start_check]: (mob/living/user)
-#define COMSIG_ITEM_DISABLE_EMBED "item_disable_embed" ///from [/obj/item/proc/disableEmbedding]:
-#define COMSIG_MINE_TRIGGERED "minegoboom" ///from [/obj/item/mine/proc/trigger_mine]:
-///from [/obj/structure/closet/supplypod/proc/endlaunch]:
-#define COMSIG_SUPPLYPOD_LANDED "supplypodgoboom"
-
-// Item mouse siganls
-#define COMSIG_ITEM_MOUSE_EXIT "item_mouse_exit" //from base of obj/item/MouseExited(): (location, control, params)
-#define COMSIG_ITEM_MOUSE_ENTER "item_mouse_enter" //from base of obj/item/MouseEntered(): (location, control, params)
-
-///Called when an item is being offered, from [/obj/item/proc/on_offered(mob/living/carbon/offerer)]
-#define COMSIG_ITEM_OFFERING "item_offering"
- ///Interrupts the offer proc
- #define COMPONENT_OFFER_INTERRUPT (1<<0)
-///Called when an someone tries accepting an offered item, from [/obj/item/proc/on_offer_taken(mob/living/carbon/offerer, mob/living/carbon/taker)]
-#define COMSIG_ITEM_OFFER_TAKEN "item_offer_taken"
- ///Interrupts the offer acceptance
- #define COMPONENT_OFFER_TAKE_INTERRUPT (1<<0)
-/// sent from obj/effect/attackby(): (/obj/effect/hit_effect, /mob/living/attacker, params)
-#define COMSIG_ITEM_ATTACK_EFFECT "item_effect_attacked"
-
-// /obj/item signals for economy
-#define COMSIG_ITEM_SOLD "item_sold" //called when an item is sold by the exports subsystem
-#define COMSIG_STRUCTURE_UNWRAPPED "structure_unwrapped" //called when a wrapped up structure is opened by hand
-#define COMSIG_ITEM_UNWRAPPED "item_unwrapped" //called when a wrapped up item is opened by hand
- #define COMSIG_ITEM_SPLIT_VALUE 1
-#define COMSIG_ITEM_SPLIT_PROFIT "item_split_profits" //Called when getting the item's exact ratio for cargo's profit.
-#define COMSIG_ITEM_SPLIT_PROFIT_DRY "item_split_profits_dry" //Called when getting the item's exact ratio for cargo's profit, without selling the item.
/// Admin helps
/// From /datum/admin_help/RemoveActive().
@@ -585,21 +520,6 @@
/// Called when the player replies. From /client/proc/cmd_admin_pm().
#define COMSIG_ADMIN_HELP_REPLIED "admin_help_replied"
-// /obj/item/clothing signals
-#define COMSIG_SHOES_STEP_ACTION "shoes_step_action" //from base of obj/item/clothing/shoes/proc/step_action(): ()
-#define COMSIG_SUIT_SPACE_TOGGLE "suit_space_toggle" //from base of /obj/item/clothing/suit/space/proc/toggle_spacesuit(): (obj/item/clothing/suit/space/suit)
-
-// /obj/item/implant signals
-#define COMSIG_IMPLANT_ACTIVATED "implant_activated" //from base of /obj/item/implant/proc/activate(): ()
-#define COMSIG_IMPLANT_IMPLANTING "implant_implanting" //from base of /obj/item/implant/proc/implant(): (list/args)
- #define COMPONENT_STOP_IMPLANTING 1
-#define COMSIG_IMPLANT_OTHER "implant_other" //called on already installed implants when a new one is being added in /obj/item/implant/proc/implant(): (list/args, obj/item/implant/new_implant)
- //#define COMPONENT_STOP_IMPLANTING 1 //The name makes sense for both
- #define COMPONENT_DELETE_NEW_IMPLANT 2
- #define COMPONENT_DELETE_OLD_IMPLANT 4
-#define COMSIG_IMPLANT_EXISTING_UPLINK "implant_uplink_exists" //called on implants being implanted into someone with an uplink implant: (datum/component/uplink)
- //This uses all return values of COMSIG_IMPLANT_OTHER
-
// /obj/item/pda signals
#define COMSIG_PDA_CHANGE_RINGTONE "pda_change_ringtone" //called on pda when the user changes the ringtone: (mob/living/user, new_ringtone)
#define COMPONENT_STOP_RINGTONE_CHANGE 1
@@ -615,10 +535,6 @@
// /obj/item/gun signals
#define COMSIG_MOB_FIRED_GUN "mob_fired_gun" //called in /obj/item/gun/process_fire (user, target, params, zone_override)
-// /obj/item/grenade signals
-#define COMSIG_GRENADE_PRIME "grenade_prime" //called in /obj/item/gun/process_fire (user, target, params, zone_override)
-#define COMSIG_GRENADE_ARMED "grenade_armed" //called in /obj/item/gun/process_fire (user, target, params, zone_override)
-
// /obj/projectile signals (sent to the firer)
#define COMSIG_PROJECTILE_SELF_ON_HIT "projectile_self_on_hit" // from base of /obj/projectile/proc/on_hit(): (atom/movable/firer, atom/target, Angle)
#define COMSIG_PROJECTILE_ON_HIT "projectile_on_hit" // from base of /obj/projectile/proc/on_hit(): (atom/movable/firer, atom/target, Angle)
@@ -665,9 +581,6 @@
//Creamed
#define COMSIG_COMPONENT_CLEAN_FACE_ACT "clean_face_act" //called when you wash your face at a sink: (num/strength)
-//Food
-#define COMSIG_FOOD_EATEN "food_eaten" //from base of obj/item/reagent_containers/food/snacks/attack(): (mob/living/eater, mob/feeder)
-
//Gibs
#define COMSIG_GIBS_STREAK "gibs_streak" // from base of /obj/effect/decal/cleanable/blood/gibs/streak(): (list/directions, list/diseases)
@@ -753,10 +666,6 @@
#define COMSIG_BEAM_BEFORE_DRAW "beam_before_draw"
#define BEAM_CANCEL_DRAW (1 << 0)
-// Aquarium related signals
-#define COMSIG_AQUARIUM_SURFACE_CHANGED "aquarium_surface_changed"
-#define COMSIG_AQUARIUM_FLUID_CHANGED "aquarium_fluid_changed"
-
// Fish signals
#define COMSIG_FISH_STATUS_CHANGED "fish_status_changed"
#define COMSIG_FISH_STIRRED "fish_stirred"
diff --git a/code/__DEFINES/dcs/signals/signals_obj/signals_item/signals_clothing.dm b/code/__DEFINES/dcs/signals/signals_obj/signals_item/signals_clothing.dm
new file mode 100644
index 000000000000..6eb107d55fda
--- /dev/null
+++ b/code/__DEFINES/dcs/signals/signals_obj/signals_item/signals_clothing.dm
@@ -0,0 +1,10 @@
+// Format:
+// When the signal is called: (signal arguments)
+// All signals send the source datum of the signal as the first argument
+
+// /obj/item/clothing signals
+
+//from base of obj/item/clothing/shoes/proc/step_action(): ()
+#define COMSIG_SHOES_STEP_ACTION "shoes_step_action"
+//from base of /obj/item/clothing/suit/space/proc/toggle_spacesuit(): (obj/item/clothing/suit/space/suit)
+#define COMSIG_SUIT_SPACE_TOGGLE "suit_space_toggle"
diff --git a/code/__DEFINES/dcs/signals/signals_obj/signals_item/signals_food.dm b/code/__DEFINES/dcs/signals/signals_obj/signals_item/signals_food.dm
new file mode 100644
index 000000000000..831363f5a523
--- /dev/null
+++ b/code/__DEFINES/dcs/signals/signals_obj/signals_item/signals_food.dm
@@ -0,0 +1,22 @@
+// Eating stuff
+/// From datum/component/edible/proc/TakeBite: (mob/living/eater, mob/feeder, bitecount, bitesize)
+#define COMSIG_FOOD_EATEN "food_eaten"
+/// From base of Component/edible/On_Consume: (mob/living/eater, mob/living/feeder)
+#define COMSIG_FOOD_CONSUMED "food_consumed"
+
+// Deep frying foods
+/// An item becomes fried - From /datum/element/fried_item/Attach: (fry_time)
+#define COMSIG_ITEM_FRIED "item_fried"
+ #define COMSIG_FRYING_HANDLED (1<<0)
+
+// Microwaving foods
+///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 /datum/component/edible/on_compost(source, /mob/living/user)
+#define COMSIG_EDIBLE_ON_COMPOST "on_compost"
+ // Used to stop food from being composted.
+ #define COMPONENT_EDIBLE_BLOCK_COMPOST 1
diff --git a/code/__DEFINES/dcs/signals/signals_obj/signals_item/signals_grenade.dm b/code/__DEFINES/dcs/signals/signals_obj/signals_item/signals_grenade.dm
new file mode 100644
index 000000000000..03767ecbc53f
--- /dev/null
+++ b/code/__DEFINES/dcs/signals/signals_obj/signals_item/signals_grenade.dm
@@ -0,0 +1,11 @@
+// Format:
+// When the signal is called: (signal arguments)
+// All signals send the source datum of the signal as the first argument
+
+// /obj/item/grenade signals
+
+//called in /obj/item/gun/process_fire (user, target, params, zone_override)
+#define COMSIG_GRENADE_PRIME "grenade_prime"
+
+//called in /obj/item/gun/process_fire (user, target, params, zone_override)
+#define COMSIG_GRENADE_ARMED "grenade_armed"
diff --git a/code/__DEFINES/dcs/signals/signals_obj/signals_item/signals_implant.dm b/code/__DEFINES/dcs/signals/signals_obj/signals_item/signals_implant.dm
new file mode 100644
index 000000000000..95123ef8b309
--- /dev/null
+++ b/code/__DEFINES/dcs/signals/signals_obj/signals_item/signals_implant.dm
@@ -0,0 +1,14 @@
+// Format:
+// When the signal is called: (signal arguments)
+// All signals send the source datum of the signal as the first argument
+
+// /obj/item/implant signals
+#define COMSIG_IMPLANT_ACTIVATED "implant_activated" //from base of /obj/item/implant/proc/activate(): ()
+#define COMSIG_IMPLANT_IMPLANTING "implant_implanting" //from base of /obj/item/implant/proc/implant(): (list/args)
+ #define COMPONENT_STOP_IMPLANTING 1
+#define COMSIG_IMPLANT_OTHER "implant_other" //called on already installed implants when a new one is being added in /obj/item/implant/proc/implant(): (list/args, obj/item/implant/new_implant)
+ //#define COMPONENT_STOP_IMPLANTING 1 //The name makes sense for both
+ #define COMPONENT_DELETE_NEW_IMPLANT 2
+ #define COMPONENT_DELETE_OLD_IMPLANT 4
+#define COMSIG_IMPLANT_EXISTING_UPLINK "implant_uplink_exists" //called on implants being implanted into someone with an uplink implant: (datum/component/uplink)
+ //This uses all return values of COMSIG_IMPLANT_OTHER
diff --git a/code/__DEFINES/dcs/signals/signals_obj/signals_item/signals_item.dm b/code/__DEFINES/dcs/signals/signals_obj/signals_item/signals_item.dm
new file mode 100644
index 000000000000..536efc724f92
--- /dev/null
+++ b/code/__DEFINES/dcs/signals/signals_obj/signals_item/signals_item.dm
@@ -0,0 +1,67 @@
+// Format:
+// When the signal is called: (signal arguments)
+// All signals send the source datum of the signal as the first argument
+
+// /obj/item signals
+///from base of obj/item/equipped(): (/mob/equipper, slot)
+#define COMSIG_ITEM_EQUIPPED "item_equip"
+///from base of obj/item/dropped(): (mob/user)
+#define COMSIG_ITEM_DROPPED "item_drop"
+///from base of obj/item/pickup(): (/mob/taker)
+#define COMSIG_ITEM_PICKUP "item_pickup"
+
+///from base of mob/living/carbon/attacked_by(): (mob/living/carbon/target, mob/living/user, hit_zone)
+#define COMSIG_ITEM_ATTACK_ZONE "item_attack_zone"
+///from base of obj/item/hit_reaction(): (list/args)
+#define COMSIG_ITEM_HIT_REACT "item_hit_react"
+
+#define COMSIG_ITEM_ATTACK "item_attack" //from base of obj/item/attack(): (/mob/living/target, /mob/living/user)
+#define COMSIG_ITEM_ATTACK_SELF "item_attack_self" //from base of obj/item/attack_self(): (/mob)
+ #define COMPONENT_NO_INTERACT 1
+#define COMSIG_ITEM_ATTACK_OBJ "item_attack_obj" //from base of obj/item/attack_obj(): (/obj, /mob)
+ #define COMPONENT_NO_ATTACK_OBJ 1
+#define COMSIG_ITEM_PRE_ATTACK "item_pre_attack" //from base of obj/item/pre_attack(): (atom/target, mob/user, params)
+ #define COMPONENT_NO_ATTACK 1
+#define COMSIG_ITEM_AFTERATTACK "item_afterattack" //from base of obj/item/afterattack(): (atom/target, mob/user, params)
+#define COMSIG_ITEM_ATTACK_QDELETED "item_attack_qdeleted" //from base of obj/item/attack_qdeleted(): (atom/target, mob/user, params)
+#define COMSIG_ITEM_IMBUE_SOUL "item_imbue_soul" //return a truthy value to prevent ensouling, checked in /obj/effect/proc_holder/spell/targeted/lichdom/cast(): (mob/user)
+#define COMSIG_ITEM_MARK_RETRIEVAL "item_mark_retrieval" //called before marking an object for retrieval, checked in /obj/effect/proc_holder/spell/targeted/summonitem/cast() : (mob/user)
+ #define COMPONENT_BLOCK_MARK_RETRIEVAL 1
+#define COMSIG_ITEM_WEARERCROSSED "wearer_crossed" //called on item when crossed by something (): (/atom/movable, mob/living/crossed)
+
+///from base of item/sharpener/attackby(): (amount, max)
+#define COMSIG_ITEM_SHARPEN_ACT "sharpen_act"
+ #define COMPONENT_BLOCK_SHARPEN_APPLIED 1
+ #define COMPONENT_BLOCK_SHARPEN_BLOCKED 2
+ #define COMPONENT_BLOCK_SHARPEN_ALREADY 4
+ #define COMPONENT_BLOCK_SHARPEN_MAXED 8
+
+#define COMSIG_TOOL_IN_USE "tool_in_use" ///from base of [/obj/item/proc/tool_check_callback]: (mob/living/user)
+#define COMSIG_TOOL_START_USE "tool_start_use" ///from base of [/obj/item/proc/tool_start_check]: (mob/living/user)
+#define COMSIG_ITEM_DISABLE_EMBED "item_disable_embed" ///from [/obj/item/proc/disableEmbedding]:
+#define COMSIG_MINE_TRIGGERED "minegoboom" ///from [/obj/item/mine/proc/trigger_mine]:
+///from [/obj/structure/closet/supplypod/proc/endlaunch]:
+#define COMSIG_SUPPLYPOD_LANDED "supplypodgoboom"
+
+// Item mouse siganls
+#define COMSIG_ITEM_MOUSE_EXIT "item_mouse_exit" //from base of obj/item/MouseExited(): (location, control, params)
+#define COMSIG_ITEM_MOUSE_ENTER "item_mouse_enter" //from base of obj/item/MouseEntered(): (location, control, params)
+
+///Called when an item is being offered, from [/obj/item/proc/on_offered(mob/living/carbon/offerer)]
+#define COMSIG_ITEM_OFFERING "item_offering"
+ ///Interrupts the offer proc
+ #define COMPONENT_OFFER_INTERRUPT (1<<0)
+///Called when an someone tries accepting an offered item, from [/obj/item/proc/on_offer_taken(mob/living/carbon/offerer, mob/living/carbon/taker)]
+#define COMSIG_ITEM_OFFER_TAKEN "item_offer_taken"
+ ///Interrupts the offer acceptance
+ #define COMPONENT_OFFER_TAKE_INTERRUPT (1<<0)
+/// sent from obj/effect/attackby(): (/obj/effect/hit_effect, /mob/living/attacker, params)
+#define COMSIG_ITEM_ATTACK_EFFECT "item_effect_attacked"
+
+// /obj/item signals for economy
+#define COMSIG_ITEM_SOLD "item_sold" //called when an item is sold by the exports subsystem
+#define COMSIG_STRUCTURE_UNWRAPPED "structure_unwrapped" //called when a wrapped up structure is opened by hand
+#define COMSIG_ITEM_UNWRAPPED "item_unwrapped" //called when a wrapped up item is opened by hand
+ #define COMSIG_ITEM_SPLIT_VALUE 1
+#define COMSIG_ITEM_SPLIT_PROFIT "item_split_profits" //Called when getting the item's exact ratio for cargo's profit.
+#define COMSIG_ITEM_SPLIT_PROFIT_DRY "item_split_profits_dry" //Called when getting the item's exact ratio for cargo's profit, without selling the item.
diff --git a/code/__DEFINES/dcs/signals/signals_obj/signals_machine/signals_aquarium.dm b/code/__DEFINES/dcs/signals/signals_obj/signals_machine/signals_aquarium.dm
new file mode 100644
index 000000000000..d4c88d7c16b2
--- /dev/null
+++ b/code/__DEFINES/dcs/signals/signals_obj/signals_machine/signals_aquarium.dm
@@ -0,0 +1,7 @@
+// Format:
+// When the signal is called: (signal arguments)
+// All signals send the source datum of the signal as the first argument
+
+// Aquarium related signals
+#define COMSIG_AQUARIUM_SURFACE_CHANGED "aquarium_surface_changed"
+#define COMSIG_AQUARIUM_FLUID_CHANGED "aquarium_fluid_changed"
diff --git a/code/__DEFINES/dcs/signals/signals_obj/signals_machine/signals_machinery.dm b/code/__DEFINES/dcs/signals/signals_obj/signals_machine/signals_machinery.dm
new file mode 100644
index 000000000000..929a2f844074
--- /dev/null
+++ b/code/__DEFINES/dcs/signals/signals_obj/signals_machine/signals_machinery.dm
@@ -0,0 +1,12 @@
+// Format:
+// When the signal is called: (signal arguments)
+// All signals send the source datum of the signal as the first argument
+
+// /obj/machinery signals
+
+///from /obj/machinery/obj_break(damage_flag): (damage_flag)
+#define COMSIG_MACHINERY_BROKEN "machinery_broken"
+///from base power_change() when power is lost
+#define COMSIG_MACHINERY_POWER_LOST "machinery_power_lost"
+///from base power_change() when power is restored
+#define COMSIG_MACHINERY_POWER_RESTORED "machinery_power_restored"
diff --git a/code/__DEFINES/dcs/signals/signals_obj/signals_machine/signals_supermatter.dm b/code/__DEFINES/dcs/signals/signals_obj/signals_machine/signals_supermatter.dm
new file mode 100644
index 000000000000..b4e8abe2b80b
--- /dev/null
+++ b/code/__DEFINES/dcs/signals/signals_obj/signals_machine/signals_supermatter.dm
@@ -0,0 +1,9 @@
+// Format:
+// When the signal is called: (signal arguments)
+// All signals send the source datum of the signal as the first argument
+
+// /obj/machinery/power/supermatter_crystal signals
+/// from /obj/machinery/power/supermatter_crystal/process_atmos(); when the SM delam reaches the point of sounding alarms
+#define COMSIG_SUPERMATTER_DELAM_START_ALARM "sm_delam_start_alarm"
+/// from /obj/machinery/power/supermatter_crystal/process_atmos(); when the SM sounds an audible alarm
+#define COMSIG_SUPERMATTER_DELAM_ALARM "sm_delam_alarm"
diff --git a/code/__DEFINES/dcs/signals/signals_obj/signals_object.dm b/code/__DEFINES/dcs/signals/signals_obj/signals_object.dm
new file mode 100644
index 000000000000..137925811720
--- /dev/null
+++ b/code/__DEFINES/dcs/signals/signals_obj/signals_object.dm
@@ -0,0 +1,12 @@
+// Format:
+// When the signal is called: (signal arguments)
+// All signals send the source datum of the signal as the first argument
+
+// /obj signals
+
+///from base of obj/deconstruct(): (disassembled)
+#define COMSIG_OBJ_DECONSTRUCT "obj_deconstruct"
+///from base of code/game/machinery
+#define COMSIG_OBJ_DEFAULT_UNFASTEN_WRENCH "obj_default_unfasten_wrench"
+///from base of /turf/proc/levelupdate(). (intact) true to hide and false to unhide
+#define COMSIG_OBJ_HIDE "obj_hide"
diff --git a/code/__DEFINES/food.dm b/code/__DEFINES/food.dm
index f2b6a8fd196d..a12ceca284dd 100644
--- a/code/__DEFINES/food.dm
+++ b/code/__DEFINES/food.dm
@@ -49,6 +49,16 @@
#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)
#define STOP_SERVING_BREAKFAST (15 MINUTES)
+
+///Amount of reagents you start with on crafted food excluding the used parts
+#define CRAFTED_FOOD_BASE_REAGENT_MODIFIER 0.7
+///Modifier of reagents you get when crafting food from the parts used
+#define CRAFTED_FOOD_INGREDIENT_REAGENT_MODIFIER 0.5
+
+#define IS_EDIBLE(O) (O.GetComponent(/datum/component/edible))
diff --git a/code/__DEFINES/processing.dm b/code/__DEFINES/processing.dm
new file mode 100644
index 000000000000..905c03830d51
--- /dev/null
+++ b/code/__DEFINES/processing.dm
@@ -0,0 +1,3 @@
+#define TOOL_PROCESSING_RESULT "result"
+#define TOOL_PROCESSING_AMOUNT "amount"
+#define TOOL_PROCESSING_TIME "time"
diff --git a/code/__DEFINES/tools.dm b/code/__DEFINES/tools.dm
index 320648170b44..35860ac927f4 100644
--- a/code/__DEFINES/tools.dm
+++ b/code/__DEFINES/tools.dm
@@ -14,6 +14,7 @@
#define TOOL_DRILL "drill"
#define TOOL_SCALPEL "scalpel"
#define TOOL_SAW "saw"
+#define TOOL_KNIFE "knife" //luv me kuh-nyfe
// If delay between the start and the end of tool operation is less than MIN_TOOL_SOUND_DELAY,
// tool sound is only played when op is started. If not, it's played twice.
diff --git a/code/__HELPERS/unsorted.dm b/code/__HELPERS/unsorted.dm
index d6b048de4289..185c6c595b80 100644
--- a/code/__HELPERS/unsorted.dm
+++ b/code/__HELPERS/unsorted.dm
@@ -1425,10 +1425,15 @@ GLOBAL_DATUM_INIT(dview_mob, /mob/dview, new)
REMOVE_TRAIT(the_atom2,trait,source)
/proc/get_random_food()
- var/list/blocked = list(/obj/item/reagent_containers/food/snacks/store/bread,
- /obj/item/reagent_containers/food/snacks/breadslice,
- /obj/item/reagent_containers/food/snacks/store/cake,
- /obj/item/reagent_containers/food/snacks/cakeslice,
+ var/static/list/allowed_food = list()
+
+ if(!LAZYLEN(allowed_food)) //it's static so we only ever do this once
+ var/list/blocked = list(
+ /obj/item/food/spaghetti,
+ /obj/item/food/bread,
+ /obj/item/food/breadslice,
+ /obj/item/food/cake,
+ /obj/item/food/cakeslice,
/obj/item/reagent_containers/food/snacks/store,
/obj/item/reagent_containers/food/snacks/pie,
/obj/item/reagent_containers/food/snacks/kebab,
@@ -1440,15 +1445,21 @@ GLOBAL_DATUM_INIT(dview_mob, /mob/dview, new)
/obj/item/reagent_containers/food/snacks/soup,
/obj/item/reagent_containers/food/snacks/grown,
/obj/item/reagent_containers/food/snacks/grown/mushroom,
- /obj/item/reagent_containers/food/snacks/deepfryholder,
+ /obj/item/food/deepfryholder,
/obj/item/reagent_containers/food/snacks/clothing,
/obj/item/reagent_containers/food/snacks/grown/shell, //base types
- /obj/item/reagent_containers/food/snacks/store/bread,
+ /obj/item/food/bread,
/obj/item/reagent_containers/food/snacks/grown/nettle
)
- blocked |= typesof(/obj/item/reagent_containers/food/snacks/customizable)
+ blocked |= typesof(/obj/item/reagent_containers/food/snacks/customizable)
- return pick(subtypesof(/obj/item/reagent_containers/food/snacks) - blocked)
+ var/list/unfiltered_allowed_food = subtypesof(/obj/item/food) - blocked
+ for(var/obj/item/food/food as anything in unfiltered_allowed_food)
+ if(!initial(food.icon_state)) //food with no icon_state should probably not be spawned
+ continue
+ allowed_food.Add(food)
+
+ return pick(allowed_food)
/proc/get_random_drink()
var/list/blocked = list(/obj/item/reagent_containers/food/drinks/soda_cans,
diff --git a/code/datums/components/edible.dm b/code/datums/components/edible.dm
deleted file mode 100644
index b65a2d8b7e32..000000000000
--- a/code/datums/components/edible.dm
+++ /dev/null
@@ -1,259 +0,0 @@
-/*!
-
-This component makes it possible to make things edible. What this means is that you can take a bite or force someone to take a bite (in the case of items).
-These items take a specific time to eat, and can do most of the things our original food items could.
-
-Behavior that's still missing from this component that original food items had that should either be put into seperate components or somewhere else:
- Components:
- Drying component (jerky etc)
- Customizable component (custom pizzas etc)
- Processable component (Slicing and cooking behavior essentialy, making it go from item A to B when conditions are met.)
- Dunkable component (Dunking things into reagent containers to absorb a specific amount of reagents)
-
- Misc:
- Something for cakes (You can store things inside)
-
-*/
-/datum/component/edible
- ///Amount of reagents taken per bite
- var/bite_consumption = 2
- ///Amount of bites taken so far
- var/bitecount = 0
- ///Flags for food
- var/food_flags = NONE
- ///Bitfield of the types of this food
- var/foodtypes = NONE
- ///Amount of seconds it takes to eat this food
- var/eat_time = 30
- ///Defines how much it lowers someones satiety (Need to eat, essentialy)
- var/junkiness = 0
- ///Message to send when eating
- var/list/eatverbs
- ///Callback to be ran for when you take a bite of something
- var/datum/callback/after_eat
- ///Last time we checked for food likes
- var/last_check_time
- ///Color we use when stuffed in things
- var/filling_color = "#FFFFFF"
-
-/datum/component/edible/Initialize(list/initial_reagents, food_flags = NONE, foodtypes = NONE, volume = 50, eat_time = 30, list/tastes, list/eatverbs = list("bite","chew","nibble","gnaw","gobble","chomp"), bite_consumption = 2, filling_color = "#FFFFFF", datum/callback/after_eat)
- if(!isatom(parent))
- return COMPONENT_INCOMPATIBLE
-
- RegisterSignal(parent, COMSIG_PARENT_EXAMINE, PROC_REF(examine))
- RegisterSignal(parent, COMSIG_ATOM_ATTACK_ANIMAL, PROC_REF(UseByAnimal))
- if(isitem(parent))
- RegisterSignal(parent, COMSIG_ITEM_ATTACK, PROC_REF(UseFromHand))
- else if(isturf(parent))
- RegisterSignal(parent, COMSIG_ATOM_ATTACK_HAND, PROC_REF(TryToEatTurf))
-
- 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.filling_color = filling_color
-
- var/atom/owner = parent
-
- owner.create_reagents(volume, INJECTABLE)
-
- if(initial_reagents)
- for(var/rid in initial_reagents)
- var/amount = initial_reagents[rid]
- if(tastes && tastes.len && (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(!(food_flags & FOOD_IN_CONTAINER))
- switch (bitecount)
- if (0)
- return
- if(1)
- examine_list += "[parent] was bitten by someone!"
- if(2,3)
- examine_list += "[parent] was bitten [bitecount] times!"
- else
- examine_list += "[parent] was bitten multiple times!"
-
-/datum/component/edible/proc/UseFromHand(obj/item/source, mob/living/M, mob/living/user)
- SIGNAL_HANDLER
-
- return TryToEat(M, user)
-
-/datum/component/edible/proc/TryToEatTurf(datum/source, mob/user)
- SIGNAL_HANDLER
-
- return TryToEat(user, user)
-
-///All the checks for the act of eating itself and
-/datum/component/edible/proc/TryToEat(mob/living/eater, mob/living/feeder)
-
- set waitfor = FALSE
-
- var/atom/owner = parent
-
- if(feeder.a_intent == INTENT_HARM)
- return
- if(!owner.reagents.total_volume)//Shouldn't be needed but it checks to see if it has anything left in it.
- to_chat(feeder, "None of [owner] left, oh no!")
- if(isturf(parent))
- var/turf/T = parent
- T.ScrapeAway(1, CHANGETURF_INHERIT_AIR)
- else
- qdel(parent)
- return
- if(!CanConsume(eater, feeder))
- return
- var/fullness = eater.nutrition + 10 //The theoretical fullness of the person eating if they were to eat this
- for(var/datum/reagent/consumable/C in eater.reagents.reagent_list) //we add the nutrition value of what we're currently digesting
- fullness += C.nutriment_factor * C.volume / C.metabolization_rate
-
- . = COMPONENT_ITEM_NO_ATTACK //Point of no return I suppose
-
- if(eater == feeder)//If you're eating it yourself.
- if(!do_after(feeder, eat_time, eater)) //Gotta pass the minimal eat time
- return
- var/eatverb = pick(eatverbs)
- if(junkiness && eater.satiety < -150 && eater.nutrition > NUTRITION_LEVEL_STARVING + 50 && !HAS_TRAIT(eater, TRAIT_VORACIOUS))
- to_chat(eater, "You don't feel like eating any more junk food at the moment!")
- return
- else if(fullness <= 50)
- eater.visible_message("[eater] hungrily [eatverb]s \the [parent], gobbling it down!", "You hungrily [eatverb] \the [parent], gobbling it down!")
- else if(fullness > 50 && fullness < 150)
- eater.visible_message("[eater] hungrily [eatverb]s \the [parent].", "You hungrily [eatverb] \the [parent].")
- else if(fullness > 150 && fullness < 500)
- eater.visible_message("[eater] [eatverb]s \the [parent].", "You [eatverb] \the [parent].")
- else if(fullness > 500 && fullness < 600)
- eater.visible_message("[eater] unwillingly [eatverb]s a bit of \the [parent].", "You unwillingly [eatverb] a bit of \the [parent].")
- else if(fullness > (600 * (1 + eater.overeatduration / 2000))) // The more you eat - the more you can eat
- eater.visible_message("[eater] cannot force any more of \the [parent] to go down [eater.p_their()] throat!", "You cannot force any more of \the [parent] to go down your throat!")
- return
- else //If you're feeding it to someone else.
- if(isbrain(eater))
- to_chat(feeder, "[eater] doesn't seem to have a mouth!")
- return
- if(fullness <= (600 * (1 + eater.overeatduration / 1000)))
- eater.visible_message("[feeder] attempts to feed [eater] [parent].", \
- "[feeder] attempts to feed you [parent].")
- else
- eater.visible_message("[feeder] cannot force any more of [parent] down [eater]'s throat!", \
- "[feeder] cannot force any more of [parent] down your throat!")
- return
- if(!do_after(feeder, target = eater)) //Wait 3 seconds before you can feed
- return
-
- log_combat(feeder, eater, "fed", owner.reagents.log_list())
- eater.visible_message("[feeder] forces [eater] to eat [parent]!", \
- "[feeder] forces you to eat [parent]!")
-
- TakeBite(eater, feeder)
-
-///This function lets the eater take a bite and transfers the reagents to the eater.
-/datum/component/edible/proc/TakeBite(mob/living/eater, mob/living/feeder)
-
- var/atom/owner = parent
-
- if(!owner?.reagents)
- return FALSE
- if(eater.satiety > -200)
- eater.satiety -= junkiness
- playsound(eater.loc,'sound/items/eatfood.ogg', rand(10,50), TRUE)
- if(owner.reagents.total_volume)
- SEND_SIGNAL(parent, COMSIG_FOOD_EATEN, eater, feeder)
- var/fraction = min(bite_consumption / owner.reagents.total_volume, 1)
- owner.reagents.trans_to(eater, bite_consumption, transfered_by = feeder, method = INGEST)
- bitecount++
- On_Consume(eater)
- checkLiked(fraction, eater)
-
- //Invoke our after eat callback if it is valid
- if(after_eat)
- after_eat.Invoke(eater, feeder)
-
- return TRUE
-
-///Checks whether or not the eater can actually consume the food
-/datum/component/edible/proc/CanConsume(mob/living/eater, mob/living/feeder)
- if(!iscarbon(eater))
- return FALSE
- var/mob/living/carbon/C = eater
- var/covered = ""
- if(C.is_mouth_covered(head_only = 1))
- covered = "headgear"
- else if(C.is_mouth_covered(mask_only = 1))
- covered = "mask"
- if(covered)
- var/who = (isnull(feeder) || eater == feeder) ? "your" : "[eater.p_their()]"
- to_chat(feeder, "You have to remove [who] [covered] first!")
- return FALSE
- return TRUE
-
-///Check foodtypes to see if we should send a moodlet
-/datum/component/edible/proc/checkLiked(fraction, mob/M)
- if(last_check_time + 50 > world.time)
- return FALSE
- if(!ishuman(M))
- return FALSE
- var/mob/living/carbon/human/H = M
- if(HAS_TRAIT(H, TRAIT_AGEUSIA) && foodtypes & H.dna.species.toxic_food)
- to_chat(H, "You don't feel so good...")
- H.adjust_disgust(25 + 30 * fraction)
- else
- if(foodtypes & H.dna.species.toxic_food)
- to_chat(H,"What the hell was that thing?!")
- H.adjust_disgust(25 + 30 * fraction)
- SEND_SIGNAL(H, COMSIG_ADD_MOOD_EVENT, "toxic_food", /datum/mood_event/disgusting_food)
- else if(foodtypes & H.dna.species.disliked_food)
- to_chat(H,"That didn't taste very good...")
- H.adjust_disgust(11 + 15 * fraction)
- SEND_SIGNAL(H, COMSIG_ADD_MOOD_EVENT, "gross_food", /datum/mood_event/gross_food)
- else if(foodtypes & H.dna.species.liked_food)
- to_chat(H,"I love this taste!")
- H.adjust_disgust(-5 + -2.5 * fraction)
- SEND_SIGNAL(H, COMSIG_ADD_MOOD_EVENT, "fav_food", /datum/mood_event/favorite_food)
- if((foodtypes & BREAKFAST) && world.time - SSticker.round_start_time < STOP_SERVING_BREAKFAST)
- SEND_SIGNAL(H, COMSIG_ADD_MOOD_EVENT, "breakfast", /datum/mood_event/breakfast)
- last_check_time = world.time
-
-///Delete the item when it is fully eaten
-/datum/component/edible/proc/On_Consume(mob/living/eater)
-
- var/atom/owner = parent
-
- if(!eater)
- return
- if(!owner.reagents.total_volume)
- if(isturf(parent))
- var/turf/T = parent
- T.ScrapeAway(1, CHANGETURF_INHERIT_AIR)
- else
- qdel(parent)
-
-///Ability to feed food to puppers
-/datum/component/edible/proc/UseByAnimal(datum/source, mob/user)
-
- SIGNAL_HANDLER
-
-
- var/atom/owner = parent
-
- if(!isdog(user))
- return
- var/mob/living/L = user
- if(bitecount == 0 || prob(50))
- L.manual_emote("nibbles away at \the [parent]")
- bitecount++
- . = COMPONENT_ITEM_NO_ATTACK
- L.taste(owner.reagents) // why should carbons get all the fun?
- if(bitecount >= 5)
- var/sattisfaction_text = pick("burps from enjoyment", "yaps for more", "woofs twice", "looks at the area where \the [parent] was")
- if(sattisfaction_text)
- L.manual_emote(sattisfaction_text)
- qdel(parent)
diff --git a/code/datums/components/food/edible.dm b/code/datums/components/food/edible.dm
new file mode 100644
index 000000000000..cde77f969911
--- /dev/null
+++ b/code/datums/components/food/edible.dm
@@ -0,0 +1,494 @@
+/*!
+
+This component makes it possible to make things edible. What this means is that you can take a bite or force someone to take a bite (in the case of items).
+These items take a specific time to eat, and can do most of the things our original food items could.
+
+Behavior that's still missing from this component that original food items had that should either be put into seperate components or somewhere else:
+ Components:
+ Drying component (jerky etc)
+ Customizable component (custom pizzas etc)
+ Processable component (Slicing and cooking behavior essentialy, making it go from item A to B when conditions are met.)
+ Microwavability component
+ Frying component
+
+ Misc:
+ Something for cakes (You can store things inside)
+
+*/
+/datum/component/edible
+ dupe_mode = COMPONENT_DUPE_UNIQUE_PASSARGS
+ ///Amount of reagents taken per bite
+ var/bite_consumption = 2
+ ///Amount of bites taken so far
+ var/bitecount = 0
+ ///Flags for food
+ var/food_flags = NONE
+ ///Bitfield of the types of this food
+ var/foodtypes = NONE
+ ///Amount of seconds it takes to eat this food
+ var/eat_time = 30
+ ///Defines how much it lowers someones satiety (Need to eat, essentialy)
+ var/junkiness = 0
+ ///Message to send when eating
+ var/list/eatverbs
+ ///Callback to be ran before you eat something, so you can check if someone *can* eat it.
+ var/datum/callback/pre_eat
+ ///Callback to be ran before composting something, in case you don't want a piece of food to be compostable for some reason.
+ var/datum/callback/on_compost
+ ///Callback to be ran for when you take a bite of something
+ var/datum/callback/after_eat
+ ///Callback to be ran for when you finish eating something
+ var/datum/callback/on_consume
+ ///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
+ ///The flavortext for taste
+ var/list/tastes
+ ///The type of atom this creates when the object is microwaved.
+ var/microwaved_type
+
+ //TEMP VAR, filling is nonfunctional because newfood isnt customizable yet
+ var/filling_color
+
+/datum/component/edible/Initialize(list/initial_reagents,
+ food_flags = NONE,
+ foodtypes = NONE,
+ volume = 50,
+ eat_time = 10,
+ list/tastes,
+ list/eatverbs = list("bite","chew","nibble","gnaw","gobble","chomp"),
+ bite_consumption = 2,
+ microwaved_type,
+ junkiness,
+ filling_color = null, //Temp var
+ datum/callback/pre_eat,
+ datum/callback/on_compost,
+ datum/callback/after_eat,
+ datum/callback/on_consume
+)
+ if(!isatom(parent))
+ return COMPONENT_INCOMPATIBLE
+
+ RegisterSignal(parent, COMSIG_PARENT_EXAMINE, PROC_REF(examine))
+ RegisterSignal(parent, COMSIG_ATOM_ATTACK_ANIMAL, PROC_REF(use_by_animal))
+ RegisterSignal(parent, COMSIG_ATOM_CHECKPARTS, PROC_REF(on_craft))
+ RegisterSignal(parent, COMSIG_ATOM_CREATEDBY_PROCESSING, PROC_REF(on_processed))
+ RegisterSignal(parent, COMSIG_ITEM_MICROWAVE_COOKED, PROC_REF(on_microwave_cooked))
+ RegisterSignal(parent, COMSIG_EDIBLE_ON_COMPOST, PROC_REF(compost))
+
+ if(isitem(parent))
+ RegisterSignal(parent, COMSIG_ITEM_ATTACK, PROC_REF(use_from_hand))
+ RegisterSignal(parent, COMSIG_ITEM_FRIED, PROC_REF(on_fried))
+ RegisterSignal(parent, COMSIG_ITEM_MICROWAVE_ACT, PROC_REF(on_microwaved))
+
+ 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.
+
+ src.bite_consumption = bite_consumption
+ src.food_flags = food_flags
+ src.foodtypes = foodtypes
+ src.eat_time = eat_time
+ src.eatverbs = string_list(eatverbs)
+ src.junkiness = junkiness
+ src.pre_eat = pre_eat
+ src.on_compost = on_compost
+ 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
+
+ var/atom/owner = parent
+
+ owner.create_reagents(volume, INJECTABLE)
+
+ 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)
+
+/datum/component/edible/InheritComponent(datum/component/C,
+ i_am_original,
+ list/initial_reagents,
+ food_flags = NONE,
+ foodtypes = NONE,
+ volume = 50,
+ eat_time = 30,
+ list/tastes,
+ list/eatverbs = list("bite","chew","nibble","gnaw","gobble","chomp"),
+ bite_consumption = 2,
+ filling_color = null, //Temp var
+ datum/callback/pre_eat,
+ datum/callback/on_compost,
+ datum/callback/after_eat,
+ datum/callback/on_consume
+ )
+
+ . = ..()
+ 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.pre_eat = pre_eat
+ src.on_compost = on_compost
+ src.after_eat = after_eat
+ src.on_consume = on_consume
+
+/datum/component/edible/Destroy(force, silent)
+ QDEL_NULL(pre_eat)
+ QDEL_NULL(on_compost)
+ QDEL_NULL(after_eat)
+ QDEL_NULL(on_consume)
+ return ..()
+
+/datum/component/edible/proc/examine(datum/source, mob/user, list/examine_list)
+ SIGNAL_HANDLER
+
+ if(!(food_flags & FOOD_IN_CONTAINER))
+ switch (bitecount)
+ if (0)
+ return
+ if(1)
+ examine_list += "[parent] was bitten by someone!"
+ if(2,3)
+ examine_list += "[parent] was bitten [bitecount] times!"
+ else
+ examine_list += "[parent] was bitten multiple times!"
+
+/datum/component/edible/proc/use_from_hand(obj/item/source, mob/living/M, mob/living/user)
+ SIGNAL_HANDLER
+
+ return TryToEat(M, user)
+
+/datum/component/edible/proc/on_fried(fry_object)
+ SIGNAL_HANDLER
+ var/atom/our_atom = parent
+ our_atom.reagents.trans_to(fry_object, our_atom.reagents.total_volume)
+ qdel(our_atom)
+ return COMSIG_FRYING_HANDLED
+
+///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/on_processed(datum/source, atom/original_atom, list/chosen_processing_option)
+ SIGNAL_HANDLER
+
+ if(!original_atom.reagents)
+ return
+
+ var/atom/this_food = parent
+ var/reagents_for_slice = chosen_processing_option[TOOL_PROCESSING_AMOUNT]
+
+ this_food.create_reagents(volume) //Make sure we have a reagent container
+
+ original_atom.reagents.trans_to(this_food, reagents_for_slice)
+
+ if(original_atom.name != initial(original_atom.name))
+ this_food.name = "slice of [original_atom.name]"
+ if(original_atom.desc != initial(original_atom.desc))
+ this_food.desc = "[original_atom.desc]"
+
+///Called when food is crafted through a crafting recipe datum.
+/datum/component/edible/proc/on_craft(datum/source, list/parts_list, datum/crafting_recipe/food/recipe)
+ SIGNAL_HANDLER
+
+ var/atom/this_food = parent
+
+ this_food.reagents.clear_reagents()
+
+ for(var/obj/item/crafted_part in this_food.contents)
+ crafted_part.reagents?.trans_to(this_food.reagents, crafted_part.reagents.maximum_volume, CRAFTED_FOOD_INGREDIENT_REAGENT_MODIFIER)
+
+ var/list/objects_to_delete = list()
+
+ // Remove all non recipe objects from the contents
+ for(var/content_object in this_food.contents)
+ for(var/recipe_object in recipe.real_parts)
+ if(istype(content_object, recipe_object))
+ continue
+ objects_to_delete += content_object
+
+ QDEL_LIST(objects_to_delete)
+
+ for(var/r_id in initial_reagents)
+ var/amount = initial_reagents[r_id] * CRAFTED_FOOD_BASE_REAGENT_MODIFIER
+ if(r_id == /datum/reagent/consumable/nutriment || r_id == /datum/reagent/consumable/nutriment/vitamin)
+ this_food.reagents.add_reagent(r_id, amount, tastes)
+ else
+ this_food.reagents.add_reagent(r_id, amount)
+
+ SSblackbox.record_feedback("tally", "food_made", 1, type)
+
+/datum/component/edible/proc/on_microwaved(datum/source, obj/machinery/microwave/used_microwave)
+ SIGNAL_HANDLER
+
+ var/turf/parent_turf = get_turf(parent)
+
+ if(!microwaved_type)
+ new /obj/item/reagent_containers/food/snacks/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/on_microwave_cooked(datum/source, obj/item/source_item, cooking_efficiency = 1)
+ SIGNAL_HANDLER
+
+ var/atom/this_food = parent
+
+ this_food.reagents.clear_reagents()
+
+ source_item.reagents?.trans_to(this_food, source_item.reagents.total_volume)
+
+ for(var/r_id in initial_reagents)
+ var/amount = initial_reagents[r_id] * cooking_efficiency * CRAFTED_FOOD_BASE_REAGENT_MODIFIER
+ if(r_id == /datum/reagent/consumable/nutriment || r_id == /datum/reagent/consumable/nutriment/vitamin)
+ this_food.reagents.add_reagent(r_id, amount, tastes)
+ else
+ this_food.reagents.add_reagent(r_id, amount)
+
+///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)))
+ return TRUE
+ if(owner.reagents.total_volume)
+ return FALSE
+ return TRUE
+
+/// Normal time to forcefeed someone something
+#define EAT_TIME_FORCE_FEED (3 SECONDS)
+
+///All the checks for the act of eating itself and
+/datum/component/edible/proc/TryToEat(mob/living/eater, mob/living/feeder)
+
+ set waitfor = FALSE // We might end up sleeping here, so we don't want to hold up anything
+
+ var/atom/owner = parent
+
+ if(feeder.a_intent == INTENT_HARM)
+ return
+
+ . = COMPONENT_CANCEL_ATTACK_CHAIN //Point of no return I suppose
+
+ if(IsFoodGone(owner, feeder))
+ return
+
+ if(!CanConsume(eater, feeder))
+ return
+ var/fullness = eater.nutrition + 10 //The theoretical fullness of the person eating if they were to eat this
+
+ var/time_to_eat = (eater = feeder) ? eat_time : EAT_TIME_FORCE_FEED
+
+ if(eater == feeder)//If you're eating it yourself.
+ if(eat_time && !do_after(feeder, time_to_eat, eater, timed_action_flags = food_flags & FOOD_FINGER_FOOD ? IGNORE_USER_LOC_CHANGE | IGNORE_TARGET_LOC_CHANGE : NONE)) //Gotta pass the minimal eat time
+ return
+ if(IsFoodGone(owner, feeder))
+ return
+ var/eatverb = pick(eatverbs)
+
+ if(junkiness && eater.satiety < -150 && eater.nutrition > NUTRITION_LEVEL_STARVING + 50 && !HAS_TRAIT(eater, TRAIT_VORACIOUS))
+ to_chat(eater, "You don't feel like eating any more junk food at the moment!")
+ return
+ else if(fullness <= 50)
+ eater.visible_message("[eater] hungrily [eatverb]s \the [parent], gobbling it down!", "You hungrily [eatverb] \the [parent], gobbling it down!")
+ else if(fullness > 50 && fullness < 150)
+ eater.visible_message("[eater] hungrily [eatverb]s \the [parent].", "You hungrily [eatverb] \the [parent].")
+ else if(fullness > 150 && fullness < 500)
+ eater.visible_message("[eater] [eatverb]s \the [parent].", "You [eatverb] \the [parent].")
+ else if(fullness > 500 && fullness < 600)
+ eater.visible_message("[eater] unwillingly [eatverb]s a bit of \the [parent].", "You unwillingly [eatverb] a bit of \the [parent].")
+ else if(fullness > (600 * (1 + eater.overeatduration / 2000))) // The more you eat - the more you can eat
+ eater.visible_message("[eater] cannot force any more of \the [parent] to go down [eater.p_their()] throat!", "You cannot force any more of \the [parent] to go down your throat!")
+ return
+
+
+
+
+
+ else //If you're feeding it to someone else.
+ if(isbrain(eater))
+ to_chat(feeder, "[eater] doesn't seem to have a mouth!")
+ return
+ if(fullness <= (600 * (1 + eater.overeatduration / 1000)))
+ eater.visible_message(
+ "[feeder] attempts to feed [eater] [parent].", \
+ "[feeder] attempts to feed you [parent]."
+ )
+ if(eater.is_blind())
+ to_chat(eater, "You feel someone trying to feed you something!")
+ else
+ eater.visible_message(
+ "[feeder] cannot force any more of [parent] down [eater]'s throat!", \
+ "[feeder] cannot force any more of [parent] down your throat!"
+ )
+ if(eater.is_blind())
+ to_chat(eater, "You're too full to eat what's being fed to you!")
+ return
+ if(!do_after(feeder, delay = time_to_eat, target = eater)) //Wait 3 seconds before you can feed
+ return
+ if(IsFoodGone(owner, feeder))
+ return
+ log_combat(feeder, eater, "fed", owner.reagents.log_list())
+ eater.visible_message(
+ "[feeder] forces [eater] to eat [parent]!", \
+ "[feeder] forces you to eat [parent]!"
+ )
+ if(eater.is_blind())
+ to_chat(eater, "You're forced to eat something!")
+
+ TakeBite(eater, feeder)
+
+ //If we're not force-feeding, try take another bite
+ if(eater == feeder && eat_time)
+ INVOKE_ASYNC(src, PROC_REF(TryToEat), eater, feeder)
+
+#undef EAT_TIME_FORCE_FEED
+
+///This function lets the eater take a bite and transfers the reagents to the eater.
+/datum/component/edible/proc/TakeBite(mob/living/eater, mob/living/feeder)
+
+ var/atom/owner = parent
+
+ if(!owner?.reagents)
+ return FALSE
+ if(eater.satiety > -200)
+ eater.satiety -= junkiness
+ playsound(eater.loc,'sound/items/eatfood.ogg', rand(10,50), TRUE)
+ if(!owner.reagents.total_volume)
+ return
+ SEND_SIGNAL(parent, COMSIG_FOOD_EATEN, eater, feeder, bitecount, bite_consumption)
+ var/fraction = min(bite_consumption / owner.reagents.total_volume, 1)
+ owner.reagents.trans_to(eater, bite_consumption, transfered_by = feeder, method = INGEST)
+ bitecount++
+ check_liked(fraction, eater)
+ if(!owner.reagents.total_volume)
+ on_consume(eater, feeder)
+
+ //Invoke our after eat callback if it is valid
+ if(after_eat)
+ after_eat.Invoke(eater, feeder, bitecount)
+
+ return TRUE
+
+///Checks if we can compost something, and handles it
+/datum/component/edible/proc/compost(mob/living/user)
+ SIGNAL_HANDLER
+ if(on_compost && !on_compost.Invoke(user))
+ return COMPONENT_EDIBLE_BLOCK_COMPOST
+
+///Checks whether or not the eater can actually consume the food
+/datum/component/edible/proc/CanConsume(mob/living/eater, mob/living/feeder)
+ if(!iscarbon(eater))
+ return FALSE
+ if(pre_eat && !pre_eat.Invoke(eater, feeder))
+ return FALSE
+ var/mob/living/carbon/C = eater
+ var/covered = ""
+ if(C.is_mouth_covered(head_only = 1))
+ covered = "headgear"
+ else if(C.is_mouth_covered(mask_only = 1))
+ covered = "mask"
+ if(covered)
+ var/who = (isnull(feeder) || eater == feeder) ? "your" : "[eater.p_their()]"
+ to_chat(feeder, "You have to remove [who] [covered] first!")
+ return FALSE
+ return TRUE
+
+///Check foodtypes to see if we should send a moodlet
+/datum/component/edible/proc/check_liked(fraction, mob/eater)
+ if(last_check_time + 50 > world.time)
+ return FALSE
+ if(!ishuman(eater))
+ return FALSE
+ var/mob/living/carbon/human/human_eater = eater
+ if((foodtypes & BREAKFAST) && world.time - SSticker.round_start_time < STOP_SERVING_BREAKFAST)
+ SEND_SIGNAL(human_eater, COMSIG_ADD_MOOD_EVENT, "breakfast", /datum/mood_event/breakfast)
+ if(HAS_TRAIT(human_eater, TRAIT_AGEUSIA))
+ if(foodtypes & human_eater.dna.species.toxic_food)
+ to_chat(human_eater, "You don't feel so good...")
+ human_eater.adjust_disgust(25 + 30 * fraction)
+ else
+ if(foodtypes & human_eater.dna.species.toxic_food)
+ to_chat(human_eater,"What the hell was that thing?!")
+ human_eater.adjust_disgust(25 + 30 * fraction)
+ SEND_SIGNAL(human_eater, COMSIG_ADD_MOOD_EVENT, "toxic_food", /datum/mood_event/disgusting_food)
+ else if(foodtypes & human_eater.dna.species.disliked_food)
+ to_chat(human_eater,"That didn't taste very good...")
+ human_eater.adjust_disgust(11 + 15 * fraction)
+ SEND_SIGNAL(human_eater, COMSIG_ADD_MOOD_EVENT, "gross_food", /datum/mood_event/gross_food)
+ else if(foodtypes & human_eater.dna.species.liked_food)
+ to_chat(human_eater,"I love this taste!")
+ human_eater.adjust_disgust(-5 + -2.5 * fraction)
+ SEND_SIGNAL(human_eater, COMSIG_ADD_MOOD_EVENT, "fav_food", /datum/mood_event/favorite_food)
+ last_check_time = world.time
+
+ /* Should shiptest ever want to move taste to tongues as Beestation & later TGstation did, rather than on species
+ var/obj/item/organ/tongue/tongue = human_eater.getorganslot(ORGAN_SLOT_TONGUE)
+ if((foodtypes & BREAKFAST) && world.time - SSticker.round_start_time < STOP_SERVING_BREAKFAST)
+ SEND_SIGNAL(human_eater, COMSIG_ADD_MOOD_EVENT, "breakfast", /datum/mood_event/breakfast)
+ if(HAS_TRAIT(human_eater, TRAIT_AGEUSIA))
+ if(foodtypes & tongue.toxic_food)
+ to_chat(human_eater, "You don't feel so good...")
+ human_eater.adjust_disgust(25 + 30 * fraction)
+ else
+ if(foodtypes & tongue.toxic_food)
+ to_chat(human_eater,"What the hell was that thing?!")
+ human_eater.adjust_disgust(25 + 30 * fraction)
+ SEND_SIGNAL(human_eater, COMSIG_ADD_MOOD_EVENT, "toxic_food", /datum/mood_event/disgusting_food)
+ else if(foodtypes & tongue.disliked_food)
+ to_chat(human_eater,"That didn't taste very good...")
+ human_eater.adjust_disgust(11 + 15 * fraction)
+ SEND_SIGNAL(human_eater, COMSIG_ADD_MOOD_EVENT, "gross_food", /datum/mood_event/gross_food)
+ else if(foodtypes & tongue.liked_food)
+ to_chat(human_eater,"I love this taste!")
+ human_eater.adjust_disgust(-5 + -2.5 * fraction)
+ SEND_SIGNAL(human_eater, COMSIG_ADD_MOOD_EVENT, "fav_food", /datum/mood_event/favorite_food)
+ last_check_time = world.time
+ */
+
+///Delete the item when it is fully eaten
+/datum/component/edible/proc/on_consume(mob/living/eater, mob/living/feeder)
+ SEND_SIGNAL(parent, COMSIG_FOOD_CONSUMED, eater, feeder)
+
+ on_consume?.Invoke(eater, feeder)
+
+ if(isturf(parent))
+ var/turf/T = parent
+ T.ScrapeAway(1, CHANGETURF_INHERIT_AIR)
+ else
+ qdel(parent)
+
+///Ability to feed food to puppers
+/datum/component/edible/proc/use_by_animal(datum/source, mob/user)
+ SIGNAL_HANDLER
+ var/atom/owner = parent
+
+ if(!isdog(user))
+ return
+ var/mob/living/L = user
+ if(bitecount == 0 || prob(50))
+ L.manual_emote("nibbles away at \the [parent].")
+ bitecount++
+ . = COMPONENT_CANCEL_ATTACK_CHAIN
+ L.taste(owner.reagents) // why should carbons get all the fun?
+ if(bitecount >= 5)
+ var/satisfaction_text = pick("burps from enjoyment.", "yaps for more!", "woofs twice.", "looks at the area where \the [parent] was.")
+ L.manual_emote(satisfaction_text)
+ qdel(parent)
diff --git a/code/datums/components/food/food_storage.dm b/code/datums/components/food/food_storage.dm
new file mode 100644
index 000000000000..259ef4a8b6c6
--- /dev/null
+++ b/code/datums/components/food/food_storage.dm
@@ -0,0 +1,204 @@
+/// --Food storage component--
+/// This component lets you slide one item into large foods, such as bread, cheese wheels, or cakes.
+/// Consuming food storages with an item inside can cause unique interactions, such as eating glass shards.
+
+/datum/component/food_storage
+ /// Reference to what we have in our food.
+ var/obj/item/stored_item
+ /// The amount of volume the food has on creation - Used for probabilities
+ var/initial_volume = 10
+ /// Minimum size items that can be inserted
+ var/minimum_weight_class = WEIGHT_CLASS_SMALL
+ /// What are the odds we bite into the stored item?
+ var/bad_chance_of_discovery = 0
+ /// What are the odds we see the stored item before we bite it?
+ var/good_chance_of_discovery = 100
+ /// The stored item was found out somehow.
+ var/discovered = FALSE
+
+/datum/component/food_storage/Initialize(_minimum_weight_class = WEIGHT_CLASS_SMALL, _bad_chance = 0, _good_chance = 100)
+
+ RegisterSignal(parent, COMSIG_PARENT_ATTACKBY, PROC_REF(try_inserting_item))
+ RegisterSignal(parent, COMSIG_ATOM_ATTACK_HAND, PROC_REF(try_removing_item))
+ RegisterSignal(parent, COMSIG_FOOD_EATEN, PROC_REF(consume_food_storage))
+
+ var/atom/food = parent
+ initial_volume = food.reagents.total_volume
+
+ minimum_weight_class = _minimum_weight_class
+ bad_chance_of_discovery = _bad_chance
+ good_chance_of_discovery = _good_chance
+
+/datum/component/food_storage/Destroy(force, silent)
+ if(stored_item)
+ stored_item.forceMove(stored_item.drop_location())
+ stored_item.dropped()
+ stored_item = null
+ . = ..()
+
+/** Begins the process of inserted an item.
+ *
+ * Clicking on the food storage with an item will begin a do_after, which if successful inserts the item.
+ *
+ * Arguments
+ * inserted_item - the item being placed into the food
+ * user - the person inserting the item
+ */
+/datum/component/food_storage/proc/try_inserting_item(datum/source, obj/item/inserted_item, mob/user, params)
+ SIGNAL_HANDLER
+
+ // No matryoshka-ing food storage
+ if(istype(inserted_item, /obj/item/storage) || IS_EDIBLE(inserted_item))
+ return
+
+ //Harm intent will bypass inserting for injecting food with syringes and such
+ if(user.a_intent == INTENT_HARM)
+ return
+
+ if(inserted_item.w_class > minimum_weight_class)
+ to_chat(user, "\The [inserted_item.name] won't fit in \the [parent].")
+ return
+
+ if(!QDELETED(stored_item))
+ to_chat(user, "There's something in \the [parent].")
+ return
+
+ if(HAS_TRAIT(inserted_item, TRAIT_NODROP))
+ to_chat(user, "\the [inserted_item] is stuck to your hand, you can't put into \the [parent]!")
+ return
+
+ user.visible_message("[user.name] begins inserting [inserted_item.name] into \the [parent].", \
+ "You start to insert the [inserted_item.name] into \the [parent].")
+
+ INVOKE_ASYNC(src, PROC_REF(insert_item), inserted_item, user)
+ return COMPONENT_CANCEL_ATTACK_CHAIN
+
+/** Begins the process of attempting to remove the stored item.
+ *
+ * Clicking on food storage on grab intent will begin a do_after, which if successful removes the stored_item.
+ *
+ * Arguments
+ * user - the person removing the item.
+ */
+/datum/component/food_storage/proc/try_removing_item(datum/source, mob/user)
+ SIGNAL_HANDLER
+
+ var/atom/food = parent
+
+ if(user.a_intent != INTENT_GRAB)
+ return
+
+ if(QDELETED(stored_item))
+ return
+
+ if(!food.can_interact(user))
+ return
+
+ user.visible_message("[user.name] begins tearing at \the [parent].", \
+ "You start to rip into \the [parent].")
+
+ INVOKE_ASYNC(src, PROC_REF(begin_remove_item), user)
+ return COMPONENT_CANCEL_ATTACK_CHAIN
+
+/** Inserts the item into the food, after a do_after.
+ *
+ * Arguments
+ * inserted_item - The item being inserted.
+ * user - the person inserting the item.
+ */
+/datum/component/food_storage/proc/insert_item(obj/item/inserted_item, mob/user)
+ if(do_after(user, 1.5 SECONDS, target = parent))
+ var/atom/food = parent
+ to_chat(user, "You slip [inserted_item.name] inside \the [parent].")
+ inserted_item.forceMove(food)
+ user.log_message("[key_name(user)] inserted [inserted_item] into [parent] at [AREACOORD(user)]", LOG_ATTACK)
+ food.add_fingerprint(user)
+ inserted_item.add_fingerprint(user)
+
+ stored_item = inserted_item
+
+/** Removes the item from the food, after a do_after.
+ *
+ * Arguments
+ * user - person removing the item.
+ */
+/datum/component/food_storage/proc/begin_remove_item(mob/user)
+ if(do_after(user, 10 SECONDS, target = parent))
+ remove_item(user)
+
+/**
+ * Removes the stored item, putting it in user's hands or on the ground, then updates the reference.
+ */
+/datum/component/food_storage/proc/remove_item(mob/user)
+ if(user.put_in_hands(stored_item))
+ user.visible_message("[user.name] slowly pulls [stored_item.name] out of \the [parent].", \
+ "You slowly pull [stored_item.name] out of \the [parent].")
+ else
+ stored_item.dropped()
+ stored_item.visible_message("[stored_item.name] falls out of \the [parent].")
+
+ update_stored_item()
+
+/** Checks for stored items when the food is eaten.
+ *
+ * If the food is eaten while an item is stored in it, calculates the odds that the item will be found.
+ * Then, if the item is found before being bitten, the item is removed.
+ * If the item is found by biting into it, calls on_accidental_consumption on the stored item.
+ * Afterwards, removes the item from the food if it was discovered.
+ *
+ * Arguments
+ * target - person doing the eating (can be the same as user)
+ * user - person causing the eating to happen
+ * bitecount - how many times the current food has been bitten
+ * bitesize - how large bties are for this food
+ */
+/datum/component/food_storage/proc/consume_food_storage(datum/source, mob/living/target, mob/living/user, bitecount, bitesize)
+ SIGNAL_HANDLER
+
+ if(QDELETED(stored_item)) //if the stored item was deleted/null...
+ if(!update_stored_item()) //check if there's a replacement item
+ return
+
+ /// Chance of biting the held item = amount of bites / (intitial reagents / reagents per bite) * 100
+ bad_chance_of_discovery = (bitecount / (initial_volume / bitesize))*100
+ /// Chance of finding the held item = bad chance - 50
+ good_chance_of_discovery = bad_chance_of_discovery - 50
+
+ if(prob(good_chance_of_discovery)) //finding the item, without biting it
+ discovered = TRUE
+ to_chat(target, "It feels like there's something in \the [parent]...!")
+
+ else if(prob(bad_chance_of_discovery)) //finding the item, BY biting it
+ user.log_message("[key_name(user)] just fed [key_name(target)] a/an [stored_item] which was hidden in [parent] at [AREACOORD(target)]", LOG_ATTACK)
+ discovered = stored_item.on_accidental_consumption(target, user, parent)
+ update_stored_item() //make sure if the item was changed, the reference changes as well
+
+ if(!QDELETED(stored_item) && discovered)
+ INVOKE_ASYNC(src, PROC_REF(remove_item), user)
+
+/** Updates the reference of the stored item.
+ *
+ * Checks the food's contents for if an alternate item was placed into the food.
+ * If there is an alternate item, updates the reference to the new item.
+ * If there isn't, updates the reference to null.
+ *
+ * Returns FALSE if the ref is nulled, or TRUE is another item replaced it.
+ */
+/datum/component/food_storage/proc/update_stored_item()
+ var/atom/food = parent
+ if(!food?.contents.len) //if there's no items in the food or food is deleted somehow
+ stored_item = null
+ return FALSE
+
+ for(var/obj/item/i in food.contents) //search the food's contents for a replacement item
+ if(IS_EDIBLE(i))
+ continue
+ if(QDELETED(i))
+ continue
+
+ stored_item = i //we found something to replace it
+ return TRUE
+
+ //if there's nothing else in the food, or we found nothing valid
+ stored_item = null
+ return FALSE
diff --git a/code/datums/elements/dunkable.dm b/code/datums/elements/food/dunkable.dm
similarity index 99%
rename from code/datums/elements/dunkable.dm
rename to code/datums/elements/food/dunkable.dm
index 1eaee1d8cbbc..80661d5c4ac0 100644
--- a/code/datums/elements/dunkable.dm
+++ b/code/datums/elements/food/dunkable.dm
@@ -17,8 +17,6 @@
UnregisterSignal(target, COMSIG_ITEM_AFTERATTACK)
/datum/element/dunkable/proc/get_dunked(datum/source, atom/target, mob/user, proximity_flag)
- SIGNAL_HANDLER
-
if(!proximity_flag) // if the user is not adjacent to the container
return
var/obj/item/reagent_containers/container = target // the container we're trying to dunk into
diff --git a/code/datums/elements/food/edible.dm b/code/datums/elements/food/edible.dm
new file mode 100644
index 000000000000..a06a5ec28b79
--- /dev/null
+++ b/code/datums/elements/food/edible.dm
@@ -0,0 +1,471 @@
+/*!
+
+This component makes it possible to make things edible. What this means is that you can take a bite or force someone to take a bite (in the case of items).
+These items take a specific time to eat, and can do most of the things our original food items could.
+
+Behavior that's still missing from this component that original food items had that should either be put into seperate components or somewhere else:
+ Components:
+ Drying component (jerky etc)
+ Customizable component (custom pizzas etc)
+ Processable component (Slicing and cooking behavior essentialy, making it go from item A to B when conditions are met.)
+ Microwavability component
+ Frying component
+
+ Misc:
+ Something for cakes (You can store things inside)
+
+*/
+/datum/component/edible
+ dupe_mode = COMPONENT_DUPE_UNIQUE_PASSARGS
+ ///Amount of reagents taken per bite
+ var/bite_consumption = 2
+ ///Amount of bites taken so far
+ var/bitecount = 0
+ ///Flags for food
+ var/food_flags = NONE
+ ///Bitfield of the types of this food
+ var/foodtypes = NONE
+ ///Amount of seconds it takes to eat this food
+ var/eat_time = 30
+ ///Defines how much it lowers someones satiety (Need to eat, essentialy)
+ var/junkiness = 0
+ ///Message to send when eating
+ var/list/eatverbs
+ ///Callback to be ran before you eat something, so you can check if someone *can* eat it.
+ var/datum/callback/pre_eat
+ ///Callback to be ran before composting something, in case you don't want a piece of food to be compostable for some reason.
+ var/datum/callback/on_compost
+ ///Callback to be ran for when you take a bite of something
+ var/datum/callback/after_eat
+ ///Callback to be ran for when you finish eating something
+ var/datum/callback/on_consume
+ ///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
+ ///The flavortext for taste
+ var/list/tastes
+ ///The type of atom this creates when the object is microwaved.
+ var/microwaved_type
+
+ //TEMP VAR. To be phased out
+ var/filling_color = null
+
+
+/datum/component/edible/Initialize(list/initial_reagents,
+ food_flags = NONE,
+ foodtypes = NONE,
+ volume = 50,
+ eat_time = 10,
+ list/tastes,
+ list/eatverbs = list("bite","chew","nibble","gnaw","gobble","chomp"),
+ bite_consumption = 2,
+ microwaved_type,
+ junkiness,
+ datum/callback/pre_eat,
+ datum/callback/on_compost,
+ datum/callback/after_eat,
+ datum/callback/on_consume
+)
+ if(!isatom(parent))
+ return COMPONENT_INCOMPATIBLE
+
+ RegisterSignal(parent, COMSIG_PARENT_EXAMINE, PROC_REF(examine))
+ RegisterSignal(parent, COMSIG_ATOM_ATTACK_ANIMAL, PROC_REF(use_by_animal))
+ RegisterSignal(parent, COMSIG_ATOM_CHECKPARTS, PROC_REF(on_craft))
+ RegisterSignal(parent, COMSIG_ATOM_CREATEDBY_PROCESSING, PROC_REF(on_processed))
+ RegisterSignal(parent, COMSIG_ITEM_MICROWAVE_COOKED, PROC_REF(on_microwave_cooked))
+ RegisterSignal(parent, COMSIG_EDIBLE_ON_COMPOST, PROC_REF(compost))
+
+ if(isitem(parent))
+ RegisterSignal(parent, COMSIG_ITEM_ATTACK, PROC_REF(use_from_hand))
+ RegisterSignal(parent, COMSIG_ITEM_FRIED, PROC_REF(on_fried))
+ RegisterSignal(parent, COMSIG_ITEM_MICROWAVE_ACT, PROC_REF(on_microwaved))
+
+ 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.
+
+ src.bite_consumption = bite_consumption
+ src.food_flags = food_flags
+ src.foodtypes = foodtypes
+ src.initial_reagents = initial_reagents
+ src.tastes = tastes
+ src.eat_time = eat_time
+ src.eatverbs = string_list(eatverbs)
+ src.junkiness = junkiness
+ src.pre_eat = pre_eat
+ src.on_compost = on_compost
+ 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
+
+ var/atom/owner = parent
+
+ owner.create_reagents(volume, INJECTABLE)
+
+ 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)
+
+/datum/component/edible/InheritComponent(datum/component/C,
+ i_am_original,
+ list/initial_reagents,
+ food_flags = NONE,
+ foodtypes = NONE,
+ volume = 50,
+ eat_time = 30,
+ list/tastes,
+ list/eatverbs = list("bite","chew","nibble","gnaw","gobble","chomp"),
+ bite_consumption = 2,
+ datum/callback/pre_eat,
+ datum/callback/on_compost,
+ datum/callback/after_eat,
+ datum/callback/on_consume
+ )
+
+ . = ..()
+ 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.pre_eat = pre_eat
+ src.on_compost = on_compost
+ src.after_eat = after_eat
+ src.on_consume = on_consume
+
+/datum/component/edible/Destroy(force, silent)
+ QDEL_NULL(pre_eat)
+ QDEL_NULL(on_compost)
+ QDEL_NULL(after_eat)
+ QDEL_NULL(on_consume)
+ return ..()
+
+/datum/component/edible/proc/examine(datum/source, mob/user, list/examine_list)
+ SIGNAL_HANDLER
+
+ if(!(food_flags & FOOD_IN_CONTAINER))
+ switch (bitecount)
+ if (0)
+ return
+ if(1)
+ examine_list += "[parent] was bitten by someone!"
+ if(2,3)
+ examine_list += "[parent] was bitten [bitecount] times!"
+ else
+ examine_list += "[parent] was bitten multiple times!"
+
+/datum/component/edible/proc/use_from_hand(obj/item/source, mob/living/M, mob/living/user)
+ SIGNAL_HANDLER
+
+ return TryToEat(M, user)
+
+/datum/component/edible/proc/on_fried(fry_object)
+ SIGNAL_HANDLER
+ var/atom/our_atom = parent
+ our_atom.reagents.trans_to(fry_object, our_atom.reagents.total_volume)
+ qdel(our_atom)
+ return COMSIG_FRYING_HANDLED
+
+///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/on_processed(datum/source, atom/original_atom, list/chosen_processing_option)
+ SIGNAL_HANDLER
+
+ if(!original_atom.reagents)
+ return
+
+ var/atom/this_food = parent
+ var/reagents_for_slice = chosen_processing_option[TOOL_PROCESSING_AMOUNT]
+
+ this_food.create_reagents(volume) //Make sure we have a reagent container
+
+ original_atom.reagents.trans_to(this_food, reagents_for_slice)
+
+ if(original_atom.name != initial(original_atom.name))
+ this_food.name = "slice of [original_atom.name]"
+ if(original_atom.desc != initial(original_atom.desc))
+ this_food.desc = "[original_atom.desc]"
+
+///Called when food is crafted through a crafting recipe datum.
+/datum/component/edible/proc/on_craft(datum/source, list/parts_list, datum/crafting_recipe/food/recipe)
+ SIGNAL_HANDLER
+
+ var/atom/this_food = parent
+
+ this_food.reagents.clear_reagents()
+
+ for(var/obj/item/crafted_part in this_food.contents)
+ crafted_part.reagents?.trans_to(this_food.reagents, crafted_part.reagents.maximum_volume, CRAFTED_FOOD_INGREDIENT_REAGENT_MODIFIER)
+
+ var/list/objects_to_delete = list()
+
+ // Remove all non recipe objects from the contents
+ for(var/content_object in this_food.contents)
+ for(var/recipe_object in recipe.real_parts)
+ if(istype(content_object, recipe_object))
+ continue
+ objects_to_delete += content_object
+
+ QDEL_LIST(objects_to_delete)
+
+ for(var/r_id in initial_reagents)
+ var/amount = initial_reagents[r_id] * CRAFTED_FOOD_BASE_REAGENT_MODIFIER
+ if(r_id == /datum/reagent/consumable/nutriment || r_id == /datum/reagent/consumable/nutriment/vitamin)
+ this_food.reagents.add_reagent(r_id, amount, tastes)
+ else
+ this_food.reagents.add_reagent(r_id, amount)
+
+ SSblackbox.record_feedback("tally", "food_made", 1, type)
+
+/datum/component/edible/proc/on_microwaved(datum/source, obj/machinery/microwave/used_microwave)
+ SIGNAL_HANDLER
+
+ var/turf/parent_turf = get_turf(parent)
+
+ if(!microwaved_type)
+ new /obj/item/reagent_containers/food/snacks/badrecipe(parent_turf)
+ qdel(src)
+ 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)
+
+///Corrects the reagents on the newly cooked food
+/datum/component/edible/proc/on_microwave_cooked(datum/source, obj/item/source_item, cooking_efficiency = 1)
+ SIGNAL_HANDLER
+
+ var/atom/this_food = parent
+
+ this_food.reagents.clear_reagents()
+
+ source_item.reagents?.trans_to(this_food, source_item.reagents.total_volume)
+
+ for(var/r_id in initial_reagents)
+ var/amount = initial_reagents[r_id] * cooking_efficiency * CRAFTED_FOOD_BASE_REAGENT_MODIFIER
+ if(r_id == /datum/reagent/consumable/nutriment || r_id == /datum/reagent/consumable/nutriment/vitamin)
+ this_food.reagents.add_reagent(r_id, amount, tastes)
+ else
+ this_food.reagents.add_reagent(r_id, amount)
+
+///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)))
+ return TRUE
+ if(owner.reagents.total_volume)
+ return FALSE
+ return TRUE
+
+/// Normal time to forcefeed someone something
+#define EAT_TIME_FORCE_FEED (3 SECONDS)
+
+///All the checks for the act of eating itself and
+/datum/component/edible/proc/TryToEat(mob/living/eater, mob/living/feeder)
+
+ set waitfor = FALSE // We might end up sleeping here, so we don't want to hold up anything
+
+ var/atom/owner = parent
+
+ if(feeder.a_intent == INTENT_HARM)
+ return
+
+ . = COMPONENT_CANCEL_ATTACK_CHAIN //Point of no return I suppose
+
+ if(IsFoodGone(owner, feeder))
+ return
+
+ if(!CanConsume(eater, feeder))
+ return
+ var/fullness = eater.nutrition + 10 //The theoretical fullness of the person eating if they were to eat this
+
+ var/time_to_eat = (eater = feeder) ? eat_time : EAT_TIME_FORCE_FEED
+
+ if(eater == feeder)//If you're eating it yourself.
+ if(eat_time && !do_after(feeder, time_to_eat, eater, timed_action_flags = food_flags & FOOD_FINGER_FOOD ? IGNORE_USER_LOC_CHANGE | IGNORE_TARGET_LOC_CHANGE : NONE)) //Gotta pass the minimal eat time
+ return
+ if(IsFoodGone(owner, feeder))
+ return
+ var/eatverb = pick(eatverbs)
+
+ if(junkiness && eater.satiety < -150 && eater.nutrition > NUTRITION_LEVEL_STARVING + 50 && !HAS_TRAIT(eater, TRAIT_VORACIOUS))
+ to_chat(eater, "You don't feel like eating any more junk food at the moment!")
+ return
+ else if(fullness <= 50)
+ eater.visible_message("[eater] hungrily [eatverb]s \the [parent], gobbling it down!", "You hungrily [eatverb] \the [parent], gobbling it down!")
+ else if(fullness > 50 && fullness < 150)
+ eater.visible_message("[eater] hungrily [eatverb]s \the [parent].", "You hungrily [eatverb] \the [parent].")
+ else if(fullness > 150 && fullness < 500)
+ eater.visible_message("[eater] [eatverb]s \the [parent].", "You [eatverb] \the [parent].")
+ else if(fullness > 500 && fullness < 600)
+ eater.visible_message("[eater] unwillingly [eatverb]s a bit of \the [parent].", "You unwillingly [eatverb] a bit of \the [parent].")
+ else if(fullness > (600 * (1 + eater.overeatduration / 2000))) // The more you eat - the more you can eat
+ eater.visible_message("[eater] cannot force any more of \the [parent] to go down [eater.p_their()] throat!", "You cannot force any more of \the [parent] to go down your throat!")
+ return
+
+
+
+
+
+ else //If you're feeding it to someone else.
+ if(isbrain(eater))
+ to_chat(feeder, "[eater] doesn't seem to have a mouth!")
+ return
+ if(fullness <= (600 * (1 + eater.overeatduration / 1000)))
+ eater.visible_message(
+ "[feeder] attempts to feed [eater] [parent].", \
+ "[feeder] attempts to feed you [parent]."
+ )
+ if(eater.is_blind())
+ to_chat(eater, "You feel someone trying to feed you something!")
+ else
+ eater.visible_message(
+ "[feeder] cannot force any more of [parent] down [eater]'s throat!", \
+ "[feeder] cannot force any more of [parent] down your throat!"
+ )
+ if(eater.is_blind())
+ to_chat(eater, "You're too full to eat what's being fed to you!")
+ return
+ if(!do_after(feeder, delay = time_to_eat, target = eater)) //Wait 3 seconds before you can feed
+ return
+ if(IsFoodGone(owner, feeder))
+ return
+ log_combat(feeder, eater, "fed", owner.reagents.log_list())
+ eater.visible_message(
+ "[feeder] forces [eater] to eat [parent]!", \
+ "[feeder] forces you to eat [parent]!"
+ )
+ if(eater.is_blind())
+ to_chat(eater, "You're forced to eat something!")
+
+ TakeBite(eater, feeder)
+
+ //If we're not force-feeding, try take another bite
+ if(eater == feeder && eat_time)
+ INVOKE_ASYNC(src, PROC_REF(TryToEat), eater, feeder)
+
+#undef EAT_TIME_FORCE_FEED
+
+///This function lets the eater take a bite and transfers the reagents to the eater.
+/datum/component/edible/proc/TakeBite(mob/living/eater, mob/living/feeder)
+
+ var/atom/owner = parent
+
+ if(!owner?.reagents)
+ return FALSE
+ if(eater.satiety > -200)
+ eater.satiety -= junkiness
+ playsound(eater.loc,'sound/items/eatfood.ogg', rand(10,50), TRUE)
+ if(!owner.reagents.total_volume)
+ return
+ SEND_SIGNAL(parent, COMSIG_FOOD_EATEN, eater, feeder, bitecount, bite_consumption)
+ var/fraction = min(bite_consumption / owner.reagents.total_volume, 1)
+ owner.reagents.trans_to(eater, bite_consumption, transfered_by = feeder, method = INGEST)
+ bitecount++
+ check_liked(fraction, eater)
+ if(!owner.reagents.total_volume)
+ on_consume(eater, feeder)
+
+ //Invoke our after eat callback if it is valid
+ if(after_eat)
+ after_eat.Invoke(eater, feeder, bitecount)
+
+ return TRUE
+
+///Checks if we can compost something, and handles it
+/datum/component/edible/proc/compost(mob/living/user)
+ SIGNAL_HANDLER
+ if(on_compost && !on_compost.Invoke(user))
+ return COMPONENT_EDIBLE_BLOCK_COMPOST
+
+///Checks whether or not the eater can actually consume the food
+/datum/component/edible/proc/CanConsume(mob/living/eater, mob/living/feeder)
+ if(!iscarbon(eater))
+ return FALSE
+ if(pre_eat && !pre_eat.Invoke(eater, feeder))
+ return FALSE
+ var/mob/living/carbon/C = eater
+ var/covered = ""
+ if(C.is_mouth_covered(head_only = 1))
+ covered = "headgear"
+ else if(C.is_mouth_covered(mask_only = 1))
+ covered = "mask"
+ if(covered)
+ var/who = (isnull(feeder) || eater == feeder) ? "your" : "[eater.p_their()]"
+ to_chat(feeder, "You have to remove [who] [covered] first!")
+ return FALSE
+ return TRUE
+
+///Check foodtypes to see if we should send a moodlet
+/datum/component/edible/proc/check_liked(fraction, mob/eater)
+ if(last_check_time + 50 > world.time)
+ return FALSE
+ if(!ishuman(eater))
+ return FALSE
+ var/mob/living/carbon/human/human_eater = eater
+ var/obj/item/organ/tongue/tongue = human_eater.getorganslot(ORGAN_SLOT_TONGUE)
+ if((foodtypes & BREAKFAST) && world.time - SSticker.round_start_time < STOP_SERVING_BREAKFAST)
+ SEND_SIGNAL(human_eater, COMSIG_ADD_MOOD_EVENT, "breakfast", /datum/mood_event/breakfast)
+ if(HAS_TRAIT(human_eater, TRAIT_AGEUSIA))
+ if(foodtypes & tongue.toxic_food)
+ to_chat(human_eater, "You don't feel so good...")
+ human_eater.adjust_disgust(25 + 30 * fraction)
+ else
+ if(foodtypes & tongue.toxic_food)
+ to_chat(human_eater,"What the hell was that thing?!")
+ human_eater.adjust_disgust(25 + 30 * fraction)
+ SEND_SIGNAL(human_eater, COMSIG_ADD_MOOD_EVENT, "toxic_food", /datum/mood_event/disgusting_food)
+ else if(foodtypes & tongue.disliked_food)
+ to_chat(human_eater,"That didn't taste very good...")
+ human_eater.adjust_disgust(11 + 15 * fraction)
+ SEND_SIGNAL(human_eater, COMSIG_ADD_MOOD_EVENT, "gross_food", /datum/mood_event/gross_food)
+ else if(foodtypes & tongue.liked_food)
+ to_chat(human_eater,"I love this taste!")
+ human_eater.adjust_disgust(-5 + -2.5 * fraction)
+ SEND_SIGNAL(human_eater, COMSIG_ADD_MOOD_EVENT, "fav_food", /datum/mood_event/favorite_food)
+ last_check_time = world.time
+
+///Delete the item when it is fully eaten
+/datum/component/edible/proc/on_consume(mob/living/eater, mob/living/feeder)
+ SEND_SIGNAL(parent, COMSIG_FOOD_CONSUMED, eater, feeder)
+
+ on_consume?.Invoke(eater, feeder)
+
+ if(isturf(parent))
+ var/turf/T = parent
+ T.ScrapeAway(1, CHANGETURF_INHERIT_AIR)
+ else
+ qdel(parent)
+
+///Ability to feed food to puppers
+/datum/component/edible/proc/use_by_animal(datum/source, mob/user)
+ SIGNAL_HANDLER
+ var/atom/owner = parent
+
+ if(!isdog(user))
+ return
+ var/mob/living/L = user
+ if(bitecount == 0 || prob(50))
+ L.manual_emote("nibbles away at \the [parent].")
+ bitecount++
+ . = COMPONENT_CANCEL_ATTACK_CHAIN
+ L.taste(owner.reagents) // why should carbons get all the fun?
+ if(bitecount >= 5)
+ var/satisfaction_text = pick("burps from enjoyment.", "yaps for more!", "woofs twice.", "looks at the area where \the [parent] was.")
+ L.manual_emote(satisfaction_text)
+ qdel(parent)
diff --git a/code/datums/elements/food/food_trash.dm b/code/datums/elements/food/food_trash.dm
new file mode 100644
index 000000000000..6c484c414a07
--- /dev/null
+++ b/code/datums/elements/food/food_trash.dm
@@ -0,0 +1,40 @@
+// If an item has the food_trash element it will drop an item when it is consumed.
+/datum/element/food_trash
+ element_flags = ELEMENT_BESPOKE
+ id_arg_index = 2
+ /// The type of trash that is spawned by this element
+ var/trash
+ ///Flags of the trash element that change its behavior UNUSED UNTIL PART 2
+ //var/flags
+ ///Generate trash proc path
+ var/generate_trash_procpath
+
+/datum/element/food_trash/Attach(datum/target, atom/trash, flags, generate_trash_proc)
+ . = ..()
+ if(!isatom(target))
+ return ELEMENT_INCOMPATIBLE
+ src.trash = trash
+ //src.flags = flags
+ RegisterSignal(target, COMSIG_FOOD_CONSUMED, PROC_REF(generate_trash))
+ if(!generate_trash_procpath && generate_trash_proc)
+ generate_trash_procpath = generate_trash_proc
+
+/datum/element/food_trash/Detach(datum/target)
+ . = ..()
+ UnregisterSignal(target, COMSIG_FOOD_CONSUMED)
+
+/datum/element/food_trash/proc/generate_trash(datum/source, mob/living/eater, mob/living/feeder)
+ SIGNAL_HANDLER
+
+ ///cringy signal_handler shouldnt be needed if you dont want to return but oh well
+ INVOKE_ASYNC(src, PROC_REF(async_generate_trash), source)
+
+/datum/element/food_trash/proc/async_generate_trash(datum/source)
+ var/atom/edible_object = source
+
+ var/obj/item/trash_item = generate_trash_procpath ? call(source, generate_trash_procpath)() : new trash(edible_object.drop_location())
+
+ if(isliving(edible_object.loc))
+ var/mob/living/food_holding_mob = edible_object.loc
+ food_holding_mob.dropItemToGround(edible_object)
+ food_holding_mob.put_in_hands(trash_item)
diff --git a/code/datums/elements/food/processable.dm b/code/datums/elements/food/processable.dm
new file mode 100644
index 000000000000..503e5169c877
--- /dev/null
+++ b/code/datums/elements/food/processable.dm
@@ -0,0 +1,47 @@
+// If an item has the processable item, it can be processed into another item with a specific tool. This adds generic behavior for those actions to make it easier to set-up generically.
+/datum/element/processable
+ element_flags = ELEMENT_BESPOKE
+ id_arg_index = 2
+ ///The type of atom this creates when the processing recipe is used.
+ var/result_atom_type
+ ///The tool behaviour for this processing recipe
+ var/tool_behaviour
+ ///Time to process the atom
+ var/time_to_process
+ ///Amount of the resulting actor this will create
+ var/amount_created
+ ///Whether or not the atom being processed has to be on a table or tray to process it
+ var/table_required
+
+/datum/element/processable/Attach(datum/target, tool_behaviour, result_atom_type, amount_created = 3, time_to_process = 20, table_required = FALSE)
+ . = ..()
+ if(!isatom(target))
+ return ELEMENT_INCOMPATIBLE
+
+ src.tool_behaviour = tool_behaviour
+ src.amount_created = amount_created
+ src.time_to_process = time_to_process
+ src.result_atom_type = result_atom_type
+ src.table_required = table_required
+
+ RegisterSignal(target, COMSIG_ATOM_TOOL_ACT(tool_behaviour), PROC_REF(try_process))
+
+/datum/element/processable/Detach(datum/target)
+ . = ..()
+ UnregisterSignal(target, COMSIG_ATOM_TOOL_ACT(tool_behaviour))
+
+/datum/element/processable/proc/try_process(datum/source, mob/living/user, obj/item/I, list/mutable_recipes)
+ SIGNAL_HANDLER
+
+ if(table_required)
+ var/obj/item/found_item = source
+ var/found_location = found_item.loc
+ var/found_turf = isturf(found_location)
+ var/found_table = locate(/obj/structure/table) in found_location
+ var/found_tray = locate(/obj/item/storage/bag/tray) in found_location
+ if(!found_turf && !istype(found_location, /obj/item/storage/bag/tray) || found_turf && !(found_table || found_tray))
+ to_chat(user, "You cannot make that here! You need a table or at least a tray.")
+ return
+
+ mutable_recipes += list(list(TOOL_PROCESSING_RESULT = result_atom_type, TOOL_PROCESSING_AMOUNT = amount_created, TOOL_PROCESSING_TIME = time_to_process))
+ return COMPONENT_NO_AFTERATTACK
diff --git a/code/datums/materials/_material.dm b/code/datums/materials/_material.dm
index 4f505cb2a3e7..1b05f7d7ef95 100644
--- a/code/datums/materials/_material.dm
+++ b/code/datums/materials/_material.dm
@@ -79,6 +79,16 @@ Simple datum which is instanced once per type and is used for every object of sa
/atom/proc/mat_update_desc(/datum/material/mat)
return
+
+/**
+ * This proc is called when the mat is found in an item that's consumed by accident. see /obj/item/proc/on_accidental_consumption.
+ * Arguments
+ * * M - person consuming the mat
+ * * S - (optional) item the mat is contained in (NOT the item with the mat itself)
+ */
+/datum/material/proc/on_accidental_mat_consumption(mob/living/carbon/M, obj/item/S)
+ return FALSE
+
///This proc is called when the material is added to an object specifically.
/datum/material/proc/on_applied_obj(obj/o, amount, material_flags)
if(material_flags & MATERIAL_AFFECT_STATISTICS)
diff --git a/code/datums/traits/negative.dm b/code/datums/traits/negative.dm
index d1a8fd6acaa5..873729866a40 100644
--- a/code/datums/traits/negative.dm
+++ b/code/datums/traits/negative.dm
@@ -105,7 +105,7 @@
if("Clown")
heirloom_type = /obj/item/bikehorn/golden
if("Mime")
- heirloom_type = /obj/item/reagent_containers/food/snacks/baguette
+ heirloom_type = /obj/item/food/baguette
if("Janitor")
heirloom_type = pick(/obj/item/mop, /obj/item/clothing/suit/caution, /obj/item/reagent_containers/glass/bucket, /obj/item/paper/fluff/stations/soap)
if("Cook")
@@ -464,7 +464,7 @@
to_chat(H, "You think of a dumb thing you said a long time ago and scream internally.")
dumb_thing = FALSE //only once per life
if(prob(1))
- new/obj/item/reagent_containers/food/snacks/spaghetti/pastatomato(get_turf(H)) //now that's what I call spaghetti code
+ new/obj/item/food/spaghetti/pastatomato(get_turf(H)) //now that's what I call spaghetti code
// small chance to make eye contact with inanimate objects/mindless mobs because of nerves
/datum/quirk/social_anxiety/proc/looks_at_floor(datum/source, atom/A)
diff --git a/code/game/atoms.dm b/code/game/atoms.dm
index 6d9f0df9f2ec..80db6272f2fd 100644
--- a/code/game/atoms.dm
+++ b/code/game/atoms.dm
@@ -1265,25 +1265,71 @@
* Must return parent proc ..() in the end if overridden
*/
/atom/proc/tool_act(mob/living/user, obj/item/I, tool_type)
+ var/signal_result
+
+ var/list/processing_recipes = list() //List of recipes that can be mutated by sending the signal
+ signal_result = SEND_SIGNAL(src, COMSIG_ATOM_TOOL_ACT(tool_type), user, I, processing_recipes)
+ if(processing_recipes.len)
+ process_recipes(user, I, processing_recipes)
+ if(QDELETED(I))
+ return TRUE
switch(tool_type)
if(TOOL_CROWBAR)
- . |= crowbar_act(user, I)
+ . = crowbar_act(user, I)
if(TOOL_MULTITOOL)
- . |= multitool_act(user, I)
+ . = multitool_act(user, I)
if(TOOL_SCREWDRIVER)
- . |= screwdriver_act(user, I)
+ . = screwdriver_act(user, I)
if(TOOL_WRENCH)
- . |= wrench_act(user, I)
+ . = wrench_act(user, I)
if(TOOL_WIRECUTTER)
- . |= wirecutter_act(user, I)
+ . = wirecutter_act(user, I)
if(TOOL_WELDER)
- . |= welder_act(user, I)
+ . = welder_act(user, I)
if(TOOL_ANALYZER)
- . |= analyzer_act(user, I)
- if(. & COMPONENT_BLOCK_TOOL_ATTACK)
+ . = analyzer_act(user, I)
+ if(. || signal_result & COMPONENT_BLOCK_TOOL_ATTACK) //Either the proc or the signal handled the tool's events in some way.
return TRUE
-//! Tool-specific behavior procs. They send signals, so try to call ..()
+/atom/proc/process_recipes(mob/living/user, obj/item/I, list/processing_recipes)
+ //Only one recipe? use the first
+ if(processing_recipes.len == 1)
+ StartProcessingAtom(user, I, processing_recipes[1])
+ return
+ //Otherwise, select one with a radial
+ ShowProcessingGui(user, I, processing_recipes)
+
+///Creates the radial and processes the selected option
+/atom/proc/ShowProcessingGui(mob/living/user, obj/item/I, list/possible_options)
+ var/list/choices_to_options = list() //Dict of object name | dict of object processing settings
+ var/list/choices = list()
+
+ for(var/i in possible_options)
+ var/list/current_option = i
+ var/atom/current_option_type = current_option[TOOL_PROCESSING_RESULT]
+ choices_to_options[initial(current_option_type.name)] = current_option
+ var/image/option_image = image(icon = initial(current_option_type.icon), icon_state = initial(current_option_type.icon_state))
+ choices += list("[initial(current_option_type.name)]" = option_image)
+
+ var/pick = show_radial_menu(user, src, choices, radius = 36, require_near = TRUE)
+
+ StartProcessingAtom(user, I, choices_to_options[pick])
+
+
+/atom/proc/StartProcessingAtom(mob/living/user, obj/item/I, list/chosen_option)
+ to_chat(user, "You start working on [src]")
+ if(I.use_tool(src, user, chosen_option[TOOL_PROCESSING_TIME], volume=50))
+ var/atom/atom_to_create = chosen_option[TOOL_PROCESSING_RESULT]
+ for(var/i = 1 to chosen_option[TOOL_PROCESSING_AMOUNT])
+ new atom_to_create(loc)
+ to_chat(user, "You manage to create [chosen_option[TOOL_PROCESSING_AMOUNT]] [initial(atom_to_create.name)] from [src]")
+ qdel(src)
+ return
+
+/atom/proc/OnCreatedFromProcessing(mob/living/user, obj/item/I, list/chosen_option, atom/original_atom)
+ return
+
+//! Tool-specific behavior procs.
///
///Crowbar act
diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm
index 033307e5472f..88c5df2262da 100644
--- a/code/game/objects/items.dm
+++ b/code/game/objects/items.dm
@@ -817,7 +817,8 @@ GLOBAL_VAR_INIT(embedpocalypse, FALSE) // if true, all items will be able to emb
..()
/obj/item/proc/microwave_act(obj/machinery/microwave/M)
- SEND_SIGNAL(src, COMSIG_ITEM_MICROWAVE_ACT, M)
+ if(SEND_SIGNAL(src, COMSIG_ITEM_MICROWAVE_ACT, M) & COMPONENT_SUCCESFUL_MICROWAVE)
+ return
if(istype(M) && M.dirty < 100)
M.dirty++
@@ -1126,3 +1127,95 @@ GLOBAL_VAR_INIT(embedpocalypse, FALSE) // if true, all items will be able to emb
*/
/obj/item/proc/get_writing_implement_details()
return null
+
+/// How many different types of mats will be counted in a bite?
+#define MAX_MATS_PER_BITE 2
+
+/*
+ * On accidental consumption: when you somehow end up eating an item accidentally (currently, this is used for when items are hidden in food like bread or cake)
+ *
+ * The base proc will check if the item is sharp and has a decent force.
+ * Then, it checks the item's mat datums for the effects it applies afterwards.
+ * Then, it checks tiny items.
+ * After all that, it returns TRUE if the item is set to be discovered. Otherwise, it returns FALSE.
+ *
+ * This works similarily to /suicide_act: if you want an item to have a unique interaction, go to that item
+ * and give it an /on_accidental_consumption proc override. For a simple example of this, check out the nuke disk.
+ *
+ * Arguments
+ * * M - the mob accidentally consuming the item
+ * * user - the mob feeding M the item - usually, it's the same as M
+ * * source_item - the item that held the item being consumed - bread, cake, etc
+ * * discover_after - if the item will be discovered after being chomped (FALSE will usually mean it was swallowed, TRUE will usually mean it was bitten into and discovered)
+ */
+/obj/item/proc/on_accidental_consumption(mob/living/carbon/victim, mob/living/carbon/user, obj/item/source_item, discover_after = TRUE)
+ if(get_sharpness() && force >= 5) //if we've got something sharp with a decent force (ie, not plastic)
+ INVOKE_ASYNC(victim, TYPE_PROC_REF(/mob, emote), "scream")
+ victim.visible_message("[victim] looks like [victim.p_theyve()] just bit something they shouldn't have!", \
+ "OH GOD! Was that a crunch? That didn't feel good at all!!")
+
+ victim.apply_damage(max(15, force), BRUTE, BODY_ZONE_HEAD)
+ victim.losebreath += 2
+ if(tryEmbed(victim.get_bodypart(BODY_ZONE_CHEST), forced = TRUE)) //and if it embeds successfully in their chest, cause a lot of pain
+ victim.apply_damage(max(25, force*1.5), BRUTE, BODY_ZONE_CHEST)
+ victim.losebreath += 6
+ discover_after = FALSE
+ if(QDELETED(src)) // in case trying to embed it caused its deletion (say, if it's DROPDEL)
+ return
+ source_item?.reagents?.add_reagent(/datum/reagent/blood, 2)
+
+ else if(custom_materials?.len) //if we've got materials, lets see whats in it
+ /// How many mats have we found? You can only be affected by two material datums by default
+ var/found_mats = 0
+ /// How much of each material is in it? Used to determine if the glass should break
+ var/total_material_amount = 0
+
+ for(var/mats in custom_materials)
+ total_material_amount += custom_materials[mats]
+ if(found_mats >= MAX_MATS_PER_BITE)
+ continue //continue instead of break so we can finish adding up all the mats to the total
+
+ var/datum/material/discovered_mat = mats
+ if(discovered_mat.on_accidental_mat_consumption(victim, source_item))
+ found_mats++
+
+ //if there's glass in it and the glass is more than 60% of the item, then we can shatter it
+ if(custom_materials[SSmaterials.GetMaterialRef(/datum/material/glass)] >= total_material_amount * 0.60)
+ if(prob(66)) //66% chance to break it
+ /// The glass shard that is spawned into the source item
+ var/obj/item/shard/broken_glass = new /obj/item/shard(loc)
+ broken_glass.name = "broken [name]"
+ broken_glass.desc = "This used to be \a [name], but it sure isn't anymore."
+ playsound(victim, "shatter", 25, TRUE)
+ qdel(src)
+ if(QDELETED(source_item))
+ broken_glass.on_accidental_consumption(victim, user)
+ else //33% chance to just "crack" it (play a sound) and leave it in the bread
+ playsound(victim, "shatter", 15, TRUE)
+ discover_after = FALSE
+
+ victim.adjust_disgust(33)
+ victim.visible_message(
+ "[victim] looks like [victim.p_theyve()] just bitten into something hard.", \
+ "Eugh! Did I just bite into something?")
+
+ else if(w_class == WEIGHT_CLASS_TINY) //small items like soap or toys that don't have mat datums
+ /// victim's chest (for cavity implanting the item)
+ var/obj/item/bodypart/chest/victim_cavity = victim.get_bodypart(BODY_ZONE_CHEST)
+ if(victim_cavity.cavity_item)
+ victim.vomit(5, FALSE, FALSE, distance = 0)
+ forceMove(drop_location())
+ to_chat(victim, "You vomit up a [name]! [source_item? "Was that in \the [source_item]?" : ""]")
+ else
+ victim.transferItemToLoc(src, victim, TRUE)
+ victim.losebreath += 2
+ victim_cavity.cavity_item = src
+ to_chat(victim, "You swallow hard. [source_item? "Something small was in \the [source_item]..." : ""]")
+ discover_after = FALSE
+
+ else
+ to_chat(victim, "[source_item? "Something strange was in the \the [source_item]..." : "I just bit something strange..."] ")
+
+ return discover_after
+
+#undef MAX_MATS_PER_BITE
diff --git a/code/game/objects/items/food/_food.dm b/code/game/objects/items/food/_food.dm
new file mode 100644
index 000000000000..b8233e0ecc76
--- /dev/null
+++ b/code/game/objects/items/food/_food.dm
@@ -0,0 +1,67 @@
+///Abstract class to allow us to easily create all the generic "normal" food without too much copy pasta of adding more components
+/obj/item/food
+ name = "food"
+ desc = "you eat this"
+ resistance_flags = FLAMMABLE
+ w_class = WEIGHT_CLASS_SMALL
+ icon = 'icons/obj/food/food.dmi'
+ icon_state = null
+ lefthand_file = 'icons/mob/inhands/misc/food_lefthand.dmi'
+ righthand_file = 'icons/mob/inhands/misc/food_righthand.dmi'
+ ///List of reagents this food gets on creation
+ var/list/food_reagents
+ ///Extra flags for things such as if the food is in a container or not
+ var/food_flags
+ ///Bitflag of the types of food this food is
+ var/foodtypes
+ ///Amount of volume the food can contain
+ var/max_volume
+ ///How long it will take to eat this food without any other modifiers
+ var/eat_time
+ ///Tastes to describe this food
+ var/list/tastes
+ ///Verbs used when eating this food in the to_chat messages
+ var/list/eatverbs
+ ///How much reagents per bite
+ var/bite_consumption
+ ///What you get if you microwave the food, this should be replaced once I fully re-work cooking.
+ var/microwaved_type
+ ///Type of atom thats spawned after eating this item
+ var/trash_type
+
+/obj/item/food/Initialize()
+ . = ..()
+ if(food_reagents)
+ food_reagents = string_assoc_list(food_reagents)
+ if(tastes)
+ tastes = string_assoc_list(tastes)
+ if(eatverbs)
+ eatverbs = string_list(eatverbs)
+ make_edible()
+ make_processable()
+ make_leave_trash()
+
+///This proc adds the edible component, overwrite this if you for some reason want to change some specific args like callbacks.
+/obj/item/food/proc/make_edible()
+ AddComponent(/datum/component/edible,\
+ 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,\
+ )
+
+
+///This proc handles processable elements, overwrite this if you want to add behavior such as slicing, forking, spooning, whatever, to turn the item into something else
+/obj/item/food/proc/make_processable()
+ return
+
+///This proc handles trash components, overwrite this if you want the object to spawn trash
+/obj/item/food/proc/make_leave_trash()
+ if(trash_type)
+ AddElement(/datum/element/food_trash, trash_type)
+ return
diff --git a/code/game/objects/items/food/bread.dm b/code/game/objects/items/food/bread.dm
new file mode 100644
index 000000000000..609315a9ea12
--- /dev/null
+++ b/code/game/objects/items/food/bread.dm
@@ -0,0 +1,378 @@
+
+/obj/item/food/bread
+ name = "bread?"
+ desc = "This shouldn't exist, report to codermonkeys"
+ icon = 'icons/obj/food/burgerbread.dmi'
+ max_volume = 80
+ tastes = list("bread" = 10)
+ foodtypes = GRAIN
+ eat_time = 3 SECONDS
+ /// type is spawned 5 at a time and replaces this bread loaf when processed by cutting tool
+ var/obj/item/food/breadslice/slice_type
+ /// so that the yield can change if it isnt 5
+ var/yield = 5
+
+/obj/item/food/bread/Initialize(mapload)
+ . = ..()
+ AddElement(/datum/element/dunkable, 10)
+ AddComponent(/datum/component/food_storage)
+
+/obj/item/food/bread/make_processable()
+ if (slice_type)
+ AddElement(/datum/element/processable, TOOL_KNIFE, slice_type, yield, 3 SECONDS, table_required = TRUE)
+ AddElement(/datum/element/processable, TOOL_SAW, slice_type, yield, 4 SECONDS, table_required = TRUE)
+
+/obj/item/food/breadslice
+ name = "breadslice?"
+ desc = "This shouldn't exist, report to codermonkeys"
+ icon = 'icons/obj/food/burgerbread.dmi'
+ foodtypes = GRAIN
+ food_flags = FOOD_FINGER_FOOD
+ eat_time = 0.5 SECONDS
+ w_class = WEIGHT_CLASS_SMALL
+
+/obj/item/food/breadslice/Initialize()
+ . = ..()
+ AddElement(/datum/element/dunkable, 10)
+
+/obj/item/food/bread/plain
+ name = "bread"
+ desc = "Some plain old earthen bread."
+ icon_state = "bread"
+ food_reagents = list(
+ /datum/reagent/consumable/nutriment = 10
+ )
+ tastes = list("bread" = 10)
+ foodtypes = GRAIN
+ w_class = WEIGHT_CLASS_SMALL
+ slice_type = /obj/item/food/breadslice/plain
+
+/obj/item/food/breadslice/plain
+ name = "bread slice"
+ desc = "A slice of home."
+ icon_state = "breadslice"
+ foodtypes = GRAIN
+ food_reagents = list(
+ /datum/reagent/consumable/nutriment = 2
+ )
+
+/obj/item/food/breadslice/moldy
+ name = "moldy bread slice"
+ desc = "Entire stations have been ripped apart over arguing whether this is still good to eat."
+ icon_state = "moldybreadslice"
+ food_reagents = list(
+ /datum/reagent/consumable/nutriment = 2,
+ /datum/reagent/consumable/mold = 10,
+ )
+ tastes = list("decaying fungus" = 1)
+ foodtypes = GROSS
+
+/obj/item/food/bread/meat
+ name = "meatbread loaf"
+ desc = "The culinary base of every self-respecting eloquen/tg/entleman."
+ icon_state = "meatbread"
+ food_reagents = list(
+ /datum/reagent/consumable/nutriment = 20,
+ /datum/reagent/consumable/nutriment/vitamin = 10
+ )
+ tastes = list("bread" = 10, "meat" = 10)
+ foodtypes = GRAIN | MEAT
+ slice_type = /obj/item/food/breadslice/meat
+
+/obj/item/food/breadslice/meat
+ name = "meatbread slice"
+ desc = "A slice of delicious meatbread."
+ icon_state = "meatbreadslice"
+ food_reagents = list(
+ /datum/reagent/consumable/nutriment = 4,
+ /datum/reagent/consumable/nutriment/vitamin = 2
+ )
+ tastes = list("bread" = 1, "meat" = 1)
+ foodtypes = GRAIN | MEAT
+
+/obj/item/food/bread/xenomeat
+ name = "xenomeatbread loaf"
+ desc = "Extra Heretical."
+ icon_state = "xenomeatbread"
+ food_reagents = list(
+ /datum/reagent/consumable/nutriment = 20,
+ /datum/reagent/consumable/nutriment/vitamin = 10
+ )
+ tastes = list("bread" = 10, "acid" = 10)
+ foodtypes = GRAIN | MEAT
+ slice_type = /obj/item/food/breadslice/xenomeat
+
+/obj/item/food/breadslice/xenomeat
+ name = "xenomeatbread slice"
+ desc = "A slice of delicious meatbread. Extra Heretical."
+ icon_state = "xenobreadslice"
+ food_reagents = list(
+ /datum/reagent/consumable/nutriment = 4,
+ /datum/reagent/consumable/nutriment/vitamin = 2
+ )
+ tastes = list("bread" = 10, "acid" = 10)
+ foodtypes = GRAIN | MEAT
+
+/obj/item/food/bread/spidermeat
+ name = "spider meat loaf"
+ desc = "Reassuringly green meatloaf made from spider meat."
+ icon_state = "spidermeatbread"
+ food_reagents = list(
+ /datum/reagent/consumable/nutriment = 20,
+ /datum/reagent/toxin = 15,
+ /datum/reagent/consumable/nutriment/vitamin = 10
+ )
+ tastes = list("bread" = 10, "cobwebs" = 5)
+ foodtypes = GRAIN | MEAT | TOXIC
+ slice_type = /obj/item/food/breadslice/spidermeat
+
+/obj/item/food/breadslice/spidermeat
+ name = "spider meat bread slice"
+ desc = "A slice of meatloaf made from an animal that most likely still wants you dead."
+ icon_state = "xenobreadslice"
+ food_reagents = list(
+ /datum/reagent/consumable/nutriment = 3,
+ /datum/reagent/toxin = 3,
+ /datum/reagent/consumable/nutriment/vitamin = 1
+ )
+ tastes = list("bread" = 10, "cobwebs" = 5)
+ foodtypes = GRAIN | MEAT | TOXIC
+
+/obj/item/food/bread/banana
+ name = "banana-nut bread"
+ desc = "A heavenly and filling treat."
+ icon_state = "bananabread"
+ food_reagents = list(
+ /datum/reagent/consumable/nutriment = 20,
+ /datum/reagent/consumable/banana = 20
+ )
+ tastes = list("bread" = 10) // bananjuice will also flavour
+ foodtypes = GRAIN | FRUIT
+ slice_type = /obj/item/food/breadslice/banana
+
+/obj/item/food/breadslice/banana
+ name = "banana-nut bread slice"
+ desc = "A slice of delicious banana bread."
+ icon_state = "bananabreadslice"
+ food_reagents = list(
+ /datum/reagent/consumable/nutriment = 4,
+ /datum/reagent/consumable/banana = 4
+ )
+ tastes = list("bread" = 10)
+ foodtypes = GRAIN | FRUIT
+
+/obj/item/food/bread/tofu
+ name = "Tofubread"
+ desc = "Like meatbread but for vegetarians. Not guaranteed to give superpowers."
+ icon_state = "tofubread"
+ food_reagents = list(
+ /datum/reagent/consumable/nutriment = 20,
+ /datum/reagent/consumable/nutriment/vitamin = 10
+ )
+ tastes = list("bread" = 10, "tofu" = 10)
+ foodtypes = GRAIN | VEGETABLES
+ slice_type = /obj/item/food/breadslice/tofu
+
+/obj/item/food/breadslice/tofu
+ name = "tofubread slice"
+ desc = "A slice of delicious tofubread."
+ icon_state = "tofubreadslice"
+ food_reagents = list(
+ /datum/reagent/consumable/nutriment = 4,
+ /datum/reagent/consumable/nutriment/vitamin = 2
+ )
+ tastes = list("bread" = 10, "tofu" = 10)
+ foodtypes = GRAIN | VEGETABLES
+
+/obj/item/food/bread/creamcheese
+ name = "cream cheese bread"
+ desc = "Just a schmear."
+ icon_state = "creamcheesebread"
+ food_reagents = list(
+ /datum/reagent/consumable/nutriment = 20,
+ /datum/reagent/consumable/nutriment/vitamin = 10
+ )
+ tastes = list("bread" = 10, "cheese" = 10)
+ foodtypes = GRAIN | DAIRY
+ slice_type = /obj/item/food/breadslice/creamcheese
+
+/obj/item/food/breadslice/creamcheese
+ name = "cream cheese bread slice"
+ desc = "A slice of Brotherly love!"
+ icon_state = "creamcheesebreadslice"
+ food_reagents = list(
+ /datum/reagent/consumable/nutriment = 3,
+ /datum/reagent/consumable/nutriment/vitamin = 2
+ )
+ tastes = list("bread" = 10, "cheese" = 10)
+ foodtypes = GRAIN | DAIRY
+
+/obj/item/food/bread/mimana
+ name = "mimana bread"
+ desc = "Best eaten in silence."
+ icon_state = "mimanabread"
+ food_reagents = list(
+ /datum/reagent/consumable/nutriment = 20,
+ /datum/reagent/toxin/mutetoxin = 10,
+ /datum/reagent/consumable/nothing = 10,
+ /datum/reagent/consumable/nutriment/vitamin = 10
+ )
+ tastes = list("bread" = 10, "silence" = 10)
+ foodtypes = GRAIN | FRUIT
+ slice_type = /obj/item/food/breadslice/mimana
+
+/obj/item/food/breadslice/mimana
+ name = "mimana bread slice"
+ desc = "A slice of silence!"
+ icon_state = "mimanabreadslice"
+ food_reagents = list(
+ /datum/reagent/consumable/nutriment = 4,
+ /datum/reagent/toxin/mutetoxin = 2,
+ /datum/reagent/consumable/nothing = 2,
+ /datum/reagent/consumable/nutriment/vitamin = 2
+ )
+ foodtypes = GRAIN | FRUIT
+
+/obj/item/food/breadslice/custom
+ name = "bread slice"
+ icon_state = "tofubreadslice"
+ foodtypes = GRAIN
+
+/obj/item/food/baguette
+ name = "baguette"
+ desc = "Bon appetit!"
+ icon = 'icons/obj/food/burgerbread.dmi'
+ icon_state = "baguette"
+ item_state = null
+ mob_overlay_state = "baguette"
+ food_reagents = list(
+ /datum/reagent/consumable/nutriment = 8,
+ /datum/reagent/consumable/nutriment/vitamin = 3
+ )
+ bite_consumption = 3
+ w_class = WEIGHT_CLASS_NORMAL
+ slot_flags = ITEM_SLOT_BACK|ITEM_SLOT_BELT
+ attack_verb = list("touche")
+ tastes = list("bread" = 1)
+ foodtypes = GRAIN
+
+/obj/item/food/garlicbread
+ name = "garlic bread"
+ desc = "Alas, it is limited."
+ icon = 'icons/obj/food/burgerbread.dmi'
+ icon_state = "garlicbread"
+ item_state = null
+ food_reagents = list(
+ /datum/reagent/consumable/nutriment = 10,
+ /datum/reagent/consumable/nutriment/vitamin = 6,
+ /datum/reagent/consumable/garlic = 2
+ )
+ bite_consumption = 3
+ tastes = list("bread" = 1, "garlic" = 1, "butter" = 1)
+ foodtypes = GRAIN
+
+/obj/item/food/deepfryholder
+ name = "Deep Fried Foods Holder Obj"
+ desc = "If you can see this description the code for the deep fryer fucked up."
+ icon = 'icons/obj/food/food.dmi'
+ icon_state = ""
+ bite_consumption = 2
+
+/obj/item/food/deepfryholder/make_edible()
+ 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_REF(On_Consume)))
+
+
+/obj/item/food/deepfryholder/Initialize(mapload, obj/item/fried)
+ . = ..()
+ name = fried.name //We'll determine the other stuff when it's actually removed
+ appearance = fried.appearance
+ layer = initial(layer)
+ plane = initial(plane)
+ lefthand_file = fried.lefthand_file
+ righthand_file = fried.righthand_file
+ mob_overlay_state = fried.mob_overlay_state
+ desc = fried.desc
+ w_class = fried.w_class
+ slowdown = fried.slowdown
+ equip_delay_self = fried.equip_delay_self
+ equip_delay_other = fried.equip_delay_other
+ strip_delay = fried.strip_delay
+ species_exception = fried.species_exception
+ item_flags = fried.item_flags
+ obj_flags = fried.obj_flags
+ inhand_x_dimension = fried.inhand_x_dimension
+ inhand_y_dimension = fried.inhand_y_dimension
+
+ if(!(SEND_SIGNAL(fried, COMSIG_ITEM_FRIED, src) & COMSIG_FRYING_HANDLED)) //If frying is handled by signal don't do the defaault behavior.
+ fried.forceMove(src)
+
+
+/obj/item/food/deepfryholder/Destroy()
+ if(contents)
+ QDEL_LIST(contents)
+ return ..()
+
+/obj/item/food/deepfryholder/proc/On_Consume(eater, feeder)
+ if(contents)
+ QDEL_LIST(contents)
+
+
+/obj/item/food/deepfryholder/proc/fry(cook_time = 30)
+ switch(cook_time)
+ if(0 to 15)
+ add_atom_colour(rgb(166,103,54), FIXED_COLOUR_PRIORITY)
+ name = "lightly-fried [name]"
+ desc = "[desc] It's been lightly fried in a deep fryer."
+ if(16 to 49)
+ add_atom_colour(rgb(103,63,24), FIXED_COLOUR_PRIORITY)
+ name = "fried [name]"
+ desc = "[desc] It's been fried, increasing its tastiness value by [rand(1, 75)]%."
+ if(50 to 59)
+ add_atom_colour(rgb(63,23,4), FIXED_COLOUR_PRIORITY)
+ name = "deep-fried [name]"
+ desc = "[desc] Deep-fried to perfection."
+ if(60 to INFINITY)
+ add_atom_colour(rgb(33,19,9), FIXED_COLOUR_PRIORITY)
+ name = "\proper the physical manifestation of the very concept of fried foods"
+ desc = "A heavily-fried... something. Who can tell anymore?"
+ foodtypes |= FRIED
+
+/obj/item/food/butterbiscuit
+ name = "butter biscuit"
+ desc = "Well butter my biscuit!"
+ icon = 'icons/obj/food/food.dmi'
+ icon_state = "butterbiscuit"
+ food_reagents = list(
+ /datum/reagent/consumable/nutriment = 6,
+ /datum/reagent/consumable/nutriment/vitamin = 1
+ )
+ tastes = list("butter" = 1, "biscuit" = 1)
+ foodtypes = GRAIN | BREAKFAST
+ w_class = WEIGHT_CLASS_SMALL
+
+/obj/item/food/butterdog
+ name = "butterdog"
+ desc = "Made from exotic butters."
+ icon = 'icons/obj/food/food.dmi'
+ icon_state = "butterdog"
+ bite_consumption = 1
+ food_reagents = list(
+ /datum/reagent/consumable/nutriment = 6,
+ /datum/reagent/consumable/nutriment/vitamin = 1
+ )
+ tastes = list("butter" = 1, "exotic butter" = 1)
+ foodtypes = GRAIN | DAIRY
+ w_class = WEIGHT_CLASS_SMALL
+
+/obj/item/food/butterdog/ComponentInitialize()
+ . = ..()
+ AddComponent(/datum/component/slippery, 8 SECONDS)
diff --git a/code/game/objects/items/food/cake.dm b/code/game/objects/items/food/cake.dm
new file mode 100644
index 000000000000..d6299a24d524
--- /dev/null
+++ b/code/game/objects/items/food/cake.dm
@@ -0,0 +1,538 @@
+/obj/item/food/cake
+ icon = 'icons/obj/food/piecake.dmi'
+ bite_consumption = 3
+ max_volume = 80
+ food_reagents = list(
+ /datum/reagent/consumable/nutriment = 20,
+ /datum/reagent/consumable/nutriment/vitamin = 5
+ )
+ tastes = list("cake" = 1)
+ foodtypes = GRAIN | DAIRY
+ /// type is spawned 5 at a time and replaces this cake when processed by cutting tool
+ var/obj/item/food/cakeslice/slice_type
+ /// changes yield of sliced cake, default for cake is 5
+ var/yield = 5
+
+/obj/item/food/cake/Initialize(mapload)
+ . = ..()
+ AddComponent(/datum/component/food_storage)
+
+/obj/item/food/cake/make_processable()
+ if (slice_type)
+ AddElement(/datum/element/processable, TOOL_KNIFE, slice_type, yield, 3 SECONDS, table_required = TRUE)
+
+/obj/item/food/cakeslice
+ icon = 'icons/obj/food/piecake.dmi'
+ food_reagents = list(
+ /datum/reagent/consumable/nutriment = 4,
+ /datum/reagent/consumable/nutriment/vitamin = 1
+ )
+ tastes = list("cake" = 1)
+ foodtypes = GRAIN | DAIRY
+ w_class = WEIGHT_CLASS_SMALL
+
+/obj/item/food/cake/plain
+ name = "plain cake"
+ desc = "A plain cake, not a lie." //Many of the cakes seem to follow this desc scheme, so I am going to try and put either a hint about its contents, or a fun fact. Lets try to follow this.
+ icon_state = "plaincake"
+ food_reagents = list(
+ /datum/reagent/consumable/nutriment = 30,
+ /datum/reagent/consumable/nutriment/vitamin = 7
+ )
+ tastes = list("sweetness" = 2, "cake" = 5)
+ foodtypes = GRAIN | DAIRY | SUGAR
+ slice_type = /obj/item/food/cakeslice/plain
+
+/obj/item/food/cakeslice/plain
+ name = "plain cake slice"
+ desc = "Just a slice of cake, it is enough for everyone."
+ icon_state = "plaincake_slice"
+ tastes = list("sweetness" = 2,"cake" = 5)
+ foodtypes = GRAIN | DAIRY | SUGAR
+
+/obj/item/food/cake/carrot
+ name = "carrot cake"
+ desc = "Scientifically proven to improve eyesight! Not a lie."
+ icon_state = "carrotcake"
+ food_reagents = list(
+ /datum/reagent/consumable/nutriment = 20,
+ /datum/reagent/medicine/oculine = 10,
+ /datum/reagent/consumable/nutriment/vitamin = 5
+ )
+ tastes = list("cake" = 5, "sweetness" = 2, "carrot" = 1)
+ foodtypes = GRAIN | DAIRY | VEGETABLES | SUGAR
+ slice_type = /obj/item/food/cakeslice/carrot
+
+/obj/item/food/cakeslice/carrot
+ name = "carrot cake slice"
+ desc = "Carrotty slice of Carrot Cake, carrots are good for your eyes! Also not a lie."
+ icon_state = "carrotcake_slice"
+ food_reagents = list(
+ /datum/reagent/consumable/nutriment = 4,
+ /datum/reagent/medicine/oculine = 2,
+ /datum/reagent/consumable/nutriment/vitamin = 1
+ )
+ tastes = list("cake" = 5, "sweetness" = 2, "carrot" = 1)
+ foodtypes = GRAIN | DAIRY | VEGETABLES | SUGAR
+
+/obj/item/food/cake/brain
+ name = "brain cake"
+ desc = "Yeah... its actually made out of brain. I wish it were a lie."
+ icon_state = "braincake"
+ food_reagents = list(
+ /datum/reagent/consumable/nutriment = 15,
+ /datum/reagent/medicine/mannitol = 10,
+ /datum/reagent/consumable/nutriment/vitamin = 5
+ )
+ tastes = list("cake" = 5, "sweetness" = 2, "brains" = 1)
+ foodtypes = GRAIN | DAIRY | MEAT | GROSS | SUGAR
+ slice_type = /obj/item/food/cakeslice/brain
+
+/obj/item/food/cakeslice/brain
+ name = "brain cake slice"
+ desc = "Lemme tell you something about prions. THEY'RE DELICIOUS. A terrifying not-lie."
+ icon_state = "braincakeslice"
+ food_reagents = list(
+ /datum/reagent/consumable/nutriment = 4,
+ /datum/reagent/medicine/mannitol = 2,
+ /datum/reagent/consumable/nutriment/vitamin = 1
+ )
+ tastes = list("cake" = 5, "sweetness" = 2, "brains" = 1)
+ foodtypes = GRAIN | DAIRY | MEAT | GROSS | SUGAR
+
+/obj/item/food/cake/cheese
+ name = "cheese cake"
+ desc = "DANGEROUSLY cheesy."
+ icon_state = "cheesecake"
+ food_reagents = list(
+ /datum/reagent/consumable/nutriment = 20,
+ /datum/reagent/consumable/nutriment/vitamin = 8
+ )
+ tastes = list("cake" = 4, "cream cheese" = 3)
+ foodtypes = GRAIN | DAIRY
+ slice_type = /obj/item/food/cakeslice/cheese
+
+/obj/item/food/cakeslice/cheese
+ name = "cheese cake slice"
+ desc = "Slice of pure cheestisfaction."
+ icon_state = "cheesecake_slice"
+ food_reagents = list(
+ /datum/reagent/consumable/nutriment = 4,
+ /datum/reagent/consumable/nutriment/vitamin = 1.3
+ )
+ tastes = list("cake" = 4, "cream cheese" = 3)
+ foodtypes = GRAIN | DAIRY
+
+/obj/item/food/cake/orange
+ name = "orange cake"
+ desc = "A cake with added orange."
+ icon_state = "orangecake"
+ food_reagents = list(
+ /datum/reagent/consumable/nutriment = 20,
+ /datum/reagent/consumable/nutriment/vitamin = 10
+ )
+ tastes = list("cake" = 5, "sweetness" = 2, "oranges" = 2)
+ foodtypes = GRAIN | DAIRY | FRUIT | SUGAR
+ slice_type = /obj/item/food/cakeslice/orange
+
+/obj/item/food/cakeslice/orange
+ name = "orange cake slice"
+ desc = "Just a slice of cake, it is enough for everyone."
+ icon_state = "orangecake_slice"
+ tastes = list("cake" = 5, "sweetness" = 2, "oranges" = 2)
+ foodtypes = GRAIN | DAIRY | FRUIT | SUGAR
+
+/obj/item/food/cake/lime
+ name = "lime cake"
+ desc = "A cake with added lime."
+ icon_state = "limecake"
+ food_reagents = list(
+ /datum/reagent/consumable/nutriment = 20,
+ /datum/reagent/consumable/nutriment/vitamin = 10
+ )
+ tastes = list("cake" = 5, "sweetness" = 2, "unbearable sourness" = 2)
+ foodtypes = GRAIN | DAIRY | FRUIT | SUGAR
+ slice_type = /obj/item/food/cakeslice/lime
+
+/obj/item/food/cakeslice/lime
+ name = "lime cake slice"
+ desc = "Just a slice of cake, it is enough for everyone."
+ icon_state = "limecake_slice"
+ tastes = list("cake" = 5, "sweetness" = 2, "unbearable sourness" = 2)
+ foodtypes = GRAIN | DAIRY | FRUIT | SUGAR
+
+/obj/item/food/cake/lemon
+ name = "lemon cake"
+ desc = "A cake with added lemon."
+ icon_state = "lemoncake"
+ food_reagents = list(
+ /datum/reagent/consumable/nutriment = 20,
+ /datum/reagent/consumable/nutriment/vitamin = 10
+ )
+ tastes = list("cake" = 5, "sweetness" = 3, "sourness" = 1) //lemon cake is never as sour as it is sweet, have you ever actually eaten it?
+ foodtypes = GRAIN | DAIRY | FRUIT | SUGAR
+ slice_type = /obj/item/food/cakeslice/lemon
+
+/obj/item/food/cakeslice/lemon
+ name = "lemon cake slice"
+ desc = "Just a slice of cake, it is enough for everyone."
+ icon_state = "lemoncake_slice"
+ tastes = list("cake" = 5, "sweetness" = 2, "sourness" = 2)
+ foodtypes = GRAIN | DAIRY | FRUIT | SUGAR
+
+/obj/item/food/cake/chocolate
+ name = "chocolate cake"
+ desc = "A cake with added chocolate."
+ icon_state = "chocolatecake"
+ food_reagents = list(
+ /datum/reagent/consumable/nutriment = 20,
+ /datum/reagent/consumable/nutriment/vitamin = 10
+ )
+ tastes = list("cake" = 5, "sweetness" = 1, "chocolate" = 4)
+ foodtypes = GRAIN | DAIRY | JUNKFOOD | SUGAR
+ slice_type = /obj/item/food/cakeslice/chocolate
+
+/obj/item/food/cakeslice/chocolate
+ name = "chocolate cake slice"
+ desc = "Just a slice of cake, it is enough for everyone."
+ icon_state = "chocolatecake_slice"
+ tastes = list("cake" = 5, "sweetness" = 1, "chocolate" = 4)
+ foodtypes = GRAIN | DAIRY | JUNKFOOD | SUGAR
+
+/obj/item/food/cake/birthday
+ name = "birthday cake"
+ desc = "Happy Birthday little clown..."
+ icon_state = "birthdaycake"
+ food_reagents = list(
+ /datum/reagent/consumable/nutriment = 20,
+ /datum/reagent/consumable/sprinkles = 10,
+ /datum/reagent/consumable/nutriment/vitamin = 5
+ )
+ tastes = list("cake" = 5, "sweetness" = 1)
+ foodtypes = GRAIN | DAIRY | JUNKFOOD | SUGAR
+ slice_type = /obj/item/food/cakeslice/birthday
+
+/obj/item/food/cake/birthday/microwave_act(obj/machinery/microwave/M) //super sekrit club
+ new /obj/item/clothing/head/hardhat/cakehat(get_turf(src))
+ qdel(src)
+
+/obj/item/food/cakeslice/birthday
+ name = "birthday cake slice"
+ desc = "A slice of your birthday."
+ icon_state = "birthdaycakeslice"
+ food_reagents = list(
+ /datum/reagent/consumable/nutriment = 4,
+ /datum/reagent/consumable/sprinkles = 2,
+ /datum/reagent/consumable/nutriment/vitamin = 1
+ )
+ tastes = list("cake" = 5, "sweetness" = 1)
+ foodtypes = GRAIN | DAIRY | JUNKFOOD | SUGAR
+
+/obj/item/food/cake/birthday/energy
+ name = "energy cake"
+ desc = "Just enough calories for a whole nuclear operative squad."
+ icon_state = "energycake"
+ force = 5
+ hitsound = 'sound/weapons/blade1.ogg'
+ food_reagents = list(
+ /datum/reagent/consumable/nutriment = 10,
+ /datum/reagent/consumable/sprinkles = 10,
+ /datum/reagent/consumable/nutriment/vitamin = 5,
+ /datum/reagent/consumable/pacfuel = 10,
+ /datum/reagent/consumable/liquidelectricity = 10
+ )
+ tastes = list("cake" = 3, "a Vlad's Salad" = 1)
+ slice_type = /obj/item/food/cakeslice/birthday/energy
+
+/obj/item/food/cake/birthday/energy/microwave_act(obj/machinery/microwave/M) //super sekriter club
+ new /obj/item/clothing/head/hardhat/cakehat/energycake(get_turf(src))
+ qdel(src)
+
+/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, BURN, BODY_ZONE_HEAD) // ITs an ENERGY sword, so it burns, duh
+ playsound(user, 'sound/weapons/blade1.ogg', 5, TRUE)
+
+/obj/item/food/cake/birthday/energy/attack(mob/living/target_mob, mob/living/user)
+ . = ..()
+ if(HAS_TRAIT(user, TRAIT_PACIFISM) && target_mob != user) //Prevents pacifists from attacking others directly
+ return
+ energy_bite(target_mob, user)
+
+/obj/item/food/cakeslice/birthday/energy
+ name = "energy cake slice"
+ desc = "For the traitor on the go."
+ icon_state = "energycakeslice"
+ force = 2
+ hitsound = 'sound/weapons/blade1.ogg'
+ food_reagents = list(
+ /datum/reagent/consumable/nutriment = 4,
+ /datum/reagent/consumable/sprinkles = 2,
+ /datum/reagent/consumable/nutriment/vitamin = 1,
+ /datum/reagent/consumable/pacfuel = 2,
+ /datum/reagent/consumable/liquidelectricity = 2
+ )
+ tastes = list("cake" = 3, "a Vlad's Salad" = 1)
+
+/obj/item/food/cakeslice/birthday/energy/proc/energy_bite(mob/living/user)
+ to_chat(user, "As you eat the cake slice, you accidentally hurt yourself on the embedded energy dagger!")
+ user.apply_damage(18, BURN, BODY_ZONE_HEAD)
+ playsound(user, 'sound/weapons/blade1.ogg', 5, TRUE)
+
+/obj/item/food/cakeslice/birthday/energy/attack(mob/living/target_mob, mob/living/user)
+ . = ..()
+ if(HAS_TRAIT(user, TRAIT_PACIFISM) && target_mob != user) //Prevents pacifists from attacking others directly
+ return
+ energy_bite(target_mob, user)
+
+/obj/item/food/cake/apple
+ name = "apple cake"
+ desc = "A cake centred with Apple."
+ icon_state = "applecake"
+ food_reagents = list(
+ /datum/reagent/consumable/nutriment = 20,
+ /datum/reagent/consumable/nutriment/vitamin = 10
+ )
+ tastes = list("cake" = 5, "sweetness" = 1, "apple" = 1)
+ foodtypes = GRAIN | DAIRY | FRUIT | SUGAR
+ slice_type = /obj/item/food/cakeslice/apple
+
+/obj/item/food/cakeslice/apple
+ name = "apple cake slice"
+ desc = "A slice of heavenly cake."
+ icon_state = "applecakeslice"
+ tastes = list("cake" = 5, "sweetness" = 1, "apple" = 1)
+ foodtypes = GRAIN | DAIRY | FRUIT | SUGAR
+
+/obj/item/food/cake/slimecake
+ name = "Slime cake"
+ desc = "A cake made of slimes. Probably not electrified."
+ icon_state = "slimecake"
+ tastes = list("cake" = 5, "sweetness" = 1, "slime" = 1)
+ foodtypes = GRAIN | DAIRY | SUGAR
+ slice_type = /obj/item/food/cakeslice/slimecake
+
+/obj/item/food/cakeslice/slimecake
+ name = "slime cake slice"
+ desc = "A slice of slime cake."
+ icon_state = "slimecake_slice"
+ tastes = list("cake" = 5, "sweetness" = 1, "slime" = 1)
+ foodtypes = GRAIN | DAIRY | SUGAR
+
+/obj/item/food/cake/pumpkinspice
+ name = "pumpkin spice cake"
+ desc = "A hollow cake with real pumpkin."
+ icon_state = "pumpkinspicecake"
+ tastes = list("cake" = 5, "sweetness" = 1, "pumpkin" = 1)
+ foodtypes = GRAIN | DAIRY | VEGETABLES | SUGAR
+ slice_type = /obj/item/food/cakeslice/pumpkinspice
+
+/obj/item/food/cakeslice/pumpkinspice
+ name = "pumpkin spice cake slice"
+ desc = "A spicy slice of pumpkin goodness."
+ icon_state = "pumpkinspicecakeslice"
+ tastes = list("cake" = 5, "sweetness" = 1, "pumpkin" = 1)
+ foodtypes = GRAIN | DAIRY | VEGETABLES | SUGAR
+
+/obj/item/food/cake/bsvc // blackberry strawberries vanilla cake
+ name = "blackberry and strawberry vanilla cake"
+ desc = "A plain cake, filled with assortment of blackberries and strawberries!"
+ icon_state = "blackbarry_strawberries_cake_vanilla_cake"
+ tastes = list("blackberry" = 2, "strawberries" = 2, "vanilla" = 2, "sweetness" = 2, "cake" = 3)
+ foodtypes = GRAIN | DAIRY | FRUIT | SUGAR
+ slice_type = /obj/item/food/cakeslice/bsvc
+
+/obj/item/food/cakeslice/bsvc
+ name = "blackberry and strawberry vanilla cake slice"
+ desc = "Just a slice of cake filled with assortment of blackberries and strawberries!"
+ icon_state = "blackbarry_strawberries_cake_vanilla_slice"
+ tastes = list("blackberry" = 2, "strawberries" = 2, "vanilla" = 2, "sweetness" = 2,"cake" = 3)
+ foodtypes = GRAIN | DAIRY | FRUIT | SUGAR
+
+/obj/item/food/cake/bscc // blackbarry strawberries chocolate cake
+ name = "blackberry and strawberry chocolate cake"
+ desc = "A chocolate cake, filled with assortment of blackberries and strawberries!"
+ icon_state = "blackbarry_strawberries_cake_coco_cake"
+ food_reagents = list(
+ /datum/reagent/consumable/nutriment = 20,
+ /datum/reagent/consumable/nutriment/vitamin = 5,
+ /datum/reagent/consumable/coco = 5
+ )
+ tastes = list("blackberry" = 2, "strawberries" = 2, "chocolate" = 4, "sweetness" = 2,"cake" = 3)
+ foodtypes = GRAIN | DAIRY | FRUIT | SUGAR
+ slice_type = /obj/item/food/cakeslice/bscc
+
+/obj/item/food/cakeslice/bscc
+ name = "blackberry and strawberry chocolate cake slice"
+ desc = "Just a slice of cake filled with assortment of blackberries and strawberries!"
+ icon_state = "blackbarry_strawberries_cake_coco_slice"
+ tastes = list("blackberry" = 2, "strawberries" = 2, "chocolate" = 4, "sweetness" = 2,"cake" = 3)
+ foodtypes = GRAIN | DAIRY | FRUIT | SUGAR
+
+/obj/item/food/cake/holy_cake
+ name = "angel food cake"
+ desc = "A cake made for angels and chaplains alike! Contains holy water."
+ icon_state = "holy_cake"
+ food_reagents = list(
+ /datum/reagent/consumable/nutriment = 1,
+ /datum/reagent/consumable/nutriment/vitamin = 3,
+ /datum/reagent/water/holywater = 10
+ )
+ tastes = list("cake" = 5, "sweetness" = 1, "clouds" = 1)
+ foodtypes = GRAIN | DAIRY | SUGAR
+ slice_type = /obj/item/food/cakeslice/holy_cake_slice
+
+/obj/item/food/cakeslice/holy_cake_slice
+ name = "angel food cake slice"
+ desc = "A slice of heavenly cake."
+ icon_state = "holy_cake_slice"
+ tastes = list("cake" = 5, "sweetness" = 1, "clouds" = 1)
+ foodtypes = GRAIN | DAIRY | SUGAR
+
+/obj/item/food/cake/pound_cake
+ name = "pound cake"
+ desc = "A condensed cake made for filling people up quickly."
+ icon_state = "pound_cake"
+ food_reagents = list(
+ /datum/reagent/consumable/nutriment = 60,
+ /datum/reagent/consumable/nutriment/vitamin = 5
+ )
+ tastes = list("cake" = 5, "sweetness" = 1, "batter" = 1)
+ foodtypes = GRAIN | DAIRY | SUGAR | JUNKFOOD
+ slice_type = /obj/item/food/cakeslice/pound_cake_slice
+ yield = 10 //cause its so damn THICC (seriously these things are fucking huge a pound of each ingredient are you kidding)
+
+/obj/item/food/cakeslice/pound_cake_slice
+ name = "pound cake slice"
+ desc = "A slice of condensed cake made for filling people up quickly."
+ icon_state = "pound_cake_slice"
+ food_reagents = list(
+ /datum/reagent/consumable/nutriment = 9,
+ /datum/reagent/consumable/nutriment/vitamin = 0.5
+ )
+ tastes = list("cake" = 5, "sweetness" = 5, "batter" = 1)
+ foodtypes = GRAIN | DAIRY | SUGAR | JUNKFOOD
+
+/obj/item/food/cake/hardware_cake
+ name = "hardware cake"
+ desc = "A quote on quote cake that is made with electronic boards and leaks acid..."
+ icon_state = "hardware_cake"
+ food_reagents = list(
+ /datum/reagent/consumable/nutriment = 20,
+ /datum/reagent/consumable/nutriment/vitamin = 5,
+ /datum/reagent/toxin/acid = 15,
+ /datum/reagent/fuel/oil = 15
+ )
+ tastes = list("acid" = 3, "metal" = 4, "glass" = 5)
+ foodtypes = GRAIN | GROSS
+ slice_type = /obj/item/food/cakeslice/hardware_cake_slice
+
+/obj/item/food/cakeslice/hardware_cake_slice
+ name = "hardware cake slice"
+ desc = "A slice of electronic boards and some acid."
+ icon_state = "hardware_cake_slice"
+ food_reagents = list(
+ /datum/reagent/consumable/nutriment = 4,
+ /datum/reagent/consumable/nutriment/vitamin = 1,
+ /datum/reagent/toxin/acid = 3,
+ /datum/reagent/fuel/oil = 3
+ )
+ tastes = list("acid" = 3, "metal" = 4, "glass" = 5)
+ foodtypes = GRAIN | GROSS
+
+/obj/item/food/cake/vanilla_cake
+ name = "vanilla cake"
+ desc = "A vanilla frosted cake."
+ icon_state = "vanillacake"
+ food_reagents = list(
+ /datum/reagent/consumable/nutriment = 20,
+ /datum/reagent/consumable/nutriment/vitamin = 5,
+ /datum/reagent/consumable/sugar = 15,
+ /datum/reagent/consumable/vanilla = 15
+ )
+ tastes = list("cake" = 1, "sugar" = 1, "vanilla" = 10)
+ foodtypes = GRAIN | SUGAR | DAIRY
+ slice_type = /obj/item/food/cakeslice/vanilla_slice
+
+/obj/item/food/cakeslice/vanilla_slice
+ name = "vanilla cake slice"
+ desc = "A slice of vanilla frosted cake."
+ icon_state = "vanillacake_slice"
+ food_reagents = list(
+ /datum/reagent/consumable/nutriment = 4,
+ /datum/reagent/consumable/nutriment/vitamin = 1,
+ /datum/reagent/consumable/sugar = 3,
+ /datum/reagent/consumable/vanilla = 3
+ )
+ tastes = list("cake" = 1, "sugar" = 1, "vanilla" = 10)
+ foodtypes = GRAIN | SUGAR | DAIRY
+
+/obj/item/food/cake/clown_cake
+ name = "clown cake"
+ desc = "A funny cake with a clown face on it."
+ icon_state = "clowncake"
+ food_reagents = list(
+ /datum/reagent/consumable/nutriment = 20,
+ /datum/reagent/consumable/nutriment/vitamin = 5,
+ /datum/reagent/consumable/banana = 15
+ )
+ tastes = list("cake" = 1, "sugar" = 1, "joy" = 10)
+ foodtypes = GRAIN | SUGAR | DAIRY
+ slice_type = /obj/item/food/cakeslice/clown_slice
+
+/obj/item/food/cakeslice/clown_slice
+ name = "clown cake slice"
+ desc = "A slice of bad jokes, and silly props."
+ icon_state = "clowncake_slice"
+ food_reagents = list(
+ /datum/reagent/consumable/nutriment = 4,
+ /datum/reagent/consumable/nutriment/vitamin = 1,
+ /datum/reagent/consumable/banana = 3
+ )
+ tastes = list("cake" = 1, "sugar" = 1, "joy" = 10)
+ foodtypes = GRAIN | SUGAR | DAIRY
+
+/obj/item/food/cake/trumpet
+ name = "spaceman's cake"
+ desc = "A spaceman's trumpet frosted cake."
+ icon_state = "trumpetcake"
+ food_reagents = list(
+ /datum/reagent/consumable/nutriment = 20,
+ /datum/reagent/consumable/nutriment/vitamin = 5,
+ /datum/reagent/medicine/polypyr = 15,
+ /datum/reagent/consumable/cream = 5,
+ /datum/reagent/consumable/nutriment/vitamin = 5,
+ /datum/reagent/consumable/berryjuice = 5
+ )
+ tastes = list("cake" = 4, "violets" = 2, "jam" = 2)
+ foodtypes = GRAIN | DAIRY | FRUIT | SUGAR
+ slice_type = /obj/item/food/cakeslice/trumpet
+
+/obj/item/food/cakeslice/trumpet
+ name = "spaceman's cake"
+ desc = "A spaceman's trumpet frosted cake."
+ icon_state = "trumpetcakeslice"
+ food_reagents = list(
+ /datum/reagent/consumable/nutriment = 4,
+ /datum/reagent/consumable/nutriment/vitamin = 1,
+ /datum/reagent/medicine/polypyr = 3,
+ /datum/reagent/consumable/cream = 1,
+ /datum/reagent/consumable/nutriment/vitamin = 1,
+ /datum/reagent/consumable/berryjuice = 1
+ )
+ tastes = list("cake" = 4, "violets" = 2, "jam" = 2)
+ foodtypes = GRAIN | DAIRY | FRUIT | SUGAR
+
+/obj/item/food/cake/brioche
+ name = "brioche cake"
+ desc = "A ring of sweet, glazed buns."
+ icon_state = "briochecake"
+ tastes = list("cake" = 4, "butter" = 2, "cream" = 1)
+ foodtypes = GRAIN | DAIRY | SUGAR
+ slice_type = /obj/item/food/cakeslice/brioche
+ yield = 6
+
+/obj/item/food/cakeslice/brioche
+ name = "brioche cake slice"
+ desc = "Delicious sweet-bread. Who needs anything else?"
+ icon_state = "briochecake_slice"
diff --git a/code/game/objects/items/food/spaghetti.dm b/code/game/objects/items/food/spaghetti.dm
new file mode 100644
index 000000000000..a6c5394e0647
--- /dev/null
+++ b/code/game/objects/items/food/spaghetti.dm
@@ -0,0 +1,98 @@
+
+/obj/item/food/spaghetti
+ icon = 'icons/obj/food/pizzaspaghetti.dmi'
+ food_reagents = list(/datum/reagent/consumable/nutriment = 1, /datum/reagent/consumable/nutriment/vitamin = 1)
+ foodtypes = GRAIN
+
+/obj/item/food/spaghetti/Initialize()
+ . = ..()
+ if(!microwaved_type) // This isn't cooked, why would you put uncooked spaghetti in your pocket?
+ var/list/display_message = list(
+ "Something wet falls out of their pocket and hits the ground. Is that... [name]?",
+ "Oh shit! All your pocket [name] fell out!")
+ AddComponent(/datum/component/spill, display_message, 'sound/effects/splat.ogg')
+
+/obj/item/food/spaghetti/raw
+ name = "spaghetti"
+ desc = "Now that's a nic'e pasta!"
+ icon_state = "spaghetti"
+ tastes = list("pasta" = 1)
+ microwaved_type = /obj/item/food/spaghetti/boiledspaghetti
+
+/obj/item/food/spaghetti/boiledspaghetti
+ name = "boiled spaghetti"
+ desc = "A plain dish of noodles, this needs more ingredients."
+ icon_state = "spaghettiboiled"
+ trash_type = /obj/item/trash/plate
+ food_reagents = list(/datum/reagent/consumable/nutriment = 2, /datum/reagent/consumable/nutriment/vitamin = 1)
+ microwaved_type = null
+
+/obj/item/food/spaghetti/pastatomato
+ name = "spaghetti"
+ desc = "Spaghetti and crushed tomatoes. Just like your abusive father used to make!"
+ icon_state = "pastatomato"
+ trash_type = /obj/item/trash/plate
+ bite_consumption = 4
+ food_reagents = list(/datum/reagent/consumable/nutriment = 6, /datum/reagent/consumable/tomatojuice = 10, /datum/reagent/consumable/nutriment/vitamin = 4)
+ microwaved_type = null
+ tastes = list("pasta" = 1, "tomato" = 1)
+ foodtypes = GRAIN | VEGETABLES
+
+/obj/item/food/spaghetti/copypasta
+ name = "copypasta"
+ desc = "You probably shouldn't try this, you always hear people talking about how bad it is..."
+ icon_state = "copypasta"
+ trash_type = /obj/item/trash/plate
+ bite_consumption = 4
+ food_reagents = list(/datum/reagent/consumable/nutriment = 12, /datum/reagent/consumable/tomatojuice = 20, /datum/reagent/consumable/nutriment/vitamin = 8)
+ microwaved_type = null
+ tastes = list("pasta" = 1, "tomato" = 1)
+ foodtypes = GRAIN | VEGETABLES
+
+/obj/item/food/spaghetti/meatballspaghetti
+ name = "spaghetti and meatballs"
+ desc = "Now that's a nic'e meatball!"
+ icon_state = "meatballspaghetti"
+ trash_type = /obj/item/trash/plate
+ food_reagents = list(/datum/reagent/consumable/nutriment = 4, /datum/reagent/consumable/nutriment/vitamin = 2)
+ microwaved_type = null
+ tastes = list("pasta" = 1, "meat" = 1)
+ foodtypes = GRAIN | MEAT
+
+/obj/item/food/spaghetti/spesslaw
+ name = "spesslaw"
+ desc = "A lawyers favourite."
+ icon_state = "spesslaw"
+ trash_type = /obj/item/trash/plate
+ food_reagents = list(/datum/reagent/consumable/nutriment = 4, /datum/reagent/consumable/nutriment/vitamin = 3)
+ microwaved_type = null
+ tastes = list("pasta" = 1, "meat" = 1)
+
+/obj/item/food/spaghetti/chowmein
+ name = "chow mein"
+ desc = "A nice mix of noodles and fried vegetables."
+ icon_state = "chowmein"
+ trash_type = /obj/item/trash/plate
+ food_reagents = list(/datum/reagent/consumable/nutriment = 6, /datum/reagent/consumable/nutriment/vitamin = 6)
+ microwaved_type = null
+ tastes = list("noodle" = 1, "tomato" = 1)
+
+/obj/item/food/spaghetti/beefnoodle
+ name = "beef noodle"
+ desc = "Nutritious, beefy and noodly."
+ icon_state = "beefnoodle"
+ trash_type = /obj/item/reagent_containers/glass/bowl
+ food_reagents = list(/datum/reagent/consumable/nutriment = 4, /datum/reagent/consumable/nutriment/vitamin = 6, /datum/reagent/liquidgibs = 3)
+ microwaved_type = null
+ tastes = list("noodle" = 1, "meat" = 1)
+ foodtypes = GRAIN | MEAT
+
+/obj/item/food/spaghetti/butternoodles
+ name = "butter noodles"
+ desc = "Noodles covered in savory butter. Simple and slippery, but delicious."
+ icon_state = "butternoodles"
+ trash_type = /obj/item/trash/plate
+ food_reagents = list(/datum/reagent/consumable/nutriment = 9, /datum/reagent/consumable/nutriment/vitamin = 2)
+ microwaved_type = null
+ tastes = list("noodle" = 1, "butter" = 1)
+ foodtypes = GRAIN | DAIRY
diff --git a/code/game/objects/items/kitchen.dm b/code/game/objects/items/kitchen.dm
index 9e90329404f0..4186e500ab98 100644
--- a/code/game/objects/items/kitchen.dm
+++ b/code/game/objects/items/kitchen.dm
@@ -88,6 +88,7 @@
item_flags = EYE_STAB
var/bayonet = FALSE //Can this be attached to a gun?
custom_price = 250
+ tool_behaviour = TOOL_KNIFE
/obj/item/kitchen/knife/ComponentInitialize()
. = ..()
diff --git a/code/game/objects/items/storage/belt.dm b/code/game/objects/items/storage/belt.dm
index 2904745f25aa..cfa4a16f2073 100644
--- a/code/game/objects/items/storage/belt.dm
+++ b/code/game/objects/items/storage/belt.dm
@@ -520,7 +520,7 @@
/obj/item/reagent_containers/food/snacks/cheesynachos,
/obj/item/reagent_containers/food/snacks/cubannachos,
/obj/item/reagent_containers/food/snacks/nugget,
- /obj/item/reagent_containers/food/snacks/spaghetti/pastatomato,
+ /obj/item/food/spaghetti/pastatomato,
/obj/item/reagent_containers/food/snacks/rofflewaffles,
/obj/item/reagent_containers/food/snacks/donkpocket,
/obj/item/reagent_containers/food/drinks/soda_cans/cola,
diff --git a/code/modules/cargo/bounties/chef.dm b/code/modules/cargo/bounties/chef.dm
index d0e946ba2a6e..969a41601fbb 100644
--- a/code/modules/cargo/bounties/chef.dm
+++ b/code/modules/cargo/bounties/chef.dm
@@ -2,7 +2,7 @@
name = "Birthday Cake"
description = "Nanotrasen's birthday is coming up! Ship them a birthday cake to celebrate!"
reward = 4000
- wanted_types = list(/obj/item/reagent_containers/food/snacks/store/cake/birthday, /obj/item/reagent_containers/food/snacks/cakeslice/birthday)
+ wanted_types = list(/obj/item/food/cake/birthday, /obj/item/food/cakeslice/birthday)
/datum/bounty/item/chef/soup
name = "Soup"
@@ -43,7 +43,7 @@
name = "Bread"
description = "Problems with central planning have led to bread prices skyrocketing. Ship some bread to ease tensions."
reward = 1000
- wanted_types = list(/obj/item/reagent_containers/food/snacks/store/bread, /obj/item/reagent_containers/food/snacks/breadslice, /obj/item/reagent_containers/food/snacks/bun, /obj/item/reagent_containers/food/snacks/pizzabread, /obj/item/reagent_containers/food/snacks/rawpastrybase)
+ wanted_types = list(/obj/item/food/bread, /obj/item/food/breadslice, /obj/item/reagent_containers/food/snacks/bun, /obj/item/reagent_containers/food/snacks/pizzabread, /obj/item/reagent_containers/food/snacks/rawpastrybase)
/datum/bounty/item/chef/pie
name = "Pie"
diff --git a/code/modules/cargo/packs/food.dm b/code/modules/cargo/packs/food.dm
index c7d8b77f46a5..9c366406af5c 100644
--- a/code/modules/cargo/packs/food.dm
+++ b/code/modules/cargo/packs/food.dm
@@ -163,10 +163,10 @@
name = "Bread Crate"
desc = "A crate full of various breads. Bready to either be eaten or made into delicious meals."
cost = 1000
- contains = list(/obj/item/reagent_containers/food/snacks/store/bread/plain,
- /obj/item/reagent_containers/food/snacks/breadslice/plain,
- /obj/item/reagent_containers/food/snacks/breadslice/plain,
- /obj/item/reagent_containers/food/snacks/breadslice/plain, //Weighted to be more common
+ contains = list(/obj/item/food/bread/plain,
+ /obj/item/food/breadslice/plain,
+ /obj/item/food/breadslice/plain,
+ /obj/item/food/breadslice/plain, //Weighted to be more common
/obj/item/reagent_containers/food/snacks/bun,
/obj/item/reagent_containers/food/snacks/tortilla,
/obj/item/reagent_containers/food/snacks/pizzabread
diff --git a/code/modules/clothing/outfits/ert/frontiersmen_ert.dm b/code/modules/clothing/outfits/ert/frontiersmen_ert.dm
index b3a2b20f687c..1ab6b3cf320e 100644
--- a/code/modules/clothing/outfits/ert/frontiersmen_ert.dm
+++ b/code/modules/clothing/outfits/ert/frontiersmen_ert.dm
@@ -59,7 +59,7 @@
/obj/item/storage/backpack/satchel = 20,
/obj/item/storage/backpack/messenger = 20,
/obj/item/melee/baton/cattleprod/loaded = 5,
- /obj/item/reagent_containers/food/snacks/baguette = 2, // yes you can put this on your back
+ /obj/item/food/baguette = 2, // yes you can put this on your back
/obj/item/deployable_turret_folded = 1,
/obj/item/gun/ballistic/automatic/hmg/skm_lmg/extended = 1,
))
diff --git a/code/modules/food_and_drinks/food/customizables.dm b/code/modules/food_and_drinks/food/customizables.dm
index fc3df2f74713..3147ee9a5de4 100644
--- a/code/modules/food_and_drinks/food/customizables.dm
+++ b/code/modules/food_and_drinks/food/customizables.dm
@@ -45,7 +45,7 @@
to_chat(user, "The ingredient is too big for [src]!")
else if((ingredients.len >= ingMax) || (reagents.total_volume >= volume))
to_chat(user, "You can't add more ingredients to [src]!")
- else if(istype(I, /obj/item/reagent_containers/food/snacks/pizzaslice/custom) || istype(I, /obj/item/reagent_containers/food/snacks/cakeslice/custom))
+ else if(istype(I, /obj/item/reagent_containers/food/snacks/pizzaslice/custom))
to_chat(user, "Adding [I.name] to [src] would make a mess.")
else
if(!user.transferItemToLoc(I, src))
@@ -170,26 +170,6 @@
foodtype = GRAIN
-/obj/item/reagent_containers/food/snacks/customizable/bread
- name = "bread"
- ingMax = 6
- slice_path = /obj/item/reagent_containers/food/snacks/breadslice/custom
- slices_num = 5
- icon = 'icons/obj/food/burgerbread.dmi'
- icon_state = "tofubread"
- foodtype = GRAIN
-
-
-/obj/item/reagent_containers/food/snacks/customizable/cake
- name = "cake"
- ingMax = 6
- slice_path = /obj/item/reagent_containers/food/snacks/cakeslice/custom
- slices_num = 5
- icon = 'icons/obj/food/piecake.dmi'
- icon_state = "plaincake"
- foodtype = GRAIN | DAIRY
-
-
/obj/item/reagent_containers/food/snacks/customizable/kebab
name = "kebab"
desc = "Delicious food on a stick."
@@ -199,15 +179,6 @@
ingMax = 6
icon_state = "rod"
-/obj/item/reagent_containers/food/snacks/customizable/pasta
- name = "spaghetti"
- desc = "Noodles. With stuff. Delicious."
- ingredients_placement = INGREDIENTS_SCATTER
- ingMax = 6
- icon = 'icons/obj/food/pizzaspaghetti.dmi'
- icon_state = "spaghettiboiled"
- foodtype = GRAIN
-
/obj/item/reagent_containers/food/snacks/customizable/pie
name = "pie"
@@ -238,43 +209,6 @@
icon_state = "bowl"
-/obj/item/reagent_containers/food/snacks/customizable/sandwich
- name = "toast"
- desc = "A timeless classic."
- ingredients_placement = INGREDIENTS_STACK
- icon = 'icons/obj/food/burgerbread.dmi'
- icon_state = "breadslice"
- var/finished = 0
- foodtype = GRAIN
-
-/obj/item/reagent_containers/food/snacks/customizable/sandwich/initialize_custom_food(obj/item/reagent_containers/BASE, obj/item/I, mob/user)
- icon_state = BASE.icon_state
- ..()
-
-/obj/item/reagent_containers/food/snacks/customizable/sandwich/attackby(obj/item/I, mob/user, params)
- if(istype(I, /obj/item/reagent_containers/food/snacks/breadslice)) //we're finishing the custom food.
- var/obj/item/reagent_containers/food/snacks/breadslice/BS = I
- if(finished)
- return
- to_chat(user, "You finish the [src.name].")
- finished = 1
- name = "[customname] sandwich"
- BS.reagents.trans_to(src, BS.reagents.total_volume, transfered_by = user)
- ingMax = ingredients.len //can't add more ingredients after that
- var/mutable_appearance/TOP = mutable_appearance(icon, "[BS.icon_state]")
- TOP.pixel_y = 2 * ingredients.len + 3
- add_overlay(TOP)
- if(istype(BS, /obj/item/reagent_containers/food/snacks/breadslice/custom))
- var/mutable_appearance/filling = new(icon, "[initial(BS.icon_state)]_filling")
- filling.color = BS.filling_color
- filling.pixel_y = 2 * ingredients.len + 3
- add_overlay(filling)
- qdel(BS)
- return
- else
- ..()
-
-
/obj/item/reagent_containers/food/snacks/customizable/soup
name = "soup"
desc = "A bowl with liquid and... stuff in it."
diff --git a/code/modules/food_and_drinks/food/snacks.dm b/code/modules/food_and_drinks/food/snacks.dm
index 61121a3ca950..9e84c272dbb6 100644
--- a/code/modules/food_and_drinks/food/snacks.dm
+++ b/code/modules/food_and_drinks/food/snacks.dm
@@ -56,6 +56,16 @@ All foods are distributed among various categories. Use common sense.
//Placeholder for effect that trigger on eating that aren't tied to reagents.
+/obj/item/reagent_containers/food/snacks/Initialize(mapload)
+ . = ..()
+ RegisterSignal(src, COMSIG_ITEM_FRIED, PROC_REF(on_fried))
+
+
+/obj/item/reagent_containers/food/snacks/proc/on_fried(fry_object)
+ reagents.trans_to(fry_object, reagents.total_volume)
+ qdel()
+ return COMSIG_FRYING_HANDLED
+
/obj/item/reagent_containers/food/snacks/add_initial_reagents()
if(tastes && tastes.len)
if(list_reagents)
@@ -175,7 +185,7 @@ All foods are distributed among various categories. Use common sense.
if(W.w_class > WEIGHT_CLASS_SMALL)
to_chat(user, span_warning("[S] is too big for [src]!"))
return FALSE
- if(istype(S) && (!S.customfoodfilling || istype(W, /obj/item/reagent_containers/food/snacks/customizable) || istype(W, /obj/item/reagent_containers/food/snacks/pizzaslice/custom) || istype(W, /obj/item/reagent_containers/food/snacks/cakeslice/custom)))
+ if(!S.customfoodfilling || istype(W, /obj/item/reagent_containers/food/snacks/customizable) || istype(W, /obj/item/reagent_containers/food/snacks/pizzaslice/custom))
to_chat(user, span_warning("[src] can't be filled with [S]!"))
return FALSE
if(contents.len >= 20)
@@ -337,26 +347,10 @@ All foods are distributed among various categories. Use common sense.
/// All the food items that can store an item inside itself, like bread or cake.
/obj/item/reagent_containers/food/snacks/store
w_class = WEIGHT_CLASS_NORMAL
- var/stored_item = 0
-/obj/item/reagent_containers/food/snacks/store/attackby(obj/item/W, mob/user, params)
- ..()
- if(W.w_class <= WEIGHT_CLASS_SMALL & !istype(W, /obj/item/reagent_containers/food/snacks)) //can't slip snacks inside, they're used for custom foods.
- if(W.get_sharpness())
- return 0
- if(stored_item)
- return 0
- if(!iscarbon(user))
- return 0
- if(contents.len >= 20)
- to_chat(user, "[src] is full.")
- return 0
- to_chat(user, "You slip [W] inside [src].")
- user.transferItemToLoc(W, src)
- add_fingerprint(user)
- contents += W
- stored_item = 1
- return 1 // no afterattack here
+/obj/item/reagent_containers/food/snacks/store/Initialize()
+ . = ..()
+ AddComponent(/datum/component/food_storage)
/obj/item/reagent_containers/food/snacks/MouseDrop(atom/over)
var/turf/T = get_turf(src)
diff --git a/code/modules/food_and_drinks/food/snacks/dough.dm b/code/modules/food_and_drinks/food/snacks/dough.dm
index 9567690dc71c..4f5f06379927 100644
--- a/code/modules/food_and_drinks/food/snacks/dough.dm
+++ b/code/modules/food_and_drinks/food/snacks/dough.dm
@@ -7,7 +7,7 @@
desc = "A piece of dough."
icon = 'icons/obj/food/food_ingredients.dmi'
icon_state = "dough"
- cooked_type = /obj/item/reagent_containers/food/snacks/store/bread/plain
+ cooked_type = /obj/item/food/bread/plain
list_reagents = list(/datum/reagent/consumable/nutriment = 6)
w_class = WEIGHT_CLASS_NORMAL
tastes = list("dough" = 1)
@@ -82,7 +82,7 @@
desc = "Cook it to get a cake."
icon = 'icons/obj/food/food_ingredients.dmi'
icon_state = "cakebatter"
- cooked_type = /obj/item/reagent_containers/food/snacks/store/cake/plain
+ cooked_type = /obj/item/food/cake/plain
list_reagents = list(/datum/reagent/consumable/nutriment = 9)
w_class = WEIGHT_CLASS_NORMAL
tastes = list("batter" = 1)
diff --git a/code/modules/food_and_drinks/food/snacks_bread.dm b/code/modules/food_and_drinks/food/snacks_bread.dm
deleted file mode 100644
index 13342a968900..000000000000
--- a/code/modules/food_and_drinks/food/snacks_bread.dm
+++ /dev/null
@@ -1,302 +0,0 @@
-
-/obj/item/reagent_containers/food/snacks/store/bread
- icon = 'icons/obj/food/burgerbread.dmi'
- volume = 80
- slices_num = 5
- tastes = list("bread" = 10)
- foodtype = GRAIN
-
-/obj/item/reagent_containers/food/snacks/store/bread/Initialize()
- . = ..()
- AddElement(/datum/element/dunkable, 10)
-
-/obj/item/reagent_containers/food/snacks/breadslice
- icon = 'icons/obj/food/burgerbread.dmi'
- bitesize = 2
- custom_food_type = /obj/item/reagent_containers/food/snacks/customizable/sandwich
- filling_color = "#FFA500"
- list_reagents = list(/datum/reagent/consumable/nutriment = 2)
- slot_flags = ITEM_SLOT_HEAD
- customfoodfilling = 0 //to avoid infinite bread-ception
- foodtype = GRAIN
-
-/obj/item/reagent_containers/food/snacks/breadslice/Initialize()
- . = ..()
- AddElement(/datum/element/dunkable, 10)
-
-/obj/item/reagent_containers/food/snacks/store/bread/plain
- name = "bread"
- desc = "Some plain old earthen bread."
- icon_state = "bread"
- bonus_reagents = list(/datum/reagent/consumable/nutriment = 7)
- list_reagents = list(/datum/reagent/consumable/nutriment = 10)
- custom_food_type = /obj/item/reagent_containers/food/snacks/customizable/bread
- slice_path = /obj/item/reagent_containers/food/snacks/breadslice/plain
- tastes = list("bread" = 10)
- foodtype = GRAIN
-
-/obj/item/reagent_containers/food/snacks/breadslice/plain
- name = "bread slice"
- desc = "A slice of home."
- icon_state = "breadslice"
- customfoodfilling = 1
- foodtype = GRAIN
-
-/obj/item/reagent_containers/food/snacks/breadslice/moldy
- name = "moldy bread slice"
- desc = "Entire stations have been ripped apart over arguing whether this is still good to eat."
- icon_state = "moldybreadslice"
- customfoodfilling = 0
- bonus_reagents = list(/datum/reagent/consumable/mold = 10)
- tastes = list("decaying fungus" = 1)
- foodtype = GROSS
-
-/obj/item/reagent_containers/food/snacks/store/bread/meat
- name = "meatbread loaf"
- desc = "The culinary base of every self-respecting eloquen/tg/entleman."
- icon_state = "meatbread"
- slice_path = /obj/item/reagent_containers/food/snacks/breadslice/meat
- bonus_reagents = list(/datum/reagent/consumable/nutriment = 5, /datum/reagent/consumable/nutriment/vitamin = 10)
- list_reagents = list(/datum/reagent/consumable/nutriment = 30, /datum/reagent/consumable/nutriment/vitamin = 5)
- tastes = list("bread" = 10, "meat" = 10)
- foodtype = GRAIN | MEAT
-
-/obj/item/reagent_containers/food/snacks/breadslice/meat
- name = "meatbread slice"
- desc = "A slice of delicious meatbread."
- icon_state = "meatbreadslice"
- foodtype = GRAIN | MEAT
-
-/obj/item/reagent_containers/food/snacks/store/bread/xenomeat
- name = "xenomeatbread loaf"
- desc = "The culinary base of every self-respecting eloquen/tg/entleman. Extra Heretical."
- icon_state = "xenomeatbread"
- slice_path = /obj/item/reagent_containers/food/snacks/breadslice/xenomeat
- bonus_reagents = list(/datum/reagent/consumable/nutriment = 5, /datum/reagent/consumable/nutriment/vitamin = 10)
- list_reagents = list(/datum/reagent/consumable/nutriment = 30, /datum/reagent/consumable/nutriment/vitamin = 5)
- tastes = list("bread" = 10, "acid" = 10)
- foodtype = GRAIN | MEAT
-
-/obj/item/reagent_containers/food/snacks/breadslice/xenomeat
- name = "xenomeatbread slice"
- desc = "A slice of delicious meatbread. Extra Heretical."
- icon_state = "xenobreadslice"
- filling_color = "#32CD32"
- list_reagents = list(/datum/reagent/consumable/nutriment = 6, /datum/reagent/consumable/nutriment/vitamin = 1)
- foodtype = GRAIN | MEAT
-
-/obj/item/reagent_containers/food/snacks/store/bread/spidermeat
- name = "spider meat loaf"
- desc = "Reassuringly green meatloaf made from spider meat."
- icon_state = "spidermeatbread"
- slice_path = /obj/item/reagent_containers/food/snacks/breadslice/spidermeat
- bonus_reagents = list(/datum/reagent/consumable/nutriment = 5, /datum/reagent/consumable/nutriment/vitamin = 10)
- list_reagents = list(/datum/reagent/consumable/nutriment = 30, /datum/reagent/toxin = 15, /datum/reagent/consumable/nutriment/vitamin = 5)
- tastes = list("bread" = 10, "cobwebs" = 5)
- foodtype = GRAIN | MEAT | TOXIC
-
-/obj/item/reagent_containers/food/snacks/breadslice/spidermeat
- name = "spider meat bread slice"
- desc = "A slice of meatloaf made from an animal that most likely still wants you dead."
- icon_state = "spiderbreadslice"
- filling_color = "#7CFC00"
- list_reagents = list(/datum/reagent/consumable/nutriment = 6, /datum/reagent/toxin = 3, /datum/reagent/consumable/nutriment/vitamin = 1)
- foodtype = GRAIN | MEAT | TOXIC
-
-/obj/item/reagent_containers/food/snacks/store/bread/banana
- name = "banana-nut bread"
- desc = "A heavenly and filling treat."
- icon_state = "bananabread"
- slice_path = /obj/item/reagent_containers/food/snacks/breadslice/banana
- bonus_reagents = list(/datum/reagent/consumable/nutriment = 5, /datum/reagent/consumable/banana = 20)
- list_reagents = list(/datum/reagent/consumable/nutriment = 20, /datum/reagent/consumable/banana = 20)
- tastes = list("bread" = 10) // bananjuice will also flavour
- foodtype = GRAIN | FRUIT
-
-
-/obj/item/reagent_containers/food/snacks/breadslice/banana
- name = "banana-nut bread slice"
- desc = "A slice of delicious banana bread."
- icon_state = "bananabreadslice"
- filling_color = "#FFD700"
- list_reagents = list(/datum/reagent/consumable/nutriment = 4, /datum/reagent/consumable/banana = 4)
- foodtype = GRAIN | FRUIT
-
-/obj/item/reagent_containers/food/snacks/store/bread/tofu
- name = "Tofubread"
- desc = "Like meatbread but for vegetarians. Not guaranteed to give superpowers."
- icon_state = "tofubread"
- slice_path = /obj/item/reagent_containers/food/snacks/breadslice/tofu
- bonus_reagents = list(/datum/reagent/consumable/nutriment = 5, /datum/reagent/consumable/nutriment/vitamin = 10)
- list_reagents = list(/datum/reagent/consumable/nutriment = 20, /datum/reagent/consumable/nutriment/vitamin = 5)
- tastes = list("bread" = 10, "tofu" = 10)
- foodtype = GRAIN | VEGETABLES
-
-/obj/item/reagent_containers/food/snacks/breadslice/tofu
- name = "tofubread slice"
- desc = "A slice of delicious tofubread."
- icon_state = "tofubreadslice"
- filling_color = "#FF8C00"
- list_reagents = list(/datum/reagent/consumable/nutriment = 4, /datum/reagent/consumable/nutriment/vitamin = 1)
- foodtype = GRAIN | VEGETABLES
-
-/obj/item/reagent_containers/food/snacks/store/bread/creamcheese
- name = "cream cheese bread"
- desc = "Yum yum yum!"
- icon_state = "creamcheesebread"
- slice_path = /obj/item/reagent_containers/food/snacks/breadslice/creamcheese
- bonus_reagents = list(/datum/reagent/consumable/nutriment = 5, /datum/reagent/consumable/nutriment/vitamin = 5)
- list_reagents = list(/datum/reagent/consumable/nutriment = 20, /datum/reagent/consumable/nutriment/vitamin = 5)
- tastes = list("bread" = 10, "cheese" = 10)
- foodtype = GRAIN | DAIRY
-
-/obj/item/reagent_containers/food/snacks/breadslice/creamcheese
- name = "cream cheese bread slice"
- desc = "A slice of yum!"
- icon_state = "creamcheesebreadslice"
- filling_color = "#FF8C00"
- list_reagents = list(/datum/reagent/consumable/nutriment = 4, /datum/reagent/consumable/nutriment/vitamin = 1)
- foodtype = GRAIN | DAIRY
-
-/obj/item/reagent_containers/food/snacks/store/bread/mimana
- name = "mimana bread"
- desc = "Best eaten in silence."
- icon_state = "mimanabread"
- slice_path = /obj/item/reagent_containers/food/snacks/breadslice/mimana
- bonus_reagents = list(/datum/reagent/consumable/nutriment = 5, /datum/reagent/consumable/nutriment/vitamin = 5)
- list_reagents = list(/datum/reagent/consumable/nutriment = 20, /datum/reagent/toxin/mutetoxin = 5, /datum/reagent/consumable/nothing = 5, /datum/reagent/consumable/nutriment/vitamin = 5)
- tastes = list("bread" = 10, "silence" = 10)
- foodtype = GRAIN | FRUIT
-
-/obj/item/reagent_containers/food/snacks/breadslice/mimana
- name = "mimana bread slice"
- desc = "A slice of silence!"
- icon_state = "mimanabreadslice"
- filling_color = "#C0C0C0"
- list_reagents = list(/datum/reagent/consumable/nutriment = 2, /datum/reagent/toxin/mutetoxin = 1, /datum/reagent/consumable/nothing = 1, /datum/reagent/consumable/nutriment/vitamin = 1)
- foodtype = GRAIN | FRUIT
-
-/obj/item/reagent_containers/food/snacks/breadslice/custom
- name = "bread slice"
- icon_state = "tofubreadslice"
- filling_color = "#FFFFFF"
- foodtype = GRAIN
-
-/obj/item/reagent_containers/food/snacks/baguette
- name = "baguette"
- desc = "Bon appetit!"
- icon = 'icons/obj/food/burgerbread.dmi'
- icon_state = "baguette"
- item_state = "baguette"
- bonus_reagents = list(/datum/reagent/consumable/nutriment = 2, /datum/reagent/consumable/nutriment/vitamin = 2)
- list_reagents = list(/datum/reagent/consumable/nutriment = 6, /datum/reagent/consumable/nutriment/vitamin = 1)
- bitesize = 3
- w_class = WEIGHT_CLASS_NORMAL
- slot_flags = ITEM_SLOT_BACK|ITEM_SLOT_BELT
- attack_verb = list("touche'd")
- tastes = list("bread" = 1)
- foodtype = GRAIN
-
-/obj/item/reagent_containers/food/snacks/garlicbread
- name = "garlic bread"
- desc = "Alas, it is limited."
- icon = 'icons/obj/food/burgerbread.dmi'
- icon_state = "garlicbread"
- item_state = "garlicbread"
- bonus_reagents = list(/datum/reagent/consumable/nutriment = 5, /datum/reagent/consumable/nutriment/vitamin = 2)
- list_reagents = list(/datum/reagent/consumable/nutriment = 5, /datum/reagent/consumable/nutriment/vitamin = 4, /datum/reagent/consumable/garlic = 2)
- bitesize = 3
- tastes = list("bread" = 1, "garlic" = 1, "butter" = 1)
- foodtype = GRAIN
-
-/obj/item/reagent_containers/food/snacks/deepfryholder
- name = "Deep Fried Foods Holder Obj"
- desc = "If you can see this description the code for the deep fryer fucked up."
- icon = 'icons/obj/food/food.dmi'
- icon_state = ""
- bitesize = 2
-
-/obj/item/reagent_containers/food/snacks/deepfryholder/Initialize(mapload, obj/item/fried)
- . = ..()
- name = fried.name //We'll determine the other stuff when it's actually removed
- appearance = fried.appearance
- layer = initial(layer)
- plane = initial(plane)
- lefthand_file = fried.lefthand_file
- righthand_file = fried.righthand_file
- item_state = fried.item_state
- desc = fried.desc
- w_class = fried.w_class
- slowdown = fried.slowdown
- equip_delay_self = fried.equip_delay_self
- equip_delay_other = fried.equip_delay_other
- strip_delay = fried.strip_delay
- species_exception = fried.species_exception
- item_flags = fried.item_flags
- obj_flags = fried.obj_flags
- inhand_x_dimension = fried.inhand_x_dimension
- inhand_y_dimension = fried.inhand_y_dimension
-
- if(istype(fried, /obj/item/reagent_containers/food/snacks))
- fried.reagents.trans_to(src, fried.reagents.total_volume)
- qdel(fried)
- else
- fried.forceMove(src)
-
-/obj/item/reagent_containers/food/snacks/deepfryholder/Destroy()
- if(contents)
- QDEL_LIST(contents)
- . = ..()
-
-/obj/item/reagent_containers/food/snacks/deepfryholder/On_Consume(mob/living/eater)
- if(contents)
- QDEL_LIST(contents)
- ..()
-
-/obj/item/reagent_containers/food/snacks/deepfryholder/proc/fry(cook_time = 30)
- switch(cook_time)
- if(0 to 15)
- add_atom_colour(rgb(166,103,54), FIXED_COLOUR_PRIORITY)
- name = "lightly-fried [name]"
- desc = "[desc] It's been lightly fried in a deep fryer."
- if(16 to 49)
- add_atom_colour(rgb(103,63,24), FIXED_COLOUR_PRIORITY)
- name = "fried [name]"
- desc = "[desc] It's been fried, increasing its tastiness value by [rand(1, 75)]%."
- if(50 to 59)
- add_atom_colour(rgb(63,23,4), FIXED_COLOUR_PRIORITY)
- name = "deep-fried [name]"
- desc = "[desc] Deep-fried to perfection."
- if(60 to INFINITY)
- add_atom_colour(rgb(33,19,9), FIXED_COLOUR_PRIORITY)
- name = "\proper the physical manifestation of the very concept of fried foods"
- desc = "A heavily-fried...something. Who can tell anymore?"
- filling_color = color
- foodtype |= FRIED
-
-/obj/item/reagent_containers/food/snacks/butterbiscuit
- name = "butter biscuit"
- desc = "Well butter my biscuit!"
- icon = 'icons/obj/food/food.dmi'
- icon_state = "butterbiscuit"
- filling_color = "#F0E68C"
- list_reagents = list(/datum/reagent/consumable/nutriment = 5)
- bonus_reagents = list(/datum/reagent/consumable/nutriment = 1, /datum/reagent/consumable/nutriment/vitamin = 1)
- tastes = list("butter" = 1, "biscuit" = 1)
- foodtype = GRAIN | BREAKFAST
-
-/obj/item/reagent_containers/food/snacks/butterdog
- name = "butterdog"
- desc = "Made from exotic butters."
- icon = 'icons/obj/food/food.dmi'
- icon_state = "butterdog"
- bitesize = 1
- filling_color = "#F1F49A"
- list_reagents = list(/datum/reagent/consumable/nutriment = 5)
- bonus_reagents = list(/datum/reagent/consumable/nutriment = 1, /datum/reagent/consumable/nutriment/vitamin = 1)
- tastes = list("butter", "exotic butter")
- foodtype = GRAIN | DAIRY
-
-/obj/item/reagent_containers/food/snacks/butterdog/ComponentInitialize()
- . = ..()
- AddComponent(/datum/component/slippery, 80)
diff --git a/code/modules/food_and_drinks/food/snacks_cake.dm b/code/modules/food_and_drinks/food/snacks_cake.dm
deleted file mode 100644
index d6f6151d47ac..000000000000
--- a/code/modules/food_and_drinks/food/snacks_cake.dm
+++ /dev/null
@@ -1,431 +0,0 @@
-/obj/item/reagent_containers/food/snacks/store/cake
- icon = 'icons/obj/food/piecake.dmi'
- slice_path = /obj/item/reagent_containers/food/snacks/cakeslice/plain
- slices_num = 5
- bitesize = 3
- volume = 80
- list_reagents = list(/datum/reagent/consumable/nutriment = 20, /datum/reagent/consumable/nutriment/vitamin = 5)
- tastes = list("cake" = 1)
- foodtype = GRAIN | DAIRY
-
-/obj/item/reagent_containers/food/snacks/cakeslice
- icon = 'icons/obj/food/piecake.dmi'
- trash = /obj/item/trash/plate
- list_reagents = list(/datum/reagent/consumable/nutriment = 4, /datum/reagent/consumable/nutriment/vitamin = 1)
- customfoodfilling = 0 //to avoid infinite cake-ception
- tastes = list("cake" = 1)
- foodtype = GRAIN | DAIRY
-
-/obj/item/reagent_containers/food/snacks/store/cake/plain
- name = "plain cake"
- desc = "A plain cake, not a lie."
- icon_state = "plaincake"
- custom_food_type = /obj/item/reagent_containers/food/snacks/customizable/cake
- bonus_reagents = list(/datum/reagent/consumable/nutriment = 10, /datum/reagent/consumable/nutriment/vitamin = 2)
- tastes = list("sweetness" = 2,"cake" = 5)
- foodtype = GRAIN | DAIRY | SUGAR
-
-/obj/item/reagent_containers/food/snacks/cakeslice/plain
- name = "plain cake slice"
- desc = "Just a slice of cake, it is enough for everyone."
- icon_state = "plaincake_slice"
- filling_color = "#FFD700"
- customfoodfilling = 1
- tastes = list("sweetness" = 2,"cake" = 5)
- foodtype = GRAIN | DAIRY | SUGAR
-
-/obj/item/reagent_containers/food/snacks/store/cake/carrot
- name = "carrot cake"
- desc = "A favorite desert of a certain wascally wabbit. Not a lie."
- icon_state = "carrotcake"
- slice_path = /obj/item/reagent_containers/food/snacks/cakeslice/carrot
- slices_num = 5
- bonus_reagents = list(/datum/reagent/consumable/nutriment = 3, /datum/reagent/medicine/oculine = 5, /datum/reagent/consumable/nutriment/vitamin = 10)
- list_reagents = list(/datum/reagent/consumable/nutriment = 20, /datum/reagent/medicine/oculine = 10, /datum/reagent/consumable/nutriment/vitamin = 5)
- tastes = list("cake" = 5, "sweetness" = 2, "carrot" = 1)
- foodtype = GRAIN | DAIRY | VEGETABLES | SUGAR
-
-/obj/item/reagent_containers/food/snacks/cakeslice/carrot
- name = "carrot cake slice"
- desc = "Carrotty slice of Carrot Cake, carrots are good for your eyes! Also not a lie."
- icon_state = "carrotcake_slice"
- filling_color = "#FFA500"
- list_reagents = list(/datum/reagent/consumable/nutriment = 4, /datum/reagent/medicine/oculine = 2, /datum/reagent/consumable/nutriment/vitamin = 1)
- tastes = list("cake" = 5, "sweetness" = 2, "carrot" = 1)
- foodtype = GRAIN | DAIRY | VEGETABLES | SUGAR
-
-/obj/item/reagent_containers/food/snacks/store/cake/brain
- name = "brain cake"
- desc = "A squishy cake-thing."
- icon_state = "braincake"
- slice_path = /obj/item/reagent_containers/food/snacks/cakeslice/brain
- slices_num = 5
- bonus_reagents = list(/datum/reagent/consumable/nutriment = 5, /datum/reagent/medicine/mannitol = 10, /datum/reagent/consumable/nutriment/vitamin = 10)
- list_reagents = list(/datum/reagent/consumable/nutriment = 20, /datum/reagent/medicine/mannitol = 10, /datum/reagent/consumable/nutriment/vitamin = 5)
- tastes = list("cake" = 5, "sweetness" = 2, "brains" = 1)
- foodtype = GRAIN | DAIRY | MEAT | GROSS | SUGAR
-
-/obj/item/reagent_containers/food/snacks/cakeslice/brain
- name = "brain cake slice"
- desc = "Lemme tell you something about prions. THEY'RE DELICIOUS."
- icon_state = "braincakeslice"
- filling_color = "#FF69B4"
- list_reagents = list(/datum/reagent/consumable/nutriment = 4, /datum/reagent/medicine/mannitol = 2, /datum/reagent/consumable/nutriment/vitamin = 1)
- tastes = list("cake" = 5, "sweetness" = 2, "brains" = 1)
- foodtype = GRAIN | DAIRY | MEAT | GROSS | SUGAR
-
-/obj/item/reagent_containers/food/snacks/store/cake/cheese
- name = "cheese cake"
- desc = "DANGEROUSLY cheesy."
- icon_state = "cheesecake"
- slice_path = /obj/item/reagent_containers/food/snacks/cakeslice/cheese
- slices_num = 5
- bonus_reagents = list(/datum/reagent/consumable/nutriment/vitamin = 10)
- tastes = list("cake" = 4, "cream cheese" = 3)
- foodtype = GRAIN | DAIRY
-
-/obj/item/reagent_containers/food/snacks/cakeslice/cheese
- name = "cheese cake slice"
- desc = "Slice of pure cheestisfaction."
- icon_state = "cheesecake_slice"
- filling_color = "#FFFACD"
- tastes = list("cake" = 4, "cream cheese" = 3)
- foodtype = GRAIN | DAIRY
-
-/obj/item/reagent_containers/food/snacks/store/cake/orange
- name = "orange cake"
- desc = "A cake with added orange."
- icon_state = "orangecake"
- slice_path = /obj/item/reagent_containers/food/snacks/cakeslice/orange
- slices_num = 5
- bonus_reagents = list(/datum/reagent/consumable/nutriment = 3, /datum/reagent/consumable/nutriment/vitamin = 10)
- tastes = list("cake" = 5, "sweetness" = 2, "oranges" = 2)
- foodtype = GRAIN | DAIRY | FRUIT | SUGAR
-
-/obj/item/reagent_containers/food/snacks/cakeslice/orange
- name = "orange cake slice"
- desc = "Just a slice of cake, it is enough for everyone."
- icon_state = "orangecake_slice"
- filling_color = "#FFA500"
- tastes = list("cake" = 5, "sweetness" = 2, "oranges" = 2)
- foodtype = GRAIN | DAIRY | FRUIT | SUGAR
-
-/obj/item/reagent_containers/food/snacks/store/cake/lime
- name = "lime cake"
- desc = "A cake with added lime."
- icon_state = "limecake"
- slice_path = /obj/item/reagent_containers/food/snacks/cakeslice/lime
- slices_num = 5
- bonus_reagents = list(/datum/reagent/consumable/nutriment = 3, /datum/reagent/consumable/nutriment/vitamin = 10)
- tastes = list("cake" = 5, "sweetness" = 2, "unbearable sourness" = 2)
- foodtype = GRAIN | DAIRY | FRUIT | SUGAR
-
-/obj/item/reagent_containers/food/snacks/cakeslice/lime
- name = "lime cake slice"
- desc = "Just a slice of cake, it is enough for everyone."
- icon_state = "limecake_slice"
- filling_color = "#00FF00"
- tastes = list("cake" = 5, "sweetness" = 2, "unbearable sourness" = 2)
- foodtype = GRAIN | DAIRY | FRUIT | SUGAR
-
-/obj/item/reagent_containers/food/snacks/store/cake/lemon
- name = "lemon cake"
- desc = "A cake with added lemon."
- icon_state = "lemoncake"
- slice_path = /obj/item/reagent_containers/food/snacks/cakeslice/lemon
- slices_num = 5
- bonus_reagents = list(/datum/reagent/consumable/nutriment = 3, /datum/reagent/consumable/nutriment/vitamin = 10)
- tastes = list("cake" = 5, "sweetness" = 2, "sourness" = 2)
- foodtype = GRAIN | DAIRY | FRUIT | SUGAR
-
-/obj/item/reagent_containers/food/snacks/cakeslice/lemon
- name = "lemon cake slice"
- desc = "Just a slice of cake, it is enough for everyone."
- icon_state = "lemoncake_slice"
- filling_color = "#FFEE00"
- tastes = list("cake" = 5, "sweetness" = 2, "sourness" = 2)
- foodtype = GRAIN | DAIRY | FRUIT | SUGAR
-
-/obj/item/reagent_containers/food/snacks/store/cake/chocolate
- name = "chocolate cake"
- desc = "A cake with added chocolate."
- icon_state = "chocolatecake"
- slice_path = /obj/item/reagent_containers/food/snacks/cakeslice/chocolate
- slices_num = 5
- bonus_reagents = list(/datum/reagent/consumable/nutriment = 3, /datum/reagent/consumable/nutriment/vitamin = 10)
- tastes = list("cake" = 5, "sweetness" = 1, "chocolate" = 4)
- foodtype = GRAIN | DAIRY | JUNKFOOD | SUGAR
-
-/obj/item/reagent_containers/food/snacks/cakeslice/chocolate
- name = "chocolate cake slice"
- desc = "Just a slice of cake, it is enough for everyone."
- icon_state = "chocolatecake_slice"
- filling_color = "#A0522D"
- tastes = list("cake" = 5, "sweetness" = 1, "chocolate" = 4)
- foodtype = GRAIN | DAIRY | JUNKFOOD | SUGAR
-
-/obj/item/reagent_containers/food/snacks/store/cake/birthday
- name = "birthday cake"
- desc = "Happy Birthday little clown..."
- icon_state = "birthdaycake"
- slice_path = /obj/item/reagent_containers/food/snacks/cakeslice/birthday
- slices_num = 5
- bonus_reagents = list(/datum/reagent/consumable/nutriment = 7, /datum/reagent/consumable/sprinkles = 10, /datum/reagent/consumable/nutriment/vitamin = 5)
- list_reagents = list(/datum/reagent/consumable/nutriment = 20, /datum/reagent/consumable/sprinkles = 10, /datum/reagent/consumable/nutriment/vitamin = 5)
- tastes = list("cake" = 5, "sweetness" = 1)
- foodtype = GRAIN | DAIRY | JUNKFOOD | SUGAR
-
-/obj/item/reagent_containers/food/snacks/store/cake/birthday/microwave_act(obj/machinery/microwave/M) //super sekrit club
- new /obj/item/clothing/head/hardhat/cakehat(get_turf(src))
- qdel(src)
-
-/obj/item/reagent_containers/food/snacks/cakeslice/birthday
- name = "birthday cake slice"
- desc = "A slice of your birthday."
- icon_state = "birthdaycakeslice"
- filling_color = "#DC143C"
- list_reagents = list(/datum/reagent/consumable/nutriment = 4, /datum/reagent/consumable/sprinkles = 2, /datum/reagent/consumable/nutriment/vitamin = 1)
- tastes = list("cake" = 5, "sweetness" = 1)
- foodtype = GRAIN | DAIRY | JUNKFOOD | SUGAR
-
-/obj/item/reagent_containers/food/snacks/store/cake/birthday/energy
- name = "energy cake"
- desc = "Just enough calories for a whole nuclear operative squad."
- icon_state = "energycake"
- force = 5
- hitsound = 'sound/weapons/blade1.ogg'
- slice_path = /obj/item/reagent_containers/food/snacks/cakeslice/birthday/energy
- list_reagents = list(/datum/reagent/consumable/nutriment = 10, /datum/reagent/consumable/sprinkles = 10, /datum/reagent/consumable/nutriment/vitamin = 5, /datum/reagent/consumable/pacfuel = 10, /datum/reagent/consumable/liquidelectricity = 10)
- tastes = list("cake" = 3, "a Vlad's Salad" = 1)
-
-/obj/item/reagent_containers/food/snacks/store/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)
- playsound(user, 'sound/weapons/blade1.ogg', 5, TRUE)
-
-/obj/item/reagent_containers/food/snacks/store/cake/birthday/energy/attack(mob/living/M, mob/living/user)
- . = ..()
- if(HAS_TRAIT(user, TRAIT_PACIFISM) && M != user) //Prevents pacifists from attacking others directly
- return
- energy_bite(M, user)
-
-/obj/item/reagent_containers/food/snacks/store/cake/birthday/energy/microwave_act(obj/machinery/microwave/M) //super sekriter club
- new /obj/item/clothing/head/hardhat/cakehat/energycake(get_turf(src))
- qdel(src)
-
-/obj/item/reagent_containers/food/snacks/cakeslice/birthday/energy
- name = "energy cake slice"
- desc = "For the traitor on the go."
- icon_state = "energycakeslice"
- force = 2
- hitsound = 'sound/weapons/blade1.ogg'
- filling_color = "#00FF00"
- list_reagents = list(/datum/reagent/consumable/nutriment = 4, /datum/reagent/consumable/sprinkles = 2, /datum/reagent/consumable/nutriment/vitamin = 1, /datum/reagent/consumable/pacfuel = 2, /datum/reagent/consumable/liquidelectricity = 2)
- tastes = list("cake" = 3, "a Vlad's Salad" = 1)
-
-/obj/item/reagent_containers/food/snacks/cakeslice/birthday/energy/proc/energy_bite(mob/living/user)
- to_chat(user, "As you eat the cake slice, you accidentally hurt yourself on the embedded energy dagger!")
- user.apply_damage(18,BRUTE,BODY_ZONE_HEAD)
- playsound(user, 'sound/weapons/blade1.ogg', 5, TRUE)
-
-/obj/item/reagent_containers/food/snacks/cakeslice/birthday/energy/attack(mob/living/M, mob/living/user)
- . = ..()
- if(HAS_TRAIT(user, TRAIT_PACIFISM) && M != user) //Prevents pacifists from attacking others directly
- return
- energy_bite(M, user)
-
-/obj/item/reagent_containers/food/snacks/store/cake/apple
- name = "apple cake"
- desc = "A cake centred with Apple."
- icon_state = "applecake"
- slice_path = /obj/item/reagent_containers/food/snacks/cakeslice/apple
- slices_num = 5
- bonus_reagents = list(/datum/reagent/consumable/nutriment = 3, /datum/reagent/consumable/nutriment/vitamin = 10)
- tastes = list("cake" = 5, "sweetness" = 1, "apple" = 1)
- foodtype = GRAIN | DAIRY | FRUIT | SUGAR
-
-/obj/item/reagent_containers/food/snacks/cakeslice/apple
- name = "apple cake slice"
- desc = "A slice of heavenly cake."
- icon_state = "applecakeslice"
- filling_color = "#FF4500"
- tastes = list("cake" = 5, "sweetness" = 1, "apple" = 1)
- foodtype = GRAIN | DAIRY | FRUIT | SUGAR
-
-/obj/item/reagent_containers/food/snacks/cakeslice/custom
- name = "cake slice"
- icon_state = "plaincake_slice"
- filling_color = "#FFFFFF"
- foodtype = GRAIN | DAIRY
-
-/obj/item/reagent_containers/food/snacks/store/cake/slimecake
- name = "Slime cake"
- desc = "A cake made of slimes. Probably not electrified."
- icon_state = "slimecake"
- slice_path = /obj/item/reagent_containers/food/snacks/cakeslice/slimecake
- bonus_reagents = list(/datum/reagent/consumable/nutriment = 1, /datum/reagent/consumable/nutriment/vitamin = 3)
- tastes = list("cake" = 5, "sweetness" = 1, "slime" = 1)
- foodtype = GRAIN | DAIRY | SUGAR
-
-/obj/item/reagent_containers/food/snacks/cakeslice/slimecake
- name = "slime cake slice"
- desc = "A slice of slime cake."
- icon_state = "slimecake_slice"
- filling_color = "#00FFFF"
- tastes = list("cake" = 5, "sweetness" = 1, "slime" = 1)
- foodtype = GRAIN | DAIRY | SUGAR
-
-/obj/item/reagent_containers/food/snacks/store/cake/pumpkinspice
- name = "pumpkin spice cake"
- desc = "A hollow cake with real pumpkin."
- icon_state = "pumpkinspicecake"
- slice_path = /obj/item/reagent_containers/food/snacks/cakeslice/pumpkinspice
- bonus_reagents = list(/datum/reagent/consumable/nutriment = 3, /datum/reagent/consumable/nutriment/vitamin = 5)
- tastes = list("cake" = 5, "sweetness" = 1, "pumpkin" = 1)
- foodtype = GRAIN | DAIRY | VEGETABLES | SUGAR
-
-/obj/item/reagent_containers/food/snacks/cakeslice/pumpkinspice
- name = "pumpkin spice cake slice"
- desc = "A spicy slice of pumpkin goodness."
- icon_state = "pumpkinspicecakeslice"
- filling_color = "#FFD700"
- tastes = list("cake" = 5, "sweetness" = 1, "pumpkin" = 1)
- foodtype = GRAIN | DAIRY | VEGETABLES | SUGAR
-
-/obj/item/reagent_containers/food/snacks/store/cake/bsvc // blackberry strawberries vanilla cake
- name = "blackberry and strawberry vanilla cake"
- desc = "A plain cake, filled with assortment of blackberries and strawberries!"
- icon_state = "blackbarry_strawberries_cake_vanilla_cake"
- slice_path = /obj/item/reagent_containers/food/snacks/cakeslice/bsvc
- bonus_reagents = list(/datum/reagent/consumable/nutriment = 14, /datum/reagent/consumable/nutriment/vitamin = 4)
- tastes = list("blackberry" = 2, "strawberries" = 2, "vanilla" = 2, "sweetness" = 2, "cake" = 3)
- foodtype = GRAIN | DAIRY | FRUIT | SUGAR
-
-/obj/item/reagent_containers/food/snacks/cakeslice/bsvc
- name = "blackberry and strawberry vanilla cake slice"
- desc = "Just a slice of cake filled with assortment of blackberries and strawberries!"
- icon_state = "blackbarry_strawberries_cake_vanilla_slice"
- filling_color = "#FFD700"
- tastes = list("blackberry" = 2, "strawberries" = 2, "vanilla" = 2, "sweetness" = 2,"cake" = 3)
- foodtype = GRAIN | DAIRY | FRUIT | SUGAR
-
-/obj/item/reagent_containers/food/snacks/store/cake/bscc // blackbarry strawberries chocolate cake
- name = "blackberry and strawberry chocolate cake"
- desc = "A chocolate cake, filled with assortment of blackberries and strawberries!"
- icon_state = "blackbarry_strawberries_cake_coco_cake"
- slice_path = /obj/item/reagent_containers/food/snacks/cakeslice/bscc
- bonus_reagents = list(/datum/reagent/consumable/nutriment = 14, /datum/reagent/consumable/nutriment/vitamin = 4, /datum/reagent/consumable/coco = 5)
- tastes = list("blackberry" = 2, "strawberries" = 2, "chocolate" = 2, "sweetness" = 2,"cake" = 3)
- foodtype = GRAIN | DAIRY | FRUIT | SUGAR
-
-/obj/item/reagent_containers/food/snacks/cakeslice/bscc
- name = "blackberry and strawberry chocolate cake slice"
- desc = "Just a slice of cake filled with assortment of blackberries and strawberries!"
- icon_state = "blackbarry_strawberries_cake_coco_slice"
- filling_color = "#FFD700"
- tastes = list("blackberry" = 2, "strawberries" = 2, "chocolate" = 2, "sweetness" = 2,"cake" = 3)
- foodtype = GRAIN | DAIRY | FRUIT | SUGAR
-
-/obj/item/reagent_containers/food/snacks/store/cake/holy_cake
- name = "angel food cake"
- desc = "A cake made for angels and chaplains alike! Contains holy water."
- icon_state = "holy_cake"
- slice_path = /obj/item/reagent_containers/food/snacks/cakeslice/holy_cake_slice
- bonus_reagents = list(/datum/reagent/consumable/nutriment = 1, /datum/reagent/consumable/nutriment/vitamin = 3, /datum/reagent/water/holywater = 10)
- tastes = list("cake" = 5, "sweetness" = 1, "clouds" = 1)
- foodtype = GRAIN | DAIRY | SUGAR
-
-/obj/item/reagent_containers/food/snacks/cakeslice/holy_cake_slice
- name = "angel food cake slice"
- desc = "A slice of heavenly cake."
- icon_state = "holy_cake_slice"
- filling_color = "#00FFFF"
- tastes = list("cake" = 5, "sweetness" = 1, "clouds" = 1)
- foodtype = GRAIN | DAIRY | SUGAR
-
-/obj/item/reagent_containers/food/snacks/store/cake/pound_cake
- name = "pound cake"
- desc = "A condensed cake made for filling people up quickly."
- icon_state = "pound_cake"
- slices_num = 7 //Its ment to feed the party
- slice_path = /obj/item/reagent_containers/food/snacks/cakeslice/pound_cake_slice
- bonus_reagents = list(/datum/reagent/consumable/nutriment = 60)
- tastes = list("cake" = 5, "sweetness" = 1, "batter" = 1)
- foodtype = GRAIN | DAIRY | SUGAR | JUNKFOOD
-
-/obj/item/reagent_containers/food/snacks/cakeslice/pound_cake_slice
- name = "pound cake slice"
- desc = "A slice of condensed cake made for filling people up quickly."
- icon_state = "pound_cake_slice"
- filling_color = "#00FFFF"
- tastes = list("cake" = 5, "sweetness" = 5, "batter" = 1)
- foodtype = GRAIN | DAIRY | SUGAR | JUNKFOOD
-
-/obj/item/reagent_containers/food/snacks/store/cake/hardware_cake
- name = "hardware cake"
- desc = "A quote on quote cake that is made with electronic boards and leaks acid..."
- icon_state = "hardware_cake"
- slice_path = /obj/item/reagent_containers/food/snacks/cakeslice/hardware_cake_slice
- bonus_reagents = list(/datum/reagent/toxin/acid = 15, /datum/reagent/fuel/oil = 15)
- tastes = list("acid" = 3, "metal" = 4, "glass" = 5)
- foodtype = GRAIN | GROSS
-
-/obj/item/reagent_containers/food/snacks/cakeslice/hardware_cake_slice
- name = "hardware cake slice"
- desc = "A slice of electronic boards and some acid."
- icon_state = "hardware_cake_slice"
- filling_color = "#00FFFF"
- tastes = list("acid" = 3, "metal" = 4, "glass" = 5)
- foodtype = GRAIN | GROSS
-
-/obj/item/reagent_containers/food/snacks/store/cake/vanilla_cake
- name = "vanilla cake"
- desc = "A vanilla frosted cake."
- icon_state = "vanillacake"
- slice_path = /obj/item/reagent_containers/food/snacks/cakeslice/vanilla_slice
- bonus_reagents = list(/datum/reagent/consumable/sugar = 15, /datum/reagent/consumable/vanilla = 15)
- tastes = list("cake" = 1, "sugar" = 1, "vanilla" = 10)
- foodtype = GRAIN | SUGAR | DAIRY
-
-/obj/item/reagent_containers/food/snacks/cakeslice/vanilla_slice
- name = "vanilla cake slice"
- desc = "A slice of vanilla frosted cake."
- icon_state = "vanillacake_slice"
- filling_color = "#00FFFF"
- tastes = list("cake" = 1, "sugar" = 1, "vanilla" = 10)
- foodtype = GRAIN | SUGAR | DAIRY
-
-/obj/item/reagent_containers/food/snacks/store/cake/clown_cake
- name = "clown cake"
- desc = "A funny cake with a clown face on it."
- icon_state = "clowncake"
- slice_path = /obj/item/reagent_containers/food/snacks/cakeslice/clown_slice
- bonus_reagents = list(/datum/reagent/consumable/sugar = 15)
- tastes = list("cake" = 1, "sugar" = 1, "joy" = 10)
- foodtype = GRAIN | SUGAR | DAIRY
-
-/obj/item/reagent_containers/food/snacks/cakeslice/clown_slice
- name = "clown cake slice"
- desc = "A slice of bad jokes, and silly props."
- icon_state = "clowncake_slice"
- filling_color = "#00FFFF"
- tastes = list("cake" = 1, "sugar" = 1, "joy" = 10)
- foodtype = GRAIN | SUGAR | DAIRY
-
-/obj/item/reagent_containers/food/snacks/store/cake/trumpet
- name = "spaceman's cake"
- desc = "A spaceman's trumpet frosted cake."
- icon_state = "trumpetcake"
- slice_path = /obj/item/reagent_containers/food/snacks/cakeslice/trumpet
- bonus_reagents = list(/datum/reagent/medicine/polypyr = 15, /datum/reagent/consumable/cream = 5, /datum/reagent/consumable/nutriment/vitamin = 5, /datum/reagent/consumable/berryjuice = 5)
- filling_color = "#7A3D80"
- tastes = list("cake" = 4, "violets" = 2, "jam" = 2)
- foodtype = GRAIN | DAIRY | FRUIT | SUGAR
-
-/obj/item/reagent_containers/food/snacks/cakeslice/trumpet
- name = "spaceman's cake"
- desc = "A spaceman's trumpet frosted cake."
- icon_state = "trumpetcakeslice"
- filling_color = "#7A3D80"
- tastes = list("cake" = 4, "violets" = 2, "jam" = 2)
- foodtype = GRAIN | DAIRY | FRUIT | SUGAR
diff --git a/code/modules/food_and_drinks/food/snacks_egg.dm b/code/modules/food_and_drinks/food/snacks_egg.dm
index 360053c28ca4..665d94e1fa9b 100644
--- a/code/modules/food_and_drinks/food/snacks_egg.dm
+++ b/code/modules/food_and_drinks/food/snacks_egg.dm
@@ -10,6 +10,8 @@
filling_color = "#A0522D"
tastes = list("chocolate" = 4, "sweetness" = 1)
foodtype = JUNKFOOD | SUGAR
+ /*food_flags = FOOD_FINGER_FOOD*/
+ w_class = WEIGHT_CLASS_TINY
/obj/item/reagent_containers/food/snacks/egg
name = "egg"
@@ -18,7 +20,8 @@
list_reagents = list(/datum/reagent/consumable/eggyolk = 5)
cooked_type = /obj/item/reagent_containers/food/snacks/boiledegg
filling_color = "#F0E68C"
- foodtype = MEAT
+ foodtype = MEAT | RAW
+ w_class = WEIGHT_CLASS_TINY
grind_results = list()
var/static/chick_count = 0 //I copied this from the chicken_count (note the "en" in there) variable from chicken code.
@@ -106,6 +109,8 @@
list_reagents = list(/datum/reagent/consumable/nutriment = 2, /datum/reagent/consumable/nutriment/vitamin = 1)
tastes = list("egg" = 1)
foodtype = MEAT | BREAKFAST
+ /*food_flags = FOOD_FINGER_FOOD*/
+ w_class = WEIGHT_CLASS_TINY
/obj/item/reagent_containers/food/snacks/omelette //FUCK THIS
name = "omelette du fromage"
diff --git a/code/modules/food_and_drinks/food/snacks_frozen.dm b/code/modules/food_and_drinks/food/snacks_frozen.dm
index e35cb7eeb5fe..d79b91507c1b 100644
--- a/code/modules/food_and_drinks/food/snacks_frozen.dm
+++ b/code/modules/food_and_drinks/food/snacks_frozen.dm
@@ -8,20 +8,24 @@
desc = "Portable Ice-cream in its own packaging."
icon = 'icons/obj/food/frozen_treats.dmi'
icon_state = "icecreamsandwich"
+ w_class = WEIGHT_CLASS_TINY
bonus_reagents = list(/datum/reagent/consumable/nutriment = 1, /datum/reagent/consumable/ice = 2)
list_reagents = list(/datum/reagent/consumable/nutriment = 2, /datum/reagent/consumable/ice = 2)
tastes = list("ice cream" = 1)
foodtype = GRAIN | DAIRY | SUGAR
+ /*food_flags = FOOD_FINGER_FOOD*/
/obj/item/reagent_containers/food/snacks/strawberryicecreamsandwich
name = "strawberry ice cream sandwich"
desc = "Portable ice-cream in its own packaging of the strawberry variety."
icon = 'icons/obj/food/frozen_treats.dmi'
icon_state = "strawberryicecreamsandwich"
+ w_class = WEIGHT_CLASS_TINY
bonus_reagents = list(/datum/reagent/consumable/nutriment = 2, /datum/reagent/consumable/ice = 2)
list_reagents = list(/datum/reagent/consumable/nutriment = 2, /datum/reagent/consumable/ice = 2)
tastes = list("ice cream" = 2, "berry" = 2)
foodtype = FRUIT | DAIRY | SUGAR
+ /*food_flags = FOOD_FINGER_FOOD*/
/obj/item/reagent_containers/food/snacks/spacefreezy
@@ -29,6 +33,7 @@
desc = "The best icecream in space."
icon = 'icons/obj/food/frozen_treats.dmi'
icon_state = "spacefreezy"
+ w_class = WEIGHT_CLASS_TINY
bonus_reagents = list(/datum/reagent/consumable/nutriment = 2, /datum/reagent/consumable/nutriment/vitamin = 2)
list_reagents = list(/datum/reagent/consumable/nutriment = 6, /datum/reagent/consumable/bluecherryjelly = 5, /datum/reagent/consumable/nutriment/vitamin = 4)
filling_color = "#87CEFA"
@@ -40,6 +45,7 @@
desc = "A classic dessert."
icon = 'icons/obj/food/frozen_treats.dmi'
icon_state = "sundae"
+ w_class = WEIGHT_CLASS_SMALL
bonus_reagents = list(/datum/reagent/consumable/nutriment = 2, /datum/reagent/consumable/nutriment/vitamin = 1)
list_reagents = list(/datum/reagent/consumable/nutriment = 6, /datum/reagent/consumable/banana = 5, /datum/reagent/consumable/nutriment/vitamin = 2)
filling_color = "#FFFACD"
@@ -66,12 +72,14 @@
desc = "It's just shaved ice. Still fun to chew on."
icon = 'icons/obj/food/frozen_treats.dmi'
icon_state = "flavorless_sc"
+ w_class = WEIGHT_CLASS_SMALL
trash = /obj/item/reagent_containers/food/drinks/sillycup //We dont eat paper cups
bonus_reagents = list(/datum/reagent/water = 10) //Base line will allways give water
list_reagents = list(/datum/reagent/water = 1) // We dont get food for water/juices
filling_color = "#FFFFFF" //Ice is white
tastes = list("ice" = 1, "water" = 1)
foodtype = SUGAR //We use SUGAR as a base line to act in as junkfood, other wise we use fruit
+ /*food_flags = FOOD_FINGER_FOOD*/
/obj/item/reagent_containers/food/snacks/snowcones/lime
name = "lime snowcone"
diff --git a/code/modules/food_and_drinks/food/snacks_meat.dm b/code/modules/food_and_drinks/food/snacks_meat.dm
index 510130ce08be..c088b2259610 100644
--- a/code/modules/food_and_drinks/food/snacks_meat.dm
+++ b/code/modules/food_and_drinks/food/snacks_meat.dm
@@ -211,6 +211,8 @@
filling_color = "#800000"
tastes = list("meat" = 1)
foodtype = MEAT
+ /*food_flags = FOOD_FINGER_FOOD*/
+ w_class = WEIGHT_CLASS_SMALL
/obj/item/reagent_containers/food/snacks/sausage
name = "sausage"
@@ -223,6 +225,7 @@
slices_num = 6
slice_path = /obj/item/reagent_containers/food/snacks/salami
foodtype = MEAT | BREAKFAST
+ /*food_flags = FOOD_FINGER_FOOD*/
var/roasted = FALSE
/obj/item/reagent_containers/food/snacks/sausage/Initialize()
@@ -266,6 +269,8 @@
filling_color = "#CD853F"
tastes = list("the jungle" = 1, "bananas" = 1)
foodtype = MEAT | SUGAR
+ /*food_flags = FOOD_FINGER_FOOD*/
+ w_class = WEIGHT_CLASS_TINY
var/faction
var/spawned_mob = /mob/living/carbon/monkey
custom_price = 300
@@ -359,6 +364,8 @@
list_reagents = list(/datum/reagent/consumable/nutriment = 2)
tastes = list("\"chicken\"" = 1)
foodtype = MEAT
+ /*food_flags = FOOD_FINGER_FOOD*/
+ w_class = WEIGHT_CLASS_TINY
/obj/item/reagent_containers/food/snacks/nugget/Initialize()
. = ..()
diff --git a/code/modules/food_and_drinks/food/snacks_other.dm b/code/modules/food_and_drinks/food/snacks_other.dm
index 361e36ae9544..0e55d21b3505 100644
--- a/code/modules/food_and_drinks/food/snacks_other.dm
+++ b/code/modules/food_and_drinks/food/snacks_other.dm
@@ -37,7 +37,9 @@
filling_color = "#FF1493"
tastes = list("watermelon" = 1)
foodtype = FRUIT
+ /*food_flags = FOOD_FINGER_FOOD*/
juice_results = list(/datum/reagent/consumable/watermelonjuice = 5)
+ w_class = WEIGHT_CLASS_SMALL
/obj/item/reagent_containers/food/snacks/candy_corn
name = "candy corn"
@@ -47,6 +49,8 @@
filling_color = "#FF8C00"
tastes = list("candy corn" = 1)
foodtype = JUNKFOOD | SUGAR
+ /*food_flags = FOOD_FINGER_FOOD*/
+ w_class = WEIGHT_CLASS_TINY
/obj/item/reagent_containers/food/snacks/candy_corn/prison
name = "desiccated candy corn"
@@ -64,6 +68,8 @@
filling_color = "#A0522D"
tastes = list("chocolate" = 1)
foodtype = JUNKFOOD | SUGAR
+ /*food_flags = FOOD_FINGER_FOOD*/
+ w_class = WEIGHT_CLASS_TINY
/obj/item/reagent_containers/food/snacks/hugemushroomslice
name = "huge mushroom slice"
@@ -179,6 +185,8 @@
list_reagents = list(/datum/reagent/toxin/minttoxin = 2)
filling_color = "#800000"
foodtype = TOXIC | SUGAR
+ /*food_flags = FOOD_FINGER_FOOD*/
+ w_class = WEIGHT_CLASS_TINY
/obj/item/reagent_containers/food/snacks/eggwrap
name = "egg wrap"
@@ -216,6 +224,8 @@
filling_color = "#00800"
tastes = list("cobwebs" = 1, "sugar" = 2)
foodtype = JUNKFOOD | SUGAR
+ /*food_flags = FOOD_FINGER_FOOD*/
+ w_class = WEIGHT_CLASS_TINY
/obj/item/reagent_containers/food/snacks/chococoin
name = "chocolate coin"
@@ -226,6 +236,8 @@
filling_color = "#A0522D"
tastes = list("chocolate" = 1)
foodtype = JUNKFOOD | SUGAR
+ /*food_flags = FOOD_FINGER_FOOD*/
+ w_class = WEIGHT_CLASS_SMALL
/obj/item/reagent_containers/food/snacks/fudgedice
name = "fudge dice"
@@ -237,6 +249,8 @@
trash = /obj/item/dice/fudge
tastes = list("fudge" = 1)
foodtype = JUNKFOOD | SUGAR
+ /*food_flags = FOOD_FINGER_FOOD*/
+ w_class = WEIGHT_CLASS_SMALL
/obj/item/reagent_containers/food/snacks/chocoorange
name = "chocolate orange"
@@ -247,6 +261,8 @@
filling_color = "#A0522D"
tastes = list("chocolate" = 3, "oranges" = 1)
foodtype = JUNKFOOD | SUGAR
+ /*food_flags = FOOD_FINGER_FOOD*/
+ w_class = WEIGHT_CLASS_SMALL
/obj/item/reagent_containers/food/snacks/eggplantparm
name = "eggplant parmigiana"
@@ -391,6 +407,8 @@
filling_color = "#F2CE91"
tastes = list("oats" = 3, "nuts" = 2, "honey" = 1)
foodtype = GRAIN | SUGAR
+ /*food_flags = FOOD_FINGER_FOOD*/
+ w_class = WEIGHT_CLASS_SMALL
/obj/item/reagent_containers/food/snacks/stuffedlegion
name = "stuffed legion"
@@ -471,6 +489,8 @@
next_succ = 0
tastes = list("candy" = 1)
foodtype = JUNKFOOD | SUGAR
+ /*food_flags = FOOD_FINGER_FOOD*/
+ w_class = WEIGHT_CLASS_TINY
/obj/item/reagent_containers/food/snacks/chewable/lollipop/Initialize()
. = ..()
@@ -562,6 +582,8 @@
list_reagents = list(/datum/reagent/consumable/sugar = 5, /datum/reagent/medicine/bicaridine = 2, /datum/reagent/medicine/kelotane = 2) //Kek
tastes = list("candy")
foodtype = JUNKFOOD
+ /*food_flags = FOOD_FINGER_FOOD*/
+ w_class = WEIGHT_CLASS_TINY
/obj/item/reagent_containers/food/snacks/gumball/Initialize()
. = ..()
@@ -642,6 +664,7 @@
desc = "delicious, golden, fatty goodness on a stick."
icon_state = "butteronastick"
trash = /obj/item/stack/rods
+ /*food_flags = FOOD_FINGER_FOOD*/
/obj/item/reagent_containers/food/snacks/onionrings
name = "onion rings"
@@ -652,6 +675,7 @@
gender = PLURAL
tastes = list("batter" = 3, "onion" = 1)
foodtype = VEGETABLES
+ w_class = WEIGHT_CLASS_SMALL
/obj/item/reagent_containers/food/snacks/pineappleslice
name = "pineapple slice"
@@ -661,6 +685,7 @@
juice_results = list(/datum/reagent/consumable/pineapplejuice = 3)
tastes = list("pineapple" = 1)
foodtype = FRUIT | PINEAPPLE
+ w_class = WEIGHT_CLASS_TINY
/obj/item/reagent_containers/food/snacks/tinychocolate
name = "chocolate"
diff --git a/code/modules/food_and_drinks/food/snacks_pastry.dm b/code/modules/food_and_drinks/food/snacks_pastry.dm
index ee0dd7ab58de..7cb9f05900ba 100644
--- a/code/modules/food_and_drinks/food/snacks_pastry.dm
+++ b/code/modules/food_and_drinks/food/snacks_pastry.dm
@@ -13,6 +13,8 @@
filling_color = "#D2691E"
tastes = list("donut" = 1)
foodtype = JUNKFOOD | GRAIN | FRIED | SUGAR | BREAKFAST
+ /*food_flags = FOOD_FINGER_FOOD*/
+ w_class = WEIGHT_CLASS_SMALL
var/decorated_icon = "donut_homer"
var/is_decorated = FALSE
var/extra_reagent = null
@@ -336,6 +338,8 @@
filling_color = "#F4A460"
tastes = list("muffin" = 1)
foodtype = GRAIN | SUGAR | BREAKFAST
+ /*food_flags = FOOD_FINGER_FOOD*/
+ w_class = WEIGHT_CLASS_SMALL
/obj/item/reagent_containers/food/snacks/muffin/berry
name = "berry muffin"
@@ -420,6 +424,8 @@
filling_color = "#CD853F"
tastes = list("meat" = 2, "dough" = 2, "laziness" = 1)
foodtype = GRAIN
+ /*food_flags = FOOD_FINGER_FOOD*/
+ w_class = WEIGHT_CLASS_SMALL
/obj/item/reagent_containers/food/snacks/donkpocket/warm
name = "warm Donk-pocket"
@@ -565,6 +571,8 @@
filling_color = "#F0E68C"
tastes = list("cookie" = 1)
foodtype = GRAIN | SUGAR
+ /*food_flags = FOOD_FINGER_FOOD*/
+ w_class = WEIGHT_CLASS_SMALL
/obj/item/reagent_containers/food/snacks/cookie/Initialize()
. = ..()
@@ -583,6 +591,8 @@
filling_color = "#F4A460"
tastes = list("cookie" = 1)
foodtype = GRAIN | SUGAR
+ /*food_flags = FOOD_FINGER_FOOD*/
+ w_class = WEIGHT_CLASS_TINY
/obj/item/reagent_containers/food/snacks/fortunecookie/proc/get_fortune()
var/atom/drop_location = drop_location()
@@ -613,6 +623,8 @@
filling_color = "#F0E68C"
tastes = list("pretzel" = 1)
foodtype = GRAIN | SUGAR
+ /*food_flags = FOOD_FINGER_FOOD*/
+ w_class = WEIGHT_CLASS_SMALL
/obj/item/reagent_containers/food/snacks/plumphelmetbiscuit
name = "plump helmet biscuit"
@@ -623,6 +635,8 @@
filling_color = "#F0E68C"
tastes = list("mushroom" = 1, "biscuit" = 1)
foodtype = GRAIN | VEGETABLES
+ /*food_flags = FOOD_FINGER_FOOD*/
+ w_class = WEIGHT_CLASS_SMALL
/obj/item/reagent_containers/food/snacks/plumphelmetbiscuit/Initialize()
var/fey = prob(10)
@@ -644,6 +658,8 @@
filling_color = "#F0E68C"
tastes = list("cracker" = 1)
foodtype = GRAIN
+ /*food_flags = FOOD_FINGER_FOOD*/
+ w_class = WEIGHT_CLASS_TINY
/obj/item/reagent_containers/food/snacks/hotdog
name = "hotdog"
@@ -732,21 +748,19 @@
name = "cherry cupcake"
desc = "A sweet cupcake with cherry bits."
icon_state = "cherrycupcake"
- bonus_reagents = list(/datum/reagent/consumable/nutriment = 1, /datum/reagent/consumable/nutriment/vitamin = 1)
+ bonus_reagents = list(/datum/reagent/consumable/nutriment = 1, /datum/reagent/consumable/nutriment/vitamin = 3)
list_reagents = list(/datum/reagent/consumable/nutriment = 5, /datum/reagent/consumable/nutriment/vitamin = 1)
filling_color = "#F0E68C"
tastes = list("cake" = 3, "cherry" = 1)
foodtype = GRAIN | FRUIT | SUGAR
+ /*food_flags = FOOD_FINGER_FOOD*/
+ w_class = WEIGHT_CLASS_SMALL
-/obj/item/reagent_containers/food/snacks/bluecherrycupcake
+/obj/item/reagent_containers/food/snacks/cherrycupcake/blue
name = "blue cherry cupcake"
desc = "Blue cherries inside a delicious cupcake."
icon_state = "bluecherrycupcake"
- bonus_reagents = list(/datum/reagent/consumable/nutriment = 1, /datum/reagent/consumable/nutriment/vitamin = 3)
- list_reagents = list(/datum/reagent/consumable/nutriment = 5, /datum/reagent/consumable/nutriment/vitamin = 1)
- filling_color = "#F0E68C"
tastes = list("cake" = 3, "blue cherry" = 1)
- foodtype = GRAIN | FRUIT | SUGAR
/obj/item/reagent_containers/food/snacks/honeybun
name = "honey bun"
diff --git a/code/modules/food_and_drinks/food/snacks_sandwichtoast.dm b/code/modules/food_and_drinks/food/snacks_sandwichtoast.dm
index c15a6606be97..169d208bf30d 100644
--- a/code/modules/food_and_drinks/food/snacks_sandwichtoast.dm
+++ b/code/modules/food_and_drinks/food/snacks_sandwichtoast.dm
@@ -9,6 +9,8 @@
cooked_type = /obj/item/reagent_containers/food/snacks/toastedsandwich
tastes = list("meat" = 2, "cheese" = 1, "bread" = 2, "lettuce" = 1)
foodtype = GRAIN | VEGETABLES
+ /*food_flags = FOOD_FINGER_FOOD*/
+ w_class = WEIGHT_CLASS_SMALL
/obj/item/reagent_containers/food/snacks/toastedsandwich
name = "toasted sandwich"
@@ -31,6 +33,8 @@
list_reagents = list(/datum/reagent/consumable/nutriment = 6, /datum/reagent/consumable/nutriment/vitamin = 1)
tastes = list("toast" = 1, "cheese" = 1)
foodtype = GRAIN | DAIRY
+ /*food_flags = FOOD_FINGER_FOOD*/
+ w_class = WEIGHT_CLASS_SMALL
/obj/item/reagent_containers/food/snacks/jellysandwich
name = "jelly sandwich"
diff --git a/code/modules/food_and_drinks/food/snacks_spaghetti.dm b/code/modules/food_and_drinks/food/snacks_spaghetti.dm
deleted file mode 100644
index 88c1188f1dee..000000000000
--- a/code/modules/food_and_drinks/food/snacks_spaghetti.dm
+++ /dev/null
@@ -1,106 +0,0 @@
-
-/obj/item/reagent_containers/food/snacks/spaghetti
- name = "spaghetti"
- desc = "Now that's a nic'e pasta!"
- icon = 'icons/obj/food/pizzaspaghetti.dmi'
- icon_state = "spaghetti"
- list_reagents = list(/datum/reagent/consumable/nutriment = 1, /datum/reagent/consumable/nutriment/vitamin = 1)
- cooked_type = /obj/item/reagent_containers/food/snacks/spaghetti/boiledspaghetti
- filling_color = "#F0E68C"
- tastes = list("pasta" = 1)
- foodtype = GRAIN
-
-/obj/item/reagent_containers/food/snacks/spaghetti/Initialize()
- . = ..()
- if(!cooked_type) // This isn't cooked, why would you put uncooked spaghetti in your pocket?
- var/list/display_message = list(
- "Something wet falls out of their pocket and hits the ground. Is that... [name]?",
- "Oh shit! All your pocket [name] fell out!")
- AddComponent(/datum/component/spill, display_message, 'sound/effects/splat.ogg')
-
-/obj/item/reagent_containers/food/snacks/spaghetti/boiledspaghetti
- name = "boiled spaghetti"
- desc = "A plain dish of noodles, this needs more ingredients."
- icon_state = "spaghettiboiled"
- trash = /obj/item/trash/plate
- bonus_reagents = list(/datum/reagent/consumable/nutriment = 2)
- list_reagents = list(/datum/reagent/consumable/nutriment = 2, /datum/reagent/consumable/nutriment/vitamin = 1)
- cooked_type = null
- custom_food_type = /obj/item/reagent_containers/food/snacks/customizable/pasta
-
-/obj/item/reagent_containers/food/snacks/spaghetti/pastatomato
- name = "spaghetti"
- desc = "Spaghetti and crushed tomatoes. Just like your abusive father used to make!"
- icon_state = "pastatomato"
- trash = /obj/item/trash/plate
- bitesize = 4
- bonus_reagents = list(/datum/reagent/consumable/nutriment = 1, /datum/reagent/consumable/tomatojuice = 10, /datum/reagent/consumable/nutriment/vitamin = 4)
- list_reagents = list(/datum/reagent/consumable/nutriment = 6, /datum/reagent/consumable/tomatojuice = 10, /datum/reagent/consumable/nutriment/vitamin = 4)
- cooked_type = null
- filling_color = "#DC143C"
- tastes = list("pasta" = 1, "tomato" = 1)
- foodtype = GRAIN | VEGETABLES
-
-/obj/item/reagent_containers/food/snacks/spaghetti/copypasta
- name = "copypasta"
- desc = "You probably shouldn't try this, you always hear people talking about how bad it is..."
- icon_state = "copypasta"
- trash = /obj/item/trash/plate
- bitesize = 4
- bonus_reagents = list(/datum/reagent/consumable/nutriment = 1, /datum/reagent/consumable/nutriment/vitamin = 4)
- list_reagents = list(/datum/reagent/consumable/nutriment = 12, /datum/reagent/consumable/tomatojuice = 20, /datum/reagent/consumable/nutriment/vitamin = 8)
- cooked_type = null
- filling_color = "#DC143C"
- tastes = list("pasta" = 1, "tomato" = 1)
- foodtype = GRAIN | VEGETABLES
-
-/obj/item/reagent_containers/food/snacks/spaghetti/meatballspaghetti
- name = "spaghetti and meatballs"
- desc = "Now that's a nic'e meatball!"
- icon_state = "meatballspaghetti"
- trash = /obj/item/trash/plate
- bonus_reagents = list(/datum/reagent/consumable/nutriment = 1, /datum/reagent/consumable/nutriment/vitamin = 4)
- list_reagents = list(/datum/reagent/consumable/nutriment = 8, /datum/reagent/consumable/nutriment/vitamin = 4)
- cooked_type = null
- tastes = list("pasta" = 1, "tomato" = 1, "meat" = 1)
- foodtype = GRAIN | MEAT
-
-/obj/item/reagent_containers/food/snacks/spaghetti/spesslaw
- name = "spesslaw"
- desc = "A lawyers favourite."
- icon_state = "spesslaw"
- trash = /obj/item/trash/plate
- bonus_reagents = list(/datum/reagent/consumable/nutriment = 1, /datum/reagent/consumable/nutriment/vitamin = 6)
- list_reagents = list(/datum/reagent/consumable/nutriment = 8, /datum/reagent/consumable/nutriment/vitamin = 6)
- cooked_type = null
- tastes = list("pasta" = 1, "tomato" = 1, "meat" = 1)
-
-/obj/item/reagent_containers/food/snacks/spaghetti/chowmein
- name = "chow mein"
- desc = "A nice mix of noodles and fried vegetables."
- icon_state = "chowmein"
- trash = /obj/item/trash/plate
- bonus_reagents = list(/datum/reagent/consumable/nutriment = 3, /datum/reagent/consumable/nutriment/vitamin = 4)
- list_reagents = list(/datum/reagent/consumable/nutriment = 7, /datum/reagent/consumable/nutriment/vitamin = 6)
- cooked_type = null
- tastes = list("noodle" = 1, "tomato" = 1)
-
-/obj/item/reagent_containers/food/snacks/spaghetti/beefnoodle
- name = "beef noodle"
- desc = "Nutritious, beefy and noodly."
- icon_state = "beefnoodle"
- trash = /obj/item/reagent_containers/glass/bowl
- bonus_reagents = list(/datum/reagent/consumable/nutriment = 5, /datum/reagent/consumable/nutriment/vitamin = 6, /datum/reagent/liquidgibs = 3)
- cooked_type = null
- tastes = list("noodle" = 1, "meat" = 1)
- foodtype = GRAIN | MEAT
-
-/obj/item/reagent_containers/food/snacks/spaghetti/butternoodles
- name = "butter noodles"
- desc = "Noodles covered in savory butter. Simple and slippery, but delicious."
- icon_state = "butternoodles"
- trash = /obj/item/trash/plate
- bonus_reagents = list(/datum/reagent/consumable/nutriment = 8, /datum/reagent/consumable/nutriment/vitamin = 1)
- cooked_type = null
- tastes = list("noodle" = 1, "butter" = 1)
- foodtype = GRAIN | DAIRY
diff --git a/code/modules/food_and_drinks/food/snacks_vend.dm b/code/modules/food_and_drinks/food/snacks_vend.dm
index 94477d1932aa..b071add1027a 100644
--- a/code/modules/food_and_drinks/food/snacks_vend.dm
+++ b/code/modules/food_and_drinks/food/snacks_vend.dm
@@ -12,6 +12,8 @@
filling_color = "#D2691E"
tastes = list("candy" = 1)
foodtype = JUNKFOOD | SUGAR
+ /*food_flags = FOOD_FINGER_FOOD*/
+ w_class = WEIGHT_CLASS_TINY
/obj/item/reagent_containers/food/snacks/candy/bronx
name = "South Bronx Paradise bar"
@@ -82,7 +84,9 @@
filling_color = "#8B0000"
tastes = list("dried raisins" = 1)
foodtype = JUNKFOOD | FRUIT | SUGAR
+ /*food_flags = FOOD_FINGER_FOOD*/
custom_price = 90
+ w_class = WEIGHT_CLASS_SMALL
/obj/item/reagent_containers/food/snacks/no_raisin/healthy
name = "homemade raisins"
@@ -99,7 +103,9 @@
junkiness = 25
filling_color = "#FFD700"
foodtype = JUNKFOOD | GRAIN | SUGAR
+ /*food_flags = FOOD_FINGER_FOOD*/
custom_price = 30
+ w_class = WEIGHT_CLASS_SMALL
/obj/item/reagent_containers/food/snacks/candy_trash
name = "candy cigarette butt"
@@ -136,6 +142,7 @@
filling_color = "#F5F5DC"
tastes = list("sweetness" = 3, "cake" = 1)
foodtype = GRAIN | FRUIT | VEGETABLES
+ w_class = WEIGHT_CLASS_SMALL
/obj/item/reagent_containers/food/snacks/energybar
name = "High-power energy bars"
@@ -146,3 +153,5 @@
filling_color = "#97ee63"
tastes = list("pure electricity" = 3, "fitness" = 2)
foodtype = TOXIC
+ /*food_flags = FOOD_FINGER_FOOD*/
+ w_class = WEIGHT_CLASS_SMALL
diff --git a/code/modules/food_and_drinks/kitchen_machinery/deep_fryer.dm b/code/modules/food_and_drinks/kitchen_machinery/deep_fryer.dm
index 8eccd04c8404..62e6a4075a93 100644
--- a/code/modules/food_and_drinks/kitchen_machinery/deep_fryer.dm
+++ b/code/modules/food_and_drinks/kitchen_machinery/deep_fryer.dm
@@ -18,6 +18,8 @@
// _- _
// -
+//God bless These Deepfried States o7 -2024
+
/obj/machinery/deepfryer
name = "deep fryer"
desc = "Deep fried everything."
@@ -27,7 +29,7 @@
use_power = IDLE_POWER_USE
idle_power_usage = IDLE_DRAW_LOW
layer = BELOW_OBJ_LAYER
- var/obj/item/reagent_containers/food/snacks/deepfryholder/frying //What's being fried RIGHT NOW?
+ var/obj/item/food/deepfryholder/frying //What's being fried RIGHT NOW?
var/cook_time = 0
var/oil_use = 0.05 //How much cooking oil is used per tick
var/fry_speed = 1 //How quickly we fry food
@@ -93,7 +95,7 @@
if(I.resistance_flags & INDESTRUCTIBLE)
to_chat(user, "You don't feel it would be wise to fry [I]...")
return
- if(istype(I, /obj/item/reagent_containers/food/snacks/deepfryholder))
+ if(istype(I, /obj/item/food/deepfryholder))
to_chat(user, "Your cooking skills are not up to the legendary Doublefry technique.")
return
if(default_unfasten_wrench(user, I))
@@ -105,7 +107,7 @@
return ..()
else if(!frying && user.transferItemToLoc(I, src))
to_chat(user, "You put [I] into [src].")
- frying = new/obj/item/reagent_containers/food/snacks/deepfryholder(src, I)
+ frying = new/obj/item/food/deepfryholder(src, I)
icon_state = "fryer_on"
fry_loop.start()
diff --git a/code/modules/food_and_drinks/kitchen_machinery/icecream_vat.dm b/code/modules/food_and_drinks/kitchen_machinery/icecream_vat.dm
index 1d4e366ad6d9..de4d844aa3ac 100644
--- a/code/modules/food_and_drinks/kitchen_machinery/icecream_vat.dm
+++ b/code/modules/food_and_drinks/kitchen_machinery/icecream_vat.dm
@@ -210,7 +210,7 @@
return
/obj/item/reagent_containers/food/snacks/icecream
- name = "ice cream cone"
+ name = "waffle cone"
desc = "Delicious waffle cone, but no ice cream."
icon = 'icons/obj/kitchen.dmi'
icon_state = "icecream_cone_waffle" //default for admin-spawned cones, href_list["cone"] should overwrite this all the time
@@ -220,6 +220,7 @@
var/cone_type
bitesize = 4
foodtype = DAIRY | SUGAR
+ /*food_flags = FOOD_FINGER_FOOD*/
/obj/item/reagent_containers/food/snacks/icecream/Initialize()
. = ..()
diff --git a/code/modules/food_and_drinks/recipes/processor_recipes.dm b/code/modules/food_and_drinks/recipes/processor_recipes.dm
index 98c5fa053c8f..0a0b00094e79 100644
--- a/code/modules/food_and_drinks/recipes/processor_recipes.dm
+++ b/code/modules/food_and_drinks/recipes/processor_recipes.dm
@@ -31,7 +31,7 @@
/datum/food_processor_process/spaghetti
input = /obj/item/reagent_containers/food/snacks/doughslice
- output = /obj/item/reagent_containers/food/snacks/spaghetti
+ output = /obj/item/food/spaghetti
/datum/food_processor_process/corn
input = /obj/item/reagent_containers/food/snacks/grown/corn
diff --git a/code/modules/food_and_drinks/recipes/tablecraft/recipes_bread.dm b/code/modules/food_and_drinks/recipes/tablecraft/recipes_bread.dm
index f29e948adf4c..0dec69a393f5 100644
--- a/code/modules/food_and_drinks/recipes/tablecraft/recipes_bread.dm
+++ b/code/modules/food_and_drinks/recipes/tablecraft/recipes_bread.dm
@@ -6,83 +6,83 @@
/datum/crafting_recipe/food/meatbread
name = "Meat bread"
reqs = list(
- /obj/item/reagent_containers/food/snacks/store/bread/plain = 1,
+ /obj/item/food/bread/plain = 1,
/obj/item/reagent_containers/food/snacks/meat/cutlet/plain = 3,
/obj/item/reagent_containers/food/snacks/cheesewedge = 3
)
- result = /obj/item/reagent_containers/food/snacks/store/bread/meat
+ result = /obj/item/food/bread/meat
subcategory = CAT_BREAD
/datum/crafting_recipe/food/xenomeatbread
name = "Xenomeat bread"
reqs = list(
- /obj/item/reagent_containers/food/snacks/store/bread/plain = 1,
+ /obj/item/food/bread/plain = 1,
/obj/item/reagent_containers/food/snacks/meat/cutlet/xeno = 3,
/obj/item/reagent_containers/food/snacks/cheesewedge = 3
)
- result = /obj/item/reagent_containers/food/snacks/store/bread/xenomeat
+ result = /obj/item/food/bread/xenomeat
subcategory = CAT_BREAD
/datum/crafting_recipe/food/spidermeatbread
name = "Spidermeat bread"
reqs = list(
- /obj/item/reagent_containers/food/snacks/store/bread/plain = 1,
+ /obj/item/food/bread/plain = 1,
/obj/item/reagent_containers/food/snacks/meat/cutlet/spider = 3,
/obj/item/reagent_containers/food/snacks/cheesewedge = 3
)
- result = /obj/item/reagent_containers/food/snacks/store/bread/spidermeat
+ result = /obj/item/food/bread/spidermeat
subcategory = CAT_BREAD
/datum/crafting_recipe/food/banananutbread
name = "Banana nut bread"
reqs = list(
/datum/reagent/consumable/milk = 5,
- /obj/item/reagent_containers/food/snacks/store/bread/plain = 1,
+ /obj/item/food/bread/plain = 1,
/obj/item/reagent_containers/food/snacks/boiledegg = 3,
/obj/item/reagent_containers/food/snacks/grown/banana = 1
)
- result = /obj/item/reagent_containers/food/snacks/store/bread/banana
+ result = /obj/item/food/bread/banana
subcategory = CAT_BREAD
/datum/crafting_recipe/food/tofubread
name = "Tofu bread"
reqs = list(
- /obj/item/reagent_containers/food/snacks/store/bread/plain = 1,
+ /obj/item/food/bread/plain = 1,
/obj/item/reagent_containers/food/snacks/tofu = 3,
/obj/item/reagent_containers/food/snacks/cheesewedge = 3
)
- result = /obj/item/reagent_containers/food/snacks/store/bread/tofu
+ result = /obj/item/food/bread/tofu
subcategory = CAT_BREAD
/datum/crafting_recipe/food/creamcheesebread
name = "Cream cheese bread"
reqs = list(
/datum/reagent/consumable/milk = 5,
- /obj/item/reagent_containers/food/snacks/store/bread/plain = 1,
+ /obj/item/food/bread/plain = 1,
/obj/item/reagent_containers/food/snacks/cheesewedge = 2
)
- result = /obj/item/reagent_containers/food/snacks/store/bread/creamcheese
+ result = /obj/item/food/bread/creamcheese
subcategory = CAT_BREAD
/datum/crafting_recipe/food/mimanabread
name = "Mimana bread"
reqs = list(
/datum/reagent/consumable/soymilk = 5,
- /obj/item/reagent_containers/food/snacks/store/bread/plain = 1,
+ /obj/item/food/bread/plain = 1,
/obj/item/reagent_containers/food/snacks/tofu = 3,
/obj/item/reagent_containers/food/snacks/grown/banana/mime = 1
)
- result = /obj/item/reagent_containers/food/snacks/store/bread/mimana
+ result = /obj/item/food/bread/mimana
subcategory = CAT_BREAD
/datum/crafting_recipe/food/garlicbread
name = "Garlic Bread"
time = 40
reqs = list(/obj/item/reagent_containers/food/snacks/grown/garlic = 1,
- /obj/item/reagent_containers/food/snacks/breadslice/plain = 1,
+ /obj/item/food/breadslice/plain = 1,
/obj/item/reagent_containers/food/snacks/butter = 1
)
- result = /obj/item/reagent_containers/food/snacks/garlicbread
+ result = /obj/item/food/garlicbread
subcategory = CAT_BREAD
/datum/crafting_recipe/food/butterbiscuit
@@ -91,7 +91,7 @@
/obj/item/reagent_containers/food/snacks/bun = 1,
/obj/item/reagent_containers/food/snacks/butter = 1
)
- result = /obj/item/reagent_containers/food/snacks/butterbiscuit
+ result = /obj/item/food/butterbiscuit
subcategory = CAT_BREAD
/datum/crafting_recipe/food/butterdog
@@ -100,14 +100,14 @@
/obj/item/reagent_containers/food/snacks/bun = 1,
/obj/item/reagent_containers/food/snacks/butter = 3,
)
- result = /obj/item/reagent_containers/food/snacks/butterdog
+ result = /obj/item/food/butterdog
subcategory = CAT_BREAD
/datum/crafting_recipe/food/moldybread // why would you make this?
name = "Moldy Bread"
reqs = list(
- /obj/item/reagent_containers/food/snacks/breadslice/plain = 1,
+ /obj/item/food/breadslice/plain = 1,
/obj/item/reagent_containers/food/snacks/grown/mushroom/amanita = 1
)
- result = /obj/item/reagent_containers/food/snacks/breadslice/moldy
+ result = /obj/item/food/breadslice/moldy
subcategory = CAT_BREAD
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 dcae05095ae8..7a3a4c6837b5 100644
--- a/code/modules/food_and_drinks/recipes/tablecraft/recipes_cake.dm
+++ b/code/modules/food_and_drinks/recipes/tablecraft/recipes_cake.dm
@@ -6,190 +6,190 @@
/datum/crafting_recipe/food/carrotcake
name = "Carrot cake"
reqs = list(
- /obj/item/reagent_containers/food/snacks/store/cake/plain = 1,
+ /obj/item/food/cake/plain = 1,
/obj/item/reagent_containers/food/snacks/grown/carrot = 2
)
- result = /obj/item/reagent_containers/food/snacks/store/cake/carrot
+ result = /obj/item/food/cake/carrot
subcategory = CAT_CAKE
/datum/crafting_recipe/food/cheesecake
name = "Cheese cake"
reqs = list(
- /obj/item/reagent_containers/food/snacks/store/cake/plain = 1,
+ /obj/item/food/cake/plain = 1,
/obj/item/reagent_containers/food/snacks/cheesewedge = 2
)
- result = /obj/item/reagent_containers/food/snacks/store/cake/cheese
+ result = /obj/item/food/cake/cheese
subcategory = CAT_CAKE
/datum/crafting_recipe/food/applecake
name = "Apple cake"
reqs = list(
- /obj/item/reagent_containers/food/snacks/store/cake/plain = 1,
+ /obj/item/food/cake/plain = 1,
/obj/item/reagent_containers/food/snacks/grown/apple = 2
)
- result = /obj/item/reagent_containers/food/snacks/store/cake/apple
+ result = /obj/item/food/cake/apple
subcategory = CAT_CAKE
/datum/crafting_recipe/food/orangecake
name = "Orange cake"
reqs = list(
- /obj/item/reagent_containers/food/snacks/store/cake/plain = 1,
+ /obj/item/food/cake/plain = 1,
/obj/item/reagent_containers/food/snacks/grown/citrus/orange = 2
)
- result = /obj/item/reagent_containers/food/snacks/store/cake/orange
+ result = /obj/item/food/cake/orange
subcategory = CAT_CAKE
/datum/crafting_recipe/food/limecake
name = "Lime cake"
reqs = list(
- /obj/item/reagent_containers/food/snacks/store/cake/plain = 1,
+ /obj/item/food/cake/plain = 1,
/obj/item/reagent_containers/food/snacks/grown/citrus/lime = 2
)
- result = /obj/item/reagent_containers/food/snacks/store/cake/lime
+ result = /obj/item/food/cake/lime
subcategory = CAT_CAKE
/datum/crafting_recipe/food/lemoncake
name = "Lemon cake"
reqs = list(
- /obj/item/reagent_containers/food/snacks/store/cake/plain = 1,
+ /obj/item/food/cake/plain = 1,
/obj/item/reagent_containers/food/snacks/grown/citrus/lemon = 2
)
- result = /obj/item/reagent_containers/food/snacks/store/cake/lemon
+ result = /obj/item/food/cake/lemon
subcategory = CAT_CAKE
/datum/crafting_recipe/food/chocolatecake
name = "Chocolate cake"
reqs = list(
- /obj/item/reagent_containers/food/snacks/store/cake/plain = 1,
+ /obj/item/food/cake/plain = 1,
/obj/item/reagent_containers/food/snacks/chocolatebar = 2
)
- result = /obj/item/reagent_containers/food/snacks/store/cake/chocolate
+ result = /obj/item/food/cake/chocolate
subcategory = CAT_CAKE
/datum/crafting_recipe/food/birthdaycake
name = "Birthday cake"
reqs = list(
- /obj/item/reagent_containers/food/snacks/store/cake/plain = 1,
+ /obj/item/food/cake/plain = 1,
/obj/item/candle = 1,
/datum/reagent/consumable/sugar = 5,
/datum/reagent/consumable/caramel = 2
)
- result = /obj/item/reagent_containers/food/snacks/store/cake/birthday
+ result = /obj/item/food/cake/birthday
subcategory = CAT_CAKE
/datum/crafting_recipe/food/energycake
name = "Energy cake"
reqs = list(
- /obj/item/reagent_containers/food/snacks/store/cake/birthday = 1,
+ /obj/item/food/cake/birthday = 1,
/obj/item/melee/transforming/energy/sword = 1,
)
- blacklist = list(/obj/item/reagent_containers/food/snacks/store/cake/birthday/energy)
- result = /obj/item/reagent_containers/food/snacks/store/cake/birthday/energy
+ blacklist = list(/obj/item/food/cake/birthday/energy)
+ result = /obj/item/food/cake/birthday/energy
subcategory = CAT_CAKE
/datum/crafting_recipe/food/braincake
name = "Brain cake"
reqs = list(
/obj/item/organ/brain = 1,
- /obj/item/reagent_containers/food/snacks/store/cake/plain = 1
+ /obj/item/food/cake/plain = 1
)
- result = /obj/item/reagent_containers/food/snacks/store/cake/brain
+ result = /obj/item/food/cake/brain
subcategory = CAT_CAKE
/datum/crafting_recipe/food/slimecake
name = "Slime cake"
reqs = list(
/obj/item/slime_extract = 1,
- /obj/item/reagent_containers/food/snacks/store/cake/plain = 1
+ /obj/item/food/cake/plain = 1
)
- result = /obj/item/reagent_containers/food/snacks/store/cake/slimecake
+ result = /obj/item/food/cake/slimecake
subcategory = CAT_CAKE
/datum/crafting_recipe/food/pumpkinspicecake
name = "Pumpkin spice cake"
reqs = list(
- /obj/item/reagent_containers/food/snacks/store/cake/plain = 1,
+ /obj/item/food/cake/plain = 1,
/obj/item/reagent_containers/food/snacks/grown/pumpkin = 2
)
- result = /obj/item/reagent_containers/food/snacks/store/cake/pumpkinspice
+ result = /obj/item/food/cake/pumpkinspice
subcategory = CAT_CAKE
/datum/crafting_recipe/food/holycake
name = "Angel food cake"
reqs = list(
/datum/reagent/water/holywater = 15,
- /obj/item/reagent_containers/food/snacks/store/cake/plain = 1
+ /obj/item/food/cake/plain = 1
)
- result = /obj/item/reagent_containers/food/snacks/store/cake/holy_cake
+ result = /obj/item/food/cake/holy_cake
subcategory = CAT_CAKE
/datum/crafting_recipe/food/poundcake
name = "Pound cake"
reqs = list(
- /obj/item/reagent_containers/food/snacks/store/cake/plain = 4
+ /obj/item/food/cake/plain = 4
)
- result = /obj/item/reagent_containers/food/snacks/store/cake/pound_cake
+ result = /obj/item/food/cake/pound_cake
subcategory = CAT_CAKE
/datum/crafting_recipe/food/hardwarecake
name = "Hardware cake"
reqs = list(
- /obj/item/reagent_containers/food/snacks/store/cake/plain = 1,
+ /obj/item/food/cake/plain = 1,
/obj/item/circuitboard = 2,
/datum/reagent/toxin/acid = 5
)
- result = /obj/item/reagent_containers/food/snacks/store/cake/hardware_cake
+ result = /obj/item/food/cake/hardware_cake
subcategory = CAT_CAKE
/datum/crafting_recipe/food/bscccake
name = "blackberry and strawberry chocolate cake"
reqs = list(
- /obj/item/reagent_containers/food/snacks/store/cake/plain = 1,
+ /obj/item/food/cake/plain = 1,
/obj/item/reagent_containers/food/snacks/chocolatebar = 2,
/obj/item/reagent_containers/food/snacks/grown/berries = 5
)
- result = /obj/item/reagent_containers/food/snacks/store/cake/bscc
+ result = /obj/item/food/cake/bscc
subcategory = CAT_CAKE
/datum/crafting_recipe/food/bscvcake
name = "blackberry and strawberry vanilla cake"
reqs = list(
- /obj/item/reagent_containers/food/snacks/store/cake/plain = 1,
+ /obj/item/food/cake/plain = 1,
/obj/item/reagent_containers/food/snacks/grown/berries = 5
)
- result = /obj/item/reagent_containers/food/snacks/store/cake/bsvc
+ result = /obj/item/food/cake/bsvc
subcategory = CAT_CAKE
/datum/crafting_recipe/food/clowncake
name = "clown cake"
always_availible = FALSE
reqs = list(
- /obj/item/reagent_containers/food/snacks/store/cake/plain = 1,
+ /obj/item/food/cake/plain = 1,
/obj/item/reagent_containers/food/snacks/sundae = 2,
/obj/item/reagent_containers/food/snacks/grown/banana = 5
)
- result = /obj/item/reagent_containers/food/snacks/store/cake/clown_cake
+ result = /obj/item/food/cake/clown_cake
subcategory = CAT_CAKE
/datum/crafting_recipe/food/vanillacake
name = "vanilla cake"
always_availible = FALSE
reqs = list(
- /obj/item/reagent_containers/food/snacks/store/cake/plain = 1,
+ /obj/item/food/cake/plain = 1,
/obj/item/reagent_containers/food/snacks/grown/vanillapod = 2
)
- result = /obj/item/reagent_containers/food/snacks/store/cake/vanilla_cake
+ result = /obj/item/food/cake/vanilla_cake
subcategory = CAT_CAKE
/datum/crafting_recipe/food/trumpetcake
name = "Spaceman's Cake"
reqs = list(
- /obj/item/reagent_containers/food/snacks/store/cake/plain = 1,
+ /obj/item/food/cake/plain = 1,
/obj/item/reagent_containers/food/snacks/grown/trumpet = 2,
/datum/reagent/consumable/cream = 5,
/datum/reagent/consumable/berryjuice = 5
)
- result = /obj/item/reagent_containers/food/snacks/store/cake/trumpet
+ result = /obj/item/food/cake/trumpet
subcategory = CAT_CAKE
@@ -198,7 +198,7 @@
reqs = list(
/obj/item/organ/brain = 1,
/obj/item/organ/heart = 1,
- /obj/item/reagent_containers/food/snacks/store/cake/birthday = 1,
+ /obj/item/food/cake/birthday = 1,
/obj/item/reagent_containers/food/snacks/meat/slab = 3,
/datum/reagent/blood = 30,
/datum/reagent/consumable/sprinkles = 5,
diff --git a/code/modules/food_and_drinks/recipes/tablecraft/recipes_drink.dm b/code/modules/food_and_drinks/recipes/tablecraft/recipes_drink.dm
index 4e0ade4fa22d..96c67eca7a9e 100644
--- a/code/modules/food_and_drinks/recipes/tablecraft/recipes_drink.dm
+++ b/code/modules/food_and_drinks/recipes/tablecraft/recipes_drink.dm
@@ -139,7 +139,7 @@
time = 30
reqs = list(
/obj/item/storage/bag/trash = 1,
- /obj/item/reagent_containers/food/snacks/breadslice/moldy = 1,
+ /obj/item/food/breadslice/moldy = 1,
/obj/item/reagent_containers/food/snacks/grown = 4,
/obj/item/reagent_containers/food/snacks/candy_corn = 2,
/datum/reagent/water = 15
diff --git a/code/modules/food_and_drinks/recipes/tablecraft/recipes_egg.dm b/code/modules/food_and_drinks/recipes/tablecraft/recipes_egg.dm
index 522f362e777e..a4ab818fdd6f 100644
--- a/code/modules/food_and_drinks/recipes/tablecraft/recipes_egg.dm
+++ b/code/modules/food_and_drinks/recipes/tablecraft/recipes_egg.dm
@@ -36,7 +36,7 @@
reqs = list(
/obj/item/reagent_containers/food/snacks/friedegg = 1,
/obj/item/reagent_containers/food/snacks/meat/steak = 1,
- /obj/item/reagent_containers/food/snacks/breadslice/plain = 1,
+ /obj/item/food/breadslice/plain = 1,
)
result = /obj/item/reagent_containers/food/snacks/benedict
subcategory = CAT_EGG
diff --git a/code/modules/food_and_drinks/recipes/tablecraft/recipes_misc.dm b/code/modules/food_and_drinks/recipes/tablecraft/recipes_misc.dm
index 1bb3d250a9ae..b1191fda7ada 100644
--- a/code/modules/food_and_drinks/recipes/tablecraft/recipes_misc.dm
+++ b/code/modules/food_and_drinks/recipes/tablecraft/recipes_misc.dm
@@ -102,7 +102,7 @@
/datum/reagent/consumable/blackpepper = 1,
/obj/item/reagent_containers/food/snacks/pastrybase = 2
)
- result = /obj/item/reagent_containers/food/snacks/baguette
+ result = /obj/item/food/baguette
subcategory = CAT_MISCFOOD
////////////////////////////////////////////////TOAST////////////////////////////////////////////////
@@ -111,7 +111,7 @@
name = "Slime toast"
reqs = list(
/datum/reagent/toxin/slimejelly = 5,
- /obj/item/reagent_containers/food/snacks/breadslice/plain = 1
+ /obj/item/food/breadslice/plain = 1
)
result = /obj/item/reagent_containers/food/snacks/jelliedtoast/slime
subcategory = CAT_MISCFOOD
@@ -120,7 +120,7 @@
name = "Jellied toast"
reqs = list(
/datum/reagent/consumable/cherryjelly = 5,
- /obj/item/reagent_containers/food/snacks/breadslice/plain = 1
+ /obj/item/food/breadslice/plain = 1
)
result = /obj/item/reagent_containers/food/snacks/jelliedtoast/cherry
subcategory = CAT_MISCFOOD
@@ -128,7 +128,7 @@
/datum/crafting_recipe/food/butteredtoast
name = "Buttered Toast"
reqs = list(
- /obj/item/reagent_containers/food/snacks/breadslice/plain = 1,
+ /obj/item/food/breadslice/plain = 1,
/obj/item/reagent_containers/food/snacks/butter = 1
)
result = /obj/item/reagent_containers/food/snacks/butteredtoast
@@ -138,7 +138,7 @@
name = "Two bread"
reqs = list(
/datum/reagent/consumable/ethanol/wine = 5,
- /obj/item/reagent_containers/food/snacks/breadslice/plain = 2
+ /obj/item/food/breadslice/plain = 2
)
result = /obj/item/reagent_containers/food/snacks/twobread
subcategory = CAT_MISCFOOD
diff --git a/code/modules/food_and_drinks/recipes/tablecraft/recipes_pastry.dm b/code/modules/food_and_drinks/recipes/tablecraft/recipes_pastry.dm
index cc61c7048fdc..a1c1297647c3 100644
--- a/code/modules/food_and_drinks/recipes/tablecraft/recipes_pastry.dm
+++ b/code/modules/food_and_drinks/recipes/tablecraft/recipes_pastry.dm
@@ -473,7 +473,7 @@
reqs = list(
/datum/reagent/consumable/eggyolk = 5,
/obj/item/reagent_containers/food/snacks/cheesewedge = 1,
- /obj/item/reagent_containers/food/snacks/store/bread/plain = 1
+ /obj/item/food/bread/plain = 1
)
result = /obj/item/reagent_containers/food/snacks/khachapuri
subcategory = CAT_PASTRY
@@ -575,7 +575,7 @@
/obj/item/reagent_containers/food/snacks/pastrybase = 1,
/obj/item/reagent_containers/food/snacks/grown/bluecherries = 1
)
- result = /obj/item/reagent_containers/food/snacks/bluecherrycupcake
+ result = /obj/item/reagent_containers/food/snacks/cherrycupcake/blue
subcategory = CAT_PASTRY
/datum/crafting_recipe/food/honeybun
diff --git a/code/modules/food_and_drinks/recipes/tablecraft/recipes_sandwich.dm b/code/modules/food_and_drinks/recipes/tablecraft/recipes_sandwich.dm
index 41829e9ec2b8..b8cefcb9bd80 100644
--- a/code/modules/food_and_drinks/recipes/tablecraft/recipes_sandwich.dm
+++ b/code/modules/food_and_drinks/recipes/tablecraft/recipes_sandwich.dm
@@ -9,7 +9,7 @@
/datum/crafting_recipe/food/sandwich
name = "Sandwich"
reqs = list(
- /obj/item/reagent_containers/food/snacks/breadslice/plain = 2,
+ /obj/item/food/breadslice/plain = 2,
/obj/item/reagent_containers/food/snacks/meat/steak = 1,
/obj/item/reagent_containers/food/snacks/cheesewedge = 1
)
@@ -19,7 +19,7 @@
/datum/crafting_recipe/food/grilledcheesesandwich
name = "Cheese sandwich"
reqs = list(
- /obj/item/reagent_containers/food/snacks/breadslice/plain = 2,
+ /obj/item/food/breadslice/plain = 2,
/obj/item/reagent_containers/food/snacks/cheesewedge = 2
)
result = /obj/item/reagent_containers/food/snacks/grilledcheese
@@ -29,7 +29,7 @@
name = "Jelly sandwich"
reqs = list(
/datum/reagent/toxin/slimejelly = 5,
- /obj/item/reagent_containers/food/snacks/breadslice/plain = 2,
+ /obj/item/food/breadslice/plain = 2,
)
result = /obj/item/reagent_containers/food/snacks/jellysandwich/slime
subcategory = CAT_SANDWICH
@@ -38,7 +38,7 @@
name = "Jelly sandwich"
reqs = list(
/datum/reagent/consumable/cherryjelly = 5,
- /obj/item/reagent_containers/food/snacks/breadslice/plain = 2,
+ /obj/item/food/breadslice/plain = 2,
)
result = /obj/item/reagent_containers/food/snacks/jellysandwich/cherry
subcategory = CAT_SANDWICH
@@ -46,7 +46,7 @@
/datum/crafting_recipe/food/notasandwich
name = "Not a sandwich"
reqs = list(
- /obj/item/reagent_containers/food/snacks/breadslice/plain = 2,
+ /obj/item/food/breadslice/plain = 2,
/obj/item/clothing/mask/fakemoustache = 1
)
result = /obj/item/reagent_containers/food/snacks/notasandwich
@@ -55,7 +55,7 @@
/datum/crafting_recipe/food/blt
name = "BLT"
reqs = list(
- /obj/item/reagent_containers/food/snacks/breadslice/plain = 2,
+ /obj/item/food/breadslice/plain = 2,
/obj/item/reagent_containers/food/snacks/meat/bacon = 2,
/obj/item/reagent_containers/food/snacks/grown/cabbage = 1,
/obj/item/reagent_containers/food/snacks/grown/tomato = 1
diff --git a/code/modules/food_and_drinks/recipes/tablecraft/recipes_spaghetti.dm b/code/modules/food_and_drinks/recipes/tablecraft/recipes_spaghetti.dm
index 796c360c3448..2ad56d0ce62b 100644
--- a/code/modules/food_and_drinks/recipes/tablecraft/recipes_spaghetti.dm
+++ b/code/modules/food_and_drinks/recipes/tablecraft/recipes_spaghetti.dm
@@ -6,65 +6,65 @@
/datum/crafting_recipe/food/tomatopasta
name = "Tomato pasta"
reqs = list(
- /obj/item/reagent_containers/food/snacks/spaghetti/boiledspaghetti = 1,
+ /obj/item/food/spaghetti/boiledspaghetti = 1,
/obj/item/reagent_containers/food/snacks/grown/tomato = 2
)
- result = /obj/item/reagent_containers/food/snacks/spaghetti/pastatomato
+ result = /obj/item/food/spaghetti/pastatomato
subcategory = CAT_SPAGHETTI
/datum/crafting_recipe/food/copypasta
name = "Copypasta"
reqs = list(
- /obj/item/reagent_containers/food/snacks/spaghetti/pastatomato = 2
+ /obj/item/food/spaghetti/pastatomato = 2
)
- result = /obj/item/reagent_containers/food/snacks/spaghetti/copypasta
+ result = /obj/item/food/spaghetti/copypasta
subcategory = CAT_SPAGHETTI
/datum/crafting_recipe/food/spaghettimeatball
name = "Spaghetti meatball"
reqs = list(
- /obj/item/reagent_containers/food/snacks/spaghetti/boiledspaghetti = 1,
+ /obj/item/food/spaghetti/boiledspaghetti = 1,
/obj/item/reagent_containers/food/snacks/meatball = 2
)
- result = /obj/item/reagent_containers/food/snacks/spaghetti/meatballspaghetti
+ result = /obj/item/food/spaghetti/meatballspaghetti
subcategory = CAT_SPAGHETTI
/datum/crafting_recipe/food/spesslaw
name = "Spesslaw"
reqs = list(
- /obj/item/reagent_containers/food/snacks/spaghetti/boiledspaghetti = 1,
+ /obj/item/food/spaghetti/boiledspaghetti = 1,
/obj/item/reagent_containers/food/snacks/meatball = 4
)
- result = /obj/item/reagent_containers/food/snacks/spaghetti/spesslaw
+ result = /obj/item/food/spaghetti/spesslaw
subcategory = CAT_SPAGHETTI
/datum/crafting_recipe/food/beefnoodle
name = "Beef noodle"
reqs = list(
/obj/item/reagent_containers/glass/bowl = 1,
- /obj/item/reagent_containers/food/snacks/spaghetti/boiledspaghetti = 1,
+ /obj/item/food/spaghetti/boiledspaghetti = 1,
/obj/item/reagent_containers/food/snacks/meat/cutlet = 2,
/obj/item/reagent_containers/food/snacks/grown/cabbage = 1
)
- result = /obj/item/reagent_containers/food/snacks/spaghetti/beefnoodle
+ result = /obj/item/food/spaghetti/beefnoodle
subcategory = CAT_SPAGHETTI
/datum/crafting_recipe/food/chowmein
name = "Chowmein"
reqs = list(
- /obj/item/reagent_containers/food/snacks/spaghetti/boiledspaghetti = 1,
+ /obj/item/food/spaghetti/boiledspaghetti = 1,
/obj/item/reagent_containers/food/snacks/meat/cutlet = 1,
/obj/item/reagent_containers/food/snacks/grown/cabbage = 2,
/obj/item/reagent_containers/food/snacks/grown/carrot = 1
)
- result = /obj/item/reagent_containers/food/snacks/spaghetti/chowmein
+ result = /obj/item/food/spaghetti/chowmein
subcategory = CAT_SPAGHETTI
/datum/crafting_recipe/food/butternoodles
name = "Butter Noodles"
reqs = list(
- /obj/item/reagent_containers/food/snacks/spaghetti/boiledspaghetti = 1,
+ /obj/item/food/spaghetti/boiledspaghetti = 1,
/obj/item/reagent_containers/food/snacks/butter = 1
)
- result = /obj/item/reagent_containers/food/snacks/spaghetti/butternoodles
+ result = /obj/item/food/spaghetti/butternoodles
subcategory = CAT_SPAGHETTI
diff --git a/code/modules/holiday/easter.dm b/code/modules/holiday/easter.dm
index 9d88d3107551..2e40c8ed04c6 100644
--- a/code/modules/holiday/easter.dm
+++ b/code/modules/holiday/easter.dm
@@ -174,36 +174,12 @@
/datum/crafting_recipe/food/hotcrossbun
name = "Hot-Cross Bun"
reqs = list(
- /obj/item/reagent_containers/food/snacks/store/bread/plain = 1,
+ /obj/item/food/bread/plain = 1,
/datum/reagent/consumable/sugar = 1
)
result = /obj/item/reagent_containers/food/snacks/hotcrossbun
subcategory = CAT_MISCFOOD
-
-/obj/item/reagent_containers/food/snacks/store/cake/brioche
- name = "brioche cake"
- desc = "A ring of sweet, glazed buns."
- icon_state = "briochecake"
- slice_path = /obj/item/reagent_containers/food/snacks/cakeslice/brioche
- slices_num = 6
- bonus_reagents = list(/datum/reagent/consumable/nutriment = 10, /datum/reagent/consumable/nutriment/vitamin = 2)
-
-/obj/item/reagent_containers/food/snacks/cakeslice/brioche
- name = "brioche cake slice"
- desc = "Delicious sweet-bread. Who needs anything else?"
- icon_state = "briochecake_slice"
- filling_color = "#FFD700"
-
-/datum/crafting_recipe/food/briochecake
- name = "Brioche cake"
- reqs = list(
- /obj/item/reagent_containers/food/snacks/store/cake/plain = 1,
- /datum/reagent/consumable/sugar = 2
- )
- result = /obj/item/reagent_containers/food/snacks/store/cake/brioche
- subcategory = CAT_MISCFOOD
-
/obj/item/reagent_containers/food/snacks/scotchegg
name = "scotch egg"
desc = "A boiled egg wrapped in a delicious, seasoned meatball."
@@ -234,7 +210,7 @@
/datum/crafting_recipe/food/mammi
name = "Mammi"
reqs = list(
- /obj/item/reagent_containers/food/snacks/store/bread/plain = 1,
+ /obj/item/food/bread/plain = 1,
/obj/item/reagent_containers/food/snacks/chocolatebar = 1,
/datum/reagent/consumable/milk = 5
)
diff --git a/code/modules/mapping/mapping_helpers.dm b/code/modules/mapping/mapping_helpers.dm
index e9ac7662edab..2040764eefb9 100644
--- a/code/modules/mapping/mapping_helpers.dm
+++ b/code/modules/mapping/mapping_helpers.dm
@@ -281,7 +281,7 @@ INITIALIZE_IMMEDIATE(/obj/effect/mapping_helpers/no_lava)
if(length(table))
var/turf/food_turf = get_turf(pick(table))
new /obj/item/kitchen/knife(food_turf)
- var/obj/item/reagent_containers/food/snacks/store/cake/birthday/iancake = new(food_turf)
+ var/obj/item/food/cake/birthday/iancake = new(food_turf)
iancake.desc = "Happy birthday, Ian!"
//some balloons! this picks an open turf and pops a few balloons in and around that turf, yay.
diff --git a/code/modules/mob/living/simple_animal/friendly/cat.dm b/code/modules/mob/living/simple_animal/friendly/cat.dm
index 1916a7c52adb..646a3eb8436b 100644
--- a/code/modules/mob/living/simple_animal/friendly/cat.dm
+++ b/code/modules/mob/living/simple_animal/friendly/cat.dm
@@ -270,7 +270,7 @@
maxHealth = 50
gender = FEMALE
harm_intent_damage = 10
- butcher_results = list(/obj/item/organ/brain = 1, /obj/item/organ/heart = 1, /obj/item/reagent_containers/food/snacks/cakeslice/birthday = 3, \
+ butcher_results = list(/obj/item/organ/brain = 1, /obj/item/organ/heart = 1, /obj/item/food/cakeslice/birthday = 3, \
/obj/item/reagent_containers/food/snacks/meat/slab = 2)
response_harm_continuous = "takes a bite out of"
response_harm_simple = "take a bite out of"
diff --git a/code/modules/paperwork/fax.dm b/code/modules/paperwork/fax.dm
index bce7a3f322c5..0bf0a3eb51d3 100644
--- a/code/modules/paperwork/fax.dm
+++ b/code/modules/paperwork/fax.dm
@@ -36,7 +36,7 @@
/// List of types which should be allowed to be faxed if hacked
var/static/list/exotic_types = list(
/obj/item/reagent_containers/food/snacks/pizzaslice,
- /obj/item/reagent_containers/food/snacks/breadslice,
+ /obj/item/food/breadslice,
/obj/item/reagent_containers/food/snacks/donkpocket,
/obj/item/reagent_containers/food/snacks/cookie,
/obj/item/reagent_containers/food/snacks/salami,
diff --git a/code/modules/reagents/chemistry/reagents/food_reagents.dm b/code/modules/reagents/chemistry/reagents/food_reagents.dm
index 7c2b3f62099f..b78fd6aa8198 100644
--- a/code/modules/reagents/chemistry/reagents/food_reagents.dm
+++ b/code/modules/reagents/chemistry/reagents/food_reagents.dm
@@ -113,9 +113,9 @@
/datum/reagent/consumable/cooking_oil/expose_obj(obj/O, reac_volume)
if(holder && holder.chem_temp >= fry_temperature)
- if(isitem(O) && !istype(O, /obj/item/reagent_containers/food/snacks/deepfryholder))
+ if(isitem(O) && !istype(O, /obj/item/food/deepfryholder))
O.loc.visible_message("[O] rapidly fries as it's splashed with hot oil! Somehow.")
- var/obj/item/reagent_containers/food/snacks/deepfryholder/F = new(O.drop_location(), O)
+ var/obj/item/food/deepfryholder/F = new(O.drop_location(), O)
F.fry(volume)
F.reagents.add_reagent(/datum/reagent/consumable/cooking_oil, reac_volume)
diff --git a/code/modules/reagents/chemistry/recipes/slime_extracts.dm b/code/modules/reagents/chemistry/recipes/slime_extracts.dm
index d3bf1e211290..7429db4c1dec 100644
--- a/code/modules/reagents/chemistry/recipes/slime_extracts.dm
+++ b/code/modules/reagents/chemistry/recipes/slime_extracts.dm
@@ -139,7 +139,7 @@
var/chosen = getbork()
var/obj/B = new chosen(T)
if(prob(5))//Fry it!
- var/obj/item/reagent_containers/food/snacks/deepfryholder/fried
+ var/obj/item/food/deepfryholder/fried
fried = new(T, B)
fried.fry() // actually set the name and colour it
B = fried
diff --git a/code/modules/research/xenobiology/crossbreeding/charged.dm b/code/modules/research/xenobiology/crossbreeding/charged.dm
index 25aa79302918..f01b148d4d5e 100644
--- a/code/modules/research/xenobiology/crossbreeding/charged.dm
+++ b/code/modules/research/xenobiology/crossbreeding/charged.dm
@@ -107,7 +107,7 @@ Charged extracts:
effect_desc = "Creates a slime cake and some drinks."
/obj/item/slimecross/charged/silver/do_effect(mob/user)
- new /obj/item/reagent_containers/food/snacks/store/cake/slimecake(get_turf(user))
+ new /obj/item/food/cake/slimecake(get_turf(user))
for(var/i in 1 to 10)
var/drink_type = get_random_drink()
new drink_type(get_turf(user))
diff --git a/code/modules/surgery/organs/heart.dm b/code/modules/surgery/organs/heart.dm
index 26b93d2c4642..6ba9ce69d700 100644
--- a/code/modules/surgery/organs/heart.dm
+++ b/code/modules/surgery/organs/heart.dm
@@ -55,7 +55,7 @@
update_appearance()
return 1
-/obj/item/organ/heart/OnEatFrom(eater, feeder)
+/obj/item/organ/heart/on_eat_from(eater, feeder)
. = ..()
beating = FALSE
update_appearance()
diff --git a/code/modules/surgery/organs/organ_internal.dm b/code/modules/surgery/organs/organ_internal.dm
index b8871b21524e..72b7fba9d2da 100644
--- a/code/modules/surgery/organs/organ_internal.dm
+++ b/code/modules/surgery/organs/organ_internal.dm
@@ -38,7 +38,14 @@
/obj/item/organ/Initialize()
. = ..()
if(organ_flags & ORGAN_EDIBLE)
- AddComponent(/datum/component/edible, food_reagents, null, RAW | MEAT | GORE, null, 10, null, null, null, COLOR_PINK, CALLBACK(src, PROC_REF(OnEatFrom)))
+ AddComponent(/datum/component/edible,\
+ initial_reagents = food_reagents,\
+ foodtypes = RAW | MEAT | GORE,\
+ volume = 10,\
+ filling_color = COLOR_PINK,\
+ pre_eat = CALLBACK(src, PROC_REF(pre_eat)),\
+ on_compost = CALLBACK(src, PROC_REF(pre_compost)),\
+ after_eat = CALLBACK(src, PROC_REF(on_eat_from)))
///When you take a bite you cant jam it in for surgery anymore.
/obj/item/organ/proc/Insert(mob/living/carbon/M, special = 0, drop_if_replaced = TRUE)
@@ -133,8 +140,21 @@
STOP_PROCESSING(SSobj, src)
return ..()
-/obj/item/organ/proc/OnEatFrom(eater, feeder)
- useable = FALSE //You can't use it anymore after eating it you spaztic
+// Put any "can we eat this" checks for edible organs here
+/obj/item/organ/proc/pre_eat(eater, feeder)
+ if(iscarbon(eater))
+ var/mob/living/carbon/target = eater
+ for(var/S in target.surgeries)
+ var/datum/surgery/surgery = S
+ if(surgery.location == zone)
+ return FALSE
+ return TRUE
+
+/obj/item/organ/proc/pre_compost(user)
+ return TRUE
+
+/obj/item/organ/proc/on_eat_from(eater, feeder)
+ useable = FALSE //You bit it, no more using it
/obj/item/organ/item_action_slot_check(slot,mob/user)
return //so we don't grant the organ's action to mobs who pick up the organ.
diff --git a/code/modules/unit_tests/create_and_destroy.dm b/code/modules/unit_tests/create_and_destroy.dm
index 017356d9152a..9aee2ca10624 100644
--- a/code/modules/unit_tests/create_and_destroy.dm
+++ b/code/modules/unit_tests/create_and_destroy.dm
@@ -72,7 +72,7 @@
ignore += typesof(/obj/effect/pod_landingzone_effect)
ignore += typesof(/obj/effect/pod_landingzone)
//These want fried food to take on the shape of, we can't pass that in
- ignore += typesof(/obj/item/reagent_containers/food/snacks/deepfryholder)
+ ignore += typesof(/obj/item/food/deepfryholder)
//Can't pass in a thing to glow
ignore += typesof(/obj/effect/abstract/eye_lighting)
//It wants a lot more context then we have
diff --git a/code/modules/unit_tests/serving_tray.dm b/code/modules/unit_tests/serving_tray.dm
index 9bd487ba68a8..b4dc1f77a520 100644
--- a/code/modules/unit_tests/serving_tray.dm
+++ b/code/modules/unit_tests/serving_tray.dm
@@ -6,7 +6,7 @@
var/obj/structure/table/the_table = allocate(/obj/structure/table)
var/obj/item/storage/bag/tray/test_tray = allocate(/obj/item/storage/bag/tray)
var/obj/item/reagent_containers/food/banana = allocate(/obj/item/reagent_containers/food/snacks/grown/banana)
- var/obj/item/reagent_containers/food/the_bread = allocate(/obj/item/reagent_containers/food/snacks/breadslice)
+ var/obj/item/reagent_containers/food/the_bread = allocate(/obj/item/food/breadslice)
var/obj/item/reagent_containers/food/sugarcookie = allocate(/obj/item/reagent_containers/food/snacks/sugarcookie)
var/obj/item/clothing/under/jumpsuit = allocate(/obj/item/clothing/under/color/black)
diff --git a/code/modules/vending/sustenance.dm b/code/modules/vending/sustenance.dm
index 0519285d26a5..0677a77edb58 100644
--- a/code/modules/vending/sustenance.dm
+++ b/code/modules/vending/sustenance.dm
@@ -7,7 +7,7 @@
icon_state = "sustenance"
products = list(
/obj/item/reagent_containers/food/snacks/tofu/prison = 24,
- /obj/item/reagent_containers/food/snacks/breadslice/moldy = 15,
+ /obj/item/food/breadslice/moldy = 15,
/obj/item/reagent_containers/food/drinks/ice/prison = 12,
/obj/item/reagent_containers/food/snacks/candy_corn/prison = 6)
contraband = list(
diff --git a/config/admins.txt b/config/admins.txt
index b695c94f084b..24f777f26b19 100644
--- a/config/admins.txt
+++ b/config/admins.txt
@@ -5,5 +5,6 @@
#If SQL-based admin loading is enabled, admins listed here will always be loaded first and will override any duplicate entries in the database.
MarkSuckerberg = Development Head
+rkz = Development Head
#just use the database, this is deprecated
diff --git a/shiptest.dme b/shiptest.dme
index c0d9a7d4df66..3c2c0f334380 100644
--- a/shiptest.dme
+++ b/shiptest.dme
@@ -108,6 +108,7 @@
#include "code\__DEFINES\plumbing.dm"
#include "code\__DEFINES\power.dm"
#include "code\__DEFINES\preferences.dm"
+#include "code\__DEFINES\processing.dm"
#include "code\__DEFINES\procpath.dm"
#include "code\__DEFINES\profile.dm"
#include "code\__DEFINES\projectiles.dm"
@@ -155,7 +156,16 @@
#include "code\__DEFINES\wires.dm"
#include "code\__DEFINES\dcs\flags.dm"
#include "code\__DEFINES\dcs\helpers.dm"
-#include "code\__DEFINES\dcs\signals.dm"
+#include "code\__DEFINES\dcs\signals\signals.dm"
+#include "code\__DEFINES\dcs\signals\signals_obj\signals_object.dm"
+#include "code\__DEFINES\dcs\signals\signals_obj\signals_item\signals_clothing.dm"
+#include "code\__DEFINES\dcs\signals\signals_obj\signals_item\signals_food.dm"
+#include "code\__DEFINES\dcs\signals\signals_obj\signals_item\signals_grenade.dm"
+#include "code\__DEFINES\dcs\signals\signals_obj\signals_item\signals_implant.dm"
+#include "code\__DEFINES\dcs\signals\signals_obj\signals_item\signals_item.dm"
+#include "code\__DEFINES\dcs\signals\signals_obj\signals_machine\signals_aquarium.dm"
+#include "code\__DEFINES\dcs\signals\signals_obj\signals_machine\signals_machinery.dm"
+#include "code\__DEFINES\dcs\signals\signals_obj\signals_machine\signals_supermatter.dm"
#include "code\__HELPERS\_auxtools_api.dm"
#include "code\__HELPERS\_lists.dm"
#include "code\__HELPERS\_logging.dm"
@@ -480,7 +490,6 @@
#include "code\datums\components\deployable.dm"
#include "code\datums\components\dooropendeathproc.dm"
#include "code\datums\components\earprotection.dm"
-#include "code\datums\components\edible.dm"
#include "code\datums\components\edit_complainer.dm"
#include "code\datums\components\embedded.dm"
#include "code\datums\components\empprotection.dm"
@@ -558,6 +567,8 @@
#include "code\datums\components\fantasy\affix.dm"
#include "code\datums\components\fantasy\prefixes.dm"
#include "code\datums\components\fantasy\suffixes.dm"
+#include "code\datums\components\food\edible.dm"
+#include "code\datums\components\food\food_storage.dm"
#include "code\datums\components\plumbing\_plumbing.dm"
#include "code\datums\components\plumbing\chemical_acclimator.dm"
#include "code\datums\components\plumbing\filter.dm"
@@ -640,7 +651,6 @@
#include "code\datums\elements\cleaning.dm"
#include "code\datums\elements\connect_loc.dm"
#include "code\datums\elements\digitalcamo.dm"
-#include "code\datums\elements\dunkable.dm"
#include "code\datums\elements\earhealing.dm"
#include "code\datums\elements\embed.dm"
#include "code\datums\elements\firestacker.dm"
@@ -661,6 +671,9 @@
#include "code\datums\elements\world_icon.dm"
#include "code\datums\elements\decals\_decals.dm"
#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\processable.dm"
#include "code\datums\helper_datums\events.dm"
#include "code\datums\helper_datums\getrev.dm"
#include "code\datums\helper_datums\icon_snapshot.dm"
@@ -1252,6 +1265,10 @@
#include "code\game\objects\items\devices\radio\headset.dm"
#include "code\game\objects\items\devices\radio\intercom.dm"
#include "code\game\objects\items\devices\radio\radio.dm"
+#include "code\game\objects\items\food\_food.dm"
+#include "code\game\objects\items\food\bread.dm"
+#include "code\game\objects\items\food\cake.dm"
+#include "code\game\objects\items\food\spaghetti.dm"
#include "code\game\objects\items\grenades\antigravity.dm"
#include "code\game\objects\items\grenades\chem_grenade.dm"
#include "code\game\objects\items\grenades\clusterbuster.dm"
@@ -2177,9 +2194,7 @@
#include "code\modules\food_and_drinks\food\customizables.dm"
#include "code\modules\food_and_drinks\food\ration.dm"
#include "code\modules\food_and_drinks\food\snacks.dm"
-#include "code\modules\food_and_drinks\food\snacks_bread.dm"
#include "code\modules\food_and_drinks\food\snacks_burgers.dm"
-#include "code\modules\food_and_drinks\food\snacks_cake.dm"
#include "code\modules\food_and_drinks\food\snacks_egg.dm"
#include "code\modules\food_and_drinks\food\snacks_frozen.dm"
#include "code\modules\food_and_drinks\food\snacks_meat.dm"
@@ -2190,7 +2205,6 @@
#include "code\modules\food_and_drinks\food\snacks_salad.dm"
#include "code\modules\food_and_drinks\food\snacks_sandwichtoast.dm"
#include "code\modules\food_and_drinks\food\snacks_soup.dm"
-#include "code\modules\food_and_drinks\food\snacks_spaghetti.dm"
#include "code\modules\food_and_drinks\food\snacks_vend.dm"
#include "code\modules\food_and_drinks\food\snacks\dough.dm"
#include "code\modules\food_and_drinks\food\snacks\meat.dm"
diff --git a/tools/UpdatePaths/Scripts/17256_NEWFOOD_cakebreadnoodle.txt b/tools/UpdatePaths/Scripts/17256_NEWFOOD_cakebreadnoodle.txt
new file mode 100644
index 000000000000..b8cec913eef2
--- /dev/null
+++ b/tools/UpdatePaths/Scripts/17256_NEWFOOD_cakebreadnoodle.txt
@@ -0,0 +1,22 @@
+/obj/item/food/bread : /obj/item/food/bread/plain{@OLD}
+/obj/item/food/bread/@SUBTYPES : /obj/item/food/bread/@SUBTYPES{@OLD}
+/obj/item/food/breadslice : /obj/item/food/breadslice/plain{@OLD}
+/obj/item/food/breadslice/@SUBTYPES : /obj/item/food/breadslice/@SUBTYPES{@OLD}
+/obj/item/food/cake : /obj/item/food/cake/plain{@OLD}
+/obj/item/food/cake/@SUBTYPES : /obj/item/food/cake/@SUBTYPES{@OLD}
+/obj/item/food/cakeslice : /obj/item/food/cakeslice/plain{@OLD}
+/obj/item/food/cakeslice/@SUBTYPES : /obj/item/food/cakeslice/@SUBTYPES{@OLD}
+
+/obj/item/reagent_containers/food/snacks/cherrycupcake/blue : /obj/item/reagent_containers/food/snacks/cherrycupcake/blue{@OLD}
+
+/obj/item/food/spaghetti : /obj/item/food/spaghetti/raw{@OLD}
+/obj/item/food/spaghetti/@SUBTYPES : /obj/item/food/spaghetti/@SUBTYPES{@OLD}
+
+/obj/item/food/garlicbread : /obj/item/food/garlicbread{@OLD}
+/obj/item/food/butterbiscuit : /obj/item/food/butterbiscuit{@OLD}
+/obj/item/food/butterdog : /obj/item/food/butterdog{@OLD}
+
+/obj/item/food/baguette : /obj/item/food/baguette{@OLD}
+/obj/item/food/baguette/@SUBTYPES : /obj/item/food/baguette/@SUBTYPES{@OLD}
+
+/obj/item/food/deepfryholder : /obj/item/food/deepfryholder{@OLD}