[MIRROR] Moth tourist bots -- They ask for your hat (#4152)

* Moth tourist bots -- They ask for your hat (#57563)

Adds a rare, once per restaurant venue, chance for a moth tourist bot to show up. Asks for the hat, gloves, or shoes you have on.

Closes #57541 if this is merged first, somehow. It includes the testing fix (since I needed to multiply all the weights to allow for rare bots anyway).

Wings are randomized.

I thought it was funny, and it's infrequent enough for the gag to hopefully not lose its magic.

Also a good test bench for the code to allow more dynamic customers. A lot of supporting code was added to make more customizable customers without influencing the surface area of the venue code too much.

Co-authored-by: ATH1909 <42606352+ATH1909@ users.noreply.github.com>

* Moth tourist bots -- They ask for your hat

* Update _customer.dm

Co-authored-by: Mothblocks <35135081+Mothblocks@users.noreply.github.com>
Co-authored-by: ATH1909 <42606352+ATH1909@ users.noreply.github.com>
Co-authored-by: Gandalf2k15 <jzo123@hotmail.com>
This commit is contained in:
SkyratBot
2021-03-15 20:48:31 +00:00
committed by GitHub
co-authored by ATH1909 Mothblocks Gandalf2k15
parent f54ec042d2
commit e3b36b1a33
8 changed files with 172 additions and 8 deletions
+1
View File
@@ -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)))
@@ -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, "<span class='warning'>This card lacks the access to change this venues status.</span>")
@@ -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"
@@ -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])
@@ -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
Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.6 KiB

After

Width:  |  Height:  |  Size: 7.9 KiB

Binary file not shown.
+8
View File
@@ -0,0 +1,8 @@
Annoy
Bug
Buzz
Flap
Fluff
Flutter
Noise
Wing