diff options
author | Shauren <shauren.trinity@gmail.com> | 2020-01-03 21:55:45 +0100 |
---|---|---|
committer | Shauren <shauren.trinity@gmail.com> | 2022-10-04 00:19:38 +0200 |
commit | 76be303351ae398b7f9e69e4c472cb5b05fce45e (patch) | |
tree | b7139aa70f1e9492fe8b94224fee28bbbe1ec34c /src/server/game/Instances/InstanceScript.h | |
parent | 9b924522d0549dd67b10e2cbdfc20297dd21e182 (diff) |
Core/Scripts: Save instance data in JSON format
Diffstat (limited to 'src/server/game/Instances/InstanceScript.h')
-rw-r--r-- | src/server/game/Instances/InstanceScript.h | 112 |
1 files changed, 97 insertions, 15 deletions
diff --git a/src/server/game/Instances/InstanceScript.h b/src/server/game/Instances/InstanceScript.h index 77c8886628d..a296877d123 100644 --- a/src/server/game/Instances/InstanceScript.h +++ b/src/server/game/Instances/InstanceScript.h @@ -22,9 +22,9 @@ #include "Common.h" #include "Duration.h" #include <array> -#include <iosfwd> #include <map> #include <set> +#include <variant> #define OUT_SAVE_INST_DATA TC_LOG_DEBUG("scripts", "Saving Instance Data for Instance %s (Map %d, Instance Id %d)", instance->GetMapName(), instance->GetId(), instance->GetInstanceId()) #define OUT_SAVE_INST_DATA_COMPLETE TC_LOG_DEBUG("scripts", "Saving Instance Data for Instance %s (Map %d, Instance Id %d) completed.", instance->GetMapName(), instance->GetId(), instance->GetInstanceId()) @@ -37,6 +37,7 @@ class Creature; class GameObject; class InstanceMap; class ModuleReference; +class PersistentInstanceScriptValueBase; class Player; class Unit; struct DungeonEncounterEntry; @@ -154,12 +155,21 @@ struct MinionInfo BossInfo* bossInfo; }; -struct UpdateSaveDataEvent +struct UpdateBossStateSaveDataEvent { + DungeonEncounterEntry const* DungeonEncounter; uint32 BossId; EncounterState NewState; }; +struct UpdateAdditionalSaveDataEvent +{ + explicit UpdateAdditionalSaveDataEvent(char const* key, std::variant<int64, double> value) : Key(key), Value(value) { } + + char const* Key; + std::variant<int64, double> Value; +}; + typedef std::multimap<uint32 /*entry*/, DoorInfo> DoorInfoMap; typedef std::pair<DoorInfoMap::const_iterator, DoorInfoMap::const_iterator> DoorInfoMapBounds; @@ -180,14 +190,13 @@ class TC_GAME_API InstanceScript : public ZoneScript // if we're starting without any saved instance data virtual void Create(); // if we're loading existing instance save data - virtual void Load(char const* data); + void Load(char const* data); // When save is needed, this function generates the data - virtual std::string GetSaveData(); - - virtual std::string UpdateSaveData(std::string const& oldData, UpdateSaveDataEvent const& event); + std::string GetSaveData(); - void SaveToDB(); + std::string UpdateBossStateSaveData(std::string const& oldData, UpdateBossStateSaveDataEvent const& event); + std::string UpdateAdditionalSaveData(std::string const& oldData, UpdateAdditionalSaveDataEvent const& event); virtual void Update(uint32 /*diff*/) { } void UpdateCombatResurrection(uint32 diff); @@ -307,6 +316,10 @@ class TC_GAME_API InstanceScript : public ZoneScript uint8 GetCombatResurrectionCharges() const { return _combatResurrectionCharges; } uint32 GetCombatResurrectionChargeInterval() const; + void RegisterPersistentScriptValue(PersistentInstanceScriptValueBase* value) { _persistentScriptValues.push_back(value); } + std::string const& GetHeader() const { return headers; } + std::vector<PersistentInstanceScriptValueBase*>& GetPersistentScriptValues() { return _persistentScriptValues; } + protected: void SetHeaders(std::string const& dataHeaders); void SetBossNumber(uint32 number) { bosses.resize(number); } @@ -337,13 +350,8 @@ class TC_GAME_API InstanceScript : public ZoneScript // Pay very much attention at how the returned BossInfo data is modified to avoid issues. BossInfo* GetBossInfo(uint32 id); - // Instance Load and Save - bool ReadSaveDataHeaders(std::istringstream& data); - void ReadSaveDataBossStates(std::istringstream& data); - virtual void ReadSaveDataMore(std::istringstream& /*data*/) { } - void WriteSaveDataHeaders(std::ostringstream& data); - void WriteSaveDataBossStates(std::ostringstream& data); - virtual void WriteSaveDataMore(std::ostringstream& /*data*/) { } + // Override this function to validate all additional data loads + virtual void AfterDataLoad() { } bool _SkipCheckRequiredBosses(Player const* player = nullptr) const; @@ -352,8 +360,11 @@ class TC_GAME_API InstanceScript : public ZoneScript void LoadDungeonEncounterData(uint32 bossId, std::array<uint32, MAX_DUNGEON_ENCOUNTERS_PER_BOSS> const& dungeonEncounterIds); void UpdateEncounterState(EncounterCreditType type, uint32 creditEntry, Unit* source); - std::vector<char> headers; + void SaveToDB(); + + std::string headers; std::vector<BossInfo> bosses; + std::vector<PersistentInstanceScriptValueBase*> _persistentScriptValues; DoorInfoMap doors; MinionInfoMap minions; ObjectInfoMap _creatureInfo; @@ -376,4 +387,75 @@ class TC_GAME_API InstanceScript : public ZoneScript friend class debug_commandscript; }; +class TC_GAME_API PersistentInstanceScriptValueBase +{ +protected: + PersistentInstanceScriptValueBase(InstanceScript& instance, char const* name, std::variant<int64, double> value); + +public: + virtual ~PersistentInstanceScriptValueBase(); + + char const* GetName() const { return _name; } + + UpdateAdditionalSaveDataEvent CreateEvent() const + { + return UpdateAdditionalSaveDataEvent(_name, _value); + } + + void LoadValue(int64 value) + { + _value.emplace<int64>(value); + } + + void LoadValue(double value) + { + _value.emplace<double>(value); + } + +protected: + void NotifyValueChanged(); + + InstanceScript& _instance; + char const* _name; + std::variant<int64, double> _value; +}; + +template<typename T> +class PersistentInstanceScriptValue : public PersistentInstanceScriptValueBase +{ +public: + PersistentInstanceScriptValue(InstanceScript& instance, char const* name, T value = {}) + : PersistentInstanceScriptValueBase(instance, name, WrapValue(value)) + { + } + + operator T() const + { + return std::visit([](auto v) { return static_cast<T>(v); }, _value); + } + + PersistentInstanceScriptValue& operator=(T value) + { + _value = WrapValue(value); + NotifyValueChanged(); + return *this; + } + + void LoadValue(T value) + { + _value = WrapValue(value); + } + +private: + static std::variant<int64, double> WrapValue(T value) + { + if constexpr (std::is_integral_v<T> || std::is_enum_v<T>) + return int64(value); + else if constexpr (std::is_floating_point_v<T>) + return double(value); + else + return {}; + } +}; + #endif // TRINITY_INSTANCE_DATA_H |