From f5f8f5bd8e7ac58dce2996e41f20b8b5301fbcc0 Mon Sep 17 00:00:00 2001 From: Ted John Date: Fri, 15 May 2020 00:24:24 +0100 Subject: [PATCH] Use named flags for Peep instead of number --- distribution/openrct2.d.ts | 45 +++++++++++++++++++++++--- src/openrct2/scripting/Duktape.hpp | 40 +++++++++++++++++++++++ src/openrct2/scripting/ScEntity.hpp | 50 ++++++++++++++++++++++++++--- 3 files changed, 125 insertions(+), 10 deletions(-) diff --git a/distribution/openrct2.d.ts b/distribution/openrct2.d.ts index d87043a963..c0737a0c55 100644 --- a/distribution/openrct2.d.ts +++ b/distribution/openrct2.d.ts @@ -730,11 +730,6 @@ declare global { */ name: string; - /** - * Main flags for peep behaviour. - */ - flags: number; - /** * The peep's direct destination. */ @@ -749,8 +744,48 @@ declare global { * The target energy value. Energy will increase / decrease slowly towards this value. */ energyTarget: number; + + /** + * Gets whether a given flag is set or not. + * @param key The flag to test. + */ + getFlag(key: PeepFlags): boolean; + + /** + * Sets the given flag to the given value. + * @param key The flag to set. + * @param value Whether to set or clear the flag. + */ + setFlag(key: PeepFlags, value: boolean): void; } + type PeepFlags = + "leavingPark" | + "slowWalk" | + "tracking" | + "waving" | + "hasPaidForParkEntry" | + "photo" | + "painting" | + "wow" | + "litter" | + "lost" | + "hunger" | + "toilet" | + "crowded" | + "happiness" | + "nausea" | + "purple" | + "pizza" | + "explode" | + "rideShouldBeMarkedAsFavourite" | + "parkEntranceChosen" | + "contagious" | + "joy" | + "angry" | + "iceCream" | + "hereWeAre"; + type PeepType = "guest" | "staff"; /** diff --git a/src/openrct2/scripting/Duktape.hpp b/src/openrct2/scripting/Duktape.hpp index 4057c4d013..2563727885 100644 --- a/src/openrct2/scripting/Duktape.hpp +++ b/src/openrct2/scripting/Duktape.hpp @@ -185,6 +185,46 @@ namespace OpenRCT2::Scripting DukStackFrame(DukStackFrame&&) = delete; }; + /** + * Bi-directional map for converting between strings and enums / numbers. + */ + template class DukEnumMap + { + private: + std::unordered_map _s2n; + std::unordered_map _n2s; + + public: + DukEnumMap(const std::initializer_list>& items) + { + _s2n = std::unordered_map(items.begin(), items.end()); + for (const auto& kvp : items) + { + _n2s.emplace(std::get<1>(kvp), std::get<0>(kvp)); + } + } + + std::string_view operator[](T k) const + { + auto it = _n2s.find(k); + if (it == _n2s.end()) + { + return ""; + } + return it->second; + } + + T operator[](const std::string_view& k) const + { + auto it = _s2n.find(k); + if (it == _s2n.end()) + { + return 0; + } + return it->second; + } + }; + inline duk_ret_t duk_json_decode_wrapper(duk_context* ctx, void*) { duk_json_decode(ctx, -1); diff --git a/src/openrct2/scripting/ScEntity.hpp b/src/openrct2/scripting/ScEntity.hpp index 9383eeb68e..4ddcc44528 100644 --- a/src/openrct2/scripting/ScEntity.hpp +++ b/src/openrct2/scripting/ScEntity.hpp @@ -20,6 +20,8 @@ # include "ScriptEngine.h" # include +# include +# include namespace OpenRCT2::Scripting { @@ -174,6 +176,34 @@ namespace OpenRCT2::Scripting } }; + static const DukEnumMap PeepFlagMap({ + { "leavingPark", PEEP_FLAGS_LEAVING_PARK }, + { "slowWalk", PEEP_FLAGS_SLOW_WALK }, + { "tracking", PEEP_FLAGS_TRACKING }, + { "waving", PEEP_FLAGS_WAVING }, + { "hasPaidForParkEntry", PEEP_FLAGS_HAS_PAID_FOR_PARK_ENTRY }, + { "photo", PEEP_FLAGS_PHOTO }, + { "painting", PEEP_FLAGS_PAINTING }, + { "wow", PEEP_FLAGS_WOW }, + { "litter", PEEP_FLAGS_LITTER }, + { "lost", PEEP_FLAGS_LOST }, + { "hunger", PEEP_FLAGS_HUNGER }, + { "toilet", PEEP_FLAGS_TOILET }, + { "crowded", PEEP_FLAGS_CROWDED }, + { "happiness", PEEP_FLAGS_HAPPINESS }, + { "nausea", PEEP_FLAGS_NAUSEA }, + { "purple", PEEP_FLAGS_PURPLE }, + { "pizza", PEEP_FLAGS_PIZZA }, + { "explode", PEEP_FLAGS_EXPLODE }, + { "rideShouldBeMarkedAsFavourite", PEEP_FLAGS_RIDE_SHOULD_BE_MARKED_AS_FAVOURITE }, + { "parkEntranceChosen", PEEP_FLAGS_PARK_ENTRANCE_CHOSEN }, + { "contagious", PEEP_FLAGS_CONTAGIOUS }, + { "joy", PEEP_FLAGS_JOY }, + { "angry", PEEP_FLAGS_ANGRY }, + { "iceCream", PEEP_FLAGS_ICE_CREAM }, + { "hereWeAre", PEEP_FLAGS_HERE_WE_ARE }, + }); + class ScPeep : public ScEntity { public: @@ -187,10 +217,11 @@ namespace OpenRCT2::Scripting dukglue_set_base_class(ctx); dukglue_register_property(ctx, &ScPeep::peepType_get, nullptr, "peepType"); dukglue_register_property(ctx, &ScPeep::name_get, &ScPeep::name_set, "name"); - dukglue_register_property(ctx, &ScPeep::flags_get, &ScPeep::flags_set, "flags"); dukglue_register_property(ctx, &ScPeep::destination_get, &ScPeep::destination_set, "destination"); dukglue_register_property(ctx, &ScPeep::energy_get, &ScPeep::energy_set, "energy"); dukglue_register_property(ctx, &ScPeep::energyTarget_get, &ScPeep::energyTarget_set, "energyTarget"); + dukglue_register_method(ctx, &ScPeep::getFlag, "getFlag"); + dukglue_register_method(ctx, &ScPeep::setFlag, "setFlag"); } private: @@ -219,19 +250,28 @@ namespace OpenRCT2::Scripting } } - uint32_t flags_get() const + bool getFlag(const std::string& key) const { auto peep = GetPeep(); - return peep != nullptr ? peep->peep_flags : 0; + if (peep != nullptr) + { + auto mask = PeepFlagMap[key]; + return (peep->peep_flags & mask) != 0; + } + return false; } - void flags_set(uint32_t value) + void setFlag(const std::string& key, bool value) { ThrowIfGameStateNotMutable(); auto peep = GetPeep(); if (peep != nullptr) { - peep->peep_flags = value; + auto mask = PeepFlagMap[key]; + if (value) + peep->peep_flags |= mask; + else + peep->peep_flags &= ~mask; peep->Invalidate(); } }