diff --git a/_maps/map_files/Deltastation/DeltaStation2.dmm b/_maps/map_files/Deltastation/DeltaStation2.dmm index dd0ed105efd..9fc5bfd10af 100644 --- a/_maps/map_files/Deltastation/DeltaStation2.dmm +++ b/_maps/map_files/Deltastation/DeltaStation2.dmm @@ -29135,8 +29135,6 @@ /turf/open/space, /area/space/nearstation) "cqu" = ( -/obj/structure/table/wood, -/obj/item/clothing/mask/cigarette/pipe, /obj/effect/turf_decal/tile/neutral{ dir = 1 }, @@ -29147,6 +29145,7 @@ /obj/effect/turf_decal/tile/neutral{ dir = 8 }, +/obj/machinery/restaurant_portal/restaurant, /turf/open/floor/iron/dark, /area/service/bar/atrium) "cqH" = ( @@ -69065,8 +69064,6 @@ /turf/open/floor/iron, /area/engineering/main) "hzj" = ( -/obj/structure/table/wood, -/obj/item/clothing/head/fedora, /obj/effect/turf_decal/tile/neutral{ dir = 1 }, @@ -69077,6 +69074,7 @@ /obj/effect/turf_decal/tile/neutral{ dir = 8 }, +/obj/machinery/restaurant_portal/bar, /turf/open/floor/iron/dark, /area/service/bar/atrium) "hzE" = ( @@ -73928,6 +73926,7 @@ /obj/effect/turf_decal/tile/yellow{ dir = 8 }, +/obj/item/clothing/head/fedora, /turf/open/floor/iron, /area/service/bar/atrium) "jqu" = ( @@ -88938,6 +88937,7 @@ /obj/item/reagent_containers/glass/bowl, /obj/effect/turf_decal/bot, /obj/item/food/dough, +/obj/item/holosign_creator/robot_seat/restaurant, /turf/open/floor/iron, /area/service/kitchen) "oJI" = ( @@ -103602,6 +103602,7 @@ }, /obj/item/clipboard, /obj/item/toy/figure/bartender, +/obj/item/holosign_creator/robot_seat/bar, /turf/open/floor/iron/dark, /area/service/bar) "udl" = ( @@ -113574,6 +113575,7 @@ /obj/effect/turf_decal/tile/yellow{ dir = 8 }, +/obj/item/clothing/mask/cigarette/pipe, /turf/open/floor/iron, /area/service/bar/atrium) "xRL" = ( diff --git a/_maps/map_files/IceBoxStation/IceBoxStation.dmm b/_maps/map_files/IceBoxStation/IceBoxStation.dmm index ca185029ab0..097455881c4 100644 --- a/_maps/map_files/IceBoxStation/IceBoxStation.dmm +++ b/_maps/map_files/IceBoxStation/IceBoxStation.dmm @@ -27315,7 +27315,9 @@ /turf/open/floor/iron/white, /area/medical/virology) "cXd" = ( -/obj/structure/chair/stool/bar, +/obj/structure/chair/stool/bar{ + dir = 4 + }, /obj/effect/turf_decal/tile/bar, /obj/effect/turf_decal/tile/bar{ dir = 1 @@ -40570,6 +40572,16 @@ /obj/item/clothing/suit/hooded/wintercoat, /turf/open/floor/iron, /area/commons/storage/mining) +"mCN" = ( +/obj/effect/turf_decal/tile/bar, +/obj/effect/turf_decal/tile/bar{ + dir = 1 + }, +/obj/structure/chair/stool/bar{ + dir = 4 + }, +/turf/open/floor/iron, +/area/service/bar) "mDf" = ( /obj/effect/mapping_helpers/airlock/cyclelink_helper, /obj/machinery/door/airlock/engineering{ @@ -42945,6 +42957,12 @@ /obj/machinery/navbeacon/wayfinding, /turf/open/floor/iron, /area/commons/dorms) +"opx" = ( +/obj/machinery/restaurant_portal/restaurant, +/turf/open/floor/iron/white/corner{ + dir = 1 + }, +/area/hallway/primary/starboard) "opE" = ( /obj/effect/turf_decal/tile/yellow{ dir = 4 @@ -43319,6 +43337,14 @@ }, /turf/closed/wall, /area/commons/fitness) +"oHO" = ( +/obj/structure/chair/stool/bar{ + dir = 1 + }, +/turf/open/floor/iron/white/corner{ + dir = 1 + }, +/area/hallway/primary/starboard) "oHS" = ( /obj/effect/landmark/event_spawn, /obj/structure/cable, @@ -48821,6 +48847,7 @@ /obj/structure/closet/secure_closet/bar{ req_access_txt = "25" }, +/obj/item/holosign_creator/robot_seat/bar, /turf/open/floor/wood, /area/service/bar) "sCq" = ( @@ -49339,6 +49366,7 @@ /obj/structure/table, /obj/effect/spawner/lootdrop/donkpockets, /obj/item/reagent_containers/glass/beaker, +/obj/item/holosign_creator/robot_seat/restaurant, /turf/open/floor/iron/cafeteria, /area/service/kitchen) "sWw" = ( @@ -56104,6 +56132,14 @@ }, /turf/open/floor/iron, /area/cargo/miningdock) +"xzy" = ( +/obj/effect/turf_decal/tile/bar, +/obj/effect/turf_decal/tile/bar{ + dir = 1 + }, +/obj/machinery/restaurant_portal/bar, +/turf/open/floor/iron, +/area/service/bar) "xzA" = ( /obj/structure/table, /obj/item/folder/white, @@ -92629,7 +92665,7 @@ oHj dSU crr iHa -dLp +xzy jcA hYS jcA @@ -93402,10 +93438,10 @@ gYp dEb jUE cXd -cXd -cXd -cXd -cXd +mCN +mCN +mCN +mCN dLp wUq wXj @@ -94950,7 +94986,7 @@ nUo nUo tIN mjA -bbz +opx aYV iKz aYV @@ -95464,7 +95500,7 @@ omc nUo xiq xoj -bbz +oHO aYV iKz aYV @@ -95721,7 +95757,7 @@ sWv nZu xiq pIM -bbz +oHO aYV iKz aYV @@ -95978,7 +96014,7 @@ rmK nUo myl pIM -bbz +oHO aYV iKz cBm @@ -96235,7 +96271,7 @@ rmK nUo xiq ewZ -bbz +oHO aYV iKz bdc diff --git a/_maps/map_files/KiloStation/KiloStation.dmm b/_maps/map_files/KiloStation/KiloStation.dmm index f65ed254639..63822f74d55 100644 --- a/_maps/map_files/KiloStation/KiloStation.dmm +++ b/_maps/map_files/KiloStation/KiloStation.dmm @@ -9553,10 +9553,8 @@ /obj/effect/turf_decal/tile/red{ dir = 1 }, -/obj/item/kirbyplants{ - icon_state = "plant-21" - }, /obj/effect/turf_decal/stripes/corner, +/obj/effect/spawner/randomcolavend, /turf/open/floor/iron, /area/hallway/primary/fore) "auj" = ( @@ -57258,6 +57256,7 @@ pixel_y = 5 }, /obj/item/reagent_containers/glass/beaker, +/obj/item/holosign_creator/robot_seat/restaurant, /turf/open/floor/iron/dark, /area/service/kitchen) "eOX" = ( @@ -57348,14 +57347,10 @@ /turf/open/floor/iron/dark, /area/service/chapel/office) "eRD" = ( -/obj/structure/table/wood, /obj/effect/turf_decal/tile/neutral{ dir = 4 }, /obj/effect/turf_decal/tile/neutral, -/obj/machinery/computer/libraryconsole{ - pixel_y = 5 - }, /obj/effect/decal/cleanable/cobweb, /obj/structure/extinguisher_cabinet{ pixel_x = -26 @@ -57363,6 +57358,7 @@ /obj/item/radio/intercom{ pixel_y = 22 }, +/obj/machinery/restaurant_portal/bar, /turf/open/floor/iron/dark, /area/service/bar) "eRF" = ( @@ -82925,6 +82921,7 @@ /obj/machinery/light{ dir = 4 }, +/obj/item/holosign_creator/robot_seat/bar, /turf/open/floor/iron/dark, /area/service/bar) "tfm" = ( @@ -87327,7 +87324,6 @@ /area/cargo/miningoffice) "vyL" = ( /obj/effect/turf_decal/bot, -/obj/effect/spawner/randomcolavend, /obj/effect/turf_decal/tile/neutral, /obj/effect/turf_decal/tile/neutral{ dir = 8 @@ -87335,6 +87331,7 @@ /obj/effect/turf_decal/tile/neutral{ dir = 1 }, +/obj/machinery/restaurant_portal/restaurant, /turf/open/floor/iron/dark, /area/service/bar/atrium) "vyM" = ( diff --git a/_maps/map_files/MetaStation/MetaStation.dmm b/_maps/map_files/MetaStation/MetaStation.dmm index 4e6817ee34d..d107386632c 100644 --- a/_maps/map_files/MetaStation/MetaStation.dmm +++ b/_maps/map_files/MetaStation/MetaStation.dmm @@ -22819,7 +22819,11 @@ /turf/open/floor/iron/dark, /area/security/office) "ciV" = ( -/obj/item/kirbyplants/random, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/table/wood, +/obj/effect/spawner/lootdrop/gambling, /turf/open/floor/wood, /area/service/bar) "ciX" = ( @@ -25755,9 +25759,6 @@ /turf/open/floor/plating, /area/science/mixing) "cAS" = ( -/obj/structure/chair/stool{ - pixel_y = 8 - }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer2{ dir = 9 }, @@ -42568,9 +42569,6 @@ /obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden/layer2{ dir = 1 }, -/obj/structure/chair/stool{ - pixel_y = 8 - }, /turf/open/floor/wood, /area/service/bar) "hZZ" = ( @@ -50013,10 +50011,10 @@ /turf/open/floor/iron/white, /area/medical/medbay/central) "lgc" = ( -/obj/item/kirbyplants/random, /obj/effect/turf_decal/siding/wood{ dir = 8 }, +/obj/machinery/restaurant_portal/bar, /turf/open/floor/wood, /area/service/bar) "lgq" = ( @@ -58494,6 +58492,7 @@ /obj/machinery/light{ dir = 1 }, +/obj/machinery/restaurant_portal/restaurant, /turf/open/floor/wood, /area/service/bar) "oFp" = ( @@ -59817,8 +59816,6 @@ dir = 4 }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer2, -/obj/structure/table/wood, -/obj/effect/spawner/lootdrop/gambling, /turf/open/floor/wood, /area/service/bar) "pds" = ( @@ -60286,6 +60283,7 @@ dir = 1 }, /obj/structure/table/reinforced, +/obj/item/holosign_creator/robot_seat/bar, /turf/open/floor/iron, /area/service/bar) "pod" = ( @@ -68883,6 +68881,9 @@ /obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ dir = 4 }, +/obj/structure/chair/stool{ + pixel_y = 8 + }, /turf/open/floor/wood, /area/service/bar) "sGh" = ( @@ -74850,6 +74851,9 @@ dir = 4 }, /obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden/layer2, +/obj/structure/chair/stool{ + pixel_y = 8 + }, /turf/open/floor/wood, /area/service/bar) "vih" = ( @@ -75238,6 +75242,7 @@ id = "kitchen_counter"; name = "Kitchen Counter Shutters" }, +/obj/item/holosign_creator/robot_seat/restaurant, /turf/open/floor/iron/cafeteria{ dir = 5 }, @@ -117069,7 +117074,7 @@ bhG bjp tFU hkR -ciV +otW otW pTE rNI @@ -117588,7 +117593,7 @@ rXA rSf oNP vic -imL +ciV sFA mio vlj diff --git a/code/__DEFINES/ai.dm b/code/__DEFINES/ai.dm index a87781a40c0..73d5ed53dd3 100644 --- a/code/__DEFINES/ai.dm +++ b/code/__DEFINES/ai.dm @@ -60,3 +60,12 @@ #define BB_VENDING_UNTILT_COOLDOWN "BB_vending_untilt_cooldown" #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 +#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" +#define BB_CUSTOMER_CUSTOMERINFO "BB_customer_customerinfo" +#define BB_CUSTOMER_EATING "BB_customer_eating" +#define BB_CUSTOMER_ATTENDING_VENUE "BB_customer_attending_avenue" +#define BB_CUSTOMER_LEAVING "BB_customer_leaving" diff --git a/code/__DEFINES/dcs/signals.dm b/code/__DEFINES/dcs/signals.dm index 1e5f6703642..a9c9d34892b 100644 --- a/code/__DEFINES/dcs/signals.dm +++ b/code/__DEFINES/dcs/signals.dm @@ -909,6 +909,8 @@ ///called on an object by its NTNET connection component on a port distruction (port, list/data)) #define COMSIG_COMPONENT_NTNET_PORT_UPDATED "ntnet_port_updated" +///Restaurant +#define COMSIG_ITEM_SOLD_TO_CUSTOMER "item_sold_to_customer" //Nanites diff --git a/code/__DEFINES/food.dm b/code/__DEFINES/food.dm index f8694d882f2..b59162b943c 100644 --- a/code/__DEFINES/food.dm +++ b/code/__DEFINES/food.dm @@ -57,3 +57,21 @@ #define FOOD_LIKED 1 #define FOOD_DISLIKED 2 #define FOOD_TOXIC 3 + +///Venue reagent requirement +#define VENUE_BAR_MINIMUM_REAGENTS 10 + + + +///Food price classes +#define FOOD_PRICE_TRASH 10 //cheap and quick. +#define FOOD_PRICE_CHEAP 40 //In line with prices of cheap snacks and foods you find in vending machine, practically disposable. +#define FOOD_PRICE_NORMAL 100 //Half a crate of profit, selling 4 of these lets you buy a kitchen crate from cargo. +#define FOOD_PRICE_EXOTIC 300 //Making one of these should be worth the time investment, solid chunk of profit. +#define FOOD_PRICE_LEGENDARY 1000 //Large windfall for making something from this list. + + +#define DRINK_PRICE_STOCK 20 +#define DRINK_PRICE_EASY 35 +#define DRINK_PRICE_MEDIUM 80 +#define DRINK_PRICE_HIGH 200 diff --git a/code/__DEFINES/footsteps.dm b/code/__DEFINES/footsteps.dm index 02af15e40d2..1c6d639ebce 100644 --- a/code/__DEFINES/footsteps.dm +++ b/code/__DEFINES/footsteps.dm @@ -24,6 +24,7 @@ #define FOOTSTEP_MOB_HUMAN 5 //Warning: Only works on /mob/living/carbon/human #define FOOTSTEP_MOB_SLIME 6 #define FOOTSTEP_OBJ_MACHINE 7 +#define FOOTSTEP_OBJ_ROBOT 8 /* diff --git a/code/__DEFINES/subsystems.dm b/code/__DEFINES/subsystems.dm index 5d945cf5d1c..cb002c68c1b 100644 --- a/code/__DEFINES/subsystems.dm +++ b/code/__DEFINES/subsystems.dm @@ -127,6 +127,7 @@ #define INIT_ORDER_NETWORKS 45 #define INIT_ORDER_ECONOMY 40 #define INIT_ORDER_OUTPUTS 35 +#define INIT_ORDER_RESTAURANT 34 #define INIT_ORDER_ATOMS 30 #define INIT_ORDER_LANGUAGE 25 #define INIT_ORDER_MACHINES 20 diff --git a/code/controllers/subsystem/restaurant.dm b/code/controllers/subsystem/restaurant.dm new file mode 100644 index 00000000000..7917c0fc77e --- /dev/null +++ b/code/controllers/subsystem/restaurant.dm @@ -0,0 +1,24 @@ +/*! +This subsystem exists to serve as a holder for important info for the restaurant system for chef and bartender. +*/ + +SUBSYSTEM_DEF(restaurant) + name = "Restaurant" + wait = 20 SECONDS //Roll for new guests but don't do it too fast. + init_order = INIT_ORDER_RESTAURANT + flags = SS_NO_FIRE + ///All venues that exist, assoc list of type - reference + var/list/all_venues = list() + ///All customer data datums that exist, assoc list of type - reference + var/list/all_customers = list() + ///Seats claimed by robots. They want these. Don't be rude about it to them. assoc list of seat key and robot mob value + var/list/claimed_seats = list() + ///Caches appearances of food, assoc list where key is the type of food, and value is the appearance. Used so we don't have to keep creating new food. Gets filled whenever a new food that hasn't been ordered gets ordered for the first time. + var/list/food_appearance_cache = list() + +/datum/controller/subsystem/restaurant/Initialize(timeofday) + . = ..() + for(var/key in subtypesof(/datum/venue)) + all_venues[key] = new key() + for(var/key in subtypesof(/datum/customer_data)) + all_customers[key] = new key() diff --git a/code/datums/ai/_ai_controller.dm b/code/datums/ai/_ai_controller.dm index abe43e515cd..635df1e8594 100644 --- a/code/datums/ai/_ai_controller.dm +++ b/code/datums/ai/_ai_controller.dm @@ -16,8 +16,6 @@ have ways of interacting with a specific atom and control it. They posses a blac var/ai_status ///Current movement target of the AI, generally set by decision making. var/atom/current_movement_target - ///Delay between atom movements, if this is not a multiplication of the delay in - var/move_delay ///This is a list of variables the AI uses and can be mutated by actions. When an action is performed you pass this list and any relevant keys for the variables it can mutate. var/list/blackboard = list() ///Tracks recent pathing attempts, if we fail too many in a row we fail our current plans. @@ -115,7 +113,7 @@ have ways of interacting with a specific atom and control it. They posses a blac return else if(ai_movement.moving_controllers[src] != current_movement_target) //We're too far, if we're not already moving start doing it. - ai_movement.start_moving_towards(src, current_movement_target) //Then start moving + ai_movement.start_moving_towards(src, current_movement_target, current_behavior.required_distance) //Then start moving if(current_behavior.behavior_flags & AI_BEHAVIOR_MOVE_AND_PERFORM) //If we can move and perform then do so. current_behavior.perform(delta_time, src) diff --git a/code/datums/ai/generic_actions.dm b/code/datums/ai/generic_actions.dm index a3af839a568..99b75ae230a 100644 --- a/code/datums/ai/generic_actions.dm +++ b/code/datums/ai/generic_actions.dm @@ -14,3 +14,11 @@ var/mob/living/living_pawn = controller.pawn INVOKE_ASYNC(living_pawn, /mob.proc/emote, pick(screeches)) finish_action(controller, TRUE) + +///Moves to target then finishes +/datum/ai_behavior/move_to_target + behavior_flags = AI_BEHAVIOR_REQUIRE_MOVEMENT + +/datum/ai_behavior/move_to_target/perform(delta_time, datum/ai_controller/controller) + . = ..() + finish_action(controller, TRUE) diff --git a/code/datums/ai/movement/_ai_movement.dm b/code/datums/ai/movement/_ai_movement.dm index 6b0eb02cfb9..495db7ae672 100644 --- a/code/datums/ai/movement/_ai_movement.dm +++ b/code/datums/ai/movement/_ai_movement.dm @@ -2,10 +2,12 @@ /datum/ai_movement ///Assoc list ist of controllers that are currently moving as key, and what they are moving to as value var/list/moving_controllers = list() + ///Does this type require processing? + var/requires_processing = TRUE /datum/ai_movement/proc/start_moving_towards(datum/ai_controller/controller, atom/current_movement_target) controller.pathing_attempts = 0 - if(!moving_controllers.len) + if(!moving_controllers.len && requires_processing) START_PROCESSING(SSai_movement, src) moving_controllers[controller] = current_movement_target @@ -13,6 +15,6 @@ controller.pathing_attempts = 0 moving_controllers -= controller - if(!moving_controllers.len) + if(!moving_controllers.len && requires_processing) STOP_PROCESSING(SSai_movement, src) diff --git a/code/datums/ai/movement/ai_movement_basic_avoidance.dm b/code/datums/ai/movement/ai_movement_basic_avoidance.dm new file mode 100644 index 00000000000..25b868d6f44 --- /dev/null +++ b/code/datums/ai/movement/ai_movement_basic_avoidance.dm @@ -0,0 +1,12 @@ +///Uses Byond's basic obstacle avoidance mvovement +/datum/ai_movement/basic_avoidance + requires_processing = FALSE + +/datum/ai_movement/basic_avoidance/start_moving_towards(datum/ai_controller/controller, atom/current_movement_target, min_distance) + . = ..() + walk_to(controller.pawn, current_movement_target, min_distance, controller.movement_delay) + + +/datum/ai_movement/basic_avoidance/stop_moving_towards(datum/ai_controller/controller) + . = ..() + walk_to(controller.pawn, src) diff --git a/code/datums/ai/robot_customer/robot_customer_behaviors.dm b/code/datums/ai/robot_customer/robot_customer_behaviors.dm new file mode 100644 index 00000000000..36608ff8101 --- /dev/null +++ b/code/datums/ai/robot_customer/robot_customer_behaviors.dm @@ -0,0 +1,111 @@ +/datum/ai_behavior/find_seat + action_cooldown = 8 SECONDS + +/datum/ai_behavior/find_seat/perform(delta_time, datum/ai_controller/controller) + . = ..() + var/mob/living/simple_animal/robot_customer/customer_pawn = controller.pawn + var/datum/customer_data/customer_data = controller.blackboard[BB_CUSTOMER_CUSTOMERINFO] + + var/obj/structure/holosign/robot_seat/found_seat + + for(var/obj/structure/holosign/robot_seat/potential_seat in oview(7, controller.pawn)) + + if(potential_seat.linked_venue != controller.blackboard[BB_CUSTOMER_ATTENDING_VENUE]) //Incorrect venue + continue + + if(SSrestaurant.claimed_seats[potential_seat]) //Someone called dibs + continue + var/turf/seat_turf = get_turf(potential_seat) + + if(seat_turf.is_blocked_turf()) //Someone called dibsies + continue + + found_seat = potential_seat + break + + if(found_seat) + customer_pawn.say(pick(customer_data.found_seat_lines)) + controller.blackboard[BB_CUSTOMER_MY_SEAT] = found_seat + SSrestaurant.claimed_seats[found_seat] = customer_pawn + finish_action(controller, TRUE) + else + customer_pawn.say(pick(customer_data.cant_find_seat_lines)) + finish_action(controller, FALSE) + + +/datum/ai_behavior/order_food + behavior_flags = AI_BEHAVIOR_REQUIRE_MOVEMENT + required_distance = 0 + +/datum/ai_behavior/order_food/perform(delta_time, datum/ai_controller/controller) + . = ..() + var/mob/living/simple_animal/robot_customer/customer_pawn = controller.pawn + var/datum/customer_data/customer_data = controller.blackboard[BB_CUSTOMER_CUSTOMERINFO] + + if(get_turf(controller.blackboard[BB_CUSTOMER_MY_SEAT]) == get_turf(customer_pawn)) + var/obj/structure/chair/my_seat = locate(/obj/structure/chair) in get_turf(customer_pawn) + if(my_seat) + controller.pawn.setDir(my_seat.dir) //Sit in your seat + + var/datum/venue/attending_venue = controller.blackboard[BB_CUSTOMER_ATTENDING_VENUE] + + controller.blackboard[BB_CUSTOMER_CURRENT_ORDER] = attending_venue.order_food(customer_pawn, customer_data) + + finish_action(controller, TRUE) + +/datum/ai_behavior/wait_for_food + behavior_flags = AI_BEHAVIOR_REQUIRE_MOVEMENT | AI_BEHAVIOR_MOVE_AND_PERFORM + required_distance = 0 + +/datum/ai_behavior/wait_for_food/perform(delta_time, datum/ai_controller/controller) + . = ..() + if(controller.blackboard[BB_CUSTOMER_EATING]) + finish_action(controller, TRUE) + return + + controller.blackboard[BB_CUSTOMER_PATIENCE] -= delta_time + if(controller.blackboard[BB_CUSTOMER_PATIENCE] < 0 || controller.blackboard[BB_CUSTOMER_LEAVING]) // Check if we're leaving because sometthing mightve forced us to + finish_action(controller, FALSE) + return + + if(DT_PROB(1, delta_time)) + var/mob/living/simple_animal/robot_customer/customer_pawn = controller.pawn + var/datum/customer_data/customer_data = controller.blackboard[BB_CUSTOMER_CUSTOMERINFO] + customer_pawn.say(pick(customer_data.wait_for_food_lines)) + + if(get_turf(controller.blackboard[BB_CUSTOMER_MY_SEAT]) == get_turf(controller.pawn)) + var/obj/structure/chair/my_seat = locate(/obj/structure/chair) in get_turf(controller.pawn) + if(my_seat) + controller.pawn.setDir(my_seat.dir) //Sit in your seat + + + ///Now check if theres a meal infront of us. + var/datum/venue/attending_venue = controller.blackboard[BB_CUSTOMER_ATTENDING_VENUE] + + var/turf/infront_turf = get_step(controller.pawn, controller.pawn.dir) + for(var/obj/item/I in infront_turf.contents) + if(attending_venue.is_correct_order(I, controller.blackboard[BB_CUSTOMER_CURRENT_ORDER])) + var/datum/ai_controller/robot_customer/customer = controller + customer.eat_order(I, attending_venue) + break + + +/datum/ai_behavior/wait_for_food/finish_action(datum/ai_controller/controller, succeeded) + . = ..() + var/mob/living/simple_animal/robot_customer/customer_pawn = controller.pawn + var/datum/customer_data/customer_data = controller.blackboard[BB_CUSTOMER_CUSTOMERINFO] + controller.blackboard[BB_CUSTOMER_LEAVING] = TRUE + customer_pawn.update_icon() //They might have a special leaving accesoiry (french flag) + if(succeeded) + customer_pawn.say(pick(customer_data.leave_happy_lines)) + else + customer_pawn.say(pick(customer_data.leave_mad_lines)) + +/datum/ai_behavior/leave_venue + behavior_flags = AI_BEHAVIOR_REQUIRE_MOVEMENT + required_distance = 1 + +/datum/ai_behavior/leave_venue/perform(delta_time, datum/ai_controller/controller) + . = ..() + qdel(controller.pawn) //save the world, my final message, goodbye. + finish_action(controller, TRUE) diff --git a/code/datums/ai/robot_customer/robot_customer_controller.dm b/code/datums/ai/robot_customer/robot_customer_controller.dm new file mode 100644 index 00000000000..7f17974c171 --- /dev/null +++ b/code/datums/ai/robot_customer/robot_customer_controller.dm @@ -0,0 +1,60 @@ +/datum/ai_controller/robot_customer + ai_movement = /datum/ai_movement/basic_avoidance + movement_delay = 1 SECONDS + blackboard = list(BB_CUSTOMER_CURRENT_ORDER = null, + BB_CUSTOMER_MY_SEAT = null, + BB_CUSTOMER_PATIENCE = 999, + BB_CUSTOMER_CUSTOMERINFO = null, + BB_CUSTOMER_EATING = FALSE, + BB_CUSTOMER_LEAVING = FALSE, + BB_CUSTOMER_ATTENDING_VENUE = null) + + +/datum/ai_controller/robot_customer/TryPossessPawn(atom/new_pawn) + if(!istype(new_pawn, /mob/living/simple_animal/robot_customer)) + return AI_CONTROLLER_INCOMPATIBLE + RegisterSignal(new_pawn, COMSIG_PARENT_ATTACKBY, .proc/on_attackby) + return ..() //Run parent at end + +/datum/ai_controller/robot_customer/UnpossessPawn(destroy) + UnregisterSignal(pawn, list(COMSIG_PARENT_ATTACKBY)) + return ..() //Run parent at end + +/datum/ai_controller/robot_customer/SelectBehaviors(delta_time) + current_behaviors = list() + if(blackboard[BB_CUSTOMER_LEAVING]) + var/datum/venue/attending_venue = blackboard[BB_CUSTOMER_ATTENDING_VENUE] + current_movement_target = attending_venue.restaurant_portal + current_behaviors += GET_AI_BEHAVIOR(/datum/ai_behavior/leave_venue) + return + + var/obj/my_seat = blackboard[BB_CUSTOMER_MY_SEAT] + + if(!my_seat) //We havn't got a seat yet! find one! + current_behaviors += GET_AI_BEHAVIOR(/datum/ai_behavior/find_seat) + return + + current_movement_target = my_seat + + if(!blackboard[BB_CUSTOMER_CURRENT_ORDER]) //We havn't ordered yet even ordered yet. go on! go over there and go do it! + current_behaviors += GET_AI_BEHAVIOR(/datum/ai_behavior/order_food) + return + else + current_behaviors += GET_AI_BEHAVIOR(/datum/ai_behavior/wait_for_food) + + +/datum/ai_controller/robot_customer/proc/on_attackby(datum/source, obj/item/I, mob/user) + 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, "You hand [I] to [pawn]") + eat_order(I, attending_venue) + return COMPONENT_NO_AFTERATTACK + + +/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) + + diff --git a/code/datums/components/footstep.dm b/code/datums/components/footstep.dm index 4f51e30e173..ff9a56a5e6a 100644 --- a/code/datums/components/footstep.dm +++ b/code/datums/components/footstep.dm @@ -40,6 +40,10 @@ footstep_sounds = 'sound/effects/bang.ogg' RegisterSignal(parent, list(COMSIG_MOVABLE_MOVED), .proc/play_simplestep_machine) //Note that this doesn't get called for humans. return + if(FOOTSTEP_OBJ_ROBOT) + footstep_sounds = 'sound/effects/tank_treads.ogg' + RegisterSignal(parent, list(COMSIG_MOVABLE_MOVED), .proc/play_simplestep_machine) //Note that this doesn't get called for humans. + return RegisterSignal(parent, list(COMSIG_MOVABLE_MOVED), .proc/play_simplestep) //Note that this doesn't get called for humans. ///Prepares a footstep. Determines if it should get played. Returns the turf it should get played on. Note that it is always a /turf/open diff --git a/code/datums/elements/food/food_trash.dm b/code/datums/elements/food/food_trash.dm index dccda8caaf1..1cfd5b22de4 100644 --- a/code/datums/elements/food/food_trash.dm +++ b/code/datums/elements/food/food_trash.dm @@ -25,6 +25,7 @@ RegisterSignal(target, COMSIG_ITEM_ON_GRIND, .proc/generate_trash) RegisterSignal(target, COMSIG_ITEM_ON_JUICE, .proc/generate_trash) RegisterSignal(target, COMSIG_ITEM_ON_COMPOSTED, .proc/generate_trash) + RegisterSignal(target, COMSIG_ITEM_SOLD_TO_CUSTOMER, .proc/generate_trash) /datum/element/food_trash/Detach(datum/target) . = ..() diff --git a/code/datums/elements/food/venue_price.dm b/code/datums/elements/food/venue_price.dm new file mode 100644 index 00000000000..76016deaf3b --- /dev/null +++ b/code/datums/elements/food/venue_price.dm @@ -0,0 +1,23 @@ +///This component can be used to give something value for venues +/datum/element/venue_price + element_flags = ELEMENT_BESPOKE + id_arg_index = 2 + var/venue_price + +/datum/element/venue_price/Attach(datum/target, venue_price) + . = ..() + if(!venue_price) + 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/item_sold) + +/datum/element/venue_price/Detach(datum/target) + . = ..() + UnregisterSignal(target, COMSIG_ITEM_SOLD_TO_CUSTOMER) + +/datum/element/venue_price/proc/item_sold(datum/source, obj/item/container) + SIGNAL_HANDLER + + new /obj/item/holochip(get_turf(container), venue_price) + playsound(get_turf(container), 'sound/effects/cashregister.ogg', 60, TRUE) diff --git a/code/game/alternate_appearance.dm b/code/game/alternate_appearance.dm index 5ee152fed7c..48dffe0746c 100644 --- a/code/game/alternate_appearance.dm +++ b/code/game/alternate_appearance.dm @@ -186,3 +186,6 @@ GLOBAL_LIST_EMPTY(active_alternate_appearances) ..(key, I, FALSE) seer = M add_hud_to(seer) + + +/datum/atom_hud/alternate_appearance/basic/food_demands diff --git a/code/game/objects/items/circuitboards/machine_circuitboards.dm b/code/game/objects/items/circuitboards/machine_circuitboards.dm index c2b356f8866..37b38b302f5 100644 --- a/code/game/objects/items/circuitboards/machine_circuitboards.dm +++ b/code/game/objects/items/circuitboards/machine_circuitboards.dm @@ -1192,6 +1192,12 @@ /obj/item/stock_parts/matter_bin = 2) needs_anchored = FALSE +/obj/item/circuitboard/machine/restaurant_portal + name = "Restaurant Portal" + icon_state = "service" + build_path = /obj/machinery/restaurant_portal + needs_anchored = TRUE + /obj/item/circuitboard/machine/abductor name = "alien board (Report This)" icon_state = "abductor_mod" diff --git a/code/game/objects/items/food/_food.dm b/code/game/objects/items/food/_food.dm index 77e0fe141a6..5c21b664d10 100644 --- a/code/game/objects/items/food/_food.dm +++ b/code/game/objects/items/food/_food.dm @@ -34,6 +34,8 @@ var/junkiness ///Will this food turn into badrecipe on a grill? Don't use this for everything; preferably mostly for food that is made on a grill to begin with so it burns after some time var/burns_on_grill = FALSE + ///Price of this food if sold in a venue + var/venue_value /obj/item/food/Initialize() . = ..() @@ -43,6 +45,8 @@ tastes = string_assoc_list(tastes) if(eatverbs) eatverbs = string_list(eatverbs) + if(venue_value) + AddElement(/datum/element/venue_price, venue_value) MakeEdible() MakeProcessable() MakeLeaveTrash() diff --git a/code/game/objects/items/food/bread.dm b/code/game/objects/items/food/bread.dm index afc122f6a61..41510dba45f 100644 --- a/code/game/objects/items/food/bread.dm +++ b/code/game/objects/items/food/bread.dm @@ -30,6 +30,7 @@ tastes = list("bread" = 10) foodtypes = GRAIN w_class = WEIGHT_CLASS_SMALL + venue_value = FOOD_PRICE_CHEAP /obj/item/food/bread/plain/Initialize() . = ..() @@ -69,6 +70,8 @@ food_reagents = list(/datum/reagent/consumable/nutriment = 20, /datum/reagent/consumable/nutriment/vitamin = 10, /datum/reagent/consumable/nutriment/protein = 12) tastes = list("bread" = 10, "meat" = 10) foodtypes = GRAIN | MEAT + venue_value = FOOD_PRICE_CHEAP + /obj/item/food/bread/meat/MakeProcessable() AddElement(/datum/element/processable, TOOL_KNIFE, /obj/item/food/breadslice/meat, 5, 30) @@ -141,6 +144,7 @@ food_reagents = list(/datum/reagent/consumable/nutriment = 20, /datum/reagent/consumable/nutriment/vitamin = 10, /datum/reagent/consumable/nutriment/protein = 10) tastes = list("bread" = 10, "tofu" = 10) foodtypes = GRAIN | VEGETABLES + venue_value = FOOD_PRICE_CHEAP /obj/item/food/bread/tofu/MakeProcessable() AddElement(/datum/element/processable, TOOL_KNIFE, /obj/item/food/breadslice/tofu, 5, 30) @@ -221,6 +225,7 @@ attack_verb_simple = list("touche") tastes = list("bread" = 1) foodtypes = GRAIN + venue_value = FOOD_PRICE_CHEAP /obj/item/food/garlicbread name = "garlic bread" @@ -232,6 +237,7 @@ bite_consumption = 3 tastes = list("bread" = 1, "garlic" = 1, "butter" = 1) foodtypes = GRAIN + venue_value = FOOD_PRICE_NORMAL /obj/item/food/deepfryholder name = "Deep Fried Foods Holder Obj" @@ -317,6 +323,7 @@ tastes = list("butter" = 1, "biscuit" = 1) foodtypes = GRAIN | BREAKFAST w_class = WEIGHT_CLASS_SMALL + venue_value = FOOD_PRICE_CHEAP /obj/item/food/butterdog name = "butterdog" diff --git a/code/game/objects/items/food/burgers.dm b/code/game/objects/items/food/burgers.dm index 65e96a1a904..2e58e14a080 100644 --- a/code/game/objects/items/food/burgers.dm +++ b/code/game/objects/items/food/burgers.dm @@ -9,11 +9,12 @@ w_class = WEIGHT_CLASS_SMALL /obj/item/food/burger/plain - name = "burger" + name = "plain burger" desc = "The cornerstone of every nutritious breakfast." food_reagents = list(/datum/reagent/consumable/nutriment = 2, /datum/reagent/consumable/nutriment/protein = 6, /datum/reagent/consumable/nutriment/vitamin = 1) foodtypes = GRAIN | MEAT custom_price = PAYCHECK_ASSISTANT * 0.8 + venue_value = FOOD_PRICE_CHEAP /obj/item/food/burger/plain/Initialize() . = ..() @@ -35,6 +36,7 @@ foodtypes = MEAT | GRAIN | GROSS var/subjectname = "" var/subjectjob = null + venue_value = FOOD_PRICE_CHEAP /obj/item/food/burger/human/CheckParts(list/parts_list) ..() @@ -54,6 +56,8 @@ desc = "You monster." food_reagents = list(/datum/reagent/consumable/nutriment = 2, /datum/reagent/consumable/nutriment/protein = 6, /datum/reagent/consumable/nutriment/vitamin = 6) foodtypes = GRAIN | MEAT | GROSS + venue_value = FOOD_PRICE_EXOTIC + /obj/item/food/burger/appendix name = "appendix burger" @@ -62,6 +66,7 @@ icon_state = "appendixburger" tastes = list("bun" = 4, "grass" = 2) foodtypes = GRAIN | MEAT | GROSS + venue_value = FOOD_PRICE_NORMAL /obj/item/food/burger/fish name = "fillet -o- carp sandwich" @@ -70,6 +75,7 @@ food_reagents = list(/datum/reagent/consumable/nutriment = 3, /datum/reagent/consumable/nutriment/protein = 6, /datum/reagent/consumable/nutriment/vitamin = 4) tastes = list("bun" = 4, "fish" = 4) foodtypes = GRAIN | MEAT + venue_value = FOOD_PRICE_EXOTIC /obj/item/food/burger/tofu name = "tofu burger" @@ -78,6 +84,7 @@ food_reagents = list(/datum/reagent/consumable/nutriment = 3, /datum/reagent/consumable/nutriment/protein = 6, /datum/reagent/consumable/nutriment/vitamin = 3) tastes = list("bun" = 4, "tofu" = 4) foodtypes = GRAIN | VEGETABLES + venue_value = FOOD_PRICE_CHEAP /obj/item/food/burger/roburger name = "roburger" @@ -86,6 +93,7 @@ food_reagents = list(/datum/reagent/consumable/nutriment = 8, /datum/reagent/nanomachines = 6, /datum/reagent/consumable/nutriment/vitamin = 6) tastes = list("bun" = 4, "lettuce" = 2, "sludge" = 1) foodtypes = GRAIN | TOXIC + venue_value = FOOD_PRICE_EXOTIC /obj/item/food/burger/roburgerbig name = "roburger" @@ -103,6 +111,7 @@ food_reagents = list(/datum/reagent/consumable/nutriment = 3, /datum/reagent/consumable/nutriment/protein = 6, /datum/reagent/consumable/nutriment/vitamin = 5) tastes = list("bun" = 4, "acid" = 4) foodtypes = GRAIN | MEAT + venue_value = FOOD_PRICE_EXOTIC /obj/item/food/burger/bearger name = "bearger" @@ -110,6 +119,7 @@ icon_state = "bearger" food_reagents = list(/datum/reagent/consumable/nutriment = 3, /datum/reagent/consumable/nutriment/protein = 6, /datum/reagent/consumable/nutriment/vitamin = 5) foodtypes = GRAIN | MEAT + venue_value = FOOD_PRICE_EXOTIC /obj/item/food/burger/clown name = "clown burger" @@ -117,6 +127,7 @@ icon_state = "clownburger" food_reagents = list(/datum/reagent/consumable/nutriment = 4, /datum/reagent/consumable/nutriment/protein = 6, /datum/reagent/medicine/mannitol = 6, /datum/reagent/consumable/nutriment/vitamin = 6) foodtypes = GRAIN | FRUIT + venue_value = FOOD_PRICE_NORMAL /obj/item/food/burger/mime name = "mime burger" @@ -124,6 +135,7 @@ icon_state = "mimeburger" food_reagents = list(/datum/reagent/consumable/nutriment = 6, /datum/reagent/consumable/nutriment/protein = 9, /datum/reagent/consumable/nutriment/vitamin = 4, /datum/reagent/consumable/nothing = 6) foodtypes = GRAIN + venue_value = FOOD_PRICE_NORMAL /obj/item/food/burger/brain name = "brainburger" @@ -132,6 +144,7 @@ food_reagents = list(/datum/reagent/consumable/nutriment = 6, /datum/reagent/medicine/mannitol = 6, /datum/reagent/consumable/nutriment/vitamin = 5, /datum/reagent/consumable/nutriment/protein = 6) tastes = list("bun" = 4, "brains" = 2) foodtypes = GRAIN | MEAT | GROSS + venue_value = FOOD_PRICE_CHEAP /obj/item/food/burger/ghost name = "ghost burger" @@ -143,6 +156,7 @@ alpha = 170 verb_say = "moans" verb_yell = "wails" + venue_value = FOOD_PRICE_EXOTIC /obj/item/food/burger/ghost/Initialize() . = ..() @@ -251,6 +265,7 @@ food_reagents = list(/datum/reagent/consumable/nutriment = 6, /datum/reagent/consumable/nutriment/protein = 5, /datum/reagent/consumable/nutriment/vitamin = 10) tastes = list("bun" = 4, "magic" = 2) foodtypes = GRAIN | MEAT + venue_value = FOOD_PRICE_NORMAL /obj/item/food/burger/bigbite name = "big bite burger" @@ -259,6 +274,7 @@ food_reagents = list(/datum/reagent/consumable/nutriment = 4, /datum/reagent/consumable/nutriment/protein = 10, /datum/reagent/consumable/nutriment/vitamin = 5) w_class = WEIGHT_CLASS_NORMAL foodtypes = GRAIN | MEAT | DAIRY + venue_value = FOOD_PRICE_NORMAL /obj/item/food/burger/jelly name = "jelly burger" @@ -266,6 +282,7 @@ icon_state = "jellyburger" tastes = list("bun" = 4, "jelly" = 2) foodtypes = GRAIN | MEAT + venue_value = FOOD_PRICE_EXOTIC /obj/item/food/burger/jelly/slime food_reagents = list(/datum/reagent/consumable/nutriment = 6, /datum/reagent/toxin/slimejelly = 6, /datum/reagent/consumable/nutriment/vitamin = 6) @@ -285,6 +302,7 @@ max_volume = 100 tastes = list("bun" = 4, "type two diabetes" = 10) foodtypes = GRAIN | MEAT | DAIRY + venue_value = FOOD_PRICE_EXOTIC /obj/item/food/burger/fivealarm name = "five alarm burger" @@ -292,6 +310,7 @@ icon_state = "fivealarmburger" food_reagents = list(/datum/reagent/consumable/nutriment = 4, /datum/reagent/consumable/nutriment/protein = 6, /datum/reagent/consumable/capsaicin = 5, /datum/reagent/consumable/condensedcapsaicin = 5, /datum/reagent/consumable/nutriment/vitamin = 6) foodtypes = GRAIN | MEAT + venue_value = FOOD_PRICE_NORMAL /obj/item/food/burger/rat name = "rat burger" @@ -299,6 +318,7 @@ icon_state = "ratburger" food_reagents = list(/datum/reagent/consumable/nutriment = 3, /datum/reagent/consumable/nutriment/protein = 6, /datum/reagent/consumable/nutriment/vitamin = 2) foodtypes = GRAIN | MEAT | GROSS + venue_value = FOOD_PRICE_CHEAP /obj/item/food/burger/baseball name = "home run baseball burger" @@ -307,6 +327,7 @@ food_reagents = list(/datum/reagent/consumable/nutriment = 3, /datum/reagent/consumable/nutriment/protein = 5, /datum/reagent/consumable/nutriment/vitamin = 2) foodtypes = GRAIN | GROSS custom_price = PAYCHECK_ASSISTANT * 0.8 + venue_value = FOOD_PRICE_NORMAL /obj/item/food/burger/baconburger name = "bacon burger" @@ -316,6 +337,7 @@ tastes = list("bacon" = 4, "bun" = 2) foodtypes = GRAIN | MEAT custom_premium_price = PAYCHECK_ASSISTANT * 1.6 + venue_value = FOOD_PRICE_NORMAL /obj/item/food/burger/empoweredburger name = "empowered burger" @@ -324,6 +346,7 @@ food_reagents = list(/datum/reagent/consumable/nutriment = 5, /datum/reagent/consumable/nutriment/protein = 5, /datum/reagent/consumable/nutriment/vitamin = 1, /datum/reagent/consumable/liquidelectricity = 5) tastes = list("bun" = 2, "pure electricity" = 4) foodtypes = GRAIN | TOXIC + venue_value = FOOD_PRICE_CHEAP /obj/item/food/burger/crab name = "crab burger" @@ -332,6 +355,7 @@ food_reagents = list(/datum/reagent/consumable/nutriment = 4, /datum/reagent/consumable/nutriment/protein = 5, /datum/reagent/consumable/nutriment/vitamin = 4) tastes = list("bun" = 2, "crab meat" = 4) foodtypes = GRAIN | MEAT + venue_value = FOOD_PRICE_NORMAL /obj/item/food/burger/soylent name = "soylent burger" @@ -340,6 +364,7 @@ food_reagents = list(/datum/reagent/consumable/nutriment = 4, /datum/reagent/consumable/nutriment/protein = 6, /datum/reagent/consumable/nutriment/vitamin = 4) tastes = list("bun" = 2, "assistant" = 4) foodtypes = GRAIN | MEAT | DAIRY + venue_value = FOOD_PRICE_EXOTIC /obj/item/food/burger/rib name = "mcrib" @@ -348,6 +373,7 @@ food_reagents = list(/datum/reagent/consumable/nutriment = 2, /datum/reagent/consumable/nutriment/protein = 7, /datum/reagent/consumable/nutriment/vitamin = 4, /datum/reagent/consumable/bbqsauce = 1) tastes = list("bun" = 2, "pork patty" = 4) foodtypes = GRAIN | MEAT + venue_value = FOOD_PRICE_NORMAL /obj/item/food/burger/mcguffin name = "mcguffin" @@ -356,6 +382,7 @@ tastes = list("muffin" = 2, "bacon" = 3) food_reagents = list(/datum/reagent/consumable/nutriment = 2, /datum/reagent/consumable/eggyolk = 3, /datum/reagent/consumable/nutriment/protein = 7, /datum/reagent/consumable/nutriment/vitamin = 1) foodtypes = GRAIN | MEAT | BREAKFAST + venue_value = FOOD_PRICE_NORMAL /obj/item/food/burger/chicken name = "chicken sandwich" //Apparently the proud people of Americlapstan object to this thing being called a burger. Apparently McDonald's just calls it a burger in Europe as to not scare and confuse us. @@ -364,6 +391,7 @@ tastes = list("bun" = 2, "chicken" = 4, "God's covenant" = 1) food_reagents = list(/datum/reagent/consumable/nutriment = 3, /datum/reagent/consumable/mayonnaise = 3, /datum/reagent/consumable/nutriment/protein = 7, /datum/reagent/consumable/nutriment/vitamin = 1, /datum/reagent/consumable/cooking_oil = 2) foodtypes = GRAIN | MEAT | FRIED + venue_value = FOOD_PRICE_NORMAL /obj/item/food/burger/cheese name = "cheese burger" @@ -372,6 +400,7 @@ tastes = list("bun" = 2, "beef patty" = 4, "cheese" = 3) food_reagents = list(/datum/reagent/consumable/nutriment = 3, /datum/reagent/consumable/nutriment/protein = 7, /datum/reagent/consumable/nutriment/vitamin = 2) foodtypes = GRAIN | MEAT | DAIRY + venue_value = FOOD_PRICE_CHEAP /obj/item/food/burger/cheese/Initialize() . = ..() diff --git a/code/game/objects/items/food/cake.dm b/code/game/objects/items/food/cake.dm index fffd8713c0d..a1b9a3225eb 100644 --- a/code/game/objects/items/food/cake.dm +++ b/code/game/objects/items/food/cake.dm @@ -43,6 +43,8 @@ food_reagents = list(/datum/reagent/consumable/nutriment = 20, /datum/reagent/medicine/oculine = 10, /datum/reagent/consumable/nutriment/vitamin = 5) tastes = list("cake" = 5, "sweetness" = 2, "carrot" = 1) foodtypes = GRAIN | DAIRY | VEGETABLES | SUGAR + venue_value = FOOD_PRICE_CHEAP + /obj/item/food/cake/carrot/MakeProcessable() AddElement(/datum/element/processable, TOOL_KNIFE, /obj/item/food/cakeslice/carrot, 5, 30) @@ -81,6 +83,8 @@ food_reagents = list(/datum/reagent/consumable/nutriment = 20, /datum/reagent/consumable/nutriment/vitamin = 8, /datum/reagent/consumable/nutriment/protein = 5) tastes = list("cake" = 4, "cream cheese" = 3) foodtypes = GRAIN | DAIRY + venue_value = FOOD_PRICE_CHEAP + /obj/item/food/cake/cheese/MakeProcessable() AddElement(/datum/element/processable, TOOL_KNIFE, /obj/item/food/cakeslice/cheese, 5, 30) @@ -100,6 +104,7 @@ food_reagents = list(/datum/reagent/consumable/nutriment = 20, /datum/reagent/consumable/nutriment/vitamin = 10) tastes = list("cake" = 5, "sweetness" = 2, "oranges" = 2) foodtypes = GRAIN | DAIRY | FRUIT | SUGAR + venue_value = FOOD_PRICE_CHEAP /obj/item/food/cake/orange/MakeProcessable() AddElement(/datum/element/processable, TOOL_KNIFE, /obj/item/food/cakeslice/orange, 5, 30) @@ -118,6 +123,7 @@ food_reagents = list(/datum/reagent/consumable/nutriment = 20, /datum/reagent/consumable/nutriment/vitamin = 10) tastes = list("cake" = 5, "sweetness" = 2, "unbearable sourness" = 2) foodtypes = GRAIN | DAIRY | FRUIT | SUGAR + venue_value = FOOD_PRICE_CHEAP /obj/item/food/cake/lime/MakeProcessable() AddElement(/datum/element/processable, TOOL_KNIFE, /obj/item/food/cakeslice/lime, 5, 30) @@ -136,6 +142,7 @@ food_reagents = list(/datum/reagent/consumable/nutriment = 20, /datum/reagent/consumable/nutriment/vitamin = 10) tastes = list("cake" = 5, "sweetness" = 2, "sourness" = 2) foodtypes = GRAIN | DAIRY | FRUIT | SUGAR + venue_value = FOOD_PRICE_CHEAP /obj/item/food/cake/lemon/MakeProcessable() AddElement(/datum/element/processable, TOOL_KNIFE, /obj/item/food/cakeslice/lemon, 5, 30) @@ -154,6 +161,7 @@ food_reagents = list(/datum/reagent/consumable/nutriment = 20, /datum/reagent/consumable/nutriment/vitamin = 10) tastes = list("cake" = 5, "sweetness" = 1, "chocolate" = 4) foodtypes = GRAIN | DAIRY | JUNKFOOD | SUGAR + venue_value = FOOD_PRICE_CHEAP /obj/item/food/cake/chocolate/MakeProcessable() AddElement(/datum/element/processable, TOOL_KNIFE, /obj/item/food/cakeslice/chocolate, 5, 30) @@ -243,6 +251,7 @@ food_reagents = list(/datum/reagent/consumable/nutriment = 20, /datum/reagent/consumable/nutriment/vitamin = 10) tastes = list("cake" = 5, "sweetness" = 1, "apple" = 1) foodtypes = GRAIN | DAIRY | FRUIT | SUGAR + venue_value = FOOD_PRICE_CHEAP /obj/item/food/cake/apple/MakeProcessable() AddElement(/datum/element/processable, TOOL_KNIFE, /obj/item/food/cakeslice/apple, 5, 30) @@ -279,6 +288,7 @@ food_reagents = list(/datum/reagent/consumable/nutriment = 20, /datum/reagent/consumable/nutriment/vitamin = 5) tastes = list("cake" = 5, "sweetness" = 1, "pumpkin" = 1) foodtypes = GRAIN | DAIRY | VEGETABLES | SUGAR + venue_value = FOOD_PRICE_CHEAP /obj/item/food/cake/pumpkinspice/MakeProcessable() AddElement(/datum/element/processable, TOOL_KNIFE, /obj/item/food/cakeslice/pumpkinspice, 5, 30) @@ -351,6 +361,7 @@ food_reagents = list(/datum/reagent/consumable/nutriment = 60, /datum/reagent/consumable/nutriment/vitamin = 5) tastes = list("cake" = 5, "sweetness" = 1, "batter" = 1) foodtypes = GRAIN | DAIRY | SUGAR | JUNKFOOD + venue_value = FOOD_PRICE_CHEAP /obj/item/food/cake/pound_cake/MakeProcessable() AddElement(/datum/element/processable, TOOL_KNIFE, /obj/item/food/cakeslice/pound_cake_slice, 7, 30) diff --git a/code/game/objects/items/food/egg.dm b/code/game/objects/items/food/egg.dm index f3534674ca5..a48a584cf83 100644 --- a/code/game/objects/items/food/egg.dm +++ b/code/game/objects/items/food/egg.dm @@ -113,6 +113,7 @@ w_class = WEIGHT_CLASS_SMALL tastes = list("egg" = 1, "cheese" = 1) foodtypes = MEAT | BREAKFAST | DAIRY + venue_value = FOOD_PRICE_CHEAP /obj/item/food/omelette/attackby(obj/item/W, mob/user, params) if(istype(W, /obj/item/kitchen/fork)) diff --git a/code/game/objects/items/food/meat.dm b/code/game/objects/items/food/meat.dm index 2bce1d3d662..65cea9a6e97 100644 --- a/code/game/objects/items/food/meat.dm +++ b/code/game/objects/items/food/meat.dm @@ -52,6 +52,7 @@ tastes = list("fish" = 1, "breadcrumbs" = 1) foodtypes = MEAT w_class = WEIGHT_CLASS_SMALL + venue_value = FOOD_PRICE_EXOTIC /obj/item/food/fishandchips name = "fish and chips" @@ -60,6 +61,7 @@ food_reagents = list(/datum/reagent/consumable/nutriment = 3, /datum/reagent/consumable/nutriment/protein = 5, /datum/reagent/consumable/nutriment/vitamin = 2) tastes = list("fish" = 1, "chips" = 1) foodtypes = MEAT | VEGETABLES | FRIED + venue_value = FOOD_PRICE_EXOTIC /obj/item/food/fishfry name = "fish fry" @@ -118,6 +120,7 @@ tastes = list("meat" = 1, "salmon" = 1) foodtypes = MEAT | ALCOHOL w_class = WEIGHT_CLASS_SMALL + venue_value = FOOD_PRICE_EXOTIC /obj/item/food/raw_meatball name = "raw meatball" @@ -169,6 +172,7 @@ foodtypes = MEAT w_class = WEIGHT_CLASS_SMALL burns_on_grill = TRUE + venue_value = FOOD_PRICE_CHEAP /obj/item/food/meatball/human name = "strange meatball" @@ -281,6 +285,7 @@ var/roasted = FALSE w_class = WEIGHT_CLASS_SMALL burns_on_grill = TRUE + venue_value = FOOD_PRICE_CHEAP /obj/item/food/sausage/MakeProcessable() AddElement(/datum/element/processable, TOOL_KNIFE, /obj/item/food/salami, 6, 30) @@ -450,6 +455,7 @@ tastes = list("\"chicken\"" = 1) foodtypes = MEAT w_class = WEIGHT_CLASS_TINY + venue_value = FOOD_PRICE_CHEAP /obj/item/food/nugget/Initialize() . = ..() @@ -511,6 +517,7 @@ food_reagents = list(/datum/reagent/consumable/nutriment/protein = 16, /datum/reagent/consumable/nutriment/vitamin = 6) tastes = list("tender meat" = 3, "metal" = 1) foodtypes = MEAT | GROSS + venue_value = FOOD_PRICE_CHEAP /obj/item/food/kebab/monkey name = "meat-kebab" @@ -518,6 +525,7 @@ food_reagents = list(/datum/reagent/consumable/nutriment/protein = 16, /datum/reagent/consumable/nutriment/vitamin = 2) tastes = list("meat" = 3, "metal" = 1) foodtypes = MEAT + venue_value = FOOD_PRICE_CHEAP /obj/item/food/kebab/tofu name = "tofu-kebab" @@ -525,6 +533,7 @@ food_reagents = list(/datum/reagent/consumable/nutriment/protein = 15) tastes = list("tofu" = 3, "metal" = 1) foodtypes = VEGETABLES + venue_value = FOOD_PRICE_CHEAP /obj/item/food/kebab/tail name = "lizard-tail kebab" @@ -541,6 +550,7 @@ food_reagents = list(/datum/reagent/consumable/nutriment/protein = 10, /datum/reagent/consumable/nutriment/vitamin = 2) tastes = list("rat meat" = 1, "metal" = 1) foodtypes = MEAT | GROSS + venue_value = FOOD_PRICE_CHEAP /obj/item/food/kebab/rat/double name = "double rat-kebab" diff --git a/code/game/objects/items/food/misc.dm b/code/game/objects/items/food/misc.dm index 5ebd68d9d84..d86d56f9cc6 100644 --- a/code/game/objects/items/food/misc.dm +++ b/code/game/objects/items/food/misc.dm @@ -23,7 +23,7 @@ icon_state = "royalcheese" food_reagents = list(/datum/reagent/consumable/nutriment = 15, /datum/reagent/consumable/nutriment/vitamin = 5, /datum/reagent/gold = 20, /datum/reagent/toxin/mutagen = 5) w_class = WEIGHT_CLASS_BULKY - tastes = list("cheese" = 4, "royalty" = 1) + tastes = list("cheese" = 4, "royalty" = 1) rat_heal = 70 /obj/item/food/cheese @@ -120,6 +120,7 @@ tastes = list("fries" = 3, "salt" = 1) foodtypes = VEGETABLES | GRAIN | FRIED w_class = WEIGHT_CLASS_SMALL + venue_value = FOOD_PRICE_CHEAP /obj/item/food/fries/Initialize() . = ..() @@ -157,6 +158,7 @@ tastes = list("fries" = 3, "cheese" = 1) foodtypes = VEGETABLES | GRAIN | DAIRY w_class = WEIGHT_CLASS_SMALL + venue_value = FOOD_PRICE_CHEAP /obj/item/food/cheesyfries/Initialize() . = ..() @@ -762,6 +764,7 @@ w_class = WEIGHT_CLASS_SMALL tastes = list("cream cheese" = 4, "crab" = 3, "crispiness" = 2) foodtypes = MEAT | DAIRY | GRAIN + venue_value = FOOD_PRICE_CHEAP /obj/item/food/cornchips name = "boritos corn chips" diff --git a/code/game/objects/items/food/pastries.dm b/code/game/objects/items/food/pastries.dm index 81a4a21ece1..09f1cc1ba16 100644 --- a/code/game/objects/items/food/pastries.dm +++ b/code/game/objects/items/food/pastries.dm @@ -612,6 +612,7 @@ tastes = list("bun" = 3, "meat" = 2) foodtypes = GRAIN | MEAT | VEGETABLES w_class = WEIGHT_CLASS_SMALL + venue_value = FOOD_PRICE_CHEAP /obj/item/food/hotdog/debug eat_time = 0 @@ -711,6 +712,7 @@ foodtypes = GRAIN | SUGAR | BREAKFAST w_class = WEIGHT_CLASS_SMALL burns_on_grill = TRUE + venue_value = FOOD_PRICE_CHEAP /obj/item/food/pancakes/raw name = "goopy pancake" diff --git a/code/game/objects/items/food/pie.dm b/code/game/objects/items/food/pie.dm index 2b4fbe51b54..1636921a233 100644 --- a/code/game/objects/items/food/pie.dm +++ b/code/game/objects/items/food/pie.dm @@ -7,6 +7,7 @@ food_reagents = list(/datum/reagent/consumable/nutriment = 10, /datum/reagent/consumable/nutriment/vitamin = 2) tastes = list("pie" = 1) foodtypes = GRAIN + venue_value = FOOD_PRICE_NORMAL /obj/item/food/pieslice name = "pie slice" @@ -68,6 +69,7 @@ food_reagents = list(/datum/reagent/consumable/nutriment = 11, /datum/reagent/consumable/berryjuice = 5, /datum/reagent/consumable/nutriment/vitamin = 4) tastes = list("pie" = 1, "blackberries" = 1) foodtypes = GRAIN | FRUIT | SUGAR + venue_value = FOOD_PRICE_NORMAL /obj/item/food/pie/bearypie name = "beary pie" diff --git a/code/game/objects/items/food/pizza.dm b/code/game/objects/items/food/pizza.dm index 6072923b769..c5487432916 100644 --- a/code/game/objects/items/food/pizza.dm +++ b/code/game/objects/items/food/pizza.dm @@ -6,6 +6,7 @@ food_reagents = list(/datum/reagent/consumable/nutriment = 28, /datum/reagent/consumable/nutriment/protein = 3, /datum/reagent/consumable/tomatojuice = 6, /datum/reagent/consumable/nutriment/vitamin = 5) tastes = list("crust" = 1, "tomato" = 1, "cheese" = 1) foodtypes = GRAIN | DAIRY | VEGETABLES + venue_value = FOOD_PRICE_CHEAP /// type is spawned 6 at a time and replaces this pizza when processed by cutting tool var/obj/item/food/pizzaslice/slice_type ///What label pizza boxes use if this pizza spawns in them. @@ -99,6 +100,7 @@ foodtypes = GRAIN | VEGETABLES | DAIRY slice_type = /obj/item/food/pizzaslice/vegetable boxtag = "Gourmet Vegetable" + venue_value = FOOD_PRICE_NORMAL /obj/item/food/pizzaslice/vegetable name = "vegetable pizza slice" diff --git a/code/game/objects/items/food/salad.dm b/code/game/objects/items/food/salad.dm index e1c2519d88d..90b04b25f5d 100644 --- a/code/game/objects/items/food/salad.dm +++ b/code/game/objects/items/food/salad.dm @@ -9,6 +9,7 @@ tastes = list("leaves" = 1) foodtypes = VEGETABLES eatverbs = list("devour","nibble","gnaw","gobble","chomp") //who the fuck gnaws and devours on a salad + venue_value = FOOD_PRICE_NORMAL /obj/item/food/salad/aesirsalad name = "\improper Aesir salad" diff --git a/code/game/objects/items/food/soup.dm b/code/game/objects/items/food/soup.dm index e48ebd0261c..b93129d336e 100644 --- a/code/game/objects/items/food/soup.dm +++ b/code/game/objects/items/food/soup.dm @@ -8,6 +8,7 @@ tastes = list("tasteless soup" = 1) foodtypes = VEGETABLES eatverbs = list("slurp","sip","inhale","drink") + venue_value = FOOD_PRICE_CHEAP /obj/item/food/soup/wish name = "wish soup" @@ -31,6 +32,7 @@ food_reagents = list(/datum/reagent/consumable/nutriment = 6, /datum/reagent/consumable/nutriment/protein = 6, /datum/reagent/consumable/nutriment/vitamin = 8, /datum/reagent/water = 5) tastes = list("meat" = 1) foodtypes = MEAT + venue_value = FOOD_PRICE_NORMAL /obj/item/food/soup/slime name = "slime soup" @@ -39,6 +41,7 @@ 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" @@ -72,6 +75,7 @@ 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" @@ -80,6 +84,7 @@ 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" @@ -102,7 +107,7 @@ 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!" @@ -126,6 +131,7 @@ 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" @@ -207,7 +213,7 @@ 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." @@ -231,6 +237,7 @@ 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" diff --git a/code/game/objects/items/food/spaghetti.dm b/code/game/objects/items/food/spaghetti.dm index e47e9775db7..525b7b7a5f1 100644 --- a/code/game/objects/items/food/spaghetti.dm +++ b/code/game/objects/items/food/spaghetti.dm @@ -8,6 +8,7 @@ microwaved_type = /obj/item/food/spaghetti/boiledspaghetti tastes = list("pasta" = 1) foodtypes = GRAIN + venue_value = FOOD_PRICE_CHEAP /obj/item/food/spaghetti/Initialize() . = ..() diff --git a/code/game/objects/items/holosign_creator.dm b/code/game/objects/items/holosign_creator.dm index 037316a108f..9dc243b69b2 100644 --- a/code/game/objects/items/holosign_creator.dm +++ b/code/game/objects/items/holosign_creator.dm @@ -20,6 +20,8 @@ /obj/item/holosign_creator/examine(mob/user) . = ..() + if(!signs) + return . += "It is currently maintaining [signs.len]/[max_signs] projections." /obj/item/holosign_creator/afterattack(atom/target, mob/user, proximity_flag) @@ -65,6 +67,13 @@ qdel(H) to_chat(user, "You clear all active holograms.") +/obj/item/holosign_creator/Destroy() + . = ..() + if(LAZYLEN(signs)) + for(var/H in signs) + qdel(H) + + /obj/item/holosign_creator/janibarrier name = "custodial holobarrier projector" desc = "A holographic projector that creates hard light wet floor barriers." diff --git a/code/game/objects/structures/holosign.dm b/code/game/objects/structures/holosign.dm index 1e8961819d7..f769d657330 100644 --- a/code/game/objects/structures/holosign.dm +++ b/code/game/objects/structures/holosign.dm @@ -8,11 +8,13 @@ max_integrity = 1 armor = list(MELEE = 0, BULLET = 50, LASER = 50, ENERGY = 50, BOMB = 0, BIO = 0, RAD = 0, FIRE = 20, ACID = 20) var/obj/item/holosign_creator/projector + var/use_vis_overlay = TRUE /obj/structure/holosign/Initialize(loc, source_projector) . = ..() - alpha = 0 - SSvis_overlays.add_vis_overlay(src, icon, icon_state, ABOVE_MOB_LAYER, plane, dir, add_appearance_flags = RESET_ALPHA) //you see mobs under it, but you hit them like they are above it + if(use_vis_overlay) + alpha = 0 + SSvis_overlays.add_vis_overlay(src, icon, icon_state, ABOVE_MOB_LAYER, plane, dir, add_appearance_flags = RESET_ALPHA) //you see mobs under it, but you hit them like they are above it if(source_projector) projector = source_projector LAZYADD(projector.signs, src) @@ -27,6 +29,9 @@ . = ..() if(.) return + attack_holosign(user, modifiers) + +/obj/structure/holosign/proc/attack_holosign(mob/living/user, list/modifiers) user.do_attack_animation(src, ATTACK_EFFECT_PUNCH) user.changeNext_move(CLICK_CD_MELEE) take_damage(5 , BRUTE, MELEE, 1) diff --git a/code/modules/food_and_drinks/recipes/tablecraft/recipes_burger.dm b/code/modules/food_and_drinks/recipes/tablecraft/recipes_burger.dm index dfffb5a68a3..84e6cb64a99 100644 --- a/code/modules/food_and_drinks/recipes/tablecraft/recipes_burger.dm +++ b/code/modules/food_and_drinks/recipes/tablecraft/recipes_burger.dm @@ -17,7 +17,7 @@ subcategory = CAT_BURGER /datum/crafting_recipe/food/burger - name = "Burger" + name = "Plain Burger" reqs = list( /obj/item/food/patty/plain = 1, /obj/item/food/bun = 1 diff --git a/code/modules/food_and_drinks/restaurant/_venue.dm b/code/modules/food_and_drinks/restaurant/_venue.dm new file mode 100644 index 00000000000..52686e4f074 --- /dev/null +++ b/code/modules/food_and_drinks/restaurant/_venue.dm @@ -0,0 +1,188 @@ +///Represents the abstract concept of a food venue in the code. +/datum/venue + ///Name of the venue, also used for the icon state of any radials it can be selected in + var/name = "unnamed venue" + ///Max amount of guests at any time + var/max_guests = 6 + ///Weighted list of customer types + var/list/customer_types = list(/datum/customer_data/american = 5, /datum/customer_data/italian = 3, /datum/customer_data/french = 3) + ///Is the venue open at the moment? + var/open + ///Portal linked to this venue at the moment + var/obj/machinery/restaurant_portal/restaurant_portal + ///Lists the current visitors of a venue + var/list/current_visitors = list() + ///Cooldown for next guest to arrive + COOLDOWN_DECLARE(visit_cooldown) + ///Min time between new visits + var/min_time_between_visitor = 60 SECONDS + ///Max time between new visits + var/max_time_between_visitor = 90 SECONDS + ///Required access to mess with the venue + var/req_access = ACCESS_KITCHEN + + +/datum/venue/process(delta_time) + if(!COOLDOWN_FINISHED(src, visit_cooldown)) + return + COOLDOWN_START(src, visit_cooldown, rand(min_time_between_visitor, max_time_between_visitor)) + if(current_visitors.len < max_guests) + create_new_customer() + +///Spawns a new customer at the portal +/datum/venue/proc/create_new_customer() + var/mob/living/simple_animal/robot_customer/new_customer = new /mob/living/simple_animal/robot_customer(get_turf(restaurant_portal), pickweight(customer_types), src) + current_visitors += new_customer + +/datum/venue/proc/order_food(mob/living/simple_animal/robot_customer/customer_pawn, datum/customer_data/customer_data) + return + +///Checks if the object used is correct for the venue +/datum/venue/proc/is_correct_order(atom/movable/object_used, wanted_item) + return FALSE + +///The line the robot says when ordering +/datum/venue/proc/order_food_line(order) + return "broken venue pls call a coder" + +///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, order_item) + +///Toggles whether the venue is open or not +/datum/venue/proc/toggle_open() + if(open) + close() + else + open() + +/datum/venue/proc/open() + open = TRUE + restaurant_portal.update_icon() + COOLDOWN_START(src, visit_cooldown, 10 SECONDS) //First one comes faster + START_PROCESSING(SSobj, src) + +/datum/venue/proc/close() + open = FALSE + restaurant_portal.update_icon() + STOP_PROCESSING(SSobj, src) + for(var/mob/living/simple_animal/robot_customer as anything in current_visitors) + robot_customer.ai_controller.blackboard[BB_CUSTOMER_LEAVING] = TRUE //LEAVEEEEEE + +/obj/machinery/restaurant_portal + name = "restaurant portal" + desc = "A robot-only gate into the wonders of Space Station cuisine!" + icon = 'icons/obj/machines/restaurant_portal.dmi' + icon_state = "portal" + density = TRUE + use_power = IDLE_POWER_USE + idle_power_usage = 10 + active_power_usage = 100 + circuit = /obj/item/circuitboard/machine/restaurant_portal + + layer = BELOW_OBJ_LAYER + density = FALSE + anchored = TRUE + resistance_flags = INDESTRUCTIBLE | FIRE_PROOF | UNACIDABLE | ACID_PROOF + ///What venue is this portal for? Uses a typepath which is turned into an instance on Initialize + var/datum/venue/linked_venue = /datum/venue + + +/obj/machinery/restaurant_portal/Initialize() + . = ..() + if(linked_venue) + linked_venue = SSrestaurant.all_venues[linked_venue] + linked_venue.restaurant_portal = src + +/obj/machinery/restaurant_portal/Destroy() + . = ..() + +/obj/machinery/restaurant_portal/update_overlays() + . = ..() + if(!linked_venue.open) //Any open venues + . += mutable_appearance(icon, "portal_door") + +/obj/machinery/restaurant_portal/attack_hand(mob/living/user) + var/obj/item/card/id/used_id = user.get_idcard(TRUE) + + if(!used_id) + return ..() + + if(!(linked_venue.req_access in used_id.GetAccess())) + to_chat(user, "This card lacks the access to change this venues status.") + return + + linked_venue.toggle_open() + update_icon() + +/obj/machinery/restaurant_portal/attacked_by(obj/item/I, mob/living/user) + if(!istype(I, /obj/item/card/id)) + return ..() + + var/obj/item/card/id/used_id = I + + if(!(linked_venue.req_access in used_id.GetAccess())) + to_chat(user, "This card lacks the access to change this venues status.") + return + + var/list/radial_items = list() + var/list/radial_results = list() + + for(var/type_key in SSrestaurant.all_venues) + var/datum/venue/venue = SSrestaurant.all_venues[type_key] + radial_items[venue.name] = image('icons/obj/machines/restaurant_portal.dmi', venue.name) + radial_results[venue.name] = venue + + var/choice = show_radial_menu(user, src, radial_items, null, require_near = TRUE) + + if(!choice) + return + + var/datum/venue/chosen_venue = radial_results[choice] + + + + if(!(chosen_venue.req_access in used_id.GetAccess())) + to_chat(user, "This card lacks the access to change this venues status.") + return + + to_chat(user, "You change the portal's linked venue.") + + if(linked_venue && linked_venue.restaurant_portal) //We're already linked, unlink us. + if(linked_venue.open) + linked_venue.close() + linked_venue.restaurant_portal.linked_venue = null + + linked_venue = chosen_venue + linked_venue.restaurant_portal = src + + +/obj/item/holosign_creator/robot_seat + name = "seating indicator placer" + creation_time = 1 SECONDS + holosign_type = /obj/structure/holosign/robot_seat + desc = "Use this to place seats for your restaurant guests!" + resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF + +/obj/item/holosign_creator/robot_seat/attack_self(mob/user) + return +/obj/structure/holosign/robot_seat + density = FALSE + desc = "Used to indicate a place to sit for a robot tourist. I better be careful." + icon = 'icons/effects/effects.dmi' + icon_state = "eating_zone" + layer = BELOW_MOB_LAYER + use_vis_overlay = FALSE + var/datum/venue/linked_venue = /datum/venue + +/obj/structure/holosign/robot_seat/Initialize(loc, source_projector) + . = ..() + linked_venue = SSrestaurant.all_venues[linked_venue] + +/obj/structure/holosign/robot_seat/attack_holosign(mob/living/user, list/modifiers) + return + +/obj/structure/holosign/robot_seat/attacked_by(obj/item/I, mob/living/user) + . = ..() + if(I.type == projector?.type && !SSrestaurant.claimed_seats[src]) + qdel(src) diff --git a/code/modules/food_and_drinks/restaurant/customers/_customer.dm b/code/modules/food_and_drinks/restaurant/customers/_customer.dm new file mode 100644 index 00000000000..a714d7657eb --- /dev/null +++ b/code/modules/food_and_drinks/restaurant/customers/_customer.dm @@ -0,0 +1,86 @@ +/datum/customer_data + ///Name of the robot's origin + var/nationality = "Generic" + ///The types of food this robot likes in a assoc list of venue type | weighted list. does NOT include subtypes. + var/list/orderable_objects = list() + ///The amount a robot pays for each food he likes in an assoc list type | payment + var/list/order_prices = list() + ///Datum AI used for the robot. Should almost never be overwritten unless theyre subtypes of ai_controller/robot_customer + var/datum/ai_controller/ai_controller_used = /datum/ai_controller/robot_customer + ///Patience of the AI, how long they will wait for their meal. + var/total_patience = 600 SECONDS + ///Lines the robot says when it finds a seat + var/list/found_seat_lines = list("I found a seat") + ///Lines the robot says when it can't find a seat + var/list/cant_find_seat_lines = list("I did not find a seat") + ///Lines the robot says when leaving without food + var/list/leave_mad_lines = list("Leaving without food") + ///Lines the robot says when leaving with food + var/list/leave_happy_lines = list("Leaving with food") + ///Lines the robot says when leaving waiting for food + var/list/wait_for_food_lines = list("I'm still waiting for food") + ///Clothing sets to pick from when dressing the robot. + var/list/clothing_sets = list("amerifat_clothes") + ///List of prefixes for our robots name + var/list/name_prefixes + ///Prefix file to uise + var/prefix_file = "strings/names/american_prefix.txt" + ///Base icon for the customer + var/base_icon = "amerifat" + +/datum/customer_data/New() + . = ..() + name_prefixes = world.file2list(prefix_file) + +/datum/customer_data/proc/get_overlays(mob/living/simple_animal/robot_customer/customer) + return + +/datum/customer_data/american + nationality = "Space-American" + orderable_objects = list( + /datum/venue/restaurant = list(/obj/item/food/burger/plain = 25, /obj/item/food/burger/cheese = 15, /obj/item/food/burger/superbite = 1, /obj/item/food/fries = 10, /obj/item/food/cheesyfries = 6, /obj/item/food/pie/applepie = 4, /obj/item/food/pie/pumpkinpie = 2, /obj/item/food/hotdog = 8, /obj/item/food/pizza/pineapple = 1, /obj/item/food/burger/baconburger = 10, /obj/item/food/pancakes = 4), + /datum/venue/bar = list(/datum/reagent/consumable/ethanol/b52 = 6, /datum/reagent/consumable/ethanol/manhattan = 3, /datum/reagent/consumable/ethanol/atomicbomb = 1, /datum/reagent/consumable/ethanol/beer = 25)) + + + found_seat_lines = list("I hope there's a seat that supports my weight.", "I hope I can bring my gun in here.", "I hope they have the triple deluxe fatty burger.", "I just love the culture here.") + cant_find_seat_lines = list("I'm so tired from standing...", "I have chronic back pain, please hurry up and get me a seat!", "I'm not going to tip if I don't get a seat.") + leave_mad_lines = list("NO TIP FOR YOU. GOODBYE!", "At least at SpaceDonalds they serve their food FAST!", "This venue is horrendous!", "I will speak to your manager!", "I'll be sure to leave a bad Yelp review.") + leave_happy_lines = list("An extra tip for you my friend.", "Thanks for the great food!", "Diabetes is a myth anyway!") + wait_for_food_lines = list("Listen buddy, I'm getting real impatient over here!", "I've been waiting for ages...") + + +/datum/customer_data/italian + nationality = "Space-Italian" + prefix_file = "strings/names/italian_prefix.txt" + base_icon = "italian" + clothing_sets = list("italian_pison", "italian_godfather") + + found_seat_lines = list("What a wonderful place to sit.", "I hope they serve it like-a my momma used to make it.") + cant_find_seat_lines = list("Mamma mia! I just want a seat!", "Why-a you making me stand here?") + leave_mad_lines = list("I have-a not seen-a this much disrespect in years!", "What-a horrendous establishment!") + leave_happy_lines = list("That's amoreee!", "Just like momma used to make it!") + wait_for_food_lines = list("I'ma so hungry...") + orderable_objects = list( + /datum/venue/restaurant = list(/obj/item/food/spaghetti/pastatomato = 20, /obj/item/food/spaghetti/copypasta = 6, /obj/item/food/spaghetti/meatballspaghetti = 4, /obj/item/food/pizza/vegetable = 2, /obj/item/food/pizza/mushroom = 2, /obj/item/food/pizza/meat = 2, /obj/item/food/pizza/margherita = 2), + /datum/venue/bar = list(/datum/reagent/consumable/ethanol/fanciulli = 5, /datum/reagent/consumable/ethanol/branca_menta = 3, /datum/reagent/consumable/ethanol/beer = 10, /datum/reagent/consumable/lemonade = 8, /datum/reagent/consumable/ethanol/godfather = 5)) + + +/datum/customer_data/french + nationality = "Space-French" + prefix_file = "strings/names/french_prefix.txt" + base_icon = "french" + clothing_sets = list("french_fit") + found_seat_lines = list("Hon hon hon", "It's not the Eiffel tower but it will do.", "Yuck, I guess this will make do.") + cant_find_seat_lines = list("Making someone like me stand? How dare you.", "What a filthy lobby!") + leave_mad_lines = list("Sacre bleu!", "Merde! This place is shittier than the Rhine!") + leave_happy_lines = list("Hon hon hon.", "A good effort.") + wait_for_food_lines = list("Hon hon hon") + orderable_objects = list( + /datum/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/venue/bar = list(/datum/reagent/consumable/ethanol/champagne = 15, /datum/reagent/consumable/ethanol/mojito = 5, /datum/reagent/consumable/ethanol/sidecar = 5, /datum/reagent/consumable/ethanol/between_the_sheets = 4, /datum/reagent/consumable/ethanol/beer = 10)) + +/datum/customer_data/french/get_overlays(mob/living/simple_animal/robot_customer/customer) + if(customer.ai_controller.blackboard[BB_CUSTOMER_LEAVING]) + var/mutable_appearance/flag = mutable_appearance(customer.icon, "french_flag") + flag.appearance_flags = RESET_COLOR + return flag diff --git a/code/modules/food_and_drinks/restaurant/generic_venues.dm b/code/modules/food_and_drinks/restaurant/generic_venues.dm new file mode 100644 index 00000000000..d319d269a84 --- /dev/null +++ b/code/modules/food_and_drinks/restaurant/generic_venues.dm @@ -0,0 +1,119 @@ +/////RESTAURANT///// +/datum/venue/restaurant + name = "restaurant" + req_access = ACCESS_KITCHEN + +/datum/venue/restaurant/order_food(mob/living/simple_animal/robot_customer/customer_pawn, datum/customer_data/customer_data) + var/obj/item/object_to_order = pickweight(customer_data.orderable_objects[type]) //Get what object we are ordering + + . = object_to_order + + customer_pawn.say(order_food_line(object_to_order)) + + var/appearance = SSrestaurant.food_appearance_cache[object_to_order] + + if(!appearance) //We havn't made this one before, do so now. + var/obj/item/temp_object = new object_to_order() //Make a temp object so we can see it including any overlays + appearance = temp_object.appearance //And then steal its appearance + SSrestaurant.food_appearance_cache[object_to_order] = appearance //and cache it for future orders + qdel(temp_object) + + var/image/I = image(icon = 'icons/obj/machines/restaurant_portal.dmi' , icon_state = "thought_bubble", loc = customer_pawn, layer = HUD_LAYER) + + I.appearance = appearance + I.underlays += mutable_appearance(icon = 'icons/obj/machines/restaurant_portal.dmi' , icon_state = "thought_bubble") + I.pixel_y = 32 + I.pixel_x = 16 + I.plane = HUD_PLANE + I.appearance_flags = RESET_COLOR + customer_pawn.hud_to_show_on_hover = customer_pawn.add_alt_appearance(/datum/atom_hud/alternate_appearance/basic/food_demands, "food_thoughts", I) + +/datum/venue/restaurant/is_correct_order(atom/movable/object_used, wanted_item) + return object_used.type == wanted_item + +/datum/venue/restaurant/order_food_line(obj/item/order) + return "I'll take \a [initial(order.name)]" + +/datum/venue/restaurant/on_get_order(mob/living/simple_animal/robot_customer/customer_pawn, obj/item/order_item) + . = ..() + customer_pawn.visible_message("[customer_pawn] pushes [order_item] into their mouth-shaped hole!", "You push [order_item] into your mouth-shaped hole.") + playsound(get_turf(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 + +/obj/structure/holosign/robot_seat/restaurant + name = "restaurant seating" + linked_venue = /datum/venue/restaurant + + + + +/////BAR///// +/datum/venue/bar + name = "bar" + req_access = ACCESS_BAR + min_time_between_visitor = 40 SECONDS + max_time_between_visitor = 60 SECONDS + +/datum/venue/bar/order_food(mob/living/simple_animal/robot_customer/customer_pawn, datum/customer_data/customer_data) + var/datum/reagent/reagent_to_order = pickweight(customer_data.orderable_objects[type]) + + var/glass_visual + + if(initial(reagent_to_order.glass_icon_state)) + glass_visual = initial(reagent_to_order.glass_icon_state) + else if(initial(reagent_to_order.shot_glass_icon_state)) + glass_visual = initial(reagent_to_order.shot_glass_icon_state) + else if(initial(reagent_to_order.fallback_icon_state)) + glass_visual = initial(reagent_to_order.fallback_icon_state) + else + CRASH("[reagent_to_order] has no icon sprite for restaurant code, please set a fallback_icon_state for this reagent.") + + customer_pawn.say(order_food_line(reagent_to_order)) + + var/image/I = image(icon = 'icons/obj/machines/restaurant_portal.dmi' , icon_state = "thought_bubble", loc = customer_pawn, layer = HUD_LAYER) + I.add_overlay(mutable_appearance('icons/obj/drinks.dmi', glass_visual)) + I.pixel_y = 32 + I.pixel_x = 16 + I.plane = HUD_PLANE + I.appearance_flags = RESET_COLOR + customer_pawn.hud_to_show_on_hover = customer_pawn.add_alt_appearance(/datum/atom_hud/alternate_appearance/basic/food_demands, "food_thoughts", I) + + return reagent_to_order + +/datum/venue/bar/order_food_line(datum/reagent/order) + return "I'll take a glass of [initial(order.name)]" + +/datum/venue/bar/on_get_order(mob/living/simple_animal/robot_customer/customer_pawn, obj/item/order_item) + var/datum/reagent/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, order_item) + + customer_pawn.visible_message("[customer_pawn] slurps up [order_item] in one go!", "You slurp up [order_item] in one go.") + playsound(get_turf(customer_pawn), 'sound/items/drink.ogg', 50, TRUE) + 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(istype(object_used, /obj/item/reagent_containers/food/drinks)) + var/obj/item/reagent_containers/food/drinks/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 + +/obj/item/holosign_creator/robot_seat/bar + name = "bar seating indicator placer" + holosign_type = /obj/structure/holosign/robot_seat/bar + +/obj/structure/holosign/robot_seat/bar + name = "bar seating" + linked_venue = /datum/venue/bar diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index e0116c6c960..ac2d36b73f1 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -191,10 +191,6 @@ // called when something steps onto a human // this could be made more general, but for now just handle mulebot /mob/living/carbon/human/Crossed(atom/movable/AM) - var/mob/living/simple_animal/bot/mulebot/MB = AM - if(istype(MB)) - MB.RunOver(src) - . = ..() spreadFire(AM) diff --git a/code/modules/mob/living/simple_animal/bot/mulebot.dm b/code/modules/mob/living/simple_animal/bot/mulebot.dm index 6e3045641db..eaa6c9a4517 100644 --- a/code/modules/mob/living/simple_animal/bot/mulebot.dm +++ b/code/modules/mob/living/simple_animal/bot/mulebot.dm @@ -115,6 +115,13 @@ return return ..() +/mob/living/simple_animal/bot/mulebot/Cross(atom/movable/AM) + . = ..() + if(ishuman(AM)) + RunOver(AM) + + + /// returns true if the bot is fully powered. /mob/living/simple_animal/bot/mulebot/proc/has_power(bypass_open_check) return (!open || bypass_open_check) && cell && cell.charge > 0 && (!wires.is_cut(WIRE_POWER1) && !wires.is_cut(WIRE_POWER2)) @@ -724,7 +731,6 @@ visible_message("[src] knocks over [L]!") return ..() -// called from mob/living/carbon/human/Crossed() // when mulebot is in the same loc /mob/living/simple_animal/bot/mulebot/proc/RunOver(mob/living/carbon/human/H) log_combat(src, H, "run over", null, "(DAMTYPE: [uppertext(BRUTE)])") diff --git a/code/modules/mob/living/simple_animal/friendly/robot_customer.dm b/code/modules/mob/living/simple_animal/friendly/robot_customer.dm new file mode 100644 index 00000000000..a1cfa1f00a9 --- /dev/null +++ b/code/modules/mob/living/simple_animal/friendly/robot_customer.dm @@ -0,0 +1,81 @@ +///Robot customers +/mob/living/simple_animal/robot_customer + name = "space-tourist bot" + maxHealth = 50000000 //go fuck yourself + health = 50000000 + desc = "I wonder what they'll order..." + icon = 'icons/mob/tourists.dmi' + icon_state = "amerifat" + icon_living = "amerifat" + ///Override so it uses datum ai + can_have_ai = FALSE + AIStatus = AI_OFF + del_on_death = TRUE + mob_biotypes = MOB_ROBOTIC|MOB_HUMANOID + ai_controller = /datum/ai_controller/robot_customer + unsuitable_atmos_damage = 0 + minbodytemp = 0 + maxbodytemp = 1000 + var/clothes_set = "amerifat_clothes" + var/datum/atom_hud/hud_to_show_on_hover + + +/mob/living/simple_animal/robot_customer/Initialize(mapload, datum/customer_data/customer_data = /datum/customer_data/american, datum/venue/attending_venue = SSrestaurant.all_venues[/datum/venue/restaurant]) + ADD_TRAIT(src, TRAIT_NOMOBSWAP, INNATE_TRAIT) //dont push me bitch + ADD_TRAIT(src, TRAIT_NO_TELEPORT, INNATE_TRAIT) //dont teleport me bitch + AddComponent(/datum/component/footstep, FOOTSTEP_OBJ_ROBOT, 1, -6, vary = TRUE) + var/datum/customer_data/customer_info = SSrestaurant.all_customers[customer_data] + clothes_set = pick(customer_info.clothing_sets) + ai_controller = customer_info.ai_controller_used + . = ..() + ai_controller.blackboard[BB_CUSTOMER_CUSTOMERINFO] = customer_info + ai_controller.blackboard[BB_CUSTOMER_ATTENDING_VENUE] = attending_venue + ai_controller.blackboard[BB_CUSTOMER_PATIENCE] = customer_info.total_patience + icon_state = customer_info.base_icon + name = "[pick(customer_info.name_prefixes)]-bot ([customer_info.nationality])" + color = rgb(rand(150,255), rand(150,255), rand(150,255)) + update_icon() + +///Clean up on the mobs seat etc when its deleted (Either by murder or because it left) +/mob/living/simple_animal/robot_customer/Destroy() + var/datum/venue/attending_venue = ai_controller.blackboard[BB_CUSTOMER_ATTENDING_VENUE] + attending_venue.current_visitors -= src + SSrestaurant.claimed_seats[ai_controller.blackboard[BB_CUSTOMER_MY_SEAT]] = null + QDEL_NULL(hud_to_show_on_hover) + return ..() + +/mob/living/simple_animal/robot_customer/MouseEntered(location, control, params) + . = ..() + hud_to_show_on_hover?.add_hud_to(usr) + +/mob/living/simple_animal/robot_customer/MouseExited(location, control, params) + . = ..() + hud_to_show_on_hover?.remove_hud_from(usr) + +/mob/living/simple_animal/robot_customer/update_overlays() + . = ..() + var/mutable_appearance/features = mutable_appearance(icon, "[icon_state]_features") + features.appearance_flags = RESET_COLOR + . += features + + var/mutable_appearance/clothes = mutable_appearance(icon, clothes_set) + clothes.appearance_flags = RESET_COLOR + . += clothes + + var/datum/customer_data/customer_info = ai_controller.blackboard[BB_CUSTOMER_CUSTOMERINFO] + + var/bonus_overlays = customer_info.get_overlays(src) + if(bonus_overlays) + . += bonus_overlays + +/mob/living/simple_animal/robot_customer/send_speech(message, message_range, obj/source, bubble_type, list/spans, datum/language/message_language, list/message_mods) + . = ..() + playsound(get_turf(src), 'sound/effects/tourist_talk.ogg', 100, TRUE) + +/mob/living/simple_animal/robot_customer/examine(mob/user) + . = ..() + if(ai_controller.blackboard[BB_CUSTOMER_CURRENT_ORDER]) + var/datum/venue/attending_venue = ai_controller.blackboard[BB_CUSTOMER_ATTENDING_VENUE] + . += "Their order was: \"[attending_venue.order_food_line(ai_controller.blackboard[BB_CUSTOMER_CURRENT_ORDER])].\"" + + diff --git a/code/modules/mob/living/simple_animal/simple_animal.dm b/code/modules/mob/living/simple_animal/simple_animal.dm index cc857f2022d..2e44f79e58d 100644 --- a/code/modules/mob/living/simple_animal/simple_animal.dm +++ b/code/modules/mob/living/simple_animal/simple_animal.dm @@ -173,7 +173,7 @@ var/pet_bonus_emote = "" -/mob/living/simple_animal/Initialize() +/mob/living/simple_animal/Initialize(mapload) . = ..() GLOB.simple_animals[AIStatus] += src if(gender == PLURAL) diff --git a/code/modules/reagents/chemistry/reagents.dm b/code/modules/reagents/chemistry/reagents.dm index e2e259432c7..63061bf24cf 100644 --- a/code/modules/reagents/chemistry/reagents.dm +++ b/code/modules/reagents/chemistry/reagents.dm @@ -34,6 +34,8 @@ GLOBAL_LIST_INIT(name2reagent, build_name2reagent()) var/glass_icon_state = null /// used for shot glasses, mostly for alcohol var/shot_glass_icon_state = null + /// fallback icon if the reagent has no glass or shot glass icon state. Used for restaurants. + var/fallback_icon_state = null /// reagent holder this belongs to var/datum/reagents/holder = null /// LIQUID, SOLID, GAS diff --git a/code/modules/reagents/chemistry/reagents/alcohol_reagents.dm b/code/modules/reagents/chemistry/reagents/alcohol_reagents.dm index 946f11919cd..1088f2f3e94 100644 --- a/code/modules/reagents/chemistry/reagents/alcohol_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/alcohol_reagents.dm @@ -98,6 +98,8 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_desc = "A freezing pint of beer." ph = 4 chemical_flags = REAGENT_CAN_BE_SYNTHESIZED + fallback_icon_state = "beer" + glass_price = DRINK_PRICE_STOCK // Beer is a chemical composition of alcohol and various other things. It's a garbage nutrient but hey, it's still one. Also alcohol is bad, mmmkay? @@ -116,6 +118,7 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_desc = "A freezing pint of watery light beer." ph = 5 chemical_flags = REAGENT_CAN_BE_SYNTHESIZED + fallback_icon_state = "beer" /datum/reagent/consumable/ethanol/beer/maltliquor name = "Malt Liquor" @@ -894,6 +897,7 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_desc = "Kahlua, Irish Cream, and cognac. You will get bombed." shot_glass_icon_state = "b52glass" chemical_flags = REAGENT_CAN_BE_SYNTHESIZED + glass_price = DRINK_PRICE_EASY /datum/reagent/consumable/ethanol/b52/on_mob_metabolize(mob/living/M) playsound(M, 'sound/effects/explosion_distant.ogg', 100, FALSE) @@ -946,6 +950,7 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_name = "Manhattan" glass_desc = "The Detective's undercover drink of choice. He never could stomach gin..." chemical_flags = REAGENT_CAN_BE_SYNTHESIZED + glass_price = DRINK_PRICE_EASY /datum/reagent/consumable/ethanol/manhattan_proj @@ -1457,6 +1462,7 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_name = "Atomic Bomb" glass_desc = "Nanotrasen cannot take legal responsibility for your actions after imbibing." chemical_flags = REAGENT_CAN_BE_SYNTHESIZED + glass_price = DRINK_PRICE_HIGH /datum/reagent/consumable/ethanol/atomicbomb/on_mob_life(mob/living/carbon/M, delta_time, times_fired) M.set_drugginess(50 * REM * delta_time) @@ -1928,6 +1934,7 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_name = "Sidecar" glass_desc = "The one ride you'll gladly give up the wheel for." chemical_flags = REAGENT_CAN_BE_SYNTHESIZED + glass_price = DRINK_PRICE_MEDIUM /datum/reagent/consumable/ethanol/between_the_sheets name = "Between the Sheets" @@ -1977,6 +1984,7 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_name = "Mojito" glass_desc = "A drink that looks as refreshing as it tastes." chemical_flags = REAGENT_CAN_BE_SYNTHESIZED + glass_price = DRINK_PRICE_MEDIUM /datum/reagent/consumable/ethanol/moscow_mule name = "Moscow Mule" @@ -2038,6 +2046,7 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_name = "glass of fanciulli" glass_desc = "A glass of Fanciulli. It's just Manhattan with Fernet." chemical_flags = REAGENT_CAN_BE_SYNTHESIZED + glass_price = DRINK_PRICE_HIGH /datum/reagent/consumable/ethanol/fanciulli/on_mob_life(mob/living/carbon/M, delta_time, times_fired) M.adjust_nutrition(-5 * REM * delta_time) @@ -2062,6 +2071,7 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_name = "glass of branca menta" glass_desc = "A glass of Branca Menta, perfect for those lazy and hot Sunday summer afternoons." //Get lazy literally by drinking this chemical_flags = REAGENT_CAN_BE_SYNTHESIZED + glass_price = DRINK_PRICE_MEDIUM /datum/reagent/consumable/ethanol/branca_menta/on_mob_life(mob/living/carbon/M, delta_time, times_fired) @@ -2207,6 +2217,7 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_name = "Champagne" glass_desc = "The flute clearly displays the slowly rising bubbles." chemical_flags = REAGENT_CAN_BE_SYNTHESIZED + glass_price = DRINK_PRICE_EASY /datum/reagent/consumable/ethanol/wizz_fizz @@ -2493,6 +2504,7 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_name = "Godfather" glass_desc = "A classic from old Italy and enjoyed by gangsters, pray the orange peel doesnt end up in your mouth." chemical_flags = REAGENT_CAN_BE_SYNTHESIZED + glass_price = DRINK_PRICE_MEDIUM /datum/reagent/consumable/ethanol/godmother name = "Godmother" diff --git a/code/modules/reagents/chemistry/reagents/drink_reagents.dm b/code/modules/reagents/chemistry/reagents/drink_reagents.dm index 93a20cea5ef..b921a7efeb1 100644 --- a/code/modules/reagents/chemistry/reagents/drink_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/drink_reagents.dm @@ -329,6 +329,7 @@ glass_name = "pitcher of lemonade" glass_desc = "This drink leaves you feeling nostalgic for some reason." chemical_flags = REAGENT_CAN_BE_SYNTHESIZED + glass_price = DRINK_PRICE_EASY /datum/reagent/consumable/tea/arnold_palmer name = "Arnold Palmer" diff --git a/code/modules/reagents/chemistry/reagents/food_reagents.dm b/code/modules/reagents/chemistry/reagents/food_reagents.dm index b3e08a0ee6d..aced7fd7d5b 100755 --- a/code/modules/reagents/chemistry/reagents/food_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/food_reagents.dm @@ -11,13 +11,20 @@ name = "Consumable" taste_description = "generic food" taste_mult = 4 - /// 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 impure_chem = /datum/reagent/water inverse_chem_val = 0.1 inverse_chem = /datum/reagent/water failed_chem = /datum/reagent/consumable/nutriment + /// 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' + ///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 + +/datum/reagent/consumable/New() + . = ..() + if(glass_price) + AddElement(/datum/element/venue_price, glass_price) /datum/reagent/consumable/on_mob_life(mob/living/carbon/M, delta_time, times_fired) current_cycle++ diff --git a/code/modules/research/designs/autolathe_designs.dm b/code/modules/research/designs/autolathe_designs.dm index 3e5208a9c47..12e489a9365 100644 --- a/code/modules/research/designs/autolathe_designs.dm +++ b/code/modules/research/designs/autolathe_designs.dm @@ -1217,3 +1217,24 @@ materials = list(/datum/material/iron = 100, /datum/material/glass = 50) build_path = /obj/item/assembly/control category = list("initial","Misc") + + +/datum/design/holosign/restaurant + name = "Restaurant Seating Projector" + desc = "A holographic projector that creates seating designation for restaurants." + id = "holosignrestaurant" + build_type = AUTOLATHE + materials = list(/datum/material/iron = 2000, /datum/material/glass = 1000) + build_path = /obj/item/holosign_creator/robot_seat/restaurant + category = list("Equipment") + departmental_flags = DEPARTMENTAL_FLAG_SERVICE + +/datum/design/holosign/bar + name = "Bar Seating Projector" + desc = "A holographic projector that creates seating designation for bars." + id = "holosignbar" + build_type = AUTOLATHE + materials = list(/datum/material/iron = 2000, /datum/material/glass = 1000) + build_path = /obj/item/holosign_creator/robot_seat/bar + category = list("Equipment") + departmental_flags = DEPARTMENTAL_FLAG_SERVICE diff --git a/code/modules/research/designs/machine_designs.dm b/code/modules/research/designs/machine_designs.dm index 3bb3f2d6335..293f9c2ccad 100644 --- a/code/modules/research/designs/machine_designs.dm +++ b/code/modules/research/designs/machine_designs.dm @@ -633,6 +633,14 @@ build_path = /obj/item/circuitboard/machine/sheetifier category = list ("Misc. Machinery") + +/datum/design/board/restaurant_portal + name = "Machine Design (Restaurant Portal)" + desc = "The circuit board for a restaurant portal" + id = "restaurant_portal" + build_path = /obj/item/circuitboard/machine/restaurant_portal + category = list ("Misc. Machinery") + /datum/design/board/vendatray name = "Machine Design (Vend-a-Tray)" desc = "The circuit board for a Vend-a-Tray." diff --git a/code/modules/research/techweb/all_nodes.dm b/code/modules/research/techweb/all_nodes.dm index f02b791f2c9..120c120c678 100644 --- a/code/modules/research/techweb/all_nodes.dm +++ b/code/modules/research/techweb/all_nodes.dm @@ -9,7 +9,7 @@ description = "NT default research technologies." // Default research tech, prevents bricking design_ids = list("basic_matter_bin", "basic_cell", "basic_scanning", "basic_capacitor", "basic_micro_laser", "micro_mani", "basic_electrolite", "c-reader", "desttagger", "salestagger", "handlabel", "packagewrap", - "destructive_analyzer", "circuit_imprinter", "experimentor", "rdconsole", "bepis", "design_disk", "tech_disk", "rdserver", "rdservercontrol", "mechfab", + "destructive_analyzer", "circuit_imprinter", "experimentor", "rdconsole", "bepis", "design_disk", "tech_disk", "rdserver", "rdservercontrol", "mechfab", "restaurant_portal", "paystand", "space_heater", "bucket", "sec_rshot", "sec_beanbag_slug", "sec_Islug", "sec_dart", "sec_38", "rglass", "plasteel", "experi_scanner", "destructive_scanner", "doppler_array", "plastitanium", "plasmaglass", "plasmareinforcedglass", "titaniumglass", "plastitaniumglass", "plastic_knife", "plastic_fork", "plastic_spoon", "conveyor_belt", "conveyor_switch", "b6mm","b6mm_rubber","b9mm","b9mm_rubber","b10mm","b10mm_rubber","b12mm","b12mm_rubber") //SKYRAT EDIT ADDITION - SEC_HAUL diff --git a/icons/effects/effects.dmi b/icons/effects/effects.dmi index 7bdbe698795..0a947c671bf 100644 Binary files a/icons/effects/effects.dmi and b/icons/effects/effects.dmi differ diff --git a/icons/mob/tourists.dmi b/icons/mob/tourists.dmi new file mode 100644 index 00000000000..546cff2aed7 Binary files /dev/null and b/icons/mob/tourists.dmi differ diff --git a/icons/obj/machines/restaurant_portal.dmi b/icons/obj/machines/restaurant_portal.dmi new file mode 100644 index 00000000000..62591d4b56f Binary files /dev/null and b/icons/obj/machines/restaurant_portal.dmi differ diff --git a/sound/effects/tank_treads.ogg b/sound/effects/tank_treads.ogg new file mode 100644 index 00000000000..be4e0ff273b Binary files /dev/null and b/sound/effects/tank_treads.ogg differ diff --git a/sound/effects/tourist_talk.ogg b/sound/effects/tourist_talk.ogg new file mode 100644 index 00000000000..239e1a79753 Binary files /dev/null and b/sound/effects/tourist_talk.ogg differ diff --git a/strings/names/american_prefix.txt b/strings/names/american_prefix.txt new file mode 100644 index 00000000000..58293ab5713 --- /dev/null +++ b/strings/names/american_prefix.txt @@ -0,0 +1,23 @@ +Yeehaw +Gun +Republican +Vietnam +Burger +Grill +Chub +Obesi +Diabeti +Anti-healthcare +Cowboy +New York +Texas +Florida +Anti-vax +Nixon +Independi +Oorah +Freedom +Liberty +Barbeque +Democra +Second amendment diff --git a/strings/names/french_prefix.txt b/strings/names/french_prefix.txt new file mode 100644 index 00000000000..201a35dd230 --- /dev/null +++ b/strings/names/french_prefix.txt @@ -0,0 +1,9 @@ +Baguette +Snail +Surrender +White flag +Eiffel +Paris +Beret +Hon hon +Wine \ No newline at end of file diff --git a/strings/names/italian_prefix.txt b/strings/names/italian_prefix.txt new file mode 100644 index 00000000000..e0a3d83e6e6 --- /dev/null +++ b/strings/names/italian_prefix.txt @@ -0,0 +1,8 @@ +Mob +Don +Pizza +Vespa +Pasta +Venice +Rome +Centuri \ No newline at end of file diff --git a/tgstation.dme b/tgstation.dme index c75e5bfc09e..5d575bc138e 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -348,6 +348,7 @@ #include "code\controllers\subsystem\radiation.dm" #include "code\controllers\subsystem\radio.dm" #include "code\controllers\subsystem\research.dm" +#include "code\controllers\subsystem\restaurant.dm" #include "code\controllers\subsystem\runechat.dm" #include "code\controllers\subsystem\server_maint.dm" #include "code\controllers\subsystem\shuttle.dm" @@ -444,9 +445,12 @@ #include "code\datums\ai\monkey\monkey_behaviors.dm" #include "code\datums\ai\monkey\monkey_controller.dm" #include "code\datums\ai\movement\_ai_movement.dm" +#include "code\datums\ai\movement\ai_movement_basic_avoidance.dm" #include "code\datums\ai\movement\ai_movement_dumb.dm" #include "code\datums\ai\objects\vending_machines\vending_machine_behaviors.dm" #include "code\datums\ai\objects\vending_machines\vending_machine_controller.dm" +#include "code\datums\ai\robot_customer\robot_customer_behaviors.dm" +#include "code\datums\ai\robot_customer\robot_customer_controller.dm" #include "code\datums\announcers\_announcer.dm" #include "code\datums\announcers\default_announcer.dm" #include "code\datums\announcers\intern_announcer.dm" @@ -680,6 +684,7 @@ #include "code\datums\elements\food\dunkable.dm" #include "code\datums\elements\food\food_trash.dm" #include "code\datums\elements\food\processable.dm" +#include "code\datums\elements\food\venue_price.dm" #include "code\datums\helper_datums\events.dm" #include "code\datums\helper_datums\getrev.dm" #include "code\datums\helper_datums\icon_snapshot.dm" @@ -2134,6 +2139,9 @@ #include "code\modules\food_and_drinks\recipes\tablecraft\recipes_sandwich.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\generic_venues.dm" +#include "code\modules\food_and_drinks\restaurant\customers\_customer.dm" #include "code\modules\games\cas.dm" #include "code\modules\games\kotahi.dm" #include "code\modules\games\tarot.dm" @@ -2583,6 +2591,7 @@ #include "code\modules\mob\living\simple_animal\friendly\mouse.dm" #include "code\modules\mob\living\simple_animal\friendly\penguin.dm" #include "code\modules\mob\living\simple_animal\friendly\pet.dm" +#include "code\modules\mob\living\simple_animal\friendly\robot_customer.dm" #include "code\modules\mob\living\simple_animal\friendly\sloth.dm" #include "code\modules\mob\living\simple_animal\friendly\snake.dm" #include "code\modules\mob\living\simple_animal\friendly\drone\_drone.dm"