mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-08-31 00:58:26 +01:00
[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:
co-authored by
ATH1909
Mothblocks
Gandalf2k15
parent
f54ec042d2
commit
e3b36b1a33
@@ -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.
@@ -0,0 +1,8 @@
|
||||
Annoy
|
||||
Bug
|
||||
Buzz
|
||||
Flap
|
||||
Fluff
|
||||
Flutter
|
||||
Noise
|
||||
Wing
|
||||
Reference in New Issue
Block a user