Add guest thoughts to plugin API (#18732)

Co-authored-by: Tulio Leao <tupaschoal@gmail.com>
This commit is contained in:
Matthew 2022-12-29 10:56:11 -05:00 committed by GitHub
parent 279675ba45
commit d00c71399b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 388 additions and 1 deletions

View File

@ -1,6 +1,7 @@
0.4.4 (in development)
------------------------------------------------------------------------
- Feature: [#18537] Add shift/control modifiers to window close buttons, closing all but the given window or all windows of the same type, respectively.
- Feature: [#18732] [Plugin] API to get the guests thoughts.
- Feature: [#18744] Cheat to allow using a regular path as a queue path.
- Improved: [#18826] [Plugin] Added all actions and their documentation to plugin API.

View File

@ -2493,8 +2493,173 @@ declare global {
* Countdown between 0 and 255 that keeps track of how long the guest has been looking for its current destination.
*/
lostCountdown: number;
/**
* The list of thoughts this guest has.
*/
readonly thoughts: Thought[];
}
/**
* Represents a guest's thought. This is a copy of a thought at a given time
* and its values will not update.
*/
interface Thought {
/**
* The type of thought.
*/
readonly type: ThoughtType;
/**
* The thought argument.
*/
readonly item: number;
/**
* The freshness of the thought - the larger the number, the less fresh
* the thought.
*/
readonly freshness: number;
/**
* The freshness timeout.
*/
readonly freshTimeout: number;
/**
* Get the string for this thought.
* The result contains Unicode quotes on either end, e.g. I feel sick
*/
toString(): string;
}
type ThoughtType =
"cant_afford_ride" |
"spent_money" |
"sick" |
"very_sick" |
"more_thrilling" |
"intense" |
"havent_finished" |
"sickening" |
"bad_value" |
"go_home" |
"good_value" |
"already_got" |
"cant_afford_item" |
"not_hungry" |
"not_thirsty" |
"drowning" |
"lost" |
"was_great" |
"queuing_ages" |
"tired" |
"hungry" |
"thirsty" |
"toilet" |
"cant_find" |
"not_paying" |
"not_while_raining" |
"bad_litter" |
"cant_find_exit" |
"get_off" |
"get_out" |
"not_safe" |
"path_disgusting" |
"crowded" |
"vandalism" |
"scenery" |
"very_clean" |
"fountains" |
"music" |
"balloon" |
"toy" |
"map" |
"photo" |
"umbrella" |
"drink" |
"burger" |
"chips" |
"ice_cream" |
"candyfloss" |
"pizza" |
"popcorn" |
"hot_dog" |
"tentacle" |
"hat" |
"toffee_apple" |
"tshirt" |
"doughnut" |
"coffee" |
"chicken" |
"lemonade" |
"wow" |
"wow2" |
"watched" |
"balloon_much" |
"toy_much" |
"map_much" |
"photo_much" |
"umbrella_much" |
"drink_much" |
"burger_much" |
"chips_much" |
"ice_cream_much" |
"candyfloss_much" |
"pizza_much" |
"popcorn_much" |
"hot_dog_much" |
"tentacle_much" |
"hat_much" |
"toffee_apple_much" |
"tshirt_much" |
"doughnut_much" |
"coffee_much" |
"chicken_much" |
"lemonade_much" |
"photo2" |
"photo3" |
"photo4" |
"pretzel" |
"hot_chocolate" |
"iced_tea" |
"funnel_cake" |
"sunglasses" |
"beef_noodles" |
"fried_rice_noodles" |
"wonton_soup" |
"meatball_soup" |
"fruit_juice" |
"soybean_milk" |
"sujongkwa" |
"sub_sandwich" |
"cookie" |
"roast_sausage" |
"photo2_much" |
"photo3_much" |
"photo4_much" |
"pretzel_much" |
"hot_chocolate_much" |
"iced_tea_much" |
"funnel_cake_much" |
"sunglasses_much" |
"beef_noodles_much" |
"fried_rice_noodles_much" |
"wonton_soup_much" |
"meatball_soup_much" |
"fruit_juice_much" |
"soybean_milk_much" |
"sujongkwa_much" |
"sub_sandwich_much" |
"cookie_much" |
"roast_sausage_much" |
"help" |
"running_out" |
"new_ride" |
"nice_ride_deprecated" |
"excited_deprecated" |
"here_we_are";
/**
* Represents a staff member.
*/

View File

@ -422,6 +422,7 @@ void ScriptEngine::Initialise()
ScVehicle::Register(ctx);
ScPeep::Register(ctx);
ScGuest::Register(ctx);
ScThought::Register(ctx);
# ifndef DISABLE_NETWORK
ScSocket::Register(ctx);
ScListener::Register(ctx);

View File

@ -46,7 +46,7 @@ namespace OpenRCT2
namespace OpenRCT2::Scripting
{
static constexpr int32_t OPENRCT2_PLUGIN_API_VERSION = 66;
static constexpr int32_t OPENRCT2_PLUGIN_API_VERSION = 67;
// Versions marking breaking changes.
static constexpr int32_t API_VERSION_33_PEEP_DEPRECATION = 33;

View File

@ -12,9 +12,138 @@
# include "ScGuest.hpp"
# include "../../../entity/Guest.h"
# include "../../../localisation/Localisation.h"
namespace OpenRCT2::Scripting
{
static const DukEnumMap<PeepThoughtType> ThoughtTypeMap({
{ "cant_afford_ride", PeepThoughtType::CantAffordRide },
{ "spent_money", PeepThoughtType::SpentMoney },
{ "sick", PeepThoughtType::Sick },
{ "very_sick", PeepThoughtType::VerySick },
{ "more_thrilling", PeepThoughtType::MoreThrilling },
{ "intense", PeepThoughtType::Intense },
{ "havent_finished", PeepThoughtType::HaventFinished },
{ "sickening", PeepThoughtType::Sickening },
{ "bad_value", PeepThoughtType::BadValue },
{ "go_home", PeepThoughtType::GoHome },
{ "good_value", PeepThoughtType::GoodValue },
{ "already_got", PeepThoughtType::AlreadyGot },
{ "cant_afford_item", PeepThoughtType::CantAffordItem },
{ "not_hungry", PeepThoughtType::NotHungry },
{ "not_thirsty", PeepThoughtType::NotThirsty },
{ "drowning", PeepThoughtType::Drowning },
{ "lost", PeepThoughtType::Lost },
{ "was_great", PeepThoughtType::WasGreat },
{ "queuing_ages", PeepThoughtType::QueuingAges },
{ "tired", PeepThoughtType::Tired },
{ "hungry", PeepThoughtType::Hungry },
{ "thirsty", PeepThoughtType::Thirsty },
{ "toilet", PeepThoughtType::Toilet },
{ "cant_find", PeepThoughtType::CantFind },
{ "not_paying", PeepThoughtType::NotPaying },
{ "not_while_raining", PeepThoughtType::NotWhileRaining },
{ "bad_litter", PeepThoughtType::BadLitter },
{ "cant_find_exit", PeepThoughtType::CantFindExit },
{ "get_off", PeepThoughtType::GetOff },
{ "get_out", PeepThoughtType::GetOut },
{ "not_safe", PeepThoughtType::NotSafe },
{ "path_disgusting", PeepThoughtType::PathDisgusting },
{ "crowded", PeepThoughtType::Crowded },
{ "vandalism", PeepThoughtType::Vandalism },
{ "scenery", PeepThoughtType::Scenery },
{ "very_clean", PeepThoughtType::VeryClean },
{ "fountains", PeepThoughtType::Fountains },
{ "music", PeepThoughtType::Music },
{ "balloon", PeepThoughtType::Balloon },
{ "toy", PeepThoughtType::Toy },
{ "map", PeepThoughtType::Map },
{ "photo", PeepThoughtType::Photo },
{ "umbrella", PeepThoughtType::Umbrella },
{ "drink", PeepThoughtType::Drink },
{ "burger", PeepThoughtType::Burger },
{ "chips", PeepThoughtType::Chips },
{ "ice_cream", PeepThoughtType::IceCream },
{ "candyfloss", PeepThoughtType::Candyfloss },
{ "pizza", PeepThoughtType::Pizza },
{ "popcorn", PeepThoughtType::Popcorn },
{ "hot_dog", PeepThoughtType::HotDog },
{ "tentacle", PeepThoughtType::Tentacle },
{ "hat", PeepThoughtType::Hat },
{ "toffee_apple", PeepThoughtType::ToffeeApple },
{ "tshirt", PeepThoughtType::Tshirt },
{ "doughnut", PeepThoughtType::Doughnut },
{ "coffee", PeepThoughtType::Coffee },
{ "chicken", PeepThoughtType::Chicken },
{ "lemonade", PeepThoughtType::Lemonade },
{ "wow", PeepThoughtType::Wow },
{ "wow2", PeepThoughtType::Wow2 },
{ "watched", PeepThoughtType::Watched },
{ "balloon_much", PeepThoughtType::BalloonMuch },
{ "toy_much", PeepThoughtType::ToyMuch },
{ "map_much", PeepThoughtType::MapMuch },
{ "photo_much", PeepThoughtType::PhotoMuch },
{ "umbrella_much", PeepThoughtType::UmbrellaMuch },
{ "drink_much", PeepThoughtType::DrinkMuch },
{ "burger_much", PeepThoughtType::BurgerMuch },
{ "chips_much", PeepThoughtType::ChipsMuch },
{ "ice_cream_much", PeepThoughtType::IceCreamMuch },
{ "candyfloss_much", PeepThoughtType::CandyflossMuch },
{ "pizza_much", PeepThoughtType::PizzaMuch },
{ "popcorn_much", PeepThoughtType::PopcornMuch },
{ "hot_dog_much", PeepThoughtType::HotDogMuch },
{ "tentacle_much", PeepThoughtType::TentacleMuch },
{ "hat_much", PeepThoughtType::HatMuch },
{ "toffee_apple_much", PeepThoughtType::ToffeeAppleMuch },
{ "tshirt_much", PeepThoughtType::TshirtMuch },
{ "doughnut_much", PeepThoughtType::DoughnutMuch },
{ "coffee_much", PeepThoughtType::CoffeeMuch },
{ "chicken_much", PeepThoughtType::ChickenMuch },
{ "lemonade_much", PeepThoughtType::LemonadeMuch },
{ "photo2", PeepThoughtType::Photo2 },
{ "photo3", PeepThoughtType::Photo3 },
{ "photo4", PeepThoughtType::Photo4 },
{ "pretzel", PeepThoughtType::Pretzel },
{ "hot_chocolate", PeepThoughtType::HotChocolate },
{ "iced_tea", PeepThoughtType::IcedTea },
{ "funnel_cake", PeepThoughtType::FunnelCake },
{ "sunglasses", PeepThoughtType::Sunglasses },
{ "beef_noodles", PeepThoughtType::BeefNoodles },
{ "fried_rice_noodles", PeepThoughtType::FriedRiceNoodles },
{ "wonton_soup", PeepThoughtType::WontonSoup },
{ "meatball_soup", PeepThoughtType::MeatballSoup },
{ "fruit_juice", PeepThoughtType::FruitJuice },
{ "soybean_milk", PeepThoughtType::SoybeanMilk },
{ "sujongkwa", PeepThoughtType::Sujongkwa },
{ "sub_sandwich", PeepThoughtType::SubSandwich },
{ "cookie", PeepThoughtType::Cookie },
{ "roast_sausage", PeepThoughtType::RoastSausage },
{ "photo2_much", PeepThoughtType::Photo2Much },
{ "photo3_much", PeepThoughtType::Photo3Much },
{ "photo4_much", PeepThoughtType::Photo4Much },
{ "pretzel_much", PeepThoughtType::PretzelMuch },
{ "hot_chocolate_much", PeepThoughtType::HotChocolateMuch },
{ "iced_tea_much", PeepThoughtType::IcedTeaMuch },
{ "funnel_cake_much", PeepThoughtType::FunnelCakeMuch },
{ "sunglasses_much", PeepThoughtType::SunglassesMuch },
{ "beef_noodles_much", PeepThoughtType::BeefNoodlesMuch },
{ "fried_rice_noodles_much", PeepThoughtType::FriedRiceNoodlesMuch },
{ "wonton_soup_much", PeepThoughtType::WontonSoupMuch },
{ "meatball_soup_much", PeepThoughtType::MeatballSoupMuch },
{ "fruit_juice_much", PeepThoughtType::FruitJuiceMuch },
{ "soybean_milk_much", PeepThoughtType::SoybeanMilkMuch },
{ "sujongkwa_much", PeepThoughtType::SujongkwaMuch },
{ "sub_sandwich_much", PeepThoughtType::SubSandwichMuch },
{ "cookie_much", PeepThoughtType::CookieMuch },
{ "roast_sausage_much", PeepThoughtType::RoastSausageMuch },
{ "help", PeepThoughtType::Help },
{ "running_out", PeepThoughtType::RunningOut },
{ "new_ride", PeepThoughtType::NewRide },
{ "nice_ride_deprecated", PeepThoughtType::NiceRideDeprecated },
{ "excited_deprecated", PeepThoughtType::ExcitedDeprecated },
{ "here_we_are", PeepThoughtType::HereWeAre },
});
ScGuest::ScGuest(EntityId id)
: ScPeep(id)
{
@ -43,6 +172,7 @@ namespace OpenRCT2::Scripting
dukglue_register_property(ctx, &ScGuest::isInPark_get, nullptr, "isInPark");
dukglue_register_property(ctx, &ScGuest::isLost_get, nullptr, "isLost");
dukglue_register_property(ctx, &ScGuest::lostCountdown_get, &ScGuest::lostCountdown_set, "lostCountdown");
dukglue_register_property(ctx, &ScGuest::thoughts_get, nullptr, "thoughts");
}
Guest* ScGuest::GetGuest() const
@ -337,6 +467,75 @@ namespace OpenRCT2::Scripting
}
}
DukValue ScGuest::thoughts_get() const
{
auto ctx = GetContext()->GetScriptEngine().GetContext();
duk_push_array(ctx);
auto peep = GetGuest();
if (peep != nullptr)
{
duk_uarridx_t index = 0;
for (const auto& thought : peep->Thoughts)
{
if (thought.type == PeepThoughtType::None)
break;
if (thought.freshness == 0)
continue;
auto scThoughtPtr = std::make_shared<ScThought>(thought);
auto dukThought = GetObjectAsDukValue(ctx, scThoughtPtr);
dukThought.push();
duk_put_prop_index(ctx, -2, index);
index++;
}
}
return DukValue::take_from_stack(ctx, -1);
}
ScThought::ScThought(PeepThought backing)
: _backing(backing)
{
}
void ScThought::Register(duk_context* ctx)
{
dukglue_register_property(ctx, &ScThought::type_get, nullptr, "type");
dukglue_register_property(ctx, &ScThought::item_get, nullptr, "item");
dukglue_register_property(ctx, &ScThought::freshness_get, nullptr, "freshness");
dukglue_register_property(ctx, &ScThought::freshTimeout_get, nullptr, "freshTimeout");
dukglue_register_method(ctx, &ScThought::toString, "toString");
}
std::string ScThought::type_get() const
{
return std::string(ThoughtTypeMap[_backing.type]);
}
uint16_t ScThought::item_get() const
{
return _backing.item;
}
uint8_t ScThought::freshness_get() const
{
return _backing.freshness;
}
uint8_t ScThought::freshTimeout_get() const
{
return _backing.fresh_timeout;
}
std::string ScThought::toString() const
{
// format string with arguments
auto ft = Formatter();
peep_thought_set_format_args(&_backing, ft);
return format_string(STR_STRINGID, ft.Data());
}
} // namespace OpenRCT2::Scripting
#endif

View File

@ -11,10 +11,29 @@
#ifdef ENABLE_SCRIPTING
# include "../../../entity/Guest.h"
# include "ScPeep.hpp"
namespace OpenRCT2::Scripting
{
class ScThought
{
private:
PeepThought _backing;
public:
ScThought(PeepThought backing);
static void Register(duk_context* ctx);
private:
std::string type_get() const;
uint16_t item_get() const;
uint8_t freshness_get() const;
uint8_t freshTimeout_get() const;
std::string toString() const;
};
class ScGuest : public ScPeep
{
public:
@ -82,6 +101,8 @@ namespace OpenRCT2::Scripting
uint8_t lostCountdown_get() const;
void lostCountdown_set(uint8_t value);
DukValue thoughts_get() const;
};
} // namespace OpenRCT2::Scripting