aboutsummaryrefslogtreecommitdiff
path: root/src/server/game/Instances/InstanceScript.h
diff options
context:
space:
mode:
authorShauren <shauren.trinity@gmail.com>2020-01-03 21:55:45 +0100
committerShauren <shauren.trinity@gmail.com>2022-10-04 00:19:38 +0200
commit76be303351ae398b7f9e69e4c472cb5b05fce45e (patch)
treeb7139aa70f1e9492fe8b94224fee28bbbe1ec34c /src/server/game/Instances/InstanceScript.h
parent9b924522d0549dd67b10e2cbdfc20297dd21e182 (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.h112
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