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 | |
parent | 9b924522d0549dd67b10e2cbdfc20297dd21e182 (diff) |
Core/Scripts: Save instance data in JSON format
Diffstat (limited to 'src/server')
39 files changed, 740 insertions, 1219 deletions
diff --git a/src/server/game/Instances/InstanceScript.cpp b/src/server/game/Instances/InstanceScript.cpp index 159eb82b89e..9c1956c4dfb 100644 --- a/src/server/game/Instances/InstanceScript.cpp +++ b/src/server/game/Instances/InstanceScript.cpp @@ -27,6 +27,7 @@ #include "Group.h" #include "InstancePackets.h" #include "InstanceScenario.h" +#include "InstanceScriptData.h" #include "LFGMgr.h" #include "Log.h" #include "Map.h" @@ -35,11 +36,11 @@ #include "Player.h" #include "RBAC.h" #include "ScriptReloadMgr.h" +#include "SmartEnum.h" #include "SpellMgr.h" #include "World.h" #include "WorldSession.h" #include "WorldStateMgr.h" -#include <sstream> #include <cstdarg> #ifdef TRINITY_API_USE_DYNAMIC_LINKING @@ -83,17 +84,6 @@ void InstanceScript::SaveToDB() { if (InstanceScenario* scenario = instance->GetInstanceScenario()) scenario->SaveToDB(); - - std::string data = GetSaveData(); - if (data.empty()) - return; - - CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_INSTANCE_DATA); - stmt->setUInt32(0, GetCompletedEncounterMask()); - stmt->setString(1, data); - stmt->setUInt32(2, _entranceId); - stmt->setUInt32(3, instance->GetInstanceId()); - CharacterDatabase.Execute(stmt); } bool InstanceScript::IsEncounterInProgress() const @@ -171,9 +161,7 @@ GameObject* InstanceScript::GetGameObject(uint32 type) void InstanceScript::SetHeaders(std::string const& dataHeaders) { - for (char header : dataHeaders) - if (isalpha(header)) - headers.push_back(header); + headers = dataHeaders; } void InstanceScript::LoadBossBoundaries(BossBoundaryData const& data) @@ -451,8 +439,8 @@ bool InstanceScript::SetBossState(uint32 id, EncounterState state) bossInfo->state = state; SaveToDB(); - if (state == DONE && dungeonEncounter) - instance->UpdateInstanceLock(dungeonEncounter, { id, state }); + if (dungeonEncounter) + instance->UpdateInstanceLock({ dungeonEncounter, id, state }); } for (uint32 type = 0; type < MAX_DOOR_TYPES; ++type) @@ -493,12 +481,11 @@ void InstanceScript::Load(char const* data) OUT_LOAD_INST_DATA(data); - std::istringstream loadStream(data); - - if (ReadSaveDataHeaders(loadStream)) + InstanceScriptDataReader reader(*this); + if (reader.Load(data) == InstanceScriptDataReader::Result::Ok) { - ReadSaveDataBossStates(loadStream); - ReadSaveDataMore(loadStream); + UpdateSpawnGroups(); + AfterDataLoad(); } else OUT_LOAD_INST_DATA_FAIL; @@ -506,86 +493,39 @@ void InstanceScript::Load(char const* data) OUT_LOAD_INST_DATA_COMPLETE; } -bool InstanceScript::ReadSaveDataHeaders(std::istringstream& data) -{ - for (char header : headers) - { - char buff; - data >> buff; - - if (header != buff) - return false; - } - - return true; -} - -void InstanceScript::ReadSaveDataBossStates(std::istringstream& data) -{ - uint32 bossId = 0; - for (; bossId < bosses.size(); ++bossId) - { - uint32 buff; - data >> buff; - if (buff == IN_PROGRESS || buff == FAIL || buff == SPECIAL) - buff = NOT_STARTED; - - if (buff < TO_BE_DECIDED) - SetBossState(bossId, EncounterState(buff)); - } - UpdateSpawnGroups(); -} - std::string InstanceScript::GetSaveData() { OUT_SAVE_INST_DATA; - std::ostringstream saveStream; + InstanceScriptDataWriter writer(*this); - WriteSaveDataHeaders(saveStream); - WriteSaveDataBossStates(saveStream); - WriteSaveDataMore(saveStream); + writer.FillData(); OUT_SAVE_INST_DATA_COMPLETE; - return saveStream.str(); + return writer.GetString(); } -std::string InstanceScript::UpdateSaveData(std::string const& oldData, UpdateSaveDataEvent const& event) +std::string InstanceScript::UpdateBossStateSaveData(std::string const& oldData, UpdateBossStateSaveDataEvent const& event) { if (!instance->GetMapDifficulty()->IsUsingEncounterLocks()) return GetSaveData(); - std::size_t position = (headers.size() + event.BossId) * 2; - std::string newData = oldData; - if (position >= oldData.length()) - { - // Initialize blank data - std::ostringstream saveStream; - WriteSaveDataHeaders(saveStream); - for (std::size_t i = 0; i < bosses.size(); ++i) - saveStream << uint32(NOT_STARTED) << ' '; - - WriteSaveDataMore(saveStream); - - newData = saveStream.str(); - } - - newData[position] = uint32(event.NewState) + '0'; - - return newData; + InstanceScriptDataWriter writer(*this); + writer.FillDataFrom(oldData); + writer.SetBossState(event); + return writer.GetString(); } -void InstanceScript::WriteSaveDataHeaders(std::ostringstream& data) +std::string InstanceScript::UpdateAdditionalSaveData(std::string const& oldData, UpdateAdditionalSaveDataEvent const& event) { - for (char header : headers) - data << header << ' '; -} + if (!instance->GetMapDifficulty()->IsUsingEncounterLocks()) + return GetSaveData(); -void InstanceScript::WriteSaveDataBossStates(std::ostringstream& data) -{ - for (BossInfo const& bossInfo : bosses) - data << uint32(bossInfo.state) << ' '; + InstanceScriptDataWriter writer(*this); + writer.FillDataFrom(oldData); + writer.SetAdditionalData(event); + return writer.GetString(); } void InstanceScript::HandleGameObject(ObjectGuid guid, bool open, GameObject* go /*= nullptr*/) @@ -935,26 +875,9 @@ void InstanceScript::UpdatePhasing() }); } -/*static*/ char const* InstanceScript::GetBossStateName(uint8 state) +char const* InstanceScript::GetBossStateName(uint8 state) { - // See enum EncounterState in InstanceScript.h - switch (state) - { - case NOT_STARTED: - return "NOT_STARTED"; - case IN_PROGRESS: - return "IN_PROGRESS"; - case FAIL: - return "FAIL"; - case DONE: - return "DONE"; - case SPECIAL: - return "SPECIAL"; - case TO_BE_DECIDED: - return "TO_BE_DECIDED"; - default: - return "INVALID"; - } + return EnumUtils::ToConstant(EncounterState(state)); } void InstanceScript::UpdateCombatResurrection(uint32 diff) @@ -1012,6 +935,19 @@ uint32 InstanceScript::GetCombatResurrectionChargeInterval() const return interval; } +PersistentInstanceScriptValueBase::PersistentInstanceScriptValueBase(InstanceScript& instance, char const* name, std::variant<int64, double> value) + : _instance(instance), _name(name), _value(std::move(value)) +{ + _instance.RegisterPersistentScriptValue(this); +} + +PersistentInstanceScriptValueBase::~PersistentInstanceScriptValueBase() = default; + +void PersistentInstanceScriptValueBase::NotifyValueChanged() +{ + _instance.instance->UpdateInstanceLock(CreateEvent()); +} + bool InstanceHasScript(WorldObject const* obj, char const* scriptName) { if (InstanceMap* instance = obj->GetMap()->ToInstanceMap()) 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 diff --git a/src/server/game/Instances/InstanceScriptData.cpp b/src/server/game/Instances/InstanceScriptData.cpp new file mode 100644 index 00000000000..ee19a912742 --- /dev/null +++ b/src/server/game/Instances/InstanceScriptData.cpp @@ -0,0 +1,270 @@ +/* + * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "InstanceScriptData.h" +#include "DB2Stores.h" +#include "InstanceScript.h" +#include "Log.h" +#include "Map.h" +#include "World.h" +#include <rapidjson/pointer.h> +#include <rapidjson/stringbuffer.h> +#include <rapidjson/writer.h> +#include <rapidjson/error/en.h> + +namespace +{ + std::string const HeadersKey = "Header"; + + std::string const BossStatesSaveDataKey = "BossStates"; + + std::string const MoreSaveDataKey = "AdditionalData"; +} + +InstanceScriptDataReader::Result InstanceScriptDataReader::Load(char const* data) +{ + /* + Expected JSON + + { + "Header": "HEADER_STRING_SET_BY_SCRIPT", + "BossStates": [0,2,0,...] // indexes are boss ids, values are EncounterState + "AdditionalData: { // optional + "ExtraKey1": 123 + "AnotherExtraKey": 2.0 + } + } + */ + if (_doc.Parse(data).HasParseError()) + { + TC_LOG_ERROR("scripts.data.load", "JSON parser error %s at " SZFMTD " while loading data for instance %u [%u-%s | %u-%s]", + rapidjson::GetParseError_En(_doc.GetParseError()), _doc.GetErrorOffset(), + GetInstanceId(), GetMapId(), GetMapName(), GetDifficultyId(), GetDifficultyName()); + return Result::MalformedJson; + } + + if (!_doc.IsObject()) + { + TC_LOG_ERROR("scripts.data.load", "Root JSON value is not an object for instance %u [%u-%s | %u-%s]", + GetInstanceId(), GetMapId(), GetMapName(), GetDifficultyId(), GetDifficultyName()); + return Result::RootIsNotAnObject; + } + + Result result = ParseHeader(); + if (result != Result::Ok) + return result; + + result = ParseBossStates(); + if (result != Result::Ok) + return result; + + result = ParseAdditionalData(); + if (result != Result::Ok) + return result; + + return Result::Ok; +} + +InstanceScriptDataReader::Result InstanceScriptDataReader::ParseHeader() +{ + auto headerItr = _doc.FindMember(HeadersKey); + if (headerItr == _doc.MemberEnd()) + { + TC_LOG_ERROR("scripts.data.load", "Missing data header for instance %u [%u-%s | %u-%s]", + GetInstanceId(), GetMapId(), GetMapName(), GetDifficultyId(), GetDifficultyName()); + return Result::MissingHeader; + } + + if (headerItr->value != _instance.GetHeader()) + { + TC_LOG_ERROR("scripts.data.load", "Incorrect data header for instance %u [%u-%s | %u-%s], expected \"%s\" got \"%s\"", + GetInstanceId(), GetMapId(), GetMapName(), GetDifficultyId(), GetDifficultyName(), + _instance.GetHeader().c_str(), headerItr->value.IsString() ? headerItr->value.GetString() : ""); + return Result::UnexpectedHeader; + } + + return Result::Ok; +} + +InstanceScriptDataReader::Result InstanceScriptDataReader::ParseBossStates() +{ + auto bossStatesItr = _doc.FindMember(BossStatesSaveDataKey); + if (bossStatesItr == _doc.MemberEnd()) + { + TC_LOG_ERROR("scripts.data.load", "Missing boss states for instance %u [%u-%s | %u-%s]", + GetInstanceId(), GetMapId(), GetMapName(), GetDifficultyId(), GetDifficultyName()); + return Result::MissingBossStates; + } + + if (!bossStatesItr->value.IsArray()) + { + TC_LOG_ERROR("scripts.data.load", "Boss states is not an array for instance %u [%u-%s | %u-%s]", + GetInstanceId(), GetMapId(), GetMapName(), GetDifficultyId(), GetDifficultyName()); + return Result::BossStatesIsNotAnObject; + } + + for (uint32 bossId = 0; bossId < bossStatesItr->value.Size(); ++bossId) + { + if (bossId >= _instance.GetEncounterCount()) + { + TC_LOG_ERROR("scripts.data.load", "Boss states has entry for boss with higher id (%u) than number of bosses (%u) for instance %u [%u-%s | %u-%s]", + bossId, _instance.GetEncounterCount(), GetInstanceId(), GetMapId(), GetMapName(), GetDifficultyId(), GetDifficultyName()); + return Result::UnknownBoss; + } + + auto& bossState = bossStatesItr->value[bossId]; + if (!bossState.IsNumber()) + { + TC_LOG_ERROR("scripts.data.load", "Boss state for boss (%u) is not a number for instance %u [%u-%s | %u-%s]", + bossId, GetInstanceId(), GetMapId(), GetMapName(), GetDifficultyId(), GetDifficultyName()); + return Result::BossStateIsNotAnObject; + } + + EncounterState state = EncounterState(bossState.GetInt()); + if (state == IN_PROGRESS || state == FAIL || state == SPECIAL) + state = NOT_STARTED; + + if (state < TO_BE_DECIDED) + _instance.SetBossState(bossId, state); + } + + return Result::Ok; +} + +InstanceScriptDataReader::Result InstanceScriptDataReader::ParseAdditionalData() +{ + auto moreDataItr = _doc.FindMember(MoreSaveDataKey); + if (moreDataItr == _doc.MemberEnd()) + return Result::Ok; + + if (!moreDataItr->value.IsObject()) + { + TC_LOG_ERROR("scripts.data.load", "Additional data is not an object for instance %u [%u-%s | %u-%s]", + GetInstanceId(), GetMapId(), GetMapName(), GetDifficultyId(), GetDifficultyName()); + return Result::AdditionalDataIsNotAnObject; + } + + for (PersistentInstanceScriptValueBase* value : _instance.GetPersistentScriptValues()) + { + auto valueItr = moreDataItr->value.FindMember(value->GetName()); + if (valueItr != moreDataItr->value.MemberEnd() && !valueItr->value.IsNull()) + { + if (!valueItr->value.IsNumber()) + { + TC_LOG_ERROR("scripts.data.load", "Additional data value for key %s is not a number for instance %u [%u-%s | %u-%s]", + value->GetName(), GetInstanceId(), GetMapId(), GetMapName(), GetDifficultyId(), GetDifficultyName()); + return Result::AdditionalDataUnexpectedValueType; + } + + if (valueItr->value.IsDouble()) + value->LoadValue(valueItr->value.GetDouble()); + else + value->LoadValue(valueItr->value.GetInt64()); + } + } + + return Result::Ok; +} + +uint32 InstanceScriptDataReader::GetInstanceId() const { return _instance.instance->GetInstanceId(); } +uint32 InstanceScriptDataReader::GetMapId() const { return _instance.instance->GetId(); } +char const* InstanceScriptDataReader::GetMapName() const { return _instance.instance->GetMapName(); } +uint32 InstanceScriptDataReader::GetDifficultyId() const { return uint32(_instance.instance->GetDifficultyID()); } +char const* InstanceScriptDataReader::GetDifficultyName() const { return sDifficultyStore.AssertEntry(_instance.instance->GetDifficultyID())->Name[sWorld->GetDefaultDbcLocale()]; } + +std::string InstanceScriptDataWriter::GetString() +{ + rapidjson::StringBuffer buffer; + rapidjson::Writer<rapidjson::StringBuffer> writer(buffer); + _doc.Accept(writer); + + return std::string(buffer.GetString(), buffer.GetSize()); +} + +void InstanceScriptDataWriter::FillData(bool withValues) +{ + _doc.SetObject(); + _doc.AddMember(rapidjson::StringRef(HeadersKey), _instance.GetHeader(), _doc.GetAllocator()); + + rapidjson::Value bossStates(rapidjson::kArrayType); + for (uint32 bossId = 0; bossId < _instance.GetEncounterCount(); ++bossId) + { + rapidjson::Value bossStateValue(rapidjson::kNumberType); + bossStateValue.SetInt(withValues ? _instance.GetBossState(bossId) : NOT_STARTED); + bossStates.PushBack(bossStateValue.Move(), _doc.GetAllocator()); + } + _doc.AddMember(rapidjson::StringRef(BossStatesSaveDataKey), bossStates.Move(), _doc.GetAllocator()); + + if (!_instance.GetPersistentScriptValues().empty()) + { + rapidjson::Value moreData(rapidjson::kObjectType); + for (PersistentInstanceScriptValueBase* additionalValue : _instance.GetPersistentScriptValues()) + { + if (withValues) + { + UpdateAdditionalSaveDataEvent data = additionalValue->CreateEvent(); + std::visit([&](auto v) + { + moreData.AddMember(rapidjson::StringRef(data.Key), rapidjson::Value(v), _doc.GetAllocator()); + }, data.Value); + } + else + moreData.AddMember(rapidjson::StringRef(additionalValue->GetName()), rapidjson::Value(), _doc.GetAllocator()); + } + + _doc.AddMember(rapidjson::StringRef(MoreSaveDataKey), moreData.Move(), _doc.GetAllocator()); + } +} + +void InstanceScriptDataWriter::FillDataFrom(std::string const& data) +{ + if (_doc.Parse(data).HasParseError()) + FillData(false); +} + +void InstanceScriptDataWriter::SetBossState(UpdateBossStateSaveDataEvent const& data) +{ + std::string bossIdKey = Trinity::StringFormat("%u", data.BossId); + + rapidjson::Pointer::Token tokens[] = + { + { BossStatesSaveDataKey.c_str(), uint32(BossStatesSaveDataKey.length()), rapidjson::kPointerInvalidIndex }, + { bossIdKey.c_str(), uint32(bossIdKey.length()), rapidjson::kPointerInvalidIndex } + }; + rapidjson::Pointer ptr(tokens, std::size(tokens)); + + // jsonptr("/BossStates/BossId") + rapidjson::Value stateValue(rapidjson::kNumberType); + stateValue.SetInt(data.NewState); + rapidjson::SetValueByPointer(_doc, ptr, stateValue.Move()); +} + +void InstanceScriptDataWriter::SetAdditionalData(UpdateAdditionalSaveDataEvent const& data) +{ + rapidjson::Pointer::Token tokens[] = + { + { MoreSaveDataKey.c_str(), uint32(MoreSaveDataKey.length()), rapidjson::kPointerInvalidIndex }, + { data.Key, uint32(strlen(data.Key)), rapidjson::kPointerInvalidIndex } + }; + rapidjson::Pointer ptr(tokens, std::size(tokens)); + + // jsonptr("/AdditionalData/CustomValueName") + std::visit([&](auto v) + { + rapidjson::SetValueByPointer(_doc, ptr, v); + }, data.Value); +} diff --git a/src/server/game/Instances/InstanceScriptData.h b/src/server/game/Instances/InstanceScriptData.h new file mode 100644 index 00000000000..c489123d625 --- /dev/null +++ b/src/server/game/Instances/InstanceScriptData.h @@ -0,0 +1,86 @@ +/* + * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef InstanceScriptData_h__ +#define InstanceScriptData_h__ + +#include "Errors.h" // rapidjson depends on WPAssert +#include <rapidjson/document.h> +#include <string> + +class InstanceScript; +struct UpdateBossStateSaveDataEvent; +struct UpdateAdditionalSaveDataEvent; + +class InstanceScriptDataReader +{ +public: + enum class Result + { + Ok, + MalformedJson, + RootIsNotAnObject, + MissingHeader, + UnexpectedHeader, + MissingBossStates, + BossStatesIsNotAnObject, + UnknownBoss, + BossStateIsNotAnObject, + MissingBossState, + BossStateValueIsNotANumber, + AdditionalDataIsNotAnObject, + AdditionalDataUnexpectedValueType + }; + + InstanceScriptDataReader(InstanceScript& instance) : _instance(instance) { } + + Result Load(char const* data); + +private: + Result ParseHeader(); + Result ParseBossStates(); + Result ParseAdditionalData(); + + // logging helpers + uint32 GetInstanceId() const; + uint32 GetMapId() const; + char const* GetMapName() const; + uint32 GetDifficultyId() const; + char const* GetDifficultyName() const; + + InstanceScript& _instance; + rapidjson::Document _doc; +}; + +class InstanceScriptDataWriter +{ +public: + InstanceScriptDataWriter(InstanceScript& instance) : _instance(instance) { } + + std::string GetString(); + void FillData(bool withValues = true); + void FillDataFrom(std::string const& data); + + void SetBossState(UpdateBossStateSaveDataEvent const& data); + void SetAdditionalData(UpdateAdditionalSaveDataEvent const& data); + +private: + InstanceScript& _instance; + rapidjson::Document _doc; +}; + +#endif // InstanceScriptData_h__ diff --git a/src/server/game/Maps/Map.cpp b/src/server/game/Maps/Map.cpp index 5d2a530b9d7..c8540ac80e7 100644 --- a/src/server/game/Maps/Map.cpp +++ b/src/server/game/Maps/Map.cpp @@ -3014,13 +3014,56 @@ std::string const& InstanceMap::GetScriptName() const return sObjectMgr->GetScriptName(i_script_id); } -void InstanceMap::UpdateInstanceLock(DungeonEncounterEntry const* dungeonEncounter, UpdateSaveDataEvent const& updateSaveDataEvent) +void InstanceMap::UpdateInstanceLock(UpdateBossStateSaveDataEvent const& updateSaveDataEvent) +{ + if (i_instanceLock) + { + uint32 instanceCompletedEncounters = i_instanceLock->GetData()->CompletedEncountersMask | (1u << updateSaveDataEvent.DungeonEncounter->Bit); + + MapDb2Entries entries{ GetEntry(), GetMapDifficulty() }; + + CharacterDatabaseTransaction trans = CharacterDatabase.BeginTransaction(); + + if (entries.IsInstanceIdBound()) + sInstanceLockMgr.UpdateSharedInstanceLock(trans, + { GetInstanceId(), i_data->GetSaveData(), instanceCompletedEncounters, updateSaveDataEvent.DungeonEncounter }); + + for (MapReference& mapReference : m_mapRefManager) + { + Player* player = mapReference.GetSource(); + // never instance bind GMs with GM mode enabled + if (player->IsGameMaster()) + continue; + + InstanceLock const* playerLock = sInstanceLockMgr.FindActiveInstanceLock(player->GetGUID(), entries); + std::string const* oldData = nullptr; + if (playerLock) + oldData = &playerLock->GetData()->Data; + + bool isNewLock = !playerLock || !playerLock->GetData()->CompletedEncountersMask || playerLock->IsExpired(); + + InstanceLock const* newLock = sInstanceLockMgr.UpdateInstanceLockForPlayer(trans, player->GetGUID(), entries, + { GetInstanceId(), i_data->UpdateBossStateSaveData(oldData ? *oldData : "", updateSaveDataEvent), instanceCompletedEncounters, updateSaveDataEvent.DungeonEncounter }); + + if (isNewLock) + { + WorldPackets::Instance::InstanceSaveCreated data; + data.Gm = player->IsGameMaster(); + player->SendDirectMessage(data.Write()); + + player->GetSession()->SendCalendarRaidLockoutAdded(newLock); + } + } + + CharacterDatabase.CommitTransaction(trans); + } +} + +void InstanceMap::UpdateInstanceLock(UpdateAdditionalSaveDataEvent const& updateSaveDataEvent) { if (i_instanceLock) { uint32 instanceCompletedEncounters = i_instanceLock->GetData()->CompletedEncountersMask; - if (dungeonEncounter) - instanceCompletedEncounters |= 1u << dungeonEncounter->Bit; MapDb2Entries entries{ GetEntry(), GetMapDifficulty() }; @@ -3028,7 +3071,7 @@ void InstanceMap::UpdateInstanceLock(DungeonEncounterEntry const* dungeonEncount if (entries.IsInstanceIdBound()) sInstanceLockMgr.UpdateSharedInstanceLock(trans, - { GetInstanceId(), i_data->GetSaveData(), instanceCompletedEncounters, dungeonEncounter }); + { GetInstanceId(), i_data->GetSaveData(), instanceCompletedEncounters, nullptr }); for (MapReference& mapReference : m_mapRefManager) { @@ -3045,7 +3088,7 @@ void InstanceMap::UpdateInstanceLock(DungeonEncounterEntry const* dungeonEncount bool isNewLock = !playerLock || !playerLock->GetData()->CompletedEncountersMask || playerLock->IsExpired(); InstanceLock const* newLock = sInstanceLockMgr.UpdateInstanceLockForPlayer(trans, player->GetGUID(), entries, - { GetInstanceId(), i_data->UpdateSaveData(oldData ? *oldData : "", updateSaveDataEvent), instanceCompletedEncounters, dungeonEncounter }); + { GetInstanceId(), i_data->UpdateAdditionalSaveData(oldData ? *oldData : "", updateSaveDataEvent), instanceCompletedEncounters, nullptr }); if (isNewLock) { diff --git a/src/server/game/Maps/Map.h b/src/server/game/Maps/Map.h index 68a81710c64..8f06fd77538 100644 --- a/src/server/game/Maps/Map.h +++ b/src/server/game/Maps/Map.h @@ -65,7 +65,6 @@ class Weather; class WorldObject; class WorldPacket; struct DungeonEncounterEntry; -struct UpdateSaveDataEvent; struct MapDifficultyEntry; struct MapEntry; struct Position; @@ -73,6 +72,8 @@ struct ScriptAction; struct ScriptInfo; struct SmoothPhasingInfo; struct SummonPropertiesEntry; +struct UpdateAdditionalSaveDataEvent; +struct UpdateBossStateSaveDataEvent; class Transport; enum Difficulty : uint8; enum WeatherState : uint32; @@ -814,7 +815,8 @@ class TC_GAME_API InstanceMap : public Map InstanceScenario const* GetInstanceScenario() const { return i_scenario; } void SetInstanceScenario(InstanceScenario* scenario) { i_scenario = scenario; } InstanceLock const* GetInstanceLock() const { return i_instanceLock; } - void UpdateInstanceLock(DungeonEncounterEntry const* dungeonEncounter, UpdateSaveDataEvent const& updateSaveDataEvent); + void UpdateInstanceLock(UpdateBossStateSaveDataEvent const& updateSaveDataEvent); + void UpdateInstanceLock(UpdateAdditionalSaveDataEvent const& updateSaveDataEvent); void CreateInstanceLockForPlayer(Player* player); void UnloadAll() override; EnterState CannotEnter(Player* player) override; diff --git a/src/server/scripts/Commands/cs_instance.cpp b/src/server/scripts/Commands/cs_instance.cpp index 63d43b525bf..210f23ebae4 100644 --- a/src/server/scripts/Commands/cs_instance.cpp +++ b/src/server/scripts/Commands/cs_instance.cpp @@ -164,23 +164,23 @@ public: static bool HandleInstanceSaveDataCommand(ChatHandler* handler) { - Player* player = handler->GetSession()->GetPlayer(); - InstanceMap* map = player->GetMap()->ToInstanceMap(); - if (!map) - { - handler->PSendSysMessage(LANG_NOT_DUNGEON); - handler->SetSentErrorMessage(true); - return false; - } + //Player* player = handler->GetSession()->GetPlayer(); + //InstanceMap* map = player->GetMap()->ToInstanceMap(); + //if (!map) + //{ + // handler->PSendSysMessage(LANG_NOT_DUNGEON); + // handler->SetSentErrorMessage(true); + // return false; + //} - if (!map->GetInstanceScript()) - { - handler->PSendSysMessage(LANG_NO_INSTANCE_DATA); - handler->SetSentErrorMessage(true); - return false; - } + //if (!map->GetInstanceScript()) + //{ + // handler->PSendSysMessage(LANG_NO_INSTANCE_DATA); + // handler->SetSentErrorMessage(true); + // return false; + //} - map->GetInstanceScript()->SaveToDB(); + //map->GetInstanceScript()->SaveToDB(); return true; } diff --git a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/instance_blackrock_depths.cpp b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/instance_blackrock_depths.cpp index 8c06fa25d62..61f938dfd2c 100644 --- a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/instance_blackrock_depths.cpp +++ b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/instance_blackrock_depths.cpp @@ -22,7 +22,6 @@ #include "Log.h" #include "Map.h" #include "ScriptedCreature.h" -#include <sstream> #define TIMER_TOMBOFTHESEVEN 15000 #define MAX_ENCOUNTER 6 @@ -84,7 +83,7 @@ public: instance_blackrock_depths_InstanceMapScript(InstanceMap* map) : InstanceScript(map) { SetHeaders(DataHeader); - memset(&encounter, 0, sizeof(encounter)); + SetBossNumber(MAX_ENCOUNTER); BarAleCount = 0; GhostKillCount = 0; @@ -92,9 +91,6 @@ public: TombEventCounter = 0; } - uint32 encounter[MAX_ENCOUNTER]; - std::string str_data; - ObjectGuid EmperorGUID; ObjectGuid PhalanxGUID; ObjectGuid MagmusGUID; @@ -210,44 +206,30 @@ public: switch (type) { case TYPE_RING_OF_LAW: - encounter[0] = data; + SetBossState(0, EncounterState(data)); break; case TYPE_VAULT: - encounter[1] = data; + SetBossState(1, EncounterState(data)); break; case TYPE_BAR: if (data == SPECIAL) ++BarAleCount; else - encounter[2] = data; + SetBossState(2, EncounterState(data)); break; case TYPE_TOMB_OF_SEVEN: - encounter[3] = data; + SetBossState(3, EncounterState(data)); break; case TYPE_LYCEUM: - encounter[4] = data; + SetBossState(4, EncounterState(data)); break; case TYPE_IRON_HALL: - encounter[5] = data; + SetBossState(5, EncounterState(data)); break; case DATA_GHOSTKILL: GhostKillCount += data; break; } - - if (data == DONE || GhostKillCount >= TOMB_OF_SEVEN_BOSS_NUM) - { - OUT_SAVE_INST_DATA; - - std::ostringstream saveStream; - saveStream << encounter[0] << ' ' << encounter[1] << ' ' << encounter[2] << ' ' - << encounter[3] << ' ' << encounter[4] << ' ' << encounter[5] << ' ' << GhostKillCount; - - str_data = saveStream.str(); - - SaveToDB(); - OUT_SAVE_INST_DATA_COMPLETE; - } } uint32 GetData(uint32 type) const override @@ -255,20 +237,20 @@ public: switch (type) { case TYPE_RING_OF_LAW: - return encounter[0]; + return GetBossState(0); case TYPE_VAULT: - return encounter[1]; + return GetBossState(1); case TYPE_BAR: - if (encounter[2] == IN_PROGRESS && BarAleCount == 3) + if (GetBossState(2) == IN_PROGRESS && BarAleCount == 3) return SPECIAL; else - return encounter[2]; + return GetBossState(2); case TYPE_TOMB_OF_SEVEN: - return encounter[3]; + return GetBossState(3); case TYPE_LYCEUM: - return encounter[4]; + return GetBossState(4); case TYPE_IRON_HALL: - return encounter[5]; + return GetBossState(5); case DATA_GHOSTKILL: return GhostKillCount; } @@ -319,36 +301,6 @@ public: return ObjectGuid::Empty; } - std::string GetSaveData() override - { - return str_data; - } - - void Load(char const* in) override - { - if (!in) - { - OUT_LOAD_INST_DATA_FAIL; - return; - } - - OUT_LOAD_INST_DATA(in); - - std::istringstream loadStream(in); - loadStream >> encounter[0] >> encounter[1] >> encounter[2] >> encounter[3] - >> encounter[4] >> encounter[5] >> GhostKillCount; - - for (uint8 i = 0; i < MAX_ENCOUNTER; ++i) - if (encounter[i] == IN_PROGRESS) - encounter[i] = NOT_STARTED; - if (GhostKillCount > 0 && GhostKillCount < TOMB_OF_SEVEN_BOSS_NUM) - GhostKillCount = 0;//reset tomb of seven event - if (GhostKillCount >= TOMB_OF_SEVEN_BOSS_NUM) - GhostKillCount = TOMB_OF_SEVEN_BOSS_NUM; - - OUT_LOAD_INST_DATA_COMPLETE; - } - void TombOfSevenEvent() { if (GhostKillCount < TOMB_OF_SEVEN_BOSS_NUM && !TombBossGUIDs[TombEventCounter].IsEmpty()) diff --git a/src/server/scripts/EasternKingdoms/BlackrockMountain/MoltenCore/instance_molten_core.cpp b/src/server/scripts/EasternKingdoms/BlackrockMountain/MoltenCore/instance_molten_core.cpp index c5492c7ef91..187cc0f6d58 100644 --- a/src/server/scripts/EasternKingdoms/BlackrockMountain/MoltenCore/instance_molten_core.cpp +++ b/src/server/scripts/EasternKingdoms/BlackrockMountain/MoltenCore/instance_molten_core.cpp @@ -172,7 +172,7 @@ class instance_molten_core : public InstanceMapScript return true; } - void ReadSaveDataMore(std::istringstream& /*data*/) override + void AfterDataLoad() override { if (CheckMajordomoExecutus()) _executusSchedule = true; diff --git a/src/server/scripts/EasternKingdoms/Gnomeregan/instance_gnomeregan.cpp b/src/server/scripts/EasternKingdoms/Gnomeregan/instance_gnomeregan.cpp index 41a9bdae0aa..6edbfaf0a7c 100644 --- a/src/server/scripts/EasternKingdoms/Gnomeregan/instance_gnomeregan.cpp +++ b/src/server/scripts/EasternKingdoms/Gnomeregan/instance_gnomeregan.cpp @@ -21,7 +21,6 @@ #include "gnomeregan.h" #include "InstanceScript.h" #include "Map.h" -#include <sstream> class instance_gnomeregan : public InstanceMapScript { diff --git a/src/server/scripts/EasternKingdoms/Scholomance/instance_scholomance.cpp b/src/server/scripts/EasternKingdoms/Scholomance/instance_scholomance.cpp index cbaff8dfd3e..a7d88433b88 100644 --- a/src/server/scripts/EasternKingdoms/Scholomance/instance_scholomance.cpp +++ b/src/server/scripts/EasternKingdoms/Scholomance/instance_scholomance.cpp @@ -161,7 +161,7 @@ class instance_scholomance : public InstanceMapScript instance->SummonCreature(NPC_DARKMASTER_GANDLING, GandlingLoc); } - void ReadSaveDataMore(std::istringstream& /*data*/) override + void AfterDataLoad() override { CheckToSpawnGandling(); } diff --git a/src/server/scripts/EasternKingdoms/ShadowfangKeep/instance_shadowfang_keep.cpp b/src/server/scripts/EasternKingdoms/ShadowfangKeep/instance_shadowfang_keep.cpp index c299759aa16..162c4911671 100644 --- a/src/server/scripts/EasternKingdoms/ShadowfangKeep/instance_shadowfang_keep.cpp +++ b/src/server/scripts/EasternKingdoms/ShadowfangKeep/instance_shadowfang_keep.cpp @@ -30,7 +30,6 @@ EndScriptData */ #include "Map.h" #include "ScriptedCreature.h" #include "TemporarySummon.h" -#include <sstream> #define MAX_ENCOUNTER 4 @@ -84,15 +83,12 @@ public: instance_shadowfang_keep_InstanceMapScript(InstanceMap* map) : InstanceScript(map) { SetHeaders(DataHeader); - memset(&m_auiEncounter, 0, sizeof(m_auiEncounter)); + SetBossNumber(MAX_ENCOUNTER); uiPhase = 0; uiTimer = 0; } - uint32 m_auiEncounter[MAX_ENCOUNTER]; - std::string str_data; - ObjectGuid uiAshGUID; ObjectGuid uiAdaGUID; ObjectGuid uiArchmageArugalGUID; @@ -120,17 +116,17 @@ public: { case GO_COURTYARD_DOOR: DoorCourtyardGUID = go->GetGUID(); - if (m_auiEncounter[0] == DONE) + if (GetBossState(0) == DONE) HandleGameObject(ObjectGuid::Empty, true, go); break; case GO_SORCERER_DOOR: DoorSorcererGUID = go->GetGUID(); - if (m_auiEncounter[2] == DONE) + if (GetBossState(2) == DONE) HandleGameObject(ObjectGuid::Empty, true, go); break; case GO_ARUGAL_DOOR: DoorArugalGUID = go->GetGUID(); - if (m_auiEncounter[3] == DONE) + if (GetBossState(3) == DONE) HandleGameObject(ObjectGuid::Empty, true, go); break; } @@ -155,12 +151,12 @@ public: case TYPE_FREE_NPC: if (data == DONE) DoUseDoorOrButton(DoorCourtyardGUID); - m_auiEncounter[0] = data; + SetBossState(0, EncounterState(data)); break; case TYPE_RETHILGORE: if (data == DONE) DoSpeech(); - m_auiEncounter[1] = data; + SetBossState(1, EncounterState(data)); break; case TYPE_FENRUS: switch (data) @@ -173,27 +169,14 @@ public: DoUseDoorOrButton(DoorSorcererGUID); break; } - m_auiEncounter[2] = data; + SetBossState(2, EncounterState(data)); break; case TYPE_NANDOS: if (data == DONE) DoUseDoorOrButton(DoorArugalGUID); - m_auiEncounter[3] = data; + SetBossState(3, EncounterState(data)); break; } - - if (data == DONE) - { - OUT_SAVE_INST_DATA; - - std::ostringstream saveStream; - saveStream << m_auiEncounter[0] << ' ' << m_auiEncounter[1] << ' ' << m_auiEncounter[2] << ' ' << m_auiEncounter[3]; - - str_data = saveStream.str(); - - SaveToDB(); - OUT_SAVE_INST_DATA_COMPLETE; - } } uint32 GetData(uint32 type) const override @@ -201,44 +184,17 @@ public: switch (type) { case TYPE_FREE_NPC: - return m_auiEncounter[0]; + return GetBossState(0); case TYPE_RETHILGORE: - return m_auiEncounter[1]; + return GetBossState(1); case TYPE_FENRUS: - return m_auiEncounter[2]; + return GetBossState(2); case TYPE_NANDOS: - return m_auiEncounter[3]; + return GetBossState(3); } return 0; } - std::string GetSaveData() override - { - return str_data; - } - - void Load(char const* in) override - { - if (!in) - { - OUT_LOAD_INST_DATA_FAIL; - return; - } - - OUT_LOAD_INST_DATA(in); - - std::istringstream loadStream(in); - loadStream >> m_auiEncounter[0] >> m_auiEncounter[1] >> m_auiEncounter[2] >> m_auiEncounter[3]; - - for (uint8 i = 0; i < MAX_ENCOUNTER; ++i) - { - if (m_auiEncounter[i] == IN_PROGRESS) - m_auiEncounter[i] = NOT_STARTED; - } - - OUT_LOAD_INST_DATA_COMPLETE; - } - void Update(uint32 uiDiff) override { if (GetData(TYPE_FENRUS) != DONE) diff --git a/src/server/scripts/EasternKingdoms/Stratholme/instance_stratholme.cpp b/src/server/scripts/EasternKingdoms/Stratholme/instance_stratholme.cpp index c2c2022f73b..7cf6697426e 100644 --- a/src/server/scripts/EasternKingdoms/Stratholme/instance_stratholme.cpp +++ b/src/server/scripts/EasternKingdoms/Stratholme/instance_stratholme.cpp @@ -34,7 +34,6 @@ EndScriptData */ #include "MotionMaster.h" #include "Player.h" #include "stratholme.h" -#include <sstream> enum InstanceEvents { @@ -60,9 +59,7 @@ class instance_stratholme : public InstanceMapScript instance_stratholme_InstanceMapScript(InstanceMap* map) : InstanceScript(map) { SetHeaders(DataHeader); - - for (uint8 i = 0; i < MAX_ENCOUNTER; ++i) - EncounterState[i] = NOT_STARTED; + SetBossNumber(MAX_ENCOUNTER); for (uint8 i = 0; i < 5; ++i) IsSilverHandDead[i] = false; @@ -71,7 +68,6 @@ class instance_stratholme : public InstanceMapScript scarletsKilled = 0; } - uint32 EncounterState[MAX_ENCOUNTER]; uint8 scarletsKilled; bool IsSilverHandDead[5]; @@ -126,7 +122,7 @@ class instance_stratholme : public InstanceMapScript bool StartSlaugtherSquare() { //change to DONE when crystals implemented - if (EncounterState[1] == IN_PROGRESS && EncounterState[2] == IN_PROGRESS && EncounterState[3] == IN_PROGRESS) + if (GetBossState(1) == IN_PROGRESS && GetBossState(2) == IN_PROGRESS && GetBossState(3) == IN_PROGRESS) { HandleGameObject(portGauntletGUID, true); HandleGameObject(portSlaugtherGUID, true); @@ -254,9 +250,9 @@ class instance_stratholme : public InstanceMapScript switch (data) { case IN_PROGRESS: - if (EncounterState[0] == IN_PROGRESS || EncounterState[0] == FAIL) + if (GetBossState(0) == IN_PROGRESS || GetBossState(0) == FAIL) break; - EncounterState[0] = data; + SetBossState(0, EncounterState(data)); events.ScheduleEvent(EVENT_BARON_RUN, 45min); TC_LOG_DEBUG("scripts", "Instance Stratholme: Baron run in progress."); break; @@ -264,10 +260,10 @@ class instance_stratholme : public InstanceMapScript DoRemoveAurasDueToSpellOnPlayers(SPELL_BARON_ULTIMATUM); if (Creature* ysida = instance->GetCreature(ysidaGUID)) ysida->CastSpell(ysida, SPELL_PERM_FEIGN_DEATH, true); - EncounterState[0] = data; + SetBossState(0, EncounterState(data)); break; case DONE: - EncounterState[0] = data; + SetBossState(0, EncounterState(data)); if (Creature* ysida = instance->GetCreature(ysidaGUID)) { @@ -303,7 +299,7 @@ class instance_stratholme : public InstanceMapScript } break; case TYPE_BARONESS: - EncounterState[1] = data; + SetBossState(1, EncounterState(data)); if (data == IN_PROGRESS) { HandleGameObject(ziggurat1GUID, true); @@ -312,7 +308,7 @@ class instance_stratholme : public InstanceMapScript } break; case TYPE_NERUB: - EncounterState[2] = data; + SetBossState(2, EncounterState(data)); if (data == IN_PROGRESS) { HandleGameObject(ziggurat2GUID, true); @@ -321,7 +317,7 @@ class instance_stratholme : public InstanceMapScript } break; case TYPE_PALLID: - EncounterState[3] = data; + SetBossState(3, EncounterState(data)); if (data == IN_PROGRESS) { HandleGameObject(ziggurat3GUID, true); @@ -362,7 +358,7 @@ class instance_stratholme : public InstanceMapScript events.ScheduleEvent(EVENT_SLAUGHTER_SQUARE, 1min); TC_LOG_DEBUG("scripts", "Instance Stratholme: Slaugther event will continue in 1 minute."); } - EncounterState[4] = data; + SetBossState(4, EncounterState(data)); break; case TYPE_BARON: if (data == IN_PROGRESS) @@ -383,7 +379,7 @@ class instance_stratholme : public InstanceMapScript SetData(TYPE_BARON_RUN, DONE); } - EncounterState[5] = data; + SetBossState(5, EncounterState(data)); break; case TYPE_SH_AELMAR: IsSilverHandDead[0] = (data) ? true : false; @@ -401,46 +397,6 @@ class instance_stratholme : public InstanceMapScript IsSilverHandDead[4] = (data) ? true : false; break; } - - if (data == DONE) - SaveToDB(); - } - - std::string GetSaveData() override - { - OUT_SAVE_INST_DATA; - - std::ostringstream saveStream; - saveStream << EncounterState[0] << ' ' << EncounterState[1] << ' ' << EncounterState[2] << ' ' - << EncounterState[3] << ' ' << EncounterState[4] << ' ' << EncounterState[5]; - - OUT_SAVE_INST_DATA_COMPLETE; - return saveStream.str(); - } - - void Load(char const* in) override - { - if (!in) - { - OUT_LOAD_INST_DATA_FAIL; - return; - } - - OUT_LOAD_INST_DATA(in); - - std::istringstream loadStream(in); - loadStream >> EncounterState[0] >> EncounterState[1] >> EncounterState[2] >> EncounterState[3] - >> EncounterState[4] >> EncounterState[5]; - - // Do not reset 1, 2 and 3. they are not set to done, yet . - if (EncounterState[0] == IN_PROGRESS) - EncounterState[0] = NOT_STARTED; - if (EncounterState[4] == IN_PROGRESS) - EncounterState[4] = NOT_STARTED; - if (EncounterState[5] == IN_PROGRESS) - EncounterState[5] = NOT_STARTED; - - OUT_LOAD_INST_DATA_COMPLETE; } uint32 GetData(uint32 type) const override @@ -452,17 +408,17 @@ class instance_stratholme : public InstanceMapScript return 1; return 0; case TYPE_BARON_RUN: - return EncounterState[0]; + return GetBossState(0); case TYPE_BARONESS: - return EncounterState[1]; + return GetBossState(1); case TYPE_NERUB: - return EncounterState[2]; + return GetBossState(2); case TYPE_PALLID: - return EncounterState[3]; + return GetBossState(3); case TYPE_RAMSTEIN: - return EncounterState[4]; + return GetBossState(4); case TYPE_BARON: - return EncounterState[5]; + return GetBossState(5); } return 0; } diff --git a/src/server/scripts/EasternKingdoms/Uldaman/instance_uldaman.cpp b/src/server/scripts/EasternKingdoms/Uldaman/instance_uldaman.cpp index 4582ed6d45d..b3365ace584 100644 --- a/src/server/scripts/EasternKingdoms/Uldaman/instance_uldaman.cpp +++ b/src/server/scripts/EasternKingdoms/Uldaman/instance_uldaman.cpp @@ -32,7 +32,6 @@ EndScriptData */ #include "MotionMaster.h" #include "ObjectAccessor.h" #include "uldaman.h" -#include <sstream> enum Spells { @@ -64,21 +63,12 @@ class instance_uldaman : public InstanceMapScript instance_uldaman_InstanceMapScript(InstanceMap* map) : InstanceScript(map) { SetHeaders(DataHeader); - memset(&m_auiEncounter, 0, sizeof(m_auiEncounter)); + SetBossNumber(MAX_ENCOUNTER); ironayaSealDoorTimer = 27000; //animation time keystoneCheck = false; } - bool IsEncounterInProgress() const override - { - for (uint8 i = 0; i < MAX_ENCOUNTER; ++i) - if (m_auiEncounter[i] == IN_PROGRESS) - return true; - - return false; - } - ObjectGuid archaedasGUID; ObjectGuid ironayaGUID; ObjectGuid whoWokeuiArchaedasGUID; @@ -99,9 +89,6 @@ class instance_uldaman : public InstanceMapScript GuidVector earthenGuardians; GuidVector archaedasWallMinions; // minions lined up around the wall - uint32 m_auiEncounter[MAX_ENCOUNTER]; - std::string str_data; - void OnGameObjectCreate(GameObject* go) override { switch (go->GetEntry()) @@ -109,14 +96,14 @@ class instance_uldaman : public InstanceMapScript case GO_ALTAR_OF_THE_KEEPER_TEMPLE_DOOR: // lock the door altarOfTheKeeperTempleDoor = go->GetGUID(); - if (m_auiEncounter[0] == DONE) + if (GetBossState(0) == DONE) HandleGameObject(ObjectGuid::Empty, true, go); break; case GO_ARCHAEDAS_TEMPLE_DOOR: archaedasTempleDoor = go->GetGUID(); - if (m_auiEncounter[0] == DONE) + if (GetBossState(0) == DONE) HandleGameObject(ObjectGuid::Empty, true, go); break; @@ -125,21 +112,21 @@ class instance_uldaman : public InstanceMapScript go->ReplaceAllFlags(GO_FLAG_IN_USE | GO_FLAG_NODESPAWN); ancientVaultDoor = go->GetGUID(); - if (m_auiEncounter[1] == DONE) + if (GetBossState(1) == DONE) HandleGameObject(ObjectGuid::Empty, true, go); break; case GO_IRONAYA_SEAL_DOOR: ironayaSealDoor = go->GetGUID(); - if (m_auiEncounter[2] == DONE) + if (GetBossState(2) == DONE) HandleGameObject(ObjectGuid::Empty, true, go); break; case GO_KEYSTONE: keystoneGUID = go->GetGUID(); - if (m_auiEncounter[2] == DONE) + if (GetBossState(2) == DONE) { HandleGameObject(ObjectGuid::Empty, true, go); go->SetFlag(GO_FLAG_INTERACT_COND); @@ -345,13 +332,13 @@ class instance_uldaman : public InstanceMapScript switch (type) { case DATA_ALTAR_DOORS: - m_auiEncounter[0] = data; + SetBossState(0, EncounterState(data)); if (data == DONE) SetDoor(altarOfTheKeeperTempleDoor, true); break; case DATA_ANCIENT_DOOR: - m_auiEncounter[1] = data; + SetBossState(1, EncounterState(data)); if (data == DONE) //archeadas defeat { SetDoor(archaedasTempleDoor, true); //re open enter door @@ -360,7 +347,7 @@ class instance_uldaman : public InstanceMapScript break; case DATA_IRONAYA_DOOR: - m_auiEncounter[2] = data; + SetBossState(2, EncounterState(data)); break; case DATA_STONE_KEEPERS: @@ -371,7 +358,7 @@ class instance_uldaman : public InstanceMapScript switch (data) { case NOT_STARTED: - if (m_auiEncounter[0] == DONE) //if players opened the doors + if (GetBossState(0) == DONE) //if players opened the doors SetDoor(archaedasTempleDoor, true); RespawnMinions(); @@ -391,19 +378,6 @@ class instance_uldaman : public InstanceMapScript keystoneCheck = true; break; } - - if (data == DONE) - { - OUT_SAVE_INST_DATA; - - std::ostringstream saveStream; - saveStream << m_auiEncounter[0] << ' ' << m_auiEncounter[1] << ' ' << m_auiEncounter[2]; - - str_data = saveStream.str(); - - SaveToDB(); - OUT_SAVE_INST_DATA_COMPLETE; - } } void SetGuidData(uint32 type, ObjectGuid data) override @@ -416,33 +390,6 @@ class instance_uldaman : public InstanceMapScript } } - std::string GetSaveData() override - { - return str_data; - } - - void Load(char const* in) override - { - if (!in) - { - OUT_LOAD_INST_DATA_FAIL; - return; - } - - OUT_LOAD_INST_DATA(in); - - std::istringstream loadStream(in); - loadStream >> m_auiEncounter[0] >> m_auiEncounter[1] >> m_auiEncounter[2]; - - for (uint8 i = 0; i < MAX_ENCOUNTER; ++i) - { - if (m_auiEncounter[i] == IN_PROGRESS) - m_auiEncounter[i] = NOT_STARTED; - } - - OUT_LOAD_INST_DATA_COMPLETE; - } - void OnCreatureCreate(Creature* creature) override { switch (creature->GetEntry()) @@ -467,7 +414,7 @@ class instance_uldaman : public InstanceMapScript case 7228: // Ironaya ironayaGUID = creature->GetGUID(); - if (m_auiEncounter[2] != DONE) + if (GetBossState(2) != DONE) SetFrozenState (creature); break; diff --git a/src/server/scripts/EasternKingdoms/ZulAman/instance_zulaman.cpp b/src/server/scripts/EasternKingdoms/ZulAman/instance_zulaman.cpp index 3ce83c5867e..4af4457d367 100644 --- a/src/server/scripts/EasternKingdoms/ZulAman/instance_zulaman.cpp +++ b/src/server/scripts/EasternKingdoms/ZulAman/instance_zulaman.cpp @@ -22,7 +22,6 @@ #include "Map.h" #include "ScriptedCreature.h" #include "zulaman.h" -#include <sstream> class instance_zulaman : public InstanceMapScript { @@ -31,7 +30,8 @@ class instance_zulaman : public InstanceMapScript struct instance_zulaman_InstanceScript : public InstanceScript { - instance_zulaman_InstanceScript(InstanceMap* map) : InstanceScript(map) + instance_zulaman_InstanceScript(InstanceMap* map) : InstanceScript(map), + ZulAmanState(*this, "TimedRunState", NOT_STARTED) { SetHeaders(DataHeader); SetBossNumber(EncounterCount); @@ -146,7 +146,6 @@ class instance_zulaman : public InstanceMapScript events.ScheduleEvent(EVENT_UPDATE_ZULAMAN_TIMER, 1min); SpeedRunTimer = 15; ZulAmanState = data; - SaveToDB(); } break; } @@ -240,7 +239,6 @@ class instance_zulaman : public InstanceMapScript switch (eventId) { case EVENT_UPDATE_ZULAMAN_TIMER: - SaveToDB(); DoUpdateWorldState(WORLD_STATE_ZULAMAN_TIMER, --SpeedRunTimer); if (SpeedRunTimer) events.ScheduleEvent(EVENT_UPDATE_ZULAMAN_TIMER, 1min); @@ -257,24 +255,13 @@ class instance_zulaman : public InstanceMapScript } } - void WriteSaveDataMore(std::ostringstream& data) override + void AfterDataLoad() override { - data << ZulAmanState << ' ' - << SpeedRunTimer << ' ' - << ZulAmanBossCount; - } - - void ReadSaveDataMore(std::istringstream& data) override - { - data >> ZulAmanState; - data >> SpeedRunTimer; - data >> ZulAmanBossCount; - - if (ZulAmanState == IN_PROGRESS && SpeedRunTimer && SpeedRunTimer <= 15) + // Speed run cannot be resumed after reset/crash + if (ZulAmanState != NOT_STARTED) { - events.ScheduleEvent(EVENT_UPDATE_ZULAMAN_TIMER, 1min); - DoUpdateWorldState(WORLD_STATE_ZULAMAN_TIMER_ENABLED, 1); - DoUpdateWorldState(WORLD_STATE_ZULAMAN_TIMER, SpeedRunTimer); + SpeedRunTimer = 0; + ZulAmanState.LoadValue(FAIL); } } @@ -291,7 +278,7 @@ class instance_zulaman : public InstanceMapScript ObjectGuid StrangeGongGUID; ObjectGuid MasiveGateGUID; uint32 SpeedRunTimer; - uint32 ZulAmanState; + PersistentInstanceScriptValue<uint32> ZulAmanState; uint32 ZulAmanBossCount; }; diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/instance_hyjal.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/instance_hyjal.cpp index fab847ec648..6e368abee84 100644 --- a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/instance_hyjal.cpp +++ b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/instance_hyjal.cpp @@ -30,7 +30,6 @@ EndScriptData */ #include "InstanceScript.h" #include "Log.h" #include "Map.h" -#include <sstream> /* Battle of Mount Hyjal encounters: 0 - Rage Winterchill event @@ -157,12 +156,10 @@ public: case DATA_ALLIANCE_RETREAT: allianceRetreat = data; HandleGameObject(HordeGate, true); - SaveToDB(); break; case DATA_HORDE_RETREAT: hordeRetreat = data; HandleGameObject(ElfGate, true); - SaveToDB(); break; case DATA_RAIDDAMAGE: RaidDamage += data; @@ -206,16 +203,6 @@ public: return true; } - void ReadSaveDataMore(std::istringstream& loadStream) override - { - loadStream >> allianceRetreat >> hordeRetreat >> RaidDamage; - } - - void WriteSaveDataMore(std::ostringstream& saveStream) override - { - saveStream << allianceRetreat << ' ' << hordeRetreat << ' ' << RaidDamage; - } - uint32 GetData(uint32 type) const override { switch (type) @@ -228,6 +215,14 @@ public: return 0; } + void AfterDataLoad() override + { + if (GetBossState(DATA_ANETHERON) == DONE) + allianceRetreat = 1; + if (GetBossState(DATA_AZGALOR) == DONE) + hordeRetreat = 1; + } + protected: GuidList m_uiAncientGemGUID; ObjectGuid HordeGate; diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/CullingOfStratholme/instance_culling_of_stratholme.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/CullingOfStratholme/instance_culling_of_stratholme.cpp index 7b504ed8375..167082fd16e 100644 --- a/src/server/scripts/Kalimdor/CavernsOfTime/CullingOfStratholme/instance_culling_of_stratholme.cpp +++ b/src/server/scripts/Kalimdor/CavernsOfTime/CullingOfStratholme/instance_culling_of_stratholme.cpp @@ -265,7 +265,11 @@ class instance_culling_of_stratholme : public InstanceMapScript struct instance_culling_of_stratholme_InstanceMapScript : public InstanceScript { - instance_culling_of_stratholme_InstanceMapScript(InstanceMap* map) : InstanceScript(map), _currentState(JUST_STARTED), _infiniteGuardianTimeout(0), _waveCount(0), _currentSpawnLoc(0) + instance_culling_of_stratholme_InstanceMapScript(InstanceMap* map) : InstanceScript(map), + _currentState(*this, "currentState", JUST_STARTED), + _infiniteGuardianTimeout(*this, "infiniteGuardianTimeout", 0), + _waveCount(0), + _currentSpawnLoc(0) { SetHeaders(DataHeader); SetBossNumber(EncounterCount); @@ -275,30 +279,16 @@ class instance_culling_of_stratholme : public InstanceMapScript _plagueCrates.reserve(NUM_PLAGUE_CRATES); } - void WriteSaveDataMore(std::ostringstream& data) override + void AfterDataLoad() override { - data << _currentState << ' ' << _infiniteGuardianTimeout; - } - - void ReadSaveDataMore(std::istringstream& data) override - { - // read current instance progress from save data, then regress to the previous stable state - uint32 state = JUST_STARTED; - time_t infiniteGuardianTime = 0; - data >> state; - data >> infiniteGuardianTime; // UNIX timestamp - - COSProgressStates loadState = GetStableStateFor(COSProgressStates(state)); + COSProgressStates loadState = GetStableStateFor(_currentState); SetInstanceProgress(loadState, true); - if (infiniteGuardianTime) - { - _infiniteGuardianTimeout = infiniteGuardianTime; + if (_infiniteGuardianTimeout) events.ScheduleEvent(EVENT_GUARDIAN_TICK, 0s); - } - time_t timediff = (infiniteGuardianTime - GameTime::GetGameTime()); - if (!infiniteGuardianTime) + time_t timediff = (_infiniteGuardianTimeout - GameTime::GetGameTime()); + if (!_infiniteGuardianTimeout) timediff = -1; TC_LOG_DEBUG("scripts.cos", "instance_culling_of_stratholme::ReadSaveDataMore: Loaded with state %u and guardian timeout at %zu minutes %zu seconds from now", (uint32)loadState, timediff / MINUTE, timediff % MINUTE); @@ -752,8 +742,6 @@ class instance_culling_of_stratholme : public InstanceMapScript SpawnInfiniteCorruptor(); events.RescheduleEvent(EVENT_RESPAWN_ARTHAS, 1s); } - - SaveToDB(); } private: @@ -791,9 +779,9 @@ class instance_culling_of_stratholme : public InstanceMapScript } EventMap events; - COSProgressStates _currentState; + PersistentInstanceScriptValue<COSProgressStates> _currentState; std::unordered_map<uint32, uint32> _currentWorldStates; - time_t _infiniteGuardianTimeout; + PersistentInstanceScriptValue<time_t> _infiniteGuardianTimeout; // Generic ObjectGuid _chromieGUID; diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/EscapeFromDurnholdeKeep/instance_old_hillsbrad.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/EscapeFromDurnholdeKeep/instance_old_hillsbrad.cpp index cef1bc9ad92..9f5c2510f26 100644 --- a/src/server/scripts/Kalimdor/CavernsOfTime/EscapeFromDurnholdeKeep/instance_old_hillsbrad.cpp +++ b/src/server/scripts/Kalimdor/CavernsOfTime/EscapeFromDurnholdeKeep/instance_old_hillsbrad.cpp @@ -167,7 +167,7 @@ public: return ObjectGuid::Empty; } - void ReadSaveDataMore(std::istringstream&) override + void AfterDataLoad() override { if (GetBossState(DATA_LIEUTENANT_DRAKE) == DONE) mBarrelCount = 5; diff --git a/src/server/scripts/Kalimdor/HallsOfOrigination/instance_halls_of_origination.cpp b/src/server/scripts/Kalimdor/HallsOfOrigination/instance_halls_of_origination.cpp index dddd6ec7ef7..484d29d0487 100644 --- a/src/server/scripts/Kalimdor/HallsOfOrigination/instance_halls_of_origination.cpp +++ b/src/server/scripts/Kalimdor/HallsOfOrigination/instance_halls_of_origination.cpp @@ -22,7 +22,6 @@ #include "halls_of_origination.h" #include "InstanceScript.h" #include "Map.h" -#include <sstream> DoorData const doorData[] = { @@ -201,16 +200,10 @@ class instance_halls_of_origination : public InstanceMapScript } } - void WriteSaveDataMore(std::ostringstream& data) override + void AfterDataLoad() override { - data << _deadElementals; - } - - void ReadSaveDataMore(std::istringstream& data) override - { - uint32 deadElementals; - data >> deadElementals; - IncreaseDeadElementals(deadElementals); + if (GetBossState(BOSS_ANRAPHET) == DONE) + IncreaseDeadElementals(4); } protected: diff --git a/src/server/scripts/Kalimdor/WailingCaverns/instance_wailing_caverns.cpp b/src/server/scripts/Kalimdor/WailingCaverns/instance_wailing_caverns.cpp index d7730710aa2..f0606e6bca5 100644 --- a/src/server/scripts/Kalimdor/WailingCaverns/instance_wailing_caverns.cpp +++ b/src/server/scripts/Kalimdor/WailingCaverns/instance_wailing_caverns.cpp @@ -28,7 +28,6 @@ EndScriptData */ #include "Log.h" #include "Map.h" #include "wailing_caverns.h" -#include <sstream> #define MAX_ENCOUNTER 9 @@ -47,13 +46,11 @@ public: instance_wailing_caverns_InstanceMapScript(InstanceMap* map) : InstanceScript(map) { SetHeaders(DataHeader); - memset(&m_auiEncounter, 0, sizeof(m_auiEncounter)); + SetBossNumber(MAX_ENCOUNTER); yelled = false; } - uint32 m_auiEncounter[MAX_ENCOUNTER]; - bool yelled; ObjectGuid NaralexGUID; @@ -67,33 +64,32 @@ public: { switch (type) { - case TYPE_LORD_COBRAHN: m_auiEncounter[0] = data;break; - case TYPE_LORD_PYTHAS: m_auiEncounter[1] = data;break; - case TYPE_LADY_ANACONDRA: m_auiEncounter[2] = data;break; - case TYPE_LORD_SERPENTIS: m_auiEncounter[3] = data;break; - case TYPE_NARALEX_EVENT: m_auiEncounter[4] = data;break; - case TYPE_NARALEX_PART1: m_auiEncounter[5] = data;break; - case TYPE_NARALEX_PART2: m_auiEncounter[6] = data;break; - case TYPE_NARALEX_PART3: m_auiEncounter[7] = data;break; - case TYPE_MUTANUS_THE_DEVOURER: m_auiEncounter[8] = data;break; + case TYPE_LORD_COBRAHN: SetBossState(0, EncounterState(data));break; + case TYPE_LORD_PYTHAS: SetBossState(1, EncounterState(data));break; + case TYPE_LADY_ANACONDRA: SetBossState(2, EncounterState(data));break; + case TYPE_LORD_SERPENTIS: SetBossState(3, EncounterState(data));break; + case TYPE_NARALEX_EVENT: SetBossState(4, EncounterState(data));break; + case TYPE_NARALEX_PART1: SetBossState(5, EncounterState(data));break; + case TYPE_NARALEX_PART2: SetBossState(6, EncounterState(data));break; + case TYPE_NARALEX_PART3: SetBossState(7, EncounterState(data));break; + case TYPE_MUTANUS_THE_DEVOURER: SetBossState(8, EncounterState(data));break; case TYPE_NARALEX_YELLED: yelled = true; break; } - if (data == DONE)SaveToDB(); } uint32 GetData(uint32 type) const override { switch (type) { - case TYPE_LORD_COBRAHN: return m_auiEncounter[0]; - case TYPE_LORD_PYTHAS: return m_auiEncounter[1]; - case TYPE_LADY_ANACONDRA: return m_auiEncounter[2]; - case TYPE_LORD_SERPENTIS: return m_auiEncounter[3]; - case TYPE_NARALEX_EVENT: return m_auiEncounter[4]; - case TYPE_NARALEX_PART1: return m_auiEncounter[5]; - case TYPE_NARALEX_PART2: return m_auiEncounter[6]; - case TYPE_NARALEX_PART3: return m_auiEncounter[7]; - case TYPE_MUTANUS_THE_DEVOURER: return m_auiEncounter[8]; + case TYPE_LORD_COBRAHN: return GetBossState(0); + case TYPE_LORD_PYTHAS: return GetBossState(1); + case TYPE_LADY_ANACONDRA: return GetBossState(2); + case TYPE_LORD_SERPENTIS: return GetBossState(3); + case TYPE_NARALEX_EVENT: return GetBossState(4); + case TYPE_NARALEX_PART1: return GetBossState(5); + case TYPE_NARALEX_PART2: return GetBossState(6); + case TYPE_NARALEX_PART3: return GetBossState(7); + case TYPE_MUTANUS_THE_DEVOURER: return GetBossState(8); case TYPE_NARALEX_YELLED: return yelled; } return 0; @@ -104,41 +100,6 @@ public: if (data == DATA_NARALEX)return NaralexGUID; return ObjectGuid::Empty; } - - std::string GetSaveData() override - { - OUT_SAVE_INST_DATA; - - std::ostringstream saveStream; - saveStream << m_auiEncounter[0] << ' ' << m_auiEncounter[1] << ' ' << m_auiEncounter[2] << ' ' - << m_auiEncounter[3] << ' ' << m_auiEncounter[4] << ' ' << m_auiEncounter[5] << ' ' - << m_auiEncounter[6] << ' ' << m_auiEncounter[7] << ' ' << m_auiEncounter[8]; - - OUT_SAVE_INST_DATA_COMPLETE; - return saveStream.str(); - } - - void Load(char const* in) override - { - if (!in) - { - OUT_LOAD_INST_DATA_FAIL; - return; - } - - OUT_LOAD_INST_DATA(in); - - std::istringstream loadStream(in); - loadStream >> m_auiEncounter[0] >> m_auiEncounter[1] >> m_auiEncounter[2] >> m_auiEncounter[3] - >> m_auiEncounter[4] >> m_auiEncounter[5] >> m_auiEncounter[6] >> m_auiEncounter[7] >> m_auiEncounter[8]; - - for (uint8 i = 0; i < MAX_ENCOUNTER; ++i) - if (m_auiEncounter[i] != DONE) - m_auiEncounter[i] = NOT_STARTED; - - OUT_LOAD_INST_DATA_COMPLETE; - } - }; }; diff --git a/src/server/scripts/Northrend/AzjolNerub/Ahnkahet/instance_ahnkahet.cpp b/src/server/scripts/Northrend/AzjolNerub/Ahnkahet/instance_ahnkahet.cpp index 3eb08a405e0..fce945a8e11 100644 --- a/src/server/scripts/Northrend/AzjolNerub/Ahnkahet/instance_ahnkahet.cpp +++ b/src/server/scripts/Northrend/AzjolNerub/Ahnkahet/instance_ahnkahet.cpp @@ -21,7 +21,6 @@ #include "InstanceScript.h" #include "Map.h" #include "ScriptMgr.h" -#include <sstream> DoorData const doorData[] = { @@ -128,15 +127,13 @@ class instance_ahnkahet : public InstanceMapScript return 0; } - void WriteSaveDataMore(std::ostringstream& data) override + void AfterDataLoad() override { - data << SpheresState[0] << ' ' << SpheresState[1]; - } - - void ReadSaveDataMore(std::istringstream& data) override - { - data >> SpheresState[0]; - data >> SpheresState[1]; + if (GetBossState(DATA_PRINCE_TALDARAM) == DONE) + { + SpheresState[0] = IN_PROGRESS; + SpheresState[1] = IN_PROGRESS; + } } protected: diff --git a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheChampion/instance_trial_of_the_champion.cpp b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheChampion/instance_trial_of_the_champion.cpp index a970518ff33..4735f87452b 100644 --- a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheChampion/instance_trial_of_the_champion.cpp +++ b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheChampion/instance_trial_of_the_champion.cpp @@ -30,7 +30,6 @@ EndScriptData */ #include "MotionMaster.h" #include "Player.h" #include "trial_of_the_champion.h" -#include <sstream> constexpr uint32 ToCEncounterCount = 4; @@ -46,12 +45,11 @@ public: struct instance_trial_of_the_champion_InstanceMapScript : public InstanceScript { - instance_trial_of_the_champion_InstanceMapScript(InstanceMap* map) : InstanceScript(map) + instance_trial_of_the_champion_InstanceMapScript(InstanceMap* map) : InstanceScript(map), + uiMovementDone(*this, "uiMovementDone"), uiGrandChampionsDeaths(*this, "uiGrandChampionsDeaths") { SetHeaders(DataHeader); SetBossNumber(ToCEncounterCount); - uiMovementDone = 0; - uiGrandChampionsDeaths = 0; uiArgentSoldierDeaths = 0; teamInInstance = 0; @@ -59,8 +57,8 @@ public: } uint32 teamInInstance; - uint16 uiMovementDone; - uint16 uiGrandChampionsDeaths; + PersistentInstanceScriptValue<uint16> uiMovementDone; + PersistentInstanceScriptValue<uint16> uiGrandChampionsDeaths; uint8 uiArgentSoldierDeaths; ObjectGuid uiAnnouncerGUID; @@ -165,7 +163,7 @@ public: } else if (state == DONE) { - ++uiGrandChampionsDeaths; + uiGrandChampionsDeaths = uiGrandChampionsDeaths + 1; if (uiGrandChampionsDeaths == 3) { if (Creature* pAnnouncer = instance->GetCreature(uiAnnouncerGUID)) @@ -227,10 +225,10 @@ public: } } break; + case BOSS_BLACK_KNIGHT: + SetBossState(BOSS_BLACK_KNIGHT, EncounterState(uiData)); + break; } - - if (uiData == DONE) - SaveToDB(); } uint32 GetData(uint32 uiData) const override @@ -274,16 +272,6 @@ public: break; } } - - void WriteSaveDataMore(std::ostringstream& stream) override - { - stream << uiGrandChampionsDeaths << ' ' << uiMovementDone; - } - - void ReadSaveDataMore(std::istringstream& stream) override - { - stream >> uiGrandChampionsDeaths >> uiMovementDone; - } }; }; diff --git a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheChampion/trial_of_the_champion.h b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheChampion/trial_of_the_champion.h index 2da7435e328..b4542a73582 100644 --- a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheChampion/trial_of_the_champion.h +++ b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheChampion/trial_of_the_champion.h @@ -21,7 +21,7 @@ #include "CreatureAIImpl.h" #define ToCScriptName "instance_trial_of_the_champion" -#define DataHeader "TC" +#define DataHeader "TCv0.1" enum TCData { diff --git a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/instance_trial_of_the_crusader.cpp b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/instance_trial_of_the_crusader.cpp index 4a6f285d4ae..00551025db4 100644 --- a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/instance_trial_of_the_crusader.cpp +++ b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/instance_trial_of_the_crusader.cpp @@ -25,7 +25,6 @@ #include "ScriptedCreature.h" #include "TemporarySummon.h" #include "trial_of_the_crusader.h" -#include <sstream> // ToDo: Remove magic numbers of events @@ -107,7 +106,6 @@ class instance_trial_of_the_crusader : public InstanceMapScript LoadBossBoundaries(boundaries); LoadObjectData(creatureData, gameObjectData); LoadDoorData(doorData); - TrialCounter = 50; EventStage = 0; NorthrendBeasts = NOT_STARTED; NorthrendBeastsCount = 4; @@ -118,7 +116,6 @@ class instance_trial_of_the_crusader : public InstanceMapScript SnoboldCount = 0; MistressOfPainCount = 0; PlayerDeathCount = 0; - NeedSave = false; CrusadersSpecialState = false; TributeToDedicatedInsanity = false; // NYI, set to true when implement it DoUpdateWorldState(UPDATE_STATE_UI_SHOW, instance->IsHeroic() ? 1 : 0); @@ -140,15 +137,6 @@ class instance_trial_of_the_crusader : public InstanceMapScript snoboldGUIDS.push_back(creature->GetGUID()); } - // Summon prevention to heroic modes - uint32 GetCreatureEntry(ObjectGuid::LowType /*guidLow*/, CreatureData const* data) override - { - if (!TrialCounter) - return 0; - - return data->id; - } - void OnGameObjectCreate(GameObject* go) override { InstanceScript::OnGameObjectCreate(go); @@ -241,46 +229,6 @@ class instance_trial_of_the_crusader : public InstanceMapScript case DONE: { EventStage = 6000; - uint32 tributeChest = 0; - if (instance->GetDifficultyID() == DIFFICULTY_10_HC) - { - if (TrialCounter >= 50) - tributeChest = GO_TRIBUTE_CHEST_10H_99; - else - { - if (TrialCounter >= 45) - tributeChest = GO_TRIBUTE_CHEST_10H_50; - else - { - if (TrialCounter >= 25) - tributeChest = GO_TRIBUTE_CHEST_10H_45; - else - tributeChest = GO_TRIBUTE_CHEST_10H_25; - } - } - } - else if (instance->GetDifficultyID() == DIFFICULTY_25_HC) - { - if (TrialCounter >= 50) - tributeChest = GO_TRIBUTE_CHEST_25H_99; - else - { - if (TrialCounter >= 45) - tributeChest = GO_TRIBUTE_CHEST_25H_50; - else - { - if (TrialCounter >= 25) - tributeChest = GO_TRIBUTE_CHEST_25H_45; - else - tributeChest = GO_TRIBUTE_CHEST_25H_25; - } - } - } - - if (tributeChest) - if (Creature* tirion = GetCreature(DATA_FORDRING)) - if (GameObject* chest = tirion->SummonGameObject(tributeChest, 805.62f, 134.87f, 142.16f, 3.27f, QuaternionData::fromEulerAnglesZYX(3.27f, 0.0f, 0.0f), 7_days)) - chest->SetRespawnTime(chest->GetRespawnDelay()); break; } default: @@ -296,26 +244,9 @@ class instance_trial_of_the_crusader : public InstanceMapScript TC_LOG_DEBUG("scripts", "[ToCr] BossState(type %u) %u = state %u;", type, GetBossState(type), state); if (state == FAIL) { - if (instance->IsHeroic()) - { - --TrialCounter; - // decrease attempt counter at wipe - DoUpdateWorldState(UPDATE_STATE_UI_COUNT, TrialCounter); - - // if theres no more attemps allowed - if (!TrialCounter) - { - if (Creature* anubarak = GetCreature(DATA_ANUBARAK)) - anubarak->DespawnOrUnsummon(); - } - } - NeedSave = true; EventStage = (type == DATA_NORTHREND_BEASTS ? 666 : 0); state = NOT_STARTED; } - - if (state == DONE || NeedSave) - Save(); } return true; } @@ -354,10 +285,6 @@ class instance_trial_of_the_crusader : public InstanceMapScript { switch (type) { - case TYPE_COUNTER: - TrialCounter = data; - data = DONE; - break; case TYPE_EVENT: EventStage = data; data = NOT_STARTED; @@ -440,10 +367,6 @@ class instance_trial_of_the_crusader : public InstanceMapScript { switch (type) { - case DATA_TEAM: - return Team; - case TYPE_COUNTER: - return TrialCounter; case TYPE_EVENT: return EventStage; case TYPE_NORTHREND_BEASTS: @@ -563,60 +486,6 @@ class instance_trial_of_the_crusader : public InstanceMapScript } } - void Save() - { - OUT_SAVE_INST_DATA; - - std::ostringstream saveStream; - - for (uint8 i = 0; i < EncounterCount; ++i) - saveStream << GetBossState(i) << ' '; - - saveStream << TrialCounter << ' ' - << PlayerDeathCount << ' ' - << uint32(TributeToDedicatedInsanity ? 1 : 0); - SaveDataBuffer = saveStream.str(); - - SaveToDB(); - OUT_SAVE_INST_DATA_COMPLETE; - NeedSave = false; - } - - std::string GetSaveData() override - { - return SaveDataBuffer; - } - - void Load(char const* strIn) override - { - if (!strIn) - { - OUT_LOAD_INST_DATA_FAIL; - return; - } - - OUT_LOAD_INST_DATA(strIn); - - std::istringstream loadStream(strIn); - - uint32 tmpState; - for (uint8 i = 0; i < EncounterCount; ++i) - { - loadStream >> tmpState; - if (tmpState == IN_PROGRESS || tmpState > SPECIAL) - tmpState = NOT_STARTED; - SetBossState(i, EncounterState(tmpState)); - } - - loadStream >> TrialCounter; - loadStream >> PlayerDeathCount; - loadStream >> tmpState; - TributeToDedicatedInsanity = tmpState != 0; - EventStage = 0; - - OUT_LOAD_INST_DATA_COMPLETE; - } - bool CheckAchievementCriteriaMeet(uint32 criteria_id, Player const* /*source*/, Unit const* /*target*/, uint32 /*miscvalue1*/) override { switch (criteria_id) @@ -633,7 +502,7 @@ class instance_trial_of_the_crusader : public InstanceMapScript case THREE_SIXTY_PAIN_SPIKE_25_PLAYER_HEROIC: return MistressOfPainCount >= 2; case A_TRIBUTE_TO_DEDICATED_INSANITY: - return false/*TrialCounter == 50 && TributeToDedicatedInsanity*/; + return false; // no longer obtainable default: break; } @@ -642,14 +511,11 @@ class instance_trial_of_the_crusader : public InstanceMapScript } protected: - uint32 TrialCounter; uint32 EventStage; uint32 EventTimer; uint32 NorthrendBeasts; uint32 Team; - bool NeedSave; bool CrusadersSpecialState; - std::string SaveDataBuffer; GuidVector snoboldGUIDS; // Achievement stuff diff --git a/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/instance_halls_of_reflection.cpp b/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/instance_halls_of_reflection.cpp index ab46d266aa1..f2d5624a4bf 100644 --- a/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/instance_halls_of_reflection.cpp +++ b/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/instance_halls_of_reflection.cpp @@ -24,7 +24,6 @@ #include "ScriptMgr.h" #include "TemporarySummon.h" #include "Transport.h" -#include <sstream> Position const JainaSpawnPos = { 5236.659f, 1929.894f, 707.7781f, 0.8726646f }; // Jaina Spawn Position Position const SylvanasSpawnPos = { 5236.667f, 1929.906f, 707.7781f, 0.8377581f }; // Sylvanas Spawn Position (sniffed) @@ -457,8 +456,6 @@ class instance_halls_of_reflection : public InstanceMapScript default: break; } - - SaveToDB(); } void SetGuidData(uint32 type, ObjectGuid data) override @@ -728,31 +725,16 @@ class instance_halls_of_reflection : public InstanceMapScript return ObjectGuid::Empty; } - void WriteSaveDataMore(std::ostringstream& data) override + void AfterDataLoad() override { - data << _introState << ' ' << _frostswornGeneralState << ' ' << _quelDelarState; - } - - void ReadSaveDataMore(std::istringstream& data) override - { - uint32 temp = 0; - data >> temp; - if (temp == DONE) - SetData(DATA_INTRO_EVENT, DONE); - else - SetData(DATA_INTRO_EVENT, NOT_STARTED); - - data >> temp; - if (temp == DONE) - SetData(DATA_FROSTSWORN_GENERAL, DONE); - else - SetData(DATA_FROSTSWORN_GENERAL, NOT_STARTED); + if (GetBossState(DATA_FALRIC) == DONE) + { + _introState = DONE; + _quelDelarState = DONE; + } - data >> temp; - if (temp == DONE) - SetData(DATA_QUEL_DELAR_EVENT, DONE); - else - SetData(DATA_QUEL_DELAR_EVENT, NOT_STARTED); + if (GetBossState(DATA_THE_LICH_KING_ESCAPE) == DONE) + _frostswornGeneralState = DONE; } private: diff --git a/src/server/scripts/Northrend/Gundrak/instance_gundrak.cpp b/src/server/scripts/Northrend/Gundrak/instance_gundrak.cpp index 49eb21f8f72..62004f0396b 100644 --- a/src/server/scripts/Northrend/Gundrak/instance_gundrak.cpp +++ b/src/server/scripts/Northrend/Gundrak/instance_gundrak.cpp @@ -23,7 +23,6 @@ #include "gundrak.h" #include "Map.h" #include "ScriptMgr.h" -#include <sstream> DoorData const doorData[] = { @@ -242,25 +241,14 @@ class instance_gundrak : public InstanceMapScript } } - void WriteSaveDataMore(std::ostringstream& data) override + void AfterDataLoad() override { - data << uint32(SladRanStatueState) << ' '; - data << uint32(DrakkariColossusStatueState) << ' '; - data << uint32(MoorabiStatueState) << ' '; - } - - void ReadSaveDataMore(std::istringstream& data) override - { - uint32 temp; - - data >> temp; - SladRanStatueState = GOState(temp); - - data >> temp; - DrakkariColossusStatueState = GOState(temp); - - data >> temp; - MoorabiStatueState = GOState(temp); + if (GetBossState(DATA_SLAD_RAN) == DONE) + SladRanStatueState = GO_STATE_DESTROYED; + if (GetBossState(DATA_DRAKKARI_COLOSSUS) == DONE) + DrakkariColossusStatueState = GO_STATE_DESTROYED; + if (GetBossState(DATA_MOORABI) == DONE) + MoorabiStatueState = GO_STATE_DESTROYED; if (IsBridgeReady()) Events.ScheduleEvent(DATA_BRIDGE, TIMER_STATUE_ACTIVATION); @@ -314,7 +302,6 @@ class instance_gundrak : public InstanceMapScript ToggleGameObject(type, GO_STATE_DESTROYED); ToggleGameObject(DATA_TRAPDOOR, GO_STATE_READY); ToggleGameObject(DATA_COLLISION, GO_STATE_ACTIVE); - SaveToDB(); return; default: return; @@ -329,8 +316,6 @@ class instance_gundrak : public InstanceMapScript if (IsBridgeReady()) Events.ScheduleEvent(DATA_BRIDGE, TIMER_STATUE_ACTIVATION); - - SaveToDB(); } } diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_blood_queen_lana_thel.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_blood_queen_lana_thel.cpp index 6533aea45cb..14850f3f014 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_blood_queen_lana_thel.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_blood_queen_lana_thel.cpp @@ -69,7 +69,6 @@ enum Spells SPELL_TWILIGHT_BLOODBOLT = 71446, SPELL_INCITE_TERROR = 73070, SPELL_BLOODBOLT_WHIRL = 71772, - SPELL_ANNIHILATE = 71322, SPELL_CLEAR_ALL_STATUS_AILMENTS = 70939, // Blood Infusion @@ -125,12 +124,10 @@ enum Points POINT_CENTER = 1, POINT_AIR = 2, POINT_GROUND = 3, - POINT_MINCHAR = 4, }; Position const centerPos = {4595.7090f, 2769.4190f, 400.6368f, 0.000000f}; Position const airPos = {4595.7090f, 2769.4190f, 422.3893f, 0.000000f}; -Position const mincharPos = {4629.3711f, 2782.6089f, 424.6390f, 0.000000f}; bool IsVampire(Unit const* unit) { @@ -150,8 +147,6 @@ struct boss_blood_queen_lana_thel : public BossAI void Initialize() { _offtankGUID.Clear(); - _creditBloodQuickening = false; - _killMinchar = false; } void Reset() override @@ -188,7 +183,6 @@ struct boss_blood_queen_lana_thel : public BossAI DoCast(me, SPELL_SHROUD_OF_SORROW, true); DoCast(me, SPELL_FRENZIED_BLOODTHIRST_VISUAL, true); DoCastSelf(SPELL_CLEAR_ALL_STATUS_AILMENTS, true); - _creditBloodQuickening = instance->GetData(DATA_BLOOD_QUICKENING_STATE) == IN_PROGRESS; } void JustDied(Unit* /*killer*/) override @@ -200,22 +194,6 @@ struct boss_blood_queen_lana_thel : public BossAI DoCastAOE(SPELL_BLOOD_INFUSION_CREDIT, true); CleanAuras(); - - // Blah, credit the quest - if (_creditBloodQuickening) - { - instance->SetData(DATA_BLOOD_QUICKENING_STATE, DONE); - if (Player* player = me->GetLootRecipient()) - player->RewardPlayerAndGroupAtEvent(Is25ManRaid() ? NPC_INFILTRATOR_MINCHAR_BQ_25 : NPC_INFILTRATOR_MINCHAR_BQ, player); - if (Creature* minchar = me->FindNearestCreature(NPC_INFILTRATOR_MINCHAR_BQ, 200.0f)) - { - minchar->SetEmoteState(EMOTE_ONESHOT_NONE); - minchar->SetAnimTier(AnimTier::Ground); - minchar->SetCanFly(false); - minchar->RemoveAllAuras(); - minchar->GetMotionMaster()->MoveCharge(4629.3711f, 2782.6089f, 401.5301f, SPEED_CHARGE / 3.0f); - } - } } void CleanAuras() @@ -232,38 +210,15 @@ struct boss_blood_queen_lana_thel : public BossAI instance->DoRemoveAurasDueToSpellOnPlayers(PRESENCE_OF_THE_DARKFALLEN); } - void DoAction(int32 action) override - { - if (action != ACTION_KILL_MINCHAR) - return; - - if (instance->GetBossState(DATA_BLOOD_QUEEN_LANA_THEL) == IN_PROGRESS) - _killMinchar = true; - else - { - me->SetDisableGravity(true); - me->GetMotionMaster()->MovePoint(POINT_MINCHAR, mincharPos); - } - } - void EnterEvadeMode(EvadeReason why) override { if (!_EnterEvadeMode(why)) return; CleanAuras(); - if (_killMinchar) - { - _killMinchar = false; - me->SetDisableGravity(true); - me->GetMotionMaster()->MovePoint(POINT_MINCHAR, mincharPos); - } - else - { - me->AddUnitState(UNIT_STATE_EVADE); - me->GetMotionMaster()->MoveTargetedHome(); - Reset(); - } + me->AddUnitState(UNIT_STATE_EVADE); + me->GetMotionMaster()->MoveTargetedHome(); + Reset(); } void JustReachedHome() override @@ -323,12 +278,6 @@ struct boss_blood_queen_lana_thel : public BossAI AttackStart(victim); events.ScheduleEvent(EVENT_BLOOD_MIRROR, 2500ms, EVENT_GROUP_CANCELLABLE); break; - case POINT_MINCHAR: - DoCast(me, SPELL_ANNIHILATE, true); - // already in evade mode - me->GetMotionMaster()->MoveTargetedHome(); - Reset(); - break; default: break; } @@ -508,8 +457,6 @@ private: GuidSet _vampires; GuidSet _bloodboltedPlayers; ObjectGuid _offtankGUID; - bool _creditBloodQuickening; - bool _killMinchar; }; // helper for shortened code diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_sindragosa.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_sindragosa.cpp index 31e1d23e11f..94bc112d91a 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_sindragosa.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_sindragosa.cpp @@ -1501,9 +1501,6 @@ class at_sindragosa_lair : public AreaTriggerScript if (!instance->GetData(DATA_SINDRAGOSA_FROSTWYRMS) && !instance->GetGuidData(DATA_SINDRAGOSA) && instance->GetBossState(DATA_SINDRAGOSA) != DONE) { - if (player->GetMap()->IsHeroic() && !instance->GetData(DATA_HEROIC_ATTEMPTS)) - return true; - player->GetMap()->LoadGrid(SindragosaSpawnPos.GetPositionX(), SindragosaSpawnPos.GetPositionY()); if (Creature* sindragosa = player->GetMap()->SummonCreature(NPC_SINDRAGOSA, SindragosaSpawnPos)) sindragosa->AI()->DoAction(ACTION_START_FROSTWYRM); diff --git a/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.cpp b/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.cpp index 276d6a7b0bf..81859e1cfe0 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.cpp @@ -1559,20 +1559,6 @@ class at_icc_shutdown_traps : public AreaTriggerScript } }; -class at_icc_start_blood_quickening : public AreaTriggerScript -{ - public: - at_icc_start_blood_quickening() : AreaTriggerScript("at_icc_start_blood_quickening") { } - - bool OnTrigger(Player* player, AreaTriggerEntry const* /*areaTrigger*/) override - { - if (InstanceScript* instance = player->GetInstanceScript()) - if (instance->GetData(DATA_BLOOD_QUICKENING_STATE) == NOT_STARTED) - instance->SetData(DATA_BLOOD_QUICKENING_STATE, IN_PROGRESS); - return true; - } -}; - class at_icc_nerubar_broodkeeper : public OnlyOnceAreaTriggerScript { public: @@ -1627,6 +1613,5 @@ void AddSC_icecrown_citadel() // AreaTriggers new at_icc_saurfang_portal(); new at_icc_shutdown_traps(); - new at_icc_start_blood_quickening(); new at_icc_nerubar_broodkeeper(); } diff --git a/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.h b/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.h index da491854aa8..7b8570fd82c 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.h +++ b/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.h @@ -23,7 +23,7 @@ #include "SpellScript.h" #define ICCScriptName "instance_icecrown_citadel" -#define DataHeader "IC" +#define DataHeader "ICCv1" uint32 const EncounterCount = 13; @@ -103,8 +103,6 @@ enum ICDataTypes DATA_RIMEFANG = 25, DATA_COLDFLAME_JETS = 26, DATA_TEAM_IN_INSTANCE = 27, - DATA_BLOOD_QUICKENING_STATE = 28, - DATA_HEROIC_ATTEMPTS = 29, DATA_CROK_SCOURGEBANE = 30, DATA_CAPTAIN_ARNATH = 31, DATA_CAPTAIN_BRANDON = 32, @@ -499,9 +497,6 @@ enum ICSharedActions ACTION_ROTFACE_DEATH = -366272, ACTION_CHANGE_PHASE = -366780, - // Blood-Queen Lana'thel - ACTION_KILL_MINCHAR = -379550, - // Frostwing Halls gauntlet event ACTION_VRYKUL_DEATH = 37129, diff --git a/src/server/scripts/Northrend/IcecrownCitadel/instance_icecrown_citadel.cpp b/src/server/scripts/Northrend/IcecrownCitadel/instance_icecrown_citadel.cpp index 6b71835447b..132980fae3f 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/instance_icecrown_citadel.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/instance_icecrown_citadel.cpp @@ -29,7 +29,6 @@ #include "TemporarySummon.h" #include "Transport.h" #include "TransportMgr.h" -#include <sstream> #include <unordered_set> enum EventIds @@ -46,7 +45,6 @@ enum EventIds enum TimedEvents { - EVENT_UPDATE_EXECUTION_TIME = 1, EVENT_QUAKE_SHATTER = 2, EVENT_REBUILD_PLATFORM = 3, EVENT_RESPAWN_GUNSHIP = 4 @@ -122,27 +120,6 @@ DungeonEncounterData const encounters[] = { DATA_THE_LICH_KING, {{ 1106 }} } }; -// this doesnt have to only store questgivers, also can be used for related quest spawns -struct WeeklyQuest -{ - uint32 creatureEntry; - uint32 questId[2]; // 10 and 25 man versions -}; - -// when changing the content, remember to update SetData, DATA_BLOOD_QUICKENING_STATE case for NPC_ALRIN_THE_AGILE index -WeeklyQuest const WeeklyQuestData[WeeklyNPCs] = -{ - { NPC_INFILTRATOR_MINCHAR, { QUEST_DEPROGRAMMING_10, QUEST_DEPROGRAMMING_25 } }, // Deprogramming - { NPC_KOR_KRON_LIEUTENANT, { QUEST_SECURING_THE_RAMPARTS_10, QUEST_SECURING_THE_RAMPARTS_25 } }, // Securing the Ramparts - { NPC_ROTTING_FROST_GIANT_10, { QUEST_SECURING_THE_RAMPARTS_10, QUEST_SECURING_THE_RAMPARTS_25 } }, // Securing the Ramparts - { NPC_ROTTING_FROST_GIANT_25, { QUEST_SECURING_THE_RAMPARTS_10, QUEST_SECURING_THE_RAMPARTS_25 } }, // Securing the Ramparts - { NPC_ALCHEMIST_ADRIANNA, { QUEST_RESIDUE_RENDEZVOUS_10, QUEST_RESIDUE_RENDEZVOUS_25 } }, // Residue Rendezvous - { NPC_ALRIN_THE_AGILE, { QUEST_BLOOD_QUICKENING_10, QUEST_BLOOD_QUICKENING_25 } }, // Blood Quickening - { NPC_INFILTRATOR_MINCHAR_BQ, { QUEST_BLOOD_QUICKENING_10, QUEST_BLOOD_QUICKENING_25 } }, // Blood Quickening - { NPC_MINCHAR_BEAM_STALKER, { QUEST_BLOOD_QUICKENING_10, QUEST_BLOOD_QUICKENING_25 } }, // Blood Quickening - { NPC_VALITHRIA_DREAMWALKER_QUEST, { QUEST_RESPITE_FOR_A_TORNMENTED_SOUL_10, QUEST_RESPITE_FOR_A_TORNMENTED_SOUL_25 } } // Respite for a Tormented Soul -}; - // NPCs spawned at Light's Hammer on Lich King dead Position const JainaSpawnPos = { -48.65278f, 2211.026f, 27.98586f, 3.124139f }; Position const MuradinSpawnPos = { -47.34549f, 2208.087f, 27.98586f, 3.106686f }; @@ -163,11 +140,6 @@ class instance_icecrown_citadel : public InstanceMapScript LoadDungeonEncounterData(encounters); LoadBossBoundaries(boundaries); LoadDoorData(doorData); - HeroicAttempts = MaxHeroicAttempts; - ColdflameJetsState = NOT_STARTED; - UpperSpireTeleporterActiveState = NOT_STARTED; - BloodQuickeningState = NOT_STARTED; - BloodQuickeningMinutes = 0; BloodPrinceIntro = 1; SindragosaIntro = 1; IsBonedEligible = true; @@ -358,22 +330,7 @@ class instance_icecrown_citadel : public InstanceMapScript case NPC_INFILTRATOR_MINCHAR_BQ: case NPC_MINCHAR_BEAM_STALKER: case NPC_VALITHRIA_DREAMWALKER_QUEST: - { - for (uint8 questIndex = 0; questIndex < WeeklyNPCs; ++questIndex) - { - if (WeeklyQuestData[questIndex].creatureEntry == entry) - { - uint8 diffIndex = instance->Is25ManRaid() ? 1 : 0; - if (!sQuestPoolMgr->IsQuestActive(WeeklyQuestData[questIndex].questId[diffIndex])) - return 0; - break; - } - } - - if (entry == NPC_KOR_KRON_LIEUTENANT && GetData(DATA_TEAM_IN_INSTANCE) == ALLIANCE) - return NPC_SKYBREAKER_LIEUTENANT; - break; - } + return 0; case NPC_HORDE_GUNSHIP_CANNON: case NPC_ORGRIMS_HAMMER_CREW: case NPC_SKY_REAVER_KORM_BLACKSCAR: @@ -487,9 +444,6 @@ class instance_icecrown_citadel : public InstanceMapScript case NPC_RIMEFANG: case NPC_SPINESTALKER: { - if (instance->IsHeroic() && !HeroicAttempts) - return; - if (GetBossState(DATA_SINDRAGOSA) == DONE) return; @@ -747,10 +701,6 @@ class instance_icecrown_citadel : public InstanceMapScript return UpperSpireTeleporterActiveState; case DATA_TEAM_IN_INSTANCE: return instance->GetTeamInInstance(); - case DATA_BLOOD_QUICKENING_STATE: - return BloodQuickeningState; - case DATA_HEROIC_ATTEMPTS: - return HeroicAttempts; case DATA_BLOOD_PRINCE_COUNCIL_INTRO: return BloodPrinceIntro; case DATA_SINDRAGOSA_INTRO: @@ -838,25 +788,6 @@ class instance_icecrown_citadel : public InstanceMapScript return ObjectGuid::Empty; } - void HandleHeroicAttempts() - { - if (HeroicAttempts) - { - --HeroicAttempts; - DoUpdateWorldState(WORLDSTATE_ATTEMPTS_REMAINING, HeroicAttempts); - } - - if (!HeroicAttempts) - { - for (ObjectGuid const& bossGuid : { ProfessorPutricideGUID, BloodQueenLanaThelGUID, SindragosaGUID, TheLichKingGUID }) - { - if (Creature* boss = instance->GetCreature(bossGuid)) - if (boss->IsAlive()) - boss->DespawnOrUnsummon(); - } - } - } - bool SetBossState(uint32 type, EncounterState state) override { if (!InstanceScript::SetBossState(type, state)) @@ -973,32 +904,22 @@ class instance_icecrown_citadel : public InstanceMapScript break; case DATA_PROFESSOR_PUTRICIDE: HandleGameObject(PlagueSigilGUID, state != DONE); - if (instance->IsHeroic() && state == FAIL) - HandleHeroicAttempts(); - else if (state == DONE) + if (state == DONE) CheckLichKingAvailability(); break; case DATA_BLOOD_QUEEN_LANA_THEL: HandleGameObject(BloodwingSigilGUID, state != DONE); - if (instance->IsHeroic() && state == FAIL) - HandleHeroicAttempts(); - else if (state == DONE) + if (state == DONE) CheckLichKingAvailability(); break; case DATA_VALITHRIA_DREAMWALKER: if (state == DONE) - { - if (sQuestPoolMgr->IsQuestActive(WeeklyQuestData[8].questId[instance->Is25ManRaid() ? 1 : 0])) - instance->SummonCreature(NPC_VALITHRIA_DREAMWALKER_QUEST, ValithriaSpawnPos); if (GameObject* teleporter = instance->GetGameObject(TeleporterSindragosaGUID)) SetTeleporterState(teleporter, true); - } break; case DATA_SINDRAGOSA: HandleGameObject(FrostwingSigilGUID, state != DONE); - if (instance->IsHeroic() && state == FAIL) - HandleHeroicAttempts(); - else if (state == DONE) + if (state == DONE) CheckLichKingAvailability(); break; case DATA_THE_LICH_KING: @@ -1011,9 +932,7 @@ class instance_icecrown_citadel : public InstanceMapScript if (GameObject* platform = instance->GetGameObject(ArthasPlatformGUID)) platform->SetFarVisible(state == IN_PROGRESS); - if (instance->IsHeroic() && state == FAIL) - HandleHeroicAttempts(); - else if (state == DONE) + if (state == DONE) { if (GameObject* bolvar = instance->GetGameObject(FrozenBolvarGUID)) bolvar->SetRespawnTime(7 * DAY); @@ -1065,48 +984,12 @@ class instance_icecrown_citadel : public InstanceMapScript break; case DATA_COLDFLAME_JETS: ColdflameJetsState = data; - if (ColdflameJetsState == DONE) - SaveToDB(); - break; - case DATA_BLOOD_QUICKENING_STATE: - { - // skip if nothing changes - if (BloodQuickeningState == data) - break; - - // 5 is the index of Blood Quickening - if (!sQuestPoolMgr->IsQuestActive(WeeklyQuestData[5].questId[instance->Is25ManRaid() ? 1 : 0])) - break; - - switch (data) - { - case IN_PROGRESS: - Events.ScheduleEvent(EVENT_UPDATE_EXECUTION_TIME, 1min); - BloodQuickeningMinutes = 30; - DoUpdateWorldState(WORLDSTATE_SHOW_TIMER, 1); - DoUpdateWorldState(WORLDSTATE_EXECUTION_TIME, BloodQuickeningMinutes); - break; - case DONE: - Events.CancelEvent(EVENT_UPDATE_EXECUTION_TIME); - BloodQuickeningMinutes = 0; - DoUpdateWorldState(WORLDSTATE_SHOW_TIMER, 0); - break; - default: - break; - } - - BloodQuickeningState = data; - SaveToDB(); break; - } case DATA_UPPERSPIRE_TELE_ACT: UpperSpireTeleporterActiveState = data; if (UpperSpireTeleporterActiveState == DONE) - { if (GameObject* go = instance->GetGameObject(TeleporterUpperSpireGUID)) SetTeleporterState(go, true); - SaveToDB(); - } break; case DATA_BLOOD_PRINCE_COUNCIL_INTRO: BloodPrinceIntro = data; @@ -1343,36 +1226,18 @@ class instance_icecrown_citadel : public InstanceMapScript } } - void WriteSaveDataMore(std::ostringstream& data) override + void AfterDataLoad() override { - data << HeroicAttempts << ' ' - << ColdflameJetsState << ' ' - << BloodQuickeningState << ' ' - << BloodQuickeningMinutes << ' ' - << UpperSpireTeleporterActiveState; - } - - void ReadSaveDataMore(std::istringstream& data) override - { - uint32 temp = 0; - - data >> HeroicAttempts; - - data >> temp; - ColdflameJetsState = temp == DONE ? DONE : NOT_STARTED; - - data >> temp; - BloodQuickeningState = temp == DONE ? DONE : NOT_STARTED; - - data >> BloodQuickeningMinutes; - - data >> temp; - UpperSpireTeleporterActiveState = temp == DONE ? DONE : NOT_STARTED; + if (GetBossState(DATA_DEATHBRINGER_SAURFANG) == DONE) + { + ColdflameJetsState = DONE; + UpperSpireTeleporterActiveState = DONE; + } } void Update(uint32 diff) override { - if (BloodQuickeningState != IN_PROGRESS && GetBossState(DATA_THE_LICH_KING) != IN_PROGRESS && GetBossState(DATA_ICECROWN_GUNSHIP_BATTLE) != FAIL) + if (GetBossState(DATA_THE_LICH_KING) != IN_PROGRESS && GetBossState(DATA_ICECROWN_GUNSHIP_BATTLE) != FAIL) return; Events.Update(diff); @@ -1381,25 +1246,6 @@ class instance_icecrown_citadel : public InstanceMapScript { switch (eventId) { - case EVENT_UPDATE_EXECUTION_TIME: - { - --BloodQuickeningMinutes; - if (BloodQuickeningMinutes) - { - Events.ScheduleEvent(EVENT_UPDATE_EXECUTION_TIME, 1min); - DoUpdateWorldState(WORLDSTATE_SHOW_TIMER, 1); - DoUpdateWorldState(WORLDSTATE_EXECUTION_TIME, BloodQuickeningMinutes); - } - else - { - BloodQuickeningState = DONE; - DoUpdateWorldState(WORLDSTATE_SHOW_TIMER, 0); - if (Creature* bq = instance->GetCreature(BloodQueenLanaThelGUID)) - bq->AI()->DoAction(ACTION_KILL_MINCHAR); - } - SaveToDB(); - break; - } case EVENT_QUAKE_SHATTER: { if (GameObject* platform = instance->GetGameObject(ArthasPlatformGUID)) @@ -1552,9 +1398,6 @@ class instance_icecrown_citadel : public InstanceMapScript std::unordered_set<ObjectGuid::LowType> FrostwyrmGUIDs; std::unordered_set<ObjectGuid::LowType> SpinestalkerTrash; std::unordered_set<ObjectGuid::LowType> RimefangTrash; - uint32 BloodQuickeningState; - uint32 HeroicAttempts; - uint16 BloodQuickeningMinutes; uint8 BloodPrinceIntro; uint8 SindragosaIntro; bool IsBonedEligible; diff --git a/src/server/scripts/Northrend/Naxxramas/instance_naxxramas.cpp b/src/server/scripts/Northrend/Naxxramas/instance_naxxramas.cpp index 3e145abe5b2..48bf18f6d4e 100644 --- a/src/server/scripts/Northrend/Naxxramas/instance_naxxramas.cpp +++ b/src/server/scripts/Northrend/Naxxramas/instance_naxxramas.cpp @@ -124,8 +124,6 @@ class instance_naxxramas : public InstanceMapScript hadSapphironBirth = false; CurrentWingTaunt = SAY_KELTHUZAD_FIRST_WING_TAUNT; - - playerDied = false; } void OnCreatureCreate(Creature* creature) override @@ -250,12 +248,6 @@ class instance_naxxramas : public InstanceMapScript void OnUnitDeath(Unit* unit) override { - if (!playerDied && unit->IsPlayer() && IsEncounterInProgress()) - { - playerDied = true; - SaveToDB(); - } - if (Creature* creature = unit->ToCreature()) if (creature->GetEntry() == NPC_BIGGLESWORTH) { @@ -544,26 +536,12 @@ class instance_naxxramas : public InstanceMapScript case 13239: // Loatheb case 13240: // Thaddius case 7617: // Kel'Thuzad - if (AreAllEncountersDone() && !playerDied) - return true; return false; } return false; } - void WriteSaveDataMore(std::ostringstream& data) override - { - data << uint32(playerDied ? 1 : 0); - } - - void ReadSaveDataMore(std::istringstream& data) override - { - uint32 tmpState; - data >> tmpState; - playerDied = tmpState != 0; - } - protected: /* The Arachnid Quarter */ // Anub'rekhan @@ -608,9 +586,6 @@ class instance_naxxramas : public InstanceMapScript bool hadSapphironBirth; uint8 CurrentWingTaunt; - /* The Immortal / The Undying */ - bool playerDied; - EventMap events; }; diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_algalon_the_observer.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_algalon_the_observer.cpp index 850f9fd886a..0b7f8d2eb7a 100644 --- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_algalon_the_observer.cpp +++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_algalon_the_observer.cpp @@ -152,9 +152,6 @@ enum Events EVENT_OUTRO_9, EVENT_OUTRO_10, EVENT_OUTRO_11, - EVENT_DESPAWN_ALGALON_1, - EVENT_DESPAWN_ALGALON_2, - EVENT_DESPAWN_ALGALON_3, // Living Constellation EVENT_ARCANE_BARRAGE @@ -334,18 +331,6 @@ struct boss_algalon_the_observer : public BossAI events.CancelEvent(EVENT_RESUME_UPDATING); events.ScheduleEvent(EVENT_ASCEND_TO_THE_HEAVENS, 1s + 500ms); break; - case EVENT_DESPAWN_ALGALON: - events.Reset(); - events.SetPhase(PHASE_ROLE_PLAY); - if (me->IsInCombat()) - events.ScheduleEvent(EVENT_ASCEND_TO_THE_HEAVENS, 1ms); - events.ScheduleEvent(EVENT_DESPAWN_ALGALON_1, 5s); - events.ScheduleEvent(EVENT_DESPAWN_ALGALON_2, 17s); - events.ScheduleEvent(EVENT_DESPAWN_ALGALON_3, 26s); - me->DespawnOrUnsummon(34s); - me->SetUnitFlag(UNIT_FLAG_UNINTERACTIBLE); - me->SetImmuneToNPC(true); - break; case ACTION_INIT_ALGALON: _firstPull = false; me->SetImmuneToPC(false); @@ -385,7 +370,6 @@ struct boss_algalon_the_observer : public BossAI DoZoneInCombat(); introDelay = 26500ms; summons.DespawnEntry(NPC_AZEROTH); - instance->SetData(EVENT_DESPAWN_ALGALON, 0); events.ScheduleEvent(EVENT_START_COMBAT, 16s); } @@ -687,15 +671,6 @@ struct boss_algalon_the_observer : public BossAI DoCastSelf(SPELL_TELEPORT); me->DespawnOrUnsummon(1s + 200ms); break; - case EVENT_DESPAWN_ALGALON_1: - Talk(SAY_ALGALON_DESPAWN_1); - break; - case EVENT_DESPAWN_ALGALON_2: - Talk(SAY_ALGALON_DESPAWN_2); - break; - case EVENT_DESPAWN_ALGALON_3: - Talk(SAY_ALGALON_DESPAWN_3); - break; default: break; } diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/instance_ulduar.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/instance_ulduar.cpp index 1df315a7cc7..32b0ad030cf 100644 --- a/src/server/scripts/Northrend/Ulduar/Ulduar/instance_ulduar.cpp +++ b/src/server/scripts/Northrend/Ulduar/Ulduar/instance_ulduar.cpp @@ -27,7 +27,6 @@ #include "ScriptMgr.h" #include "TemporarySummon.h" #include "Vehicle.h" -#include <sstream> static BossBoundaryData const boundaries = { @@ -168,7 +167,6 @@ class instance_ulduar : public InstanceMapScript LoadMinionData(minionData); LoadObjectData(creatureData, objectData); - _algalonTimer = 61; _maxArmorItemLevel = 0; _maxWeaponItemLevel = 0; TeamInInstance = 0; @@ -183,7 +181,7 @@ class instance_ulduar : public InstanceMapScript IsDriveMeCrazyEligible = true; _algalonSummoned = false; _summonAlgalon = false; - _CoUAchivePlayerDeathMask = 0; + _algalonFirstIntro = true; memset(_summonObservationRingKeeper, 0, sizeof(_summonObservationRingKeeper)); memset(_summonYSKeeper, 0, sizeof(_summonYSKeeper)); @@ -234,7 +232,7 @@ class instance_ulduar : public InstanceMapScript { _summonAlgalon = false; TempSummon* algalon = instance->SummonCreature(NPC_ALGALON, AlgalonLandPos); - if (_algalonTimer && _algalonTimer <= 60) + if (!_algalonFirstIntro) algalon->AI()->DoAction(ACTION_INIT_ALGALON); else algalon->SetImmuneToPC(false); @@ -349,28 +347,24 @@ class instance_ulduar : public InstanceMapScript case NPC_FREYA_YS: KeeperGUIDs[0] = creature->GetGUID(); _summonYSKeeper[0] = false; - SaveToDB(); ++keepersCount; DoUpdateWorldState(WORLD_STATE_YOGG_SARON_KEEPERS, keepersCount); break; case NPC_HODIR_YS: KeeperGUIDs[1] = creature->GetGUID(); _summonYSKeeper[1] = false; - SaveToDB(); ++keepersCount; DoUpdateWorldState(WORLD_STATE_YOGG_SARON_KEEPERS, keepersCount); break; case NPC_THORIM_YS: KeeperGUIDs[2] = creature->GetGUID(); _summonYSKeeper[2] = false; - SaveToDB(); ++keepersCount; DoUpdateWorldState(WORLD_STATE_YOGG_SARON_KEEPERS, keepersCount); break; case NPC_MIMIRON_YS: KeeperGUIDs[3] = creature->GetGUID(); _summonYSKeeper[3] = false; - SaveToDB(); ++keepersCount; DoUpdateWorldState(WORLD_STATE_YOGG_SARON_KEEPERS, keepersCount); break; @@ -526,19 +520,6 @@ class instance_ulduar : public InstanceMapScript void OnUnitDeath(Unit* unit) override { - // Champion/Conqueror of Ulduar - if (unit->GetTypeId() == TYPEID_PLAYER) - { - for (uint8 i = 0; i < DATA_ALGALON; ++i) - { - if (GetBossState(i) == IN_PROGRESS) - { - _CoUAchivePlayerDeathMask |= (1 << i); - SaveToDB(); - } - } - } - Creature* creature = unit->ToCreature(); if (!creature) return; @@ -690,10 +671,6 @@ class instance_ulduar : public InstanceMapScript case DATA_ALGALON: if (state == DONE) { - _events.CancelEvent(EVENT_UPDATE_ALGALON_TIMER); - _events.CancelEvent(EVENT_DESPAWN_ALGALON); - DoUpdateWorldState(WORLD_STATE_ALGALON_TIMER_ENABLED, 0); - _algalonTimer = 61; if (GameObject* gift = GetGameObject(DATA_GIFT_OF_THE_OBSERVER)) gift->SetRespawnTime(gift->GetRespawnDelay()); // get item level (recheck weapons) @@ -707,6 +684,7 @@ class instance_ulduar : public InstanceMapScript } else if (state == IN_PROGRESS) { + _algalonFirstIntro = false; // get item level (armor cannot be swapped in combat) Map::PlayerList const& players = instance->GetPlayers(); for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr) @@ -747,7 +725,6 @@ class instance_ulduar : public InstanceMapScript if (data >= 2 && GetBossState(DATA_FLAME_LEVIATHAN) == NOT_STARTED) { _events.ScheduleEvent(EVENT_LEVIATHAN_BREAK_DOOR, 5s); - SaveToDB(); } break; case DATA_HODIR_RARE_CACHE: @@ -768,13 +745,6 @@ class instance_ulduar : public InstanceMapScript case DATA_DRIVE_ME_CRAZY: IsDriveMeCrazyEligible = data ? true : false; break; - case EVENT_DESPAWN_ALGALON: - DoUpdateWorldState(WORLD_STATE_ALGALON_TIMER_ENABLED, 1); - DoUpdateWorldState(WORLD_STATE_ALGALON_DESPAWN_TIMER, 60); - _algalonTimer = 60; - _events.ScheduleEvent(EVENT_DESPAWN_ALGALON, 1h); - _events.ScheduleEvent(EVENT_UPDATE_ALGALON_TIMER, 1min); - break; case DATA_ALGALON_SUMMON_STATE: _algalonSummoned = true; break; @@ -883,94 +853,49 @@ class instance_ulduar : public InstanceMapScript return IsDriveMeCrazyEligible; case CRITERIA_C_O_U_LEVIATHAN_10: case CRITERIA_C_O_U_LEVIATHAN_25: - return (_CoUAchivePlayerDeathMask & (1 << DATA_FLAME_LEVIATHAN)) == 0; case CRITERIA_C_O_U_IGNIS_10: case CRITERIA_C_O_U_IGNIS_25: - return (_CoUAchivePlayerDeathMask & (1 << DATA_IGNIS)) == 0; case CRITERIA_C_O_U_RAZORSCALE_10: case CRITERIA_C_O_U_RAZORSCALE_25: - return (_CoUAchivePlayerDeathMask & (1 << DATA_RAZORSCALE)) == 0; case CRITERIA_C_O_U_XT002_10: case CRITERIA_C_O_U_XT002_25: - return (_CoUAchivePlayerDeathMask & (1 << DATA_XT002)) == 0; case CRITERIA_C_O_U_IRON_COUNCIL_10: case CRITERIA_C_O_U_IRON_COUNCIL_25: - return (_CoUAchivePlayerDeathMask & (1 << DATA_ASSEMBLY_OF_IRON)) == 0; case CRITERIA_C_O_U_KOLOGARN_10: case CRITERIA_C_O_U_KOLOGARN_25: - return (_CoUAchivePlayerDeathMask & (1 << DATA_KOLOGARN)) == 0; case CRITERIA_C_O_U_AURIAYA_10: case CRITERIA_C_O_U_AURIAYA_25: - return (_CoUAchivePlayerDeathMask & (1 << DATA_AURIAYA)) == 0; case CRITERIA_C_O_U_HODIR_10: case CRITERIA_C_O_U_HODIR_25: - return (_CoUAchivePlayerDeathMask & (1 << DATA_HODIR)) == 0; case CRITERIA_C_O_U_THORIM_10: case CRITERIA_C_O_U_THORIM_25: - return (_CoUAchivePlayerDeathMask & (1 << DATA_THORIM)) == 0; case CRITERIA_C_O_U_FREYA_10: case CRITERIA_C_O_U_FREYA_25: - return (_CoUAchivePlayerDeathMask & (1 << DATA_FREYA)) == 0; case CRITERIA_C_O_U_MIMIRON_10: case CRITERIA_C_O_U_MIMIRON_25: - return (_CoUAchivePlayerDeathMask & (1 << DATA_MIMIRON)) == 0; case CRITERIA_C_O_U_VEZAX_10: case CRITERIA_C_O_U_VEZAX_25: - return (_CoUAchivePlayerDeathMask & (1 << DATA_VEZAX)) == 0; case CRITERIA_C_O_U_YOGG_SARON_10: case CRITERIA_C_O_U_YOGG_SARON_25: - return (_CoUAchivePlayerDeathMask & (1 << DATA_YOGG_SARON)) == 0; + return false; } return false; } - void WriteSaveDataMore(std::ostringstream& data) override - { - data << ColossusData << ' ' << _algalonTimer << ' ' << uint32(_algalonSummoned ? 1 : 0); - - for (uint8 i = 0; i < 4; ++i) - data << ' ' << uint32(!KeeperGUIDs[i].IsEmpty() ? 1 : 0); - - data << ' ' << _CoUAchivePlayerDeathMask; - } - - void ReadSaveDataMore(std::istringstream& data) override + void AfterDataLoad() override { - uint32 tempState; - data >> tempState; - SetData(DATA_COLOSSUS, tempState); - - data >> _algalonTimer; - data >> tempState; - _algalonSummoned = tempState != 0; - if (_algalonSummoned && GetBossState(DATA_ALGALON) != DONE) - { - _summonAlgalon = true; - if (_algalonTimer && _algalonTimer <= 60) - { - _events.ScheduleEvent(EVENT_UPDATE_ALGALON_TIMER, 1min); - DoUpdateWorldState(WORLD_STATE_ALGALON_TIMER_ENABLED, 1); - DoUpdateWorldState(WORLD_STATE_ALGALON_DESPAWN_TIMER, _algalonTimer); - } - } - - for (uint8 i = 0; i < 4; ++i) - { - data >> tempState; - _summonYSKeeper[i] = tempState != 0; - } + if (GetBossState(DATA_FLAME_LEVIATHAN) == DONE) + SetData(DATA_COLOSSUS, DONE); - if (GetBossState(DATA_FREYA) == DONE && !_summonYSKeeper[0]) + if (GetBossState(DATA_FREYA) == DONE) _summonObservationRingKeeper[0] = true; - if (GetBossState(DATA_HODIR) == DONE && !_summonYSKeeper[1]) + if (GetBossState(DATA_HODIR) == DONE) _summonObservationRingKeeper[1] = true; - if (GetBossState(DATA_THORIM) == DONE && !_summonYSKeeper[2]) + if (GetBossState(DATA_THORIM) == DONE) _summonObservationRingKeeper[2] = true; - if (GetBossState(DATA_MIMIRON) == DONE && !_summonYSKeeper[3]) + if (GetBossState(DATA_MIMIRON) == DONE) _summonObservationRingKeeper[3] = true; - - data >> _CoUAchivePlayerDeathMask; } void Update(uint32 diff) override @@ -984,19 +909,6 @@ class instance_ulduar : public InstanceMapScript { switch (eventId) { - case EVENT_UPDATE_ALGALON_TIMER: - SaveToDB(); - DoUpdateWorldState(WORLD_STATE_ALGALON_DESPAWN_TIMER, --_algalonTimer); - if (_algalonTimer) - _events.ScheduleEvent(EVENT_UPDATE_ALGALON_TIMER, 1min); - else - { - DoUpdateWorldState(WORLD_STATE_ALGALON_TIMER_ENABLED, 0); - _events.CancelEvent(EVENT_UPDATE_ALGALON_TIMER); - if (Creature* algalon = GetCreature(DATA_ALGALON)) - algalon->AI()->DoAction(EVENT_DESPAWN_ALGALON); - } - break; case EVENT_DESPAWN_LEVIATHAN_VEHICLES: // Eject all players from vehicles and make them untargetable. // They will be despawned after a while @@ -1054,14 +966,13 @@ class instance_ulduar : public InstanceMapScript private: EventMap _events; - uint32 _algalonTimer; bool _summonAlgalon; bool _algalonSummoned; + bool _algalonFirstIntro; bool _summonObservationRingKeeper[4]; bool _summonYSKeeper[4]; uint32 _maxArmorItemLevel; uint32 _maxWeaponItemLevel; - uint32 _CoUAchivePlayerDeathMask; }; InstanceScript* GetInstanceScript(InstanceMap* map) const override diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/ulduar.h b/src/server/scripts/Northrend/Ulduar/Ulduar/ulduar.h index 2056d438e7d..5df7b50bcaa 100644 --- a/src/server/scripts/Northrend/Ulduar/Ulduar/ulduar.h +++ b/src/server/scripts/Northrend/Ulduar/Ulduar/ulduar.h @@ -477,8 +477,8 @@ enum UlduarAchievementData { // FL Achievement boolean DATA_UNBROKEN = 29052906, // 2905, 2906 are achievement IDs, - MAX_HERALD_ARMOR_ITEMLEVEL = 226, - MAX_HERALD_WEAPON_ITEMLEVEL = 232 + MAX_HERALD_ARMOR_ITEMLEVEL = 35, + MAX_HERALD_WEAPON_ITEMLEVEL = 35 }; enum UlduarSharedSpells @@ -489,8 +489,6 @@ enum UlduarSharedSpells enum UlduarEvents { - EVENT_DESPAWN_ALGALON = 1, - EVENT_UPDATE_ALGALON_TIMER = 2, ACTION_INIT_ALGALON = 6, EVENT_DESPAWN_LEVIATHAN_VEHICLES = 7, EVENT_LEVIATHAN_BREAK_DOOR = 8 diff --git a/src/server/scripts/Northrend/UtgardeKeep/UtgardeKeep/instance_utgarde_keep.cpp b/src/server/scripts/Northrend/UtgardeKeep/UtgardeKeep/instance_utgarde_keep.cpp index 7eb762e21b8..4b1fedc4b97 100644 --- a/src/server/scripts/Northrend/UtgardeKeep/UtgardeKeep/instance_utgarde_keep.cpp +++ b/src/server/scripts/Northrend/UtgardeKeep/UtgardeKeep/instance_utgarde_keep.cpp @@ -20,7 +20,6 @@ #include "GameObject.h" #include "InstanceScript.h" #include "utgarde_keep.h" -#include <sstream> DoorData const doorData[] = { @@ -166,9 +165,6 @@ class instance_utgarde_keep : public InstanceMapScript HandleGameObject(Forges[i].BellowGUID, data != NOT_STARTED); HandleGameObject(Forges[i].FireGUID, data != NOT_STARTED); Forges[i].Event = data; - - if (data == DONE) - SaveToDB(); break; } default: @@ -176,16 +172,11 @@ class instance_utgarde_keep : public InstanceMapScript } } - void WriteSaveDataMore(std::ostringstream& data) override - { - for (uint8 i = 0; i < 3; ++i) - data << Forges[i].Event << ' '; - } - - void ReadSaveDataMore(std::istringstream& data) override + void AfterDataLoad() override { - for (uint8 i = 0; i < 3; ++i) - data >> Forges[i].Event; + if (GetBossState(DATA_PRINCE_KELESETH) == DONE) + for (uint8 i = 0; i < 3; ++i) + Forges[i].Event = DONE; } protected: diff --git a/src/server/scripts/Northrend/VioletHold/instance_violet_hold.cpp b/src/server/scripts/Northrend/VioletHold/instance_violet_hold.cpp index 58723958ed4..8cbeee0cb1b 100644 --- a/src/server/scripts/Northrend/VioletHold/instance_violet_hold.cpp +++ b/src/server/scripts/Northrend/VioletHold/instance_violet_hold.cpp @@ -26,7 +26,6 @@ #include "TaskScheduler.h" #include "ScriptMgr.h" #include "TemporarySummon.h" -#include <sstream> /* * TODO: @@ -197,16 +196,15 @@ class instance_violet_hold : public InstanceMapScript struct instance_violet_hold_InstanceMapScript : public InstanceScript { - instance_violet_hold_InstanceMapScript(InstanceMap* map) : InstanceScript(map) + instance_violet_hold_InstanceMapScript(InstanceMap* map) : InstanceScript(map), + FirstBossId(*this, "FirstBossId", 0), + SecondBossId(*this, "SecondBossId", 0) { SetHeaders(DataHeader); SetBossNumber(EncounterCount); LoadObjectData(creatureData, gameObjectData); LoadMinionData(minionData); - FirstBossId = 0; - SecondBossId = 0; - DoorIntegrity = 100; WaveCount = 0; EventState = NOT_STARTED; @@ -794,17 +792,6 @@ class instance_violet_hold : public InstanceMapScript } } - void WriteSaveDataMore(std::ostringstream& data) override - { - data << FirstBossId << ' ' << SecondBossId; - } - - void ReadSaveDataMore(std::istringstream& data) override - { - data >> FirstBossId; - data >> SecondBossId; - } - bool CheckWipe() const { Map::PlayerList const& players = instance->GetPlayers(); @@ -943,8 +930,8 @@ class instance_violet_hold : public InstanceMapScript static uint8 const ActivationCrystalCount = 5; ObjectGuid ActivationCrystalGUIDs[ActivationCrystalCount]; - uint32 FirstBossId; - uint32 SecondBossId; + PersistentInstanceScriptValue<uint32> FirstBossId; + PersistentInstanceScriptValue<uint32> SecondBossId; uint8 DoorIntegrity; uint8 WaveCount; diff --git a/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/instance_serpent_shrine.cpp b/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/instance_serpent_shrine.cpp index ebde8fa0ccc..d50073a73d5 100644 --- a/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/instance_serpent_shrine.cpp +++ b/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/instance_serpent_shrine.cpp @@ -26,12 +26,10 @@ EndScriptData */ #include "GameObject.h" #include "GameObjectAI.h" #include "InstanceScript.h" -#include "Log.h" #include "Map.h" #include "Player.h" #include "serpent_shrine.h" #include "TemporarySummon.h" -#include <sstream> #define MAX_ENCOUNTER 6 @@ -285,7 +283,6 @@ class instance_serpent_shrine : public InstanceMapScript case DATA_TRASH: if (data == 1 && TrashCount < MIN_KILLS) ++TrashCount;//+1 died - SaveToDB(); break; case DATA_WATER: Water = data; @@ -350,16 +347,6 @@ class instance_serpent_shrine : public InstanceMapScript return 0; } - void WriteSaveDataMore(std::ostringstream& stream) override - { - stream << TrashCount; - } - - void ReadSaveDataMore(std::istringstream& stream) override - { - stream >> TrashCount; - } - private: ObjectGuid LurkerBelow; ObjectGuid Sharkkis; diff --git a/src/server/scripts/Outland/HellfireCitadel/ShatteredHalls/instance_shattered_halls.cpp b/src/server/scripts/Outland/HellfireCitadel/ShatteredHalls/instance_shattered_halls.cpp index cb856a4de10..52dec1e3174 100644 --- a/src/server/scripts/Outland/HellfireCitadel/ShatteredHalls/instance_shattered_halls.cpp +++ b/src/server/scripts/Outland/HellfireCitadel/ShatteredHalls/instance_shattered_halls.cpp @@ -30,7 +30,6 @@ EndScriptData */ #include "shattered_halls.h" #include "SpellAuras.h" #include "TemporarySummon.h" -#include <sstream> DoorData const doorData[] = { @@ -118,7 +117,6 @@ class instance_shattered_halls : public InstanceMapScript executionTimer = 55 * MINUTE * IN_MILLISECONDS; DoCastSpellOnPlayers(SPELL_KARGATH_EXECUTIONER_1); executionerGUID = creature->GetGUID(); - SaveToDB(); break; case NPC_CAPTAIN_ALINA: case NPC_CAPTAIN_BONESHATTER: @@ -153,7 +151,6 @@ class instance_shattered_halls : public InstanceMapScript { DoCastSpellOnPlayers(SPELL_REMOVE_KARGATH_EXECUTIONER); executionTimer = 0; - SaveToDB(); } break; case DATA_KARGATH: @@ -185,47 +182,11 @@ class instance_shattered_halls : public InstanceMapScript } } - void WriteSaveDataMore(std::ostringstream& data) override + void AfterDataLoad() override { - if (!instance->IsHeroic()) - return; - - data << uint32(executed) << ' ' - << executionTimer << ' '; - } - - void ReadSaveDataMore(std::istringstream& data) override - { - if (!instance->IsHeroic()) - return; - - uint32 readbuff; - data >> readbuff; - executed = uint8(readbuff); - data >> readbuff; - - if (executed > VictimCount) - { - executed = VictimCount; - executionTimer = 0; - return; - } - - if (!readbuff) - return; - - Creature* executioner = nullptr; - - instance->LoadGrid(Executioner.GetPositionX(), Executioner.GetPositionY()); - if (Creature* kargath = instance->GetCreature(kargathGUID)) - if (executionerGUID.IsEmpty()) - executioner = kargath->SummonCreature(NPC_SHATTERED_EXECUTIONER, Executioner); - - if (executioner) - for (uint8 i = executed; i < VictimCount; ++i) - executioner->SummonCreature(executionerVictims[i](GetData(DATA_TEAM_IN_INSTANCE)), executionerVictims[i].GetPos()); - - executionTimer = readbuff; + // timed events are not resumable after reset/crash + executed = VictimCount; + executionTimer = 0; } uint32 GetData(uint32 type) const override @@ -266,8 +227,6 @@ class instance_shattered_halls : public InstanceMapScript if (Creature* executioner = instance->GetCreature(executionerGUID)) executioner->AI()->SetData(DATA_PRISONERS_EXECUTED, executed); - - SaveToDB(); } else executionTimer -= diff; |