diff --git a/code/modules/clothing/clothing.dm b/code/modules/clothing/clothing.dm index fe130ae3137..9ab21114acd 100644 --- a/code/modules/clothing/clothing.dm +++ b/code/modules/clothing/clothing.dm @@ -66,6 +66,7 @@ if((clothing_flags & VOICEBOX_TOGGLABLE)) actions_types += /datum/action/item_action/toggle_voice_box . = ..() + AddElement(/datum/element/venue_price, FOOD_PRICE_CHEAP) if(ispath(pocket_storage_component_path)) LoadComponent(pocket_storage_component_path) if(can_be_bloody && ((body_parts_covered & FEET) || (flags_inv & HIDESHOES))) diff --git a/code/modules/food_and_drinks/restaurant/_venue.dm b/code/modules/food_and_drinks/restaurant/_venue.dm index a582224ea14..a1cb3f5c578 100644 --- a/code/modules/food_and_drinks/restaurant/_venue.dm +++ b/code/modules/food_and_drinks/restaurant/_venue.dm @@ -5,7 +5,7 @@ ///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, /datum/customer_data/japanese = 3, /datum/customer_data/japanese/salaryman = 2, /datum/customer_data/mexican = 3) + var/list/customer_types ///Is the venue open at the moment? var/open ///Portal linked to this venue at the moment @@ -29,7 +29,6 @@ ///Seats linked to this venue, assoc list of key holosign of seat position, and value of robot assigned to it, if any. var/list/linked_seats = list() - /datum/venue/process(delta_time) if(!COOLDOWN_FINISHED(src, visit_cooldown)) return @@ -39,7 +38,27 @@ ///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) + var/list/customer_types_to_choose = customer_types + var/datum/customer_data/customer_type + + // In practice, the list will never run out, but this is for sanity. + while (customer_types_to_choose.len) + customer_type = pickweight(customer_types_to_choose) + + var/datum/customer_data/customer = SSrestaurant.all_customers[customer_type] + if (customer.can_use(src)) + break + + // Only copy the list once, so that we're not mutating ourselves. + if (customer_types_to_choose == customer_types) + customer_types_to_choose = customer_types.Copy() + + customer_types_to_choose -= customer_type + + if (initial(customer_type.is_unique)) + customer_types -= customer_type + + var/mob/living/simple_animal/robot_customer/new_customer = new /mob/living/simple_animal/robot_customer(get_turf(restaurant_portal), customer_type, src) current_visitors += new_customer /datum/venue/proc/order_food(mob/living/simple_animal/robot_customer/customer_pawn, datum/customer_data/customer_data) @@ -95,6 +114,8 @@ ///What venue is this portal for? Uses a typepath which is turned into an instance on Initialize var/datum/venue/linked_venue = /datum/venue + /// A weak reference to the mob who turned on the portal + var/datum/weakref/turned_on_portal /obj/machinery/restaurant_portal/Initialize() . = ..() @@ -104,6 +125,7 @@ /obj/machinery/restaurant_portal/Destroy() . = ..() + turned_on_portal = null /obj/machinery/restaurant_portal/update_overlays() . = ..() @@ -148,7 +170,7 @@ var/datum/venue/chosen_venue = radial_results[choice] - + turned_on_portal = WEAKREF(user) if(!(chosen_venue.req_access in used_id.GetAccess())) to_chat(user, "This card lacks the access to change this venues status.") diff --git a/code/modules/food_and_drinks/restaurant/customers/_customer.dm b/code/modules/food_and_drinks/restaurant/customers/_customer.dm index 243a951c548..c234c736f82 100644 --- a/code/modules/food_and_drinks/restaurant/customers/_customer.dm +++ b/code/modules/food_and_drinks/restaurant/customers/_customer.dm @@ -39,13 +39,29 @@ ///Sound to use when this robot type speaks var/speech_sound = 'sound/creatures/tourist/tourist_talk.ogg' + /// Is this unique once per venue? + var/is_unique = FALSE + /datum/customer_data/New() . = ..() name_prefixes = world.file2list(prefix_file) +/// Can this customer be chosen for this venue? +/datum/customer_data/proc/can_use(datum/venue/venue) + return TRUE + +/// Gets the order of this customer. +/// You want to override this if you have dynamic orders, such as the moth tourists requesting the chef's clothes. +/// If the list of orders are static, just modify orderable_objects. +/datum/customer_data/proc/get_order(datum/venue/venue) + return pickweight(orderable_objects[venue.type]) + /datum/customer_data/proc/get_overlays(mob/living/simple_animal/robot_customer/customer) return +/datum/customer_data/proc/get_underlays(mob/living/simple_animal/robot_customer/customer) + return + /datum/customer_data/american nationality = "Space-American" orderable_objects = list( @@ -155,6 +171,101 @@ /datum/venue/restaurant = list(/obj/item/food/tofu = 5, /obj/item/food/soup/miso = 6, /obj/item/food/soup/vegetable = 4, /obj/item/food/sashimi = 4, /obj/item/food/chawanmushi = 4, /obj/item/food/meatbun = 4, /obj/item/food/beef_stroganoff = 2), /datum/venue/bar = list(/datum/reagent/consumable/ethanol/beer = 14, /datum/reagent/consumable/ethanol/sake = 9, /datum/reagent/consumable/cafe_latte = 3, /datum/reagent/consumable/coffee = 3, /datum/reagent/consumable/soy_latte = 3, /datum/reagent/consumable/ethanol/atomicbomb = 1)) +/datum/customer_data/moth + nationality = "Mothman" + prefix_file = "strings/names/moth_prefix.txt" + base_icon = "mothbot" + found_seat_lines = list("Give me your hat!", "Moth?", "Certainly an... interesting venue.") + cant_find_seat_lines = list("If I can't find a seat, I'm flappity flapping out of here quick!", "I'm trying to flutter here!") + leave_mad_lines = list("I'm telling all my moth friends to never come here!", "Zero star rating, even worse than that time I ate a mothball!","Closing down permanently would still be too good of a fate for this place.") + leave_happy_lines = list("I'd tip you my hat, but I ate it!", "I hope that wasn't a collectible!", "That was the greatest thing I ever ate, even better than Guanaco!") + wait_for_food_lines = list("How hard is it to get food here? You're even wearing food yourself!", "My fuzzy robotic tummy is rumbling!", "I don't like waiting!") + friendly_pull_line = "Moff?" + first_warning_line = "Go away, I'm trying to get some hats here!" + second_warning_line = "Last warning! I'll destroy you!" + self_defense_line = "Flap attack!" + + speech_sound = 'sound/creatures/tourist/tourist_talk_moth.ogg' + + // Always asks for the clothes that you have on, but this is a fallback. + orderable_objects = list( + /datum/venue/restaurant = list( + /obj/item/clothing/head/chefhat = 3, + /obj/item/clothing/shoes/sneakers/black = 3, + /obj/item/clothing/gloves/color/black = 1, + ), + ) + + clothing_sets = list("mothbot_clothes") + is_unique = TRUE + + /// The wings chosen for the moth customers. + var/list/wings_chosen + +// The whole gag is taking off your hat and giving it to the customer. +// If it takes any more effort, it loses a bit of the comedy. +// Therefore, only show up if it's reasonable for that gag to happen. +/datum/customer_data/moth/can_use(datum/venue/venue) + return !isnull(get_dynamic_order(venue)) + +/datum/customer_data/moth/proc/get_dynamic_order(datum/venue/venue) + var/mob/living/carbon/buffet = venue.restaurant_portal?.turned_on_portal?.resolve() + if (!istype(buffet)) + return + + var/list/orderable = list() + + if (!QDELETED(buffet.head)) + orderable[buffet.head] = 5 + + if (!QDELETED(buffet.gloves)) + orderable[buffet.gloves] = 5 + + if (!QDELETED(buffet.shoes)) + orderable[buffet.shoes] = 1 + + if (orderable.len) + var/datum/order = pickweight(orderable) + return order.type + +/datum/customer_data/moth/proc/get_wings(mob/living/simple_animal/robot_customer/customer) + var/customer_ref = WEAKREF(customer) + if (!LAZYACCESS(wings_chosen, customer_ref)) + LAZYSET(wings_chosen, customer_ref, pick(GLOB.sprite_accessories["wings"])) + return wings_chosen[customer_ref] + +/datum/customer_data/moth/get_underlays(mob/living/simple_animal/robot_customer/customer) + var/list/underlays = list() + + var/datum/sprite_accessory/moth_wings/wings = get_wings(customer) + + var/mutable_appearance/wings_behind = mutable_appearance(icon = 'icons/mob/moth_wings.dmi', icon_state = "m_moth_wings_[wings.icon_state]_BEHIND") + wings_behind.appearance_flags = RESET_COLOR + underlays += wings_behind + + return underlays + +/datum/customer_data/moth/get_overlays(mob/living/simple_animal/robot_customer/customer) + var/list/overlays = list() + + var/datum/sprite_accessory/moth_wings/wings = get_wings(customer) + + var/mutable_appearance/wings_front = mutable_appearance(icon = 'icons/mob/moth_wings.dmi', icon_state = "m_moth_wings_[wings.icon_state]_FRONT") + wings_front.appearance_flags = RESET_COLOR + overlays += wings_front + + var/mutable_appearance/jetpack = mutable_appearance(icon = customer.icon, icon_state = "mothbot_jetpack") + jetpack.appearance_flags = RESET_COLOR + overlays += jetpack + + return overlays + +/datum/customer_data/moth/get_order(datum/venue/venue) + var/dynamic_order = get_dynamic_order(venue) + + // Fall back to basic clothing. + return dynamic_order || ..() + /datum/customer_data/mexican nationality = "Space-Mexican" base_icon = "mexican" diff --git a/code/modules/food_and_drinks/restaurant/generic_venues.dm b/code/modules/food_and_drinks/restaurant/generic_venues.dm index 2d82edd36da..453c91a9d31 100644 --- a/code/modules/food_and_drinks/restaurant/generic_venues.dm +++ b/code/modules/food_and_drinks/restaurant/generic_venues.dm @@ -5,10 +5,18 @@ req_access = ACCESS_KITCHEN min_time_between_visitor = 80 SECONDS max_time_between_visitor = 100 SECONDS - + customer_types = list( + /datum/customer_data/american = 50, + /datum/customer_data/italian = 30, + /datum/customer_data/french = 30, + /datum/customer_data/mexican = 30, + /datum/customer_data/japanese = 30, + /datum/customer_data/japanese/salaryman = 20, + /datum/customer_data/moth = 1, + ) /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 + var/obj/item/object_to_order = customer_data.get_order(src) . = object_to_order @@ -66,6 +74,14 @@ req_access = ACCESS_BAR min_time_between_visitor = 40 SECONDS max_time_between_visitor = 60 SECONDS + customer_types = list( + /datum/customer_data/american = 50, + /datum/customer_data/italian = 30, + /datum/customer_data/french = 30, + /datum/customer_data/mexican = 30, + /datum/customer_data/japanese = 30, + /datum/customer_data/japanese/salaryman = 20, + ) /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]) diff --git a/code/modules/mob/living/simple_animal/friendly/robot_customer.dm b/code/modules/mob/living/simple_animal/friendly/robot_customer.dm index 3185461c933..77c58bdbad3 100644 --- a/code/modules/mob/living/simple_animal/friendly/robot_customer.dm +++ b/code/modules/mob/living/simple_animal/friendly/robot_customer.dm @@ -61,6 +61,14 @@ /mob/living/simple_animal/robot_customer/update_overlays() . = ..() + + var/datum/customer_data/customer_info = ai_controller.blackboard[BB_CUSTOMER_CUSTOMERINFO] + + var/new_underlays = customer_info.get_underlays(src) + if (new_underlays) + underlays.Cut() + underlays += new_underlays + var/mutable_appearance/features = mutable_appearance(icon, "[icon_state]_features") features.appearance_flags = RESET_COLOR . += features @@ -69,8 +77,6 @@ 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 diff --git a/icons/mob/tourists.dmi b/icons/mob/tourists.dmi index 56e72712b62..8551feec641 100644 Binary files a/icons/mob/tourists.dmi and b/icons/mob/tourists.dmi differ diff --git a/sound/creatures/tourist/tourist_talk_moth.ogg b/sound/creatures/tourist/tourist_talk_moth.ogg new file mode 100644 index 00000000000..fdbf20633db Binary files /dev/null and b/sound/creatures/tourist/tourist_talk_moth.ogg differ diff --git a/strings/names/moth_prefix.txt b/strings/names/moth_prefix.txt new file mode 100644 index 00000000000..6afcdd47d14 --- /dev/null +++ b/strings/names/moth_prefix.txt @@ -0,0 +1,8 @@ +Annoy +Bug +Buzz +Flap +Fluff +Flutter +Noise +Wing