aboutsummaryrefslogtreecommitdiff
path: root/src/game
diff options
context:
space:
mode:
authorBrian <runningnak3d@gmail.com>2010-02-14 19:13:14 -0700
committerBrian <runningnak3d@gmail.com>2010-02-14 19:13:14 -0700
commit486c00891ba34884e5b2cdd8d44b4d8496f11283 (patch)
tree7df304b9020ed21b87bd66978d2dc6e6683edce7 /src/game
parent7799ade4da0da17034039439d692122e976c0138 (diff)
* Core switch to client 3.3.2 (11403)
* Credits (in no particular order) to: * n0n4m3, raczman, manuel, Spp, Malcrom, Teacher, QAston, Tartalo, * thenecromancer, Xanadu, Trazom, Zor, kiper * Additional credits to: * TOM_RUS and NoFantasy from MaNGOS * Thanks for testing Aokromes and XTElite1 * SoTA still needs some work, but is very playable (huge thanks to raczman and * kiper) * To upgrade, you need to apply all SQL from sql/updates/3.2.2a_old from the * last rev you are on * and then apply all SQL from sql/updates/3.3.2_old to char / realmd / world * DBs * Known problem with guild banks. --HG-- branch : trunk
Diffstat (limited to 'src/game')
-rw-r--r--src/game/ArenaTeam.cpp8
-rw-r--r--src/game/BattleGround.h8
-rw-r--r--src/game/BattleGroundIC.cpp52
-rw-r--r--src/game/BattleGroundIC.h14
-rw-r--r--src/game/BattleGroundMgr.cpp41
-rw-r--r--src/game/BattleGroundSA.cpp633
-rw-r--r--src/game/BattleGroundSA.h287
-rw-r--r--src/game/CharacterHandler.cpp25
-rw-r--r--src/game/Chat.cpp6
-rw-r--r--src/game/Creature.cpp8
-rw-r--r--src/game/Creature.h2
-rw-r--r--src/game/DBCEnums.h19
-rw-r--r--src/game/DBCStores.cpp21
-rw-r--r--src/game/DBCStores.h2
-rw-r--r--src/game/DBCStructure.h128
-rw-r--r--src/game/DBCfmt.h12
-rw-r--r--src/game/GameEventMgr.cpp6
-rw-r--r--src/game/GameObject.cpp64
-rw-r--r--src/game/GameObject.h2
-rw-r--r--src/game/GossipDef.cpp55
-rw-r--r--src/game/Group.cpp103
-rw-r--r--src/game/Group.h22
-rw-r--r--src/game/GroupHandler.cpp24
-rw-r--r--src/game/Item.cpp34
-rw-r--r--src/game/Item.h3
-rw-r--r--src/game/ItemHandler.cpp8
-rw-r--r--src/game/ItemPrototype.h2
-rw-r--r--src/game/LFGHandler.cpp18
-rw-r--r--src/game/Language.h7
-rw-r--r--src/game/Level1.cpp9
-rw-r--r--src/game/Level2.cpp4
-rw-r--r--src/game/Level3.cpp5
-rw-r--r--src/game/LootMgr.h5
-rw-r--r--src/game/Mail.cpp2
-rw-r--r--src/game/Map.cpp5
-rw-r--r--src/game/MiscHandler.cpp48
-rw-r--r--src/game/Object.cpp9
-rw-r--r--src/game/Object.h20
-rw-r--r--src/game/ObjectMgr.cpp108
-rw-r--r--src/game/ObjectMgr.h37
-rw-r--r--src/game/Opcodes.cpp128
-rw-r--r--src/game/Opcodes.h166
-rw-r--r--src/game/Pet.cpp10
-rw-r--r--src/game/PetHandler.cpp4
-rw-r--r--src/game/Player.cpp229
-rw-r--r--src/game/Player.h56
-rw-r--r--src/game/PoolHandler.cpp329
-rw-r--r--src/game/PoolHandler.h115
-rw-r--r--src/game/QueryHandler.cpp68
-rw-r--r--src/game/QuestDef.cpp151
-rw-r--r--src/game/QuestDef.h10
-rw-r--r--src/game/QuestHandler.cpp19
-rw-r--r--src/game/SharedDefines.h124
-rw-r--r--src/game/Spell.cpp32
-rw-r--r--src/game/SpellAuraDefines.h12
-rw-r--r--src/game/SpellAuraEffects.cpp41
-rw-r--r--src/game/SpellAuras.cpp3
-rw-r--r--src/game/SpellEffects.cpp68
-rw-r--r--src/game/SpellMgr.cpp40
-rw-r--r--src/game/SpellMgr.h20
-rw-r--r--src/game/Totem.cpp18
-rw-r--r--src/game/Unit.cpp217
-rw-r--r--src/game/Unit.h8
-rw-r--r--src/game/UpdateFields.h761
-rw-r--r--src/game/World.cpp10
-rw-r--r--src/game/World.h3
-rw-r--r--src/game/WorldSession.h3
67 files changed, 3234 insertions, 1277 deletions
diff --git a/src/game/ArenaTeam.cpp b/src/game/ArenaTeam.cpp
index 320d8aa6b98..45ac5057de2 100644
--- a/src/game/ArenaTeam.cpp
+++ b/src/game/ArenaTeam.cpp
@@ -46,7 +46,9 @@ ArenaTeam::ArenaTeam()
m_stats.games_week = 0;
m_stats.games_season = 0;
m_stats.rank = 0;
- if (sWorld.getConfig(CONFIG_ARENA_SEASON_ID) >= 6)
+ if (sWorld.getConfig(CONFIG_ARENA_START_RATING)>=0)
+ m_stats.rating = sWorld.getConfig(CONFIG_ARENA_START_RATING);
+ else if (sWorld.getConfig(CONFIG_ARENA_SEASON_ID) >= 6)
m_stats.rating = 0;
else
m_stats.rating = 1500;
@@ -143,7 +145,9 @@ bool ArenaTeam::AddMember(const uint64& PlayerGuid)
newmember.games_week = 0;
newmember.wins_season = 0;
newmember.wins_week = 0;
- if (sWorld.getConfig(CONFIG_ARENA_SEASON_ID) >= 6)
+ if (sWorld.getConfig(CONFIG_ARENA_START_PERSONAL_RATING) >= 0)
+ newmember.personal_rating = sWorld.getConfig(CONFIG_ARENA_START_PERSONAL_RATING);
+ else if (sWorld.getConfig(CONFIG_ARENA_SEASON_ID) >= 6)
{
if (m_stats.rating < 1000)
newmember.personal_rating = 0;
diff --git a/src/game/BattleGround.h b/src/game/BattleGround.h
index 9bbc9a9104e..67dcfaa5b88 100644
--- a/src/game/BattleGround.h
+++ b/src/game/BattleGround.h
@@ -201,8 +201,10 @@ enum ScoreType
SCORE_TOWERS_DEFENDED = 14,
SCORE_MINES_CAPTURED = 15,
SCORE_LEADERS_KILLED = 16,
- SCORE_SECONDARY_OBJECTIVES = 17
- // TODO : implement them
+ SCORE_SECONDARY_OBJECTIVES = 17,
+ //SOTA
+ SCORE_DESTROYED_DEMOLISHER = 18,
+ SCORE_DESTROYED_WALL = 19
};
enum ArenaType
@@ -503,6 +505,8 @@ class BattleGround
virtual void EventPlayerCapturedFlag(Player* /*player*/) {}
void EventPlayerLoggedIn(Player* player, uint64 plr_guid);
void EventPlayerLoggedOut(Player* player);
+ virtual void EventPlayerDamagedGO(Player* /*player*/, GameObject* /*target_obj*/, uint32 /*eventId*/) {}
+ virtual void EventPlayerUsedGO(Player* player, GameObject* go){}
/* Death related */
virtual WorldSafeLocsEntry const* GetClosestGraveYard(Player* player);
diff --git a/src/game/BattleGroundIC.cpp b/src/game/BattleGroundIC.cpp
index 216b7cbe727..73783e3b1ab 100644
--- a/src/game/BattleGroundIC.cpp
+++ b/src/game/BattleGroundIC.cpp
@@ -23,6 +23,8 @@
BattleGroundIC::BattleGroundIC()
{
+ m_BgCreatures.resize(2);
+ m_BgObjects.resize(5);
//TODO FIX ME!
m_StartMessageIds[BG_STARTING_EVENT_FIRST] = LANG_BG_WS_START_TWO_MINUTES;
m_StartMessageIds[BG_STARTING_EVENT_SECOND] = LANG_BG_WS_START_ONE_MINUTE;
@@ -78,4 +80,52 @@ void BattleGroundIC::UpdatePlayerScore(Player* Source, uint32 type, uint32 value
return;
BattleGround::UpdatePlayerScore(Source,type,value);
-} \ No newline at end of file
+}
+
+bool BattleGroundIC::SetupBattleGround()
+{
+ AddObject(0, 195157, 459.72f, -419.93f, 42.55f, 0, 0, 0, 0.9996573f, 0.02617699f, 10*MINUTE);
+ AddObject(1, 195158, 797.72f, -1009.48f, 138.52f, 0, 0, 0, 0.9996573f, 0.02617699f, 10*MINUTE);
+ AddObject(2, 195338, 418.98f, -838.33f, 51.09f, 0, 0, 0, 0.9996573f, 0.02617699f, 10*MINUTE);
+ AddObject(3, 195343, 1267.45f, -390.88f, 24.23f, 0, 0, 0, 0.9996573f, 0.02617699f, 10*MINUTE);
+ AddObject(4, 195333, 769.27f, -833.53f, 9.57f, 0, 0, 0, 0.9996573f, 0.02617699f, 10*MINUTE);
+ SpawnLeader(ALLIANCE);
+ SpawnLeader(HORDE);
+ return true;
+}
+
+void BattleGroundIC::SpawnLeader(uint32 teamid)
+{
+ if (teamid == ALLIANCE)
+ AddCreature(34924, 0, ALLIANCE, 307.03f, -833.04f, 48.91f, 6.23f, 10*MINUTE);
+ else
+ AddCreature(34922, 1, HORDE, 1264.42f, -766.80f, 48.91f, 3.28f, 10*MINUTE);
+}
+
+void BattleGroundIC::HandleKillUnit(Creature *unit, Player *killer)
+{
+ if (GetStatus() != STATUS_IN_PROGRESS)
+ return;
+
+ uint32 entry = unit->GetEntry();
+ if (entry == 34924)
+ {
+ RewardHonorToTeam(500,HORDE);
+ EndBattleGround(HORDE);
+ }
+ else if (entry == 34922)
+ {
+ RewardHonorToTeam(500,ALLIANCE);
+ EndBattleGround(ALLIANCE);
+ }
+}
+
+void BattleGroundIC::EndBattleGround(uint32 winner)
+{
+ BattleGround::EndBattleGround(winner);
+}
+void BattleGroundIC::EventPlayerClickedOnFlag(Player *source, GameObject* /*target_obj*/)
+{
+ if (GetStatus() != STATUS_IN_PROGRESS)
+ return;
+}
diff --git a/src/game/BattleGroundIC.h b/src/game/BattleGroundIC.h
index 5c4b17cc926..987350fc9f3 100644
--- a/src/game/BattleGroundIC.h
+++ b/src/game/BattleGroundIC.h
@@ -21,6 +21,12 @@
class BattleGround;
+enum Buffs
+{
+ OIL_REFINERY = 68719,
+ QUARRY = 68720
+};
+
class BattleGroundICScore : public BattleGroundScore
{
public:
@@ -44,11 +50,15 @@ class BattleGroundIC : public BattleGround
void RemovePlayer(Player *plr,uint64 guid);
void HandleAreaTrigger(Player *Source, uint32 Trigger);
- //bool SetupBattleGround();
+ bool SetupBattleGround();
+ void SpawnLeader(uint32 teamid);
+ void HandleKillUnit(Creature *unit, Player *killer);
+ void EndBattleGround(uint32 winner);
+ void EventPlayerClickedOnFlag(Player *source, GameObject* /*target_obj*/);
/* Scorekeeping */
void UpdatePlayerScore(Player *Source, uint32 type, uint32 value);
private:
};
-#endif \ No newline at end of file
+#endif
diff --git a/src/game/BattleGroundMgr.cpp b/src/game/BattleGroundMgr.cpp
index 7948fd321d6..d3f79b25576 100644
--- a/src/game/BattleGroundMgr.cpp
+++ b/src/game/BattleGroundMgr.cpp
@@ -1239,18 +1239,18 @@ void BattleGroundMgr::Update(uint32 diff)
void BattleGroundMgr::BuildBattleGroundStatusPacket(WorldPacket *data, BattleGround *bg, uint8 QueueSlot, uint8 StatusID, uint32 Time1, uint32 Time2, uint8 arenatype)
{
- // we can be in 3 queues in same time...
+ // we can be in 2 queues in same time...
if (StatusID == 0 || !bg)
{
- data->Initialize(SMSG_BATTLEFIELD_STATUS, 4*3);
- *data << uint32(QueueSlot); // queue id (0...2)
+ data->Initialize(SMSG_BATTLEFIELD_STATUS, 4+8);
+ *data << uint32(QueueSlot); // queue id (0...1)
*data << uint64(0);
return;
}
- data->Initialize(SMSG_BATTLEFIELD_STATUS, (4+1+1+4+2+4+1+4+4+4));
- *data << uint32(QueueSlot); // queue id (0...2) - player can be in 3 queues in time
+ data->Initialize(SMSG_BATTLEFIELD_STATUS, (4+8+1+1+4+1+4+4+4));
+ *data << uint32(QueueSlot); // queue id (0...1) - player can be in 2 queues in time
// The following segment is read as uint64 in client but can be appended as their original type.
*data << uint8(arenatype);
sLog.outDebug("BattleGroundMgr::BuildBattleGroundStatusPacket: arenatype = %u for bg instanceID %u, TypeID %u.", arenatype, bg->GetClientInstanceID(), bg->GetTypeID());
@@ -1258,6 +1258,8 @@ void BattleGroundMgr::BuildBattleGroundStatusPacket(WorldPacket *data, BattleGro
*data << uint32(bg->GetTypeID());
*data << uint16(0x1F90);
// End of uint64 segment, decomposed this way for simplicity
+ *data << uint8(0); // 3.3.0
+ *data << uint8(0); // 3.3.0
*data << uint32(bg->GetClientInstanceID());
// alliance/horde for BG and skirmish/rated for Arenas
// following displays the minimap-icon 0 = faction icon 1 = arenaicon
@@ -1378,7 +1380,11 @@ void BattleGroundMgr::BuildPvpLogDataPacket(WorldPacket *data, BattleGround *bg)
case BATTLEGROUND_BE:
case BATTLEGROUND_AA:
case BATTLEGROUND_RL:
- case BATTLEGROUND_SA: // wotlk
+ case BATTLEGROUND_SA:
+ *data << uint32(2);
+ *data << uint32(((BattleGroundSAScore*)itr->second)->demolishers_destroyed);
+ *data << uint32(((BattleGroundSAScore*)itr->second)->gates_destroyed);
+ break;
case BATTLEGROUND_DS: // wotlk
case BATTLEGROUND_RV: // wotlk
case BATTLEGROUND_IC: // wotlk
@@ -1514,8 +1520,16 @@ BattleGround * BattleGroundMgr::CreateNewBattleGround(BattleGroundTypeId bgTypeI
//for arenas there is random map used
if (bg_template->isArena())
{
- BattleGroundTypeId arenas[] = {BATTLEGROUND_RV, BATTLEGROUND_NA, BATTLEGROUND_BE, BATTLEGROUND_RL};
- uint32 arena_num = urand(1,3); // Disable Ring of Valor due to LoS problems
+ // for type enter in arenas
+ uint32 arenaswitch = urand(1, 3);
+
+ if (sWorld.getConfig(CONFIG_ARENA_LK_ARENAS_ENABLE) == 1)
+ arenaswitch = urand(0, 4); // Enable Ring of Valor and Dalaran Sewers arenas - in these arenas problem with LoS
+ else
+ arenaswitch = urand(1, 3); // Disable WoTLK Arenas (Ring of Valor, Dalaran Sewers)
+
+ BattleGroundTypeId arenas[] = {BATTLEGROUND_RV, BATTLEGROUND_NA, BATTLEGROUND_BE, BATTLEGROUND_RL, BATTLEGROUND_DS};
+ uint32 arena_num = arenaswitch;
bgTypeId = arenas[arena_num];
bg_template = GetBattleGroundTemplate(bgTypeId);
if (!bg_template)
@@ -1691,8 +1705,9 @@ void BattleGroundMgr::CreateInitialBattleGrounds()
}
if (MinLvl == 0 || MaxLvl == 0 || MinLvl > MaxLvl)
{
- MinLvl = bl->minlvl;
- MaxLvl = bl->maxlvl;
+ //TO-DO: FIX ME
+ MinLvl = 0;//bl->minlvl;
+ MaxLvl = 80;//bl->maxlvl;
}
start1 = fields[5].GetUInt32();
@@ -1838,15 +1853,17 @@ void BattleGroundMgr::BuildBattleGroundListPacket(WorldPacket *data, const uint6
if(bgTypeId == BATTLEGROUND_AA) // arena
{
*data << uint8(4); // unk
+ *data << uint8(0); // unk
*data << uint32(0); // unk (count?)
}
else // battleground
{
- *data << uint8(0x00); // unk, different for each bg type
+ *data << uint8(0); // unk, different for each bg type
+ *data << uint8(0); // unk
size_t count_pos = data->wpos();
uint32 count = 0;
- *data << uint32(0x00); // number of bg instances
+ *data << uint32(0); // number of bg instances
uint32 queue_id = plr->GetBattleGroundQueueIdFromLevel(bgTypeId);
for (std::set<uint32>::iterator itr = m_ClientBattleGroundIds[bgTypeId][queue_id].begin(); itr != m_ClientBattleGroundIds[bgTypeId][queue_id].end(); ++itr)
diff --git a/src/game/BattleGroundSA.cpp b/src/game/BattleGroundSA.cpp
index acf16ad3af0..ce2e9e0611e 100644
--- a/src/game/BattleGroundSA.cpp
+++ b/src/game/BattleGroundSA.cpp
@@ -20,24 +20,293 @@
#include "BattleGroundSA.h"
#include "Language.h"
#include "Player.h"
+#include "GameObject.h"
+#include "ObjectMgr.h"
+#include "WorldPacket.h"
+
+/*
+ The crap needs shitload of DB data fixed, will paste it here:
+
+ Cannons:
+ update creature_template set IconName = "Gunner" where entry = 27894;
+ UPDATE `creature_template` SET `vehicleid`=160 WHERE `entry`=27894;
+ ^^ Sniffed by el manuel, should be good.
+ UPDATE `creature_template` SET `spell1`=49872 WHERE `entry`=27894;
+ UPDATE `creature_template` set `unit_flags`=`unit_flags`|4 WHERE `entry`=27894;
+
+ UPDATE `creature_template` SET `vehicleid`=158 WHERE `entry`=28781;
+ UPDATE `creature_template` set `spell1=49872 where `entry`=32795;
+ UPDATE `creature_template` set `spell1=52338,`spell2`=60206 where `entry`=32796;
+ */
BattleGroundSA::BattleGroundSA()
{
//TODO FIX ME!
- m_StartMessageIds[BG_STARTING_EVENT_FIRST] = LANG_BG_WS_START_TWO_MINUTES;
- m_StartMessageIds[BG_STARTING_EVENT_SECOND] = LANG_BG_WS_START_ONE_MINUTE;
- m_StartMessageIds[BG_STARTING_EVENT_THIRD] = LANG_BG_WS_START_HALF_MINUTE;
- m_StartMessageIds[BG_STARTING_EVENT_FOURTH] = LANG_BG_WS_HAS_BEGUN;
+ m_StartMessageIds[BG_STARTING_EVENT_FIRST] = LANG_BG_SA_START_TWO_MINUTES;
+ m_StartMessageIds[BG_STARTING_EVENT_SECOND] = LANG_BG_SA_START_ONE_MINUTE;
+ m_StartMessageIds[BG_STARTING_EVENT_THIRD] = LANG_BG_SA_START_HALF_MINUTE;
+ m_StartMessageIds[BG_STARTING_EVENT_FOURTH] = LANG_BG_SA_HAS_BEGUN;
+ m_BgObjects.resize(BG_SA_MAXOBJ);
+ m_BgCreatures.resize(BG_SA_MAXNPC + BG_SA_MAX_GY);
+ TimerEnabled = false;
}
BattleGroundSA::~BattleGroundSA()
{
+ sLog.outError("SOTA ZDYCHA: \n%u %u\n %u %u",BG_SA_MAXOBJ,m_BgObjects.size(),BG_SA_MAXNPC,m_BgCreatures.size());
+}
+
+void BattleGroundSA::Reset()
+{
+ TotalTime = 0;
+ attackers = ( (urand(0,1)) ? TEAM_ALLIANCE : TEAM_HORDE);
+ for(uint8 i = 0; i <= 5; i++)
+ {
+ GateStatus[i] = BG_SA_GATE_OK;
+ }
+ ShipsStarted = false;
+ status = BG_SA_WARMUP;
+}
+
+bool BattleGroundSA::SetupBattleGround()
+{
+ return ResetObjs();
+}
+
+bool BattleGroundSA::ResetObjs()
+{
+
+ uint32 atF = BG_SA_Factions[attackers];
+ uint32 defF = BG_SA_Factions[attackers ? TEAM_ALLIANCE : TEAM_HORDE];
+ sLog.outError("SOTA: Attacking team: %u %u %u",attackers,atF,defF);
+
+ for(uint8 i = 0; i <BG_SA_MAXOBJ; i++)
+ DelObject(i);
+
+ for(uint8 i = 0; i < BG_SA_MAXNPC; i++)
+ DelCreature(i);
+
+ for(uint8 i = BG_SA_MAXNPC; i < BG_SA_MAXNPC + BG_SA_MAX_GY; i++)
+ DelCreature(i);
+
+ for(uint8 i = 0; i < 6; i++)
+ GateStatus[i] = BG_SA_GATE_OK;
+
+ for(uint8 i = 0; i < BG_SA_CENTRAL_FLAG; i++)
+ {
+ if(!AddObject(i,BG_SA_ObjEntries[i],
+ BG_SA_ObjSpawnlocs[i][0],BG_SA_ObjSpawnlocs[i][1],
+ BG_SA_ObjSpawnlocs[i][2],BG_SA_ObjSpawnlocs[i][3],
+ 0,0,0,0,RESPAWN_ONE_DAY))
+ return false;
+ else
+ sLog.outError("SOTA: object %u spawned",i);
+ }
+
+ GetBGObject(BG_SA_TITAN_RELIC)->SetUInt32Value(GAMEOBJECT_FACTION, defF);
+ GetBGObject(BG_SA_TITAN_RELIC)->Refresh();
+
+ //Cannons and demolishers - NPCs are spawned
+ //By capturing GYs.
+ for(uint8 i = 0; i < BG_SA_NPC_SPARKLIGHT; i++)
+ {
+ if(!AddCreature(BG_SA_NpcEntries[i], i, (attackers == TEAM_ALLIANCE ? TEAM_HORDE : TEAM_ALLIANCE),
+ BG_SA_NpcSpawnlocs[i][0],BG_SA_NpcSpawnlocs[i][1],
+ BG_SA_NpcSpawnlocs[i][2],BG_SA_NpcSpawnlocs[i][3]))
+ return false;
+ }
+
+ OverrideGunFaction();
+
+ for(uint8 i = 0; i <= BG_SA_TITAN_RELIC; i++)
+ {
+ SpawnBGObject(i, RESPAWN_IMMEDIATELY);
+ GetBGObject(i)->SetUInt32Value(GAMEOBJECT_FACTION, defF);
+ }
+
+ for(uint8 i = 0; i <= 5; i++)
+ {
+ GateStatus[i] = BG_SA_GATE_OK;
+ }
+
+ // MAD props for Kiper for discovering those values - 4 hours of his work.
+ GetBGObject(BG_SA_BOAT_ONE)->UpdateRotationFields(1.0f, 0.0002f);
+ GetBGObject(BG_SA_BOAT_TWO)->UpdateRotationFields(1.0f, 0.00001f);
+ SpawnBGObject(BG_SA_BOAT_ONE, RESPAWN_IMMEDIATELY);
+ SpawnBGObject(BG_SA_BOAT_TWO, RESPAWN_IMMEDIATELY);
+
+ TotalTime = 0;
+ ShipsStarted = false;
+
+ //Graveyards!
+ for(uint8 i = 0;i < BG_SA_MAX_GY; i++)
+ {
+ WorldSafeLocsEntry const *sg = NULL;
+ sg = sWorldSafeLocsStore.LookupEntry(BG_SA_GYEntries[i]);
+
+ if(!sg)
+ {
+ sLog.outError("SOTA: Can't find GY entry %u",BG_SA_GYEntries[i]);
+ return false;
+ }
+
+ if(i == BG_SA_BEACH_GY)
+ {
+ GraveyardStatus[i] = attackers;
+ AddSpiritGuide(i + BG_SA_MAXNPC, sg->x, sg->y, sg->z, BG_SA_GYOrientation[i], ((attackers == TEAM_HORDE )? HORDE : ALLIANCE));
+ }
+ else
+ {
+ GraveyardStatus[i] = ((attackers == TEAM_HORDE )? TEAM_ALLIANCE : TEAM_HORDE);
+ sLog.outError("SOTA: Spawning GY %u %f %f %f team %u",i,sg->x,sg->y,sg->z,GraveyardStatus[i]);
+ if(!AddSpiritGuide(i + BG_SA_MAXNPC, sg->x, sg->y, sg->z, BG_SA_GYOrientation[i], ((attackers == TEAM_HORDE )? ALLIANCE : HORDE) ))
+ {
+ sLog.outError("SOTA: couldn't spawn GY: %u",i);
+ }
+ }
+ }
+
+ //GY capture points
+ for(uint8 i = BG_SA_CENTRAL_FLAG; i < BG_SA_MAXOBJ; i++)
+ {
+ AddObject(i, BG_SA_ObjEntries[i] - (attackers == TEAM_ALLIANCE ? 1:0),
+ BG_SA_ObjSpawnlocs[i][0], BG_SA_ObjSpawnlocs[i][1],
+ BG_SA_ObjSpawnlocs[i][2], BG_SA_ObjSpawnlocs[i][3],
+ 0,0,0,0,RESPAWN_ONE_DAY);
+ GetBGObject(i)->SetUInt32Value(GAMEOBJECT_FACTION, atF);
+ }
+
+ //Player may enter BEFORE we set up bG - lets update his worldstates anyway...
+ UpdateWorldState(BG_SA_RIGHT_GY_HORDE , GraveyardStatus[BG_SA_RIGHT_CAPTURABLE_GY] == TEAM_HORDE?1:0 );
+ UpdateWorldState(BG_SA_LEFT_GY_HORDE , GraveyardStatus[BG_SA_LEFT_CAPTURABLE_GY] == TEAM_HORDE?1:0 );
+ UpdateWorldState(BG_SA_CENTER_GY_HORDE , GraveyardStatus[BG_SA_CENTRAL_CAPTURABLE_GY] == TEAM_HORDE?1:0 );
+
+ UpdateWorldState(BG_SA_RIGHT_GY_ALLIANCE , GraveyardStatus[BG_SA_RIGHT_CAPTURABLE_GY] == TEAM_ALLIANCE?1:0 );
+ UpdateWorldState(BG_SA_LEFT_GY_ALLIANCE , GraveyardStatus[BG_SA_LEFT_CAPTURABLE_GY] == TEAM_ALLIANCE?1:0 );
+ UpdateWorldState(BG_SA_CENTER_GY_ALLIANCE , GraveyardStatus[BG_SA_CENTRAL_CAPTURABLE_GY] == TEAM_ALLIANCE?1:0 );
+
+ if(attackers == TEAM_ALLIANCE)
+ {
+ UpdateWorldState(BG_SA_ALLY_ATTACKS, 1);
+ UpdateWorldState(BG_SA_HORDE_ATTACKS, 0);
+
+ UpdateWorldState(BG_SA_RIGHT_ATT_TOKEN_ALL, 1);
+ UpdateWorldState(BG_SA_LEFT_ATT_TOKEN_ALL, 1);
+ UpdateWorldState(BG_SA_RIGHT_ATT_TOKEN_HRD, 0);
+ UpdateWorldState(BG_SA_LEFT_ATT_TOKEN_HRD, 0);
+
+ UpdateWorldState(BG_SA_HORDE_DEFENCE_TOKEN,1);
+ UpdateWorldState(BG_SA_ALLIANCE_DEFENCE_TOKEN,0);
+
+ }
+ else
+ {
+ UpdateWorldState(BG_SA_HORDE_ATTACKS, 1);
+ UpdateWorldState(BG_SA_ALLY_ATTACKS, 0);
+
+ UpdateWorldState(BG_SA_RIGHT_ATT_TOKEN_ALL, 0);
+ UpdateWorldState(BG_SA_LEFT_ATT_TOKEN_ALL, 0);
+ UpdateWorldState(BG_SA_RIGHT_ATT_TOKEN_HRD, 1);
+ UpdateWorldState(BG_SA_LEFT_ATT_TOKEN_HRD, 1);
+
+ UpdateWorldState(BG_SA_HORDE_DEFENCE_TOKEN,0);
+ UpdateWorldState(BG_SA_ALLIANCE_DEFENCE_TOKEN,1);
+
+ }
+
+ UpdateWorldState(BG_SA_PURPLE_GATEWS, 1);
+ UpdateWorldState(BG_SA_RED_GATEWS, 1);
+ UpdateWorldState(BG_SA_BLUE_GATEWS, 1);
+ UpdateWorldState(BG_SA_GREEN_GATEWS, 1);
+ UpdateWorldState(BG_SA_YELLOW_GATEWS, 1);
+ UpdateWorldState(BG_SA_ANCIENT_GATEWS, 1);
+
+ TeleportPlayers();
+
+ return true;
+}
+
+void BattleGroundSA::StartShips()
+{
+ if(ShipsStarted)
+ return;
+ sLog.outError("SOTA: Starting boats!");
+ DoorOpen(BG_SA_BOAT_ONE);
+ DoorOpen(BG_SA_BOAT_TWO);
+
+ for(int i = BG_SA_BOAT_ONE; i <= BG_SA_BOAT_TWO; i++)
+ {
+ for( BattleGroundPlayerMap::const_iterator itr = GetPlayers().begin(); itr != GetPlayers().end();itr++)
+ {
+ if(Player* p = objmgr.GetPlayer(itr->first))
+ {
+ if(p->GetTeamId() != attackers)
+ continue;
+
+ UpdateData data;
+ WorldPacket pkt;
+ GetBGObject(i)->BuildValuesUpdateBlockForPlayer(&data, p);
+ data.BuildPacket(&pkt);
+ p->GetSession()->SendPacket(&pkt);
+ }
+ }
+ }
+
+ ShipsStarted = true;
}
void BattleGroundSA::Update(uint32 diff)
{
BattleGround::Update(diff);
+ TotalTime += diff;
+
+ if(status == BG_SA_WARMUP || status == BG_SA_SECOND_WARMUP)
+ {
+ if(TotalTime >= BG_SA_WARMUPLENGTH)
+ {
+ TotalTime = 0;
+ ToggleTimer();
+ status = (status == BG_SA_WARMUP) ? BG_SA_ROUND_ONE : BG_SA_ROUND_TWO;
+ }
+ if(TotalTime >= BG_SA_BOAT_START)
+ StartShips();
+ return;
+ }
+ else if(status == BG_SA_ROUND_ONE)
+ {
+ if(TotalTime >= BG_SA_ROUNDLENGTH)
+ {
+ RoundScores[0].time = TotalTime;
+ TotalTime = 0;
+ status = BG_SA_SECOND_WARMUP;
+ attackers = (attackers == TEAM_ALLIANCE) ? TEAM_HORDE : TEAM_ALLIANCE;
+ RoundScores[0].winner = attackers;
+ status = BG_SA_SECOND_WARMUP;
+ ToggleTimer();
+ ResetObjs();
+ return;
+ }
+
+ }
+ else if(status == BG_SA_ROUND_TWO)
+ {
+ if(TotalTime >= BG_SA_ROUNDLENGTH)
+ {
+ RoundScores[1].time = TotalTime;
+ RoundScores[1].winner = (attackers == TEAM_ALLIANCE) ? TEAM_HORDE : TEAM_ALLIANCE;
+
+ if(RoundScores[0].time < RoundScores[1].time)
+ EndBattleGround(RoundScores[0].winner == TEAM_ALLIANCE ? ALLIANCE : HORDE);
+ else
+ EndBattleGround(RoundScores[1].winner == TEAM_ALLIANCE ? ALLIANCE : HORDE);
+
+ return;
+ }
+ }
+
+ if(status == BG_SA_ROUND_ONE || status == BG_SA_ROUND_TWO)
+ SendTime();
}
void BattleGroundSA::StartingEventCloseDoors()
@@ -48,18 +317,81 @@ void BattleGroundSA::StartingEventOpenDoors()
{
}
+void BattleGroundSA::FillInitialWorldStates(WorldPacket& data)
+{
+ uint32 ally_attacks = uint32(attackers == TEAM_ALLIANCE ? 1 : 0);
+ uint32 horde_attacks = uint32(attackers == TEAM_HORDE ? 1 : 0);
+
+ for(uint8 i = 0; i < BG_SA_MAX_GY; i++)
+ sLog.outError("UWS: %u",GraveyardStatus[i]);
+
+ data << uint32(BG_SA_ANCIENT_GATEWS) << uint32(GateStatus[BG_SA_ANCIENT_GATE]);
+ data << uint32(BG_SA_YELLOW_GATEWS) << uint32(GateStatus[BG_SA_YELLOW_GATE]);
+ data << uint32(BG_SA_GREEN_GATEWS) << uint32(GateStatus[BG_SA_GREEN_GATE]);
+ data << uint32(BG_SA_BLUE_GATEWS) << uint32(GateStatus[BG_SA_BLUE_GATE]);
+ data << uint32(BG_SA_RED_GATEWS) << uint32(GateStatus[BG_SA_RED_GATE]);
+ data << uint32(BG_SA_PURPLE_GATEWS) << uint32(GateStatus[BG_SA_PURPLE_GATE]);
+
+ data << uint32(BG_SA_BONUS_TIMER) << uint32(0);
+
+ data << uint32(BG_SA_HORDE_ATTACKS)<< horde_attacks;
+ data << uint32(BG_SA_ALLY_ATTACKS) << ally_attacks;
+
+ //Time will be sent on first update...
+ data << uint32(BG_SA_ENABLE_TIMER) << ((TimerEnabled) ? uint32(1) : uint32(0));
+ data << uint32(BG_SA_TIMER_MINS) << uint32(0);
+ data << uint32(BG_SA_TIMER_SEC_TENS) << uint32(0);
+ data << uint32(BG_SA_TIMER_SEC_DECS) << uint32(0);
+
+ data << uint32(BG_SA_RIGHT_GY_HORDE) << uint32(GraveyardStatus[BG_SA_RIGHT_CAPTURABLE_GY] == TEAM_HORDE?1:0 );
+ data << uint32(BG_SA_LEFT_GY_HORDE) << uint32(GraveyardStatus[BG_SA_LEFT_CAPTURABLE_GY] == TEAM_HORDE?1:0 );
+ data << uint32(BG_SA_CENTER_GY_HORDE) << uint32(GraveyardStatus[BG_SA_CENTRAL_CAPTURABLE_GY] == TEAM_HORDE?1:0 );
+
+ data << uint32(BG_SA_RIGHT_GY_ALLIANCE) << uint32(GraveyardStatus[BG_SA_RIGHT_CAPTURABLE_GY] == TEAM_ALLIANCE?1:0 );
+ data << uint32(BG_SA_LEFT_GY_ALLIANCE) << uint32(GraveyardStatus[BG_SA_LEFT_CAPTURABLE_GY] == TEAM_ALLIANCE?1:0 );
+ data << uint32(BG_SA_CENTER_GY_ALLIANCE) << uint32(GraveyardStatus[BG_SA_CENTRAL_CAPTURABLE_GY] == TEAM_ALLIANCE?1:0 );
+
+ data << uint32(BG_SA_HORDE_DEFENCE_TOKEN) << ally_attacks;
+ data << uint32(BG_SA_ALLIANCE_DEFENCE_TOKEN) << horde_attacks;
+
+ data << uint32(BG_SA_LEFT_ATT_TOKEN_HRD) << horde_attacks;
+ data << uint32(BG_SA_RIGHT_ATT_TOKEN_HRD) << horde_attacks;
+ data << uint32(BG_SA_RIGHT_ATT_TOKEN_ALL) << ally_attacks;
+ data << uint32(BG_SA_LEFT_ATT_TOKEN_ALL) << ally_attacks;
+}
+
void BattleGroundSA::AddPlayer(Player *plr)
{
BattleGround::AddPlayer(plr);
//create score and add it to map, default values are set in constructor
BattleGroundSAScore* sc = new BattleGroundSAScore;
+ if(!ShipsStarted)
+ if(plr->GetTeamId() == attackers)
+ {
+ plr->CastSpell(plr,12438,true);//Without this player falls before boat loads...
+
+ if(urand(0,1))
+ plr->TeleportTo(607, 2682.936f, -830.368f, 50.0f, 2.895f, 0);
+ else
+ plr->TeleportTo(607, 2577.003f, 980.261f, 50.0f, 0.807f, 0);
+
+ }else
+ plr->TeleportTo(607, 1209.7f, -65.16f, 70.1f, 0.0f, 0);
+ else
+ {
+ if(plr->GetTeamId() == attackers)
+ plr->TeleportTo(607, 1600.381f, -106.263f, 8.8745f, 3.78f, 0);
+ else
+ plr->TeleportTo(607, 1209.7f, -65.16f, 70.1f, 0.0f, 0);
+ }
+
m_PlayerScores[plr->GetGUID()] = sc;
}
void BattleGroundSA::RemovePlayer(Player* /*plr*/,uint64 /*guid*/)
{
-
+
}
void BattleGroundSA::HandleAreaTrigger(Player * /*Source*/, uint32 /*Trigger*/)
@@ -76,5 +408,294 @@ void BattleGroundSA::UpdatePlayerScore(Player* Source, uint32 type, uint32 value
if(itr == m_PlayerScores.end()) // player not found...
return;
- BattleGround::UpdatePlayerScore(Source,type,value);
+ if(type == SCORE_DESTROYED_DEMOLISHER)
+ ((BattleGroundSAScore*)itr->second)->demolishers_destroyed += value;
+ else if(type == SCORE_DESTROYED_WALL)
+ ((BattleGroundSAScore*)itr->second)->gates_destroyed += value;
+ else
+ BattleGround::UpdatePlayerScore(Source,type,value);
+}
+
+void BattleGroundSA::TeleportPlayers()
+{
+ for (BattleGroundPlayerMap::const_iterator itr = GetPlayers().begin(); itr != GetPlayers().end(); ++itr)
+ {
+ if(Player *plr = objmgr.GetPlayer(itr->first))
+ {
+
+ if(plr->GetTeamId() == attackers)
+ {
+ plr->CastSpell(plr,12438,true);//Without this player falls before boat loads...
+
+ if(urand(0,1))
+ plr->TeleportTo(607, 2682.936f, -830.368f, 50.0f, 2.895f, 0);
+ else
+ plr->TeleportTo(607, 2577.003f, 980.261f, 50.0f, 0.807f, 0);
+ }
+ else
+ plr->TeleportTo(607, 1209.7f, -65.16f, 70.1f, 0.0f, 0);
+
+ }
+ }
+}
+
+void BattleGroundSA::EventPlayerDamagedGO(Player* plr, GameObject* go, uint32 event)
+{
+ sLog.outError("SOTA: EventGO %u",event);
+
+ switch(event)
+ {
+ case 19046: //Green gate destroyed
+ DestroyGate(BG_SA_GREEN_GATE,plr);
+ return;
+ case 19045: //blue gate
+ DestroyGate(BG_SA_BLUE_GATE,plr);
+ return;
+ case 19047: //red gate
+ DestroyGate(BG_SA_RED_GATE,plr);
+ return;
+ case 19048: //purple gate
+ DestroyGate(BG_SA_PURPLE_GATE,plr);
+ return;
+ case 19049: //yellow gate
+ DestroyGate(BG_SA_YELLOW_GATE,plr);
+ return;
+ case 19837: //ancient gate
+ DestroyGate(BG_SA_ANCIENT_GATE,plr);
+ return;
+ default:
+ return;
+ }
+
+}
+
+void BattleGroundSA::HandleKillUnit(Creature* unit, Player* killer)
+{
+ if(!unit)
+ return;
+
+ if(unit->GetEntry() == 28781) //Demolisher
+ UpdatePlayerScore(killer, SCORE_DESTROYED_DEMOLISHER, 1);
+
+}
+
+/*
+ You may ask what the fuck does it do?
+ Prevents owner overwriting guns faction with own.
+ */
+void BattleGroundSA::OverrideGunFaction()
+{
+ if(!m_BgCreatures[0])
+ return;
+
+ for(uint8 i = BG_SA_GUN_1; i <= BG_SA_GUN_10;i++)
+ if(Creature* gun = GetBGCreature(i))
+ {
+ gun->setFaction(BG_SA_Factions[attackers? TEAM_ALLIANCE : TEAM_HORDE]);
+ }
+
+ for(uint8 i = BG_SA_DEMOLISHER_1; i <= BG_SA_DEMOLISHER_4;i++)
+ if(Creature* dem = GetBGCreature(i))
+ {
+ dem->setFaction(BG_SA_Factions[attackers]);
+ }
+
+}
+
+void BattleGroundSA::DestroyGate(uint32 i, Player* pl)
+{
+ if(!GateStatus[i])
+ return;
+
+ if(GameObject* g = GetBGObject(i))
+ {
+ if(g->GetGOValue()->building.health == 0)
+ {
+ GateStatus[i] = BG_SA_GATE_DESTROYED;
+ uint32 uws;
+ switch(i)
+ {
+ case 0:
+ uws = BG_SA_GREEN_GATEWS;
+ break;
+ case 1:
+ uws = BG_SA_YELLOW_GATEWS;
+ break;
+ case 2:
+ uws = BG_SA_BLUE_GATEWS;
+ break;
+ case 3:
+ uws = BG_SA_RED_GATEWS;
+ break;
+ case 4:
+ uws = BG_SA_PURPLE_GATEWS;
+ break;
+ case 5:
+ uws = BG_SA_ANCIENT_GATEWS;
+ break;
+ default:
+ ASSERT(false);
+ break;
+ }
+
+ if(i < 5)
+ DelObject(i+9);
+ sLog.outError("SOTA: gate %u destroyed!",i+1);
+ UpdateWorldState(uws, GateStatus[i]);
+ UpdatePlayerScore(pl,SCORE_DESTROYED_WALL, 1);
+ }
+ }
+
+}
+
+WorldSafeLocsEntry const* BattleGroundSA::GetClosestGraveYard(Player* player)
+{
+ uint32 safeloc = 0;
+ WorldSafeLocsEntry const* ret;
+ float dist, nearest;
+ float x,y,z;
+
+ player->GetPosition(x,y,z);
+
+ if(player->GetTeamId() == attackers)
+ safeloc = BG_SA_GYEntries[BG_SA_BEACH_GY];
+ else
+ safeloc = BG_SA_GYEntries[BG_SA_DEFENDER_LAST_GY];
+
+ ret = sWorldSafeLocsStore.LookupEntry(safeloc);
+ nearest = sqrt((ret->x - x)*(ret->x - x) + (ret->y - y)*(ret->y - y)+(ret->z - z)*(ret->z - z));
+
+ for(uint8 i = BG_SA_LEFT_CAPTURABLE_GY; i < BG_SA_MAX_GY; i++)
+ {
+ if(GraveyardStatus[i] != player->GetTeamId())
+ continue;
+
+ dist = sqrt((ret->x - x)*(ret->x - x) + (ret->y - y)*(ret->y - y)+(ret->z - z)*(ret->z - z));
+ if(dist < nearest)
+ {
+ ret = sWorldSafeLocsStore.LookupEntry(BG_SA_GYEntries[i]);
+ nearest = dist;
+ }
+ }
+
+ return ret;
+}
+
+void BattleGroundSA::SendTime()
+{
+ uint32 end_of_round = (BG_SA_ROUNDLENGTH - TotalTime);
+ UpdateWorldState(BG_SA_TIMER_MINS, end_of_round/60000);
+ UpdateWorldState(BG_SA_TIMER_SEC_TENS, (end_of_round%60000)/10000);
+ UpdateWorldState(BG_SA_TIMER_SEC_DECS, ((end_of_round%60000)%10000)/1000);
+}
+
+void BattleGroundSA::EventPlayerClickedOnFlag(Player *Source, GameObject* target_obj)
+{
+
+ switch(target_obj->GetEntry())
+ {
+ case 191307:
+ case 191308:
+ CaptureGraveyard(BG_SA_LEFT_CAPTURABLE_GY);
+ break;
+ case 191305:
+ case 191306:
+ CaptureGraveyard(BG_SA_RIGHT_CAPTURABLE_GY);
+ break;
+ case 191310:
+ case 191309:
+ CaptureGraveyard(BG_SA_CENTRAL_CAPTURABLE_GY);
+ break;
+ default:
+ return;
+ };
+
+}
+
+void BattleGroundSA::CaptureGraveyard(BG_SA_Graveyards i)
+{
+
+ DelCreature(BG_SA_MAXNPC + i);
+ GraveyardStatus[i] = (GraveyardStatus[i] == TEAM_ALLIANCE? TEAM_HORDE : TEAM_ALLIANCE);
+ WorldSafeLocsEntry const *sg = NULL;
+ sg = sWorldSafeLocsStore.LookupEntry(BG_SA_GYEntries[i]);
+ AddSpiritGuide(i + BG_SA_MAXNPC, sg->x, sg->y, sg->z, BG_SA_GYOrientation[i], (GraveyardStatus[i] == TEAM_ALLIANCE? ALLIANCE : HORDE ));
+ uint32 npc = 0;
+
+ switch(i)
+ {
+ case BG_SA_LEFT_CAPTURABLE_GY:
+ sLog.outError("LEFT GY");
+ SpawnBGObject(BG_SA_LEFT_FLAG,RESPAWN_ONE_DAY);
+ npc = BG_SA_NPC_RIGSPARK;
+ AddCreature(BG_SA_NpcEntries[npc], npc, attackers,
+ BG_SA_NpcSpawnlocs[npc][0], BG_SA_NpcSpawnlocs[npc][1],
+ BG_SA_NpcSpawnlocs[npc][2], BG_SA_NpcSpawnlocs[npc][3]);
+ UpdateWorldState(BG_SA_LEFT_GY_ALLIANCE, (GraveyardStatus[i] == TEAM_ALLIANCE? 1:0));
+ UpdateWorldState(BG_SA_LEFT_GY_HORDE, (GraveyardStatus[i] == TEAM_ALLIANCE? 0:1));
+ break;
+ case BG_SA_RIGHT_CAPTURABLE_GY:
+ sLog.outError("RIGHT GY");
+ SpawnBGObject(BG_SA_RIGHT_FLAG, RESPAWN_ONE_DAY);
+ npc = BG_SA_NPC_SPARKLIGHT;
+ AddCreature(BG_SA_NpcEntries[npc], npc, attackers,
+ BG_SA_NpcSpawnlocs[npc][0], BG_SA_NpcSpawnlocs[npc][1],
+ BG_SA_NpcSpawnlocs[npc][2], BG_SA_NpcSpawnlocs[npc][3]);
+ UpdateWorldState(BG_SA_RIGHT_GY_ALLIANCE, (GraveyardStatus[i] == TEAM_ALLIANCE? 1:0));
+ UpdateWorldState(BG_SA_RIGHT_GY_HORDE, (GraveyardStatus[i] == TEAM_ALLIANCE? 0:1));
+ break;
+ case BG_SA_CENTRAL_CAPTURABLE_GY:
+ SpawnBGObject(BG_SA_CENTRAL_FLAG, RESPAWN_ONE_DAY);
+ UpdateWorldState(BG_SA_CENTER_GY_ALLIANCE, (GraveyardStatus[i] == TEAM_ALLIANCE? 1:0));
+ UpdateWorldState(BG_SA_CENTER_GY_HORDE, (GraveyardStatus[i] == TEAM_ALLIANCE? 0:1));
+ break;
+ default:
+ ASSERT(0);
+ break;
+ };
+
+
+}
+
+void BattleGroundSA::EventPlayerUsedGO(Player* Source, GameObject* object)
+{
+
+ if(object->GetEntry() == BG_SA_ObjEntries[BG_SA_TITAN_RELIC])
+ {
+ sLog.outError("SOTA: Match ended.");
+ if(Source->GetTeamId() == attackers)
+ {
+
+ if(status == BG_SA_ROUND_ONE)
+ {
+ RoundScores[0].winner = attackers;
+ RoundScores[0].time = TotalTime;
+ attackers = (attackers == TEAM_ALLIANCE) ? TEAM_HORDE : TEAM_ALLIANCE;
+ status = BG_SA_SECOND_WARMUP;
+ TotalTime = 0;
+ ToggleTimer();
+ ResetObjs();
+ }
+ else if(status == BG_SA_ROUND_TWO)
+ {
+ RoundScores[1].winner = attackers;
+ RoundScores[1].time = TotalTime;
+ ToggleTimer();
+ if(RoundScores[0].time < RoundScores[1].time)
+ EndBattleGround(RoundScores[0].winner == TEAM_ALLIANCE ? ALLIANCE : HORDE);
+ else
+ EndBattleGround(RoundScores[1].winner == TEAM_ALLIANCE ? ALLIANCE : HORDE);
+
+ }
+ }
+ }
+
+}
+
+void BattleGroundSA::ToggleTimer()
+{
+
+ TimerEnabled = !TimerEnabled;
+ UpdateWorldState(BG_SA_ENABLE_TIMER, (TimerEnabled) ? 1 : 0);
+
}
diff --git a/src/game/BattleGroundSA.h b/src/game/BattleGroundSA.h
index 3ba23d02656..17b30c51240 100644
--- a/src/game/BattleGroundSA.h
+++ b/src/game/BattleGroundSA.h
@@ -24,8 +24,267 @@ class BattleGround;
class BattleGroundSAScore : public BattleGroundScore
{
public:
- BattleGroundSAScore() {};
+ BattleGroundSAScore(): demolishers_destroyed(0), gates_destroyed(0) {};
virtual ~BattleGroundSAScore() {};
+ uint8 demolishers_destroyed;
+ uint8 gates_destroyed;
+};
+
+enum BG_SA_Status
+ {
+ BG_SA_NOTSTARTED = 0,
+ BG_SA_WARMUP,
+ BG_SA_ROUND_ONE,
+ BG_SA_SECOND_WARMUP,
+ BG_SA_ROUND_TWO,
+ BG_SA_BONUS_ROUND
+ };
+
+enum BG_SA_GateState
+ {
+ BG_SA_GATE_OK = 1,
+ BG_SA_GATE_DAMAGED = 2,
+ BG_SA_GATE_DESTROYED = 3
+ };
+
+enum BG_SA_Timers
+ {
+ BG_SA_BOAT_START = 60000,
+ BG_SA_WARMUPLENGTH = 120000,
+ BG_SA_ROUNDLENGTH = 600000
+ };
+
+enum BG_SA_WorldStates
+ {
+ BG_SA_TIMER_MINS = 3559,
+ BG_SA_TIMER_SEC_TENS = 3560,
+ BG_SA_TIMER_SEC_DECS = 3561,
+ BG_SA_ALLY_ATTACKS = 4352,
+ BG_SA_HORDE_ATTACKS = 4353,
+
+ BG_SA_PURPLE_GATEWS = 3614,
+ BG_SA_RED_GATEWS = 3617,
+ BG_SA_BLUE_GATEWS = 3620,
+ BG_SA_GREEN_GATEWS = 3623,
+ BG_SA_YELLOW_GATEWS = 3638,
+ BG_SA_ANCIENT_GATEWS = 3849,
+
+
+ BG_SA_LEFT_GY_ALLIANCE = 3635,
+ BG_SA_RIGHT_GY_ALLIANCE = 3636,
+ BG_SA_CENTER_GY_ALLIANCE = 3637,
+
+ BG_SA_RIGHT_ATT_TOKEN_ALL = 3627,
+ BG_SA_LEFT_ATT_TOKEN_ALL = 3626,
+
+ BG_SA_LEFT_ATT_TOKEN_HRD = 3629,
+ BG_SA_RIGHT_ATT_TOKEN_HRD = 3628,
+
+ BG_SA_HORDE_DEFENCE_TOKEN = 3631,
+ BG_SA_ALLIANCE_DEFENCE_TOKEN = 3630,
+
+ BG_SA_RIGHT_GY_HORDE = 3632,
+ BG_SA_LEFT_GY_HORDE = 3633,
+ BG_SA_CENTER_GY_HORDE = 3634,
+
+ BG_SA_BONUS_TIMER = 0xdf3,
+ BG_SA_ENABLE_TIMER = 3564,
+ };
+
+enum BG_SA_NPCs
+ {
+ BG_SA_GUN_1 = 0,
+ BG_SA_GUN_2,
+ BG_SA_GUN_3,
+ BG_SA_GUN_4,
+ BG_SA_GUN_5,
+ BG_SA_GUN_6,
+ BG_SA_GUN_7,
+ BG_SA_GUN_8,
+ BG_SA_GUN_9,
+ BG_SA_GUN_10,
+ BG_SA_DEMOLISHER_1,
+ BG_SA_DEMOLISHER_2,
+ BG_SA_DEMOLISHER_3,
+ BG_SA_DEMOLISHER_4,
+ BG_SA_NPC_SPARKLIGHT,
+ BG_SA_NPC_RIGSPARK,
+ BG_SA_MAXNPC
+ };
+
+const uint32 BG_SA_NpcEntries[BG_SA_MAXNPC] =
+ {
+ 27894,
+ 27894,
+ 27894,
+ 27894,
+ 27894,
+ 27894,
+ 27894,
+ 27894,
+ 27894,
+ 27894,
+ //4 beach demolishers
+ 28781,
+ 28781,
+ 28781,
+ 28781,
+ //Fizzle Sparklight, or whatever his name was
+ 29260,
+ 29262,
+ };
+
+const float BG_SA_NpcSpawnlocs[BG_SA_MAXNPC][4] =
+ {
+ //Cannons
+ { 1436.429f, 110.05f, 41.407f, 5.4f },
+ { 1404.9023f, 84.758f, 41.183f, 5.46f },
+ { 1068.693f, -86.951f, 93.81f, 0.02f },
+ { 1068.83f, -127.56f, 96.45f, 0.0912f },
+ { 1422.115f, -196.433f, 42.1825f, 1.0222f },
+ { 1454.887f, -220.454f, 41.956f, 0.9627f },
+ { 1232.345f, -187.517f, 66.945f, 0.45f },
+ { 1249.634f, -224.189f, 66.72f, 0.635f },
+ { 1236.213f, 92.287f, 64.965f, 5.751f },
+ { 1215.11f, 57.772f, 64.739f, 5.78f } ,
+ //Demolishers
+ { 1611.597656,-117.270073,8.719355,2.513274},
+ { 1575.562500,-158.421875,5.024450,2.129302},
+ { 1618.047729,61.424641,7.248210,3.979351},
+ { 1575.103149,98.873344,2.830360,3.752458},
+ //Npcs
+ { 1348.644165, -298.786469, 31.080130, 1.710423},
+ { 1358.191040, 195.527786, 31.018187, 4.171337},
+ };
+
+enum BG_SA_Objects
+ {
+ BG_SA_GREEN_GATE = 0,
+ BG_SA_YELLOW_GATE,
+ BG_SA_BLUE_GATE,
+ BG_SA_RED_GATE,
+ BG_SA_PURPLE_GATE,
+ BG_SA_ANCIENT_GATE,
+ BG_SA_TITAN_RELIC,
+ BG_SA_BOAT_ONE,
+ BG_SA_BOAT_TWO,
+ BG_SA_SIGIL_1,
+ BG_SA_SIGIL_2,
+ BG_SA_SIGIL_3,
+ BG_SA_SIGIL_4,
+ BG_SA_SIGIL_5,
+ BG_SA_CENTRAL_FLAGPOLE,
+ BG_SA_RIGHT_FLAGPOLE,
+ BG_SA_LEFT_FLAGPOLE,
+ BG_SA_CENTRAL_FLAG,
+ BG_SA_RIGHT_FLAG,
+ BG_SA_LEFT_FLAG,
+ BG_SA_MAXOBJ
+ };
+
+const float BG_SA_ObjSpawnlocs[BG_SA_MAXOBJ][4] =
+ {
+ { 1411.57f, 108.163f, 28.692f, 5.441f },
+ { 1055.452f, -108.1f, 82.134f, 0.034f },
+ { 1431.3413f, -219.437f, 30.893f, 0.9736f },
+ { 1227.667f, -212.555f, 55.372f, 0.5023f },
+ { 1214.681f, 81.21f, 53.413f, 5.745f },
+ { 878.555f, -108.989f, 119.835f, 0.0565f },
+ { 836.5f, -108.8f, 120.219f, 0.0f },
+ //Ships
+ { 2679.696777, -826.891235, 3.712860, 5.78367f}, //rot2 1 rot3 0.0002
+ { 2574.003662, 981.261475, 2.603424, 0.807696},
+ //Sigils
+ { 1414.054f, 106.72f, 41.442f, 5.441f },
+ { 1060.63f, -107.8f, 94.7f, 0.034f },
+ { 1433.383f, -216.4f, 43.642f, 0.9736f },
+ { 1230.75f, -210.724f, 67.611f, 0.5023f },
+ { 1217.8f, 79.532f, 66.58f, 5.745f },
+ //Flagpoles
+ { 1215.114258,-65.711861,70.084267,-3.124123},
+ {1338.863892,-153.336533,30.895121,-2.530723},
+ {1309.124268,9.410645,30.893402,-1.623156},
+ //Flags
+ { 1215.108032,-65.715767,70.084267,-3.124123},
+ { 1338.859253,-153.327316,30.895077,-2.530723},
+ { 1309.192017,9.416233,30.893402,1.518436},
+ };
+
+/* Ships:
+ * 193182 - ally
+ * 193183 - horde
+ * 193184 - horde
+ * 193185 - ally
+ * Banners:
+ * 191308 - left one,
+ * 191306 - right one,
+ * 191310 - central,
+ * Ally ones, substract 1
+ * to get horde ones.
+ */
+
+const uint32 BG_SA_ObjEntries[BG_SA_MAXOBJ] =
+ {
+ 190722,
+ 190727,
+ 190724,
+ 190726,
+ 190723,
+ 192549,
+ 192834,
+ 193182,
+ 193185,
+ 192687,
+ 192685,
+ 192689,
+ 192690,
+ 192691,
+ 191311,
+ 191311,
+ 191311,
+ 191310,
+ 191306,
+ 191308,
+ };
+
+const uint32 BG_SA_Factions[2] =
+ {
+ 1732,
+ 1735,
+ };
+
+enum BG_SA_Graveyards
+ {
+ BG_SA_BEACH_GY = 0,
+ BG_SA_DEFENDER_LAST_GY,
+ BG_SA_RIGHT_CAPTURABLE_GY,
+ BG_SA_LEFT_CAPTURABLE_GY,
+ BG_SA_CENTRAL_CAPTURABLE_GY,
+ BG_SA_MAX_GY
+ };
+
+const uint32 BG_SA_GYEntries[BG_SA_MAX_GY] =
+ {
+ 1350,
+ 1349,
+ 1347,
+ 1346,
+ 1348,
+ };
+
+const float BG_SA_GYOrientation[BG_SA_MAX_GY] =
+ {
+ 6.202f,
+ 1.926f, //right capturable GY
+ 3.917f, //left capturable GY
+ 3.104f, //center, capturable
+ 6.148f, //defender last GY
+ };
+
+struct BG_SA_RoundScore
+{
+ TeamId winner;
+ uint32 time;
};
class BattleGroundSA : public BattleGround
@@ -41,14 +300,38 @@ class BattleGroundSA : public BattleGround
virtual void AddPlayer(Player *plr);
virtual void StartingEventCloseDoors();
virtual void StartingEventOpenDoors();
+ virtual bool SetupBattleGround();
+ virtual void Reset();
+ virtual void FillInitialWorldStates(WorldPacket& data);
+ virtual void EventPlayerDamagedGO(Player* plr, GameObject* go, uint32 event);
+ virtual void HandleKillUnit(Creature* unit, Player* killer);
+ virtual WorldSafeLocsEntry const* GetClosestGraveYard(Player* player);
+ virtual void EventPlayerClickedOnFlag(Player *Source, GameObject* target_obj);
+ virtual void EventPlayerUsedGO(Player* Source, GameObject* object);
void RemovePlayer(Player *plr,uint64 guid);
void HandleAreaTrigger(Player *Source, uint32 Trigger);
- //bool SetupBattleGround();
+
/* Scorekeeping */
void UpdatePlayerScore(Player *Source, uint32 type, uint32 value);
private:
+ bool ResetObjs();
+ void StartShips();
+ void TeleportPlayers();
+ void OverrideGunFaction();
+ void DestroyGate(uint32 i, Player* pl);
+ void SendTime();
+ void CaptureGraveyard(BG_SA_Graveyards i);
+ void ToggleTimer();
+ TeamId attackers;
+ uint32 TotalTime;
+ bool ShipsStarted;
+ BG_SA_GateState GateStatus[6];
+ BG_SA_Status status;
+ TeamId GraveyardStatus[BG_SA_MAX_GY];
+ BG_SA_RoundScore RoundScores[2];
+ bool TimerEnabled;
};
#endif
diff --git a/src/game/CharacterHandler.cpp b/src/game/CharacterHandler.cpp
index bc2b4d97a4e..17b23b61e64 100644
--- a/src/game/CharacterHandler.cpp
+++ b/src/game/CharacterHandler.cpp
@@ -456,6 +456,8 @@ void WorldSession::HandleCharCreateOpcode( WorldPacket & recv_data )
if ((have_same_race && skipCinematics == 1) || skipCinematics == 2)
pNewChar->setCinematic(1); // not show intro
+ pNewChar->SetAtLoginFlag(AT_LOGIN_FIRST); // First login
+
// Player created, save it now
pNewChar->SaveToDB();
charcount+=1;
@@ -659,22 +661,21 @@ void WorldSession::HandlePlayerLogin(LoginQueryHolder * holder)
if(guild)
{
data.Initialize(SMSG_GUILD_EVENT, (2+guild->GetMOTD().size()+1));
- data << (uint8)GE_MOTD;
- data << (uint8)1;
+ data << uint8(GE_MOTD);
+ data << uint8(1);
data << guild->GetMOTD();
SendPacket(&data);
DEBUG_LOG( "WORLD: Sent guild-motd (SMSG_GUILD_EVENT)" );
+ guild->DisplayGuildBankTabsInfo(this);
+
data.Initialize(SMSG_GUILD_EVENT, (5+10)); // we guess size
- data<<(uint8)GE_SIGNED_ON;
- data<<(uint8)1;
- data<<pCurrChar->GetName();
- data<<pCurrChar->GetGUID();
+ data<<uint8(GE_SIGNED_ON);
+ data<<uint8(1);
+ data<< pCurrChar->GetName();
+ data<< pCurrChar->GetGUID();
guild->BroadcastPacket(&data);
DEBUG_LOG( "WORLD: Sent guild-signed-on (SMSG_GUILD_EVENT)" );
-
- // Increment online members of the guild
- guild->IncOnlineMemberCount();
}
else
{
@@ -689,9 +690,6 @@ void WorldSession::HandlePlayerLogin(LoginQueryHolder * holder)
data << uint32(0);
SendPacket(&data);
- if(!pCurrChar->isAlive())
- pCurrChar->SendCorpseReclaimDelay(true);
-
pCurrChar->SendInitialPacketsBeforeAddToMap();
//Show cinematic at the first time that player login
@@ -784,6 +782,9 @@ void WorldSession::HandlePlayerLogin(LoginQueryHolder * holder)
SendNotification(LANG_RESET_TALENTS);
}
+ if (pCurrChar->HasAtLoginFlag(AT_LOGIN_FIRST))
+ pCurrChar->RemoveAtLoginFlag(AT_LOGIN_FIRST);
+
// show time before shutdown if shutdown planned.
if(sWorld.IsShutdowning())
sWorld.ShutdownMsg(true,pCurrChar);
diff --git a/src/game/Chat.cpp b/src/game/Chat.cpp
index 3c595d49124..588289b6e4d 100644
--- a/src/game/Chat.cpp
+++ b/src/game/Chat.cpp
@@ -1819,7 +1819,7 @@ void ChatHandler::FillMessageData(WorldPacket *data, WorldSession* session, uint
case CHAT_MSG_MONSTER_EMOTE:
case CHAT_MSG_RAID_BOSS_WHISPER:
case CHAT_MSG_RAID_BOSS_EMOTE:
- case CHAT_MSG_BN:
+ case CHAT_MSG_BATTLENET:
{
*data << uint64(speaker->GetGUID());
*data << uint32(0); // 2.1.0
@@ -1838,7 +1838,7 @@ void ChatHandler::FillMessageData(WorldPacket *data, WorldSession* session, uint
return;
}
default:
- if (type != CHAT_MSG_REPLY && type != CHAT_MSG_IGNORED && type != CHAT_MSG_DND && type != CHAT_MSG_AFK)
+ if (type != CHAT_MSG_WHISPER_INFORM && type != CHAT_MSG_IGNORED && type != CHAT_MSG_DND && type != CHAT_MSG_AFK)
target_guid = 0; // only for CHAT_MSG_WHISPER_INFORM used original value target_guid
break;
}
@@ -1855,7 +1855,7 @@ void ChatHandler::FillMessageData(WorldPacket *data, WorldSession* session, uint
*data << uint64(target_guid);
*data << uint32(messageLength);
*data << message;
- if (session != 0 && type != CHAT_MSG_REPLY && type != CHAT_MSG_DND && type != CHAT_MSG_AFK)
+ if (session != 0 && type != CHAT_MSG_WHISPER_INFORM && type != CHAT_MSG_DND && type != CHAT_MSG_AFK)
*data << uint8(session->GetPlayer()->chatTag());
else
*data << uint8(0);
diff --git a/src/game/Creature.cpp b/src/game/Creature.cpp
index 433b5e1610d..7816412a0ad 100644
--- a/src/game/Creature.cpp
+++ b/src/game/Creature.cpp
@@ -972,7 +972,7 @@ void Creature::SetLootRecipient(Unit *unit)
{
m_lootRecipient = 0;
RemoveFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE);
- RemoveFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_OTHER_TAGGER);
+ RemoveFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_TAPPED);
return;
}
@@ -981,7 +981,7 @@ void Creature::SetLootRecipient(Unit *unit)
return;
m_lootRecipient = player->GetGUID();
- SetFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_OTHER_TAGGER);
+ SetFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_TAPPED);
}
void Creature::SaveToDB()
@@ -1583,9 +1583,9 @@ void Creature::Respawn(bool force)
if (IsAIEnabled)
AI()->JustRespawned();
- uint16 poolid = poolhandler.IsPartOfAPool(GetGUIDLow(), GetTypeId());
+ uint16 poolid = GetDBTableGUIDLow() ? poolhandler.IsPartOfAPool<Creature>(GetDBTableGUIDLow()) : 0;
if (poolid)
- poolhandler.UpdatePool(poolid, GetGUIDLow(), TYPEID_UNIT);
+ poolhandler.UpdatePool<Creature>(poolid, GetDBTableGUIDLow());
}
SetToNotify();
diff --git a/src/game/Creature.h b/src/game/Creature.h
index 3aa88c1b9db..d19ee3635a1 100644
--- a/src/game/Creature.h
+++ b/src/game/Creature.h
@@ -54,6 +54,8 @@ enum CreatureFlagsExtra
//CREATURE_FLAG_EXTRA_CHARM_AI = 0x00008000, // use ai when charmed
CREATURE_FLAG_EXTRA_NO_CRIT = 0x00020000, // creature can't do critical strikes
CREATURE_FLAG_EXTRA_NO_SKILLGAIN = 0x00040000, // creature won't increase weapon skills
+ CREATURE_FLAG_EXTRA_TAUNT_DIMINISH = 0x00080000, // Taunt is a subject to diminishing returns on this creautre
+ CREATURE_FLAG_EXTRA_ALL_DIMINISH = 0x00100000, // Creature is subject to all diminishing returns as player are
};
// GCC have alternative #pragma pack(N) syntax and old gcc version not support pack(push,N), also any gcc version not support it at some platform
diff --git a/src/game/DBCEnums.h b/src/game/DBCEnums.h
index 090369d091e..715c0933bde 100644
--- a/src/game/DBCEnums.h
+++ b/src/game/DBCEnums.h
@@ -196,8 +196,11 @@ enum AchievementCriteriaTypes
ACHIEVEMENT_CRITERIA_TYPE_LEARN_SKILL_LINE= 112,
ACHIEVEMENT_CRITERIA_TYPE_EARN_HONORABLE_KILL = 113,
ACHIEVEMENT_CRITERIA_TYPE_ACCEPTED_SUMMONINGS = 114,
- // 0..114 => 115 criteria types total
- ACHIEVEMENT_CRITERIA_TYPE_TOTAL = 115,
+ // 0..115 => 116 criteria types total
+ ACHIEVEMENT_CRITERIA_TYPE_EARN_ACHIEVEMENT_POINTS = 115,
+ ACHIEVEMENT_CRITERIA_TYPE_USE_LFD_TO_GROUP_WITH_PLAYERS = 119,
+ // 0..119 => 120 criteria types total
+ ACHIEVEMENT_CRITERIA_TYPE_TOTAL = 120,
};
enum AreaFlags
@@ -283,13 +286,13 @@ enum FactionMasks
// if none flags set then non-aggressive creature
};
-enum MapTypes
+enum MapTypes // Lua_IsInInstance
{
- MAP_COMMON = 0,
- MAP_INSTANCE = 1,
- MAP_RAID = 2,
- MAP_BATTLEGROUND = 3,
- MAP_ARENA = 4
+ MAP_COMMON = 0, // none
+ MAP_INSTANCE = 1, // party
+ MAP_RAID = 2, // raid
+ MAP_BATTLEGROUND = 3, // pvp
+ MAP_ARENA = 4 // arena
};
enum AbilytyLearnType
diff --git a/src/game/DBCStores.cpp b/src/game/DBCStores.cpp
index 97985a23363..989e94fb2d5 100644
--- a/src/game/DBCStores.cpp
+++ b/src/game/DBCStores.cpp
@@ -108,7 +108,8 @@ MapDifficultyMap sMapDifficultyMap;
DBCStorage <MovieEntry> sMovieStore(MovieEntryfmt);
DBCStorage <QuestSortEntry> sQuestSortStore(QuestSortEntryfmt);
-
+DBCStorage <QuestXPEntry> sQuestXPStore(QuestXPfmt);
+DBCStorage <QuestFactionRewEntry> sQuestFactionRewardStore(QuestFactionRewardfmt);
DBCStorage <RandomPropertiesPointsEntry> sRandomPropertiesPointsStore(RandomPropertiesPointsfmt);
DBCStorage <ScalingStatDistributionEntry> sScalingStatDistributionStore(ScalingStatDistributionfmt);
DBCStorage <ScalingStatValuesEntry> sScalingStatValuesStore(ScalingStatValuesfmt);
@@ -215,7 +216,7 @@ void LoadDBCStores(const std::string& dataPath)
{
std::string dbcPath = dataPath+"dbc/";
- const uint32 DBCFilesCount = 82;
+ const uint32 DBCFilesCount = 83;
barGoLink bar(DBCFilesCount);
@@ -328,6 +329,8 @@ void LoadDBCStores(const std::string& dataPath)
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sMovieStore, dbcPath,"Movie.dbc");
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sQuestSortStore, dbcPath,"QuestSort.dbc");
+ LoadDBC(availableDbcLocales,bar,bad_dbc_files,sQuestXPStore, dbcPath,"QuestXP.dbc");
+ LoadDBC(availableDbcLocales,bar,bad_dbc_files,sQuestFactionRewardStore, dbcPath,"QuestFactionReward.dbc");
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sRandomPropertiesPointsStore, dbcPath,"RandPropPoints.dbc");
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sScalingStatDistributionStore, dbcPath,"ScalingStatDistribution.dbc");
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sScalingStatValuesStore, dbcPath,"ScalingStatValues.dbc");
@@ -523,13 +526,13 @@ void LoadDBCStores(const std::string& dataPath)
}
// Check loaded DBC files proper version
- if( !sSpellStore.LookupEntry(69599) || // last added spell in 3.2.2
- !sMapStore.LookupEntry(650) || // last map added in 3.2.2
- !sGemPropertiesStore.LookupEntry(1629) || // last gem property added in 3.2.2
- !sItemExtendedCostStore.LookupEntry(2723) || // last item extended cost added in 3.2.2
- !sCharTitlesStore.LookupEntry(171) || // last char title added in 3.2.2
- !sAreaStore.LookupEntry(3091) || // last area (areaflag) added in 3.2.2
- !sItemStore.LookupEntry(49667) ) // last client known item added in 3.2.2
+ if( !sSpellStore.LookupEntry(74445) || // last added spell in 3.3.2
+ !sMapStore.LookupEntry(718) || // last map added in 3.3.2
+ !sGemPropertiesStore.LookupEntry(1629) || // last gem property added in 3.3.2
+ !sItemExtendedCostStore.LookupEntry(2982) || // last item extended cost added in 3.3.2
+ !sCharTitlesStore.LookupEntry(177) || // last char title added in 3.3.2
+ !sAreaStore.LookupEntry(3461) || // last area (areaflag) added in 3.3.2
+ !sItemStore.LookupEntry(52686) ) // last client known item added in 3.3.2
{
sLog.outError("\nYou have _outdated_ DBC files. Please extract correct versions from current using client.");
exit(1);
diff --git a/src/game/DBCStores.h b/src/game/DBCStores.h
index 8c1fdbb8f63..fb301660525 100644
--- a/src/game/DBCStores.h
+++ b/src/game/DBCStores.h
@@ -117,6 +117,8 @@ extern DBCStorage <MapEntry> sMapStore;
extern MapDifficultyMap sMapDifficultyMap;
extern DBCStorage <MovieEntry> sMovieStore;
extern DBCStorage <QuestSortEntry> sQuestSortStore;
+extern DBCStorage <QuestXPEntry> sQuestXPStore;
+extern DBCStorage <QuestFactionRewEntry> sQuestFactionRewardStore;
extern DBCStorage <RandomPropertiesPointsEntry> sRandomPropertiesPointsStore;
extern DBCStorage <ScalingStatDistributionEntry> sScalingStatDistributionStore;
extern DBCStorage <ScalingStatValuesEntry> sScalingStatValuesStore;
diff --git a/src/game/DBCStructure.h b/src/game/DBCStructure.h
index 91517153929..15f489573ff 100644
--- a/src/game/DBCStructure.h
+++ b/src/game/DBCStructure.h
@@ -595,16 +595,13 @@ struct BattlemasterListEntry
uint32 id; // 0
int32 mapid[8]; // 1-8 mapid
uint32 type; // 9 (3 - BG, 4 - arena)
- uint32 minlvl; // 10
- uint32 maxlvl; // 11
- uint32 maxplayersperteam; // 12
- // 13 minplayers
- // 14 0 or 9
- // 15
- char* name[16]; // 16-31
- // 32 string flag, unused
- // 33 unused
- //uint32 unk; // 34 new 3.1
+ uint32 maxplayersperteam; // 10
+ //uint32 unk1; // 11 (0 or 1)
+ char* name[16]; // 12-27
+ // 28 string flag, unused
+ // 29 unused
+ //uint32 unk2; // 30 new 3.1
+
};
#define MAX_OUTFIT_ITEMS 24
@@ -812,10 +809,14 @@ struct FactionEntry
int32 BaseRepValue[4]; // 10-13 m_reputationBase
uint32 ReputationFlags[4]; // 14-17 m_reputationFlags
uint32 team; // 18 m_parentFactionID
- char* name[16]; // 19-34 m_name_lang
- // 35 string flags
- //char* description[16]; // 36-51 m_description_lang
- // 52 string flags
+ //float unk1; // 19
+ //float unk2; // 20
+ //uint32 unk3 // 21
+ //uint32 unk4; // 22
+ char* name[16]; // 23-38 m_name_lang
+ // 39 string flags
+ //char* description[16]; // 40-55 m_description_lang
+ // 56 string flags
};
struct FactionTemplateEntry
@@ -1114,23 +1115,24 @@ struct MapEntry
uint32 MapID; // 0
//char* internalname; // 1 unused
uint32 map_type; // 2
- // 3 0 or 1 for battlegrounds (not arenas)
- char* name[16]; // 4-19
- // 20 name flags, unused
- uint32 linked_zone; // 21 common zone for instance and continent map
- //char* hordeIntro[16]; // 23-37 text for PvP Zones
- // 38 intro text flags
- //char* allianceIntro[16]; // 39-54 text for PvP Zones
- // 55 intro text flags
- uint32 multimap_id; // 56
- // 57
- int32 entrance_map; // 58 map_id of entrance map
- float entrance_x; // 59 entrance x coordinate (if exist single entry)
- float entrance_y; // 60 entrance y coordinate (if exist single entry)
- // 61 -1, 0 and 720
- uint32 addon; // 62 (0-original maps,1-tbc addon)
- uint32 unk_time; // 63 some kind of time? - for pre-bc raids
- //uint32 maxPlayers; // 64 max players
+ //uint32 unk_330; // 3
+ // 4 0 or 1 for battlegrounds (not arenas)
+ char* name[16]; // 5-20
+ // 21 name flags, unused
+ uint32 linked_zone; // 22 common zone for instance and continent map
+ //char* hordeIntro[16]; // 23-38 text for PvP Zones
+ // 39 intro text flags
+ //char* allianceIntro[16]; // 40-55 text for PvP Zones
+ // 56 intro text flags
+ uint32 multimap_id; // 57
+ // 58
+ int32 entrance_map; // 59 map_id of entrance map
+ float entrance_x; // 60 entrance x coordinate (if exist single entry)
+ float entrance_y; // 61 entrance y coordinate (if exist single entry)
+ // 62 -1, 0 and 720
+ uint32 addon; // 63 (0-original maps,1-tbc addon)
+ uint32 unk_time; // 64 some kind of time?
+ //uint32 maxPlayers; // 65 max players
// Helpers
uint32 Expansion() const { return addon; }
@@ -1195,6 +1197,18 @@ struct QuestSortEntry
// 17 name flags
};
+struct QuestXPEntry
+{
+ uint32 id;
+ uint32 Exp[10];
+};
+
+struct QuestFactionRewEntry
+{
+ uint32 id;
+ int32 QuestRewFactionValue[10];
+};
+
struct RandomPropertiesPointsEntry
{
//uint32 Id; // 0 hidden key
@@ -1221,19 +1235,20 @@ struct ScalingStatValuesEntry
uint32 dpsMod[6]; // 10-15 DPS mod for level
uint32 spellBonus; // 16 spell power for level
uint32 ssdMultiplier2; // 17 there's data from 3.1 dbc ssdMultiplier[3]
- //uint32 unk1; // 18 all fields equal to 0
- //uint32 unk2; // 19 unk, probably also Armor for level
+ uint32 ssdMultiplier3; // 18 3.3
+ //uint32 unk2; // 19 unk, probably also Armor for level (flag 0x80000?)
uint32 armorMod2[4]; // 20-23 Armor for level
uint32 getssdMultiplier(uint32 mask) const
{
- if (mask & 0x001F)
+ if (mask & 0x4001F)
{
if(mask & 0x00000001) return ssdMultiplier[0];
if(mask & 0x00000002) return ssdMultiplier[1];
if(mask & 0x00000004) return ssdMultiplier[2];
if(mask & 0x00000008) return ssdMultiplier2;
if(mask & 0x00000010) return ssdMultiplier[3];
+ if(mask & 0x00040000) return ssdMultiplier3;
}
return 0;
}
@@ -1407,7 +1422,7 @@ struct SpellEntry
//uint32 modalNextSpell; // 48 m_modalNextSpell not used
uint32 StackAmount; // 49 m_cumulativeAura
uint32 Totem[2]; // 50-51 m_totem
- int32 Reagent[8]; // 50-59 m_reagent
+ int32 Reagent[8]; // 52-59 m_reagent
uint32 ReagentCount[8]; // 60-67 m_reagentCount
int32 EquippedItemClass; // 68 m_equippedItemClass (value)
int32 EquippedItemSubClassMask; // 69 m_equippedItemSubclass (mask)
@@ -1421,8 +1436,8 @@ struct SpellEntry
uint32 EffectMechanic[MAX_SPELL_EFFECTS]; // 89-91 m_effectMechanic
uint32 EffectImplicitTargetA[MAX_SPELL_EFFECTS]; // 92-94 m_implicitTargetA
uint32 EffectImplicitTargetB[MAX_SPELL_EFFECTS]; // 95-97 m_implicitTargetB
- uint32 EffectRadiusIndex[MAX_SPELL_EFFECTS]; // 98-100 m_effectRadiusIndex - spellradius.dbc
- uint32 EffectApplyAuraName[MAX_SPELL_EFFECTS]; // 101-103 m_effectAura
+ uint32 EffectRadiusIndex[MAX_SPELL_EFFECTS]; // 98-100 m_effectRadiusIndex - spellradius.dbc
+ uint32 EffectApplyAuraName[MAX_SPELL_EFFECTS]; // 101-103 m_effectAura
uint32 EffectAmplitude[MAX_SPELL_EFFECTS]; // 104-106 m_effectAuraPeriod
float EffectMultipleValue[MAX_SPELL_EFFECTS]; // 107-109 m_effectAmplitude
uint32 EffectChainTarget[MAX_SPELL_EFFECTS]; // 110-112 m_effectChainTargets
@@ -1431,6 +1446,43 @@ struct SpellEntry
int32 EffectMiscValueB[MAX_SPELL_EFFECTS]; // 119-121 m_effectMiscValueB
uint32 EffectTriggerSpell[MAX_SPELL_EFFECTS]; // 122-124 m_effectTriggerSpell
float EffectPointsPerComboPoint[MAX_SPELL_EFFECTS]; // 125-127 m_effectPointsPerCombo
+ flag96 EffectSpellClassMask[MAX_SPELL_EFFECTS]; // 128-136
+ uint32 SpellVisual[2]; // 137-138 m_spellVisualID
+ uint32 SpellIconID; // 139 m_spellIconID
+ uint32 activeIconID; // 140 m_activeIconID
+ //uint32 spellPriority; // 141 not used
+ char* SpellName[16]; // 142-157 m_name_lang
+ //uint32 SpellNameFlag; // 158 not used
+ char* Rank[16]; // 159-174 m_nameSubtext_lang
+ //uint32 RankFlags; // 175 not used
+ //char* Description[16]; // 176-191 m_description_lang not used
+ //uint32 DescriptionFlags; // 192 not used
+ //char* ToolTip[16]; // 193-208 m_auraDescription_lang not used
+ //uint32 ToolTipFlags; // 209 not used
+ uint32 ManaCostPercentage; // 210 m_manaCostPct
+ uint32 StartRecoveryCategory; // 211 m_startRecoveryCategory
+ uint32 StartRecoveryTime; // 212 m_startRecoveryTime
+ uint32 MaxTargetLevel; // 213 m_maxTargetLevel
+ uint32 SpellFamilyName; // 214 m_spellClassSet
+ flag96 SpellFamilyFlags; // 215-217
+ uint32 MaxAffectedTargets; // 218 m_maxTargets
+ uint32 DmgClass; // 219 m_defenseType
+ uint32 PreventionType; // 220 m_preventionType
+ //uint32 StanceBarOrder; // 221 m_stanceBarOrder not used
+ float DmgMultiplier[3]; // 222-224 m_effectChainAmplitude
+ //uint32 MinFactionId; // 225 m_minFactionID not used
+ //uint32 MinReputation; // 226 m_minReputation not used
+ //uint32 RequiredAuraVision; // 227 m_requiredAuraVision not used
+ uint32 TotemCategory[2]; // 228-229 m_requiredTotemCategoryID
+ int32 AreaGroupId; // 230 m_requiredAreaGroupId
+ uint32 SchoolMask; // 231 m_schoolMask
+ uint32 runeCostID; // 232 m_runeCostID
+ //uint32 spellMissileID; // 233 m_spellMissileID not used
+ //uint32 PowerDisplayId; // 234 PowerDisplay.dbc, new in 3.1
+ //float unk_320_4[3]; // 235-237 3.2.0
+ //uint32 spellDescriptionVariableID; // 238 3.2.0
+ //uint32 SpellDifficultyId; // 239 3.3.0
+ /*
flag96 EffectSpellClassMask[MAX_SPELL_EFFECTS]; // 127-136
uint32 SpellVisual[2]; // 137-138 m_spellVisualID
uint32 SpellIconID; // 139 m_spellIconID
@@ -1466,7 +1518,7 @@ struct SpellEntry
//uint32 PowerDisplayId; // 234 PowerDisplay.dbc, new in 3.1
//float unk_320_4[3]; // 235-237 3.2.0
//uint32 spellDescriptionVariableID; // 238 3.2.0
-
+*/
// helpers
int32 CalculateSimpleValue(uint8 eff) const { return EffectBasePoints[eff]+int32(EffectBaseDice[eff]); }
diff --git a/src/game/DBCfmt.h b/src/game/DBCfmt.h
index bac2ff19028..a323e47501a 100644
--- a/src/game/DBCfmt.h
+++ b/src/game/DBCfmt.h
@@ -30,7 +30,7 @@ const char AreaTriggerEntryfmt[]="niffffffff";
const char AuctionHouseEntryfmt[]="niiixxxxxxxxxxxxxxxxx";
const char BankBagSlotPricesEntryfmt[]="ni";
const char BarberShopStyleEntryfmt[]="nixxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxiii";
-const char BattlemasterListEntryfmt[]="niiiiiiiiiiiixxxssssssssssssssssxxx";
+const char BattlemasterListEntryfmt[]="niiiiiiiiiixssssssssssssssssxxx";
const char CharStartOutfitEntryfmt[]="diiiiiiiiiiiiiiiiiiiiiiiiixxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
const char CharTitlesEntryfmt[]="nxssssssssssssssssxxxxxxxxxxxxxxxxxxi";
const char ChatChannelsEntryfmt[]="iixssssssssssssssssxxxxxxxxxxxxxxxxxx";
@@ -47,7 +47,7 @@ const char DurabilityCostsfmt[]="niiiiiiiiiiiiiiiiiiiiiiiiiiiii";
const char DurabilityQualityfmt[]="nf";
const char EmotesEntryfmt[]="nxxiiix";
const char EmotesTextEntryfmt[]="nxixxxxxxxxxxxxxxxx";
-const char FactionEntryfmt[]="niiiiiiiiiiiiiiiiiissssssssssssssssxxxxxxxxxxxxxxxxxx";
+const char FactionEntryfmt[]="niiiiiiiiiiiiiiiiiixxxxssssssssssssssssxxxxxxxxxxxxxxxxxx";
const char FactionTemplateEntryfmt[]="niiiiiiiiiiiii";
const char GameObjectDisplayInfofmt[]="nxxxxxxxxxxxffffffx";
const char GemPropertiesEntryfmt[]="nixxi";
@@ -75,19 +75,21 @@ const char ItemRandomSuffixfmt[]="nssssssssssssssssxxiiiiiiiiii";
const char ItemSetEntryfmt[]="dssssssssssssssssxxxxxxxxxxxxxxxxxxiiiiiiiiiiiiiiiiii";
const char LockEntryfmt[]="niiiiiiiiiiiiiiiiiiiiiiiixxxxxxxx";
const char MailTemplateEntryfmt[]="nxxxxxxxxxxxxxxxxxssssssssssssssssx";
-const char MapEntryfmt[]="nxixssssssssssssssssxixxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxixiffxiix";
+const char MapEntryfmt[]="nxixxssssssssssssssssxixxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxixiffxiix";
const char MapDifficultyEntryfmt[]="diixxxxxxxxxxxxxxxxxiix";
const char MovieEntryfmt[]="nxx";
const char QuestSortEntryfmt[]="nxxxxxxxxxxxxxxxxx";
+const char QuestXPfmt[]="niiiiiiiiii";
+const char QuestFactionRewardfmt[]="niiiiiiiiii";
const char RandomPropertiesPointsfmt[]="niiiiiiiiiiiiiii";
const char ScalingStatDistributionfmt[]="niiiiiiiiiiiiiiiiiiiii";
-const char ScalingStatValuesfmt[]="iniiiiiiiiiiiiiiiixxiiii";
+const char ScalingStatValuesfmt[]="iniiiiiiiiiiiiiiiiixiiii";
const char SkillLinefmt[]="nixssssssssssssssssxxxxxxxxxxxxxxxxxxixxxxxxxxxxxxxxxxxi";
const char SkillLineAbilityfmt[]="niiiixxiiiiixx";
const char SoundEntriesfmt[]="nxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
const char SpellCastTimefmt[]="nixx";
const char SpellDurationfmt[]="niii";
-const char SpellEntryfmt[]="niiiiiiiiiiiixixiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiifxiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiffffffiiiiiiiiiiiiiiiiiiiiifffiiiiiiiiiiiiiiifffiiiiiiiiiiiiixssssssssssssssssxssssssssssssssssxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxiiiiiiiiiiixfffxxxiiiiixxxxxx";
+const char SpellEntryfmt[]="niiiiiiiiiiiixixiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiifxiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiffffffiiiiiiiiiiiiiiiiiiiiifffiiiiiiiiiiiiiiifffiiiiiiiiiiiiixssssssssssssssssxssssssssssssssssxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxiiiiiiiiiiixfffxxxiiiiixxxxxxx";
const std::string CustomSpellEntryfmt="pappppppppaaaaaapaaaaaaaaaaapaaapapppppppaaaaapaapaaaaaaaaaaaaaaaaaappppppppppppppppppppppppppppppppppppppppppaaaaaapppppppppaaapppppppppaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaappppppppapppaaaaappaaaaaaa";
const std::string CustomSpellEntryIndex = "Id";
const char SpellFocusObjectfmt[]="nxxxxxxxxxxxxxxxxx";
diff --git a/src/game/GameEventMgr.cpp b/src/game/GameEventMgr.cpp
index 19c716007ec..fb1ab876f6e 100644
--- a/src/game/GameEventMgr.cpp
+++ b/src/game/GameEventMgr.cpp
@@ -1301,11 +1301,7 @@ void GameEventMgr::GameEventSpawn(int16 event_id)
}
for (IdList::iterator itr = mGameEventPoolIds[internal_event_id].begin(); itr != mGameEventPoolIds[internal_event_id].end(); ++itr)
- {
- poolhandler.SpawnPool(*itr, 0, 0);
- poolhandler.SpawnPool(*itr, 0, TYPEID_GAMEOBJECT);
- poolhandler.SpawnPool(*itr, 0, TYPEID_UNIT);
- }
+ poolhandler.SpawnPool(*itr);
}
void GameEventMgr::GameEventUnspawn(int16 event_id)
diff --git a/src/game/GameObject.cpp b/src/game/GameObject.cpp
index 30045eb7ddf..e7a1871f07e 100644
--- a/src/game/GameObject.cpp
+++ b/src/game/GameObject.cpp
@@ -73,6 +73,9 @@ GameObject::~GameObject()
void GameObject::CleanupsBeforeDelete(bool finalCleanup)
{
+ if (IsInWorld())
+ RemoveFromWorld();
+
if(m_uint32Values) // field array can be not exist if GameOBject not loaded
{
// Possible crash at access to deleted GO in Unit::m_gameobj
@@ -224,9 +227,15 @@ void GameObject::Update(uint32 /*p_time*/)
case GAMEOBJECT_TYPE_TRAP:
{
// Arming Time for GAMEOBJECT_TYPE_TRAP (6)
- Unit* owner = GetOwner();
- if (owner && owner->isInCombat())
- m_cooldownTime = time(NULL) + GetGOInfo()->trap.startDelay;
+ GameObjectInfo const* goInfo = GetGOInfo();
+ // Bombs
+ if (goInfo->trap.charges == 2)
+ m_cooldownTime = time(NULL) + 10; // Hardcoded tooltip value
+ else if (Unit* owner = GetOwner())
+ {
+ if (owner->isInCombat())
+ m_cooldownTime = time(NULL) + goInfo->trap.startDelay;
+ }
m_lootState = GO_READY;
break;
}
@@ -301,9 +310,9 @@ void GameObject::Update(uint32 /*p_time*/)
return;
}
// respawn timer
- uint16 poolid = poolhandler.IsPartOfAPool(GetGUIDLow(), TYPEID_GAMEOBJECT);
+ uint16 poolid = GetDBTableGUIDLow() ? poolhandler.IsPartOfAPool<GameObject>(GetDBTableGUIDLow()) : 0;
if (poolid)
- poolhandler.UpdatePool(poolid, GetGUIDLow(), TYPEID_GAMEOBJECT);
+ poolhandler.UpdatePool<GameObject>(poolid, GetDBTableGUIDLow());
else
GetMap()->Add(this);
break;
@@ -320,7 +329,15 @@ void GameObject::Update(uint32 /*p_time*/)
if(m_cooldownTime >= time(NULL))
return;
- // traps
+ // Type 2 - Bomb ( will go away after casting it's spell )
+ if(goInfo->trap.charges == 2)
+ {
+ if(goInfo->trap.spellId)
+ CastSpell(NULL, goInfo->trap.spellId); // FIXME: null target won't work for target type 1
+ SetLootState(GO_JUST_DEACTIVATED);
+ break;
+ }
+ // Type 0 and 1 - trap ( type 0 will not get removed after casting a spell )
Unit* owner = GetOwner();
Unit* ok = NULL; // pointer to appropriate target if found any
@@ -373,11 +390,7 @@ void GameObject::Update(uint32 /*p_time*/)
m_cooldownTime = time(NULL) + 4; // 4 seconds
- // count charges
- //if(goInfo->trap.charges > 0)
- // AddUse();
-
- if(owner)
+ if(owner) // || goInfo->trap.charges == 1)
SetLootState(GO_JUST_DEACTIVATED);
if(IsBattleGroundTrap && ok->GetTypeId() == TYPEID_PLAYER)
@@ -524,9 +537,9 @@ void GameObject::Delete()
SetGoState(GO_STATE_READY);
SetUInt32Value(GAMEOBJECT_FLAGS, GetGOInfo()->flags);
- uint16 poolid = poolhandler.IsPartOfAPool(GetGUIDLow(), TYPEID_GAMEOBJECT);
+ uint16 poolid = GetDBTableGUIDLow() ? poolhandler.IsPartOfAPool<GameObject>(GetDBTableGUIDLow()) : 0;
if (poolid)
- poolhandler.UpdatePool(poolid, GetGUIDLow(), TYPEID_GAMEOBJECT);
+ poolhandler.UpdatePool<GameObject>(poolid, GetDBTableGUIDLow());
else
AddObjectToRemoveList();
}
@@ -1118,6 +1131,11 @@ void GameObject::Use(Unit* user)
break;
}
+ if (BattleGround* bg = player->GetBattleGround())
+ {
+ bg->EventPlayerUsedGO(player, this);
+ }
+
player->CastedCreatureOrGO(info->id, GetGUID(), 0);
}
@@ -1489,14 +1507,14 @@ void GameObject::CastSpell(Unit* target, uint32 spellId)
if(Unit *owner = GetOwner())
{
trigger->setFaction(owner->getFaction());
- trigger->CastSpell(target, spellInfo, true, 0, 0, owner->GetGUID());
+ trigger->CastSpell(target ? target : trigger, spellInfo, true, 0, 0, owner->GetGUID());
}
else
{
trigger->setFaction(14);
// Set owner guid for target if no owner avalible - needed by trigger auras
// - trigger gets despawned and there's no caster avalible (see AuraEffect::TriggerSpell())
- trigger->CastSpell(target, spellInfo, true, 0, 0, target ? target->GetGUID() : 0);
+ trigger->CastSpell(target ? target : trigger, spellInfo, true, 0, 0, target ? target->GetGUID() : 0);
}
//trigger->setDeathState(JUST_DIED);
//trigger->RemoveCorpse();
@@ -1531,11 +1549,18 @@ bool GameObject::IsInRange(float x, float y, float z, float radius) const
&& dz < info->maxZ + radius && dz > info->minZ - radius;
}
-void GameObject::TakenDamage(uint32 damage)
+void GameObject::TakenDamage(uint32 damage, Unit *who)
{
if (!m_goValue->building.health)
return;
+ Player* pwho = NULL;
+ if(who && who->GetTypeId() == TYPEID_PLAYER)
+ pwho = (Player*)who;
+
+ if(who && who->IsVehicle())
+ pwho = (Player*)who->GetCharmerOrOwner();
+
if (m_goValue->building.health > damage)
m_goValue->building.health -= damage;
else
@@ -1550,7 +1575,12 @@ void GameObject::TakenDamage(uint32 damage)
SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_DESTROYED);
SetUInt32Value(GAMEOBJECT_DISPLAYID, m_goInfo->building.destroyedDisplayId);
EventInform(m_goInfo->building.destroyedEvent);
- }
+ if(pwho)
+ {
+ if(BattleGround* bg = pwho->GetBattleGround())
+ bg->EventPlayerDamagedGO(pwho, this, m_goInfo->building.destroyedEvent);
+ }
+ }
}
else // from intact to damaged
{
diff --git a/src/game/GameObject.h b/src/game/GameObject.h
index 7f84bb2d3ec..671bd84addf 100644
--- a/src/game/GameObject.h
+++ b/src/game/GameObject.h
@@ -725,7 +725,7 @@ class GameObject : public WorldObject, public GridObject<GameObject>
void CastSpell(Unit *target, uint32 spell);
void SendCustomAnim();
bool IsInRange(float x, float y, float z, float radius) const;
- void TakenDamage(uint32 damage);
+ void TakenDamage(uint32 damage, Unit* who = NULL);
void Rebuild();
void EventInform(uint32 eventId);
diff --git a/src/game/GossipDef.cpp b/src/game/GossipDef.cpp
index f4587917630..f35205a8c09 100644
--- a/src/game/GossipDef.cpp
+++ b/src/game/GossipDef.cpp
@@ -434,8 +434,6 @@ void PlayerMenu::SendQuestGiverStatus( uint8 questStatus, uint64 npcGUID )
void PlayerMenu::SendQuestGiverQuestDetails( Quest const *pQuest, uint64 npcGUID, bool ActivateAccept )
{
- WorldPacket data(SMSG_QUESTGIVER_QUEST_DETAILS, 100); // guess size
-
std::string Title = pQuest->GetTitle();
std::string Details = pQuest->GetDetails();
std::string Objectives = pQuest->GetObjectives();
@@ -458,16 +456,18 @@ void PlayerMenu::SendQuestGiverQuestDetails( Quest const *pQuest, uint64 npcGUID
}
}
+ WorldPacket data(SMSG_QUESTGIVER_QUEST_DETAILS, 100); // guess size
data << uint64(npcGUID);
data << uint64(0); // wotlk, something todo with quest sharing?
data << uint32(pQuest->GetQuestId());
data << Title;
data << Details;
data << Objectives;
- data << uint32(ActivateAccept);
+ data << uint8(ActivateAccept ? 1 : 0);
data << uint32(pQuest->GetSuggestedPlayers());
data << uint8(0); // new wotlk
data << uint8(0); // new 3.1
+ data << uint8(0); // new 3.3.0
if (pQuest->HasFlag(QUEST_FLAGS_HIDDEN_REWARDS))
{
@@ -508,12 +508,25 @@ void PlayerMenu::SendQuestGiverQuestDetails( Quest const *pQuest, uint64 npcGUID
data << uint32(pQuest->GetRewOrReqMoney());
}
+ data << uint32(0);
// rewarded honor points. Multiply with 10 to satisfy client
data << uint32(10*Trinity::Honor::hk_honor_at_level(pSession->GetPlayer()->getLevel(), pQuest->GetRewHonorableKills()));
+ data << float(0); // new 3.3.0
data << uint32(pQuest->GetRewSpell()); // reward spell, this spell will display (icon) (casted if RewSpellCast==0)
data << int32(pQuest->GetRewSpellCast()); // casted spell
data << uint32(pQuest->GetCharTitleId()); // CharTitleId, new 2.4.0, player gets this title (id from CharTitles)
data << uint32(pQuest->GetBonusTalents()); // bonus talents
+ data << uint32(0);
+ data << uint32(0);
+
+ for(int i = 0; i < QUEST_REPUTATIONS_COUNT; ++i)
+ data << uint32(pQuest->RewRepFaction[i]);
+
+ for(int i = 0; i < QUEST_REPUTATIONS_COUNT; ++i)
+ data << int32(pQuest->RewRepValueId[i]);
+
+ for(int i = 0; i < QUEST_REPUTATIONS_COUNT; ++i)
+ data << int32(pQuest->RewRepValue[i]);
data << uint32(QUEST_EMOTE_COUNT);
for (uint32 i=0; i < QUEST_EMOTE_COUNT; ++i)
@@ -563,6 +576,7 @@ void PlayerMenu::SendQuestQueryResponse( Quest const *pQuest )
data << uint32(pQuest->GetQuestId()); // quest id
data << uint32(pQuest->GetQuestMethod()); // Accepted values: 0, 1 or 2. 0==IsAutoComplete() (skip objectives/details)
data << uint32(pQuest->GetQuestLevel()); // may be -1, static data, in other cases must be used dynamic level: Player::GetQuestLevel (0 is not known, but assuming this is no longer valid for quest intended for client)
+ data << uint32(pQuest->GetMinLevel()); // min level
data << uint32(pQuest->GetZoneOrSort()); // zone or sort to display in quest log
data << uint32(pQuest->GetType()); // quest type
@@ -575,6 +589,7 @@ void PlayerMenu::SendQuestQueryResponse( Quest const *pQuest )
data << uint32(pQuest->GetRepObjectiveValue2()); // shown in quest log as part of quest objective OPPOSITE faction
data << uint32(pQuest->GetNextQuestInChain()); // client will request this quest from NPC, if not 0
+ data << uint32(0); // unk 3.3.0
if (pQuest->HasFlag(QUEST_FLAGS_HIDDEN_REWARDS))
data << uint32(0); // Hide money rewarded
@@ -587,11 +602,14 @@ void PlayerMenu::SendQuestQueryResponse( Quest const *pQuest )
// rewarded honor points
data << uint32(Trinity::Honor::hk_honor_at_level(pSession->GetPlayer()->getLevel(), pQuest->GetRewHonorableKills()));
+ data << float(0); // new reward honor (multipled by ~62 at client side)
data << uint32(pQuest->GetSrcItemId()); // source item id
data << uint32(pQuest->GetFlags() & 0xFFFF); // quest flags
data << uint32(pQuest->GetCharTitleId()); // CharTitleId, new 2.4.0, player gets this title (id from CharTitles)
data << uint32(pQuest->GetPlayersSlain()); // players slain
data << uint32(pQuest->GetBonusTalents()); // bonus talents
+ data << uint32(0); // bonus arena points
+ data << uint32(0); // unknown
int iI;
@@ -616,6 +634,15 @@ void PlayerMenu::SendQuestQueryResponse( Quest const *pQuest )
}
}
+ for(int i = 0; i < QUEST_REPUTATIONS_COUNT; ++i) // reward factions ids
+ data << uint32(pQuest->RewRepFaction[i]);
+
+ for(int i = 0; i < QUEST_REPUTATIONS_COUNT; ++i) // columnid+1 QuestFactionReward.dbc?
+ data << int32(pQuest->RewRepValueId[i]);
+
+ for(int i = 0; i < QUEST_REPUTATIONS_COUNT; ++i) // unk (0)
+ data << int32(pQuest->RewRepValue[i]);
+
data << pQuest->GetPointMapId();
data << pQuest->GetPointX();
data << pQuest->GetPointY();
@@ -625,6 +652,7 @@ void PlayerMenu::SendQuestQueryResponse( Quest const *pQuest )
data << Objectives;
data << Details;
data << EndText;
+ data << uint8(0); // some string
for (iI = 0; iI < QUEST_OBJECTIVES_COUNT; ++iI)
{
@@ -639,6 +667,7 @@ void PlayerMenu::SendQuestQueryResponse( Quest const *pQuest )
}
data << uint32(pQuest->ReqCreatureOrGOCount[iI]);
data << uint32(pQuest->ReqSourceId[iI]);
+ data << uint32(0); // req source count?
}
for (iI = 0; iI < QUEST_ITEM_OBJECTIVES_COUNT; ++iI)
@@ -674,12 +703,12 @@ void PlayerMenu::SendQuestGiverOfferReward( Quest const* pQuest, uint64 npcGUID,
WorldPacket data( SMSG_QUESTGIVER_OFFER_REWARD, 50 ); // guess size
- data << npcGUID;
- data << pQuest->GetQuestId();
+ data << uint64(npcGUID);
+ data << uint32(pQuest->GetQuestId());
data << Title;
data << OfferRewardText;
- data << uint32( EnableNext );
+ data << uint8(EnableNext ? 1 : 0);
data << uint32(0); // unk
uint32 EmoteCount = 0;
@@ -726,15 +755,29 @@ void PlayerMenu::SendQuestGiverOfferReward( Quest const* pQuest, uint64 npcGUID,
data << uint32(0);
}
+ data << uint32(0);
data << uint32(pQuest->GetRewOrReqMoney());
// rewarded honor points. Multiply with 10 to satisfy client
data << uint32(10*Trinity::Honor::hk_honor_at_level(pSession->GetPlayer()->getLevel(), pQuest->GetRewHonorableKills()));
+ data << float(0);
data << uint32(0x08); // unused by client?
data << uint32(pQuest->GetRewSpell()); // reward spell, this spell will display (icon) (casted if RewSpellCast==0)
data << int32(pQuest->GetRewSpellCast()); // casted spell
data << uint32(0); // unknown
data << uint32(pQuest->GetBonusTalents()); // bonus talents
+ data << uint32(0);
+ data << uint32(0);
+
+ for(int i = 0; i < QUEST_REPUTATIONS_COUNT; ++i) // reward factions ids
+ data << uint32(pQuest->RewRepFaction[i]);
+
+ for(int i = 0; i < QUEST_REPUTATIONS_COUNT; ++i) // columnid in QuestFactionReward.dbc (zero based)?
+ data << int32(pQuest->RewRepValueId[i]);
+
+ for(int i = 0; i < QUEST_REPUTATIONS_COUNT; ++i) // reward reputation override?
+ data << uint32(pQuest->RewRepValue[i]);
+
pSession->SendPacket( &data );
sLog.outDebug( "WORLD: Sent SMSG_QUESTGIVER_OFFER_REWARD NPCGuid=%u, questid=%u", GUID_LOPART(npcGUID), pQuest->GetQuestId() );
}
diff --git a/src/game/Group.cpp b/src/game/Group.cpp
index a4ebf7bfc27..abd1c2c8869 100644
--- a/src/game/Group.cpp
+++ b/src/game/Group.cpp
@@ -364,8 +364,9 @@ uint32 Group::RemoveMember(const uint64 &guid, const uint8 &method)
}
else
{
- data.Initialize(SMSG_GROUP_LIST, 24);
- data << uint64(0) << uint64(0) << uint64(0);
+ data.Initialize(SMSG_GROUP_LIST, 1+1+1+1+8+4+4+8);
+ data << uint8(0x10) << uint8(0) << uint8(0) << uint8(0);
+ data << uint64(0) << uint32(0) << uint32(0) << uint64(0);
player->GetSession()->SendPacket(&data);
}
@@ -447,8 +448,9 @@ void Group::Disband(bool hideDestroy)
}
else
{
- data.Initialize(SMSG_GROUP_LIST, 24);
- data << uint64(0) << uint64(0) << uint64(0);
+ data.Initialize(SMSG_GROUP_LIST, 1+1+1+1+8+4+4+8);
+ data << uint8(0x10) << uint8(0) << uint8(0) << uint8(0);
+ data << uint64(0) << uint32(0) << uint32(0) << uint64(0);
player->GetSession()->SendPacket(&data);
}
@@ -479,7 +481,7 @@ void Group::Disband(bool hideDestroy)
void Group::SendLootStartRoll(uint32 CountDown, const Roll &r)
{
- WorldPacket data(SMSG_LOOT_START_ROLL, (8+4+4+4+4+4+4));
+ WorldPacket data(SMSG_LOOT_START_ROLL, (8+4+4+4+4+4+4+1));
data << uint64(r.itemGUID); // guid of rolled item
data << uint32(r.totalPlayersRolling); // maybe the number of players rolling for it???
data << uint32(r.itemid); // the itemEntryId for the item that shall be rolled for
@@ -487,6 +489,7 @@ void Group::SendLootStartRoll(uint32 CountDown, const Roll &r)
data << uint32(r.itemRandomPropId); // item random property ID
data << uint32(r.itemCount); // items in stack
data << uint32(CountDown); // the countdown time to choose "need" or "greed"
+ data << uint8(ALL_ROLL_TYPE_MASK); // roll type mask
for (Roll::PlayerVote::const_iterator itr=r.playerVote.begin(); itr!=r.playerVote.end(); ++itr)
{
@@ -751,8 +754,15 @@ void Group::CountRollVote(const uint64& playerGUID, const uint64& Guid, uint32 N
itr->second = GREED;
}
break;
+ case ROLL_DISENCHANT: // player choose Disenchant
+ {
+ SendLootRoll(0, playerGUID, 128, ROLL_DISENCHANT, *roll);
+ ++roll->totalGreed;
+ itr->second = DISENCHANT;
+ }
+ break;
}
- if (roll->totalPass + roll->totalGreed + roll->totalNeed >= roll->totalPlayersRolling)
+ if (roll->totalPass + roll->totalNeed + roll->totalGreed >= roll->totalPlayersRolling)
{
CountTheRoll(rollI, NumberOfPlayers);
}
@@ -833,42 +843,56 @@ void Group::CountTheRoll(Rolls::iterator rollI, uint32 NumberOfPlayers)
uint8 maxresul = 0;
uint64 maxguid = (*roll->playerVote.begin()).first;
Player *player;
+ RollVote rollvote;
Roll::PlayerVote::iterator itr;
for (itr=roll->playerVote.begin(); itr!=roll->playerVote.end(); ++itr)
{
- if (itr->second != GREED)
+ if (itr->second != GREED && itr->second != DISENCHANT)
continue;
uint8 randomN = urand(1, 99);
- SendLootRoll(0, itr->first, randomN, ROLL_GREED, *roll);
+ SendLootRoll(0, itr->first, randomN, itr->second, *roll);
if (maxresul < randomN)
{
maxguid = itr->first;
maxresul = randomN;
+ rollvote = itr->second;
}
}
- SendLootRollWon(0, maxguid, maxresul, ROLL_GREED, *roll);
+ SendLootRollWon(0, maxguid, maxresul, rollvote, *roll);
player = objmgr.GetPlayer(maxguid);
if(player && player->GetSession())
{
player->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_ROLL_GREED_ON_LOOT, roll->itemid, maxresul);
- ItemPosCountVec dest;
LootItem *item = &(roll->getLoot()->items[roll->itemSlot]);
- uint8 msg = player->CanStoreNewItem( NULL_BAG, NULL_SLOT, dest, roll->itemid, item->count );
- if ( msg == EQUIP_ERR_OK )
+
+ if(rollvote == GREED)
+ {
+ ItemPosCountVec dest;
+ uint8 msg = player->CanStoreNewItem( NULL_BAG, NULL_SLOT, dest, roll->itemid, item->count );
+ if ( msg == EQUIP_ERR_OK )
+ {
+ item->is_looted = true;
+ roll->getLoot()->NotifyItemRemoved(roll->itemSlot);
+ --roll->getLoot()->unlootedCount;
+ player->StoreNewItem( dest, roll->itemid, true, item->randomPropertyId);
+ }
+ else
+ {
+ item->is_blocked = false;
+ player->SendEquipError( msg, NULL, NULL );
+ }
+ }
+ else if(rollvote == DISENCHANT)
{
item->is_looted = true;
roll->getLoot()->NotifyItemRemoved(roll->itemSlot);
--roll->getLoot()->unlootedCount;
- player->StoreNewItem( dest, roll->itemid, true, item->randomPropertyId);
- }
- else
- {
- item->is_blocked = false;
- player->SendEquipError( msg, NULL, NULL );
+ ItemPrototype const *pProto = ObjectMgr::GetItemPrototype(roll->itemid);
+ player->AutoStoreLoot(pProto->DisenchantID, LootTemplates_Disenchant, true);
}
}
}
@@ -883,23 +907,24 @@ void Group::CountTheRoll(Rolls::iterator rollI, uint32 NumberOfPlayers)
delete roll;
}
-void Group::SetTargetIcon(uint8 id, uint64 guid)
+void Group::SetTargetIcon(uint8 id, uint64 whoGuid, uint64 targetGuid)
{
if(id >= TARGETICONCOUNT)
return;
// clean other icons
- if( guid != 0 )
+ if( targetGuid != 0 )
for (int i=0; i<TARGETICONCOUNT; ++i)
- if( m_targetIcons[i] == guid )
- SetTargetIcon(i, 0);
+ if( m_targetIcons[i] == targetGuid )
+ SetTargetIcon(i, 0, 0);
- m_targetIcons[id] = guid;
+ m_targetIcons[id] = targetGuid;
- WorldPacket data(MSG_RAID_TARGET_UPDATE, (2+8));
- data << (uint8)0;
- data << id;
- data << guid;
+ WorldPacket data(MSG_RAID_TARGET_UPDATE, (1+8+1+8));
+ data << uint8(0); // set targets
+ data << uint64(whoGuid);
+ data << uint8(id);
+ data << uint64(targetGuid);
BroadcastPacket(&data, true);
}
@@ -932,15 +957,15 @@ void Group::SendTargetIconList(WorldSession *session)
return;
WorldPacket data(MSG_RAID_TARGET_UPDATE, (1+TARGETICONCOUNT*9));
- data << (uint8)1;
+ data << uint8(1); // list targets
for (int i=0; i<TARGETICONCOUNT; ++i)
{
if(m_targetIcons[i] == 0)
continue;
- data << (uint8)i;
- data << m_targetIcons[i];
+ data << uint8(i);
+ data << uint64(m_targetIcons[i]);
}
session->SendPacket(&data);
@@ -957,18 +982,24 @@ void Group::SendUpdate()
continue;
// guess size
WorldPacket data(SMSG_GROUP_LIST, (1+1+1+1+8+4+GetMembersCount()*20));
- data << uint8(m_groupType); // group type
+ data << uint8(m_groupType); // group type (flags in 3.3)
data << uint8(isBGGroup() ? 1 : 0); // 2.0.x, isBattleGroundGroup?
data << uint8(citr->group); // groupid
data << uint8(0); // unk
+ if(m_groupType & GROUPTYPE_LFD)
+ {
+ data << uint8(0);
+ data << uint32(0);
+ }
data << uint64(0x50000000FFFFFFFELL); // related to voice chat?
+ data << uint32(0); // 3.3, may be some kind of time
data << uint32(GetMembersCount()-1);
for (member_citerator citr2 = m_memberSlots.begin(); citr2 != m_memberSlots.end(); ++citr2)
{
if(citr->guid == citr2->guid)
continue;
Player* member = objmgr.GetPlayer(citr2->guid);
-
+
// Sometimes objmgr can't find player when he is teleporting between maps, causing him to show up as offline
uint8 onlineState = (member) ? MEMBER_STATUS_ONLINE : MEMBER_STATUS_OFFLINE;
onlineState = onlineState | ((isBGGroup()) ? MEMBER_STATUS_PVP : 0);
@@ -978,6 +1009,7 @@ void Group::SendUpdate()
data << uint8(onlineState); // online-state
data << uint8(citr2->group); // groupid
data << uint8(citr2->flags); // See enum GroupMemberFlags
+ data << uint8(0); // 3.3
}
data << uint64(m_leaderGuid); // leader guid
@@ -988,6 +1020,7 @@ void Group::SendUpdate()
data << uint8(m_lootThreshold); // loot threshold
data << uint8(m_dungeonDifficulty); // Dungeon Difficulty
data << uint8(m_raidDifficulty); // Raid Difficulty
+ data << uint8(0); // 3.3
}
player->GetSession()->SendPacket( &data );
}
@@ -1232,7 +1265,7 @@ void Group::_removeRolls(const uint64 &guid)
if(itr2 == roll->playerVote.end())
continue;
- if (itr2->second == GREED) --roll->totalGreed;
+ if (itr2->second == GREED || itr2->second == DISENCHANT) --roll->totalGreed;
if (itr2->second == NEED) --roll->totalNeed;
if (itr2->second == PASS) --roll->totalPass;
if (itr2->second != NOT_VALID) --roll->totalPlayersRolling;
@@ -1279,7 +1312,7 @@ bool Group::_setMainTank(const uint64 &guid, const bool &apply)
RemoveUniqueGroupMemberFlag(MEMBER_FLAG_MAINTANK); // Remove main tank flag from current if any.
ToggleGroupMemberFlag(slot, MEMBER_FLAG_MAINTANK, apply); // And apply main tank flag on new main tank.
-
+
if (!isBGGroup())
CharacterDatabase.PExecute("UPDATE groups SET mainTank='%u' WHERE leaderGuid='%u'", GUID_LOPART(m_mainTank), GUID_LOPART(m_leaderGuid));
return true;
@@ -1293,7 +1326,7 @@ bool Group::_setMainAssistant(const uint64 &guid, const bool &apply)
RemoveUniqueGroupMemberFlag(MEMBER_FLAG_MAINASSIST); // Remove main assist flag from current if any.
ToggleGroupMemberFlag(slot, MEMBER_FLAG_MAINASSIST, apply); // Apply main assist flag on new main assist.
-
+
if (!isBGGroup())
CharacterDatabase.PExecute("UPDATE groups SET mainAssistant='%u' WHERE leaderGuid='%u'", GUID_LOPART(m_mainAssistant), GUID_LOPART(m_leaderGuid));
return true;
diff --git a/src/game/Group.h b/src/game/Group.h
index 5cc09927dcd..58244d0cc5f 100644
--- a/src/game/Group.h
+++ b/src/game/Group.h
@@ -39,8 +39,9 @@ enum RollVote
PASS = 0,
NEED = 1,
GREED = 2,
- NOT_EMITED_YET = 3,
- NOT_VALID = 4
+ DISENCHANT = 3,
+ NOT_EMITED_YET = 4,
+ NOT_VALID = 5
};
enum GroupMemberOnlineStatus
@@ -65,8 +66,13 @@ enum GroupMemberFlags
enum GroupType
{
- GROUPTYPE_NORMAL = 0,
- GROUPTYPE_RAID = 1
+ GROUPTYPE_NORMAL = 0x00,
+ GROUPTYPE_BG = 0x01,
+ GROUPTYPE_RAID = 0x02,
+ GROUPTYPE_BGRAID = GROUPTYPE_BG | GROUPTYPE_RAID, // mask
+ // 0x04?
+ GROUPTYPE_LFD = 0x08,
+ // 0x10, leave/change group?, I saw this flag when leaving group and after leaving BG while in group
};
class BattleGround;
@@ -289,7 +295,7 @@ class Group
SendUpdate();
}
- void SetTargetIcon(uint8 id, uint64 guid);
+ void SetTargetIcon(uint8 id, uint64 whoGuid, uint64 targetGuid);
Difficulty GetDifficulty(bool isRaid) const { return isRaid ? m_raidDifficulty : m_dungeonDifficulty; }
Difficulty GetDungeonDifficulty() const { return m_dungeonDifficulty; }
@@ -407,7 +413,7 @@ class Group
if (m_subGroupsCounts)
--m_subGroupsCounts[subgroup];
}
-
+
void RemoveUniqueGroupMemberFlag(GroupMemberFlags flag)
{
for (member_witerator itr = m_memberSlots.begin(); itr != m_memberSlots.end(); ++itr)
@@ -416,14 +422,14 @@ class Group
itr->flags &= ~flag;
}
}
-
+
void ToggleGroupMemberFlag(member_witerator slot, uint8 flag, bool apply)
{
if (apply)
slot->flags |= flag;
else
slot->flags &= ~flag;
- }
+ }
MemberSlotList m_memberSlots;
GroupRefManager m_memberMgr;
diff --git a/src/game/GroupHandler.cpp b/src/game/GroupHandler.cpp
index 4f2a1dc4c8d..cf52bec2074 100644
--- a/src/game/GroupHandler.cpp
+++ b/src/game/GroupHandler.cpp
@@ -126,7 +126,7 @@ void WorldSession::HandleGroupInviteOpcode( WorldPacket & recv_data )
if(group)
{
// not have permissions for invite
- if(!group->IsLeader(GetPlayer()->GetGUID()) && !group->IsAssistant(GetPlayer()->GetGUID()))
+ if(group->isRaidGroup() && !group->IsLeader(GetPlayer()->GetGUID()) && !group->IsAssistant(GetPlayer()->GetGUID()))
{
SendPartyResult(PARTY_OP_INVITE, "", PARTY_RESULT_YOU_NOT_LEADER);
return;
@@ -428,9 +428,9 @@ void WorldSession::HandleMinimapPingOpcode(WorldPacket& recv_data)
// everything's fine, do it
WorldPacket data(MSG_MINIMAP_PING, (8+4+4));
- data << GetPlayer()->GetGUID();
- data << x;
- data << y;
+ data << uint64(GetPlayer()->GetGUID());
+ data << float(x);
+ data << float(y);
GetPlayer()->GetGroup()->BroadcastPacket(&data, true, -1, GetPlayer()->GetGUID());
}
@@ -451,10 +451,10 @@ void WorldSession::HandleRandomRollOpcode(WorldPacket& recv_data)
//sLog.outDebug("ROLL: MIN: %u, MAX: %u, ROLL: %u", minimum, maximum, roll);
WorldPacket data(MSG_RANDOM_ROLL, 4+4+4+8);
- data << minimum;
- data << maximum;
- data << roll;
- data << GetPlayer()->GetGUID();
+ data << uint32(minimum);
+ data << uint32(maximum);
+ data << uint32(roll);
+ data << uint64(GetPlayer()->GetGUID());
if(GetPlayer()->GetGroup())
GetPlayer()->GetGroup()->BroadcastPacket(&data, false);
else
@@ -485,7 +485,7 @@ void WorldSession::HandleRaidTargetUpdateOpcode( WorldPacket & recv_data )
uint64 guid;
recv_data >> guid;
- group->SetTargetIcon(x, guid);
+ group->SetTargetIcon(x, _player->GetGUID(), guid);
}
}
@@ -535,11 +535,7 @@ void WorldSession::HandleGroupChangeSubGroupOpcode( WorldPacket & recv_data )
//Do not allow leader to change group of player in combat
if (movedPlayer->isInCombat())
- {
- WorldPacket data(SMSG_GROUP_SWAP_FAILED, (0));
- SendPacket(&data);
return;
- }
// everything's fine, do it
group->ChangeMembersGroup(movedPlayer, groupNr);
@@ -586,7 +582,7 @@ void WorldSession::HandlePartyAssignmentOpcode( WorldPacket & recv_data )
// everything's fine, do it
if (flag == MEMBER_FLAG_MAINTANK)
group->SetMainTank(guid, apply);
-
+
else if (flag == MEMBER_FLAG_MAINASSIST)
group->SetMainAssistant(guid, apply);
}
diff --git a/src/game/Item.cpp b/src/game/Item.cpp
index d1a5612b95c..00f271ca89e 100644
--- a/src/game/Item.cpp
+++ b/src/game/Item.cpp
@@ -726,6 +726,36 @@ bool Item::CanBeTraded(bool mail) const
return true;
}
+
+bool Item::HasEnchantRequiredSkill(const Player *pPlayer) const
+{
+
+ // Check all enchants for required skill
+ for (uint32 enchant_slot = PERM_ENCHANTMENT_SLOT; enchant_slot < MAX_ENCHANTMENT_SLOT; ++enchant_slot)
+ if (uint32 enchant_id = GetEnchantmentId(EnchantmentSlot(enchant_slot)))
+ if (SpellItemEnchantmentEntry const* enchantEntry = sSpellItemEnchantmentStore.LookupEntry(enchant_id))
+ if (enchantEntry->requiredSkill && pPlayer->GetSkillValue(enchantEntry->requiredSkill) < enchantEntry->requiredSkillValue)
+ return false;
+
+ return true;
+}
+
+
+uint32 Item::GetEnchantRequiredLevel() const
+{
+
+ uint32 level = 0;
+
+ // Check all enchants for required level
+ for (uint32 enchant_slot = PERM_ENCHANTMENT_SLOT; enchant_slot < MAX_ENCHANTMENT_SLOT; ++enchant_slot)
+ if (uint32 enchant_id = GetEnchantmentId(EnchantmentSlot(enchant_slot)))
+ if (SpellItemEnchantmentEntry const* enchantEntry = sSpellItemEnchantmentStore.LookupEntry(enchant_id))
+ if (enchantEntry->requiredLevel > level)
+ level = enchantEntry->requiredLevel;
+
+ return level;
+}
+
bool Item::IsBoundByEnchant() const
{
// Check all enchants for soulbound
@@ -741,6 +771,10 @@ bool Item::IsFitToSpellRequirements(SpellEntry const* spellInfo) const
{
ItemPrototype const* proto = GetProto();
+ //Lava Lash
+ if (spellInfo->Id==60103 && spellInfo->EquippedItemClass==ITEM_CLASS_WEAPON)
+ return true;
+
if (spellInfo->EquippedItemClass != -1) // -1 == any item class
{
// Special case - accept vellum for armor/weapon requirements
diff --git a/src/game/Item.h b/src/game/Item.h
index 37d7b7c2dfd..8e504800e9a 100644
--- a/src/game/Item.h
+++ b/src/game/Item.h
@@ -250,6 +250,9 @@ class Item : public Object
void SetInTrade(bool b = true) { mb_in_trade = b; }
bool IsInTrade() const { return mb_in_trade; }
+ bool HasEnchantRequiredSkill(const Player *pPlayer) const;
+ uint32 GetEnchantRequiredLevel() const;
+
bool IsFitToSpellRequirements(SpellEntry const* spellInfo) const;
bool IsTargetValidForItemUse(Unit* pUnitTarget);
bool IsLimitedToAnotherMapOrZone( uint32 cur_mapId, uint32 cur_zoneId) const;
diff --git a/src/game/ItemHandler.cpp b/src/game/ItemHandler.cpp
index 4993f8bcd12..b36fd844923 100644
--- a/src/game/ItemHandler.cpp
+++ b/src/game/ItemHandler.cpp
@@ -1341,7 +1341,7 @@ void WorldSession::HandleCancelTempEnchantmentOpcode(WorldPacket& recv_data)
void WorldSession::HandleItemRefundInfoRequest(WorldPacket& recv_data)
{
- sLog.outDebug("WORLD: CMSG_ITEM_REFUND_INFO_REQUEST");
+ sLog.outDebug("WORLD: CMSG_ITEM_REFUND_INFO");
uint64 guid;
@@ -1362,7 +1362,7 @@ void WorldSession::HandleItemRefundInfoRequest(WorldPacket& recv_data)
}
// item refund system not implemented yet
- WorldPacket data(SMSG_ITEM_REFUND_TIMER, 8+4+4+4+4*4+4*4+4+4); // guess size
+ WorldPacket data(SMSG_ITEM_REFUND_INFO_RESPONSE, 8+4+4+4+4*4+4*4+4+4); // guess size
data << uint64(guid); // item guid
data << uint32(1); // unknown
data << uint32(item->GetPaidHonorPoints()); // honor point cost
@@ -1398,13 +1398,13 @@ void WorldSession::HandleItemRefund(WorldPacket &recv_data)
if(item->GetRefundExpiryTime() <= time(NULL)) // item refund has expired
{
- WorldPacket data(SMSG_ITEM_REFUND);
+ WorldPacket data(SMSG_ITEM_REFUND_RESULT);
data << uint64(guid); // guid
data << uint32(1); // error, abort refund
return;
}
- WorldPacket data(SMSG_ITEM_REFUND);
+ WorldPacket data(SMSG_ITEM_REFUND_RESULT);
data << uint64(guid); // guid?
data << uint32(0); // must be 0 or client side error in refund
data << uint32(0); // unk - message sent to client?
diff --git a/src/game/ItemPrototype.h b/src/game/ItemPrototype.h
index 872bcd34f67..768df0cc11b 100644
--- a/src/game/ItemPrototype.h
+++ b/src/game/ItemPrototype.h
@@ -60,7 +60,7 @@ enum ItemModType
ITEM_MOD_EXPERTISE_RATING = 37,
ITEM_MOD_ATTACK_POWER = 38,
ITEM_MOD_RANGED_ATTACK_POWER = 39,
- ITEM_MOD_FERAL_ATTACK_POWER = 40,
+ //ITEM_MOD_FERAL_ATTACK_POWER = 40, not in 3.3
ITEM_MOD_SPELL_HEALING_DONE = 41, // deprecated
ITEM_MOD_SPELL_DAMAGE_DONE = 42, // deprecated
ITEM_MOD_MANA_REGENERATION = 43,
diff --git a/src/game/LFGHandler.cpp b/src/game/LFGHandler.cpp
index 89abfec79a0..63fc3ad2439 100644
--- a/src/game/LFGHandler.cpp
+++ b/src/game/LFGHandler.cpp
@@ -259,7 +259,7 @@ void WorldSession::HandleLookingForGroup(WorldPacket& recv_data)
}
void WorldSession::SendLfgResult(uint32 type, uint32 entry, uint8 lfg_type)
-{
+{/*
uint32 number = 0;
WorldPacket data(MSG_LOOKING_FOR_GROUP);
@@ -267,18 +267,18 @@ void WorldSession::SendLfgResult(uint32 type, uint32 entry, uint8 lfg_type)
data << uint32(entry); // entry from LFGDungeons.dbc
data << uint8(0);
- /*if(uint8)
+ if(uint8)
{
uint32 count1;
for(count1)
{
uint64; // player guid
}
- }*/
+ }
data << uint32(0); // count2
data << uint32(0);
- /*for(count2)
+ for(count2)
{
uint64 // not player guid
uint32 flags;
@@ -297,7 +297,7 @@ void WorldSession::SendLfgResult(uint32 type, uint32 entry, uint8 lfg_type)
uint8
}
}
- }*/
+ }
size_t count3_pos = data.wpos();
data << uint32(0); // count3
@@ -389,6 +389,7 @@ void WorldSession::SendLfgResult(uint32 type, uint32 entry, uint8 lfg_type)
data.put<uint32>(count3_pos, number); // fill count placeholder
SendPacket(&data);
+*/
}
void WorldSession::HandleSetLfgOpcode( WorldPacket & recv_data )
@@ -429,10 +430,5 @@ void WorldSession::HandleLfgSetRoles(WorldPacket &recv_data)
void WorldSession::SendLfgUpdate(uint8 unk1, uint8 unk2, uint8 unk3)
{
- WorldPacket data(SMSG_LFG_UPDATE, 3);
- data << uint8(unk1);
- data << uint8(unk2);
- data << uint8(unk3);
- SendPacket(&data);
-}
+}
diff --git a/src/game/Language.h b/src/game/Language.h
index 6558908d302..86235315d27 100644
--- a/src/game/Language.h
+++ b/src/game/Language.h
@@ -953,6 +953,13 @@ enum TrinityStrings
LANG_OPVP_ZM_GOSSIP_ALLIANCE = 10054,
LANG_OPVP_ZM_GOSSIP_HORDE = 10055,
+ LANG_BG_SA_START_TWO_MINUTES = 10056,
+ LANG_BG_SA_START_ONE_MINUTE = 10057,
+ LANG_BG_SA_START_HALF_MINUTE = 10058,
+ LANG_BG_SA_HAS_BEGUN = 10059,
+ LANG_BG_SA_IS_UNDER_ATTACK = 10060,
+ LANG_BG_SA_IS_DESTROYED = 10061,
+
// Use for custom patches 11000-11999
LANG_AUTO_BROADCAST = 11000,
LANG_INVALID_REALMID = 11001,
diff --git a/src/game/Level1.cpp b/src/game/Level1.cpp
index d31cf17b567..9a9c60f245e 100644
--- a/src/game/Level1.cpp
+++ b/src/game/Level1.cpp
@@ -495,7 +495,7 @@ bool ChatHandler::HandleGMTicketAssignToCommand(const char* args)
SendSysMessage(LANG_COMMAND_TICKETNOTEXIST);
return true;
}
-
+
uint64 tarGUID = objmgr.GetPlayerGUIDByName(targm.c_str());
uint64 accid = objmgr.GetPlayerAccountIdByGUID(tarGUID);
uint32 gmlevel = accmgr.GetSecurity(accid, realmID);
@@ -2205,6 +2205,13 @@ bool ChatHandler::HandleTeleCommand(const char * args)
return false;
}
+ if (_player->isInCombat())
+ {
+ SendSysMessage(LANG_YOU_IN_COMBAT);
+ SetSentErrorMessage(true);
+ return false;
+ }
+
MapEntry const * me = sMapStore.LookupEntry(tele->mapId);
if(!me || me->IsBattleGroundOrArena())
{
diff --git a/src/game/Level2.cpp b/src/game/Level2.cpp
index 530a243794d..62fc94b541a 100644
--- a/src/game/Level2.cpp
+++ b/src/game/Level2.cpp
@@ -508,8 +508,8 @@ bool ChatHandler::HandleGameObjectTargetCommand(const char* args)
o = fields[5].GetFloat();
mapid = fields[6].GetUInt16();
phase = fields[7].GetUInt16();
- pool_id = poolhandler.IsPartOfAPool(lowguid, TYPEID_GAMEOBJECT);
- if (!pool_id || (pool_id && poolhandler.IsSpawnedObject(pool_id, lowguid, TYPEID_GAMEOBJECT)))
+ pool_id = poolhandler.IsPartOfAPool<GameObject>(lowguid);
+ if (!pool_id || poolhandler.IsSpawnedObject<GameObject>(lowguid))
found = true;
} while( result->NextRow() && (!found) );
diff --git a/src/game/Level3.cpp b/src/game/Level3.cpp
index aa146210a77..0d56d12a816 100644
--- a/src/game/Level3.cpp
+++ b/src/game/Level3.cpp
@@ -2458,8 +2458,11 @@ bool ChatHandler::HandleLearnAllMyTalentsCommand(const char* /*args*/)
// learn highest rank of talent and learn all non-talent spell ranks (recursive by tree)
player->learnSpellHighRank(spellId);
+ player->AddTalent(spellId, player->GetActiveSpec(), true);
}
+ player->SetFreeTalentPoints(0);
+
SendSysMessage(LANG_COMMAND_LEARN_CLASS_TALENTS);
return true;
}
@@ -2536,6 +2539,8 @@ bool ChatHandler::HandleLearnAllMyPetTalentsCommand(const char* /*args*/)
pet->learnSpellHighRank(spellid);
}
+ pet->SetFreeTalentPoints(0);
+
SendSysMessage(LANG_COMMAND_LEARN_PET_TALENTS);
return true;
}
diff --git a/src/game/LootMgr.h b/src/game/LootMgr.h
index 00e0bb8d1b5..3db547e0836 100644
--- a/src/game/LootMgr.h
+++ b/src/game/LootMgr.h
@@ -34,9 +34,12 @@ enum RollType
ROLL_PASS = 0,
ROLL_NEED = 1,
ROLL_GREED = 2,
- MAX_ROLL_TYPE = 3
+ ROLL_DISENCHANT = 3,
+ MAX_ROLL_TYPE = 4
};
+#define ALL_ROLL_TYPE_MASK 0x0F
+
#define MAX_NR_LOOT_ITEMS 16
// note: the client cannot show more than 16 items total
#define MAX_NR_QUEST_ITEMS 32
diff --git a/src/game/Mail.cpp b/src/game/Mail.cpp
index 12425866090..64403a3b488 100644
--- a/src/game/Mail.cpp
+++ b/src/game/Mail.cpp
@@ -546,7 +546,7 @@ void WorldSession::HandleGetMailList(WorldPacket & recv_data )
uint8 item_count = (*itr)->items.size(); // max count is MAX_MAIL_ITEMS (12)
- size_t next_mail_size = 2+4+1+8+4*8+((*itr)->subject.size()+1)+1+item_count*(1+4+4+6*3*4+4+4+1+4+4+4);
+ size_t next_mail_size = 2+4+1+((*itr)->messageType == MAIL_NORMAL ? 8 : 4)+4*8+((*itr)->subject.size()+1)+1+item_count*(1+4+4+7*3*4+4+4+4+4+4+4+1);
if (data.wpos()+next_mail_size > maxPacketSize)
{
diff --git a/src/game/Map.cpp b/src/game/Map.cpp
index 0d65f26127b..dbfe03f5ee3 100644
--- a/src/game/Map.cpp
+++ b/src/game/Map.cpp
@@ -2692,7 +2692,6 @@ bool InstanceMap::Add(Player *player)
}
}
- if(i_data) i_data->OnPlayerEnter(player);
// for normal instances cancel the reset schedule when the
// first player enters (no players yet)
SetResetSchedule(false);
@@ -2706,6 +2705,10 @@ bool InstanceMap::Add(Player *player)
// this will acquire the same mutex so it cannot be in the previous block
Map::Add(player);
+
+ if (i_data)
+ i_data->OnPlayerEnter(player);
+
return true;
}
diff --git a/src/game/MiscHandler.cpp b/src/game/MiscHandler.cpp
index b366c37c40b..52853c57fd3 100644
--- a/src/game/MiscHandler.cpp
+++ b/src/game/MiscHandler.cpp
@@ -1115,7 +1115,9 @@ void WorldSession::HandleMoveUnRootAck(WorldPacket& recv_data)
recv_data.read_skip<uint32>(); // unk
MovementInfo movementInfo;
+ movementInfo.guid = guid;
ReadMovementInfo(recv_data, &movementInfo);
+ recv_data.read_skip<float>(); // unk2
*/
}
@@ -1498,10 +1500,27 @@ void WorldSession::HandleSetDungeonDifficultyOpcode( WorldPacket & recv_data )
if(_player->getLevel() < LEVELREQUIREMENT_HEROIC)
return;
- if(Group *pGroup = _player->GetGroup())
+ Group *pGroup = _player->GetGroup();
+ if(pGroup)
{
if(pGroup->IsLeader(_player->GetGUID()))
{
+ for(GroupReference *itr = pGroup->GetFirstMember(); itr != NULL; itr = itr->next())
+ {
+ Player* pGroupGuy = itr->getSource();
+ if(!pGroupGuy)
+ continue;
+
+ if(!pGroupGuy->IsInMap(pGroupGuy))
+ return;
+
+ map = pGroupGuy->GetMap();
+ if(map && map->IsRaidOrHeroicDungeon() )
+ {
+ sLog.outError("WorldSession::HandleSetDungeonDifficultyOpcode: player %d tried to reset the instance while inside!", _player->GetGUIDLow());
+ return;
+ }
+ }
// the difficulty is set even if the instances can't be reset
//_player->SendDungeonDifficulty(true);
pGroup->ResetInstances(INSTANCE_RESET_CHANGE_DIFFICULTY, false, _player);
@@ -1547,6 +1566,22 @@ void WorldSession::HandleSetRaidDifficultyOpcode( WorldPacket & recv_data )
{
if(pGroup->IsLeader(_player->GetGUID()))
{
+ for(GroupReference *itr = pGroup->GetFirstMember(); itr != NULL; itr = itr->next())
+ {
+ Player* pGroupGuy = itr->getSource();
+ if(!pGroupGuy)
+ continue;
+
+ if(!pGroupGuy->IsInMap(pGroupGuy))
+ return;
+
+ map = pGroupGuy->GetMap();
+ if(map && map->IsRaidOrHeroicDungeon() )
+ {
+ sLog.outError("WorldSession::HandleSetDungeonDifficultyOpcode: player %d tried to reset the instance while inside!", _player->GetGUIDLow());
+ return;
+ }
+ }
// the difficulty is set even if the instances can't be reset
//_player->SendDungeonDifficulty(true);
pGroup->ResetInstances(INSTANCE_RESET_CHANGE_DIFFICULTY, true, _player);
@@ -1594,9 +1629,10 @@ void WorldSession::HandleMoveSetCanFlyAckOpcode( WorldPacket & recv_data )
recv_data.read_skip<uint32>(); // unk
MovementInfo movementInfo;
+ movementInfo.guid = guid;
ReadMovementInfo(recv_data, &movementInfo);
- recv_data.read_skip<uint32>(); // unk2
+ recv_data.read_skip<float>(); // unk2
_player->m_mover->m_movementInfo.flags = movementInfo.GetMovementFlags();
}
@@ -1640,6 +1676,14 @@ void WorldSession::HandleWorldStateUITimerUpdate(WorldPacket& recv_data)
SendPacket(&data);
}
+void WorldSession::HandleReadyForAccountDataTimes(WorldPacket& recv_data)
+{
+ // empty opcode
+ sLog.outDebug("WORLD: CMSG_READY_FOR_ACCOUNT_DATA_TIMES");
+
+ SendAccountDataTimes(GLOBAL_CACHE_MASK);
+}
+
void WorldSession::SendSetPhaseShift(uint32 PhaseShift)
{
WorldPacket data(SMSG_SET_PHASE_SHIFT, 4);
diff --git a/src/game/Object.cpp b/src/game/Object.cpp
index 1b8a21650bd..4e0f7c01964 100644
--- a/src/game/Object.cpp
+++ b/src/game/Object.cpp
@@ -611,7 +611,7 @@ void Object::_BuildValuesUpdate(uint8 updatetype, ByteBuffer * data, UpdateMask
if(!target->isAllowedToLoot((Creature*)this))
*data << (m_uint32Values[ index ] & ~UNIT_DYNFLAG_LOOTABLE);
else
- *data << (m_uint32Values[ index ] & ~UNIT_DYNFLAG_OTHER_TAGGER);
+ *data << (m_uint32Values[ index ] & ~UNIT_DYNFLAG_TAPPED);
}
else
*data << m_uint32Values[ index ];
@@ -1103,8 +1103,8 @@ bool Object::PrintIndexError(uint32 index, bool set) const
bool Position::HasInLine(const Unit * const target, float distance, float width) const
{
- assert(target);
- if(!HasInArc(M_PI, target) || !target->IsWithinDist3d(m_positionX, m_positionY, m_positionZ, distance)) return false;
+ if (!HasInArc(M_PI, target) || !target->IsWithinDist3d(m_positionX, m_positionY, m_positionZ, distance))
+ return false;
width += target->GetObjectSize();
float angle = GetRelativeAngle(target);
return abs(sin(angle)) * GetExactDist2d(target->GetPositionX(), target->GetPositionY()) < width;
@@ -1193,7 +1193,6 @@ InstanceData* WorldObject::GetInstanceData()
float WorldObject::GetDistanceZ(const WorldObject* obj) const
{
- assert(obj);
float dz = fabs(GetPositionZ() - obj->GetPositionZ());
float sizefactor = GetObjectSize() + obj->GetObjectSize();
float dist = dz - sizefactor;
@@ -1202,7 +1201,6 @@ float WorldObject::GetDistanceZ(const WorldObject* obj) const
bool WorldObject::_IsWithinDist(WorldObject const* obj, float dist2compare, bool is3D) const
{
- assert(obj);
float dx = GetPositionX() - obj->GetPositionX();
float dy = GetPositionY() - obj->GetPositionY();
float distsq = dx*dx + dy*dy;
@@ -1360,7 +1358,6 @@ void Position::GetSinCos(const float x, const float y, float &vsin, float &vcos)
bool Position::HasInArc(float arc, const Position *obj) const
{
- assert(obj);
// always have self in arc
if(obj == this)
return true;
diff --git a/src/game/Object.h b/src/game/Object.h
index 22c7415a15a..0b4b71c13a5 100644
--- a/src/game/Object.h
+++ b/src/game/Object.h
@@ -377,7 +377,7 @@ struct Position
void Relocate(const Position &pos)
{ m_positionX = pos.m_positionX; m_positionY = pos.m_positionY; m_positionZ = pos.m_positionZ; m_orientation = pos.m_orientation; }
void Relocate(const Position *pos)
- { assert(pos); m_positionX = pos->m_positionX; m_positionY = pos->m_positionY; m_positionZ = pos->m_positionZ; m_orientation = pos->m_orientation; }
+ { m_positionX = pos->m_positionX; m_positionY = pos->m_positionY; m_positionZ = pos->m_positionZ; m_orientation = pos->m_orientation; }
void SetOrientation(float orientation)
{ m_orientation = orientation; }
@@ -405,33 +405,33 @@ struct Position
float GetExactDist2d(const float x, const float y) const
{ return sqrt(GetExactDist2dSq(x, y)); }
float GetExactDist2dSq(const Position *pos) const
- { assert(pos); float dx = m_positionX - pos->m_positionX; float dy = m_positionY - pos->m_positionY; return dx*dx + dy*dy; }
+ { float dx = m_positionX - pos->m_positionX; float dy = m_positionY - pos->m_positionY; return dx*dx + dy*dy; }
float GetExactDist2d(const Position *pos) const
- { assert(pos); return sqrt(GetExactDist2dSq(pos)); }
+ { return sqrt(GetExactDist2dSq(pos)); }
float GetExactDistSq(float x, float y, float z) const
{ float dz = m_positionZ - z; return GetExactDist2dSq(x, y) + dz*dz; }
float GetExactDist(float x, float y, float z) const
{ return sqrt(GetExactDistSq(x, y, z)); }
float GetExactDistSq(const Position *pos) const
- { assert(pos); float dx = m_positionX - pos->m_positionX; float dy = m_positionY - pos->m_positionY; float dz = m_positionZ - pos->m_positionZ; return dx*dx + dy*dy + dz*dz; }
+ { float dx = m_positionX - pos->m_positionX; float dy = m_positionY - pos->m_positionY; float dz = m_positionZ - pos->m_positionZ; return dx*dx + dy*dy + dz*dz; }
float GetExactDist(const Position *pos) const
- { assert(pos); return sqrt(GetExactDistSq(pos)); }
+ { return sqrt(GetExactDistSq(pos)); }
float GetAngle(const Position *pos) const;
float GetAngle(float x, float y) const;
float GetRelativeAngle(const Position *pos) const
- { assert(pos); return GetAngle(pos) - m_orientation; }
+ { return GetAngle(pos) - m_orientation; }
float GetRelativeAngle(float x, float y) const { return GetAngle(x, y) - m_orientation; }
void GetSinCos(float x, float y, float &vsin, float &vcos) const;
bool IsInDist2d(float x, float y, float dist) const
{ return GetExactDist2dSq(x, y) < dist * dist; }
bool IsInDist2d(const Position *pos, float dist) const
- { assert(pos); return GetExactDist2dSq(pos) < dist * dist; }
+ { return GetExactDist2dSq(pos) < dist * dist; }
bool IsInDist(float x, float y, float z, float dist) const
{ return GetExactDistSq(x, y, z) < dist * dist; }
bool IsInDist(const Position *pos, float dist) const
- { assert(pos); return GetExactDistSq(pos) < dist * dist; }
+ { return GetExactDistSq(pos) < dist * dist; }
bool HasInArc(float arcangle, const Position *pos) const;
bool HasInLine(const Unit *target, float distance, float width) const;
};
@@ -513,7 +513,7 @@ class WorldObject : public Object, public WorldLocation
virtual void SetPhaseMask(uint32 newPhaseMask, bool update);
uint32 GetPhaseMask() const { return m_phaseMask; }
- bool InSamePhase(WorldObject const* obj) const { assert(obj); return InSamePhase(obj->GetPhaseMask()); }
+ bool InSamePhase(WorldObject const* obj) const { return InSamePhase(obj->GetPhaseMask()); }
bool InSamePhase(uint32 phasemask) const { return (GetPhaseMask() & phasemask); }
uint32 GetZoneId() const;
@@ -529,7 +529,6 @@ class WorldObject : public Object, public WorldLocation
float GetDistance(const WorldObject *obj) const
{
- assert(obj);
float d = GetExactDist(obj) - GetObjectSize() - obj->GetObjectSize();
return d > 0.0f ? d : 0.0f;
}
@@ -545,7 +544,6 @@ class WorldObject : public Object, public WorldLocation
}
float GetDistance2d(const WorldObject* obj) const
{
- assert(obj);
float d = GetExactDist2d(obj) - GetObjectSize() - obj->GetObjectSize();
return d > 0.0f ? d : 0.0f;
}
diff --git a/src/game/ObjectMgr.cpp b/src/game/ObjectMgr.cpp
index b9265081cf5..e44207c63db 100644
--- a/src/game/ObjectMgr.cpp
+++ b/src/game/ObjectMgr.cpp
@@ -2325,6 +2325,29 @@ void ObjectMgr::LoadItemPrototypes()
const_cast<ItemPrototype*>(proto)->HolidayId = 0;
}
}
+
+ // check some dbc referecned items (avoid duplicate reports)
+ std::set<uint32> notFoundOutfit;
+ for (uint32 i = 1; i < sCharStartOutfitStore.GetNumRows(); ++i)
+ {
+ CharStartOutfitEntry const* entry = sCharStartOutfitStore.LookupEntry(i);
+ if (!entry)
+ continue;
+
+ for(int j = 0; j < MAX_OUTFIT_ITEMS; ++j)
+ {
+ if(entry->ItemId[j] <= 0)
+ continue;
+
+ uint32 item_id = entry->ItemId[j];
+
+ if(!GetItemPrototype(item_id))
+ notFoundOutfit.insert(item_id);
+ }
+ }
+
+ for(std::set<uint32>::const_iterator itr = notFoundOutfit.begin(); itr != notFoundOutfit.end(); ++itr)
+ sLog.outErrorDb("Item (Entry: %u) not exist in `item_template` but referenced in `CharStartOutfit.dnc`", *itr);
}
void ObjectMgr::LoadItemRequiredTarget()
@@ -3451,7 +3474,7 @@ void ObjectMgr::LoadQuests()
// 9 10 11 12 13 14 15 16 17 18
"RepObjectiveFaction, RepObjectiveValue, RepObjectiveFaction2, RepObjectiveValue2, RequiredMinRepFaction, RequiredMinRepValue, RequiredMaxRepFaction, RequiredMaxRepValue, SuggestedPlayers, LimitTime,"
// 19 20 21 22 23 24 25 26 27 28 29 30
- "QuestFlags, SpecialFlags, CharTitleId, PlayersSlain, BonusTalents, PrevQuestId, NextQuestId, ExclusiveGroup, NextQuestInChain, SrcItemId, SrcItemCount, SrcSpell,"
+ "QuestFlags, SpecialFlags, CharTitleId, PlayersSlain, BonusTalents, PrevQuestId, NextQuestId, ExclusiveGroup, NextQuestInChain, RewXPId, SrcItemId, SrcItemCount, SrcSpell,"
// 31 32 33 34 35 36 37 38 39 40
"Title, Details, Objectives, OfferRewardText, RequestItemsText, EndText, ObjectiveText1, ObjectiveText2, ObjectiveText3, ObjectiveText4,"
// 41 42 43 44 45 46 47 48 49 50 51 52
@@ -3469,9 +3492,10 @@ void ObjectMgr::LoadQuests()
// 85 86 87 88 89 90 91 92
"RewItemId1, RewItemId2, RewItemId3, RewItemId4, RewItemCount1, RewItemCount2, RewItemCount3, RewItemCount4,"
// 93 94 95 96 97 98 99 100 101 102
- "RewRepFaction1, RewRepFaction2, RewRepFaction3, RewRepFaction4, RewRepFaction5, RewRepValue1, RewRepValue2, RewRepValue3, RewRepValue4, RewRepValue5,"
+ "RewRepFaction1, RewRepFaction2, RewRepFaction3, RewRepFaction4, RewRepFaction5, RewRepValueId1, RewRepValueId2, RewRepValueId3, RewRepValueId4, RewRepValueId5,"
+ "RewRepValue1, RewRepValue2, RewRepValue3, RewRepValue4, RewRepValue5,"
// 103 104 105 106 107 108 109 110 111 112 113
- "RewHonorableKills, RewOrReqMoney, RewMoneyMaxLevel, RewSpell, RewSpellCast, RewMailTemplateId, RewMailDelaySecs, PointMapId, PointX, PointY, PointOpt,"
+ "RewHonorAddition, RewHonorMultiplier, RewOrReqMoney, RewMoneyMaxLevel, RewSpell, RewSpellCast, RewMailTemplateId, RewMailDelaySecs, PointMapId, PointX, PointY, PointOpt,"
// 114 115 116 117 118 119 120 121
"DetailsEmote1, DetailsEmote2, DetailsEmote3, DetailsEmote4, DetailsEmoteDelay1, DetailsEmoteDelay2, DetailsEmoteDelay3, DetailsEmoteDelay4,"
// 122 123 124 125 126 127
@@ -3938,30 +3962,29 @@ void ObjectMgr::LoadQuests()
for (uint8 j = 0; j < QUEST_REPUTATIONS_COUNT; ++j)
{
- if(qinfo->RewRepFaction[j])
+ if (qinfo->RewRepFaction[j])
{
- if(!qinfo->RewRepValue[j])
+ if (abs(qinfo->RewRepValueId[j]) > 9)
{
- sLog.outErrorDb("Quest %u has `RewRepFaction%d` = %u but `RewRepValue%d` = 0, quest will not reward this reputation.",
- qinfo->GetQuestId(),j+1,qinfo->RewRepValue[j],j+1);
- // no changes
+ sLog.outErrorDb("Quest %u has RewRepValueId%d = %i. That is outside the range of valid values (-9 to 9).", qinfo->GetQuestId(), j+1, qinfo->RewRepValueId[j]);
}
-
if(!sFactionStore.LookupEntry(qinfo->RewRepFaction[j]))
{
- sLog.outErrorDb("Quest %u has `RewRepFaction%d` = %u but raw faction (faction.dbc) %u does not exist, quest will not reward reputation for this faction.",
- qinfo->GetQuestId(),j+1,qinfo->RewRepFaction[j] ,qinfo->RewRepFaction[j] );
+ sLog.outErrorDb("Quest %u has `RewRepFaction%d` = %u but raw faction (faction.dbc) %u does not exist, quest will not reward reputation for this faction.", qinfo->GetQuestId(),j+1,qinfo->RewRepFaction[j] ,qinfo->RewRepFaction[j] );
qinfo->RewRepFaction[j] = 0; // quest will not reward this
}
- }
+ }
+
+
else if(qinfo->RewRepValue[j]!=0)
{
- sLog.outErrorDb("Quest %u has `RewRepFaction%d` = 0 but `RewRepValue%d` = %u.",
+ sLog.outErrorDb("Quest %u has `RewRepFaction%d` = 0 but `RewRepValue%d` = %i.",
qinfo->GetQuestId(),j+1,j+1,qinfo->RewRepValue[j]);
// no changes, quest ignore this data
}
}
+
if(qinfo->RewSpell)
{
SpellEntry const* spellInfo = sSpellStore.LookupEntry(qinfo->RewSpell);
@@ -6595,6 +6618,65 @@ void ObjectMgr::LoadPointsOfInterest()
sLog.outString(">> Loaded %u Points of Interest definitions", count);
}
+void ObjectMgr::LoadQuestPOI()
+{
+ uint32 count = 0;
+
+ // 0 1 2 3
+ QueryResult_AutoPtr result = WorldDatabase.Query("SELECT questId, id, objIndex, mapid, WorldMapAreaId, FloorId, unk3, unk4 FROM quest_poi order by questId");
+
+ if(!result)
+ {
+ barGoLink bar(1);
+
+ bar.step();
+
+ sLog.outString();
+ sLog.outErrorDb(">> Loaded 0 quest POI definitions. DB table `quest_poi` is empty.");
+ return;
+ }
+
+ barGoLink bar(result->GetRowCount());
+
+ do
+ {
+ Field *fields = result->Fetch();
+ bar.step();
+
+ uint32 questId = fields[0].GetUInt32();
+ uint32 id = fields[1].GetUInt32();
+ int32 objIndex = fields[2].GetInt32();
+ uint32 mapId = fields[3].GetUInt32();
+ uint32 WorldMapAreaId = fields[4].GetUInt32();
+ uint32 FloorId = fields[5].GetUInt32();
+ uint32 unk3 = fields[6].GetUInt32();
+ uint32 unk4 = fields[7].GetUInt32();
+
+ QuestPOI POI(objIndex, mapId, WorldMapAreaId, FloorId, unk3, unk4);
+
+ QueryResult_AutoPtr points = WorldDatabase.PQuery("SELECT x, y FROM quest_poi_points WHERE questId='%u' AND id='%i'", questId, id);
+
+ if(points)
+ {
+ do
+ {
+ Field *pointFields = points->Fetch();
+ int32 x = pointFields[0].GetInt32();
+ int32 y = pointFields[1].GetInt32();
+ QuestPOIPoint point(x, y);
+ POI.points.push_back(point);
+ } while (points->NextRow());
+ }
+
+ mQuestPOIMap[questId].push_back(POI);
+
+ ++count;
+ } while (result->NextRow());
+
+ sLog.outString();
+ sLog.outString(">> Loaded %u quest POI definitions", count);
+}
+
void ObjectMgr::LoadNPCSpellClickSpells()
{
uint32 count = 0;
diff --git a/src/game/ObjectMgr.h b/src/game/ObjectMgr.h
index bfbaea67a87..63483958ab0 100644
--- a/src/game/ObjectMgr.h
+++ b/src/game/ObjectMgr.h
@@ -249,6 +249,32 @@ typedef std::pair<GossipMenusMap::const_iterator, GossipMenusMap::const_iterator
typedef std::multimap<uint32,GossipMenuItems> GossipMenuItemsMap;
typedef std::pair<GossipMenuItemsMap::const_iterator, GossipMenuItemsMap::const_iterator> GossipMenuItemsMapBounds;
+struct QuestPOIPoint
+{
+ int32 x;
+ int32 y;
+
+ QuestPOIPoint() : x(0), y(0) {}
+ QuestPOIPoint(int32 _x, int32 _y) : x(_x), y(_y) {}
+};
+
+struct QuestPOI
+{
+ int32 ObjectiveIndex;
+ uint32 MapId;
+ uint32 Unk1;
+ uint32 Unk2;
+ uint32 Unk3;
+ uint32 Unk4;
+ std::vector<QuestPOIPoint> points;
+
+ QuestPOI() : ObjectiveIndex(0), MapId(0), Unk1(0), Unk2(0), Unk3(0), Unk4(0) {}
+ QuestPOI(int32 objIndex, uint32 mapId, uint32 unk1, uint32 unk2, uint32 unk3, uint32 unk4) : ObjectiveIndex(objIndex), MapId(mapId), Unk1(unk1), Unk2(unk2), Unk3(unk3), Unk4(unk4) {}
+};
+
+typedef std::vector<QuestPOI> QuestPOIVector;
+typedef UNORDERED_MAP<uint32, QuestPOIVector> QuestPOIMap;
+
#define WEATHER_SEASONS 4
struct WeatherSeasonChances
{
@@ -542,6 +568,14 @@ class ObjectMgr
return NULL;
}
+ QuestPOIVector const* GetQuestPOIVector(uint32 questId)
+ {
+ QuestPOIMap::const_iterator itr = mQuestPOIMap.find(questId);
+ if(itr != mQuestPOIMap.end())
+ return &itr->second;
+ return NULL;
+ }
+
void LoadGuilds();
void LoadArenaTeams();
void LoadGroups();
@@ -627,6 +661,7 @@ class ObjectMgr
void LoadReputationOnKill();
void LoadPointsOfInterest();
+ void LoadQuestPOI();
void LoadNPCSpellClickSpells();
@@ -989,6 +1024,8 @@ class ObjectMgr
GossipMenuItemsMap m_mGossipMenuItemsMap;
PointOfInterestMap mPointsOfInterest;
+ QuestPOIMap mQuestPOIMap;
+
WeatherZoneMap mWeatherZoneMap;
//character reserved names
diff --git a/src/game/Opcodes.cpp b/src/game/Opcodes.cpp
index 12f2c8704fa..834ef3f2d3d 100644
--- a/src/game/Opcodes.cpp
+++ b/src/game/Opcodes.cpp
@@ -511,8 +511,8 @@ OpcodeHandler opcodeTable[NUM_MSG_TYPES] =
/*0x1E0*/ { "CMSG_SETSHEATHED", STATUS_LOGGEDIN, &WorldSession::HandleSetSheathedOpcode },
/*0x1E1*/ { "SMSG_COOLDOWN_CHEAT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
/*0x1E2*/ { "SMSG_SPELL_DELAYED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x1E3*/ { "CMSG_PLAYER_MACRO_OBSOLETE", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x1E4*/ { "SMSG_PLAYER_MACRO_OBSOLETE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x1E3*/ { "CMSG_QUEST_POI_QUERY", STATUS_LOGGEDIN, &WorldSession::HandleQuestPOIQuery },
+ /*0x1E4*/ { "SMSG_QUEST_POI_QUERY_RESPONSE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
/*0x1E5*/ { "CMSG_GHOST", STATUS_NEVER, &WorldSession::Handle_NULL },
/*0x1E6*/ { "CMSG_GM_INVIS", STATUS_NEVER, &WorldSession::Handle_NULL },
/*0x1E7*/ { "SMSG_INVALID_PROMOTION_CODE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
@@ -537,10 +537,10 @@ OpcodeHandler opcodeTable[NUM_MSG_TYPES] =
/*0x1FA*/ { "CMSG_GM_NUKE", STATUS_NEVER, &WorldSession::Handle_NULL },
/*0x1FB*/ { "MSG_RANDOM_ROLL", STATUS_LOGGEDIN, &WorldSession::HandleRandomRollOpcode },
/*0x1FC*/ { "SMSG_ENVIRONMENTALDAMAGELOG", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x1FD*/ { "CMSG_RWHOIS_OBSOLETE", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x1FD*/ { "CMSG_PLAYER_DIFFICULTY_CHANGE", STATUS_NEVER, &WorldSession::Handle_NULL },
/*0x1FE*/ { "SMSG_RWHOIS", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x1FF*/ { "MSG_LOOKING_FOR_GROUP", STATUS_LOGGEDIN, &WorldSession::HandleLookingForGroup },
- /*0x200*/ { "CMSG_SET_LOOKING_FOR_GROUP", STATUS_LOGGEDIN, &WorldSession::HandleSetLfgOpcode },
+ /*0x1FF*/ { "SMSG_LFG_COMPLETION_REWARD", STATUS_LOGGEDIN, &WorldSession::Handle_ServerSide },
+ /*0x200*/ { "SMSG_LFG_ERROR", STATUS_LOGGEDIN, &WorldSession::Handle_ServerSide },
/*0x201*/ { "CMSG_UNLEARN_SPELL", STATUS_NEVER, &WorldSession::Handle_NULL },
/*0x202*/ { "CMSG_UNLEARN_SKILL", STATUS_LOGGEDIN, &WorldSession::HandleUnlearnSkillOpcode },
/*0x203*/ { "SMSG_REMOVED_SPELL", STATUS_NEVER, &WorldSession::Handle_ServerSide },
@@ -554,7 +554,7 @@ OpcodeHandler opcodeTable[NUM_MSG_TYPES] =
/*0x20B*/ { "CMSG_UPDATE_ACCOUNT_DATA", STATUS_AUTHED, &WorldSession::HandleUpdateAccountData },
/*0x20C*/ { "SMSG_UPDATE_ACCOUNT_DATA", STATUS_NEVER, &WorldSession::Handle_ServerSide },
/*0x20D*/ { "SMSG_CLEAR_FAR_SIGHT_IMMEDIATE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x20E*/ { "SMSG_POWERGAINLOG_OBSOLETE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x20E*/ { "SMSG_PLAYER_DIFFICULTY_CHANGE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
/*0x20F*/ { "CMSG_GM_TEACH", STATUS_NEVER, &WorldSession::Handle_NULL },
/*0x210*/ { "CMSG_GM_CREATE_ITEM_TARGET", STATUS_NEVER, &WorldSession::Handle_NULL },
/*0x211*/ { "CMSG_GMTICKET_GETTICKET", STATUS_LOGGEDIN, &WorldSession::HandleGMTicketGetTicketOpcode },
@@ -687,7 +687,7 @@ OpcodeHandler opcodeTable[NUM_MSG_TYPES] =
/*0x290*/ { "CMSG_BUYBACK_ITEM", STATUS_LOGGEDIN, &WorldSession::HandleBuybackItem },
/*0x291*/ { "SMSG_SERVER_MESSAGE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
/*0x292*/ { "CMSG_SET_SAVED_INSTANCE_EXTEND", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x293*/ { "CMSG_MEETINGSTONE_LEAVE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x293*/ { "SMSG_LFG_OFFER_CONTINUE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
/*0x294*/ { "CMSG_MEETINGSTONE_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL },
/*0x295*/ { "SMSG_MEETINGSTONE_SETQUEUE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
/*0x296*/ { "CMSG_MEETINGSTONE_INFO", STATUS_LOGGEDIN, &WorldSession::HandleMeetingStoneInfo },
@@ -727,7 +727,7 @@ OpcodeHandler opcodeTable[NUM_MSG_TYPES] =
/*0x2B8*/ { "SMSG_AREA_TRIGGER_MESSAGE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
/*0x2B9*/ { "CMSG_SHOWING_HELM", STATUS_LOGGEDIN, &WorldSession::HandleShowingHelmOpcode },
/*0x2BA*/ { "CMSG_SHOWING_CLOAK", STATUS_LOGGEDIN, &WorldSession::HandleShowingCloakOpcode },
- /*0x2BB*/ { "SMSG_MEETINGSTONE_JOINFAILED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x2BB*/ { "SMSG_LFG_ROLE_CHECK_RESULT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
/*0x2BC*/ { "SMSG_PLAYER_SKINNED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
/*0x2BD*/ { "SMSG_DURABILITY_DAMAGE_DEATH", STATUS_NEVER, &WorldSession::Handle_ServerSide },
/*0x2BE*/ { "CMSG_SET_EXPLORATION", STATUS_NEVER, &WorldSession::Handle_NULL },
@@ -888,29 +888,29 @@ OpcodeHandler opcodeTable[NUM_MSG_TYPES] =
/*0x359*/ { "MSG_MOVE_START_ASCEND", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes },
/*0x35A*/ { "MSG_MOVE_STOP_ASCEND", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes },
/*0x35B*/ { "SMSG_ARENA_TEAM_STATS", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x35C*/ { "CMSG_LFG_SET_AUTOJOIN", STATUS_AUTHED, &WorldSession::HandleLfgSetAutoJoinOpcode },
- /*0x35D*/ { "CMSG_LFG_CLEAR_AUTOJOIN", STATUS_LOGGEDIN, &WorldSession::HandleLfgClearAutoJoinOpcode },
- /*0x35E*/ { "CMSG_LFM_SET_AUTOFILL", STATUS_AUTHED, &WorldSession::HandleLfmSetAutoFillOpcode },
- /*0x35F*/ { "CMSG_LFM_CLEAR_AUTOFILL", STATUS_LOGGEDIN, &WorldSession::HandleLfmClearAutoFillOpcode },
- /*0x360*/ { "CMSG_ACCEPT_LFG_MATCH", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x361*/ { "CMSG_DECLINE_LFG_MATCH", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x362*/ { "CMSG_CANCEL_PENDING_LFG", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x363*/ { "CMSG_CLEAR_LOOKING_FOR_GROUP", STATUS_LOGGEDIN, &WorldSession::HandleLfgClearOpcode },
- /*0x364*/ { "CMSG_CLEAR_LOOKING_FOR_MORE", STATUS_LOGGEDIN, &WorldSession::HandleLfmClearOpcode },
- /*0x365*/ { "CMSG_SET_LOOKING_FOR_MORE", STATUS_LOGGEDIN, &WorldSession::HandleSetLfmOpcode },
+ /*0x35C*/ { "CMSG_LFG_JOIN", STATUS_LOGGEDIN, &WorldSession::HandleLfgSetAutoJoinOpcode },
+ /*0x35D*/ { "CMSG_LFG_LEAVE", STATUS_LOGGEDIN, &WorldSession::HandleLfgClearAutoJoinOpcode },
+ /*0x35E*/ { "CMSG_SEARCH_LFG_JOIN", STATUS_LOGGEDIN, &WorldSession::HandleLfmSetAutoFillOpcode },
+ /*0x35F*/ { "CMSG_SEARCH_LFG_LEAVE", STATUS_LOGGEDIN, &WorldSession::HandleLfmClearAutoFillOpcode },
+ /*0x360*/ { "SMSG_UPDATE_LFG_LIST", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x361*/ { "SMSG_LFG_PROPOSAL_DECLINED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x362*/ { "CMSG_LFG_PROPOSAL_RESULT", STATUS_LOGGEDIN, &WorldSession::Handle_NULL },
+ /*0x363*/ { "SMSG_LFG_ROLE_CHECK", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x364*/ { "SMSG_LFG_ROLE_CHECK_FAILED_RESULT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x365*/ { "SMSG_LFG_QUEUE_STATUS_UPDATE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
/*0x366*/ { "CMSG_SET_LFG_COMMENT", STATUS_LOGGEDIN, &WorldSession::HandleSetLfgCommentOpcode },
- /*0x367*/ { "SMSG_LFG_TIMEDOUT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x368*/ { "SMSG_LFG_OTHER_TIMEDOUT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x369*/ { "SMSG_LFG_AUTOJOIN_FAILED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x36A*/ { "SMSG_LFG_AUTOJOIN_FAILED_NO_PLAYER", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x36B*/ { "SMSG_LFG_LEADER_IS_LFM", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x36C*/ { "SMSG_LFG_UPDATE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x36D*/ { "SMSG_LFG_UPDATE_LFM", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x36E*/ { "SMSG_LFG_UPDATE_LFG", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x36F*/ { "SMSG_LFG_UPDATE_QUEUED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x370*/ { "SMSG_LFG_PENDING_INVITE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x371*/ { "SMSG_LFG_PENDING_MATCH", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x372*/ { "SMSG_LFG_PENDING_MATCH_DONE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x367*/ { "SMSG_LFG_LFG_PROPOSAL_INFO", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x368*/ { "SMSG_LFG_LFG_PROPOSAL_INFO2", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x369*/ { "SMSG_LFG_UPDATE_LIST", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x36A*/ { "CMSG_LFG_SET_ROLES", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x36B*/ { "CMSG_LFG_SET_NEEDS", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x36C*/ { "CMSG_LFG_SET_BOOT_VOTE", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x36D*/ { "SMSG_LFG_BOOT_PROPOSAL_UPDATE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x36E*/ { "CMSG_LFD_PLAYER_LOCK_INFO_REQUEST", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x36F*/ { "SMSG_LFG_PLAYER_LOCK_INFO_RESPONSE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x370*/ { "CMSG_LFG_TELEPORT", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x371*/ { "CMSG_LFD_PARTY_LOCK_INFO_REQUEST", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x372*/ { "SMSG_LFG_PLAYER_LOCK_INFO_UPDATE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
/*0x373*/ { "SMSG_TITLE_EARNED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
/*0x374*/ { "CMSG_SET_TITLE", STATUS_LOGGEDIN, &WorldSession::HandleSetTitleOpcode },
/*0x375*/ { "CMSG_CANCEL_MOUNT_AURA", STATUS_LOGGEDIN, &WorldSession::HandleCancelMountAuraOpcode },
@@ -1218,7 +1218,7 @@ OpcodeHandler opcodeTable[NUM_MSG_TYPES] =
/*0x4A3*/ { "SMSG_SERVER_BUCK_DATA_START", STATUS_NEVER, &WorldSession::Handle_ServerSide },
/*0x4A4*/ { "CMSG_QUERY_VEHICLE_STATUS", STATUS_NEVER, &WorldSession::Handle_NULL },
/*0x4A5*/ { "UMSG_UNKNOWN_1189", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x4A6*/ { "SMSG_UNKNOWN_1190", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x4A6*/ { "SMSG_BATTLEGROUND_INFO_THROTTLED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
/*0x4A7*/ { "SMSG_PLAYER_VEHICLE_DATA", STATUS_NEVER, &WorldSession::Handle_ServerSide },
/*0x4A8*/ { "CMSG_PLAYER_VEHICLE_ENTER", STATUS_LOGGEDIN, &WorldSession::HandleEnterPlayerVehicle },
/*0x4A9*/ { "CMSG_EJECT_PASSENGER", STATUS_LOGGEDIN, &WorldSession::HandleEjectPasenger },
@@ -1230,16 +1230,16 @@ OpcodeHandler opcodeTable[NUM_MSG_TYPES] =
/*0x4AF*/ { "UMSG_UNKNOWN_1199", STATUS_NEVER, &WorldSession::Handle_NULL },
/*0x4B0*/ { "UMSG_UNKNOWN_1200", STATUS_NEVER, &WorldSession::Handle_NULL },
/*0x4B1*/ { "UMSG_UNKNOWN_1201", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x4B2*/ { "SMSG_ITEM_REFUND_TIMER", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x4B3*/ { "CMSG_ITEM_REFUND_INFO_REQUEST", STATUS_LOGGEDIN, &WorldSession::HandleItemRefundInfoRequest },
+ /*0x4B2*/ { "SMSG_ITEM_REFUND_INFO_RESPONSE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x4B3*/ { "CMSG_ITEM_REFUND_INFO", STATUS_LOGGEDIN, &WorldSession::HandleItemRefundInfoRequest },
/*0x4B4*/ { "CMSG_ITEM_REFUND", STATUS_LOGGEDIN, &WorldSession::HandleItemRefund },
- /*0x4B5*/ { "SMSG_UNKNOWN_1205", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x4B5*/ { "SMSG_ITEM_REFUND_RESULT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
/*0x4B6*/ { "CMSG_CORPSE_MAP_POSITION_QUERY", STATUS_LOGGEDIN, &WorldSession::HandleCorpseMapPositionQuery },
/*0x4B7*/ { "CMSG_CORPSE_MAP_POSITION_QUERY_RESPONSE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x4B8*/ { "CMSG_LFG_SET_ROLES", STATUS_LOGGEDIN, &WorldSession::HandleLfgSetRoles },
+ /*0x4B8*/ { "CMSG_LFG_SET_ROLES_2", STATUS_LOGGEDIN, &WorldSession::HandleLfgSetRoles },
/*0x4B9*/ { "UMSG_UNKNOWN_1209", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x4BA*/ { "CMSG_UNKNOWN_1210", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x4BB*/ { "SMSG_UNKNOWN_1211", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x4BA*/ { "CMSG_CALENDAR_CONTEXT_EVENT_SIGNUP", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x4BB*/ { "SMSG_CALENDAR_ACTION_PENDING", STATUS_NEVER, &WorldSession::Handle_ServerSide },
/*0x4BC*/ { "SMSG_EQUIPMENT_SET_LIST", STATUS_NEVER, &WorldSession::Handle_ServerSide },
/*0x4BD*/ { "CMSG_EQUIPMENT_SET_SAVE", STATUS_LOGGEDIN, &WorldSession::HandleEquipmentSetSave },
/*0x4BE*/ { "CMSG_UNKNOWN_1214", STATUS_NEVER, &WorldSession::Handle_NULL },
@@ -1251,8 +1251,8 @@ OpcodeHandler opcodeTable[NUM_MSG_TYPES] =
/*0x4C4*/ { "UMSG_UNKNOWN_1220", STATUS_NEVER, &WorldSession::Handle_NULL },
/*0x4C5*/ { "UMSG_UNKNOWN_1221", STATUS_NEVER, &WorldSession::Handle_NULL },
/*0x4C6*/ { "UMSG_UNKNOWN_1222", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x4C7*/ { "SMSG_UNKNOWN_1223", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x4C8*/ { "SMSG_UNKNOWN_1224", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x4C7*/ { "SMSG_ARENA_OPPONENT_UPDATE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x4C8*/ { "SMSG_ARENA_TEAM_CHANGE_FAILED_QUEUED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
/*0x4C9*/ { "UMSG_UNKNOWN_1225", STATUS_NEVER, &WorldSession::Handle_NULL },
/*0x4CA*/ { "UMSG_UNKNOWN_1226", STATUS_NEVER, &WorldSession::Handle_NULL },
/*0x4CB*/ { "UMSG_UNKNOWN_1227", STATUS_NEVER, &WorldSession::Handle_NULL },
@@ -1269,36 +1269,50 @@ OpcodeHandler opcodeTable[NUM_MSG_TYPES] =
/*0x4D6*/ { "SMSG_EQUIPMENT_SET_USE_RESULT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
/*0x4D7*/ { "UMSG_UNKNOWN_1239", STATUS_NEVER, &WorldSession::Handle_NULL },
/*0x4D8*/ { "SMSG_UNKNOWN_1240", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x4D9*/ { "CMSG_UNKNOWN_1241", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x4DA*/ { "SMSG_UNKNOWN_1242", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x4D9*/ { "CMSG_CHAR_FACTION_CHANGE", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x4DA*/ { "SMSG_CHAR_FACTION_CHANGE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
/*0x4DB*/ { "UMSG_UNKNOWN_1243", STATUS_NEVER, &WorldSession::Handle_NULL },
/*0x4DC*/ { "UMSG_UNKNOWN_1244", STATUS_NEVER, &WorldSession::Handle_NULL },
/*0x4DD*/ { "UMSG_UNKNOWN_1245", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x4DE*/ { "SMSG_UNKNOWN_1246", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x4DF*/ { "CMSG_UNKNOWN_1247", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x4E0*/ { "SMSG_UNKNOWN_1248", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x4E1*/ { "SMSG_UNKNOWN_1249", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x4E2*/ { "CMSG_UNKNOWN_1250", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x4E3*/ { "CMSG_UNKNOWN_1251", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x4E4*/ { "SMSG_UNKNOWN_1252", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x4E5*/ { "SMSG_UNKNOWN_1253", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x4E6*/ { "SMSG_UNKNOWN_1254", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x4E7*/ { "CMSG_UNKNOWN_1255", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x4E8*/ { "SMSG_UNKNOWN_1256", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x4DE*/ { "SMSG_BATTLEFIELD_MGR_ENTRY_INVITE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x4DF*/ { "CMSG_BATTLEFIELD_MGR_ENTRY_INVITE_RESPONS", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x4E0*/ { "SMSG_BATTLEFIELD_MGR_ENTERED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x4E1*/ { "SMSG_BATTLEFIELD_MGR_QUEUE_INVITE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x4E2*/ { "CMSG_BATTLEFIELD_MGR_QUEUE_INVITE_RESPONSE", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x4E3*/ { "CMSG_BATTLEFIELD_MGR_QUEUE_REQUEST", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x4E4*/ { "SMSG_BATTLEFIELD_MGR_QUEUE_REQUEST_RESPONSE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x4E5*/ { "SMSG_BATTLEFIELD_MGR_EJECT_PENDING", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x4E6*/ { "SMSG_BATTLEFIELD_MGR_EJECTED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x4E7*/ { "CMSG_BATTLEFIELD_MGR_EXIT_REQUEST", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x4E8*/ { "SMSG_BATTLEFIELD_MGR_STATE_CHANGE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
/*0x4E9*/ { "UMSG_UNKNOWN_1257", STATUS_NEVER, &WorldSession::Handle_NULL },
/*0x4EA*/ { "UMSG_UNKNOWN_1258", STATUS_NEVER, &WorldSession::Handle_NULL },
/*0x4EB*/ { "MSG_SET_RAID_DIFFICULTY", STATUS_LOGGEDIN, &WorldSession::HandleSetRaidDifficultyOpcode },
/*0x4EC*/ { "UMSG_UNKNOWN_1260", STATUS_NEVER, &WorldSession::Handle_NULL },
/*0x4ED*/ { "SMSG_TOGGLE_XP_GAIN", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x4EE*/ { "SMSG_UNKNOWN_1262", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x4EF*/ { "SMSG_UNKNOWN_1263", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x4F0*/ { "CMSG_UNKNOWN_1264", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x4F1*/ { "SMSG_UNKNOWN_1265", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x4EE*/ { "SMSG_GMRESPONSE_DB_ERROR", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x4EF*/ { "SMSG_GMRESPONSE_RECEIVED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x4F0*/ { "CMSG_GMRESPONSE_RESOLVE", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x4F1*/ { "SMSG_GMRESPONSE_STATUS_UPDATE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
/*0x4F2*/ { "UMSG_UNKNOWN_1266", STATUS_NEVER, &WorldSession::Handle_NULL },
/*0x4F3*/ { "UMSG_UNKNOWN_1267", STATUS_NEVER, &WorldSession::Handle_NULL },
/*0x4F4*/ { "UMSG_UNKNOWN_1268", STATUS_NEVER, &WorldSession::Handle_NULL },
/*0x4F5*/ { "UMSG_UNKNOWN_1269", STATUS_NEVER, &WorldSession::Handle_NULL },
/*0x4F6*/ { "CMSG_WORLD_STATE_UI_TIMER_UPDATE", STATUS_LOGGEDIN, &WorldSession::HandleWorldStateUITimerUpdate },
/*0x4F7*/ { "SMSG_WORLD_STATE_UI_TIMER_UPDATE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x4F8*/ { "CMSG_UNKNOWN_1272", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x4F8*/ { "CMSG_CHAR_RACE_CHANGE", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x4F9*/ { "UMSG_UNKNOWN_1273", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x4FA*/ { "SMSG_TALENTS_INVOLUNTARILY_RESET", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x4FB*/ { "UMSG_UNKNOWN_1275", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x4FC*/ { "SMSG_UNKNOWN_1276", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x4FD*/ { "SMSG_LOOT_SLOT_CHANGED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x4FE*/ { "UMSG_UNKNOWN_1278", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x4FF*/ { "CMSG_READY_FOR_ACCOUNT_DATA_TIMES", STATUS_AUTHED, &WorldSession::HandleReadyForAccountDataTimes },
+ /*0x500*/ { "CMSG_QUERY_QUESTS_COMPLETED", STATUS_LOGGEDIN, &WorldSession::HandleQueryQuestsCompleted },
+ /*0x501*/ { "SMSG_QUERY_QUESTS_COMPLETED_RESPONSE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x502*/ { "CMSG_GM_REPORT_LAG", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x503*/ { "UMSG_UNKNOWN_1283", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x504*/ { "UMSG_UNKNOWN_1284", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x505*/ { "UMSG_UNKNOWN_1285", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x506*/ { "UMSG_UNKNOWN_1286", STATUS_NEVER, &WorldSession::Handle_NULL },
};
diff --git a/src/game/Opcodes.h b/src/game/Opcodes.h
index d3f80834764..a7464ba77a2 100644
--- a/src/game/Opcodes.h
+++ b/src/game/Opcodes.h
@@ -369,7 +369,7 @@ enum Opcodes
SMSG_ATTACKERSTATEUPDATE = 0x14A,
SMSG_BATTLEFIELD_PORT_DENIED = 0x14B,
SMSG_DAMAGE_DONE_OBSOLETE = 0x14C,
- SMSG_DAMAGE_TAKEN_OBSOLETE = 0x14D,
+ SMSG_UNIT_SPELLCAST_START = 0x14D,
SMSG_CANCEL_COMBAT = 0x14E,
SMSG_SPELLBREAKLOG = 0x14F,
SMSG_SPELLHEALLOG = 0x150,
@@ -404,7 +404,7 @@ enum Opcodes
CMSG_DUEL_CANCELLED = 0x16D,
SMSG_MOUNTRESULT = 0x16E,
SMSG_DISMOUNTRESULT = 0x16F,
- SMSG_PUREMOUNT_CANCELLED_OBSOLETE = 0x170,
+ SMSG_PUREMOUNT_CANCELLED_OBSOLETE = 0x170, // ERR_REMOVE_FROM_PVP_QUEUE_* events
CMSG_MOUNTSPECIAL_ANIM = 0x171,
SMSG_MOUNTSPECIAL_ANIM = 0x172,
SMSG_PET_TAME_FAILURE = 0x173,
@@ -545,10 +545,10 @@ enum Opcodes
CMSG_GM_NUKE = 0x1FA,
MSG_RANDOM_ROLL = 0x1FB,
SMSG_ENVIRONMENTALDAMAGELOG = 0x1FC,
- CMSG_RWHOIS_OBSOLETE = 0x1FD,
+ CMSG_PLAYER_DIFFICULTY_CHANGE = 0x1FD,
SMSG_RWHOIS = 0x1FE,
- MSG_LOOKING_FOR_GROUP = 0x1FF,
- CMSG_SET_LOOKING_FOR_GROUP = 0x200,
+ SMSG_LFG_COMPLETION_REWARD = 0x1FF, // uint32, uint8, uint32, uint32, uint32, uint32, uint32, uint8, for(uint8) {uint32,uint32,uint32}
+ SMSG_LFG_ERROR = 0x200, // uint32 (1,2,4,6;0,5,7)
CMSG_UNLEARN_SPELL = 0x201,
CMSG_UNLEARN_SKILL = 0x202,
SMSG_REMOVED_SPELL = 0x203,
@@ -562,7 +562,7 @@ enum Opcodes
CMSG_UPDATE_ACCOUNT_DATA = 0x20B,
SMSG_UPDATE_ACCOUNT_DATA = 0x20C,
SMSG_CLEAR_FAR_SIGHT_IMMEDIATE = 0x20D,
- SMSG_POWERGAINLOG_OBSOLETE = 0x20E,
+ SMSG_PLAYER_DIFFICULTY_CHANGE = 0x20E,
CMSG_GM_TEACH = 0x20F,
CMSG_GM_CREATE_ITEM_TARGET = 0x210,
CMSG_GMTICKET_GETTICKET = 0x211,
@@ -578,7 +578,7 @@ enum Opcodes
SMSG_GMTICKET_SYSTEMSTATUS = 0x21B,
CMSG_SPIRIT_HEALER_ACTIVATE = 0x21C,
CMSG_SET_STAT_CHEAT = 0x21D,
- SMSG_SET_REST_START_OBSOLETE = 0x21E,
+ SMSG_QUEST_FORCE_REMOVE = 0x21E, // uint32 questid
CMSG_SKILL_BUY_STEP = 0x21F,
CMSG_SKILL_BUY_RANK = 0x220,
CMSG_XP_CHEAT = 0x221,
@@ -695,13 +695,13 @@ enum Opcodes
CMSG_BUYBACK_ITEM = 0x290,
SMSG_SERVER_MESSAGE = 0x291,
CMSG_SET_SAVED_INSTANCE_EXTEND = 0x292, // lua: SetSavedInstanceExtend
- SMSG_MEETINGSTONE_LEAVE = 0x293,
- CMSG_MEETINGSTONE_CHEAT = 0x294,
- SMSG_MEETINGSTONE_SETQUEUE = 0x295,
- CMSG_MEETINGSTONE_INFO = 0x296,
- SMSG_MEETINGSTONE_COMPLETE = 0x297,
- SMSG_MEETINGSTONE_IN_PROGRESS = 0x298,
- SMSG_MEETINGSTONE_MEMBER_ADDED = 0x299,
+ SMSG_LFG_OFFER_CONTINUE = 0x293,
+ CMSG_MEETINGSTONE_CHEAT = 0x294, // not found 3.3
+ SMSG_MEETINGSTONE_SETQUEUE = 0x295, // string, showed in console
+ CMSG_MEETINGSTONE_INFO = 0x296, // EVENT_LFG_UPDATE
+ SMSG_MEETINGSTONE_COMPLETE = 0x297, // EVENT_MAIL_SHOW
+ SMSG_MEETINGSTONE_IN_PROGRESS = 0x298, // uint32, some UPDATE_COOLDOWN events
+ SMSG_MEETINGSTONE_MEMBER_ADDED = 0x299, // uint32, errors: ERR_NOT_IN_GROUP (2,51) and ERR_NOT_IN_RAID (3,39,40)
CMSG_GMTICKETSYSTEM_TOGGLE = 0x29A,
CMSG_CANCEL_GROWTH_AURA = 0x29B,
SMSG_CANCEL_AUTO_REPEAT = 0x29C,
@@ -735,7 +735,7 @@ enum Opcodes
SMSG_AREA_TRIGGER_MESSAGE = 0x2B8,
CMSG_SHOWING_HELM = 0x2B9,
CMSG_SHOWING_CLOAK = 0x2BA,
- SMSG_MEETINGSTONE_JOINFAILED = 0x2BB,
+ SMSG_LFG_ROLE_CHECK_RESULT = 0x2BB,
SMSG_PLAYER_SKINNED = 0x2BC,
SMSG_DURABILITY_DAMAGE_DEATH = 0x2BD,
CMSG_SET_EXPLORATION = 0x2BE,
@@ -896,29 +896,29 @@ enum Opcodes
MSG_MOVE_START_ASCEND = 0x359,
MSG_MOVE_STOP_ASCEND = 0x35A,
SMSG_ARENA_TEAM_STATS = 0x35B,
- CMSG_LFG_SET_AUTOJOIN = 0x35C,
- CMSG_LFG_CLEAR_AUTOJOIN = 0x35D,
- CMSG_LFM_SET_AUTOFILL = 0x35E,
- CMSG_LFM_CLEAR_AUTOFILL = 0x35F,
- CMSG_ACCEPT_LFG_MATCH = 0x360,
- CMSG_DECLINE_LFG_MATCH = 0x361,
- CMSG_CANCEL_PENDING_LFG = 0x362,
- CMSG_CLEAR_LOOKING_FOR_GROUP = 0x363,
- CMSG_CLEAR_LOOKING_FOR_MORE = 0x364,
- CMSG_SET_LOOKING_FOR_MORE = 0x365,
- CMSG_SET_LFG_COMMENT = 0x366,
- SMSG_LFG_TIMEDOUT = 0x367,
- SMSG_LFG_OTHER_TIMEDOUT = 0x368,
- SMSG_LFG_AUTOJOIN_FAILED = 0x369,
- SMSG_LFG_AUTOJOIN_FAILED_NO_PLAYER = 0x36A,
- SMSG_LFG_LEADER_IS_LFM = 0x36B,
- SMSG_LFG_UPDATE = 0x36C,
- SMSG_LFG_UPDATE_LFM = 0x36D,
- SMSG_LFG_UPDATE_LFG = 0x36E,
- SMSG_LFG_UPDATE_QUEUED = 0x36F,
- SMSG_LFG_PENDING_INVITE = 0x370,
- SMSG_LFG_PENDING_MATCH = 0x371,
- SMSG_LFG_PENDING_MATCH_DONE = 0x372,
+ CMSG_LFG_JOIN = 0x35C, // CMSG JoinLFG
+ CMSG_LFG_LEAVE = 0x35D, // CMSG LeaveLFG
+ CMSG_SEARCH_LFG_JOIN = 0x35E, // CMSG SearchLFGJoin
+ CMSG_SEARCH_LFG_LEAVE = 0x35F, // CMSG SearchLFGLeave
+ SMSG_UPDATE_LFG_LIST = 0x360, // SMSG uint32, uint32, if(uint8) { uint32 count, for(count) { uint64} }, uint32 count2, uint32, for(count2) { uint64, uint32 flags, if(flags & 0x2) {string}, if(flags & 0x10) {for(3) uint8}, if(flags & 0x80) {uint64, uint32}}, uint32 count3, uint32, for(count3) {uint64, uint32 flags, if(flags & 0x1) {uint8, uint8, uint8, for(3) uint8, uint32, uint32, uint32, uint32, uint32, uint32, float, float, uint32, uint32, uint32, uint32, uint32, float, uint32, uint32, uint32, uint32, uint32, uint32}, if(flags&0x2) string, if(flags&0x4) uint8, if(flags&0x8) uint64, if(flags&0x10) uint8, if(flags&0x20) uint32, if(flags&0x40) uint8, if(flags& 0x80) {uint64, uint32}}
+ SMSG_LFG_PROPOSAL_DECLINED = 0x361, // SMSG uint32, uint8, uint32, uint32, uint8, for(uint8) {uint32,uint8,uint8,uint8,uint8}
+ CMSG_LFG_PROPOSAL_RESULT = 0x362, // CMSG AcceptProposal, RejectProposal
+ SMSG_LFG_ROLE_CHECK = 0x363, // SMSG uint32, uint8, for(uint8) uint32, uint8, for(uint8) { uint64, uint8, uint32, uint8, }
+ SMSG_LFG_ROLE_CHECK_FAILED_RESULT = 0x364, // SMSG uint32 unk, uint32, if(unk==6) { uint8 count, for(count) uint64 }
+ SMSG_LFG_QUEUE_STATUS_UPDATE = 0x365, // SMSG uint32 dungeon, uint32 lfgtype, uint32, uint32, uint32, uint32, uint8, uint8, uint8, uint8
+ CMSG_SET_LFG_COMMENT = 0x366, // CMSG SetLFGComment
+ SMSG_LFG_LFG_PROPOSAL_INFO = 0x367, // SMSG uint8, if(uint8) { uint8, uint8, uint8, uint8, if(uint8) for(uint8) uint32, string}
+ SMSG_LFG_LFG_PROPOSAL_INFO2 = 0x368, // SMSG uint8, if(uint8) { uint8, uint8, uint8, for(3) uint8, uint8, if(uint8) for(uint8) uint32, string}
+ SMSG_LFG_UPDATE_LIST = 0x369, // SMSG uint8
+ CMSG_LFG_SET_ROLES = 0x36A, // CMSG SetLFGRoles
+ CMSG_LFG_SET_NEEDS = 0x36B, // CMSG SetLFGNeeds
+ CMSG_LFG_SET_BOOT_VOTE = 0x36C, // CMSG SetLFGBootVote
+ SMSG_LFG_BOOT_PROPOSAL_UPDATE = 0x36D, // SMSG uint8, uint8, uint8, uint64, uint32, uint32, uint32, uint32
+ CMSG_LFD_PLAYER_LOCK_INFO_REQUEST = 0x36E, // CMSG RequestLFDPlayerLockInfo
+ SMSG_LFG_PLAYER_LOCK_INFO_RESPONSE = 0x36F, // SMSG uint8, for(uint8) { uint32, uint8, uint32, uint32, uint32, uint32, uint8, for(uint8) {uint32,uint32, uint32}}, uint32, for(uint32) {uint32,uint32}
+ CMSG_LFG_TELEPORT = 0x370, // CMSG LFGTeleport
+ CMSG_LFD_PARTY_LOCK_INFO_REQUEST = 0x371, // CMSG RequestLFDPartyLockInfo
+ SMSG_LFG_PLAYER_LOCK_INFO_UPDATE = 0x372, // SMSG uint8, for(uint8) uint64
SMSG_TITLE_EARNED = 0x373,
CMSG_SET_TITLE = 0x374,
CMSG_CANCEL_MOUNT_AURA = 0x375,
@@ -1156,8 +1156,8 @@ enum Opcodes
CMSG_FORCE_PITCH_RATE_CHANGE_ACK = 0x45D,
SMSG_SPLINE_SET_PITCH_RATE = 0x45E,
SMSG_MOVE_ABANDON_TRANSPORT = 0x45F,
- MSG_MOVE_ABANDON_TRANSPORT = 0x460,
- CMSG_MOVE_ABANDON_TRANSPORT_ACK = 0x461,
+ SMSG_CALENDAR_UPDATE_INVITE_LIST = 0x460,
+ SMSG_CALENDAR_UPDATE_INVITE_LIST2 = 0x461,
CMSG_UPDATE_MISSILE_TRAJECTORY = 0x462,
SMSG_UPDATE_ACCOUNT_DATA_COMPLETE = 0x463,
SMSG_TRIGGER_MOVIE = 0x464,
@@ -1173,7 +1173,7 @@ enum Opcodes
CMSG_COMPLETE_ACHIEVEMENT_CHEAT = 0x46E,
SMSG_QUESTUPDATE_ADD_PVP_KILL = 0x46F,
CMSG_SET_CRITERIA_CHEAT = 0x470,
- SMSG_GROUP_SWAP_FAILED = 0x471,
+ SMSG_CALENDAR_UPDATE_INVITE_LIST3 = 0x471,
CMSG_UNITANIMTIER_CHEAT = 0x472,
CMSG_CHAR_CUSTOMIZE = 0x473,
SMSG_CHAR_CUSTOMIZE = 0x474,
@@ -1226,7 +1226,7 @@ enum Opcodes
SMSG_SERVER_BUCK_DATA_START = 0x4A3, // not found
CMSG_QUERY_VEHICLE_STATUS = 0x4A4, // not found
UMSG_UNKNOWN_1189 = 0x4A5, // not found, old SMSG_PET_GUIDS
- SMSG_UNKNOWN_1190 = 0x4A6, // smsg unk, "You can't do that yet"
+ SMSG_BATTLEGROUND_INFO_THROTTLED = 0x4A6, // empty, "You can't do that yet"
SMSG_PLAYER_VEHICLE_DATA = 0x4A7, // smsg guid+uint32 (vehicle)
CMSG_PLAYER_VEHICLE_ENTER = 0x4A8, // cmsg uint64
CMSG_EJECT_PASSENGER = 0x4A9, // cmsg uint64
@@ -1238,16 +1238,16 @@ enum Opcodes
UMSG_UNKNOWN_1199 = 0x4AF, // not found
UMSG_UNKNOWN_1200 = 0x4B0, // not found
UMSG_UNKNOWN_1201 = 0x4B1, // not found
- SMSG_ITEM_REFUND_TIMER = 0x4B2, // refund something
- CMSG_ITEM_REFUND_INFO_REQUEST = 0x4B3, // refund request?
+ SMSG_ITEM_REFUND_INFO_RESPONSE = 0x4B2, // refund item info
+ CMSG_ITEM_REFUND_INFO = 0x4B3, // refund request?
CMSG_ITEM_REFUND = 0x4B4, // lua: ContainerRefundItemPurchase
- SMSG_ITEM_REFUND = 0x4B5, // refund something
+ SMSG_ITEM_REFUND_RESULT = 0x4B5, // refund item result
CMSG_CORPSE_MAP_POSITION_QUERY = 0x4B6, // CMSG, uint32
CMSG_CORPSE_MAP_POSITION_QUERY_RESPONSE = 0x4B7, // SMSG, 3*float+float
- CMSG_LFG_SET_ROLES = 0x4B8, // CMSG, empty, lua: SetLFGRoles
+ UMSG_UNKNOWN_1208 = 0x4B8, // not found
UMSG_UNKNOWN_1209 = 0x4B9, // not found
- CMSG_UNKNOWN_1210 = 0x4BA, // CMSG, uint64, lua: CalendarContextEventSignUp
- SMSG_UNKNOWN_1211 = 0x4BB, // SMSG, calendar related
+ CMSG_CALENDAR_CONTEXT_EVENT_SIGNUP = 0x4BA, // CMSG, uint64, lua: CalendarContextEventSignUp
+ SMSG_CALENDAR_ACTION_PENDING = 0x4BB, // SMSG, calendar related EVENT_CALENDAR_ACTION_PENDING
SMSG_EQUIPMENT_SET_LIST = 0x4BC, // SMSG, equipment manager list?
CMSG_EQUIPMENT_SET_SAVE = 0x4BD, // CMSG, lua: SaveEquipmentSet
CMSG_UNKNOWN_1214 = 0x4BE, // CMSG, missle?
@@ -1259,57 +1259,71 @@ enum Opcodes
UMSG_UNKNOWN_1220 = 0x4C4, // not found 3.2
UMSG_UNKNOWN_1221 = 0x4C5, // not found 3.2
UMSG_UNKNOWN_1222 = 0x4C6, // not found 3.2
- SMSG_UNKNOWN_1223 = 0x4C7, // uint64, arena pet? 3.2
- SMSG_UNKNOWN_1224 = 0x4C8, // uint32 "Can't modify arena team while queued or in a match." 3.2
+ SMSG_ARENA_OPPONENT_UPDATE = 0x4C7, // uint64, EVENT_ARENA_OPPONENT_UPDATE
+ SMSG_ARENA_TEAM_CHANGE_FAILED_QUEUED = 0x4C8, // uint32 "Can't modify arena team while queued or in a match." 3.2
UMSG_UNKNOWN_1225 = 0x4C9, // not found 3.2
UMSG_UNKNOWN_1226 = 0x4CA, // not found 3.2
UMSG_UNKNOWN_1227 = 0x4CB, // not found 3.2
UMSG_UNKNOWN_1228 = 0x4CC, // not found 3.2
- SMSG_UNKNOWN_1229 = 0x4CD, // SMSG, any opcode?
- SMSG_UNKNOWN_1230 = 0x4CE, // SMSG, movement related
- CMSG_UNKNOWN_1231_ACK = 0x4CF, // movement related
- SMSG_UNKNOWN_1232 = 0x4D0, // SMSG, movement related
- CMSG_UNKNOWN_1233_ACK = 0x4D1, // movement related
- SMSG_UNKNOWN_1234 = 0x4D2, // SMSG, movement related
- SMSG_UNKNOWN_1235 = 0x4D3, // SMSG, movement related
- SMSG_UNKNOWN_1236 = 0x4D4, // SMSG, movement related
+ SMSG_UNKNOWN_1229 = 0x4CD, // SMSG, handles any opcode
+ SMSG_FORCE_UNK1_SPEED_CHANGE = 0x4CE, // SMSG, movement related
+ CMSG_FORCE_UNK1_SPEED_CHANGE_ACK = 0x4CF, // movement related
+ SMSG_FORCE_UNK2_SPEED_CHANGE = 0x4D0, // SMSG, movement related
+ CMSG_FORCE_UNK2_SPEED_CHANGE_ACK = 0x4D1, // movement related
+ MSG_MOVE_UNKNOWN_1234 = 0x4D2, // SMSG, movement related
+ SMSG_SPLINE_MOVE_UNKNOWN_1235 = 0x4D3, // SMSG, movement related
+ SMSG_SPLINE_MOVE_UNKNOWN_1236 = 0x4D4, // SMSG, movement related
CMSG_EQUIPMENT_SET_USE = 0x4D5, // CMSG, lua: UseEquipmentSet
SMSG_EQUIPMENT_SET_USE_RESULT = 0x4D6, // SMSG, UseEquipmentSetResult?
UMSG_UNKNOWN_1239 = 0x4D7, // not found 3.2
- SMSG_UNKNOWN_1240 = 0x4D8, // SMSG, uint64, string
+ SMSG_UNKNOWN_1240 = 0x4D8, // SMSG, uint64, string, doing nothing
CMSG_CHAR_FACTION_CHANGE = 0x4D9, // lua: CreateCharacter (PFC client response)
SMSG_CHAR_FACTION_CHANGE = 0x4DA, // response to 1241 (PFC server response)
UMSG_UNKNOWN_1243 = 0x4DB, // not found 3.2
UMSG_UNKNOWN_1244 = 0x4DC, // not found 3.2
UMSG_UNKNOWN_1245 = 0x4DD, // not found 3.2
- SMSG_UNKNOWN_1246 = 0x4DE, // uint32, BattlefieldMgrEntryInvite
- CMSG_UNKNOWN_1247 = 0x4DF, // lua: BattlefieldMgrEntryInviteResponse
- SMSG_UNKNOWN_1248 = 0x4E0, // uint32, uint8, uint8
- SMSG_UNKNOWN_1249 = 0x4E1, // uint32 BattlefieldMgrQueueInvite
- CMSG_UNKNOWN_1250 = 0x4E2, // lua: BattlefieldMgrQueueInviteResponse
- CMSG_UNKNOWN_1251 = 0x4E3, // lua: BattlefieldMgrQueueRequest
- SMSG_UNKNOWN_1252 = 0x4E4, // uint32, uint8 queue full/can't join
- SMSG_UNKNOWN_1253 = 0x4E5, // uint32 wintergrasp is full, you'll be ejected soon
- SMSG_UNKNOWN_1254 = 0x4E6, // uint32, uint32, uint8
- CMSG_UNKNOWN_1255 = 0x4E7, // lua: BattlefieldMgrExitRequest
- SMSG_UNKNOWN_1256 = 0x4E8, // uint32, uint32
+ SMSG_BATTLEFIELD_MGR_ENTRY_INVITE = 0x4DE, // uint32, EVENT_BATTLEFIELD_MGR_ENTRY_INVITE
+ CMSG_BATTLEFIELD_MGR_ENTRY_INVITE_RESPONSE = 0x4DF, // lua: BattlefieldMgrEntryInviteResponse
+ SMSG_BATTLEFIELD_MGR_ENTERED = 0x4E0, // uint32, uint8, uint8 EVENT_BATTLEFIELD_MGR_ENTERED
+ SMSG_BATTLEFIELD_MGR_QUEUE_INVITE = 0x4E1, // uint32 EVENT_BATTLEFIELD_MGR_QUEUE_INVITE
+ CMSG_BATTLEFIELD_MGR_QUEUE_INVITE_RESPONSE = 0x4E2, // lua: BattlefieldMgrQueueInviteResponse
+ CMSG_BATTLEFIELD_MGR_QUEUE_REQUEST = 0x4E3, // lua: BattlefieldMgrQueueRequest
+ SMSG_BATTLEFIELD_MGR_QUEUE_REQUEST_RESPONSE = 0x4E4, // uint32, uint8 EVENT_BATTLEFIELD_MGR_QUEUE_REQUEST_RESPONSE
+ SMSG_BATTLEFIELD_MGR_EJECT_PENDING = 0x4E5, // uint32 EVENT_BATTLEFIELD_MGR_EJECT_PENDING
+ SMSG_BATTLEFIELD_MGR_EJECTED = 0x4E6, // uint32, uint32, uint8 EVENT_BATTLEFIELD_MGR_EJECTED
+ CMSG_BATTLEFIELD_MGR_EXIT_REQUEST = 0x4E7, // lua: BattlefieldMgrExitRequest
+ SMSG_BATTLEFIELD_MGR_STATE_CHANGE = 0x4E8, // uint32, uint32 EVENT_BATTLEFIELD_MGR_STATE_CHANGE
UMSG_UNKNOWN_1257 = 0x4E9, // not found 3.2
UMSG_UNKNOWN_1258 = 0x4EA, // not found 3.2
MSG_SET_RAID_DIFFICULTY = 0x4EB, // lua: SetRaidDifficulty
UMSG_UNKNOWN_1260 = 0x4EC, // not found 3.2
SMSG_TOGGLE_XP_GAIN = 0x4ED, // enable/disable XP gain console message
- SMSG_UNKNOWN_1262 = 0x4EE,
- SMSG_UNKNOWN_1263 = 0x4EF,
- CMSG_UNKNOWN_1264 = 0x4F0, // lua: GMResponseResolve
- SMSG_UNKNOWN_1265 = 0x4F1,
+ SMSG_GMRESPONSE_DB_ERROR = 0x4EE, // empty
+ SMSG_GMRESPONSE_RECEIVED = 0x4EF, // uint32, uint32, string[2000], string[4000][4]
+ CMSG_GMRESPONSE_RESOLVE = 0x4F0, // lua: GMResponseResolve
+ SMSG_GMRESPONSE_STATUS_UPDATE = 0x4F1, // uint8 (1 - EVENT_GMSURVEY_DISPLAY, 0 - EVENT_UPDATE_TICKET)
UMSG_UNKNOWN_1266 = 0x4F2, // not found 3.2
UMSG_UNKNOWN_1267 = 0x4F3, // not found 3.2
UMSG_UNKNOWN_1268 = 0x4F4, // not found 3.2
UMSG_UNKNOWN_1269 = 0x4F5, // not found 3.2
CMSG_WORLD_STATE_UI_TIMER_UPDATE = 0x4F6,
SMSG_WORLD_STATE_UI_TIMER_UPDATE = 0x4F7,
- CMSG_UNKNOWN_1272 = 0x4F8, // called from lua: CreateCharacter, paid race change
- NUM_MSG_TYPES = 0x4F9
+ CMSG_CHAR_RACE_CHANGE = 0x4F8, // called from lua: CreateCharacter, paid race change
+ UMSG_UNKNOWN_1273 = 0x4F9, // not found 10554
+ SMSG_TALENTS_INVOLUNTARILY_RESET = 0x4FA, // uint8 EVENT_TALENTS_INVOLUNTARILY_RESET
+ UMSG_UNKNOWN_1275 = 0x4FB, // not found 10554
+ SMSG_UNKNOWN_1276 = 0x4FC, // does nothing in 10554
+ SMSG_LOOT_SLOT_CHANGED = 0x4FD, // EVENT_LOOT_SLOT_CHANGED
+ UMSG_UNKNOWN_1278 = 0x4FE, // not found 10596
+ CMSG_READY_FOR_ACCOUNT_DATA_TIMES = 0x4FF, // lua: ReadyForAccountDataTimes
+ CMSG_QUERY_QUESTS_COMPLETED = 0x500, // lua: QueryQuestsCompleted
+ SMSG_QUERY_QUESTS_COMPLETED_RESPONSE = 0x501, // response to 0x500
+ CMSG_GM_REPORT_LAG = 0x502, // lua: GMReportLag
+ UMSG_UNKNOWN_1283 = 0x503,
+ UMSG_UNKNOWN_1284 = 0x504,
+ UMSG_UNKNOWN_1285 = 0x505,
+ UMSG_UNKNOWN_1286 = 0x506,
+ NUM_MSG_TYPES = 0x507
};
/// Player state
diff --git a/src/game/Pet.cpp b/src/game/Pet.cpp
index 5bb5be55908..981f864136c 100644
--- a/src/game/Pet.cpp
+++ b/src/game/Pet.cpp
@@ -40,7 +40,7 @@ char const* petTypeSuffix[MAX_PET_TYPE] =
"'s Companion" // MINI_PET
};
-#define PET_XP_FACTOR 0.1f
+#define PET_XP_FACTOR 0.05f
Pet::Pet(Player *owner, PetType type) : Guardian(NULL, owner),
m_petType(type), m_removed(false), m_happinessTimer(7500), m_duration(0),
@@ -215,7 +215,7 @@ bool Pet::LoadPetFromDB( Player* owner, uint32 petentry, uint32 petnumber, bool
case HUNTER_PET:
SetUInt32Value(UNIT_FIELD_BYTES_0, 0x02020100); //class=warrior,gender=none,power=focus
SetSheath(SHEATH_STATE_MELEE);
- SetByteValue(UNIT_FIELD_BYTES_2, 2, fields[9].GetBool() ? UNIT_RENAME_NOT_ALLOWED : UNIT_RENAME_ALLOWED);
+ SetByteFlag(UNIT_FIELD_BYTES_2, 2, fields[9].GetBool() ? UNIT_CAN_BE_ABANDONED : UNIT_CAN_BE_RENAMED | UNIT_CAN_BE_ABANDONED);
SetUInt32Value(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE);
// this enables popup window (pet abandon, cancel)
@@ -420,7 +420,7 @@ void Pet::SavePetToDB(PetSaveMode mode)
<< uint32(GetReactState()) << ", "
<< uint32(mode) << ", '"
<< name.c_str() << "', "
- << uint32((GetByteValue(UNIT_FIELD_BYTES_2, 2) == UNIT_RENAME_ALLOWED)?0:1) << ", "
+ << uint32(HasByteFlag(UNIT_FIELD_BYTES_2, 2, UNIT_CAN_BE_RENAMED) ? 0 : 1) << ", "
<< curhealth << ", "
<< curmana << ", "
<< GetPower(POWER_HAPPINESS) << ", '";
@@ -785,7 +785,7 @@ bool Pet::CreateBaseAtCreature(Creature* creature)
{
SetUInt32Value(UNIT_FIELD_BYTES_0, 0x02020100);
SetSheath(SHEATH_STATE_MELEE);
- SetByteValue(UNIT_FIELD_BYTES_2, 2, UNIT_RENAME_ALLOWED);
+ SetByteFlag(UNIT_FIELD_BYTES_2, 2, UNIT_CAN_BE_RENAMED | UNIT_CAN_BE_ABANDONED);
SetUInt32Value(UNIT_MOD_CAST_SPEED, creature->GetUInt32Value(UNIT_MOD_CAST_SPEED));
}
return true;
@@ -1949,7 +1949,7 @@ void Pet::SynchronizeLevelWithOwner()
if (getLevel() > owner->getLevel())
{
GivePetLevel(owner->getLevel());
- SetUInt32Value(UNIT_FIELD_PETNEXTLEVELEXP, objmgr.GetXPForLevel(owner->getLevel())/4);
+ SetUInt32Value(UNIT_FIELD_PETNEXTLEVELEXP, objmgr.GetXPForLevel(owner->getLevel())/5);
SetUInt32Value(UNIT_FIELD_PETEXPERIENCE, GetUInt32Value(UNIT_FIELD_PETNEXTLEVELEXP)-1);
}
break;
diff --git a/src/game/PetHandler.cpp b/src/game/PetHandler.cpp
index 11d03ffb13d..f6d6cf3e2da 100644
--- a/src/game/PetHandler.cpp
+++ b/src/game/PetHandler.cpp
@@ -515,7 +515,7 @@ void WorldSession::HandlePetRename( WorldPacket & recv_data )
Pet* pet = ObjectAccessor::GetPet(petguid);
// check it!
if( !pet || !pet->isPet() || ((Pet*)pet)->getPetType()!= HUNTER_PET ||
- pet->GetByteValue(UNIT_FIELD_BYTES_2, 2) != UNIT_RENAME_ALLOWED ||
+ !pet->HasByteFlag(UNIT_FIELD_BYTES_2, 2, UNIT_CAN_BE_RENAMED) ||
pet->GetOwnerGUID() != _player->GetGUID() || !pet->GetCharmInfo() )
return;
@@ -538,7 +538,7 @@ void WorldSession::HandlePetRename( WorldPacket & recv_data )
if(owner && (owner->GetTypeId() == TYPEID_PLAYER) && ((Player*)owner)->GetGroup())
((Player*)owner)->SetGroupUpdateFlag(GROUP_UPDATE_FLAG_PET_NAME);
- pet->SetByteValue(UNIT_FIELD_BYTES_2, 2, UNIT_RENAME_NOT_ALLOWED);
+ pet->RemoveByteFlag(UNIT_FIELD_BYTES_2, 2, UNIT_CAN_BE_RENAMED);
if(isdeclined)
{
diff --git a/src/game/Player.cpp b/src/game/Player.cpp
index 985908dff0a..46906a03e94 100644
--- a/src/game/Player.cpp
+++ b/src/game/Player.cpp
@@ -758,16 +758,10 @@ bool Player::Create( uint32 guidlow, const std::string& name, uint8 race, uint8
uint32 item_id = oEntry->ItemId[j];
- // Hack for not existed item id in dbc 3.0.3
- if(item_id==40582)
- continue;
-
+ // just skip, reported in ObjectMgr::LoadItemPrototypes
ItemPrototype const* iProto = objmgr.GetItemPrototype(item_id);
- if(!iProto)
- {
- sLog.outErrorDb("Initial item id %u (race %u class %u) from CharStartOutfit.dbc not listed in `item_template`, ignoring.",item_id,getRace(),getClass());
+ if (!iProto)
continue;
- }
// BuyCount by default
uint32 count = iProto->BuyCount;
@@ -787,6 +781,11 @@ bool Player::Create( uint32 guidlow, const std::string& name, uint8 race, uint8
if(iProto->Stackable < count)
count = iProto->Stackable;
}
+ // special amount for daggers
+ else if(iProto->Class==ITEM_CLASS_WEAPON && iProto->SubClass==ITEM_SUBCLASS_WEAPON_DAGGER)
+ {
+ count = 2; // will placed to 2 slots
+ }
StoreNewItemInBestSlots(item_id, count);
}
@@ -1539,7 +1538,8 @@ bool Player::BuildEnumData( QueryResult_AutoPtr result, WorldPacket * p_data )
*p_data << uint32(char_flags); // character flags
// character customize flags
*p_data << uint32(atLoginFlags & AT_LOGIN_CUSTOMIZE ? CHAR_CUSTOMIZE_FLAG_CUSTOMIZE : CHAR_CUSTOMIZE_FLAG_NONE);
- *p_data << uint8(1); // unknown
+ // First login
+ *p_data << uint8(atLoginFlags & AT_LOGIN_FIRST ? 1 : 0);
// Pets info
{
@@ -2074,6 +2074,10 @@ void Player::Regenerate(Powers power)
{
bool recentCast = IsUnderLastManaUseEffect();
float ManaIncreaseRate = sWorld.getRate(RATE_POWER_MANA);
+
+ if (getLevel() < 15)
+ ManaIncreaseRate = sWorld.getRate(RATE_POWER_MANA) * (2.066f - (getLevel() * 0.066f));
+
if (recentCast) // Trinity Updates Mana in intervals of 2s, which is correct
addvalue += GetFloatValue(UNIT_FIELD_POWER_REGEN_INTERRUPTED_FLAT_MODIFIER) * ManaIncreaseRate * 0.001f * m_regenTimer;
else
@@ -2175,6 +2179,9 @@ void Player::RegenerateHealth()
float HealthIncreaseRate = sWorld.getRate(RATE_HEALTH);
+ if (getLevel() < 15)
+ HealthIncreaseRate = sWorld.getRate(RATE_HEALTH) * (2.066f - (getLevel() * 0.066f));
+
float addvalue = 0.0f;
// polymorphed case
@@ -2497,7 +2504,7 @@ void Player::GiveXP(uint32 xp, Unit* victim)
return;
// XP resting bonus for kill
- uint32 rested_bonus_xp = victim ? GetXPRestBonus(xp) : 0;
+ uint32 rested_bonus_xp = victim ? GetXPRestBonus(xp) : 0;
// Heirloom Experience Bonus
float heirloomModifier = 1.0f;
@@ -3991,7 +3998,7 @@ void Player::InitVisibleBits()
updateVisualBits.SetBit(UNIT_NPC_FLAGS);
// PLAYER_QUEST_LOG_x also visible bit on official (but only on party/raid)...
- for (uint16 i = PLAYER_QUEST_LOG_1_1; i < PLAYER_QUEST_LOG_25_2; i += 4)
+ for (uint16 i = PLAYER_QUEST_LOG_1_1; i < PLAYER_QUEST_LOG_25_2; i += MAX_QUEST_OFFSET)
updateVisualBits.SetBit(i);
// Players visible items are not inventory stuff
@@ -4100,7 +4107,7 @@ TrainerSpellState Player::GetTrainerSpellState(TrainerSpell const* trainer_spell
{
if (!trainer_spell->learnedSpell[i])
continue;
-
+
if(!HasSpell(trainer_spell->learnedSpell[i]))
{
hasSpell = false;
@@ -6294,13 +6301,38 @@ void Player::RewardReputation(Quest const *pQuest)
// quest reputation reward/loss
for (uint8 i = 0; i < QUEST_REPUTATIONS_COUNT; ++i)
{
- if(pQuest->RewRepFaction[i] && pQuest->RewRepValue[i] )
+ if (!pQuest->RewRepFaction[i])
+ continue;
+ if (pQuest->RewRepValue[i])
{
int32 rep = CalculateReputationGain(GetQuestLevel(pQuest), pQuest->RewRepValue[i], pQuest->RewRepFaction[i], true);
- FactionEntry const* factionEntry = sFactionStore.LookupEntry(pQuest->RewRepFaction[i]);
- if(factionEntry)
+ if (FactionEntry const* factionEntry = sFactionStore.LookupEntry(pQuest->RewRepFaction[i]))
GetReputationMgr().ModifyReputation(factionEntry, rep);
}
+ else
+ {
+ uint32 row = 1;
+ int32 field = 0;
+
+ if (pQuest->RewRepValueId[i] < 0)
+ {
+ ++row;
+ field = abs(pQuest->RewRepValueId[i]);
+ }
+ else
+ field = pQuest->RewRepValueId[i];
+ if (const QuestFactionRewEntry *pRow = sQuestFactionRewardStore.LookupEntry(row))
+ {
+ int32 repPoints = pRow->QuestRewFactionValue[field];
+
+ if (!repPoints)
+ continue;
+
+ repPoints = CalculateReputationGain(GetQuestLevel(pQuest), repPoints, pQuest->RewRepFaction[i], true);
+ if (const FactionEntry* factionEntry = sFactionStore.LookupEntry(pQuest->RewRepFaction[i]))
+ GetReputationMgr().ModifyReputation(factionEntry, repPoints);
+ }
+ }
}
// TODO: implement reputation spillover
@@ -6817,7 +6849,7 @@ void Player::DuelComplete(DuelCompleteType type)
duel->opponent->AttackStop();
}
break;
- case DUEL_WON:
+ case DUEL_WON:
GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LOSE_DUEL, 1);
if (duel->opponent)
{
@@ -6895,37 +6927,32 @@ void Player::_ApplyItemMods(Item *item, uint8 slot,bool apply)
if (!proto)
return;
- // not apply mods for broken item
- if (item->IsBroken())
- {
- if (proto->Socket[0].Color)
- CorrectMetaGemEnchants(slot, apply);
+ if (proto->Socket[0].Color) //only (un)equipping of items with sockets can influence metagems, so no need to waste time with normal items
+ CorrectMetaGemEnchants(slot, apply);
+ // not apply/remove mods for broken item
+ if (item->IsBroken())
return;
- }
sLog.outDetail("applying mods for item %u ",item->GetGUIDLow());
uint8 attacktype = Player::GetAttackBySlot(slot);
- //check disarm only on mod apply to allow remove item mods
+ // check disarm only on mod apply to allow remove item mods
if (!CanUseAttackType(attacktype) )
return;
- if(attacktype < MAX_ATTACK)
+ if (attacktype < MAX_ATTACK)
_ApplyWeaponDependentAuraMods(item,WeaponAttackType(attacktype),apply);
_ApplyItemBonuses(proto,slot,apply);
- if( slot==EQUIPMENT_SLOT_RANGED )
+ if (slot==EQUIPMENT_SLOT_RANGED)
_ApplyAmmoBonuses();
ApplyItemEquipSpell(item,apply);
ApplyEnchantment(item, apply);
- if(proto->Socket[0].Color) //only (un)equipping of items with sockets can influence metagems, so no need to waste time with normal items
- CorrectMetaGemEnchants(slot, apply);
-
sLog.outDebug("_ApplyItemMods complete.");
}
@@ -7095,9 +7122,9 @@ void Player::_ApplyItemBonuses(ItemPrototype const *proto, uint8 slot, bool appl
case ITEM_MOD_RANGED_ATTACK_POWER:
HandleStatModifier(UNIT_MOD_ATTACK_POWER_RANGED, TOTAL_VALUE, float(val), apply);
break;
- case ITEM_MOD_FERAL_ATTACK_POWER:
- ApplyFeralAPBonus(int32(val), apply);
- break;
+// case ITEM_MOD_FERAL_ATTACK_POWER:
+// ApplyFeralAPBonus(int32(val), apply);
+// break;
case ITEM_MOD_MANA_REGENERATION:
ApplyManaRegenBonus(int32(val), apply);
break;
@@ -8686,40 +8713,39 @@ void Player::SendInitWorldStates(uint32 zoneid, uint32 areaid)
break;
case 3703: // Shattrath City
case 4384: // SA
- /*if (bg && bg->GetTypeID() == BATTLEGROUND_SA)
- bg->FillInitialWorldStates(data);
+ if (bg && bg->GetTypeID() == BATTLEGROUND_SA)
+ bg->FillInitialWorldStates(data);
else
- {*/
+ {
// 1-3 A defend, 4-6 H defend, 7-9 unk defend, 1 - ok, 2 - half destroyed, 3 - destroyed
- data << uint32(0xf09) << uint32(0x4); // 7 3849 Gate of Temple
- data << uint32(0xe36) << uint32(0x4); // 8 3638 Gate of Yellow Moon
- data << uint32(0xe27) << uint32(0x4); // 9 3623 Gate of Green Emerald
- data << uint32(0xe24) << uint32(0x4); // 10 3620 Gate of Blue Sapphire
- data << uint32(0xe21) << uint32(0x4); // 11 3617 Gate of Red Sun
- data << uint32(0xe1e) << uint32(0x4); // 12 3614 Gate of Purple Ametyst
+ data << uint32(0xf09) << uint32(0x0); // 7 3849 Gate of Temple
+ data << uint32(0xe36) << uint32(0x0); // 8 3638 Gate of Yellow Moon
+ data << uint32(0xe27) << uint32(0x0); // 9 3623 Gate of Green Emerald
+ data << uint32(0xe24) << uint32(0x0); // 10 3620 Gate of Blue Sapphire
+ data << uint32(0xe21) << uint32(0x0); // 11 3617 Gate of Red Sun
+ data << uint32(0xe1e) << uint32(0x0); // 12 3614 Gate of Purple Ametyst
data << uint32(0xdf3) << uint32(0x0); // 13 3571 bonus timer (1 - on, 0 - off)
data << uint32(0xded) << uint32(0x0); // 14 3565 Horde Attacker
- data << uint32(0xdec) << uint32(0x1); // 15 3564 Alliance Attacker
+ data << uint32(0xdec) << uint32(0x0); // 15 3564 Alliance Attacker
// End Round (timer), better explain this by example, eg. ends in 19:59 -> A:BC
- data << uint32(0xde9) << uint32(0x9); // 16 3561 C
- data << uint32(0xde8) << uint32(0x5); // 17 3560 B
- data << uint32(0xde7) << uint32(0x19); // 18 3559 A
- data << uint32(0xe35) << uint32(0x1); // 19 3637 East g - Horde control
- data << uint32(0xe34) << uint32(0x1); // 20 3636 West g - Horde control
- data << uint32(0xe33) << uint32(0x1); // 21 3635 South g - Horde control
+ data << uint32(0xde9) << uint32(0x0); // 16 3561 C
+ data << uint32(0xde8) << uint32(0x0); // 17 3560 B
+ data << uint32(0xde7) << uint32(0x0); // 18 3559 A
+ data << uint32(0xe35) << uint32(0x0); // 19 3637 East g - Horde control
+ data << uint32(0xe34) << uint32(0x0); // 20 3636 West g - Horde control
+ data << uint32(0xe33) << uint32(0x0); // 21 3635 South g - Horde control
data << uint32(0xe32) << uint32(0x0); // 22 3634 East g - Alliance control
data << uint32(0xe31) << uint32(0x0); // 23 3633 West g - Alliance control
data << uint32(0xe30) << uint32(0x0); // 24 3632 South g - Alliance control
- data << uint32(0xe2f) << uint32(0x1); // 25 3631 Chamber of Ancients - Horde control
+ data << uint32(0xe2f) << uint32(0x0); // 25 3631 Chamber of Ancients - Horde control
data << uint32(0xe2e) << uint32(0x0); // 26 3630 Chamber of Ancients - Alliance control
data << uint32(0xe2d) << uint32(0x0); // 27 3629 Beach1 - Horde control
data << uint32(0xe2c) << uint32(0x0); // 28 3628 Beach2 - Horde control
- data << uint32(0xe2b) << uint32(0x1); // 29 3627 Beach1 - Alliance control
- data << uint32(0xe2a) << uint32(0x1); // 30 3626 Beach2 - Alliance control
+ data << uint32(0xe2b) << uint32(0x0); // 29 3627 Beach1 - Alliance control
+ data << uint32(0xe2a) << uint32(0x0); // 30 3626 Beach2 - Alliance control
// and many unks...
- //}
- break;
+ }
break;
case 4406: // Ring of Valor
if (bg && bg->GetTypeID() == BATTLEGROUND_RV)
@@ -9584,7 +9610,7 @@ uint8 Player::_CanTakeMoreSimilarItems(uint32 entry, uint32 count, Item* pItem,
if (curcount + count > limitEntry->maxCount)
{
if (no_space_count)
- *no_space_count = count + curcount - limitEntry->maxCount;
+ *no_space_count = count + curcount - limitEntry->maxCount;
return EQUIP_ERR_CANT_CARRY_MORE_OF_THIS; // attempt add too many limit category items
}
}
@@ -10692,6 +10718,12 @@ uint8 Player::CanBankItem( uint8 bag, uint8 slot, ItemPosCountVec &dest, Item *p
if (!pItem)
return swap ? EQUIP_ERR_ITEMS_CANT_BE_SWAPPED : EQUIP_ERR_ITEM_NOT_FOUND;
+ if (pItem->m_lootGenerated)
+ {
+ GetSession()->DoLootRelease(GetLootGUID());
+ return EQUIP_ERR_OK;
+ }
+
uint32 count = pItem->GetCount();
sLog.outDebug( "STORAGE: CanBankItem bag = %u, slot = %u, item = %u, count = %u", bag, slot, pItem->GetEntry(), pItem->GetCount());
@@ -10887,7 +10919,28 @@ uint8 Player::CanUseItem( Item *pItem, bool not_loading ) const
if (pItem->GetSkill() != 0)
{
- if (GetSkillValue( pItem->GetSkill() ) == 0)
+ bool allowEquip = false;
+ uint32 itemSkill = pItem->GetSkill();
+ // Armor that is binded to account can "morph" from plate to mail, etc. if skill is not learned yet.
+ if (pProto->Quality == ITEM_QUALITY_HEIRLOOM && pProto->Class == ITEM_CLASS_ARMOR && !HasSkill(itemSkill))
+ {
+ // TODO: when you right-click already equipped item it throws EQUIP_ERR_NO_REQUIRED_PROFICIENCY.
+
+ // In fact it's a visual bug, everything works properly... I need sniffs of operations with
+ // binded to account items from off server.
+
+ switch (this->getClass())
+ {
+ case CLASS_HUNTER:
+ case CLASS_SHAMAN:
+ allowEquip = (itemSkill == SKILL_MAIL);
+ break;
+ case CLASS_PALADIN:
+ allowEquip = (itemSkill == SKILL_PLATE_MAIL);
+ break;
+ }
+ }
+ if (!allowEquip && GetSkillValue(itemSkill) == 0)
return EQUIP_ERR_NO_REQUIRED_PROFICIENCY;
}
@@ -12131,7 +12184,7 @@ void Player::SwapItem( uint16 src, uint16 dst )
// bag swap (with items exchange) case
if(emptyBag && fullBag)
{
- ItemPrototype const* emotyProto = emptyBag->GetProto();
+ ItemPrototype const* emptyProto = emptyBag->GetProto();
uint32 count = 0;
@@ -12142,7 +12195,7 @@ void Player::SwapItem( uint16 src, uint16 dst )
continue;
ItemPrototype const* bagItemProto = bagItem->GetProto();
- if (!bagItemProto || !ItemCanGoIntoBag(bagItemProto, emotyProto))
+ if (!bagItemProto || !ItemCanGoIntoBag(bagItemProto, emptyProto))
{
// one from items not go to empty target bag
SendEquipError( EQUIP_ERR_NONEMPTY_BAG_OVER_OTHER_BAG, pSrcItem, pDstItem );
@@ -12196,6 +12249,46 @@ void Player::SwapItem( uint16 src, uint16 dst )
else if (IsEquipmentPos(src))
EquipItem(eDest2, pDstItem, true);
+ // if player is moving bags and is looting an item inside this bag
+ // release the loot
+ if (GetLootGUID())
+ {
+ bool released = false;
+ if (IsBagPos(src))
+ {
+ Bag* bag = (Bag*)pSrcItem;
+ for(int i=0; i < bag->GetBagSize(); ++i)
+ {
+ if (Item *bagItem = bag->GetItemByPos(i))
+ {
+ if (bagItem->m_lootGenerated)
+ {
+ m_session->DoLootRelease(GetLootGUID());
+ released = true; // so we don't need to look at dstBag
+ break;
+ }
+ }
+ }
+ }
+
+ if (!released && IsBagPos(dst) && pDstItem)
+ {
+ Bag* bag = (Bag*)pDstItem;
+ for(int i=0; i < bag->GetBagSize(); ++i)
+ {
+ if (Item *bagItem = bag->GetItemByPos(i))
+ {
+ if (bagItem->m_lootGenerated)
+ {
+ m_session->DoLootRelease(GetLootGUID());
+ released = true; // not realy needed here
+ break;
+ }
+ }
+ }
+ }
+ }
+
AutoUnequipOffhandIfNeed();
}
@@ -12792,8 +12885,8 @@ void Player::ApplyEnchantment(Item *item, EnchantmentSlot slot, bool apply, bool
HandleStatModifier(UNIT_MOD_ATTACK_POWER_RANGED, TOTAL_VALUE, float(enchant_amount), apply);
sLog.outDebug("+ %u RANGED_ATTACK_POWER", enchant_amount);
break;
- case ITEM_MOD_FERAL_ATTACK_POWER:
- ((Player*)this)->ApplyFeralAPBonus(enchant_amount, apply);
+// case ITEM_MOD_FERAL_ATTACK_POWER:
+// ((Player*)this)->ApplyFeralAPBonus(enchant_amount, apply);
sLog.outDebug("+ %u FERAL_ATTACK_POWER", enchant_amount);
break;
case ITEM_MOD_MANA_REGENERATION:
@@ -15038,6 +15131,7 @@ void Player::SendQuestReward( Quest const *pQuest, uint32 XP, Object * questGive
data << uint32(10*Trinity::Honor::hk_honor_at_level(getLevel(), pQuest->GetRewHonorableKills()));
data << uint32(pQuest->GetBonusTalents()); // bonus talents
+ data << uint32(0);
GetSession()->SendPacket( &data );
if (pQuest->GetQuestCompleteScript() != 0)
@@ -15125,7 +15219,7 @@ void Player::SendQuestUpdateAddItem( Quest const* pQuest, uint32 item_idx, uint3
void Player::SendQuestUpdateAddCreatureOrGo( Quest const* pQuest, uint64 guid, uint32 creatureOrGO_idx, uint32 old_count, uint32 add_count )
{
- assert(old_count + add_count < 256 && "mob/GO count store in 8 bits 2^8 = 256 (0..256)");
+ assert(old_count + add_count < 65536 && "mob/GO count store in 16 bits 2^16 = 65536 (0..65536)");
int32 entry = pQuest->ReqCreatureOrGOId[ creatureOrGO_idx ];
if (entry < 0)
@@ -15631,13 +15725,16 @@ bool Player::LoadFromDB( uint32 guid, SqlQueryHolder *holder )
m_taxi.ClearTaxiDestinations();
}
- if(uint32 node_id = m_taxi.GetTaxiSource())
+ if (uint32 node_id = m_taxi.GetTaxiSource())
{
// save source node as recall coord to prevent recall and fall from sky
TaxiNodesEntry const* nodeEntry = sTaxiNodesStore.LookupEntry(node_id);
- assert(nodeEntry); // checked in m_taxi.LoadTaxiDestinationsFromString
- mapId = nodeEntry->map_id;
- Relocate(nodeEntry->x, nodeEntry->y, nodeEntry->z,0.0f);
+ if (nodeEntry && nodeEntry->map_id == GetMapId())
+ {
+ assert(nodeEntry); // checked in m_taxi.LoadTaxiDestinationsFromString
+ mapId = nodeEntry->map_id;
+ Relocate(nodeEntry->x, nodeEntry->y, nodeEntry->z,0.0f);
+ }
// flight will started later
}
@@ -17209,7 +17306,7 @@ void Player::_SaveAuras()
CharacterDatabase.PExecute("INSERT INTO character_aura (guid,caster_guid,spell,effect_mask,recalculate_mask,stackcount,amount0,amount1,amount2,base_amount0,base_amount1,base_amount2,maxduration,remaintime,remaincharges) "
"VALUES ('%u', '" UI64FMTD "', '%u', '%u', '%u', '%u', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%u')",
- GetGUIDLow(), itr->second->GetCasterGUID(), itr->second->GetId(), effMask, recalculateMask,
+ GetGUIDLow(), itr->second->GetCasterGUID(), itr->second->GetId(), effMask, recalculateMask,
itr->second->GetStackAmount(), damage[0], damage[1], damage[2], baseDamage[0], baseDamage[1], baseDamage[2],
itr->second->GetMaxDuration(), itr->second->GetDuration(),itr->second->GetCharges());
}
@@ -17980,7 +18077,7 @@ void Player::Whisper(const std::string& text, uint32 language,uint64 receiver)
if (language != LANG_ADDON)
{
data.Initialize(SMSG_MESSAGECHAT, 200);
- rPlayer->BuildPlayerChat(&data, CHAT_MSG_REPLY, text, language);
+ rPlayer->BuildPlayerChat(&data, CHAT_MSG_WHISPER_INFORM, text, language);
GetSession()->SendPacket(&data);
}
}
@@ -19197,6 +19294,7 @@ void Player::UpdateHomebindTime(uint32 time)
if (time >= m_HomebindTimer)
{
// teleport to nearest graveyard
+ SetPhaseMask(1,true);
RepopAtGraveyard();
}
else
@@ -19212,6 +19310,7 @@ void Player::UpdateHomebindTime(uint32 time)
data << uint32(1);
GetSession()->SendPacket(&data);
sLog.outDebug("PLAYER: Player '%s' (GUID: %u) will be teleported to homebind in 60 seconds", GetName(),GetGUIDLow());
+ SetPhaseMask(2,true);
}
}
diff --git a/src/game/Player.h b/src/game/Player.h
index 5ea84581735..4236b3a29c0 100644
--- a/src/game/Player.h
+++ b/src/game/Player.h
@@ -336,7 +336,8 @@ enum LfgType
LFG_TYPE_RAID = 2,
LFG_TYPE_QUEST = 3,
LFG_TYPE_ZONE = 4,
- LFG_TYPE_HEROIC_DUNGEON = 5
+ LFG_TYPE_HEROIC_DUNGEON = 5,
+ LFG_TYPE_RANDOM_DUNGEON = 6
};
enum LfgRoles
@@ -431,7 +432,7 @@ enum PlayerFlags
PLAYER_FLAGS_UNK13 = 0x00001000, // played long time
PLAYER_FLAGS_UNK14 = 0x00002000, // played too long time
PLAYER_FLAGS_UNK15 = 0x00004000,
- PLAYER_FLAGS_UNK16 = 0x00008000, // strange visual effect (2.0.1), looks like PLAYER_FLAGS_GHOST flag
+ PLAYER_FLAGS_DEVELOPER = 0x00008000, // <Dev> prefix for something?
PLAYER_FLAGS_UNK17 = 0x00010000, // pre-3.0.3 PLAYER_FLAGS_SANCTUARY flag for player entered sanctuary
PLAYER_FLAGS_UNK18 = 0x00020000, // taxi benchmark mode (on/off) (2.0.1)
PLAYER_FLAGS_PVP_TIMER = 0x00040000, // 3.0.2, pvp timer active (after you disable pvp manually)
@@ -556,6 +557,7 @@ enum AtLoginFlags
AT_LOGIN_RESET_TALENTS = 0x04,
AT_LOGIN_CUSTOMIZE = 0x08,
AT_LOGIN_RESET_PET_TALENTS = 0x10,
+ AT_LOGIN_FIRST = 0x20,
};
typedef std::map<uint32, QuestStatusData> QuestStatusMap;
@@ -568,7 +570,7 @@ enum QuestSlotOffsets
QUEST_TIME_OFFSET = 3
};
-#define MAX_QUEST_OFFSET 4
+#define MAX_QUEST_OFFSET 5
enum QuestSlotStateMask
{
@@ -848,7 +850,7 @@ enum PlayerDelayedOperations
DELAYED_RESURRECT_PLAYER = 0x02,
DELAYED_SPELL_CAST_DESERTER = 0x04,
DELAYED_BG_MOUNT_RESTORE = 0x08, ///< Flag to restore mount state after teleport from BG
- DELAYED_BG_TAXI_RESTORE = 0x10, ///< Flag to restore taxi state after teleport from BG
+ DELAYED_BG_TAXI_RESTORE = 0x10, ///< Flag to restore taxi state after teleport from BG
DELAYED_END
};
@@ -1306,31 +1308,37 @@ class Player : public Unit, public GridObject<Player>
void ResetDailyQuestStatus();
uint16 FindQuestSlot( uint32 quest_id ) const;
- uint32 GetQuestSlotQuestId(uint16 slot) const { return GetUInt32Value(PLAYER_QUEST_LOG_1_1 + slot*MAX_QUEST_OFFSET + QUEST_ID_OFFSET); }
- uint32 GetQuestSlotState(uint16 slot) const { return GetUInt32Value(PLAYER_QUEST_LOG_1_1 + slot*MAX_QUEST_OFFSET + QUEST_STATE_OFFSET); }
- uint32 GetQuestSlotCounters(uint16 slot)const { return GetUInt32Value(PLAYER_QUEST_LOG_1_1 + slot*MAX_QUEST_OFFSET + QUEST_COUNTS_OFFSET); }
- uint8 GetQuestSlotCounter(uint16 slot,uint8 counter) const { return GetByteValue(PLAYER_QUEST_LOG_1_1 + slot*MAX_QUEST_OFFSET + QUEST_COUNTS_OFFSET,counter); }
- uint32 GetQuestSlotTime(uint16 slot) const { return GetUInt32Value(PLAYER_QUEST_LOG_1_1 + slot*MAX_QUEST_OFFSET + QUEST_TIME_OFFSET); }
- void SetQuestSlot(uint16 slot,uint32 quest_id, uint32 timer = 0)
+ uint32 GetQuestSlotQuestId(uint16 slot) const { return GetUInt32Value(PLAYER_QUEST_LOG_1_1 + slot * MAX_QUEST_OFFSET + QUEST_ID_OFFSET); }
+ uint32 GetQuestSlotState(uint16 slot) const { return GetUInt32Value(PLAYER_QUEST_LOG_1_1 + slot * MAX_QUEST_OFFSET + QUEST_STATE_OFFSET); }
+ uint16 GetQuestSlotCounter(uint16 slot, uint8 counter) const { return (uint16)(GetUInt64Value(PLAYER_QUEST_LOG_1_1 + slot * MAX_QUEST_OFFSET + QUEST_COUNTS_OFFSET) >> (counter * 16)); }
+ uint32 GetQuestSlotTime(uint16 slot) const { return GetUInt32Value(PLAYER_QUEST_LOG_1_1 + slot * MAX_QUEST_OFFSET + QUEST_TIME_OFFSET); }
+ void SetQuestSlot(uint16 slot, uint32 quest_id, uint32 timer = 0)
{
- SetUInt32Value(PLAYER_QUEST_LOG_1_1 + slot*MAX_QUEST_OFFSET + QUEST_ID_OFFSET,quest_id);
- SetUInt32Value(PLAYER_QUEST_LOG_1_1 + slot*MAX_QUEST_OFFSET + QUEST_STATE_OFFSET,0);
- SetUInt32Value(PLAYER_QUEST_LOG_1_1 + slot*MAX_QUEST_OFFSET + QUEST_COUNTS_OFFSET,0);
- SetUInt32Value(PLAYER_QUEST_LOG_1_1 + slot*MAX_QUEST_OFFSET + QUEST_TIME_OFFSET,timer);
+ SetUInt32Value(PLAYER_QUEST_LOG_1_1 + slot * MAX_QUEST_OFFSET + QUEST_ID_OFFSET, quest_id);
+ SetUInt32Value(PLAYER_QUEST_LOG_1_1 + slot * MAX_QUEST_OFFSET + QUEST_STATE_OFFSET, 0);
+ SetUInt32Value(PLAYER_QUEST_LOG_1_1 + slot * MAX_QUEST_OFFSET + QUEST_COUNTS_OFFSET, 0);
+ SetUInt32Value(PLAYER_QUEST_LOG_1_1 + slot * MAX_QUEST_OFFSET + QUEST_COUNTS_OFFSET + 1, 0);
+ SetUInt32Value(PLAYER_QUEST_LOG_1_1 + slot * MAX_QUEST_OFFSET + QUEST_TIME_OFFSET, timer);
}
- void SetQuestSlotCounter(uint16 slot,uint8 counter,uint8 count) { SetByteValue(PLAYER_QUEST_LOG_1_1 + slot*MAX_QUEST_OFFSET + QUEST_COUNTS_OFFSET,counter,count); }
- void SetQuestSlotState(uint16 slot,uint32 state) { SetFlag(PLAYER_QUEST_LOG_1_1 + slot*MAX_QUEST_OFFSET + QUEST_STATE_OFFSET,state); }
- void RemoveQuestSlotState(uint16 slot,uint32 state) { RemoveFlag(PLAYER_QUEST_LOG_1_1 + slot*MAX_QUEST_OFFSET + QUEST_STATE_OFFSET,state); }
- void SetQuestSlotTimer(uint16 slot,uint32 timer) { SetUInt32Value(PLAYER_QUEST_LOG_1_1 + slot*MAX_QUEST_OFFSET + QUEST_TIME_OFFSET,timer); }
- void SwapQuestSlot(uint16 slot1,uint16 slot2)
+ void SetQuestSlotCounter(uint16 slot, uint8 counter, uint16 count)
{
- for (uint8 i = 0; i < MAX_QUEST_OFFSET ; ++i )
+ uint64 val = GetUInt64Value(PLAYER_QUEST_LOG_1_1 + slot * MAX_QUEST_OFFSET + QUEST_COUNTS_OFFSET);
+ val &= ~((uint64)0xFFFF << (counter * 16));
+ val |= ((uint64)count << (counter * 16));
+ SetUInt64Value(PLAYER_QUEST_LOG_1_1 + slot * MAX_QUEST_OFFSET + QUEST_COUNTS_OFFSET, val);
+ }
+ void SetQuestSlotState(uint16 slot, uint32 state) { SetFlag(PLAYER_QUEST_LOG_1_1 + slot * MAX_QUEST_OFFSET + QUEST_STATE_OFFSET, state); }
+ void RemoveQuestSlotState(uint16 slot, uint32 state) { RemoveFlag(PLAYER_QUEST_LOG_1_1 + slot * MAX_QUEST_OFFSET + QUEST_STATE_OFFSET, state); }
+ void SetQuestSlotTimer(uint16 slot, uint32 timer) { SetUInt32Value(PLAYER_QUEST_LOG_1_1 + slot * MAX_QUEST_OFFSET + QUEST_TIME_OFFSET, timer); }
+ void SwapQuestSlot(uint16 slot1, uint16 slot2)
+ {
+ for (int i = 0; i < MAX_QUEST_OFFSET; ++i)
{
- uint32 temp1 = GetUInt32Value(PLAYER_QUEST_LOG_1_1 + MAX_QUEST_OFFSET *slot1 + i);
- uint32 temp2 = GetUInt32Value(PLAYER_QUEST_LOG_1_1 + MAX_QUEST_OFFSET *slot2 + i);
+ uint32 temp1 = GetUInt32Value(PLAYER_QUEST_LOG_1_1 + MAX_QUEST_OFFSET * slot1 + i);
+ uint32 temp2 = GetUInt32Value(PLAYER_QUEST_LOG_1_1 + MAX_QUEST_OFFSET * slot2 + i);
- SetUInt32Value(PLAYER_QUEST_LOG_1_1 + MAX_QUEST_OFFSET *slot1 + i, temp2);
- SetUInt32Value(PLAYER_QUEST_LOG_1_1 + MAX_QUEST_OFFSET *slot2 + i, temp1);
+ SetUInt32Value(PLAYER_QUEST_LOG_1_1 + MAX_QUEST_OFFSET * slot1 + i, temp2);
+ SetUInt32Value(PLAYER_QUEST_LOG_1_1 + MAX_QUEST_OFFSET * slot2 + i, temp1);
}
}
uint32 GetReqKillOrCastCurrentCount(uint32 quest_id, int32 entry);
diff --git a/src/game/PoolHandler.cpp b/src/game/PoolHandler.cpp
index 15afb656805..6a148b58d66 100644
--- a/src/game/PoolHandler.cpp
+++ b/src/game/PoolHandler.cpp
@@ -26,6 +26,85 @@
INSTANTIATE_SINGLETON_1(PoolHandler);
////////////////////////////////////////////////////////////
+// template class SpawnedPoolData
+
+// Method that tell amount spawned objects/subpools
+uint32 SpawnedPoolData::GetSpawnedObjects(uint32 pool_id) const
+{
+ SpawnedPoolPools::const_iterator itr = mSpawnedPools.find(pool_id);
+ return itr != mSpawnedPools.end() ? itr->second : 0;
+}
+
+// Method that tell if a creature is spawned currently
+template<>
+bool SpawnedPoolData::IsSpawnedObject<Creature>(uint32 db_guid) const
+{
+ return mSpawnedCreatures.find(db_guid) != mSpawnedCreatures.end();
+}
+
+// Method that tell if a gameobject is spawned currently
+template<>
+bool SpawnedPoolData::IsSpawnedObject<GameObject>(uint32 db_guid) const
+{
+ return mSpawnedGameobjects.find(db_guid) != mSpawnedGameobjects.end();
+}
+
+// Method that tell if a pool is spawned currently
+template<>
+bool SpawnedPoolData::IsSpawnedObject<Pool>(uint32 sub_pool_id) const
+{
+ return mSpawnedPools.find(sub_pool_id) != mSpawnedPools.end();
+}
+
+template<>
+void SpawnedPoolData::AddSpawn<Creature>(uint32 db_guid, uint32 pool_id)
+{
+ mSpawnedCreatures.insert(db_guid);
+ ++mSpawnedPools[pool_id];
+}
+
+template<>
+void SpawnedPoolData::AddSpawn<GameObject>(uint32 db_guid, uint32 pool_id)
+{
+ mSpawnedGameobjects.insert(db_guid);
+ ++mSpawnedPools[pool_id];
+}
+
+template<>
+void SpawnedPoolData::AddSpawn<Pool>(uint32 sub_pool_id, uint32 pool_id)
+{
+ mSpawnedPools[sub_pool_id] = 0;
+ ++mSpawnedPools[pool_id];
+}
+
+template<>
+void SpawnedPoolData::RemoveSpawn<Creature>(uint32 db_guid, uint32 pool_id)
+{
+ mSpawnedCreatures.erase(db_guid);
+ uint32& val = mSpawnedPools[pool_id];
+ if (val > 0)
+ --val;
+}
+
+template<>
+void SpawnedPoolData::RemoveSpawn<GameObject>(uint32 db_guid, uint32 pool_id)
+{
+ mSpawnedGameobjects.erase(db_guid);
+ uint32& val = mSpawnedPools[pool_id];
+ if (val > 0)
+ --val;
+}
+
+template<>
+void SpawnedPoolData::RemoveSpawn<Pool>(uint32 sub_pool_id, uint32 pool_id)
+{
+ mSpawnedPools.erase(sub_pool_id);
+ uint32& val = mSpawnedPools[pool_id];
+ if (val > 0)
+ --val;
+}
+
+////////////////////////////////////////////////////////////
// Methods of template class PoolGroup
// Method to add a gameobject/creature guid to the proper list depending on pool type and chance value
@@ -40,7 +119,7 @@ void PoolGroup<T>::AddEntry(PoolObject& poolitem, uint32 maxentries)
// Method to check the chances are proper in this object pool
template <class T>
-bool PoolGroup<T>::CheckPool(void)
+bool PoolGroup<T>::CheckPool() const
{
if (EqualChanced.size() == 0)
{
@@ -53,21 +132,8 @@ bool PoolGroup<T>::CheckPool(void)
return true;
}
-// Method that tell if the gameobject, creature or pool is spawned currently
template <class T>
-bool PoolGroup<T>::IsSpawnedObject(uint32 guid)
-{
- for (uint32 i=0; i<ExplicitlyChanced.size(); ++i)
- if (ExplicitlyChanced[i].guid == guid)
- return ExplicitlyChanced[i].spawned;
- for (uint32 i=0; i<EqualChanced.size(); ++i)
- if (EqualChanced[i].guid == guid)
- return EqualChanced[i].spawned;
- return false;
-}
-
-template <class T>
-void PoolGroup<T>::RollOne(int32& index, PoolObjectList** store, uint32 triggerFrom)
+PoolObject* PoolGroup<T>::RollOne(SpawnedPoolData& spawns, uint32 triggerFrom)
{
if (!ExplicitlyChanced.empty())
{
@@ -78,61 +144,50 @@ void PoolGroup<T>::RollOne(int32& index, PoolObjectList** store, uint32 triggerF
roll -= ExplicitlyChanced[i].chance;
// Triggering object is marked as spawned at this time and can be also rolled (respawn case)
// so this need explicit check for this case
- if (roll < 0 && (!ExplicitlyChanced[i].spawned || ExplicitlyChanced[i].guid == triggerFrom))
- {
- index = i;
- *store = &ExplicitlyChanced;
- return;
- }
+ if (roll < 0 && (ExplicitlyChanced[i].guid == triggerFrom || !spawns.IsSpawnedObject<T>(ExplicitlyChanced[i].guid)))
+ return &ExplicitlyChanced[i];
}
}
if (!EqualChanced.empty())
{
- index = irand(0, EqualChanced.size()-1);
+ int32 index = irand(0, EqualChanced.size()-1);
// Triggering object is marked as spawned at this time and can be also rolled (respawn case)
// so this need explicit check for this case
- if (!EqualChanced[index].spawned || EqualChanced[index].guid == triggerFrom)
- {
- *store = &EqualChanced;
- return;
- }
+ if (EqualChanced[index].guid == triggerFrom || !spawns.IsSpawnedObject<T>(EqualChanced[index].guid))
+ return &EqualChanced[index];
}
- index = -1;
+ return NULL;
}
// Main method to despawn a creature or gameobject in a pool
// If no guid is passed, the pool is just removed (event end case)
// If guid is filled, cache will be used and no removal will occur, it just fill the cache
template<class T>
-void PoolGroup<T>::DespawnObject(uint32 guid)
+void PoolGroup<T>::DespawnObject(SpawnedPoolData& spawns, uint32 guid)
{
for (size_t i=0; i<EqualChanced.size(); ++i)
{
- if (EqualChanced[i].spawned)
+ // if spawned
+ if (spawns.IsSpawnedObject<T>(EqualChanced[i].guid))
{
if (!guid || EqualChanced[i].guid == guid)
{
Despawn1Object(EqualChanced[i].guid);
-
- EqualChanced[i].spawned = false;
- if (m_SpawnedPoolAmount > 0)
- --m_SpawnedPoolAmount;
+ spawns.RemoveSpawn<T>(EqualChanced[i].guid,poolId);
}
}
}
for (size_t i = 0; i < ExplicitlyChanced.size(); ++i)
{
- if (ExplicitlyChanced[i].spawned)
+ // spawned
+ if (spawns.IsSpawnedObject<T>(ExplicitlyChanced[i].guid))
{
if (!guid || ExplicitlyChanced[i].guid == guid)
{
Despawn1Object(ExplicitlyChanced[i].guid);
- ExplicitlyChanced[i].spawned = false;
-
- if (m_SpawnedPoolAmount > 0)
- --m_SpawnedPoolAmount;
+ spawns.RemoveSpawn<T>(ExplicitlyChanced[i].guid,poolId);
}
}
}
@@ -194,10 +249,10 @@ void PoolGroup<Pool>::RemoveOneRelation(uint16 child_pool_id)
}
template <class T>
-void PoolGroup<T>::SpawnObject(uint32 limit, uint32 triggerFrom)
+void PoolGroup<T>::SpawnObject(SpawnedPoolData& spawns, uint32 limit, uint32 triggerFrom)
{
uint32 lastDespawned = 0;
- int count = limit - m_SpawnedPoolAmount;
+ int count = limit - spawns.GetSpawnedObjects(poolId);
// If triggered from some object respawn this object is still marked as spawned
// and also counted into m_SpawnedPoolAmount so we need increase count to be
@@ -208,43 +263,38 @@ void PoolGroup<T>::SpawnObject(uint32 limit, uint32 triggerFrom)
// This will try to spawn the rest of pool, not guaranteed
for (int i = 0; i < count; ++i)
{
- int index;
- PoolObjectList* store;
-
- RollOne(index, &store, triggerFrom);
- if (index == -1)
+ PoolObject* obj = RollOne(spawns,triggerFrom);
+ if (!obj)
continue;
- if ((*store)[index].guid == lastDespawned)
+ if (obj->guid == lastDespawned)
continue;
- if ((*store)[index].guid == triggerFrom)
+ if (obj->guid == triggerFrom)
{
- (*store)[index].spawned = ReSpawn1Object(triggerFrom);
+ ReSpawn1Object(obj);
triggerFrom = 0;
continue;
}
- else
- (*store)[index].spawned = Spawn1Object((*store)[index].guid);
+ spawns.AddSpawn<T>(obj->guid,poolId);
+ Spawn1Object(obj);
if (triggerFrom)
{
// One spawn one despawn no count increase
- DespawnObject(triggerFrom);
+ DespawnObject(spawns, triggerFrom);
lastDespawned = triggerFrom;
triggerFrom = 0;
}
- else
- ++m_SpawnedPoolAmount;
}
}
// Method that is actualy doing the spawn job on 1 creature
template <>
-bool PoolGroup<Creature>::Spawn1Object(uint32 guid)
+void PoolGroup<Creature>::Spawn1Object(PoolObject* obj)
{
- if (CreatureData const* data = objmgr.GetCreatureData(guid))
+ if (CreatureData const* data = objmgr.GetCreatureData(obj->guid))
{
- objmgr.AddCreatureToGrid(guid, data);
+ objmgr.AddCreatureToGrid(obj->guid, data);
// Spawn if necessary (loaded grids only)
Map* map = const_cast<Map*>(MapManager::Instance().CreateBaseMap(data->mapid));
@@ -253,26 +303,24 @@ bool PoolGroup<Creature>::Spawn1Object(uint32 guid)
{
Creature* pCreature = new Creature;
//sLog.outDebug("Spawning creature %u",guid);
- if (!pCreature->LoadFromDB(guid, map))
+ if (!pCreature->LoadFromDB(obj->guid, map))
{
delete pCreature;
- return false;
+ return;
}
else
map->Add(pCreature);
}
- return true;
}
- return false;
}
// Same for 1 gameobject
template <>
-bool PoolGroup<GameObject>::Spawn1Object(uint32 guid)
+void PoolGroup<GameObject>::Spawn1Object(PoolObject* obj)
{
- if (GameObjectData const* data = objmgr.GetGOData(guid))
+ if (GameObjectData const* data = objmgr.GetGOData(obj->guid))
{
- objmgr.AddGameobjectToGrid(guid, data);
+ objmgr.AddGameobjectToGrid(obj->guid, data);
// Spawn if necessary (loaded grids only)
// this base map checked as non-instanced and then only existed
Map* map = const_cast<Map*>(MapManager::Instance().CreateBaseMap(data->mapid));
@@ -281,10 +329,10 @@ bool PoolGroup<GameObject>::Spawn1Object(uint32 guid)
{
GameObject* pGameobject = new GameObject;
//sLog.outDebug("Spawning gameobject %u", guid);
- if (!pGameobject->LoadFromDB(guid, map))
+ if (!pGameobject->LoadFromDB(obj->guid, map))
{
delete pGameobject;
- return false;
+ return;
}
else
{
@@ -292,52 +340,38 @@ bool PoolGroup<GameObject>::Spawn1Object(uint32 guid)
map->Add(pGameobject);
}
}
- return true;
}
- return false;
}
// Same for 1 pool
template <>
-bool PoolGroup<Pool>::Spawn1Object(uint32 child_pool_id)
+void PoolGroup<Pool>::Spawn1Object(PoolObject* obj)
{
- poolhandler.SpawnPool(child_pool_id, 0, 0);
- poolhandler.SpawnPool(child_pool_id, 0, TYPEID_GAMEOBJECT);
- poolhandler.SpawnPool(child_pool_id, 0, TYPEID_UNIT);
- return true;
+ poolhandler.SpawnPool(obj->guid);
}
// Method that does the respawn job on the specified creature
template <>
-bool PoolGroup<Creature>::ReSpawn1Object(uint32 guid)
+void PoolGroup<Creature>::ReSpawn1Object(PoolObject* obj)
{
- if (CreatureData const* data = objmgr.GetCreatureData(guid))
- {
- if (Creature* pCreature = ObjectAccessor::Instance().GetObjectInWorld(MAKE_NEW_GUID(guid, data->id, HIGHGUID_UNIT), (Creature*)NULL))
+ if (CreatureData const* data = objmgr.GetCreatureData(obj->guid))
+ if (Creature* pCreature = ObjectAccessor::Instance().GetObjectInWorld(MAKE_NEW_GUID(obj->guid, data->id, HIGHGUID_UNIT), (Creature*)NULL))
pCreature->GetMap()->Add(pCreature);
- return true;
- }
- return false;
}
-// Same for 1 gameobject
+// Method that does the respawn job on the specified gameobject
template <>
-bool PoolGroup<GameObject>::ReSpawn1Object(uint32 guid)
+void PoolGroup<GameObject>::ReSpawn1Object(PoolObject* obj)
{
- if (GameObjectData const* data = objmgr.GetGOData(guid))
- {
- if (GameObject* pGameobject = ObjectAccessor::Instance().GetObjectInWorld(MAKE_NEW_GUID(guid, data->id, HIGHGUID_GAMEOBJECT), (GameObject*)NULL))
+ if (GameObjectData const* data = objmgr.GetGOData(obj->guid))
+ if (GameObject* pGameobject = ObjectAccessor::Instance().GetObjectInWorld(MAKE_NEW_GUID(obj->guid, data->id, HIGHGUID_GAMEOBJECT), (GameObject*)NULL))
pGameobject->GetMap()->Add(pGameobject);
- return true;
- }
- return false;
}
// Nothing to do for a child Pool
template <>
-bool PoolGroup<Pool>::ReSpawn1Object(uint32 /*guid*/)
+void PoolGroup<Pool>::ReSpawn1Object(PoolObject* /*obj*/)
{
- return true;
}
////////////////////////////////////////////////////////////
@@ -345,7 +379,6 @@ bool PoolGroup<Pool>::ReSpawn1Object(uint32 /*guid*/)
PoolHandler::PoolHandler()
{
- m_IsPoolSystemStarted = false;
}
void PoolHandler::LoadFromDB()
@@ -448,6 +481,7 @@ void PoolHandler::LoadFromDB()
PoolObject plObject = PoolObject(guid, chance);
PoolGroup<Creature>& cregroup = mPoolCreatureGroups[pool_id];
+ cregroup.SetPoolId(pool_id);
cregroup.AddEntry(plObject, pPoolTemplate->MaxLimit);
SearchPair p(guid, pool_id);
mCreatureSearchMap.insert(p);
@@ -519,6 +553,7 @@ void PoolHandler::LoadFromDB()
PoolObject plObject = PoolObject(guid, chance);
PoolGroup<GameObject>& gogroup = mPoolGameobjectGroups[pool_id];
+ gogroup.SetPoolId(pool_id);
gogroup.AddEntry(plObject, pPoolTemplate->MaxLimit);
SearchPair p(guid, pool_id);
mGameobjectSearchMap.insert(p);
@@ -585,6 +620,7 @@ void PoolHandler::LoadFromDB()
PoolObject plObject = PoolObject(child_pool_id, chance);
PoolGroup<Pool>& plgroup = mPoolPoolGroups[mother_pool_id];
+ plgroup.SetPoolId(mother_pool_id);
plgroup.AddEntry(plObject, pPoolTemplateMother->MaxLimit);
SearchPair p(child_pool_id, mother_pool_id);
mPoolSearchMap.insert(p);
@@ -636,87 +672,63 @@ void PoolHandler::Initialize()
sLog.outErrorDb("Pool Id (%u) has all creatures or gameobjects with explicit chance sum <>100 and no equal chance defined. The pool system cannot pick one to spawn.", pool_entry);
continue;
}
- SpawnPool(pool_entry, 0, 0);
- SpawnPool(pool_entry, 0, TYPEID_GAMEOBJECT);
- SpawnPool(pool_entry, 0, TYPEID_UNIT);
+ SpawnPool(pool_entry);;
count++;
} while (result->NextRow());
}
sLog.outBasic("Pool handling system initialized, %u pools spawned.", count);
- m_IsPoolSystemStarted = true;
}
// Call to spawn a pool, if cache if true the method will spawn only if cached entry is different
-// If it's same, the gameobject/creature is respawned only (added back to map)
-void PoolHandler::SpawnPool(uint16 pool_id, uint32 guid, uint32 type)
+// If it's same, the creature is respawned only (added back to map)
+template<>
+void PoolHandler::SpawnPool<Creature>(uint16 pool_id, uint32 db_guid)
{
- switch (type)
- {
- case TYPEID_UNIT:
- if (!mPoolCreatureGroups[pool_id].isEmpty())
- mPoolCreatureGroups[pool_id].SpawnObject(mPoolTemplate[pool_id].MaxLimit, guid);
- break;
- case TYPEID_GAMEOBJECT:
- if (!mPoolGameobjectGroups[pool_id].isEmpty())
- mPoolGameobjectGroups[pool_id].SpawnObject(mPoolTemplate[pool_id].MaxLimit, guid);
- break;
- default:
- if (!mPoolPoolGroups[pool_id].isEmpty())
- mPoolPoolGroups[pool_id].SpawnObject(mPoolTemplate[pool_id].MaxLimit, guid);
- }
+ if (!mPoolCreatureGroups[pool_id].isEmpty())
+ mPoolCreatureGroups[pool_id].SpawnObject(mSpawnedData, mPoolTemplate[pool_id].MaxLimit, db_guid);
}
-// Call to despawn a pool, all gameobjects/creatures in this pool are removed
-void PoolHandler::DespawnPool(uint16 pool_id)
+// Call to spawn a pool, if cache if true the method will spawn only if cached entry is different
+// If it's same, the gameobject is respawned only (added back to map)
+template<>
+void PoolHandler::SpawnPool<GameObject>(uint16 pool_id, uint32 db_guid)
{
- if (!mPoolCreatureGroups[pool_id].isEmpty())
- mPoolCreatureGroups[pool_id].DespawnObject();
-
if (!mPoolGameobjectGroups[pool_id].isEmpty())
- mPoolGameobjectGroups[pool_id].DespawnObject();
+ mPoolGameobjectGroups[pool_id].SpawnObject(mSpawnedData, mPoolTemplate[pool_id].MaxLimit, db_guid);
+}
+// Call to spawn a pool, if cache if true the method will spawn only if cached entry is different
+// If it's same, the pool is respawned only
+template<>
+void PoolHandler::SpawnPool<Pool>(uint16 pool_id, uint32 sub_pool_id)
+{
if (!mPoolPoolGroups[pool_id].isEmpty())
- mPoolPoolGroups[pool_id].DespawnObject();
+ mPoolPoolGroups[pool_id].SpawnObject(mSpawnedData, mPoolTemplate[pool_id].MaxLimit, sub_pool_id);
}
-// Call to update the pool when a gameobject/creature part of pool [pool_id] is ready to respawn
-// Here we cache only the creature/gameobject whose guid is passed as parameter
-// Then the spawn pool call will use this cache to decide
-void PoolHandler::UpdatePool(uint16 pool_id, uint32 guid, uint32 type)
+void PoolHandler::SpawnPool( uint16 pool_id )
{
- if (uint16 motherpoolid = IsPartOfAPool(pool_id, 0))
- SpawnPool(motherpoolid, 0, 0);
- else
- SpawnPool(pool_id, guid, type);
+ SpawnPool<Pool>(pool_id, 0);
+ SpawnPool<GameObject>(pool_id, 0);
+ SpawnPool<Creature>(pool_id, 0);
}
-// Method that tell if the gameobject/creature is part of a pool and return the pool id if yes
-uint16 PoolHandler::IsPartOfAPool(uint32 guid, uint32 type)
+// Call to despawn a pool, all gameobjects/creatures in this pool are removed
+void PoolHandler::DespawnPool(uint16 pool_id)
{
- if (type == 0) // pool of pool
- {
- SearchMap::const_iterator itr = mPoolSearchMap.find(guid);
- if (itr != mPoolSearchMap.end())
- return itr->second;
- }
- else if (type == TYPEID_GAMEOBJECT)
- {
- SearchMap::const_iterator itr = mGameobjectSearchMap.find(guid);
- if (itr != mGameobjectSearchMap.end())
- return itr->second;
- }
- else // creature
- {
- SearchMap::const_iterator itr = mCreatureSearchMap.find(guid);
- if (itr != mCreatureSearchMap.end())
- return itr->second;
- }
- return 0;
+ if (!mPoolCreatureGroups[pool_id].isEmpty())
+ mPoolCreatureGroups[pool_id].DespawnObject(mSpawnedData);
+
+ if (!mPoolGameobjectGroups[pool_id].isEmpty())
+ mPoolGameobjectGroups[pool_id].DespawnObject(mSpawnedData);
+
+ if (!mPoolPoolGroups[pool_id].isEmpty())
+ mPoolPoolGroups[pool_id].DespawnObject(mSpawnedData);
}
// Method that check chance integrity of the creatures and gameobjects in this pool
-bool PoolHandler::CheckPool(uint16 pool_id)
+bool PoolHandler::CheckPool(uint16 pool_id) const
{
return pool_id <= max_pool_id &&
mPoolGameobjectGroups[pool_id].CheckPool() &&
@@ -724,15 +736,18 @@ bool PoolHandler::CheckPool(uint16 pool_id)
mPoolPoolGroups[pool_id].CheckPool();
}
-// Method that tell if a creature or gameobject in pool_id is spawned currently
-bool PoolHandler::IsSpawnedObject(uint16 pool_id, uint32 guid, uint32 type)
+// Call to update the pool when a gameobject/creature part of pool [pool_id] is ready to respawn
+// Here we cache only the creature/gameobject whose guid is passed as parameter
+// Then the spawn pool call will use this cache to decide
+template<typename T>
+void PoolHandler::UpdatePool(uint16 pool_id, uint32 db_guid_or_pool_id)
{
- if (pool_id > max_pool_id)
- return false;
- if (type == 0)
- return mPoolPoolGroups[pool_id].IsSpawnedObject(guid);
- else if (type == TYPEID_GAMEOBJECT)
- return mPoolGameobjectGroups[pool_id].IsSpawnedObject(guid);
+ if (uint16 motherpoolid = IsPartOfAPool<Pool>(pool_id))
+ SpawnPool<Pool>(motherpoolid, pool_id);
else
- return mPoolCreatureGroups[pool_id].IsSpawnedObject(guid);
+ SpawnPool<T>(pool_id, db_guid_or_pool_id);
}
+
+template void PoolHandler::UpdatePool<Pool>(uint16 pool_id, uint32 db_guid_or_pool_id);
+template void PoolHandler::UpdatePool<GameObject>(uint16 pool_id, uint32 db_guid_or_pool_id);
+template void PoolHandler::UpdatePool<Creature>(uint16 pool_id, uint32 db_guid_or_pool_id); \ No newline at end of file
diff --git a/src/game/PoolHandler.h b/src/game/PoolHandler.h
index cfc9c989e0a..0ba4cc7769f 100644
--- a/src/game/PoolHandler.h
+++ b/src/game/PoolHandler.h
@@ -33,8 +33,33 @@ struct PoolObject
{
uint32 guid;
float chance;
- bool spawned;
- PoolObject(uint32 _guid, float _chance): guid(_guid), chance(fabs(_chance)), spawned(false) {}
+ PoolObject(uint32 _guid, float _chance): guid(_guid), chance(fabs(_chance)) {}
+};
+
+class Pool // for Pool of Pool case
+{
+};
+
+typedef std::set<uint32> SpawnedPoolObjects;
+typedef std::map<uint32,uint32> SpawnedPoolPools;
+
+class SpawnedPoolData
+{
+ public:
+ template<typename T>
+ bool IsSpawnedObject(uint32 db_guid_or_pool_id) const;
+
+ uint32 GetSpawnedObjects(uint32 pool_id) const;
+
+ template<typename T>
+ void AddSpawn(uint32 db_guid_or_pool_id, uint32 pool_id);
+
+ template<typename T>
+ void RemoveSpawn(uint32 db_guid_or_pool_id, uint32 pool_id);
+ private:
+ SpawnedPoolObjects mSpawnedCreatures;
+ SpawnedPoolObjects mSpawnedGameobjects;
+ SpawnedPoolPools mSpawnedPools;
};
template <class T>
@@ -42,27 +67,24 @@ class PoolGroup
{
typedef std::vector<PoolObject> PoolObjectList;
public:
- PoolGroup() : m_SpawnedPoolAmount(0) {}
+ explicit PoolGroup() : poolId(0) { }
+ void SetPoolId(uint32 pool_id) { poolId = pool_id; }
~PoolGroup() {};
- bool isEmpty() { return ExplicitlyChanced.empty() && EqualChanced.empty(); }
+ bool isEmpty() const { return ExplicitlyChanced.empty() && EqualChanced.empty(); }
void AddEntry(PoolObject& poolitem, uint32 maxentries);
- bool CheckPool(void);
- void RollOne(int32& index, PoolObjectList** store, uint32 triggerFrom);
- bool IsSpawnedObject(uint32 guid);
- void DespawnObject(uint32 guid=0);
+ bool CheckPool() const;
+ PoolObject* RollOne(SpawnedPoolData& spawns, uint32 triggerFrom);
+ void DespawnObject(SpawnedPoolData& spawns, uint32 guid=0);
void Despawn1Object(uint32 guid);
- void SpawnObject(uint32 limit, uint32 triggerFrom);
- bool Spawn1Object(uint32 guid);
- bool ReSpawn1Object(uint32 guid);
+ void SpawnObject(SpawnedPoolData& spawns, uint32 limit, uint32 triggerFrom);
+
+ void Spawn1Object(PoolObject* obj);
+ void ReSpawn1Object(PoolObject* obj);
void RemoveOneRelation(uint16 child_pool_id);
private:
+ uint32 poolId;
PoolObjectList ExplicitlyChanced;
PoolObjectList EqualChanced;
- uint32 m_SpawnedPoolAmount; // Used to know the number of spawned objects
-};
-
-class Pool // for Pool of Pool case
-{
};
class PoolHandler
@@ -70,17 +92,28 @@ class PoolHandler
public:
PoolHandler();
~PoolHandler() {};
+
void LoadFromDB();
- uint16 IsPartOfAPool(uint32 guid, uint32 type);
- bool IsSpawnedObject(uint16 pool_id, uint32 guid, uint32 type);
- bool CheckPool(uint16 pool_id);
- void SpawnPool(uint16 pool_id, uint32 guid, uint32 type);
- void DespawnPool(uint16 pool_id);
- void UpdatePool(uint16 pool_id, uint32 guid, uint32 type);
void Initialize();
+ template<typename T>
+ uint16 IsPartOfAPool(uint32 db_guid_or_pool_id) const;
+
+ template<typename T>
+ bool IsSpawnedObject(uint32 db_guid_or_pool_id) const { return mSpawnedData.IsSpawnedObject<T>(db_guid_or_pool_id); }
+
+ bool CheckPool(uint16 pool_id) const;
+
+ void SpawnPool(uint16 pool_id);
+ void DespawnPool(uint16 pool_id);
+
+ template<typename T>
+ void UpdatePool(uint16 pool_id, uint32 db_guid_or_pool_id);
+
protected:
- bool m_IsPoolSystemStarted;
+ template<typename T>
+ void SpawnPool(uint16 pool_id, uint32 db_guid_or_pool_id);
+
uint16 max_pool_id;
typedef std::vector<PoolTemplateData> PoolTemplateDataMap;
typedef std::vector<PoolGroup<Creature> > PoolGroupCreatureMap;
@@ -97,7 +130,43 @@ class PoolHandler
SearchMap mGameobjectSearchMap;
SearchMap mPoolSearchMap;
+ // dynamic data
+ SpawnedPoolData mSpawnedData;
};
#define poolhandler Trinity::Singleton<PoolHandler>::Instance()
+
+// Method that tell if the creature is part of a pool and return the pool id if yes
+template<>
+inline uint16 PoolHandler::IsPartOfAPool<Creature>(uint32 db_guid) const
+{
+ SearchMap::const_iterator itr = mCreatureSearchMap.find(db_guid);
+ if (itr != mCreatureSearchMap.end())
+ return itr->second;
+
+ return 0;
+}
+
+// Method that tell if the gameobject is part of a pool and return the pool id if yes
+template<>
+inline uint16 PoolHandler::IsPartOfAPool<GameObject>(uint32 db_guid) const
+{
+ SearchMap::const_iterator itr = mGameobjectSearchMap.find(db_guid);
+ if (itr != mGameobjectSearchMap.end())
+ return itr->second;
+
+ return 0;
+}
+
+// Method that tell if the pool is part of another pool and return the pool id if yes
+template<>
+inline uint16 PoolHandler::IsPartOfAPool<Pool>(uint32 pool_id) const
+{
+ SearchMap::const_iterator itr = mPoolSearchMap.find(pool_id);
+ if (itr != mPoolSearchMap.end())
+ return itr->second;
+
+ return 0;
+}
+
#endif
diff --git a/src/game/QueryHandler.cpp b/src/game/QueryHandler.cpp
index 9cb1020cedd..062f70f46ed 100644
--- a/src/game/QueryHandler.cpp
+++ b/src/game/QueryHandler.cpp
@@ -471,3 +471,71 @@ void WorldSession::HandleCorpseMapPositionQuery( WorldPacket & recv_data )
data << float(0);
SendPacket(&data);
}
+
+void WorldSession::HandleQuestPOIQuery(WorldPacket& recv_data)
+{
+ uint32 count;
+ recv_data >> count; // quest count, max=25
+
+ if(count >= MAX_QUEST_LOG_SIZE)
+ return;
+
+ WorldPacket data(SMSG_QUEST_POI_QUERY_RESPONSE, 4+(4+4)*count);
+ data << uint32(count); // count
+
+ for(int i = 0; i < count; ++i)
+ {
+ uint32 questId;
+ recv_data >> questId; // quest id
+
+ bool questOk = false;
+
+ uint16 questSlot = _player->FindQuestSlot(questId);
+
+ if(questSlot != MAX_QUEST_LOG_SIZE)
+ questOk =_player->GetQuestSlotQuestId(questSlot) == questId;
+
+ if(questOk)
+ {
+ QuestPOIVector const *POI = objmgr.GetQuestPOIVector(questId);
+
+ if(POI)
+ {
+ data << uint32(questId); // quest ID
+ data << uint32(POI->size()); // POI count
+
+ int index = 0;
+ for(QuestPOIVector::const_iterator itr = POI->begin(); itr != POI->end(); ++itr)
+ {
+ data << uint32(index); // POI index
+ data << int32(itr->ObjectiveIndex); // objective index
+ data << uint32(itr->MapId); // mapid
+ data << uint32(itr->Unk1); // unknown
+ data << uint32(itr->Unk2); // unknown
+ data << uint32(itr->Unk3); // unknown
+ data << uint32(itr->Unk4); // unknown
+ data << uint32(itr->points.size()); // POI points count
+
+ for(std::vector<QuestPOIPoint>::const_iterator itr2 = itr->points.begin(); itr2 != itr->points.end(); ++itr2)
+ {
+ data << int32(itr2->x); // POI point x
+ data << int32(itr2->y); // POI point y
+ }
+ ++index;
+ }
+ }
+ else
+ {
+ data << uint32(questId); // quest ID
+ data << uint32(0); // POI count
+ }
+ }
+ else
+ {
+ data << uint32(questId); // quest ID
+ data << uint32(0); // POI count
+ }
+ }
+
+ SendPacket(&data);
+} \ No newline at end of file
diff --git a/src/game/QuestDef.cpp b/src/game/QuestDef.cpp
index 979c002f54e..9057f7930fb 100644
--- a/src/game/QuestDef.cpp
+++ b/src/game/QuestDef.cpp
@@ -52,87 +52,92 @@ Quest::Quest(Field * questRecord)
NextQuestId = questRecord[25].GetInt32();
ExclusiveGroup = questRecord[26].GetInt32();
NextQuestInChain = questRecord[27].GetUInt32();
- SrcItemId = questRecord[28].GetUInt32();
- SrcItemCount = questRecord[29].GetUInt32();
- SrcSpell = questRecord[30].GetUInt32();
- Title = questRecord[31].GetCppString();
- Details = questRecord[32].GetCppString();
- Objectives = questRecord[33].GetCppString();
- OfferRewardText = questRecord[34].GetCppString();
- RequestItemsText = questRecord[35].GetCppString();
- EndText = questRecord[36].GetCppString();
+ XPId = questRecord[28].GetUInt32();
+ SrcItemId = questRecord[29].GetUInt32();
+ SrcItemCount = questRecord[30].GetUInt32();
+ SrcSpell = questRecord[31].GetUInt32();
+ Title = questRecord[32].GetCppString();
+ Details = questRecord[33].GetCppString();
+ Objectives = questRecord[34].GetCppString();
+ OfferRewardText = questRecord[35].GetCppString();
+ RequestItemsText = questRecord[36].GetCppString();
+ EndText = questRecord[37].GetCppString();
for (int i = 0; i < QUEST_OBJECTIVES_COUNT; ++i)
- ObjectiveText[i] = questRecord[37+i].GetCppString();
+ ObjectiveText[i] = questRecord[38+i].GetCppString();
for (int i = 0; i < QUEST_ITEM_OBJECTIVES_COUNT; ++i)
- ReqItemId[i] = questRecord[41+i].GetUInt32();
+ ReqItemId[i] = questRecord[42+i].GetUInt32();
for (int i = 0; i < QUEST_ITEM_OBJECTIVES_COUNT; ++i)
- ReqItemCount[i] = questRecord[47+i].GetUInt32();
+ ReqItemCount[i] = questRecord[48+i].GetUInt32();
for (int i = 0; i < QUEST_SOURCE_ITEM_IDS_COUNT; ++i)
- ReqSourceId[i] = questRecord[53+i].GetUInt32();
+ ReqSourceId[i] = questRecord[54+i].GetUInt32();
for (int i = 0; i < QUEST_SOURCE_ITEM_IDS_COUNT; ++i)
- ReqSourceCount[i] = questRecord[57+i].GetUInt32();
+ ReqSourceCount[i] = questRecord[58+i].GetUInt32();
for (int i = 0; i < QUEST_OBJECTIVES_COUNT; ++i)
- ReqCreatureOrGOId[i] = questRecord[61+i].GetInt32();
+ ReqCreatureOrGOId[i] = questRecord[62+i].GetInt32();
for (int i = 0; i < QUEST_OBJECTIVES_COUNT; ++i)
- ReqCreatureOrGOCount[i] = questRecord[65+i].GetUInt32();
+ ReqCreatureOrGOCount[i] = questRecord[66+i].GetUInt32();
for (int i = 0; i < QUEST_OBJECTIVES_COUNT; ++i)
- ReqSpell[i] = questRecord[69+i].GetUInt32();
+ ReqSpell[i] = questRecord[70+i].GetUInt32();
for (int i = 0; i < QUEST_REWARD_CHOICES_COUNT; ++i)
- RewChoiceItemId[i] = questRecord[73+i].GetUInt32();
+ RewChoiceItemId[i] = questRecord[74+i].GetUInt32();
for (int i = 0; i < QUEST_REWARD_CHOICES_COUNT; ++i)
- RewChoiceItemCount[i] = questRecord[79+i].GetUInt32();
+ RewChoiceItemCount[i] = questRecord[80+i].GetUInt32();
for (int i = 0; i < QUEST_REWARDS_COUNT; ++i)
- RewItemId[i] = questRecord[85+i].GetUInt32();
+ RewItemId[i] = questRecord[86+i].GetUInt32();
for (int i = 0; i < QUEST_REWARDS_COUNT; ++i)
- RewItemCount[i] = questRecord[89+i].GetUInt32();
+ RewItemCount[i] = questRecord[90+i].GetUInt32();
for (int i = 0; i < QUEST_REPUTATIONS_COUNT; ++i)
- RewRepFaction[i] = questRecord[93+i].GetUInt32();
+ RewRepFaction[i] = questRecord[94+i].GetUInt32();
for (int i = 0; i < QUEST_REPUTATIONS_COUNT; ++i)
- RewRepValue[i] = questRecord[98+i].GetInt32();
-
- RewHonorableKills = questRecord[103].GetUInt32();
- RewOrReqMoney = questRecord[104].GetInt32();
- RewMoneyMaxLevel = questRecord[105].GetUInt32();
- RewSpell = questRecord[106].GetUInt32();
- RewSpellCast = questRecord[107].GetInt32();
- RewMailTemplateId = questRecord[108].GetUInt32();
- RewMailDelaySecs = questRecord[109].GetUInt32();
- PointMapId = questRecord[110].GetUInt32();
- PointX = questRecord[111].GetFloat();
- PointY = questRecord[112].GetFloat();
- PointOpt = questRecord[113].GetUInt32();
+ RewRepValueId[i] = questRecord[99+i].GetInt32();
+
+ for (int i = 0; i < QUEST_REPUTATIONS_COUNT; ++i)
+ RewRepValue[i] = questRecord[104+i].GetInt32();
+
+ RewHonorableKills = questRecord[109].GetUInt32();
+ RewHonorMultiplier = questRecord[110].GetFloat();
+ RewOrReqMoney = questRecord[111].GetInt32();
+ RewMoneyMaxLevel = questRecord[112].GetUInt32();
+ RewSpell = questRecord[113].GetUInt32();
+ RewSpellCast = questRecord[114].GetInt32();
+ RewMailTemplateId = questRecord[115].GetUInt32();
+ RewMailDelaySecs = questRecord[116].GetUInt32();
+ PointMapId = questRecord[117].GetUInt32();
+ PointX = questRecord[118].GetFloat();
+ PointY = questRecord[119].GetFloat();
+ PointOpt = questRecord[120].GetUInt32();
for (int i = 0; i < QUEST_EMOTE_COUNT; ++i)
- DetailsEmote[i] = questRecord[114+i].GetUInt32();
+ DetailsEmote[i] = questRecord[121+i].GetUInt32();
for (int i = 0; i < QUEST_EMOTE_COUNT; ++i)
- DetailsEmoteDelay[i] = questRecord[118+i].GetUInt32();
+ DetailsEmoteDelay[i] = questRecord[125+i].GetUInt32();
- IncompleteEmote = questRecord[122].GetUInt32();
- CompleteEmote = questRecord[123].GetUInt32();
+ IncompleteEmote = questRecord[129].GetUInt32();
+ CompleteEmote = questRecord[130].GetUInt32();
for (int i = 0; i < QUEST_EMOTE_COUNT; ++i)
- OfferRewardEmote[i] = questRecord[124+i].GetInt32();
+ OfferRewardEmote[i] = questRecord[131+i].GetInt32();
for (int i = 0; i < QUEST_EMOTE_COUNT; ++i)
- OfferRewardEmoteDelay[i] = questRecord[128+i].GetInt32();
+ OfferRewardEmoteDelay[i] = questRecord[135+i].GetInt32();
- QuestStartScript = questRecord[132].GetUInt32();
- QuestCompleteScript = questRecord[133].GetUInt32();
+ QuestStartScript = questRecord[139].GetUInt32();
+ QuestCompleteScript = questRecord[140].GetUInt32();
QuestFlags |= SpecialFlags << 16;
@@ -170,39 +175,33 @@ uint32 Quest::XPValue( Player *pPlayer ) const
{
if( pPlayer )
{
- if( RewMoneyMaxLevel > 0 )
- {
- uint32 pLevel = pPlayer->getLevel();
- int32 qLevel = QuestLevel;
- float fullxp = 0;
- if (qLevel >= 15)
- fullxp = RewMoneyMaxLevel / 6.0f;
- else if (qLevel == 14)
- fullxp = RewMoneyMaxLevel / 4.8f;
- else if (qLevel == 13)
- fullxp = RewMoneyMaxLevel / 3.666f;
- else if (qLevel == 12)
- fullxp = RewMoneyMaxLevel / 2.4f;
- else if (qLevel == 11)
- fullxp = RewMoneyMaxLevel / 1.2f;
- else if (qLevel >= 1 && qLevel <= 10)
- fullxp = RewMoneyMaxLevel / 0.6f;
- else if (qLevel <= 0)
- fullxp = RewMoneyMaxLevel;
-
- if ((pLevel <= qLevel + 5) || qLevel == -1)
- return (uint32)fullxp;
- else if (pLevel == qLevel + 6)
- return (uint32)(fullxp * 0.8f);
- else if (pLevel == qLevel + 7)
- return (uint32)(fullxp * 0.6f);
- else if (pLevel == qLevel + 8)
- return (uint32)(fullxp * 0.4f);
- else if (pLevel == qLevel + 9)
- return (uint32)(fullxp * 0.2f);
- else
- return (uint32)(fullxp * 0.1f);
- }
+
+ const QuestXPEntry *xpentry;
+ int32 quest_level = (QuestLevel == -1 ? pPlayer->getLevel() : QuestLevel);
+ xpentry = sQuestXPStore.LookupEntry(quest_level);
+ if(!xpentry)
+ return 0;
+
+ int diffFactor = 2 * (quest_level - pPlayer->getLevel()) + 20;
+
+ if (diffFactor < 1)
+ diffFactor = 1;
+ else if (diffFactor > 10)
+ diffFactor = 10;
+
+ uint32 xp = diffFactor * xpentry->Exp[XPId] / 10;
+
+ if (xp <= 100)
+ xp = 5 * ((xp + 2) / 5);
+ else if (xp <= 500)
+ xp = 10 * ((xp + 5) / 10);
+ else if (xp <= 1000)
+ xp = 25 * ((xp + 12) / 25);
+ else
+ xp = 50 * ((xp + 25) / 50);
+
+ return xp;
+
}
return 0;
}
diff --git a/src/game/QuestDef.h b/src/game/QuestDef.h
index d230514b818..74a2087ad37 100644
--- a/src/game/QuestDef.h
+++ b/src/game/QuestDef.h
@@ -122,6 +122,7 @@ enum __QuestGiverStatus
enum __QuestFlags
{
// Flags used at server and sent to client
+ QUEST_FLAGS_NONE = 0x00000000,
QUEST_FLAGS_STAY_ALIVE = 0x00000001, // Not used currently
QUEST_FLAGS_PARTY_ACCEPT = 0x00000002, // Not used currently. If player in party, all players that can accept this quest will receive confirmation box to accept quest CMSG_QUEST_CONFIRM_ACCEPT/SMSG_QUEST_CONFIRM_ACCEPT
QUEST_FLAGS_EXPLORATION = 0x00000004, // Not used currently
@@ -136,6 +137,10 @@ enum __QuestFlags
QUEST_FLAGS_TBC_RACES = 0x00000800, // Not used currently: Blood elf/Draenei starting zone quests
QUEST_FLAGS_DAILY = 0x00001000, // Used to know quest is Daily one
QUEST_FLAGS_WEEKLY = 0x00008000,
+ QUEST_FLAGS_AUTOCOMPLETE = 0x00010000, // auto complete
+ QUEST_FLAGS_UNK5 = 0x00020000, // has something to do with ReqItemId and SrcItemId
+ QUEST_FLAGS_UNK6 = 0x00040000, // use Objective text as Complete text
+ QUEST_FLAGS_LOW_LEVEL = 0x00080000, // quests in starting areas
// Trinity flags for set SpecialFlags in DB if required but used only at server
QUEST_TRINITY_FLAGS_REPEATABLE = 0x010000, // Set by 1 in SpecialFlags from DB
@@ -246,6 +251,7 @@ class Quest
uint32 RewItemId[QUEST_REWARDS_COUNT];
uint32 RewItemCount[QUEST_REWARDS_COUNT];
uint32 RewRepFaction[QUEST_REPUTATIONS_COUNT];
+ int32 RewRepValueId[QUEST_REPUTATIONS_COUNT];
int32 RewRepValue[QUEST_REPUTATIONS_COUNT];
uint32 DetailsEmote[QUEST_EMOTE_COUNT];
uint32 DetailsEmoteDelay[QUEST_EMOTE_COUNT];
@@ -276,7 +282,7 @@ class Quest
int32 ZoneOrSort;
int32 SkillOrClass;
uint32 MinLevel;
- uint32 QuestLevel;
+ int32 QuestLevel;
uint32 Type;
uint32 RequiredRaces;
uint32 RequiredSkillValue;
@@ -298,6 +304,7 @@ class Quest
int32 NextQuestId;
int32 ExclusiveGroup;
uint32 NextQuestInChain;
+ uint32 XPId;
uint32 SrcItemId;
uint32 SrcItemCount;
uint32 SrcSpell;
@@ -308,6 +315,7 @@ class Quest
std::string RequestItemsText;
std::string EndText;
uint32 RewHonorableKills;
+ float RewHonorMultiplier;
int32 RewOrReqMoney;
uint32 RewMoneyMaxLevel;
uint32 RewSpell;
diff --git a/src/game/QuestHandler.cpp b/src/game/QuestHandler.cpp
index 4b9f3eddd04..d234e063d39 100644
--- a/src/game/QuestHandler.cpp
+++ b/src/game/QuestHandler.cpp
@@ -689,3 +689,22 @@ void WorldSession::HandleQuestgiverStatusMultipleQuery(WorldPacket& /*recvPacket
data.put<uint32>(0, count); // write real count
SendPacket(&data);
}
+
+void WorldSession::HandleQueryQuestsCompleted( WorldPacket & recv_data )
+{
+ uint32 count = 0;
+
+ WorldPacket data(SMSG_QUERY_QUESTS_COMPLETED_RESPONSE, 4+4*count);
+ data << uint32(count);
+
+ for(QuestStatusMap::const_iterator itr = _player->getQuestStatusMap().begin(); itr != _player->getQuestStatusMap().end(); ++itr)
+ {
+ if(itr->second.m_rewarded)
+ {
+ data << uint32(itr->first);
+ count++;
+ }
+ }
+ data.put<uint32>(0, count);
+ SendPacket(&data);
+}
diff --git a/src/game/SharedDefines.h b/src/game/SharedDefines.h
index d047dd90544..0e9c1db98fb 100644
--- a/src/game/SharedDefines.h
+++ b/src/game/SharedDefines.h
@@ -280,7 +280,7 @@ const uint32 ItemQualityColors[MAX_ITEM_QUALITY] = {
#define SPELL_ATTR_EX_DISMISS_PET 0x00000001 // 0 dismiss pet and not allow to summon new one?
#define SPELL_ATTR_EX_DRAIN_ALL_POWER 0x00000002 // 1 use all power (Only paladin Lay of Hands and Bunyanize)
#define SPELL_ATTR_EX_CHANNELED_1 0x00000004 // 2 channeled target
-#define SPELL_ATTR_EX_UNK3 0x00000008 // 3
+#define SPELL_ATTR_EX_PUT_CASTER_IN_COMBAT 0x00000008 // 3 spells that cause a caster to enter a combat
#define SPELL_ATTR_EX_UNK4 0x00000010 // 4 stealth and whirlwind
#define SPELL_ATTR_EX_NOT_BREAK_STEALTH 0x00000020 // 5 Not break stealth
#define SPELL_ATTR_EX_CHANNELED_2 0x00000040 // 6 channeled self
@@ -303,11 +303,11 @@ const uint32 ItemQualityColors[MAX_ITEM_QUALITY] = {
#define SPELL_ATTR_EX_UNK23 0x00800000 // 23
#define SPELL_ATTR_EX_UNK24 0x01000000 // 24 Req fishing pole??
#define SPELL_ATTR_EX_UNK25 0x02000000 // 25
-#define SPELL_ATTR_EX_UNK26 0x04000000 // 26
+#define SPELL_ATTR_EX_UNK26 0x04000000 // 26 works correctly with [target=focus] and [target=mouseover] macros?
#define SPELL_ATTR_EX_UNK27 0x08000000 // 27
-#define SPELL_ATTR_EX_UNK28 0x10000000 // 28
+#define SPELL_ATTR_EX_IGNORE_IMMUNITY 0x10000000 // 28 removed from Chains of Ice 3.3.0
#define SPELL_ATTR_EX_UNK29 0x20000000 // 29
-#define SPELL_ATTR_EX_UNK30 0x40000000 // 30 overpower
+#define SPELL_ATTR_EX_ENABLE_AT_DODGE 0x40000000 // 30 Overpower, Wolverine Bite
#define SPELL_ATTR_EX_UNK31 0x80000000 // 31
#define SPELL_ATTR_EX2_UNK0 0x00000001 // 0
@@ -361,7 +361,7 @@ const uint32 ItemQualityColors[MAX_ITEM_QUALITY] = {
#define SPELL_ATTR_EX3_UNK15 0x00008000 // 15 Auto Shoot, Shoot, Throw, - this is autoshot flag
#define SPELL_ATTR_EX3_UNK16 0x00010000 // 16 no triggers effects that trigger on casting a spell?? (15290 - 2.2ptr change)
#define SPELL_ATTR_EX3_NO_INITIAL_AGGRO 0x00020000 // 17 Soothe Animal, 39758, Mind Soothe
-#define SPELL_ATTR_EX3_UNK18 0x00040000 // 18
+#define SPELL_ATTR_EX3_UNK18 0x00040000 // 18 added to Explosive Trap Effect 3.3.0, removed from Mutilate 3.3.0
#define SPELL_ATTR_EX3_DISABLE_PROC 0x00080000 // 19 during aura proc no spells can trigger (20178, 20375)
#define SPELL_ATTR_EX3_DEATH_PERSISTENT 0x00100000 // 20 Death persistent spells
#define SPELL_ATTR_EX3_UNK21 0x00200000 // 21
@@ -372,8 +372,8 @@ const uint32 ItemQualityColors[MAX_ITEM_QUALITY] = {
#define SPELL_ATTR_EX3_CAN_PROC_TRIGGERED 0x04000000 // 26
#define SPELL_ATTR_EX3_DRAIN_SOUL 0x08000000 // 27 only drain soul has this flag
#define SPELL_ATTR_EX3_UNK28 0x10000000 // 28
-#define SPELL_ATTR_EX3_UNK29 0x20000000 // 29
-#define SPELL_ATTR_EX3_UNK30 0x40000000 // 30
+#define SPELL_ATTR_EX3_UNK29 0x20000000 // 29 Ignite 3.3.0
+#define SPELL_ATTR_EX3_UNK30 0x40000000 // 30 Shaman's Fire Nova 3.3.0, Sweeping Strikes 3.3.0
#define SPELL_ATTR_EX3_UNK31 0x80000000 // 31
#define SPELL_ATTR_EX4_UNK0 0x00000001 // 0
@@ -396,7 +396,7 @@ const uint32 ItemQualityColors[MAX_ITEM_QUALITY] = {
#define SPELL_ATTR_EX4_USABLE_IN_ARENA 0x00020000 // 17 usable in arena
#define SPELL_ATTR_EX4_UNK18 0x00040000 // 18
#define SPELL_ATTR_EX4_UNK19 0x00080000 // 19
-#define SPELL_ATTR_EX4_UNK20 0x00100000 // 20
+#define SPELL_ATTR_EX4_NOT_CHECK_SELFCAST_POWER 0x00100000 // 20 supersedes message "More powerful spell applied" for self casts.
#define SPELL_ATTR_EX4_UNK21 0x00200000 // 21
#define SPELL_ATTR_EX4_UNK22 0x00400000 // 22
#define SPELL_ATTR_EX4_UNK23 0x00800000 // 23
@@ -463,7 +463,7 @@ const uint32 ItemQualityColors[MAX_ITEM_QUALITY] = {
#define SPELL_ATTR_EX6_UNK18 0x00040000 // 18
#define SPELL_ATTR_EX6_UNK19 0x00080000 // 19
#define SPELL_ATTR_EX6_UNK20 0x00100000 // 20
-#define SPELL_ATTR_EX6_UNK21 0x00200000 // 21
+#define SPELL_ATTR_EX6_CLIENT_UI_TARGET_EFFECTS 0x00200000 // 21 it's only client-side attribute
#define SPELL_ATTR_EX6_UNK22 0x00400000 // 22
#define SPELL_ATTR_EX6_UNK23 0x00800000 // 23 not set in 3.0.3
#define SPELL_ATTR_EX6_UNK24 0x01000000 // 24 not set in 3.0.3
@@ -974,7 +974,7 @@ enum AuraState
AURA_STATE_HUNTER_PARRY = 7, // C |
//AURA_STATE_UNKNOWN7 = 7, // c | creature cheap shot / focused bursts spells
//AURA_STATE_UNKNOWN8 = 8, // t| test spells
- //AURA_STATE_UNKNOWN9 = 9, // |
+ //AURA_STATE_UNKNOWN9 = 9, // |
AURA_STATE_WARRIOR_VICTORY_RUSH = 10, // C | warrior victory rush
//AURA_STATE_UNKNOWN11 = 11, // C t| 60348 - Maelstrom Ready!, test spells
AURA_STATE_FAERIE_FIRE = 12, // c t|
@@ -2359,13 +2359,15 @@ enum TotemCategory
enum UnitDynFlags
{
- UNIT_DYNFLAG_LOOTABLE = 0x0001,
- UNIT_DYNFLAG_TRACK_UNIT = 0x0002,
- UNIT_DYNFLAG_OTHER_TAGGER = 0x0004,
- UNIT_DYNFLAG_ROOTED = 0x0008,
- UNIT_DYNFLAG_SPECIALINFO = 0x0010,
- UNIT_DYNFLAG_DEAD = 0x0020,
- UNIT_DYNFLAG_REFER_A_FRIEND = 0x0040
+ UNIT_DYNFLAG_NONE = 0x0000,
+ UNIT_DYNFLAG_LOOTABLE = 0x0001,
+ UNIT_DYNFLAG_TRACK_UNIT = 0x0002,
+ UNIT_DYNFLAG_TAPPED = 0x0004, // Lua_UnitIsTapped
+ UNIT_DYNFLAG_TAPPED_BY_PLAYER = 0x0008, // Lua_UnitIsTappedByPlayer
+ UNIT_DYNFLAG_SPECIALINFO = 0x0010,
+ UNIT_DYNFLAG_DEAD = 0x0020,
+ UNIT_DYNFLAG_REFER_A_FRIEND = 0x0040,
+ UNIT_DYNFLAG_TAPPED_BY_ALL_THREAT_LIST = 0x0080 // Lua_UnitIsTappedByAllThreatList
};
enum CorpseDynFlags
@@ -2396,8 +2398,8 @@ enum ChatMsg
CHAT_MSG_OFFICER = 0x05,
CHAT_MSG_YELL = 0x06,
CHAT_MSG_WHISPER = 0x07,
- CHAT_MSG_WHISPER_INFORM = 0x08, // WHISPER_FOREIGN?
- CHAT_MSG_REPLY = 0x09, // WHISPER_INFORM?
+ CHAT_MSG_WHISPER_FOREIGN = 0x08,
+ CHAT_MSG_WHISPER_INFORM = 0x09,
CHAT_MSG_EMOTE = 0x0A,
CHAT_MSG_TEXT_EMOTE = 0x0B,
CHAT_MSG_MONSTER_SAY = 0x0C,
@@ -2429,18 +2431,20 @@ enum ChatMsg
CHAT_MSG_BG_SYSTEM_HORDE = 0x26,
CHAT_MSG_RAID_LEADER = 0x27,
CHAT_MSG_RAID_WARNING = 0x28,
- CHAT_MSG_RAID_BOSS_WHISPER = 0x29,
- CHAT_MSG_RAID_BOSS_EMOTE = 0x2A,
+ CHAT_MSG_RAID_BOSS_EMOTE = 0x29,
+ CHAT_MSG_RAID_BOSS_WHISPER = 0x2A,
CHAT_MSG_FILTERED = 0x2B,
CHAT_MSG_BATTLEGROUND = 0x2C,
CHAT_MSG_BATTLEGROUND_LEADER = 0x2D,
CHAT_MSG_RESTRICTED = 0x2E,
- CHAT_MSG_BN = 0x2F,
+ CHAT_MSG_BATTLENET = 0x2F,
CHAT_MSG_ACHIEVEMENT = 0x30,
- CHAT_MSG_GUILD_ACHIEVEMENT = 0x31
+ CHAT_MSG_GUILD_ACHIEVEMENT = 0x31,
+ CHAT_MSG_ARENA_POINTS = 0x32,
+ CHAT_MSG_PARTY_LEADER = 0x33
};
-#define MAX_CHAT_MSG_TYPE 0x32
+#define MAX_CHAT_MSG_TYPE 0x33
enum ChatLinkColors
{
@@ -2632,41 +2636,43 @@ enum ResponseCodes
CHAR_CREATE_CHARACTER_GOLD_LIMIT = 0x44,
- CHAR_DELETE_IN_PROGRESS = 0x45,
- CHAR_DELETE_SUCCESS = 0x46,
- CHAR_DELETE_FAILED = 0x47,
- CHAR_DELETE_FAILED_LOCKED_FOR_TRANSFER = 0x48,
- CHAR_DELETE_FAILED_GUILD_LEADER = 0x49,
- CHAR_DELETE_FAILED_ARENA_CAPTAIN = 0x4A,
-
- CHAR_LOGIN_IN_PROGRESS = 0x4B,
- CHAR_LOGIN_SUCCESS = 0x4C,
- CHAR_LOGIN_NO_WORLD = 0x4D,
- CHAR_LOGIN_DUPLICATE_CHARACTER = 0x4E,
- CHAR_LOGIN_NO_INSTANCES = 0x4F,
- CHAR_LOGIN_FAILED = 0x50,
- CHAR_LOGIN_DISABLED = 0x51,
- CHAR_LOGIN_NO_CHARACTER = 0x52,
- CHAR_LOGIN_LOCKED_FOR_TRANSFER = 0x53,
- CHAR_LOGIN_LOCKED_BY_BILLING = 0x54,
-
- CHAR_NAME_SUCCESS = 0x55,
- CHAR_NAME_FAILURE = 0x56,
- CHAR_NAME_NO_NAME = 0x57,
- CHAR_NAME_TOO_SHORT = 0x58,
- CHAR_NAME_TOO_LONG = 0x59,
- CHAR_NAME_INVALID_CHARACTER = 0x5A,
- CHAR_NAME_MIXED_LANGUAGES = 0x5B,
- CHAR_NAME_PROFANE = 0x5C,
- CHAR_NAME_RESERVED = 0x5D,
- CHAR_NAME_INVALID_APOSTROPHE = 0x5E,
- CHAR_NAME_MULTIPLE_APOSTROPHES = 0x5F,
- CHAR_NAME_THREE_CONSECUTIVE = 0x60,
- CHAR_NAME_INVALID_SPACE = 0x61,
- CHAR_NAME_CONSECUTIVE_SPACES = 0x62,
- CHAR_NAME_RUSSIAN_CONSECUTIVE_SILENT_CHARACTERS = 0x63,
- CHAR_NAME_RUSSIAN_SILENT_CHARACTER_AT_BEGINNING_OR_END = 0x64,
- CHAR_NAME_DECLENSION_DOESNT_MATCH_BASE_NAME = 0x65
+ CHAR_CREATE_FORCE_LOGIN = 0x45,
+
+ CHAR_DELETE_IN_PROGRESS = 0x46,
+ CHAR_DELETE_SUCCESS = 0x47,
+ CHAR_DELETE_FAILED = 0x48,
+ CHAR_DELETE_FAILED_LOCKED_FOR_TRANSFER = 0x49,
+ CHAR_DELETE_FAILED_GUILD_LEADER = 0x4A,
+ CHAR_DELETE_FAILED_ARENA_CAPTAIN = 0x4B,
+
+ CHAR_LOGIN_IN_PROGRESS = 0x4C,
+ CHAR_LOGIN_SUCCESS = 0x4D,
+ CHAR_LOGIN_NO_WORLD = 0x4E,
+ CHAR_LOGIN_DUPLICATE_CHARACTER = 0x4F,
+ CHAR_LOGIN_NO_INSTANCES = 0x50,
+ CHAR_LOGIN_FAILED = 0x51,
+ CHAR_LOGIN_DISABLED = 0x52,
+ CHAR_LOGIN_NO_CHARACTER = 0x53,
+ CHAR_LOGIN_LOCKED_FOR_TRANSFER = 0x54,
+ CHAR_LOGIN_LOCKED_BY_BILLING = 0x55,
+
+ CHAR_NAME_SUCCESS = 0x56,
+ CHAR_NAME_FAILURE = 0x57,
+ CHAR_NAME_NO_NAME = 0x58,
+ CHAR_NAME_TOO_SHORT = 0x59,
+ CHAR_NAME_TOO_LONG = 0x5A,
+ CHAR_NAME_INVALID_CHARACTER = 0x5B,
+ CHAR_NAME_MIXED_LANGUAGES = 0x5C,
+ CHAR_NAME_PROFANE = 0x5D,
+ CHAR_NAME_RESERVED = 0x5E,
+ CHAR_NAME_INVALID_APOSTROPHE = 0x5F,
+ CHAR_NAME_MULTIPLE_APOSTROPHES = 0x60,
+ CHAR_NAME_THREE_CONSECUTIVE = 0x61,
+ CHAR_NAME_INVALID_SPACE = 0x62,
+ CHAR_NAME_CONSECUTIVE_SPACES = 0x63,
+ CHAR_NAME_RUSSIAN_CONSECUTIVE_SILENT_CHARACTERS = 0x64,
+ CHAR_NAME_RUSSIAN_SILENT_CHARACTER_AT_BEGINNING_OR_END = 0x65,
+ CHAR_NAME_DECLENSION_DOESNT_MATCH_BASE_NAME = 0x66
};
/// Ban function modes
diff --git a/src/game/Spell.cpp b/src/game/Spell.cpp
index ad2a6c867be..9bcb0751252 100644
--- a/src/game/Spell.cpp
+++ b/src/game/Spell.cpp
@@ -2899,6 +2899,13 @@ void Spell::cast(bool skipCheck)
m_preCastSpell = 11196; // Recently Bandaged
break;
}
+ case SPELLFAMILY_MAGE:
+ {
+ // Permafrost
+ if (m_spellInfo->SpellFamilyFlags[1] & 0x00001000 || m_spellInfo->SpellFamilyFlags[0] & 0x00100220)
+ m_preCastSpell = 68391;
+ break;
+ }
}
// traded items have trade slot instead of guid in m_itemTargetGUID
// set to real guid to be sent later to the client
@@ -4621,7 +4628,7 @@ SpellCastResult Spell::CheckCast(bool strict)
// - with greater than 15 min CD without SPELL_ATTR_EX4_USABLE_IN_ARENA flag
// - with SPELL_ATTR_EX4_NOT_USABLE_IN_ARENA flag
if ((m_spellInfo->AttributesEx4 & SPELL_ATTR_EX4_NOT_USABLE_IN_ARENA) ||
- GetSpellRecoveryTime(m_spellInfo) > 15 * MINUTE * IN_MILISECONDS && !(m_spellInfo->AttributesEx4 & SPELL_ATTR_EX4_USABLE_IN_ARENA))
+ GetSpellRecoveryTime(m_spellInfo) > 10 * MINUTE * IN_MILISECONDS && !(m_spellInfo->AttributesEx4 & SPELL_ATTR_EX4_USABLE_IN_ARENA))
if(MapEntry const* mapEntry = sMapStore.LookupEntry(m_caster->GetMapId()))
if(mapEntry->IsBattleArena())
return SPELL_FAILED_NOT_IN_ARENA;
@@ -4825,6 +4832,11 @@ SpellCastResult Spell::CheckCast(bool strict)
if(m_targets.getUnitTarget() && !m_caster->IsFriendlyTo(m_targets.getUnitTarget()) && !m_caster->HasInArc( M_PI, m_targets.getUnitTarget() ))
return SPELL_FAILED_UNIT_NOT_INFRONT;
}
+ else if(m_spellInfo->SpellIconID == 33 && m_spellInfo->SpellFamilyName == SPELLFAMILY_SHAMAN && m_spellInfo->SpellFamilyFlags[0] & SPELLFAMILYFLAG_SHAMAN_FIRE_NOVA)
+ {
+ if (!m_caster->m_SummonSlot[1])
+ return SPELL_FAILED_SUCCESS;
+ }
else if (m_spellInfo->SpellFamilyName == SPELLFAMILY_DEATHKNIGHT && m_spellInfo->SpellFamilyFlags[0] == 0x2000) // Death Coil (DeathKnight)
{
Unit* target = m_targets.getUnitTarget();
@@ -5290,6 +5302,17 @@ SpellCastResult Spell::CheckCast(bool strict)
}
break;
}
+ case SPELL_AURA_RANGED_AP_ATTACKER_CREATURES_BONUS:
+ {
+ if (!m_targets.getUnitTarget() && m_targets.getUnitTarget()->GetTypeId() != TYPEID_UNIT)
+ return SPELL_FAILED_BAD_IMPLICIT_TARGETS;
+
+ // can be casted at non-friendly unit or own pet/charm
+ if (m_caster->IsFriendlyTo(m_targets.getUnitTarget()))
+ return SPELL_FAILED_TARGET_FRIENDLY;
+
+ break;
+ }
case SPELL_AURA_PERIODIC_MANA_LEECH:
{
if (!m_targets.getUnitTarget())
@@ -6609,6 +6632,13 @@ int32 Spell::CalculateDamageDone(Unit *unit, const uint32 effectMask, float *mul
{
if(int32 reducedPct = unit->GetMaxNegativeAuraModifier(SPELL_AURA_MOD_AOE_DAMAGE_AVOIDANCE))
m_damage = m_damage * (100 + reducedPct) / 100;
+
+ if (m_caster->GetTypeId() == TYPEID_PLAYER)
+ {
+ uint32 targetAmount = m_UniqueTargetInfo.size();
+ if (targetAmount > 10)
+ m_damage = m_damage * 10/targetAmount;
+ }
}
}
if(m_applyMultiplierMask & (1 << i))
diff --git a/src/game/SpellAuraDefines.h b/src/game/SpellAuraDefines.h
index 77736e21cc9..8b21062e371 100644
--- a/src/game/SpellAuraDefines.h
+++ b/src/game/SpellAuraDefines.h
@@ -351,7 +351,17 @@ enum AuraType
SPELL_AURA_304 = 304,
SPELL_AURA_MOD_MINIMUM_SPEED = 305,
SPELL_AURA_306 = 306,
- TOTAL_AURAS = 307
+ SPELL_AURA_307 = 307,
+ SPELL_AURA_308 = 308,
+ SPELL_AURA_309 = 309,
+ SPELL_AURA_RANGED_AP_ATTACKER_CREATURES_BONUS = 310,
+ SPELL_AURA_311 = 311,
+ SPELL_AURA_312 = 312,
+ SPELL_AURA_313 = 313,
+ SPELL_AURA_314 = 314,
+ SPELL_AURA_315 = 315,
+ SPELL_AURA_PERIODIC_HASTE = 316,
+ TOTAL_AURAS = 317
};
enum AuraObjectType
diff --git a/src/game/SpellAuraEffects.cpp b/src/game/SpellAuraEffects.cpp
index 30e019d669d..951692de7fa 100644
--- a/src/game/SpellAuraEffects.cpp
+++ b/src/game/SpellAuraEffects.cpp
@@ -360,7 +360,18 @@ pAuraEffectHandler AuraEffectHandler[TOTAL_AURAS]=
&AuraEffect::HandleNULL, //303 17 spells
&AuraEffect::HandleNULL, //304 2 spells (alcohol effect?)
&AuraEffect::HandleAuraModIncreaseSpeed, //305 SPELL_AURA_MOD_MINIMUM_SPEED
- &AuraEffect::HandleNULL //306 1 spell
+ &AuraEffect::HandleNULL, //306 1 spell
+ &AuraEffect::HandleNULL, //307 absorb healing?
+ &AuraEffect::HandleNULL, //308 new aura for hunter traps
+ &AuraEffect::HandleNULL, //309 absorb healing?
+ &AuraEffect::HandleNoImmediateEffect, //310 5 spells SPELL_AURA_RANGED_AP_ATTACKER_CREATURES_BONUS implemented in Unit::MeleeDamageBonus
+ &AuraEffect::HandleNULL, //311 0 spells in 3.3
+ &AuraEffect::HandleNULL, //312 0 spells in 3.3
+ &AuraEffect::HandleNULL, //313 0 spells in 3.3
+ &AuraEffect::HandleNULL, //314 1 test spell (reduce duration of silince/magic)
+ &AuraEffect::HandleNULL, //315 underwater walking
+ &AuraEffect::HandleNoImmediateEffect, //316 SPELL_AURA_PERIODIC_HASTE implemented in AuraEffect::CalculatePeriodic
+ &AuraEffect::HandleNULL
};
AuraEffect::AuraEffect(Aura * base, uint8 effIndex, int32 *baseAmount, Unit * caster) :
@@ -725,9 +736,29 @@ void AuraEffect::CalculatePeriodic(Unit * caster, bool create)
return;
Player* modOwner = caster ? caster->GetSpellModOwner() : NULL;
- //apply casting time mods for channeled spells
- if(modOwner && m_amplitude && IsChanneledSpell(m_spellProto))
- modOwner->ModSpellCastTime(m_spellProto, m_amplitude);
+ // Apply casting time mods
+ if(modOwner && m_amplitude)
+ {
+ // For channeled spells
+ if (IsChanneledSpell(m_spellProto)) {
+ modOwner->ModSpellCastTime(m_spellProto, m_amplitude);
+ }
+ // For spells that can benefit from haste
+ else if (modOwner->HasAuraType(SPELL_AURA_PERIODIC_HASTE)) {
+ const Unit::AuraEffectList &effList = modOwner->GetAuraEffectsByType(SPELL_AURA_PERIODIC_HASTE);
+ for (Unit::AuraEffectList::const_iterator itr = effList.begin(), end = effList.end(); itr != end; ++itr)
+ {
+ if ((*itr)->IsAffectedOnSpell(m_spellProto))
+ {
+ float hasteMod = modOwner->GetFloatValue(UNIT_MOD_CAST_SPEED);
+ m_amplitude *= hasteMod;
+ GetBase()->SetMaxDuration(GetBase()->GetMaxDuration() * hasteMod);
+ GetBase()->SetDuration(GetBase()->GetDuration() * hasteMod);
+ break;
+ }
+ }
+ }
+ }
// Apply periodic time mod
if(modOwner && m_amplitude)
@@ -989,7 +1020,7 @@ void AuraEffect::UpdatePeriodic(Unit * caster)
break;
case 46394: // Brutallus Burn
if (m_tickNumber % 11 == 0)
- SetAmount(GetAmount() * 2); ;
+ SetAmount(GetAmount() * 2);
break;
}
break;
diff --git a/src/game/SpellAuras.cpp b/src/game/SpellAuras.cpp
index 3ca24609a3e..354d79fb723 100644
--- a/src/game/SpellAuras.cpp
+++ b/src/game/SpellAuras.cpp
@@ -916,7 +916,10 @@ void Aura::HandleAuraSpecificMods(AuraApplication const * aurApp, Unit * caster,
case 48020: // Demonic Circle
if(target->GetTypeId() == TYPEID_PLAYER)
if(GameObject* obj = target->GetGameObject(48018))
+ {
((Player*)target)->TeleportTo(obj->GetMapId(),obj->GetPositionX(),obj->GetPositionY(),obj->GetPositionZ(),obj->GetOrientation());
+ ((Player*)target)->RemoveMovementImpairingAuras();
+ }
break;
}
break;
diff --git a/src/game/SpellEffects.cpp b/src/game/SpellEffects.cpp
index 56eb08e56de..904b275cc25 100644
--- a/src/game/SpellEffects.cpp
+++ b/src/game/SpellEffects.cpp
@@ -492,7 +492,7 @@ void Spell::SpellDamageSchoolDmg(uint32 effect_idx)
{
uint32 pdamage = aura->GetAmount() > 0 ? aura->GetAmount() : 0;
pdamage = m_caster->SpellDamageBonus(unitTarget, aura->GetSpellProto(), pdamage, DOT, aura->GetBase()->GetStackAmount());
- damage += pdamage * 4; // 4 ticks of 3 seconds = 12 secs
+ damage += pdamage * aura->GetTotalTicks() * 60 / 100;
apply_direct_bonus = false;
// Glyph of Conflagrate
if (!m_caster->HasAura(56235))
@@ -1979,6 +1979,37 @@ void Spell::EffectDummy(uint32 i)
m_caster->CastCustomSpell(unitTarget, 39609, &EffectBasePoints0, NULL, NULL, true, NULL, NULL, m_originalCasterGUID);
return;
}
+ // Fire Nova
+ if (m_spellInfo->SpellIconID == 33)
+ {
+ if (!m_caster)
+ return;
+
+ uint32 triggered_spell_id;
+ switch(m_spellInfo->Id)
+ {
+ case 1535: triggered_spell_id = 8349; break;
+ case 8498: triggered_spell_id = 8502; break;
+ case 8499: triggered_spell_id = 8503; break;
+ case 11314: triggered_spell_id = 11306; break;
+ case 11315: triggered_spell_id = 11307; break;
+ case 25546: triggered_spell_id = 25535; break;
+ case 25547: triggered_spell_id = 25537; break;
+ case 61649: triggered_spell_id = 61650; break;
+ case 61657: triggered_spell_id = 61654; break;
+ default:
+ break;
+ }
+ // fire slot
+ if (triggered_spell_id && m_caster->m_SummonSlot[1])
+ {
+ Creature* totem = m_caster->GetMap()->GetCreature(m_caster->m_SummonSlot[1]);
+ if (totem && totem->isTotem())
+ totem->CastSpell(totem, triggered_spell_id, true);
+ return;
+ }
+ return;
+ }
// Lava Lash
if (m_spellInfo->SpellFamilyFlags[2] & SPELLFAMILYFLAG2_SHAMAN_LAVA_LASH)
{
@@ -3351,12 +3382,10 @@ void Spell::EffectOpenLock(uint32 effIndex)
//CanUseBattleGroundObject() already called in CheckCast()
// in battleground check
if(BattleGround *bg = player->GetBattleGround())
- {
- // check if it's correct bg
- if(bg->GetTypeID() == BATTLEGROUND_AB || bg->GetTypeID() == BATTLEGROUND_AV)
- bg->EventPlayerClickedOnFlag(player, gameObjTarget);
- return;
- }
+ {
+ bg->EventPlayerClickedOnFlag(player, gameObjTarget);
+ return;
+ }
}
else if (goInfo->type == GAMEOBJECT_TYPE_FLAGSTAND)
{
@@ -4525,15 +4554,6 @@ void Spell::SpellDamageWeaponDmg(uint32 i)
spell_bonus += int32(0.13f*m_caster->SpellBaseDamageBonus(GetSpellSchoolMask(m_spellInfo)));
}
break;
- // Judgement of Blood/of the Martyr backlash damage (33%)
- if (m_spellInfo->SpellFamilyFlags[0] & 0x0000000800000000LL && m_spellInfo->SpellIconID==153)
- {
- int32 damagePoint = m_damage * 33 / 100;
- if (m_spellInfo->Id == 31898)
- m_caster->CastCustomSpell(m_caster, 32220, &damagePoint, NULL, NULL, true);
- else
- m_caster->CastCustomSpell(m_caster, 53725, &damagePoint, NULL, NULL, true);
- }
}
case SPELLFAMILY_SHAMAN:
{
@@ -4552,7 +4572,7 @@ void Spell::SpellDamageWeaponDmg(uint32 i)
((Player*)m_caster)->AddComboPoints(unitTarget,1, this);
}
// Shred, Maul - Rend and Tear
- else if (m_spellInfo->SpellFamilyFlags[0] & 0x00008800 && unitTarget->HasAuraState(AURA_STATE_BLEEDING, m_spellInfo, m_caster))
+ else if (m_spellInfo->SpellFamilyFlags[0] & 0x00008800 && unitTarget->HasAuraState(AURA_STATE_BLEEDING))
{
if (AuraEffect const* rendAndTear = m_caster->GetDummyAuraEffect(SPELLFAMILY_DRUID, 2859, 0))
{
@@ -4723,11 +4743,19 @@ void Spell::EffectHealMaxHealth(uint32 /*i*/)
int32 addhealth;
if(m_spellInfo->SpellFamilyName == SPELLFAMILY_PALADIN) // Lay on Hands
+ {
+ if (m_caster && m_caster->GetGUID() == unitTarget->GetGUID())
+ m_caster->CastSpell(m_caster, 25771, true);
+
addhealth = m_caster->GetMaxHealth();
+ }
else
addhealth = unitTarget->GetMaxHealth() - unitTarget->GetHealth();
if(m_originalCaster)
- m_originalCaster->DealHeal(unitTarget, addhealth, m_spellInfo);
+ {
+ addhealth=m_originalCaster->SpellHealingBonus(unitTarget,m_spellInfo, addhealth, HEAL);
+ m_originalCaster->DealHeal(unitTarget, addhealth, m_spellInfo);
+ }
}
void Spell::EffectInterruptCast(uint32 i)
@@ -7321,7 +7349,7 @@ void Spell::EffectWMODamage(uint32 /*i*/)
goft = sFactionTemplateStore.LookupEntry(gameObjTarget->GetUInt32Value(GAMEOBJECT_FACTION));
// Do not allow to damage GO's of friendly factions (ie: Wintergrasp Walls)
if (casterft && goft && !casterft->IsFriendlyTo(*goft))
- gameObjTarget->TakenDamage((uint32)damage);
+ gameObjTarget->TakenDamage((uint32)damage, caster);
}
}
@@ -7442,7 +7470,7 @@ void Spell::EffectRenamePet(uint32 /*eff_idx*/)
!((Creature*)unitTarget)->isPet() || ((Pet*)unitTarget)->getPetType() != HUNTER_PET)
return;
- unitTarget->SetByteValue(UNIT_FIELD_BYTES_2, 2, UNIT_RENAME_ALLOWED);
+ unitTarget->RemoveByteFlag(UNIT_FIELD_BYTES_2, 2, UNIT_CAN_BE_RENAMED);
}
void Spell::EffectPlayMusic(uint32 i)
diff --git a/src/game/SpellMgr.cpp b/src/game/SpellMgr.cpp
index 48d1d325ad2..4c1d2816df4 100644
--- a/src/game/SpellMgr.cpp
+++ b/src/game/SpellMgr.cpp
@@ -2382,7 +2382,24 @@ bool SpellMgr::IsSpellValid(SpellEntry const *spellInfo, Player *pl, bool msg)
case SPELL_EFFECT_CREATE_ITEM:
case SPELL_EFFECT_CREATE_ITEM_2:
{
- if(!ObjectMgr::GetItemPrototype(spellInfo->EffectItemType[i]))
+ if (spellInfo->EffectItemType[i] == 0)
+ {
+ // skip auto-loot crafting spells, its not need explicit item info (but have special fake items sometime)
+ if (!IsLootCraftingSpell(spellInfo))
+ {
+ if(msg)
+ {
+ if(pl)
+ ChatHandler(pl).PSendSysMessage("Craft spell %u not have create item entry.",spellInfo->Id);
+ else
+ sLog.outErrorDb("Craft spell %u not have create item entry.",spellInfo->Id);
+ }
+ return false;
+ }
+
+ }
+ // also possible IsLootCraftingSpell case but fake item must exist anyway
+ else if (!ObjectMgr::GetItemPrototype(spellInfo->EffectItemType[i]))
{
if (msg)
{
@@ -2814,6 +2831,9 @@ DiminishingGroup GetDiminishingReturnsGroupForSpell(SpellEntry const* spellproto
// Frostbite
if (spellproto->SpellFamilyFlags[1] & 0x80000000)
return DIMINISHING_TRIGGER_ROOT;
+ // Frost Nova, Shatterd Barrier
+ if (spellproto->SpellFamilyFlags[0] & 0x00080040)
+ return DIMINISHING_CONTROL_ROOT;
break;
}
case SPELLFAMILY_ROGUE:
@@ -2998,6 +3018,18 @@ bool IsDiminishingReturnsGroupDurationLimited(DiminishingGroup group)
return false;
}
+DiminishingLevels GetDiminishingReturnsMaxLevel(DiminishingGroup group)
+{
+ switch(group)
+ {
+ case DIMINISHING_TAUNT:
+ return DIMINISHING_LEVEL_TAUNT_IMMUNE;
+ default:
+ return DIMINISHING_LEVEL_IMMUNE;
+ }
+ return DIMINISHING_LEVEL_IMMUNE;
+}
+
DiminishingReturnsType GetDiminishingReturnsGroupType(DiminishingGroup group)
{
switch(group)
@@ -3052,7 +3084,7 @@ bool SpellArea::IsFitToRequirements(Player const* player, uint32 newZone, uint32
if (auraSpell) // not have expected aura
if (!player || auraSpell > 0 && !player->HasAura(auraSpell) || auraSpell < 0 && player->HasAura(-auraSpell))
return false;
-
+
// Extra conditions -- leaving the possibility add extra conditions...
switch(spellId)
{
@@ -3253,7 +3285,7 @@ void SpellMgr::LoadSpellRequired()
uint32 spell_id = fields[0].GetUInt32();
uint32 spell_req = fields[1].GetUInt32();
- // validate table
+ // check if chain is made with valid first spell
SpellEntry const * spell = sSpellStore.LookupEntry(spell_id);
if (!spell)
{
@@ -3314,7 +3346,7 @@ void SpellMgr::LoadSpellRanks()
std::list < std::pair < int32, int32 > > rankChain;
int32 currentSpell = -1;
int32 lastSpell = -1;
-
+
// fill one chain
while(currentSpell == lastSpell && !finished)
{
diff --git a/src/game/SpellMgr.h b/src/game/SpellMgr.h
index 331270bddd6..8fc6c562c22 100644
--- a/src/game/SpellMgr.h
+++ b/src/game/SpellMgr.h
@@ -127,6 +127,7 @@ enum SpellFamilyFlag
SPELLFAMILYFLAG_SHAMAN_MANA_SPRING = 0x00004000,
SPELLFAMILYFLAG2_SHAMAN_LAVA_LASH = 0x00000004,
SPELLFAMILYFLAG_SHAMAN_FLAMETONGUE = 0x00200000,
+ SPELLFAMILYFLAG_SHAMAN_FIRE_NOVA = 0x28000000,
// Deathknight
SPELLFAMILYFLAG_DK_DEATH_STRIKE = 0x00000010,
@@ -503,6 +504,7 @@ inline uint32 GetDispellMask(DispelType dispel)
DiminishingGroup GetDiminishingReturnsGroupForSpell(SpellEntry const* spellproto, bool triggered);
bool IsDiminishingReturnsGroupDurationLimited(DiminishingGroup group);
DiminishingReturnsType GetDiminishingReturnsGroupType(DiminishingGroup group);
+DiminishingLevels GetDiminishingReturnsMaxLevel(DiminishingGroup group);
int32 GetDiminishingReturnsLimitDuration(DiminishingGroup group, SpellEntry const* spellproto);
// Spell proc event related declarations (accessed using SpellMgr functions)
@@ -574,6 +576,8 @@ enum ProcFlagsEx
PROC_EX_ABSORB = 0x0000400,
PROC_EX_REFLECT = 0x0000800,
PROC_EX_INTERRUPT = 0x0001000, // Melee hit result can be Interrupt (not used)
+ PROC_EX_FULL_BLOCK = 0x0002000, // block al attack damage
+ PROC_EX_RESERVED2 = 0x0004000,
PROC_EX_NOT_ACTIVE_SPELL = 0x0008000, // Spell mustn't do damage/heal to proc
PROC_EX_EX_TRIGGER_ALWAYS = 0x0010000, // If set trigger always no matter of hit result
PROC_EX_EX_ONE_TIME_TRIGGER = 0x0020000, // If set trigger always but only one time (not implemented yet)
@@ -1267,6 +1271,22 @@ class SpellMgr
return true;
}
+ const SpellsRequiringSpellMap GetSpellsRequiringSpell()
+ {
+ return this->mSpellsReqSpell;
+ }
+
+ uint32 GetSpellRequired(uint32 spell_id) const
+ {
+ SpellRequiredMap::const_iterator itr = mSpellReq.find(spell_id);
+
+ if(itr == mSpellReq.end())
+ return NULL;
+
+ return itr->second;
+ }
+
+
// Modifiers
public:
static SpellMgr& Instance();
diff --git a/src/game/Totem.cpp b/src/game/Totem.cpp
index 0358cc0c990..6b277136444 100644
--- a/src/game/Totem.cpp
+++ b/src/game/Totem.cpp
@@ -73,6 +73,24 @@ void Totem::InitStats(uint32 duration)
display_id = cinfo->Modelid3;
else
display_id = cinfo->Modelid1;
+
+ switch (((Player*)m_owner)->getRace())
+ {
+ case RACE_ORC:
+ if (cinfo->Modelid2)
+ display_id = cinfo->Modelid2;
+ else
+ display_id = cinfo->Modelid1;
+ break;
+ case RACE_TROLL:
+ if (cinfo->Modelid4)
+ display_id = cinfo->Modelid4;
+ else
+ display_id = cinfo->Modelid1;
+ break;
+ default:
+ break;
+ }
break;
default:
break;
diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp
index 3454928fc88..60eadb288a5 100644
--- a/src/game/Unit.cpp
+++ b/src/game/Unit.cpp
@@ -228,6 +228,10 @@ void Unit::Update(uint32 p_time)
// Spells must be processed with event system BEFORE they go to _UpdateSpells.
// Or else we may have some SPELL_STATE_FINISHED spells stalled in pointers, that is bad.
m_Events.Update(p_time);
+
+ if (!IsInWorld())
+ return;
+
_UpdateSpells(p_time);
// If this is set during update SetCantProc(false) call is missing somewhere in the code
@@ -519,8 +523,9 @@ void Unit::GetRandomContactPoint(const Unit* obj, float &x, float &y, float &z,
void Unit::UpdateInterruptMask()
{
m_interruptMask = 0;
- for (AuraApplicationList::const_iterator i = m_interruptableAuras.begin(); i != m_interruptableAuras.end(); ++i)
- m_interruptMask |= (*i)->GetBase()->GetSpellProto()->AuraInterruptFlags;
+ for(AuraApplicationList::const_iterator i = m_interruptableAuras.begin(); i != m_interruptableAuras.end(); ++i)
+ if (*i && (*i)->GetBase() && (*i)->GetBase()->GetSpellProto())
+ m_interruptMask |= (*i)->GetBase()->GetSpellProto()->AuraInterruptFlags;
if (Spell* spell = m_currentSpells[CURRENT_CHANNELED_SPELL])
if (spell->getState() == SPELL_STATE_CASTING)
@@ -1390,6 +1395,7 @@ void Unit::CalculateMeleeDamage(Unit *pVictim, uint32 damage, CalcDamageInfo *da
{
damageInfo->TargetState = VICTIMSTATE_BLOCKS;
damageInfo->blocked_amount = damageInfo->damage;
+ damageInfo->procEx |= PROC_EX_FULL_BLOCK;
}
else
damageInfo->procEx |= PROC_EX_NORMAL_HIT;
@@ -3156,7 +3162,12 @@ float Unit::GetUnitCriticalChance(WeaponAttackType attackType, const Unit *pVict
// reduce crit chance from Rating for players
if (attackType != RANGED_ATTACK)
+ {
crit -= pVictim->GetMeleeCritChanceReduction();
+ // Glyph of barkskin
+ if (pVictim->HasAura(63057) && pVictim->HasAura(22812))
+ crit-=25.0f;
+ }
else
crit -= pVictim->GetRangedCritChanceReduction();
@@ -5285,19 +5296,6 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, AuraEffect* trigger
}
return false;
}
- // Improved Divine Spirit
- case 33174:
- case 33182:
- {
- int32 spelldmg = CalculateSpellDamage(procSpell, 0, procSpell->EffectBasePoints[0],pVictim);
- if (AuraEffect * Aur = pVictim->GetAuraEffect(procSpell->Id, effIndex+1, triggeredByAura->GetCasterGUID()))
- {
- // Remove aura mods
- Aur->ChangeAmount(Aur->GetAmount() + spelldmg);
- return true;
- }
- return false;
- }
// Eye for an Eye
case 9799:
case 25988:
@@ -5808,23 +5806,6 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, AuraEffect* trigger
triggered_spell_id = 12654;
break;
}
- // Combustion
- case 11129:
- {
- Unit *caster = triggeredByAura->GetCaster();
- if (!caster || !damage)
- return false;
-
- //last charge and crit
- if (triggeredByAura->GetBase()->GetCharges() <= 1 && (procEx & PROC_EX_CRITICAL_HIT) )
- {
- RemoveAurasDueToSpell(28682); //-> remove Combustion auras
- return true; // charge counting (will removed)
- }
-
- CastSpell(this, 28682, true, castItem, triggeredByAura);
- return (procEx & PROC_EX_CRITICAL_HIT);// charge update only at crit hits, no hidden cooldowns
- }
// Glyph of Ice Block
case 56372:
{
@@ -6142,14 +6123,10 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, AuraEffect* trigger
if(!pVictim || !pVictim->isAlive())
return false;
- // pVictim is caster of aura
- if(triggeredByAura->GetCasterGUID() != pVictim->GetGUID())
- return false;
-
// heal amount
int32 team = triggerAmount*damage/500;
int32 self = triggerAmount*damage/100 - team;
- pVictim->CastCustomSpell(pVictim,15290,&team,&self,NULL,true,castItem,triggeredByAura);
+ CastCustomSpell(this,15290,&team,&self,NULL,true,castItem,triggeredByAura);
return true; // no hidden cooldown
}
// Priest Tier 6 Trinket (Ashtongue Talisman of Acumen)
@@ -6242,6 +6219,27 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, AuraEffect* trigger
triggered_spell_id = 28810;
break;
}
+ // Earthen Power (Rank 1, 2)
+ case 51523:
+ case 51524:
+ {
+ // Totem itself must be a caster of this spell
+ Unit* caster = NULL;
+ for (ControlList::iterator itr = m_Controlled.begin(); itr != m_Controlled.end(); ++itr)
+ {
+ if ((*itr)->GetEntry() != 2630)
+ continue;
+
+ caster = (*itr);
+ break;
+ }
+
+ if (!caster)
+ return false;
+
+ caster->CastSpell(caster, 59566, true, castItem, triggeredByAura, originalCaster);
+ return true;
+ }
}
break;
}
@@ -6731,7 +6729,9 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, AuraEffect* trigger
if(effIndex != 0) // effect 1,2 used by seal unleashing code
return false;
- triggered_spell_id = 31803;
+ // At melee attack or Hammer of the Righteous spell damage considered as melee attack
+ if ((procFlag & PROC_FLAG_SUCCESSFUL_MELEE_HIT) || (procSpell && procSpell->Id == 53595) )
+ triggered_spell_id = 31803;
// On target with 5 stacks of Holy Vengeance direct damage is done
if (Aura * aur = pVictim->GetAura(triggered_spell_id, GetGUID()))
{
@@ -6754,7 +6754,9 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, AuraEffect* trigger
if(effIndex != 0) // effect 1,2 used by seal unleashing code
return false;
- triggered_spell_id = 53742;
+ // At melee attack or Hammer of the Righteous spell damage considered as melee attack
+ if ((procFlag & PROC_FLAG_SUCCESSFUL_MELEE_HIT) || (procSpell && procSpell->Id == 53595))
+ triggered_spell_id = 53742;
// On target with 5 stacks of Blood Corruption direct damage is done
if (Aura * aur = pVictim->GetAura(triggered_spell_id, GetGUID()))
{
@@ -6849,16 +6851,6 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, AuraEffect* trigger
{
switch(dummySpell->Id)
{
- // Improved fire nova totem
- case 16086:
- case 16544:
- triggered_spell_id = 51880;
- break;
- // Earthen Power (Rank 1, 2)
- case 51523:
- case 51524:
- triggered_spell_id = 63532;
- break;
// Tidal Force
case 55198:
{
@@ -7150,7 +7142,7 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, AuraEffect* trigger
return false;
// Water Shield
- if (AuraEffect const * aurEff = GetAuraEffect(SPELL_AURA_PROC_TRIGGER_SPELL, SPELLFAMILY_SHAMAN, 0, 0x00000020))
+ if (AuraEffect const * aurEff = GetAuraEffect(SPELL_AURA_PROC_TRIGGER_SPELL, SPELLFAMILY_SHAMAN, 0, 0x00000020, 0))
{
uint32 spell = aurEff->GetSpellProto()->EffectTriggerSpell[aurEff->GetEffIndex()];
CastSpell(this, spell, true, castItem, triggeredByAura);
@@ -7231,6 +7223,11 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, AuraEffect* trigger
if (AuraEffect const * aurEff = GetAuraEffect(SPELL_AURA_PROC_TRIGGER_SPELL, SPELLFAMILY_SHAMAN, 0x400, 0, 0))
{
uint32 spell = spellmgr.GetSpellWithRank(26364, spellmgr.GetSpellRank(aurEff->GetId()));
+
+ // custom cooldown processing case
+ if (GetTypeId() == TYPEID_PLAYER && ((Player*)this)->HasSpellCooldown(spell))
+ ((Player*)this)->RemoveSpellCooldown(spell);
+
CastSpell(target, spell, true, castItem, triggeredByAura);
aurEff->GetBase()->DropCharge();
return true;
@@ -7296,6 +7293,13 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, AuraEffect* trigger
triggered_spell_id = 61607;
break;
}
+ // Unholy Blight
+ if (dummySpell->Id == 49194)
+ {
+ basepoints0 = triggerAmount * damage / 100;
+ triggered_spell_id = 50536;
+ break;
+ }
// Vendetta
if (dummySpell->SpellFamilyFlags[0] & 0x10000)
{
@@ -7632,6 +7636,46 @@ bool Unit::HandleAuraProc(Unit *pVictim, uint32 damage, Aura * triggeredByAura,
switch(dummySpell->SpellFamilyName)
{
+ case SPELLFAMILY_MAGE:
+ {
+ // Combustion
+ switch (dummySpell->Id)
+ {
+ case 11129:
+ {
+ *handled = true;
+ Unit *caster = triggeredByAura->GetCaster();
+ if (!caster || !damage)
+ return false;
+
+ //last charge and crit
+ if (triggeredByAura->GetCharges() <= 1 && (procEx & PROC_EX_CRITICAL_HIT) )
+ {
+ RemoveAurasDueToSpell(28682); //-> remove Combustion auras
+ return true; // charge counting (will removed)
+ }
+
+ this->CastSpell(this, 28682, true);
+ return false; // ordinary chrages will be removed during crit chance computations.
+ }
+ // Empowered Fire
+ case 31656:
+ case 31657:
+ case 31658:
+ {
+ *handled = true;
+
+ SpellEntry const *spInfo = sSpellStore.LookupEntry(67545);
+ if (!spInfo)
+ return false;
+
+ int32 bp0 = this->GetCreateMana() * spInfo->CalculateSimpleValue(0) / 100;
+ this->CastCustomSpell(this, 67545, &bp0, NULL, NULL, true, NULL, triggeredByAura->GetEffect(0), this->GetGUID());
+ return true;
+ }
+ }
+ break;
+ }
case SPELLFAMILY_DEATHKNIGHT:
{
// Blood of the North
@@ -8135,6 +8179,13 @@ bool Unit::HandleProcTriggerSpell(Unit *pVictim, uint32 damage, AuraEffect* trig
trigger_spell_id = 26470;
break;
}
+ // Unyielding Knights (item exploit 29108\29109)
+ case 38164:
+ {
+ if(pVictim->GetEntry() != 19457) // Proc only if you target is Grillok
+ return false;
+ break;
+ }
// Deflection
case 52420:
{
@@ -8284,17 +8335,6 @@ bool Unit::HandleProcTriggerSpell(Unit *pVictim, uint32 damage, AuraEffect* trig
// Need add combopoint AFTER finish movie (or they dropped in finish phase)
break;
}
- case 22959:
- {
- // Glyph of Improved Scorch
- if (AuraEffect * aurEff = GetAuraEffect(56371,0))
- {
- for (int32 count = aurEff->GetAmount(); count>0; count--)
- CastSpell(pVictim, 22959, true);
- return true;
- }
- break;
- }
// Bloodthirst (($m/100)% of max health)
case 23880:
{
@@ -10296,8 +10336,10 @@ bool Unit::isSpellCrit(Unit *pVictim, SpellEntry const *spellProto, SpellSchoolM
switch(spellProto->SpellFamilyName)
{
case SPELLFAMILY_DRUID:
- // Rend and Tear - bonus crit chance for bleeding targets of Ferocious Bite
- if (spellProto->SpellFamilyFlags[0] & 0x00800000 && pVictim->HasAuraState(AURA_STATE_BLEEDING, spellProto, this))
+ // Rend and Tear - bonus crit chance for Ferocious Bite on bleeding targets
+ if (spellProto->SpellFamilyFlags[0] & 0x00800000
+ && spellProto->SpellIconID == 1680
+ && pVictim->HasAuraState(AURA_STATE_BLEEDING))
{
if (AuraEffect const *rendAndTear = GetDummyAuraEffect(SPELLFAMILY_DRUID, 2859, 1))
crit_chance += rendAndTear->GetAmount();
@@ -10891,7 +10933,18 @@ void Unit::MeleeDamageBonus(Unit *pVictim, uint32 *pdamage, WeaponAttackType att
// ..done (base at attack power for marked target and base at attack power for creature type)
int32 APbonus = 0;
- if (attType == RANGED_ATTACK)
+
+ if (attType == RANGED_ATTACK && pVictim->GetTypeId() == TYPEID_UNIT)
+ {
+ APbonus += pVictim->GetTotalAuraModifier(SPELL_AURA_RANGED_AP_ATTACKER_CREATURES_BONUS);
+
+ // ..done (base at attack power and creature type)
+ AuraEffectList const& mCreatureAttackPower = GetAuraEffectsByType(SPELL_AURA_MOD_RANGED_ATTACK_POWER_VERSUS);
+ for (AuraEffectList::const_iterator i = mCreatureAttackPower.begin(); i != mCreatureAttackPower.end(); ++i)
+ if (creatureTypeMask & uint32((*i)->GetMiscValue()))
+ APbonus += (*i)->GetAmount();
+ }
+ else if (attType == RANGED_ATTACK)
{
APbonus += pVictim->GetTotalAuraModifier(SPELL_AURA_RANGED_ATTACK_POWER_ATTACKER_BONUS);
@@ -11390,7 +11443,7 @@ void Unit::ClearInCombat()
if (GetTypeId() != TYPEID_PLAYER)
{
clearUnitState(UNIT_STAT_ATTACK_PLAYER);
- if (HasFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_OTHER_TAGGER))
+ if (HasFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_TAPPED))
SetUInt32Value(UNIT_DYNAMIC_FLAGS, ((Creature*)this)->GetCreatureInfo()->dynamicflags);
}
else
@@ -12416,7 +12469,7 @@ void Unit::IncrDiminishing(DiminishingGroup group)
{
if (i->DRGroup != group)
continue;
- if (i->hitCount < DIMINISHING_LEVEL_IMMUNE)
+ if (i->hitCount < GetDiminishingReturnsMaxLevel(group))
i->hitCount += 1;
return;
}
@@ -12425,7 +12478,7 @@ void Unit::IncrDiminishing(DiminishingGroup group)
void Unit::ApplyDiminishingToDuration(DiminishingGroup group, int32 &duration,Unit* caster,DiminishingLevels Level, int32 limitduration)
{
- if (duration == -1 || group == DIMINISHING_NONE || (caster->IsFriendlyTo(this) && caster != this))
+ if (duration == -1 || group == DIMINISHING_NONE || caster->IsFriendlyTo(this))
return;
// test pet/charm masters instead pets/charmeds
@@ -12438,14 +12491,35 @@ void Unit::ApplyDiminishingToDuration(DiminishingGroup group, int32 &duration,Un
Unit const* target = targetOwner ? targetOwner : this;
Unit const* source = casterOwner ? casterOwner : caster;
- if (target->GetTypeId() == TYPEID_PLAYER && source->GetTypeId() == TYPEID_PLAYER)
+ if ((target->GetTypeId() == TYPEID_PLAYER
+ || ((Creature*)target)->GetCreatureInfo()->flags_extra & CREATURE_FLAG_EXTRA_ALL_DIMINISH)
+ && source->GetTypeId() == TYPEID_PLAYER)
duration = limitduration;
}
float mod = 1.0f;
+ if (group == DIMINISHING_TAUNT)
+ {
+ if(GetTypeId() == TYPEID_UNIT && (((Creature*)this)->GetCreatureInfo()->flags_extra & CREATURE_FLAG_EXTRA_TAUNT_DIMINISH))
+ {
+ DiminishingLevels diminish = Level;
+ switch(diminish)
+ {
+ case DIMINISHING_LEVEL_1: break;
+ case DIMINISHING_LEVEL_2: mod = 0.65f; break;
+ case DIMINISHING_LEVEL_3: mod = 0.4225f; break;
+ case DIMINISHING_LEVEL_4: mod = 0.274625f; break;
+ case DIMINISHING_LEVEL_TAUNT_IMMUNE: mod = 0.0f; break;
+ default: break;
+ }
+ }
+ }
// Some diminishings applies to mobs too (for example, Stun)
- if ((GetDiminishingReturnsGroupType(group) == DRTYPE_PLAYER && (targetOwner ? (targetOwner->GetTypeId() == TYPEID_PLAYER) : (GetTypeId() == TYPEID_PLAYER))) || GetDiminishingReturnsGroupType(group) == DRTYPE_ALL)
+ else if ((GetDiminishingReturnsGroupType(group) == DRTYPE_PLAYER
+ && ((targetOwner ? (targetOwner->GetTypeId() == TYPEID_PLAYER) : (GetTypeId() == TYPEID_PLAYER))
+ || (GetTypeId() == TYPEID_UNIT && ((Creature*)this)->GetCreatureInfo()->flags_extra & CREATURE_FLAG_EXTRA_ALL_DIMINISH)))
+ || GetDiminishingReturnsGroupType(group) == DRTYPE_ALL)
{
DiminishingLevels diminish = Level;
switch(diminish)
@@ -13381,6 +13455,7 @@ bool InitTriggerAuraData()
isNonTriggerAura[SPELL_AURA_MOD_POWER_REGEN]=true;
isNonTriggerAura[SPELL_AURA_REDUCE_PUSHBACK]=true;
+ isTriggerAura[SPELL_AURA_RANGED_AP_ATTACKER_CREATURES_BONUS] = true;
return true;
}
@@ -15444,10 +15519,10 @@ float Unit::GetCombatRatingReduction(CombatRating cr) const
return ((Player const*)this)->GetRatingBonusValue(cr);
else if (((Creature const*)this)->isPet())
{
- // Player's pet have 0.4 resilience from owner
+ // Player's pet get resilience from owner
if (Unit* owner = GetOwner())
if(owner->GetTypeId() == TYPEID_PLAYER)
- return ((Player*)owner)->GetRatingBonusValue(cr) * 0.4f;
+ return ((Player*)owner)->GetRatingBonusValue(cr);
}
return 0.0f;
diff --git a/src/game/Unit.h b/src/game/Unit.h
index 45644700b04..1390d9eb09e 100644
--- a/src/game/Unit.h
+++ b/src/game/Unit.h
@@ -244,8 +244,8 @@ enum UnitPVPStateFlags
// byte (2 from 0..3) of UNIT_FIELD_BYTES_2
enum UnitRename
{
- UNIT_RENAME_NOT_ALLOWED = 0x02,
- UNIT_RENAME_ALLOWED = 0x03
+ UNIT_CAN_BE_RENAMED = 0x01,
+ UNIT_CAN_BE_ABANDONED = 0x02,
};
#define CREATURE_MAX_SPELLS 8
@@ -775,7 +775,9 @@ enum DiminishingLevels
DIMINISHING_LEVEL_1 = 0,
DIMINISHING_LEVEL_2 = 1,
DIMINISHING_LEVEL_3 = 2,
- DIMINISHING_LEVEL_IMMUNE = 3
+ DIMINISHING_LEVEL_IMMUNE = 3,
+ DIMINISHING_LEVEL_4 = 3,
+ DIMINISHING_LEVEL_TAUNT_IMMUNE = 4,
};
struct DiminishingReturn
diff --git a/src/game/UpdateFields.h b/src/game/UpdateFields.h
index 8c2e0310c30..c18ffef8d18 100644
--- a/src/game/UpdateFields.h
+++ b/src/game/UpdateFields.h
@@ -21,414 +21,417 @@
#ifndef _UPDATEFIELDS_AUTO_H
#define _UPDATEFIELDS_AUTO_H
-// Auto generated for version 3, 2, 2, 10505
+// Auto generated for version 3, 3, 0, 11159
+
enum EObjectFields
{
- OBJECT_FIELD_GUID = 0x0000, // Size: 2, Type: LONG, Flags: PUBLIC
- OBJECT_FIELD_TYPE = 0x0002, // Size: 1, Type: INT, Flags: PUBLIC
- OBJECT_FIELD_ENTRY = 0x0003, // Size: 1, Type: INT, Flags: PUBLIC
- OBJECT_FIELD_SCALE_X = 0x0004, // Size: 1, Type: FLOAT, Flags: PUBLIC
- OBJECT_FIELD_PADDING = 0x0005, // Size: 1, Type: INT, Flags: NONE
- OBJECT_END = 0x0006,
+ OBJECT_FIELD_GUID = 0x0000, // Size: 2, Type: LONG, Flags: PUBLIC
+ OBJECT_FIELD_TYPE = 0x0002, // Size: 1, Type: INT, Flags: PUBLIC
+ OBJECT_FIELD_ENTRY = 0x0003, // Size: 1, Type: INT, Flags: PUBLIC
+ OBJECT_FIELD_SCALE_X = 0x0004, // Size: 1, Type: FLOAT, Flags: PUBLIC
+ OBJECT_FIELD_PADDING = 0x0005, // Size: 1, Type: INT, Flags: NONE
+ OBJECT_END = 0x0006,
};
enum EItemFields
{
- ITEM_FIELD_OWNER = OBJECT_END + 0x0000, // Size: 2, Type: LONG, Flags: PUBLIC
- ITEM_FIELD_CONTAINED = OBJECT_END + 0x0002, // Size: 2, Type: LONG, Flags: PUBLIC
- ITEM_FIELD_CREATOR = OBJECT_END + 0x0004, // Size: 2, Type: LONG, Flags: PUBLIC
- ITEM_FIELD_GIFTCREATOR = OBJECT_END + 0x0006, // Size: 2, Type: LONG, Flags: PUBLIC
- ITEM_FIELD_STACK_COUNT = OBJECT_END + 0x0008, // Size: 1, Type: INT, Flags: OWNER, ITEM_OWNER
- ITEM_FIELD_DURATION = OBJECT_END + 0x0009, // Size: 1, Type: INT, Flags: OWNER, ITEM_OWNER
- ITEM_FIELD_SPELL_CHARGES = OBJECT_END + 0x000A, // Size: 5, Type: INT, Flags: OWNER, ITEM_OWNER
- ITEM_FIELD_FLAGS = OBJECT_END + 0x000F, // Size: 1, Type: INT, Flags: PUBLIC
- ITEM_FIELD_ENCHANTMENT_1_1 = OBJECT_END + 0x0010, // Size: 2, Type: INT, Flags: PUBLIC
- ITEM_FIELD_ENCHANTMENT_1_3 = OBJECT_END + 0x0012, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
- ITEM_FIELD_ENCHANTMENT_2_1 = OBJECT_END + 0x0013, // Size: 2, Type: INT, Flags: PUBLIC
- ITEM_FIELD_ENCHANTMENT_2_3 = OBJECT_END + 0x0015, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
- ITEM_FIELD_ENCHANTMENT_3_1 = OBJECT_END + 0x0016, // Size: 2, Type: INT, Flags: PUBLIC
- ITEM_FIELD_ENCHANTMENT_3_3 = OBJECT_END + 0x0018, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
- ITEM_FIELD_ENCHANTMENT_4_1 = OBJECT_END + 0x0019, // Size: 2, Type: INT, Flags: PUBLIC
- ITEM_FIELD_ENCHANTMENT_4_3 = OBJECT_END + 0x001B, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
- ITEM_FIELD_ENCHANTMENT_5_1 = OBJECT_END + 0x001C, // Size: 2, Type: INT, Flags: PUBLIC
- ITEM_FIELD_ENCHANTMENT_5_3 = OBJECT_END + 0x001E, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
- ITEM_FIELD_ENCHANTMENT_6_1 = OBJECT_END + 0x001F, // Size: 2, Type: INT, Flags: PUBLIC
- ITEM_FIELD_ENCHANTMENT_6_3 = OBJECT_END + 0x0021, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
- ITEM_FIELD_ENCHANTMENT_7_1 = OBJECT_END + 0x0022, // Size: 2, Type: INT, Flags: PUBLIC
- ITEM_FIELD_ENCHANTMENT_7_3 = OBJECT_END + 0x0024, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
- ITEM_FIELD_ENCHANTMENT_8_1 = OBJECT_END + 0x0025, // Size: 2, Type: INT, Flags: PUBLIC
- ITEM_FIELD_ENCHANTMENT_8_3 = OBJECT_END + 0x0027, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
- ITEM_FIELD_ENCHANTMENT_9_1 = OBJECT_END + 0x0028, // Size: 2, Type: INT, Flags: PUBLIC
- ITEM_FIELD_ENCHANTMENT_9_3 = OBJECT_END + 0x002A, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
- ITEM_FIELD_ENCHANTMENT_10_1 = OBJECT_END + 0x002B, // Size: 2, Type: INT, Flags: PUBLIC
- ITEM_FIELD_ENCHANTMENT_10_3 = OBJECT_END + 0x002D, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
- ITEM_FIELD_ENCHANTMENT_11_1 = OBJECT_END + 0x002E, // Size: 2, Type: INT, Flags: PUBLIC
- ITEM_FIELD_ENCHANTMENT_11_3 = OBJECT_END + 0x0030, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
- ITEM_FIELD_ENCHANTMENT_12_1 = OBJECT_END + 0x0031, // Size: 2, Type: INT, Flags: PUBLIC
- ITEM_FIELD_ENCHANTMENT_12_3 = OBJECT_END + 0x0033, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
- ITEM_FIELD_PROPERTY_SEED = OBJECT_END + 0x0034, // Size: 1, Type: INT, Flags: PUBLIC
- ITEM_FIELD_RANDOM_PROPERTIES_ID = OBJECT_END + 0x0035, // Size: 1, Type: INT, Flags: PUBLIC
- ITEM_FIELD_ITEM_TEXT_ID = OBJECT_END + 0x0036, // Size: 1, Type: INT, Flags: OWNER
- ITEM_FIELD_DURABILITY = OBJECT_END + 0x0037, // Size: 1, Type: INT, Flags: OWNER, ITEM_OWNER
- ITEM_FIELD_MAXDURABILITY = OBJECT_END + 0x0038, // Size: 1, Type: INT, Flags: OWNER, ITEM_OWNER
- ITEM_FIELD_CREATE_PLAYED_TIME = OBJECT_END + 0x0039, // Size: 1, Type: INT, Flags: PUBLIC
- ITEM_END = OBJECT_END + 0x003A,
+ ITEM_FIELD_OWNER = OBJECT_END + 0x0000, // Size: 2, Type: LONG, Flags: PUBLIC
+ ITEM_FIELD_CONTAINED = OBJECT_END + 0x0002, // Size: 2, Type: LONG, Flags: PUBLIC
+ ITEM_FIELD_CREATOR = OBJECT_END + 0x0004, // Size: 2, Type: LONG, Flags: PUBLIC
+ ITEM_FIELD_GIFTCREATOR = OBJECT_END + 0x0006, // Size: 2, Type: LONG, Flags: PUBLIC
+ ITEM_FIELD_STACK_COUNT = OBJECT_END + 0x0008, // Size: 1, Type: INT, Flags: OWNER, ITEM_OWNER
+ ITEM_FIELD_DURATION = OBJECT_END + 0x0009, // Size: 1, Type: INT, Flags: OWNER, ITEM_OWNER
+ ITEM_FIELD_SPELL_CHARGES = OBJECT_END + 0x000A, // Size: 5, Type: INT, Flags: OWNER, ITEM_OWNER
+ ITEM_FIELD_FLAGS = OBJECT_END + 0x000F, // Size: 1, Type: INT, Flags: PUBLIC
+ ITEM_FIELD_ENCHANTMENT_1_1 = OBJECT_END + 0x0010, // Size: 2, Type: INT, Flags: PUBLIC
+ ITEM_FIELD_ENCHANTMENT_1_3 = OBJECT_END + 0x0012, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
+ ITEM_FIELD_ENCHANTMENT_2_1 = OBJECT_END + 0x0013, // Size: 2, Type: INT, Flags: PUBLIC
+ ITEM_FIELD_ENCHANTMENT_2_3 = OBJECT_END + 0x0015, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
+ ITEM_FIELD_ENCHANTMENT_3_1 = OBJECT_END + 0x0016, // Size: 2, Type: INT, Flags: PUBLIC
+ ITEM_FIELD_ENCHANTMENT_3_3 = OBJECT_END + 0x0018, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
+ ITEM_FIELD_ENCHANTMENT_4_1 = OBJECT_END + 0x0019, // Size: 2, Type: INT, Flags: PUBLIC
+ ITEM_FIELD_ENCHANTMENT_4_3 = OBJECT_END + 0x001B, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
+ ITEM_FIELD_ENCHANTMENT_5_1 = OBJECT_END + 0x001C, // Size: 2, Type: INT, Flags: PUBLIC
+ ITEM_FIELD_ENCHANTMENT_5_3 = OBJECT_END + 0x001E, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
+ ITEM_FIELD_ENCHANTMENT_6_1 = OBJECT_END + 0x001F, // Size: 2, Type: INT, Flags: PUBLIC
+ ITEM_FIELD_ENCHANTMENT_6_3 = OBJECT_END + 0x0021, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
+ ITEM_FIELD_ENCHANTMENT_7_1 = OBJECT_END + 0x0022, // Size: 2, Type: INT, Flags: PUBLIC
+ ITEM_FIELD_ENCHANTMENT_7_3 = OBJECT_END + 0x0024, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
+ ITEM_FIELD_ENCHANTMENT_8_1 = OBJECT_END + 0x0025, // Size: 2, Type: INT, Flags: PUBLIC
+ ITEM_FIELD_ENCHANTMENT_8_3 = OBJECT_END + 0x0027, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
+ ITEM_FIELD_ENCHANTMENT_9_1 = OBJECT_END + 0x0028, // Size: 2, Type: INT, Flags: PUBLIC
+ ITEM_FIELD_ENCHANTMENT_9_3 = OBJECT_END + 0x002A, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
+ ITEM_FIELD_ENCHANTMENT_10_1 = OBJECT_END + 0x002B, // Size: 2, Type: INT, Flags: PUBLIC
+ ITEM_FIELD_ENCHANTMENT_10_3 = OBJECT_END + 0x002D, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
+ ITEM_FIELD_ENCHANTMENT_11_1 = OBJECT_END + 0x002E, // Size: 2, Type: INT, Flags: PUBLIC
+ ITEM_FIELD_ENCHANTMENT_11_3 = OBJECT_END + 0x0030, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
+ ITEM_FIELD_ENCHANTMENT_12_1 = OBJECT_END + 0x0031, // Size: 2, Type: INT, Flags: PUBLIC
+ ITEM_FIELD_ENCHANTMENT_12_3 = OBJECT_END + 0x0033, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
+ ITEM_FIELD_PROPERTY_SEED = OBJECT_END + 0x0034, // Size: 1, Type: INT, Flags: PUBLIC
+ ITEM_FIELD_RANDOM_PROPERTIES_ID = OBJECT_END + 0x0035, // Size: 1, Type: INT, Flags: PUBLIC
+ ITEM_FIELD_ITEM_TEXT_ID = OBJECT_END + 0x0036, // Size: 1, Type: INT, Flags: OWNER
+ ITEM_FIELD_DURABILITY = OBJECT_END + 0x0037, // Size: 1, Type: INT, Flags: OWNER, ITEM_OWNER
+ ITEM_FIELD_MAXDURABILITY = OBJECT_END + 0x0038, // Size: 1, Type: INT, Flags: OWNER, ITEM_OWNER
+ ITEM_FIELD_CREATE_PLAYED_TIME = OBJECT_END + 0x0039, // Size: 1, Type: INT, Flags: PUBLIC
+ ITEM_END = OBJECT_END + 0x003A,
};
enum EContainerFields
{
- CONTAINER_FIELD_NUM_SLOTS = ITEM_END + 0x0000, // Size: 1, Type: INT, Flags: PUBLIC
- CONTAINER_ALIGN_PAD = ITEM_END + 0x0001, // Size: 1, Type: BYTES, Flags: NONE
- CONTAINER_FIELD_SLOT_1 = ITEM_END + 0x0002, // Size: 72, Type: LONG, Flags: PUBLIC
- CONTAINER_END = ITEM_END + 0x004A,
+ CONTAINER_FIELD_NUM_SLOTS = ITEM_END + 0x0000, // Size: 1, Type: INT, Flags: PUBLIC
+ CONTAINER_ALIGN_PAD = ITEM_END + 0x0001, // Size: 1, Type: BYTES, Flags: NONE
+ CONTAINER_FIELD_SLOT_1 = ITEM_END + 0x0002, // Size: 72, Type: LONG, Flags: PUBLIC
+ CONTAINER_END = ITEM_END + 0x004A,
};
enum EUnitFields
{
- UNIT_FIELD_CHARM = OBJECT_END + 0x0000, // Size: 2, Type: LONG, Flags: PUBLIC
- UNIT_FIELD_SUMMON = OBJECT_END + 0x0002, // Size: 2, Type: LONG, Flags: PUBLIC
- UNIT_FIELD_CRITTER = OBJECT_END + 0x0004, // Size: 2, Type: LONG, Flags: PRIVATE
- UNIT_FIELD_CHARMEDBY = OBJECT_END + 0x0006, // Size: 2, Type: LONG, Flags: PUBLIC
- UNIT_FIELD_SUMMONEDBY = OBJECT_END + 0x0008, // Size: 2, Type: LONG, Flags: PUBLIC
- UNIT_FIELD_CREATEDBY = OBJECT_END + 0x000A, // Size: 2, Type: LONG, Flags: PUBLIC
- UNIT_FIELD_TARGET = OBJECT_END + 0x000C, // Size: 2, Type: LONG, Flags: PUBLIC
- UNIT_FIELD_CHANNEL_OBJECT = OBJECT_END + 0x000E, // Size: 2, Type: LONG, Flags: PUBLIC
- UNIT_FIELD_BYTES_0 = OBJECT_END + 0x0010, // Size: 1, Type: BYTES, Flags: PUBLIC
- UNIT_FIELD_HEALTH = OBJECT_END + 0x0011, // Size: 1, Type: INT, Flags: PUBLIC
- UNIT_FIELD_POWER1 = OBJECT_END + 0x0012, // Size: 1, Type: INT, Flags: PUBLIC
- UNIT_FIELD_POWER2 = OBJECT_END + 0x0013, // Size: 1, Type: INT, Flags: PUBLIC
- UNIT_FIELD_POWER3 = OBJECT_END + 0x0014, // Size: 1, Type: INT, Flags: PUBLIC
- UNIT_FIELD_POWER4 = OBJECT_END + 0x0015, // Size: 1, Type: INT, Flags: PUBLIC
- UNIT_FIELD_POWER5 = OBJECT_END + 0x0016, // Size: 1, Type: INT, Flags: PUBLIC
- UNIT_FIELD_POWER6 = OBJECT_END + 0x0017, // Size: 1, Type: INT, Flags: PUBLIC
- UNIT_FIELD_POWER7 = OBJECT_END + 0x0018, // Size: 1, Type: INT, Flags: PUBLIC
- UNIT_FIELD_MAXHEALTH = OBJECT_END + 0x0019, // Size: 1, Type: INT, Flags: PUBLIC
- UNIT_FIELD_MAXPOWER1 = OBJECT_END + 0x001A, // Size: 1, Type: INT, Flags: PUBLIC
- UNIT_FIELD_MAXPOWER2 = OBJECT_END + 0x001B, // Size: 1, Type: INT, Flags: PUBLIC
- UNIT_FIELD_MAXPOWER3 = OBJECT_END + 0x001C, // Size: 1, Type: INT, Flags: PUBLIC
- UNIT_FIELD_MAXPOWER4 = OBJECT_END + 0x001D, // Size: 1, Type: INT, Flags: PUBLIC
- UNIT_FIELD_MAXPOWER5 = OBJECT_END + 0x001E, // Size: 1, Type: INT, Flags: PUBLIC
- UNIT_FIELD_MAXPOWER6 = OBJECT_END + 0x001F, // Size: 1, Type: INT, Flags: PUBLIC
- UNIT_FIELD_MAXPOWER7 = OBJECT_END + 0x0020, // Size: 1, Type: INT, Flags: PUBLIC
- UNIT_FIELD_POWER_REGEN_FLAT_MODIFIER = OBJECT_END + 0x0021, // Size: 7, Type: FLOAT, Flags: PRIVATE, OWNER
+ UNIT_FIELD_CHARM = OBJECT_END + 0x0000, // Size: 2, Type: LONG, Flags: PUBLIC
+ UNIT_FIELD_SUMMON = OBJECT_END + 0x0002, // Size: 2, Type: LONG, Flags: PUBLIC
+ UNIT_FIELD_CRITTER = OBJECT_END + 0x0004, // Size: 2, Type: LONG, Flags: PRIVATE
+ UNIT_FIELD_CHARMEDBY = OBJECT_END + 0x0006, // Size: 2, Type: LONG, Flags: PUBLIC
+ UNIT_FIELD_SUMMONEDBY = OBJECT_END + 0x0008, // Size: 2, Type: LONG, Flags: PUBLIC
+ UNIT_FIELD_CREATEDBY = OBJECT_END + 0x000A, // Size: 2, Type: LONG, Flags: PUBLIC
+ UNIT_FIELD_TARGET = OBJECT_END + 0x000C, // Size: 2, Type: LONG, Flags: PUBLIC
+ UNIT_FIELD_CHANNEL_OBJECT = OBJECT_END + 0x000E, // Size: 2, Type: LONG, Flags: PUBLIC
+ UNIT_FIELD_BYTES_0 = OBJECT_END + 0x0010, // Size: 1, Type: BYTES, Flags: PUBLIC
+ UNIT_FIELD_HEALTH = OBJECT_END + 0x0011, // Size: 1, Type: INT, Flags: PUBLIC
+ UNIT_FIELD_POWER1 = OBJECT_END + 0x0012, // Size: 1, Type: INT, Flags: PUBLIC
+ UNIT_FIELD_POWER2 = OBJECT_END + 0x0013, // Size: 1, Type: INT, Flags: PUBLIC
+ UNIT_FIELD_POWER3 = OBJECT_END + 0x0014, // Size: 1, Type: INT, Flags: PUBLIC
+ UNIT_FIELD_POWER4 = OBJECT_END + 0x0015, // Size: 1, Type: INT, Flags: PUBLIC
+ UNIT_FIELD_POWER5 = OBJECT_END + 0x0016, // Size: 1, Type: INT, Flags: PUBLIC
+ UNIT_FIELD_POWER6 = OBJECT_END + 0x0017, // Size: 1, Type: INT, Flags: PUBLIC
+ UNIT_FIELD_POWER7 = OBJECT_END + 0x0018, // Size: 1, Type: INT, Flags: PUBLIC
+ UNIT_FIELD_MAXHEALTH = OBJECT_END + 0x0019, // Size: 1, Type: INT, Flags: PUBLIC
+ UNIT_FIELD_MAXPOWER1 = OBJECT_END + 0x001A, // Size: 1, Type: INT, Flags: PUBLIC
+ UNIT_FIELD_MAXPOWER2 = OBJECT_END + 0x001B, // Size: 1, Type: INT, Flags: PUBLIC
+ UNIT_FIELD_MAXPOWER3 = OBJECT_END + 0x001C, // Size: 1, Type: INT, Flags: PUBLIC
+ UNIT_FIELD_MAXPOWER4 = OBJECT_END + 0x001D, // Size: 1, Type: INT, Flags: PUBLIC
+ UNIT_FIELD_MAXPOWER5 = OBJECT_END + 0x001E, // Size: 1, Type: INT, Flags: PUBLIC
+ UNIT_FIELD_MAXPOWER6 = OBJECT_END + 0x001F, // Size: 1, Type: INT, Flags: PUBLIC
+ UNIT_FIELD_MAXPOWER7 = OBJECT_END + 0x0020, // Size: 1, Type: INT, Flags: PUBLIC
+ UNIT_FIELD_POWER_REGEN_FLAT_MODIFIER = OBJECT_END + 0x0021, // Size: 7, Type: FLOAT, Flags: PRIVATE, OWNER
UNIT_FIELD_POWER_REGEN_INTERRUPTED_FLAT_MODIFIER = OBJECT_END + 0x0028, // Size: 7, Type: FLOAT, Flags: PRIVATE, OWNER
- UNIT_FIELD_LEVEL = OBJECT_END + 0x002F, // Size: 1, Type: INT, Flags: PUBLIC
- UNIT_FIELD_FACTIONTEMPLATE = OBJECT_END + 0x0030, // Size: 1, Type: INT, Flags: PUBLIC
- UNIT_VIRTUAL_ITEM_SLOT_ID = OBJECT_END + 0x0031, // Size: 3, Type: INT, Flags: PUBLIC
- UNIT_FIELD_FLAGS = OBJECT_END + 0x0034, // Size: 1, Type: INT, Flags: PUBLIC
- UNIT_FIELD_FLAGS_2 = OBJECT_END + 0x0035, // Size: 1, Type: INT, Flags: PUBLIC
- UNIT_FIELD_AURASTATE = OBJECT_END + 0x0036, // Size: 1, Type: INT, Flags: PUBLIC
- UNIT_FIELD_BASEATTACKTIME = OBJECT_END + 0x0037, // Size: 2, Type: INT, Flags: PUBLIC
- UNIT_FIELD_RANGEDATTACKTIME = OBJECT_END + 0x0039, // Size: 1, Type: INT, Flags: PRIVATE
- UNIT_FIELD_BOUNDINGRADIUS = OBJECT_END + 0x003A, // Size: 1, Type: FLOAT, Flags: PUBLIC
- UNIT_FIELD_COMBATREACH = OBJECT_END + 0x003B, // Size: 1, Type: FLOAT, Flags: PUBLIC
- UNIT_FIELD_DISPLAYID = OBJECT_END + 0x003C, // Size: 1, Type: INT, Flags: PUBLIC
- UNIT_FIELD_NATIVEDISPLAYID = OBJECT_END + 0x003D, // Size: 1, Type: INT, Flags: PUBLIC
- UNIT_FIELD_MOUNTDISPLAYID = OBJECT_END + 0x003E, // Size: 1, Type: INT, Flags: PUBLIC
- UNIT_FIELD_MINDAMAGE = OBJECT_END + 0x003F, // Size: 1, Type: FLOAT, Flags: PRIVATE, OWNER, PARTY_LEADER
- UNIT_FIELD_MAXDAMAGE = OBJECT_END + 0x0040, // Size: 1, Type: FLOAT, Flags: PRIVATE, OWNER, PARTY_LEADER
- UNIT_FIELD_MINOFFHANDDAMAGE = OBJECT_END + 0x0041, // Size: 1, Type: FLOAT, Flags: PRIVATE, OWNER, PARTY_LEADER
- UNIT_FIELD_MAXOFFHANDDAMAGE = OBJECT_END + 0x0042, // Size: 1, Type: FLOAT, Flags: PRIVATE, OWNER, PARTY_LEADER
- UNIT_FIELD_BYTES_1 = OBJECT_END + 0x0043, // Size: 1, Type: BYTES, Flags: PUBLIC
- UNIT_FIELD_PETNUMBER = OBJECT_END + 0x0044, // Size: 1, Type: INT, Flags: PUBLIC
- UNIT_FIELD_PET_NAME_TIMESTAMP = OBJECT_END + 0x0045, // Size: 1, Type: INT, Flags: PUBLIC
- UNIT_FIELD_PETEXPERIENCE = OBJECT_END + 0x0046, // Size: 1, Type: INT, Flags: OWNER
- UNIT_FIELD_PETNEXTLEVELEXP = OBJECT_END + 0x0047, // Size: 1, Type: INT, Flags: OWNER
- UNIT_DYNAMIC_FLAGS = OBJECT_END + 0x0048, // Size: 1, Type: INT, Flags: DYNAMIC
- UNIT_CHANNEL_SPELL = OBJECT_END + 0x0049, // Size: 1, Type: INT, Flags: PUBLIC
- UNIT_MOD_CAST_SPEED = OBJECT_END + 0x004A, // Size: 1, Type: FLOAT, Flags: PUBLIC
- UNIT_CREATED_BY_SPELL = OBJECT_END + 0x004B, // Size: 1, Type: INT, Flags: PUBLIC
- UNIT_NPC_FLAGS = OBJECT_END + 0x004C, // Size: 1, Type: INT, Flags: DYNAMIC
- UNIT_NPC_EMOTESTATE = OBJECT_END + 0x004D, // Size: 1, Type: INT, Flags: PUBLIC
- UNIT_FIELD_STAT0 = OBJECT_END + 0x004E, // Size: 1, Type: INT, Flags: PRIVATE, OWNER
- UNIT_FIELD_STAT1 = OBJECT_END + 0x004F, // Size: 1, Type: INT, Flags: PRIVATE, OWNER
- UNIT_FIELD_STAT2 = OBJECT_END + 0x0050, // Size: 1, Type: INT, Flags: PRIVATE, OWNER
- UNIT_FIELD_STAT3 = OBJECT_END + 0x0051, // Size: 1, Type: INT, Flags: PRIVATE, OWNER
- UNIT_FIELD_STAT4 = OBJECT_END + 0x0052, // Size: 1, Type: INT, Flags: PRIVATE, OWNER
- UNIT_FIELD_POSSTAT0 = OBJECT_END + 0x0053, // Size: 1, Type: INT, Flags: PRIVATE, OWNER
- UNIT_FIELD_POSSTAT1 = OBJECT_END + 0x0054, // Size: 1, Type: INT, Flags: PRIVATE, OWNER
- UNIT_FIELD_POSSTAT2 = OBJECT_END + 0x0055, // Size: 1, Type: INT, Flags: PRIVATE, OWNER
- UNIT_FIELD_POSSTAT3 = OBJECT_END + 0x0056, // Size: 1, Type: INT, Flags: PRIVATE, OWNER
- UNIT_FIELD_POSSTAT4 = OBJECT_END + 0x0057, // Size: 1, Type: INT, Flags: PRIVATE, OWNER
- UNIT_FIELD_NEGSTAT0 = OBJECT_END + 0x0058, // Size: 1, Type: INT, Flags: PRIVATE, OWNER
- UNIT_FIELD_NEGSTAT1 = OBJECT_END + 0x0059, // Size: 1, Type: INT, Flags: PRIVATE, OWNER
- UNIT_FIELD_NEGSTAT2 = OBJECT_END + 0x005A, // Size: 1, Type: INT, Flags: PRIVATE, OWNER
- UNIT_FIELD_NEGSTAT3 = OBJECT_END + 0x005B, // Size: 1, Type: INT, Flags: PRIVATE, OWNER
- UNIT_FIELD_NEGSTAT4 = OBJECT_END + 0x005C, // Size: 1, Type: INT, Flags: PRIVATE, OWNER
- UNIT_FIELD_RESISTANCES = OBJECT_END + 0x005D, // Size: 7, Type: INT, Flags: PRIVATE, OWNER, PARTY_LEADER
- UNIT_FIELD_RESISTANCEBUFFMODSPOSITIVE = OBJECT_END + 0x0064, // Size: 7, Type: INT, Flags: PRIVATE, OWNER
- UNIT_FIELD_RESISTANCEBUFFMODSNEGATIVE = OBJECT_END + 0x006B, // Size: 7, Type: INT, Flags: PRIVATE, OWNER
- UNIT_FIELD_BASE_MANA = OBJECT_END + 0x0072, // Size: 1, Type: INT, Flags: PUBLIC
- UNIT_FIELD_BASE_HEALTH = OBJECT_END + 0x0073, // Size: 1, Type: INT, Flags: PRIVATE, OWNER
- UNIT_FIELD_BYTES_2 = OBJECT_END + 0x0074, // Size: 1, Type: BYTES, Flags: PUBLIC
- UNIT_FIELD_ATTACK_POWER = OBJECT_END + 0x0075, // Size: 1, Type: INT, Flags: PRIVATE, OWNER
- UNIT_FIELD_ATTACK_POWER_MODS = OBJECT_END + 0x0076, // Size: 1, Type: TWO_SHORT, Flags: PRIVATE, OWNER
- UNIT_FIELD_ATTACK_POWER_MULTIPLIER = OBJECT_END + 0x0077, // Size: 1, Type: FLOAT, Flags: PRIVATE, OWNER
- UNIT_FIELD_RANGED_ATTACK_POWER = OBJECT_END + 0x0078, // Size: 1, Type: INT, Flags: PRIVATE, OWNER
- UNIT_FIELD_RANGED_ATTACK_POWER_MODS = OBJECT_END + 0x0079, // Size: 1, Type: TWO_SHORT, Flags: PRIVATE, OWNER
+ UNIT_FIELD_LEVEL = OBJECT_END + 0x002F, // Size: 1, Type: INT, Flags: PUBLIC
+ UNIT_FIELD_FACTIONTEMPLATE = OBJECT_END + 0x0030, // Size: 1, Type: INT, Flags: PUBLIC
+ UNIT_VIRTUAL_ITEM_SLOT_ID = OBJECT_END + 0x0031, // Size: 3, Type: INT, Flags: PUBLIC
+ UNIT_FIELD_FLAGS = OBJECT_END + 0x0034, // Size: 1, Type: INT, Flags: PUBLIC
+ UNIT_FIELD_FLAGS_2 = OBJECT_END + 0x0035, // Size: 1, Type: INT, Flags: PUBLIC
+ UNIT_FIELD_AURASTATE = OBJECT_END + 0x0036, // Size: 1, Type: INT, Flags: PUBLIC
+ UNIT_FIELD_BASEATTACKTIME = OBJECT_END + 0x0037, // Size: 2, Type: INT, Flags: PUBLIC
+ UNIT_FIELD_RANGEDATTACKTIME = OBJECT_END + 0x0039, // Size: 1, Type: INT, Flags: PRIVATE
+ UNIT_FIELD_BOUNDINGRADIUS = OBJECT_END + 0x003A, // Size: 1, Type: FLOAT, Flags: PUBLIC
+ UNIT_FIELD_COMBATREACH = OBJECT_END + 0x003B, // Size: 1, Type: FLOAT, Flags: PUBLIC
+ UNIT_FIELD_DISPLAYID = OBJECT_END + 0x003C, // Size: 1, Type: INT, Flags: PUBLIC
+ UNIT_FIELD_NATIVEDISPLAYID = OBJECT_END + 0x003D, // Size: 1, Type: INT, Flags: PUBLIC
+ UNIT_FIELD_MOUNTDISPLAYID = OBJECT_END + 0x003E, // Size: 1, Type: INT, Flags: PUBLIC
+ UNIT_FIELD_MINDAMAGE = OBJECT_END + 0x003F, // Size: 1, Type: FLOAT, Flags: PRIVATE, OWNER, PARTY_LEADER
+ UNIT_FIELD_MAXDAMAGE = OBJECT_END + 0x0040, // Size: 1, Type: FLOAT, Flags: PRIVATE, OWNER, PARTY_LEADER
+ UNIT_FIELD_MINOFFHANDDAMAGE = OBJECT_END + 0x0041, // Size: 1, Type: FLOAT, Flags: PRIVATE, OWNER, PARTY_LEADER
+ UNIT_FIELD_MAXOFFHANDDAMAGE = OBJECT_END + 0x0042, // Size: 1, Type: FLOAT, Flags: PRIVATE, OWNER, PARTY_LEADER
+ UNIT_FIELD_BYTES_1 = OBJECT_END + 0x0043, // Size: 1, Type: BYTES, Flags: PUBLIC
+ UNIT_FIELD_PETNUMBER = OBJECT_END + 0x0044, // Size: 1, Type: INT, Flags: PUBLIC
+ UNIT_FIELD_PET_NAME_TIMESTAMP = OBJECT_END + 0x0045, // Size: 1, Type: INT, Flags: PUBLIC
+ UNIT_FIELD_PETEXPERIENCE = OBJECT_END + 0x0046, // Size: 1, Type: INT, Flags: OWNER
+ UNIT_FIELD_PETNEXTLEVELEXP = OBJECT_END + 0x0047, // Size: 1, Type: INT, Flags: OWNER
+ UNIT_DYNAMIC_FLAGS = OBJECT_END + 0x0048, // Size: 1, Type: INT, Flags: DYNAMIC
+ UNIT_CHANNEL_SPELL = OBJECT_END + 0x0049, // Size: 1, Type: INT, Flags: PUBLIC
+ UNIT_MOD_CAST_SPEED = OBJECT_END + 0x004A, // Size: 1, Type: FLOAT, Flags: PUBLIC
+ UNIT_CREATED_BY_SPELL = OBJECT_END + 0x004B, // Size: 1, Type: INT, Flags: PUBLIC
+ UNIT_NPC_FLAGS = OBJECT_END + 0x004C, // Size: 1, Type: INT, Flags: DYNAMIC
+ UNIT_NPC_EMOTESTATE = OBJECT_END + 0x004D, // Size: 1, Type: INT, Flags: PUBLIC
+ UNIT_FIELD_STAT0 = OBJECT_END + 0x004E, // Size: 1, Type: INT, Flags: PRIVATE, OWNER
+ UNIT_FIELD_STAT1 = OBJECT_END + 0x004F, // Size: 1, Type: INT, Flags: PRIVATE, OWNER
+ UNIT_FIELD_STAT2 = OBJECT_END + 0x0050, // Size: 1, Type: INT, Flags: PRIVATE, OWNER
+ UNIT_FIELD_STAT3 = OBJECT_END + 0x0051, // Size: 1, Type: INT, Flags: PRIVATE, OWNER
+ UNIT_FIELD_STAT4 = OBJECT_END + 0x0052, // Size: 1, Type: INT, Flags: PRIVATE, OWNER
+ UNIT_FIELD_POSSTAT0 = OBJECT_END + 0x0053, // Size: 1, Type: INT, Flags: PRIVATE, OWNER
+ UNIT_FIELD_POSSTAT1 = OBJECT_END + 0x0054, // Size: 1, Type: INT, Flags: PRIVATE, OWNER
+ UNIT_FIELD_POSSTAT2 = OBJECT_END + 0x0055, // Size: 1, Type: INT, Flags: PRIVATE, OWNER
+ UNIT_FIELD_POSSTAT3 = OBJECT_END + 0x0056, // Size: 1, Type: INT, Flags: PRIVATE, OWNER
+ UNIT_FIELD_POSSTAT4 = OBJECT_END + 0x0057, // Size: 1, Type: INT, Flags: PRIVATE, OWNER
+ UNIT_FIELD_NEGSTAT0 = OBJECT_END + 0x0058, // Size: 1, Type: INT, Flags: PRIVATE, OWNER
+ UNIT_FIELD_NEGSTAT1 = OBJECT_END + 0x0059, // Size: 1, Type: INT, Flags: PRIVATE, OWNER
+ UNIT_FIELD_NEGSTAT2 = OBJECT_END + 0x005A, // Size: 1, Type: INT, Flags: PRIVATE, OWNER
+ UNIT_FIELD_NEGSTAT3 = OBJECT_END + 0x005B, // Size: 1, Type: INT, Flags: PRIVATE, OWNER
+ UNIT_FIELD_NEGSTAT4 = OBJECT_END + 0x005C, // Size: 1, Type: INT, Flags: PRIVATE, OWNER
+ UNIT_FIELD_RESISTANCES = OBJECT_END + 0x005D, // Size: 7, Type: INT, Flags: PRIVATE, OWNER, PARTY_LEADER
+ UNIT_FIELD_RESISTANCEBUFFMODSPOSITIVE = OBJECT_END + 0x0064, // Size: 7, Type: INT, Flags: PRIVATE, OWNER
+ UNIT_FIELD_RESISTANCEBUFFMODSNEGATIVE = OBJECT_END + 0x006B, // Size: 7, Type: INT, Flags: PRIVATE, OWNER
+ UNIT_FIELD_BASE_MANA = OBJECT_END + 0x0072, // Size: 1, Type: INT, Flags: PUBLIC
+ UNIT_FIELD_BASE_HEALTH = OBJECT_END + 0x0073, // Size: 1, Type: INT, Flags: PRIVATE, OWNER
+ UNIT_FIELD_BYTES_2 = OBJECT_END + 0x0074, // Size: 1, Type: BYTES, Flags: PUBLIC
+ UNIT_FIELD_ATTACK_POWER = OBJECT_END + 0x0075, // Size: 1, Type: INT, Flags: PRIVATE, OWNER
+ UNIT_FIELD_ATTACK_POWER_MODS = OBJECT_END + 0x0076, // Size: 1, Type: TWO_SHORT, Flags: PRIVATE, OWNER
+ UNIT_FIELD_ATTACK_POWER_MULTIPLIER = OBJECT_END + 0x0077, // Size: 1, Type: FLOAT, Flags: PRIVATE, OWNER
+ UNIT_FIELD_RANGED_ATTACK_POWER = OBJECT_END + 0x0078, // Size: 1, Type: INT, Flags: PRIVATE, OWNER
+ UNIT_FIELD_RANGED_ATTACK_POWER_MODS = OBJECT_END + 0x0079, // Size: 1, Type: TWO_SHORT, Flags: PRIVATE, OWNER
UNIT_FIELD_RANGED_ATTACK_POWER_MULTIPLIER = OBJECT_END + 0x007A, // Size: 1, Type: FLOAT, Flags: PRIVATE, OWNER
- UNIT_FIELD_MINRANGEDDAMAGE = OBJECT_END + 0x007B, // Size: 1, Type: FLOAT, Flags: PRIVATE, OWNER
- UNIT_FIELD_MAXRANGEDDAMAGE = OBJECT_END + 0x007C, // Size: 1, Type: FLOAT, Flags: PRIVATE, OWNER
- UNIT_FIELD_POWER_COST_MODIFIER = OBJECT_END + 0x007D, // Size: 7, Type: INT, Flags: PRIVATE, OWNER
- UNIT_FIELD_POWER_COST_MULTIPLIER = OBJECT_END + 0x0084, // Size: 7, Type: FLOAT, Flags: PRIVATE, OWNER
- UNIT_FIELD_MAXHEALTHMODIFIER = OBJECT_END + 0x008B, // Size: 1, Type: FLOAT, Flags: PRIVATE, OWNER
- UNIT_FIELD_HOVERHEIGHT = OBJECT_END + 0x008C, // Size: 1, Type: FLOAT, Flags: PUBLIC
- UNIT_FIELD_PADDING = OBJECT_END + 0x008D, // Size: 1, Type: INT, Flags: NONE
- UNIT_END = OBJECT_END + 0x008E,
+ UNIT_FIELD_MINRANGEDDAMAGE = OBJECT_END + 0x007B, // Size: 1, Type: FLOAT, Flags: PRIVATE, OWNER
+ UNIT_FIELD_MAXRANGEDDAMAGE = OBJECT_END + 0x007C, // Size: 1, Type: FLOAT, Flags: PRIVATE, OWNER
+ UNIT_FIELD_POWER_COST_MODIFIER = OBJECT_END + 0x007D, // Size: 7, Type: INT, Flags: PRIVATE, OWNER
+ UNIT_FIELD_POWER_COST_MULTIPLIER = OBJECT_END + 0x0084, // Size: 7, Type: FLOAT, Flags: PRIVATE, OWNER
+ UNIT_FIELD_MAXHEALTHMODIFIER = OBJECT_END + 0x008B, // Size: 1, Type: FLOAT, Flags: PRIVATE, OWNER
+ UNIT_FIELD_HOVERHEIGHT = OBJECT_END + 0x008C, // Size: 1, Type: FLOAT, Flags: PUBLIC
+ UNIT_FIELD_PADDING = OBJECT_END + 0x008D, // Size: 1, Type: INT, Flags: NONE
+ UNIT_END = OBJECT_END + 0x008E,
- PLAYER_DUEL_ARBITER = UNIT_END + 0x0000, // Size: 2, Type: LONG, Flags: PUBLIC
- PLAYER_FLAGS = UNIT_END + 0x0002, // Size: 1, Type: INT, Flags: PUBLIC
- PLAYER_GUILDID = UNIT_END + 0x0003, // Size: 1, Type: INT, Flags: PUBLIC
- PLAYER_GUILDRANK = UNIT_END + 0x0004, // Size: 1, Type: INT, Flags: PUBLIC
- PLAYER_BYTES = UNIT_END + 0x0005, // Size: 1, Type: BYTES, Flags: PUBLIC
- PLAYER_BYTES_2 = UNIT_END + 0x0006, // Size: 1, Type: BYTES, Flags: PUBLIC
- PLAYER_BYTES_3 = UNIT_END + 0x0007, // Size: 1, Type: BYTES, Flags: PUBLIC
- PLAYER_DUEL_TEAM = UNIT_END + 0x0008, // Size: 1, Type: INT, Flags: PUBLIC
- PLAYER_GUILD_TIMESTAMP = UNIT_END + 0x0009, // Size: 1, Type: INT, Flags: PUBLIC
- PLAYER_QUEST_LOG_1_1 = UNIT_END + 0x000A, // Size: 1, Type: INT, Flags: PARTY_MEMBER
- PLAYER_QUEST_LOG_1_2 = UNIT_END + 0x000B, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_QUEST_LOG_1_3 = UNIT_END + 0x000C, // Size: 1, Type: BYTES, Flags: PRIVATE
- PLAYER_QUEST_LOG_1_4 = UNIT_END + 0x000D, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_QUEST_LOG_2_1 = UNIT_END + 0x000E, // Size: 1, Type: INT, Flags: PARTY_MEMBER
- PLAYER_QUEST_LOG_2_2 = UNIT_END + 0x000F, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_QUEST_LOG_2_3 = UNIT_END + 0x0010, // Size: 1, Type: BYTES, Flags: PRIVATE
- PLAYER_QUEST_LOG_2_4 = UNIT_END + 0x0011, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_QUEST_LOG_3_1 = UNIT_END + 0x0012, // Size: 1, Type: INT, Flags: PARTY_MEMBER
- PLAYER_QUEST_LOG_3_2 = UNIT_END + 0x0013, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_QUEST_LOG_3_3 = UNIT_END + 0x0014, // Size: 1, Type: BYTES, Flags: PRIVATE
- PLAYER_QUEST_LOG_3_4 = UNIT_END + 0x0015, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_QUEST_LOG_4_1 = UNIT_END + 0x0016, // Size: 1, Type: INT, Flags: PARTY_MEMBER
- PLAYER_QUEST_LOG_4_2 = UNIT_END + 0x0017, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_QUEST_LOG_4_3 = UNIT_END + 0x0018, // Size: 1, Type: BYTES, Flags: PRIVATE
- PLAYER_QUEST_LOG_4_4 = UNIT_END + 0x0019, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_QUEST_LOG_5_1 = UNIT_END + 0x001A, // Size: 1, Type: INT, Flags: PARTY_MEMBER
- PLAYER_QUEST_LOG_5_2 = UNIT_END + 0x001B, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_QUEST_LOG_5_3 = UNIT_END + 0x001C, // Size: 1, Type: BYTES, Flags: PRIVATE
- PLAYER_QUEST_LOG_5_4 = UNIT_END + 0x001D, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_QUEST_LOG_6_1 = UNIT_END + 0x001E, // Size: 1, Type: INT, Flags: PARTY_MEMBER
- PLAYER_QUEST_LOG_6_2 = UNIT_END + 0x001F, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_QUEST_LOG_6_3 = UNIT_END + 0x0020, // Size: 1, Type: BYTES, Flags: PRIVATE
- PLAYER_QUEST_LOG_6_4 = UNIT_END + 0x0021, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_QUEST_LOG_7_1 = UNIT_END + 0x0022, // Size: 1, Type: INT, Flags: PARTY_MEMBER
- PLAYER_QUEST_LOG_7_2 = UNIT_END + 0x0023, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_QUEST_LOG_7_3 = UNIT_END + 0x0024, // Size: 1, Type: BYTES, Flags: PRIVATE
- PLAYER_QUEST_LOG_7_4 = UNIT_END + 0x0025, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_QUEST_LOG_8_1 = UNIT_END + 0x0026, // Size: 1, Type: INT, Flags: PARTY_MEMBER
- PLAYER_QUEST_LOG_8_2 = UNIT_END + 0x0027, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_QUEST_LOG_8_3 = UNIT_END + 0x0028, // Size: 1, Type: BYTES, Flags: PRIVATE
- PLAYER_QUEST_LOG_8_4 = UNIT_END + 0x0029, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_QUEST_LOG_9_1 = UNIT_END + 0x002A, // Size: 1, Type: INT, Flags: PARTY_MEMBER
- PLAYER_QUEST_LOG_9_2 = UNIT_END + 0x002B, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_QUEST_LOG_9_3 = UNIT_END + 0x002C, // Size: 1, Type: BYTES, Flags: PRIVATE
- PLAYER_QUEST_LOG_9_4 = UNIT_END + 0x002D, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_QUEST_LOG_10_1 = UNIT_END + 0x002E, // Size: 1, Type: INT, Flags: PARTY_MEMBER
- PLAYER_QUEST_LOG_10_2 = UNIT_END + 0x002F, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_QUEST_LOG_10_3 = UNIT_END + 0x0030, // Size: 1, Type: BYTES, Flags: PRIVATE
- PLAYER_QUEST_LOG_10_4 = UNIT_END + 0x0031, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_QUEST_LOG_11_1 = UNIT_END + 0x0032, // Size: 1, Type: INT, Flags: PARTY_MEMBER
- PLAYER_QUEST_LOG_11_2 = UNIT_END + 0x0033, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_QUEST_LOG_11_3 = UNIT_END + 0x0034, // Size: 1, Type: BYTES, Flags: PRIVATE
- PLAYER_QUEST_LOG_11_4 = UNIT_END + 0x0035, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_QUEST_LOG_12_1 = UNIT_END + 0x0036, // Size: 1, Type: INT, Flags: PARTY_MEMBER
- PLAYER_QUEST_LOG_12_2 = UNIT_END + 0x0037, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_QUEST_LOG_12_3 = UNIT_END + 0x0038, // Size: 1, Type: BYTES, Flags: PRIVATE
- PLAYER_QUEST_LOG_12_4 = UNIT_END + 0x0039, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_QUEST_LOG_13_1 = UNIT_END + 0x003A, // Size: 1, Type: INT, Flags: PARTY_MEMBER
- PLAYER_QUEST_LOG_13_2 = UNIT_END + 0x003B, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_QUEST_LOG_13_3 = UNIT_END + 0x003C, // Size: 1, Type: BYTES, Flags: PRIVATE
- PLAYER_QUEST_LOG_13_4 = UNIT_END + 0x003D, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_QUEST_LOG_14_1 = UNIT_END + 0x003E, // Size: 1, Type: INT, Flags: PARTY_MEMBER
- PLAYER_QUEST_LOG_14_2 = UNIT_END + 0x003F, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_QUEST_LOG_14_3 = UNIT_END + 0x0040, // Size: 1, Type: BYTES, Flags: PRIVATE
- PLAYER_QUEST_LOG_14_4 = UNIT_END + 0x0041, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_QUEST_LOG_15_1 = UNIT_END + 0x0042, // Size: 1, Type: INT, Flags: PARTY_MEMBER
- PLAYER_QUEST_LOG_15_2 = UNIT_END + 0x0043, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_QUEST_LOG_15_3 = UNIT_END + 0x0044, // Size: 1, Type: BYTES, Flags: PRIVATE
- PLAYER_QUEST_LOG_15_4 = UNIT_END + 0x0045, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_QUEST_LOG_16_1 = UNIT_END + 0x0046, // Size: 1, Type: INT, Flags: PARTY_MEMBER
- PLAYER_QUEST_LOG_16_2 = UNIT_END + 0x0047, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_QUEST_LOG_16_3 = UNIT_END + 0x0048, // Size: 1, Type: BYTES, Flags: PRIVATE
- PLAYER_QUEST_LOG_16_4 = UNIT_END + 0x0049, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_QUEST_LOG_17_1 = UNIT_END + 0x004A, // Size: 1, Type: INT, Flags: PARTY_MEMBER
- PLAYER_QUEST_LOG_17_2 = UNIT_END + 0x004B, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_QUEST_LOG_17_3 = UNIT_END + 0x004C, // Size: 1, Type: BYTES, Flags: PRIVATE
- PLAYER_QUEST_LOG_17_4 = UNIT_END + 0x004D, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_QUEST_LOG_18_1 = UNIT_END + 0x004E, // Size: 1, Type: INT, Flags: PARTY_MEMBER
- PLAYER_QUEST_LOG_18_2 = UNIT_END + 0x004F, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_QUEST_LOG_18_3 = UNIT_END + 0x0050, // Size: 1, Type: BYTES, Flags: PRIVATE
- PLAYER_QUEST_LOG_18_4 = UNIT_END + 0x0051, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_QUEST_LOG_19_1 = UNIT_END + 0x0052, // Size: 1, Type: INT, Flags: PARTY_MEMBER
- PLAYER_QUEST_LOG_19_2 = UNIT_END + 0x0053, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_QUEST_LOG_19_3 = UNIT_END + 0x0054, // Size: 1, Type: BYTES, Flags: PRIVATE
- PLAYER_QUEST_LOG_19_4 = UNIT_END + 0x0055, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_QUEST_LOG_20_1 = UNIT_END + 0x0056, // Size: 1, Type: INT, Flags: PARTY_MEMBER
- PLAYER_QUEST_LOG_20_2 = UNIT_END + 0x0057, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_QUEST_LOG_20_3 = UNIT_END + 0x0058, // Size: 1, Type: BYTES, Flags: PRIVATE
- PLAYER_QUEST_LOG_20_4 = UNIT_END + 0x0059, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_QUEST_LOG_21_1 = UNIT_END + 0x005A, // Size: 1, Type: INT, Flags: PARTY_MEMBER
- PLAYER_QUEST_LOG_21_2 = UNIT_END + 0x005B, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_QUEST_LOG_21_3 = UNIT_END + 0x005C, // Size: 1, Type: BYTES, Flags: PRIVATE
- PLAYER_QUEST_LOG_21_4 = UNIT_END + 0x005D, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_QUEST_LOG_22_1 = UNIT_END + 0x005E, // Size: 1, Type: INT, Flags: PARTY_MEMBER
- PLAYER_QUEST_LOG_22_2 = UNIT_END + 0x005F, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_QUEST_LOG_22_3 = UNIT_END + 0x0060, // Size: 1, Type: BYTES, Flags: PRIVATE
- PLAYER_QUEST_LOG_22_4 = UNIT_END + 0x0061, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_QUEST_LOG_23_1 = UNIT_END + 0x0062, // Size: 1, Type: INT, Flags: PARTY_MEMBER
- PLAYER_QUEST_LOG_23_2 = UNIT_END + 0x0063, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_QUEST_LOG_23_3 = UNIT_END + 0x0064, // Size: 1, Type: BYTES, Flags: PRIVATE
- PLAYER_QUEST_LOG_23_4 = UNIT_END + 0x0065, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_QUEST_LOG_24_1 = UNIT_END + 0x0066, // Size: 1, Type: INT, Flags: PARTY_MEMBER
- PLAYER_QUEST_LOG_24_2 = UNIT_END + 0x0067, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_QUEST_LOG_24_3 = UNIT_END + 0x0068, // Size: 1, Type: BYTES, Flags: PRIVATE
- PLAYER_QUEST_LOG_24_4 = UNIT_END + 0x0069, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_QUEST_LOG_25_1 = UNIT_END + 0x006A, // Size: 1, Type: INT, Flags: PARTY_MEMBER
- PLAYER_QUEST_LOG_25_2 = UNIT_END + 0x006B, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_QUEST_LOG_25_3 = UNIT_END + 0x006C, // Size: 1, Type: BYTES, Flags: PRIVATE
- PLAYER_QUEST_LOG_25_4 = UNIT_END + 0x006D, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_VISIBLE_ITEM_1_ENTRYID = UNIT_END + 0x006E, // Size: 1, Type: INT, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_1_ENCHANTMENT = UNIT_END + 0x006F, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_2_ENTRYID = UNIT_END + 0x0070, // Size: 1, Type: INT, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_2_ENCHANTMENT = UNIT_END + 0x0071, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_3_ENTRYID = UNIT_END + 0x0072, // Size: 1, Type: INT, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_3_ENCHANTMENT = UNIT_END + 0x0073, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_4_ENTRYID = UNIT_END + 0x0074, // Size: 1, Type: INT, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_4_ENCHANTMENT = UNIT_END + 0x0075, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_5_ENTRYID = UNIT_END + 0x0076, // Size: 1, Type: INT, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_5_ENCHANTMENT = UNIT_END + 0x0077, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_6_ENTRYID = UNIT_END + 0x0078, // Size: 1, Type: INT, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_6_ENCHANTMENT = UNIT_END + 0x0079, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_7_ENTRYID = UNIT_END + 0x007A, // Size: 1, Type: INT, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_7_ENCHANTMENT = UNIT_END + 0x007B, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_8_ENTRYID = UNIT_END + 0x007C, // Size: 1, Type: INT, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_8_ENCHANTMENT = UNIT_END + 0x007D, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_9_ENTRYID = UNIT_END + 0x007E, // Size: 1, Type: INT, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_9_ENCHANTMENT = UNIT_END + 0x007F, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_10_ENTRYID = UNIT_END + 0x0080, // Size: 1, Type: INT, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_10_ENCHANTMENT = UNIT_END + 0x0081, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_11_ENTRYID = UNIT_END + 0x0082, // Size: 1, Type: INT, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_11_ENCHANTMENT = UNIT_END + 0x0083, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_12_ENTRYID = UNIT_END + 0x0084, // Size: 1, Type: INT, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_12_ENCHANTMENT = UNIT_END + 0x0085, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_13_ENTRYID = UNIT_END + 0x0086, // Size: 1, Type: INT, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_13_ENCHANTMENT = UNIT_END + 0x0087, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_14_ENTRYID = UNIT_END + 0x0088, // Size: 1, Type: INT, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_14_ENCHANTMENT = UNIT_END + 0x0089, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_15_ENTRYID = UNIT_END + 0x008A, // Size: 1, Type: INT, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_15_ENCHANTMENT = UNIT_END + 0x008B, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_16_ENTRYID = UNIT_END + 0x008C, // Size: 1, Type: INT, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_16_ENCHANTMENT = UNIT_END + 0x008D, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_17_ENTRYID = UNIT_END + 0x008E, // Size: 1, Type: INT, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_17_ENCHANTMENT = UNIT_END + 0x008F, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_18_ENTRYID = UNIT_END + 0x0090, // Size: 1, Type: INT, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_18_ENCHANTMENT = UNIT_END + 0x0091, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_19_ENTRYID = UNIT_END + 0x0092, // Size: 1, Type: INT, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_19_ENCHANTMENT = UNIT_END + 0x0093, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
- PLAYER_CHOSEN_TITLE = UNIT_END + 0x0094, // Size: 1, Type: INT, Flags: PUBLIC
- PLAYER_FAKE_INEBRIATION = UNIT_END + 0x0095, // Size: 1, Type: INT, Flags: PUBLIC
- PLAYER_FIELD_INV_SLOT_HEAD = UNIT_END + 0x0096, // Size: 46, Type: LONG, Flags: PRIVATE
- PLAYER_FIELD_PACK_SLOT_1 = UNIT_END + 0x00C4, // Size: 32, Type: LONG, Flags: PRIVATE
- PLAYER_FIELD_BANK_SLOT_1 = UNIT_END + 0x00E4, // Size: 56, Type: LONG, Flags: PRIVATE
- PLAYER_FIELD_BANKBAG_SLOT_1 = UNIT_END + 0x011C, // Size: 14, Type: LONG, Flags: PRIVATE
- PLAYER_FIELD_VENDORBUYBACK_SLOT_1 = UNIT_END + 0x012A, // Size: 24, Type: LONG, Flags: PRIVATE
- PLAYER_FIELD_KEYRING_SLOT_1 = UNIT_END + 0x0142, // Size: 64, Type: LONG, Flags: PRIVATE
- PLAYER_FIELD_CURRENCYTOKEN_SLOT_1 = UNIT_END + 0x0182, // Size: 64, Type: LONG, Flags: PRIVATE
- PLAYER_FARSIGHT = UNIT_END + 0x01C2, // Size: 2, Type: LONG, Flags: PRIVATE
- PLAYER__FIELD_KNOWN_TITLES = UNIT_END + 0x01C4, // Size: 2, Type: LONG, Flags: PRIVATE
- PLAYER__FIELD_KNOWN_TITLES1 = UNIT_END + 0x01C6, // Size: 2, Type: LONG, Flags: PRIVATE
- PLAYER__FIELD_KNOWN_TITLES2 = UNIT_END + 0x01C8, // Size: 2, Type: LONG, Flags: PRIVATE
- PLAYER_FIELD_KNOWN_CURRENCIES = UNIT_END + 0x01CA, // Size: 2, Type: LONG, Flags: PRIVATE
- PLAYER_XP = UNIT_END + 0x01CC, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_NEXT_LEVEL_XP = UNIT_END + 0x01CD, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_SKILL_INFO_1_1 = UNIT_END + 0x01CE, // Size: 384, Type: TWO_SHORT, Flags: PRIVATE
- PLAYER_CHARACTER_POINTS1 = UNIT_END + 0x034E, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_CHARACTER_POINTS2 = UNIT_END + 0x034F, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_TRACK_CREATURES = UNIT_END + 0x0350, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_TRACK_RESOURCES = UNIT_END + 0x0351, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_BLOCK_PERCENTAGE = UNIT_END + 0x0352, // Size: 1, Type: FLOAT, Flags: PRIVATE
- PLAYER_DODGE_PERCENTAGE = UNIT_END + 0x0353, // Size: 1, Type: FLOAT, Flags: PRIVATE
- PLAYER_PARRY_PERCENTAGE = UNIT_END + 0x0354, // Size: 1, Type: FLOAT, Flags: PRIVATE
- PLAYER_EXPERTISE = UNIT_END + 0x0355, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_OFFHAND_EXPERTISE = UNIT_END + 0x0356, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_CRIT_PERCENTAGE = UNIT_END + 0x0357, // Size: 1, Type: FLOAT, Flags: PRIVATE
- PLAYER_RANGED_CRIT_PERCENTAGE = UNIT_END + 0x0358, // Size: 1, Type: FLOAT, Flags: PRIVATE
- PLAYER_OFFHAND_CRIT_PERCENTAGE = UNIT_END + 0x0359, // Size: 1, Type: FLOAT, Flags: PRIVATE
- PLAYER_SPELL_CRIT_PERCENTAGE1 = UNIT_END + 0x035A, // Size: 7, Type: FLOAT, Flags: PRIVATE
- PLAYER_SHIELD_BLOCK = UNIT_END + 0x0361, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_SHIELD_BLOCK_CRIT_PERCENTAGE = UNIT_END + 0x0362, // Size: 1, Type: FLOAT, Flags: PRIVATE
- PLAYER_EXPLORED_ZONES_1 = UNIT_END + 0x0363, // Size: 128, Type: BYTES, Flags: PRIVATE
- PLAYER_REST_STATE_EXPERIENCE = UNIT_END + 0x03E3, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_FIELD_COINAGE = UNIT_END + 0x03E4, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_FIELD_MOD_DAMAGE_DONE_POS = UNIT_END + 0x03E5, // Size: 7, Type: INT, Flags: PRIVATE
- PLAYER_FIELD_MOD_DAMAGE_DONE_NEG = UNIT_END + 0x03EC, // Size: 7, Type: INT, Flags: PRIVATE
- PLAYER_FIELD_MOD_DAMAGE_DONE_PCT = UNIT_END + 0x03F3, // Size: 7, Type: INT, Flags: PRIVATE
- PLAYER_FIELD_MOD_HEALING_DONE_POS = UNIT_END + 0x03FA, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_FIELD_MOD_HEALING_PCT = UNIT_END + 0x03FB, // Size: 1, Type: FLOAT, Flags: PRIVATE
- PLAYER_FIELD_MOD_HEALING_DONE_PCT = UNIT_END + 0x03FC, // Size: 1, Type: FLOAT, Flags: PRIVATE
- PLAYER_FIELD_MOD_TARGET_RESISTANCE = UNIT_END + 0x03FD, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_FIELD_MOD_TARGET_PHYSICAL_RESISTANCE = UNIT_END + 0x03FE, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_FIELD_BYTES = UNIT_END + 0x03FF, // Size: 1, Type: BYTES, Flags: PRIVATE
- PLAYER_AMMO_ID = UNIT_END + 0x0400, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_SELF_RES_SPELL = UNIT_END + 0x0401, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_FIELD_PVP_MEDALS = UNIT_END + 0x0402, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_FIELD_BUYBACK_PRICE_1 = UNIT_END + 0x0403, // Size: 12, Type: INT, Flags: PRIVATE
- PLAYER_FIELD_BUYBACK_TIMESTAMP_1 = UNIT_END + 0x040F, // Size: 12, Type: INT, Flags: PRIVATE
- PLAYER_FIELD_KILLS = UNIT_END + 0x041B, // Size: 1, Type: TWO_SHORT, Flags: PRIVATE
- PLAYER_FIELD_TODAY_CONTRIBUTION = UNIT_END + 0x041C, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_FIELD_YESTERDAY_CONTRIBUTION = UNIT_END + 0x041D, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_FIELD_LIFETIME_HONORABLE_KILLS = UNIT_END + 0x041E, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_FIELD_BYTES2 = UNIT_END + 0x041F, // Size: 1, Type: 6, Flags: PRIVATE
- PLAYER_FIELD_WATCHED_FACTION_INDEX = UNIT_END + 0x0420, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_FIELD_COMBAT_RATING_1 = UNIT_END + 0x0421, // Size: 25, Type: INT, Flags: PRIVATE
- PLAYER_FIELD_ARENA_TEAM_INFO_1_1 = UNIT_END + 0x043A, // Size: 21, Type: INT, Flags: PRIVATE
- PLAYER_FIELD_HONOR_CURRENCY = UNIT_END + 0x044F, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_FIELD_ARENA_CURRENCY = UNIT_END + 0x0450, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_FIELD_MAX_LEVEL = UNIT_END + 0x0451, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_FIELD_DAILY_QUESTS_1 = UNIT_END + 0x0452, // Size: 25, Type: INT, Flags: PRIVATE
- PLAYER_RUNE_REGEN_1 = UNIT_END + 0x046B, // Size: 4, Type: FLOAT, Flags: PRIVATE
- PLAYER_NO_REAGENT_COST_1 = UNIT_END + 0x046F, // Size: 3, Type: INT, Flags: PRIVATE
- PLAYER_FIELD_GLYPH_SLOTS_1 = UNIT_END + 0x0472, // Size: 6, Type: INT, Flags: PRIVATE
- PLAYER_FIELD_GLYPHS_1 = UNIT_END + 0x0478, // Size: 6, Type: INT, Flags: PRIVATE
- PLAYER_GLYPHS_ENABLED = UNIT_END + 0x047E, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_FIELD_PADDING = UNIT_END + 0x047F, // Size: 1, Type: INT, Flags: NONE
- PLAYER_END = UNIT_END + 0x0480,
+ PLAYER_DUEL_ARBITER = UNIT_END + 0x0000, // Size: 2, Type: LONG, Flags: PUBLIC
+ PLAYER_FLAGS = UNIT_END + 0x0002, // Size: 1, Type: INT, Flags: PUBLIC
+ PLAYER_GUILDID = UNIT_END + 0x0003, // Size: 1, Type: INT, Flags: PUBLIC
+ PLAYER_GUILDRANK = UNIT_END + 0x0004, // Size: 1, Type: INT, Flags: PUBLIC
+ PLAYER_BYTES = UNIT_END + 0x0005, // Size: 1, Type: BYTES, Flags: PUBLIC
+ PLAYER_BYTES_2 = UNIT_END + 0x0006, // Size: 1, Type: BYTES, Flags: PUBLIC
+ PLAYER_BYTES_3 = UNIT_END + 0x0007, // Size: 1, Type: BYTES, Flags: PUBLIC
+ PLAYER_DUEL_TEAM = UNIT_END + 0x0008, // Size: 1, Type: INT, Flags: PUBLIC
+ PLAYER_GUILD_TIMESTAMP = UNIT_END + 0x0009, // Size: 1, Type: INT, Flags: PUBLIC
+ PLAYER_QUEST_LOG_1_1 = UNIT_END + 0x000A, // Size: 1, Type: INT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_1_2 = UNIT_END + 0x000B, // Size: 1, Type: INT, Flags: PRIVATE
+ PLAYER_QUEST_LOG_1_3 = UNIT_END + 0x000C, // Size: 2, Type: TWO_SHORT, Flags: PRIVATE
+ PLAYER_QUEST_LOG_1_5 = UNIT_END + 0x000E, // Size: 1, Type: INT, Flags: PRIVATE
+ PLAYER_QUEST_LOG_2_1 = UNIT_END + 0x000F, // Size: 1, Type: INT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_2_2 = UNIT_END + 0x0010, // Size: 1, Type: INT, Flags: PRIVATE
+ PLAYER_QUEST_LOG_2_3 = UNIT_END + 0x0011, // Size: 2, Type: TWO_SHORT, Flags: PRIVATE
+ PLAYER_QUEST_LOG_2_5 = UNIT_END + 0x0013, // Size: 1, Type: INT, Flags: PRIVATE
+ PLAYER_QUEST_LOG_3_1 = UNIT_END + 0x0014, // Size: 1, Type: INT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_3_2 = UNIT_END + 0x0015, // Size: 1, Type: INT, Flags: PRIVATE
+ PLAYER_QUEST_LOG_3_3 = UNIT_END + 0x0016, // Size: 2, Type: TWO_SHORT, Flags: PRIVATE
+ PLAYER_QUEST_LOG_3_5 = UNIT_END + 0x0018, // Size: 1, Type: INT, Flags: PRIVATE
+ PLAYER_QUEST_LOG_4_1 = UNIT_END + 0x0019, // Size: 1, Type: INT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_4_2 = UNIT_END + 0x001A, // Size: 1, Type: INT, Flags: PRIVATE
+ PLAYER_QUEST_LOG_4_3 = UNIT_END + 0x001B, // Size: 2, Type: TWO_SHORT, Flags: PRIVATE
+ PLAYER_QUEST_LOG_4_5 = UNIT_END + 0x001D, // Size: 1, Type: INT, Flags: PRIVATE
+ PLAYER_QUEST_LOG_5_1 = UNIT_END + 0x001E, // Size: 1, Type: INT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_5_2 = UNIT_END + 0x001F, // Size: 1, Type: INT, Flags: PRIVATE
+ PLAYER_QUEST_LOG_5_3 = UNIT_END + 0x0020, // Size: 2, Type: TWO_SHORT, Flags: PRIVATE
+ PLAYER_QUEST_LOG_5_5 = UNIT_END + 0x0022, // Size: 1, Type: INT, Flags: PRIVATE
+ PLAYER_QUEST_LOG_6_1 = UNIT_END + 0x0023, // Size: 1, Type: INT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_6_2 = UNIT_END + 0x0024, // Size: 1, Type: INT, Flags: PRIVATE
+ PLAYER_QUEST_LOG_6_3 = UNIT_END + 0x0025, // Size: 2, Type: TWO_SHORT, Flags: PRIVATE
+ PLAYER_QUEST_LOG_6_5 = UNIT_END + 0x0027, // Size: 1, Type: INT, Flags: PRIVATE
+ PLAYER_QUEST_LOG_7_1 = UNIT_END + 0x0028, // Size: 1, Type: INT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_7_2 = UNIT_END + 0x0029, // Size: 1, Type: INT, Flags: PRIVATE
+ PLAYER_QUEST_LOG_7_3 = UNIT_END + 0x002A, // Size: 2, Type: TWO_SHORT, Flags: PRIVATE
+ PLAYER_QUEST_LOG_7_5 = UNIT_END + 0x002C, // Size: 1, Type: INT, Flags: PRIVATE
+ PLAYER_QUEST_LOG_8_1 = UNIT_END + 0x002D, // Size: 1, Type: INT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_8_2 = UNIT_END + 0x002E, // Size: 1, Type: INT, Flags: PRIVATE
+ PLAYER_QUEST_LOG_8_3 = UNIT_END + 0x002F, // Size: 2, Type: TWO_SHORT, Flags: PRIVATE
+ PLAYER_QUEST_LOG_8_5 = UNIT_END + 0x0031, // Size: 1, Type: INT, Flags: PRIVATE
+ PLAYER_QUEST_LOG_9_1 = UNIT_END + 0x0032, // Size: 1, Type: INT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_9_2 = UNIT_END + 0x0033, // Size: 1, Type: INT, Flags: PRIVATE
+ PLAYER_QUEST_LOG_9_3 = UNIT_END + 0x0034, // Size: 2, Type: TWO_SHORT, Flags: PRIVATE
+ PLAYER_QUEST_LOG_9_5 = UNIT_END + 0x0036, // Size: 1, Type: INT, Flags: PRIVATE
+ PLAYER_QUEST_LOG_10_1 = UNIT_END + 0x0037, // Size: 1, Type: INT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_10_2 = UNIT_END + 0x0038, // Size: 1, Type: INT, Flags: PRIVATE
+ PLAYER_QUEST_LOG_10_3 = UNIT_END + 0x0039, // Size: 2, Type: TWO_SHORT, Flags: PRIVATE
+ PLAYER_QUEST_LOG_10_5 = UNIT_END + 0x003B, // Size: 1, Type: INT, Flags: PRIVATE
+ PLAYER_QUEST_LOG_11_1 = UNIT_END + 0x003C, // Size: 1, Type: INT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_11_2 = UNIT_END + 0x003D, // Size: 1, Type: INT, Flags: PRIVATE
+ PLAYER_QUEST_LOG_11_3 = UNIT_END + 0x003E, // Size: 2, Type: TWO_SHORT, Flags: PRIVATE
+ PLAYER_QUEST_LOG_11_5 = UNIT_END + 0x0040, // Size: 1, Type: INT, Flags: PRIVATE
+ PLAYER_QUEST_LOG_12_1 = UNIT_END + 0x0041, // Size: 1, Type: INT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_12_2 = UNIT_END + 0x0042, // Size: 1, Type: INT, Flags: PRIVATE
+ PLAYER_QUEST_LOG_12_3 = UNIT_END + 0x0043, // Size: 2, Type: TWO_SHORT, Flags: PRIVATE
+ PLAYER_QUEST_LOG_12_5 = UNIT_END + 0x0045, // Size: 1, Type: INT, Flags: PRIVATE
+ PLAYER_QUEST_LOG_13_1 = UNIT_END + 0x0046, // Size: 1, Type: INT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_13_2 = UNIT_END + 0x0047, // Size: 1, Type: INT, Flags: PRIVATE
+ PLAYER_QUEST_LOG_13_3 = UNIT_END + 0x0048, // Size: 2, Type: TWO_SHORT, Flags: PRIVATE
+ PLAYER_QUEST_LOG_13_5 = UNIT_END + 0x004A, // Size: 1, Type: INT, Flags: PRIVATE
+ PLAYER_QUEST_LOG_14_1 = UNIT_END + 0x004B, // Size: 1, Type: INT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_14_2 = UNIT_END + 0x004C, // Size: 1, Type: INT, Flags: PRIVATE
+ PLAYER_QUEST_LOG_14_3 = UNIT_END + 0x004D, // Size: 2, Type: TWO_SHORT, Flags: PRIVATE
+ PLAYER_QUEST_LOG_14_5 = UNIT_END + 0x004F, // Size: 1, Type: INT, Flags: PRIVATE
+ PLAYER_QUEST_LOG_15_1 = UNIT_END + 0x0050, // Size: 1, Type: INT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_15_2 = UNIT_END + 0x0051, // Size: 1, Type: INT, Flags: PRIVATE
+ PLAYER_QUEST_LOG_15_3 = UNIT_END + 0x0052, // Size: 2, Type: TWO_SHORT, Flags: PRIVATE
+ PLAYER_QUEST_LOG_15_5 = UNIT_END + 0x0054, // Size: 1, Type: INT, Flags: PRIVATE
+ PLAYER_QUEST_LOG_16_1 = UNIT_END + 0x0055, // Size: 1, Type: INT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_16_2 = UNIT_END + 0x0056, // Size: 1, Type: INT, Flags: PRIVATE
+ PLAYER_QUEST_LOG_16_3 = UNIT_END + 0x0057, // Size: 2, Type: TWO_SHORT, Flags: PRIVATE
+ PLAYER_QUEST_LOG_16_5 = UNIT_END + 0x0059, // Size: 1, Type: INT, Flags: PRIVATE
+ PLAYER_QUEST_LOG_17_1 = UNIT_END + 0x005A, // Size: 1, Type: INT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_17_2 = UNIT_END + 0x005B, // Size: 1, Type: INT, Flags: PRIVATE
+ PLAYER_QUEST_LOG_17_3 = UNIT_END + 0x005C, // Size: 2, Type: TWO_SHORT, Flags: PRIVATE
+ PLAYER_QUEST_LOG_17_5 = UNIT_END + 0x005E, // Size: 1, Type: INT, Flags: PRIVATE
+ PLAYER_QUEST_LOG_18_1 = UNIT_END + 0x005F, // Size: 1, Type: INT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_18_2 = UNIT_END + 0x0060, // Size: 1, Type: INT, Flags: PRIVATE
+ PLAYER_QUEST_LOG_18_3 = UNIT_END + 0x0061, // Size: 2, Type: TWO_SHORT, Flags: PRIVATE
+ PLAYER_QUEST_LOG_18_5 = UNIT_END + 0x0063, // Size: 1, Type: INT, Flags: PRIVATE
+ PLAYER_QUEST_LOG_19_1 = UNIT_END + 0x0064, // Size: 1, Type: INT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_19_2 = UNIT_END + 0x0065, // Size: 1, Type: INT, Flags: PRIVATE
+ PLAYER_QUEST_LOG_19_3 = UNIT_END + 0x0066, // Size: 2, Type: TWO_SHORT, Flags: PRIVATE
+ PLAYER_QUEST_LOG_19_5 = UNIT_END + 0x0068, // Size: 1, Type: INT, Flags: PRIVATE
+ PLAYER_QUEST_LOG_20_1 = UNIT_END + 0x0069, // Size: 1, Type: INT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_20_2 = UNIT_END + 0x006A, // Size: 1, Type: INT, Flags: PRIVATE
+ PLAYER_QUEST_LOG_20_3 = UNIT_END + 0x006B, // Size: 2, Type: TWO_SHORT, Flags: PRIVATE
+ PLAYER_QUEST_LOG_20_5 = UNIT_END + 0x006D, // Size: 1, Type: INT, Flags: PRIVATE
+ PLAYER_QUEST_LOG_21_1 = UNIT_END + 0x006E, // Size: 1, Type: INT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_21_2 = UNIT_END + 0x006F, // Size: 1, Type: INT, Flags: PRIVATE
+ PLAYER_QUEST_LOG_21_3 = UNIT_END + 0x0070, // Size: 2, Type: TWO_SHORT, Flags: PRIVATE
+ PLAYER_QUEST_LOG_21_5 = UNIT_END + 0x0072, // Size: 1, Type: INT, Flags: PRIVATE
+ PLAYER_QUEST_LOG_22_1 = UNIT_END + 0x0073, // Size: 1, Type: INT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_22_2 = UNIT_END + 0x0074, // Size: 1, Type: INT, Flags: PRIVATE
+ PLAYER_QUEST_LOG_22_3 = UNIT_END + 0x0075, // Size: 2, Type: TWO_SHORT, Flags: PRIVATE
+ PLAYER_QUEST_LOG_22_5 = UNIT_END + 0x0077, // Size: 1, Type: INT, Flags: PRIVATE
+ PLAYER_QUEST_LOG_23_1 = UNIT_END + 0x0078, // Size: 1, Type: INT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_23_2 = UNIT_END + 0x0079, // Size: 1, Type: INT, Flags: PRIVATE
+ PLAYER_QUEST_LOG_23_3 = UNIT_END + 0x007A, // Size: 2, Type: TWO_SHORT, Flags: PRIVATE
+ PLAYER_QUEST_LOG_23_5 = UNIT_END + 0x007C, // Size: 1, Type: INT, Flags: PRIVATE
+ PLAYER_QUEST_LOG_24_1 = UNIT_END + 0x007D, // Size: 1, Type: INT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_24_2 = UNIT_END + 0x007E, // Size: 1, Type: INT, Flags: PRIVATE
+ PLAYER_QUEST_LOG_24_3 = UNIT_END + 0x007F, // Size: 2, Type: TWO_SHORT, Flags: PRIVATE
+ PLAYER_QUEST_LOG_24_5 = UNIT_END + 0x0081, // Size: 1, Type: INT, Flags: PRIVATE
+ PLAYER_QUEST_LOG_25_1 = UNIT_END + 0x0082, // Size: 1, Type: INT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_25_2 = UNIT_END + 0x0083, // Size: 1, Type: INT, Flags: PRIVATE
+ PLAYER_QUEST_LOG_25_3 = UNIT_END + 0x0084, // Size: 2, Type: TWO_SHORT, Flags: PRIVATE
+ PLAYER_QUEST_LOG_25_5 = UNIT_END + 0x0086, // Size: 1, Type: INT, Flags: PRIVATE
+ PLAYER_VISIBLE_ITEM_1_ENTRYID = UNIT_END + 0x0087, // Size: 1, Type: INT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_1_ENCHANTMENT = UNIT_END + 0x0088, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_2_ENTRYID = UNIT_END + 0x0089, // Size: 1, Type: INT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_2_ENCHANTMENT = UNIT_END + 0x008A, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_3_ENTRYID = UNIT_END + 0x008B, // Size: 1, Type: INT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_3_ENCHANTMENT = UNIT_END + 0x008C, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_4_ENTRYID = UNIT_END + 0x008D, // Size: 1, Type: INT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_4_ENCHANTMENT = UNIT_END + 0x008E, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_5_ENTRYID = UNIT_END + 0x008F, // Size: 1, Type: INT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_5_ENCHANTMENT = UNIT_END + 0x0090, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_6_ENTRYID = UNIT_END + 0x0091, // Size: 1, Type: INT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_6_ENCHANTMENT = UNIT_END + 0x0092, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_7_ENTRYID = UNIT_END + 0x0093, // Size: 1, Type: INT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_7_ENCHANTMENT = UNIT_END + 0x0094, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_8_ENTRYID = UNIT_END + 0x0095, // Size: 1, Type: INT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_8_ENCHANTMENT = UNIT_END + 0x0096, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_9_ENTRYID = UNIT_END + 0x0097, // Size: 1, Type: INT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_9_ENCHANTMENT = UNIT_END + 0x0098, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_10_ENTRYID = UNIT_END + 0x0099, // Size: 1, Type: INT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_10_ENCHANTMENT = UNIT_END + 0x009A, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_11_ENTRYID = UNIT_END + 0x009B, // Size: 1, Type: INT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_11_ENCHANTMENT = UNIT_END + 0x009C, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_12_ENTRYID = UNIT_END + 0x009D, // Size: 1, Type: INT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_12_ENCHANTMENT = UNIT_END + 0x009E, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_13_ENTRYID = UNIT_END + 0x009F, // Size: 1, Type: INT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_13_ENCHANTMENT = UNIT_END + 0x00A0, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_14_ENTRYID = UNIT_END + 0x00A1, // Size: 1, Type: INT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_14_ENCHANTMENT = UNIT_END + 0x00A2, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_15_ENTRYID = UNIT_END + 0x00A3, // Size: 1, Type: INT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_15_ENCHANTMENT = UNIT_END + 0x00A4, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_16_ENTRYID = UNIT_END + 0x00A5, // Size: 1, Type: INT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_16_ENCHANTMENT = UNIT_END + 0x00A6, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_17_ENTRYID = UNIT_END + 0x00A7, // Size: 1, Type: INT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_17_ENCHANTMENT = UNIT_END + 0x00A8, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_18_ENTRYID = UNIT_END + 0x00A9, // Size: 1, Type: INT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_18_ENCHANTMENT = UNIT_END + 0x00AA, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_19_ENTRYID = UNIT_END + 0x00AB, // Size: 1, Type: INT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_19_ENCHANTMENT = UNIT_END + 0x00AC, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
+ PLAYER_CHOSEN_TITLE = UNIT_END + 0x00AD, // Size: 1, Type: INT, Flags: PUBLIC
+ PLAYER_FAKE_INEBRIATION = UNIT_END + 0x00AE, // Size: 1, Type: INT, Flags: PUBLIC
+ PLAYER_FIELD_PAD_0 = UNIT_END + 0x00AF, // Size: 1, Type: INT, Flags: NONE
+ PLAYER_FIELD_INV_SLOT_HEAD = UNIT_END + 0x00B0, // Size: 46, Type: LONG, Flags: PRIVATE
+ PLAYER_FIELD_PACK_SLOT_1 = UNIT_END + 0x00DE, // Size: 32, Type: LONG, Flags: PRIVATE
+ PLAYER_FIELD_BANK_SLOT_1 = UNIT_END + 0x00FE, // Size: 56, Type: LONG, Flags: PRIVATE
+ PLAYER_FIELD_BANKBAG_SLOT_1 = UNIT_END + 0x0136, // Size: 14, Type: LONG, Flags: PRIVATE
+ PLAYER_FIELD_VENDORBUYBACK_SLOT_1 = UNIT_END + 0x0144, // Size: 24, Type: LONG, Flags: PRIVATE
+ PLAYER_FIELD_KEYRING_SLOT_1 = UNIT_END + 0x015C, // Size: 64, Type: LONG, Flags: PRIVATE
+ PLAYER_FIELD_CURRENCYTOKEN_SLOT_1 = UNIT_END + 0x019C, // Size: 64, Type: LONG, Flags: PRIVATE
+ PLAYER_FARSIGHT = UNIT_END + 0x01DC, // Size: 2, Type: LONG, Flags: PRIVATE
+ PLAYER__FIELD_KNOWN_TITLES = UNIT_END + 0x01DE, // Size: 2, Type: LONG, Flags: PRIVATE
+ PLAYER__FIELD_KNOWN_TITLES1 = UNIT_END + 0x01E0, // Size: 2, Type: LONG, Flags: PRIVATE
+ PLAYER__FIELD_KNOWN_TITLES2 = UNIT_END + 0x01E2, // Size: 2, Type: LONG, Flags: PRIVATE
+ PLAYER_FIELD_KNOWN_CURRENCIES = UNIT_END + 0x01E4, // Size: 2, Type: LONG, Flags: PRIVATE
+ PLAYER_XP = UNIT_END + 0x01E6, // Size: 1, Type: INT, Flags: PRIVATE
+ PLAYER_NEXT_LEVEL_XP = UNIT_END + 0x01E7, // Size: 1, Type: INT, Flags: PRIVATE
+ PLAYER_SKILL_INFO_1_1 = UNIT_END + 0x01E8, // Size: 384, Type: TWO_SHORT, Flags: PRIVATE
+ PLAYER_CHARACTER_POINTS1 = UNIT_END + 0x0368, // Size: 1, Type: INT, Flags: PRIVATE
+ PLAYER_CHARACTER_POINTS2 = UNIT_END + 0x0369, // Size: 1, Type: INT, Flags: PRIVATE
+ PLAYER_TRACK_CREATURES = UNIT_END + 0x036A, // Size: 1, Type: INT, Flags: PRIVATE
+ PLAYER_TRACK_RESOURCES = UNIT_END + 0x036B, // Size: 1, Type: INT, Flags: PRIVATE
+ PLAYER_BLOCK_PERCENTAGE = UNIT_END + 0x036C, // Size: 1, Type: FLOAT, Flags: PRIVATE
+ PLAYER_DODGE_PERCENTAGE = UNIT_END + 0x036D, // Size: 1, Type: FLOAT, Flags: PRIVATE
+ PLAYER_PARRY_PERCENTAGE = UNIT_END + 0x036E, // Size: 1, Type: FLOAT, Flags: PRIVATE
+ PLAYER_EXPERTISE = UNIT_END + 0x036F, // Size: 1, Type: INT, Flags: PRIVATE
+ PLAYER_OFFHAND_EXPERTISE = UNIT_END + 0x0370, // Size: 1, Type: INT, Flags: PRIVATE
+ PLAYER_CRIT_PERCENTAGE = UNIT_END + 0x0371, // Size: 1, Type: FLOAT, Flags: PRIVATE
+ PLAYER_RANGED_CRIT_PERCENTAGE = UNIT_END + 0x0372, // Size: 1, Type: FLOAT, Flags: PRIVATE
+ PLAYER_OFFHAND_CRIT_PERCENTAGE = UNIT_END + 0x0373, // Size: 1, Type: FLOAT, Flags: PRIVATE
+ PLAYER_SPELL_CRIT_PERCENTAGE1 = UNIT_END + 0x0374, // Size: 7, Type: FLOAT, Flags: PRIVATE
+ PLAYER_SHIELD_BLOCK = UNIT_END + 0x037B, // Size: 1, Type: INT, Flags: PRIVATE
+ PLAYER_SHIELD_BLOCK_CRIT_PERCENTAGE = UNIT_END + 0x037C, // Size: 1, Type: FLOAT, Flags: PRIVATE
+ PLAYER_EXPLORED_ZONES_1 = UNIT_END + 0x037D, // Size: 128, Type: BYTES, Flags: PRIVATE
+ PLAYER_REST_STATE_EXPERIENCE = UNIT_END + 0x03FD, // Size: 1, Type: INT, Flags: PRIVATE
+ PLAYER_FIELD_COINAGE = UNIT_END + 0x03FE, // Size: 1, Type: INT, Flags: PRIVATE
+ PLAYER_FIELD_MOD_DAMAGE_DONE_POS = UNIT_END + 0x03FF, // Size: 7, Type: INT, Flags: PRIVATE
+ PLAYER_FIELD_MOD_DAMAGE_DONE_NEG = UNIT_END + 0x0406, // Size: 7, Type: INT, Flags: PRIVATE
+ PLAYER_FIELD_MOD_DAMAGE_DONE_PCT = UNIT_END + 0x040D, // Size: 7, Type: INT, Flags: PRIVATE
+ PLAYER_FIELD_MOD_HEALING_DONE_POS = UNIT_END + 0x0414, // Size: 1, Type: INT, Flags: PRIVATE
+ PLAYER_FIELD_MOD_HEALING_PCT = UNIT_END + 0x0415, // Size: 1, Type: FLOAT, Flags: PRIVATE
+ PLAYER_FIELD_MOD_HEALING_DONE_PCT = UNIT_END + 0x0416, // Size: 1, Type: FLOAT, Flags: PRIVATE
+ PLAYER_FIELD_MOD_TARGET_RESISTANCE = UNIT_END + 0x0417, // Size: 1, Type: INT, Flags: PRIVATE
+ PLAYER_FIELD_MOD_TARGET_PHYSICAL_RESISTANCE = UNIT_END + 0x0418, // Size: 1, Type: INT, Flags: PRIVATE
+ PLAYER_FIELD_BYTES = UNIT_END + 0x0419, // Size: 1, Type: BYTES, Flags: PRIVATE
+ PLAYER_AMMO_ID = UNIT_END + 0x041A, // Size: 1, Type: INT, Flags: PRIVATE
+ PLAYER_SELF_RES_SPELL = UNIT_END + 0x041B, // Size: 1, Type: INT, Flags: PRIVATE
+ PLAYER_FIELD_PVP_MEDALS = UNIT_END + 0x041C, // Size: 1, Type: INT, Flags: PRIVATE
+ PLAYER_FIELD_BUYBACK_PRICE_1 = UNIT_END + 0x041D, // Size: 12, Type: INT, Flags: PRIVATE
+ PLAYER_FIELD_BUYBACK_TIMESTAMP_1 = UNIT_END + 0x0429, // Size: 12, Type: INT, Flags: PRIVATE
+ PLAYER_FIELD_KILLS = UNIT_END + 0x0435, // Size: 1, Type: TWO_SHORT, Flags: PRIVATE
+ PLAYER_FIELD_TODAY_CONTRIBUTION = UNIT_END + 0x0436, // Size: 1, Type: INT, Flags: PRIVATE
+ PLAYER_FIELD_YESTERDAY_CONTRIBUTION = UNIT_END + 0x0437, // Size: 1, Type: INT, Flags: PRIVATE
+ PLAYER_FIELD_LIFETIME_HONORABLE_KILLS = UNIT_END + 0x0438, // Size: 1, Type: INT, Flags: PRIVATE
+ PLAYER_FIELD_BYTES2 = UNIT_END + 0x0439, // Size: 1, Type: 6, Flags: PRIVATE
+ PLAYER_FIELD_WATCHED_FACTION_INDEX = UNIT_END + 0x043A, // Size: 1, Type: INT, Flags: PRIVATE
+ PLAYER_FIELD_COMBAT_RATING_1 = UNIT_END + 0x043B, // Size: 25, Type: INT, Flags: PRIVATE
+ PLAYER_FIELD_ARENA_TEAM_INFO_1_1 = UNIT_END + 0x0454, // Size: 21, Type: INT, Flags: PRIVATE
+ PLAYER_FIELD_HONOR_CURRENCY = UNIT_END + 0x0469, // Size: 1, Type: INT, Flags: PRIVATE
+ PLAYER_FIELD_ARENA_CURRENCY = UNIT_END + 0x046A, // Size: 1, Type: INT, Flags: PRIVATE
+ PLAYER_FIELD_MAX_LEVEL = UNIT_END + 0x046B, // Size: 1, Type: INT, Flags: PRIVATE
+ PLAYER_FIELD_DAILY_QUESTS_1 = UNIT_END + 0x046C, // Size: 25, Type: INT, Flags: PRIVATE
+ PLAYER_RUNE_REGEN_1 = UNIT_END + 0x0485, // Size: 4, Type: FLOAT, Flags: PRIVATE
+ PLAYER_NO_REAGENT_COST_1 = UNIT_END + 0x0489, // Size: 3, Type: INT, Flags: PRIVATE
+ PLAYER_FIELD_GLYPH_SLOTS_1 = UNIT_END + 0x048C, // Size: 6, Type: INT, Flags: PRIVATE
+ PLAYER_FIELD_GLYPHS_1 = UNIT_END + 0x0492, // Size: 6, Type: INT, Flags: PRIVATE
+ PLAYER_GLYPHS_ENABLED = UNIT_END + 0x0498, // Size: 1, Type: INT, Flags: PRIVATE
+ PLAYER_FIELD_PADDING = UNIT_END + 0x0499, // Size: 1, Type: INT, Flags: NONE
+ PLAYER_END = UNIT_END + 0x049A,
};
enum EGameObjectFields
{
- OBJECT_FIELD_CREATED_BY = OBJECT_END + 0x0000, // Size: 2, Type: LONG, Flags: PUBLIC
- GAMEOBJECT_DISPLAYID = OBJECT_END + 0x0002, // Size: 1, Type: INT, Flags: PUBLIC
- GAMEOBJECT_FLAGS = OBJECT_END + 0x0003, // Size: 1, Type: INT, Flags: PUBLIC
- GAMEOBJECT_PARENTROTATION = OBJECT_END + 0x0004, // Size: 4, Type: FLOAT, Flags: PUBLIC
- GAMEOBJECT_DYNAMIC = OBJECT_END + 0x0008, // Size: 1, Type: TWO_SHORT, Flags: DYNAMIC
- GAMEOBJECT_FACTION = OBJECT_END + 0x0009, // Size: 1, Type: INT, Flags: PUBLIC
- GAMEOBJECT_LEVEL = OBJECT_END + 0x000A, // Size: 1, Type: INT, Flags: PUBLIC
- GAMEOBJECT_BYTES_1 = OBJECT_END + 0x000B, // Size: 1, Type: BYTES, Flags: PUBLIC
- GAMEOBJECT_END = OBJECT_END + 0x000C,
+ OBJECT_FIELD_CREATED_BY = OBJECT_END + 0x0000, // Size: 2, Type: LONG, Flags: PUBLIC
+ GAMEOBJECT_DISPLAYID = OBJECT_END + 0x0002, // Size: 1, Type: INT, Flags: PUBLIC
+ GAMEOBJECT_FLAGS = OBJECT_END + 0x0003, // Size: 1, Type: INT, Flags: PUBLIC
+ GAMEOBJECT_PARENTROTATION = OBJECT_END + 0x0004, // Size: 4, Type: FLOAT, Flags: PUBLIC
+ GAMEOBJECT_DYNAMIC = OBJECT_END + 0x0008, // Size: 1, Type: TWO_SHORT, Flags: DYNAMIC
+ GAMEOBJECT_FACTION = OBJECT_END + 0x0009, // Size: 1, Type: INT, Flags: PUBLIC
+ GAMEOBJECT_LEVEL = OBJECT_END + 0x000A, // Size: 1, Type: INT, Flags: PUBLIC
+ GAMEOBJECT_BYTES_1 = OBJECT_END + 0x000B, // Size: 1, Type: BYTES, Flags: PUBLIC
+ GAMEOBJECT_END = OBJECT_END + 0x000C,
};
+
enum EDynamicObjectFields
{
- DYNAMICOBJECT_CASTER = OBJECT_END + 0x0000, // Size: 2, Type: LONG, Flags: PUBLIC
- DYNAMICOBJECT_BYTES = OBJECT_END + 0x0002, // Size: 1, Type: BYTES, Flags: PUBLIC
- DYNAMICOBJECT_SPELLID = OBJECT_END + 0x0003, // Size: 1, Type: INT, Flags: PUBLIC
- DYNAMICOBJECT_RADIUS = OBJECT_END + 0x0004, // Size: 1, Type: FLOAT, Flags: PUBLIC
- DYNAMICOBJECT_CASTTIME = OBJECT_END + 0x0005, // Size: 1, Type: INT, Flags: PUBLIC
- DYNAMICOBJECT_END = OBJECT_END + 0x0006,
+ DYNAMICOBJECT_CASTER = OBJECT_END + 0x0000, // Size: 2, Type: LONG, Flags: PUBLIC
+ DYNAMICOBJECT_BYTES = OBJECT_END + 0x0002, // Size: 1, Type: BYTES, Flags: PUBLIC
+ DYNAMICOBJECT_SPELLID = OBJECT_END + 0x0003, // Size: 1, Type: INT, Flags: PUBLIC
+ DYNAMICOBJECT_RADIUS = OBJECT_END + 0x0004, // Size: 1, Type: FLOAT, Flags: PUBLIC
+ DYNAMICOBJECT_CASTTIME = OBJECT_END + 0x0005, // Size: 1, Type: INT, Flags: PUBLIC
+ DYNAMICOBJECT_END = OBJECT_END + 0x0006,
};
enum ECorpseFields
{
- CORPSE_FIELD_OWNER = OBJECT_END + 0x0000, // Size: 2, Type: LONG, Flags: PUBLIC
- CORPSE_FIELD_PARTY = OBJECT_END + 0x0002, // Size: 2, Type: LONG, Flags: PUBLIC
- CORPSE_FIELD_DISPLAY_ID = OBJECT_END + 0x0004, // Size: 1, Type: INT, Flags: PUBLIC
- CORPSE_FIELD_ITEM = OBJECT_END + 0x0005, // Size: 19, Type: INT, Flags: PUBLIC
- CORPSE_FIELD_BYTES_1 = OBJECT_END + 0x0018, // Size: 1, Type: BYTES, Flags: PUBLIC
- CORPSE_FIELD_BYTES_2 = OBJECT_END + 0x0019, // Size: 1, Type: BYTES, Flags: PUBLIC
- CORPSE_FIELD_GUILD = OBJECT_END + 0x001A, // Size: 1, Type: INT, Flags: PUBLIC
- CORPSE_FIELD_FLAGS = OBJECT_END + 0x001B, // Size: 1, Type: INT, Flags: PUBLIC
- CORPSE_FIELD_DYNAMIC_FLAGS = OBJECT_END + 0x001C, // Size: 1, Type: INT, Flags: DYNAMIC
- CORPSE_FIELD_PAD = OBJECT_END + 0x001D, // Size: 1, Type: INT, Flags: NONE
- CORPSE_END = OBJECT_END + 0x001E,
+ CORPSE_FIELD_OWNER = OBJECT_END + 0x0000, // Size: 2, Type: LONG, Flags: PUBLIC
+ CORPSE_FIELD_PARTY = OBJECT_END + 0x0002, // Size: 2, Type: LONG, Flags: PUBLIC
+ CORPSE_FIELD_DISPLAY_ID = OBJECT_END + 0x0004, // Size: 1, Type: INT, Flags: PUBLIC
+ CORPSE_FIELD_ITEM = OBJECT_END + 0x0005, // Size: 19, Type: INT, Flags: PUBLIC
+ CORPSE_FIELD_BYTES_1 = OBJECT_END + 0x0018, // Size: 1, Type: BYTES, Flags: PUBLIC
+ CORPSE_FIELD_BYTES_2 = OBJECT_END + 0x0019, // Size: 1, Type: BYTES, Flags: PUBLIC
+ CORPSE_FIELD_GUILD = OBJECT_END + 0x001A, // Size: 1, Type: INT, Flags: PUBLIC
+ CORPSE_FIELD_FLAGS = OBJECT_END + 0x001B, // Size: 1, Type: INT, Flags: PUBLIC
+ CORPSE_FIELD_DYNAMIC_FLAGS = OBJECT_END + 0x001C, // Size: 1, Type: INT, Flags: DYNAMIC
+ CORPSE_FIELD_PAD = OBJECT_END + 0x001D, // Size: 1, Type: INT, Flags: NONE
+ CORPSE_END = OBJECT_END + 0x001E,
};
#endif
diff --git a/src/game/World.cpp b/src/game/World.cpp
index f413fc7dfd1..6a0ec55a86e 100644
--- a/src/game/World.cpp
+++ b/src/game/World.cpp
@@ -264,8 +264,6 @@ World::AddSession_ (WorldSession* s)
pkt << uint32(sWorld.getConfig(CONFIG_CLIENTCACHE_VERSION));
s->SendPacket(&pkt);
- s->SendAccountDataTimes(GLOBAL_CACHE_MASK);
-
s->SendTutorialsData();
UpdateMaxSessionCounters ();
@@ -1044,7 +1042,10 @@ void World::LoadConfigSettings(bool reload)
m_configs[CONFIG_ARENA_QUEUE_ANNOUNCER_ENABLE] = sConfig.GetBoolDefault("Arena.QueueAnnouncer.Enable", false);
m_configs[CONFIG_ARENA_QUEUE_ANNOUNCER_PLAYERONLY] = sConfig.GetBoolDefault("Arena.QueueAnnouncer.PlayerOnly", false);
m_configs[CONFIG_ARENA_SEASON_ID] = sConfig.GetIntDefault ("Arena.ArenaSeason.ID", 1);
+ m_configs[CONFIG_ARENA_START_RATING] = sConfig.GetIntDefault ("Arena.ArenaStartRating", 0);
+ m_configs[CONFIG_ARENA_START_PERSONAL_RATING] = sConfig.GetIntDefault ("Arena.ArenaStartPersonalRating", 0);
m_configs[CONFIG_ARENA_SEASON_IN_PROGRESS] = sConfig.GetBoolDefault("Arena.ArenaSeason.InProgress", true);
+ m_configs[CONFIG_ARENA_LK_ARENAS_ENABLE] = sConfig.GetIntDefault ("Arena.LK.ArenasEnable", 0);
m_configs[CONFIG_OFFHAND_CHECK_AT_SPELL_UNLEARN] = sConfig.GetBoolDefault("OffhandCheckAtSpellUnlearn", false);
@@ -1406,6 +1407,11 @@ void World::SetInitialWorldSettings()
sLog.outString("Loading Quests...");
objmgr.LoadQuests(); // must be loaded after DBCs, creature_template, item_template, gameobject tables
+
+ sLog.outString( "Loading Quest POI" );
+ objmgr.LoadQuestPOI();
+
+ sLog.outString("Loading Quests Relations...");
objmgr.LoadQuestRelations(); // must be after quest load
sLog.outString("Loading UNIT_NPC_FLAG_SPELLCLICK Data...");
diff --git a/src/game/World.h b/src/game/World.h
index b8d9b217562..f89a998afcc 100644
--- a/src/game/World.h
+++ b/src/game/World.h
@@ -239,6 +239,9 @@ enum WorldConfigs
CONFIG_ARENA_QUEUE_ANNOUNCER_PLAYERONLY,
CONFIG_ARENA_SEASON_ID,
CONFIG_ARENA_SEASON_IN_PROGRESS,
+ CONFIG_ARENA_START_RATING,
+ CONFIG_ARENA_START_PERSONAL_RATING,
+ CONFIG_ARENA_LK_ARENAS_ENABLE,
CONFIG_MAX_WHO,
CONFIG_BG_START_MUSIC,
CONFIG_START_ALL_SPELLS,
diff --git a/src/game/WorldSession.h b/src/game/WorldSession.h
index a6019d8112c..ce3974312ab 100644
--- a/src/game/WorldSession.h
+++ b/src/game/WorldSession.h
@@ -726,6 +726,9 @@ class WorldSession
void HandleEquipmentSetDelete(WorldPacket& recv_data);
void HandleEquipmentSetUse(WorldPacket& recv_data);
void HandleWorldStateUITimerUpdate(WorldPacket& recv_data);
+ void HandleReadyForAccountDataTimes(WorldPacket& recv_data);
+ void HandleQueryQuestsCompleted(WorldPacket& recv_data);
+ void HandleQuestPOIQuery(WorldPacket& recv_data);
void HandleOnPVPKill(Player *killed);
bool HandleOnPlayerChat(const char *text);
uint32 HandleOnGetXP(uint32 amount);