aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/server/authserver/Authentication/AuthCodes.cpp1
-rw-r--r--src/server/authserver/Server/AuthSocket.cpp6
-rw-r--r--src/server/authserver/Server/RealmSocket.cpp4
-rw-r--r--src/server/collision/Management/VMapManager2.cpp3
-rw-r--r--src/server/collision/Maps/MapTree.cpp74
-rw-r--r--src/server/collision/Maps/MapTree.h3
-rw-r--r--src/server/collision/Maps/TileAssembler.cpp32
-rw-r--r--src/server/collision/Maps/TileAssembler.h4
-rw-r--r--src/server/collision/Models/WorldModel.cpp55
-rw-r--r--src/server/game/AI/CoreAI/UnitAI.cpp49
-rw-r--r--src/server/game/AI/SmartScripts/SmartScript.cpp26
-rw-r--r--src/server/game/AI/SmartScripts/SmartScriptMgr.h1
-rw-r--r--src/server/game/Achievements/AchievementMgr.cpp19
-rw-r--r--src/server/game/Battlefield/Zones/BattlefieldWG.h1
-rw-r--r--src/server/game/Battlegrounds/ArenaTeam.cpp36
-rw-r--r--src/server/game/Battlegrounds/ArenaTeam.h2
-rw-r--r--src/server/game/Chat/Chat.cpp4
-rw-r--r--src/server/game/Chat/Chat.h2
-rw-r--r--src/server/game/Entities/Creature/Creature.cpp38
-rw-r--r--src/server/game/Entities/Creature/GossipDef.cpp44
-rw-r--r--src/server/game/Entities/GameObject/GameObject.cpp5
-rw-r--r--src/server/game/Entities/Item/Item.cpp24
-rw-r--r--src/server/game/Entities/Item/Item.h4
-rw-r--r--src/server/game/Entities/Player/Player.cpp22
-rw-r--r--src/server/game/Entities/Transport/Transport.cpp22
-rw-r--r--src/server/game/Entities/Transport/Transport.h4
-rw-r--r--src/server/game/Entities/Unit/Unit.cpp13
-rw-r--r--src/server/game/Entities/Vehicle/Vehicle.cpp20
-rw-r--r--src/server/game/Entities/Vehicle/Vehicle.h4
-rw-r--r--src/server/game/Entities/Vehicle/VehicleDefines.h4
-rw-r--r--src/server/game/Handlers/ItemHandler.cpp24
-rw-r--r--src/server/game/Handlers/MailHandler.cpp10
-rw-r--r--src/server/game/Handlers/QuestHandler.cpp2
-rw-r--r--src/server/game/Miscellaneous/Language.h61
-rw-r--r--src/server/game/Movement/MotionMaster.h4
-rw-r--r--src/server/game/Movement/Spline/MoveSplineInit.cpp7
-rw-r--r--src/server/game/Scripting/ScriptLoader.cpp2
-rw-r--r--src/server/game/Server/Protocol/Opcodes.cpp37
-rw-r--r--src/server/game/Server/Protocol/Opcodes.h2
-rw-r--r--src/server/game/Server/WorldSession.h2
-rw-r--r--src/server/game/Spells/SpellEffects.cpp10
-rw-r--r--src/server/game/Spells/SpellMgr.cpp3
-rw-r--r--src/server/scripts/Commands/CMakeLists.txt1
-rw-r--r--src/server/scripts/Commands/cs_arena.cpp347
-rw-r--r--src/server/scripts/Commands/cs_misc.cpp382
-rw-r--r--src/server/scripts/Commands/cs_server.cpp3
-rw-r--r--src/server/scripts/EasternKingdoms/SunwellPlateau/boss_kalecgos.cpp19
-rw-r--r--src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/boss_falric.cpp8
-rw-r--r--src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/boss_marwyn.cpp8
-rw-r--r--src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/halls_of_reflection.cpp950
-rw-r--r--src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/halls_of_reflection.h136
-rw-r--r--src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/instance_halls_of_reflection.cpp667
-rw-r--r--src/server/scripts/Northrend/Gundrak/gundrak.h31
-rw-r--r--src/server/scripts/Northrend/Gundrak/instance_gundrak.cpp334
-rw-r--r--src/server/scripts/Spells/spell_quest.cpp32
-rw-r--r--src/server/shared/Database/Implementation/CharacterDatabase.cpp7
-rwxr-xr-xsrc/server/shared/Database/Implementation/CharacterDatabase.h3
-rw-r--r--src/server/shared/Database/Implementation/LoginDatabase.cpp2
-rw-r--r--src/server/shared/Database/Implementation/WorldDatabase.cpp2
-rw-r--r--src/server/shared/Database/Implementation/WorldDatabase.h1
60 files changed, 2327 insertions, 1296 deletions
diff --git a/src/server/authserver/Authentication/AuthCodes.cpp b/src/server/authserver/Authentication/AuthCodes.cpp
index 55229e0d18b..b47ef21b24b 100644
--- a/src/server/authserver/Authentication/AuthCodes.cpp
+++ b/src/server/authserver/Authentication/AuthCodes.cpp
@@ -37,6 +37,7 @@ namespace AuthHelper
static RealmBuildInfo const PreBcAcceptedClientBuilds[] =
{
+ {6141, 1, 12, 3, ' '},
{6005, 1, 12, 2, ' '},
{5875, 1, 12, 1, ' '},
{0, 0, 0, 0, ' '} // terminator
diff --git a/src/server/authserver/Server/AuthSocket.cpp b/src/server/authserver/Server/AuthSocket.cpp
index 2e73498eb52..792e1bf2a86 100644
--- a/src/server/authserver/Server/AuthSocket.cpp
+++ b/src/server/authserver/Server/AuthSocket.cpp
@@ -196,12 +196,12 @@ const AuthHandler table[] =
Patcher PatchesCache;
// Constructor - set the N and g values for SRP6
-AuthSocket::AuthSocket(RealmSocket& socket) : pPatch(NULL), socket_(socket)
+AuthSocket::AuthSocket(RealmSocket& socket) :
+ pPatch(NULL), socket_(socket), _authed(false), _build(0),
+ _expversion(0), _accountSecurityLevel(SEC_PLAYER)
{
N.SetHexStr("894B645E89E1535BBDAD5B8B290650530801B18EBFBF5E8FAB3C82872A3E9BB7");
g.SetDword(7);
- _authed = false;
- _accountSecurityLevel = SEC_PLAYER;
}
// Close patch file descriptor before leaving
diff --git a/src/server/authserver/Server/RealmSocket.cpp b/src/server/authserver/Server/RealmSocket.cpp
index e249894a4d3..6710a6a88ae 100644
--- a/src/server/authserver/Server/RealmSocket.cpp
+++ b/src/server/authserver/Server/RealmSocket.cpp
@@ -27,7 +27,9 @@ RealmSocket::Session::Session(void) {}
RealmSocket::Session::~Session(void) { }
-RealmSocket::RealmSocket(void) : input_buffer_(4096), session_(NULL), _remoteAddress()
+RealmSocket::RealmSocket(void) :
+ input_buffer_(4096), session_(NULL),
+ _remoteAddress(), _remotePort(0)
{
reference_counting_policy().value(ACE_Event_Handler::Reference_Counting_Policy::ENABLED);
diff --git a/src/server/collision/Management/VMapManager2.cpp b/src/server/collision/Management/VMapManager2.cpp
index 8a1bd346957..6355dbcf4ce 100644
--- a/src/server/collision/Management/VMapManager2.cpp
+++ b/src/server/collision/Management/VMapManager2.cpp
@@ -96,7 +96,10 @@ namespace VMAP
std::string mapFileName = getMapFileName(mapId);
StaticMapTree* newTree = new StaticMapTree(mapId, basePath);
if (!newTree->InitMap(mapFileName, this))
+ {
+ delete newTree;
return false;
+ }
instanceTree = iInstanceMapTrees.insert(InstanceTreeMap::value_type(mapId, newTree)).first;
}
diff --git a/src/server/collision/Maps/MapTree.cpp b/src/server/collision/Maps/MapTree.cpp
index 7dbfcd78bc9..dc12bb68e0d 100644
--- a/src/server/collision/Maps/MapTree.cpp
+++ b/src/server/collision/Maps/MapTree.cpp
@@ -119,8 +119,9 @@ namespace VMAP
return intersectionCallBack.result;
}
- StaticMapTree::StaticMapTree(uint32 mapID, const std::string &basePath)
- : iMapID(mapID), iIsTiled(false), iTreeValues(0), iBasePath(basePath)
+ StaticMapTree::StaticMapTree(uint32 mapID, const std::string &basePath) :
+ iMapID(mapID), iIsTiled(false), iTreeValues(NULL),
+ iNTreeValues(0), iBasePath(basePath)
{
if (iBasePath.length() > 0 && iBasePath[iBasePath.length()-1] != '/' && iBasePath[iBasePath.length()-1] != '\\')
{
@@ -273,54 +274,49 @@ namespace VMAP
bool StaticMapTree::InitMap(const std::string &fname, VMapManager2* vm)
{
VMAP_DEBUG_LOG(LOG_FILTER_MAPS, "StaticMapTree::InitMap() : initializing StaticMapTree '%s'", fname.c_str());
- bool success = true;
+ bool success = false;
std::string fullname = iBasePath + fname;
FILE* rf = fopen(fullname.c_str(), "rb");
if (!rf)
return false;
- else
+
+ char chunk[8];
+ char tiled = '\0';
+
+ if (readChunk(rf, chunk, VMAP_MAGIC, 8) && fread(&tiled, sizeof(char), 1, rf) == 1 &&
+ readChunk(rf, chunk, "NODE", 4) && iTree.readFromFile(rf))
{
- char chunk[8];
- //general info
- if (!readChunk(rf, chunk, VMAP_MAGIC, 8)) success = false;
- char tiled = '\0';
- if (success && fread(&tiled, sizeof(char), 1, rf) != 1) success = false;
- iIsTiled = bool(tiled);
- // Nodes
- if (success && !readChunk(rf, chunk, "NODE", 4)) success = false;
- if (success) success = iTree.readFromFile(rf);
- if (success)
- {
- iNTreeValues = iTree.primCount();
- iTreeValues = new ModelInstance[iNTreeValues];
- }
+ iNTreeValues = iTree.primCount();
+ iTreeValues = new ModelInstance[iNTreeValues];
+ success = readChunk(rf, chunk, "GOBJ", 4);
+ }
+
+ iIsTiled = bool(tiled);
- if (success && !readChunk(rf, chunk, "GOBJ", 4)) success = false;
- // global model spawns
- // only non-tiled maps have them, and if so exactly one (so far at least...)
- ModelSpawn spawn;
+ // global model spawns
+ // only non-tiled maps have them, and if so exactly one (so far at least...)
+ ModelSpawn spawn;
#ifdef VMAP_DEBUG
- TC_LOG_DEBUG(LOG_FILTER_MAPS, "StaticMapTree::InitMap() : map isTiled: %u", static_cast<uint32>(iIsTiled));
+ TC_LOG_DEBUG(LOG_FILTER_MAPS, "StaticMapTree::InitMap() : map isTiled: %u", static_cast<uint32>(iIsTiled));
#endif
- if (!iIsTiled && ModelSpawn::readFromFile(rf, spawn))
+ if (!iIsTiled && ModelSpawn::readFromFile(rf, spawn))
+ {
+ WorldModel* model = vm->acquireModelInstance(iBasePath, spawn.name);
+ VMAP_DEBUG_LOG(LOG_FILTER_MAPS, "StaticMapTree::InitMap() : loading %s", spawn.name.c_str());
+ if (model)
{
- WorldModel* model = vm->acquireModelInstance(iBasePath, spawn.name);
- VMAP_DEBUG_LOG(LOG_FILTER_MAPS, "StaticMapTree::InitMap() : loading %s", spawn.name.c_str());
- if (model)
- {
- // assume that global model always is the first and only tree value (could be improved...)
- iTreeValues[0] = ModelInstance(spawn, model);
- iLoadedSpawns[0] = 1;
- }
- else
- {
- success = false;
- VMAP_ERROR_LOG(LOG_FILTER_GENERAL, "StaticMapTree::InitMap() : could not acquire WorldModel pointer for '%s'", spawn.name.c_str());
- }
+ // assume that global model always is the first and only tree value (could be improved...)
+ iTreeValues[0] = ModelInstance(spawn, model);
+ iLoadedSpawns[0] = 1;
+ }
+ else
+ {
+ success = false;
+ VMAP_ERROR_LOG(LOG_FILTER_GENERAL, "StaticMapTree::InitMap() : could not acquire WorldModel pointer for '%s'", spawn.name.c_str());
}
-
- fclose(rf);
}
+
+ fclose(rf);
return success;
}
diff --git a/src/server/collision/Maps/MapTree.h b/src/server/collision/Maps/MapTree.h
index e97c44d089e..c66893da82f 100644
--- a/src/server/collision/Maps/MapTree.h
+++ b/src/server/collision/Maps/MapTree.h
@@ -85,7 +85,8 @@ namespace VMAP
struct AreaInfo
{
- AreaInfo(): result(false), ground_Z(-G3D::inf()) {}
+ AreaInfo(): result(false), ground_Z(-G3D::inf()), flags(0), adtId(0),
+ rootId(0), groupId(0) {}
bool result;
float ground_Z;
uint32 flags;
diff --git a/src/server/collision/Maps/TileAssembler.cpp b/src/server/collision/Maps/TileAssembler.cpp
index a73e5ed4dc3..b2d381b0ffd 100644
--- a/src/server/collision/Maps/TileAssembler.cpp
+++ b/src/server/collision/Maps/TileAssembler.cpp
@@ -152,23 +152,25 @@ namespace VMAP
uint32 x, y;
StaticMapTree::unpackTileID(tile->first, x, y);
tilefilename << std::setw(2) << x << '_' << std::setw(2) << y << ".vmtile";
- FILE* tilefile = fopen(tilefilename.str().c_str(), "wb");
- // file header
- if (success && fwrite(VMAP_MAGIC, 1, 8, tilefile) != 8) success = false;
- // write number of tile spawns
- if (success && fwrite(&nSpawns, sizeof(uint32), 1, tilefile) != 1) success = false;
- // write tile spawns
- for (uint32 s=0; s<nSpawns; ++s)
+ if (FILE* tilefile = fopen(tilefilename.str().c_str(), "wb"))
{
- if (s)
- ++tile;
- const ModelSpawn &spawn2 = map_iter->second->UniqueEntries[tile->second];
- success = success && ModelSpawn::writeToFile(tilefile, spawn2);
- // MapTree nodes to update when loading tile:
- std::map<uint32, uint32>::iterator nIdx = modelNodeIdx.find(spawn2.ID);
- if (success && fwrite(&nIdx->second, sizeof(uint32), 1, tilefile) != 1) success = false;
+ // file header
+ if (success && fwrite(VMAP_MAGIC, 1, 8, tilefile) != 8) success = false;
+ // write number of tile spawns
+ if (success && fwrite(&nSpawns, sizeof(uint32), 1, tilefile) != 1) success = false;
+ // write tile spawns
+ for (uint32 s=0; s<nSpawns; ++s)
+ {
+ if (s)
+ ++tile;
+ const ModelSpawn &spawn2 = map_iter->second->UniqueEntries[tile->second];
+ success = success && ModelSpawn::writeToFile(tilefile, spawn2);
+ // MapTree nodes to update when loading tile:
+ std::map<uint32, uint32>::iterator nIdx = modelNodeIdx.find(spawn2.ID);
+ if (success && fwrite(&nIdx->second, sizeof(uint32), 1, tilefile) != 1) success = false;
+ }
+ fclose(tilefile);
}
- fclose(tilefile);
}
// break; //test, extract only first map; TODO: remvoe this line
}
diff --git a/src/server/collision/Maps/TileAssembler.h b/src/server/collision/Maps/TileAssembler.h
index a11ce272d62..56cb7600e4f 100644
--- a/src/server/collision/Maps/TileAssembler.h
+++ b/src/server/collision/Maps/TileAssembler.h
@@ -40,6 +40,7 @@ namespace VMAP
private:
G3D::Matrix3 iRotation;
public:
+ ModelPosition(): iScale(0.0f) { }
G3D::Vector3 iPos;
G3D::Vector3 iDir;
float iScale;
@@ -74,7 +75,8 @@ namespace VMAP
std::vector<G3D::Vector3> vertexArray;
class WmoLiquid* liquid;
- GroupModel_Raw() : liquid(0) {}
+ GroupModel_Raw() : mogpflags(0), GroupWMOID(0), liquidflags(0),
+ liquid(NULL) {}
~GroupModel_Raw();
bool Read(FILE* f);
diff --git a/src/server/collision/Models/WorldModel.cpp b/src/server/collision/Models/WorldModel.cpp
index ca0f95c74e3..3c72cb80308 100644
--- a/src/server/collision/Models/WorldModel.cpp
+++ b/src/server/collision/Models/WorldModel.cpp
@@ -205,35 +205,48 @@ namespace VMAP
bool WmoLiquid::writeToFile(FILE* wf)
{
- bool result = true;
- if (result && fwrite(&iTilesX, sizeof(uint32), 1, wf) != 1) result = false;
- if (result && fwrite(&iTilesY, sizeof(uint32), 1, wf) != 1) result = false;
- if (result && fwrite(&iCorner, sizeof(Vector3), 1, wf) != 1) result = false;
- if (result && fwrite(&iType, sizeof(uint32), 1, wf) != 1) result = false;
- uint32 size = (iTilesX + 1)*(iTilesY + 1);
- if (result && fwrite(iHeight, sizeof(float), size, wf) != size) result = false;
- size = iTilesX*iTilesY;
- if (result && fwrite(iFlags, sizeof(uint8), size, wf) != size) result = false;
+ bool result = false;
+ if (fwrite(&iTilesX, sizeof(uint32), 1, wf) == 1 &&
+ fwrite(&iTilesY, sizeof(uint32), 1, wf) == 1 &&
+ fwrite(&iCorner, sizeof(Vector3), 1, wf) == 1 &&
+ fwrite(&iType, sizeof(uint32), 1, wf) == 1)
+ {
+ uint32 size = (iTilesX + 1) * (iTilesY + 1);
+ if (fwrite(iHeight, sizeof(float), size, wf) == size)
+ {
+ size = iTilesX*iTilesY;
+ result = fwrite(iFlags, sizeof(uint8), size, wf) == size;
+ }
+ }
+
return result;
}
bool WmoLiquid::readFromFile(FILE* rf, WmoLiquid* &out)
{
- bool result = true;
+ bool result = false;
WmoLiquid* liquid = new WmoLiquid();
- if (result && fread(&liquid->iTilesX, sizeof(uint32), 1, rf) != 1) result = false;
- if (result && fread(&liquid->iTilesY, sizeof(uint32), 1, rf) != 1) result = false;
- if (result && fread(&liquid->iCorner, sizeof(Vector3), 1, rf) != 1) result = false;
- if (result && fread(&liquid->iType, sizeof(uint32), 1, rf) != 1) result = false;
- uint32 size = (liquid->iTilesX + 1)*(liquid->iTilesY + 1);
- liquid->iHeight = new float[size];
- if (result && fread(liquid->iHeight, sizeof(float), size, rf) != size) result = false;
- size = liquid->iTilesX * liquid->iTilesY;
- liquid->iFlags = new uint8[size];
- if (result && fread(liquid->iFlags, sizeof(uint8), size, rf) != size) result = false;
+
+ if (fread(&liquid->iTilesX, sizeof(uint32), 1, rf) == 1 &&
+ fread(&liquid->iTilesY, sizeof(uint32), 1, rf) == 1 &&
+ fread(&liquid->iCorner, sizeof(Vector3), 1, rf) == 1 &&
+ fread(&liquid->iType, sizeof(uint32), 1, rf) == 1)
+ {
+ uint32 size = (liquid->iTilesX + 1) * (liquid->iTilesY + 1);
+ liquid->iHeight = new float[size];
+ if (fread(liquid->iHeight, sizeof(float), size, rf) == size)
+ {
+ size = liquid->iTilesX * liquid->iTilesY;
+ liquid->iFlags = new uint8[size];
+ result = fread(liquid->iFlags, sizeof(uint8), size, rf) == size;
+ }
+ }
+
if (!result)
delete liquid;
- out = liquid;
+ else
+ out = liquid;
+
return result;
}
diff --git a/src/server/game/AI/CoreAI/UnitAI.cpp b/src/server/game/AI/CoreAI/UnitAI.cpp
index 0ab807466d5..70c4761e025 100644
--- a/src/server/game/AI/CoreAI/UnitAI.cpp
+++ b/src/server/game/AI/CoreAI/UnitAI.cpp
@@ -123,34 +123,45 @@ void UnitAI::DoCastToAllHostilePlayers(uint32 spellid, bool triggered)
void UnitAI::DoCast(uint32 spellId)
{
Unit* target = NULL;
- //TC_LOG_ERROR(LOG_FILTER_GENERAL, "aggre %u %u", spellId, (uint32)AISpellInfo[spellId].target);
+
switch (AISpellInfo[spellId].target)
{
default:
- case AITARGET_SELF: target = me; break;
- case AITARGET_VICTIM: target = me->getVictim(); break;
+ case AITARGET_SELF:
+ target = me;
+ break;
+ case AITARGET_VICTIM:
+ target = me->getVictim();
+ break;
case AITARGET_ENEMY:
{
- const SpellInfo* spellInfo = sSpellMgr->GetSpellInfo(spellId);
- bool playerOnly = spellInfo->AttributesEx3 & SPELL_ATTR3_ONLY_TARGET_PLAYERS;
- //float range = GetSpellMaxRange(spellInfo, false);
- target = SelectTarget(SELECT_TARGET_RANDOM, 0, spellInfo->GetMaxRange(false), playerOnly);
+ if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId))
+ {
+ bool playerOnly = spellInfo->AttributesEx3 & SPELL_ATTR3_ONLY_TARGET_PLAYERS;
+ target = SelectTarget(SELECT_TARGET_RANDOM, 0, spellInfo->GetMaxRange(false), playerOnly);
+ }
break;
}
- case AITARGET_ALLY: target = me; break;
- case AITARGET_BUFF: target = me; break;
+ case AITARGET_ALLY:
+ target = me;
+ break;
+ case AITARGET_BUFF:
+ target = me;
+ break;
case AITARGET_DEBUFF:
{
- const SpellInfo* spellInfo = sSpellMgr->GetSpellInfo(spellId);
- bool playerOnly = spellInfo->AttributesEx3 & SPELL_ATTR3_ONLY_TARGET_PLAYERS;
- float range = spellInfo->GetMaxRange(false);
-
- DefaultTargetSelector targetSelector(me, range, playerOnly, -(int32)spellId);
- if (!(spellInfo->AuraInterruptFlags & AURA_INTERRUPT_FLAG_NOT_VICTIM)
- && targetSelector(me->getVictim()))
- target = me->getVictim();
- else
- target = SelectTarget(SELECT_TARGET_RANDOM, 0, targetSelector);
+ if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId))
+ {
+ bool playerOnly = spellInfo->AttributesEx3 & SPELL_ATTR3_ONLY_TARGET_PLAYERS;
+ float range = spellInfo->GetMaxRange(false);
+
+ DefaultTargetSelector targetSelector(me, range, playerOnly, -(int32)spellId);
+ if (!(spellInfo->AuraInterruptFlags & AURA_INTERRUPT_FLAG_NOT_VICTIM)
+ && targetSelector(me->getVictim()))
+ target = me->getVictim();
+ else
+ target = SelectTarget(SELECT_TARGET_RANDOM, 0, targetSelector);
+ }
break;
}
}
diff --git a/src/server/game/AI/SmartScripts/SmartScript.cpp b/src/server/game/AI/SmartScripts/SmartScript.cpp
index 576d77a2e24..9d182ee6885 100644
--- a/src/server/game/AI/SmartScripts/SmartScript.cpp
+++ b/src/server/game/AI/SmartScripts/SmartScript.cpp
@@ -657,9 +657,18 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
{
if (IsUnit(*itr))
{
- (*itr)->ToUnit()->SetFlag(UNIT_FIELD_FLAGS, e.action.unitFlag.flag);
- TC_LOG_DEBUG(LOG_FILTER_DATABASE_AI, "SmartScript::ProcessAction:: SMART_ACTION_SET_UNIT_FLAG. Unit %u added flag %u to UNIT_FIELD_FLAGS",
+ if (!e.action.unitFlag.type)
+ {
+ (*itr)->ToUnit()->SetFlag(UNIT_FIELD_FLAGS, e.action.unitFlag.flag);
+ TC_LOG_DEBUG(LOG_FILTER_DATABASE_AI, "SmartScript::ProcessAction:: SMART_ACTION_SET_UNIT_FLAG. Unit %u added flag %u to UNIT_FIELD_FLAGS",
+ (*itr)->GetGUIDLow(), e.action.unitFlag.flag);
+ }
+ else
+ {
+ (*itr)->ToUnit()->SetFlag(UNIT_FIELD_FLAGS_2, e.action.unitFlag.flag);
+ TC_LOG_DEBUG(LOG_FILTER_DATABASE_AI, "SmartScript::ProcessAction:: SMART_ACTION_SET_UNIT_FLAG. Unit %u added flag %u to UNIT_FIELD_FLAGS_2",
(*itr)->GetGUIDLow(), e.action.unitFlag.flag);
+ }
}
}
@@ -676,9 +685,18 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
{
if (IsUnit(*itr))
{
- (*itr)->ToUnit()->RemoveFlag(UNIT_FIELD_FLAGS, e.action.unitFlag.flag);
- TC_LOG_DEBUG(LOG_FILTER_DATABASE_AI, "SmartScript::ProcessAction:: SMART_ACTION_REMOVE_UNIT_FLAG. Unit %u removed flag %u to UNIT_FIELD_FLAGS",
+ if (!e.action.unitFlag.type)
+ {
+ (*itr)->ToUnit()->RemoveFlag(UNIT_FIELD_FLAGS, e.action.unitFlag.flag);
+ TC_LOG_DEBUG(LOG_FILTER_DATABASE_AI, "SmartScript::ProcessAction:: SMART_ACTION_REMOVE_UNIT_FLAG. Unit %u removed flag %u to UNIT_FIELD_FLAGS",
+ (*itr)->GetGUIDLow(), e.action.unitFlag.flag);
+ }
+ else
+ {
+ (*itr)->ToUnit()->RemoveFlag(UNIT_FIELD_FLAGS_2, e.action.unitFlag.flag);
+ TC_LOG_DEBUG(LOG_FILTER_DATABASE_AI, "SmartScript::ProcessAction:: SMART_ACTION_REMOVE_UNIT_FLAG. Unit %u removed flag %u to UNIT_FIELD_FLAGS_2",
(*itr)->GetGUIDLow(), e.action.unitFlag.flag);
+ }
}
}
diff --git a/src/server/game/AI/SmartScripts/SmartScriptMgr.h b/src/server/game/AI/SmartScripts/SmartScriptMgr.h
index 875a67d7f3c..d80b4816d4b 100644
--- a/src/server/game/AI/SmartScripts/SmartScriptMgr.h
+++ b/src/server/game/AI/SmartScripts/SmartScriptMgr.h
@@ -828,6 +828,7 @@ struct SmartAction
struct
{
uint32 flag;
+ uint32 type;
} unitFlag;
struct
diff --git a/src/server/game/Achievements/AchievementMgr.cpp b/src/server/game/Achievements/AchievementMgr.cpp
index f7811753147..888605b4745 100644
--- a/src/server/game/Achievements/AchievementMgr.cpp
+++ b/src/server/game/Achievements/AchievementMgr.cpp
@@ -406,8 +406,11 @@ void AchievementMgr<Player>::SendPacket(WorldPacket* data) const
}
template<class T>
-void AchievementMgr<T>::RemoveCriteriaProgress(const AchievementCriteriaEntry* entry)
+void AchievementMgr<T>::RemoveCriteriaProgress(AchievementCriteriaEntry const* entry)
{
+ if (!entry)
+ return;
+
CriteriaProgressMap::iterator criteriaProgress = m_criteriaProgress.find(entry->ID);
if (criteriaProgress == m_criteriaProgress.end())
return;
@@ -420,8 +423,11 @@ void AchievementMgr<T>::RemoveCriteriaProgress(const AchievementCriteriaEntry* e
}
template<>
-void AchievementMgr<Guild>::RemoveCriteriaProgress(const AchievementCriteriaEntry* entry)
+void AchievementMgr<Guild>::RemoveCriteriaProgress(AchievementCriteriaEntry const* entry)
{
+ if (!entry)
+ return;
+
CriteriaProgressMap::iterator criteriaProgress = m_criteriaProgress.find(entry->ID);
if (criteriaProgress == m_criteriaProgress.end())
return;
@@ -1448,6 +1454,9 @@ void AchievementMgr<T>::UpdateAchievementCriteria(AchievementCriteriaTypes type,
template<class T>
bool AchievementMgr<T>::IsCompletedCriteria(AchievementCriteriaEntry const* achievementCriteria, AchievementEntry const* achievement)
{
+ if (!achievement)
+ return false;
+
// counter can never complete
if (achievement->flags & ACHIEVEMENT_FLAG_COUNTER)
return false;
@@ -2049,10 +2058,14 @@ void AchievementMgr<T>::SendAllAchievementData(Player* /*receiver*/) const
template<>
void AchievementMgr<Guild>::SendAllAchievementData(Player* receiver) const
{
+ VisibleAchievementPred isVisible;
WorldPacket data(SMSG_GUILD_ACHIEVEMENT_DATA, m_completedAchievements.size() * (4 + 4) + 3);
- data.WriteBits(m_completedAchievements.size(), 23);
+ data.WriteBits(std::count_if(m_completedAchievements.begin(), m_completedAchievements.end(), isVisible), 23);
for (CompletedAchievementMap::const_iterator itr = m_completedAchievements.begin(); itr != m_completedAchievements.end(); ++itr)
{
+ if (!isVisible(*itr))
+ continue;
+
data.AppendPackedTime(itr->second.date);
data << uint32(itr->first);
}
diff --git a/src/server/game/Battlefield/Zones/BattlefieldWG.h b/src/server/game/Battlefield/Zones/BattlefieldWG.h
index 10d28118325..f2d96c1d1a0 100644
--- a/src/server/game/Battlefield/Zones/BattlefieldWG.h
+++ b/src/server/game/Battlefield/Zones/BattlefieldWG.h
@@ -1481,6 +1481,7 @@ struct WGWorkshop
bf = _bf;
workshopId = _workshopId;
+ teamControl = BATTLEFIELD_WG_TEAM_NEUTRAL;
}
void GiveControlTo(uint8 team, bool init /* for first call in setup*/)
diff --git a/src/server/game/Battlegrounds/ArenaTeam.cpp b/src/server/game/Battlegrounds/ArenaTeam.cpp
index 668858618cb..9639e36f204 100644
--- a/src/server/game/Battlegrounds/ArenaTeam.cpp
+++ b/src/server/game/Battlegrounds/ArenaTeam.cpp
@@ -271,6 +271,19 @@ bool ArenaTeam::LoadMembersFromDB(QueryResult result)
return true;
}
+bool ArenaTeam::SetName(std::string const& name)
+{
+ if (TeamName == name || name.empty() || name.length() > 24 || sObjectMgr->IsReservedName(name) || !ObjectMgr::IsValidCharterName(name))
+ return false;
+
+ TeamName = name;
+ PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_ARENA_TEAM_NAME);
+ stmt->setString(0, TeamName);
+ stmt->setUInt32(1, GetId());
+ CharacterDatabase.Execute(stmt);
+ return true;
+}
+
void ArenaTeam::SetCaptain(uint64 guid)
{
// Disable remove/promote buttons
@@ -360,6 +373,29 @@ void ArenaTeam::Disband(WorldSession* session)
sArenaTeamMgr->RemoveArenaTeam(TeamId);
}
+void ArenaTeam::Disband()
+{
+ // Remove all members from arena team
+ while (!Members.empty())
+ DelMember(Members.front().Guid, false);
+
+ // Update database
+ SQLTransaction trans = CharacterDatabase.BeginTransaction();
+
+ PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_ARENA_TEAM);
+ stmt->setUInt32(0, TeamId);
+ trans->Append(stmt);
+
+ stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_ARENA_TEAM_MEMBERS);
+ stmt->setUInt32(0, TeamId);
+ trans->Append(stmt);
+
+ CharacterDatabase.CommitTransaction(trans);
+
+ // Remove arena team from ObjectMgr
+ sArenaTeamMgr->RemoveArenaTeam(TeamId);
+}
+
void ArenaTeam::Roster(WorldSession* session)
{
Player* player = NULL;
diff --git a/src/server/game/Battlegrounds/ArenaTeam.h b/src/server/game/Battlegrounds/ArenaTeam.h
index 59b1275a549..e25fbba235b 100644
--- a/src/server/game/Battlegrounds/ArenaTeam.h
+++ b/src/server/game/Battlegrounds/ArenaTeam.h
@@ -118,6 +118,7 @@ class ArenaTeam
uint32 backgroundColor, uint8 emblemStyle, uint32 emblemColor,
uint8 borderStyle, uint32 borderColor);
void Disband(WorldSession* session);
+ void Disband();
typedef std::list<ArenaTeamMember> MemberList;
@@ -134,6 +135,7 @@ class ArenaTeam
uint32 GetAverageMMR(Group* group) const;
void SetCaptain(uint64 guid);
+ bool SetName(std::string const& name);
bool AddMember(uint64 PlayerGuid);
void DelMember(uint64 guid, bool cleanDb);
diff --git a/src/server/game/Chat/Chat.cpp b/src/server/game/Chat/Chat.cpp
index d62f9e4eaa7..1515c75597f 100644
--- a/src/server/game/Chat/Chat.cpp
+++ b/src/server/game/Chat/Chat.cpp
@@ -143,7 +143,7 @@ bool ChatHandler::isAvailable(ChatCommand const& cmd) const
return m_session->GetSecurity() >= AccountTypes(cmd.SecurityLevel);
}
- return m_session->HasPermission(permission);
+ return HasPermission(permission);
}
bool ChatHandler::HasLowerSecurity(Player* target, uint64 guid, bool strong)
@@ -205,7 +205,7 @@ bool ChatHandler::hasStringAbbr(const char* name, const char* part)
if (!*part)
return false;
- for (;;)
+ while (true)
{
if (!*part)
return true;
diff --git a/src/server/game/Chat/Chat.h b/src/server/game/Chat/Chat.h
index 538273062ae..298bb91692b 100644
--- a/src/server/game/Chat/Chat.h
+++ b/src/server/game/Chat/Chat.h
@@ -86,6 +86,7 @@ class ChatHandler
// function with different implementation for chat/console
virtual bool isAvailable(ChatCommand const& cmd) const;
+ virtual bool HasPermission(uint32 permission) const { return m_session->HasPermission(permission); }
virtual std::string GetNameLink() const { return GetNameLink(m_session->GetPlayer()); }
virtual bool needReportToTarget(Player* chr) const;
virtual LocaleConstant GetSessionDbcLocale() const;
@@ -149,6 +150,7 @@ class CliHandler : public ChatHandler
// overwrite functions
const char *GetTrinityString(int32 entry) const;
bool isAvailable(ChatCommand const& cmd) const;
+ bool HasPermission(uint32 /*permission*/) const { return true; }
void SendSysMessage(const char *str);
std::string GetNameLink() const;
bool needReportToTarget(Player* chr) const;
diff --git a/src/server/game/Entities/Creature/Creature.cpp b/src/server/game/Entities/Creature/Creature.cpp
index cf8a01a765e..79beab4f7e6 100644
--- a/src/server/game/Entities/Creature/Creature.cpp
+++ b/src/server/game/Entities/Creature/Creature.cpp
@@ -2451,19 +2451,18 @@ uint32 Creature::GetVendorItemCurrentCount(VendorItem const* vItem)
time_t ptime = time(NULL);
if (time_t(vCount->lastIncrementTime + vItem->incrtime) <= ptime)
- {
- ItemTemplate const* pProto = sObjectMgr->GetItemTemplate(vItem->item);
-
- uint32 diff = uint32((ptime - vCount->lastIncrementTime)/vItem->incrtime);
- if ((vCount->count + diff * pProto->BuyCount) >= vItem->maxcount)
+ if (ItemTemplate const* pProto = sObjectMgr->GetItemTemplate(vItem->item))
{
- m_vendorItemCounts.erase(itr);
- return vItem->maxcount;
- }
+ uint32 diff = uint32((ptime - vCount->lastIncrementTime)/vItem->incrtime);
+ if ((vCount->count + diff * pProto->BuyCount) >= vItem->maxcount)
+ {
+ m_vendorItemCounts.erase(itr);
+ return vItem->maxcount;
+ }
- vCount->count += diff * pProto->BuyCount;
- vCount->lastIncrementTime = ptime;
- }
+ vCount->count += diff * pProto->BuyCount;
+ vCount->lastIncrementTime = ptime;
+ }
return vCount->count;
}
@@ -2490,15 +2489,14 @@ uint32 Creature::UpdateVendorItemCurrentCount(VendorItem const* vItem, uint32 us
time_t ptime = time(NULL);
if (time_t(vCount->lastIncrementTime + vItem->incrtime) <= ptime)
- {
- ItemTemplate const* pProto = sObjectMgr->GetItemTemplate(vItem->item);
-
- uint32 diff = uint32((ptime - vCount->lastIncrementTime)/vItem->incrtime);
- if ((vCount->count + diff * pProto->BuyCount) < vItem->maxcount)
- vCount->count += diff * pProto->BuyCount;
- else
- vCount->count = vItem->maxcount;
- }
+ if (ItemTemplate const* pProto = sObjectMgr->GetItemTemplate(vItem->item))
+ {
+ uint32 diff = uint32((ptime - vCount->lastIncrementTime)/vItem->incrtime);
+ if ((vCount->count + diff * pProto->BuyCount) < vItem->maxcount)
+ vCount->count += diff * pProto->BuyCount;
+ else
+ vCount->count = vItem->maxcount;
+ }
vCount->count = vCount->count > used_count ? vCount->count-used_count : 0;
vCount->lastIncrementTime = ptime;
diff --git a/src/server/game/Entities/Creature/GossipDef.cpp b/src/server/game/Entities/Creature/GossipDef.cpp
index c6d9bd52e18..3cefc5881e9 100644
--- a/src/server/game/Entities/Creature/GossipDef.cpp
+++ b/src/server/game/Entities/Creature/GossipDef.cpp
@@ -184,7 +184,9 @@ void PlayerMenu::SendGossipMenu(uint32 titleTextId, uint64 objectGUID) const
data << item.BoxMessage; // accept text (related to money) pop up box, 2.0.3
}
- data << uint32(_questMenu.GetMenuItemCount()); // max count 0x20
+ size_t count_pos = data.wpos();
+ data << uint32(0); // max count 0x20
+ uint32 count = 0;
// Store this instead of checking the Singleton every loop iteration
bool questLevelInTitle = sWorld->getBoolConfig(CONFIG_UI_QUESTLEVELS_IN_DIALOGS);
@@ -193,26 +195,29 @@ void PlayerMenu::SendGossipMenu(uint32 titleTextId, uint64 objectGUID) const
{
QuestMenuItem const& item = _questMenu.GetItem(i);
uint32 questID = item.QuestId;
- Quest const* quest = sObjectMgr->GetQuestTemplate(questID);
-
- data << uint32(questID);
- data << uint32(item.QuestIcon);
- data << int32(quest->GetQuestLevel());
- data << uint32(quest->GetFlags()); // 3.3.3 quest flags
- data << uint8(0); // 3.3.3 changes icon: blue question or yellow exclamation
- std::string title = quest->GetTitle();
+ if (Quest const* quest = sObjectMgr->GetQuestTemplate(questID))
+ {
+ ++count;
+ data << uint32(questID);
+ data << uint32(item.QuestIcon);
+ data << int32(quest->GetQuestLevel());
+ data << uint32(quest->GetFlags()); // 3.3.3 quest flags
+ data << uint8(0); // 3.3.3 changes icon: blue question or yellow exclamation
+ std::string title = quest->GetTitle();
- int32 locale = _session->GetSessionDbLocaleIndex();
- if (locale >= 0)
- if (QuestLocale const* localeData = sObjectMgr->GetQuestLocale(questID))
- ObjectMgr::GetLocaleString(localeData->Title, locale, title);
+ int32 locale = _session->GetSessionDbLocaleIndex();
+ if (locale >= 0)
+ if (QuestLocale const* localeData = sObjectMgr->GetQuestLocale(questID))
+ ObjectMgr::GetLocaleString(localeData->Title, locale, title);
- if (questLevelInTitle)
- AddQuestLevelToTitle(title, quest->GetQuestLevel());
+ if (questLevelInTitle)
+ AddQuestLevelToTitle(title, quest->GetQuestLevel());
- data << title; // max 0x200
+ data << title; // max 0x200
+ }
}
+ data.put<uint8>(count_pos, count);
_session->SendPacket(&data);
}
@@ -300,20 +305,21 @@ void PlayerMenu::SendQuestGiverQuestList(QEmote eEmote, const std::string& Title
data << uint32(eEmote._Emote); // NPC emote
size_t count_pos = data.wpos();
- data << uint8 (_questMenu.GetMenuItemCount());
+ data << uint8 (0);
uint32 count = 0;
// Store this instead of checking the Singleton every loop iteration
bool questLevelInTitle = sWorld->getBoolConfig(CONFIG_UI_QUESTLEVELS_IN_DIALOGS);
- for (; count < _questMenu.GetMenuItemCount(); ++count)
+ for (uint32 i = 0; i < _questMenu.GetMenuItemCount(); ++i)
{
- QuestMenuItem const& qmi = _questMenu.GetItem(count);
+ QuestMenuItem const& qmi = _questMenu.GetItem(i);
uint32 questID = qmi.QuestId;
if (Quest const* quest = sObjectMgr->GetQuestTemplate(questID))
{
+ ++count;
std::string title = quest->GetTitle();
int32 locale = _session->GetSessionDbLocaleIndex();
diff --git a/src/server/game/Entities/GameObject/GameObject.cpp b/src/server/game/Entities/GameObject/GameObject.cpp
index ff74c6921f7..8d15e6ab39a 100644
--- a/src/server/game/Entities/GameObject/GameObject.cpp
+++ b/src/server/game/Entities/GameObject/GameObject.cpp
@@ -87,7 +87,10 @@ bool GameObject::AIM_Initialize()
std::string GameObject::GetAIName() const
{
- return sObjectMgr->GetGameObjectTemplate(GetEntry())->AIName;
+ if (GameObjectTemplate const* got = sObjectMgr->GetGameObjectTemplate(GetEntry()))
+ return got->AIName;
+
+ return "";
}
void GameObject::CleanupsBeforeDelete(bool /*finalCleanup*/)
diff --git a/src/server/game/Entities/Item/Item.cpp b/src/server/game/Entities/Item/Item.cpp
index a25bd463a55..86d02132eca 100644
--- a/src/server/game/Entities/Item/Item.cpp
+++ b/src/server/game/Entities/Item/Item.cpp
@@ -858,16 +858,26 @@ bool Item::IsFitToSpellRequirements(SpellInfo const* spellInfo) const
return true;
}
-void Item::SetEnchantment(EnchantmentSlot slot, uint32 id, uint32 duration, uint32 charges)
+void Item::SetEnchantment(EnchantmentSlot slot, uint32 id, uint32 duration, uint32 charges, uint64 caster /*= 0*/)
{
// Better lost small time at check in comparison lost time at item save to DB.
if ((GetEnchantmentId(slot) == id) && (GetEnchantmentDuration(slot) == duration) && (GetEnchantmentCharges(slot) == charges))
return;
+ Player* owner = GetOwner();
+ if (slot < MAX_INSPECTED_ENCHANTMENT_SLOT)
+ {
+ if (uint32 oldEnchant = GetEnchantmentId(slot))
+ owner->GetSession()->SendEnchantmentLog(GetOwnerGUID(), 0, GetEntry(), oldEnchant);
+
+ if (id)
+ owner->GetSession()->SendEnchantmentLog(GetOwnerGUID(), caster, GetEntry(), id);
+ }
+
SetUInt32Value(ITEM_FIELD_ENCHANTMENT_1_1 + slot*MAX_ENCHANTMENT_OFFSET + ENCHANTMENT_ID_OFFSET, id);
SetUInt32Value(ITEM_FIELD_ENCHANTMENT_1_1 + slot*MAX_ENCHANTMENT_OFFSET + ENCHANTMENT_DURATION_OFFSET, duration);
SetUInt32Value(ITEM_FIELD_ENCHANTMENT_1_1 + slot*MAX_ENCHANTMENT_OFFSET + ENCHANTMENT_CHARGES_OFFSET, charges);
- SetState(ITEM_CHANGED, GetOwner());
+ SetState(ITEM_CHANGED, owner);
}
void Item::SetEnchantmentDuration(EnchantmentSlot slot, uint32 duration, Player* owner)
@@ -984,6 +994,16 @@ bool Item::IsLimitedToAnotherMapOrZone(uint32 cur_mapId, uint32 cur_zoneId) cons
return proto && ((proto->Map && proto->Map != cur_mapId) || (proto->Area && proto->Area != cur_zoneId));
}
+void Item::SendUpdateSockets()
+{
+ WorldPacket data(SMSG_SOCKET_GEMS_RESULT, 8+4+4+4+4);
+ data << uint64(GetGUID());
+ for (uint32 i = SOCK_ENCHANTMENT_SLOT; i <= BONUS_ENCHANTMENT_SLOT; ++i)
+ data << uint32(GetEnchantmentId(EnchantmentSlot(i)));
+
+ GetOwner()->GetSession()->SendPacket(&data);
+}
+
// Though the client has the information in the item's data field,
// we have to send SMSG_ITEM_TIME_UPDATE to display the remaining
// time.
diff --git a/src/server/game/Entities/Item/Item.h b/src/server/game/Entities/Item/Item.h
index f69ac0f8965..cdc79d96d67 100644
--- a/src/server/game/Entities/Item/Item.h
+++ b/src/server/game/Entities/Item/Item.h
@@ -295,7 +295,7 @@ class Item : public Object
void SetItemRandomProperties(int32 randomPropId);
void UpdateItemSuffixFactor();
static int32 GenerateItemRandomPropertyId(uint32 item_id);
- void SetEnchantment(EnchantmentSlot slot, uint32 id, uint32 duration, uint32 charges);
+ void SetEnchantment(EnchantmentSlot slot, uint32 id, uint32 duration, uint32 charges, uint64 caster = 0);
void SetEnchantmentDuration(EnchantmentSlot slot, uint32 duration, Player* owner);
void SetEnchantmentCharges(EnchantmentSlot slot, uint32 charges);
void ClearEnchantment(EnchantmentSlot slot);
@@ -306,6 +306,8 @@ class Item : public Object
std::string const& GetText() const { return m_text; }
void SetText(std::string const& text) { m_text = text; }
+ void SendUpdateSockets();
+
void SendTimeUpdate(Player* owner);
void UpdateDuration(Player* owner, uint32 diff);
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp
index 10004862b74..718223304da 100644
--- a/src/server/game/Entities/Player/Player.cpp
+++ b/src/server/game/Entities/Player/Player.cpp
@@ -8017,6 +8017,10 @@ void Player::DuelComplete(DuelCompleteType type)
if (getClass() == CLASS_DEATH_KNIGHT && duel->opponent->GetQuestStatus(12733) == QUEST_STATUS_INCOMPLETE)
duel->opponent->CastSpell(duel->opponent, 52994, true);
+ // Honor points after duel (the winner) - ImpConfig
+ if (uint32 amount = sWorld->getIntConfig(CONFIG_HONOR_AFTER_DUEL))
+ duel->opponent->RewardHonor(NULL, 1, amount);
+
break;
default:
break;
@@ -8063,10 +8067,6 @@ void Player::DuelComplete(DuelCompleteType type)
else if (duel->opponent->GetComboTarget() == GetPetGUID())
duel->opponent->ClearComboPoints();
- // Honor points after duel (the winner) - ImpConfig
- if (uint32 amount = sWorld->getIntConfig(CONFIG_HONOR_AFTER_DUEL))
- duel->opponent->RewardHonor(NULL, 1, amount);
-
//cleanups
SetUInt64Value(PLAYER_DUEL_ARBITER, 0);
SetUInt32Value(PLAYER_DUEL_TEAM, 0);
@@ -9885,6 +9885,16 @@ void Player::SendInitWorldStates(uint32 zoneid, uint32 areaid)
bf->FillInitialWorldStates(data);
break;
}
+ case 4820:
+ if (instance && mapid == 668)
+ instance->FillInitialWorldStates(data);
+ else
+ {
+ data << uint32(4884) << uint32(0); // 9 WORLD_STATE_HOR_WAVES_ENABLED
+ data << uint32(4882) << uint32(0); // 10 WORLD_STATE_HOR_WAVE_COUNT
+ }
+ break;
+
// No break here, intended.
default:
data << uint32(0x914) << uint32(0x0); // 7
@@ -22711,7 +22721,7 @@ void Player::UpdateTriggerVisibility()
if (!obj || !(obj->isTrigger() || obj->HasAuraType(SPELL_AURA_TRANSFORM))) // can transform into triggers
continue;
- obj->BuildCreateUpdateBlockForPlayer(&udata, this);
+ obj->BuildValuesUpdateBlockForPlayer(&udata, this);
}
}
@@ -23681,7 +23691,7 @@ void Player::UpdateForQuestWorldObjects()
if (buildUpdateBlock)
{
- obj->BuildCreateUpdateBlockForPlayer(&udata, this);
+ obj->BuildValuesUpdateBlockForPlayer(&udata, this);
break;
}
}
diff --git a/src/server/game/Entities/Transport/Transport.cpp b/src/server/game/Entities/Transport/Transport.cpp
index 43664a7853e..3ed41781982 100644
--- a/src/server/game/Entities/Transport/Transport.cpp
+++ b/src/server/game/Entities/Transport/Transport.cpp
@@ -691,30 +691,34 @@ void Transport::UpdatePassengerPositions()
float x, y, z, o;
npc->m_movementInfo.t_pos.GetPosition(x, y, z, o);
- CalculatePassengerPosition(x, y, z, o);
+ CalculatePassengerPosition(x, y, z, &o);
GetMap()->CreatureRelocation(npc, x, y, z, o, false);
npc->GetTransportHomePosition(x, y, z, o);
- CalculatePassengerPosition(x, y, z, o);
+ CalculatePassengerPosition(x, y, z, &o);
npc->SetHomePosition(x, y, z, o);
}
}
-void Transport::CalculatePassengerPosition(float& x, float& y, float& z, float& o) const
+void Transport::CalculatePassengerPosition(float& x, float& y, float& z, float* o /*= NULL*/) const
{
- float inx = x, iny = y, inz = z, ino = o;
- o = GetOrientation() + ino;
+ float inx = x, iny = y, inz = z;
+ if (o)
+ *o = Position::NormalizeOrientation(GetOrientation() + *o);
+
x = GetPositionX() + inx * std::cos(GetOrientation()) - iny * std::sin(GetOrientation());
y = GetPositionY() + iny * std::cos(GetOrientation()) + inx * std::sin(GetOrientation());
z = GetPositionZ() + inz;
}
-void Transport::CalculatePassengerOffset(float& x, float& y, float& z, float& o) const
+void Transport::CalculatePassengerOffset(float& x, float& y, float& z, float* o /*= NULL*/) const
{
- o -= GetOrientation();
+ if (o)
+ *o = Position::NormalizeOrientation(*o - GetOrientation());
+
z -= GetPositionZ();
y -= GetPositionY(); // y = searchedY * std::cos(o) + searchedX * std::sin(o)
x -= GetPositionX(); // x = searchedX * std::cos(o) + searchedY * std::sin(o + pi)
float inx = x, iny = y;
- y = (iny - inx * tan(GetOrientation())) / (cos(GetOrientation()) + std::sin(GetOrientation()) * tan(GetOrientation()));
- x = (inx + iny * tan(GetOrientation())) / (cos(GetOrientation()) + std::sin(GetOrientation()) * tan(GetOrientation()));
+ y = (iny - inx * std::tan(GetOrientation())) / (std::cos(GetOrientation()) + std::sin(GetOrientation()) * std::tan(GetOrientation()));
+ x = (inx + iny * std::tan(GetOrientation())) / (std::cos(GetOrientation()) + std::sin(GetOrientation()) * std::tan(GetOrientation()));
}
diff --git a/src/server/game/Entities/Transport/Transport.h b/src/server/game/Entities/Transport/Transport.h
index bae09335f62..445bec456fd 100644
--- a/src/server/game/Entities/Transport/Transport.h
+++ b/src/server/game/Entities/Transport/Transport.h
@@ -50,10 +50,10 @@ class Transport : public GameObject, public TransportBase
void UpdatePassengerPositions();
/// This method transforms supplied transport offsets into global coordinates
- void CalculatePassengerPosition(float& x, float& y, float& z, float& o) const;
+ void CalculatePassengerPosition(float& x, float& y, float& z, float* o = NULL) const;
/// This method transforms supplied global coordinates into local offsets
- void CalculatePassengerOffset(float& x, float& y, float& z, float& o) const;
+ void CalculatePassengerOffset(float& x, float& y, float& z, float* o = NULL) const;
void BuildStartMovePacket(Map const* targetMap);
void BuildStopMovePacket(Map const* targetMap);
diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp
index a0aea414cef..8fa929131e2 100644
--- a/src/server/game/Entities/Unit/Unit.cpp
+++ b/src/server/game/Entities/Unit/Unit.cpp
@@ -416,15 +416,8 @@ void Unit::UpdateSplinePosition()
pos.m_positionZ = loc.z;
pos.SetOrientation(loc.orientation);
- if (Unit* vehicle = GetVehicleBase())
- {
- loc.x += vehicle->GetPositionX();
- loc.y += vehicle->GetPositionY();
- loc.z += vehicle->GetPositionZMinusOffset();
- loc.orientation = vehicle->GetOrientation();
- }
- else if (TransportBase* transport = GetDirectTransport())
- transport->CalculatePassengerPosition(loc.x, loc.y, loc.z, loc.orientation);
+ if (TransportBase* transport = GetDirectTransport())
+ transport->CalculatePassengerPosition(loc.x, loc.y, loc.z, &loc.orientation);
}
if (HasUnitState(UNIT_STATE_CANNOT_TURN))
@@ -11246,7 +11239,7 @@ void Unit::setDeathState(DeathState s)
SetPower(getPowerType(), 0);
// players in instance don't have ZoneScript, but they have InstanceScript
- if (ZoneScript* zoneScript = GetZoneScript() ? GetZoneScript() : (ZoneScript*)GetInstanceScript())
+ if (ZoneScript* zoneScript = GetZoneScript() ? GetZoneScript() : GetInstanceScript())
zoneScript->OnUnitDeath(this);
}
else if (s == JUST_RESPAWNED)
diff --git a/src/server/game/Entities/Vehicle/Vehicle.cpp b/src/server/game/Entities/Vehicle/Vehicle.cpp
index 214a47a6611..503d89a8e82 100644
--- a/src/server/game/Entities/Vehicle/Vehicle.cpp
+++ b/src/server/game/Entities/Vehicle/Vehicle.cpp
@@ -556,7 +556,7 @@ void Vehicle::RelocatePassengers()
float px, py, pz, po;
passenger->m_movementInfo.t_pos.GetPosition(px, py, pz, po);
- CalculatePassengerPosition(px, py, pz, po);
+ CalculatePassengerPosition(px, py, pz, &po);
passenger->UpdatePosition(px, py, pz, po);
}
@@ -675,24 +675,28 @@ uint8 Vehicle::GetAvailableSeatCount() const
return ret;
}
-void Vehicle::CalculatePassengerPosition(float& x, float& y, float& z, float& o) const
+void Vehicle::CalculatePassengerPosition(float& x, float& y, float& z, float* o /*= NULL*/) const
{
- float inx = x, iny = y, inz = z, ino = o;
- o = GetBase()->GetOrientation() + ino;
+ float inx = x, iny = y, inz = z;
+ if (o)
+ *o = Position::NormalizeOrientation(GetBase()->GetOrientation() + *o);
+
x = GetBase()->GetPositionX() + inx * std::cos(GetBase()->GetOrientation()) - iny * std::sin(GetBase()->GetOrientation());
y = GetBase()->GetPositionY() + iny * std::cos(GetBase()->GetOrientation()) + inx * std::sin(GetBase()->GetOrientation());
z = GetBase()->GetPositionZ() + inz;
}
-void Vehicle::CalculatePassengerOffset(float& x, float& y, float& z, float& o) const
+void Vehicle::CalculatePassengerOffset(float& x, float& y, float& z, float* o /*= NULL*/) const
{
- o -= GetBase()->GetOrientation();
+ if (o)
+ *o = Position::NormalizeOrientation(*o - GetBase()->GetOrientation());
+
z -= GetBase()->GetPositionZ();
y -= GetBase()->GetPositionY(); // y = searchedY * std::cos(o) + searchedX * std::sin(o)
x -= GetBase()->GetPositionX(); // x = searchedX * std::cos(o) + searchedY * std::sin(o + pi)
float inx = x, iny = y;
- y = (iny - inx * tan(GetBase()->GetOrientation())) / (cos(GetBase()->GetOrientation()) + std::sin(GetBase()->GetOrientation()) * tan(GetBase()->GetOrientation()));
- x = (inx + iny * tan(GetBase()->GetOrientation())) / (cos(GetBase()->GetOrientation()) + std::sin(GetBase()->GetOrientation()) * tan(GetBase()->GetOrientation()));
+ y = (iny - inx * std::tan(GetBase()->GetOrientation())) / (std::cos(GetBase()->GetOrientation()) + std::sin(GetBase()->GetOrientation()) * std::tan(GetBase()->GetOrientation()));
+ x = (inx + iny * std::tan(GetBase()->GetOrientation())) / (std::cos(GetBase()->GetOrientation()) + std::sin(GetBase()->GetOrientation()) * std::tan(GetBase()->GetOrientation()));
}
/**
diff --git a/src/server/game/Entities/Vehicle/Vehicle.h b/src/server/game/Entities/Vehicle/Vehicle.h
index 3e4a2fd3a78..c83a9fa5f33 100644
--- a/src/server/game/Entities/Vehicle/Vehicle.h
+++ b/src/server/game/Entities/Vehicle/Vehicle.h
@@ -89,10 +89,10 @@ class Vehicle : public TransportBase
void InitMovementInfoForBase();
/// This method transforms supplied transport offsets into global coordinates
- void CalculatePassengerPosition(float& x, float& y, float& z, float& o) const;
+ void CalculatePassengerPosition(float& x, float& y, float& z, float* o = NULL) const;
/// This method transforms supplied global coordinates into local offsets
- void CalculatePassengerOffset(float& x, float& y, float& z, float& o) const;
+ void CalculatePassengerOffset(float& x, float& y, float& z, float* o = NULL) const;
void RemovePendingEvent(VehicleJoinEvent* e);
void RemovePendingEventsForSeat(int8 seatId);
diff --git a/src/server/game/Entities/Vehicle/VehicleDefines.h b/src/server/game/Entities/Vehicle/VehicleDefines.h
index 9db8c15f697..55c47df86ad 100644
--- a/src/server/game/Entities/Vehicle/VehicleDefines.h
+++ b/src/server/game/Entities/Vehicle/VehicleDefines.h
@@ -105,10 +105,10 @@ protected:
public:
/// This method transforms supplied transport offsets into global coordinates
- virtual void CalculatePassengerPosition(float& x, float& y, float& z, float& o) const = 0;
+ virtual void CalculatePassengerPosition(float& x, float& y, float& z, float* o = NULL) const = 0;
/// This method transforms supplied global coordinates into local offsets
- virtual void CalculatePassengerOffset(float& x, float& y, float& z, float& o) const = 0;
+ virtual void CalculatePassengerOffset(float& x, float& y, float& z, float* o = NULL) const = 0;
};
#endif
diff --git a/src/server/game/Handlers/ItemHandler.cpp b/src/server/game/Handlers/ItemHandler.cpp
index d7be695e142..f23a1c9632f 100644
--- a/src/server/game/Handlers/ItemHandler.cpp
+++ b/src/server/game/Handlers/ItemHandler.cpp
@@ -891,14 +891,14 @@ void WorldSession::HandleAutoStoreBankItemOpcode(WorldPacket& recvPacket)
}
}
-void WorldSession::SendEnchantmentLog(uint64 Target, uint64 Caster, uint32 ItemID, uint32 SpellID)
+void WorldSession::SendEnchantmentLog(uint64 target, uint64 caster, uint32 itemId, uint32 enchantId)
{
- WorldPacket data(SMSG_ENCHANTMENTLOG, (8+8+4+4+1)); // last check 4.3.4
- data.appendPackGUID(Target);
- data.appendPackGUID(Caster);
- data << uint32(ItemID);
- data << uint32(SpellID);
- SendPacket(&data);
+ WorldPacket data(SMSG_ENCHANTMENTLOG, (8+8+4+4));
+ data.appendPackGUID(target);
+ data.appendPackGUID(caster);
+ data << uint32(itemId);
+ data << uint32(enchantId);
+ GetPlayer()->SendMessageToSet(&data, true);
}
void WorldSession::SendItemEnchantTimeUpdate(uint64 Playerguid, uint64 Itemguid, uint32 slot, uint32 Duration)
@@ -1201,10 +1201,12 @@ void WorldSession::HandleSocketOpcode(WorldPacket& recvData)
{
if (GemEnchants[i])
{
- uint32 gemCount = 1;
- itemTarget->SetEnchantment(EnchantmentSlot(SOCK_ENCHANTMENT_SLOT+i), GemEnchants[i], 0, 0);
+ itemTarget->SetEnchantment(EnchantmentSlot(SOCK_ENCHANTMENT_SLOT+i), GemEnchants[i], 0, 0, _player->GetGUID());
if (Item* guidItem = _player->GetItemByGuid(gem_guids[i]))
+ {
+ uint32 gemCount = 1;
_player->DestroyItemCount(guidItem, gemCount, true);
+ }
}
}
@@ -1215,7 +1217,7 @@ void WorldSession::HandleSocketOpcode(WorldPacket& recvData)
if (SocketBonusActivated ^ SocketBonusToBeActivated) //if there was a change...
{
_player->ApplyEnchantment(itemTarget, BONUS_ENCHANTMENT_SLOT, false);
- itemTarget->SetEnchantment(BONUS_ENCHANTMENT_SLOT, (SocketBonusToBeActivated ? itemTarget->GetTemplate()->socketBonus : 0), 0, 0);
+ itemTarget->SetEnchantment(BONUS_ENCHANTMENT_SLOT, (SocketBonusToBeActivated ? itemTarget->GetTemplate()->socketBonus : 0), 0, 0, _player->GetGUID());
_player->ApplyEnchantment(itemTarget, BONUS_ENCHANTMENT_SLOT, true);
//it is not displayed, client has an inbuilt system to determine if the bonus is activated
}
@@ -1224,6 +1226,8 @@ void WorldSession::HandleSocketOpcode(WorldPacket& recvData)
_player->RemoveTradeableItem(itemTarget);
itemTarget->ClearSoulboundTradeable(_player); // clear tradeable flag
+
+ itemTarget->SendUpdateSockets();
}
void WorldSession::HandleCancelTempEnchantmentOpcode(WorldPacket& recvData)
diff --git a/src/server/game/Handlers/MailHandler.cpp b/src/server/game/Handlers/MailHandler.cpp
index cea83bbfa93..d34ea534753 100644
--- a/src/server/game/Handlers/MailHandler.cpp
+++ b/src/server/game/Handlers/MailHandler.cpp
@@ -307,10 +307,10 @@ void WorldSession::HandleSendMail(WorldPacket& recvData)
Item* item = items[i];
if (log)
{
- sLog->outCommand(GetAccountId(), "GM %s (Account: %u) mail item: %s (Entry: %u Count: %u) "
- "to player: %s (Account: %u)", GetPlayerName().c_str(), GetAccountId(),
+ sLog->outCommand(GetAccountId(), "GM %s (GUID: %u) (Account: %u) mail item: %s (Entry: %u Count: %u) "
+ "to player: %s (GUID: %u) (Account: %u)", GetPlayerName().c_str(), GetGuidLow(), GetAccountId(),
item->GetTemplate()->Name1.c_str(), item->GetEntry(), item->GetCount(),
- receiverName.c_str(), receiverAccountId);
+ receiverName.c_str(), GUID_LOPART(receiverGuid), receiverAccountId);
}
item->SetNotRefundable(GetPlayer()); // makes the item no longer refundable
@@ -329,8 +329,8 @@ void WorldSession::HandleSendMail(WorldPacket& recvData)
if (log && money > 0)
{
- sLog->outCommand(GetAccountId(), "GM %s (Account: %u) mail money: " UI64FMTD " to player: %s (Account: %u)",
- GetPlayerName().c_str(), GetAccountId(), money, receiverName.c_str(), receiverAccountId);
+ sLog->outCommand(GetAccountId(), "GM %s (GUID: %u) (Account: %u) mail money: " UI64FMTD " to player: %s (GUID: %u) (Account: %u)",
+ GetPlayerName().c_str(), GetGuidLow(), GetAccountId(), money, receiverName.c_str(), GUID_LOPART(receiverGuid), receiverAccountId);
}
}
diff --git a/src/server/game/Handlers/QuestHandler.cpp b/src/server/game/Handlers/QuestHandler.cpp
index c785684cf0e..45be13ae776 100644
--- a/src/server/game/Handlers/QuestHandler.cpp
+++ b/src/server/game/Handlers/QuestHandler.cpp
@@ -603,7 +603,7 @@ void WorldSession::HandlePushQuestToParty(WorldPacket& recvPacket)
continue;
}
- player->PlayerTalkClass->SendQuestGiverQuestDetails(quest, player->GetGUID(), true);
+ player->PlayerTalkClass->SendQuestGiverQuestDetails(quest, _player->GetGUID(), true);
player->SetDivider(_player->GetGUID());
}
}
diff --git a/src/server/game/Miscellaneous/Language.h b/src/server/game/Miscellaneous/Language.h
index c26bbc1dfc9..f3323682e1b 100644
--- a/src/server/game/Miscellaneous/Language.h
+++ b/src/server/game/Miscellaneous/Language.h
@@ -452,7 +452,7 @@ enum TrinityStrings
LANG_COMMAND_GRAVEYARDALRLINKED = 450,
LANG_COMMAND_GRAVEYARDLINKED = 451,
LANG_COMMAND_GRAVEYARDWRONGZONE = 452,
- // = 453, see LANG_PINFO_BAN
+ // = 453, see LANG_PINFO_PLAYER
LANG_COMMAND_GRAVEYARDERROR = 454,
LANG_COMMAND_GRAVEYARD_NOTEAM = 455,
LANG_COMMAND_GRAVEYARD_ANY = 456,
@@ -563,13 +563,9 @@ enum TrinityStrings
LANG_NPCINFO_TRAINER = 546,
LANG_NPCINFO_DUNGEON_ID = 547,
- LANG_PINFO_ACCOUNT = 548,
- LANG_PINFO_LEVEL = 549,
- LANG_PINFO_MUTE = 550,
- LANG_PINFO_BAN = 453,
- LANG_PINFO_MAP_ONLINE = 714,
- LANG_PINFO_MAP_OFFLINE = 716,
- LANG_PINFO_GUILD_INFO = 749,
+ // = 548, see LANG_PINFO_GM_ACTIVE
+ // = 549, see LANG_PINFO_BANNED
+ // = 550, see LANG_PINFO_MUTED
LANG_YOU_SET_EXPLORE_ALL = 551,
LANG_YOU_SET_EXPLORE_NOTHING = 552,
@@ -717,9 +713,9 @@ enum TrinityStrings
LANG_BG_QUEUE_ANNOUNCE_SELF = 711,
LANG_BG_QUEUE_ANNOUNCE_WORLD = 712,
LANG_YOUR_ARENA_LEVEL_REQ_ERROR = 713,
-// = 714, see LANG_PINFO_MAP_ONLINE
+// = 714, see LANG_PINFO_ACC_ACCOUNT
LANG_YOUR_BG_LEVEL_REQ_ERROR = 715,
-// = 716, see LANG_PINFO_MAP_OFFLINE
+// = 716, see LANG_PINFO_ACC_LASTLOGIN
LANG_BG_STARTED_ANNOUNCE_WORLD = 717,
LANG_ARENA_QUEUE_ANNOUNCE_WORLD_JOIN= 718,
LANG_ARENA_QUEUE_ANNOUNCE_WORLD_EXIT= 719,
@@ -754,10 +750,10 @@ enum TrinityStrings
// LANG_DIST_ARENA_POINTS_END = 746,
LANG_BG_DISABLED = 747,
LANG_ARENA_DISABLED = 748,
-// = 749, not used
+// = 749, see LANG_PINFO_ACC_OS
LANG_BATTLEGROUND_PREMATURE_FINISH_WARNING = 750, // "Not enough players. This game will close in %u mins."
LANG_BATTLEGROUND_PREMATURE_FINISH_WARNING_SECS = 751, // "Not enough players. This game will close in %u seconds."
-// = 752, not used
+// = 752, see LANG_PINFO_ACC_IP
// LANG_BG_WS_START_TWO_MINUTES = 753, - defined above
// LANG_BG_AB_START_TWO_MINUTES = 754, - defined above
// LANG_BG_EY_START_TWO_MINUTES = 755, - defined above
@@ -815,7 +811,46 @@ enum TrinityStrings
LANG_NPCINFO_MAILBOX = 841,
LANG_NPCINFO_PLAYER_VEHICLE = 842,
- // Room for in-game strings 843-999 not used
+ // Pinfo commands
+ LANG_PINFO_PLAYER = 453,
+ LANG_PINFO_GM_ACTIVE = 548,
+ LANG_PINFO_BANNED = 549,
+ LANG_PINFO_MUTED = 550,
+ LANG_PINFO_ACC_ACCOUNT = 714,
+ LANG_PINFO_ACC_LASTLOGIN = 716,
+ LANG_PINFO_ACC_OS = 749,
+ LANG_PINFO_ACC_IP = 752,
+ LANG_PINFO_CHR_LEVEL = 843,
+ LANG_PINFO_CHR_RACE = 844,
+ LANG_PINFO_CHR_ALIVE = 845,
+ LANG_PINFO_CHR_PHASE = 846,
+ LANG_PINFO_CHR_MONEY = 847,
+ LANG_PINFO_CHR_MAP = 848,
+ LANG_PINFO_CHR_GUILD = 849,
+ LANG_PINFO_CHR_GUILD_RANK = 850,
+ LANG_PINFO_CHR_GUILD_NOTE = 851,
+ LANG_PINFO_CHR_GUILD_ONOTE = 852,
+ LANG_PINFO_CHR_PLAYEDTIME = 853,
+ LANG_PINFO_CHR_MAILS = 854,
+
+ LANG_CHARACTER_GENDER_MALE = 855,
+ LANG_CHARACTER_GENDER_FEMALE = 856,
+
+ LANG_ARENA_ERROR_NOT_FOUND = 857,
+ LANG_ARENA_ERROR_NAME_EXISTS = 858,
+ LANG_ARENA_ERROR_SIZE = 859,
+ LANG_ARENA_ERROR_COMBAT = 860,
+ LANG_AREAN_ERROR_NAME_NOT_FOUND = 861,
+ LANG_ARENA_ERROR_NOT_MEMBER = 862,
+ LANG_ARENA_ERROR_CAPTAIN = 863,
+ LANG_ARENA_CREATE = 864,
+ LANG_ARENA_DISBAND = 865,
+ LANG_ARENA_RENAME = 866,
+ LANG_ARENA_CAPTAIN = 867,
+ LANG_ARENA_INFO_HEADER = 868,
+ LANG_ARENA_INFO_MEMBERS = 869,
+ LANG_ARENA_LOOKUP = 870,
+ // Room for in-game strings 870-999 not used
// Level 4 (CLI only commands)
LANG_COMMAND_EXIT = 1000,
diff --git a/src/server/game/Movement/MotionMaster.h b/src/server/game/Movement/MotionMaster.h
index f2f3959dba5..156813f56fb 100644
--- a/src/server/game/Movement/MotionMaster.h
+++ b/src/server/game/Movement/MotionMaster.h
@@ -153,8 +153,8 @@ class MotionMaster //: private std::stack<MovementGenerator *>
void MoveChase(Unit* target, float dist = 0.0f, float angle = 0.0f);
void MoveConfused();
void MoveFleeing(Unit* enemy, uint32 time = 0);
- void MovePoint(uint32 id, const Position &pos)
- { MovePoint(id, pos.m_positionX, pos.m_positionY, pos.m_positionZ); }
+ void MovePoint(uint32 id, Position const& pos, bool generatePath = true)
+ { MovePoint(id, pos.m_positionX, pos.m_positionY, pos.m_positionZ, generatePath); }
void MovePoint(uint32 id, float x, float y, float z, bool generatePath = true);
// These two movement types should only be used with creatures having landing/takeoff animations
diff --git a/src/server/game/Movement/Spline/MoveSplineInit.cpp b/src/server/game/Movement/Spline/MoveSplineInit.cpp
index d42df898a7e..8a60ae05f41 100644
--- a/src/server/game/Movement/Spline/MoveSplineInit.cpp
+++ b/src/server/game/Movement/Spline/MoveSplineInit.cpp
@@ -207,13 +207,8 @@ namespace Movement
Vector3 TransportPathTransform::operator()(Vector3 input)
{
if (_transformForTransport)
- {
if (TransportBase* transport = _owner->GetDirectTransport())
- {
- float unused = 0.0f; // need reference
- transport->CalculatePassengerOffset(input.x, input.y, input.z, unused);
- }
- }
+ transport->CalculatePassengerOffset(input.x, input.y, input.z);
return input;
}
diff --git a/src/server/game/Scripting/ScriptLoader.cpp b/src/server/game/Scripting/ScriptLoader.cpp
index ec1b7ac609e..b566f9dabe1 100644
--- a/src/server/game/Scripting/ScriptLoader.cpp
+++ b/src/server/game/Scripting/ScriptLoader.cpp
@@ -46,6 +46,7 @@ void AddSC_SmartSCripts();
//Commands
void AddSC_account_commandscript();
void AddSC_achievement_commandscript();
+void AddSC_arena_commandscript();
void AddSC_ban_commandscript();
void AddSC_bf_commandscript();
void AddSC_cast_commandscript();
@@ -680,6 +681,7 @@ void AddCommandScripts()
{
AddSC_account_commandscript();
AddSC_achievement_commandscript();
+ AddSC_arena_commandscript();
AddSC_ban_commandscript();
AddSC_bf_commandscript();
AddSC_cast_commandscript();
diff --git a/src/server/game/Server/Protocol/Opcodes.cpp b/src/server/game/Server/Protocol/Opcodes.cpp
index 7572bfcc860..5e66efea913 100644
--- a/src/server/game/Server/Protocol/Opcodes.cpp
+++ b/src/server/game/Server/Protocol/Opcodes.cpp
@@ -1166,6 +1166,7 @@ void OpcodeTable::Initialize()
DEFINE_OPCODE_HANDLER(SMSG_SHOWTAXINODES, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
DEFINE_OPCODE_HANDLER(SMSG_SHOW_BANK, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
DEFINE_OPCODE_HANDLER(SMSG_SHOW_RATINGS, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_SOCKET_GEMS_RESULT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
DEFINE_OPCODE_HANDLER(SMSG_SOR_START_EXPERIENCE_INCOMPLETE, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
DEFINE_OPCODE_HANDLER(SMSG_SPELLBREAKLOG, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
DEFINE_OPCODE_HANDLER(SMSG_SPELLDAMAGESHIELD, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
@@ -1263,7 +1264,6 @@ void OpcodeTable::Initialize()
DEFINE_OPCODE_HANDLER(SMSG_UPDATE_DUNGEON_ENCOUNTER_FOR_LOOT, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
DEFINE_OPCODE_HANDLER(SMSG_UPDATE_INSTANCE_ENCOUNTER_UNIT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
DEFINE_OPCODE_HANDLER(SMSG_UPDATE_INSTANCE_OWNERSHIP, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
- DEFINE_OPCODE_HANDLER(SMSG_UPDATE_ITEM_ENCHANTMENTS, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
DEFINE_OPCODE_HANDLER(SMSG_UPDATE_LAST_INSTANCE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
DEFINE_OPCODE_HANDLER(SMSG_UPDATE_OBJECT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
DEFINE_OPCODE_HANDLER(SMSG_UPDATE_SERVER_PLAYER_POSITION, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
@@ -1440,13 +1440,10 @@ void OpcodeTable::Initialize()
//DEFINE_OPCODE_HANDLER(CMSG_MOVE_CHARM_PORT_CHEAT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
//DEFINE_OPCODE_HANDLER(CMSG_MOVE_CHARM_TELEPORT_CHEAT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
//DEFINE_OPCODE_HANDLER(CMSG_MOVE_ENABLE_SWIM_TO_FLY_TRANS_ACK, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
- //DEFINE_OPCODE_HANDLER(CMSG_MOVE_SET_FLY, STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleMovementOpcodes );
//DEFINE_OPCODE_HANDLER(CMSG_MOVE_SET_RELATIVE_POSITION, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
- //DEFINE_OPCODE_HANDLER(CMSG_MOVE_SET_RUN_SPEED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
//DEFINE_OPCODE_HANDLER(CMSG_MOVE_SET_VEHICLE_REC_ID_ACK, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
//DEFINE_OPCODE_HANDLER(CMSG_MOVE_START_SWIM_CHEAT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
//DEFINE_OPCODE_HANDLER(CMSG_MOVE_STOP_SWIM_CHEAT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
- //DEFINE_OPCODE_HANDLER(CMSG_MOVE_TOGGLE_COLLISION_ACK, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
//DEFINE_OPCODE_HANDLER(CMSG_NEW_SPELL_SLOT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
//DEFINE_OPCODE_HANDLER(CMSG_NO_SPELL_VARIANCE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
//DEFINE_OPCODE_HANDLER(CMSG_PERFORM_ACTION_SET, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
@@ -1557,18 +1554,12 @@ void OpcodeTable::Initialize()
//DEFINE_OPCODE_HANDLER(MSG_GM_RESETINSTANCELIMIT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
//DEFINE_OPCODE_HANDLER(MSG_GM_SHOWLABEL, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
//DEFINE_OPCODE_HANDLER(MSG_GM_SUMMON, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
- //DEFINE_OPCODE_HANDLER(MSG_MOVE_FEATHER_FALL, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
- //DEFINE_OPCODE_HANDLER(MSG_MOVE_GRAVITY_CHNG, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
- //DEFINE_OPCODE_HANDLER(MSG_MOVE_HOVER, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
- //DEFINE_OPCODE_HANDLER(MSG_MOVE_ROOT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
//DEFINE_OPCODE_HANDLER(MSG_MOVE_SET_ALL_SPEED_CHEAT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
- //DEFINE_OPCODE_HANDLER(MSG_MOVE_SET_COLLISION_HEIGHT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
//DEFINE_OPCODE_HANDLER(MSG_MOVE_SET_FLIGHT_BACK_SPEED_CHEAT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
//DEFINE_OPCODE_HANDLER(MSG_MOVE_SET_FLIGHT_SPEED_CHEAT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
//DEFINE_OPCODE_HANDLER(MSG_MOVE_SET_PITCH_RATE_CHEAT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
//DEFINE_OPCODE_HANDLER(MSG_MOVE_SET_RAW_POSITION_ACK, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
//DEFINE_OPCODE_HANDLER(MSG_MOVE_SET_RUN_BACK_SPEED_CHEAT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
- //DEFINE_OPCODE_HANDLER(MSG_MOVE_SET_RUN_SPEED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
//DEFINE_OPCODE_HANDLER(MSG_MOVE_SET_RUN_SPEED_CHEAT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
//DEFINE_OPCODE_HANDLER(MSG_MOVE_SET_SWIM_BACK_SPEED_CHEAT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
//DEFINE_OPCODE_HANDLER(MSG_MOVE_SET_SWIM_SPEED_CHEAT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
@@ -1578,10 +1569,6 @@ void OpcodeTable::Initialize()
//DEFINE_OPCODE_HANDLER(MSG_MOVE_STOP_SWIM_CHEAT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
//DEFINE_OPCODE_HANDLER(MSG_MOVE_TOGGLE_FALL_LOGGING, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
//DEFINE_OPCODE_HANDLER(MSG_MOVE_TOGGLE_LOGGING, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
- //DEFINE_OPCODE_HANDLER(MSG_MOVE_UPDATE_CAN_FLY, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
- //DEFINE_OPCODE_HANDLER(MSG_MOVE_UPDATE_CAN_TRANSITION_BETWEEN_SWIM_AND_FLY, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
- //DEFINE_OPCODE_HANDLER(MSG_MOVE_UPDATE_MOUSE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
- //DEFINE_OPCODE_HANDLER(MSG_MOVE_WATER_WALK, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
//DEFINE_OPCODE_HANDLER(MSG_NULL_ACTION, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
//DEFINE_OPCODE_HANDLER(MSG_PVP_LOG_DATA, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandlePVPLogDataOpcode );
//DEFINE_OPCODE_HANDLER(MSG_VIEW_PHASE_SHIFT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
@@ -1602,11 +1589,6 @@ void OpcodeTable::Initialize()
//DEFINE_OPCODE_HANDLER(SMSG_COMBAT_LOG_MULTIPLE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
//DEFINE_OPCODE_HANDLER(SMSG_COMMENTATOR_GET_PLAYER_INFO, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
//DEFINE_OPCODE_HANDLER(SMSG_COMPLETION_NPC_RESPONCE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
- //DEFINE_OPCODE_HANDLER(SMSG_COMPRESSED_ACHIEVEMENT_DATA, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
- //DEFINE_OPCODE_HANDLER(SMSG_COMPRESSED_CHAR_ENUM, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
- //DEFINE_OPCODE_HANDLER(SMSG_COMPRESSED_GUILD_ROSTER, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
- //DEFINE_OPCODE_HANDLER(SMSG_COMPRESSED_UNKNOWN_1310, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
- //DEFINE_OPCODE_HANDLER(SMSG_COMPRESSED_UPDATE_OBJECT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
//DEFINE_OPCODE_HANDLER(SMSG_CORPSE_IS_NOT_IN_INSTANCE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
//DEFINE_OPCODE_HANDLER(SMSG_DAMAGE_DONE_OBSOLETE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
//DEFINE_OPCODE_HANDLER(SMSG_DBLOOKUP, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
@@ -1647,15 +1629,10 @@ void OpcodeTable::Initialize()
//DEFINE_OPCODE_HANDLER(SMSG_MEETINGSTONE_SETQUEUE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
//DEFINE_OPCODE_HANDLER(SMSG_MINIGAME_MOVE_FAILED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
//DEFINE_OPCODE_HANDLER(SMSG_MOVE_CHARACTER_CHEAT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
- //DEFINE_OPCODE_HANDLER(SMSG_MOVE_DISABLE_COLLISION, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
- //DEFINE_OPCODE_HANDLER(SMSG_MOVE_DISABLE_GRAVITY, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
- //DEFINE_OPCODE_HANDLER(SMSG_MOVE_ENABLE_COLLISION, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
- //DEFINE_OPCODE_HANDLER(SMSG_MOVE_ENABLE_GRAVITY, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
//DEFINE_OPCODE_HANDLER(SMSG_MOVE_SET_VEHICLE_REC_ID, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
//DEFINE_OPCODE_HANDLER(SMSG_MOVE_SET_WALK_IN_AIR, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
//DEFINE_OPCODE_HANDLER(SMSG_MOVE_SKIP_TIME, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
//DEFINE_OPCODE_HANDLER(SMSG_MOVE_UNSET_WALK_IN_AIR, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
- //DEFINE_OPCODE_HANDLER(SMSG_MOVE_UPDATE_TELEPORT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
//DEFINE_OPCODE_HANDLER(SMSG_NPC_WONT_TALK, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
//DEFINE_OPCODE_HANDLER(SMSG_PET_UNLEARN_CONFIRM, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
//DEFINE_OPCODE_HANDLER(SMSG_PLAYER_UNK_DEAD_ALIVE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
@@ -1680,18 +1657,6 @@ void OpcodeTable::Initialize()
//DEFINE_OPCODE_HANDLER(SMSG_SHOW_MAILBOX, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
//DEFINE_OPCODE_HANDLER(SMSG_SPELL_CHANCE_PROC_LOG, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
//DEFINE_OPCODE_HANDLER(SMSG_SPELL_CHANCE_RESIST_PUSHBACK, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
- //DEFINE_OPCODE_HANDLER(SMSG_SPLINE_MOVE_LAND_WALK, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
- //DEFINE_OPCODE_HANDLER(SMSG_SPLINE_MOVE_NORMAL_FALL, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
- //DEFINE_OPCODE_HANDLER(SMSG_SPLINE_MOVE_SET_WATER_WALK, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
- //DEFINE_OPCODE_HANDLER(SMSG_SPLINE_SET_FLIGHT_BACK_SPEED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
- //DEFINE_OPCODE_HANDLER(SMSG_SPLINE_SET_FLIGHT_SPEED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
- //DEFINE_OPCODE_HANDLER(SMSG_SPLINE_SET_PITCH_RATE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
- //DEFINE_OPCODE_HANDLER(SMSG_SPLINE_SET_RUN_BACK_SPEED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
- //DEFINE_OPCODE_HANDLER(SMSG_SPLINE_SET_RUN_SPEED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
- //DEFINE_OPCODE_HANDLER(SMSG_SPLINE_SET_SWIM_BACK_SPEED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
- //DEFINE_OPCODE_HANDLER(SMSG_SPLINE_SET_SWIM_SPEED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
- //DEFINE_OPCODE_HANDLER(SMSG_SPLINE_SET_TURN_RATE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
- //DEFINE_OPCODE_HANDLER(SMSG_SPLINE_SET_WALK_SPEED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
//DEFINE_OPCODE_HANDLER(SMSG_VOICE_SESSION_ADJUST_PRIORITY, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
//DEFINE_OPCODE_HANDLER(SMSG_VOICE_SESSION_ENABLE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
//DEFINE_OPCODE_HANDLER(SMSG_ZONE_MAP, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
diff --git a/src/server/game/Server/Protocol/Opcodes.h b/src/server/game/Server/Protocol/Opcodes.h
index d7c1cfdd3e1..ad3ced93210 100644
--- a/src/server/game/Server/Protocol/Opcodes.h
+++ b/src/server/game/Server/Protocol/Opcodes.h
@@ -1250,6 +1250,7 @@ enum Opcodes
SMSG_SHOWTAXINODES = 0x2A36,
SMSG_SHOW_BANK = 0x2627,
SMSG_SHOW_RATINGS = 0x11B4,
+ SMSG_SOCKET_GEMS_RESULT = 0x6014,
SMSG_SOR_START_EXPERIENCE_INCOMPLETE = 0x7CA7,
SMSG_SPELLBREAKLOG = 0x6B17,
SMSG_SPELLDAMAGESHIELD = 0x2927,
@@ -1348,7 +1349,6 @@ enum Opcodes
SMSG_UPDATE_DUNGEON_ENCOUNTER_FOR_LOOT = 0x3CB5,
SMSG_UPDATE_INSTANCE_ENCOUNTER_UNIT = 0x4007,
SMSG_UPDATE_INSTANCE_OWNERSHIP = 0x4915,
- SMSG_UPDATE_ITEM_ENCHANTMENTS = 0x6014,
SMSG_UPDATE_LAST_INSTANCE = 0x0437,
SMSG_UPDATE_OBJECT = 0x4715,
SMSG_UPDATE_SERVER_PLAYER_POSITION = 0x74A3,
diff --git a/src/server/game/Server/WorldSession.h b/src/server/game/Server/WorldSession.h
index d4c4e5ef477..bc8718ef721 100644
--- a/src/server/game/Server/WorldSession.h
+++ b/src/server/game/Server/WorldSession.h
@@ -328,7 +328,7 @@ class WorldSession
void SendAuctionRemovedNotification(uint32 auctionId, uint32 itemEntry, int32 randomPropertyId);
//Item Enchantment
- void SendEnchantmentLog(uint64 Target, uint64 Caster, uint32 ItemID, uint32 SpellID);
+ void SendEnchantmentLog(uint64 target, uint64 caster, uint32 itemId, uint32 enchantId);
void SendItemEnchantTimeUpdate(uint64 Playerguid, uint64 Itemguid, uint32 slot, uint32 Duration);
//Taxi
diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp
index 4be79d4b52b..80eadb9ac0e 100644
--- a/src/server/game/Spells/SpellEffects.cpp
+++ b/src/server/game/Spells/SpellEffects.cpp
@@ -2602,7 +2602,7 @@ void Spell::EffectEnchantItemPerm(SpellEffIndex effIndex)
// remove old enchanting before applying new if equipped
item_owner->ApplyEnchantment(itemTarget, PERM_ENCHANTMENT_SLOT, false);
- itemTarget->SetEnchantment(PERM_ENCHANTMENT_SLOT, enchant_id, 0, 0);
+ itemTarget->SetEnchantment(PERM_ENCHANTMENT_SLOT, enchant_id, 0, 0, m_caster->GetGUID());
// add new enchanting if equipped
item_owner->ApplyEnchantment(itemTarget, PERM_ENCHANTMENT_SLOT, true);
@@ -2667,7 +2667,7 @@ void Spell::EffectEnchantItemPrismatic(SpellEffIndex effIndex)
// remove old enchanting before applying new if equipped
item_owner->ApplyEnchantment(itemTarget, PRISMATIC_ENCHANTMENT_SLOT, false);
- itemTarget->SetEnchantment(PRISMATIC_ENCHANTMENT_SLOT, enchant_id, 0, 0);
+ itemTarget->SetEnchantment(PRISMATIC_ENCHANTMENT_SLOT, enchant_id, 0, 0, m_caster->GetGUID());
// add new enchanting if equipped
item_owner->ApplyEnchantment(itemTarget, PRISMATIC_ENCHANTMENT_SLOT, true);
@@ -2749,7 +2749,7 @@ void Spell::EffectEnchantItemTmp(SpellEffIndex effIndex)
// remove old enchanting before applying new if equipped
item_owner->ApplyEnchantment(itemTarget, TEMP_ENCHANTMENT_SLOT, false);
- itemTarget->SetEnchantment(TEMP_ENCHANTMENT_SLOT, enchant_id, duration * 1000, 0);
+ itemTarget->SetEnchantment(TEMP_ENCHANTMENT_SLOT, enchant_id, duration * 1000, 0, m_caster->GetGUID());
// add new enchanting if equipped
item_owner->ApplyEnchantment(itemTarget, TEMP_ENCHANTMENT_SLOT, true);
@@ -4243,7 +4243,7 @@ void Spell::EffectEnchantHeldItem(SpellEffIndex effIndex)
if (!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER)
return;
- Player* item_owner = (Player*)unitTarget;
+ Player* item_owner = unitTarget->ToPlayer();
Item* item = item_owner->GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_MAINHAND);
if (!item)
@@ -4274,7 +4274,7 @@ void Spell::EffectEnchantHeldItem(SpellEffIndex effIndex)
return;
// Apply the temporary enchantment
- item->SetEnchantment(slot, enchant_id, duration*IN_MILLISECONDS, 0);
+ item->SetEnchantment(slot, enchant_id, duration*IN_MILLISECONDS, 0, m_caster->GetGUID());
item_owner->ApplyEnchantment(item, slot, true);
}
}
diff --git a/src/server/game/Spells/SpellMgr.cpp b/src/server/game/Spells/SpellMgr.cpp
index a2a4a85808a..3ee6266b0d2 100644
--- a/src/server/game/Spells/SpellMgr.cpp
+++ b/src/server/game/Spells/SpellMgr.cpp
@@ -499,6 +499,9 @@ uint32 SpellMgr::GetSpellIdForDifficulty(uint32 spellId, Unit const* caster) con
SpellInfo const* SpellMgr::GetSpellForDifficultyFromSpell(SpellInfo const* spell, Unit const* caster) const
{
+ if (!spell)
+ return NULL;
+
uint32 newSpellId = GetSpellIdForDifficulty(spell->Id, caster);
SpellInfo const* newSpell = GetSpellInfo(newSpellId);
if (!newSpell)
diff --git a/src/server/scripts/Commands/CMakeLists.txt b/src/server/scripts/Commands/CMakeLists.txt
index 15e16c2caf1..ce31fa1f4d3 100644
--- a/src/server/scripts/Commands/CMakeLists.txt
+++ b/src/server/scripts/Commands/CMakeLists.txt
@@ -12,6 +12,7 @@ set(scripts_STAT_SRCS
${scripts_STAT_SRCS}
Commands/cs_account.cpp
Commands/cs_achievement.cpp
+ Commands/cs_arena.cpp
Commands/cs_ban.cpp
Commands/cs_bf.cpp
Commands/cs_cast.cpp
diff --git a/src/server/scripts/Commands/cs_arena.cpp b/src/server/scripts/Commands/cs_arena.cpp
new file mode 100644
index 00000000000..82a1109efd2
--- /dev/null
+++ b/src/server/scripts/Commands/cs_arena.cpp
@@ -0,0 +1,347 @@
+/*
+ * Copyright (C) 2008-2013 TrinityCore <http://www.trinitycore.org/>
+ *
+ * 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/>.
+ */
+
+/* ScriptData
+Name: arena_commandscript
+%Complete: 100
+Comment: All arena team related commands
+Category: commandscripts
+EndScriptData */
+
+#include "ObjectMgr.h"
+#include "Chat.h"
+#include "Language.h"
+#include "ArenaTeamMgr.h"
+#include "Player.h"
+#include "ScriptMgr.h"
+
+class arena_commandscript : public CommandScript
+{
+public:
+ arena_commandscript() : CommandScript("arena_commandscript") { }
+
+ ChatCommand* GetCommands() const
+ {
+ static ChatCommand arenaCommandTable[] =
+ {
+ { "create", SEC_ADMINISTRATOR, true, &HandleArenaCreateCommand, "", NULL },
+ { "disband", SEC_ADMINISTRATOR, true, &HandleArenaDisbandCommand, "", NULL },
+ { "rename", SEC_ADMINISTRATOR, true, &HandleArenaRenameCommand, "", NULL },
+ { "captain", SEC_ADMINISTRATOR, false, &HandleArenaCaptainCommand, "", NULL },
+ { "info", SEC_GAMEMASTER, true, &HandleArenaInfoCommand, "", NULL },
+ { "lookup", SEC_GAMEMASTER, false, &HandleArenaLookupCommand, "", NULL },
+ { NULL, SEC_GAMEMASTER, false, NULL, "", NULL }
+ };
+ static ChatCommand commandTable[] =
+ {
+ { "arena", SEC_GAMEMASTER, false, NULL, "", arenaCommandTable },
+ { NULL, SEC_PLAYER, false, NULL, "", NULL }
+ };
+ return commandTable;
+ }
+
+ static bool HandleArenaCreateCommand(ChatHandler* handler, char const* args)
+ {
+ if (!*args)
+ return false;
+
+ Player* target;
+ if (!handler->extractPlayerTarget(*args != '"' ? (char*)args : NULL, &target))
+ return false;
+
+ char* tailStr = *args != '"' ? strtok(NULL, "") : (char*)args;
+ if (!tailStr)
+ return false;
+
+ char* name = handler->extractQuotedArg(tailStr);
+ if (!name)
+ return false;
+ char* typeStr = strtok(NULL, "");
+ if (!typeStr)
+ return false;
+ int8 type = atoi(typeStr);
+ if (sArenaTeamMgr->GetArenaTeamByName(name))
+ {
+ handler->PSendSysMessage(LANG_ARENA_ERROR_NAME_EXISTS, name);
+ handler->SetSentErrorMessage(true);
+ return false;
+ }
+
+ if (type == 2 || type == 3 || type == 5 )
+ {
+ if (Player::GetArenaTeamIdFromDB(target->GetGUID(), type) != 0)
+ {
+ handler->PSendSysMessage(LANG_ARENA_ERROR_SIZE, target->GetName().c_str());
+ handler->SetSentErrorMessage(true);
+ return false;
+ }
+
+ ArenaTeam* Arena = new ArenaTeam();
+
+ if (!Arena->Create(target->GetGUID(), type, name, 4293102085, 101, 4293253939, 4, 4284049911))
+ {
+ delete Arena;
+ handler->SendSysMessage(LANG_BAD_VALUE);
+ handler->SetSentErrorMessage(true);
+ return false;
+ }
+
+ sArenaTeamMgr->AddArenaTeam(Arena);
+ handler->PSendSysMessage(LANG_ARENA_CREATE, Arena->GetName().c_str(), Arena->GetId(), Arena->GetType(), Arena->GetCaptain());
+ }
+ else
+ {
+ handler->SendSysMessage(LANG_BAD_VALUE);
+ handler->SetSentErrorMessage(true);
+ return false;
+ }
+ return true;
+ }
+
+ static bool HandleArenaDisbandCommand(ChatHandler* handler, char const* args)
+ {
+ if (!*args)
+ return false;
+
+ uint32 teamId = atoi((char*)args);
+ if (!teamId)
+ return false;
+
+ ArenaTeam* Arena = sArenaTeamMgr->GetArenaTeamById(teamId);
+
+ if (!Arena)
+ {
+ handler->PSendSysMessage(LANG_ARENA_ERROR_NOT_FOUND, teamId);
+ handler->SetSentErrorMessage(true);
+ return false;
+ }
+
+ if (Arena->IsFighting())
+ {
+ handler->SendSysMessage(LANG_ARENA_ERROR_COMBAT);
+ handler->SetSentErrorMessage(true);
+ return false;
+ }
+ std::string name = Arena->GetName();
+ Arena->Disband();
+ if (handler->GetSession())
+ TC_LOG_DEBUG(LOG_FILTER_ARENAS, "GameMaster: %s [GUID: %u] disbanded arena team type: %u [Id: %u].",
+ handler->GetSession()->GetPlayer()->GetName().c_str(), handler->GetSession()->GetPlayer()->GetGUIDLow(), Arena->GetType(), teamId);
+ else
+ TC_LOG_DEBUG(LOG_FILTER_ARENAS, "Console: disbanded arena team type: %u [Id: %u].", Arena->GetType(), teamId);
+ delete(Arena);
+ handler->PSendSysMessage(LANG_ARENA_DISBAND, name.c_str(), teamId);
+ return true;
+ }
+
+ static bool HandleArenaRenameCommand(ChatHandler* handler, char const* _args)
+ {
+ if (!*_args)
+ return false;
+
+ char* args = (char *)_args;
+
+ char const* oldArenaStr = handler->extractQuotedArg(args);
+ if (!oldArenaStr)
+ {
+ handler->SendSysMessage(LANG_BAD_VALUE);
+ handler->SetSentErrorMessage(true);
+ return false;
+ }
+
+ char const* newArenaStr = handler->extractQuotedArg(strtok(NULL, ""));
+ if (!newArenaStr)
+ {
+ handler->SendSysMessage(LANG_BAD_VALUE);
+ handler->SetSentErrorMessage(true);
+ return false;
+ }
+
+ ArenaTeam* Arena = sArenaTeamMgr->GetArenaTeamByName(oldArenaStr);
+ if (!Arena)
+ {
+ handler->PSendSysMessage(LANG_AREAN_ERROR_NAME_NOT_FOUND, oldArenaStr);
+ handler->SetSentErrorMessage(true);
+ return false;
+ }
+
+ if (sArenaTeamMgr->GetArenaTeamByName(newArenaStr))
+ {
+ handler->PSendSysMessage(LANG_ARENA_ERROR_NAME_EXISTS, oldArenaStr);
+ handler->SetSentErrorMessage(true);
+ return false;
+ }
+
+ if (Arena->IsFighting())
+ {
+ handler->SendSysMessage(LANG_ARENA_ERROR_COMBAT);
+ handler->SetSentErrorMessage(true);
+ return false;
+ }
+
+ if (!Arena->SetName(newArenaStr))
+ {
+ handler->SendSysMessage(LANG_BAD_VALUE);
+ handler->SetSentErrorMessage(true);
+ return false;
+ }
+ handler->PSendSysMessage(LANG_ARENA_RENAME, Arena->GetId(), oldArenaStr, newArenaStr);
+ if (handler->GetSession())
+ TC_LOG_DEBUG(LOG_FILTER_ARENAS, "GameMaster: %s [GUID: %u] rename arena team \"%s\"[Id: %u] to \"%s\"",
+ handler->GetSession()->GetPlayer()->GetName().c_str(), handler->GetSession()->GetPlayer()->GetGUIDLow(), oldArenaStr, Arena->GetId(), newArenaStr);
+ else
+ TC_LOG_DEBUG(LOG_FILTER_ARENAS, "Console: rename arena team \"%s\"[Id: %u] to \"%s\"", oldArenaStr, Arena->GetId(), newArenaStr);
+ return true;
+ }
+
+ static bool HandleArenaCaptainCommand(ChatHandler* handler, char const* args)
+ {
+ if (!*args)
+ return false;
+
+ char* idStr;
+ char* nameStr;
+ handler->extractOptFirstArg((char*)args, &idStr, &nameStr);
+ if (!idStr)
+ return false;
+
+ uint32 teamId = atoi(idStr);
+ if (!teamId)
+ return false;
+
+ Player* target;
+ uint64 targetGuid;
+ if (!handler->extractPlayerTarget(nameStr, &target, &targetGuid))
+ return false;
+
+ ArenaTeam* Arena = sArenaTeamMgr->GetArenaTeamById(teamId);
+
+ if (!Arena)
+ {
+ handler->PSendSysMessage(LANG_ARENA_ERROR_NOT_FOUND, teamId);
+ handler->SetSentErrorMessage(true);
+ return false;
+ }
+
+ if (!target)
+ {
+ handler->PSendSysMessage(LANG_PLAYER_NOT_EXIST_OR_OFFLINE, nameStr);
+ handler->SetSentErrorMessage(true);
+ return false;
+ }
+
+ if (Arena->IsFighting())
+ {
+ handler->SendSysMessage(LANG_ARENA_ERROR_COMBAT);
+ handler->SetSentErrorMessage(true);
+ return false;
+ }
+
+ if (!Arena->IsMember(targetGuid))
+ {
+ handler->PSendSysMessage(LANG_ARENA_ERROR_NOT_MEMBER, nameStr, Arena->GetName().c_str());
+ handler->SetSentErrorMessage(true);
+ return false;
+ }
+
+ if (Arena->GetCaptain() == targetGuid)
+ {
+ handler->PSendSysMessage(LANG_ARENA_ERROR_CAPTAIN, nameStr, Arena->GetName().c_str());
+ handler->SetSentErrorMessage(true);
+ return false;
+ }
+
+ Player* oldCaptain = sObjectMgr->GetPlayerByLowGUID(Arena->GetCaptain());
+ Arena->SetCaptain(targetGuid);
+ handler->PSendSysMessage(LANG_ARENA_CAPTAIN, Arena->GetName().c_str(), Arena->GetId(), oldCaptain->GetName().c_str(), target->GetName().c_str());
+ if (handler->GetSession())
+ TC_LOG_DEBUG(LOG_FILTER_ARENAS, "GameMaster: %s [GUID: %u] promoted player: %s [GUID: %u] to leader of arena team \"%s\"[Id: %u]",
+ handler->GetSession()->GetPlayer()->GetName().c_str(), handler->GetSession()->GetPlayer()->GetGUIDLow(), target->GetName().c_str(), target->GetGUIDLow(), Arena->GetName().c_str(), Arena->GetId());
+ else
+ TC_LOG_DEBUG(LOG_FILTER_ARENAS, "Console: promoted player: %s [GUID: %u] to leader of arena team \"%s\"[Id: %u]",
+ target->GetName().c_str(), target->GetGUIDLow(), Arena->GetName().c_str(), Arena->GetId());
+ return true;
+ }
+
+ static bool HandleArenaInfoCommand(ChatHandler* handler, char const* args)
+ {
+ if (!*args)
+ return false;
+
+ uint32 teamId = atoi((char*)args);
+ if (!teamId)
+ return false;
+
+ ArenaTeam* Arena = sArenaTeamMgr->GetArenaTeamById(teamId);
+
+ if (!Arena)
+ {
+ handler->PSendSysMessage(LANG_ARENA_ERROR_NOT_FOUND, teamId);
+ handler->SetSentErrorMessage(true);
+ return false;
+ }
+
+ handler->PSendSysMessage(LANG_ARENA_INFO_HEADER, Arena->GetName().c_str(), Arena->GetId(), Arena->GetRating(), Arena->GetType(), Arena->GetType());
+ for (ArenaTeam::MemberList::iterator itr = Arena->m_membersBegin(); itr != Arena->m_membersEnd(); ++itr)
+ {
+ handler->PSendSysMessage(LANG_ARENA_INFO_MEMBERS, itr->Name.c_str(), GUID_LOPART(itr->Guid), itr->PersonalRating, (Arena->GetCaptain() == itr->Guid ? "- Captain" : ""));
+ }
+ return true;
+ }
+
+ static bool HandleArenaLookupCommand(ChatHandler* handler, char const* args)
+ {
+ if (!*args)
+ return false;
+
+ std::string namepart = args;
+ std::wstring wnamepart;
+
+ if (!Utf8toWStr(namepart, wnamepart))
+ return false;
+
+ wstrToLower(wnamepart);
+
+ bool found = false;
+ ArenaTeamMgr::ArenaTeamContainer::const_iterator i = sArenaTeamMgr->GetArenaTeamMapBegin();
+ for (; i != sArenaTeamMgr->GetArenaTeamMapEnd(); ++i)
+ {
+ ArenaTeam* Arena = i->second;
+
+ if (Utf8FitTo(Arena->GetName(), wnamepart))
+ {
+ if (handler->GetSession())
+ handler->PSendSysMessage(LANG_ARENA_LOOKUP, Arena->GetName().c_str(), Arena->GetId(), Arena->GetType(), Arena->GetType());
+
+ if (!found)
+ found = true;
+
+ continue;
+ }
+ }
+
+ if (!found)
+ handler->PSendSysMessage(LANG_AREAN_ERROR_NAME_NOT_FOUND, namepart.c_str());
+
+ return true;
+ }
+};
+
+void AddSC_arena_commandscript()
+{
+ new arena_commandscript();
+}
diff --git a/src/server/scripts/Commands/cs_misc.cpp b/src/server/scripts/Commands/cs_misc.cpp
index 489c11e0f94..46eda11bfed 100644
--- a/src/server/scripts/Commands/cs_misc.cpp
+++ b/src/server/scripts/Commands/cs_misc.cpp
@@ -1472,37 +1472,124 @@ public:
return true;
}
- // show info of player
+
+ /**
+ * @name Player command: .pinfo
+ * @date 05/19/2013
+ *
+ * @brief Prints information about a character and it's linked account to the commander
+ *
+ * Non-applying information, e.g. a character that is not in gm mode right now or
+ * that is not banned/muted, is not printed
+ *
+ * This can be done either by giving a name or by targeting someone, else, it'll use the commander
+ *
+ * @param args name Prints information according to the given name to the commander
+ * target Prints information on the target to the commander
+ * none No given args results in printing information on the commander
+ *
+ * @return Several pieces of information about the character and the account
+ **/
+
static bool HandlePInfoCommand(ChatHandler* handler, char const* args)
{
+ // Define ALL the player variables!
Player* target;
uint64 targetGuid;
std::string targetName;
+ // To make sure we get a target, we convert our guid to an omniversal...
uint32 parseGUID = MAKE_NEW_GUID(atol((char*)args), 0, HIGHGUID_PLAYER);
+ // ... and make sure we get a target, somehow.
if (sObjectMgr->GetPlayerNameByGUID(parseGUID, targetName))
{
target = sObjectMgr->GetPlayerByLowGUID(parseGUID);
targetGuid = parseGUID;
}
+ // if not, then return false. Which shouldn't happen, now should it ?
else if (!handler->extractPlayerTarget((char*)args, &target, &targetGuid, &targetName))
return false;
- uint32 accId = 0;
- uint32 money = 0;
- uint32 totalPlayerTime = 0;
- uint8 level = 0;
- uint32 latency = 0;
- uint8 race;
- uint8 Class;
- int64 muteTime = 0;
- int64 banTime = -1;
+ /* The variables we extract for the command. They are
+ * default as "does not exist" to prevent problems
+ * The output is printed in the follow manner:
+ *
+ * Player %s %s (guid: %u) - I. LANG_PINFO_PLAYER
+ * ** GM Mode active, Phase: -1 - II. LANG_PINFO_GM_ACTIVE (if GM)
+ * ** Banned: (Type, Reason, Time, By) - III. LANG_PINFO_BANNED (if banned)
+ * ** Muted: (Time, Reason, By) - IV. LANG_PINFO_MUTED (if muted)
+ * * Account: %s (id: %u), GM Level: %u - V. LANG_PINFO_ACC_ACCOUNT
+ * * Last Login: %u (Failed Logins: %u) - VI. LANG_PINFO_ACC_LASTLOGIN
+ * * Uses OS: %s - Latency: %u ms - Email %s - VII. LANG_PINFO_ACC_OS
+ * * Last IP: %u (Locked: %s) - VIII. LANG_PINFO_ACC_IP
+ * * Level: %u (%u/%u XP (%u XP left) - IX. LANG_PINFO_CHR_LEVEL
+ * * Race: %s %s, Class %s - X. LANG_PINFO_CHR_RACE
+ * * Alive ?: %s - XI. LANG_PINFO_CHR_ALIVE
+ * * Phase: %s - XII. LANG_PINFO_CHR_PHASE (if not GM)
+ * * Money: %ug%us%uc - XIII. LANG_PINFO_CHR_MONEY
+ * * Map: %s, Area: %s - XIV. LANG_PINFO_CHR_MAP
+ * * Guild: %s (Id: %u) - XV. LANG_PINFO_CHR_GUILD (if in guild)
+ * ** Rank: %s - XVI. LANG_PINFO_CHR_GUILD_RANK (if in guild)
+ * ** Note: %s - XVII. LANG_PINFO_CHR_GUILD_NOTE (if in guild and has note)
+ * ** O. Note: %s - XVIII.LANG_PINFO_CHR_GUILD_ONOTE (if in guild and has officer note)
+ * * Played time: %s - XIX. LANG_PINFO_CHR_PLAYEDTIME
+ * * Mails: %u Read/%u Total - XX. LANG_PINFO_CHR_MAILS (if has mails)
+ *
+ * Not all of them can be moved to the top. These should
+ * place the most important ones to the head, though.
+ *
+ * For a cleaner overview, I segment each output in Roman numerals
+ */
+
+ // Account data print variables
+ std::string userName = handler->GetTrinityString(LANG_ERROR);
+ uint32 accId = 0;
+ uint32 lowguid = GUID_LOPART(targetGuid);
+ std::string eMail = handler->GetTrinityString(LANG_ERROR);
+ uint32 security = 0;
+ std::string lastIp = handler->GetTrinityString(LANG_ERROR);
+ uint8 locked = 0;
+ std::string lastLogin = handler->GetTrinityString(LANG_ERROR);
+ uint32 failedLogins = 0;
+ uint32 latency = 0;
+ std::string OS = "None";
+
+ // Mute data print variables
+ int64 muteTime = -1;
+ std::string muteReason = "unknown";
+ std::string muteBy = "unknown";
+
+ // Ban data print variables
+ int64 banTime = -1;
+ std::string banType = "None";
+ std::string banReason = "Unknown";
+ std::string bannedBy = "Unknown";
+
+ // Character data print variables
+ uint8 raceid, classid = 0; //RACE_NONE, CLASS_NONE
+ std::string raceStr, classStr = "None";
+ uint8 gender = 0;
+ int8 locale = handler->GetSessionDbcLocale();
+ std::string genderStr = handler->GetTrinityString(LANG_ERROR);
+ uint32 totalPlayerTime = 0;
+ uint8 level = 0;
+ std::string alive = handler->GetTrinityString(LANG_ERROR);
+ uint32 money = 0;
+ uint32 xp = 0;
+ uint32 xptotal = 0;
+
+ // Position data print
uint32 mapId;
uint32 areaId;
uint32 phase = 0;
+ std::string areaName = "<unknown>";
+ std::string zoneName = "<unknown>";
+
+ // Guild data print is only defined if part of Guild
+
+ // Mail data print is only defined if you have a mail
- // get additional information from Player object
if (target)
{
// check online security
@@ -1514,11 +1601,13 @@ public:
totalPlayerTime = target->GetTotalPlayedTime();
level = target->getLevel();
latency = target->GetSession()->GetLatency();
- race = target->getRace();
- Class = target->getClass();
+ raceid = target->getRace();
+ classid = target->getClass();
muteTime = target->GetSession()->m_muteTime;
mapId = target->GetMapId();
areaId = target->GetAreaId();
+ alive = target->isAlive() ? "Yes" : "No";
+ gender = target->getGender();
phase = target->GetPhaseMask();
}
// get additional information from DB
@@ -1528,8 +1617,9 @@ public:
if (handler->HasLowerSecurity(NULL, targetGuid))
return false;
+ // Query informations from the DB
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHAR_PINFO);
- stmt->setUInt32(0, GUID_LOPART(targetGuid));
+ stmt->setUInt32(0, lowguid);
PreparedQueryResult result = CharacterDatabase.Query(stmt);
if (!result)
@@ -1540,20 +1630,20 @@ public:
level = fields[1].GetUInt8();
money = fields[2].GetUInt32();
accId = fields[3].GetUInt32();
- race = fields[4].GetUInt8();
- Class = fields[5].GetUInt8();
+ raceid = fields[4].GetUInt8();
+ classid = fields[5].GetUInt8();
mapId = fields[6].GetUInt16();
areaId = fields[7].GetUInt16();
+ gender = fields[8].GetUInt8();
+ uint32 health = fields[9].GetUInt32();
+ uint32 playerFlags = fields[10].GetUInt32();
+ if (!health || playerFlags & PLAYER_FLAGS_GHOST)
+ alive = "No";
+ else
+ alive = "Yes";
}
- std::string userName = handler->GetTrinityString(LANG_ERROR);
- std::string eMail = handler->GetTrinityString(LANG_ERROR);
- std::string muteReason = "";
- std::string muteBy = "";
- std::string lastIp = handler->GetTrinityString(LANG_ERROR);
- uint32 security = 0;
- std::string lastLogin = handler->GetTrinityString(LANG_ERROR);
-
+ // Query the prepared statement for login data
PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_PINFO);
stmt->setInt32(0, int32(realmID));
stmt->setUInt32(1, accId);
@@ -1565,23 +1655,18 @@ public:
userName = fields[0].GetString();
security = fields[1].GetUInt8();
eMail = fields[2].GetString();
- muteTime = fields[5].GetUInt64();
- muteReason = fields[6].GetString();
- muteBy = fields[7].GetString();
-
- if (eMail.empty())
- eMail = "-";
+ // Only fetch these fields if commander has sufficient rights AND is online (prevent cheating)
+ /// @TODO: Add RBAC for "Can query ip and login data"
if (!handler->GetSession() || handler->GetSession()->GetSecurity() >= AccountTypes(security))
{
lastIp = fields[3].GetString();
lastLogin = fields[4].GetString();
uint32 ip = inet_addr(lastIp.c_str());
-#if TRINITY_ENDIAN == BIGENDIAN
EndianConvertReverse(ip);
-#endif
+ // If ip2nation table is populated, it displays the country
PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_IP2NATION_COUNTRY);
stmt->setUInt32(0, ip);
if (PreparedQueryResult result2 = LoginDatabase.Query(stmt))
@@ -1592,27 +1677,26 @@ public:
lastIp.append(")");
}
}
- else
- {
- lastIp = "-";
- lastLogin = "-";
- }
+ muteTime = fields[5].GetUInt64();
+ muteReason = fields[6].GetString();
+ muteBy = fields[7].GetString();
+ failedLogins = fields[8].GetUInt32();
+ locked = fields[9].GetUInt8();
+ OS = fields[10].GetString();
}
+ // Creates a chat link to the character. Returns nameLink
std::string nameLink = handler->playerLink(targetName);
- handler->PSendSysMessage(LANG_PINFO_ACCOUNT, (target ? "" : handler->GetTrinityString(LANG_OFFLINE)), nameLink.c_str(), GUID_LOPART(targetGuid), userName.c_str(), accId, eMail.c_str(), security, lastIp.c_str(), lastLogin.c_str(), latency);
-
- std::string bannedby = "unknown";
- std::string banreason = "";
-
- stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_PINFO_BANS);
- stmt->setUInt32(0, accId);
- PreparedQueryResult result2 = LoginDatabase.Query(stmt);
+ // Returns banType, banTime, bannedBy, banreason
+ PreparedStatement* stmt2 = LoginDatabase.GetPreparedStatement(LOGIN_SEL_PINFO_BANS);
+ stmt2->setUInt32(0, accId);
+ PreparedQueryResult result2 = LoginDatabase.Query(stmt2);
if (!result2)
{
+ banType = "Character";
stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_PINFO_BANS);
- stmt->setUInt32(0, GUID_LOPART(targetGuid));
+ stmt->setUInt32(0, lowguid);
result2 = CharacterDatabase.Query(stmt);
}
@@ -1620,49 +1704,19 @@ public:
{
Field* fields = result2->Fetch();
banTime = int64(fields[1].GetUInt64() ? 0 : fields[0].GetUInt32());
- bannedby = fields[2].GetString();
- banreason = fields[3].GetString();
+ bannedBy = fields[2].GetString();
+ banReason = fields[3].GetString();
}
- if (muteTime > 0)
- handler->PSendSysMessage(LANG_PINFO_MUTE, secsToTimeString(muteTime - time(NULL), true).c_str(), muteBy.c_str(), muteReason.c_str());
-
- if (banTime >= 0)
- handler->PSendSysMessage(LANG_PINFO_BAN, banTime > 0 ? secsToTimeString(banTime - time(NULL), true).c_str() : "permanently", bannedby.c_str(), banreason.c_str());
+ // Can be used to query data from World database
+ stmt2 = WorldDatabase.GetPreparedStatement(WORLD_SEL_REQ_XP);
+ stmt2->setUInt8(0, level);
+ PreparedQueryResult result3 = WorldDatabase.Query(stmt2);
- std::string raceStr, ClassStr;
- switch (race)
+ if (result3)
{
- case RACE_HUMAN:
- raceStr = "Human";
- break;
- case RACE_ORC:
- raceStr = "Orc";
- break;
- case RACE_DWARF:
- raceStr = "Dwarf";
- break;
- case RACE_NIGHTELF:
- raceStr = "Night Elf";
- break;
- case RACE_UNDEAD_PLAYER:
- raceStr = "Undead";
- break;
- case RACE_TAUREN:
- raceStr = "Tauren";
- break;
- case RACE_GNOME:
- raceStr = "Gnome";
- break;
- case RACE_TROLL:
- raceStr = "Troll";
- break;
- case RACE_BLOODELF:
- raceStr = "Blood Elf";
- break;
- case RACE_DRAENEI:
- raceStr = "Draenei";
- break;
+ Field* fields = result3->Fetch();
+ xptotal = fields[0].GetUInt32();
case RACE_GOBLIN:
raceStr = "Goblin";
break;
@@ -1671,52 +1725,68 @@ public:
break;
}
- switch (Class)
+ // Can be used to query data from Characters database
+ stmt2 = CharacterDatabase.GetPreparedStatement(CHAR_SEL_PINFO_XP);
+ stmt2->setUInt32(0, lowguid);
+ PreparedQueryResult result4 = CharacterDatabase.Query(stmt2);
+
+ if (result4)
{
- case CLASS_WARRIOR:
- ClassStr = "Warrior";
- break;
- case CLASS_PALADIN:
- ClassStr = "Paladin";
- break;
- case CLASS_HUNTER:
- ClassStr = "Hunter";
- break;
- case CLASS_ROGUE:
- ClassStr = "Rogue";
- break;
- case CLASS_PRIEST:
- ClassStr = "Priest";
- break;
- case CLASS_DEATH_KNIGHT:
- ClassStr = "Death Knight";
- break;
- case CLASS_SHAMAN:
- ClassStr = "Shaman";
- break;
- case CLASS_MAGE:
- ClassStr = "Mage";
- break;
- case CLASS_WARLOCK:
- ClassStr = "Warlock";
- break;
- case CLASS_DRUID:
- ClassStr = "Druid";
- break;
+ Field* fields = result4->Fetch();
+ xp = fields[0].GetUInt32();
}
- std::string timeStr = secsToTimeString(totalPlayerTime, true, true);
- uint32 gold = money /GOLD;
- uint32 silv = (money % GOLD) / SILVER;
- uint32 copp = (money % GOLD) % SILVER;
- handler->PSendSysMessage(LANG_PINFO_LEVEL, raceStr.c_str(), ClassStr.c_str(), timeStr.c_str(), level, gold, silv, copp);
+ // Initiate output
+ // Output I. LANG_PINFO_PLAYER
+ handler->PSendSysMessage(LANG_PINFO_PLAYER, target ? "" : handler->GetTrinityString(LANG_OFFLINE), nameLink.c_str(), lowguid);
- // Add map, zone, subzone and phase to output
- std::string areaName = "<unknown>";
- std::string zoneName = "";
+ // Output II. LANG_PINFO_GM_ACTIVE
+ if (target && target->isGameMaster())
+ handler->PSendSysMessage(LANG_PINFO_GM_ACTIVE);
- MapEntry const* map = sMapStore.LookupEntry(mapId);
+ // Output III. LANG_PINFO_BANNED if ban exists and is applied
+ if (banTime >= 0)
+ handler->PSendSysMessage(LANG_PINFO_BANNED, banType.c_str(), banTime > 0 ? secsToTimeString(banTime - time(NULL), true).c_str() : "permanently", banReason.c_str(), bannedBy.c_str());
+
+ // Output IV. LANG_PINFO_MUTED if mute is applied
+ if (muteTime > 0)
+ handler->PSendSysMessage(LANG_PINFO_MUTED, secsToTimeString(muteTime - time(NULL), true).c_str(), muteReason.c_str(), muteBy.c_str());
+
+ // Output V. LANG_PINFO_ACC_ACCOUNT
+ handler->PSendSysMessage(LANG_PINFO_ACC_ACCOUNT, userName.c_str(), accId, security);
+
+ // Output VI. LANG_PINFO_ACC_LASTLOGIN
+ handler->PSendSysMessage(LANG_PINFO_ACC_LASTLOGIN, lastLogin.c_str(), failedLogins);
+
+ // Output VIII. LANG_PINFO_ACC_OS
+ handler->PSendSysMessage(LANG_PINFO_ACC_OS, OS.c_str(), latency, eMail.c_str());
+ // Output IX. LANG_PINFO_ACC_IP
+ handler->PSendSysMessage(LANG_PINFO_ACC_IP, lastIp.c_str(), locked ? "Yes" : "No");
+
+ // Output X. LANG_PINFO_CHR_LEVEL
+ handler->PSendSysMessage(LANG_PINFO_CHR_LEVEL, level, xp, xptotal, (xptotal - xp));
+
+ // Output XI. LANG_PINFO_CHR_RACE
+ raceStr = GetRaceName(raceid, locale);
+ classStr = GetClassName(classid, locale);
+ handler->PSendSysMessage(LANG_PINFO_CHR_RACE, (gender == 0 ? handler->GetTrinityString(LANG_CHARACTER_GENDER_MALE) : handler->GetTrinityString(LANG_CHARACTER_GENDER_FEMALE)), raceStr.c_str(), classStr.c_str());
+
+ // Output XII. LANG_PINFO_CHR_ALIVE
+ handler->PSendSysMessage(LANG_PINFO_CHR_ALIVE, alive.c_str());
+
+ // Output XIII. LANG_PINFO_CHR_PHASE if player is not in GM mode (GM is in every phase)
+ if (target && !target->isGameMaster()) // IsInWorld() returns false on loadingscreen, so it's more
+ handler->PSendSysMessage(LANG_PINFO_CHR_PHASE, phase); // precise than just target (safer ?).
+ // However, as we usually just require a target here, we use target instead.
+ // Output XIV. LANG_PINFO_CHR_MONEY
+ uint32 gold = money / GOLD;
+ uint32 silv = (money % GOLD) / SILVER;
+ uint32 copp = (money % GOLD) % SILVER;
+ handler->PSendSysMessage(LANG_PINFO_CHR_MONEY, gold, silv, copp);
+
+ // Position data
+ MapEntry const* map = sMapStore.LookupEntry(mapId);
AreaTableEntry const* area = GetAreaEntryByAreaID(areaId);
if (area)
{
@@ -1728,30 +1798,55 @@ public:
}
if (target)
- {
- if (!zoneName.empty())
- handler->PSendSysMessage(LANG_PINFO_MAP_ONLINE, map->name, zoneName.c_str(), areaName.c_str(), phase);
- else
- handler->PSendSysMessage(LANG_PINFO_MAP_ONLINE, map->name, areaName.c_str(), "<unknown>", phase);
+ handler->PSendSysMessage(LANG_PINFO_CHR_MAP, map->name[locale], (!zoneName.empty() ? zoneName.c_str() : "<Unknown>"), (!areaName.empty() ? areaName.c_str() : "<Unknown>"));
+
+ // Guild Data - an own query, because it may not happen.
+ PreparedStatement* stmt3 = CharacterDatabase.GetPreparedStatement(CHAR_SEL_GUILD_MEMBER_EXTENDED);
+ stmt3->setUInt32(0, lowguid);
+ PreparedQueryResult result5 = CharacterDatabase.Query(stmt3);
+ if (result5)
+ {
+ Field* fields = result5->Fetch();
+ uint32 guildId = fields[0].GetUInt32();
+ std::string guildName = fields[1].GetString();
+ std::string guildRank = fields[2].GetString();
+ std::string note = fields[3].GetString();
+ std::string officeNote = fields[4].GetString();
+
+ // Output XVII. - XX.
+ handler->PSendSysMessage(LANG_PINFO_CHR_GUILD, guildName.c_str(), guildId);
+ handler->PSendSysMessage(LANG_PINFO_CHR_GUILD_RANK, guildRank.c_str());
+ // Only output XIX and XX if they are not empty
+ if (!note.empty())
+ handler->PSendSysMessage(LANG_PINFO_CHR_GUILD_NOTE, note.c_str());
+ if (!officeNote.empty())
+ handler->PSendSysMessage(LANG_PINFO_CHR_GUILD_ONOTE, officeNote.c_str());
}
- else
- handler->PSendSysMessage(LANG_PINFO_MAP_OFFLINE, map->name, areaName.c_str());
- stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_GUILD_MEMBER_EXTENDED);
- stmt->setUInt32(0, GUID_LOPART(targetGuid));
+ // Output XXI. LANG_PINFO_CHR_PLAYEDTIME
+ handler->PSendSysMessage(LANG_PINFO_CHR_PLAYEDTIME, (secsToTimeString(totalPlayerTime, true, true)).c_str());
- result = CharacterDatabase.Query(stmt);
- if (result)
+ // Mail Data - an own query, because it may or may not be useful.
+ // SQL: "SELECT SUM(CASE WHEN (checked & 1) THEN 1 ELSE 0 END) AS 'readmail', COUNT(*) AS 'totalmail' FROM mail WHERE `receiver` = ?"
+ stmt3 = CharacterDatabase.GetPreparedStatement(CHAR_SEL_PINFO_MAILS);
+ stmt3->setUInt32(0, lowguid);
+ PreparedQueryResult result6 = CharacterDatabase.Query(stmt3);
+ if (result6)
{
- Field* fields = result->Fetch();
+ // Define the variables, so the compiler knows they exist
+ uint32 rmailint = 0;
- uint32 guildId = fields[0].GetUInt32();
- std::string guildName = fields[1].GetString();
- std::string guildRank = fields[2].GetString();
- std::string note = fields[3].GetString();
- std::string officeNote = fields[4].GetString();
+ // Fetch the fields - readmail is a SUM(x) and given out as char! Thus...
+ Field* fields = result6->Fetch();
+ std::string readmail = fields[0].GetString();
+ uint64 totalmail = fields[1].GetUInt64();
- handler->PSendSysMessage(LANG_PINFO_GUILD_INFO, guildName.c_str(), guildId, guildRank.c_str(), note.c_str(), officeNote.c_str());
+ // ... we have to convert it from Char to int. We can use totalmail as it is
+ rmailint = atol(readmail.c_str());
+
+ // Output XXII. LANG_INFO_CHR_MAILS if at least one mails is given
+ if (totalmail >= 1)
+ handler->PSendSysMessage(LANG_PINFO_CHR_MAILS, rmailint, totalmail);
}
return true;
@@ -1789,6 +1884,7 @@ public:
return true;
}
+
// mute player for some times
static bool HandleMuteCommand(ChatHandler* handler, char const* args)
{
diff --git a/src/server/scripts/Commands/cs_server.cpp b/src/server/scripts/Commands/cs_server.cpp
index 309380a9cbb..11b4ebf33ae 100644
--- a/src/server/scripts/Commands/cs_server.cpp
+++ b/src/server/scripts/Commands/cs_server.cpp
@@ -338,7 +338,8 @@ public:
}
else
sWorld->ShutdownServ(time, SHUTDOWN_MASK_IDLE, SHUTDOWN_EXIT_CODE);
- return true;
+
+ return true;
}
// Exit the realm
diff --git a/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_kalecgos.cpp b/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_kalecgos.cpp
index 9e312ef8f94..b6b701c513d 100644
--- a/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_kalecgos.cpp
+++ b/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_kalecgos.cpp
@@ -716,27 +716,27 @@ public:
if (CheckTimer <= diff)
{
Creature* Kalec = Unit::GetCreature(*me, KalecGUID);
- if (!Kalec || (Kalec && !Kalec->isAlive()))
+ if (!Kalec || !Kalec->isAlive())
{
if (Creature* Kalecgos = Unit::GetCreature(*me, KalecgosGUID))
Kalecgos->AI()->EnterEvadeMode();
- return;
+ return;
}
+
if (HealthBelowPct(10) && !isEnraged)
{
if (Creature* Kalecgos = Unit::GetCreature(*me, KalecgosGUID))
Kalecgos->AI()->DoAction(DO_ENRAGE);
DoAction(DO_ENRAGE);
}
+
Creature* Kalecgos = Unit::GetCreature(*me, KalecgosGUID);
- if (Kalecgos)
+ if (Kalecgos && !Kalecgos->isInCombat())
{
- if (!Kalecgos->isInCombat())
- {
- me->AI()->EnterEvadeMode();
- return;
- }
+ me->AI()->EnterEvadeMode();
+ return;
}
+
if (!isBanished && HealthBelowPct(1))
{
if (Kalecgos)
@@ -746,8 +746,7 @@ public:
me->DealDamage(me, me->GetHealth());
return;
}
- else
- DoAction(DO_BANISH);
+ DoAction(DO_BANISH);
}
else
{
diff --git a/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/boss_falric.cpp b/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/boss_falric.cpp
index 58dc74d0f0a..9d266c77b77 100644
--- a/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/boss_falric.cpp
+++ b/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/boss_falric.cpp
@@ -19,7 +19,7 @@
#include "ScriptedCreature.h"
#include "halls_of_reflection.h"
-enum Yells
+enum Texts
{
SAY_AGGRO = 0,
SAY_SLAY = 1,
@@ -68,14 +68,14 @@ public:
uiHopelessnessCount = 0;
if (instance)
- instance->SetData(DATA_FALRIC_EVENT, NOT_STARTED);
+ instance->SetBossState(DATA_FALRIC_EVENT, NOT_STARTED);
}
void EnterCombat(Unit* /*who*/)
{
Talk(SAY_AGGRO);
if (instance)
- instance->SetData(DATA_FALRIC_EVENT, IN_PROGRESS);
+ instance->SetBossState(DATA_FALRIC_EVENT, IN_PROGRESS);
events.ScheduleEvent(EVENT_QUIVERING_STRIKE, 23000);
events.ScheduleEvent(EVENT_IMPENDING_DESPAIR, 9000);
@@ -87,7 +87,7 @@ public:
Talk(SAY_DEATH);
if (instance)
- instance->SetData(DATA_FALRIC_EVENT, DONE);
+ instance->SetBossState(DATA_FALRIC_EVENT, DONE);
}
void KilledUnit(Unit* /*victim*/)
diff --git a/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/boss_marwyn.cpp b/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/boss_marwyn.cpp
index 08d5cf70ee1..e82f0d48ebd 100644
--- a/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/boss_marwyn.cpp
+++ b/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/boss_marwyn.cpp
@@ -19,7 +19,7 @@
#include "ScriptedCreature.h"
#include "halls_of_reflection.h"
-enum Yells
+enum Texts
{
SAY_AGGRO = 0,
SAY_SLAY = 1,
@@ -63,14 +63,14 @@ public:
boss_horAI::Reset();
if (instance)
- instance->SetData(DATA_MARWYN_EVENT, NOT_STARTED);
+ instance->SetBossState(DATA_MARWYN_EVENT, NOT_STARTED);
}
void EnterCombat(Unit* /*who*/)
{
Talk(SAY_AGGRO);
if (instance)
- instance->SetData(DATA_MARWYN_EVENT, IN_PROGRESS);
+ instance->SetBossState(DATA_MARWYN_EVENT, IN_PROGRESS);
events.ScheduleEvent(EVENT_OBLITERATE, 30000); /// @todo Check timer
events.ScheduleEvent(EVENT_WELL_OF_CORRUPTION, 13000);
@@ -83,7 +83,7 @@ public:
Talk(SAY_DEATH);
if (instance)
- instance->SetData(DATA_MARWYN_EVENT, DONE);
+ instance->SetBossState(DATA_MARWYN_EVENT, DONE);
}
void KilledUnit(Unit* /*victim*/)
diff --git a/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/halls_of_reflection.cpp b/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/halls_of_reflection.cpp
index b140801d8f1..a64f2cf5467 100644
--- a/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/halls_of_reflection.cpp
+++ b/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/halls_of_reflection.cpp
@@ -18,10 +18,10 @@
#include "ScriptMgr.h"
#include "ScriptedCreature.h"
#include "ScriptedGossip.h"
-#include "halls_of_reflection.h"
#include "Player.h"
+#include "halls_of_reflection.h"
-enum Yells
+enum Text
{
SAY_JAINA_INTRO_1 = 0,
SAY_JAINA_INTRO_2 = 1,
@@ -66,17 +66,19 @@ enum Yells
SAY_LK_INTRO_1 = 0,
SAY_LK_INTRO_2 = 1,
SAY_LK_INTRO_3 = 2,
+ SAY_LK_JAINA_INTRO_END = 3,
+ SAY_LK_SYLVANAS_INTRO_END = 4,
SAY_FALRIC_INTRO_1 = 5,
SAY_FALRIC_INTRO_2 = 6,
- SAY_MARWYN_INTRO_1 = 4
+ SAY_MARWYN_INTRO_1 = 4,
};
enum Events
{
- EVENT_NONE,
-
+ EVENT_WALK_INTRO1 = 1,
+ EVENT_WALK_INTRO2,
EVENT_START_INTRO,
EVENT_SKIP_INTRO,
@@ -125,8 +127,13 @@ enum Events
EVENT_INTRO_LK_7,
EVENT_INTRO_LK_8,
EVENT_INTRO_LK_9,
+ EVENT_INTRO_LK_10,
+ EVENT_INTRO_LK_11,
EVENT_INTRO_END,
+
+ EVENT_OPEN_FROSTWORN_DOOR,
+ EVENT_CLOSE_FROSTWORN_DOOR,
};
enum eEnum
@@ -140,6 +147,17 @@ enum eEnum
QUEST_WRATH_OF_THE_LICH_KING_H2 = 24802,
};
+enum Spells
+{
+ SPELL_CAST_VISUAL = 65633, // Jaina/Sylavana
+ SPELL_BOSS_SPAWN_AURA = 72712, // Falric and Marwyn
+ SPELL_UTHER_DESPAWN = 70693,
+ SPELL_TAKE_FROSTMOURNE = 72729,
+ SPELL_FROSTMOURNE_DESPAWN = 72726,
+ SPELL_FROSTMOURNE_VISUAL = 73220,
+ SPELL_FROSTMOURNE_SOUNDS = 70667,
+};
+
const Position HallsofReflectionLocs[]=
{
{5283.234863f, 1990.946777f, 707.695679f, 0.929097f}, // 2 Loralen Follows
@@ -147,7 +165,7 @@ const Position HallsofReflectionLocs[]=
{5401.866699f, 2110.837402f, 707.695251f, 0.800610f}, // 10 Loralen follows
};
-const Position SpawnPos = {5262.540527f, 1949.693726f, 707.695007f, 0.808736f}; // Jaina/Sylvanas Beginning Position
+const Position IntroPos = {5265.89f, 1952.98f, 707.6978f, 0.0f}; // Jaina/Sylvanas Intro Start Position
const Position MoveThronePos = {5306.952148f, 1998.499023f, 709.341431f, 1.277278f}; // Jaina/Sylvanas walks to throne
const Position UtherSpawnPos = {5308.310059f, 2003.857178f, 709.341431f, 4.650315f};
const Position LichKingSpawnPos = {5362.917480f, 2062.307129f, 707.695374f, 3.945812f};
@@ -156,58 +174,10 @@ const Position LichKingMoveAwayPos = {5400.069824f, 2102.7131689f, 707.69525f,
class npc_jaina_or_sylvanas_hor : public CreatureScript
{
-private:
- bool m_isSylvana;
-
-public:
- npc_jaina_or_sylvanas_hor(bool isSylvana, const char* name) : CreatureScript(name), m_isSylvana(isSylvana) { }
-
- bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action)
- {
- player->PlayerTalkClass->ClearMenus();
- switch (action)
- {
- case GOSSIP_ACTION_INFO_DEF+1:
- player->CLOSE_GOSSIP_MENU();
- if (creature->AI())
- creature->AI()->DoAction(ACTION_START_INTRO);
- creature->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
- break;
- case GOSSIP_ACTION_INFO_DEF+2:
- player->CLOSE_GOSSIP_MENU();
- if (creature->AI())
- creature->AI()->DoAction(ACTION_SKIP_INTRO);
- creature->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
- break;
- }
+ public:
+ npc_jaina_or_sylvanas_hor() : CreatureScript("npc_jaina_or_sylvanas_hor") { }
- return true;
- }
-
- bool OnGossipHello(Player* player, Creature* creature)
- {
- if (creature->isQuestGiver())
- player->PrepareQuestMenu(creature->GetGUID());
-
- QuestStatus status = player->GetQuestStatus(m_isSylvana ? QUEST_DELIVRANCE_FROM_THE_PIT_H2 : QUEST_DELIVRANCE_FROM_THE_PIT_A2);
- if (status == QUEST_STATUS_COMPLETE || status == QUEST_STATUS_REWARDED)
- player->ADD_GOSSIP_ITEM( 0, "Can you remove the sword?", GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1);
-
- // once last quest is completed, she offers this shortcut of the starting event
- status = player->GetQuestStatus(m_isSylvana ? QUEST_WRATH_OF_THE_LICH_KING_H2 : QUEST_WRATH_OF_THE_LICH_KING_A2);
- if (status == QUEST_STATUS_COMPLETE || status == QUEST_STATUS_REWARDED)
- player->ADD_GOSSIP_ITEM( 0, "Dark Lady, I think I hear Arthas coming. Whatever you're going to do, do it quickly.", GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+2);
-
- player->SEND_GOSSIP_MENU(DEFAULT_GOSSIP_MESSAGE, creature->GetGUID());
- return true;
- }
-
- CreatureAI* GetAI(Creature* creature) const
- {
- return new npc_jaina_or_sylvanas_horAI(creature);
- }
-
- // AI of Part1: handle the intro till start of gauntlet event.
+ // AI of Part1
struct npc_jaina_or_sylvanas_horAI : public ScriptedAI
{
npc_jaina_or_sylvanas_horAI(Creature* creature) : ScriptedAI(creature)
@@ -221,6 +191,24 @@ public:
EventMap events;
+ void sGossipSelect(Player* player, uint32 /*sender*/, uint32 action)
+ {
+ player->PlayerTalkClass->ClearMenus();
+ switch (action)
+ {
+ case 0:
+ player->CLOSE_GOSSIP_MENU();
+ events.ScheduleEvent(EVENT_START_INTRO, 1000);
+ me->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP|UNIT_NPC_FLAG_QUESTGIVER);
+ break;
+ case 1:
+ player->CLOSE_GOSSIP_MENU();
+ events.ScheduleEvent(EVENT_SKIP_INTRO, 1000);
+ me->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP|UNIT_NPC_FLAG_QUESTGIVER);
+ break;
+ }
+ }
+
void Reset()
{
events.Reset();
@@ -228,22 +216,9 @@ public:
utherGUID = 0;
lichkingGUID = 0;
- me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
+ me->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP|UNIT_NPC_FLAG_QUESTGIVER);
me->SetStandState(UNIT_STAND_STATE_STAND);
- me->SetVisible(true);
- }
-
- void DoAction(int32 actionId)
- {
- switch (actionId)
- {
- case ACTION_START_INTRO:
- events.ScheduleEvent(EVENT_START_INTRO, 0);
- break;
- case ACTION_SKIP_INTRO:
- events.ScheduleEvent(EVENT_SKIP_INTRO, 0);
- break;
- }
+ events.ScheduleEvent(EVENT_WALK_INTRO1, 3000);
}
void UpdateAI(uint32 diff)
@@ -251,6 +226,26 @@ public:
events.Update(diff);
switch (events.ExecuteEvent())
{
+ case EVENT_WALK_INTRO1:
+ me->GetMotionMaster()->MovePoint(0, IntroPos);
+ if (instance->GetData(DATA_TEAM_IN_INSTANCE) == ALLIANCE)
+ {
+ Talk(SAY_JAINA_INTRO_1);
+ events.ScheduleEvent(EVENT_WALK_INTRO2, 7000);
+ }
+ else
+ {
+ Talk(SAY_SYLVANAS_INTRO_1);
+ events.ScheduleEvent(EVENT_WALK_INTRO2, 9000);
+ }
+ break;
+ case EVENT_WALK_INTRO2:
+ if (instance->GetData(DATA_TEAM_IN_INSTANCE) == ALLIANCE)
+ Talk(SAY_JAINA_INTRO_2);
+ else
+ Talk(SAY_SYLVANAS_INTRO_2);
+ me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP|UNIT_NPC_FLAG_QUESTGIVER);
+ break;
case EVENT_START_INTRO:
me->GetMotionMaster()->MovePoint(0, MoveThronePos);
// Begining of intro is differents between fActions as the speech sequence and timers are differents.
@@ -259,27 +254,25 @@ public:
else
events.ScheduleEvent(EVENT_INTRO_H2_1, 0);
break;
-
- // A2 Intro Events
+ // A2 Intro Events
case EVENT_INTRO_A2_1:
Talk(SAY_JAINA_INTRO_3);
- events.ScheduleEvent(EVENT_INTRO_A2_2, 5000);
+ events.ScheduleEvent(EVENT_INTRO_A2_2, 7000);
break;
case EVENT_INTRO_A2_2:
Talk(SAY_JAINA_INTRO_4);
events.ScheduleEvent(EVENT_INTRO_A2_3, 10000);
break;
case EVENT_INTRO_A2_3:
- /// @todo she's doing some kind of spell casting emote
+ me->CastSpell(me, SPELL_CAST_VISUAL, false);
+ me->CastSpell(me, SPELL_FROSTMOURNE_SOUNDS, true);
instance->HandleGameObject(instance->GetData64(DATA_FROSTMOURNE), true);
events.ScheduleEvent(EVENT_INTRO_A2_4, 10000);
break;
case EVENT_INTRO_A2_4:
- // spawn UTHER during speach 2
if (Creature* uther = me->SummonCreature(NPC_UTHER, UtherSpawnPos, TEMPSUMMON_MANUAL_DESPAWN))
{
uther->GetMotionMaster()->MoveIdle();
- uther->SetReactState(REACT_PASSIVE); // be sure he will not aggro arthas
utherGUID = uther->GetGUID();
}
events.ScheduleEvent(EVENT_INTRO_A2_5, 2000);
@@ -291,57 +284,57 @@ public:
break;
case EVENT_INTRO_A2_6:
Talk(SAY_JAINA_INTRO_5);
- events.ScheduleEvent(EVENT_INTRO_A2_7, 6000);
+ events.ScheduleEvent(EVENT_INTRO_A2_7, 7000);
break;
case EVENT_INTRO_A2_7:
if (Creature* uther = me->GetCreature(*me, utherGUID))
uther->AI()->Talk(SAY_UTHER_INTRO_A2_2);
- events.ScheduleEvent(EVENT_INTRO_A2_8, 6500);
+ events.ScheduleEvent(EVENT_INTRO_A2_8, 7000);
break;
case EVENT_INTRO_A2_8:
Talk(SAY_JAINA_INTRO_6);
- events.ScheduleEvent(EVENT_INTRO_A2_9, 2000);
+ events.ScheduleEvent(EVENT_INTRO_A2_9, 1200);
break;
case EVENT_INTRO_A2_9:
if (Creature* uther = me->GetCreature(*me, utherGUID))
uther->AI()->Talk(SAY_UTHER_INTRO_A2_3);
- events.ScheduleEvent(EVENT_INTRO_A2_10, 9000);
+ events.ScheduleEvent(EVENT_INTRO_A2_10, 11000);
break;
case EVENT_INTRO_A2_10:
Talk(SAY_JAINA_INTRO_7);
- events.ScheduleEvent(EVENT_INTRO_A2_11, 5000);
+ events.ScheduleEvent(EVENT_INTRO_A2_11, 6000);
break;
case EVENT_INTRO_A2_11:
if (Creature* uther = me->GetCreature(*me, utherGUID))
uther->AI()->Talk(SAY_UTHER_INTRO_A2_4);
- events.ScheduleEvent(EVENT_INTRO_A2_12, 11000);
+ events.ScheduleEvent(EVENT_INTRO_A2_12, 12000);
break;
case EVENT_INTRO_A2_12:
Talk(SAY_JAINA_INTRO_8);
- events.ScheduleEvent(EVENT_INTRO_A2_13, 4000);
+ events.ScheduleEvent(EVENT_INTRO_A2_13, 6000);
break;
case EVENT_INTRO_A2_13:
if (Creature* uther = me->GetCreature(*me, utherGUID))
uther->AI()->Talk(SAY_UTHER_INTRO_A2_5);
- events.ScheduleEvent(EVENT_INTRO_A2_14, 12500);
+ events.ScheduleEvent(EVENT_INTRO_A2_14, 13000);
break;
case EVENT_INTRO_A2_14:
Talk(SAY_JAINA_INTRO_9);
- events.ScheduleEvent(EVENT_INTRO_A2_15, 10000);
+ events.ScheduleEvent(EVENT_INTRO_A2_15, 12000);
break;
case EVENT_INTRO_A2_15:
if (Creature* uther = me->GetCreature(*me, utherGUID))
uther->AI()->Talk(SAY_UTHER_INTRO_A2_6);
- events.ScheduleEvent(EVENT_INTRO_A2_16, 22000);
+ events.ScheduleEvent(EVENT_INTRO_A2_16, 25000);
break;
case EVENT_INTRO_A2_16:
if (Creature* uther = me->GetCreature(*me, utherGUID))
uther->AI()->Talk(SAY_UTHER_INTRO_A2_7);
- events.ScheduleEvent(EVENT_INTRO_A2_17, 4000);
+ events.ScheduleEvent(EVENT_INTRO_A2_17, 6000);
break;
case EVENT_INTRO_A2_17:
Talk(SAY_JAINA_INTRO_10);
- events.ScheduleEvent(EVENT_INTRO_A2_18, 2000);
+ events.ScheduleEvent(EVENT_INTRO_A2_18, 5000);
break;
case EVENT_INTRO_A2_18:
if (Creature* uther = me->GetCreature(*me, utherGUID))
@@ -349,14 +342,13 @@ public:
uther->HandleEmoteCommand(EMOTE_ONESHOT_NO);
uther->AI()->Talk(SAY_UTHER_INTRO_A2_8);
}
- events.ScheduleEvent(EVENT_INTRO_A2_19, 11000);
+ events.ScheduleEvent(EVENT_INTRO_A2_19, 12000);
break;
case EVENT_INTRO_A2_19:
Talk(SAY_JAINA_INTRO_11);
- events.ScheduleEvent(EVENT_INTRO_LK_1, 2000);
+ events.ScheduleEvent(EVENT_INTRO_LK_1, 3000);
break;
-
- // H2 Intro Events
+ // H2 Intro Events
case EVENT_INTRO_H2_1:
Talk(SAY_SYLVANAS_INTRO_1);
events.ScheduleEvent(EVENT_INTRO_H2_2, 8000);
@@ -367,7 +359,9 @@ public:
break;
case EVENT_INTRO_H2_3:
Talk(SAY_SYLVANAS_INTRO_3);
- /// @todo she's doing some kind of spell casting emote
+ me->CastSpell(me, SPELL_CAST_VISUAL, false);
+ me->CastSpell(me, SPELL_FROSTMOURNE_SOUNDS, true);
+ instance->HandleGameObject(instance->GetData64(DATA_FROSTMOURNE), true);
events.ScheduleEvent(EVENT_INTRO_H2_4, 6000);
break;
case EVENT_INTRO_H2_4:
@@ -375,7 +369,6 @@ public:
if (Creature* uther = me->SummonCreature(NPC_UTHER, UtherSpawnPos, TEMPSUMMON_MANUAL_DESPAWN))
{
uther->GetMotionMaster()->MoveIdle();
- uther->SetReactState(REACT_PASSIVE); // be sure he will not aggro arthas
utherGUID = uther->GetGUID();
}
events.ScheduleEvent(EVENT_INTRO_H2_5, 2000);
@@ -433,126 +426,159 @@ public:
Talk(SAY_SYLVANAS_INTRO_8);
events.ScheduleEvent(EVENT_INTRO_LK_1, 2000);
break;
-
- // Remaining Intro Events common for both faction
+ // Remaining Intro Events common for both faction
case EVENT_INTRO_LK_1:
// Spawn LK in front of door, and make him move to the sword.
- if (Creature* lichking = me->SummonCreature(NPC_LICH_KING_EVENT, LichKingSpawnPos, TEMPSUMMON_MANUAL_DESPAWN))
+ if (Creature* lichking = me->SummonCreature(NPC_LICH_KING_PART1, LichKingSpawnPos, TEMPSUMMON_MANUAL_DESPAWN))
{
+ lichking->SetUnitMovementFlags(MOVEMENTFLAG_WALKING);
lichking->GetMotionMaster()->MovePoint(0, LichKingMoveThronePos);
- lichking->SetReactState(REACT_PASSIVE);
+ //lichking->SetReactState(REACT_PASSIVE);
lichkingGUID = lichking->GetGUID();
+ events.ScheduleEvent(EVENT_OPEN_FROSTWORN_DOOR, 0);
+ events.ScheduleEvent(EVENT_CLOSE_FROSTWORN_DOOR, 4000);
}
-
if (Creature* uther = me->GetCreature(*me, utherGUID))
{
+ uther->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_COWER);
if (instance->GetData(DATA_TEAM_IN_INSTANCE) == ALLIANCE)
uther->AI()->Talk(SAY_UTHER_INTRO_A2_9);
else
uther->AI()->Talk(SAY_UTHER_INTRO_H2_7);
}
-
- events.ScheduleEvent(EVENT_INTRO_LK_2, 11000);
+ events.ScheduleEvent(EVENT_INTRO_LK_2, 10000);
break;
-
case EVENT_INTRO_LK_2:
- if (Creature* lichking = me->GetCreature(*me, lichkingGUID))
- lichking->AI()->Talk(SAY_LK_INTRO_1);
- events.ScheduleEvent(EVENT_INTRO_LK_3, 2000);
- break;
-
+ if (Creature* lichking = me->GetCreature(*me, lichkingGUID))
+ lichking->AI()->Talk(SAY_LK_INTRO_1);
+ events.ScheduleEvent(EVENT_INTRO_LK_3, 1000);
+ break;
case EVENT_INTRO_LK_3:
- // The Lich King banishes Uther to the abyss.
- if (Creature* uther = me->GetCreature(*me, utherGUID))
- {
- uther->DisappearAndDie();
- utherGUID = 0;
- }
-
- // He steps forward and removes the runeblade from the heap of skulls.
-
- events.ScheduleEvent(EVENT_INTRO_LK_4, 4000);
- break;
-
+ // The Lich King banishes Uther to the abyss.
+ if (Creature* uther = me->GetCreature(*me, utherGUID))
+ {
+ uther->CastSpell(uther, SPELL_UTHER_DESPAWN, true);
+ uther->DespawnOrUnsummon(5000);
+ utherGUID = 0;
+ }
+ events.ScheduleEvent(EVENT_INTRO_LK_4, 9000);
+ break;
case EVENT_INTRO_LK_4:
- if (Creature* lichking = me->GetCreature(*me, lichkingGUID))
- lichking->AI()->Talk(SAY_LK_INTRO_2);
- events.ScheduleEvent(EVENT_INTRO_LK_5, 10000);
+ // He steps forward and removes the runeblade from the heap of skulls.
+ if (Creature* lichking = me->GetCreature(*me, lichkingGUID))
+ {
+ if (GameObject* frostmourne = ObjectAccessor::GetGameObject(*me, instance->GetData64(DATA_FROSTMOURNE)))
+ frostmourne->SetPhaseMask(2, true);
+ lichking->CastSpell(lichking, SPELL_TAKE_FROSTMOURNE, true);
+ lichking->CastSpell(lichking, SPELL_FROSTMOURNE_VISUAL, true);
+ }
+ events.ScheduleEvent(EVENT_INTRO_LK_5, 8000);
break;
-
case EVENT_INTRO_LK_5:
+ if (Creature* lichking = me->GetCreature(*me, lichkingGUID))
+ lichking->AI()->Talk(SAY_LK_INTRO_2);
+ events.ScheduleEvent(EVENT_INTRO_LK_6, 8000);
+ break;
+ case EVENT_INTRO_LK_6:
// summon Falric and Marwyn. then go back to the door
- if (Creature* pFalric = me->GetCreature(*me, instance->GetData64(DATA_FALRIC)))
- pFalric->SetVisible(true);
- if (Creature* pMarwyn = me->GetCreature(*me, instance->GetData64(DATA_MARWYN)))
- pMarwyn->SetVisible(true);
-
+ if (Creature* falric = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_FALRIC_EVENT)))
+ {
+ falric->CastSpell(falric, SPELL_BOSS_SPAWN_AURA, true);
+ falric->SetVisible(true);
+ }
+ if (Creature* marwyn = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_MARWYN_EVENT)))
+ {
+ marwyn->CastSpell(marwyn, SPELL_BOSS_SPAWN_AURA, true);
+ marwyn->SetVisible(true);
+ }
if (Creature* lichking = me->GetCreature(*me, lichkingGUID))
{
- lichking->GetMotionMaster()->MovePoint(0, LichKingSpawnPos);
lichking->AI()->Talk(SAY_LK_INTRO_3);
+ lichking->SetUnitMovementFlags(MOVEMENTFLAG_WALKING);
+ lichking->GetMotionMaster()->MovePoint(0, LichKingMoveAwayPos);
}
-
- events.ScheduleEvent(EVENT_INTRO_LK_6, 8000);
- break;
-
- case EVENT_INTRO_LK_6:
- if (Creature* falric = me->GetCreature(*me, instance->GetData64(DATA_FALRIC)))
- falric->AI()->Talk(SAY_FALRIC_INTRO_1);
-
- events.ScheduleEvent(EVENT_INTRO_LK_7, 2000);
+ events.ScheduleEvent(EVENT_INTRO_LK_7, 10000);
+ events.ScheduleEvent(EVENT_OPEN_FROSTWORN_DOOR, 5000);
break;
-
case EVENT_INTRO_LK_7:
- if (Creature* marwyn = me->GetCreature(*me, instance->GetData64(DATA_MARWYN)))
+ if (Creature* marwyn = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_MARWYN_EVENT)))
marwyn->AI()->Talk(SAY_MARWYN_INTRO_1);
-
- events.ScheduleEvent(EVENT_INTRO_LK_8, 2000);
+ events.ScheduleEvent(EVENT_INTRO_LK_8, 1000);
break;
-
case EVENT_INTRO_LK_8:
- if (Creature* falric = me->GetCreature(*me, instance->GetData64(DATA_FALRIC)))
- falric->AI()->Talk(SAY_FALRIC_INTRO_2);
-
+ if (Creature* falric = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_FALRIC_EVENT)))
+ falric->AI()->Talk(SAY_FALRIC_INTRO_1);
events.ScheduleEvent(EVENT_INTRO_LK_9, 5000);
break;
-
case EVENT_INTRO_LK_9:
+ if (Creature* falric = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_FALRIC_EVENT)))
+ falric->AI()->Talk(SAY_FALRIC_INTRO_2);
+ events.ScheduleEvent(EVENT_INTRO_LK_10, 7000);
+ break;
+ case EVENT_INTRO_LK_10:
if (instance->GetData(DATA_TEAM_IN_INSTANCE) == ALLIANCE)
Talk(SAY_JAINA_INTRO_END);
else
Talk(SAY_SYLVANAS_INTRO_END);
-
- me->GetMotionMaster()->MovePoint(0, LichKingSpawnPos);
+ me->GetMotionMaster()->MovePoint(0, LichKingMoveAwayPos);
/// @todo Loralen/Koreln shall run also
- events.ScheduleEvent(EVENT_INTRO_END, 10000);
+ events.ScheduleEvent(EVENT_INTRO_LK_11, 5000);
+ break;
+ case EVENT_INTRO_LK_11:
+ if (Creature* lichking = me->GetCreature(*me, lichkingGUID))
+ {
+ if (instance->GetData(DATA_TEAM_IN_INSTANCE) == ALLIANCE)
+ lichking->AI()->Talk(SAY_LK_JAINA_INTRO_END);
+ else
+ lichking->AI()->Talk(SAY_LK_SYLVANAS_INTRO_END);
+ }
+ events.ScheduleEvent(EVENT_INTRO_END, 5000);
break;
-
case EVENT_INTRO_END:
if (instance)
- instance->SetData(DATA_WAVE_COUNT, SPECIAL); // start first wave
-
+ {
+ instance->SetData(DATA_INTRO_EVENT, DONE);
+ instance->ProcessEvent(0, EVENT_SPAWN_WAVES);
+ }
// Loralen or Koreln disappearAndDie()
- me->DisappearAndDie();
+ if (Creature* lichking = me->GetCreature(*me, lichkingGUID))
+ {
+ lichking->DespawnOrUnsummon(5000);
+ lichkingGUID = 0;
+ }
+ me->DespawnOrUnsummon(10000);
+ events.ScheduleEvent(EVENT_CLOSE_FROSTWORN_DOOR, 7000);
break;
-
case EVENT_SKIP_INTRO:
- /// @todo implement
-
- if (Creature* pFalric = me->GetCreature(*me, instance->GetData64(DATA_FALRIC)))
- pFalric->SetVisible(true);
- if (Creature* pMarwyn = me->GetCreature(*me, instance->GetData64(DATA_MARWYN)))
- pMarwyn->SetVisible(true);
-
- me->GetMotionMaster()->MovePoint(0, LichKingSpawnPos);
+ me->GetMotionMaster()->MovePoint(0, MoveThronePos);
/// @todo Loralen/Koreln shall run also
-
- events.ScheduleEvent(EVENT_INTRO_END, 15000);
+ if (Creature* lichking = me->SummonCreature(NPC_LICH_KING_PART1, LichKingSpawnPos, TEMPSUMMON_MANUAL_DESPAWN))
+ {
+ lichking->SetUnitMovementFlags(MOVEMENTFLAG_WALKING);
+ lichking->GetMotionMaster()->MovePoint(0, LichKingMoveThronePos);
+ lichking->SetReactState(REACT_PASSIVE);
+ lichkingGUID = lichking->GetGUID();
+ events.ScheduleEvent(EVENT_OPEN_FROSTWORN_DOOR, 0);
+ events.ScheduleEvent(EVENT_CLOSE_FROSTWORN_DOOR, 4000);
+ }
+ events.ScheduleEvent(EVENT_INTRO_LK_4, 15000);
+ break;
+ case EVENT_OPEN_FROSTWORN_DOOR:
+ if (GameObject* gate = ObjectAccessor::GetGameObject(*me, instance->GetData64(DATA_FROSTWORN_DOOR)))
+ instance->HandleGameObject(0 ,true, gate);
+ break;
+ case EVENT_CLOSE_FROSTWORN_DOOR:
+ if (GameObject* gate = ObjectAccessor::GetGameObject(*me, instance->GetData64(DATA_FROSTWORN_DOOR)))
+ instance->HandleGameObject(0 ,false, gate);
break;
}
}
};
+ CreatureAI* GetAI(Creature* creature) const
+ {
+ return new npc_jaina_or_sylvanas_horAI(creature);
+ }
};
enum TrashSpells
@@ -626,27 +652,56 @@ enum TrashEvents
EVENT_ICE_SHOT,
};
-class npc_ghostly_priest : public CreatureScript
+struct npc_gauntlet_trash : public ScriptedAI
{
-public:
- npc_ghostly_priest() : CreatureScript("npc_ghostly_priest") { }
+ npc_gauntlet_trash(Creature* creature) : ScriptedAI(creature),
+ instance(creature->GetInstanceScript())
+ {
+ }
- CreatureAI* GetAI(Creature* creature) const
+ void Reset()
{
- return new npc_ghostly_priestAI(creature);
+ me->CastSpell(me, SPELL_WELL_OF_SOULS, true);
+ events.Reset();
}
- struct npc_ghostly_priestAI: public ScriptedAI
+ void EnterEvadeMode()
{
- npc_ghostly_priestAI(Creature* creature) : ScriptedAI(creature)
- {
- }
+ if (instance->GetData(DATA_WAVE_COUNT) != NOT_STARTED)
+ instance->SetData(DATA_WAVE_COUNT, NOT_STARTED);
+ }
- EventMap events;
+ void SetData(uint32 type, uint32 value)
+ {
+ if (type)
+ return;
- void Reset()
+ InternalWaveId = value;
+ }
+
+ uint32 GetData(uint32 type) const
+ {
+ if (type)
+ return 0;
+
+ return InternalWaveId;
+ }
+
+protected:
+ EventMap events;
+ InstanceScript* instance;
+ uint32 InternalWaveId;
+};
+
+class npc_ghostly_priest : public CreatureScript
+{
+public:
+ npc_ghostly_priest() : CreatureScript("npc_ghostly_priest") { }
+
+ struct npc_ghostly_priestAI : public npc_gauntlet_trash
+ {
+ npc_ghostly_priestAI(Creature* creature) : npc_gauntlet_trash(creature)
{
- events.Reset();
}
void EnterCombat(Unit* /*who*/)
@@ -667,45 +722,46 @@ public:
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
- while (uint32 eventId = events.ExecuteEvent())
+ switch (events.ExecuteEvent())
{
- switch (eventId)
- {
- case EVENT_SHADOW_WORD_PAIN:
- if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM))
- DoCast(target, SPELL_SHADOW_WORD_PAIN);
- events.ScheduleEvent(EVENT_SHADOW_WORD_PAIN, 8000);
- return;
- case EVENT_CIRCLE_OF_DESTRUCTION:
- if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM))
- DoCast(target, SPELL_CIRCLE_OF_DESTRUCTION);
- events.ScheduleEvent(EVENT_CIRCLE_OF_DESTRUCTION, 12000);
- return;
- case EVENT_COWER_IN_FEAR:
- if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM))
- DoCast(target, SPELL_COWER_IN_FEAR);
- events.ScheduleEvent(EVENT_COWER_IN_FEAR, 10000);
- return;
- case EVENT_DARK_MENDING:
- // find an ally with missing HP
- if (Unit* target = DoSelectLowestHpFriendly(40, DUNGEON_MODE(30000, 50000)))
- {
- DoCast(target, SPELL_DARK_MENDING);
- events.ScheduleEvent(EVENT_DARK_MENDING, 20000);
- }
- else
- {
- // no friendly unit with missing hp. re-check in just 5 sec.
- events.ScheduleEvent(EVENT_DARK_MENDING, 5000);
- }
- return;
- }
+ case EVENT_SHADOW_WORD_PAIN:
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM))
+ DoCast(target, SPELL_SHADOW_WORD_PAIN);
+ events.ScheduleEvent(EVENT_SHADOW_WORD_PAIN, 8000);
+ break;
+ case EVENT_CIRCLE_OF_DESTRUCTION:
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM))
+ DoCast(target, SPELL_CIRCLE_OF_DESTRUCTION);
+ events.ScheduleEvent(EVENT_CIRCLE_OF_DESTRUCTION, 12000);
+ break;
+ case EVENT_COWER_IN_FEAR:
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM))
+ DoCast(target, SPELL_COWER_IN_FEAR);
+ events.ScheduleEvent(EVENT_COWER_IN_FEAR, 10000);
+ break;
+ case EVENT_DARK_MENDING:
+ // find an ally with missing HP
+ if (Unit* target = DoSelectLowestHpFriendly(40, DUNGEON_MODE(30000, 50000)))
+ {
+ DoCast(target, SPELL_DARK_MENDING);
+ events.ScheduleEvent(EVENT_DARK_MENDING, 20000);
+ }
+ else
+ {
+ // no friendly unit with missing hp. re-check in just 5 sec.
+ events.ScheduleEvent(EVENT_DARK_MENDING, 5000);
+ }
+ break;
}
DoMeleeAttackIfReady();
}
};
+ CreatureAI* GetAI(Creature* creature) const
+ {
+ return new npc_ghostly_priestAI(creature);
+ }
};
class npc_phantom_mage : public CreatureScript
@@ -713,22 +769,10 @@ class npc_phantom_mage : public CreatureScript
public:
npc_phantom_mage() : CreatureScript("npc_phantom_mage") { }
- CreatureAI* GetAI(Creature* creature) const
- {
- return new npc_phantom_mageAI(creature);
- }
-
- struct npc_phantom_mageAI: public ScriptedAI
+ struct npc_phantom_mageAI : public npc_gauntlet_trash
{
- npc_phantom_mageAI(Creature* creature) : ScriptedAI(creature)
- {
- }
-
- EventMap events;
-
- void Reset()
+ npc_phantom_mageAI(Creature* creature) : npc_gauntlet_trash(creature)
{
- events.Reset();
}
void EnterCombat(Unit* /*who*/)
@@ -750,39 +794,40 @@ public:
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
- while (uint32 eventId = events.ExecuteEvent())
+ switch (events.ExecuteEvent())
{
- switch (eventId)
- {
- case EVENT_FIREBALL:
- if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM))
- DoCast(target, SPELL_FIREBALL);
- events.ScheduleEvent(EVENT_FIREBALL, 15000);
- return;
- case EVENT_FLAMESTRIKE:
- DoCast(SPELL_FLAMESTRIKE);
- events.ScheduleEvent(EVENT_FLAMESTRIKE, 15000);
- return;
- case EVENT_FROSTBOLT:
- if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM))
- DoCast(target, SPELL_FROSTBOLT);
- events.ScheduleEvent(EVENT_FROSTBOLT, 15000);
- return;
- case EVENT_CHAINS_OF_ICE:
- if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM))
- DoCast(target, SPELL_CHAINS_OF_ICE);
- events.ScheduleEvent(EVENT_CHAINS_OF_ICE, 15000);
- return;
- case EVENT_HALLUCINATION:
- DoCast(SPELL_HALLUCINATION);
- return;
- }
+ case EVENT_FIREBALL:
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM))
+ DoCast(target, SPELL_FIREBALL);
+ events.ScheduleEvent(EVENT_FIREBALL, 15000);
+ break;
+ case EVENT_FLAMESTRIKE:
+ DoCast(SPELL_FLAMESTRIKE);
+ events.ScheduleEvent(EVENT_FLAMESTRIKE, 15000);
+ break;
+ case EVENT_FROSTBOLT:
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM))
+ DoCast(target, SPELL_FROSTBOLT);
+ events.ScheduleEvent(EVENT_FROSTBOLT, 15000);
+ break;
+ case EVENT_CHAINS_OF_ICE:
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM))
+ DoCast(target, SPELL_CHAINS_OF_ICE);
+ events.ScheduleEvent(EVENT_CHAINS_OF_ICE, 15000);
+ break;
+ case EVENT_HALLUCINATION:
+ DoCast(SPELL_HALLUCINATION);
+ break;
}
DoMeleeAttackIfReady();
}
};
+ CreatureAI* GetAI(Creature* creature) const
+ {
+ return new npc_phantom_mageAI(creature);
+ }
};
class npc_phantom_hallucination : public CreatureScript
@@ -790,16 +835,9 @@ class npc_phantom_hallucination : public CreatureScript
public:
npc_phantom_hallucination() : CreatureScript("npc_phantom_hallucination") { }
- CreatureAI* GetAI(Creature* creature) const
- {
- return new npc_phantom_hallucinationAI(creature);
- }
-
struct npc_phantom_hallucinationAI : public npc_phantom_mage::npc_phantom_mageAI
{
- npc_phantom_hallucinationAI(Creature* creature) : npc_phantom_mage::npc_phantom_mageAI(creature)
- {
- }
+ npc_phantom_hallucinationAI(Creature* creature) : npc_phantom_mage::npc_phantom_mageAI(creature) {}
void JustDied(Unit* /*killer*/)
{
@@ -807,6 +845,10 @@ public:
}
};
+ CreatureAI* GetAI(Creature* creature) const
+ {
+ return new npc_phantom_hallucinationAI(creature);
+ }
};
class npc_shadowy_mercenary : public CreatureScript
@@ -814,22 +856,10 @@ class npc_shadowy_mercenary : public CreatureScript
public:
npc_shadowy_mercenary() : CreatureScript("npc_shadowy_mercenary") { }
- CreatureAI* GetAI(Creature* creature) const
+ struct npc_shadowy_mercenaryAI : public npc_gauntlet_trash
{
- return new npc_shadowy_mercenaryAI(creature);
- }
-
- struct npc_shadowy_mercenaryAI: public ScriptedAI
- {
- npc_shadowy_mercenaryAI(Creature* creature) : ScriptedAI(creature)
- {
- }
-
- EventMap events;
-
- void Reset()
+ npc_shadowy_mercenaryAI(Creature* creature) : npc_gauntlet_trash(creature)
{
- events.Reset();
}
void EnterCombat(Unit* /*who*/)
@@ -850,34 +880,35 @@ public:
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
- while (uint32 eventId = events.ExecuteEvent())
+ switch (events.ExecuteEvent())
{
- switch (eventId)
- {
- case EVENT_SHADOW_STEP:
- DoCast(SPELL_SHADOW_STEP);
- events.ScheduleEvent(EVENT_SHADOW_STEP, 8000);
- return;
- case EVENT_DEADLY_POISON:
- DoCast(me->getVictim(), SPELL_DEADLY_POISON);
- events.ScheduleEvent(EVENT_DEADLY_POISON, 10000);
- return;
- case EVENT_ENVENOMED_DAGGER_THROW:
- if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM))
- DoCast(target, SPELL_ENVENOMED_DAGGER_THROW);
- events.ScheduleEvent(EVENT_ENVENOMED_DAGGER_THROW, 10000);
- return;
- case EVENT_KIDNEY_SHOT:
- DoCast(me->getVictim(), SPELL_KIDNEY_SHOT);
- events.ScheduleEvent(EVENT_KIDNEY_SHOT, 10000);
- return;
- }
+ case EVENT_SHADOW_STEP:
+ DoCast(SPELL_SHADOW_STEP);
+ events.ScheduleEvent(EVENT_SHADOW_STEP, 8000);
+ break;
+ case EVENT_DEADLY_POISON:
+ DoCast(me->getVictim(), SPELL_DEADLY_POISON);
+ events.ScheduleEvent(EVENT_DEADLY_POISON, 10000);
+ break;
+ case EVENT_ENVENOMED_DAGGER_THROW:
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM))
+ DoCast(target, SPELL_ENVENOMED_DAGGER_THROW);
+ events.ScheduleEvent(EVENT_ENVENOMED_DAGGER_THROW, 10000);
+ break;
+ case EVENT_KIDNEY_SHOT:
+ DoCast(me->getVictim(), SPELL_KIDNEY_SHOT);
+ events.ScheduleEvent(EVENT_KIDNEY_SHOT, 10000);
+ break;
}
DoMeleeAttackIfReady();
}
};
+ CreatureAI* GetAI(Creature* creature) const
+ {
+ return new npc_shadowy_mercenaryAI(creature);
+ }
};
class npc_spectral_footman : public CreatureScript
@@ -885,29 +916,176 @@ class npc_spectral_footman : public CreatureScript
public:
npc_spectral_footman() : CreatureScript("npc_spectral_footman") { }
+ struct npc_spectral_footmanAI : public npc_gauntlet_trash
+ {
+ npc_spectral_footmanAI(Creature* creature) : npc_gauntlet_trash(creature)
+ {
+ }
+
+ void EnterCombat(Unit* /*who*/)
+ {
+ events.ScheduleEvent(EVENT_SPECTRAL_STRIKE, 5000); /// @todo adjust timers
+ events.ScheduleEvent(EVENT_SHIELD_BASH, 10000);
+ events.ScheduleEvent(EVENT_TORTURED_ENRAGE, 15000);
+ }
+
+ void UpdateAI(uint32 diff)
+ {
+ if (!UpdateVictim())
+ return;
+
+ events.Update(diff);
+
+ if (me->HasUnitState(UNIT_STATE_CASTING))
+ return;
+
+ switch (events.ExecuteEvent())
+ {
+ case EVENT_SPECTRAL_STRIKE:
+ DoCast(me->getVictim(), SPELL_SPECTRAL_STRIKE);
+ events.ScheduleEvent(EVENT_SPECTRAL_STRIKE, 5000);
+ break;
+ case EVENT_SHIELD_BASH:
+ DoCast(me->getVictim(), SPELL_SHIELD_BASH);
+ events.ScheduleEvent(EVENT_SHIELD_BASH, 5000);
+ break;
+ case EVENT_TORTURED_ENRAGE:
+ DoCast(SPELL_TORTURED_ENRAGE);
+ events.ScheduleEvent(EVENT_TORTURED_ENRAGE, 15000);
+ break;
+ }
+
+ DoMeleeAttackIfReady();
+ }
+ };
+
CreatureAI* GetAI(Creature* creature) const
{
return new npc_spectral_footmanAI(creature);
}
+};
+
+class npc_tortured_rifleman : public CreatureScript
+{
+public:
+ npc_tortured_rifleman() : CreatureScript("npc_tortured_rifleman") { }
- struct npc_spectral_footmanAI: public ScriptedAI
+ struct npc_tortured_riflemanAI : public npc_gauntlet_trash
{
- npc_spectral_footmanAI(Creature* creature) : ScriptedAI(creature)
+ npc_tortured_riflemanAI(Creature* creature) : npc_gauntlet_trash(creature)
{
}
+ void EnterCombat(Unit* /*who*/)
+ {
+ events.ScheduleEvent(EVENT_SHOOT, 2000); /// @todo adjust timers
+ events.ScheduleEvent(EVENT_CURSED_ARROW, 10000);
+ events.ScheduleEvent(EVENT_FROST_TRAP, 1000);
+ events.ScheduleEvent(EVENT_ICE_SHOT, 15000);
+ }
+
+ void UpdateAI(uint32 diff)
+ {
+ if (!UpdateVictim())
+ return;
+
+ events.Update(diff);
+
+ if (me->HasUnitState(UNIT_STATE_CASTING))
+ return;
+
+ switch (events.ExecuteEvent())
+ {
+ case EVENT_SHOOT:
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM))
+ DoCast(target, SPELL_SHOOT);
+ events.ScheduleEvent(EVENT_SHOOT, 2000);
+ break;
+ case EVENT_CURSED_ARROW:
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM))
+ DoCast(target, SPELL_CURSED_ARROW);
+ events.ScheduleEvent(EVENT_CURSED_ARROW, 10000);
+ break;
+ case EVENT_FROST_TRAP:
+ DoCast(SPELL_FROST_TRAP);
+ events.ScheduleEvent(EVENT_FROST_TRAP, 30000);
+ break;
+ case EVENT_ICE_SHOT:
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM))
+ DoCast(target, SPELL_ICE_SHOT);
+ events.ScheduleEvent(EVENT_ICE_SHOT, 15000);
+ break;
+ }
+
+ DoMeleeAttackIfReady();
+ }
+ };
+
+ CreatureAI* GetAI(Creature* creature) const
+ {
+ return new npc_tortured_riflemanAI(creature);
+ }
+};
+
+
+enum GeneralEvents
+{
+ //General
+ EVENT_SHIELD = 0,
+ EVENT_SPIKE = 1,
+ EVENT_CLONE = 2,
+
+ SAY_AGGRO = 0,
+ SAY_DEATH = 1,
+
+ SPELL_SHIELD_THROWN = 69222, // 73076 on hc
+ SPELL_SPIKE = 69184, // 70399 on hc
+ SPELL_CLONE_NAME = 57507,
+ SPELL_CLONE_MODEL = 45204,
+
+ // Reflection
+ EVENT_BALEFUL_STRIKE = 0,
+
+ SPELL_BALEFUL_STRIKE = 69933, // 70400 on hc
+ SPELL_SPIRIT_BURST = 69900, // 73046 on hc
+};
+
+class npc_frostworn_general : public CreatureScript
+{
+public:
+ npc_frostworn_general() : CreatureScript("npc_frostworn_general") { }
+
+ struct npc_frostworn_generalAI : public ScriptedAI
+ {
+ npc_frostworn_generalAI(Creature* creature) : ScriptedAI(creature)
+ {
+ instance = me->GetInstanceScript();
+ Reset();
+ }
+
+ InstanceScript* instance;
+
EventMap events;
void Reset()
{
events.Reset();
+ instance->SetData(DATA_FROSWORN_EVENT, NOT_STARTED);
}
- void EnterCombat(Unit* /*who*/)
+ void JustDied(Unit* /*killer*/)
{
- events.ScheduleEvent(EVENT_SPECTRAL_STRIKE, 5000); /// @todo adjust timers
- events.ScheduleEvent(EVENT_SHIELD_BASH, 10000);
- events.ScheduleEvent(EVENT_TORTURED_ENRAGE, 15000);
+ Talk(SAY_DEATH);
+ instance->SetData(DATA_FROSWORN_EVENT, DONE);
+ }
+
+ void EnterCombat(Unit* /*victim*/)
+ {
+ Talk(SAY_AGGRO);
+ events.ScheduleEvent(EVENT_SHIELD, 5000);
+ events.ScheduleEvent(EVENT_SPIKE, 14000);
+ events.ScheduleEvent(EVENT_CLONE, 22000);
+ instance->SetData(DATA_FROSWORN_EVENT, IN_PROGRESS);
}
void UpdateAI(uint32 diff)
@@ -920,45 +1098,61 @@ public:
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
- while (uint32 eventId = events.ExecuteEvent())
+ switch (events.ExecuteEvent())
{
- switch (eventId)
- {
- case EVENT_SPECTRAL_STRIKE:
- DoCast(me->getVictim(), SPELL_SPECTRAL_STRIKE);
- events.ScheduleEvent(EVENT_SPECTRAL_STRIKE, 5000);
- return;
- case EVENT_SHIELD_BASH:
- DoCast(me->getVictim(), SPELL_SHIELD_BASH);
- events.ScheduleEvent(EVENT_SHIELD_BASH, 5000);
- return;
- case EVENT_TORTURED_ENRAGE:
- DoCast(SPELL_TORTURED_ENRAGE);
- events.ScheduleEvent(EVENT_TORTURED_ENRAGE, 15000);
- return;
- }
+ case EVENT_SHIELD:
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
+ DoCast(target, SPELL_SHIELD_THROWN);
+ events.ScheduleEvent(EVENT_SHIELD, urand(8000, 12000));
+ break;
+ case EVENT_SPIKE:
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
+ DoCast(target, SPELL_SPIKE);
+ events.ScheduleEvent(EVENT_SPIKE, urand(15000, 20000));
+ break;
+ case EVENT_CLONE:
+ SummonClones();
+ events.ScheduleEvent(EVENT_CLONE, 60000);
+ break;
}
DoMeleeAttackIfReady();
}
- };
-};
+ void SummonClones()
+ {
+ std::list<Unit *> playerList;
+ SelectTargetList(playerList, 5, SELECT_TARGET_TOPAGGRO, 0, true);
+ for (std::list<Unit*>::const_iterator itr = playerList.begin(); itr != playerList.end(); ++itr)
+ {
+ Unit* temp = (*itr);
+ Creature* reflection = me->SummonCreature(NPC_REFLECTION, temp->GetPositionX(), temp->GetPositionY(), temp->GetPositionZ(), temp->GetOrientation(), TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 3000);
+ reflection->SetName(temp->GetName());
+ temp->CastSpell(reflection, SPELL_CLONE_NAME, true);
+ temp->CastSpell(reflection, SPELL_CLONE_MODEL, true);
+ reflection->setFaction(me->getFaction());
+ reflection->AI()->AttackStart(temp);
+ }
-class npc_tortured_rifleman : public CreatureScript
-{
-public:
- npc_tortured_rifleman() : CreatureScript("npc_tortured_rifleman") { }
+ }
+ };
CreatureAI* GetAI(Creature* creature) const
{
- return new npc_tortured_riflemanAI(creature);
+ return new npc_frostworn_generalAI(creature);
}
+};
+
+class npc_spiritual_reflection : public CreatureScript
+{
+public:
+ npc_spiritual_reflection() : CreatureScript("npc_spiritual_reflection") { }
- struct npc_tortured_riflemanAI : public ScriptedAI
+ struct npc_spiritual_reflectionAI : public ScriptedAI
{
- npc_tortured_riflemanAI(Creature* creature) : ScriptedAI(creature)
+ npc_spiritual_reflectionAI(Creature *creature) : ScriptedAI(creature)
{
+ Reset();
}
EventMap events;
@@ -968,12 +1162,14 @@ public:
events.Reset();
}
- void EnterCombat(Unit* /*who*/)
+ void EnterCombat(Unit* /*victim*/)
{
- events.ScheduleEvent(EVENT_SHOOT, 2000); /// @todo adjust timers
- events.ScheduleEvent(EVENT_CURSED_ARROW, 10000);
- events.ScheduleEvent(EVENT_FROST_TRAP, 1000);
- events.ScheduleEvent(EVENT_ICE_SHOT, 15000);
+ events.ScheduleEvent(EVENT_BALEFUL_STRIKE, 3000);
+ }
+
+ void JustDied(Unit* killer)
+ {
+ DoCast(killer, SPELL_SPIRIT_BURST);
}
void UpdateAI(uint32 diff)
@@ -986,46 +1182,90 @@ public:
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
- while (uint32 eventId = events.ExecuteEvent())
+ switch (events.ExecuteEvent())
{
- switch (eventId)
- {
- case EVENT_SHOOT:
- if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM))
- DoCast(target, SPELL_SHOOT);
- events.ScheduleEvent(EVENT_SHOOT, 2000);
- return;
- case EVENT_CURSED_ARROW:
- if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM))
- DoCast(target, SPELL_CURSED_ARROW);
- events.ScheduleEvent(EVENT_CURSED_ARROW, 10000);
- return;
- case EVENT_FROST_TRAP:
- DoCast(SPELL_FROST_TRAP);
- events.ScheduleEvent(EVENT_FROST_TRAP, 30000);
- return;
- case EVENT_ICE_SHOT:
- if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM))
- DoCast(target, SPELL_ICE_SHOT);
- events.ScheduleEvent(EVENT_ICE_SHOT, 15000);
- return;
- }
+ case EVENT_BALEFUL_STRIKE:
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
+ DoCast(target, SPELL_BALEFUL_STRIKE);
+ events.ScheduleEvent(EVENT_BALEFUL_STRIKE, urand(3000, 8000));
}
DoMeleeAttackIfReady();
}
};
+ CreatureAI* GetAI(Creature* creature) const
+ {
+ return new npc_spiritual_reflectionAI(creature);
+ }
+};
+
+class at_hor_intro_start : public AreaTriggerScript
+{
+public:
+ at_hor_intro_start() : AreaTriggerScript("at_hor_intro_start") {}
+
+ bool OnTrigger(Player* player, AreaTriggerEntry const* /*trigger*/)
+ {
+ InstanceScript* instance = player->GetInstanceScript();
+
+ if (player->isGameMaster())
+ return true;
+
+ if (instance->GetData(DATA_INTRO_EVENT) == NOT_STARTED)
+ {
+ instance->SetData(DATA_INTRO_EVENT, IN_PROGRESS);
+ }
+
+ return true;
+ }
+};
+
+class at_hor_waves_restarter : public AreaTriggerScript
+{
+public:
+ at_hor_waves_restarter() : AreaTriggerScript("at_hor_waves_restarter") {}
+
+ bool OnTrigger(Player* player, AreaTriggerEntry const* /*trigger*/)
+ {
+ InstanceScript* instance = player->GetInstanceScript();
+
+ if (player->isGameMaster())
+ return true;
+
+ if (instance->GetData(DATA_WAVE_COUNT))
+ return true;
+
+ if (instance->GetData(DATA_INTRO_EVENT) == DONE && instance->GetBossState(DATA_MARWYN_EVENT) != DONE)
+ {
+ instance->ProcessEvent(0, EVENT_SPAWN_WAVES);
+
+ if (Creature* falric = player->GetCreature(*player, instance->GetData64(DATA_FALRIC_EVENT)))
+ {
+ falric->CastSpell(falric, SPELL_BOSS_SPAWN_AURA, true);
+ falric->SetVisible(true);
+ }
+ if (Creature* marwyn = player->GetCreature(*player, instance->GetData64(DATA_MARWYN_EVENT)))
+ {
+ marwyn->CastSpell(marwyn, SPELL_BOSS_SPAWN_AURA, true);
+ marwyn->SetVisible(true);
+ }
+ }
+ return true;
+ }
};
void AddSC_halls_of_reflection()
{
- new npc_jaina_or_sylvanas_hor(true, "npc_sylvanas_hor_part1");
- new npc_jaina_or_sylvanas_hor(false, "npc_jaina_hor_part1");
+ new npc_jaina_or_sylvanas_hor();
new npc_ghostly_priest();
new npc_phantom_mage();
new npc_phantom_hallucination();
new npc_shadowy_mercenary();
new npc_spectral_footman();
new npc_tortured_rifleman();
+ new at_hor_intro_start();
+ new at_hor_waves_restarter();
+ new npc_frostworn_general();
+ new npc_spiritual_reflection();
}
diff --git a/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/halls_of_reflection.h b/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/halls_of_reflection.h
index 2cab1cca214..4787a6b9fdc 100644
--- a/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/halls_of_reflection.h
+++ b/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/halls_of_reflection.h
@@ -18,54 +18,83 @@
#ifndef DEF_HALLS_OF_REFLECTION_H
#define DEF_HALLS_OF_REFLECTION_H
-enum Data
-{
- DATA_FALRIC_EVENT,
- DATA_MARWYN_EVENT,
- DATA_LICHKING_EVENT,
- DATA_WAVE_COUNT,
- DATA_TEAM_IN_INSTANCE,
-};
+#define HoRScriptName "instance_halls_of_reflection"
+#define MAX_ENCOUNTER 3
-enum Data64
+/* Halls of Reflection encounters:
+0- Falric
+1- Marwyn
+2- The Lich King
+*/
+
+enum Data
{
- DATA_FALRIC,
- DATA_MARWYN,
- DATA_LICHKING,
- DATA_FROSTMOURNE,
+ DATA_FALRIC_EVENT = 0,
+ DATA_MARWYN_EVENT = 1,
+ DATA_LICHKING_EVENT = 2,
+ DATA_INTRO_EVENT = 3,
+ DATA_FROSWORN_EVENT = 4,
+
+ DATA_WAVE_COUNT = 5,
+ DATA_TEAM_IN_INSTANCE = 6,
+ DATA_FROSTMOURNE = 7,
+ DATA_FROSTWORN_DOOR = 8,
};
enum Creatures
{
- NPC_FALRIC = 38112,
- NPC_MARWYN = 38113,
- NPC_LICH_KING_EVENT = 37226,
- NPC_LICH_KING_BOSS = 36954,
-
- NPC_UTHER = 37225,
NPC_JAINA_PART1 = 37221,
- NPC_JAINA_PART2 = 36955,
NPC_SYLVANAS_PART1 = 37223,
- NPC_SYLVANAS_PART2 = 37554,
+ NPC_UTHER = 37225,
+ NPC_LICH_KING_PART1 = 37226,
+ NPC_LORALEN = 37779,
+ NPC_KORELN = 37582,
+ NPC_FALRIC = 38112,
+ NPC_MARWYN = 38113,
NPC_WAVE_MERCENARY = 38177,
NPC_WAVE_FOOTMAN = 38173,
NPC_WAVE_RIFLEMAN = 38176,
NPC_WAVE_PRIEST = 38175,
NPC_WAVE_MAGE = 38172,
+
+ NPC_FROSTWORN_GENERAL = 36723,
+ NPC_REFLECTION = 37068, // 37107 for tank only?
+
+ NPC_JAINA_PART2 = 36955,
+ NPC_SYLVANAS_PART2 = 37554,
+ NPC_LICH_KING_PART2 = 36954,
+ NPC_BARTLETT = 37182, // High Captain Justin Bartlett
+ NPC_KORM = 37833, // Sky-Reaver Korm Blackscar
+ NPC_ICE_WALL = 37014, // Ice Wall Target
};
enum GameObjects
{
GO_FROSTMOURNE = 202302,
- GO_FROSTMOURNE_ALTAR = 202236,
- GO_FRONT_DOOR = 201976,
- GO_ARTHAS_DOOR = 197341,
+ GO_ENTRANCE_DOOR = 201976,
+ GO_FROSTWORN_DOOR = 197341,
+ GO_ARTHAS_DOOR = 197342,
+ //GO_ESCAPE_DOOR = 197343, // always open ?
+
+ GO_ICE_WALL = 201385,
+ GO_CAVE = 201596,
+
+ GO_STAIRS_SKYBREAKER = 201709,
+ GO_SKYBREAKER = 201598,
+ GO_STAIRS_ORGRIM_HAMMER = 202211,
+ GO_ORGRIM_HAMMER = 201599,
+ GO_PORTAL = 202079,
+
+ GO_CAPTAIN_CHEST_1 = 202212, //3145
+ GO_CAPTAIN_CHEST_2 = 201710, //30357
+ GO_CAPTAIN_CHEST_3 = 202337, //3246
+ GO_CAPTAIN_CHEST_4 = 202336, //3333
};
enum HorWorldStates
{
- WORLD_STATE_HOR = 4884,
+ WORLD_STATE_HOR_WAVES_ENABLED = 4884,
WORLD_STATE_HOR_WAVE_COUNT = 4882,
};
@@ -75,6 +104,21 @@ enum Actions
ACTION_ENTER_COMBAT,
};
+enum TrashGeneralSpells
+{
+ // General spells
+ SPELL_WELL_OF_SOULS = 72630, // cast when spawn(become visible)
+ SPELL_SPIRIT_ACTIVATE = 72130, // cast when unit activates
+};
+
+enum InstanceEvents
+{
+ EVENT_SPAWN_WAVES = 1,
+ EVENT_NEXT_WAVE = 2,
+ EVENT_DO_WIPE = 3,
+ EVENT_ADD_WAVE = 4,
+};
+
// Base class for FALRIC and MARWYN
// handled the summonList and the notification events to/from the InstanceScript
struct boss_horAI : ScriptedAI
@@ -92,14 +136,10 @@ struct boss_horAI : ScriptedAI
{
events.Reset();
me->SetVisible(false);
- me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE|UNIT_FLAG_NOT_SELECTABLE);
+ me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC|UNIT_FLAG_IMMUNE_TO_NPC);
me->SetReactState(REACT_PASSIVE);
- }
-
- void DamageTaken(Unit* /*who*/, uint32 &uiDamage)
- {
- if (me->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE))
- uiDamage = 0;
+ if (instance->GetData(DATA_WAVE_COUNT) != NOT_STARTED)
+ instance->ProcessEvent(0, EVENT_DO_WIPE);
}
void DoAction(int32 actionID)
@@ -107,11 +147,7 @@ struct boss_horAI : ScriptedAI
switch (actionID)
{
case ACTION_ENTER_COMBAT: // called by InstanceScript when boss shall enter in combat.
- // Just in case. Should have been done by InstanceScript
- me->SetVisible(true);
-
- // Reset flags
- me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE|UNIT_FLAG_NOT_SELECTABLE);
+ me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC|UNIT_FLAG_IMMUNE_TO_NPC);
me->SetReactState(REACT_AGGRESSIVE);
if (Unit* unit = me->SelectNearestTarget())
@@ -125,32 +161,6 @@ struct boss_horAI : ScriptedAI
void JustSummoned(Creature* summoned)
{
summons.Summon(summoned);
-
- if (Unit* target = summoned->SelectNearestTarget())
- {
- if (summoned->AI())
- summoned->AI()->AttackStart(target);
- else
- {
- summoned->GetMotionMaster()->MoveChase(target);
- summoned->Attack(target, true);
- }
- }
-
- if (summoned->AI())
- summoned->AI()->DoZoneInCombat();
- }
-
- void SummonedCreatureDespawn(Creature* summoned)
- {
- summons.Despawn(summoned);
- if (summons.empty())
- {
- if (summoned->isAlive())
- instance->SetData(DATA_WAVE_COUNT, NOT_STARTED);
- else
- instance->SetData(DATA_WAVE_COUNT, SPECIAL);
- }
}
};
diff --git a/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/instance_halls_of_reflection.cpp b/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/instance_halls_of_reflection.cpp
index dde3f7acc67..bff18b508d5 100644
--- a/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/instance_halls_of_reflection.cpp
+++ b/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/instance_halls_of_reflection.cpp
@@ -18,85 +18,50 @@
#include "ScriptMgr.h"
#include "ScriptedCreature.h"
#include "InstanceScript.h"
-#include "halls_of_reflection.h"
#include "Player.h"
+#include "WorldPacket.h"
+#include "halls_of_reflection.h"
-#define MAX_ENCOUNTER 3
-
-/* Halls of Reflection encounters:
-0- Falric
-1- Marwyn
-2- The Lich King
-*/
-
-enum eEnum
-{
- ENCOUNTER_WAVE_MERCENARY = 6,
- ENCOUNTER_WAVE_FOOTMAN = 10,
- ENCOUNTER_WAVE_RIFLEMAN = 6,
- ENCOUNTER_WAVE_PRIEST = 6,
- ENCOUNTER_WAVE_MAGE = 6,
-};
-
-enum Events
-{
- EVENT_NONE,
- EVENT_NEXT_WAVE,
- EVENT_START_LICH_KING,
-};
-
-static Position PriestSpawnPos[ENCOUNTER_WAVE_PRIEST] =
-{
- {5277.74f, 2016.88f, 707.778f, 5.96903f},
- {5295.88f, 2040.34f, 707.778f, 5.07891f},
- {5320.37f, 1980.13f, 707.778f, 2.00713f},
- {5280.51f, 1997.84f, 707.778f, 0.296706f},
- {5302.45f, 2042.22f, 707.778f, 4.90438f},
- {5306.57f, 1977.47f, 707.778f, 1.50098f},
-};
-
-static Position MageSpawnPos[ENCOUNTER_WAVE_MAGE] =
-{
- {5312.75f, 2037.12f, 707.778f, 4.59022f},
- {5309.58f, 2042.67f, 707.778f, 4.69494f},
- {5275.08f, 2008.72f, 707.778f, 6.21337f},
- {5279.65f, 2004.66f, 707.778f, 0.069813f},
- {5275.48f, 2001.14f, 707.778f, 0.174533f},
- {5316.7f, 2041.55f, 707.778f, 4.50295f},
-};
-
-static Position MercenarySpawnPos[ENCOUNTER_WAVE_MERCENARY] =
-{
- {5302.25f, 1972.41f, 707.778f, 1.37881f},
- {5311.03f, 1972.23f, 707.778f, 1.64061f},
- {5277.36f, 1993.23f, 707.778f, 0.401426f},
- {5318.7f, 2036.11f, 707.778f, 4.2237f},
- {5335.72f, 1996.86f, 707.778f, 2.74017f},
- {5299.43f, 1979.01f, 707.778f, 1.23918f},
-};
+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
+Position const GeneralSpawnPos = {5415.538f, 2117.842f, 707.7781f, 3.944444f}; // Frostsworn General
-static Position FootmenSpawnPos[ENCOUNTER_WAVE_FOOTMAN] =
+Position const SpawnPos[] =
{
- {5306.06f, 2037, 707.778f, 4.81711f},
- {5344.15f, 2007.17f, 707.778f, 3.15905f},
- {5337.83f, 2010.06f, 707.778f, 3.22886f},
- {5343.29f, 1999.38f, 707.778f, 2.9147f},
- {5340.84f, 1992.46f, 707.778f, 2.75762f},
- {5325.07f, 1977.6f, 707.778f, 2.07694f},
- {5336.6f, 2017.28f, 707.778f, 3.47321f},
- {5313.82f, 1978.15f, 707.778f, 1.74533f},
- {5280.63f, 2012.16f, 707.778f, 6.05629f},
- {5322.96f, 2040.29f, 707.778f, 4.34587f},
-};
-
-static Position RiflemanSpawnPos[ENCOUNTER_WAVE_RIFLEMAN] =
-{
- {5343.47f, 2015.95f, 707.778f, 3.49066f},
- {5337.86f, 2003.4f, 707.778f, 2.98451f},
- {5319.16f, 1974, 707.778f, 1.91986f},
- {5299.25f, 2036, 707.778f, 5.02655f},
- {5295.64f, 1973.76f, 707.778f, 1.18682f},
- {5282.9f, 2019.6f, 707.778f, 5.88176f},
+ {5309.577f, 2042.668f, 707.7781f, 4.694936f},
+ {5295.885f, 2040.342f, 707.7781f, 5.078908f},
+ {5340.836f, 1992.458f, 707.7781f, 2.757620f},
+ {5325.072f, 1977.597f, 707.7781f, 2.076942f},
+ {5277.365f, 1993.229f, 707.7781f, 0.401426f},
+ {5275.479f, 2001.135f, 707.7781f, 0.174533f},
+ {5302.448f, 2042.222f, 707.7781f, 4.904375f},
+ {5343.293f, 1999.384f, 707.7781f, 2.914700f},
+ {5295.635f, 1973.757f, 707.7781f, 1.186824f},
+ {5311.031f, 1972.229f, 707.7781f, 1.640610f},
+ {5275.076f, 2008.724f, 707.7781f, 6.213372f},
+ {5316.701f, 2041.550f, 707.7781f, 4.502949f},
+ {5344.150f, 2007.168f, 707.7781f, 3.159046f},
+ {5319.158f, 1973.998f, 707.7781f, 1.919862f},
+ {5302.247f, 1972.415f, 707.7781f, 1.378810f},
+ {5277.739f, 2016.882f, 707.7781f, 5.969026f},
+ {5322.964f, 2040.288f, 707.7781f, 4.345870f},
+ {5343.467f, 2015.951f, 707.7781f, 3.490659f},
+ {5313.820f, 1978.146f, 707.7781f, 1.745329f},
+ {5279.649f, 2004.656f, 707.7781f, 0.069814f},
+ {5306.057f, 2037.002f, 707.7781f, 4.817109f},
+ {5337.865f, 2003.403f, 707.7781f, 2.984513f},
+ {5299.434f, 1979.009f, 707.7781f, 1.239184f},
+ {5312.752f, 2037.122f, 707.7781f, 4.590216f},
+ {5335.724f, 1996.859f, 707.7781f, 2.740167f},
+ {5280.632f, 2012.156f, 707.7781f, 6.056293f},
+ {5320.369f, 1980.125f, 707.7781f, 2.007129f},
+ {5306.572f, 1977.474f, 707.7781f, 1.500983f},
+ {5336.599f, 2017.278f, 707.7781f, 3.473205f},
+ {5282.897f, 2019.597f, 707.7781f, 5.881760f},
+ {5318.704f, 2036.108f, 707.7781f, 4.223697f},
+ {5280.513f, 1997.842f, 707.7781f, 0.296706f},
+ {5337.833f, 2010.057f, 707.7781f, 3.228859f},
+ {5299.250f, 2035.998f, 707.7781f, 5.026548f},
};
class instance_halls_of_reflection : public InstanceMapScript
@@ -104,107 +69,107 @@ class instance_halls_of_reflection : public InstanceMapScript
public:
instance_halls_of_reflection() : InstanceMapScript("instance_halls_of_reflection", 668) { }
- InstanceScript* GetInstanceScript(InstanceMap* map) const
- {
- return new instance_halls_of_reflection_InstanceMapScript(map);
- }
-
struct instance_halls_of_reflection_InstanceMapScript : public InstanceScript
{
- instance_halls_of_reflection_InstanceMapScript(Map* map) : InstanceScript(map) {};
-
- uint64 uiFalric;
- uint64 uiMarwyn;
- uint64 uiLichKingEvent;
- uint64 uiJainaPart1;
- uint64 uiSylvanasPart1;
-
- uint64 uiFrostmourne;
- uint64 uiFrostmourneAltar;
- uint64 uiArthasDoor;
- uint64 uiFrontDoor;
-
- uint32 uiEncounter[MAX_ENCOUNTER];
- uint32 uiTeamInInstance;
- uint32 uiWaveCount;
- bool bIntroDone;
-
- EventMap events;
+ instance_halls_of_reflection_InstanceMapScript(Map* map) : InstanceScript(map) {}
void Initialize()
{
+ SetBossNumber(MAX_ENCOUNTER);
events.Reset();
+ _falricGUID = 0;
+ _marwynGUID = 0;
+ _jainaOrSylvanasPart1GUID = 0;
+ _frostwornGeneralGUID = 0;
+ _frostmourneGUID = 0;
+ _entranceDoorGUID = 0;
+ _frostwornDoorGUID = 0;
+ _arthasDoorGUID = 0;
+ _teamInInstance = 0;
+ _waveCount = 0;
+ _introEvent = NOT_STARTED;
+ _frostwornGeneral = NOT_STARTED;
+ }
- uiFalric = 0;
- uiMarwyn = 0;
- uiLichKingEvent = 0;
- uiJainaPart1 = 0;
- uiSylvanasPart1 = 0;
-
- uiFrostmourne = 0;
- uiFrostmourneAltar = 0;
- uiArthasDoor = 0;
- uiFrontDoor = 0;
- uiTeamInInstance = 0;
- uiWaveCount = 0;
- bIntroDone = false;
-
- for (uint8 i = 0; i < MAX_ENCOUNTER; ++i)
- uiEncounter[i] = NOT_STARTED;
+ void OnPlayerEnter(Player* player)
+ {
+ if (!_teamInInstance)
+ _teamInInstance = player->GetTeam();
}
void OnCreatureCreate(Creature* creature)
{
- Map::PlayerList const &players = instance->GetPlayers();
+ Map::PlayerList const& players = instance->GetPlayers();
if (!players.isEmpty())
if (Player* player = players.begin()->getSource())
- uiTeamInInstance = player->GetTeam();
+ _teamInInstance = player->GetTeam();
switch (creature->GetEntry())
{
+ case NPC_JAINA_PART1:
+ case NPC_SYLVANAS_PART1:
+ _jainaOrSylvanasPart1GUID = creature->GetGUID();
+ break;
case NPC_FALRIC:
- uiFalric = creature->GetGUID();
+ _falricGUID = creature->GetGUID();
break;
case NPC_MARWYN:
- uiMarwyn = creature->GetGUID();
- break;
- case NPC_LICH_KING_EVENT:
- uiLichKingEvent = creature->GetGUID();
+ _marwynGUID = creature->GetGUID();
break;
- case NPC_JAINA_PART1:
- uiJainaPart1 = creature->GetGUID();
+ case NPC_FROSTWORN_GENERAL:
+ _frostwornGeneralGUID = creature->GetGUID();
+ if (GetBossState(DATA_MARWYN_EVENT) == DONE)
+ if (Creature* general = instance->GetCreature(_frostwornGeneralGUID))
+ general->SetPhaseMask(1, true);
break;
- case NPC_SYLVANAS_PART1:
- uiSylvanasPart1 = creature->GetGUID();
+ }
+ }
+
+ void OnCreatureRemove(Creature* creature)
+ {
+ switch (creature->GetEntry())
+ {
+ case NPC_WAVE_MERCENARY:
+ case NPC_WAVE_FOOTMAN:
+ case NPC_WAVE_RIFLEMAN:
+ case NPC_WAVE_PRIEST:
+ case NPC_WAVE_MAGE:
+ {
+ uint32 internalWaveId = creature->AI()->GetData(0);
+ waveGuidList[internalWaveId].erase(creature->GetGUID());
break;
+ }
}
}
void OnGameObjectCreate(GameObject* go)
{
- /// @todo init state depending on encounters
switch (go->GetEntry())
{
case GO_FROSTMOURNE:
- uiFrostmourne = go->GetGUID();
+ _frostmourneGUID = go->GetGUID();
go->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_INTERACT_COND);
HandleGameObject(0, false, go);
+ if (GetData(DATA_INTRO_EVENT) == DONE)
+ go->SetPhaseMask(2, true);
break;
- case GO_FROSTMOURNE_ALTAR:
- uiFrostmourneAltar = go->GetGUID();
+ case GO_ENTRANCE_DOOR:
+ _entranceDoorGUID = go->GetGUID();
go->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_INTERACT_COND);
HandleGameObject(0, true, go);
break;
- case GO_FRONT_DOOR:
- uiFrontDoor = go->GetGUID();
+ case GO_FROSTWORN_DOOR:
+ _frostwornDoorGUID = go->GetGUID();
go->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_INTERACT_COND);
- HandleGameObject(0, true, go);
+ if (GetBossState(DATA_MARWYN_EVENT) == DONE)
+ HandleGameObject(0, true, go);
+ else
+ HandleGameObject(0, false, go);
break;
case GO_ARTHAS_DOOR:
- uiArthasDoor = go->GetGUID();
+ _arthasDoorGUID = go->GetGUID();
go->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_INTERACT_COND);
-
- if (uiEncounter[1] == DONE)
+ if (GetBossState(DATA_FROSWORN_EVENT) == DONE)
HandleGameObject(0, true, go);
else
HandleGameObject(0, false, go);
@@ -212,61 +177,273 @@ public:
}
}
- void SetData(uint32 type, uint32 data)
+ void FillInitialWorldStates(WorldPacket& data)
{
- if (type == DATA_WAVE_COUNT && data == SPECIAL)
- {
- bIntroDone = true;
- events.ScheduleEvent(EVENT_NEXT_WAVE, 10000);
- return;
- }
+ data << uint32(WORLD_STATE_HOR_WAVES_ENABLED) << uint32(0);
+ data << uint32(WORLD_STATE_HOR_WAVE_COUNT) << uint32(0);
+ }
- if (uiWaveCount && data == NOT_STARTED)
- DoWipe();
+ bool SetBossState(uint32 type, EncounterState state)
+ {
+ if (!InstanceScript::SetBossState(type, state))
+ return false;
switch (type)
{
case DATA_FALRIC_EVENT:
- uiEncounter[0] = data;
- if (data == DONE)
+ if (state == DONE)
+ {
+ ++_waveCount;
events.ScheduleEvent(EVENT_NEXT_WAVE, 60000);
+ }
break;
case DATA_MARWYN_EVENT:
- uiEncounter[1] = data;
- if (data == DONE)
- HandleGameObject(uiArthasDoor, true);
+ if (state == DONE)
+ {
+ HandleGameObject(_entranceDoorGUID, true);
+ HandleGameObject(_frostwornDoorGUID, true);
+ if (Creature* general = instance->GetCreature(_frostwornGeneralGUID))
+ general->SetPhaseMask(1, true);
+ }
break;
case DATA_LICHKING_EVENT:
- uiEncounter[2] = data;
break;
+ default:
+ break;
+ }
+
+ return true;
+ }
+
+ void SetData(uint32 type, uint32 data)
+ {
+ switch (type)
+ {
+ case DATA_INTRO_EVENT:
+ if (data == IN_PROGRESS)
+ {
+ if (!_introEvent)
+ {
+ if (_teamInInstance == ALLIANCE)
+ instance->SummonCreature(NPC_JAINA_PART1, JainaSpawnPos);
+ else
+ instance->SummonCreature(NPC_SYLVANAS_PART1, SylvanasSpawnPos);
+ }
+ }
+ _introEvent = data;
+ break;
+ case DATA_WAVE_COUNT:
+ if (_waveCount && data == NOT_STARTED)
+ ProcessEvent(NULL, EVENT_DO_WIPE);
+ break;
+ case DATA_FROSWORN_EVENT:
+ if (data == DONE)
+ {
+ HandleGameObject(_arthasDoorGUID, true);
+ // spawn Jaina part 2
+ // spawn LK part 2
+ }
+ _frostwornGeneral = data;
+ break;
+ }
+
+ SaveToDB();
+ }
+
+
+ // wave scheduling,checked when wave npcs die
+ void OnUnitDeath(Unit* unit)
+ {
+ Creature* creature = unit->ToCreature();
+ if (!creature)
+ return;
+
+ switch (creature->GetEntry())
+ {
+ case NPC_WAVE_MERCENARY:
+ case NPC_WAVE_FOOTMAN:
+ case NPC_WAVE_RIFLEMAN:
+ case NPC_WAVE_PRIEST:
+ case NPC_WAVE_MAGE:
+ {
+ uint32 deadNpcs = 0;
+ uint32 waveId = creature->AI()->GetData(0);
+ for (std::set<uint64>::const_iterator itr = waveGuidList[waveId].begin(); itr != waveGuidList[waveId].end(); ++itr)
+ {
+ Creature* npc = instance->GetCreature(*itr);
+ if (!npc || !npc->isAlive())
+ ++deadNpcs;
+ }
+
+ // because the current npc returns isAlive when OnUnitDeath happens
+ // we check if the number of dead npcs is equal to the list-1
+ if (deadNpcs == waveGuidList[waveId].size() - 1)
+ {
+ ++_waveCount;
+ events.ScheduleEvent(EVENT_NEXT_WAVE, 10000);
+ }
+ break;
+ }
}
+ }
+
+ void Update(uint32 diff)
+ {
+ if (!instance->HavePlayers())
+ return;
- if (data == DONE)
- SaveToDB();
+ events.Update(diff);
+
+ switch (events.ExecuteEvent())
+ {
+ case EVENT_NEXT_WAVE:
+ ProcessEvent(NULL, EVENT_ADD_WAVE);
+ break;
+ }
+ }
+
+ void ProcessEvent(WorldObject* /*go*/, uint32 eventId)
+ {
+ switch (eventId)
+ {
+ // spawning all wave npcs at once
+ case EVENT_SPAWN_WAVES:
+ _waveCount = 1;
+ DoUpdateWorldState(WORLD_STATE_HOR_WAVES_ENABLED, 1);
+ DoUpdateWorldState(WORLD_STATE_HOR_WAVE_COUNT, _waveCount);
+ {
+ std::list<uint32> possibilityList, tempList;
+ uint32 posIndex = 0;
+
+ possibilityList.push_back(NPC_WAVE_MERCENARY);
+ possibilityList.push_back(NPC_WAVE_FOOTMAN);
+ possibilityList.push_back(NPC_WAVE_RIFLEMAN);
+ possibilityList.push_back(NPC_WAVE_PRIEST);
+ possibilityList.push_back(NPC_WAVE_MAGE);
+
+ // iterate each wave
+ for (uint8 i = 0; i < 8; ++i)
+ {
+ tempList = possibilityList;
+
+ uint64 bossGuid = i <= 3 ? _falricGUID : _marwynGUID;
+
+ if (!i)
+ Trinity::Containers::RandomResizeList(tempList, 3);
+ else if (i < 6 && i != 3)
+ Trinity::Containers::RandomResizeList(tempList, 4);
+
+ for (std::list<uint32>::const_iterator itr = tempList.begin(); itr != tempList.end(); ++itr)
+ {
+ if (Creature* boss = instance->GetCreature(bossGuid))
+ {
+ if (Creature* temp = boss->SummonCreature(*itr, SpawnPos[posIndex], TEMPSUMMON_DEAD_DESPAWN))
+ {
+ temp->AI()->SetData(0, i);
+ waveGuidList[i].insert(temp->GetGUID());
+ }
+ }
+
+ ++posIndex;
+ }
+ }
+ }
+ events.ScheduleEvent(EVENT_NEXT_WAVE, 10000);
+ break;
+ case EVENT_ADD_WAVE:
+ DoUpdateWorldState(WORLD_STATE_HOR_WAVES_ENABLED, 1);
+ DoUpdateWorldState(WORLD_STATE_HOR_WAVE_COUNT, _waveCount);
+ HandleGameObject(_entranceDoorGUID, false);
+
+ if (_waveCount % 5)
+ {
+ uint32 internalWaveId = _waveCount - ((_waveCount < 5) ? 1 : 2);
+ for (std::set<uint64>::const_iterator itr = waveGuidList[internalWaveId].begin(); itr != waveGuidList[internalWaveId].end(); ++itr)
+ {
+ if (Creature* temp = instance->GetCreature(*itr))
+ {
+ temp->CastSpell(temp, SPELL_SPIRIT_ACTIVATE, true);
+ temp->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC|UNIT_FLAG_IMMUNE_TO_NPC|UNIT_FLAG_NOT_SELECTABLE);
+ temp->AI()->DoZoneInCombat();
+ }
+ }
+ }
+ else
+ {
+ uint32 bossIndex = (_waveCount / 5) - 1;
+ if (GetBossState(DATA_FALRIC_EVENT + bossIndex) != DONE)
+ {
+ if (Creature* boss = instance->GetCreature(bossIndex ? _marwynGUID : _falricGUID))
+ if (boss->AI())
+ boss->AI()->DoAction(ACTION_ENTER_COMBAT);
+ }
+ else if (_waveCount != 10)
+ {
+ ++_waveCount;
+ events.ScheduleEvent(EVENT_NEXT_WAVE, 10000);
+ }
+ }
+ break;
+ case EVENT_DO_WIPE:
+ _waveCount = 0;
+ events.Reset();
+ DoUpdateWorldState(WORLD_STATE_HOR_WAVES_ENABLED, 1);
+ DoUpdateWorldState(WORLD_STATE_HOR_WAVE_COUNT, _waveCount);
+ HandleGameObject(_entranceDoorGUID, true);
+
+ if (Creature* falric = instance->GetCreature(_falricGUID))
+ falric->SetVisible(false);
+ if (Creature* marwyn = instance->GetCreature(_marwynGUID))
+ marwyn->SetVisible(false);
+
+ //despawn wave npcs
+ for (uint8 i = 0; i < 8; ++i)
+ {
+ for (std::set<uint64>::const_iterator itr = waveGuidList[i].begin(); itr != waveGuidList[i].end(); ++itr)
+ if (Creature* creature = instance->GetCreature(*itr))
+ creature->DespawnOrUnsummon(1);
+
+ waveGuidList[i].clear();
+ }
+ break;
+ }
}
uint32 GetData(uint32 type) const
{
switch (type)
{
- case DATA_FALRIC_EVENT: return uiEncounter[0];
- case DATA_MARWYN_EVENT: return uiEncounter[1];
- case DATA_LICHKING_EVENT: return uiEncounter[2];
- case DATA_WAVE_COUNT: return uiWaveCount;
- case DATA_TEAM_IN_INSTANCE: return uiTeamInInstance;
+ case DATA_WAVE_COUNT:
+ return _waveCount;
+ case DATA_TEAM_IN_INSTANCE:
+ return _teamInInstance;
+ case DATA_INTRO_EVENT:
+ return _introEvent;
+ case DATA_FROSWORN_EVENT:
+ return _frostwornGeneral;
+ default:
+ break;
}
return 0;
}
- uint64 GetData64(uint32 identifier) const
+ uint64 GetData64(uint32 type) const
{
- switch (identifier)
+ switch (type)
{
- case DATA_FALRIC: return uiFalric;
- case DATA_MARWYN: return uiMarwyn;
- case DATA_LICHKING: return uiLichKingEvent;
- case DATA_FROSTMOURNE: return uiFrostmourne;
+ case DATA_FALRIC_EVENT:
+ return _falricGUID;
+ case DATA_MARWYN_EVENT:
+ return _marwynGUID;
+ case DATA_FROSWORN_EVENT:
+ return _frostwornGeneralGUID;
+ case DATA_FROSTWORN_DOOR:
+ return _frostwornDoorGUID;
+ case DATA_FROSTMOURNE:
+ return _frostmourneGUID;
+ default:
+ break;
}
return 0;
@@ -277,13 +454,13 @@ public:
OUT_SAVE_INST_DATA;
std::ostringstream saveStream;
- saveStream << "H R 1 " << uiEncounter[0] << ' ' << uiEncounter[1] << ' ' << uiEncounter[2];
+ saveStream << "H R " << GetBossSaveData() << _introEvent << ' ' << _frostwornGeneral;
OUT_SAVE_INST_DATA_COMPLETE;
return saveStream.str();
}
- void Load(const char* in)
+ void Load(char const* in)
{
if (!in)
{
@@ -294,135 +471,67 @@ public:
OUT_LOAD_INST_DATA(in);
char dataHead1, dataHead2;
- uint16 version;
- uint16 data0, data1, data2;
std::istringstream loadStream(in);
- loadStream >> dataHead1 >> dataHead2 >> version >> data0 >> data1 >> data2;
+ loadStream >> dataHead1 >> dataHead2;
if (dataHead1 == 'H' && dataHead2 == 'R')
{
- uiEncounter[0] = data0;
- uiEncounter[1] = data1;
- uiEncounter[2] = data2;
-
for (uint8 i = 0; i < MAX_ENCOUNTER; ++i)
- if (uiEncounter[i] == IN_PROGRESS)
- uiEncounter[i] = NOT_STARTED;
-
- } else OUT_LOAD_INST_DATA_FAIL;
-
- if (uiEncounter[0] == DONE || uiEncounter[1] == DONE)
- bIntroDone = true;
-
- OUT_LOAD_INST_DATA_COMPLETE;
- }
-
- void AddWave()
- {
- DoUpdateWorldState(WORLD_STATE_HOR, 1);
- DoUpdateWorldState(WORLD_STATE_HOR_WAVE_COUNT, uiWaveCount);
-
- switch (uiWaveCount)
- {
- case 1:
- case 2:
- case 3:
- case 4:
- if (Creature* pFalric = instance->GetCreature(uiFalric))
- SpawnWave(pFalric);
- break;
- case 5:
- if (GetData(DATA_FALRIC_EVENT) == DONE)
- events.ScheduleEvent(EVENT_NEXT_WAVE, 10000);
- else if (Creature* pFalric = instance->GetCreature(uiFalric))
- if (pFalric->AI())
- pFalric->AI()->DoAction(ACTION_ENTER_COMBAT);
- break;
- case 6:
- case 7:
- case 8:
- case 9:
- if (Creature* pMarwyn = instance->GetCreature(uiMarwyn))
- SpawnWave(pMarwyn);
- break;
- case 10:
- if (GetData(DATA_MARWYN_EVENT) != DONE) // wave should not have been started if DONE. Check anyway to avoid bug exploit!
- if (Creature* pMarwyn = instance->GetCreature(uiMarwyn))
- if (pMarwyn->AI())
- pMarwyn->AI()->DoAction(ACTION_ENTER_COMBAT);
- break;
+ {
+ uint32 tmpState;
+ loadStream >> tmpState;
+ if (tmpState == IN_PROGRESS || tmpState > SPECIAL)
+ tmpState = NOT_STARTED;
+
+ SetBossState(i, EncounterState(tmpState));
+ }
+
+ uint32 temp = 0;
+ loadStream >> temp;
+ if (temp == DONE)
+ SetData(DATA_INTRO_EVENT, DONE);
+ else
+ SetData(DATA_INTRO_EVENT, NOT_STARTED);
+
+ loadStream >> temp;
+ if (temp == DONE)
+ SetData(DATA_FROSWORN_EVENT, DONE);
+ else
+ SetData(DATA_FROSWORN_EVENT, NOT_STARTED);
}
- }
+ else
+ OUT_LOAD_INST_DATA_FAIL;
- // Wipe has been detected. Perform cleanup and reset.
- void DoWipe()
- {
- uiWaveCount = 0;
- events.Reset();
- DoUpdateWorldState(WORLD_STATE_HOR, 1);
- DoUpdateWorldState(WORLD_STATE_HOR_WAVE_COUNT, uiWaveCount);
- HandleGameObject(uiFrontDoor, true);
-
- /// @todo
- // in case of wipe, the event is normally restarted by jumping into the center of the room.
- // As I can't find a trigger area there, just respawn Jaina/Sylvanas so the event may be restarted.
- if (Creature* pJaina = instance->GetCreature(uiJainaPart1))
- pJaina->Respawn();
- if (Creature* pSylvanas = instance->GetCreature(uiSylvanasPart1))
- pSylvanas->Respawn();
-
- if (Creature* pFalric = instance->GetCreature(uiFalric))
- pFalric->SetVisible(false);
- if (Creature* pMarwyn = instance->GetCreature(uiMarwyn))
- pMarwyn->SetVisible(false);
+ OUT_LOAD_INST_DATA_COMPLETE;
}
- // spawn a wave on behalf of the summoner.
- void SpawnWave(Creature* summoner)
- {
- uint32 index;
-
- summoner->SetVisible(true);
-
- /// @todo do composition at random. # of spawn also depends on uiWaveCount
- // As of now, it is just one of each.
- index = urand(0, ENCOUNTER_WAVE_MERCENARY-1);
- summoner->SummonCreature(NPC_WAVE_MERCENARY, MercenarySpawnPos[index], TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 0);
-
- index = urand(0, ENCOUNTER_WAVE_FOOTMAN-1);
- summoner->SummonCreature(NPC_WAVE_FOOTMAN, FootmenSpawnPos[index], TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 0);
-
- index = urand(0, ENCOUNTER_WAVE_RIFLEMAN-1);
- summoner->SummonCreature(NPC_WAVE_RIFLEMAN, RiflemanSpawnPos[index], TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 0);
+ private:
+ uint64 _falricGUID;
+ uint64 _marwynGUID;
+ uint64 _jainaOrSylvanasPart1GUID;
+ uint64 _frostwornGeneralGUID;
- index = urand(0, ENCOUNTER_WAVE_PRIEST-1);
- summoner->SummonCreature(NPC_WAVE_PRIEST, PriestSpawnPos[index], TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 0);
+ uint64 _frostmourneGUID;
+ uint64 _entranceDoorGUID;
+ uint64 _frostwornDoorGUID;
+ uint64 _arthasDoorGUID;
+ uint64 _escapeDoorGUID;
- index = urand(0, ENCOUNTER_WAVE_MAGE-1);
- summoner->SummonCreature(NPC_WAVE_MAGE, MageSpawnPos[index], TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 0);
- }
-
- void Update(uint32 diff)
- {
- if (!instance->HavePlayers())
- return;
+ uint32 _teamInInstance;
+ uint32 _waveCount;
+ uint32 _introEvent;
+ uint32 _frostwornGeneral;
- events.Update(diff);
+ EventMap events;
- switch (events.ExecuteEvent())
- {
- case EVENT_NEXT_WAVE:
- uiWaveCount++;
- AddWave();
- break;
- case EVENT_START_LICH_KING:
- /// @todo
- break;
- }
- }
+ std::set<uint64> waveGuidList[8];
};
+ InstanceScript* GetInstanceScript(InstanceMap* map) const
+ {
+ return new instance_halls_of_reflection_InstanceMapScript(map);
+ }
};
void AddSC_instance_halls_of_reflection()
diff --git a/src/server/scripts/Northrend/Gundrak/gundrak.h b/src/server/scripts/Northrend/Gundrak/gundrak.h
index 0c65b4d16de..a43edb4fcd7 100644
--- a/src/server/scripts/Northrend/Gundrak/gundrak.h
+++ b/src/server/scripts/Northrend/Gundrak/gundrak.h
@@ -43,12 +43,31 @@ enum Data64
enum mainCreatures
{
- CREATURE_RUIN_DWELLER = 29920,
- CREATURE_SLAD_RAN = 29304,
- CREATURE_MOORABI = 29305,
- CREATURE_GALDARAH = 29306,
- CREATURE_DRAKKARICOLOSSUS = 29307,
- CREATURE_ECK = 29932
+ CREATURE_RUIN_DWELLER = 29920,
+ CREATURE_SLAD_RAN = 29304,
+ CREATURE_MOORABI = 29305,
+ CREATURE_GALDARAH = 29306,
+ CREATURE_DRAKKARICOLOSSUS = 29307,
+ CREATURE_ECK = 29932
+};
+
+enum Gameobjects {
+
+ GO_SLADRAN_ALTAR = 192518,
+ GO_MOORABI_ALTAR = 192519,
+ GO_DRAKKARI_COLOSSUS_ALTAR = 192520,
+ GO_SLADRAN_STATUE = 192564,
+ GO_MOORABI_STATUE = 192565,
+ GO_GALDARAH_STATUE = 192566,
+ GO_DRAKKARI_COLOSSUS_STATUE = 192567,
+ GO_ECK_THE_FEROCIOUS_DOOR = 192632,
+ GO_ECK_THE_FEROCIOUS_DOOR_BEHIND = 192569,
+ GO_GALDARAH_DOOR1 = 193208,
+ GO_GALDARAH_DOOR2 = 193209,
+ GO_GALDARAH_DOOR3 = 192568,
+ GO_BRIDGE = 193188,
+ GO_COLLISION = 192633
+
};
#endif
diff --git a/src/server/scripts/Northrend/Gundrak/instance_gundrak.cpp b/src/server/scripts/Northrend/Gundrak/instance_gundrak.cpp
index a9bbffa5fb0..d17198b0c92 100644
--- a/src/server/scripts/Northrend/Gundrak/instance_gundrak.cpp
+++ b/src/server/scripts/Northrend/Gundrak/instance_gundrak.cpp
@@ -45,44 +45,45 @@ public:
{
instance_gundrak_InstanceMapScript(Map* map) : InstanceScript(map)
{
- bHeroicMode = map->IsHeroic();
+ isHeroic = map->IsHeroic();
}
- bool bHeroicMode;
+ bool isHeroic;
bool spawnSupport;
uint32 timer;
uint32 phase;
uint64 toActivate;
- uint64 uiSladRan;
- uint64 uiMoorabi;
- uint64 uiDrakkariColossus;
- uint64 uiGalDarah;
- uint64 uiEckTheFerocious;
-
- uint64 uiSladRanAltar;
- uint64 uiMoorabiAltar;
- uint64 uiDrakkariColossusAltar;
- uint64 uiSladRanStatue;
- uint64 uiMoorabiStatue;
- uint64 uiDrakkariColossusStatue;
- uint64 uiGalDarahStatue;
- uint64 uiEckTheFerociousDoor;
- uint64 uiEckTheFerociousDoorBehind;
- uint64 uiGalDarahDoor1;
- uint64 uiGalDarahDoor2;
- uint64 uiBridge;
- uint64 uiCollision;
+ uint64 sladRanGUID;
+ uint64 moorabiGUID;
+ uint64 drakkariColossusGUID;
+ uint64 galDarahGUID;
+ uint64 eckTheFerociousGUID;
+
+ uint64 sladRanAltarGUID;
+ uint64 moorabiAltarGUID;
+ uint64 drakkariColossusAltarGUID;
+ uint64 sladRanStatueGUID;
+ uint64 moorabiStatueGUID;
+ uint64 drakkariColossusStatueGUID;
+ uint64 galDarahStatueGUID;
+ uint64 eckTheFerociousDoorGUID;
+ uint64 eckTheFerociousDoorBehindGUID;
+ uint64 galDarahDoor1GUID;
+ uint64 galDarahDoor2GUID;
+ uint64 galDarahDoor3GUID;
+ uint64 bridgeGUID;
+ uint64 collisionGUID;
uint32 m_auiEncounter[MAX_ENCOUNTER];
- GOState uiSladRanStatueState;
- GOState uiMoorabiStatueState;
- GOState uiDrakkariColossusStatueState;
- GOState uiGalDarahStatueState;
- GOState uiBridgeState;
- GOState uiCollisionState;
+ GOState sladRanStatueState;
+ GOState moorabiStatueState;
+ GOState drakkariColossusStatueState;
+ GOState galDarahStatueState;
+ GOState bridgeState;
+ GOState collisionState;
std::set<uint64> DwellerGUIDs;
@@ -96,35 +97,36 @@ public:
phase = 0;
toActivate = 0;
- uiSladRan = 0;
- uiMoorabi = 0;
- uiDrakkariColossus = 0;
- uiGalDarah = 0;
- uiEckTheFerocious = 0;
-
- uiSladRanAltar = 0;
- uiMoorabiAltar = 0;
- uiDrakkariColossusAltar = 0;
-
- uiSladRanStatue = 0;
- uiMoorabiStatue = 0;
- uiDrakkariColossusStatue = 0;
- uiGalDarahStatue = 0;
-
- uiEckTheFerociousDoor = 0;
- uiEckTheFerociousDoorBehind = 0;
- uiGalDarahDoor1 = 0;
- uiGalDarahDoor2 = 0;
-
- uiBridge = 0;
- uiCollision = 0;
-
- uiSladRanStatueState = GO_STATE_ACTIVE;
- uiMoorabiStatueState = GO_STATE_ACTIVE;
- uiDrakkariColossusStatueState = GO_STATE_ACTIVE;
- uiGalDarahStatueState = GO_STATE_READY;
- uiBridgeState = GO_STATE_ACTIVE;
- uiCollisionState = GO_STATE_READY;
+ sladRanGUID = 0;
+ moorabiGUID = 0;
+ drakkariColossusGUID = 0;
+ galDarahGUID = 0;
+ eckTheFerociousGUID = 0;
+
+ sladRanAltarGUID = 0;
+ moorabiAltarGUID = 0;
+ drakkariColossusAltarGUID = 0;
+
+ sladRanStatueGUID = 0;
+ moorabiStatueGUID = 0;
+ drakkariColossusStatueGUID = 0;
+ galDarahStatueGUID = 0;
+
+ eckTheFerociousDoorGUID = 0;
+ eckTheFerociousDoorBehindGUID = 0;
+ galDarahDoor1GUID = 0;
+ galDarahDoor2GUID = 0;
+ galDarahDoor3GUID = 0;
+
+ bridgeGUID = 0;
+ collisionGUID = 0;
+
+ sladRanStatueState = GO_STATE_ACTIVE;
+ moorabiStatueState = GO_STATE_ACTIVE;
+ drakkariColossusStatueState = GO_STATE_ACTIVE;
+ galDarahStatueState = GO_STATE_READY;
+ bridgeState = GO_STATE_ACTIVE;
+ collisionState = GO_STATE_READY;
DwellerGUIDs.clear();
@@ -144,11 +146,21 @@ public:
{
switch (creature->GetEntry())
{
- case CREATURE_SLAD_RAN: uiSladRan = creature->GetGUID(); break;
- case CREATURE_MOORABI: uiMoorabi = creature->GetGUID(); break;
- case CREATURE_GALDARAH: uiGalDarah = creature->GetGUID(); break;
- case CREATURE_DRAKKARICOLOSSUS: uiDrakkariColossus = creature->GetGUID(); break;
- case CREATURE_ECK: uiEckTheFerocious = creature->GetGUID(); break;
+ case CREATURE_SLAD_RAN:
+ sladRanGUID = creature->GetGUID();
+ break;
+ case CREATURE_MOORABI:
+ moorabiGUID = creature->GetGUID();
+ break;
+ case CREATURE_GALDARAH:
+ galDarahGUID = creature->GetGUID();
+ break;
+ case CREATURE_DRAKKARICOLOSSUS:
+ drakkariColossusGUID = creature->GetGUID();
+ break;
+ case CREATURE_ECK:
+ eckTheFerociousGUID = creature->GetGUID();
+ break;
case CREATURE_RUIN_DWELLER:
if (creature->isAlive())
DwellerGUIDs.insert(creature->GetGUID());
@@ -160,13 +172,13 @@ public:
{
switch (go->GetEntry())
{
- case 192518:
- uiSladRanAltar = go->GetGUID();
+ case GO_SLADRAN_ALTAR:
+ sladRanAltarGUID = go->GetGUID();
// Make sure that they start out as unusuable
go->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE);
if (m_auiEncounter[0] == DONE)
{
- if (uiSladRanStatueState == GO_STATE_ACTIVE)
+ if (sladRanStatueState == GO_STATE_ACTIVE)
go->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE);
else
{
@@ -175,13 +187,13 @@ public:
}
}
break;
- case 192519:
- uiMoorabiAltar = go->GetGUID();
+ case GO_MOORABI_ALTAR:
+ moorabiAltarGUID = go->GetGUID();
// Make sure that they start out as unusuable
go->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE);
if (m_auiEncounter[0] == DONE)
{
- if (uiMoorabiStatueState == GO_STATE_ACTIVE)
+ if (moorabiStatueState == GO_STATE_ACTIVE)
go->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE);
else
{
@@ -190,13 +202,13 @@ public:
}
}
break;
- case 192520:
- uiDrakkariColossusAltar = go->GetGUID();
+ case GO_DRAKKARI_COLOSSUS_ALTAR:
+ drakkariColossusAltarGUID = go->GetGUID();
// Make sure that they start out as unusuable
go->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE);
if (m_auiEncounter[0] == DONE)
{
- if (uiDrakkariColossusStatueState == GO_STATE_ACTIVE)
+ if (drakkariColossusStatueState == GO_STATE_ACTIVE)
go->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE);
else
{
@@ -205,53 +217,58 @@ public:
}
}
break;
- case 192564:
- uiSladRanStatue = go->GetGUID();
- go->SetGoState(uiSladRanStatueState);
+ case GO_SLADRAN_STATUE:
+ sladRanStatueGUID = go->GetGUID();
+ go->SetGoState(sladRanStatueState);
break;
- case 192565:
- uiMoorabiStatue = go->GetGUID();
- go->SetGoState(uiMoorabiStatueState);
+ case GO_MOORABI_STATUE:
+ moorabiStatueGUID = go->GetGUID();
+ go->SetGoState(moorabiStatueState);
break;
- case 192566:
- uiGalDarahStatue = go->GetGUID();
- go->SetGoState(uiGalDarahStatueState);
+ case GO_GALDARAH_STATUE:
+ galDarahStatueGUID = go->GetGUID();
+ go->SetGoState(galDarahStatueState);
break;
- case 192567:
- uiDrakkariColossusStatue = go->GetGUID();
- go->SetGoState(uiDrakkariColossusStatueState);
+ case GO_DRAKKARI_COLOSSUS_STATUE:
+ drakkariColossusStatueGUID = go->GetGUID();
+ go->SetGoState(drakkariColossusStatueState);
break;
- case 192632:
- uiEckTheFerociousDoor = go->GetGUID();
- if (bHeroicMode && m_auiEncounter[1] == DONE)
+ case GO_ECK_THE_FEROCIOUS_DOOR:
+ eckTheFerociousDoorGUID = go->GetGUID();
+ if (isHeroic && m_auiEncounter[1] == DONE)
HandleGameObject(0, true, go);
break;
- case 192569:
- uiEckTheFerociousDoorBehind = go->GetGUID();
- if (bHeroicMode && m_auiEncounter[4] == DONE)
+ case GO_ECK_THE_FEROCIOUS_DOOR_BEHIND:
+ eckTheFerociousDoorBehindGUID = go->GetGUID();
+ if (isHeroic && m_auiEncounter[4] == DONE)
HandleGameObject(0, true, go);
- case 193208:
- uiGalDarahDoor1 = go->GetGUID();
+ case GO_GALDARAH_DOOR1:
+ galDarahDoor1GUID = go->GetGUID();
if (m_auiEncounter[3] == DONE)
HandleGameObject(0, true, go);
break;
- case 193209:
- uiGalDarahDoor2 = go->GetGUID();
+ case GO_GALDARAH_DOOR2:
+ galDarahDoor2GUID = go->GetGUID();
if (m_auiEncounter[3] == DONE)
HandleGameObject(0, true, go);
break;
- case 193188:
- uiBridge = go->GetGUID();
- go->SetGoState(uiBridgeState);
+ case GO_BRIDGE:
+ bridgeGUID = go->GetGUID();
+ go->SetGoState(bridgeState);
break;
- case 192633:
- uiCollision = go->GetGUID();
- go->SetGoState(uiCollisionState);
+ case GO_COLLISION:
+ collisionGUID = go->GetGUID();
+ go->SetGoState(collisionState);
// Can't spawn here with SpawnGameObject because go isn't added to world yet...
- if (uiCollisionState == GO_STATE_ACTIVE_ALTERNATIVE)
+ if (collisionState == GO_STATE_ACTIVE_ALTERNATIVE)
spawnSupport = true;
break;
+ case GO_GALDARAH_DOOR3:
+ galDarahDoor3GUID = go->GetGUID();
+ if (m_auiEncounter[3] != IN_PROGRESS)
+ HandleGameObject(galDarahDoor3GUID, true, go);
+ break;
}
}
@@ -263,7 +280,7 @@ public:
m_auiEncounter[0] = data;
if (data == DONE)
{
- GameObject* go = instance->GetGameObject(uiSladRanAltar);
+ GameObject* go = instance->GetGameObject(sladRanAltarGUID);
if (go)
go->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE);
}
@@ -272,18 +289,18 @@ public:
m_auiEncounter[1] = data;
if (data == DONE)
{
- GameObject* go = instance->GetGameObject(uiMoorabiAltar);
+ GameObject* go = instance->GetGameObject(moorabiAltarGUID);
if (go)
go->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE);
- if (bHeroicMode)
- HandleGameObject(uiEckTheFerociousDoor, true);
+ if (isHeroic)
+ HandleGameObject(eckTheFerociousDoorGUID, true);
}
break;
case DATA_DRAKKARI_COLOSSUS_EVENT:
m_auiEncounter[2] = data;
if (data == DONE)
{
- GameObject* go = instance->GetGameObject(uiDrakkariColossusAltar);
+ GameObject* go = instance->GetGameObject(drakkariColossusAltarGUID);
if (go)
go->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE);
}
@@ -292,14 +309,15 @@ public:
m_auiEncounter[3] = data;
if (data == DONE)
{
- HandleGameObject(uiGalDarahDoor1, true);
- HandleGameObject(uiGalDarahDoor2, true);
+ HandleGameObject(galDarahDoor1GUID, true);
+ HandleGameObject(galDarahDoor2GUID, true);
}
+ HandleGameObject(galDarahDoor3GUID, data == IN_PROGRESS ? false : true);
break;
case DATA_ECK_THE_FEROCIOUS_EVENT:
m_auiEncounter[4] = data;
- if (bHeroicMode && data == DONE)
- HandleGameObject(uiEckTheFerociousDoorBehind, true);
+ if (isHeroic && data == DONE)
+ HandleGameObject(eckTheFerociousDoorBehindGUID, true);
break;
}
@@ -345,19 +363,19 @@ public:
switch (type)
{
case DATA_SLAD_RAN_ALTAR:
- return uiSladRanAltar;
+ return sladRanAltarGUID;
case DATA_MOORABI_ALTAR:
- return uiMoorabiAltar;
+ return moorabiAltarGUID;
case DATA_DRAKKARI_COLOSSUS_ALTAR:
- return uiDrakkariColossusAltar;
+ return drakkariColossusAltarGUID;
case DATA_SLAD_RAN_STATUE:
- return uiSladRanStatue;
+ return sladRanStatueGUID;
case DATA_MOORABI_STATUE:
- return uiMoorabiStatue;
+ return moorabiStatueGUID;
case DATA_DRAKKARI_COLOSSUS_STATUE:
- return uiDrakkariColossusStatue;
+ return drakkariColossusStatueGUID;
case DATA_DRAKKARI_COLOSSUS:
- return uiDrakkariColossus;
+ return drakkariColossusGUID;
case DATA_STATUE_ACTIVATE:
return toActivate;
}
@@ -372,9 +390,9 @@ public:
std::ostringstream saveStream;
saveStream << "G D " << m_auiEncounter[0] << ' ' << m_auiEncounter[1] << ' '
<< m_auiEncounter[2] << ' ' << m_auiEncounter[3] << ' ' << m_auiEncounter[4] << ' '
- << (uiSladRanStatue ? GetObjState(uiSladRanStatue) : GO_STATE_ACTIVE) << ' ' << (uiMoorabiStatue ? GetObjState(uiMoorabiStatue) : GO_STATE_ACTIVE) << ' '
- << (uiDrakkariColossusStatue ? GetObjState(uiDrakkariColossusStatue) : GO_STATE_ACTIVE) << ' ' << (uiGalDarahStatue ? GetObjState(uiGalDarahStatue) : GO_STATE_READY) << ' '
- << (uiBridge ? GetObjState(uiBridge) : GO_STATE_ACTIVE) << ' ' << (uiCollision ? GetObjState(uiCollision) : GO_STATE_READY);
+ << (sladRanStatueGUID ? GetObjState(sladRanStatueGUID) : GO_STATE_ACTIVE) << ' ' << (moorabiStatueGUID ? GetObjState(moorabiStatueGUID) : GO_STATE_ACTIVE) << ' '
+ << (drakkariColossusStatueGUID ? GetObjState(drakkariColossusStatueGUID) : GO_STATE_ACTIVE) << ' ' << (galDarahStatueGUID ? GetObjState(galDarahStatueGUID) : GO_STATE_READY) << ' '
+ << (bridgeGUID ? GetObjState(bridgeGUID) : GO_STATE_ACTIVE) << ' ' << (collisionGUID ? GetObjState(collisionGUID) : GO_STATE_READY);
str_data = saveStream.str();
@@ -406,12 +424,12 @@ public:
m_auiEncounter[2] = data2;
m_auiEncounter[3] = data3;
m_auiEncounter[4] = data4;
- uiSladRanStatueState = GOState(data5);
- uiMoorabiStatueState = GOState(data6);
- uiDrakkariColossusStatueState = GOState(data7);
- uiGalDarahStatueState = GOState(data8);
- uiBridgeState = GOState(data9);
- uiCollisionState = GOState(data10);
+ sladRanStatueState = GOState(data5);
+ moorabiStatueState = GOState(data6);
+ drakkariColossusStatueState = GOState(data7);
+ galDarahStatueState = GOState(data8);
+ bridgeState = GOState(data9);
+ collisionState = GOState(data10);
for (uint8 i = 0; i < MAX_ENCOUNTER; ++i)
if (m_auiEncounter[i] == IN_PROGRESS)
@@ -426,8 +444,8 @@ public:
// Spawn the support for the bridge if necessary
if (spawnSupport)
{
- if (GameObject* pCollision = instance->GetGameObject(uiCollision))
- pCollision->SummonGameObject(192743, pCollision->GetPositionX(), pCollision->GetPositionY(), pCollision->GetPositionZ(), pCollision->GetOrientation(), 0, 0, 0, 0, 0);
+ if (GameObject* collision = instance->GetGameObject(collisionGUID))
+ collision->SummonGameObject(192743, collision->GetPositionX(), collision->GetPositionY(), collision->GetPositionZ(), collision->GetOrientation(), 0, 0, 0, 0, 0);
spawnSupport = false;
}
@@ -438,25 +456,25 @@ public:
if (timer < diff)
{
timer = 0;
- if (toActivate == uiBridge)
+ if (toActivate == bridgeGUID)
{
- GameObject* pBridge = instance->GetGameObject(uiBridge);
- GameObject* pCollision = instance->GetGameObject(uiCollision);
- GameObject* pSladRanStatue = instance->GetGameObject(uiSladRanStatue);
- GameObject* pMoorabiStatue = instance->GetGameObject(uiMoorabiStatue);
- GameObject* pDrakkariColossusStatue = instance->GetGameObject(uiDrakkariColossusStatue);
- GameObject* pGalDarahStatue = instance->GetGameObject(uiGalDarahStatue);
+ GameObject* bridge = instance->GetGameObject(bridgeGUID);
+ GameObject* collision = instance->GetGameObject(collisionGUID);
+ GameObject* sladRanStatue = instance->GetGameObject(sladRanStatueGUID);
+ GameObject* moorabiStatue = instance->GetGameObject(moorabiStatueGUID);
+ GameObject* drakkariColossusStatue = instance->GetGameObject(drakkariColossusStatueGUID);
+ GameObject* galDarahStatue = instance->GetGameObject(galDarahStatueGUID);
toActivate = 0;
- if (pBridge && pCollision && pSladRanStatue && pMoorabiStatue && pDrakkariColossusStatue && pGalDarahStatue)
+ if (bridge && collision && sladRanStatue && moorabiStatue && drakkariColossusStatue && galDarahStatue)
{
- pBridge->SetGoState(GO_STATE_ACTIVE_ALTERNATIVE);
- pCollision->SetGoState(GO_STATE_ACTIVE_ALTERNATIVE);
- pSladRanStatue->SetGoState(GO_STATE_ACTIVE_ALTERNATIVE);
- pMoorabiStatue->SetGoState(GO_STATE_ACTIVE_ALTERNATIVE);
- pDrakkariColossusStatue->SetGoState(GO_STATE_ACTIVE_ALTERNATIVE);
- pGalDarahStatue->SetGoState(GO_STATE_ACTIVE_ALTERNATIVE);
+ bridge->SetGoState(GO_STATE_ACTIVE_ALTERNATIVE);
+ collision->SetGoState(GO_STATE_ACTIVE_ALTERNATIVE);
+ sladRanStatue->SetGoState(GO_STATE_ACTIVE_ALTERNATIVE);
+ moorabiStatue->SetGoState(GO_STATE_ACTIVE_ALTERNATIVE);
+ drakkariColossusStatue->SetGoState(GO_STATE_ACTIVE_ALTERNATIVE);
+ galDarahStatue->SetGoState(GO_STATE_ACTIVE_ALTERNATIVE);
// Add the GO that solidifies the bridge so you can walk on it
spawnSupport = true;
@@ -466,27 +484,27 @@ public:
else
{
uint32 spell = 0;
- GameObject* pAltar = NULL;
- if (toActivate == uiSladRanStatue)
+ GameObject* altar = NULL;
+ if (toActivate == sladRanStatueGUID)
{
spell = 57071;
- pAltar = instance->GetGameObject(uiSladRanAltar);
+ altar = instance->GetGameObject(sladRanAltarGUID);
}
- else if (toActivate == uiMoorabiStatue)
+ else if (toActivate == moorabiStatueGUID)
{
spell = 57068;
- pAltar = instance->GetGameObject(uiMoorabiAltar);
+ altar = instance->GetGameObject(moorabiAltarGUID);
}
- else if (toActivate == uiDrakkariColossusStatue)
+ else if (toActivate == drakkariColossusStatueGUID)
{
spell = 57072;
- pAltar = instance->GetGameObject(uiDrakkariColossusAltar);
+ altar = instance->GetGameObject(drakkariColossusAltarGUID);
}
// This is a workaround to make the beam cast properly. The caster should be ID 30298 but since the spells
// all are with scripted target for that same ID, it will hit itself.
- if (pAltar)
- if (Creature* trigger = pAltar->SummonCreature(18721, pAltar->GetPositionX(), pAltar->GetPositionY(), pAltar->GetPositionZ() + 3, pAltar->GetOrientation(), TEMPSUMMON_CORPSE_DESPAWN, 5000))
+ if (altar)
+ if (Creature* trigger = altar->SummonCreature(18721, altar->GetPositionX(), altar->GetPositionY(), altar->GetPositionZ() + 3, altar->GetOrientation(), TEMPSUMMON_CORPSE_DESPAWN, 5000))
{
// Set the trigger model to invisible
trigger->SetDisplayId(11686);
@@ -499,7 +517,7 @@ public:
toActivate = 0;
if (phase == 3)
- SetData64(DATA_STATUE_ACTIVATE, uiBridge);
+ SetData64(DATA_STATUE_ACTIVATE, bridgeGUID);
else
SaveToDB(); // Don't save in between last statue and bridge turning in case of crash leading to stuck instance
}
@@ -526,7 +544,7 @@ public:
bool OnGossipHello(Player* /*player*/, GameObject* go)
{
InstanceScript* instance = go->GetInstanceScript();
- uint64 uiStatue = 0;
+ uint64 statueGUID = 0;
go->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE);
go->SetGoState(GO_STATE_ACTIVE);
@@ -535,20 +553,20 @@ public:
{
switch (go->GetEntry())
{
- case 192518:
- uiStatue = instance->GetData64(DATA_SLAD_RAN_STATUE);
+ case GO_SLADRAN_ALTAR:
+ statueGUID = instance->GetData64(DATA_SLAD_RAN_STATUE);
break;
- case 192519:
- uiStatue = instance->GetData64(DATA_MOORABI_STATUE);
+ case GO_MOORABI_ALTAR:
+ statueGUID = instance->GetData64(DATA_MOORABI_STATUE);
break;
- case 192520:
- uiStatue = instance->GetData64(DATA_DRAKKARI_COLOSSUS_STATUE);
+ case GO_DRAKKARI_COLOSSUS_ALTAR:
+ statueGUID = instance->GetData64(DATA_DRAKKARI_COLOSSUS_STATUE);
break;
}
if (!instance->GetData64(DATA_STATUE_ACTIVATE))
{
- instance->SetData64(DATA_STATUE_ACTIVATE, uiStatue);
+ instance->SetData64(DATA_STATUE_ACTIVATE, statueGUID);
go->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE);
go->SetGoState(GO_STATE_ACTIVE);
}
diff --git a/src/server/scripts/Spells/spell_quest.cpp b/src/server/scripts/Spells/spell_quest.cpp
index 3036c52876d..4cc464af9ab 100644
--- a/src/server/scripts/Spells/spell_quest.cpp
+++ b/src/server/scripts/Spells/spell_quest.cpp
@@ -1640,6 +1640,37 @@ class spell_q13291_q13292_q13239_q13261_armored_decoy_summon_skytalon : public S
}
};
+class spell_q12847_summon_soul_moveto_bunny : public SpellScriptLoader
+{
+ public:
+ spell_q12847_summon_soul_moveto_bunny() : SpellScriptLoader("spell_q12847_summon_soul_moveto_bunny") { }
+
+ class spell_q12847_summon_soul_moveto_bunny_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_q12847_summon_soul_moveto_bunny_SpellScript);
+
+ void ChangeSummonPos(SpellEffIndex /*effIndex*/)
+ {
+ // Adjust effect summon position
+ WorldLocation summonPos = *GetExplTargetDest();
+ Position offset = { 0.0f, 0.0f, 2.5f, 0.0f };
+ summonPos.RelocateOffset(offset);
+ SetExplTargetDest(summonPos);
+ GetHitDest()->RelocateOffset(offset);
+ }
+
+ void Register()
+ {
+ OnEffectHit += SpellEffectFn(spell_q12847_summon_soul_moveto_bunny_SpellScript::ChangeSummonPos, EFFECT_0, SPELL_EFFECT_SUMMON);
+ }
+ };
+
+ SpellScript *GetSpellScript() const
+ {
+ return new spell_q12847_summon_soul_moveto_bunny_SpellScript();
+ }
+};
+
void AddSC_quest_spell_scripts()
{
new spell_q55_sacred_cleansing();
@@ -1680,4 +1711,5 @@ void AddSC_quest_spell_scripts()
new spell_q12527_zuldrak_rat();
new spell_q13291_q13292_q13239_q13261_frostbrood_skytalon_grab_decoy();
new spell_q13291_q13292_q13239_q13261_armored_decoy_summon_skytalon();
+ new spell_q12847_summon_soul_moveto_bunny();
}
diff --git a/src/server/shared/Database/Implementation/CharacterDatabase.cpp b/src/server/shared/Database/Implementation/CharacterDatabase.cpp
index 9704b709959..4fb9c763f16 100644
--- a/src/server/shared/Database/Implementation/CharacterDatabase.cpp
+++ b/src/server/shared/Database/Implementation/CharacterDatabase.cpp
@@ -319,6 +319,7 @@ void CharacterDatabaseConnection::DoPrepareStatements()
PrepareStatement(CHAR_UPD_ARENA_TEAM_MEMBER, "UPDATE arena_team_member SET personalRating = ?, weekGames = ?, weekWins = ?, seasonGames = ?, seasonWins = ? WHERE arenaTeamId = ? AND guid = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_REP_CHARACTER_ARENA_STATS, "REPLACE INTO character_arena_stats (guid, slot, matchMakerRating) VALUES (?, ?, ?)", CONNECTION_ASYNC);
PrepareStatement(CHAR_SEL_PLAYER_ARENA_TEAMS, "SELECT arena_team_member.arenaTeamId FROM arena_team_member JOIN arena_team ON arena_team_member.arenaTeamId = arena_team.arenaTeamId WHERE guid = ?", CONNECTION_SYNCH);
+ PrepareStatement(CHAR_UPD_ARENA_TEAM_NAME, "UPDATE arena_team SET name = ? WHERE arenaTeamId = ?", CONNECTION_ASYNC);
// Character battleground data
PrepareStatement(CHAR_INS_PLAYER_BGDATA, "INSERT INTO character_battleground_data (guid, instanceId, team, joinX, joinY, joinZ, joinO, joinMapId, taxiStart, taxiEnd, mountSpell) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC);
@@ -439,8 +440,12 @@ void CharacterDatabaseConnection::DoPrepareStatements()
PrepareStatement(CHAR_SEL_CHAR_DEL_INFO_BY_NAME, "SELECT guid, deleteInfos_Name, deleteInfos_Account, deleteDate FROM characters WHERE deleteDate IS NOT NULL AND deleteInfos_Name LIKE CONCAT('%%', ?, '%%')", CONNECTION_SYNCH);
PrepareStatement(CHAR_SEL_CHAR_DEL_INFO, "SELECT guid, deleteInfos_Name, deleteInfos_Account, deleteDate FROM characters WHERE deleteDate IS NOT NULL", CONNECTION_SYNCH);
PrepareStatement(CHAR_SEL_CHARS_BY_ACCOUNT_ID, "SELECT guid FROM characters WHERE account = ?", CONNECTION_SYNCH);
- PrepareStatement(CHAR_SEL_CHAR_PINFO, "SELECT totaltime, level, money, account, race, class, map, zone FROM characters WHERE guid = ?", CONNECTION_SYNCH);
+ PrepareStatement(CHAR_SEL_CHAR_PINFO, "SELECT totaltime, level, money, account, race, class, map, zone, gender, health, playerFlags FROM characters WHERE guid = ?", CONNECTION_SYNCH);
PrepareStatement(CHAR_SEL_PINFO_BANS, "SELECT unbandate, bandate = unbandate, bannedby, banreason FROM character_banned WHERE guid = ? AND active ORDER BY bandate ASC LIMIT 1", CONNECTION_SYNCH);
+ //0: lowGUID
+ PrepareStatement(CHAR_SEL_PINFO_MAILS, "SELECT SUM(CASE WHEN (checked & 1) THEN 1 ELSE 0 END) AS 'readmail', COUNT(*) AS 'totalmail' FROM mail WHERE `receiver` = ?", CONNECTION_SYNCH);
+ //0: lowGUID
+ PrepareStatement(CHAR_SEL_PINFO_XP, "SELECT xp FROM characters WHERE guid = ?", CONNECTION_SYNCH);
PrepareStatement(CHAR_SEL_CHAR_HOMEBIND, "SELECT mapId, zoneId, posX, posY, posZ FROM character_homebind WHERE guid = ?", CONNECTION_SYNCH);
PrepareStatement(CHAR_SEL_CHAR_GUID_NAME_BY_ACC, "SELECT guid, name FROM characters WHERE account = ?", CONNECTION_SYNCH);
PrepareStatement(CHAR_SEL_POOL_QUEST_SAVE, "SELECT quest_id FROM pool_quest_save WHERE pool_id = ?", CONNECTION_SYNCH);
diff --git a/src/server/shared/Database/Implementation/CharacterDatabase.h b/src/server/shared/Database/Implementation/CharacterDatabase.h
index d9900d53f46..53c309f9ba0 100755
--- a/src/server/shared/Database/Implementation/CharacterDatabase.h
+++ b/src/server/shared/Database/Implementation/CharacterDatabase.h
@@ -268,6 +268,7 @@ enum CharacterDatabaseStatements
CHAR_UPD_ARENA_TEAM_MEMBER,
CHAR_REP_CHARACTER_ARENA_STATS,
CHAR_SEL_PLAYER_ARENA_TEAMS,
+ CHAR_UPD_ARENA_TEAM_NAME,
CHAR_SEL_PETITION,
CHAR_SEL_PETITION_SIGNATURE,
@@ -381,6 +382,8 @@ enum CharacterDatabaseStatements
CHAR_SEL_CHARS_BY_ACCOUNT_ID,
CHAR_SEL_CHAR_PINFO,
+ CHAR_SEL_PINFO_XP,
+ CHAR_SEL_PINFO_MAILS,
CHAR_SEL_PINFO_BANS,
CHAR_SEL_CHAR_HOMEBIND,
CHAR_SEL_CHAR_GUID_NAME_BY_ACC,
diff --git a/src/server/shared/Database/Implementation/LoginDatabase.cpp b/src/server/shared/Database/Implementation/LoginDatabase.cpp
index 0118f637205..6113dd61d70 100644
--- a/src/server/shared/Database/Implementation/LoginDatabase.cpp
+++ b/src/server/shared/Database/Implementation/LoginDatabase.cpp
@@ -79,7 +79,7 @@ void LoginDatabaseConnection::DoPrepareStatements()
PrepareStatement(LOGIN_GET_USERNAME_BY_ID, "SELECT username FROM account WHERE id = ?", CONNECTION_SYNCH);
PrepareStatement(LOGIN_SEL_CHECK_PASSWORD, "SELECT 1 FROM account WHERE id = ? AND sha_pass_hash = ?", CONNECTION_SYNCH);
PrepareStatement(LOGIN_SEL_CHECK_PASSWORD_BY_NAME, "SELECT 1 FROM account WHERE username = ? AND sha_pass_hash = ?", CONNECTION_SYNCH);
- PrepareStatement(LOGIN_SEL_PINFO, "SELECT a.username, aa.gmlevel, a.email, a.last_ip, DATE_FORMAT(a.last_login, '%Y-%m-%d %T'), a.mutetime, a.mutereason, a.muteby FROM account a LEFT JOIN account_access aa ON (a.id = aa.id AND (aa.RealmID = ? OR aa.RealmID = -1)) WHERE a.id = ?", CONNECTION_SYNCH);
+ PrepareStatement(LOGIN_SEL_PINFO, "SELECT a.username, aa.gmlevel, a.email, a.last_ip, DATE_FORMAT(a.last_login, '%Y-%m-%d %T'), a.mutetime, a.mutereason, a.muteby, a.failed_logins, a.locked, a.OS FROM account a LEFT JOIN account_access aa ON (a.id = aa.id AND (aa.RealmID = ? OR aa.RealmID = -1)) WHERE a.id = ?", CONNECTION_SYNCH);
PrepareStatement(LOGIN_SEL_PINFO_BANS, "SELECT unbandate, bandate = unbandate, bannedby, banreason FROM account_banned WHERE id = ? AND active ORDER BY bandate ASC LIMIT 1", CONNECTION_SYNCH);
PrepareStatement(LOGIN_SEL_GM_ACCOUNTS, "SELECT a.username, aa.gmlevel FROM account a, account_access aa WHERE a.id=aa.id AND aa.gmlevel >= ? AND (aa.realmid = -1 OR aa.realmid = ?)", CONNECTION_SYNCH);
PrepareStatement(LOGIN_SEL_ACCOUNT_INFO, "SELECT a.username, a.last_ip, aa.gmlevel, a.expansion FROM account a LEFT JOIN account_access aa ON (a.id = aa.id) WHERE a.id = ?", CONNECTION_SYNCH);
diff --git a/src/server/shared/Database/Implementation/WorldDatabase.cpp b/src/server/shared/Database/Implementation/WorldDatabase.cpp
index c6e520cfdde..75bafb571e9 100644
--- a/src/server/shared/Database/Implementation/WorldDatabase.cpp
+++ b/src/server/shared/Database/Implementation/WorldDatabase.cpp
@@ -91,4 +91,6 @@ void WorldDatabaseConnection::DoPrepareStatements()
PrepareStatement(WORLD_INS_DISABLES, "INSERT INTO disables (entry, sourceType, flags, comment) VALUES (?, ?, ?, ?)", CONNECTION_ASYNC);
PrepareStatement(WORLD_SEL_DISABLES, "SELECT entry FROM disables WHERE entry = ? AND sourceType = ?", CONNECTION_SYNCH);
PrepareStatement(WORLD_DEL_DISABLES, "DELETE FROM disables WHERE entry = ? AND sourceType = ?", CONNECTION_ASYNC);
+ // 0: uint8
+ PrepareStatement(WORLD_SEL_REQ_XP, "SELECT xp_for_next_level FROM player_xp_for_level WHERE lvl = ?", CONNECTION_SYNCH);
}
diff --git a/src/server/shared/Database/Implementation/WorldDatabase.h b/src/server/shared/Database/Implementation/WorldDatabase.h
index d8c3c69dbba..171627bb83a 100644
--- a/src/server/shared/Database/Implementation/WorldDatabase.h
+++ b/src/server/shared/Database/Implementation/WorldDatabase.h
@@ -112,6 +112,7 @@ enum WorldDatabaseStatements
WORLD_SEL_DISABLES,
WORLD_INS_DISABLES,
WORLD_DEL_DISABLES,
+ WORLD_SEL_REQ_XP,
MAX_WORLDDATABASE_STATEMENTS
};