diff --git a/_maps/RandomRuins/IceRuins/icemoon_underground_abandoned_homestead.dmm b/_maps/RandomRuins/IceRuins/icemoon_underground_abandoned_homestead.dmm
index 2972bf7ae84..46985529cc5 100644
--- a/_maps/RandomRuins/IceRuins/icemoon_underground_abandoned_homestead.dmm
+++ b/_maps/RandomRuins/IceRuins/icemoon_underground_abandoned_homestead.dmm
@@ -132,10 +132,7 @@
pixel_x = -8;
pixel_y = 13
},
-/obj/item/food/soup/stew{
- name = "porridge";
- pixel_y = 3
- },
+/obj/item/reagent_containers/cup/bowl/soup/stew,
/turf/open/floor/wood/large{
initial_gas_mix = "ICEMOON_ATMOS"
},
diff --git a/_maps/RandomRuins/LavaRuins/lavaland_biodome_beach.dmm b/_maps/RandomRuins/LavaRuins/lavaland_biodome_beach.dmm
index 751ea8edbaf..51a1e26b898 100644
--- a/_maps/RandomRuins/LavaRuins/lavaland_biodome_beach.dmm
+++ b/_maps/RandomRuins/LavaRuins/lavaland_biodome_beach.dmm
@@ -3,7 +3,7 @@
/turf/template_noop,
/area/template_noop)
"ad" = (
-/obj/machinery/oven,
+/obj/machinery/oven/range,
/turf/open/floor/wood,
/area/ruin/powered/beach)
"aj" = (
diff --git a/_maps/RandomRuins/SpaceRuins/DJstation/kitchen_4.dmm b/_maps/RandomRuins/SpaceRuins/DJstation/kitchen_4.dmm
index 597111c9c76..c7f5d9d5718 100644
--- a/_maps/RandomRuins/SpaceRuins/DJstation/kitchen_4.dmm
+++ b/_maps/RandomRuins/SpaceRuins/DJstation/kitchen_4.dmm
@@ -55,7 +55,7 @@
/turf/closed/wall,
/area/ruin/space/djstation)
"z" = (
-/obj/machinery/oven,
+/obj/machinery/oven/range,
/turf/open/floor/iron/white,
/area/ruin/space/djstation)
"A" = (
diff --git a/_maps/RandomRuins/SpaceRuins/deepstorage.dmm b/_maps/RandomRuins/SpaceRuins/deepstorage.dmm
index 0fda79ab8d6..c89703ae007 100644
--- a/_maps/RandomRuins/SpaceRuins/deepstorage.dmm
+++ b/_maps/RandomRuins/SpaceRuins/deepstorage.dmm
@@ -384,7 +384,7 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4{
dir = 9
},
-/obj/machinery/oven,
+/obj/machinery/oven/range,
/turf/open/floor/iron/cafeteria,
/area/ruin/space/has_grav/deepstorage/kitchen)
"bb" = (
diff --git a/_maps/RandomRuins/SpaceRuins/oldstation.dmm b/_maps/RandomRuins/SpaceRuins/oldstation.dmm
index fdc22f91a4d..6d4b8e71fd8 100644
--- a/_maps/RandomRuins/SpaceRuins/oldstation.dmm
+++ b/_maps/RandomRuins/SpaceRuins/oldstation.dmm
@@ -7012,7 +7012,7 @@
/area/ruin/space/ancientstation/beta/mining)
"Kv" = (
/obj/effect/decal/cleanable/dirt,
-/obj/machinery/oven,
+/obj/machinery/oven/range,
/turf/open/floor/iron/cafeteria,
/area/ruin/space/ancientstation/charlie/kitchen)
"Kw" = (
diff --git a/_maps/RandomRuins/SpaceRuins/spacehotel.dmm b/_maps/RandomRuins/SpaceRuins/spacehotel.dmm
index 9f370c70cea..ba39055ecde 100644
--- a/_maps/RandomRuins/SpaceRuins/spacehotel.dmm
+++ b/_maps/RandomRuins/SpaceRuins/spacehotel.dmm
@@ -4028,7 +4028,7 @@
},
/area/ruin/space/has_grav/hotel/workroom)
"Tm" = (
-/obj/machinery/oven,
+/obj/machinery/oven/range,
/obj/structure/sign/warning/no_smoking/circle/directional/north,
/obj/machinery/camera/directional/north{
c_tag = "Kitchen";
diff --git a/_maps/RandomRuins/SpaceRuins/waystation.dmm b/_maps/RandomRuins/SpaceRuins/waystation.dmm
index 9b879b4b362..b88995e4949 100644
--- a/_maps/RandomRuins/SpaceRuins/waystation.dmm
+++ b/_maps/RandomRuins/SpaceRuins/waystation.dmm
@@ -1773,7 +1773,7 @@
/turf/open/floor/iron/grimy,
/area/ruin/space/has_grav/waystation/qm)
"Ga" = (
-/obj/machinery/oven,
+/obj/machinery/oven/range,
/obj/machinery/light/small/directional/north,
/obj/effect/decal/cleanable/dirt,
/turf/open/floor/iron/cafeteria,
diff --git a/_maps/RandomZLevels/SnowCabin.dmm b/_maps/RandomZLevels/SnowCabin.dmm
index 7821d686618..afd6074d2e1 100644
--- a/_maps/RandomZLevels/SnowCabin.dmm
+++ b/_maps/RandomZLevels/SnowCabin.dmm
@@ -454,8 +454,7 @@
/turf/open/floor/iron/cafeteria,
/area/awaymission/cabin)
"by" = (
-/obj/machinery/oven,
-/obj/item/plate/oven_tray,
+/obj/machinery/oven/range,
/turf/open/floor/iron/cafeteria,
/area/awaymission/cabin)
"bz" = (
diff --git a/_maps/RandomZLevels/TheBeach.dmm b/_maps/RandomZLevels/TheBeach.dmm
index b4018912d3a..1e8ac374713 100644
--- a/_maps/RandomZLevels/TheBeach.dmm
+++ b/_maps/RandomZLevels/TheBeach.dmm
@@ -1109,7 +1109,7 @@
/turf/open/floor/wood,
/area/awaymission/beach)
"Jr" = (
-/obj/machinery/oven,
+/obj/machinery/oven/range,
/turf/open/floor/wood,
/area/awaymission/beach)
"Kg" = (
diff --git a/_maps/RandomZLevels/undergroundoutpost45.dmm b/_maps/RandomZLevels/undergroundoutpost45.dmm
index c805b992823..aa8c6ab593e 100644
--- a/_maps/RandomZLevels/undergroundoutpost45.dmm
+++ b/_maps/RandomZLevels/undergroundoutpost45.dmm
@@ -10649,7 +10649,7 @@
},
/area/awaymission/undergroundoutpost45/caves)
"Ar" = (
-/obj/machinery/oven,
+/obj/machinery/oven/range,
/turf/open/floor/iron/cafeteria{
dir = 5;
heat_capacity = 1e+006
diff --git a/_maps/map_files/Deltastation/DeltaStation2.dmm b/_maps/map_files/Deltastation/DeltaStation2.dmm
index edad165ffc9..e9df241846a 100644
--- a/_maps/map_files/Deltastation/DeltaStation2.dmm
+++ b/_maps/map_files/Deltastation/DeltaStation2.dmm
@@ -55743,7 +55743,7 @@
/turf/open/floor/iron/white,
/area/station/medical/cryo)
"nPA" = (
-/obj/machinery/oven,
+/obj/machinery/oven/range,
/turf/open/floor/iron/cafeteria,
/area/station/service/kitchen)
"nPF" = (
@@ -64628,7 +64628,7 @@
/obj/machinery/light_switch/directional/north{
pixel_x = 8
},
-/obj/machinery/oven,
+/obj/machinery/oven/range,
/turf/open/floor/plating,
/area/station/service/kitchen/abandoned)
"qbW" = (
diff --git a/_maps/map_files/IceBoxStation/IceBoxStation.dmm b/_maps/map_files/IceBoxStation/IceBoxStation.dmm
index c7e1aa2b8a4..bbdd9e5b676 100644
--- a/_maps/map_files/IceBoxStation/IceBoxStation.dmm
+++ b/_maps/map_files/IceBoxStation/IceBoxStation.dmm
@@ -4956,7 +4956,7 @@
/area/station/security/prison/workout)
"bDe" = (
/obj/effect/turf_decal/tile/neutral/diagonal_edge,
-/obj/machinery/oven,
+/obj/machinery/oven/range,
/turf/open/floor/iron/kitchen/diagonal,
/area/station/service/kitchen)
"bDj" = (
@@ -26020,6 +26020,7 @@
pixel_x = 3
},
/obj/effect/spawner/random/food_or_drink/cake_ingredients,
+/obj/item/food/piedough,
/turf/open/floor/iron/kitchen/diagonal,
/area/station/service/kitchen)
"iot" = (
@@ -30310,7 +30311,7 @@
/turf/open/openspace/icemoon,
/area/station/science/server)
"jIW" = (
-/obj/machinery/oven,
+/obj/machinery/oven/range,
/turf/open/floor/plating,
/area/station/maintenance/port/aft)
"jIX" = (
@@ -36974,12 +36975,6 @@
/obj/effect/decal/cleanable/dirt,
/turf/open/floor/iron,
/area/mine/laborcamp)
-"lLO" = (
-/obj/effect/turf_decal/tile/neutral/diagonal_edge,
-/obj/structure/table,
-/obj/item/food/piedough,
-/turf/open/floor/iron/kitchen/diagonal,
-/area/station/service/kitchen)
"lLY" = (
/obj/effect/decal/cleanable/dirt,
/turf/open/floor/iron/recharge_floor,
@@ -54591,7 +54586,7 @@
/turf/open/floor/iron/dark/textured_half,
/area/mine/mechbay)
"rmD" = (
-/obj/machinery/oven,
+/obj/machinery/oven/range,
/turf/open/floor/iron/cafeteria,
/area/station/security/prison/mess)
"rmM" = (
@@ -246809,7 +246804,7 @@ xlv
iXH
qZB
oEh
-lLO
+bDe
kvs
qfe
ecZ
diff --git a/_maps/map_files/KiloStation/KiloStation.dmm b/_maps/map_files/KiloStation/KiloStation.dmm
index 49ed7d0c762..7d35896e310 100644
--- a/_maps/map_files/KiloStation/KiloStation.dmm
+++ b/_maps/map_files/KiloStation/KiloStation.dmm
@@ -4240,12 +4240,12 @@
/turf/open/floor/iron/showroomfloor,
/area/station/medical/exam_room)
"buD" = (
-/obj/machinery/griddle,
/obj/effect/turf_decal/bot,
/obj/machinery/newscaster/directional/north,
/obj/effect/turf_decal/tile/neutral/half/contrasted{
dir = 1
},
+/obj/machinery/oven/range,
/turf/open/floor/iron/dark,
/area/station/service/kitchen)
"buJ" = (
@@ -14891,11 +14891,11 @@
/turf/open/floor/plating,
/area/station/maintenance/port/fore)
"fby" = (
-/obj/machinery/oven,
/obj/effect/turf_decal/bot,
/obj/effect/turf_decal/tile/neutral/half/contrasted{
dir = 1
},
+/obj/machinery/oven/range,
/turf/open/floor/iron/dark,
/area/station/service/kitchen)
"fbz" = (
@@ -56258,12 +56258,12 @@
/turf/open/floor/iron/dark,
/area/station/medical/medbay/central)
"srk" = (
-/obj/machinery/deepfryer,
/obj/effect/turf_decal/bot,
/obj/structure/sign/poster/random/directional/north,
/obj/effect/turf_decal/tile/neutral/half/contrasted{
dir = 1
},
+/obj/machinery/griddle,
/turf/open/floor/iron/dark,
/area/station/service/kitchen)
"srs" = (
diff --git a/_maps/map_files/MetaStation/MetaStation.dmm b/_maps/map_files/MetaStation/MetaStation.dmm
index ddd27f5039e..387c609ca89 100644
--- a/_maps/map_files/MetaStation/MetaStation.dmm
+++ b/_maps/map_files/MetaStation/MetaStation.dmm
@@ -7033,7 +7033,7 @@
/turf/open/floor/iron/dark,
/area/station/engineering/atmos)
"cFe" = (
-/obj/machinery/oven,
+/obj/machinery/oven/range,
/turf/open/floor/iron/cafeteria,
/area/station/service/kitchen)
"cFp" = (
diff --git a/_maps/map_files/VoidRaptor/VoidRaptor.dmm b/_maps/map_files/VoidRaptor/VoidRaptor.dmm
index 3d015ce2de2..a9e6430e75c 100644
--- a/_maps/map_files/VoidRaptor/VoidRaptor.dmm
+++ b/_maps/map_files/VoidRaptor/VoidRaptor.dmm
@@ -65598,8 +65598,8 @@
/area/station/command/heads_quarters/ce)
"sxW" = (
/obj/structure/disposalpipe/segment,
-/obj/machinery/oven,
/obj/effect/turf_decal/bot,
+/obj/machinery/oven/range,
/turf/open/floor/iron/kitchen,
/area/station/service/kitchen)
"syd" = (
diff --git a/_maps/map_files/generic/CentCom_skyrat_z2.dmm b/_maps/map_files/generic/CentCom_skyrat_z2.dmm
index fc057752dee..f937fb7ad35 100644
--- a/_maps/map_files/generic/CentCom_skyrat_z2.dmm
+++ b/_maps/map_files/generic/CentCom_skyrat_z2.dmm
@@ -1298,7 +1298,7 @@
/turf/open/misc/dirt/planet,
/area/centcom/holding/cafepark)
"atq" = (
-/obj/machinery/oven,
+/obj/machinery/oven/range,
/turf/open/indestructible/hoteltile{
icon_state = "cafeteria"
},
@@ -3048,7 +3048,7 @@
/area/centcom/holding/cafedorms)
"aMI" = (
/obj/machinery/vending/hydronutrients{
- products = list(/obj/item/reagent_containers/cup/bottle/nutrient/ez = 50, /obj/item/reagent_containers/cup/bottle/nutrient/l4z = 20, /obj/item/reagent_containers/cup/bottle/nutrient/rh = 10, /obj/item/reagent_containers/spray/pestspray = 30, /obj/item/reagent_containers/syringe = 5, /obj/item/storage/bag/plants = 30, /obj/item/cultivator = 10, /obj/item/shovel/spade = 10, /obj/item/plant_analyzer = 10)
+ products = list(/obj/item/reagent_containers/cup/bottle/nutrient/ez=50,/obj/item/reagent_containers/cup/bottle/nutrient/l4z=20,/obj/item/reagent_containers/cup/bottle/nutrient/rh=10,/obj/item/reagent_containers/spray/pestspray=30,/obj/item/reagent_containers/syringe=5,/obj/item/storage/bag/plants=30,/obj/item/cultivator=10,/obj/item/shovel/spade=10,/obj/item/plant_analyzer=10)
},
/turf/open/indestructible/hoteltile{
icon_state = "darkfull"
@@ -3181,13 +3181,13 @@
/obj/item/storage/box/ingredients/american,
/obj/item/storage/box/ingredients/exotic,
/obj/item/reagent_containers/condiment/flour{
- list_reagents = list(/datum/reagent/consumable/flour = 90);
+ list_reagents = list(/datum/reagent/consumable/flour=90);
name = "large flour sack";
possible_transfer_amounts = list(1,5,10,15,30,60,90);
volume = 90
},
/obj/item/reagent_containers/condiment/flour{
- list_reagents = list(/datum/reagent/consumable/flour = 90);
+ list_reagents = list(/datum/reagent/consumable/flour=90);
name = "large flour sack";
possible_transfer_amounts = list(1,5,10,15,30,60,90);
volume = 90
@@ -6801,12 +6801,12 @@
/obj/item/reagent_containers/condiment/soysauce,
/obj/item/reagent_containers/condiment/sugar,
/obj/item/reagent_containers/condiment/rice{
- list_reagents = list(/datum/reagent/consumable/rice = 90);
+ list_reagents = list(/datum/reagent/consumable/rice=90);
name = "large rice sack";
possible_transfer_amounts = list(1,5,10,15,20,25,30,50,60,90)
},
/obj/item/reagent_containers/condiment/rice{
- list_reagents = list(/datum/reagent/consumable/rice = 90);
+ list_reagents = list(/datum/reagent/consumable/rice=90);
name = "large rice sack";
possible_transfer_amounts = list(1,5,10,15,20,25,30,50,60,90)
},
@@ -8708,7 +8708,7 @@
/turf/open/misc/grass/planet,
/area/centcom/holding/cafepark)
"lXo" = (
-/obj/machinery/oven,
+/obj/machinery/oven/range,
/turf/open/floor/wood,
/area/centcom/holding/cafe)
"mac" = (
@@ -9580,24 +9580,24 @@
/obj/item/storage/box/ingredients/american,
/obj/item/storage/box/ingredients/exotic,
/obj/item/reagent_containers/condiment/flour{
- list_reagents = list(/datum/reagent/consumable/flour = 90);
+ list_reagents = list(/datum/reagent/consumable/flour=90);
name = "large flour sack";
possible_transfer_amounts = list(1,5,10,15,30,60,90);
volume = 90
},
/obj/item/reagent_containers/condiment/flour{
- list_reagents = list(/datum/reagent/consumable/flour = 90);
+ list_reagents = list(/datum/reagent/consumable/flour=90);
name = "large flour sack";
possible_transfer_amounts = list(1,5,10,15,30,60,90);
volume = 90
},
/obj/item/reagent_containers/condiment/rice{
- list_reagents = list(/datum/reagent/consumable/rice = 90);
+ list_reagents = list(/datum/reagent/consumable/rice=90);
name = "large rice sack";
possible_transfer_amounts = list(1,5,10,15,20,25,30,50,60,90)
},
/obj/item/reagent_containers/condiment/rice{
- list_reagents = list(/datum/reagent/consumable/rice = 90);
+ list_reagents = list(/datum/reagent/consumable/rice=90);
name = "large rice sack";
possible_transfer_amounts = list(1,5,10,15,20,25,30,50,60,90)
},
@@ -10507,7 +10507,7 @@
/turf/open/floor/iron/dark/textured_large,
/area/cruiser_dock)
"qvk" = (
-/obj/machinery/oven,
+/obj/machinery/oven/range,
/turf/open/floor/iron/cafeteria,
/area/centcom/interlink)
"qwk" = (
diff --git a/_maps/map_files/tramstation/tramstation.dmm b/_maps/map_files/tramstation/tramstation.dmm
index d281f2483f3..f90ff1dab88 100644
--- a/_maps/map_files/tramstation/tramstation.dmm
+++ b/_maps/map_files/tramstation/tramstation.dmm
@@ -43951,7 +43951,7 @@
/turf/open/floor/catwalk_floor,
/area/station/maintenance/tram/mid)
"oCu" = (
-/obj/machinery/oven,
+/obj/machinery/oven/range,
/turf/open/floor/iron/white,
/area/station/commons/vacant_room)
"oCv" = (
@@ -58261,7 +58261,7 @@
/turf/open/floor/iron/white,
/area/station/medical/medbay/central)
"tJg" = (
-/obj/machinery/oven,
+/obj/machinery/oven/range,
/turf/open/floor/iron/white,
/area/station/service/kitchen)
"tJh" = (
diff --git a/_maps/shuttles/emergency_nature.dmm b/_maps/shuttles/emergency_nature.dmm
index a9080d727ad..26e74d66b30 100644
--- a/_maps/shuttles/emergency_nature.dmm
+++ b/_maps/shuttles/emergency_nature.dmm
@@ -379,7 +379,7 @@
dir = 5
},
/obj/structure/table/glass,
-/obj/item/food/soup/monkeysdelight{
+/obj/item/reagent_containers/cup/bowl/soup/monkey{
pixel_y = 4
},
/obj/item/reagent_containers/cup/soda_cans/monkey_energy{
diff --git a/_maps/templates/lazy_templates/ninja_den.dmm b/_maps/templates/lazy_templates/ninja_den.dmm
index 3b4ff7b14b1..25de2aa8ca6 100644
--- a/_maps/templates/lazy_templates/ninja_den.dmm
+++ b/_maps/templates/lazy_templates/ninja_den.dmm
@@ -1815,7 +1815,7 @@
},
/area/centcom/central_command_areas/holding)
"Rg" = (
-/obj/machinery/oven,
+/obj/machinery/oven/range,
/obj/machinery/light/directional/north,
/turf/open/floor/iron/cafeteria,
/area/centcom/central_command_areas/holding)
diff --git a/_maps/templates/lazy_templates/nukie_base.dmm b/_maps/templates/lazy_templates/nukie_base.dmm
index 4f3e9d1884e..87f592054f5 100644
--- a/_maps/templates/lazy_templates/nukie_base.dmm
+++ b/_maps/templates/lazy_templates/nukie_base.dmm
@@ -1144,7 +1144,7 @@
/turf/open/floor/mineral/plastitanium,
/area/centcom/syndicate_mothership/expansion_chemicalwarfare)
"nb" = (
-/obj/machinery/oven,
+/obj/machinery/oven/range,
/obj/structure/sign/poster/contraband/eat{
pixel_x = -32
},
diff --git a/code/__DEFINES/ai.dm b/code/__DEFINES/ai.dm
index 32ed1445b55..8a62039228e 100644
--- a/code/__DEFINES/ai.dm
+++ b/code/__DEFINES/ai.dm
@@ -125,13 +125,19 @@
#define BB_VENDING_BUSY_TILTING "BB_vending_busy_tilting"
#define BB_VENDING_LAST_HIT_SUCCESFUL "BB_vending_last_hit_succesful"
-///Robot customer AI controller blackboard keys
+//Robot customer AI controller blackboard keys
+/// Corresponds to the customer's order.
+/// This can be a an item typepath or an instance of a custom order datum
#define BB_CUSTOMER_CURRENT_ORDER "BB_customer_current_order"
#define BB_CUSTOMER_MY_SEAT "BB_customer_my_seat"
#define BB_CUSTOMER_PATIENCE "BB_customer_patience"
+/// A reference to a customer data datum, containing stuff like saylines and food desires
#define BB_CUSTOMER_CUSTOMERINFO "BB_customer_customerinfo"
+/// Whether we're busy eating something already
#define BB_CUSTOMER_EATING "BB_customer_eating"
+/// A reference to the venue being attended
#define BB_CUSTOMER_ATTENDING_VENUE "BB_customer_attending_avenue"
+/// Whether we're leaving the venue entirely, either happily or forced out
#define BB_CUSTOMER_LEAVING "BB_customer_leaving"
#define BB_CUSTOMER_CURRENT_TARGET "BB_customer_current_target"
/// Robot customer has said their can't find seat line at least once. Used to rate limit how often they'll complain after the first time.
diff --git a/code/__DEFINES/dcs/signals/signals_atom/signals_atom_main.dm b/code/__DEFINES/dcs/signals/signals_atom/signals_atom_main.dm
index d80e3084e52..062e5ef00dc 100644
--- a/code/__DEFINES/dcs/signals/signals_atom/signals_atom_main.dm
+++ b/code/__DEFINES/dcs/signals/signals_atom/signals_atom_main.dm
@@ -11,7 +11,12 @@
#define COMSIG_PARENT_EXAMINE "atom_examine"
///from base of atom/get_examine_name(): (/mob, list/overrides)
#define COMSIG_ATOM_GET_EXAMINE_NAME "atom_examine_name"
-#define COMSIG_PARENT_EXAMINE_MORE "atom_examine_more" ///from base of atom/examine_more(): (/mob)
+///from base of atom/examine(): (/mob, list/examine_text, can_see_inside)
+#define COMSIG_PARENT_REAGENT_EXAMINE "atom_reagent_examine"
+ /// Stop the generic reagent examine text
+ #define STOP_GENERIC_REAGENT_EXAMINE (1<<0)
+///from base of atom/examine_more(): (/mob)
+#define COMSIG_PARENT_EXAMINE_MORE "atom_examine_more"
//Positions for overrides list
#define EXAMINE_POSITION_ARTICLE (1<<0)
#define EXAMINE_POSITION_BEFORE (1<<1)
diff --git a/code/__DEFINES/dcs/signals/signals_object.dm b/code/__DEFINES/dcs/signals/signals_object.dm
index 3f0edab3f75..d21b80deee6 100644
--- a/code/__DEFINES/dcs/signals/signals_object.dm
+++ b/code/__DEFINES/dcs/signals/signals_object.dm
@@ -30,6 +30,8 @@
#define COMSIG_MACHINERY_START_PROCESSING_AIR "start_processing_air"
///from /datum/controller/subsystem/air/proc/stop_processing_machine: ()
#define COMSIG_MACHINERY_STOP_PROCESSING_AIR "stop_processing_air"
+///from /obj/machinery/RefreshParts: ()
+#define COMSIG_MACHINERY_REFRESH_PARTS "machine_refresh_parts"
///from /obj/machinery/can_interact(mob/user): Called on user when attempting to interact with a machine (obj/machinery/machine)
#define COMSIG_TRY_USE_MACHINE "try_use_machine"
diff --git a/code/__DEFINES/dcs/signals/signals_restaurant.dm b/code/__DEFINES/dcs/signals/signals_restaurant.dm
index 2a23262e887..a63fc5fdaad 100644
--- a/code/__DEFINES/dcs/signals/signals_restaurant.dm
+++ b/code/__DEFINES/dcs/signals/signals_restaurant.dm
@@ -6,3 +6,9 @@
///(customer, container) venue signal sent when a venue sells an item. source is the thing sold, which can be a datum, so we send container for location checks
#define COMSIG_ITEM_SOLD_TO_CUSTOMER "item_sold_to_customer"
+///(customer, container) venue signal sent when a venue sells an reagent. source is the thing sold, which can be a datum, so we send container for location checks
+#define COMSIG_REAGENT_SOLD_TO_CUSTOMER "reagent_sold_to_customer"
+ /// Return from either above signal to denote the transaction completed successfully, so the venue can finish processing it
+ #define TRANSACTION_SUCCESS (1<<0)
+ /// Return from either above to stop the venue default processing, allowing you to handle cleanup / aftermath yourself
+ #define TRANSACTION_HANDLED (1<<1)
diff --git a/code/__DEFINES/food.dm b/code/__DEFINES/food.dm
index f5c811b61a0..b6ba97ef312 100644
--- a/code/__DEFINES/food.dm
+++ b/code/__DEFINES/food.dm
@@ -182,6 +182,14 @@ DEFINE_BITFIELD(food_flags, list(
#define BLACKBOX_LOG_FOOD_MADE(food) SSblackbox.record_feedback("tally", "food_made", 1, food)
+/// Point water boils at
+#define WATER_BOILING_POINT (T0C + 100)
+/// Point at which soups begin to burn at
+#define SOUP_BURN_TEMP 540
+
+/// Serving size of soup. Plus or minus five units.
+#define SOUP_SERVING_SIZE 25
+
// Venues for the barbots.
#define VENUE_RESTAURANT "Restaurant Venue"
#define VENUE_BAR "Bar Venue"
diff --git a/code/__HELPERS/global_lists.dm b/code/__HELPERS/global_lists.dm
index c7de9f016d3..b82a86c91bf 100644
--- a/code/__HELPERS/global_lists.dm
+++ b/code/__HELPERS/global_lists.dm
@@ -164,44 +164,39 @@
/proc/init_crafting_recipes_atoms()
var/list/recipe_lists = list(
GLOB.crafting_recipes,
- GLOB.cooking_recipes
+ GLOB.cooking_recipes,
)
var/list/atom_lists = list(
GLOB.crafting_recipes_atoms,
- GLOB.cooking_recipes_atoms
+ GLOB.cooking_recipes_atoms,
)
- for(var/recipe_list in recipe_lists)
+ for(var/list_index in 1 to length(recipe_lists))
+ var/list/recipe_list = recipe_lists[list_index]
+ var/list/atom_list = atom_lists[list_index]
for(var/datum/crafting_recipe/recipe as anything in recipe_list)
- var/list_index = recipe_lists.Find(recipe_list)
// Result
- if(!(recipe.result in atom_lists[list_index]))
- atom_lists[list_index] += recipe.result
+ atom_list |= recipe.result
// Ingredients
for(var/atom/req_atom as anything in recipe.reqs)
- if(!(req_atom in atom_lists[list_index]))
- atom_lists[list_index] += req_atom
+ atom_list |= req_atom
// Catalysts
for(var/atom/req_atom as anything in recipe.chem_catalysts)
- if(!(req_atom in atom_lists[list_index]))
- atom_lists[list_index] += req_atom
+ atom_list |= req_atom
// Reaction data - required container
if(recipe.reaction)
var/required_container = initial(recipe.reaction.required_container)
- if(required_container && !(required_container in atom_lists[list_index]))
- atom_lists[list_index] += required_container
+ if(required_container)
+ atom_list |= required_container
// Tools
for(var/atom/req_atom as anything in recipe.tool_paths)
- if(!(req_atom in atom_lists[list_index]))
- atom_lists[list_index] += req_atom
+ atom_list |= req_atom
// Machinery
for(var/atom/req_atom as anything in recipe.machinery)
- if(!(req_atom in atom_lists[list_index]))
- atom_lists[list_index] += req_atom
+ atom_list |= req_atom
// Structures
for(var/atom/req_atom as anything in recipe.structures)
- if(!(req_atom in atom_lists[list_index]))
- atom_lists[list_index] += req_atom
+ atom_list |= req_atom
//creates every subtype of prototype (excluding prototype) and adds it to list L.
//if no list/L is provided, one is created.
diff --git a/code/__HELPERS/randoms.dm b/code/__HELPERS/randoms.dm
index ed542417377..de94471d7ff 100644
--- a/code/__HELPERS/randoms.dm
+++ b/code/__HELPERS/randoms.dm
@@ -4,28 +4,28 @@
if(!LAZYLEN(allowed_food)) //it's static so we only ever do this once
var/list/blocked = list(
- /obj/item/food/drug,
- /obj/item/food/spaghetti,
- /obj/item/food/bread,
- /obj/item/food/breadslice,
- /obj/item/food/cake,
- /obj/item/food/cakeslice,
- /obj/item/food/pie,
- /obj/item/food/pieslice,
- /obj/item/food/kebab,
- /obj/item/food/pizza,
- /obj/item/food/pizzaslice,
- /obj/item/food/salad,
- /obj/item/food/meat,
- /obj/item/food/meat/slab,
- /obj/item/food/soup,
- /obj/item/food/grown,
- /obj/item/food/grown/mushroom,
- /obj/item/food/clothing,
- /obj/item/food/meat/slab/human/mutant,
- /obj/item/food/grown/ash_flora,
- /obj/item/food/grown/nettle,
- /obj/item/food/grown/shell
+ /obj/item/food/bowled,
+ /obj/item/food/bread,
+ /obj/item/food/breadslice,
+ /obj/item/food/cake,
+ /obj/item/food/cakeslice,
+ /obj/item/food/clothing,
+ /obj/item/food/drug,
+ /obj/item/food/grown,
+ /obj/item/food/grown/ash_flora,
+ /obj/item/food/grown/mushroom,
+ /obj/item/food/grown/nettle,
+ /obj/item/food/grown/shell,
+ /obj/item/food/kebab,
+ /obj/item/food/meat,
+ /obj/item/food/meat/slab,
+ /obj/item/food/meat/slab/human/mutant,
+ /obj/item/food/pie,
+ /obj/item/food/pieslice,
+ /obj/item/food/pizza,
+ /obj/item/food/pizzaslice,
+ /obj/item/food/salad,
+ /obj/item/food/spaghetti,
)
var/list/unfiltered_allowed_food = subtypesof(/obj/item/food) - blocked
diff --git a/code/_globalvars/lists/objects.dm b/code/_globalvars/lists/objects.dm
index bee8a5c0184..6c9496108a3 100644
--- a/code/_globalvars/lists/objects.dm
+++ b/code/_globalvars/lists/objects.dm
@@ -26,10 +26,18 @@ GLOBAL_LIST(chemical_reactions_results_lookup_list) //List of all reactions with
GLOBAL_LIST(fake_reagent_blacklist) //List of all reagents that are parent types used to define a bunch of children - but aren't used themselves as anything.
GLOBAL_LIST_EMPTY(tech_list) //list of all /datum/tech datums indexed by id.
GLOBAL_LIST_EMPTY(surgeries_list) //list of all surgeries by name, associated with their path.
-GLOBAL_LIST_EMPTY(crafting_recipes) //list of all crafting recipes
-GLOBAL_LIST_EMPTY(crafting_recipes_atoms) //list of all atoms occuring in crafting recipes
-GLOBAL_LIST_EMPTY(cooking_recipes) //list of all cooking recipes
-GLOBAL_LIST_EMPTY(cooking_recipes_atoms) //list of all atoms occuring in cooking recipes
+
+/// Global list of all non-cooking related crafting recipes.
+GLOBAL_LIST_EMPTY(crafting_recipes)
+/// This is a global list of typepaths, these typepaths are atoms or reagents that are associated with crafting recipes.
+/// This includes stuff like recipe components and results.
+GLOBAL_LIST_EMPTY(crafting_recipes_atoms)
+/// Global list of all cooking related crafting recipes.
+GLOBAL_LIST_EMPTY(cooking_recipes)
+/// This is a global list of typepaths, these typepaths are atoms or reagents that are associated with cooking recipes.
+/// This includes stuff like recipe components and results.
+GLOBAL_LIST_EMPTY(cooking_recipes_atoms)
+
GLOBAL_LIST_EMPTY(rcd_list) //list of Rapid Construction Devices.
GLOBAL_LIST_EMPTY(intercoms_list) //list of wallmounted intercom radios.
GLOBAL_LIST_EMPTY(apcs_list) //list of all Area Power Controller machines, separate from machines for powernet speeeeeeed.
diff --git a/code/datums/ai/robot_customer/robot_customer_controller.dm b/code/datums/ai/robot_customer/robot_customer_controller.dm
index cf53c521b3a..ebbfe31fbed 100644
--- a/code/datums/ai/robot_customer/robot_customer_controller.dm
+++ b/code/datums/ai/robot_customer/robot_customer_controller.dm
@@ -35,9 +35,11 @@
SIGNAL_HANDLER
var/datum/venue/attending_venue = blackboard[BB_CUSTOMER_ATTENDING_VENUE]
if(attending_venue.is_correct_order(I, blackboard[BB_CUSTOMER_CURRENT_ORDER]))
- to_chat(user, span_notice("You hand [I] to [pawn]"))
+ to_chat(user, span_notice("You hand [I] to [pawn]."))
eat_order(I, attending_venue)
return COMPONENT_NO_AFTERATTACK
+ else if(!I.force)
+ INVOKE_ASYNC(src, PROC_REF(dont_want_that), I, user)
else
INVOKE_ASYNC(src, PROC_REF(warn_greytider), user)
@@ -46,13 +48,15 @@
INVOKE_ASYNC(src, PROC_REF(warn_greytider), attacker)
/datum/ai_controller/robot_customer/proc/eat_order(obj/item/order_item, datum/venue/attending_venue)
- if(!blackboard[BB_CUSTOMER_EATING])
- blackboard[BB_CUSTOMER_EATING] = TRUE
- attending_venue.on_get_order(pawn, order_item)
- var/our_order = blackboard[BB_CUSTOMER_CURRENT_ORDER]
- if(isdatum(our_order))
- qdel(our_order)
- blackboard[BB_CUSTOMER_CURRENT_ORDER] = null
+ if(blackboard[BB_CUSTOMER_EATING])
+ return
+
+ blackboard[BB_CUSTOMER_EATING] = TRUE
+ attending_venue.on_get_order(pawn, order_item)
+ var/our_order = blackboard[BB_CUSTOMER_CURRENT_ORDER]
+ if(isdatum(our_order))
+ qdel(our_order)
+ blackboard[BB_CUSTOMER_CURRENT_ORDER] = null
///Called when
@@ -76,7 +80,10 @@
customer.resist()
-
+/datum/ai_controller/robot_customer/proc/dont_want_that(mob/living/chef, obj/item/thing)
+ var/mob/living/simple_animal/robot_customer/customer = pawn
+ var/datum/customer_data/customer_data = blackboard[BB_CUSTOMER_CUSTOMERINFO]
+ customer.say(customer_data.wrong_item_line)
/datum/ai_controller/robot_customer/proc/warn_greytider(mob/living/greytider)
var/mob/living/simple_animal/robot_customer/customer = pawn
diff --git a/code/datums/components/crafting/_recipes.dm b/code/datums/components/crafting/_recipes.dm
index 1298822f978..56f8ed23970 100644
--- a/code/datums/components/crafting/_recipes.dm
+++ b/code/datums/components/crafting/_recipes.dm
@@ -1,6 +1,10 @@
/datum/crafting_recipe
- ///in-game display name
+ /// in-game display name
+ /// Optional, if not set uses result name
var/name
+ /// description displayed in game
+ /// Optional, if not set uses result desc
+ var/desc
///type paths of items consumed associated with how many are needed
var/list/reqs = list()
///type paths of items explicitly not allowed as an ingredient
@@ -77,3 +81,7 @@
if(ispath(required_pipe.pipe_type, /obj/machinery/atmospherics/pipe/smart))
return TRUE
return FALSE
+
+/// Additional UI data to be passed to the crafting UI for this recipe
+/datum/crafting_recipe/proc/crafting_ui_data()
+ return list()
diff --git a/code/datums/components/crafting/crafting.dm b/code/datums/components/crafting/crafting.dm
index 1b50b4e7b63..59f689e5b9d 100644
--- a/code/datums/components/crafting/crafting.dm
+++ b/code/datums/components/crafting/crafting.dm
@@ -405,7 +405,7 @@
data["recipes"] = list()
data["categories"] = list()
- data["foodtypes"] = list()
+ data["foodtypes"] = FOOD_FLAGS
if(user.has_dna())
var/mob/living/carbon/carbon = user
@@ -415,27 +415,14 @@
if(!is_recipe_available(recipe, user))
continue
- if(recipe.category && !(recipe.category in data["categories"]))
- data["categories"] += recipe.category
-
- if(ispath(recipe.result, /obj/item/food))
- var/obj/item/food/item = recipe.result
- var/list/foodtypes = bitfield_to_list(initial(item.foodtypes), FOOD_FLAGS)
- for(var/type in foodtypes)
- if(!(type in data["foodtypes"]))
- data["foodtypes"] += type
+ if(recipe.category)
+ data["categories"] |= recipe.category
// Materials
for(var/req in recipe.reqs)
- if(!(req in material_occurences))
- material_occurences[req] = 1
- else
- material_occurences[req] += 1
+ material_occurences[req] += 1
for(var/req in recipe.chem_catalysts)
- if(!(req in material_occurences))
- material_occurences[req] = 1
- else
- material_occurences[req] += 1
+ material_occurences[req] += 1
data["recipes"] += list(build_crafting_data(recipe))
@@ -508,39 +495,32 @@
var/atom/atom = recipe.result
data["result"] = atoms.Find(atom)
- if(ispath(recipe.type, /datum/crafting_recipe/food) && ispath(recipe.result, /obj/item/food))
- // Foodtypes
- var/obj/item/food/item = recipe.result
- var/list/foodtypes = bitfield_to_list(initial(item.foodtypes), FOOD_FLAGS)
- for(var/type in foodtypes)
- if(!(type in data["foodtypes"]))
- data["foodtypes"] += type
- data["foodtypes"] = foodtypes
- // Nutriments
- var/datum/crafting_recipe/food/food_recipe = recipe
- data["nutriments"] = food_recipe.total_nutriment_factor
+ var/recipe_data = recipe.crafting_ui_data()
+ for(var/new_data in recipe_data)
+ data[new_data] = recipe_data[new_data]
// Category
data["category"] = recipe.category
// Name, Description
- data["name"] = initial(atom.name)
- if(recipe.name) // Override if recipe has a name
- data["name"] = recipe.name
+ data["name"] = recipe.name || initial(atom.name)
if(ispath(recipe.result, /datum/reagent))
var/datum/reagent/reagent = recipe.result
if(recipe.result_amount > 1)
data["name"] = "[data["name"]] [recipe.result_amount]u"
- data["desc"] = initial(reagent.description)
+ data["desc"] = recipe.desc || initial(reagent.description)
+
else if(ispath(recipe.result, /obj/item/pipe))
var/obj/item/pipe/pipe_obj = recipe.result
var/obj/pipe_real = initial(pipe_obj.pipe_type)
- data["desc"] = initial(pipe_real.desc)
+ data["desc"] = recipe.desc || initial(pipe_real.desc)
+
else
if(ispath(recipe.result, /obj/item/stack) && recipe.result_amount > 1)
data["name"] = "[data["name"]] [recipe.result_amount]x"
- data["desc"] = initial(atom.desc)
+ data["desc"] = recipe.desc || initial(atom.desc)
+
// Crafting
if(recipe.non_craftable)
@@ -553,50 +533,55 @@
data["tool_behaviors"] = recipe.tool_behaviors
if(recipe.tool_paths)
data["tool_paths"] = list()
- for(var/req_atom as anything in recipe.tool_paths)
+ for(var/req_atom in recipe.tool_paths)
data["tool_paths"] += atoms.Find(req_atom)
// Machinery
if(recipe.machinery)
data["machinery"] = list()
- for(var/req_atom as anything in recipe.machinery)
+ for(var/req_atom in recipe.machinery)
data["machinery"] += atoms.Find(req_atom)
// Structures
if(recipe.structures)
data["structures"] = list()
- for(var/req_atom as anything in recipe.structures)
+ for(var/req_atom in recipe.structures)
data["structures"] += atoms.Find(req_atom)
// Ingredients / Materials
if(recipe.reqs.len)
data["reqs"] = list()
- for(var/req_atom as anything in recipe.reqs)
+ for(var/req_atom in recipe.reqs)
var/id = atoms.Find(req_atom)
data["reqs"]["[id]"] = recipe.reqs[req_atom]
// Catalysts
if(recipe.chem_catalysts.len)
data["chem_catalysts"] = list()
- for(var/req_atom as anything in recipe.chem_catalysts)
+ for(var/req_atom in recipe.chem_catalysts)
var/id = atoms.Find(req_atom)
data["chem_catalysts"]["[id]"] = recipe.chem_catalysts[req_atom]
// Reaction data
- if(recipe.reaction)
+ if(ispath(recipe.reaction))
data["is_reaction"] = TRUE
- var/datum/chemical_reaction/reaction = GLOB.chemical_reactions_list[recipe.reaction]
- if(!data["steps"])
- data["steps"] = list()
- if(!reaction.required_container && (recipe.reqs.len > 1 || reaction.required_catalysts.len))
- data["steps"] += "Mix all ingredients together"
- if(reaction.required_temp > T20C)
- data["steps"] += "Heat up to [reaction.required_temp]K"
- if(reaction.required_container)
- var/atom/req_atom = reaction.required_container
- var/id = atoms.Find(req_atom)
- data["reqs"]["[id]"] = 1
- data["steps"] += "Add all ingredients into the [initial(req_atom.name)]"
+ // May be called before chemical reactions list is setup
+ var/datum/chemical_reaction/reaction = GLOB.chemical_reactions_list[recipe.reaction] || new recipe.reaction()
+ if(istype(reaction))
+ if(!data["steps"])
+ data["steps"] = list()
+ if(reaction.required_container)
+ var/id = atoms.Find(reaction.required_container)
+ data["reqs"]["[id]"] = 1
+ data["steps"] += "Add all ingredients into \a [initial(reaction.required_container.name)]"
+ else if(length(recipe.reqs) > 1 || length(reaction.required_catalysts))
+ data["steps"] += "Mix all ingredients together"
+ if(reaction.required_temp > T20C)
+ data["steps"] += "Heat up to [reaction.required_temp]K"
+ else
+ stack_trace("Invalid reaction found in recipe code! ([recipe.reaction])")
+ else if(!isnull(recipe.reaction))
+ stack_trace("Invalid reaction found in recipe code! ([recipe.reaction])")
return data
diff --git a/code/datums/components/food/ice_cream_holder.dm b/code/datums/components/food/ice_cream_holder.dm
index 41267981187..60da9b207d6 100644
--- a/code/datums/components/food/ice_cream_holder.dm
+++ b/code/datums/components/food/ice_cream_holder.dm
@@ -169,7 +169,7 @@
if(compare_list(our_scoops, icecream_order.wanted_flavors))
return COMPONENT_CORRECT_ORDER
-/datum/component/ice_cream_holder/proc/sell_ice_cream(obj/item/source, mob/living/simple_animal/robot_customer/sold_to, obj/item/container)
+/datum/component/ice_cream_holder/proc/sell_ice_cream(obj/item/source, mob/living/simple_animal/robot_customer/sold_to)
SIGNAL_HANDLER
//the price of ice cream scales with the number of scoops. Yummy.
diff --git a/code/datums/components/takes_reagent_appearance.dm b/code/datums/components/takes_reagent_appearance.dm
index c54882ac5b4..0d5730fc80d 100644
--- a/code/datums/components/takes_reagent_appearance.dm
+++ b/code/datums/components/takes_reagent_appearance.dm
@@ -98,7 +98,7 @@
item_parent.name = initial(item_parent.name)
else if(style.name)
// style
- item_parent.name = style.name
+ style.set_name(item_parent)
return COMSIG_ATOM_NO_UPDATE_NAME
return NONE
@@ -120,7 +120,7 @@
item_parent.desc = initial(item_parent.desc)
else if(style.desc)
// style
- item_parent.desc = style.desc
+ style.set_desc(item_parent)
return COMSIG_ATOM_NO_UPDATE_DESC
return NONE
@@ -139,8 +139,7 @@
item_parent.icon_state = icon_state_pre_change
else if(style.icon && style.icon_state)
// style
- item_parent.icon = style.icon
- item_parent.icon_state = style.icon_state
+ style.set_appearance(item_parent)
on_icon_changed?.InvokeAsync(style)
return COMSIG_ATOM_NO_UPDATE_ICON_STATE
diff --git a/code/datums/elements/food/foodlike_drink.dm b/code/datums/elements/food/foodlike_drink.dm
new file mode 100644
index 00000000000..e83468d68a1
--- /dev/null
+++ b/code/datums/elements/food/foodlike_drink.dm
@@ -0,0 +1,49 @@
+#define DOAFTER_SOURCE_FOODLIKE_DRINK "doafter_foodlike_drink"
+
+/**
+ * This element can be attached to a reagent container to make it loop after drinking like a food item
+ */
+/datum/element/foodlike_drink
+
+/datum/element/foodlike_drink/Attach(datum/target)
+ . = ..()
+ if(!is_reagent_container(target))
+ return ELEMENT_INCOMPATIBLE
+
+ RegisterSignal(target, COMSIG_GLASS_DRANK, PROC_REF(on_drink))
+
+/datum/element/foodlike_drink/Detach(datum/source, ...)
+ . = ..()
+ UnregisterSignal(source, COMSIG_GLASS_DRANK)
+
+/datum/element/foodlike_drink/proc/on_drink(obj/item/reagent_containers/source, mob/living/drinker, mob/living/user)
+ SIGNAL_HANDLER
+
+ if(drinker != user)
+ return
+
+ if(DOING_INTERACTION(user, DOAFTER_SOURCE_FOODLIKE_DRINK))
+ return
+
+ INVOKE_ASYNC(src, PROC_REF(continue_drinking), source, user)
+
+/datum/element/foodlike_drink/proc/continue_drinking(obj/item/reagent_containers/source, mob/living/user)
+ if(!do_after(
+ user = user,
+ delay = 1.25 SECONDS,
+ timed_action_flags = IGNORE_USER_LOC_CHANGE,
+ extra_checks = CALLBACK(src, PROC_REF(can_keep_drinking), source, user),
+ interaction_key = DOAFTER_SOURCE_FOODLIKE_DRINK,
+ ))
+ return
+
+ source.attack(user, user)
+
+/datum/element/foodlike_drink/proc/can_keep_drinking(obj/item/reagent_containers/source, mob/living/user)
+ if(QDELETED(source) || user.get_active_held_item() != source)
+ return FALSE
+ if(source.reagents.total_volume <= 0)
+ return FALSE
+ return TRUE
+
+#undef DOAFTER_SOURCE_FOODLIKE_DRINK
diff --git a/code/datums/elements/food/venue_price.dm b/code/datums/elements/food/venue_price.dm
index 514346a22e3..1fcf9de040d 100644
--- a/code/datums/elements/food/venue_price.dm
+++ b/code/datums/elements/food/venue_price.dm
@@ -10,17 +10,32 @@
stack_trace("A venue_price element was attached to something without specifying an actual price.")
return ELEMENT_INCOMPATIBLE
src.venue_price = venue_price
- RegisterSignal(target, COMSIG_ITEM_SOLD_TO_CUSTOMER, PROC_REF(item_sold))
+
+ if(isitem(target))
+ RegisterSignal(target, COMSIG_ITEM_SOLD_TO_CUSTOMER, PROC_REF(item_sold))
+ if(istype(target, /datum/reagent))
+ RegisterSignal(target, COMSIG_REAGENT_SOLD_TO_CUSTOMER, PROC_REF(reagent_sold))
/datum/element/venue_price/Detach(datum/target)
. = ..()
UnregisterSignal(target, COMSIG_ITEM_SOLD_TO_CUSTOMER)
+ UnregisterSignal(target, COMSIG_REAGENT_SOLD_TO_CUSTOMER)
-/datum/element/venue_price/proc/item_sold(datum/thing_sold, mob/living/simple_animal/robot_customer/sold_to, obj/item/container)
+/datum/element/venue_price/proc/item_sold(obj/item/thing_sold, mob/living/simple_animal/robot_customer/sold_to)
SIGNAL_HANDLER
- var/datum/venue/venue_to_pay = sold_to.ai_controller?.blackboard[BB_CUSTOMER_ATTENDING_VENUE]
+ produce_cash(sold_to, thing_sold)
+ return TRANSACTION_SUCCESS
+/datum/element/venue_price/proc/reagent_sold(datum/reagent/reagent_sold, mob/living/simple_animal/robot_customer/sold_to, obj/item/container)
+ SIGNAL_HANDLER
+
+ produce_cash(sold_to, container)
+ return TRANSACTION_SUCCESS
+
+/datum/element/venue_price/proc/produce_cash(mob/living/simple_animal/robot_customer/sold_to, obj/item/container)
new /obj/item/holochip(get_turf(container), venue_price)
+ playsound(container, 'sound/effects/cashregister.ogg', 60, TRUE)
+
+ var/datum/venue/venue_to_pay = sold_to.ai_controller.blackboard[BB_CUSTOMER_ATTENDING_VENUE]
venue_to_pay.total_income += venue_price
- playsound(get_turf(container), 'sound/effects/cashregister.ogg', 60, TRUE)
diff --git a/code/game/atoms.dm b/code/game/atoms.dm
index 0b13fbc15e4..f86b0c9ab6d 100644
--- a/code/game/atoms.dm
+++ b/code/game/atoms.dm
@@ -734,31 +734,29 @@
. += EXAMINE_SECTION_BREAK //SKYRAT EDIT ADDITION
//SKYRAT EDIT ADDITION END
if(reagents)
- if(reagents.flags & TRANSPARENT)
- . += EXAMINE_SECTION_BREAK //SKYRAT EDIT ADDITION - HR sections
- . += "It contains:"
- if(length(reagents.reagent_list))
- if(user.can_see_reagents()) //Show each individual reagent
- for(var/datum/reagent/current_reagent as anything in reagents.reagent_list)
- . += "• [round(current_reagent.volume, 0.01)] units of [current_reagent.name]"
- if(reagents.is_reacting)
- . += span_warning(" It is currently reacting!") // SKYRAT EDIT CHANGE - added spacing
- . += span_notice("The solution's pH is [round(reagents.ph, 0.01)] and has a temperature of [reagents.chem_temp]K.")
- else //Otherwise, just show the total volume
- var/total_volume = 0
- for(var/datum/reagent/current_reagent as anything in reagents.reagent_list)
- total_volume += current_reagent.volume
- . += "[total_volume] units of various reagents"
- else
- . += "Nothing."
- . += EXAMINE_SECTION_BREAK //SKYRAT EDIT ADDITION
- else if(reagents.flags & AMOUNT_VISIBLE)
- if(reagents.total_volume)
- . += span_notice("It has [reagents.total_volume] unit\s left.")
- else
- . += span_danger("It's empty.")
+ var/user_sees_reagents = user.can_see_reagents()
+ var/reagent_sigreturn = SEND_SIGNAL(src, COMSIG_PARENT_REAGENT_EXAMINE, user, ., user_sees_reagents)
+ if(!(reagent_sigreturn & STOP_GENERIC_REAGENT_EXAMINE))
+ if(reagents.flags & TRANSPARENT)
+ if(reagents.total_volume > 0)
+ . += "It contains [round(reagents.total_volume, 0.01)] units of various reagents[user_sees_reagents ? ":" : "."]"
+ if(user_sees_reagents) //Show each individual reagent
+ for(var/datum/reagent/current_reagent as anything in reagents.reagent_list)
+ . += "• [round(current_reagent.volume, 0.01)] units of [current_reagent.name]"
+ if(reagents.is_reacting)
+ . += span_warning("It is currently reacting!")
+ . += span_notice("The solution's pH is [round(reagents.ph, 0.01)] and has a temperature of [reagents.chem_temp]K.")
+
+ else
+ . += "It contains:
Nothing."
+ else if(reagents.flags & AMOUNT_VISIBLE)
+ if(reagents.total_volume)
+ . += span_notice("It has [reagents.total_volume] unit\s left.")
+ else
+ . += span_danger("It's empty.")
SEND_SIGNAL(src, COMSIG_PARENT_EXAMINE, user, .)
+
/**
* Called when a mob examines (shift click or verb) this atom twice (or more) within EXAMINE_MORE_WINDOW (default 1 second)
*
diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm
index 8db2ff2261c..a46d34a3b26 100644
--- a/code/game/atoms_movable.dm
+++ b/code/game/atoms_movable.dm
@@ -283,10 +283,12 @@
underlay_appearance.overlays += turf_mask
/atom/movable/update_overlays()
- . = ..()
+ var/list/overlays = ..()
var/emissive_block = update_emissive_block()
if(emissive_block)
- . += emissive_block
+ // Emissive block should always go at the beginning of the list
+ overlays.Insert(1, emissive_block)
+ return overlays
/atom/movable/proc/onZImpact(turf/impacted_turf, levels, message = TRUE)
SHOULD_CALL_PARENT(TRUE)
diff --git a/code/game/machinery/_machinery.dm b/code/game/machinery/_machinery.dm
index 8ba617003af..7055e19df96 100644
--- a/code/game/machinery/_machinery.dm
+++ b/code/game/machinery/_machinery.dm
@@ -781,6 +781,7 @@
idle_power_usage = initial(idle_power_usage) * (1 + parts_energy_rating)
active_power_usage = initial(active_power_usage) * (1 + parts_energy_rating)
update_current_power_usage()
+ SEND_SIGNAL(src, COMSIG_MACHINERY_REFRESH_PARTS)
/obj/machinery/proc/default_pry_open(obj/item/crowbar, close_after_pry = FALSE, open_density = FALSE, closed_density = TRUE)
. = !(state_open || panel_open || is_operational || (flags_1 & NODECONSTRUCT_1)) && crowbar.tool_behaviour == TOOL_CROWBAR
diff --git a/code/game/objects/effects/effect_system/fluid_spread/effects_foam.dm b/code/game/objects/effects/effect_system/fluid_spread/effects_foam.dm
index 230c82950ec..0d44043197f 100644
--- a/code/game/objects/effects/effect_system/fluid_spread/effects_foam.dm
+++ b/code/game/objects/effects/effect_system/fluid_spread/effects_foam.dm
@@ -172,9 +172,9 @@
QDEL_NULL(chemholder)
return ..()
-/datum/effect_system/fluid_spread/foam/set_up(range = 1, amount = DIAMOND_AREA(range), atom/holder, atom/location = null, datum/reagents/carry = null, result_type = null)
+/datum/effect_system/fluid_spread/foam/set_up(range = 1, amount = DIAMOND_AREA(range), atom/holder, atom/location = null, datum/reagents/carry = null, result_type = null, stop_reactions = FALSE)
. = ..()
- carry?.copy_to(chemholder, carry.total_volume)
+ carry?.copy_to(chemholder, carry.total_volume, no_react = stop_reactions)
if(!isnull(result_type))
src.result_type = result_type
@@ -440,6 +440,14 @@
for(var/obj/item/potential_tinder in location)
potential_tinder.extinguish()
+/datum/effect_system/fluid_spread/foam/dirty
+ effect_type = /obj/effect/particle_effect/fluid/foam/dirty
+
+/obj/effect/particle_effect/fluid/foam/dirty
+ name = "dirty foam"
+ allow_duplicate_results = FALSE
+ result_type = /obj/effect/decal/cleanable/dirt
+
#undef MINIMUM_FOAM_DILUTION_RANGE
#undef MINIMUM_FOAM_DILUTION
#undef FOAM_REAGENT_SCALE
diff --git a/code/game/objects/effects/particle_holder.dm b/code/game/objects/effects/particle_holder.dm
index 3758e808be0..99de07740ed 100644
--- a/code/game/objects/effects/particle_holder.dm
+++ b/code/game/objects/effects/particle_holder.dm
@@ -65,3 +65,8 @@
particle_mob.vis_contents += src
//readd to ourselves
attached_to.vis_contents |= src
+
+/// Sets the particles position to the passed coordinate list (X, Y, Z)
+/// See [https://www.byond.com/docs/ref/#/{notes}/particles] for position documentation
+/obj/effect/abstract/particle_holder/proc/set_particle_position(list/pos)
+ particles.position = pos
diff --git a/code/game/objects/effects/particles/smoke.dm b/code/game/objects/effects/particles/smoke.dm
index 33d93596455..bf66fdb6b07 100644
--- a/code/game/objects/effects/particles/smoke.dm
+++ b/code/game/objects/effects/particles/smoke.dm
@@ -23,6 +23,11 @@
velocity = list(0, 0.3, 0)
friction = 0.25
+/particles/smoke/steam/bad
+ icon_state = list("steam_1" = 1, "smoke_1" = 1, "smoke_2" = 1, "smoke_3" = 1)
+ spawning = 2
+ velocity = list(0, 0.25, 0)
+
/particles/smoke/ash
icon_state = list("ash_1" = 2, "ash_2" = 2, "ash_3" = 1, "smoke_1" = 3, "smoke_2" = 2)
count = 500
diff --git a/code/game/objects/effects/spawners/random/food_or_drink.dm b/code/game/objects/effects/spawners/random/food_or_drink.dm
index 8753c2cfff8..a1b9976cab2 100644
--- a/code/game/objects/effects/spawners/random/food_or_drink.dm
+++ b/code/game/objects/effects/spawners/random/food_or_drink.dm
@@ -72,12 +72,12 @@
name = "soup spawner"
icon_state = "soup"
loot = list(
- /obj/item/food/soup/beet,
- /obj/item/food/soup/sweetpotato,
- /obj/item/food/soup/stew,
- /obj/item/food/soup/hotchili,
- /obj/item/food/soup/nettle,
- /obj/item/food/soup/meatball,
+ /obj/item/reagent_containers/cup/bowl/soup/hotchili,
+ /obj/item/reagent_containers/cup/bowl/soup/meatball_soup,
+ /obj/item/reagent_containers/cup/bowl/soup/nettle,
+ /obj/item/reagent_containers/cup/bowl/soup/stew,
+ /obj/item/reagent_containers/cup/bowl/soup/sweetpotato,
+ /obj/item/reagent_containers/cup/bowl/soup/white_beet,
)
/obj/effect/spawner/random/food_or_drink/salad
@@ -271,4 +271,3 @@
if(!HAS_TRAIT(SSstation, STATION_TRAIT_BIRTHDAY))
spawn_loot_chance = 0
return ..()
-
diff --git a/code/game/objects/effects/spawners/random/techstorage.dm b/code/game/objects/effects/spawners/random/techstorage.dm
index ad347539201..0fe2f487130 100644
--- a/code/game/objects/effects/spawners/random/techstorage.dm
+++ b/code/game/objects/effects/spawners/random/techstorage.dm
@@ -38,6 +38,7 @@
/obj/item/circuitboard/machine/griddle,
/obj/item/circuitboard/machine/reagentgrinder,
/obj/item/circuitboard/machine/oven,
+ /obj/item/circuitboard/machine/stove,
/obj/item/circuitboard/machine/processor,
/obj/item/circuitboard/machine/gibber,
/obj/item/circuitboard/machine/chem_dispenser/drinks,
@@ -121,4 +122,3 @@
/obj/item/circuitboard/computer/apc_control,
/obj/item/circuitboard/computer/robotics,
)
-
diff --git a/code/game/objects/items/circuitboards/machines/machine_circuitboards.dm b/code/game/objects/items/circuitboards/machines/machine_circuitboards.dm
index 3cdc8bc0a4e..25f17d83b07 100644
--- a/code/game/objects/items/circuitboards/machines/machine_circuitboards.dm
+++ b/code/game/objects/items/circuitboards/machines/machine_circuitboards.dm
@@ -1113,7 +1113,21 @@
greyscale_colors = CIRCUIT_COLOR_SERVICE
build_path = /obj/machinery/oven
req_components = list(/datum/stock_part/micro_laser = 1)
- needs_anchored = FALSE
+ needs_anchored = TRUE
+
+/obj/item/circuitboard/machine/stove
+ name = "Stove"
+ greyscale_colors = CIRCUIT_COLOR_SERVICE
+ build_path = /obj/machinery/stove
+ req_components = list(/datum/stock_part/micro_laser = 1)
+ needs_anchored = TRUE
+
+/obj/item/circuitboard/machine/range
+ name = "Range (Oven & Stove)"
+ greyscale_colors = CIRCUIT_COLOR_SERVICE
+ build_path = /obj/machinery/oven/range
+ req_components = list(/datum/stock_part/micro_laser = 2)
+ needs_anchored = TRUE
/obj/item/circuitboard/machine/dish_drive
name = "Dish Drive"
diff --git a/code/game/objects/items/food/lizard.dm b/code/game/objects/items/food/lizard.dm
index b4dea6bc828..6975991ea24 100644
--- a/code/game/objects/items/food/lizard.dm
+++ b/code/game/objects/items/food/lizard.dm
@@ -605,73 +605,6 @@
food_flags = FOOD_FINGER_FOOD
w_class = WEIGHT_CLASS_SMALL
-//Soup Dishes
-/obj/item/food/soup/atrakor_dumplings
- name = "\improper Atrakor dumpling soup"
- desc = "A bowl of rich, meaty dumpling soup, traditionally served during the festival of Atrakor's Might on Tizira. The dumplings are shaped like the Night Sky Lord himself."
- icon = 'icons/obj/food/lizard.dmi'
- icon_state = "atrakor_dumplings"
- food_reagents = list(
- /datum/reagent/consumable/nutriment = 6,
- /datum/reagent/consumable/nutriment/protein = 10,
- /datum/reagent/consumable/nutriment/vitamin = 4,
- /datum/reagent/water = 5,
- )
- tastes = list("bone broth" = 1, "onion" = 1, "potato" = 1)
- foodtypes = MEAT | VEGETABLES | NUTS
-
-/obj/item/food/soup/meatball_noodles
- name = "meatball noodle soup"
- desc = "A hearty noodle soup made from meatballs and nizaya in a rich broth. Commonly topped with a handful of chopped nuts."
- icon = 'icons/obj/food/lizard.dmi'
- icon_state = "meatball_noodles"
- food_reagents = list(
- /datum/reagent/consumable/nutriment = 6,
- /datum/reagent/consumable/nutriment/protein = 8,
- /datum/reagent/consumable/nutriment/vitamin = 6,
- /datum/reagent/water = 5,
- )
- tastes = list("bone broth" = 1, "meat" = 1, "gnocchi" = 1, "peanuts" = 1)
- foodtypes = MEAT | VEGETABLES | NUTS
-
-/obj/item/food/soup/black_broth
- name = "\improper Tiziran black broth"
- desc = "A bowl of sausage, onion, blood and vinegar, served ice cold. Every bit as rough as it sounds."
- icon = 'icons/obj/food/lizard.dmi'
- icon_state = "black_broth"
- food_reagents = list(
- /datum/reagent/consumable/nutriment/protein = 10,
- /datum/reagent/blood = 8,
- /datum/reagent/consumable/liquidgibs = 2,
- )
- tastes = list("vinegar" = 1, "metal" = 1)
- foodtypes = MEAT | VEGETABLES | GORE
-
-/obj/item/food/soup/jellyfish
- name = "jellyfish stew"
- desc = "A slimy bowl of jellyfish stew. It jiggles if you shake it."
- icon = 'icons/obj/food/lizard.dmi'
- icon_state = "jellyfish_stew"
- food_reagents = list(
- /datum/reagent/consumable/nutriment/protein = 10,
- /datum/reagent/consumable/nutriment = 6,
- )
- tastes = list("slime" = 1)
- foodtypes = MEAT | VEGETABLES | GORE
-
-/obj/item/food/soup/rootbread_soup
- name = "rootbread soup"
- desc = "A big bowl of spicy, savoury soup made with rootbread. Heavily seasoned, and very tasty."
- icon = 'icons/obj/food/lizard.dmi'
- icon_state = "rootbread_soup"
- food_reagents = list(
- /datum/reagent/consumable/nutriment/protein = 6,
- /datum/reagent/consumable/nutriment = 10,
- /datum/reagent/consumable/nutriment/vitamin = 6,
- )
- tastes = list("bread" = 1, "egg" = 1, "chili" = 1, "garlic" = 1)
- foodtypes = MEAT | VEGETABLES
-
//Egg Dishes
/obj/item/food/black_eggs
name = "black scrambled eggs"
diff --git a/code/game/objects/items/food/moth.dm b/code/game/objects/items/food/moth.dm
index a78b9d2127a..40e28b0676c 100644
--- a/code/game/objects/items/food/moth.dm
+++ b/code/game/objects/items/food/moth.dm
@@ -433,122 +433,7 @@
making up a typical meal- tomato soup, roast pumpkin, and blueberry pie." //Thankfully not made by Willy Wonka
tastes = list("tomato soup" = 1, "roast pumpkin" = 1, "blueberry pie" = 1)
-//Soups
-/obj/item/food/soup/moth_cotton_soup
- name = "flöfrölenmæsch" //flöf = cotton, rölen = ball, mæsch = soup
- desc = "A soup made from raw cotton in a flavourful vegetable broth. Enjoyed only by moths and the criminally tasteless."
- icon = 'icons/obj/food/moth.dmi'
- icon_state = "moth_cotton_soup"
- food_reagents = list(
- /datum/reagent/consumable/nutriment = 6,
- /datum/reagent/consumable/nutriment/vitamin = 12,
- /datum/reagent/water = 5,
- )
- tastes = list("cotton" = 1, "broth" = 1)
- foodtypes = VEGETABLES | CLOTH
- w_class = WEIGHT_CLASS_SMALL
-
-/obj/item/food/soup/moth_cheese_soup
- name = "ælosterrmæsch" //ælo = cheese, sterr = melt, mæsch = soup
- desc = "A simple and filling soup made from homemade cheese and sweet potato. \
- The curds provide texture while the whey provides volume- and they both provide deliciousness!"
- icon = 'icons/obj/food/moth.dmi'
- icon_state = "moth_cheese_soup"
- food_reagents = list(
- /datum/reagent/consumable/nutriment/protein = 12,
- /datum/reagent/consumable/nutriment/vitamin = 4,
- /datum/reagent/consumable/nutriment = 4,
- )
- tastes = list("cheese" = 1, "cream" = 1, "sweet potato" = 1)
- foodtypes = DAIRY | GRAIN
- w_class = WEIGHT_CLASS_SMALL
-
-/obj/item/food/soup/moth_seed_soup
- name = "misklmæsch" //miskl = seed, mæsch = soup
- desc = "A seed based soup, made by germinating seeds and then boiling them. \
- Produces a particularly bitter broth which is usually balanced by the addition of vinegar."
- icon = 'icons/obj/food/moth.dmi'
- icon_state = "moth_seed_soup"
- food_reagents = list(
- /datum/reagent/consumable/nutriment/vitamin = 12,
- /datum/reagent/consumable/nutriment = 6,
- /datum/reagent/water = 5,
- )
- tastes = list("bitterness" = 1, "sourness" = 1)
- foodtypes = VEGETABLES
- w_class = WEIGHT_CLASS_SMALL
-
-/obj/item/food/soup/vegetarian_chili
- name = "chili sin carne"
- desc = "For the hombres who don't want carne."
- icon_state = "hotchili"
- food_reagents = list(
- /datum/reagent/consumable/nutriment = 4,
- /datum/reagent/consumable/nutriment/protein = 4,
- /datum/reagent/consumable/capsaicin = 3,
- /datum/reagent/consumable/tomatojuice = 4,
- /datum/reagent/consumable/nutriment/vitamin = 6,
- )
- tastes = list("bitterness" = 1, "sourness" = 1)
- foodtypes = VEGETABLES
- w_class = WEIGHT_CLASS_SMALL
-
-/obj/item/food/soup/moth_bean_stew
- name = "prickeldröndolhaskl" //prickeld = spicy, röndol = bean, haskl = stew
- desc = "A spicy bean stew with lots of veggies, commonly served aboard the fleet as a filling and satisfying meal with rice or bread."
- icon = 'icons/obj/food/moth.dmi'
- icon_state = "moth_bean_stew"
- food_reagents = list(
- /datum/reagent/consumable/nutriment/protein = 6,
- /datum/reagent/consumable/nutriment/vitamin = 14,
- /datum/reagent/consumable/nutriment = 4,
- )
- tastes = list("beans" = 1, "cabbage" = 1, "spicy sauce" = 1)
- foodtypes = VEGETABLES
- w_class = WEIGHT_CLASS_SMALL
-
-/obj/item/food/soup/moth_oat_stew
- name = "häfmisklhaskl" //häfmiskl = oat (häf from German hafer meaning oat, miskl meaning seed), haskl = stew
- desc = "A hearty oat stew, prepared with oats, sweet potatoes, and various winter vegetables."
- icon = 'icons/obj/food/moth.dmi'
- icon_state = "moth_oat_stew"
- food_reagents = list(
- /datum/reagent/consumable/nutriment/vitamin = 14,
- /datum/reagent/consumable/nutriment = 8,
- )
- tastes = list("oats" = 1, "sweet potato" = 1, "carrot" = 1, "parsnip" = 1, "pumpkin" = 1)
- foodtypes = VEGETABLES | GRAIN
- w_class = WEIGHT_CLASS_SMALL
-
-/obj/item/food/soup/moth_fire_soup
- name = "tömpröttkrakklmæsch" //tömprött = heart (tömp = thump, rött = muscle), krakkl = fire, mæsch = soup
- desc = "Tömpröttkrakklmæsch, or heartburn soup, is a cold soup dish that originated amongst the jungle moths, \
- and is named for two things- its rosy pink colour, and its scorchingly hot chili heat."
- icon = 'icons/obj/food/moth.dmi'
- icon_state = "moth_fire_soup"
- food_reagents = list(
- /datum/reagent/consumable/nutriment/protein = 10,
- /datum/reagent/consumable/nutriment/vitamin = 10,
- )
- tastes = list("love" = 1, "hate" = 1)
- foodtypes = VEGETABLES | DAIRY
- w_class = WEIGHT_CLASS_SMALL
-
-/obj/item/food/soup/rice_porridge
- name = "rice porridge"
- desc = "A plate of rice porridge. It's mostly flavourless, but it does fill a spot. \
- To the Chinese it's congee, and moths call it höllflöfmisklsløsk." //höllflöfmiskl = rice (höllflöf = cloud, miskl = seed), sløsk = porridge
- icon = 'icons/obj/food/moth.dmi'
- icon_state = "rice_porridge"
- food_reagents = list(
- /datum/reagent/consumable/nutriment = 6,
- /datum/reagent/consumable/nutriment/vitamin = 8,
- )
- tastes = list("nothing" = 1)
- foodtypes = GRAIN
- w_class = WEIGHT_CLASS_SMALL
-
-/obj/item/food/soup/hua_mulan_congee
+/obj/item/food/bowled/hua_mulan_congee
name = "\improper Hua Mulan congee"
desc = "Nobody is quite sure why this smiley bowl of rice porridge with eggs and bacon is named after a mythological Chinese figure- \
it's just sorta what it's always been called."
@@ -563,44 +448,7 @@
foodtypes = MEAT | GRAIN
w_class = WEIGHT_CLASS_SMALL
-/obj/item/food/soup/toechtauese_rice_porridge
- name = "töchtaüse rice porridge"
- desc = "Commonly served aboard the mothic fleet, rice porridge with töchtaüse syrup is more palatable than the regular stuff, if even just because it's spicier than normal."
- icon = 'icons/obj/food/moth.dmi'
- icon_state = "toechtauese_rice_porridge"
- food_reagents = list(/datum/reagent/consumable/nutriment/protein = 6, /datum/reagent/consumable/nutriment/vitamin = 12)
- tastes = list("sugar" = 1, "spice" = 1)
- foodtypes = GRAIN | VEGETABLES
- w_class = WEIGHT_CLASS_SMALL
-
-/obj/item/food/soup/cornmeal_porridge
- name = "cornmeal porridge"
- desc = "A plate of cornmeal porridge. It's more flavourful than most porridges, and makes a good base for other flavours, too."
- icon = 'icons/obj/food/moth.dmi'
- icon_state = "cornmeal_porridge"
- food_reagents = list(
- /datum/reagent/consumable/nutriment = 8,
- /datum/reagent/consumable/nutriment/vitamin = 4,
- )
- tastes = list("cornmeal" = 1)
- foodtypes = GRAIN
- w_class = WEIGHT_CLASS_SMALL
-
-/obj/item/food/soup/cheesy_porridge //milk, polenta, firm cheese, curd cheese, butter
- name = "cheesy porridge"
- desc = "A rich and creamy bowl of cheesy cornmeal porridge."
- icon = 'icons/obj/food/moth.dmi'
- icon_state = "cheesy_porridge"
- food_reagents = list(
- /datum/reagent/consumable/nutriment/protein = 8,
- /datum/reagent/consumable/nutriment/vitamin = 4,
- /datum/reagent/consumable/nutriment = 8,
- )
- tastes = list("cornmeal" = 1, "cheese" = 1, "more cheese" = 1, "lots of cheese" = 1)
- foodtypes = DAIRY | GRAIN
- w_class = WEIGHT_CLASS_SMALL
-
-/obj/item/food/soup/fried_eggplant_polenta
+/obj/item/food/bowled/fried_eggplant_polenta
name = "fried eggplant and polenta"
desc = "Polenta loaded with cheese, served with a few discs of fried eggplant and some tomato sauce. Lække!"
icon = 'icons/obj/food/moth.dmi'
@@ -982,19 +830,6 @@
tastes = list("vanilla" = 1, "clouds" = 1, "chocolate" = 1)
foodtypes = VEGETABLES | SUGAR
-/obj/item/food/soup/red_porridge
- name = "eltsløsk ül a priktæolk" //eltsløsk = red porridge, ül a = with, prikt = sour, æolk = cream
- desc = "Red porridge with yoghurt. The name and vegetable ingredients obscure the sweet nature of the dish, which is commonly served as a dessert aboard the fleet."
- icon = 'icons/obj/food/moth.dmi'
- icon_state = "red_porridge"
- food_reagents = list(
- /datum/reagent/consumable/nutriment/vitamin = 8,
- /datum/reagent/consumable/nutriment/protein = 8,
- /datum/reagent/consumable/sugar = 8,
- )
- tastes = list("sweet beets" = 1, "sugar" = 1, "sweetened yoghurt" = 1)
- foodtypes = VEGETABLES | SUGAR | DAIRY
-
//misc food
/obj/item/food/bubblegum/wake_up
name = "wake-up gum"
diff --git a/code/game/objects/items/food/salad.dm b/code/game/objects/items/food/salad.dm
index dac93e80d2f..0c4dd9a59d6 100644
--- a/code/game/objects/items/food/salad.dm
+++ b/code/game/objects/items/food/salad.dm
@@ -164,14 +164,66 @@
desc = "A simple bowl, used for soups and salads."
icon = 'icons/obj/food/soupsalad.dmi'
icon_state = "bowl"
- reagent_flags = OPENCONTAINER
+ base_icon_state = "bowl"
+ reagent_flags = OPENCONTAINER | DUNKABLE
custom_materials = list(/datum/material/glass = 500)
w_class = WEIGHT_CLASS_NORMAL
custom_price = PAYCHECK_CREW * 0.6
+ fill_icon_thresholds = list(0)
+ fill_icon_state = "fullbowl"
+ fill_icon = 'icons/obj/food/soupsalad.dmi'
+
+ volume = SOUP_SERVING_SIZE + 5
+ gulp_size = 3
/obj/item/reagent_containers/cup/bowl/Initialize(mapload)
. = ..()
+ RegisterSignal(src, COMSIG_PARENT_REAGENT_EXAMINE, PROC_REF(reagent_special_examine))
+ AddElement(/datum/element/foodlike_drink)
AddComponent(/datum/component/customizable_reagent_holder, /obj/item/food/salad/empty, CUSTOM_INGREDIENT_ICON_FILL, max_ingredients = 6)
+ AddComponent( \
+ /datum/component/takes_reagent_appearance, \
+ on_icon_changed = CALLBACK(src, PROC_REF(on_cup_change)), \
+ on_icon_reset = CALLBACK(src, PROC_REF(on_cup_reset)), \
+ base_container_type = /obj/item/reagent_containers/cup/bowl, \
+ )
+
+/obj/item/reagent_containers/cup/bowl/on_cup_change(datum/glass_style/style)
+ . = ..()
+ fill_icon_thresholds = null
+
+/obj/item/reagent_containers/cup/bowl/on_cup_reset()
+ . = ..()
+ fill_icon_thresholds ||= list(0)
+
+/**
+ * Override standard reagent examine
+ * so that anyone examining a bowl of soup sees the soup but nothing else (unless they have sci goggles)
+ */
+/obj/item/reagent_containers/cup/bowl/proc/reagent_special_examine(datum/source, mob/user, list/examine_list, can_see_insides = FALSE)
+ SIGNAL_HANDLER
+
+ if(can_see_insides || reagents.total_volume <= 0)
+ return
+
+ var/unknown_volume = 0
+ var/list/soups_found = list()
+ for(var/datum/reagent/current_reagent as anything in reagents.reagent_list)
+ if(istype(current_reagent, /datum/reagent/consumable/nutriment/soup))
+ soups_found += "• [round(current_reagent.volume, 0.01)] units of [current_reagent.name]"
+ else
+ unknown_volume += current_reagent.volume
+
+ if(!length(soups_found))
+ // There was no soup in the pot, do normal examine
+ return
+
+ examine_list += "Inside, you can see:"
+ examine_list += soups_found
+ if(unknown_volume > 0)
+ examine_list += "• [round(unknown_volume, 0.01)] units of unknown reagents"
+
+ return STOP_GENERIC_REAGENT_EXAMINE
// empty salad for custom salads
/obj/item/food/salad/empty
diff --git a/code/game/objects/items/food/soup.dm b/code/game/objects/items/food/soup.dm
index 0985c0842d3..7e84cea5f87 100644
--- a/code/game/objects/items/food/soup.dm
+++ b/code/game/objects/items/food/soup.dm
@@ -1,281 +1,37 @@
-/obj/item/food/soup
+/obj/item/food/bowled
w_class = WEIGHT_CLASS_NORMAL
icon = 'icons/obj/food/soupsalad.dmi'
- trash_type = /obj/item/reagent_containers/cup/bowl
bite_consumption = 5
max_volume = 80
- food_reagents = list(
- /datum/reagent/consumable/nutriment = 8,
- /datum/reagent/water = 5,
- /datum/reagent/consumable/nutriment/vitamin = 4,
- )
- tastes = list("tasteless soup" = 1)
- foodtypes = VEGETABLES
+ foodtypes = NONE
eatverbs = list("slurp", "sip", "inhale", "drink")
venue_value = FOOD_PRICE_CHEAP
-/obj/item/food/soup/wish
+/obj/item/food/bowled/wish
name = "wish soup"
desc = "I wish this was soup."
icon_state = "wishsoup"
food_reagents = list(/datum/reagent/water = 10)
tastes = list("wishes" = 1)
-/obj/item/food/soup/wish/Initialize(mapload)
+/obj/item/food/bowled/wish/Initialize(mapload)
. = ..()
- var/wish_true = prob(25)
- if(wish_true)
+ if(prob(25))
desc = "A wish come true!"
reagents.add_reagent(/datum/reagent/consumable/nutriment, 9)
reagents.add_reagent(/datum/reagent/consumable/nutriment/vitamin, 1)
-/obj/item/food/soup/meatball
- name = "meatball soup"
- desc = "You've got balls kid, BALLS!"
- icon_state = "meatballsoup"
+/obj/item/food/bowled/mammi
+ name = "Mammi"
+ desc = "A bowl of mushy bread and milk. It reminds you, not too fondly, of a bowel movement."
+ icon_state = "mammi"
food_reagents = list(
- /datum/reagent/consumable/nutriment = 6,
- /datum/reagent/consumable/nutriment/protein = 6,
- /datum/reagent/consumable/nutriment/vitamin = 8,
- /datum/reagent/water = 5,
+ /datum/reagent/consumable/nutriment = 11,
+ /datum/reagent/consumable/nutriment/vitamin = 2,
)
- tastes = list("meat" = 1)
- foodtypes = MEAT
- venue_value = FOOD_PRICE_NORMAL
+ foodtypes = SUGAR | DAIRY
-/obj/item/food/soup/slime
- name = "slime soup"
- desc = "If no water is available, you may substitute tears."
- icon_state = "slimesoup"
- food_reagents = list(
- /datum/reagent/consumable/nutriment = 6,
- /datum/reagent/toxin/slimejelly = 10,
- /datum/reagent/consumable/nutriment/vitamin = 9,
- /datum/reagent/water = 5,
- )
- tastes = list("slime" = 1)
- foodtypes = TOXIC | SUGAR
- venue_value = FOOD_PRICE_NORMAL
-
-/obj/item/food/soup/blood
- name = "tomato soup"
- desc = "Smells like copper."
- icon_state = "tomatosoup"
- food_reagents = list(
- /datum/reagent/consumable/nutriment/protein = 6,
- /datum/reagent/blood = 10, /datum/reagent/water = 5,
- /datum/reagent/consumable/nutriment/vitamin = 10,
- )
- tastes = list("iron" = 1)
- foodtypes = GROSS
-
-/obj/item/food/soup/wingfangchu
- name = "wing fang chu"
- desc = "A savory dish of alien wing wang in soy."
- icon_state = "wingfangchu"
- trash_type = /obj/item/reagent_containers/cup/bowl
- food_reagents = list(
- /datum/reagent/consumable/nutriment/protein = 9,
- /datum/reagent/consumable/soysauce = 10,
- /datum/reagent/consumable/nutriment/vitamin = 7,
- )
- tastes = list("soy" = 1)
- foodtypes = MEAT
-
-/obj/item/food/soup/clownstears
- name = "clown's tears"
- desc = "Not very funny."
- icon_state = "clownstears"
- food_reagents = list(
- /datum/reagent/consumable/nutriment = 5,
- /datum/reagent/consumable/banana = 10,
- /datum/reagent/lube = 5,
- /datum/reagent/consumable/nutriment/vitamin = 16,
- /datum/reagent/consumable/clownstears = 10,
- )
- tastes = list("a bad joke" = 1)
- foodtypes = FRUIT | SUGAR
-
-/obj/item/food/soup/vegetable
- name = "vegetable soup"
- desc = "A true vegan meal."
- icon_state = "vegetablesoup"
- food_reagents = list(
- /datum/reagent/consumable/nutriment = 9,
- /datum/reagent/water = 5,
- /datum/reagent/consumable/nutriment/vitamin = 8,
- )
- tastes = list("vegetables" = 1)
- foodtypes = VEGETABLES
- venue_value = FOOD_PRICE_NORMAL
-
-/obj/item/food/soup/nettle
- name = "nettle soup"
- desc = "To think, the botanist would've beat you to death with one of these."
- icon_state = "nettlesoup"
- food_reagents = list(
- /datum/reagent/consumable/nutriment = 5,
- /datum/reagent/consumable/nutriment/protein = 2,
- /datum/reagent/water = 5,
- /datum/reagent/consumable/nutriment/vitamin = 9,
- /datum/reagent/medicine/omnizine = 5,
- )
- tastes = list("nettles" = 1)
- foodtypes = VEGETABLES
- venue_value = FOOD_PRICE_NORMAL
-
-/obj/item/food/soup/mystery
- name = "mystery soup"
- desc = "The mystery is, why aren't you eating it?"
- icon_state = "mysterysoup"
- food_reagents = list(
- /datum/reagent/consumable/nutriment = 2,
- /datum/reagent/consumable/nutriment/protein = 5,
- )
- tastes = list("chaos" = 1)
-
-/obj/item/food/soup/mystery/Initialize(mapload)
- . = ..()
- var/extra_reagent = null
- extra_reagent = pick(
- /datum/reagent/blood,
- /datum/reagent/carbon,
- /datum/reagent/consumable/banana,
- /datum/reagent/consumable/capsaicin,
- /datum/reagent/consumable/frostoil,
- /datum/reagent/medicine/oculine,
- /datum/reagent/medicine/omnizine,
- /datum/reagent/toxin,
- /datum/reagent/toxin/slimejelly,
- )
- reagents.add_reagent(extra_reagent, 5)
- reagents.add_reagent(/datum/reagent/consumable/nutriment, 6)
-
-/obj/item/food/soup/hotchili
- name = "hot chili"
- desc = "A five alarm Texan Chili!"
- icon_state = "hotchili"
- food_reagents = list(
- /datum/reagent/consumable/nutriment = 4,
- /datum/reagent/consumable/nutriment/protein = 6,
- /datum/reagent/consumable/capsaicin = 3,
- /datum/reagent/consumable/tomatojuice = 4,
- /datum/reagent/consumable/nutriment/vitamin = 4,
- )
- tastes = list("hot peppers" = 1)
- foodtypes = VEGETABLES | MEAT
- venue_value = FOOD_PRICE_NORMAL
-/obj/item/food/soup/coldchili
- name = "cold chili"
- desc = "This slush is barely a liquid!"
- icon_state = "coldchili"
- food_reagents = list(
- /datum/reagent/consumable/nutriment = 4,
- /datum/reagent/consumable/nutriment/protein = 6,
- /datum/reagent/consumable/frostoil = 3,
- /datum/reagent/consumable/tomatojuice = 4,
- /datum/reagent/consumable/nutriment/vitamin = 4,
- )
- tastes = list("tomato" = 1, "mint" = 1)
- foodtypes = VEGETABLES | MEAT
-
-/obj/item/food/soup/clownchili
- name = "chili con carnival"
- desc = "A delicious stew of meat, chiles, and salty, salty clown tears."
- icon_state = "clownchili"
- food_reagents = list(
- /datum/reagent/consumable/nutriment = 6,
- /datum/reagent/consumable/capsaicin = 1,
- /datum/reagent/consumable/tomatojuice = 4,
- /datum/reagent/consumable/nutriment/vitamin = 4,
- /datum/reagent/consumable/banana = 1,
- /datum/reagent/consumable/laughter = 1,
- )
- tastes = list("tomato" = 1, "hot peppers" = 2, "clown feet" = 2, "kind of funny" = 2, "someone's parents" = 2)
- foodtypes = VEGETABLES | MEAT
-
-/obj/item/food/soup/monkeysdelight
- name = "monkey's delight"
- desc = "A delicious soup with dumplings and hunks of monkey meat simmered to perfection, in a broth that tastes faintly of bananas."
- icon_state = "monkeysdelight"
- food_reagents = list(
- /datum/reagent/consumable/nutriment = 3,
- /datum/reagent/consumable/nutriment/protein = 9,
- /datum/reagent/consumable/banana = 5,
- /datum/reagent/consumable/nutriment/vitamin = 10,
- )
- tastes = list("the jungle" = 1, "banana" = 1)
- foodtypes = FRUIT
- venue_value = FOOD_PRICE_NORMAL
-
-/obj/item/food/soup/tomato
- name = "tomato soup"
- desc = "Drinking this feels like being a vampire! A tomato vampire..."
- icon_state = "tomatosoup"
- food_reagents = list(
- /datum/reagent/consumable/nutriment = 6,
- /datum/reagent/consumable/tomatojuice = 10,
- /datum/reagent/consumable/nutriment/vitamin = 3,
- )
- tastes = list("tomato" = 1)
- foodtypes = VEGETABLES
-
-/obj/item/food/soup/tomato/eyeball
- name = "eyeball soup"
- desc = "It looks back at you..."
- icon_state = "eyeballsoup"
- food_reagents = list(
- /datum/reagent/consumable/nutriment = 2,
- /datum/reagent/consumable/nutriment/protein = 6,
- /datum/reagent/consumable/tomatojuice = 10,
- /datum/reagent/consumable/nutriment/vitamin = 4,
- /datum/reagent/consumable/liquidgibs = 3,
- )
- tastes = list("tomato" = 1, "squirming" = 1)
- foodtypes = MEAT | GORE
-
-/obj/item/food/soup/miso
- name = "miso soup"
- desc = "The universe's best soup! Yum!!!"
- icon_state = "misosoup"
- food_reagents = list(
- /datum/reagent/consumable/nutriment = 4,
- /datum/reagent/consumable/nutriment/protein = 8,
- /datum/reagent/water = 5,
- /datum/reagent/consumable/nutriment/vitamin = 4,
- )
- tastes = list("miso" = 1)
- foodtypes = VEGETABLES | BREAKFAST
- venue_value = FOOD_PRICE_NORMAL
-
-/obj/item/food/soup/mushroom
- name = "chantrelle soup"
- desc = "A delicious and hearty mushroom soup."
- icon_state = "mushroomsoup"
- food_reagents = list(
- /datum/reagent/consumable/nutriment = 9,
- /datum/reagent/consumable/nutriment/vitamin = 6,
- )
- tastes = list("mushroom" = 1)
- foodtypes = VEGETABLES | DAIRY
-
-/obj/item/food/soup/beet
- name = "beet soup"
- desc = "Wait, how do you spell it again...?"
- icon_state = "beetsoup"
- food_reagents = list(
- /datum/reagent/consumable/nutriment = 9,
- /datum/reagent/water = 5,
- /datum/reagent/consumable/nutriment/vitamin = 6,
- )
- foodtypes = VEGETABLES
-
-/obj/item/food/soup/beet/Initialize(mapload)
- . = ..()
- name = pick("borsch", "bortsch", "borstch", "borsh", "borshch", "borscht")
- tastes = list(name = 1)
-
-/obj/item/food/soup/spacylibertyduff
+/obj/item/food/bowled/spacylibertyduff
name = "spacy liberty duff"
desc = "Jello gelatin, from Alfred Hubbard's cookbook."
icon_state = "spacylibertyduff"
@@ -288,7 +44,7 @@
tastes = list("jelly" = 1, "mushroom" = 1)
foodtypes = VEGETABLES
-/obj/item/food/soup/amanitajelly
+/obj/item/food/bowled/amanitajelly
name = "amanita jelly"
desc = "Looks curiously toxic."
icon_state = "amanitajelly"
@@ -301,187 +57,3 @@
)
tastes = list("jelly" = 1, "mushroom" = 1)
foodtypes = VEGETABLES | TOXIC
-
-/obj/item/food/soup/stew
- name = "stew"
- desc = "A nice and warm stew. Healthy and strong."
- icon_state = "stew"
- food_reagents = list(
- /datum/reagent/consumable/nutriment = 11,
- /datum/reagent/consumable/tomatojuice = 10,
- /datum/reagent/consumable/nutriment/vitamin = 6,
- )
- bite_consumption = 7
- max_volume = 100
- tastes = list("tomato" = 1, "carrot" = 1)
- foodtypes = VEGETABLES | MEAT
- venue_value = FOOD_PRICE_NORMAL
-
-/obj/item/food/soup/sweetpotato
- name = "sweet potato soup"
- desc = "Delicious sweet potato in soup form."
- icon_state = "sweetpotatosoup"
- food_reagents = list(
- /datum/reagent/consumable/nutriment = 12,
- /datum/reagent/water = 5,
- /datum/reagent/consumable/nutriment/vitamin = 6,
- )
- tastes = list("sweet potato" = 1)
- foodtypes = VEGETABLES | SUGAR
- venue_value = FOOD_PRICE_NORMAL
-
-/obj/item/food/soup/beet/red
- name = "red beet soup"
- desc = "Quite a delicacy."
- icon_state = "redbeetsoup"
- food_reagents = list(
- /datum/reagent/consumable/nutriment = 12,
- /datum/reagent/water = 5,
- /datum/reagent/consumable/nutriment/vitamin = 3,
- )
- tastes = list("beet" = 1)
- foodtypes = VEGETABLES
-
-/obj/item/food/soup/onion
- name = "french onion soup"
- desc = "Good enough to make a grown mime cry."
- icon_state = "onionsoup"
- food_reagents = list(
- /datum/reagent/consumable/nutriment = 7,
- /datum/reagent/consumable/nutriment/protein = 8,
- /datum/reagent/consumable/tomatojuice = 8,
- /datum/reagent/consumable/nutriment/vitamin = 5,
- )
- tastes = list("caramelized onions" = 1)
- foodtypes = VEGETABLES | DAIRY
-
-/obj/item/food/soup/bisque
- name = "bisque"
- desc = "A classic entree from Space-France."
- icon_state = "bisque"
- food_reagents = list(
- /datum/reagent/consumable/nutriment = 6,
- /datum/reagent/consumable/nutriment/protein = 6,
- /datum/reagent/water = 5,
- /datum/reagent/consumable/nutriment/vitamin = 6,
- )
- tastes = list("creamy texture" = 1, "crab" = 4)
- foodtypes = MEAT
- venue_value = FOOD_PRICE_EXOTIC
-
-/obj/item/food/soup/electron
- name = "electron soup"
- desc = "A gastronomic curiosity of ethereal origin. It is famed for the minature weather system formed over a properly prepared soup."
- icon_state = "electronsoup"
- food_reagents = list(
- /datum/reagent/consumable/nutriment = 3,
- /datum/reagent/consumable/liquidelectricity/enriched = 12,
- )
- tastes = list("mushroom" = 1, "electrons" = 4)
- foodtypes = VEGETABLES | TOXIC
-
-/obj/item/food/soup/bungocurry
- name = "bungo curry"
- desc = "A spicy vegetable curry made with the humble bungo fruit, Exotic!"
- icon_state = "bungocurry"
- food_reagents = list(
- /datum/reagent/consumable/nutriment = 6,
- /datum/reagent/consumable/bungojuice = 9,
- /datum/reagent/consumable/capsaicin = 5,
- /datum/reagent/consumable/nutriment/vitamin = 5,
- )
- tastes = list("bungo" = 2, "hot curry" = 4, "tropical sweetness" = 1)
- foodtypes = VEGETABLES | FRUIT | DAIRY
-
-/obj/item/food/soup/mammi
- name = "Mammi"
- desc = "A bowl of mushy bread and milk. It reminds you, not too fondly, of a bowel movement."
- icon_state = "mammi"
- food_reagents = list(
- /datum/reagent/consumable/nutriment = 11,
- /datum/reagent/consumable/nutriment/vitamin = 2,
- )
-
-/obj/item/food/soup/peasoup
- name = "pea soup"
- desc = "A humble split pea soup."
- icon_state = "peasoup"
- food_reagents = list (
- /datum/reagent/consumable/nutriment = 8,
- /datum/reagent/consumable/nutriment/vitamin = 5,
- )
- tastes = list("creamy peas"= 2, "parsnip" = 1)
- foodtypes = VEGETABLES
-
-/obj/item/food/soup/indian_curry
- name = "indian chicken curry"
- desc = "A mild, creamy curry from the old subcontinent. Liked by the Space-British, because it reminds them of the Raj."
- icon_state = "indian_curry"
- food_reagents = list(
- /datum/reagent/consumable/nutriment = 8,
- /datum/reagent/consumable/capsaicin = 1,
- /datum/reagent/consumable/nutriment/vitamin = 4,
- )
- tastes = list("chicken" = 2, "creamy curry" = 4, "earthy heat" = 1)
- foodtypes = VEGETABLES | MEAT | DAIRY
- venue_value = FOOD_PRICE_NORMAL
-
-/obj/item/food/soup/oatmeal
- name = "oatmeal"
- desc = "A nice bowl of oatmeal."
- icon_state = "oatmeal"
- food_reagents = list(
- /datum/reagent/consumable/nutriment = 11,
- /datum/reagent/consumable/milk = 10,
- /datum/reagent/consumable/nutriment/vitamin = 6,
- )
- tastes = list("oats" = 1, "milk" = 1)
- foodtypes = DAIRY | GRAIN | BREAKFAST
-
-/obj/item/food/soup/zurek
- name = "zurek"
- desc = "A traditional Polish soup composed of vegetables, meat, and an egg. Goes great with bread."
- icon_state = "zurek"
- food_reagents = list (
- /datum/reagent/consumable/nutriment = 8,
- /datum/reagent/consumable/nutriment/vitamin = 2,
- /datum/reagent/consumable/nutriment/protein = 2,
- )
- tastes = list("creamy vegetables"= 2, "sausage" = 1)
- foodtypes = VEGETABLES | MEAT | GRAIN | BREAKFAST
-
-/obj/item/food/soup/cullen_skink
- name = "cullen skink"
- desc = "A thick Scottish soup made of smoked fish, potatoes and onions."
- icon_state = "cullen_skink"
- food_reagents = list (
- /datum/reagent/consumable/nutriment = 12,
- /datum/reagent/consumable/nutriment/vitamin = 4,
- /datum/reagent/consumable/nutriment/protein = 6,
- )
- tastes = list("creamy broth" = 1, "fish" = 1, "vegetables" = 1)
- foodtypes = VEGETABLES | SEAFOOD | DAIRY
-
-/obj/item/food/soup/chicken_noodle_soup
- name = "chicken noodle soup"
- desc = "A hearty bowl of chicken noodle soup, perfect for when you're stuck at home and sick."
- icon_state = "chicken_noodle_soup"
- food_reagents = list (
- /datum/reagent/consumable/nutriment = 8,
- /datum/reagent/consumable/nutriment/vitamin = 8,
- /datum/reagent/consumable/nutriment/protein = 6,
- )
- tastes = list("broth" = 1, "chicken" = 1, "noodles" = 1, "carrots" = 1)
- foodtypes = VEGETABLES | MEAT | GRAIN
-
-/obj/item/food/soup/corn_chowder
- name = "corn chowder"
- desc = "A creamy bowl of corn chowder, with bacon bits and mixed vegetables. One bowl is never enough."
- icon_state = "corn_chowder"
- food_reagents = list (
- /datum/reagent/consumable/nutriment = 10,
- /datum/reagent/consumable/nutriment/vitamin = 8,
- /datum/reagent/consumable/nutriment/protein = 6,
- )
- tastes = list("creamy broth" = 1, "bacon" = 1, "mixed vegetables" = 1)
- foodtypes = VEGETABLES | MEAT
diff --git a/code/game/objects/items/kitchen.dm b/code/game/objects/items/kitchen.dm
index 139777dd757..03c64de236e 100644
--- a/code/game/objects/items/kitchen.dm
+++ b/code/game/objects/items/kitchen.dm
@@ -73,7 +73,7 @@
w_class = WEIGHT_CLASS_TINY
throwforce = 0
custom_materials = list(/datum/material/plastic=80)
- custom_price = PAYCHECK_LOWER * 2
+ custom_price = PAYCHECK_LOWER * 1
/obj/item/kitchen/fork/plastic/Initialize(mapload)
. = ..()
@@ -140,6 +140,7 @@
name = "spoon"
desc = "Just be careful your food doesn't melt the spoon first."
icon_state = "spoon"
+ base_icon_state = "spoon"
w_class = WEIGHT_CLASS_TINY
flags_1 = CONDUCT_1
force = 2
@@ -149,17 +150,109 @@
attack_verb_continuous = list("whacks", "spoons", "taps")
armor_type = /datum/armor/kitchen_spoon
custom_materials = list(/datum/material/iron=120)
- custom_price = PAYCHECK_LOWER * 5
+ custom_price = PAYCHECK_LOWER * 2
tool_behaviour = TOOL_MINING
toolspeed = 25 // Literally 25 times worse than the base pickaxe
+ var/spoon_sip_size = 5
+
+/obj/item/kitchen/spoon/Initialize(mapload)
+ . = ..()
+ create_reagents(5, INJECTABLE|OPENCONTAINER|DUNKABLE)
+ register_item_context()
+
+/obj/item/kitchen/spoon/add_item_context(obj/item/source, list/context, atom/target, mob/living/user)
+ if(target.is_open_container())
+ context[SCREENTIP_CONTEXT_LMB] = "Empty spoonful"
+ context[SCREENTIP_CONTEXT_RMB] = "Grab spoonful"
+ return CONTEXTUAL_SCREENTIP_SET
+ if(isliving(target))
+ context[SCREENTIP_CONTEXT_LMB] = target == user ? "[spoon_sip_size >= reagents.maximum_volume ? "Swallow" : "Taste"] spoonful" : "Give spoonful"
+ return CONTEXTUAL_SCREENTIP_SET
+ return NONE
+
+/obj/item/kitchen/spoon/update_overlays()
+ . = ..()
+ if(reagents.total_volume <= 0)
+ return
+ var/mutable_appearance/filled_overlay = mutable_appearance(icon, "[base_icon_state]_filled")
+ filled_overlay.color = mix_color_from_reagents(reagents.reagent_list)
+ . += filled_overlay
+
+/obj/item/kitchen/spoon/attack(mob/living/target_mob, mob/living/user, params)
+ if(!target_mob.reagents || reagents.total_volume <= 0)
+ return ..()
+
+ if(target_mob == user)
+ user.visible_message(
+ span_notice("[user] scoops a spoonful into [user.p_their()] mouth."),
+ span_notice("You scoop a spoonful into your mouth.")
+ )
+
+ else
+ to_chat(target_mob, span_userdanger("[target_mob.is_blind() ? "Someone" : "[user]"] forces a spoon into your face!"))
+ target_mob.balloon_alert(user, "feeding spoonful...")
+ if(!do_after(user, 3 SECONDS, target_mob))
+ target_mob.balloon_alert(user, "interrupted!")
+ return TRUE
+
+ to_chat(target_mob, span_userdanger("[target_mob.is_blind() ? "You are forced to" : "[user] forces you to"] swallow a spoonful of something!"))
+ user.visible_message(
+ span_danger("[user] scoops a spoonful into [target_mob]'s mouth."),
+ span_notice("You scoop a spoonful into [target_mob]'s mouth.")
+ )
+
+ playsound(target_mob, 'sound/items/drink.ogg', rand(10,50), vary = TRUE)
+ reagents.trans_to(target_mob, spoon_sip_size, methods = INGEST)
+ return TRUE
+
+/obj/item/kitchen/spoon/pre_attack(atom/attacked_atom, mob/living/user, params)
+ . = ..()
+ if(.)
+ return
+ if(isliving(attacked_atom))
+ return
+ if(!attacked_atom.is_open_container())
+ return
+ if(reagents.total_volume <= 0)
+ return
+
+ var/amount_given = reagents.trans_to(attacked_atom, reagents.maximum_volume)
+ if(amount_given >= reagents.total_volume)
+ attacked_atom.balloon_alert(user, "spoon emptied")
+ else if(amount_given > 0)
+ attacked_atom.balloon_alert(user, "spoon partially emptied")
+ else
+ attacked_atom.balloon_alert(user, "it's full!")
+ update_appearance(UPDATE_OVERLAYS)
+ return TRUE
+
+/obj/item/kitchen/spoon/pre_attack_secondary(atom/attacked_atom, mob/living/user, params)
+ . = ..()
+ if(. == SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN)
+ return
+ if(isliving(attacked_atom))
+ return SECONDARY_ATTACK_CALL_NORMAL
+ if(!attacked_atom.is_open_container())
+ return SECONDARY_ATTACK_CALL_NORMAL
+
+ if(reagents.total_volume >= reagents.maximum_volume || attacked_atom.reagents.total_volume <= 0)
+ return SECONDARY_ATTACK_CALL_NORMAL
+
+ if(attacked_atom.reagents.trans_to(src, reagents.maximum_volume))
+ attacked_atom.balloon_alert(user, "grabbed spoonful")
+ else
+ attacked_atom.balloon_alert(user, "spoon is full!")
+ update_appearance(UPDATE_OVERLAYS)
+ return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN
+
/obj/item/kitchen/spoon/plastic
name = "plastic spoon"
icon_state = "plastic_spoon"
force = 0
custom_materials = list(/datum/material/plastic=120)
- custom_price = PAYCHECK_LOWER * 2
toolspeed = 75 // The plastic spoon takes 5 minutes to dig through a single mineral turf... It's one, continuous, breakable, do_after...
+ custom_price = PAYCHECK_LOWER * 1
/datum/armor/kitchen_spoon
fire = 50
@@ -169,4 +262,17 @@
. = ..()
AddElement(/datum/element/easily_fragmented, PLASTIC_BREAK_PROBABILITY)
+/obj/item/kitchen/spoon/soup_ladle
+ name = "ladle"
+ desc = "What is a ladle but a comically large spoon?"
+ icon_state = "ladle"
+ base_icon_state = "ladle"
+ inhand_icon_state = "spoon"
+ custom_price = PAYCHECK_LOWER * 4
+ spoon_sip_size = 3 // just a taste
+
+/obj/item/kitchen/spoon/soup_ladle/Initialize(mapload)
+ . = ..()
+ create_reagents(SOUP_SERVING_SIZE + 5, INJECTABLE|OPENCONTAINER)
+
#undef PLASTIC_BREAK_PROBABILITY
diff --git a/code/modules/asset_cache/assets/crafting.dm b/code/modules/asset_cache/assets/crafting.dm
index 8f38cd19bfa..80b95be169f 100644
--- a/code/modules/asset_cache/assets/crafting.dm
+++ b/code/modules/asset_cache/assets/crafting.dm
@@ -2,33 +2,47 @@
/datum/asset/spritesheet/crafting
name = "crafting"
-/datum/asset/spritesheet/crafting/cooking
- name = "cooking"
-
/datum/asset/spritesheet/crafting/create_spritesheets()
var/id = 1
for(var/atom in GLOB.crafting_recipes_atoms)
add_atom_icon(atom, id++)
add_tool_icons()
+/datum/asset/spritesheet/crafting/cooking
+ name = "cooking"
+
/datum/asset/spritesheet/crafting/cooking/create_spritesheets()
var/id = 1
for(var/atom in GLOB.cooking_recipes_atoms)
add_atom_icon(atom, id++)
-///Adds the atom icon to the spritesheet with given ID
-/datum/asset/spritesheet/crafting/proc/add_atom_icon(atom, id)
- var/obj/obj = initial(atom)
- if(ispath(atom, /datum/reagent))
- var/datum/reagent/reagent = atom
- obj = initial(reagent.default_container)
- var/icon_file = initial(obj.icon_preview) || initial(obj.icon)
- var/icon_state = initial(obj.icon_state_preview) || initial(obj.icon_state)
- #ifdef UNIT_TESTS
- if(!(icon_state in icon_states(icon_file)))
- stack_trace("Atom [atom] with icon '[icon_file]' missing state '[icon_state]'")
- return
- #endif
+/**
+ * Adds the ingredient icon to the spritesheet with given ID
+ *
+ * ingredient_typepath can be an obj typepath OR a reagent typepath
+ *
+ * If it a reagent, it will use the default container's icon state,
+ * OR if it has a glass style associated, it will use that
+ */
+/datum/asset/spritesheet/crafting/proc/add_atom_icon(ingredient_typepath, id)
+ var/icon_file
+ var/icon_state
+ var/obj/preview_item = ingredient_typepath
+ if(ispath(ingredient_typepath, /datum/reagent))
+ var/datum/reagent/reagent = ingredient_typepath
+ preview_item = initial(reagent.default_container)
+ var/datum/glass_style/style = GLOB.glass_style_singletons[preview_item]?[reagent]
+ if(istype(style))
+ icon_file = style.icon
+ icon_state = style.icon_state
+
+ icon_file ||= initial(preview_item.icon_preview) || initial(preview_item.icon)
+ icon_state ||= initial(preview_item.icon_state_preview) || initial(preview_item.icon_state)
+
+ if(PERFORM_ALL_TESTS(focus_only/bad_cooking_crafting_icons))
+ if(!icon_exists(icon_file, icon_state, scream = TRUE))
+ return
+
Insert("a[id]", icon(icon_file, icon_state, SOUTH))
///Adds tool icons to the spritesheet
diff --git a/code/modules/cargo/bounties/chef.dm b/code/modules/cargo/bounties/chef.dm
index 905e04dbba1..db65252df68 100644
--- a/code/modules/cargo/bounties/chef.dm
+++ b/code/modules/cargo/bounties/chef.dm
@@ -7,12 +7,18 @@
/obj/item/food/cakeslice/birthday = TRUE
)
-/datum/bounty/item/chef/soup
+/datum/bounty/reagent/chef/soup
name = "Soup"
- description = "To quell the homeless uprising, Nanotrasen will be serving soup to all underpaid workers. Ship any type of soup."
- reward = CARGO_CRATE_VALUE * 6
- required_count = 3
- wanted_types = list(/obj/item/food/soup = TRUE)
+ description = "To quell the homeless uprising, Nanotrasen will be serving soup to all underpaid workers."
+
+/datum/bounty/reagent/chef/soup/New()
+ . = ..()
+ required_volume = pick(10, 15, 20, 25)
+ wanted_reagent = pick(subtypesof(/datum/reagent/consumable/nutriment/soup))
+ reward = CARGO_CRATE_VALUE * round(required_volume / 3)
+ // In the future there could be tiers of soup bounty corresponding to soup difficulty
+ // (IE, stew is harder to make than tomato soup, so it should reward more)
+ description += " Send us [required_volume] units of [initial(wanted_reagent.name)]."
/datum/bounty/item/chef/popcorn
name = "Popcorn Bags"
diff --git a/code/modules/cargo/bounty.dm b/code/modules/cargo/bounty.dm
index 18d176ddc86..aa527e84762 100644
--- a/code/modules/cargo/bounty.dm
+++ b/code/modules/cargo/bounty.dm
@@ -47,7 +47,7 @@
if(CIV_JOB_ROBO)
chosen_type = pick(subtypesof(/datum/bounty/item/mech))
if(CIV_JOB_CHEF)
- chosen_type = pick(subtypesof(/datum/bounty/item/chef))
+ chosen_type = pick(subtypesof(/datum/bounty/item/chef) + subtypesof(/datum/bounty/reagent/chef))
if(CIV_JOB_SEC)
chosen_type = pick(subtypesof(/datum/bounty/item/security))
if(CIV_JOB_DRINK)
diff --git a/code/modules/cargo/markets/market_items/consumables.dm b/code/modules/cargo/markets/market_items/consumables.dm
index 32955b8f843..153241e5d3d 100644
--- a/code/modules/cargo/markets/market_items/consumables.dm
+++ b/code/modules/cargo/markets/market_items/consumables.dm
@@ -2,9 +2,9 @@
category = "Consumables"
/datum/market_item/consumable/clown_tears
- name = "Bowl of Clown's Tears"
+ name = "Bottle of Clown's Tears"
desc = "Guaranteed fresh from Weepy Boggins Tragic Kitchen"
- item = /obj/item/food/soup/clownstears
+ item = /obj/item/reagent_containers/cup/bottle/clownstears
stock = 1
price_min = CARGO_CRATE_VALUE * 2.6
diff --git a/code/modules/events/holiday/easter.dm b/code/modules/events/holiday/easter.dm
index f3e853eb4b6..f4fa2a038e0 100644
--- a/code/modules/events/holiday/easter.dm
+++ b/code/modules/events/holiday/easter.dm
@@ -186,7 +186,7 @@
/obj/item/food/chocolatebar = 1,
/datum/reagent/consumable/milk = 5
)
- result = /obj/item/food/soup/mammi
+ result = /obj/item/food/bowled/mammi
category = CAT_MISCFOOD
/obj/item/food/chocolatebunny
diff --git a/code/modules/food_and_drinks/machinery/griddle.dm b/code/modules/food_and_drinks/machinery/griddle.dm
index e7db23898be..2bb01f65e57 100644
--- a/code/modules/food_and_drinks/machinery/griddle.dm
+++ b/code/modules/food_and_drinks/machinery/griddle.dm
@@ -6,6 +6,7 @@
density = TRUE
pass_flags_self = PASSMACHINE | PASSTABLE| LETPASSTHROW // It's roughly the height of a table.
idle_power_usage = BASE_MACHINE_IDLE_CONSUMPTION * 0.05
+ active_power_usage = BASE_MACHINE_ACTIVE_CONSUMPTION
layer = BELOW_OBJ_LAYER
circuit = /obj/item/circuitboard/machine/griddle
processing_flags = START_PROCESSING_MANUALLY
@@ -152,9 +153,7 @@
return STORAGE_DUMP_HANDLED
/obj/machinery/griddle/process(delta_time)
- ..()
- for(var/i in griddled_objects)
- var/obj/item/griddled_item = i
+ for(var/obj/item/griddled_item as anything in griddled_objects)
if(SEND_SIGNAL(griddled_item, COMSIG_ITEM_GRILL_PROCESS, src, delta_time) & COMPONENT_HANDLED_GRILLING)
continue
griddled_item.fire_act(1000) //Hot hot hot!
@@ -163,6 +162,10 @@
use_power(active_power_usage)
+ var/turf/griddle_loc = loc
+ if(isturf(griddle_loc))
+ griddle_loc.hotspot_expose(800, 100)
+
/obj/machinery/griddle/update_icon_state()
icon_state = "griddle[variant]_[on ? "on" : "off"]"
return ..()
diff --git a/code/modules/food_and_drinks/machinery/oven.dm b/code/modules/food_and_drinks/machinery/oven.dm
index a93e69bd8de..a63b41ef58e 100644
--- a/code/modules/food_and_drinks/machinery/oven.dm
+++ b/code/modules/food_and_drinks/machinery/oven.dm
@@ -13,12 +13,15 @@
desc = "Why do they call it oven when you of in the cold food of out hot eat the food?"
icon = 'icons/obj/machines/kitchenmachines.dmi'
icon_state = "oven_off"
+ base_icon_state = "oven"
density = TRUE
pass_flags_self = PASSMACHINE | LETPASSTHROW
layer = BELOW_OBJ_LAYER
circuit = /obj/item/circuitboard/machine/oven
processing_flags = START_PROCESSING_MANUALLY
resistance_flags = FIRE_PROOF
+ idle_power_usage = BASE_MACHINE_IDLE_CONSUMPTION * 0.1
+ active_power_usage = BASE_MACHINE_ACTIVE_CONSUMPTION * 0.8
///The tray inside of this oven, if there is one.
var/obj/item/plate/oven_tray/used_tray
@@ -32,36 +35,44 @@
/obj/machinery/oven/Initialize(mapload)
. = ..()
oven_loop = new(src)
- add_tray_to_oven(new /obj/item/plate/oven_tray(src)) //Start with a tray
+ if(mapload)
+ add_tray_to_oven(new /obj/item/plate/oven_tray(src)) //Start with a tray
/obj/machinery/oven/Destroy()
QDEL_NULL(oven_loop)
QDEL_NULL(particles)
- . = ..()
+ return ..()
+
+/// Used to determine if the oven appears active and cooking, or offline.
+/obj/machinery/oven/proc/appears_active()
+ return !open && length(used_tray?.contents) && !(machine_stat & (BROKEN|NOPOWER))
/obj/machinery/oven/update_icon_state()
- if(!open && used_tray?.contents.len)
- icon_state = "oven_on"
+ if(appears_active())
+ icon_state = "[base_icon_state]_on"
else
- icon_state = "oven_off"
+ icon_state = "[base_icon_state]_off"
return ..()
/obj/machinery/oven/update_overlays()
. = ..()
if(open)
- var/mutable_appearance/door_overlay = mutable_appearance(icon, "oven_lid_open")
+ var/mutable_appearance/door_overlay = mutable_appearance(icon, "[base_icon_state]_lid_open")
door_overlay.pixel_y = OVEN_LID_Y_OFFSET
. += door_overlay
else
- . += mutable_appearance(icon, "oven_lid_closed")
- if(used_tray?.contents.len)
- . += emissive_appearance(icon, "oven_light_mask", src, alpha = src.alpha)
+ . += mutable_appearance(icon, "[base_icon_state]_lid_closed")
+ if(length(used_tray?.contents))
+ . += emissive_appearance(icon, "[base_icon_state]_light_mask", src, alpha = src.alpha)
/obj/machinery/oven/process(delta_time)
- ..()
- if(!used_tray) //Are we actually working?
+ if(!appears_active())
set_smoke_state(OVEN_SMOKE_STATE_NONE)
+ update_baking_audio()
+ update_appearance(UPDATE_ICON)
+ end_processing()
return
+
///We take the worst smoke state, so if something is burning we always know.
var/worst_cooked_food_state = 0
for(var/obj/item/baked_item in used_tray.contents)
@@ -152,7 +163,7 @@
/obj/machinery/oven/proc/update_baking_audio()
if(!oven_loop)
return
- if(!open && used_tray?.contents.len)
+ if(appears_active())
oven_loop.start()
else
oven_loop.stop()
@@ -170,7 +181,7 @@
if(OVEN_SMOKE_STATE_NEUTRAL)
particles = new /particles/smoke/steam()
if(OVEN_SMOKE_STATE_GOOD)
- particles = new /particles/smoke/steam/mild
+ particles = new /particles/smoke/steam/mild()
/obj/machinery/oven/crowbar_act(mob/living/user, obj/item/tool)
return default_deconstruction_crowbar(tool, ignore_panel = TRUE)
@@ -179,6 +190,22 @@
default_unfasten_wrench(user, tool, time = 2 SECONDS)
return TOOL_ACT_TOOLTYPE_SUCCESS
+/obj/machinery/oven/range
+ name = "range"
+ desc = "And Oven AND a Stove? I guess that's why it's got range!"
+ icon_state = "range_off"
+ base_icon_state = "range"
+ pass_flags_self = PASSMACHINE|PASSTABLE|LETPASSTHROW // Like the griddle, short
+ active_power_usage = BASE_MACHINE_ACTIVE_CONSUMPTION * 1.2
+ circuit = /obj/item/circuitboard/machine/range
+
+/obj/machinery/oven/range/Initialize(mapload)
+ . = ..()
+ var/obj/item/reagent_containers/cup/soup_pot/mapload_container
+ if(mapload)
+ mapload_container = new(loc)
+
+ AddComponent(/datum/component/stove, container_x = -6, container_y = 14, spawn_container = mapload_container)
/obj/item/plate/oven_tray
name = "oven tray"
diff --git a/code/modules/food_and_drinks/machinery/stove.dm b/code/modules/food_and_drinks/machinery/stove.dm
new file mode 100644
index 00000000000..8382e6ff98f
--- /dev/null
+++ b/code/modules/food_and_drinks/machinery/stove.dm
@@ -0,0 +1,201 @@
+/obj/machinery/stove
+ name = "stove"
+ desc = "You'd think this thing would be more useful in here."
+ icon = 'icons/obj/machines/kitchen_stove.dmi'
+ icon_state = "stove"
+ base_icon_state = "stove"
+ density = TRUE
+ pass_flags_self = PASSMACHINE | LETPASSTHROW
+ layer = BELOW_OBJ_LAYER
+ circuit = /obj/item/circuitboard/machine/stove
+ processing_flags = START_PROCESSING_MANUALLY
+ resistance_flags = FIRE_PROOF
+ idle_power_usage = BASE_MACHINE_IDLE_CONSUMPTION * 0.1
+ active_power_usage = BASE_MACHINE_IDLE_CONSUMPTION * 0.8
+
+ // Stove icon is 32x48, we'll use a Range for preview instead
+ icon_preview = 'icons/obj/machines/kitchenmachines.dmi'
+ icon_state_preview = "range_off"
+
+/obj/machinery/stove/Initialize(mapload)
+ . = ..()
+ AddComponent(/datum/component/stove, container_x = -6, container_y = 16)
+
+// Soup pot for cooking soup
+// Future addention ideas:
+// - Thermostat you can stick in the pot to see in examine the temperature
+// - Tasting the pot to learn its exact contents w/o sci goggles (chef skillchip?)
+/obj/item/reagent_containers/cup/soup_pot
+ name = "soup pot"
+ desc = "A tall soup designed to mix and cook all kinds of soup."
+ icon = 'icons/obj/soup_pot.dmi'
+ icon_state = "pot"
+ base_icon_state = "pot"
+ volume = 200
+ possible_transfer_amounts = list(20, 50, 100, 200)
+ amount_per_transfer_from_this = 50
+ amount_list_position = 2
+ reagent_flags = REFILLABLE | DRAINABLE
+ custom_materials = list(/datum/material/iron = 5000)
+ w_class = WEIGHT_CLASS_BULKY
+ custom_price = PAYCHECK_LOWER * 8
+ fill_icon_thresholds = null
+
+ /// Max number of ingredients we can add
+ var/max_ingredients = 24
+ /// A lazylist of all the ingredients we have added
+ var/list/obj/item/added_ingredients
+
+/obj/item/reagent_containers/cup/soup_pot/Initialize(mapload, vol)
+ . = ..()
+ RegisterSignal(reagents, COMSIG_REAGENTS_CLEAR_REAGENTS, PROC_REF(on_reagents_cleared))
+ RegisterSignal(src, COMSIG_PARENT_REAGENT_EXAMINE, PROC_REF(reagent_special_examine))
+ register_context()
+
+/obj/item/reagent_containers/cup/soup_pot/add_context(atom/source, list/context, obj/item/held_item, mob/user)
+ if(isnull(held_item))
+ context[SCREENTIP_CONTEXT_RMB] = "Remove ingredient"
+ return CONTEXTUAL_SCREENTIP_SET
+
+ else if(can_add_ingredient(held_item))
+ context[SCREENTIP_CONTEXT_LMB] = "Add ingredient"
+ return CONTEXTUAL_SCREENTIP_SET
+
+ return NONE
+
+/obj/item/reagent_containers/cup/soup_pot/examine(mob/user)
+ . = ..()
+ . += span_notice("There's room for [max_ingredients - LAZYLEN(added_ingredients)] more ingredients \
+ or [reagents.maximum_volume - reagents.total_volume] more units of reagents in there.")
+
+/**
+ * Override standard reagent examine with something a bit more sensible for the soup pot,
+ * including the ingredients we have within as well
+ */
+/obj/item/reagent_containers/cup/soup_pot/proc/reagent_special_examine(datum/source, mob/user, list/examine_list, can_see_insides = FALSE)
+ SIGNAL_HANDLER
+
+ examine_list += "Inside, you can see:"
+
+ if(LAZYLEN(added_ingredients) || reagents.total_volume > 0)
+ var/list/ingredient_amounts = list()
+ for(var/obj/item/ingredient as anything in added_ingredients)
+ ingredient_amounts[ingredient.type] += 1
+
+ for(var/obj/item/ingredient_type as anything in ingredient_amounts)
+ examine_list += "• [ingredient_amounts[ingredient_type]] [initial(ingredient_type.name)]\s"
+
+ var/unknown_volume = 0
+ for(var/datum/reagent/current_reagent as anything in reagents.reagent_list)
+ if(can_see_insides \
+ || istype(current_reagent, /datum/reagent/water) \
+ || istype(current_reagent, /datum/reagent/consumable) \
+ )
+ examine_list += "• [round(current_reagent.volume, 0.01)] units of [current_reagent.name]"
+ else
+ unknown_volume += current_reagent.volume
+
+ if(unknown_volume > 0)
+ examine_list += "• [round(unknown_volume, 0.01)] units of unknown reagents"
+
+ if(reagents.total_volume > 0)
+ if(can_see_insides)
+ examine_list += span_notice("The contents of [src] have a temperature of [reagents.chem_temp]K.")
+ else if(reagents.chem_temp > WATER_BOILING_POINT) // boiling point
+ examine_list += span_notice("The contents of [src] are boiling.")
+
+ else
+ examine_list += "Nothing."
+
+ if(reagents.is_reacting)
+ examine_list += span_warning("It is currently mixing!")
+
+ return STOP_GENERIC_REAGENT_EXAMINE
+
+/obj/item/reagent_containers/cup/soup_pot/Exited(atom/movable/gone, direction)
+ . = ..()
+ LAZYREMOVE(added_ingredients, gone)
+
+/obj/item/reagent_containers/cup/soup_pot/attackby(obj/item/attacking_item, mob/user, params)
+ . = ..()
+ if(.)
+ return
+
+ if(!can_add_ingredient(attacking_item))
+ return FALSE
+
+ // Too many ingredients
+ if(LAZYLEN(added_ingredients) >= max_ingredients)
+ balloon_alert(user, "too many ingredients!")
+ return TRUE
+ if(!user.transferItemToLoc(attacking_item, src))
+ balloon_alert(user, "can't add that!")
+ return TRUE
+
+ var/atom/balloon_loc = ismachinery(loc) ? loc : src
+ balloon_loc.balloon_alert(user, "ingredient added")
+ user.face_atom(balloon_loc)
+ LAZYADD(added_ingredients, attacking_item)
+
+ update_appearance(UPDATE_OVERLAYS)
+ return TRUE
+
+/obj/item/reagent_containers/cup/soup_pot/attack_hand_secondary(mob/user, list/modifiers)
+ if(!LAZYLEN(added_ingredients))
+ return SECONDARY_ATTACK_CALL_NORMAL
+
+ var/obj/item/removed = added_ingredients[1]
+ removed.forceMove(get_turf(src))
+ user.put_in_hands(removed)
+ var/atom/balloon_loc = ismachinery(loc) ? loc : src
+ balloon_loc.balloon_alert(user, "ingredient removed")
+ user.face_atom(balloon_loc)
+
+ update_appearance(UPDATE_OVERLAYS)
+ return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN
+
+/obj/item/reagent_containers/cup/soup_pot/proc/can_add_ingredient(obj/item/ingredient)
+ // Let default reagent handling take this
+ if(ingredient.is_open_container())
+ return FALSE
+ // To big for the pot
+ if(ingredient.w_class >= WEIGHT_CLASS_BULKY)
+ return FALSE
+ if(ingredient.item_flags & (ABSTRACT|DROPDEL|HAND_ITEM))
+ return FALSE
+ if(HAS_TRAIT(ingredient, TRAIT_NO_STORAGE_INSERT))
+ return FALSE
+ return TRUE
+
+/obj/item/reagent_containers/cup/soup_pot/proc/on_reagents_cleared(datum/source, datum/reagent/changed)
+ SIGNAL_HANDLER
+
+ dump_ingredients()
+
+/obj/item/reagent_containers/cup/soup_pot/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum, do_splash)
+ . = ..()
+ if(!. && LAZYLEN(added_ingredients))
+ // Clearing reagents Will do this for us already, but if we have no reagents this is a failsafe
+ dump_ingredients()
+
+/obj/item/reagent_containers/cup/soup_pot/proc/dump_ingredients(atom/drop_loc = drop_location())
+ for(var/obj/item/ingredient as anything in added_ingredients)
+ ingredient.forceMove(drop_loc)
+ ingredient.pixel_x += rand(-4, 4)
+ ingredient.pixel_y += rand(-4, 4)
+ ingredient.SpinAnimation(loops = 1)
+ update_appearance(UPDATE_OVERLAYS)
+
+/obj/item/reagent_containers/cup/soup_pot/update_overlays()
+ . = ..()
+ if(length(added_ingredients) <= 0 && reagents.total_volume <= 0)
+ return
+ var/mutable_appearance/filled_overlay = mutable_appearance(icon, "[base_icon_state]_filling_overlay")
+ var/list/food_reagents = list()
+ for(var/obj/item/ingredient as anything in added_ingredients)
+ if(isnull(ingredient.reagents))
+ continue
+ food_reagents |= ingredient.reagents.reagent_list
+
+ filled_overlay.color = mix_color_from_reagents(reagents.reagent_list + food_reagents)
+ . += filled_overlay
diff --git a/code/modules/food_and_drinks/machinery/stove_component.dm b/code/modules/food_and_drinks/machinery/stove_component.dm
new file mode 100644
index 00000000000..cb3e4e051fa
--- /dev/null
+++ b/code/modules/food_and_drinks/machinery/stove_component.dm
@@ -0,0 +1,244 @@
+/**
+ * # Stove Component
+ *
+ * Makes the attached object a stove
+ *
+ * Pots can be put on the stove to make soup, and attack-handing it will start processing
+ * where it will heat up the pot's reagents inside
+ */
+/datum/component/stove
+ /// Whether we're currently cooking
+ VAR_FINAL/on = FALSE
+ /// A reference to the current soup pot overtop
+ VAR_FINAL/obj/item/container
+ /// A particle holder for the smoke that comes out of the soup while a container is cooking.
+ VAR_FINAL/obj/effect/abstract/particle_holder/soup_smoke
+ /// Typepath of particles to use for the particle holder.
+ VAR_FINAL/particle_type = /particles/smoke/steam/mild
+ /// The color of the flames around the burner.
+ var/flame_color = "#006eff"
+ /// Container's pixel x when placed on the stove
+ var/container_x = 0
+ /// Container's pixel y when placed on the stove
+ var/container_y = 8
+ /// Modifies how much temperature is exposed to the reagents, and in turn modifies how fast the reagents are heated.
+ var/heat_coefficient = 0.033
+
+/datum/component/stove/Initialize(container_x = 0, container_y = 8, obj/item/spawn_container)
+ if(!ismachinery(parent))
+ return COMPONENT_INCOMPATIBLE
+
+ src.container_x = container_x
+ src.container_y = container_y
+
+ // To allow maploaded pots on top of your stove.
+ if(spawn_container)
+ spawn_container.forceMove(parent)
+ add_container(spawn_container)
+
+/datum/component/stove/RegisterWithParent()
+ RegisterSignal(parent, COMSIG_PARENT_ATTACKBY, PROC_REF(on_attackby))
+ RegisterSignal(parent, COMSIG_ATOM_ATTACK_HAND_SECONDARY, PROC_REF(on_attack_hand_secondary))
+ RegisterSignal(parent, COMSIG_ATOM_EXITED, PROC_REF(on_exited))
+ RegisterSignal(parent, COMSIG_ATOM_UPDATE_OVERLAYS, PROC_REF(on_overlay_update))
+ RegisterSignal(parent, COMSIG_OBJ_DECONSTRUCT, PROC_REF(on_deconstructed))
+ RegisterSignal(parent, COMSIG_ATOM_REQUESTING_CONTEXT_FROM_ITEM, PROC_REF(on_requesting_context))
+ RegisterSignal(parent, COMSIG_PARENT_EXAMINE, PROC_REF(on_examine))
+ RegisterSignal(parent, COMSIG_MACHINERY_REFRESH_PARTS, PROC_REF(on_refresh_parts))
+
+ var/obj/machinery/real_parent = parent
+ real_parent.flags_1 |= HAS_CONTEXTUAL_SCREENTIPS_1
+
+/datum/component/stove/UnregisterFromParent()
+ if(!QDELING(parent))
+ var/obj/machinery/real_parent = parent
+ container.forceMove(real_parent.drop_location())
+
+ QDEL_NULL(soup_smoke)
+
+ UnregisterSignal(parent, list(
+ COMSIG_ATOM_ATTACK_HAND_SECONDARY,
+ COMSIG_OBJ_DECONSTRUCT,
+ COMSIG_ATOM_EXITED,
+ COMSIG_ATOM_REQUESTING_CONTEXT_FROM_ITEM,
+ COMSIG_ATOM_UPDATE_OVERLAYS,
+ COMSIG_PARENT_ATTACKBY,
+ COMSIG_PARENT_EXAMINE,
+ COMSIG_MACHINERY_REFRESH_PARTS,
+ ))
+
+/datum/component/stove/process(delta_time)
+ var/obj/machinery/real_parent = parent
+ if(real_parent.machine_stat & NOPOWER)
+ turn_off()
+ return
+
+ container?.reagents.expose_temperature(SOUP_BURN_TEMP + 80, heat_coefficient)
+ real_parent.use_power(real_parent.active_power_usage)
+
+ var/turf/stove_spot = real_parent.loc
+ if(isturf(stove_spot))
+ stove_spot.hotspot_expose(SOUP_BURN_TEMP + 80, 100)
+
+/datum/component/stove/proc/turn_on()
+ var/obj/machinery/real_parent = parent
+ if(real_parent.machine_stat & (BROKEN|NOPOWER))
+ return
+ START_PROCESSING(SSmachines, src)
+ on = TRUE
+ real_parent.update_appearance(UPDATE_OVERLAYS)
+
+/datum/component/stove/proc/turn_off()
+ var/obj/machinery/real_parent = parent
+ STOP_PROCESSING(SSmachines, src)
+ on = FALSE
+ real_parent.update_appearance(UPDATE_OVERLAYS)
+
+/datum/component/stove/proc/on_attack_hand_secondary(obj/machinery/source)
+ SIGNAL_HANDLER
+
+ var/obj/machinery/real_parent = parent
+ if(on)
+ turn_off()
+
+ else if(real_parent.machine_stat & (BROKEN|NOPOWER))
+ real_parent.balloon_alert_to_viewers("no power!")
+ return COMPONENT_SECONDARY_CANCEL_ATTACK_CHAIN
+
+ else
+ turn_on()
+
+ real_parent.balloon_alert_to_viewers("burners [on ? "on" : "off"]")
+ playsound(real_parent, 'sound/machines/click.ogg', 30, TRUE)
+ playsound(real_parent, on ? 'sound/items/welderactivate.ogg' : 'sound/items/welderdeactivate.ogg', 15, TRUE)
+
+ return COMPONENT_SECONDARY_CANCEL_ATTACK_CHAIN
+
+/datum/component/stove/proc/on_attackby(obj/machinery/source, obj/item/attacking_item, mob/user, params)
+ SIGNAL_HANDLER
+
+ if(!attacking_item.is_open_container())
+ return
+ if(!isnull(container))
+ to_chat(span_warning("You wouldn't dare try to cook two things on the same stove simultaneously. \
+ What if it cross contaminates?"))
+ return COMPONENT_NO_AFTERATTACK
+
+ if(user.transferItemToLoc(attacking_item, parent))
+ add_container(attacking_item, user)
+ to_chat(user, span_notice("You put [attacking_item] onto [parent]."))
+ return COMPONENT_NO_AFTERATTACK
+
+/datum/component/stove/proc/on_exited(obj/machinery/source, atom/movable/gone, direction)
+ SIGNAL_HANDLER
+
+ if(gone == container)
+ remove_container()
+
+/datum/component/stove/proc/on_deconstructed(obj/machinery/source)
+ SIGNAL_HANDLER
+
+ container.forceMove(source.drop_location())
+
+/datum/component/stove/proc/on_overlay_update(obj/machinery/source, list/overlays)
+ SIGNAL_HANDLER
+
+ update_smoke()
+
+ if(!on)
+ return
+
+ var/obj/real_parent = parent
+
+ // Flames around the pot
+ var/mutable_appearance/flames = mutable_appearance(real_parent.icon, "[real_parent.base_icon_state]_on_flame", alpha = real_parent.alpha)
+ flames.color = flame_color
+ overlays += flames
+ overlays += emissive_appearance(real_parent.icon, "[real_parent.base_icon_state]_on_flame", real_parent, alpha = real_parent.alpha)
+
+ // A green light that shows it's active
+ var/mutable_appearance/light = mutable_appearance(real_parent.icon, "[real_parent.base_icon_state]_on_overlay", alpha = real_parent.alpha)
+ light.color = "#00ff00"
+ overlays += light
+ overlays += emissive_appearance(real_parent.icon, "[real_parent.base_icon_state]_on_overlay", real_parent, alpha = real_parent.alpha)
+
+/datum/component/stove/proc/on_requesting_context(obj/machinery/source, list/context, obj/item/held_item)
+ SIGNAL_HANDLER
+
+ if(isnull(held_item))
+ context[SCREENTIP_CONTEXT_RMB] = "Turn [on ? "off":"on"] burner"
+ return CONTEXTUAL_SCREENTIP_SET
+
+ if(held_item.is_open_container())
+ context[SCREENTIP_CONTEXT_LMB] = "Place container"
+ return CONTEXTUAL_SCREENTIP_SET
+
+/datum/component/stove/proc/on_examine(obj/machinery/source, mob/user, list/examine_list)
+ SIGNAL_HANDLER
+
+ examine_list += span_notice("You can turn the stovetop burners [on ? "off" : "on"] with right click.")
+
+/datum/component/stove/proc/on_refresh_parts(obj/machinery/source)
+ SIGNAL_HANDLER
+
+ var/new_multiplier = 0
+ for(var/datum/stock_part/micro_laser/part in source.component_parts)
+ new_multiplier += (part.tier * 0.5)
+
+ heat_coefficient = initial(heat_coefficient) * max(round(new_multiplier), 1)
+
+/datum/component/stove/proc/add_container(obj/item/new_container, mob/user)
+ var/obj/real_parent = parent
+ real_parent.vis_contents += new_container
+ new_container.flags_1 |= IS_ONTOP_1
+ new_container.vis_flags |= VIS_INHERIT_PLANE
+
+ container = new_container
+ container.pixel_x = container_x
+ container.pixel_y = container_y
+
+ update_smoke_type()
+ RegisterSignal(container.reagents, COMSIG_REAGENTS_TEMP_CHANGE, PROC_REF(update_smoke_type))
+ real_parent.update_appearance(UPDATE_OVERLAYS)
+
+/datum/component/stove/proc/remove_container()
+ var/obj/real_parent = parent
+ container.flags_1 &= ~IS_ONTOP_1
+ container.vis_flags &= ~VIS_INHERIT_PLANE
+ real_parent.vis_contents -= container
+
+ UnregisterSignal(container.reagents, COMSIG_REAGENTS_TEMP_CHANGE)
+
+ container.pixel_x = container.base_pixel_x
+ container.pixel_y = container.base_pixel_y
+ container = null
+
+ update_smoke_type()
+ real_parent.update_appearance(UPDATE_OVERLAYS)
+
+/datum/component/stove/proc/update_smoke_type(datum/source, new_temp, old_temp)
+ SIGNAL_HANDLER
+
+ var/existing_temp = container?.reagents.chem_temp || 0
+ if(existing_temp >= SOUP_BURN_TEMP)
+ particle_type = /particles/smoke/steam/bad
+ else if(existing_temp >= WATER_BOILING_POINT)
+ particle_type = /particles/smoke/steam/mild
+ else
+ particle_type = null
+
+ update_smoke()
+
+/datum/component/stove/proc/update_smoke()
+ if(on && container?.reagents.total_volume > 0)
+ // Don't override existing particles, wasteful
+ if(isnull(soup_smoke) || soup_smoke.particles.type != particle_type)
+ QDEL_NULL(soup_smoke)
+ if(isnull(particle_type))
+ return
+ // this gets badly murdered by sidemap
+ soup_smoke = new(parent, particle_type)
+ soup_smoke.set_particle_position(list(container_x, round(world.icon_size * 0.66), 0))
+ return
+
+ QDEL_NULL(soup_smoke)
diff --git a/code/modules/food_and_drinks/recipes/drinks/drinks_alcoholic.dm b/code/modules/food_and_drinks/recipes/drinks/drinks_alcoholic.dm
index fc09d88ed7b..ec3813cfd56 100644
--- a/code/modules/food_and_drinks/recipes/drinks/drinks_alcoholic.dm
+++ b/code/modules/food_and_drinks/recipes/drinks/drinks_alcoholic.dm
@@ -393,7 +393,7 @@
/datum/chemical_reaction/drink/quintuplesec
results = list(/datum/reagent/consumable/ethanol/quintuple_sec = 15)
- required_reagents = list(/datum/reagent/consumable/ethanol/quadruple_sec = 5, /datum/reagent/consumable/clownstears = 5, /datum/reagent/consumable/ethanol/syndicatebomb = 5)
+ required_reagents = list(/datum/reagent/consumable/ethanol/quadruple_sec = 5, /datum/reagent/consumable/nutriment/soup/clown_tears = 5, /datum/reagent/consumable/ethanol/syndicatebomb = 5)
mix_message = "Judgement is upon you."
mix_sound = 'sound/items/airhorn2.ogg'
reaction_tags = REACTION_TAG_DRINK | REACTION_TAG_EASY | REACTION_TAG_OTHER
diff --git a/code/modules/food_and_drinks/recipes/food_mixtures.dm b/code/modules/food_and_drinks/recipes/food_mixtures.dm
index ff9dfbcdb85..dd7b7ef655f 100644
--- a/code/modules/food_and_drinks/recipes/food_mixtures.dm
+++ b/code/modules/food_and_drinks/recipes/food_mixtures.dm
@@ -1,19 +1,33 @@
/datum/crafting_recipe/food
- var/real_parts
- var/total_nutriment_factor
+ /// A rough equivilance for how much nutrition this recipe's result will provide
+ var/total_nutriment_factor = 0
/datum/crafting_recipe/food/on_craft_completion(mob/user, atom/result)
- if(user.mind)
+ SHOULD_CALL_PARENT(TRUE)
+ . = ..()
+ if(istype(result) && !isnull(user.mind))
ADD_TRAIT(result, TRAIT_FOOD_CHEF_MADE, REF(user.mind))
/datum/crafting_recipe/food/New()
+ . = ..()
if(ispath(result, /obj/item/food))
- var/obj/item/food/result_food = new result
+ var/obj/item/food/result_food = new result()
for(var/datum/reagent/consumable/nutriment as anything in result_food.food_reagents)
total_nutriment_factor += initial(nutriment.nutriment_factor) * result_food.food_reagents[nutriment]
- real_parts = parts.Copy()
+ qdel(result_food)
+
parts |= reqs
+/datum/crafting_recipe/food/crafting_ui_data()
+ var/list/data = list()
+
+ if(ispath(result, /obj/item/food))
+ var/obj/item/food/item = result
+ data["foodtypes"] = bitfield_to_list(initial(item.foodtypes), FOOD_FLAGS)
+ data["nutriments"] = total_nutriment_factor
+
+ return data
+
//////////////////////////////////////////FOOD MIXTURES////////////////////////////////////
/datum/chemical_reaction/food
@@ -25,27 +39,28 @@
H_ion_release = 0
reaction_tags = REACTION_TAG_FOOD | REACTION_TAG_EASY
+ /// Typepath of food that is created on reaction
+ var/atom/resulting_food_path
+
+/datum/chemical_reaction/food/on_reaction(datum/reagents/holder, datum/equilibrium/reaction, created_volume)
+ if(resulting_food_path)
+ var/atom/location = holder.my_atom.drop_location()
+ for(var/i in 1 to created_volume)
+ new resulting_food_path(location)
+
/datum/chemical_reaction/food/tofu
required_reagents = list(/datum/reagent/consumable/soymilk = 10)
required_catalysts = list(/datum/reagent/consumable/enzyme = 5)
mob_react = FALSE
reaction_flags = REACTION_INSTANT
+ resulting_food_path = /obj/item/food/tofu
/datum/chemical_reaction/food/candycorn
required_reagents = list(/datum/reagent/consumable/cornoil = 5)
required_catalysts = list(/datum/reagent/consumable/sugar = 5)
mob_react = FALSE
reaction_flags = REACTION_INSTANT
-
-/datum/chemical_reaction/food/candycorn/on_reaction(datum/reagents/holder, datum/equilibrium/reaction, created_volume)
- var/location = get_turf(holder.my_atom)
- for(var/i in 1 to created_volume)
- new /obj/item/food/candy_corn(location)
-
-/datum/chemical_reaction/food/tofu/on_reaction(datum/reagents/holder, datum/equilibrium/reaction, created_volume)
- var/location = get_turf(holder.my_atom)
- for(var/i in 1 to created_volume)
- new /obj/item/food/tofu(location)
+ resulting_food_path = /obj/item/food/candy_corn
/datum/chemical_reaction/food/chocolatepudding
results = list(/datum/reagent/consumable/chocolatepudding = 20)
@@ -58,30 +73,18 @@
/datum/chemical_reaction/food/chocolate_bar
required_reagents = list(/datum/reagent/consumable/soymilk = 2, /datum/reagent/consumable/coco = 2, /datum/reagent/consumable/sugar = 2)
reaction_flags = REACTION_INSTANT
-
-/datum/chemical_reaction/food/chocolate_bar/on_reaction(datum/reagents/holder, datum/equilibrium/reaction, created_volume)
- var/location = get_turf(holder.my_atom)
- for(var/i in 1 to created_volume)
- new /obj/item/food/chocolatebar(location)
+ resulting_food_path = /obj/item/food/chocolatebar
/datum/chemical_reaction/food/chocolate_bar2
required_reagents = list(/datum/reagent/consumable/milk/chocolate_milk = 4, /datum/reagent/consumable/sugar = 2)
mob_react = FALSE
reaction_flags = REACTION_INSTANT
-
-/datum/chemical_reaction/food/chocolate_bar2/on_reaction(datum/reagents/holder, datum/equilibrium/reaction, created_volume)
- var/location = get_turf(holder.my_atom)
- for(var/i in 1 to created_volume)
- new /obj/item/food/chocolatebar(location)
+ resulting_food_path = /obj/item/food/chocolatebar
/datum/chemical_reaction/food/chocolate_bar3
required_reagents = list(/datum/reagent/consumable/milk = 2, /datum/reagent/consumable/coco = 2, /datum/reagent/consumable/sugar = 2)
reaction_flags = REACTION_INSTANT
-
-/datum/chemical_reaction/food/chocolate_bar3/on_reaction(datum/reagents/holder, datum/equilibrium/reaction, created_volume)
- var/location = get_turf(holder.my_atom)
- for(var/i in 1 to created_volume)
- new /obj/item/food/chocolatebar(location)
+ resulting_food_path = /obj/item/food/chocolatebar
/datum/chemical_reaction/food/soysauce
results = list(/datum/reagent/consumable/soysauce = 5)
@@ -111,21 +114,13 @@
required_reagents = list(/datum/reagent/consumable/milk = 40)
required_catalysts = list(/datum/reagent/consumable/enzyme = 5)
reaction_flags = REACTION_INSTANT
-
-/datum/chemical_reaction/food/cheesewheel/on_reaction(datum/reagents/holder, datum/equilibrium/reaction, created_volume)
- var/location = get_turf(holder.my_atom)
- for(var/i in 1 to created_volume)
- new /obj/item/food/cheese/wheel(location)
+ resulting_food_path = /obj/item/food/cheese/wheel
/datum/chemical_reaction/food/synthmeat
required_reagents = list(/datum/reagent/blood = 5, /datum/reagent/medicine/cryoxadone = 1)
mob_react = FALSE
reaction_flags = REACTION_INSTANT
-
-/datum/chemical_reaction/food/synthmeat/on_reaction(datum/reagents/holder, datum/equilibrium/reaction, created_volume)
- var/location = get_turf(holder.my_atom)
- for(var/i in 1 to created_volume)
- new /obj/item/food/meat/slab/synthmeat(location)
+ resulting_food_path = /obj/item/food/meat/slab/synthmeat
/datum/chemical_reaction/food/hot_ramen
results = list(/datum/reagent/consumable/hot_ramen = 3)
@@ -155,21 +150,13 @@
required_reagents = list(/datum/reagent/water = 10, /datum/reagent/consumable/flour = 15)
mix_message = "The ingredients form a dough."
reaction_flags = REACTION_INSTANT
-
-/datum/chemical_reaction/food/dough/on_reaction(datum/reagents/holder, datum/equilibrium/reaction, created_volume)
- var/location = get_turf(holder.my_atom)
- for(var/i in 1 to created_volume)
- new /obj/item/food/dough(location)
+ resulting_food_path = /obj/item/food/dough
/datum/chemical_reaction/food/cakebatter
required_reagents = list(/datum/reagent/consumable/eggyolk = 6, /datum/reagent/consumable/eggwhite = 12, /datum/reagent/consumable/flour = 15, /datum/reagent/consumable/sugar = 5)
mix_message = "The ingredients form a cake batter."
reaction_flags = REACTION_INSTANT
-
-/datum/chemical_reaction/food/cakebatter/on_reaction(datum/reagents/holder, datum/equilibrium/reaction, created_volume)
- var/location = get_turf(holder.my_atom)
- for(var/i in 1 to created_volume)
- new /obj/item/food/cakebatter(location)
+ resulting_food_path = /obj/item/food/cakebatter
/datum/chemical_reaction/food/cakebatter/vegan
required_reagents = list(/datum/reagent/consumable/soymilk = 15, /datum/reagent/consumable/flour = 15, /datum/reagent/consumable/sugar = 5)
@@ -222,22 +209,14 @@
required_reagents = list(/datum/reagent/consumable/milk = 5, /datum/reagent/consumable/quality_oil = 2, /datum/reagent/medicine/salglu_solution = 5, /datum/reagent/consumable/cornmeal = 10, /datum/reagent/consumable/flour = 5)
mix_message = "The ingredients form a pizza dough."
reaction_flags = REACTION_INSTANT
-
-/datum/chemical_reaction/food/mothic_pizza_dough/on_reaction(datum/reagents/holder, datum/equilibrium/reaction, created_volume)
- var/location = get_turf(holder.my_atom)
- for(var/i = 1, i <= created_volume, i++)
- new /obj/item/food/mothic_pizza_dough(location)
+ resulting_food_path = /obj/item/food/mothic_pizza_dough
/datum/chemical_reaction/food/curd_cheese
required_reagents = list(/datum/reagent/consumable/milk = 15, /datum/reagent/consumable/vinegar = 5, /datum/reagent/consumable/cream = 5)
mix_message = "The milk curdles into cheese."
required_temp = 353
reaction_flags = REACTION_INSTANT
-
-/datum/chemical_reaction/food/curd_cheese/on_reaction(datum/reagents/holder, datum/equilibrium/reaction, created_volume)
- var/location = get_turf(holder.my_atom)
- for(var/i = 1, i <= created_volume, i++)
- new /obj/item/food/cheese/curd_cheese(location)
+ resulting_food_path = /obj/item/food/cheese/curd_cheese
/datum/chemical_reaction/food/mozzarella
required_reagents = list(/datum/reagent/consumable/milk = 10, /datum/reagent/consumable/cream = 10)
@@ -245,11 +224,7 @@
mix_message = "Fine ribbons of curd form in the milk."
required_temp = 353
reaction_flags = REACTION_INSTANT
-
-/datum/chemical_reaction/food/mozzarella/on_reaction(datum/reagents/holder, datum/equilibrium/reaction, created_volume)
- var/location = get_turf(holder.my_atom)
- for(var/i = 1, i <= created_volume, i++)
- new /obj/item/food/cheese/mozzarella(location)
+ resulting_food_path = /obj/item/food/cheese/mozzarella
/datum/chemical_reaction/food/cornmeal_batter
results = list(/datum/reagent/consumable/cornmeal_batter = 35)
@@ -261,11 +236,7 @@
mix_message = "The batter bakes into cornbread- somehow!"
required_temp = 473
reaction_flags = REACTION_INSTANT
-
-/datum/chemical_reaction/food/cornbread/on_reaction(datum/reagents/holder, datum/equilibrium/reaction, created_volume)
- var/location = get_turf(holder.my_atom)
- for(var/i = 1, i <= created_volume, i++)
- new /obj/item/food/bread/corn(location)
+ resulting_food_path = /obj/item/food/bread/corn
/datum/chemical_reaction/food/yoghurt
required_reagents = list(/datum/reagent/consumable/cream = 10, /datum/reagent/consumable/virus_food = 2)
diff --git a/code/modules/food_and_drinks/recipes/soup_guide.dm b/code/modules/food_and_drinks/recipes/soup_guide.dm
new file mode 100644
index 00000000000..4a1e0a58132
--- /dev/null
+++ b/code/modules/food_and_drinks/recipes/soup_guide.dm
@@ -0,0 +1,140 @@
+/datum/crafting_recipe/food/reaction/soup
+ machinery = list(/obj/machinery/stove)
+ category = CAT_SOUP
+ non_craftable = TRUE
+
+ var/expected_container = /obj/item/reagent_containers/cup/bowl
+
+/datum/crafting_recipe/food/reaction/soup/crafting_ui_data()
+ var/list/data = list()
+
+ var/datum/glass_style/has_foodtype/soup_style = GLOB.glass_style_singletons[expected_container][result]
+ if(istype(soup_style))
+ data["foodtypes"] = bitfield_to_list(soup_style.drink_type, FOOD_FLAGS)
+ data["nutriments"] = total_nutriment_factor
+
+ return data
+
+/datum/crafting_recipe/food/reaction/soup/setup_chemical_reaction_details(datum/chemical_reaction/food/soup/chemical_reaction)
+ . = ..()
+ if(!istype(chemical_reaction))
+ return
+ for(var/obj/item/ingredienttype as anything in chemical_reaction.required_ingredients)
+ reqs[ingredienttype] = chemical_reaction.required_ingredients[ingredienttype]
+
+ if(ispath(result, /datum/reagent/consumable))
+ var/datum/reagent/consumable/soup_result = result
+ total_nutriment_factor = initial(soup_result.nutriment_factor) * result_amount
+
+/datum/crafting_recipe/food/reaction/soup/meatball_soup
+ reaction = /datum/chemical_reaction/food/soup/meatballsoup
+
+/datum/crafting_recipe/food/reaction/soup/vegetable_soup
+ reaction = /datum/chemical_reaction/food/soup/vegetable_soup
+
+/datum/crafting_recipe/food/reaction/soup/nettle
+ reaction = /datum/chemical_reaction/food/soup/nettlesoup
+
+/datum/crafting_recipe/food/reaction/soup/wingfangchu
+ reaction = /datum/chemical_reaction/food/soup/wingfangchu
+
+/datum/crafting_recipe/food/reaction/soup/hotchili
+ reaction = /datum/chemical_reaction/food/soup/hotchili
+
+/datum/crafting_recipe/food/reaction/soup/coldchili
+ reaction = /datum/chemical_reaction/food/soup/coldchili
+
+/datum/crafting_recipe/food/reaction/soup/clownchili
+ reaction = /datum/chemical_reaction/food/soup/clownchili
+
+/datum/crafting_recipe/food/reaction/soup/tomatosoup
+ reaction = /datum/chemical_reaction/food/soup/tomatosoup
+
+/datum/crafting_recipe/food/reaction/soup/bloodsoup
+ name = "Blood Soup"
+ desc = "Smells like copper."
+ reaction = /datum/chemical_reaction/food/soup/bloodsoup
+ // Uses tomato soup's icon
+ result = /datum/reagent/consumable/nutriment/soup/tomato
+ // More of a vague guess than anything
+ result_amount = 30
+
+/datum/crafting_recipe/food/reaction/soup/eyeballsoup
+ reaction = /datum/chemical_reaction/food/soup/eyeballsoup
+
+/datum/crafting_recipe/food/reaction/soup/misosoup
+ reaction = /datum/chemical_reaction/food/soup/misosoup
+
+/datum/crafting_recipe/food/reaction/soup/slimesoup
+ reaction = /datum/chemical_reaction/food/soup/slimesoup
+
+/datum/crafting_recipe/food/reaction/soup/slimesoup_alt
+ reaction = /datum/chemical_reaction/food/soup/slimesoup/alt
+
+/datum/crafting_recipe/food/reaction/soup/clownstears
+ reaction = /datum/chemical_reaction/food/soup/clownstears
+
+/datum/crafting_recipe/food/reaction/soup/mysterysoup
+ reaction = /datum/chemical_reaction/food/soup/mysterysoup
+
+/datum/crafting_recipe/food/reaction/soup/monkey
+ reaction = /datum/chemical_reaction/food/soup/monkey
+
+/datum/crafting_recipe/food/reaction/soup/mushroomsoup
+ reaction = /datum/chemical_reaction/food/soup/mushroomsoup
+
+/datum/crafting_recipe/food/reaction/soup/beetsoup
+ reaction = /datum/chemical_reaction/food/soup/beetsoup
+
+/datum/crafting_recipe/food/reaction/soup/stew
+ reaction = /datum/chemical_reaction/food/soup/stew
+
+/datum/crafting_recipe/food/reaction/soup/sweetpotatosoup
+ reaction = /datum/chemical_reaction/food/soup/sweetpotatosoup
+
+/datum/crafting_recipe/food/reaction/soup/redbeetsoup
+ reaction = /datum/chemical_reaction/food/soup/redbeetsoup
+
+/datum/crafting_recipe/food/reaction/soup/onionsoup
+ reaction = /datum/chemical_reaction/food/soup/onionsoup
+
+/datum/crafting_recipe/food/reaction/soup/bisque
+ reaction = /datum/chemical_reaction/food/soup/bisque
+
+/datum/crafting_recipe/food/reaction/soup/bungocurry
+ reaction = /datum/chemical_reaction/food/soup/bungocurry
+
+/datum/crafting_recipe/food/reaction/soup/electron
+ reaction = /datum/chemical_reaction/food/soup/electron
+
+/datum/crafting_recipe/food/reaction/soup/peasoup
+ reaction = /datum/chemical_reaction/food/soup/peasoup
+
+/datum/crafting_recipe/food/reaction/soup/indian_curry
+ reaction = /datum/chemical_reaction/food/soup/indian_curry
+
+/datum/crafting_recipe/food/reaction/soup/oatmeal
+ reaction = /datum/chemical_reaction/food/soup/oatmeal
+
+/datum/crafting_recipe/food/reaction/soup/zurek
+ reaction = /datum/chemical_reaction/food/soup/zurek
+
+/datum/crafting_recipe/food/reaction/soup/cullen_skink
+ reaction = /datum/chemical_reaction/food/soup/cullen_skink
+
+/datum/crafting_recipe/food/reaction/soup/chicken_noodle_soup
+ reaction = /datum/chemical_reaction/food/soup/chicken_noodle_soup
+
+/datum/crafting_recipe/food/reaction/soup/corn_chowder
+ reaction = /datum/chemical_reaction/food/soup/corn_chowder
+
+// Other
+
+/datum/crafting_recipe/food/wishsoup
+ name = "Wish soup"
+ reqs = list(
+ /datum/reagent/water = 20,
+ /obj/item/reagent_containers/cup/bowl = 1
+ )
+ result= /obj/item/food/bowled/wish
+ category = CAT_SOUP
diff --git a/code/modules/food_and_drinks/recipes/soup_mixtures.dm b/code/modules/food_and_drinks/recipes/soup_mixtures.dm
new file mode 100644
index 00000000000..5005236ceb4
--- /dev/null
+++ b/code/modules/food_and_drinks/recipes/soup_mixtures.dm
@@ -0,0 +1,1720 @@
+/// Abstract parent for soup reagents.
+/// These are the majority result from soup recipes,
+/// but bear in mind it will(should) have other reagents along side it.
+/datum/reagent/consumable/nutriment/soup
+ name = "Soup"
+ chemical_flags = NONE
+ nutriment_factor = 12 * REAGENTS_METABOLISM // Slightly less to that of nutriment as soups will come with nutriments in tow
+ burning_temperature = 520
+ default_container = /obj/item/reagent_containers/cup/bowl
+ glass_price = FOOD_PRICE_CHEAP
+ fallback_icon = 'icons/obj/food/soupsalad.dmi'
+ fallback_icon_state = "bowl"
+ restaurant_order = /datum/custom_order/reagent/soup
+
+/**
+ * ## Soup base chemical reaction.
+ *
+ * Somewhat important note! Keep in mind one serving of soup is roughly 20-25 units. Adjust your results according.
+ *
+ * Try to aim to have each reaction worth 3 servings of soup (60u - 90u).
+ * By default soup reactions require 50 units of water,
+ * and they will also inherent the reagents of the ingredients used,
+ * so you might end up with more nutrient than you expect.
+ */
+/datum/chemical_reaction/food/soup
+ required_temp = 450
+ optimal_temp = 480
+ overheat_temp = SOUP_BURN_TEMP
+ optimal_ph_min = 1
+ optimal_ph_max = 14
+ thermic_constant = 10
+ required_reagents = null
+ mob_react = FALSE
+ required_other = TRUE
+ required_container = /obj/item/reagent_containers/cup/soup_pot
+ mix_message = "You smell something good coming from the steaming pot of soup."
+ reaction_tags = REACTION_TAG_FOOD | REACTION_TAG_EASY
+
+ // General soup guideline:
+ // - Soups should produce 60-90 units (3-4 servings)
+ // - One serving size is 20-25 units (8-9 sips, with 3u sips)
+ // - The first index of the result list should be the soup type
+
+ /// An assoc list of what ingredients are necessary to how much is needed
+ var/list/required_ingredients
+ /// Tracks the total number of ingredient items needed, for calculating multipliers. Only done once in first on_reaction
+ VAR_FINAL/total_ingredient_max
+
+ /// Multiplier applied to all reagents transfered from reagents to pot when the soup is cooked
+ var/ingredient_reagent_multiplier = 0.8
+ /// What percent of nutriment is converted to "soup" (what percent does not stay final product)?
+ /// Raise this if your ingredients have a lot of nutriment and is overpowering your other reagents
+ /// Lower this if your ingredients have a small amount of nutriment and isn't filling enough per serving
+ /// (EX: A tomato with 10 nutriment will lose 2.5 nutriment before being added to the pot)
+ var/percentage_of_nutriment_converted = 0.25
+
+/datum/chemical_reaction/food/soup/pre_reaction_other_checks(datum/reagents/holder)
+ var/obj/item/reagent_containers/cup/soup_pot/pot = holder.my_atom
+ if(!istype(pot))
+ return FALSE
+ if(!length(required_ingredients))
+ return TRUE
+
+ // This is very unoptimized for something ran every handle-reaction for every soup recipe.
+ // Look into ways for improving this, cause bleh
+ var/list/reqs_copy = required_ingredients.Copy()
+ for(var/obj/item/ingredient as anything in pot.added_ingredients)
+ // See if we fulfill all reqs
+ for(var/ingredient_type in required_ingredients)
+ if(!istype(ingredient, ingredient_type))
+ continue
+ if(isstack(ingredient))
+ var/obj/item/stack/stack_ingredient = ingredient
+ reqs_copy[ingredient_type] -= stack_ingredient.amount
+ else
+ reqs_copy[ingredient_type] -= 1
+
+ for(var/fulfilled in reqs_copy)
+ if(reqs_copy[fulfilled] > 0)
+ return FALSE
+ return TRUE
+
+/datum/chemical_reaction/food/soup/on_reaction(datum/reagents/holder, datum/equilibrium/reaction, created_volume)
+ if(!length(required_ingredients))
+ return
+
+ if(isnull(total_ingredient_max))
+ total_ingredient_max = 0
+ // We only need to calculate this once, effectively static per-type
+ for(var/ingredient_type in required_ingredients)
+ total_ingredient_max += required_ingredients[ingredient_type]
+
+ var/obj/item/reagent_containers/cup/soup_pot/pot = holder.my_atom
+ var/list/tracked_ingredients = list()
+ for(var/obj/item/ingredient as anything in pot.added_ingredients)
+ // Track all ingredients in data. Assoc list of weakref to ingredient to initial total volume.
+ tracked_ingredients[WEAKREF(ingredient)] = ingredient.reagents?.total_volume || 1
+ // Equalize temps. Otherwise when we add ingredient temps in, it'll lower reaction temp
+ ingredient.reagents?.chem_temp = holder.chem_temp
+
+ // Store a list of weakrefs to ingredients as
+ reaction.data["ingredients"] = tracked_ingredients
+
+ testing("Soup reaction started of type [type]! [length(pot.added_ingredients)] inside.")
+
+/datum/chemical_reaction/food/soup/reaction_step(datum/reagents/holder, datum/equilibrium/reaction, delta_t, delta_ph, step_reaction_vol)
+ if(!length(required_ingredients))
+ return
+
+ testing("Soup reaction step progressing with an increment volume of [step_reaction_vol] and delta_t of [delta_t].")
+ var/obj/item/reagent_containers/cup/soup_pot/pot = holder.my_atom
+ var/list/cached_ingredients = reaction.data["ingredients"]
+ var/num_current_ingredients = length(pot.added_ingredients)
+ var/num_cached_ingredients = length(cached_ingredients)
+
+ // Clamp multiplier to ingredient number
+ reaction.multiplier = min(reaction.multiplier, num_current_ingredients / total_ingredient_max)
+
+ // An ingredient was removed during the mixing process.
+ // Stop reacting immediately, we can't verify the reaction is correct still.
+ // If it is still correct it will restart shortly.
+ if(num_current_ingredients < num_cached_ingredients)
+ testing("Soup reaction ended due to losing ingredients.")
+ return END_REACTION
+
+ // An ingredient was added mid mix.
+ // Throw it in the ingredients list
+ else if(num_current_ingredients > num_cached_ingredients)
+ for(var/obj/item/new_ingredient as anything in pot.added_ingredients)
+ var/datum/weakref/new_ref = WEAKREF(new_ingredient)
+ if(cached_ingredients[new_ref])
+ continue
+ new_ingredient.reagents?.chem_temp = holder.chem_temp
+ cached_ingredients[new_ref] = new_ingredient.reagents?.total_volume || 1
+
+ for(var/datum/weakref/ingredient_ref as anything in cached_ingredients)
+ var/obj/item/ingredient = ingredient_ref.resolve()
+ // An ingredient has gone missing, stop the reaction
+ if(QDELETED(ingredient) || ingredient.loc != holder.my_atom)
+ testing("Soup reaction ended due to having an invalid ingredient present.")
+ return END_REACTION
+
+ // Don't add any more reagents if we've boiled over
+ if(reaction.data["boiled_over"])
+ continue
+
+ // Transfer 20% of the initial reagent volume of the ingredient to the soup
+ transfer_ingredient_reagents(ingredient, holder, max(cached_ingredients[ingredient_ref] * 0.2, 2))
+
+ // Uh oh we reached the top of the pot, the soup's gonna boil over.
+ if(holder.total_volume >= holder.maximum_volume * 0.95)
+ boil_over(holder)
+ reaction.data["boiled_over"] = TRUE
+
+/datum/chemical_reaction/food/soup/reaction_finish(datum/reagents/holder, datum/equilibrium/reaction, react_vol)
+ . = ..()
+ var/obj/item/reagent_containers/cup/soup_pot/pot = holder.my_atom
+ if(!istype(pot))
+ CRASH("[pot ? "Non-pot atom" : "Null pot"]) made it to the end of the [type] reaction chain.")
+ reaction.data["ingredients"] = null
+
+ testing("Soup reaction finished with a total react volume of [react_vol] and [length(pot.added_ingredients)] ingredients. Cleaning up.")
+
+ for(var/obj/item/ingredient as anything in pot.added_ingredients)
+ // Let's not mess with fireproof / indestructible items.
+ // It's not likely that soups use fireproof items as ingredients,
+ // and chef doesn't need more ways to delete things with cooking.
+ if(ingredient.resistance_flags & (FIRE_PROOF|INDESTRUCTIBLE))
+ continue
+
+ // Things that had reagents or ingredients in the soup will get deleted
+ if(!isnull(ingredient.reagents) || is_type_in_list(ingredient, required_ingredients))
+ // Send everything left behind
+ transfer_ingredient_reagents(ingredient, holder)
+ // Delete, it's done
+ qdel(ingredient)
+
+ // Everything else will just get fried
+ else
+ ingredient.AddElement(/datum/element/fried_item, 30)
+
+ LAZYNULL(pot.added_ingredients)
+ // Blackbox log the chemical reaction used, to account for soup reaction that don't produce typical results
+ BLACKBOX_LOG_FOOD_MADE(type)
+
+/datum/chemical_reaction/food/soup/proc/transfer_ingredient_reagents(obj/item/ingredient, datum/reagents/holder, amount)
+ var/datum/reagents/ingredient_pool = ingredient.reagents
+ // Some ingredients are purely flavor (no pun intended) and will have reagents
+ if(isnull(ingredient_pool) || ingredient_pool.total_volume <= 0)
+ return
+ if(isnull(amount))
+ amount = ingredient_pool.total_volume
+ testing("Soup reaction has made it to the finishing step with ingredients that still contain reagents. [amount] reagents left in [ingredient].")
+
+ // Some of the nutriment goes into "creating the soup reagent" itself, gets deleted.
+ // Mainly done so that nutriment doesn't overpower the main course
+ ingredient_pool.remove_reagent(/datum/reagent/consumable/nutriment, amount * percentage_of_nutriment_converted)
+ ingredient_pool.remove_reagent(/datum/reagent/consumable/nutriment/vitamin, amount * percentage_of_nutriment_converted)
+ // The other half of the nutriment, and the rest of the reagents, will get put directly into the pot
+ ingredient_pool.trans_to(holder, amount, ingredient_reagent_multiplier, no_react = TRUE)
+
+/datum/chemical_reaction/food/soup/proc/boil_over(datum/reagents/holder)
+ var/obj/item/reagent_containers/cup/soup_pot/pot = holder.my_atom
+ var/turf/below_pot = get_turf(pot)
+ below_pot.visible_message(span_warning("[pot] starts to boil over!"))
+ // Create a spread of dirty foam
+ var/datum/effect_system/fluid_spread/foam/dirty/soup_mess = new()
+ soup_mess.reagent_scale = 0.1 // (Just a little)
+ soup_mess.set_up(range = 1, holder = pot, location = below_pot, carry = holder, stop_reactions = TRUE)
+ soup_mess.start()
+ // Loses a bit from the foam
+ for(var/datum/reagent/reagent as anything in holder.reagent_list)
+ reagent.volume = round(reagent.volume * 0.9, 0.05)
+ holder.update_total()
+
+#ifdef TESTING
+
+/obj/item/soup_test_kit/Initialize(mapload)
+ ..()
+ new /obj/item/food/meatball(loc)
+ new /obj/item/food/grown/carrot(loc)
+ new /obj/item/food/grown/potato(loc)
+ new /obj/item/reagent_containers/cup/soup_pot(loc)
+ return INITIALIZE_HINT_QDEL
+
+#endif
+
+/// This subtype is only for easy mapping / spawning in specific types of soup.
+/// Do not use it anywhere else.
+/obj/item/reagent_containers/cup/bowl/soup
+ var/initial_reagent
+ var/initial_portion = SOUP_SERVING_SIZE
+
+/obj/item/reagent_containers/cup/bowl/soup/Initialize(mapload)
+ . = ..()
+ if(initial_reagent)
+ reagents.add_reagent(initial_reagent, initial_portion)
+
+/// This style runs dual purpose -
+/// Primarily it's just a bowl style for water,
+/// but secondarily it lets chefs know if their soup had too much water in it
+/datum/glass_style/has_foodtype/soup/watery_soup
+ required_drink_type = /datum/reagent/water
+ name = "Bowl of water"
+ desc = "A very wet bowl."
+ icon_state = "wishsoup"
+
+/datum/glass_style/has_foodtype/soup/watery_soup/set_name(obj/item/thing)
+ if(length(thing.reagents.reagent_list) <= 2)
+ return ..()
+
+ thing.name = "Watery bowl of something"
+
+/datum/glass_style/has_foodtype/soup/watery_soup/set_desc(obj/item/thing)
+ if(length(thing.reagents.reagent_list) <= 2)
+ return ..()
+
+ thing.desc = "Looks like whatever's in there is very watered down."
+
+/// So this one's kind of a "failed" result, but also a "custom" result
+/// Getting to this temperature and having no other soup reaction made means you're either messing something up
+/// or you simply aren't following a recipe. So it'll just combine
+/datum/chemical_reaction/food/soup/custom
+ required_temp = SOUP_BURN_TEMP + 40 // Only done if it's been burning for a little bit
+ optimal_temp = SOUP_BURN_TEMP + 50
+ overheat_temp = SOUP_BURN_TEMP + 60
+ thermic_constant = 0
+ mix_message = span_warning("You smell something gross coming from the pot of soup.")
+ required_reagents = list(/datum/reagent/water = 30)
+ results = list(/datum/reagent/water = 10)
+ ingredient_reagent_multiplier = 1
+ percentage_of_nutriment_converted = 0
+
+/datum/chemical_reaction/food/soup/custom/pre_reaction_other_checks(datum/reagents/holder)
+ var/obj/item/reagent_containers/cup/soup_pot/pot = holder.my_atom
+ if(!istype(pot))
+ return FALSE // Not a pot
+ if(holder.is_reacting)
+ return FALSE // Another soup is being made
+ if(length(pot.added_ingredients) <= 3)
+ return FALSE // Not a lot here to go off of
+ return TRUE
+
+// Meatball Soup
+/datum/reagent/consumable/nutriment/soup/meatball_soup
+ name = "Meatball Soup"
+ description = "You've got balls kid, BALLS!"
+ data = list("meat" = 1)
+ glass_price = FOOD_PRICE_NORMAL
+ color = "#FFFDCF"
+
+/datum/glass_style/has_foodtype/soup/meatball_soup
+ required_drink_type = /datum/reagent/consumable/nutriment/soup/meatball_soup
+ icon_state = "meatballsoup"
+ drink_type = MEAT
+
+/obj/item/reagent_containers/cup/bowl/soup/meatball_soup
+ initial_reagent = /datum/reagent/consumable/nutriment/soup/meatball_soup
+
+/datum/chemical_reaction/food/soup/meatballsoup
+ required_reagents = list(/datum/reagent/water = 50)
+ required_ingredients = list(
+ /obj/item/food/meatball = 1,
+ /obj/item/food/grown/carrot = 1,
+ /obj/item/food/grown/potato = 1,
+ )
+ results = list(
+ /datum/reagent/consumable/nutriment/soup/meatball_soup = 30,
+ /datum/reagent/water = 9,
+ )
+
+// Vegetable Soup
+/datum/reagent/consumable/nutriment/soup/vegetable_soup
+ name = "Vegetable Soup"
+ description = "A true vegan meal."
+ data = list("vegetables" = 1)
+ glass_price = FOOD_PRICE_NORMAL
+ color = "#FAA810"
+
+/datum/glass_style/has_foodtype/soup/vegetable_soup
+ required_drink_type = /datum/reagent/consumable/nutriment/soup/vegetable_soup
+ icon_state = "vegetablesoup"
+ drink_type = VEGETABLES
+
+/datum/chemical_reaction/food/soup/vegetable_soup
+ required_reagents = list(/datum/reagent/water = 50)
+ required_ingredients = list(
+ /obj/item/food/grown/carrot = 1,
+ /obj/item/food/grown/corn = 1,
+ /obj/item/food/grown/eggplant = 1,
+ /obj/item/food/grown/potato = 1,
+ )
+ results = list(
+ /datum/reagent/consumable/nutriment/soup/vegetable_soup = 30,
+ /datum/reagent/water = 9,
+ )
+
+// Nettle soup - gains some omnizine to offset the acid damage
+/datum/reagent/consumable/nutriment/soup/nettle
+ name = "Nettle Soup"
+ description = "To think, the botanist would've beat you to death with one of these."
+ data = list("nettles" = 1)
+ glass_price = FOOD_PRICE_NORMAL
+ color = "#C1E212"
+
+/datum/glass_style/has_foodtype/soup/nettle
+ required_drink_type = /datum/reagent/consumable/nutriment/soup/nettle
+ icon_state = "nettlesoup"
+ drink_type = VEGETABLES
+
+/obj/item/reagent_containers/cup/bowl/soup/nettle
+ initial_reagent = /datum/reagent/consumable/nutriment/soup/nettle
+
+/datum/chemical_reaction/food/soup/nettlesoup
+ required_reagents = list(/datum/reagent/water = 50)
+ required_ingredients = list(
+ /obj/item/food/grown/nettle = 1,
+ /obj/item/food/grown/potato = 1,
+ /obj/item/food/boiledegg = 1
+ )
+ results = list(
+ /datum/reagent/consumable/nutriment/soup/nettle = 30,
+ /datum/reagent/water = 9,
+ /datum/reagent/medicine/omnizine = 6,
+ )
+ ingredient_reagent_multiplier = 0.2 // Too much acid
+ percentage_of_nutriment_converted = 0
+
+// Wing Fang Chu
+/datum/reagent/consumable/nutriment/soup/wingfangchu
+ name = "Wing Fang Chu"
+ description = "A savory dish of alien wing wang in soy."
+ data = list("soy" = 1)
+ color = "#C1E212"
+
+/datum/glass_style/has_foodtype/soup/wingfangchu
+ required_drink_type = /datum/reagent/consumable/nutriment/soup/wingfangchu
+ icon_state = "wingfangchu"
+ drink_type = MEAT
+
+/datum/chemical_reaction/food/soup/wingfangchu
+ required_reagents = list(
+ /datum/reagent/water = 50,
+ /datum/reagent/consumable/soysauce = 5,
+ )
+ required_ingredients = list(
+ /obj/item/food/meat/cutlet/xeno = 2,
+ )
+ results = list(
+ /datum/reagent/consumable/nutriment/soup/wingfangchu = 30,
+ /datum/reagent/consumable/soysauce = 10,
+ )
+
+// Chili (Hot, not cold)
+/datum/reagent/consumable/nutriment/soup/hotchili
+ name = "Hot Chili"
+ description = "A five alarm Texan Chili!"
+ data = list("hot peppers" = 1)
+ glass_price = FOOD_PRICE_NORMAL
+ color = "#E23D12"
+
+/datum/glass_style/has_foodtype/soup/hotchili
+ required_drink_type = /datum/reagent/consumable/nutriment/soup/hotchili
+ icon_state = "hotchili"
+ drink_type = VEGETABLES | MEAT
+
+/obj/item/reagent_containers/cup/bowl/soup/hotchili
+ initial_reagent = /datum/reagent/consumable/nutriment/soup/hotchili
+
+/datum/chemical_reaction/food/soup/hotchili
+ required_reagents = list(/datum/reagent/water = 50)
+ required_ingredients = list(
+ /obj/item/food/meat/cutlet = 2,
+ /obj/item/food/grown/chili = 1,
+ /obj/item/food/grown/tomato = 1,
+ )
+ results = list(
+ /datum/reagent/consumable/nutriment/soup/hotchili = 30,
+ /datum/reagent/consumable/tomatojuice = 10,
+ // Capsaicin comes from the chillis, meaning you can make tame chili.
+ /*
+ /datum/reagent/consumable/nutriment = 4,
+ /datum/reagent/consumable/nutriment/protein = 6,
+ /datum/reagent/consumable/nutriment/vitamin = 4
+ */
+ )
+ ingredient_reagent_multiplier = 0.33 // Chilis have a TON of capsaicin naturally
+ percentage_of_nutriment_converted = 0
+
+// Chili (Cold)
+/datum/reagent/consumable/nutriment/soup/coldchili
+ name = "Cold Chili"
+ description = "This slush is barely a liquid!"
+ data = list("tomato" = 1, "mint" = 1)
+ glass_price = FOOD_PRICE_NORMAL
+ color = "#3861C2"
+
+/datum/glass_style/has_foodtype/soup/coldchili
+ required_drink_type = /datum/reagent/consumable/nutriment/soup/coldchili
+ icon_state = "coldchili"
+ drink_type = VEGETABLES | MEAT
+
+/datum/chemical_reaction/food/soup/coldchili
+ required_reagents = list(/datum/reagent/water = 50)
+ required_ingredients = list(
+ /obj/item/food/meat/cutlet = 2,
+ /obj/item/food/grown/icepepper = 1,
+ /obj/item/food/grown/tomato = 1,
+ )
+ results = list(
+ /datum/reagent/consumable/nutriment/soup/coldchili = 30,
+ /datum/reagent/consumable/tomatojuice = 10,
+ // Frost Oil comes from the chilis
+ )
+ ingredient_reagent_multiplier = 0.33 // Chilis have a TON of frost oil naturally
+ percentage_of_nutriment_converted = 0
+
+// Chili (Clownish)
+/datum/reagent/consumable/nutriment/soup/clownchili
+ name = "Chili Con Carnival"
+ description = "A delicious stew of meat, chiles, and salty, salty clown tears."
+ data = list(
+ "tomato" = 1,
+ "hot peppers" = 2,
+ "clown feet" = 2,
+ "kind of funny" = 2,
+ "someone's parents" = 2,
+ )
+ glass_price = FOOD_PRICE_EXOTIC
+ color = "#FF0000"
+
+/datum/glass_style/has_foodtype/soup/clownchili
+ required_drink_type = /datum/reagent/consumable/nutriment/soup/clownchili
+ icon_state = "clownchili"
+ drink_type = VEGETABLES | MEAT
+
+/datum/chemical_reaction/food/soup/clownchili
+ required_reagents = list(/datum/reagent/water = 50)
+ required_ingredients = list(
+ /obj/item/food/meat/cutlet = 2,
+ /obj/item/food/grown/chili = 1,
+ /obj/item/food/grown/tomato = 1,
+ /obj/item/clothing/shoes/clown_shoes = 1,
+ )
+ results = list(
+ /datum/reagent/consumable/nutriment/soup/clownchili = 30,
+ /datum/reagent/consumable/tomatojuice = 8,
+ /datum/reagent/consumable/laughter = 4,
+ /datum/reagent/consumable/banana = 4,
+ )
+ percentage_of_nutriment_converted = 0.15
+
+// Vegan Chili
+/datum/reagent/consumable/nutriment/soup/chili_sin_carne
+ name = "Chili Sin Carne"
+ description = "For the hombres who don't want carne."
+ data = list("bitterness" = 1, "sourness" = 1)
+ color = "#E23D12"
+
+/datum/glass_style/has_foodtype/soup/chili_sin_carne
+ required_drink_type = /datum/reagent/consumable/nutriment/soup/chili_sin_carne
+ icon_state = "hotchili"
+ drink_type = VEGETABLES
+
+/datum/chemical_reaction/food/soup/chili_sin_carne
+ required_reagents = list(
+ /datum/reagent/water = 40,
+ /datum/reagent/consumable/salt = 5,
+ )
+ required_ingredients = list(
+ /obj/item/food/grown/chili = 1,
+ /obj/item/food/grown/tomato = 1
+ )
+ results = list(
+ /datum/reagent/consumable/nutriment/soup/chili_sin_carne = 30,
+ /datum/reagent/consumable/tomatojuice = 10,
+ )
+
+// Tomato soup
+/datum/reagent/consumable/nutriment/soup/tomato
+ name = "Tomato Soup"
+ description = "Drinking this feels like being a vampire! A tomato vampire..."
+ data = list("tomato" = 1)
+ color = "#FF0000"
+
+/datum/glass_style/has_foodtype/soup/tomato
+ required_drink_type = /datum/reagent/consumable/nutriment/soup/tomato
+ name = "Tomato Soup"
+ icon_state = "tomatosoup"
+ drink_type = VEGETABLES | FRUIT // ??
+
+/datum/chemical_reaction/food/soup/tomatosoup
+ required_reagents = list(/datum/reagent/water = 50)
+ required_ingredients = list(
+ /obj/item/food/grown/tomato = 2,
+ )
+ results = list(
+ /datum/reagent/consumable/nutriment/soup/tomato = 30,
+ /datum/reagent/consumable/tomatojuice = 20,
+ /*
+ /datum/reagent/consumable/nutriment = 6,
+ /datum/reagent/consumable/tomatojuice = 10,
+ /datum/reagent/consumable/nutriment/vitamin = 3
+ */
+ )
+ percentage_of_nutriment_converted = 0.1
+
+// Tomato-eyeball soup
+/datum/reagent/consumable/nutriment/soup/eyeball
+ name = "Eyeball Soup"
+ description = "It looks back at you..."
+ data = list("tomato" = 1, "squirming" = 1)
+ color = "#FF1C1C"
+
+/datum/glass_style/has_foodtype/soup/eyeball
+ required_drink_type = /datum/reagent/consumable/nutriment/soup/eyeball
+ icon_state = "eyeballsoup"
+ drink_type = VEGETABLES | FRUIT | MEAT | GORE // Tomato soup + an eyeball
+
+/datum/chemical_reaction/food/soup/eyeballsoup
+ required_reagents = list(/datum/reagent/water = 50)
+ required_ingredients = list(
+ /obj/item/food/grown/tomato = 2,
+ /obj/item/organ/internal/eyes = 1,
+ )
+ results = list(
+ /datum/reagent/consumable/nutriment/soup/eyeball = 20,
+ // Logically this would be more but we wouldn't get the eyeball icon state if it was.
+ /datum/reagent/consumable/nutriment/soup/tomato = 10,
+ /datum/reagent/consumable/nutriment = 2,
+ /datum/reagent/consumable/nutriment/protein = 6,
+ /datum/reagent/consumable/tomatojuice = 6,
+ /datum/reagent/consumable/liquidgibs = 6,
+ )
+ percentage_of_nutriment_converted = 0.1
+
+// Miso soup
+/datum/reagent/consumable/nutriment/soup/miso
+ name = "Miso Soup"
+ description = "The universes best soup! Yum!!!"
+ data = list("miso" = 1)
+ glass_price = FOOD_PRICE_NORMAL
+ color = "#E2BD12"
+
+/datum/glass_style/has_foodtype/soup/miso
+ required_drink_type = /datum/reagent/consumable/nutriment/soup/miso
+ icon_state = "misosoup"
+ drink_type = VEGETABLES | BREAKFAST
+
+/datum/chemical_reaction/food/soup/misosoup
+ required_reagents = list(/datum/reagent/water = 50)
+ required_ingredients = list(
+ /obj/item/food/soydope = 2,
+ /obj/item/food/tofu = 2,
+ )
+ results = list(
+ /datum/reagent/consumable/nutriment/soup/miso = 30,
+ /datum/reagent/water = 10,
+ )
+ percentage_of_nutriment_converted = 0 // Soy has very low nutrients.
+
+// Blood soup
+// Fake tomato soup.
+// Can also appear by pouring blood into a bowl!
+/datum/glass_style/has_foodtype/soup/tomato/blood
+ required_drink_type = /datum/reagent/blood
+ name = "Tomato Soup"
+ desc = "Smells like copper."
+ drink_type = GROSS
+
+/datum/chemical_reaction/food/soup/bloodsoup
+ required_reagents = list(
+ /datum/reagent/water = 10,
+ /datum/reagent/blood = 10,
+ )
+ required_ingredients = list(
+ /obj/item/food/grown/tomato/blood = 2,
+ )
+ results = list(
+ // Blood tomatos will give us like 30u blood, so just add in the 10 from the recipe
+ /datum/reagent/blood = 10,
+ /datum/reagent/water = 8,
+ /datum/reagent/consumable/nutriment/protein = 7,
+ )
+ percentage_of_nutriment_converted = 0.1
+
+// Slime soup
+// Made with a slime extract, toxic to non-slime-people.
+// Can also be created by mixing water and slime jelly.
+/datum/reagent/consumable/nutriment/soup/slime
+ name = "Slime Soup"
+ description = "If no water is available, you may substitute tears."
+ data = list("slime" = 1)
+ glass_price = FOOD_PRICE_NORMAL
+ color = "#41C0C0"
+
+/datum/glass_style/has_foodtype/soup/slime
+ required_drink_type = /datum/reagent/consumable/nutriment/soup/slime
+ icon_state = "slimesoup"
+ drink_type = GROSS
+
+/datum/chemical_reaction/food/soup/slimesoup
+ required_reagents = list(
+ /datum/reagent/water = 40,
+ )
+ required_ingredients = list(
+ /obj/item/slime_extract = 1,
+ )
+ results = list(
+ /datum/reagent/consumable/nutriment/soup/slime = 30,
+ /datum/reagent/toxin/slimejelly = 20,
+ // Comes out of thin air, as none of our ingredients contain nutrients naturally.
+ /datum/reagent/consumable/nutriment = 7,
+ /datum/reagent/consumable/nutriment/vitamin = 7,
+ /datum/reagent/water = 6,
+ )
+
+/datum/chemical_reaction/food/soup/slimesoup/alt
+ // Alt recipe that allows you to create a slime soup by just mixing slime jelly and water.
+ // Pretty much just a normal chemical reaction.
+ // This also creates nutrients out of thin air.
+
+ required_other = FALSE
+ required_reagents = list(
+ /datum/reagent/water = 40,
+ /datum/reagent/toxin/slimejelly = 20,
+ )
+ required_ingredients = null
+
+// Clown Tear soup
+/datum/reagent/consumable/nutriment/soup/clown_tears
+ name = "Clown's Tears"
+ description = "The sorrow and melancholy of a thousand bereaved clowns, forever denied their Honkmechs."
+ nutriment_factor = 5 * REAGENTS_METABOLISM
+ ph = 9.2
+ data = list("a bad joke" = 1, "mournful honking" = 1)
+ color = "#EEF442"
+
+/datum/glass_style/has_foodtype/soup/clown_tears
+ required_drink_type = /datum/reagent/consumable/nutriment/soup/clown_tears
+ name = "clown's tears"
+ desc = "Not very funny."
+ icon_state = "clownstears"
+ drink_type = FRUIT | SUGAR
+
+/datum/chemical_reaction/food/soup/clownstears
+ required_reagents = list(
+ /datum/reagent/lube = 30,
+ )
+ required_ingredients = list(
+ /obj/item/food/grown/banana = 1,
+ /obj/item/stack/sheet/mineral/bananium = 1,
+ )
+ results = list(
+ /datum/reagent/consumable/nutriment/soup/clown_tears = 30,
+ /datum/reagent/consumable/banana = 8,
+ /datum/reagent/consumable/nutriment/vitamin = 12,
+ /datum/reagent/lube = 5,
+ )
+ percentage_of_nutriment_converted = 0 // Bananas have a small amount of nutrition naturally
+
+// Mystery soup
+// Acts a little funny, because when it's mixed it gains a new random reagent as well
+/datum/reagent/consumable/nutriment/soup/mystery
+ name = "Mystery Soup"
+ description = "The mystery is, why aren't you eating it?"
+ data = list("chaos" = 1)
+ color = "#4C2A18"
+
+/datum/glass_style/has_foodtype/soup/mystery
+ required_drink_type = /datum/reagent/consumable/nutriment/soup/mystery
+ icon_state = "mysterysoup"
+
+/datum/chemical_reaction/food/soup/mysterysoup
+ required_reagents = list(/datum/reagent/water = 50)
+ required_ingredients = list(
+ /obj/item/food/badrecipe = 1,
+ /obj/item/food/tofu = 1,
+ /obj/item/food/boiledegg = 1,
+ /obj/item/food/cheese/wedge = 1,
+ )
+ results = list(
+ /datum/reagent/consumable/nutriment/soup/mystery = 30,
+ )
+ percentage_of_nutriment_converted = 0.33 // Full of garbage
+
+ /// A list of reagent types we can randomly gain in the soup on creation
+ var/list/extra_reagent_types = list(
+ /datum/reagent/blood,
+ /datum/reagent/carbon,
+ /datum/reagent/consumable/banana,
+ /datum/reagent/consumable/capsaicin,
+ /datum/reagent/consumable/frostoil,
+ /datum/reagent/medicine/oculine,
+ /datum/reagent/medicine/omnizine,
+ /datum/reagent/toxin,
+ /datum/reagent/toxin/slimejelly,
+ )
+
+/datum/chemical_reaction/food/soup/mysterysoup/reaction_finish(datum/reagents/holder, datum/equilibrium/reaction, react_vol)
+ . = ..()
+ holder.add_reagent(pick(extra_reagent_types), 10)
+
+// Monkey Soup
+/datum/reagent/consumable/nutriment/soup/monkey
+ name = "Monkey's Delight"
+ description = "A delicious soup with dumplings and hunks of monkey meat simmered to perfection, in a broth that tastes faintly of bananas."
+ data = list("the jungle" = 1, "banana" = 1)
+ glass_price = FOOD_PRICE_NORMAL
+ color = "#4C2A18"
+
+/datum/glass_style/has_foodtype/soup/monkey
+ required_drink_type = /datum/reagent/consumable/nutriment/soup/monkey
+ icon_state = "monkeysdelight"
+ drink_type = FRUIT
+
+/obj/item/reagent_containers/cup/bowl/soup/monkey
+ initial_reagent = /datum/reagent/consumable/nutriment/soup/monkey
+
+/datum/chemical_reaction/food/soup/monkey
+ required_reagents = list(
+ /datum/reagent/water = 25,
+ /datum/reagent/consumable/flour = 5,
+ /datum/reagent/consumable/salt = 5,
+ /datum/reagent/consumable/blackpepper = 5,
+ )
+ required_ingredients = list(
+ /obj/item/food/monkeycube = 1, // This will make a monkey if a batch of 2 is made
+ /obj/item/food/grown/banana = 1,
+ )
+ results = list(
+ /datum/reagent/consumable/nutriment/soup/monkey = 30,
+ /datum/reagent/consumable/nutriment = 12,
+ /datum/reagent/consumable/salt = 4,
+ /datum/reagent/consumable/blackpepper = 4,
+ )
+
+// Cream of mushroom soup
+/datum/reagent/consumable/nutriment/soup/mushroom
+ name = "Chantrelle Soup"
+ description = "A delicious and hearty mushroom soup."
+ data = list("mushroom" = 1)
+ color = "#CEB1B0"
+
+/datum/glass_style/has_foodtype/soup/mushroom
+ required_drink_type = /datum/reagent/consumable/nutriment/soup/mushroom
+ icon_state = "mushroomsoup"
+ drink_type = VEGETABLES | DAIRY
+
+/datum/chemical_reaction/food/soup/mushroomsoup
+ required_reagents = list(
+ /datum/reagent/water = 40,
+ /datum/reagent/consumable/milk = 10,
+ )
+ required_ingredients = list(
+ /obj/item/food/grown/mushroom/chanterelle = 1,
+ )
+ results = list(
+ /datum/reagent/consumable/nutriment/soup/mushroom = 30,
+ /datum/reagent/consumable/nutriment = 9,
+ /datum/reagent/consumable/nutriment/vitamin = 8,
+ /datum/reagent/consumable/milk = 2,
+ )
+
+// Beet soup (Borscht)
+// This has a gimmick where it randomizes its name based on common mispellings on Borsch
+/datum/reagent/consumable/nutriment/soup/white_beet
+ name = "Beet Soup"
+ description = "Wait, how do you spell it again..?"
+ data = list("beet" = 1)
+ color = "#E00000"
+
+/datum/glass_style/has_foodtype/soup/white_beet
+ required_drink_type = /datum/reagent/consumable/nutriment/soup/white_beet
+ icon_state = "beetsoup"
+ drink_type = VEGETABLES | DAIRY
+
+/datum/glass_style/has_foodtype/soup/white_beet/set_name(obj/item/thing)
+ var/how_do_you_spell_it = pick("borsch", "bortsch", "borstch", "borsh", "borshch", "borscht")
+ thing.name = how_do_you_spell_it
+
+ var/datum/reagent/soup = locate(required_drink_type) in thing.reagents
+ if(!soup)
+ // Shouldn't happen but things are weird
+ return
+
+ // Update tastes with the new name
+ LAZYSET(soup.data, how_do_you_spell_it, 1)
+ // Not perfect. Doesn't clear when the bowl type is unset. But it'll do well enough
+
+/obj/item/reagent_containers/cup/bowl/soup/white_beet
+ initial_reagent = /datum/reagent/consumable/nutriment/soup/white_beet
+
+/datum/chemical_reaction/food/soup/beetsoup
+ required_reagents = list(/datum/reagent/water = 50)
+ required_ingredients = list(
+ /obj/item/food/grown/whitebeet = 1,
+ /obj/item/food/grown/cabbage = 1,
+ )
+ results = list(
+ /datum/reagent/consumable/nutriment/soup/white_beet = 30,
+ /datum/reagent/water = 10,
+ )
+ percentage_of_nutriment_converted = 0.1
+
+// Stew
+/datum/reagent/consumable/nutriment/soup/stew
+ name = "Stew"
+ description = "A nice and warm stew. Healthy and strong."
+ data = list("tomato" = 1, "carrot" = 1)
+ glass_price = FOOD_PRICE_NORMAL
+ color = "#EB7C82"
+
+/datum/glass_style/has_foodtype/soup/stew
+ required_drink_type = /datum/reagent/consumable/nutriment/soup/stew
+ icon_state = "stew"
+ drink_type = VEGETABLES | FRUIT | MEAT
+
+/obj/item/reagent_containers/cup/bowl/soup/stew
+ initial_reagent = /datum/reagent/consumable/nutriment/soup/stew
+
+/datum/chemical_reaction/food/soup/stew
+ required_reagents = list(/datum/reagent/water = 50)
+ required_ingredients = list(
+ /obj/item/food/grown/tomato = 1,
+ /obj/item/food/meat/cutlet = 3,
+ /obj/item/food/grown/potato = 1,
+ /obj/item/food/grown/carrot = 1,
+ /obj/item/food/grown/eggplant = 1,
+ /obj/item/food/grown/mushroom = 1,
+ )
+ results = list(
+ /datum/reagent/consumable/nutriment/soup/stew = 30,
+ /datum/reagent/consumable/tomatojuice = 10,
+ // Gains a ton of nutriments from the variety of ingredients.
+ )
+
+// Sweet potato soup
+/datum/reagent/consumable/nutriment/soup/sweetpotato
+ name = "Sweet Potato Soup"
+ description = "Delicious sweet potato in soup form."
+ data = list("sweet potato" = 1)
+ color = "#903E22"
+
+/datum/glass_style/has_foodtype/soup/sweetpotato
+ required_drink_type = /datum/reagent/consumable/nutriment/soup/sweetpotato
+ icon_state = "sweetpotatosoup"
+ drink_type = VEGETABLES | SUGAR
+
+/obj/item/reagent_containers/cup/bowl/soup/sweetpotato
+ initial_reagent = /datum/reagent/consumable/nutriment/soup/sweetpotato
+
+/datum/chemical_reaction/food/soup/sweetpotatosoup
+ required_reagents = list(
+ /datum/reagent/water = 40,
+ /datum/reagent/consumable/milk = 10, // Coconut milk, but, close enough
+ )
+ required_ingredients = list(
+ /obj/item/food/grown/potato/sweet = 2,
+ )
+ results = list(
+ /datum/reagent/consumable/nutriment/soup/sweetpotato = 30,
+ /datum/reagent/water = 10,
+ )
+
+// Red beet soup
+/datum/reagent/consumable/nutriment/soup/red_beet
+ name = "Red Beet Soup"
+ description = "Quite a delicacy."
+ data = list("beet" = 1)
+ color = "#851127"
+
+/datum/glass_style/has_foodtype/soup/red_beet
+ required_drink_type = /datum/reagent/consumable/nutriment/soup/red_beet
+ icon_state = "redbeetsoup"
+ drink_type = VEGETABLES
+
+/datum/chemical_reaction/food/soup/redbeetsoup
+ required_reagents = list(/datum/reagent/water = 50)
+ required_ingredients = list(
+ /obj/item/food/grown/redbeet = 1,
+ /obj/item/food/grown/cabbage = 1,
+ )
+ results = list(
+ /datum/reagent/consumable/nutriment/soup/red_beet = 30,
+ /datum/reagent/water = 10,
+ )
+ percentage_of_nutriment_converted = 0.1
+
+// French Onion soup
+/datum/reagent/consumable/nutriment/soup/french_onion
+ name = "French Onion Soup"
+ description = "Good enough to make a grown mime cry."
+ data = list("caramelized onions" = 1)
+ color = "#E1C47F"
+
+/datum/glass_style/has_foodtype/soup/french_onion
+ required_drink_type = /datum/reagent/consumable/nutriment/soup/french_onion
+ icon_state = "onionsoup"
+ drink_type = VEGETABLES | DAIRY
+
+/datum/chemical_reaction/food/soup/onionsoup
+ required_reagents = list(/datum/reagent/water = 50)
+ required_ingredients = list(
+ /obj/item/food/grown/onion = 1,
+ /obj/item/food/cheese/wedge = 1,
+ )
+ results = list(
+ /datum/reagent/consumable/nutriment/soup/french_onion = 30,
+ /datum/reagent/consumable/nutriment/protein = 8, // No idea where this comes from
+ /datum/reagent/consumable/tomatojuice = 8, // No idea where this comes from
+ )
+ ingredient_reagent_multiplier = 0.5 // Onions are very reagent heavy
+ percentage_of_nutriment_converted = 0.1
+
+// Bisque / Crab soup
+/datum/reagent/consumable/nutriment/soup/bisque
+ name = "Bisque"
+ description = "A classic entree from Space-France."
+ data = list("creamy texture" = 1, "crab" = 4)
+ glass_price = FOOD_PRICE_EXOTIC
+ color = "#C8682F"
+
+/datum/glass_style/has_foodtype/soup/bisque
+ required_drink_type = /datum/reagent/consumable/nutriment/soup/bisque
+ icon_state = "bisque"
+ drink_type = MEAT
+
+/datum/chemical_reaction/food/soup/bisque
+ required_reagents = list(/datum/reagent/water = 50)
+ required_ingredients = list(
+ /obj/item/food/meat/crab = 1,
+ /obj/item/food/boiledrice = 1,
+ )
+ results = list(
+ /datum/reagent/consumable/nutriment/soup/bisque = 30,
+ /datum/reagent/consumable/nutriment/protein = 6,
+ /datum/reagent/consumable/nutriment/vitamin = 4,
+ /datum/reagent/water = 5,
+ )
+
+// Bungo Tree Curry
+/datum/reagent/consumable/nutriment/soup/bungo
+ name = "Bungo Curry"
+ description = "A spicy vegetable curry made with the humble bungo fruit, Exotic!"
+ data = list("bungo" = 2, "hot curry" = 4, "tropical sweetness" = 1)
+ glass_price = FOOD_PRICE_NORMAL
+ color = "#E6BC32"
+
+/datum/glass_style/has_foodtype/soup/bungo
+ required_drink_type = /datum/reagent/consumable/nutriment/soup/bungo
+ icon_state = "bungocurry"
+ drink_type = VEGETABLES | FRUIT | DAIRY
+
+/datum/chemical_reaction/food/soup/bungocurry
+ required_reagents = list(
+ /datum/reagent/water = 40,
+ /datum/reagent/consumable/cream = 10,
+ )
+ required_ingredients = list(
+ /obj/item/food/grown/chili = 1,
+ /obj/item/food/grown/bungofruit = 1,
+ )
+ results = list(
+ /datum/reagent/consumable/nutriment/soup/bungo = 30,
+ /datum/reagent/consumable/bungojuice = 15,
+ )
+ percentage_of_nutriment_converted = 0.1
+
+// Electron Soup.
+// Special soup for Ethereals to consume to gain nutrition (energy) from.
+/datum/reagent/consumable/nutriment/soup/electrons
+ name = "Electron Soup"
+ description = "A gastronomic curiosity of ethereal origin. It is famed for the minature weather system formed over a properly prepared soup."
+ data = list("mushroom" = 1, "electrons" = 4)
+ glass_price = FOOD_PRICE_EXOTIC
+ color = "#E60040"
+
+/datum/glass_style/has_foodtype/soup/electrons
+ required_drink_type = /datum/reagent/consumable/nutriment/soup/electrons
+ icon_state = "electronsoup"
+ drink_type = VEGETABLES | TOXIC
+
+/datum/chemical_reaction/food/soup/electron
+ required_reagents = list(
+ /datum/reagent/water = 45,
+ /datum/reagent/consumable/salt = 5,
+ )
+ required_ingredients = list(
+ /obj/item/food/grown/mushroom/jupitercup = 1,
+ )
+ results = list(
+ /datum/reagent/consumable/nutriment/soup/electrons = 30,
+ // Jupiter cups obviously contain a fair amount of LE naturally,
+ // but to make it "worthwhile" for Ethereals to eat we add a bit extra
+ /datum/reagent/consumable/liquidelectricity/enriched = 10,
+ )
+ percentage_of_nutriment_converted = 0.10
+
+// Pea Soup
+/datum/reagent/consumable/nutriment/soup/pea
+ name = "Pea Soup"
+ description = "A humble split pea soup."
+ data = list("creamy peas" = 2, "parsnip" = 1)
+ color = "#9D7B20"
+
+/datum/glass_style/has_foodtype/soup/pea
+ required_drink_type = /datum/reagent/consumable/nutriment/soup/pea
+ icon_state = "peasoup"
+ drink_type = VEGETABLES
+
+/datum/chemical_reaction/food/soup/peasoup
+ required_reagents = list(/datum/reagent/water = 50)
+ required_ingredients = list(
+ /obj/item/food/grown/peas = 2,
+ /obj/item/food/grown/parsnip = 1,
+ /obj/item/food/grown/carrot = 1,
+ )
+ results = list(
+ /datum/reagent/consumable/nutriment/soup/pea = 30,
+ /datum/reagent/water = 10,
+ )
+
+// Indian curry
+/datum/reagent/consumable/nutriment/soup/indian_curry
+ name = "Indian Chicken Curry"
+ description = "A mild, creamy curry from the old subcontinent. Liked by the Space-British, because it reminds them of the Raj."
+ data = list("chicken" = 2, "creamy curry" = 4, "earthy heat" = 1)
+ glass_price = FOOD_PRICE_NORMAL
+ color = "#BB2D1A"
+
+/datum/glass_style/has_foodtype/soup/indian_curry
+ required_drink_type = /datum/reagent/consumable/nutriment/soup/indian_curry
+ icon_state = "indian_curry"
+ drink_type = VEGETABLES | MEAT | DAIRY
+
+/datum/chemical_reaction/food/soup/indian_curry
+ required_reagents = list(
+ /datum/reagent/water = 50,
+ /datum/reagent/consumable/cream = 5,
+ )
+ required_ingredients = list(
+ /obj/item/food/meat/slab/chicken = 1,
+ /obj/item/food/grown/onion = 2,
+ /obj/item/food/grown/chili = 1,
+ /obj/item/food/grown/garlic = 1,
+ /obj/item/food/butter = 1,
+ /obj/item/food/boiledrice = 1,
+ )
+ results = list(
+ /datum/reagent/consumable/nutriment/soup/indian_curry = 30,
+ // Gains a ton of other reagents from ingredients.
+ )
+
+// Oatmeal (Soup like)
+/datum/reagent/consumable/nutriment/soup/oatmeal
+ name = "Oatmeal"
+ description = "A nice bowl of oatmeal."
+ data = list("oats" = 1, "milk" = 1)
+ color = "#FFD7B4"
+
+/datum/glass_style/has_foodtype/soup/oatmeal
+ required_drink_type = /datum/reagent/consumable/nutriment/soup/oatmeal
+ icon_state = "oatmeal"
+ drink_type = DAIRY | GRAIN | BREAKFAST
+
+/datum/chemical_reaction/food/soup/oatmeal
+ required_reagents = list(
+ /datum/reagent/consumable/milk = 20,
+ )
+ required_ingredients = list(
+ /obj/item/food/grown/oat = 2,
+ )
+ results = list(
+ /datum/reagent/consumable/nutriment/soup/oatmeal = 20,
+ /datum/reagent/consumable/milk = 12,
+ /datum/reagent/consumable/nutriment/vitamin = 8,
+ )
+ percentage_of_nutriment_converted = 0 // Oats have barely any nutrients
+
+// Zurek, a Polish soup
+/datum/reagent/consumable/nutriment/soup/zurek
+ name = "Zurek"
+ description = "A traditional Polish soup composed of vegetables, meat, and an egg. Goes great with bread."
+ data = list("creamy vegetables" = 2, "sausage" = 1)
+ color = "#F1CB6D"
+
+/datum/glass_style/has_foodtype/soup/zurek
+ required_drink_type = /datum/reagent/consumable/nutriment/soup/zurek
+ icon_state = "zurek"
+ drink_type = VEGETABLES | MEAT | GRAIN | BREAKFAST
+
+/datum/chemical_reaction/food/soup/zurek
+ required_reagents = list(
+ /datum/reagent/water = 40,
+ /datum/reagent/consumable/flour = 10,
+ )
+ required_ingredients = list(
+ /obj/item/food/boiledegg = 1,
+ /obj/item/food/meat/cutlet = 1,
+ /obj/item/food/grown/carrot = 1,
+ /obj/item/food/grown/onion = 1,
+ )
+ results = list(
+ /datum/reagent/consumable/nutriment/soup/zurek = 30,
+ )
+ ingredient_reagent_multiplier = 0.5
+ percentage_of_nutriment_converted = 0.1
+
+// Cullen Skink, a Scottish soup with a funny name
+/datum/reagent/consumable/nutriment/soup/cullen_skink
+ name = "Cullen Skink"
+ description = "A thick Scottish soup made of smoked fish, potatoes and onions."
+ data = list("creamy broth" = 1, "fish" = 1, "vegetables" = 1)
+ color = "#F6F664"
+
+/datum/glass_style/has_foodtype/soup/cullen_skink
+ required_drink_type = /datum/reagent/consumable/nutriment/soup/cullen_skink
+ icon_state = "cullen_skink"
+ drink_type = VEGETABLES | SEAFOOD | DAIRY
+
+/datum/chemical_reaction/food/soup/cullen_skink
+ required_reagents = list(
+ /datum/reagent/water = 40,
+ /datum/reagent/consumable/milk = 10,
+ /datum/reagent/consumable/blackpepper = 4,
+ )
+ required_ingredients = list(
+ /obj/item/food/fishmeat = 1,
+ /obj/item/food/grown/onion = 1,
+ /obj/item/food/grown/potato = 1,
+ )
+ results = list(
+ /datum/reagent/consumable/nutriment/soup/cullen_skink = 30,
+ /datum/reagent/consumable/nutriment = 6,
+ /datum/reagent/consumable/nutriment/protein = 4,
+ /datum/reagent/consumable/nutriment/vitamin = 4,
+ /datum/reagent/water = 6,
+ )
+ ingredient_reagent_multiplier = 0.5
+ percentage_of_nutriment_converted = 0
+
+// Chicken Noodle Soup
+/datum/reagent/consumable/nutriment/soup/chicken_noodle_soup
+ name = "Chicken Noodle Soup"
+ description = "A hearty bowl of chicken noodle soup, perfect for when you're stuck at home and sick."
+ data = list("broth" = 1, "chicken" = 1, "noodles" = 1, "carrots" = 1)
+ color = "#DDB23E"
+
+/datum/glass_style/has_foodtype/soup/chicken_noodle_soup
+ required_drink_type = /datum/reagent/consumable/nutriment/soup/chicken_noodle_soup
+ icon_state = "chicken_noodle_soup"
+ drink_type = VEGETABLES | MEAT | GRAIN
+
+/datum/chemical_reaction/food/soup/chicken_noodle_soup
+ required_reagents = list(/datum/reagent/water = 30)
+ required_ingredients = list(
+ /obj/item/food/grown/carrot = 1,
+ /obj/item/food/meat/slab/chicken = 1,
+ /obj/item/food/spaghetti/boiledspaghetti = 1,
+ )
+ results = list(
+ /datum/reagent/consumable/nutriment/soup/chicken_noodle_soup = 30,
+ /datum/reagent/consumable/nutriment = 2,
+ /datum/reagent/consumable/nutriment/vitamin = 3,
+ /datum/reagent/consumable/nutriment/protein = 5,
+ )
+
+// Corn Cowder
+/datum/reagent/consumable/nutriment/soup/corn_chowder
+ name = "Corn Chowder"
+ description = "A creamy bowl of corn chowder, with bacon bits and mixed vegetables. One bowl is never enough."
+ data = list("creamy broth" = 1, "bacon" = 1, "mixed vegetables" = 1)
+ color = "#FFF200"
+
+/datum/glass_style/has_foodtype/soup/corn_chowder
+ required_drink_type = /datum/reagent/consumable/nutriment/soup/corn_chowder
+ icon_state = "corn_chowder"
+ drink_type = VEGETABLES | MEAT
+
+/datum/chemical_reaction/food/soup/corn_chowder
+ required_reagents = list(
+ /datum/reagent/water = 40,
+ /datum/reagent/consumable/cream = 5,
+ )
+ required_ingredients = list(
+ /obj/item/food/grown/corn = 1,
+ /obj/item/food/grown/potato = 1,
+ /obj/item/food/grown/carrot = 1,
+ /obj/item/food/meat/bacon = 1,
+ )
+ results = list(
+ /datum/reagent/consumable/nutriment/soup/corn_chowder = 30,
+ /datum/reagent/consumable/nutriment/protein = 4,
+ /datum/reagent/consumable/nutriment = 2,
+ )
+
+// Lizard stuff
+
+// Atrakor Dumpling soup
+/datum/reagent/consumable/nutriment/soup/atrakor_dumplings
+ name = "\improper Atrakor dumpling soup"
+ description = "A bowl of rich, meaty dumpling soup, traditionally served during the festival of Atrakor's Might on Tizira. The dumplings are shaped like the Night Sky Lord himself."
+ data = list("bone broth" = 1, "onion" = 1, "potato" = 1)
+ color = "#7B453B"
+
+/datum/glass_style/has_foodtype/soup/atrakor_dumplings
+ required_drink_type = /datum/reagent/consumable/nutriment/soup/atrakor_dumplings
+ icon = 'icons/obj/food/lizard.dmi'
+ icon_state = "atrakor_dumplings"
+ drink_type = MEAT | VEGETABLES | NUTS
+
+/datum/chemical_reaction/food/soup/atrakor_dumplings
+ required_reagents = list(
+ /datum/reagent/water = 40,
+ /datum/reagent/consumable/soysauce = 10,
+ )
+ required_ingredients = list(
+ /obj/item/food/meat/rawcutlet = 2,
+ /obj/item/food/grown/onion = 1,
+ /obj/item/food/lizard_dumplings = 1,
+ )
+ results = list(
+ /datum/reagent/consumable/nutriment/soup/atrakor_dumplings = 30,
+ /datum/reagent/water = 10,
+ )
+ ingredient_reagent_multiplier = 0.5
+ percentage_of_nutriment_converted = 0.2
+
+// Meatball Soup, but lizard-like
+/datum/reagent/consumable/nutriment/soup/meatball_noodles
+ name = "Meatball Noodle Soup"
+ description = "A hearty noodle soup made from meatballs and nizaya in a rich broth. Commonly topped with a handful of chopped nuts."
+ data = list("bone broth" = 1, "meat" = 1, "gnocchi" = 1, "peanuts" = 1)
+ color = "#915145"
+
+/datum/glass_style/has_foodtype/soup/meatball_noodles
+ required_drink_type = /datum/reagent/consumable/nutriment/soup/meatball_noodles
+ icon = 'icons/obj/food/lizard.dmi'
+ icon_state = "meatball_noodles"
+ drink_type = MEAT | VEGETABLES | NUTS
+
+/datum/chemical_reaction/food/soup/meatball_noodles
+ required_reagents = list(/datum/reagent/water = 50)
+ required_ingredients = list(
+ /obj/item/food/meat/rawcutlet = 2,
+ /obj/item/food/grown/onion = 1,
+ /obj/item/food/spaghetti/nizaya = 1,
+ /obj/item/food/meatball = 2,
+ /obj/item/food/grown/peanut = 1
+ )
+ results = list(
+ /datum/reagent/consumable/nutriment/soup/meatball_noodles = 30,
+ /datum/reagent/water = 10,
+ )
+ ingredient_reagent_multiplier = 0.5
+ percentage_of_nutriment_converted = 0.1
+
+// Black Broth
+/datum/reagent/consumable/nutriment/soup/black_broth
+ name = "\improper Tiziran black broth"
+ description = "A bowl of sausage, onion, blood and vinegar, served ice cold. Every bit as rough as it sounds."
+ data = list("vinegar" = 1, "iron" = 1)
+ color = "#340010"
+
+/datum/glass_style/has_foodtype/soup/black_broth
+ required_drink_type = /datum/reagent/consumable/nutriment/soup/black_broth
+ icon = 'icons/obj/food/lizard.dmi'
+ icon_state = "black_broth"
+ drink_type = MEAT | VEGETABLES | GORE
+
+/datum/chemical_reaction/food/soup/black_broth
+ required_reagents = list(
+ /datum/reagent/water = 40,
+ /datum/reagent/consumable/vinegar = 8,
+ /datum/reagent/blood = 8,
+ /datum/reagent/consumable/ice = 4,
+ )
+ required_ingredients = list(
+ /obj/item/food/tiziran_sausage = 1,
+ /obj/item/food/grown/onion = 1,
+ )
+ results = list(
+ /datum/reagent/consumable/nutriment/soup/black_broth = 30,
+ /datum/reagent/blood = 8,
+ /datum/reagent/consumable/liquidgibs = 7,
+ /datum/reagent/consumable/vinegar = 5,
+ )
+ ingredient_reagent_multiplier = 0.5
+ percentage_of_nutriment_converted = 0.1
+
+// Jellyfish Stew
+/datum/reagent/consumable/nutriment/soup/jellyfish
+ name = "Jellyfish Stew"
+ description = "A slimy bowl of jellyfish stew. It jiggles if you shake it."
+ data = list("slime" = 1)
+ color = "#3FAA7E"
+
+/datum/glass_style/has_foodtype/soup/jellyfish
+ required_drink_type = /datum/reagent/consumable/nutriment/soup/jellyfish
+ icon = 'icons/obj/food/lizard.dmi'
+ icon_state = "jellyfish_stew"
+ drink_type = MEAT | VEGETABLES | GORE
+
+/datum/chemical_reaction/food/soup/jellyfish_stew
+ required_reagents = list(/datum/reagent/water = 50)
+ required_ingredients = list(
+ /obj/item/food/canned/jellyfish = 1,
+ /obj/item/food/grown/soybeans = 1,
+ /obj/item/food/grown/redbeet = 1,
+ /obj/item/food/grown/potato = 1
+ )
+ results = list(
+ /datum/reagent/consumable/nutriment/soup/jellyfish = 30,
+ /datum/reagent/water = 5,
+ )
+
+// Rootbread Soup
+/datum/reagent/consumable/nutriment/soup/rootbread
+ name = "Rootbread Soup"
+ description = "A big bowl of spicy, savoury soup made with rootbread. Heavily seasoned, and very tasty."
+ data = list("bread" = 1, "egg" = 1, "chili" = 1, "garlic" = 1)
+ color = "#AC3232"
+
+/datum/glass_style/has_foodtype/soup/rootbread
+ required_drink_type = /datum/reagent/consumable/nutriment/soup/rootbread
+ icon = 'icons/obj/food/lizard.dmi'
+ icon_state = "rootbread_soup"
+ drink_type = MEAT | VEGETABLES
+
+/datum/chemical_reaction/food/soup/rootbread_soup
+ required_reagents = list(/datum/reagent/water = 50)
+ required_ingredients = list(
+ /obj/item/food/breadslice/root = 2,
+ /obj/item/food/grown/garlic = 1,
+ /obj/item/food/grown/chili = 1,
+ /obj/item/food/egg = 1
+ )
+ results = list(
+ /datum/reagent/consumable/nutriment/soup/rootbread = 30,
+ /datum/reagent/consumable/nutriment/protein = 8,
+ )
+ percentage_of_nutriment_converted = 0.2
+
+// Moth stuff
+
+// Cotton Soup
+/datum/reagent/consumable/nutriment/soup/cottonball
+ name = "Flöfrölenmæsch" //flöf = cotton, rölen = ball, mæsch = soup
+ description = "A soup made from raw cotton in a flavourful vegetable broth. Enjoyed only by moths and the criminally tasteless."
+ data = list("cotton" = 1, "broth" = 1)
+ color = "#E6A625"
+
+/datum/glass_style/has_foodtype/soup/cottonball
+ required_drink_type = /datum/reagent/consumable/nutriment/soup/cottonball
+ name = "flöfrölenmæsch"
+ icon = 'icons/obj/food/moth.dmi'
+ icon_state = "moth_cotton_soup"
+ drink_type = VEGETABLES | CLOTH
+
+/datum/chemical_reaction/food/soup/cottonball
+ required_reagents = list(/datum/reagent/water = 50)
+ required_ingredients = list(
+ /obj/item/grown/cotton = 1, // Why are you buying clothes at the soup store?!
+ /obj/item/food/grown/onion = 1,
+ /obj/item/food/grown/carrot = 1,
+ /obj/item/food/grown/eggplant = 1,
+ /obj/item/food/oven_baked_corn = 1,
+ )
+ results = list(
+ /datum/reagent/consumable/nutriment/soup/cottonball = 30,
+ )
+ ingredient_reagent_multiplier = 0.5
+ percentage_of_nutriment_converted = 0.1 // Cotton has no nutrition
+
+// Cheese Soup
+/datum/reagent/consumable/nutriment/soup/cheese
+ name = "Ælosterrmæsch" //ælo = cheese, sterr = melt, mæsch = soup
+ description = "A simple and filling soup made from homemade cheese and sweet potato. \
+ The curds provide texture while the whey provides volume- and they both provide deliciousness!"
+ data = list("cheese" = 1, "cream" = 1, "sweet potato" = 1)
+ color = "#F3CE3A"
+
+/datum/glass_style/has_foodtype/soup/cheese
+ required_drink_type = /datum/reagent/consumable/nutriment/soup/cheese
+ name = "ælosterrmæsch"
+ icon = 'icons/obj/food/moth.dmi'
+ icon_state = "moth_cheese_soup"
+ drink_type = DAIRY | GRAIN
+
+/datum/chemical_reaction/food/soup/cheese
+ required_reagents = list(
+ /datum/reagent/water = 30,
+ /datum/reagent/consumable/flour = 10,
+ /datum/reagent/consumable/milk = 10,
+ )
+ required_ingredients = list(
+ /obj/item/food/cheese/wedge = 2,
+ /obj/item/food/butter = 1,
+ /obj/item/food/grown/potato/sweet = 1,
+ )
+ results = list(
+ /datum/reagent/consumable/nutriment/soup/cheese = 30,
+ /datum/reagent/consumable/nutriment/protein = 8,
+ /datum/reagent/consumable/milk = 2,
+ )
+
+// Seed Soup
+/datum/reagent/consumable/nutriment/soup/seed
+ name = "Misklmæsch" //miskl = seed, mæsch = soup
+ description = "A seed based soup, made by germinating seeds and then boiling them. \
+ Produces a particularly bitter broth which is usually balanced by the addition of vinegar."
+ data = list("bitterness" = 1, "sourness" = 1)
+ color = "#4F6F31"
+
+/datum/glass_style/has_foodtype/soup/seed
+ required_drink_type = /datum/reagent/consumable/nutriment/soup/seed
+ name = "misklmæsch"
+ icon = 'icons/obj/food/moth.dmi'
+ icon_state = "moth_seed_soup"
+ drink_type = VEGETABLES
+
+/datum/chemical_reaction/food/soup/seed
+ required_reagents = list(
+ /datum/reagent/water = 40,
+ /datum/reagent/consumable/vinegar = 10,
+ )
+ required_ingredients = list(
+ /obj/item/seeds/sunflower = 1,
+ /obj/item/seeds/poppy/lily = 1,
+ /obj/item/seeds/ambrosia = 1,
+ )
+ results = list(
+ /datum/reagent/consumable/nutriment/soup/seed = 30,
+ /datum/reagent/consumable/nutriment/vitamin = 13,
+ /datum/reagent/consumable/nutriment = 12,
+ /datum/reagent/consumable/vinegar = 8,
+ /datum/reagent/water = 7,
+ )
+
+// Bean Soup
+/datum/reagent/consumable/nutriment/soup/beans
+ name = "Prickeldröndolhaskl" //prickeld = spicy, röndol = bean, haskl = stew
+ description = "A spicy bean stew with lots of veggies, commonly served aboard the fleet as a filling and satisfying meal with rice or bread."
+ data = list("beans" = 1, "cabbage" = 1, "spicy sauce" = 1)
+ color = "#DF7126"
+
+/datum/glass_style/has_foodtype/soup/beans
+ required_drink_type = /datum/reagent/consumable/nutriment/soup/beans
+ name = "prickeldröndolhaskl"
+ icon = 'icons/obj/food/moth.dmi'
+ icon_state = "moth_bean_stew"
+ drink_type = VEGETABLES
+
+/datum/chemical_reaction/food/soup/beans
+ required_reagents = list(/datum/reagent/water = 50)
+ required_ingredients = list(
+ /obj/item/food/canned/beans = 1,
+ /obj/item/food/grown/cabbage = 1,
+ /obj/item/food/grown/tomato = 1,
+ /obj/item/food/grown/onion = 1,
+ /obj/item/food/grown/chili = 1,
+ /obj/item/food/oven_baked_corn = 1,
+ )
+ results = list(
+ /datum/reagent/consumable/nutriment/soup/beans = 30,
+ /datum/reagent/consumable/nutriment/protein = 10,
+ /datum/reagent/water = 10,
+ )
+ ingredient_reagent_multiplier = 0.5
+ percentage_of_nutriment_converted = 0.1
+
+// Oat Soup, but not oatmeal
+/datum/reagent/consumable/nutriment/soup/moth_oats
+ name = "Häfmisklhaskl" //häfmiskl = oat (häf from German hafer meaning oat, miskl meaning seed), haskl = stew
+ description = "A spicy bean stew with lots of veggies, commonly served aboard the fleet as a filling and satisfying meal with rice or bread."
+ data = list("oats" = 1, "sweet potato" = 1, "carrot" = 1, "parsnip" = 1, "pumpkin" = 1)
+ color = "#CAA94E"
+
+/datum/glass_style/has_foodtype/soup/moth_oats
+ required_drink_type = /datum/reagent/consumable/nutriment/soup/moth_oats
+ name = "häfmisklhaskl"
+ icon = 'icons/obj/food/moth.dmi'
+ icon_state = "moth_oat_stew"
+ drink_type = VEGETABLES | GRAIN
+
+/datum/chemical_reaction/food/soup/moth_oats
+ required_reagents = list(/datum/reagent/water = 50)
+ required_ingredients = list(
+ /obj/item/food/grown/oat = 1,
+ /obj/item/food/grown/potato/sweet = 1,
+ /obj/item/food/grown/parsnip = 1,
+ /obj/item/food/grown/carrot = 1,
+ )
+ results = list(
+ /datum/reagent/consumable/nutriment/soup/moth_oats = 30,
+ )
+ percentage_of_nutriment_converted = 0.1
+
+// Fire Soup
+/datum/reagent/consumable/nutriment/soup/fire_soup
+ name = "Tömpröttkrakklmæsch" //tömprött = heart (tömp = thump, rött = muscle), krakkl = fire, mæsch = soup
+ description = "Tömpröttkrakklmæsch, or heartburn soup, is a cold soup dish that originated amongst the jungle moths, \
+ and is named for two things- its rosy pink colour, and its scorchingly hot chili heat."
+ data = list("love" = 1, "hate" = 1)
+ color = "#FBA8F3"
+
+/datum/glass_style/has_foodtype/soup/fire_soup
+ required_drink_type = /datum/reagent/consumable/nutriment/soup/fire_soup
+ name = "tömpröttkrakklmæsch"
+ icon = 'icons/obj/food/moth.dmi'
+ icon_state = "moth_fire_soup"
+ drink_type = VEGETABLES | DAIRY
+
+/datum/chemical_reaction/food/soup/fire_soup
+ required_reagents = list(
+ /datum/reagent/water = 30,
+ /datum/reagent/consumable/yoghurt = 15,
+ /datum/reagent/consumable/vinegar = 5,
+ )
+ required_ingredients = list(
+ /obj/item/food/grown/ghost_chili = 1,
+ /obj/item/food/tofu = 1,
+ )
+ results = list(
+ /datum/reagent/consumable/nutriment/soup/fire_soup = 30,
+ /datum/reagent/consumable/nutriment/protein = 8,
+ /datum/reagent/consumable/vinegar = 2,
+ )
+ ingredient_reagent_multiplier = 0.33 // Chilis have a TON of capsaicin naturally
+ percentage_of_nutriment_converted = 0
+
+// Rice Porridge (Soup-ish)
+/datum/reagent/consumable/nutriment/soup/rice_porridge
+ name = "Rice Porridge"
+ description = "A plate of rice porridge. It's mostly flavourless, but it does fill a spot. \
+ To the Chinese it's congee, and moths call it höllflöfmisklsløsk." //höllflöfmiskl = rice (höllflöf = cloud, miskl = seed), sløsk = porridge
+ data = list("nothing" = 1)
+ color = "#EDE3E3"
+
+/datum/glass_style/has_foodtype/soup/rice_porridge
+ required_drink_type = /datum/reagent/consumable/nutriment/soup/rice_porridge
+ name = "rice porridge"
+ icon = 'icons/obj/food/moth.dmi'
+ icon_state = "rice_porridge"
+ drink_type = GRAIN
+
+/datum/chemical_reaction/food/soup/rice_porridge
+ required_reagents = list(
+ /datum/reagent/water = 30,
+ /datum/reagent/consumable/salt = 5,
+ )
+ required_ingredients = list(
+ /obj/item/food/boiledrice = 1,
+ )
+ results = list(
+ /datum/reagent/consumable/nutriment/soup/rice_porridge = 20,
+ /datum/reagent/consumable/salt = 5,
+ )
+ percentage_of_nutriment_converted = 0.15
+
+// Cornmeal Porridge (Soup-ish)
+// Also, pretty much just a normal chemical reaction. Used in other stuff
+/datum/reagent/consumable/nutriment/soup/cornmeal_porridge
+ name = "Cornmeal Porridge"
+ description = "A plate of cornmeal porridge. It's more flavourful than most porridges, and makes a good base for other flavours, too."
+ data = list("cornmeal" = 1)
+ color = "#ECDA7B"
+
+/datum/glass_style/has_foodtype/soup/cornmeal_porridge
+ required_drink_type = /datum/reagent/consumable/nutriment/soup/cornmeal_porridge
+ name = "cornmeal porridge"
+ icon = 'icons/obj/food/moth.dmi'
+ icon_state = "cornmeal_porridge"
+ drink_type = GRAIN
+
+/datum/chemical_reaction/food/soup/cornmeal_porridge
+ required_other = FALSE
+ required_reagents = list(
+ /datum/reagent/consumable/cornmeal = 20,
+ /datum/reagent/water = 20,
+ )
+ results = list(
+ /datum/reagent/consumable/nutriment/soup/cornmeal_porridge = 20,
+ )
+
+// Cheese Porridge (Soup-ish)
+/datum/reagent/consumable/nutriment/soup/cheese_porridge
+ name = "Cheesy Porridge" //milk, polenta, firm cheese, curd cheese, butter
+ description = "A rich and creamy bowl of cheesy cornmeal porridge."
+ data = list("cornmeal" = 1, "cheese" = 1, "more cheese" = 1, "lots of cheese" = 1)
+ color = "#F0DD5A"
+
+/datum/glass_style/has_foodtype/soup/cheese_porridge
+ required_drink_type = /datum/reagent/consumable/nutriment/soup/cheese_porridge
+ name = "cheesy porridge"
+ icon = 'icons/obj/food/moth.dmi'
+ icon_state = "cheesy_porridge"
+ drink_type = DAIRY | GRAIN
+
+/datum/chemical_reaction/food/soup/cheese_porridge
+ required_reagents = list(
+ /datum/reagent/consumable/milk = 5,
+ /datum/reagent/consumable/nutriment/soup/cornmeal_porridge = 20,
+ /datum/reagent/water = 20,
+ )
+ required_ingredients = list(
+ /obj/item/food/cheese/firm_cheese_slice = 1,
+ /obj/item/food/cheese/curd_cheese = 1,
+ /obj/item/food/butter = 1,
+ )
+ results = list(
+ /datum/reagent/consumable/nutriment/soup/cheese_porridge = 30,
+ /datum/reagent/consumable/nutriment/vitamin = 8,
+ /datum/reagent/consumable/nutriment/protein = 4,
+ )
+
+// Rice Porridge again but with Toechtause
+/datum/reagent/consumable/nutriment/soup/toechtauese_rice_porridge
+ name = "Töchtaüse Rice Porridge"
+ description = "Commonly served aboard the mothic fleet, rice porridge with töchtaüse syrup is more palatable than the regular stuff, if even just because it's spicier than normal."
+ data = list("sugar" = 1, "spice" = 1)
+ color = "#D8CFCC"
+
+/datum/glass_style/has_foodtype/soup/toechtauese_rice_porridge
+ required_drink_type = /datum/reagent/consumable/nutriment/soup/toechtauese_rice_porridge
+ name = "töchtaüse rice porridge"
+ icon = 'icons/obj/food/moth.dmi'
+ icon_state = "toechtauese_rice_porridge"
+ drink_type = GRAIN | VEGETABLES
+
+/datum/chemical_reaction/food/soup/toechtauese_rice_porridge
+ required_reagents = list(
+ /datum/reagent/consumable/nutriment/soup/rice_porridge = 20,
+ /datum/reagent/consumable/toechtauese_syrup = 10,
+ /datum/reagent/water = 10,
+ )
+ required_ingredients = list(
+ /obj/item/food/grown/chili = 1,
+ )
+ results = list(
+ /datum/reagent/consumable/nutriment/soup/toechtauese_rice_porridge = 30,
+ /datum/reagent/consumable/nutriment/protein = 6,
+ /datum/reagent/consumable/nutriment/vitamin = 6,
+ /datum/reagent/consumable/toechtauese_syrup = 6,
+ )
+
+// Red Porridge
+/datum/reagent/consumable/nutriment/soup/red_porridge
+ name = "Eltsløsk ül a priktæolk" //eltsløsk = red porridge, ül a = with, prikt = sour, æolk = cream
+ description = "Red porridge with yoghurt. The name and vegetable ingredients obscure the sweet nature of the dish, which is commonly served as a dessert aboard the fleet."
+ data = list("sweet beets" = 1, "sugar" = 1, "sweetened yoghurt" = 1)
+ color = "#FF858B"
+
+/datum/glass_style/has_foodtype/soup/red_porridge
+ required_drink_type = /datum/reagent/consumable/nutriment/soup/red_porridge
+ name = "eltsløsk ül a priktæolk"
+ icon = 'icons/obj/food/moth.dmi'
+ icon_state = "red_porridge"
+ drink_type = VEGETABLES | SUGAR | DAIRY
+
+/datum/chemical_reaction/food/soup/red_porridge
+ required_temp = WATER_BOILING_POINT
+ optimal_temp = 400
+ overheat_temp = 415 // Caramel forms
+ thermic_constant = 0
+ required_reagents = list(
+ /datum/reagent/consumable/vanilla = 10,
+ /datum/reagent/consumable/yoghurt = 20,
+ /datum/reagent/consumable/sugar = 10,
+ )
+ required_ingredients = list(
+ /obj/item/food/grown/redbeet = 1,
+ )
+ results = list(
+ /datum/reagent/consumable/nutriment/soup/red_porridge = 24,
+ /datum/reagent/consumable/nutriment/protein = 8,
+ /datum/reagent/consumable/sugar = 8,
+ )
+ percentage_of_nutriment_converted = 0.1
diff --git a/code/modules/food_and_drinks/recipes/tablecraft/recipes_guide.dm b/code/modules/food_and_drinks/recipes/tablecraft/recipes_guide.dm
index 23612db1aca..e14b6e9a962 100644
--- a/code/modules/food_and_drinks/recipes/tablecraft/recipes_guide.dm
+++ b/code/modules/food_and_drinks/recipes/tablecraft/recipes_guide.dm
@@ -37,13 +37,25 @@
non_craftable = TRUE
/datum/crafting_recipe/food/reaction/New()
- ..()
+ . = ..()
if(!reaction)
return
- var/datum/chemical_reaction/chemical_reaction = new reaction // This could use GLOB.chemical_reactions_list if it was initialized by now
- reqs = chemical_reaction.required_reagents
- chem_catalysts = chemical_reaction.required_catalysts
- if (chemical_reaction.results.len)
+
+ if(length(GLOB.chemical_reactions_list))
+ setup_chemical_reaction_details(GLOB.chemical_reactions_list[reaction])
+ else
+ // May be called before chemical reactions list is instantiated
+ var/datum/chemical_reaction/chemical_reaction = new reaction()
+ setup_chemical_reaction_details(chemical_reaction)
+ qdel(chemical_reaction)
+
+/**
+ * Sets up information for our recipe based on the chemical reaction we have set.
+ */
+/datum/crafting_recipe/food/reaction/proc/setup_chemical_reaction_details(datum/chemical_reaction/chemical_reaction)
+ reqs = chemical_reaction.required_reagents?.Copy()
+ chem_catalysts = chemical_reaction.required_catalysts?.Copy()
+ if(isnull(result) && length(chemical_reaction.results))
result = chemical_reaction.results[1]
result_amount = chemical_reaction.results[result]
diff --git a/code/modules/food_and_drinks/recipes/tablecraft/recipes_lizard.dm b/code/modules/food_and_drinks/recipes/tablecraft/recipes_lizard.dm
index ee6b94d6d7f..ec5db9baf14 100644
--- a/code/modules/food_and_drinks/recipes/tablecraft/recipes_lizard.dm
+++ b/code/modules/food_and_drinks/recipes/tablecraft/recipes_lizard.dm
@@ -350,70 +350,6 @@
result = /obj/item/food/honey_roll
category = CAT_LIZARD
-/datum/crafting_recipe/food/atrakor_dumplings
- name = "Atrakor dumpling soup"
- reqs = list(
- /datum/reagent/water = 10,
- /obj/item/reagent_containers/cup/bowl = 1,
- /obj/item/food/meat/rawcutlet = 2,
- /obj/item/food/grown/onion = 1,
- /obj/item/food/lizard_dumplings = 1,
- /datum/reagent/consumable/soysauce = 5
- )
- result = /obj/item/food/soup/atrakor_dumplings
- category = CAT_LIZARD
-
-/datum/crafting_recipe/food/meatball_noodles
- name = "Meatball noodle soup"
- reqs = list(
- /datum/reagent/water = 10,
- /obj/item/reagent_containers/cup/bowl = 1,
- /obj/item/food/meat/rawcutlet = 2,
- /obj/item/food/grown/onion = 1,
- /obj/item/food/spaghetti/nizaya = 1,
- /obj/item/food/meatball = 2,
- /obj/item/food/grown/peanut = 1
- )
- result = /obj/item/food/soup/meatball_noodles
- category = CAT_LIZARD
-
-/datum/crafting_recipe/food/black_broth
- name = "Tiziran black broth"
- reqs = list(
- /obj/item/reagent_containers/cup/bowl = 1,
- /obj/item/food/tiziran_sausage = 1,
- /obj/item/food/grown/onion = 1,
- /datum/reagent/consumable/vinegar = 5,
- /datum/reagent/blood = 5,
- /datum/reagent/consumable/ice = 2
- )
- result = /obj/item/food/soup/black_broth
- category = CAT_LIZARD
-
-/datum/crafting_recipe/food/jellyfish_stew
- name = "Jellyfish stew"
- reqs = list(
- /obj/item/reagent_containers/cup/bowl = 1,
- /obj/item/food/canned/jellyfish = 1,
- /obj/item/food/grown/soybeans = 1,
- /obj/item/food/grown/redbeet = 1,
- /obj/item/food/grown/potato = 1
- )
- result = /obj/item/food/soup/jellyfish
- category = CAT_LIZARD
-
-/datum/crafting_recipe/food/rootbread_soup
- name = "Rootbread soup"
- reqs = list(
- /obj/item/reagent_containers/cup/bowl = 1,
- /obj/item/food/breadslice/root = 2,
- /obj/item/food/grown/garlic = 1,
- /obj/item/food/grown/chili = 1,
- /obj/item/food/egg = 1
- )
- result = /obj/item/food/soup/rootbread_soup
- category = CAT_LIZARD
-
/datum/crafting_recipe/food/black_eggs
name = "Black scrambled eggs"
reqs = list(
@@ -495,3 +431,25 @@
)
result = /obj/item/food/steeped_mushrooms
category = CAT_LIZARD
+
+// Soups
+
+/datum/crafting_recipe/food/reaction/soup/atrakor_dumplings
+ reaction = /datum/chemical_reaction/food/soup/atrakor_dumplings
+ category = CAT_LIZARD
+
+/datum/crafting_recipe/food/reaction/soup/meatball_noodles
+ reaction = /datum/chemical_reaction/food/soup/meatball_noodles
+ category = CAT_LIZARD
+
+/datum/crafting_recipe/food/reaction/soup/black_broth
+ reaction = /datum/chemical_reaction/food/soup/black_broth
+ category = CAT_LIZARD
+
+/datum/crafting_recipe/food/reaction/soup/jellyfish_stew
+ reaction = /datum/chemical_reaction/food/soup/jellyfish_stew
+ category = CAT_LIZARD
+
+/datum/crafting_recipe/food/reaction/soup/rootbread_soup
+ reaction = /datum/chemical_reaction/food/soup/rootbread_soup
+ category = CAT_LIZARD
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 263cddc3b84..1f238916b6a 100644
--- a/code/modules/food_and_drinks/recipes/tablecraft/recipes_misc.dm
+++ b/code/modules/food_and_drinks/recipes/tablecraft/recipes_misc.dm
@@ -321,6 +321,26 @@
result = /obj/item/food/popcorn/salty
category = CAT_MISCFOOD
+/datum/crafting_recipe/food/spacylibertyduff
+ name = "Spacy liberty duff"
+ reqs = list(
+ /datum/reagent/consumable/ethanol/vodka = 5,
+ /obj/item/reagent_containers/cup/bowl = 1,
+ /obj/item/food/grown/mushroom/libertycap = 3
+ )
+ result = /obj/item/food/bowled/spacylibertyduff
+ category = CAT_MISCFOOD
+
+/datum/crafting_recipe/food/amanitajelly
+ name = "Amanita jelly"
+ reqs = list(
+ /datum/reagent/consumable/ethanol/vodka = 5,
+ /obj/item/reagent_containers/cup/bowl = 1,
+ /obj/item/food/grown/mushroom/amanita = 3
+ )
+ result = /obj/item/food/bowled/amanitajelly
+ category = CAT_MISCFOOD
+
/datum/crafting_recipe/food/buttered_baked_potato
name = "Buttered baked potato"
reqs = list(
diff --git a/code/modules/food_and_drinks/recipes/tablecraft/recipes_moth.dm b/code/modules/food_and_drinks/recipes/tablecraft/recipes_moth.dm
index e5b7305b4ae..fadfe23a87e 100644
--- a/code/modules/food_and_drinks/recipes/tablecraft/recipes_moth.dm
+++ b/code/modules/food_and_drinks/recipes/tablecraft/recipes_moth.dm
@@ -69,8 +69,8 @@
/datum/crafting_recipe/food/loaded_curds
name = "Ozlsettitæloskekllön ede pommes (Loaded curds and fries)"
reqs = list(
+ /datum/reagent/consumable/nutriment/soup/chili_sin_carne = 10,
/obj/item/food/cheese/cheese_curds = 1,
- /obj/item/food/soup/vegetarian_chili = 1,
/obj/item/food/onion_slice = 1,
/obj/item/food/cheese/wedge = 1,
/obj/item/food/fries = 1
@@ -99,11 +99,11 @@
/datum/crafting_recipe/food/raw_baked_rice
reqs = list(
+ /datum/reagent/consumable/nutriment/soup/vegetable_soup = 10,
/obj/item/food/boiledrice = 2,
- /obj/item/food/soup/vegetable = 1,
- /obj/item/food/grown/potato = 2,
/obj/item/food/grown/chili = 1,
- /obj/item/food/grown/herbs = 1
+ /obj/item/food/grown/herbs = 1,
+ /obj/item/food/grown/potato = 2,
)
result = /obj/item/food/raw_baked_rice
category = CAT_MOTH
@@ -182,149 +182,26 @@
result = /obj/item/food/mac_balls
category = CAT_MOTH
-/datum/crafting_recipe/food/moth_cotton_soup
- name = "Flöfrölenmæsch (Cottonball soup)"
- reqs = list(
- /obj/item/grown/cotton = 1,
- /obj/item/food/grown/onion = 1,
- /obj/item/food/grown/carrot = 1,
- /obj/item/food/grown/eggplant = 1,
- /obj/item/food/oven_baked_corn = 1,
- /datum/reagent/water = 10,
- /obj/item/reagent_containers/cup/bowl = 1
- )
- result = /obj/item/food/soup/moth_cotton_soup
- category = CAT_MOTH
-
-/datum/crafting_recipe/food/moth_cheese_soup
- name = "Ælosterrmæsch (Cheese soup)"
- reqs = list(
- /obj/item/food/cheese/wedge = 2,
- /obj/item/food/butter = 1,
- /obj/item/food/grown/potato/sweet = 1,
- /datum/reagent/consumable/flour = 5,
- /datum/reagent/consumable/milk = 5,
- /obj/item/reagent_containers/cup/bowl = 1
- )
- result = /obj/item/food/soup/moth_cheese_soup
- category = CAT_MOTH
-
-/datum/crafting_recipe/food/moth_seed_soup
- name = "Misklmæsch (Seed soup)"
- reqs = list(
- /obj/item/seeds/sunflower = 1,
- /obj/item/seeds/poppy/lily = 1,
- /obj/item/seeds/ambrosia = 1,
- /datum/reagent/water = 10,
- /datum/reagent/consumable/vinegar = 5,
- /obj/item/reagent_containers/cup/bowl = 1
- )
- result = /obj/item/food/soup/moth_seed_soup
- category = CAT_MOTH
-
-/datum/crafting_recipe/food/moth_bean_stew
- name = "Prickeldröndolhaskl (Spicy bean stew)"
- reqs = list(
- /obj/item/food/canned/beans = 1,
- /obj/item/food/grown/cabbage = 1,
- /obj/item/food/grown/tomato = 1,
- /obj/item/food/grown/onion = 1,
- /obj/item/food/grown/chili = 1,
- /obj/item/food/oven_baked_corn = 1,
- /datum/reagent/water = 5,
- /obj/item/reagent_containers/cup/bowl = 1
- )
- result = /obj/item/food/soup/moth_bean_stew
- category = CAT_MOTH
-
-/datum/crafting_recipe/food/moth_oat_stew
- name = "Häfmisklhaskl (Oat stew)"
- reqs = list(
- /obj/item/food/grown/oat = 1,
- /obj/item/food/grown/potato/sweet = 1,
- /obj/item/food/grown/parsnip = 1,
- /obj/item/food/grown/carrot = 1,
- /datum/reagent/water = 5,
- /obj/item/reagent_containers/cup/bowl = 1
- )
- result = /obj/item/food/soup/moth_oat_stew
- category = CAT_MOTH
-
-/datum/crafting_recipe/food/moth_fire_soup
- name = "Tömpröttkrakklmæsch (Heartburn soup)"
- reqs = list(
- /obj/item/food/grown/ghost_chili = 1,
- /obj/item/food/tofu = 1,
- /datum/reagent/consumable/yoghurt = 10,
- /datum/reagent/consumable/vinegar = 2,
- /obj/item/reagent_containers/cup/bowl = 1
- )
- result = /obj/item/food/soup/moth_fire_soup
- category = CAT_MOTH
-
-/datum/crafting_recipe/food/rice_porridge
- name = "Rice porridge"
- reqs = list(
- /obj/item/reagent_containers/cup/bowl = 1,
- /obj/item/food/boiledrice = 1,
- /datum/reagent/water = 10,
- /datum/reagent/consumable/salt = 2
- )
- result = /obj/item/food/soup/rice_porridge
- category = CAT_MOTH
-
/datum/crafting_recipe/food/hua_mulan_congee
name = "Hua Mulan congee"
reqs = list(
- /obj/item/food/soup/rice_porridge = 1,
+ /datum/reagent/consumable/nutriment/soup/rice_porridge = 10,
/obj/item/food/meat/bacon = 1,
/obj/item/food/friedegg = 2
)
- result = /obj/item/food/soup/hua_mulan_congee
- category = CAT_MOTH
-
-/datum/crafting_recipe/food/toechtauese_rice_porridge
- name = "Töchtaüse rice porridge"
- reqs = list(
- /obj/item/food/soup/rice_porridge = 1,
- /obj/item/food/grown/chili = 1,
- /datum/reagent/consumable/toechtauese_syrup = 5
- )
- result = /obj/item/food/soup/toechtauese_rice_porridge
- category = CAT_MOTH
-
-/datum/crafting_recipe/food/cornmeal_porridge
- name = "Cornmeal porridge"
- reqs = list(
- /datum/reagent/consumable/cornmeal = 10,
- /datum/reagent/water = 10,
- /obj/item/reagent_containers/cup/bowl = 1
- )
- result = /obj/item/food/soup/cornmeal_porridge
- category = CAT_MOTH
-
-/datum/crafting_recipe/food/cheesy_porridge
- name = "Cheesy porridge"
- reqs = list(
- /obj/item/food/soup/cornmeal_porridge = 1,
- /datum/reagent/consumable/milk = 5,
- /obj/item/food/cheese/firm_cheese_slice = 1,
- /obj/item/food/cheese/curd_cheese = 1,
- /obj/item/food/butter = 1
- )
- result = /obj/item/food/soup/cheesy_porridge
+ result = /obj/item/food/bowled/hua_mulan_congee
category = CAT_MOTH
/datum/crafting_recipe/food/fried_eggplant_polenta
name = "Fried eggplant and polenta"
reqs = list(
- /obj/item/food/soup/cheesy_porridge = 1,
+ /datum/reagent/consumable/nutriment/soup/cornmeal_porridge = 10,
/obj/item/food/grown/eggplant = 1,
/obj/item/food/breadslice/plain = 2,
/obj/item/food/tomato_sauce = 1,
/obj/item/food/cheese/mozzarella = 1
)
- result = /obj/item/food/soup/fried_eggplant_polenta
+ result = /obj/item/food/bowled/fried_eggplant_polenta
category = CAT_MOTH
/datum/crafting_recipe/food/caprese_salad
@@ -470,29 +347,6 @@
result = /obj/item/food/cake/mothmallow
category = CAT_MOTH
-/datum/crafting_recipe/food/red_porridge
- name = "Eltsløsk ül a priktæolk (Red Porridge and Yoghurt)"
- reqs = list(
- /obj/item/food/grown/redbeet = 1,
- /datum/reagent/consumable/vanilla = 5,
- /datum/reagent/consumable/yoghurt = 10,
- /datum/reagent/consumable/sugar = 5
- )
- result = /obj/item/food/soup/red_porridge
- category = CAT_MOTH
-
-/datum/crafting_recipe/food/chili_sin_carne
- name = "Chili sin carne (vegetarian chili)"
- reqs = list(
- /obj/item/reagent_containers/cup/bowl = 1,
- /datum/reagent/water = 10,
- /datum/reagent/consumable/salt = 1,
- /obj/item/food/grown/chili = 1,
- /obj/item/food/grown/tomato = 1
- )
- result = /obj/item/food/soup/vegetarian_chili
- category = CAT_MOTH
-
/datum/crafting_recipe/food/moffin
name = "Moffin"
reqs = list(
@@ -502,3 +356,61 @@
)
result = /obj/item/food/muffin/moffin
category = CAT_MOTH
+
+// Soups
+
+/datum/crafting_recipe/food/reaction/soup/cottonball
+ name = "Flöfrölenmæsch (cottonball soup)"
+ reaction = /datum/chemical_reaction/food/soup/cottonball
+ category = CAT_MOTH
+
+/datum/crafting_recipe/food/reaction/soup/cheese
+ name = "Ælosterrmæsch (cheese soup)"
+ reaction = /datum/chemical_reaction/food/soup/cheese
+ category = CAT_MOTH
+
+/datum/crafting_recipe/food/reaction/soup/seed
+ name = "Misklmæsch (seed soup)"
+ reaction = /datum/chemical_reaction/food/soup/seed
+ category = CAT_MOTH
+
+/datum/crafting_recipe/food/reaction/soup/beans
+ name = "Prickeldröndolhaskl (spicy bean stew)"
+ reaction = /datum/chemical_reaction/food/soup/beans
+ category = CAT_MOTH
+
+/datum/crafting_recipe/food/reaction/soup/moth_oats
+ name = "Häfmisklhaskl (oat stew)"
+ reaction = /datum/chemical_reaction/food/soup/moth_oats
+ category = CAT_MOTH
+
+/datum/crafting_recipe/food/reaction/soup/fire_soup
+ name = "Tömpröttkrakklmæsch (heartburn soup)"
+ reaction = /datum/chemical_reaction/food/soup/fire_soup
+ category = CAT_MOTH
+
+/datum/crafting_recipe/food/reaction/soup/rice_porridge
+ reaction = /datum/chemical_reaction/food/soup/rice_porridge
+ category = CAT_MOTH
+
+/datum/crafting_recipe/food/reaction/soup/toechtauese_rice_porridge
+ reaction = /datum/chemical_reaction/food/soup/toechtauese_rice_porridge
+ category = CAT_MOTH
+
+/datum/crafting_recipe/food/reaction/soup/red_porridge
+ name = "Eltsløsk ül a priktæolk (red porridge and yoghurt)"
+ reaction = /datum/chemical_reaction/food/soup/red_porridge
+ category = CAT_MOTH
+
+/datum/crafting_recipe/food/reaction/soup/cornmeal_porridge
+ reaction = /datum/chemical_reaction/food/soup/cornmeal_porridge
+ category = CAT_MOTH
+
+/datum/crafting_recipe/food/reaction/soup/cheese_porridge
+ reaction = /datum/chemical_reaction/food/soup/cheese_porridge
+ category = CAT_MOTH
+
+/datum/crafting_recipe/food/reaction/soup/chili_sin_carne
+ name = "Chili Sin Carne (Vegetarian Chili)"
+ reaction = /datum/chemical_reaction/food/soup/chili_sin_carne
+ category = CAT_MOTH
diff --git a/code/modules/food_and_drinks/recipes/tablecraft/recipes_salad.dm b/code/modules/food_and_drinks/recipes/tablecraft/recipes_salad.dm
index 220fbdaf6cc..653aac9672c 100644
--- a/code/modules/food_and_drinks/recipes/tablecraft/recipes_salad.dm
+++ b/code/modules/food_and_drinks/recipes/tablecraft/recipes_salad.dm
@@ -34,19 +34,6 @@
result = /obj/item/food/salad/validsalad
category = CAT_SALAD
-/datum/crafting_recipe/food/monkeysdelight
- name = "Monkeys delight"
- reqs = list(
- /datum/reagent/consumable/flour = 5,
- /datum/reagent/consumable/salt = 1,
- /datum/reagent/consumable/blackpepper = 1,
- /obj/item/reagent_containers/cup/bowl = 1,
- /obj/item/food/monkeycube = 1,
- /obj/item/food/grown/banana = 1
- )
- result = /obj/item/food/soup/monkeysdelight
- category = CAT_SALAD
-
/datum/crafting_recipe/food/melonfruitbowl
name ="Melon fruit bowl"
reqs = list(
diff --git a/code/modules/food_and_drinks/recipes/tablecraft/recipes_soup.dm b/code/modules/food_and_drinks/recipes/tablecraft/recipes_soup.dm
deleted file mode 100644
index f9993277061..00000000000
--- a/code/modules/food_and_drinks/recipes/tablecraft/recipes_soup.dm
+++ /dev/null
@@ -1,384 +0,0 @@
-
-// see code/module/crafting/table.dm
-
-////////////////////////////////////////////////SOUP////////////////////////////////////////////////
-
-/datum/crafting_recipe/food/meatballsoup
- name = "Meatball soup"
- reqs = list(
- /datum/reagent/water = 10,
- /obj/item/reagent_containers/cup/bowl = 1,
- /obj/item/food/meatball = 1,
- /obj/item/food/grown/carrot = 1,
- /obj/item/food/grown/potato = 1
- )
- result = /obj/item/food/soup/meatball
- category = CAT_SOUP
-
-/datum/crafting_recipe/food/vegetablesoup
- name = "Vegetable soup"
- reqs = list(
- /datum/reagent/water = 10,
- /obj/item/reagent_containers/cup/bowl = 1,
- /obj/item/food/grown/carrot = 1,
- /obj/item/food/grown/corn = 1,
- /obj/item/food/grown/eggplant = 1,
- /obj/item/food/grown/potato = 1
- )
- result = /obj/item/food/soup/vegetable
- category = CAT_SOUP
-
-/datum/crafting_recipe/food/nettlesoup
- name = "Nettle soup"
- reqs = list(
- /datum/reagent/water = 10,
- /obj/item/reagent_containers/cup/bowl = 1,
- /obj/item/food/grown/nettle = 1,
- /obj/item/food/grown/potato = 1,
- /obj/item/food/boiledegg = 1
- )
- result = /obj/item/food/soup/nettle
- category = CAT_SOUP
-
-/datum/crafting_recipe/food/wingfangchu
- name = "Wingfangchu"
- reqs = list(
- /obj/item/reagent_containers/cup/bowl = 1,
- /datum/reagent/consumable/soysauce = 5,
- /obj/item/food/meat/cutlet/xeno = 2
- )
- result = /obj/item/food/soup/wingfangchu
- category = CAT_SOUP
-
-/datum/crafting_recipe/food/wishsoup
- name = "Wish soup"
- reqs = list(
- /datum/reagent/water = 20,
- /obj/item/reagent_containers/cup/bowl = 1
- )
- result= /obj/item/food/soup/wish
- category = CAT_SOUP
-
-/datum/crafting_recipe/food/hotchili
- name = "Hot chili"
- reqs = list(
- /obj/item/reagent_containers/cup/bowl = 1,
- /obj/item/food/meat/cutlet = 2,
- /obj/item/food/grown/chili = 1,
- /obj/item/food/grown/tomato = 1
- )
- result = /obj/item/food/soup/hotchili
- category = CAT_SOUP
-
-/datum/crafting_recipe/food/coldchili
- name = "Cold chili"
- reqs = list(
- /obj/item/reagent_containers/cup/bowl = 1,
- /obj/item/food/meat/cutlet = 2,
- /obj/item/food/grown/icepepper = 1,
- /obj/item/food/grown/tomato = 1
- )
- result = /obj/item/food/soup/coldchili
- category = CAT_SOUP
-
-/datum/crafting_recipe/food/clownchili
- name = "Chili con carnival"
- reqs = list(
- /obj/item/reagent_containers/cup/bowl = 1,
- /obj/item/food/meat/cutlet = 2,
- /obj/item/food/grown/chili = 1,
- /obj/item/food/grown/tomato = 1,
- /obj/item/clothing/shoes/clown_shoes = 1
- )
- result = /obj/item/food/soup/clownchili
- category = CAT_SOUP
-
-/datum/crafting_recipe/food/tomatosoup
- name = "Tomato soup"
- reqs = list(
- /datum/reagent/water = 10,
- /obj/item/reagent_containers/cup/bowl = 1,
- /obj/item/food/grown/tomato = 2
- )
- result = /obj/item/food/soup/tomato
- category = CAT_SOUP
-
-/datum/crafting_recipe/food/eyeballsoup
- name = "Eyeball soup"
- reqs = list(
- /datum/reagent/water = 10,
- /obj/item/reagent_containers/cup/bowl = 1,
- /obj/item/food/grown/tomato = 2,
- /obj/item/organ/internal/eyes = 1
- )
- result = /obj/item/food/soup/tomato/eyeball
- category = CAT_SOUP
-
-
-/datum/crafting_recipe/food/misosoup
- name = "Miso soup"
- reqs = list(
- /datum/reagent/water = 10,
- /obj/item/reagent_containers/cup/bowl = 1,
- /obj/item/food/soydope = 2,
- /obj/item/food/tofu = 2
- )
- result = /obj/item/food/soup/miso
- category = CAT_SOUP
-
-/datum/crafting_recipe/food/bloodsoup
- name = "Blood soup"
- reqs = list(
- /datum/reagent/blood = 10,
- /obj/item/reagent_containers/cup/bowl = 1,
- /obj/item/food/grown/tomato/blood = 2
- )
- result = /obj/item/food/soup/blood
- category = CAT_SOUP
-
-/datum/crafting_recipe/food/slimesoup
- name = "Slime soup"
- reqs = list(
- /datum/reagent/water = 10,
- /datum/reagent/toxin/slimejelly = 5,
- /obj/item/reagent_containers/cup/bowl = 1
- )
- result = /obj/item/food/soup/slime
- category = CAT_SOUP
-
-/datum/crafting_recipe/food/clownstears
- name = "Clowns tears"
- reqs = list(
- /datum/reagent/lube = 10,
- /obj/item/reagent_containers/cup/bowl = 1,
- /obj/item/food/grown/banana = 1,
- /obj/item/stack/sheet/mineral/bananium = 1
- )
- result = /obj/item/food/soup/clownstears
- category = CAT_SOUP
-
-/datum/crafting_recipe/food/mysterysoup
- name = "Mystery soup"
- reqs = list(
- /datum/reagent/water = 10,
- /obj/item/reagent_containers/cup/bowl = 1,
- /obj/item/food/badrecipe = 1,
- /obj/item/food/tofu = 1,
- /obj/item/food/boiledegg = 1,
- /obj/item/food/cheese/wedge = 1,
- )
- result = /obj/item/food/soup/mystery
- category = CAT_SOUP
-
-/datum/crafting_recipe/food/mushroomsoup
- name = "Mushroom soup"
- reqs = list(
- /datum/reagent/consumable/milk = 5,
- /datum/reagent/water = 5,
- /obj/item/reagent_containers/cup/bowl = 1,
- /obj/item/food/grown/mushroom/chanterelle = 1
- )
- result = /obj/item/food/soup/mushroom
- category = CAT_SOUP
-
-/datum/crafting_recipe/food/beetsoup
- name = "Beet soup"
- reqs = list(
- /datum/reagent/water = 10,
- /obj/item/reagent_containers/cup/bowl = 1,
- /obj/item/food/grown/whitebeet = 1,
- /obj/item/food/grown/cabbage = 1,
- )
- result = /obj/item/food/soup/beet
- category = CAT_SOUP
-
-/datum/crafting_recipe/food/stew
- name = "Stew"
- reqs = list(
- /datum/reagent/water = 10,
- /obj/item/reagent_containers/cup/bowl = 1,
- /obj/item/food/grown/tomato = 1,
- /obj/item/food/meat/cutlet = 3,
- /obj/item/food/grown/potato = 1,
- /obj/item/food/grown/carrot = 1,
- /obj/item/food/grown/eggplant = 1,
- /obj/item/food/grown/mushroom = 1
- )
- result = /obj/item/food/soup/stew
- category = CAT_SOUP
-
-/datum/crafting_recipe/food/spacylibertyduff
- name = "Spacy liberty duff"
- reqs = list(
- /datum/reagent/consumable/ethanol/vodka = 5,
- /obj/item/reagent_containers/cup/bowl = 1,
- /obj/item/food/grown/mushroom/libertycap = 3
- )
- result = /obj/item/food/soup/spacylibertyduff
- category = CAT_SOUP
-
-/datum/crafting_recipe/food/amanitajelly
- name = "Amanita jelly"
- reqs = list(
- /datum/reagent/consumable/ethanol/vodka = 5,
- /obj/item/reagent_containers/cup/bowl = 1,
- /obj/item/food/grown/mushroom/amanita = 3
- )
- result = /obj/item/food/soup/amanitajelly
- category = CAT_SOUP
-
-/datum/crafting_recipe/food/sweetpotatosoup
- name = "Sweet potato soup"
- reqs = list(
- /datum/reagent/water = 10,
- /datum/reagent/consumable/sugar = 5,
- /obj/item/reagent_containers/cup/bowl = 1,
- /obj/item/food/grown/potato/sweet = 2
- )
- result = /obj/item/food/soup/sweetpotato
- category = CAT_SOUP
-
-/datum/crafting_recipe/food/redbeetsoup
- name = "Red beet soup"
- reqs = list(
- /datum/reagent/water = 10,
- /obj/item/reagent_containers/cup/bowl = 1,
- /obj/item/food/grown/redbeet = 1,
- /obj/item/food/grown/cabbage = 1
- )
- result = /obj/item/food/soup/beet/red
- category = CAT_SOUP
-
-/datum/crafting_recipe/food/onionsoup
- name = "French onion soup"
- reqs = list(
- /datum/reagent/water = 10,
- /obj/item/reagent_containers/cup/bowl = 1,
- /obj/item/food/grown/onion = 1,
- /obj/item/food/cheese/wedge = 1,
- )
- result = /obj/item/food/soup/onion
- category = CAT_SOUP
-
-/datum/crafting_recipe/food/bisque
- name = "Bisque"
- reqs = list(
- /datum/reagent/water = 10,
- /obj/item/reagent_containers/cup/bowl = 1,
- /obj/item/food/meat/crab = 1,
- /obj/item/food/boiledrice = 1
- )
- result = /obj/item/food/soup/bisque
- category = CAT_SOUP
-
-/datum/crafting_recipe/food/bungocurry
- name = "Bungo Curry"
- reqs = list(
- /datum/reagent/water = 5,
- /datum/reagent/consumable/cream = 5,
- /obj/item/reagent_containers/cup/bowl = 1,
- /obj/item/food/grown/chili = 1,
- /obj/item/food/grown/bungofruit = 1
- )
- result = /obj/item/food/soup/bungocurry
- category = CAT_SOUP
-
-/datum/crafting_recipe/food/electron
- name = "Electron Soup"
- reqs = list(
- /datum/reagent/water = 10,
- /datum/reagent/consumable/salt = 5,
- /obj/item/reagent_containers/cup/bowl = 1,
- /obj/item/food/grown/mushroom/jupitercup = 1
- )
- result = /obj/item/food/soup/electron
- category = CAT_SOUP
-
-/datum/crafting_recipe/food/peasoup
- name = "Pea soup"
- reqs = list(
- /datum/reagent/water = 10,
- /obj/item/food/grown/peas = 2,
- /obj/item/food/grown/parsnip = 1,
- /obj/item/food/grown/carrot = 1,
- /obj/item/reagent_containers/cup/bowl = 1
- )
- result = /obj/item/food/soup/peasoup
- category = CAT_SOUP
-
-/datum/crafting_recipe/food/indian_curry
- name = "Indian Chicken Curry"
- reqs = list(
- /obj/item/reagent_containers/cup/bowl = 1,
- /obj/item/food/meat/slab/chicken = 1,
- /obj/item/food/grown/onion = 2,
- /obj/item/food/grown/chili = 1,
- /obj/item/food/grown/garlic = 1,
- /obj/item/food/butter = 1,
- /obj/item/food/boiledrice = 1,
- /datum/reagent/consumable/cream = 5
- )
- result = /obj/item/food/soup/indian_curry
- category = CAT_SOUP
-
-/datum/crafting_recipe/food/oatmeal
- name = "Oatmeal"
- reqs = list(
- /datum/reagent/consumable/milk = 10,
- /obj/item/reagent_containers/cup/bowl = 1,
- /obj/item/food/grown/oat = 1
- )
- result = /obj/item/food/soup/oatmeal
- category = CAT_SOUP
-
-/datum/crafting_recipe/food/zurek
- name = "Zurek"
- reqs = list(
- /datum/reagent/water = 10,
- /datum/reagent/consumable/flour = 5,
- /obj/item/food/boiledegg = 1,
- /obj/item/food/meat/cutlet = 1,
- /obj/item/food/grown/carrot = 1,
- /obj/item/food/grown/onion = 1,
- /obj/item/reagent_containers/cup/bowl = 1,
- )
- result = /obj/item/food/soup/zurek
- category = CAT_SOUP
-
-/datum/crafting_recipe/food/cullen_skink
- name = "Cullen Skink"
- reqs = list(
- /datum/reagent/consumable/milk = 5,
- /obj/item/food/fishmeat = 1,
- /obj/item/food/grown/onion = 1,
- /obj/item/food/grown/potato = 1,
- /datum/reagent/consumable/blackpepper = 2,
- /obj/item/reagent_containers/cup/bowl = 1,
- )
- result = /obj/item/food/soup/cullen_skink
- category = CAT_SOUP
-
-/datum/crafting_recipe/food/chicken_noodle_soup
- name = "Chicken Noodle Soup"
- reqs = list(
- /obj/item/food/meat/slab/chicken = 1,
- /obj/item/food/spaghetti/boiledspaghetti = 1,
- /obj/item/food/grown/carrot = 1,
- /datum/reagent/water = 10,
- /obj/item/reagent_containers/cup/bowl = 1,
- )
- result = /obj/item/food/soup/chicken_noodle_soup
- category = CAT_SOUP
-
-/datum/crafting_recipe/food/corn_chowder
- name = "Corn Chowder"
- reqs = list(
- /obj/item/food/grown/corn = 1,
- /obj/item/food/grown/potato = 1,
- /obj/item/food/grown/carrot = 1,
- /obj/item/food/meat/bacon = 1,
- /datum/reagent/consumable/cream = 5,
- /obj/item/reagent_containers/cup/bowl = 1,
- )
- result = /obj/item/food/soup/corn_chowder
- category = CAT_SOUP
diff --git a/code/modules/food_and_drinks/restaurant/_venue.dm b/code/modules/food_and_drinks/restaurant/_venue.dm
index 970e2819c1b..b31edd5ead8 100644
--- a/code/modules/food_and_drinks/restaurant/_venue.dm
+++ b/code/modules/food_and_drinks/restaurant/_venue.dm
@@ -65,17 +65,25 @@
/datum/venue/proc/order_food(mob/living/simple_animal/robot_customer/customer_pawn, datum/customer_data/customer_data)
var/order = pick_weight(customer_data.orderable_objects[venue_type])
+ var/list/order_args // Only for custom orders - arguments passed into New
var/image/food_image
var/food_line
+ if(ispath(order, /datum/reagent))
+ // This is pain
+ var/datum/reagent/reagent_order = order
+ order_args = list("reagent_type" = reagent_order)
+ order = initial(reagent_order.restaurant_order)
+
if(ispath(order, /datum/custom_order)) // generate the special order
- var/datum/custom_order/custom_order = new order(src)
+ var/datum/custom_order/custom_order = new order(arglist(order_args || list()))
food_image = custom_order.get_order_appearance(src)
food_line = custom_order.get_order_line(src)
order = custom_order.dispense_order()
else
food_image = get_food_appearance(order)
food_line = order_food_line(order)
+
customer_pawn.say(food_line)
// common code for the food thoughts appearance
@@ -106,7 +114,26 @@
///Effects for when a customer receives their order at this venue
/datum/venue/proc/on_get_order(mob/living/simple_animal/robot_customer/customer_pawn, obj/item/order_item)
- SEND_SIGNAL(order_item, COMSIG_ITEM_SOLD_TO_CUSTOMER, customer_pawn, order_item)
+ SHOULD_CALL_PARENT(TRUE)
+
+ // This is an item typepath, a reagent typepath, or a custom order datum instance.
+ var/order = customer_pawn.ai_controller.blackboard[BB_CUSTOMER_CURRENT_ORDER]
+
+ . = SEND_SIGNAL(order_item, COMSIG_ITEM_SOLD_TO_CUSTOMER, customer_pawn)
+
+ for(var/datum/reagent/reagent as anything in order_item.reagents?.reagent_list)
+ // Our order can be a reagent within the item we're receiving
+ if(reagent.type == order)
+ . |= SEND_SIGNAL(reagent, COMSIG_REAGENT_SOLD_TO_CUSTOMER, customer_pawn, order_item)
+ break
+
+ // Order can be a /datum/custom_order instance
+ if(istype(order, /datum/custom_order))
+ var/datum/custom_order/special_order = order
+ . |= special_order.handle_get_order(customer_pawn, order_item)
+
+ if(. & TRANSACTION_SUCCESS)
+ customers_served++
///Toggles whether the venue is open or not
/datum/venue/proc/toggle_open()
diff --git a/code/modules/food_and_drinks/restaurant/custom_order.dm b/code/modules/food_and_drinks/restaurant/custom_order.dm
index 583c9ad2034..25ea8780241 100644
--- a/code/modules/food_and_drinks/restaurant/custom_order.dm
+++ b/code/modules/food_and_drinks/restaurant/custom_order.dm
@@ -28,6 +28,15 @@
stack_trace("[type]/get_order_line() not set")
return "broken custom order pls call a coder"
+/**
+ * Handles what the bot does with the order when it gets it
+ *
+ * Return [TRANSACTION_SUCCESS] to denote the order went through successfully (Not generally necessary to include here)
+ * Return [TRANSACTION_HANDLED] to not do any further handling of the order by the
+ */
+/datum/custom_order/proc/handle_get_order(mob/living/simple_animal/robot_customer/customer_pawn, obj/item/order_item)
+ return NONE
+
/datum/custom_order/moth_clothing
/// The item type that we want to order, usually clothing
var/wanted_clothing_type
@@ -53,6 +62,13 @@
if (!QDELETED(buffet.shoes))
orderable[buffet.shoes.type] = 1
+ if(!length(orderable))
+ orderable = list(
+ /obj/item/clothing/head/utility/chefhat = 3,
+ /obj/item/clothing/shoes/sneakers/black = 3,
+ /obj/item/clothing/gloves/color/black = 1,
+ )
+
wanted_clothing_type = pick_weight(orderable)
@@ -110,3 +126,92 @@
food_image.add_overlay(i_scream)
return food_image
+
+/datum/custom_order/reagent
+ /// This is the typepath of reagent we desire
+ var/datum/reagent/consumable/nutriment/soup/reagent_type
+ /// What typepath container we want it to be in
+ var/obj/item/container_needed
+ /// How many reagents is needed
+ var/reagents_needed = VENUE_BAR_MINIMUM_REAGENTS
+
+/datum/custom_order/reagent/New(reagent_type)
+ . = ..()
+ src.reagent_type = reagent_type
+
+/datum/custom_order/reagent/get_order_line(datum/venue/our_venue)
+ return "I'll take [reagents_needed]u of [initial(reagent_type.name)]"
+
+/datum/custom_order/reagent/get_order_appearance(datum/venue/our_venue)
+ var/image/food_image = image(icon = 'icons/effects/effects.dmi' , icon_state = "thought_bubble")
+ var/datum/glass_style/draw_as = GLOB.glass_style_singletons[container_needed][reagent_type]
+ var/image/drink_image = image(
+ icon = draw_as?.icon || initial(reagent_type.fallback_icon) || initial(container_needed.icon),
+ icon_state = draw_as?.icon_state || initial(reagent_type.fallback_icon_state) || initial(container_needed.icon_state),
+ )
+ food_image.add_overlay(drink_image)
+ return food_image
+
+/datum/custom_order/reagent/handle_get_order(mob/living/simple_animal/robot_customer/customer_pawn, obj/item/order_item)
+ . = TRANSACTION_HANDLED
+
+ for(var/datum/reagent/reagent as anything in order_item.reagents?.reagent_list)
+ if(reagent.type == reagent_type)
+ . |= SEND_SIGNAL(reagent, COMSIG_REAGENT_SOLD_TO_CUSTOMER, customer_pawn, order_item)
+
+ playsound(customer_pawn, 'sound/items/drink.ogg', rand(10, 50), TRUE)
+ order_item.reagents.clear_reagents()
+
+/datum/custom_order/reagent/is_correct_order(obj/item/object_used)
+ if(..())
+ return TRUE
+ if(!istype(object_used, container_needed) || isnull(object_used.reagents))
+ return FALSE
+
+ var/datum/reagents/holder = object_used.reagents
+ // The container must be majority reagent
+ if(holder.get_master_reagent_id() != reagent_type)
+ return FALSE
+ // We must fulfill the sample size threshold
+ if(reagents_needed > holder.total_volume)
+ return FALSE
+ // Also must be at least 1/3rd of that reagent, prevent cheese
+ if(holder.get_reagent_amount(reagent_type) < holder.total_volume * 0.33)
+ return FALSE
+ return TRUE
+
+/datum/custom_order/reagent/drink
+ container_needed = /obj/item/reagent_containers/cup/glass/drinkingglass
+
+/datum/custom_order/reagent/drink/handle_get_order(mob/living/simple_animal/robot_customer/customer_pawn, obj/item/order_item)
+ customer_pawn.visible_message(
+ span_danger("[customer_pawn] slurps up [order_item] in one go!"),
+ span_danger("You slurp up [order_item] in one go."),
+ )
+ return ..()
+
+/datum/custom_order/reagent/soup
+ container_needed = /obj/item/reagent_containers/cup/bowl
+
+ /// What serving we picked for the order
+ var/picked_serving
+
+/datum/custom_order/reagent/soup/New(reagent_type)
+ . = ..()
+ var/list/serving_sizes = list(
+ "small serving (15u)" = 15,
+ "medium serving (20u)" = 20,
+ "large serving (25u)" = 25,
+ )
+ picked_serving = pick(serving_sizes)
+ reagents_needed = serving_sizes[picked_serving]
+
+/datum/custom_order/reagent/soup/get_order_line(datum/venue/our_venue)
+ return "I'll take a [picked_serving] of [initial(reagent_type.name)]"
+
+/datum/custom_order/reagent/soup/handle_get_order(mob/living/simple_animal/robot_customer/customer_pawn, obj/item/order_item)
+ customer_pawn.visible_message(
+ span_danger("[customer_pawn] pours [order_item] right down [customer_pawn.p_their()] hatch!"),
+ span_danger("You pour [order_item] down your hatch in one go."),
+ )
+ return ..()
diff --git a/code/modules/food_and_drinks/restaurant/customers/_customer.dm b/code/modules/food_and_drinks/restaurant/customers/_customer.dm
index c7ff95cb1ad..eca347011fc 100644
--- a/code/modules/food_and_drinks/restaurant/customers/_customer.dm
+++ b/code/modules/food_and_drinks/restaurant/customers/_customer.dm
@@ -25,6 +25,8 @@
var/second_warning_line = "This is your last warning!"
///Line when harrased by someone for the last time
var/self_defense_line = "Omae wa mo, shinderou."
+ ///Line sent when the customer is clicked on by someone with a 0 force item that's not the correct order
+ var/wrong_item_line = "No, I don't want that."
///Clothing sets to pick from when dressing the robot.
var/list/clothing_sets = list("amerifat_clothes")
@@ -85,10 +87,10 @@
/obj/item/food/danish_hotdog = 3,
),
VENUE_BAR = list(
+ /datum/reagent/consumable/ethanol/beer = 25,
/datum/reagent/consumable/ethanol/b52 = 6,
/datum/reagent/consumable/ethanol/manhattan = 3,
/datum/reagent/consumable/ethanol/atomicbomb = 1,
- /datum/reagent/consumable/ethanol/beer = 25,
),
)
@@ -157,10 +159,10 @@
VENUE_RESTAURANT = list(
/obj/item/food/baguette = 20,
/obj/item/food/garlicbread = 5,
- /obj/item/food/soup/onion = 4,
- /obj/item/food/pie/berryclafoutis = 2,
/obj/item/food/omelette = 15,
/datum/custom_order/icecream = 6,
+ /datum/reagent/consumable/nutriment/soup/french_onion = 4,
+ /obj/item/food/pie/berryclafoutis = 2,
),
VENUE_BAR = list(
/datum/reagent/consumable/ethanol/champagne = 10,
@@ -199,16 +201,16 @@
speech_sound = 'sound/creatures/tourist/tourist_talk_japanese1.ogg'
orderable_objects = list(
VENUE_RESTAURANT = list(
- /obj/item/food/tofu = 5,
- /obj/item/food/breadslice/plain = 5,
- /obj/item/food/soup/miso = 10,
- /obj/item/food/soup/vegetable = 4,
- /obj/item/food/sashimi = 4,
- /obj/item/food/chawanmushi = 4,
- /obj/item/food/muffin/berry = 2,
- /obj/item/food/beef_stroganoff = 2,
/datum/custom_order/icecream = 4,
+ /datum/reagent/consumable/nutriment/soup/miso = 10,
+ /datum/reagent/consumable/nutriment/soup/vegetable_soup = 4,
+ /obj/item/food/beef_stroganoff = 2,
+ /obj/item/food/breadslice/plain = 5,
+ /obj/item/food/chawanmushi = 4,
/obj/item/food/fish_poke = 5,
+ /obj/item/food/muffin/berry = 2,
+ /obj/item/food/sashimi = 4,
+ /obj/item/food/tofu = 5,
),
VENUE_BAR = list(
/datum/reagent/consumable/ethanol/sake = 8,
@@ -243,14 +245,14 @@
speech_sound = 'sound/creatures/tourist/tourist_talk_japanese2.ogg'
orderable_objects = list(
VENUE_RESTAURANT = list(
- /obj/item/food/tofu = 5,
- /obj/item/food/soup/miso = 6,
- /obj/item/food/soup/vegetable = 4,
- /obj/item/food/sashimi = 4,
- /obj/item/food/chawanmushi = 4,
- /obj/item/food/meatbun = 4,
+ /datum/reagent/consumable/nutriment/soup/miso = 6,
+ /datum/reagent/consumable/nutriment/soup/vegetable_soup = 4,
/obj/item/food/beef_stroganoff = 2,
+ /obj/item/food/chawanmushi = 4,
/obj/item/food/meat_poke = 4,
+ /obj/item/food/meatbun = 4,
+ /obj/item/food/sashimi = 4,
+ /obj/item/food/tofu = 5,
),
VENUE_BAR = list(
/datum/reagent/consumable/ethanol/beer = 14,
@@ -384,16 +386,16 @@
orderable_objects = list(
VENUE_RESTAURANT = list(
+ /datum/custom_order/icecream = 8,
+ /datum/reagent/consumable/nutriment/soup/indian_curry = 3,
+ /datum/reagent/consumable/nutriment/soup/stew = 10,
+ /obj/item/food/beef_wellington_slice = 2,
+ /obj/item/food/benedict = 5,
/obj/item/food/fishandchips = 10,
- /obj/item/food/soup/stew = 10,
- /obj/item/food/salad/ricepudding = 5,
+ /obj/item/food/full_english = 2,
/obj/item/food/grilled_cheese_sandwich = 5,
/obj/item/food/pie/meatpie = 5,
- /obj/item/food/benedict = 5,
- /obj/item/food/full_english = 2,
- /obj/item/food/soup/indian_curry = 3,
- /obj/item/food/beef_wellington_slice = 2,
- /datum/custom_order/icecream = 8
+ /obj/item/food/salad/ricepudding = 5,
),
VENUE_BAR = list(
/datum/reagent/consumable/ethanol/ale = 10,
@@ -460,5 +462,3 @@
first_warning_line = "You'd fit in well where I'm from. But you better stop."
second_warning_line = "Breaking-you-so-bad-you'll-reminisce-the-days-before-I-made-you-crooked.exe: booting..."
self_defense_line = "I have been designed to do two things: Order food, and break every bone in your body."
-
-
diff --git a/code/modules/food_and_drinks/restaurant/generic_venues.dm b/code/modules/food_and_drinks/restaurant/generic_venues.dm
index ffa678d38b4..19f1ff61323 100644
--- a/code/modules/food_and_drinks/restaurant/generic_venues.dm
+++ b/code/modules/food_and_drinks/restaurant/generic_venues.dm
@@ -43,15 +43,20 @@
return "I'll take \a [initial(object_to_order.name)]"
/datum/venue/restaurant/on_get_order(mob/living/simple_animal/robot_customer/customer_pawn, obj/item/order_item)
- . = ..()
- var/obj/item/food/ordered_food = order_item
- customer_pawn.visible_message(span_danger("[customer_pawn] pushes [ordered_food] into their mouth-shaped hole!"), span_danger("You push [ordered_food] into your mouth-shaped hole."))
- playsound(get_turf(customer_pawn),'sound/items/eatfood.ogg', rand(10,50), TRUE)
- customers_served += 1
- qdel(ordered_food)
+ var/transaction_result = ..()
+ if((transaction_result & TRANSACTION_HANDLED) || !(transaction_result & TRANSACTION_SUCCESS))
+ return
+
+ customer_pawn.visible_message(
+ span_danger("[customer_pawn] pushes [order_item] into their mouth-shaped hole!"),
+ span_danger("You push [order_item] into your mouth-shaped hole."),
+ )
+ playsound(customer_pawn, 'sound/items/eatfood.ogg', rand(10,50), TRUE)
+ qdel(order_item)
/obj/machinery/restaurant_portal/restaurant
linked_venue = /datum/venue/restaurant
+
/obj/item/holosign_creator/robot_seat/restaurant
name = "restaurant seating indicator placer"
holosign_type = /obj/structure/holosign/robot_seat/restaurant
@@ -61,8 +66,6 @@
linked_venue = /datum/venue/restaurant
-
-
/////BAR/////
/datum/venue/bar
name = "bar"
@@ -82,61 +85,6 @@
/datum/customer_data/malfunction = 1,
)
-/datum/venue/bar/get_food_appearance(order)
- var/datum/reagent/reagent_to_order = order
- // Default the icon to the fallback icon
- var/glass_visual_icon = initial(reagent_to_order.fallback_icon)
- var/glass_visual_icon_state = initial(reagent_to_order.fallback_icon_state)
-
- // Look for a glass style based on this reagent type
- for(var/potential_container in GLOB.glass_style_singletons)
- var/datum/glass_style/draw_as = GLOB.glass_style_singletons[potential_container][reagent_to_order]
- if(isnull(draw_as))
- continue
-
- // Override the crummy fallback icon if we find a glass style to use instead
- glass_visual_icon = draw_as.icon
- glass_visual_icon_state = draw_as.icon_state
- break
-
- // If we have no icon or fallback, well... Scream. Someone should fix it
- if(!glass_visual_icon || !glass_visual_icon_state)
- stack_trace("[reagent_to_order] has no icon sprite for restaurant code, please set a fallback icon for this reagent.")
- glass_visual_icon = 'icons/obj/drinks/drinks.dmi'
- glass_visual_icon_state = "glass_empty"
-
- var/image/food_image = image(icon = 'icons/effects/effects.dmi', icon_state = "thought_bubble")
- food_image.add_overlay(mutable_appearance(glass_visual_icon, glass_visual_icon_state))
-
- return food_image
-
-/datum/venue/bar/order_food_line(order)
- var/datum/reagent/reagent_to_order = order
- return "I'll take a glass of [initial(reagent_to_order.name)]"
-
-/datum/venue/bar/on_get_order(mob/living/simple_animal/robot_customer/customer_pawn, obj/item/order_item)
- var/datum/reagent/consumable/ordered_reagent_type = customer_pawn.ai_controller.blackboard[BB_CUSTOMER_CURRENT_ORDER]
-
- for(var/datum/reagent/reagent as anything in order_item.reagents.reagent_list)
- if(reagent.type != ordered_reagent_type)
- continue
- SEND_SIGNAL(reagent, COMSIG_ITEM_SOLD_TO_CUSTOMER, customer_pawn, order_item)
-
- customer_pawn.visible_message(span_danger("[customer_pawn] slurps up [order_item] in one go!"), span_danger("You slurp up [order_item] in one go."))
- playsound(get_turf(customer_pawn), 'sound/items/drink.ogg', 50, TRUE)
- customers_served += 1
- order_item.reagents.clear_reagents()
-
-
-///The bar needs to have a minimum amount of the reagent
-/datum/venue/bar/is_correct_order(object_used, wanted_item)
- . = ..()
- if(.)
- return
- if(istype(object_used, /obj/item/reagent_containers/cup/glass))
- var/obj/item/reagent_containers/cup/glass/potential_drink = object_used
- return potential_drink.reagents.has_reagent(wanted_item, VENUE_BAR_MINIMUM_REAGENTS)
-
/obj/machinery/restaurant_portal/bar
linked_venue = /datum/venue/bar
diff --git a/code/modules/hydroponics/grown/onion.dm b/code/modules/hydroponics/grown/onion.dm
index b363bb26fa2..217fe0a6d56 100644
--- a/code/modules/hydroponics/grown/onion.dm
+++ b/code/modules/hydroponics/grown/onion.dm
@@ -14,7 +14,7 @@
growthstages = 3
weed_chance = 3
growing_icon = 'icons/obj/hydroponics/growing_vegetables.dmi'
- reagents_add = list(/datum/reagent/consumable/nutriment/vitamin = 0.04, /datum/reagent/consumable/nutriment = 0.1, /datum/reagent/consumable/tearjuice = 0.5)
+ reagents_add = list(/datum/reagent/consumable/nutriment/vitamin = 0.04, /datum/reagent/consumable/nutriment = 0.1, /datum/reagent/consumable/tearjuice = 0.25)
mutatelist = list(/obj/item/seeds/onion/red)
/obj/item/food/grown/onion
diff --git a/code/modules/jobs/job_types/cook.dm b/code/modules/jobs/job_types/cook.dm
index cc596cbd9f5..6be121085d2 100644
--- a/code/modules/jobs/job_types/cook.dm
+++ b/code/modules/jobs/job_types/cook.dm
@@ -30,16 +30,18 @@
/obj/item/clothing/head/utility/chefhat,
)
+ // Adds up to 100, don't mess it up
mail_goodies = list(
- /obj/item/storage/box/ingredients/random = 80,
- /obj/item/reagent_containers/cup/bottle/caramel = 20,
- /obj/item/reagent_containers/condiment/flour = 20,
- /obj/item/reagent_containers/condiment/rice = 20,
- /obj/item/reagent_containers/condiment/ketchup = 20,
- /obj/item/reagent_containers/condiment/enzyme = 15,
- /obj/item/reagent_containers/condiment/soymilk = 15,
+ /obj/item/storage/box/ingredients/random = 40,
+ /obj/item/reagent_containers/cup/bottle/caramel = 8,
+ /obj/item/reagent_containers/condiment/flour = 8,
+ /obj/item/reagent_containers/condiment/rice = 8,
+ /obj/item/reagent_containers/condiment/ketchup = 8,
+ /obj/item/reagent_containers/condiment/enzyme = 8,
+ /obj/item/reagent_containers/condiment/soymilk = 8,
+ /obj/item/kitchen/spoon/soup_ladle = 6,
/obj/item/knife/kitchen = 4,
- /obj/item/knife/butcher = 2
+ /obj/item/knife/butcher = 2,
)
rpg_title = "Tavern Chef"
diff --git a/code/modules/mining/lavaland/ash_flora.dm b/code/modules/mining/lavaland/ash_flora.dm
index 95d8237dbd6..9da9e3592bd 100644
--- a/code/modules/mining/lavaland/ash_flora.dm
+++ b/code/modules/mining/lavaland/ash_flora.dm
@@ -382,16 +382,10 @@
desc = "A bowl made out of mushrooms. Not food, though it might have contained some at some point."
icon = 'icons/obj/lavaland/ash_flora.dmi'
icon_state = "mushroom_bowl"
-
-/obj/item/reagent_containers/cup/bowl/mushroom_bowl/update_overlays()
- . = ..()
- if(!reagents?.total_volume)
- return
- var/mutable_appearance/filling = mutable_appearance('icons/obj/lavaland/ash_flora.dmi', "fullbowl")
- filling.color = mix_color_from_reagents(reagents.reagent_list)
- . += filling
+ fill_icon_state = "fullbowl"
+ fill_icon = 'icons/obj/lavaland/ash_flora.dmi'
/obj/item/reagent_containers/cup/bowl/mushroom_bowl/update_icon_state()
- if(!reagents || !reagents.total_volume)
+ if(!reagents.total_volume)
icon_state = "mushroom_bowl"
return ..()
diff --git a/code/modules/reagents/chemistry/holder.dm b/code/modules/reagents/chemistry/holder.dm
index 94cded825ed..b8dfe753925 100644
--- a/code/modules/reagents/chemistry/holder.dm
+++ b/code/modules/reagents/chemistry/holder.dm
@@ -66,10 +66,16 @@
for(var/reaction in D.required_reagents)
reaction_ids += reaction
var/datum/reagent/reagent = find_reagent_object_from_type(reaction)
+ if(!istype(reagent))
+ stack_trace("Invalid reagent found in [D] required_reagents: [reaction]")
+ continue
reagents += list(list("name" = reagent.name, "id" = reagent.type))
for(var/product in D.results)
var/datum/reagent/reagent = find_reagent_object_from_type(product)
+ if(!istype(reagent))
+ stack_trace("Invalid reagent found in [D] results: [product]")
+ continue
product_names += reagent.name
product_ids += product
@@ -951,21 +957,13 @@
break
total_matching_catalysts++
if(cached_my_atom)
- if(!reaction.required_container)
- matching_container = TRUE
- else
- if(cached_my_atom.type == reaction.required_container)
- matching_container = TRUE
- if (isliving(cached_my_atom) && !reaction.mob_react) //Makes it so certain chemical reactions don't occur in mobs
+ matching_container = reaction.required_container ? (cached_my_atom.type == reaction.required_container) : TRUE
+
+ if(isliving(cached_my_atom) && !reaction.mob_react) //Makes it so certain chemical reactions don't occur in mobs
matching_container = FALSE
- if(!reaction.required_other)
- matching_other = TRUE
- else if(istype(cached_my_atom, /obj/item/slime_extract))
- var/obj/item/slime_extract/extract = cached_my_atom
+ matching_other = reaction.required_other ? reaction.pre_reaction_other_checks(src) : TRUE
- if(extract.Uses > 0) // added a limit to slime cores -- Muskets requested this
- matching_other = TRUE
else
if(!reaction.required_container)
matching_container = TRUE
diff --git a/code/modules/reagents/chemistry/reagents.dm b/code/modules/reagents/chemistry/reagents.dm
index f03cd699d2b..f8dbd09ddb9 100644
--- a/code/modules/reagents/chemistry/reagents.dm
+++ b/code/modules/reagents/chemistry/reagents.dm
@@ -93,17 +93,18 @@ GLOBAL_LIST_INIT(name2reagent, build_name2reagent())
/// See "Organ defines for carbon mobs" in /code/_DEFINES/mobs.dm
var/affected_organtype = ORGAN_ORGANIC
+ ///The default reagent container for the reagent, used for icon generation
+ var/obj/item/reagent_containers/default_container = /obj/item/reagent_containers/cup/bottle
+
// Used for restaurants.
///The amount a robot will pay for a glass of this (20 units but can be higher if you pour more, be frugal!)
var/glass_price
-
- ///The default reagent container for the reagent
- var/obj/item/reagent_containers/default_container = /obj/item/reagent_containers/cup/bottle
-
/// Icon for fallback item displayed in a tourist's thought bubble for if this reagent had no associated glass_style datum.
var/fallback_icon
/// Icon state for fallback item displayed in a tourist's thought bubble for if this reagent had no associated glass_style datum.
var/fallback_icon_state
+ /// When ordered in a restaurant, what custom order do we create?
+ var/restaurant_order = /datum/custom_order/reagent/drink
/datum/reagent/New()
SHOULD_CALL_PARENT(TRUE)
diff --git a/code/modules/reagents/chemistry/reagents/alcohol_reagents.dm b/code/modules/reagents/chemistry/reagents/alcohol_reagents.dm
index a3b548661d3..59336ce4d85 100644
--- a/code/modules/reagents/chemistry/reagents/alcohol_reagents.dm
+++ b/code/modules/reagents/chemistry/reagents/alcohol_reagents.dm
@@ -2086,13 +2086,14 @@
taste_description = "custard and alcohol"
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
-/datum/glass_style/drinking_glass/eggnog
+/datum/glass_style/has_foodtype/drinking_glass/eggnog
required_drink_type = /datum/reagent/consumable/ethanol/eggnog
name = "eggnog"
desc = "For enjoying the most wonderful time of the year."
icon_state = "glass_yellow"
+ drink_type = FRUIT
-/datum/glass_style/juicebox/eggnog
+/datum/glass_style/has_foodtype/juicebox/eggnog
required_drink_type = /datum/reagent/consumable/ethanol/eggnog
name = "carton of eggnog"
desc = "Tasty grape juice in a fun little container. Non-alcoholic!"
diff --git a/code/modules/reagents/chemistry/reagents/drink_reagents.dm b/code/modules/reagents/chemistry/reagents/drink_reagents.dm
index c949be0b702..3a32a98e799 100644
--- a/code/modules/reagents/chemistry/reagents/drink_reagents.dm
+++ b/code/modules/reagents/chemistry/reagents/drink_reagents.dm
@@ -13,13 +13,14 @@
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
default_container = /obj/item/reagent_containers/cup/glass/bottle/juice/orangejuice
-/datum/glass_style/drinking_glass/orangejuice
+/datum/glass_style/has_foodtype/drinking_glass/orangejuice
required_drink_type = /datum/reagent/consumable/orangejuice
name = "glass of orange juice"
desc = "Vitamins! Yay!"
icon_state = "glass_orange"
+ drink_type = FRUIT | BREAKFAST
-/datum/glass_style/juicebox/orangejuice
+/datum/glass_style/has_foodtype/juicebox/orangejuice
required_drink_type = /datum/reagent/consumable/orangejuice
name = "orange juice box"
desc = "A great source of vitamins. Stay healthy!"
@@ -119,7 +120,7 @@
taste_description = "apples"
ph = 3.2 // ~ 2.7 -> 3.7
-/datum/glass_style/juicebox/applejuice
+/datum/glass_style/has_foodtype/juicebox/applejuice
required_drink_type = /datum/reagent/consumable/applejuice
name = "apple juice box"
desc = "Sweet apple juice. Don't be late for school!"
@@ -263,12 +264,12 @@
taste_description = "grape soda"
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
-/datum/glass_style/juicebox/grapejuice
+/datum/glass_style/has_foodtype/juicebox/grapejuice
required_drink_type = /datum/reagent/consumable/grapejuice
name = "grape juice box"
- desc = "For enjoying the most wonderful time of the year."
- icon_state = "nog2"
- drink_type = MEAT
+ desc = "Tasty grape juice in a fun little container. Non-alcoholic!"
+ icon_state = "grapebox"
+ drink_type = FRUIT
/datum/reagent/consumable/plumjuice
name = "Plum Juice"
@@ -277,11 +278,12 @@
taste_description = "plums"
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
-/datum/glass_style/drinking_glass/plumjuice
+/datum/glass_style/has_foodtype/drinking_glass/plumjuice
required_drink_type = /datum/reagent/consumable/plumjuice
name = "glass of plum juice"
desc = "Noice."
icon_state = "plumjuiceglass"
+ drink_type = FRUIT
/datum/reagent/consumable/milk
name = "Milk"
@@ -292,13 +294,14 @@
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
default_container = /obj/item/reagent_containers/condiment/milk
-/datum/glass_style/drinking_glass/milk
+/datum/glass_style/has_foodtype/drinking_glass/milk
required_drink_type = /datum/reagent/consumable/milk
name = "glass of milk"
desc = "White and nutritious goodness!"
icon_state = "glass_white"
+ drink_type = DAIRY | BREAKFAST
-/datum/glass_style/juicebox/milk
+/datum/glass_style/has_foodtype/juicebox/milk
required_drink_type = /datum/reagent/consumable/milk
name = "carton of milk"
desc = "An excellent source of calcium for growing space explorers."
@@ -1196,7 +1199,7 @@
taste_description = "chocolate milk"
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
-/datum/glass_style/juicebox/chocolate_milk
+/datum/glass_style/has_foodtype/juicebox/chocolate_milk
required_drink_type = /datum/reagent/consumable/milk/chocolate_milk
name = "carton of chocolate milk"
desc = "Milk for cool kids!"
@@ -1211,11 +1214,12 @@
taste_description = "creamy chocolate"
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
-/datum/glass_style/drinking_glass/hot_coco
+/datum/glass_style/has_foodtype/drinking_glass/hot_coco
required_drink_type = /datum/reagent/consumable/hot_coco
name = "glass of hot coco"
desc = "A favorite winter drink to warm you up."
icon_state = "chocolateglass"
+ drink_type = SUGAR | DAIRY
/datum/reagent/consumable/hot_coco/on_mob_life(mob/living/carbon/affected_mob, delta_time, times_fired)
affected_mob.adjust_bodytemperature(5 * REM * TEMPERATURE_DAMAGE_COEFFICIENT * delta_time, 0, affected_mob.get_body_temp_normal())
@@ -1283,9 +1287,10 @@
taste_description = "parsnip"
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
-/datum/glass_style/drinking_glass/parsnipjuice
+/datum/glass_style/has_foodtype/drinking_glass/parsnipjuice
required_drink_type = /datum/reagent/consumable/parsnipjuice
name = "glass of parsnip juice"
+ drink_type = FRUIT
/datum/reagent/consumable/pineapplejuice
name = "Pineapple Juice"
@@ -1295,12 +1300,13 @@
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
default_container = /obj/item/reagent_containers/cup/glass/bottle/juice/pineapplejuice
-/datum/glass_style/drinking_glass/pineapplejuice
+/datum/glass_style/has_foodtype/drinking_glass/pineapplejuice
required_drink_type = /datum/reagent/consumable/pineapplejuice
name = "glass of pineapple juice"
desc = "Tart, tropical, and hotly debated."
+ drink_type = FRUIT | PINEAPPLE
-/datum/glass_style/juicebox/pineapplejuice
+/datum/glass_style/has_foodtype/juicebox/pineapplejuice
required_drink_type = /datum/reagent/consumable/pineapplejuice
name = "pineapple juice box"
desc = "Why would you even want this?"
@@ -1314,9 +1320,10 @@
taste_description = "peaches"
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
-/datum/glass_style/drinking_glass/peachjuice
+/datum/glass_style/has_foodtype/drinking_glass/peachjuice
required_drink_type = /datum/reagent/consumable/peachjuice
name = "glass of peach juice"
+ drink_type = FRUIT
/datum/reagent/consumable/cream_soda
name = "Cream Soda"
diff --git a/code/modules/reagents/chemistry/reagents/food_reagents.dm b/code/modules/reagents/chemistry/reagents/food_reagents.dm
index 691d38c87ef..3952366f6c0 100644
--- a/code/modules/reagents/chemistry/reagents/food_reagents.dm
+++ b/code/modules/reagents/chemistry/reagents/food_reagents.dm
@@ -15,7 +15,8 @@
inverse_chem = null
/// How much nutrition this reagent supplies
var/nutriment_factor = 1 * REAGENTS_METABOLISM
- var/quality = 0 //affects mood, typically higher for mixed drinks with more complex recipes'
+ /// affects mood, typically higher for mixed drinks with more complex recipes'
+ var/quality = 0
/datum/reagent/consumable/on_mob_life(mob/living/carbon/M, delta_time, times_fired)
current_cycle++
@@ -825,16 +826,6 @@
. = TRUE
..()
-/datum/reagent/consumable/clownstears
- name = "Clown's Tears"
- description = "The sorrow and melancholy of a thousand bereaved clowns, forever denied their Honkmechs."
- nutriment_factor = 5 * REAGENTS_METABOLISM
- color = "#eef442" // rgb: 238, 244, 66
- taste_description = "mournful honking"
- ph = 9.2
- chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
-
-
/datum/reagent/consumable/liquidelectricity
name = "Liquid Electricity"
description = "The blood of Ethereals, and the stuff that keeps them going. Great for them, horrid for anyone else."
diff --git a/code/modules/reagents/chemistry/recipes.dm b/code/modules/reagents/chemistry/recipes.dm
index ca2a0215dfa..1c7d8d2adab 100644
--- a/code/modules/reagents/chemistry/recipes.dm
+++ b/code/modules/reagents/chemistry/recipes.dm
@@ -13,11 +13,10 @@
///Required chemicals that must be present in the container but are not USED.
var/list/required_catalysts = new/list()
- // Both of these variables are mostly going to be used with slime cores - but if you want to, you can use them for other things
- /// the exact container path required for the reaction to happen
- var/required_container
+ /// the exact container path required for the reaction to happen, typepath
+ var/atom/required_container
/// an integer required for the reaction to happen
- var/required_other = 0
+ var/required_other = FALSE
///Determines if a chemical reaction can occur inside a mob
var/mob_react = TRUE
@@ -80,8 +79,15 @@
/datum/chemical_reaction/proc/update_info()
return
+
///REACTION PROCS
+/**
+ * Checks if this reaction can occur. Only is ran if required_other is set to TRUE.
+ */
+/datum/chemical_reaction/proc/pre_reaction_other_checks(datum/reagents/holder)
+ return TRUE
+
/**
* Shit that happens on reaction
* Only procs at the START of a reaction
diff --git a/code/modules/reagents/chemistry/recipes/others.dm b/code/modules/reagents/chemistry/recipes/others.dm
index 1f1687b3217..b35c7f9c9df 100644
--- a/code/modules/reagents/chemistry/recipes/others.dm
+++ b/code/modules/reagents/chemistry/recipes/others.dm
@@ -175,6 +175,10 @@
/datum/chemical_reaction/virus_food
results = list(/datum/reagent/consumable/virus_food = 15)
required_reagents = list(/datum/reagent/water = 5, /datum/reagent/consumable/milk = 5)
+ is_cold_recipe = TRUE
+ required_temp = 200
+ optimal_temp = 150
+ overheat_temp = 50
/datum/chemical_reaction/virus_food_mutagen
results = list(/datum/reagent/toxin/mutagen/mutagenvirusfood = 1)
diff --git a/code/modules/reagents/chemistry/recipes/slime_extracts.dm b/code/modules/reagents/chemistry/recipes/slime_extracts.dm
index 2934306b3c6..012655eec4d 100644
--- a/code/modules/reagents/chemistry/recipes/slime_extracts.dm
+++ b/code/modules/reagents/chemistry/recipes/slime_extracts.dm
@@ -1,8 +1,16 @@
/datum/chemical_reaction/slime
- var/deletes_extract = TRUE
reaction_flags = REACTION_INSTANT
reaction_tags = REACTION_TAG_EASY | REACTION_TAG_SLIME
+ required_other = TRUE
+ var/deletes_extract = TRUE
+
+/datum/chemical_reaction/slime/pre_reaction_other_checks(datum/reagents/holder)
+ var/obj/item/slime_extract/extract = holder.my_atom
+ if(!istype(extract))
+ return FALSE
+
+ return extract.Uses > 0
/datum/chemical_reaction/slime/on_reaction(datum/reagents/holder, datum/equilibrium/reaction, created_volume)
use_slime_core(holder)
@@ -21,7 +29,6 @@
/datum/chemical_reaction/slime/slimespawn
required_reagents = list(/datum/reagent/toxin/plasma = 1)
required_container = /obj/item/slime_extract/grey
- required_other = TRUE
/datum/chemical_reaction/slime/slimespawn/on_reaction(datum/reagents/holder, datum/equilibrium/reaction, created_volume)
var/mob/living/simple_animal/slime/S = new(get_turf(holder.my_atom), "grey")
@@ -31,13 +38,11 @@
/datum/chemical_reaction/slime/slimeinaprov
results = list(/datum/reagent/medicine/epinephrine = 3)
required_reagents = list(/datum/reagent/water = 5)
- required_other = TRUE
required_container = /obj/item/slime_extract/grey
/datum/chemical_reaction/slime/slimemonkey
required_reagents = list(/datum/reagent/blood = 1)
required_container = /obj/item/slime_extract/grey
- required_other = TRUE
/datum/chemical_reaction/slime/slimemonkey/on_reaction(datum/reagents/holder, datum/equilibrium/reaction, created_volume)
for(var/i in 1 to 3)
@@ -48,26 +53,22 @@
/datum/chemical_reaction/slime/slimemutate
results = list(/datum/reagent/mutationtoxin/jelly = 1)
required_reagents = list(/datum/reagent/toxin/plasma = 1)
- required_other = TRUE
required_container = /obj/item/slime_extract/green
/datum/chemical_reaction/slime/slimehuman
results = list(/datum/reagent/mutationtoxin = 1)
required_reagents = list(/datum/reagent/blood = 1)
- required_other = TRUE
required_container = /obj/item/slime_extract/green
/datum/chemical_reaction/slime/slimelizard
results = list(/datum/reagent/mutationtoxin/lizard = 1)
required_reagents = list(/datum/reagent/uranium/radium = 1)
- required_other = TRUE
required_container = /obj/item/slime_extract/green
//Metal
/datum/chemical_reaction/slime/slimemetal
required_reagents = list(/datum/reagent/toxin/plasma = 1)
required_container = /obj/item/slime_extract/metal
- required_other = TRUE
/datum/chemical_reaction/slime/slimemetal/on_reaction(datum/reagents/holder, datum/equilibrium/reaction, created_volume)
var/turf/location = get_turf(holder.my_atom)
@@ -78,7 +79,6 @@
/datum/chemical_reaction/slime/slimeglass
required_reagents = list(/datum/reagent/water = 1)
required_container = /obj/item/slime_extract/metal
- required_other = TRUE
/datum/chemical_reaction/slime/slimeglass/on_reaction(datum/reagents/holder, datum/equilibrium/reaction, created_volume)
var/turf/location = get_turf(holder.my_atom)
@@ -90,7 +90,6 @@
/datum/chemical_reaction/slime/slimemobspawn
required_reagents = list(/datum/reagent/toxin/plasma = 1)
required_container = /obj/item/slime_extract/gold
- required_other = TRUE
deletes_extract = FALSE //we do delete, but we don't do so instantly
reaction_tags = REACTION_TAG_EASY | REACTION_TAG_SLIME | REACTION_TAG_DANGEROUS
@@ -133,7 +132,6 @@
/datum/chemical_reaction/slime/slimebork
required_reagents = list(/datum/reagent/toxin/plasma = 1)
required_container = /obj/item/slime_extract/silver
- required_other = TRUE
/datum/chemical_reaction/slime/slimebork/on_reaction(datum/reagents/holder, datum/equilibrium/reaction, created_volume)
//BORK BORK BORK
@@ -171,12 +169,10 @@
results = list(/datum/reagent/consumable/frostoil = 10)
required_reagents = list(/datum/reagent/toxin/plasma = 1)
required_container = /obj/item/slime_extract/blue
- required_other = TRUE
/datum/chemical_reaction/slime/slimestabilizer
required_reagents = list(/datum/reagent/blood = 1)
required_container = /obj/item/slime_extract/blue
- required_other = TRUE
/datum/chemical_reaction/slime/slimestabilizer/on_reaction(datum/reagents/holder, datum/equilibrium/reaction, created_volume)
new /obj/item/slimepotion/slime/stabilizer(get_turf(holder.my_atom))
@@ -185,7 +181,6 @@
/datum/chemical_reaction/slime/slimefoam
required_reagents = list(/datum/reagent/water = 5)
required_container = /obj/item/slime_extract/blue
- required_other = TRUE
/datum/chemical_reaction/slime/slimefoam/on_reaction(datum/reagents/holder, datum/equilibrium/reaction, created_volume)
holder.create_foam(/datum/effect_system/fluid_spread/foam, 80, span_danger("[src] spews out foam!"), log = TRUE)
@@ -194,7 +189,6 @@
/datum/chemical_reaction/slime/slimefreeze
required_reagents = list(/datum/reagent/toxin/plasma = 1)
required_container = /obj/item/slime_extract/darkblue
- required_other = TRUE
deletes_extract = FALSE
/datum/chemical_reaction/slime/slimefreeze/on_reaction(datum/reagents/holder, datum/equilibrium/reaction, created_volume)
@@ -216,7 +210,6 @@
/datum/chemical_reaction/slime/slimefireproof
required_reagents = list(/datum/reagent/water = 1)
required_container = /obj/item/slime_extract/darkblue
- required_other = TRUE
/datum/chemical_reaction/slime/slimefireproof/on_reaction(datum/reagents/holder, datum/equilibrium/reaction, created_volume)
new /obj/item/slimepotion/fireproof(get_turf(holder.my_atom))
@@ -227,12 +220,10 @@
results = list(/datum/reagent/consumable/capsaicin = 10)
required_reagents = list(/datum/reagent/blood = 1)
required_container = /obj/item/slime_extract/orange
- required_other = TRUE
/datum/chemical_reaction/slime/slimefire
required_reagents = list(/datum/reagent/toxin/plasma = 1)
required_container = /obj/item/slime_extract/orange
- required_other = TRUE
deletes_extract = FALSE
/datum/chemical_reaction/slime/slimefire/on_reaction(datum/reagents/holder, datum/equilibrium/reaction, created_volume)
@@ -255,13 +246,11 @@
results = list(/datum/reagent/phosphorus = 10, /datum/reagent/potassium = 10, /datum/reagent/consumable/sugar = 10)
required_reagents = list(/datum/reagent/water = 5)
required_container = /obj/item/slime_extract/orange
- required_other = TRUE
//Yellow
/datum/chemical_reaction/slime/slimeoverload
required_reagents = list(/datum/reagent/blood = 1)
required_container = /obj/item/slime_extract/yellow
- required_other = TRUE
reaction_tags = REACTION_TAG_EASY | REACTION_TAG_SLIME | REACTION_TAG_DANGEROUS
/datum/chemical_reaction/slime/slimeoverload/on_reaction(datum/reagents/holder, datum/equilibrium/reaction, created_volume)
@@ -271,7 +260,6 @@
/datum/chemical_reaction/slime/slimecell
required_reagents = list(/datum/reagent/toxin/plasma = 1)
required_container = /obj/item/slime_extract/yellow
- required_other = TRUE
/datum/chemical_reaction/slime/slimecell/on_reaction(datum/reagents/holder, created_volume)
new /obj/item/stock_parts/cell/emproof/slime(get_turf(holder.my_atom))
@@ -280,7 +268,6 @@
/datum/chemical_reaction/slime/slimeglow
required_reagents = list(/datum/reagent/water = 1)
required_container = /obj/item/slime_extract/yellow
- required_other = TRUE
/datum/chemical_reaction/slime/slimeglow/on_reaction(datum/reagents/holder, datum/equilibrium/reaction, created_volume)
var/turf/T = get_turf(holder.my_atom)
@@ -292,7 +279,6 @@
/datum/chemical_reaction/slime/slimepsteroid
required_reagents = list(/datum/reagent/toxin/plasma = 1)
required_container = /obj/item/slime_extract/purple
- required_other = TRUE
/datum/chemical_reaction/slime/slimepsteroid/on_reaction(datum/reagents/holder, datum/equilibrium/reaction, created_volume)
new /obj/item/slimepotion/slime/steroid(get_turf(holder.my_atom))
@@ -302,13 +288,11 @@
results = list(/datum/reagent/medicine/regen_jelly = 5)
required_reagents = list(/datum/reagent/blood = 1)
required_container = /obj/item/slime_extract/purple
- required_other = TRUE
//Dark Purple
/datum/chemical_reaction/slime/slimeplasma
required_reagents = list(/datum/reagent/toxin/plasma = 1)
required_container = /obj/item/slime_extract/darkpurple
- required_other = TRUE
/datum/chemical_reaction/slime/slimeplasma/on_reaction(datum/reagents/holder, datum/equilibrium/reaction, created_volume)
new /obj/item/stack/sheet/mineral/plasma(get_turf(holder.my_atom), 3)
@@ -318,7 +302,6 @@
/datum/chemical_reaction/slime/slimemutator
required_reagents = list(/datum/reagent/toxin/plasma = 1)
required_container = /obj/item/slime_extract/red
- required_other = TRUE
/datum/chemical_reaction/slime/slimemutator/on_reaction(datum/reagents/holder, datum/equilibrium/reaction, created_volume)
new /obj/item/slimepotion/slime/mutator(get_turf(holder.my_atom))
@@ -327,7 +310,6 @@
/datum/chemical_reaction/slime/slimebloodlust
required_reagents = list(/datum/reagent/blood = 1)
required_container = /obj/item/slime_extract/red
- required_other = TRUE
reaction_tags = REACTION_TAG_EASY | REACTION_TAG_SLIME | REACTION_TAG_DANGEROUS
/datum/chemical_reaction/slime/slimebloodlust/on_reaction(datum/reagents/holder, datum/equilibrium/reaction, created_volume)
@@ -344,7 +326,6 @@
/datum/chemical_reaction/slime/slimespeed
required_reagents = list(/datum/reagent/water = 1)
required_container = /obj/item/slime_extract/red
- required_other = TRUE
/datum/chemical_reaction/slime/slimespeed/on_reaction(datum/reagents/holder, datum/equilibrium/reaction, created_volume)
new /obj/item/slimepotion/speed(get_turf(holder.my_atom))
@@ -354,7 +335,6 @@
/datum/chemical_reaction/slime/docility
required_reagents = list(/datum/reagent/toxin/plasma = 1)
required_container = /obj/item/slime_extract/pink
- required_other = TRUE
/datum/chemical_reaction/slime/docility/on_reaction(datum/reagents/holder, datum/equilibrium/reaction, created_volume)
new /obj/item/slimepotion/slime/docility(get_turf(holder.my_atom))
@@ -363,7 +343,6 @@
/datum/chemical_reaction/slime/gender
required_reagents = list(/datum/reagent/blood = 1)
required_container = /obj/item/slime_extract/pink
- required_other = TRUE
/datum/chemical_reaction/slime/gender/on_reaction(datum/reagents/holder, datum/equilibrium/reaction, created_volume)
new /obj/item/slimepotion/genderchange(get_turf(holder.my_atom))
@@ -373,14 +352,12 @@
/datum/chemical_reaction/slime/slimemutate2
results = list(/datum/reagent/aslimetoxin = 1)
required_reagents = list(/datum/reagent/toxin/plasma = 1)
- required_other = TRUE
required_container = /obj/item/slime_extract/black
//Oil
/datum/chemical_reaction/slime/slimeexplosion
required_reagents = list(/datum/reagent/toxin/plasma = 1)
required_container = /obj/item/slime_extract/oil
- required_other = TRUE
deletes_extract = FALSE
reaction_tags = REACTION_TAG_EASY | REACTION_TAG_SLIME | REACTION_TAG_DANGEROUS
@@ -410,13 +387,11 @@
results = list(/datum/reagent/consumable/cornoil = 10)
required_reagents = list(/datum/reagent/blood = 1)
required_container = /obj/item/slime_extract/oil
- required_other = TRUE
//Light Pink
/datum/chemical_reaction/slime/slimepotion2
required_container = /obj/item/slime_extract/lightpink
required_reagents = list(/datum/reagent/toxin/plasma = 1)
- required_other = TRUE
/datum/chemical_reaction/slime/slimepotion2/on_reaction(datum/reagents/holder, datum/equilibrium/reaction, created_volume)
new /obj/item/slimepotion/slime/sentience(get_turf(holder.my_atom))
@@ -425,7 +400,6 @@
/datum/chemical_reaction/slime/renaming
required_container = /obj/item/slime_extract/lightpink
required_reagents = list(/datum/reagent/water = 1)
- required_other = TRUE
/datum/chemical_reaction/slime/renaming/on_reaction(datum/reagents/holder, datum/equilibrium/reaction, created_volume)
new /obj/item/slimepotion/slime/renaming(holder.my_atom.drop_location())
@@ -436,7 +410,6 @@
/datum/chemical_reaction/slime/adamantine
required_reagents = list(/datum/reagent/toxin/plasma = 1)
required_container = /obj/item/slime_extract/adamantine
- required_other = TRUE
/datum/chemical_reaction/slime/adamantine/on_reaction(datum/reagents/holder, datum/equilibrium/reaction, created_volume)
new /obj/item/stack/sheet/mineral/adamantine(get_turf(holder.my_atom))
@@ -446,7 +419,6 @@
/datum/chemical_reaction/slime/slimefloor2
required_reagents = list(/datum/reagent/blood = 1)
required_container = /obj/item/slime_extract/bluespace
- required_other = TRUE
/datum/chemical_reaction/slime/slimefloor2/on_reaction(datum/reagents/holder, datum/equilibrium/reaction, created_volume)
new /obj/item/stack/tile/bluespace(get_turf(holder.my_atom), 25)
@@ -456,7 +428,6 @@
/datum/chemical_reaction/slime/slimecrystal
required_reagents = list(/datum/reagent/toxin/plasma = 1)
required_container = /obj/item/slime_extract/bluespace
- required_other = TRUE
/datum/chemical_reaction/slime/slimecrystal/on_reaction(datum/reagents/holder, datum/equilibrium/reaction, created_volume)
var/obj/item/stack/ore/bluespace_crystal/BC = new (get_turf(holder.my_atom))
@@ -466,7 +437,6 @@
/datum/chemical_reaction/slime/slimeradio
required_reagents = list(/datum/reagent/water = 1)
required_container = /obj/item/slime_extract/bluespace
- required_other = TRUE
/datum/chemical_reaction/slime/slimeradio/on_reaction(datum/reagents/holder, datum/equilibrium/reaction, created_volume)
new /obj/item/slimepotion/slime/slimeradio(get_turf(holder.my_atom))
@@ -476,7 +446,6 @@
/datum/chemical_reaction/slime/slimepsteroid2
required_reagents = list(/datum/reagent/toxin/plasma = 1)
required_container = /obj/item/slime_extract/cerulean
- required_other = TRUE
/datum/chemical_reaction/slime/slimepsteroid2/on_reaction(datum/reagents/holder, datum/equilibrium/reaction, created_volume)
new /obj/item/slimepotion/enhancer(get_turf(holder.my_atom))
@@ -485,7 +454,6 @@
/datum/chemical_reaction/slime/slime_territory
required_reagents = list(/datum/reagent/blood = 1)
required_container = /obj/item/slime_extract/cerulean
- required_other = TRUE
/datum/chemical_reaction/slime/slime_territory/on_reaction(datum/reagents/holder, datum/equilibrium/reaction, created_volume)
new /obj/item/areaeditor/blueprints/slime(get_turf(holder.my_atom))
@@ -495,7 +463,6 @@
/datum/chemical_reaction/slime/slimestop
required_reagents = list(/datum/reagent/toxin/plasma = 1)
required_container = /obj/item/slime_extract/sepia
- required_other = TRUE
/datum/chemical_reaction/slime/slimestop/on_reaction(datum/reagents/holder, datum/equilibrium/reaction, created_volume)
addtimer(CALLBACK(src, PROC_REF(slime_stop), holder), 5 SECONDS)
@@ -514,7 +481,6 @@
/datum/chemical_reaction/slime/slimecamera
required_reagents = list(/datum/reagent/water = 1)
required_container = /obj/item/slime_extract/sepia
- required_other = TRUE
/datum/chemical_reaction/slime/slimecamera/on_reaction(datum/reagents/holder, datum/equilibrium/reaction, created_volume)
new /obj/item/camera(get_turf(holder.my_atom))
@@ -524,7 +490,6 @@
/datum/chemical_reaction/slime/slimefloor
required_reagents = list(/datum/reagent/blood = 1)
required_container = /obj/item/slime_extract/sepia
- required_other = TRUE
/datum/chemical_reaction/slime/slimefloor/on_reaction(datum/reagents/holder, datum/equilibrium/reaction, created_volume)
new /obj/item/stack/tile/sepia(get_turf(holder.my_atom), 25)
@@ -534,7 +499,6 @@
/datum/chemical_reaction/slime/slimepaint
required_reagents = list(/datum/reagent/toxin/plasma = 1)
required_container = /obj/item/slime_extract/pyrite
- required_other = TRUE
/datum/chemical_reaction/slime/slimepaint/on_reaction(datum/reagents/holder, datum/equilibrium/reaction, created_volume)
var/chosen = pick(subtypesof(/obj/item/paint))
@@ -544,7 +508,6 @@
/datum/chemical_reaction/slime/slimecrayon
required_reagents = list(/datum/reagent/blood = 1)
required_container = /obj/item/slime_extract/pyrite
- required_other = TRUE
/datum/chemical_reaction/slime/slimecrayon/on_reaction(datum/reagents/holder, datum/equilibrium/reaction, created_volume)
var/chosen = pick(difflist(subtypesof(/obj/item/toy/crayon),typesof(/obj/item/toy/crayon/spraycan)))
@@ -554,7 +517,6 @@
//Rainbow :o)
/datum/chemical_reaction/slime/slime_rng
required_reagents = list(/datum/reagent/toxin/plasma = 1)
- required_other = TRUE
required_container = /obj/item/slime_extract/rainbow
/datum/chemical_reaction/slime/slime_rng/on_reaction(datum/reagents/holder, datum/equilibrium/reaction, created_volume)
@@ -571,7 +533,6 @@
/datum/chemical_reaction/slime/slimebomb
required_reagents = list(/datum/reagent/toxin/slimejelly = 1)
- required_other = TRUE
required_container = /obj/item/slime_extract/rainbow
/datum/chemical_reaction/slime/slimebomb/on_reaction(datum/reagents/holder, datum/equilibrium/reaction, created_volume)
@@ -593,7 +554,6 @@
/datum/chemical_reaction/slime/slime_transfer
required_reagents = list(/datum/reagent/blood = 1)
- required_other = TRUE
required_container = /obj/item/slime_extract/rainbow
/datum/chemical_reaction/slime/slime_transfer/on_reaction(datum/reagents/holder, datum/equilibrium/reaction, created_volume)
@@ -602,7 +562,6 @@
/datum/chemical_reaction/slime/flight_potion
required_reagents = list(/datum/reagent/water/holywater = 5, /datum/reagent/uranium = 5)
- required_other = TRUE
required_container = /obj/item/slime_extract/rainbow
/datum/chemical_reaction/slime/flight_potion/on_reaction(datum/reagents/holder, datum/equilibrium/reaction, created_volume)
diff --git a/code/modules/reagents/reagent_containers.dm b/code/modules/reagents/reagent_containers.dm
index 8d1ec8f8344..be88ae1c00b 100644
--- a/code/modules/reagents/reagent_containers.dm
+++ b/code/modules/reagents/reagent_containers.dm
@@ -22,9 +22,18 @@
var/disease_amount = 20
/// If the reagents inside of this container will splash out when the container tries to splash onto someone or something
var/spillable = FALSE
- /// The different thresholds at which the reagent fill overlay will change
+ /**
+ * The different thresholds at which the reagent fill overlay will change. See reagentfillings.dmi.
+ *
+ * Should be a list of integers which correspond to a reagent unit threshold.
+ * If null, no automatic fill overlays are generated.
+ *
+ * For example, list(0) will mean it will gain a the overlay with any reagents present. This overlay is "overlayname0".
+ * list(0, 10) whill have two overlay options, for 0-10 units ("overlayname0") and 10+ units ("overlayname10").
+ */
var/list/fill_icon_thresholds = null
/// The optional custom name for the reagent fill icon_state prefix
+ /// If not set, uses the current icon state.
var/fill_icon_state = null
/// The icon file to take fill icon appearances from
var/fill_icon = 'icons/obj/reagentfillings.dmi'
@@ -265,13 +274,13 @@
if(!reagents.total_volume)
return
- var/fill_name = fill_icon_state? fill_icon_state : icon_state
+ var/fill_name = fill_icon_state ? fill_icon_state : icon_state
var/mutable_appearance/filling = mutable_appearance(fill_icon, "[fill_name][fill_icon_thresholds[1]]")
var/percent = round((reagents.total_volume / volume) * 100)
for(var/i in 1 to fill_icon_thresholds.len)
var/threshold = fill_icon_thresholds[i]
- var/threshold_end = (i == fill_icon_thresholds.len)? INFINITY : fill_icon_thresholds[i+1]
+ var/threshold_end = (i == fill_icon_thresholds.len) ? INFINITY : fill_icon_thresholds[i+1]
if(threshold <= percent && percent < threshold_end)
filling.icon_state = "[fill_name][fill_icon_thresholds[i]]"
diff --git a/code/modules/reagents/reagent_containers/cups/_cup.dm b/code/modules/reagents/reagent_containers/cups/_cup.dm
index 295921c5d24..93283d07d62 100644
--- a/code/modules/reagents/reagent_containers/cups/_cup.dm
+++ b/code/modules/reagents/reagent_containers/cups/_cup.dm
@@ -204,6 +204,16 @@
set_custom_materials(list(GET_MATERIAL_REF(/datum/material/glass) = 5))//sets it to glass so, later on, it gets picked up by the glass catch (hope it doesn't 'break' things lol)
return ..()
+/// Callback for [datum/component/takes_reagent_appearance] to inherent style footypes
+/obj/item/reagent_containers/cup/proc/on_cup_change(datum/glass_style/has_foodtype/style)
+ if(!istype(style))
+ return
+ drink_type = style.drink_type
+
+/// Callback for [datum/component/takes_reagent_appearance] to reset to no foodtypes
+/obj/item/reagent_containers/cup/proc/on_cup_reset()
+ drink_type = NONE
+
/obj/item/reagent_containers/cup/beaker
name = "beaker"
desc = "A beaker. It can hold up to 60 units." //SKYRAT EDIT: Used to say can hold up to 50 units.
diff --git a/code/modules/reagents/reagent_containers/cups/_glass_datum.dm b/code/modules/reagents/reagent_containers/cups/_glass_datum.dm
index af3061ec067..41c6a9f00cf 100644
--- a/code/modules/reagents/reagent_containers/cups/_glass_datum.dm
+++ b/code/modules/reagents/reagent_containers/cups/_glass_datum.dm
@@ -51,7 +51,7 @@ GLOBAL_LIST_INIT(glass_style_singletons, create_glass_styles())
/datum/glass_style
/// Required - What EXACT type of reagent is needed for this style to be used
/// If not supplied, will be assumed to be an abstract type and will not be instantiated
- var/required_drink_type
+ var/datum/reagent/required_drink_type
/// Required - What EXACT type of atom is needed for this style to be used
/// If not supplied, will be assumed to be an abstract type and will not be instantiated
var/required_container_type
@@ -64,6 +64,25 @@ GLOBAL_LIST_INIT(glass_style_singletons, create_glass_styles())
/// Suggested - What icon state is used for this glass style
var/icon_state
+/// Helper to apply the entire style to something.
+/datum/glass_style/proc/set_all(obj/item/thing)
+ set_name(thing)
+ set_desc(thing)
+ set_appearance(thing)
+
+/// Sets the passed item to our name.
+/datum/glass_style/proc/set_name(obj/item/thing)
+ thing.name = name
+
+/// Sets the passed item to our description.
+/datum/glass_style/proc/set_desc(obj/item/thing)
+ thing.desc = desc
+
+/// Sets the passed item to our icon and icon state.
+/datum/glass_style/proc/set_appearance(obj/item/thing)
+ thing.icon = icon
+ thing.icon_state = icon_state
+
/datum/glass_style/drinking_glass
required_container_type = /obj/item/reagent_containers/cup/glass/drinkingglass
icon = 'icons/obj/drinks/drinks.dmi'
@@ -72,8 +91,26 @@ GLOBAL_LIST_INIT(glass_style_singletons, create_glass_styles())
required_container_type = /obj/item/reagent_containers/cup/glass/drinkingglass/shotglass
icon = 'icons/obj/drinks/shot_glasses.dmi'
-/datum/glass_style/juicebox
- required_container_type = /obj/item/reagent_containers/cup/glass/bottle/juice/smallcarton
- icon = 'icons/obj/drinks/boxes.dmi'
+/datum/glass_style/has_foodtype
/// This style changes the "drink type" of the container it's placed it as well, it's like food types
var/drink_type = NONE
+
+/datum/glass_style/has_foodtype/drinking_glass
+ required_container_type = /obj/item/reagent_containers/cup/glass/drinkingglass
+ icon = 'icons/obj/drinks/drinks.dmi'
+
+/datum/glass_style/has_foodtype/juicebox
+ required_container_type = /obj/item/reagent_containers/cup/glass/bottle/juice/smallcarton
+ icon = 'icons/obj/drinks/boxes.dmi'
+
+/datum/glass_style/has_foodtype/soup
+ required_container_type = /obj/item/reagent_containers/cup/bowl
+ icon = 'icons/obj/food/soupsalad.dmi'
+
+/datum/glass_style/has_foodtype/soup/New()
+ . = ..()
+ // By default: If name or description is unset, it will inherent from the soup reagent set
+ if(!name)
+ name = initial(required_drink_type.name)
+ if(!desc)
+ desc = initial(required_drink_type.description)
diff --git a/code/modules/reagents/reagent_containers/cups/bottle.dm b/code/modules/reagents/reagent_containers/cups/bottle.dm
index 2dbc5287a76..50907cc8b8f 100644
--- a/code/modules/reagents/reagent_containers/cups/bottle.dm
+++ b/code/modules/reagents/reagent_containers/cups/bottle.dm
@@ -434,7 +434,7 @@
/obj/item/reagent_containers/cup/bottle/clownstears
name = "bottle of distilled clown misery"
desc = "A small bottle. Contains a mythical liquid used by sublime bartenders; made from the unhappiness of clowns."
- list_reagents = list(/datum/reagent/consumable/clownstears = 30)
+ list_reagents = list(/datum/reagent/consumable/nutriment/soup/clown_tears = 30)
/obj/item/reagent_containers/cup/bottle/saltpetre
name = "saltpetre bottle"
diff --git a/code/modules/reagents/reagent_containers/cups/drinkingglass.dm b/code/modules/reagents/reagent_containers/cups/drinkingglass.dm
index c17332fb046..65f255e61dc 100644
--- a/code/modules/reagents/reagent_containers/cups/drinkingglass.dm
+++ b/code/modules/reagents/reagent_containers/cups/drinkingglass.dm
@@ -26,8 +26,8 @@
. = ..()
AddComponent( \
/datum/component/takes_reagent_appearance, \
- CALLBACK(src, PROC_REF(on_glass_change)), \
- CALLBACK(src, PROC_REF(on_glass_reset)), \
+ CALLBACK(src, PROC_REF(on_cup_change)), \
+ CALLBACK(src, PROC_REF(on_cup_reset)), \
base_container_type = base_container_type, \
)
@@ -36,12 +36,14 @@
if(!length(reagents.reagent_list))
renamedByPlayer = FALSE //so new drinks can rename the glass
-/// Having our icon state change removes fill thresholds
-/obj/item/reagent_containers/cup/glass/drinkingglass/proc/on_glass_change(datum/glass_style/style)
+// Having our icon state change removes fill thresholds
+/obj/item/reagent_containers/cup/glass/drinkingglass/on_cup_change(datum/glass_style/style)
+ . = ..()
fill_icon_thresholds = null
-/// And having our icon reset restores our fill thresholds
-/obj/item/reagent_containers/cup/glass/drinkingglass/proc/on_glass_reset()
+// And having our icon reset restores our fill thresholds
+/obj/item/reagent_containers/cup/glass/drinkingglass/on_cup_reset()
+ . = ..()
fill_icon_thresholds ||= list(0)
//Shot glasses!//
diff --git a/code/modules/reagents/reagent_containers/cups/drinks.dm b/code/modules/reagents/reagent_containers/cups/drinks.dm
index db94be24894..41549a8f689 100644
--- a/code/modules/reagents/reagent_containers/cups/drinks.dm
+++ b/code/modules/reagents/reagent_containers/cups/drinks.dm
@@ -380,16 +380,12 @@
/obj/item/reagent_containers/cup/glass/bottle/juice/smallcarton/Initialize(mapload, vol)
. = ..()
- AddComponent(/datum/component/takes_reagent_appearance, CALLBACK(src, PROC_REF(on_box_change)), CALLBACK(src, PROC_REF(on_box_reset)))
-
-/// Having our icon state change changes our food type
-/obj/item/reagent_containers/cup/glass/bottle/juice/smallcarton/proc/on_box_change(datum/glass_style/juicebox/style)
- if(!istype(style))
- return
- drink_type = style.drink_type
-
-/obj/item/reagent_containers/cup/glass/bottle/juice/smallcarton/proc/on_box_reset()
- drink_type = NONE
+ AddComponent( \
+ /datum/component/takes_reagent_appearance, \
+ on_icon_changed = CALLBACK(src, PROC_REF(on_cup_change)), \
+ on_icon_reset = CALLBACK(src, PROC_REF(on_cup_reset)), \
+ base_container_type = /obj/item/reagent_containers/cup/glass/bottle/juice/smallcarton, \
+ )
/obj/item/reagent_containers/cup/glass/bottle/juice/smallcarton/smash(atom/target, mob/thrower, ranged = FALSE)
if(bartender_check(target) && ranged)
diff --git a/code/modules/research/designs/machine_designs.dm b/code/modules/research/designs/machine_designs.dm
index 2668804b205..eb731bc9f32 100644
--- a/code/modules/research/designs/machine_designs.dm
+++ b/code/modules/research/designs/machine_designs.dm
@@ -714,6 +714,26 @@
)
departmental_flags = DEPARTMENT_BITFLAG_SERVICE
+/datum/design/board/stove
+ name = "Stove Board"
+ desc = "The circuit board for a Stove."
+ id = "stove"
+ build_path = /obj/item/circuitboard/machine/stove
+ category = list(
+ RND_CATEGORY_MACHINE + RND_SUBCATEGORY_MACHINE_KITCHEN
+ )
+ departmental_flags = DEPARTMENT_BITFLAG_SERVICE
+
+/datum/design/board/range
+ name = "Range Board"
+ desc = "The circuit board for a Range, which is both an Oven and a Stove."
+ id = "range"
+ build_path = /obj/item/circuitboard/machine/range
+ category = list(
+ RND_CATEGORY_MACHINE + RND_SUBCATEGORY_MACHINE_KITCHEN
+ )
+ departmental_flags = DEPARTMENT_BITFLAG_SERVICE
+
/datum/design/board/donksofttoyvendor
name = "Donksoft Toy Vendor Board"
desc = "The circuit board for a Donksoft Toy Vendor."
diff --git a/code/modules/research/techweb/all_nodes.dm b/code/modules/research/techweb/all_nodes.dm
index da032f640b6..44b61d50a72 100644
--- a/code/modules/research/techweb/all_nodes.dm
+++ b/code/modules/research/techweb/all_nodes.dm
@@ -495,8 +495,10 @@
"monkey_recycler",
"oven",
"processor",
+ "range", // should be in a further node, probably
"reagentgrinder",
"smartfridge",
+ "stove",
)
research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 4000)
discount_experiments = list(/datum/experiment/scanning/random/cytology = 3000) //Big discount to reinforce doing it.
diff --git a/code/modules/research/xenobiology/vatgrowing/samples/cell_lines/common.dm b/code/modules/research/xenobiology/vatgrowing/samples/cell_lines/common.dm
index 8fd2b67d3e4..7015344276f 100644
--- a/code/modules/research/xenobiology/vatgrowing/samples/cell_lines/common.dm
+++ b/code/modules/research/xenobiology/vatgrowing/samples/cell_lines/common.dm
@@ -504,7 +504,7 @@
/datum/reagent/plantnutriment/robustharvestnutriment = 1)
suppressive_reagents = list(
- /datum/reagent/consumable/clownstears = -8,
+ /datum/reagent/consumable/nutriment/soup/clown_tears = -8,
/datum/reagent/toxin/plantbgone = -4,
/datum/reagent/consumable/ethanol/silencer = -3,
/datum/reagent/consumable/nothing = -2,
@@ -529,7 +529,7 @@
/datum/reagent/consumable/space_cola = 1)
suppressive_reagents = list(
- /datum/reagent/consumable/clownstears = -8,
+ /datum/reagent/consumable/nutriment/soup/clown_tears = -8,
/datum/reagent/consumable/mintextract = -6,
/datum/reagent/consumable/ethanol/silencer = -3,
/datum/reagent/consumable/ethanol/fernet = -3,
@@ -553,7 +553,7 @@
/datum/reagent/nitrous_oxide = 2)
suppressive_reagents = list(
- /datum/reagent/consumable/clownstears = -8,
+ /datum/reagent/consumable/nutriment/soup/clown_tears = -8,
/datum/reagent/consumable/ethanol/beepsky_smash = -3,
/datum/reagent/consumable/ethanol/silencer = -3,
/datum/reagent/toxin/mutetoxin = -3,
diff --git a/code/modules/unit_tests/focus_only_tests.dm b/code/modules/unit_tests/focus_only_tests.dm
index 6bb367eab38..18b2cfbdcd5 100644
--- a/code/modules/unit_tests/focus_only_tests.dm
+++ b/code/modules/unit_tests/focus_only_tests.dm
@@ -32,3 +32,6 @@
/// Checks that no light shares a tile/pixel offsets with another
/datum/unit_test/focus_only/stacked_lights
+
+/// Checks for bad icon / icon state setups in cooking crafting menu
+/datum/unit_test/focus_only/bad_cooking_crafting_icons
diff --git a/code/modules/unit_tests/reagent_recipe_collisions.dm b/code/modules/unit_tests/reagent_recipe_collisions.dm
index 263bef45e1a..6623c73a31d 100644
--- a/code/modules/unit_tests/reagent_recipe_collisions.dm
+++ b/code/modules/unit_tests/reagent_recipe_collisions.dm
@@ -1,15 +1,16 @@
-
-
/datum/unit_test/reagent_recipe_collisions
/datum/unit_test/reagent_recipe_collisions/Run()
build_chemical_reactions_lists()
- var/list/reactions = list()
- for(var/V in GLOB.chemical_reactions_list_reactant_index)
- reactions += GLOB.chemical_reactions_list_reactant_index[V]
- for(var/i in 1 to (reactions.len-1))
- for(var/i2 in (i+1) to reactions.len)
- var/datum/chemical_reaction/r1 = reactions[i]
- var/datum/chemical_reaction/r2 = reactions[i2]
- if(chem_recipes_do_conflict(r1, r2))
- TEST_FAIL("Chemical recipe conflict between [r1.type] and [r2.type]")
+
+ // Exclude soup from this test, they all have the same "reagents" just about
+ var/list/reactions_sans_soup = GLOB.chemical_reactions_list - subtypesof(/datum/chemical_reaction/food/soup)
+
+ for(var/reaction_type_a as anything in reactions_sans_soup)
+ for(var/reaction_type_b as anything in reactions_sans_soup)
+ if(reaction_type_a == reaction_type_b)
+ continue
+ var/datum/chemical_reaction/reaction_a = reactions_sans_soup[reaction_type_a]
+ var/datum/chemical_reaction/reaction_b = reactions_sans_soup[reaction_type_b]
+ if(chem_recipes_do_conflict(reaction_a, reaction_b))
+ TEST_FAIL("Chemical recipe conflict between [reaction_type_a] and [reaction_type_b]")
diff --git a/code/modules/vending/drinnerware.dm b/code/modules/vending/drinnerware.dm
index 073f2aabf4f..e7492f43d94 100644
--- a/code/modules/vending/drinnerware.dm
+++ b/code/modules/vending/drinnerware.dm
@@ -6,9 +6,11 @@
panel_type = "panel4"
products = list(
/obj/item/storage/bag/tray = 8,
- /obj/item/reagent_containers/cup/bowl = 20,
+ /obj/item/reagent_containers/cup/bowl = 30,
+ /obj/item/reagent_containers/cup/soup_pot = 3,
/obj/item/kitchen/fork = 6,
- /obj/item/kitchen/spoon = 6,
+ /obj/item/kitchen/spoon = 10,
+ /obj/item/kitchen/spoon/soup_ladle = 3,
/obj/item/reagent_containers/cup/glass/drinkingglass = 8,
/obj/item/reagent_containers/condiment/pack/ketchup = 5,
/obj/item/reagent_containers/condiment/pack/hotsauce = 5,
diff --git a/icons/obj/food/soupsalad.dmi b/icons/obj/food/soupsalad.dmi
index 52a2c99fb3a..60fd7801778 100644
Binary files a/icons/obj/food/soupsalad.dmi and b/icons/obj/food/soupsalad.dmi differ
diff --git a/icons/obj/kitchen.dmi b/icons/obj/kitchen.dmi
index b92034675b7..8c5781ec985 100644
Binary files a/icons/obj/kitchen.dmi and b/icons/obj/kitchen.dmi differ
diff --git a/icons/obj/lavaland/ash_flora.dmi b/icons/obj/lavaland/ash_flora.dmi
index 8e7bbe5df29..d796c200071 100644
Binary files a/icons/obj/lavaland/ash_flora.dmi and b/icons/obj/lavaland/ash_flora.dmi differ
diff --git a/icons/obj/machines/kitchen_stove.dmi b/icons/obj/machines/kitchen_stove.dmi
new file mode 100644
index 00000000000..1a9e264158e
Binary files /dev/null and b/icons/obj/machines/kitchen_stove.dmi differ
diff --git a/icons/obj/machines/kitchenmachines.dmi b/icons/obj/machines/kitchenmachines.dmi
index 32098601bf9..06c21235ac1 100644
Binary files a/icons/obj/machines/kitchenmachines.dmi and b/icons/obj/machines/kitchenmachines.dmi differ
diff --git a/icons/obj/soup_pot.dmi b/icons/obj/soup_pot.dmi
new file mode 100644
index 00000000000..6a84a0aba09
Binary files /dev/null and b/icons/obj/soup_pot.dmi differ
diff --git a/modular_skyrat/modules/customization/datums/components/crafting/recipes.dm b/modular_skyrat/modules/customization/datums/components/crafting/recipes.dm
index 21d1d8b2bde..9d88e61442a 100644
--- a/modular_skyrat/modules/customization/datums/components/crafting/recipes.dm
+++ b/modular_skyrat/modules/customization/datums/components/crafting/recipes.dm
@@ -6,7 +6,7 @@
/obj/item/organ/internal/lungs = 1,
/obj/item/organ/internal/stomach = 1,
/obj/item/food/grown/onion = 1,
- /obj/item/food/soup/oatmeal = 1,
+ /obj/item/food/grown/oat = 1,
/datum/reagent/consumable/salt = 1,
)
result = /obj/item/food/snacks/store/bread/haggis
diff --git a/modular_skyrat/modules/morefermentplants/code/banana.dm b/modular_skyrat/modules/morefermentplants/code/banana.dm
index 4e0c9d66e90..449e798ba1e 100644
--- a/modular_skyrat/modules/morefermentplants/code/banana.dm
+++ b/modular_skyrat/modules/morefermentplants/code/banana.dm
@@ -1,2 +1,2 @@
/obj/item/food/grown/banana/bluespace
- distill_reagent = /datum/reagent/consumable/clownstears
+ distill_reagent = /datum/reagent/consumable/nutriment/soup/clown_tears
diff --git a/tgstation.dme b/tgstation.dme
index 3d6097c892d..9ba1bd9837a 100644
--- a/tgstation.dme
+++ b/tgstation.dme
@@ -1318,6 +1318,7 @@
#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\foodlike_drink.dm"
#include "code\datums\elements\food\fried_item.dm"
#include "code\datums\elements\food\grilled_item.dm"
#include "code\datums\elements\food\microwavable.dm"
@@ -3446,8 +3447,12 @@
#include "code\modules\food_and_drinks\machinery\oven.dm"
#include "code\modules\food_and_drinks\machinery\processor.dm"
#include "code\modules\food_and_drinks\machinery\smartfridge.dm"
+#include "code\modules\food_and_drinks\machinery\stove.dm"
+#include "code\modules\food_and_drinks\machinery\stove_component.dm"
#include "code\modules\food_and_drinks\recipes\food_mixtures.dm"
#include "code\modules\food_and_drinks\recipes\processor_recipes.dm"
+#include "code\modules\food_and_drinks\recipes\soup_guide.dm"
+#include "code\modules\food_and_drinks\recipes\soup_mixtures.dm"
#include "code\modules\food_and_drinks\recipes\drinks\drinks_alcoholic.dm"
#include "code\modules\food_and_drinks\recipes\drinks\drinks_lizard.dm"
#include "code\modules\food_and_drinks\recipes\drinks\drinks_moth.dm"
@@ -3470,7 +3475,6 @@
#include "code\modules\food_and_drinks\recipes\tablecraft\recipes_salad.dm"
#include "code\modules\food_and_drinks\recipes\tablecraft\recipes_sandwich.dm"
#include "code\modules\food_and_drinks\recipes\tablecraft\recipes_seafood.dm"
-#include "code\modules\food_and_drinks\recipes\tablecraft\recipes_soup.dm"
#include "code\modules\food_and_drinks\recipes\tablecraft\recipes_spaghetti.dm"
#include "code\modules\food_and_drinks\restaurant\_venue.dm"
#include "code\modules\food_and_drinks\restaurant\custom_order.dm"