mirror of
https://github.com/TrinityCore/TrinityCore.git
synced 2026-01-15 23:20:36 +01:00
Core/Scripts: Save instance data in JSON format
This commit is contained in:
1
sql/updates/world/master/2022_10_03_00_world.sql
Normal file
1
sql/updates/world/master/2022_10_03_00_world.sql
Normal file
@@ -0,0 +1 @@
|
||||
DELETE FROM `areatrigger_scripts` WHERE `ScriptName`='at_icc_start_blood_quickening';
|
||||
@@ -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())
|
||||
|
||||
@@ -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();
|
||||
std::string GetSaveData();
|
||||
|
||||
virtual std::string UpdateSaveData(std::string const& oldData, UpdateSaveDataEvent const& event);
|
||||
|
||||
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
|
||||
|
||||
270
src/server/game/Instances/InstanceScriptData.cpp
Normal file
270
src/server/game/Instances/InstanceScriptData.cpp
Normal file
@@ -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);
|
||||
}
|
||||
86
src/server/game/Instances/InstanceScriptData.h
Normal file
86
src/server/game/Instances/InstanceScriptData.h
Normal file
@@ -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__
|
||||
@@ -3014,13 +3014,11 @@ 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;
|
||||
if (dungeonEncounter)
|
||||
instanceCompletedEncounters |= 1u << dungeonEncounter->Bit;
|
||||
uint32 instanceCompletedEncounters = i_instanceLock->GetData()->CompletedEncountersMask | (1u << updateSaveDataEvent.DungeonEncounter->Bit);
|
||||
|
||||
MapDb2Entries entries{ GetEntry(), GetMapDifficulty() };
|
||||
|
||||
@@ -3028,7 +3026,7 @@ void InstanceMap::UpdateInstanceLock(DungeonEncounterEntry const* dungeonEncount
|
||||
|
||||
if (entries.IsInstanceIdBound())
|
||||
sInstanceLockMgr.UpdateSharedInstanceLock(trans,
|
||||
{ GetInstanceId(), i_data->GetSaveData(), instanceCompletedEncounters, dungeonEncounter });
|
||||
{ GetInstanceId(), i_data->GetSaveData(), instanceCompletedEncounters, updateSaveDataEvent.DungeonEncounter });
|
||||
|
||||
for (MapReference& mapReference : m_mapRefManager)
|
||||
{
|
||||
@@ -3045,7 +3043,52 @@ 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->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;
|
||||
|
||||
MapDb2Entries entries{ GetEntry(), GetMapDifficulty() };
|
||||
|
||||
CharacterDatabaseTransaction trans = CharacterDatabase.BeginTransaction();
|
||||
|
||||
if (entries.IsInstanceIdBound())
|
||||
sInstanceLockMgr.UpdateSharedInstanceLock(trans,
|
||||
{ GetInstanceId(), i_data->GetSaveData(), instanceCompletedEncounters, nullptr });
|
||||
|
||||
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->UpdateAdditionalSaveData(oldData ? *oldData : "", updateSaveDataEvent), instanceCompletedEncounters, nullptr });
|
||||
|
||||
if (isNewLock)
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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())
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -21,7 +21,6 @@
|
||||
#include "gnomeregan.h"
|
||||
#include "InstanceScript.h"
|
||||
#include "Map.h"
|
||||
#include <sstream>
|
||||
|
||||
class instance_gnomeregan : public InstanceMapScript
|
||||
{
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -167,7 +167,7 @@ public:
|
||||
return ObjectGuid::Empty;
|
||||
}
|
||||
|
||||
void ReadSaveDataMore(std::istringstream&) override
|
||||
void AfterDataLoad() override
|
||||
{
|
||||
if (GetBossState(DATA_LIEUTENANT_DRAKE) == DONE)
|
||||
mBarrelCount = 5;
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
#include "CreatureAIImpl.h"
|
||||
|
||||
#define ToCScriptName "instance_trial_of_the_champion"
|
||||
#define DataHeader "TC"
|
||||
#define DataHeader "TCv0.1"
|
||||
|
||||
enum TCData
|
||||
{
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
if (GetBossState(DATA_FALRIC) == DONE)
|
||||
{
|
||||
_introState = DONE;
|
||||
_quelDelarState = DONE;
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
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:
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
void AfterDataLoad() override
|
||||
{
|
||||
data << ColossusData << ' ' << _algalonTimer << ' ' << uint32(_algalonSummoned ? 1 : 0);
|
||||
if (GetBossState(DATA_FLAME_LEVIATHAN) == DONE)
|
||||
SetData(DATA_COLOSSUS, DONE);
|
||||
|
||||
for (uint8 i = 0; i < 4; ++i)
|
||||
data << ' ' << uint32(!KeeperGUIDs[i].IsEmpty() ? 1 : 0);
|
||||
|
||||
data << ' ' << _CoUAchivePlayerDeathMask;
|
||||
}
|
||||
|
||||
void ReadSaveDataMore(std::istringstream& data) 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_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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
void AfterDataLoad() override
|
||||
{
|
||||
for (uint8 i = 0; i < 3; ++i)
|
||||
data << Forges[i].Event << ' ';
|
||||
}
|
||||
|
||||
void ReadSaveDataMore(std::istringstream& data) 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:
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user