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"