diff options
Diffstat (limited to 'src')
78 files changed, 3893 insertions, 1511 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); diff --git a/src/scripts/kalimdor/onyxias_lair/boss_onyxia.cpp b/src/scripts/kalimdor/onyxias_lair/boss_onyxia.cpp index b2d83a76ae2..23cb8f3289e 100644 --- a/src/scripts/kalimdor/onyxias_lair/boss_onyxia.cpp +++ b/src/scripts/kalimdor/onyxias_lair/boss_onyxia.cpp @@ -17,276 +17,344 @@ /* ScriptData SDName: Boss_Onyxia SD%Complete: 90 -SDComment: Spell Heated Ground is wrong, flying animation, visual for area effect +SDComment: Phase 3 need additianal code. Phase 2 requires entries in spell_target_position with specific locations. See bottom of file. SDCategory: Onyxia's Lair EndScriptData */ #include "ScriptedPch.h" -#define SAY_AGGRO -1249000 -#define SAY_KILL -1249001 -#define SAY_PHASE_2_TRANS -1249002 -#define SAY_PHASE_3_TRANS -1249003 -#define EMOTE_BREATH -1249004 - -#define SPELL_WINGBUFFET 18500 -#define SPELL_FLAMEBREATH 18435 -#define SPELL_CLEAVE 19983 -#define SPELL_TAILSWEEP 15847 -#define SPELL_KNOCK_AWAY 19633 - -#define SPELL_ENGULFINGFLAMES 20019 -#define SPELL_DEEPBREATH 23461 -#define SPELL_FIREBALL 18392 - -#define SPELL_BELLOWINGROAR 18431 -#define SPELL_HEATED_GROUND 22191 //Wrong Spell - -#define SPELL_SUMMONWHELP 17646 +enum +{ + SAY_AGGRO = -1249000, + SAY_KILL = -1249001, + SAY_PHASE_2_TRANS = -1249002, + SAY_PHASE_3_TRANS = -1249003, + EMOTE_BREATH = -1249004, + + SPELL_WINGBUFFET = 18500, + SPELL_FLAMEBREATH = 18435, + SPELL_CLEAVE = 19983, + SPELL_TAILSWEEP = 15847, + SPELL_KNOCK_AWAY = 19633, + + SPELL_ENGULFINGFLAMES = 20019, + SPELL_DEEPBREATH = 23461, + SPELL_FIREBALL = 18392, + + //Not much choise about these. We have to make own defintion on the direction/start-end point + //SPELL_BREATH_NORTH_TO_SOUTH = 17086, // 20x in "array" + //SPELL_BREATH_SOUTH_TO_NORTH = 18351, // 11x in "array" + + SPELL_BREATH_EAST_TO_WEST = 18576, // 7x in "array" + SPELL_BREATH_WEST_TO_EAST = 18609, // 7x in "array" + + SPELL_BREATH_SE_TO_NW = 18564, // 12x in "array" + SPELL_BREATH_NW_TO_SE = 18584, // 12x in "array" + SPELL_BREATH_SW_TO_NE = 18596, // 12x in "array" + SPELL_BREATH_NE_TO_SW = 18617, // 12x in "array" + + //SPELL_BREATH = 21131, // 8x in "array", different initial cast than the other arrays + + SPELL_BELLOWINGROAR = 18431, + SPELL_HEATED_GROUND = 22191, + + SPELL_SUMMONWHELP = 17646, + NPC_WHELP = 11262, + MAX_WHELP = 16, + + PHASE_START = 1, + PHASE_BREATH = 2, + PHASE_END = 3 +}; -#define CREATURE_WHELP 11262 +struct sOnyxMove +{ + uint32 uiLocId; + uint32 uiLocIdEnd; + uint32 uiSpellId; + float fX, fY, fZ; +}; -static float MovementLocations[4][3]= +static sOnyxMove aMoveData[]= { - {-64.0523, -213.0619, -68.2985}, - {12.4636, -220.01490, -68.0548}, - {-38.8391, -182.3220, -68.9457}, - {-37.0390, -244.8760, -68.1278} + {0, 1, SPELL_BREATH_WEST_TO_EAST, -33.5561f, -182.682f, -60.9457f},//west + {1, 0, SPELL_BREATH_EAST_TO_WEST, -31.4963f, -250.123f, -60.1278f},//east + {2, 4, SPELL_BREATH_NW_TO_SE, 6.8951f, -180.246f, -60.896f},//north-west + {3, 5, SPELL_BREATH_NE_TO_SW, 10.2191f, -247.912f, -60.896f},//north-east + {4, 2, SPELL_BREATH_SE_TO_NW, -63.5156f, -240.096f, -60.477f},//south-east + {5, 3, SPELL_BREATH_SW_TO_NE, -58.2509f, -189.020f, -60.790f},//south-west + //{6, 7, SPELL_BREATH_SOUTH_TO_NORTH, -65.8444f, -213.809f, -60.2985f},//south + //{7, 6, SPELL_BREATH_NORTH_TO_SOUTH, 22.8763f, -217.152f, -60.0548f},//north }; -static float SpawnLocations[4][3]= +static float afSpawnLocations[2][3]= { {-30.127, -254.463, -89.440}, - {-30.817, -177.106, -89.258}, - {14.480, -241.560, -85.6300}, - {17.372, -190.840, -85.2810}, + {-30.817, -177.106, -89.258} }; struct boss_onyxiaAI : public ScriptedAI { - boss_onyxiaAI(Creature* c) : ScriptedAI(c) {} + boss_onyxiaAI(Creature* pCreature) : ScriptedAI(pCreature) {Reset();} + + uint32 m_uiPhase; - uint32 Phase; + uint32 m_uiFlameBreathTimer; + uint32 m_uiCleaveTimer; + uint32 m_uiTailSweepTimer; + uint32 m_uiWingBuffetTimer; - uint32 FlameBreathTimer; - uint32 CleaveTimer; - uint32 TailSweepTimer; - uint32 MovementTimer; - uint32 EngulfingFlamesTimer; - uint32 SummonWhelpsTimer; - uint32 BellowingRoarTimer; - uint32 WingBuffetTimer; - uint32 KnockAwayTimer; - uint32 FireballTimer; + uint32 m_uiMovePoint; + uint32 m_uiMovementTimer; + sOnyxMove* m_pPointData; - bool InitialSpawn; + uint32 m_uiEngulfingFlamesTimer; + uint32 m_uiSummonWhelpsTimer; + uint32 m_uiBellowingRoarTimer; + uint32 m_uiWhelpTimer; + + uint8 m_uiSummonCount; + bool m_bIsSummoningWhelps; void Reset() { - Phase = 1; - - FlameBreathTimer = 20000; - TailSweepTimer = 2000; - CleaveTimer = 15000; - MovementTimer = 3000; - EngulfingFlamesTimer = 15000; - SummonWhelpsTimer = 45000; - BellowingRoarTimer = 30000; - WingBuffetTimer = 17000; - KnockAwayTimer = 15000; - FireballTimer = 18000; - - InitialSpawn = true; + if (!IsCombatMovement()) + SetCombatMovement(true); + + m_uiPhase = PHASE_START; + + m_uiFlameBreathTimer = urand(10000, 20000); + m_uiTailSweepTimer = urand(15000, 20000); + m_uiCleaveTimer = urand(2000, 5000); + m_uiWingBuffetTimer = urand(10000, 20000); + + m_uiMovePoint = urand(0, 5); + m_uiMovementTimer = 20000; + m_pPointData = GetMoveData(); + + m_uiEngulfingFlamesTimer = 15000; + m_uiSummonWhelpsTimer = 45000; + m_uiBellowingRoarTimer = 30000; + m_uiWhelpTimer = 1000; + + m_uiSummonCount = 0; + m_bIsSummoningWhelps = false; } - void EnterCombat(Unit* who) + void Aggro(Unit* pWho) { DoScriptText(SAY_AGGRO, m_creature); - DoZoneInCombat(); + m_creature->SetInCombatWithZone(); } - void JustDied(Unit* Killer) + void JustSummoned(Creature *pSummoned) { + if (Unit* pTarget = SelectUnit(SELECT_TARGET_RANDOM,0)) + pSummoned->AI()->AttackStart(pTarget); + + ++m_uiSummonCount; } - void KilledUnit(Unit *victim) + void KilledUnit(Unit* pVictim) { DoScriptText(SAY_KILL, m_creature); } - void UpdateAI(const uint32 diff) + void SpellHit(Unit *pCaster, const SpellEntry* pSpell) { - if (!UpdateVictim()) - return; - - if (((m_creature->GetHealth()*100 / m_creature->GetMaxHealth()) < 60) && (Phase == 1)) + if (pSpell->Id == SPELL_BREATH_EAST_TO_WEST || + pSpell->Id == SPELL_BREATH_WEST_TO_EAST || + pSpell->Id == SPELL_BREATH_SE_TO_NW || + pSpell->Id == SPELL_BREATH_NW_TO_SE || + pSpell->Id == SPELL_BREATH_SW_TO_NE || + pSpell->Id == SPELL_BREATH_NE_TO_SW) { - Phase = 2; - m_creature->AddUnitMovementFlag(MOVEMENTFLAG_LEVITATING); - m_creature->SetHover(true); - m_creature->GetMotionMaster()->Clear(false); - m_creature->GetMotionMaster()->MoveIdle(); - DoScriptText(SAY_PHASE_2_TRANS, m_creature); + if (m_pPointData) + { + m_creature->GetMap()->CreatureRelocation(m_creature, m_pPointData->fX, m_pPointData->fY, m_pPointData->fZ, 0.0f); + m_creature->GetMotionMaster()->MovePoint(0, -10.6155, -219.357, -87.7344); + + } } + } - if (((m_creature->GetHealth()*100 / m_creature->GetMaxHealth()) < 40) && (Phase == 2)) + sOnyxMove* GetMoveData() + { + uint32 uiMaxCount = sizeof(aMoveData)/sizeof(sOnyxMove); + + for (uint32 i = 0; i < uiMaxCount; ++i) { - Phase = 3; - m_creature->RemoveUnitMovementFlag(MOVEMENTFLAG_LEVITATING); - m_creature->SetHover(false); - m_creature->GetMotionMaster()->MovePoint(0, -10.6155, -219.357, -87.7344); - DoStartMovement(m_creature->getVictim()); - m_creature->RemoveUnitMovementFlag(MOVEMENTFLAG_WALK_MODE); - DoScriptText(SAY_PHASE_3_TRANS, m_creature); - m_creature->GetMotionMaster()->MoveChase(m_creature->getVictim()); + if (aMoveData[i].uiLocId == m_uiMovePoint) + return &aMoveData[i]; } - if (Phase == 1 || Phase == 3) + return NULL; + } + + void SetNextRandomPoint() + { + uint32 uiMaxCount = sizeof(aMoveData)/sizeof(sOnyxMove); + + int iTemp = rand()%(uiMaxCount-1); + + if (iTemp >= m_uiMovePoint) + ++iTemp; + + m_uiMovePoint = iTemp; + } + + void UpdateAI(const uint32 uiDiff) + { + if (!UpdateVictim()) + return; + + if (m_uiPhase == PHASE_START || m_uiPhase == PHASE_END) { - if (FlameBreathTimer <= diff) + if (m_uiFlameBreathTimer <= uiDiff) { DoCast(m_creature->getVictim(), SPELL_FLAMEBREATH); - FlameBreathTimer = 15000; - } else FlameBreathTimer -= diff; + m_uiFlameBreathTimer = urand(10000, 20000); + } + else + m_uiFlameBreathTimer -= uiDiff; - if (TailSweepTimer <= diff) + if (m_uiTailSweepTimer <= uiDiff) { - Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 1); - if (pTarget && !m_creature->HasInArc(M_PI, pTarget)) - DoCast(pTarget, SPELL_TAILSWEEP); - - TailSweepTimer = 10000; - } else TailSweepTimer -= diff; + DoCast(m_creature, SPELL_TAILSWEEP); + m_uiTailSweepTimer = urand(15000, 20000); + } + else + m_uiTailSweepTimer -= uiDiff; - if (CleaveTimer <= diff) + if (m_uiCleaveTimer <= uiDiff) { DoCast(m_creature->getVictim(), SPELL_CLEAVE); - CleaveTimer = 10000; - } else CleaveTimer -= diff; + m_uiCleaveTimer = urand(2000, 5000); + } + else + m_uiCleaveTimer -= uiDiff; - if (WingBuffetTimer <= diff) + if (m_uiWingBuffetTimer <= uiDiff) { DoCast(m_creature->getVictim(), SPELL_WINGBUFFET); - WingBuffetTimer = 7000 + ((rand()%8)*1000); - } else WingBuffetTimer -= diff; + m_uiWingBuffetTimer = urand(15000, 30000); + } + else + m_uiWingBuffetTimer -= uiDiff; - if (KnockAwayTimer <= diff) + if (m_uiPhase == PHASE_END) { - if (rand() <= 30) + if (m_uiBellowingRoarTimer <= uiDiff) { - DoCast(m_creature->getVictim(), SPELL_KNOCK_AWAY); + DoCast(m_creature->getVictim(), SPELL_BELLOWINGROAR); + m_uiBellowingRoarTimer = 30000; } - KnockAwayTimer = 15000; - } else KnockAwayTimer -= diff; - - if (Phase == 3) + else + m_uiBellowingRoarTimer -= uiDiff; + } + else { - if (BellowingRoarTimer <= diff) + if (m_creature->GetHealth()*100 / m_creature->GetMaxHealth() < 60) { - DoCast(m_creature->getVictim(), SPELL_BELLOWINGROAR); + m_uiPhase = PHASE_BREATH; - BellowingRoarTimer = 30000; - } else BellowingRoarTimer -= diff; + SetCombatMovement(false); - if (SummonWhelpsTimer <= diff) - { - SummonWhelps(Phase); + m_creature->GetMotionMaster()->Clear(false); + m_creature->GetMotionMaster()->MoveIdle(); - SummonWhelpsTimer = 45000; - } else SummonWhelpsTimer -= diff; + DoScriptText(SAY_PHASE_2_TRANS, m_creature); + + if (m_pPointData) + m_creature->GetMotionMaster()->MovePoint(m_pPointData->uiLocId, m_pPointData->fX, m_pPointData->fY, m_pPointData->fZ); + + SetNextRandomPoint(); + return; + } } DoMeleeAttackIfReady(); } - - if (Phase == 2) + else { - if (InitialSpawn) + if (m_creature->GetHealth()*100 / m_creature->GetMaxHealth() < 40) { - InitialSpawn = false; + m_uiPhase = PHASE_END; + DoScriptText(SAY_PHASE_3_TRANS, m_creature); - for (uint32 i = 0; i < 10; ++i) - { - uint32 random = rand()%4; - Creature* Whelp = m_creature->SummonCreature(CREATURE_WHELP, SpawnLocations[random][0], SpawnLocations[random][1], SpawnLocations[random][2], 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 30000); - if (Whelp) - Whelp->AI()->AttackStart(SelectUnit(SELECT_TARGET_RANDOM, 0)); - } + SetCombatMovement(true); + m_creature->GetMotionMaster()->MoveChase(m_creature->getVictim()); + + return; } - if (EngulfingFlamesTimer <= diff) + if (m_uiMovementTimer <= uiDiff) { - DoCast(SelectUnit(SELECT_TARGET_RANDOM, 0), SPELL_ENGULFINGFLAMES); - m_creature->HandleEmoteCommand(ANIM_FLY); + m_pPointData = GetMoveData(); - EngulfingFlamesTimer = 10000; - } - else EngulfingFlamesTimer -= diff; + SetNextRandomPoint(); - if (FireballTimer <= diff) - { - DoCast(SelectUnit(SELECT_TARGET_RANDOM, 0), SPELL_FIREBALL); + m_uiMovementTimer = 25000; - FireballTimer = 18000; - } - else FireballTimer -= diff; + if (!m_pPointData) + return; - if (MovementTimer <= diff) - { - if (rand()%100 < 30) + if (m_uiMovePoint == m_pPointData->uiLocIdEnd) { + if (m_creature->IsNonMeleeSpellCasted(false)) + m_creature->InterruptNonMeleeSpells(false); + DoScriptText(EMOTE_BREATH, m_creature); - DoCast(m_creature->getVictim(), SPELL_DEEPBREATH); + DoCast(m_creature, m_pPointData->uiSpellId); + } + else + { + m_creature->GetMotionMaster()->MovePoint(m_pPointData->uiLocId, m_pPointData->fX, m_pPointData->fY, m_pPointData->fZ); } - else ChangePosition(); - - MovementTimer = 25000; - } else MovementTimer -= diff; - - if (SummonWhelpsTimer <= diff) - { - SummonWhelps(Phase); - - SummonWhelpsTimer = 45000; } - else SummonWhelpsTimer -= diff; - } - } + else + m_uiMovementTimer -= uiDiff; - void ChangePosition() - { - uint32 random = rand() % 4; - if (random<4){ - m_creature->GetMotionMaster()->MovePoint(0, MovementLocations[random][0], MovementLocations[random][1], MovementLocations[random][2]);} - } - - void SummonWhelps(uint32 Phase) - { - if (Phase == 2) - { - uint32 max = rand()%10; - for (uint32 i = 0; i < max; ++i) + if (m_uiEngulfingFlamesTimer <= uiDiff) { - uint32 random = rand()%3; - Creature* Whelp = m_creature->SummonCreature(CREATURE_WHELP, SpawnLocations[random][0], SpawnLocations[random][1], SpawnLocations[random][2], 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 30000); - if (Whelp) - Whelp->AI()->AttackStart(SelectUnit(SELECT_TARGET_RANDOM, 0)); + if (m_creature->GetMotionMaster()->GetCurrentMovementGeneratorType() != POINT_MOTION_TYPE) + { + if (Unit* pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0)) + DoCast(pTarget, SPELL_FIREBALL); + + m_uiEngulfingFlamesTimer = 8000; + } } - } + else + m_uiEngulfingFlamesTimer -= uiDiff; //engulfingflames is supposed to be activated by a fireball but haven't come by - if (Phase == 3) - { - uint32 max = rand() % 10 +1; - if (max < 5) + if (m_bIsSummoningWhelps) { - for (uint32 i = 0; i < max; ++i) + if (m_uiSummonCount < MAX_WHELP) { - uint32 random = rand()%4; - Creature* Whelp = m_creature->SummonCreature(CREATURE_WHELP, SpawnLocations[random][0], SpawnLocations[random][1], SpawnLocations[random][2], 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 30000); - if (Whelp) - Whelp->AI()->AttackStart(SelectUnit(SELECT_TARGET_RANDOM, 0)); + if (m_uiWhelpTimer <= uiDiff) + { + m_creature->SummonCreature(NPC_WHELP, afSpawnLocations[0][0], afSpawnLocations[0][1], afSpawnLocations[0][2], 0.0f, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 30000); + m_creature->SummonCreature(NPC_WHELP, afSpawnLocations[1][0], afSpawnLocations[1][1], afSpawnLocations[1][2], 0.0f, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 30000); + m_uiWhelpTimer = 1000; + } + else + m_uiWhelpTimer -= uiDiff; + } + else + { + m_bIsSummoningWhelps = false; + m_uiSummonCount = 0; + m_uiSummonWhelpsTimer = 30000; } } + else + { + if (m_uiSummonWhelpsTimer <= uiDiff) + m_bIsSummoningWhelps = true; + else + m_uiSummonWhelpsTimer -= uiDiff; + } } } }; @@ -304,4 +372,3 @@ void AddSC_boss_onyxia() newscript->GetAI = &GetAI_boss_onyxiaAI; newscript->RegisterSelf(); } - diff --git a/src/scripts/kalimdor/temple_of_ahnqiraj/boss_skeram.cpp b/src/scripts/kalimdor/temple_of_ahnqiraj/boss_skeram.cpp index 7e64259efad..11980a94b68 100644 --- a/src/scripts/kalimdor/temple_of_ahnqiraj/boss_skeram.cpp +++ b/src/scripts/kalimdor/temple_of_ahnqiraj/boss_skeram.cpp @@ -233,7 +233,7 @@ struct boss_skeramAI : public ScriptedAI for (uint8 ico = 0; ico < TARGETICONCOUNT; ++ico) { //if (grp->m_targetIcons[ico] == m_creature->GetGUID()) -- private member :( - pGrp->SetTargetIcon(ico, 0); + pGrp->SetTargetIcon(ico, 0, 0); } break; diff --git a/src/scripts/northrend/azjol_nerub/ahnkahet/boss_elder_nadox.cpp b/src/scripts/northrend/azjol_nerub/ahnkahet/boss_elder_nadox.cpp index f39ea93a11e..4451a190bf9 100644 --- a/src/scripts/northrend/azjol_nerub/ahnkahet/boss_elder_nadox.cpp +++ b/src/scripts/northrend/azjol_nerub/ahnkahet/boss_elder_nadox.cpp @@ -66,6 +66,8 @@ struct boss_elder_nadoxAI : public ScriptedAI uint32 swarmer_spawn_Timer; uint32 guard_spawn_Timer; uint32 enrage_Timer; + + bool GuardSpawned; ScriptedInstance *pInstance; @@ -80,6 +82,7 @@ struct boss_elder_nadoxAI : public ScriptedAI enrage_Timer = 5000; DeadAhnkaharGuardian = false; + GuardSpawned = false; if (pInstance) pInstance->SetData(DATA_ELDER_NADOX_EVENT, NOT_STARTED); @@ -156,11 +159,11 @@ struct boss_elder_nadoxAI : public ScriptedAI swarmer_spawn_Timer = 10000; } else swarmer_spawn_Timer -= diff; - if (guard_spawn_Timer <= diff) + if (!GuardSpawned && guard_spawn_Timer <= diff) { m_creature->MonsterTextEmote(EMOTE_HATCHES,m_creature->GetGUID(),true); DoCast(m_creature, SPELL_SUMMON_SWARM_GUARD); - guard_spawn_Timer = 25000; + GuardSpawned = true; } else guard_spawn_Timer -= diff; if (enrage_Timer <= diff) diff --git a/src/scripts/northrend/ulduar/halls_of_stone/halls_of_stone.cpp b/src/scripts/northrend/ulduar/halls_of_stone/halls_of_stone.cpp index 20f3b275d72..75f62af171a 100644 --- a/src/scripts/northrend/ulduar/halls_of_stone/halls_of_stone.cpp +++ b/src/scripts/northrend/ulduar/halls_of_stone/halls_of_stone.cpp @@ -104,12 +104,7 @@ enum Quests #define GOSSIP_ITEM_START "Brann, it would be our honor!" #define GOSSIP_ITEM_PROGRESS "Let's move Brann, enough of the history lessons!" -struct Locations -{ - float x, y, z; -}; - -static Locations SpawnLocations[]= +static Position SpawnLocations[]= { {946.992, 397.016, 208.374}, {960.748, 382.944, 208.374}, @@ -295,7 +290,6 @@ struct npc_brann_hosAI : public npc_escortAI case 13: DoScriptText(SAY_EVENT_INTRO_1, m_creature); SetEscortPaused(true); - SetRun(true); JumpToNextStep(20000); break; case 17: @@ -320,16 +314,16 @@ struct npc_brann_hosAI : public npc_escortAI { uint32 uiSpawnNumber = DUNGEON_MODE(2,3); for (uint8 i = 0; i < uiSpawnNumber; ++i) - m_creature->SummonCreature(CREATURE_DARK_RUNE_PROTECTOR, SpawnLocations[0].x, SpawnLocations[0].y, SpawnLocations[0].z, 0.0f, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 30000); - m_creature->SummonCreature(CREATURE_DARK_RUNE_STORMCALLER, SpawnLocations[0].x, SpawnLocations[0].y, SpawnLocations[0].z, 0.0f, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 30000); + m_creature->SummonCreature(CREATURE_DARK_RUNE_PROTECTOR, SpawnLocations[0], TEMPSUMMON_CORPSE_TIMED_DESPAWN, 30000); + m_creature->SummonCreature(CREATURE_DARK_RUNE_STORMCALLER, SpawnLocations[0], TEMPSUMMON_CORPSE_TIMED_DESPAWN, 30000); break; } case 2: for (uint8 i = 0; i < 2; ++i) - m_creature->SummonCreature(CREATURE_DARK_RUNE_STORMCALLER, SpawnLocations[1].x, SpawnLocations[1].y, SpawnLocations[1].z, 0.0f, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 30000); + m_creature->SummonCreature(CREATURE_DARK_RUNE_STORMCALLER, SpawnLocations[0], TEMPSUMMON_CORPSE_TIMED_DESPAWN, 30000); break; case 3: - m_creature->SummonCreature(CREATURE_IRON_GOLEM_CUSTODIAN, SpawnLocations[1].x, SpawnLocations[1].y, SpawnLocations[1].z, 0.0f, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 30000); + m_creature->SummonCreature(CREATURE_IRON_GOLEM_CUSTODIAN, SpawnLocations[0], TEMPSUMMON_CORPSE_TIMED_DESPAWN, 30000); break; } } @@ -370,6 +364,7 @@ struct npc_brann_hosAI : public npc_escortAI } bIsBattle = false; DoScriptText(SAY_ESCORT_START, m_creature); + SetRun(true); JumpToNextStep(0); break; case 3: diff --git a/src/scripts/northrend/ulduar/ulduar/boss_algalon.cpp b/src/scripts/northrend/ulduar/ulduar/boss_algalon.cpp index a9f1be65f2d..32b5190ccf4 100644 --- a/src/scripts/northrend/ulduar/ulduar/boss_algalon.cpp +++ b/src/scripts/northrend/ulduar/ulduar/boss_algalon.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008 - 2009 Trinity <http://www.trinitycore.org/> + * Copyright (C) 2008 - 2010 Trinity <http://www.trinitycore.org/> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -18,3 +18,343 @@ #include "ScriptedPch.h" #include "ulduar.h" + +#define GAMEOBJECT_GIVE_OF_THE_OBSERVER 194821 + +enum Spells +{ + SPELL_ASCEND = 64487, + SPELL_BERSERK = 47008, + SPELL_BIG_BANG = 64443, + H_SPELL_BIG_BANG = 64584, + SPELL_COSMIC_SMASH = 62301, + H_SPELL_COSMIC_SMASH = 64598, + SPELL_PHASE_PUNCH = 64412, + SPELL_QUANTUM_STRIKE = 64395, + H_SPELL_QUANTUM_STRIKE = 64592, + SPELL_BLACK_HOLE_EXPLOSION = 64122, + SPELL_ARCANE_BARAGE = 64599, + H_SPELL_ARCANE_BARAGE = 64607 +}; + +enum Creatures +{ + CREATURE_COLLAPSING_STAR = 32955, + CREATURE_BLACK_HOLE = 32953, + CREATURE_LIVING_CONSTELLATION = 33052, + CREATURE_DARK_MATTER = 33089 +}; + +#define NORDRASSIL_X 1614.288574 +#define NORDRASSIL_Y -320.713287 +#define NORDRASSIL_Z 417.321167 +#define NORDRASSIL_X 1614.276245 +#define NORDRASSIL_Y -287.016632 +#define NORDRASSIL_Z 417.321106 +#define NORDRASSIL_X 1650.428467 +#define NORDRASSIL_Y -292.331390 +#define NORDRASSIL_Z 417.321167 +#define NORDRASSIL_X 1649.501831 +#define NORDRASSIL_Y -324.609222 +#define NORDRASSIL_Z 417.322174 + +enum Texts +{ + SAY_AGGRO = -1620000, + SAY_KILL_1 = -1620005, + SAY_KILL_2 = -1620006, + SAY_BIG_BANG_1 = -1620002, + SAY_BIG_BANG_2 = -1620003, + SAY_PHASE_2 = -1620003, + SAY_BLACK_HOLE = -1620004, + SAY_BERSERK = -1620007, + SAY_SUMMON_COLLAPSING_STAR = -1620008, + SAY_ENGADED_FOR_FIRTS_TIME = -1620001, + SAY_SUMMON1 = -1620010, + SAY_SUMMON2 = -1620011, + SAY_SUMMON3 = -1620012, + SAY_DEATH_1 = -1620013, + SAY_DEATH_2 = -1620014, + SAY_DEATH_3 = -1620015, + SAY_DEATH_4 = -1620009, + SAY_DEFEAT_1 = -1620016, + SAY_DEFEAT_2 = -1620017, + SAY_DEFEAT_3 = -1620018 +}; + +struct boss_algalonAI : public ScriptedAI +{ + boss_algalonAI(Creature *c) : ScriptedAI(c) + { + pInstance = c->GetInstanceData(); + } + + ScriptedInstance* pInstance; + + std::list<uint64> m_lCollapsingStarGUIDList; + + uint32 Phase; + uint32 Ascend_Timer; + uint32 Berserk_Timer; + uint32 BigBang_Timer; + uint32 CosmicSmash_Timer; + uint32 PhasePunch_Timer; + uint32 QuantumStrike_Timer; + uint32 CollapsingStar_Timer; + uint32 uiPhase_timer; + uint32 uiStep; + + uint64 BlackHoleGUID; + + bool Enrage; + bool m_bIsHeroicMode; + bool Summon; + + void EnterCombat(Unit* who) + { + me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + me->SetReactState(REACT_PASSIVE); + } + + void KilledUnit(Unit *victim) + { + DoScriptText(RAND(SAY_KILL_1,SAY_KILL_2), me); + } + + void Reset() + { + Phase = 1; + + me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + DoScriptText(SAY_DEFEAT_1, me); + DoScriptText(SAY_DEFEAT_2, me); + DoScriptText(SAY_DEFEAT_3, me); + if (pInstance) + pInstance->SetData(TYPE_ALGALON, NOT_STARTED); + + BlackHoleGUID = 0; + + Ascend_Timer = 480000; //8 minutes + QuantumStrike_Timer = 4000 + rand()%10000; + Berserk_Timer = 360000; //6 minutes + CollapsingStar_Timer = urand(15000, 20000); //Spawns between 15 to 20 seconds + BigBang_Timer = 90000; + PhasePunch_Timer = 8000; + CosmicSmash_Timer = urand(30000, 60000); + } + + void JumpToNextStep(uint32 uiTimer) + { + uiPhase_timer = uiTimer; + ++uiStep; + } + + void Aggro(Unit* pWho) + { + me->InterruptSpell(CURRENT_CHANNELED_SPELL); + me->SetInCombatWithZone(); + if (pInstance) + pInstance->SetData(TYPE_ALGALON, IN_PROGRESS); + } + + void DespawnCollapsingStar() + { + if (m_lCollapsingStarGUIDList.empty()) + return; + for(std::list<uint64>::iterator itr = m_lCollapsingStarGUIDList.begin(); itr != m_lCollapsingStarGUIDList.end(); ++itr) + { + if (Creature* pTemp = (Creature*)Unit::GetUnit(*me, *itr)) + { + if (pTemp->isAlive()) + pTemp->ForcedDespawn(); + } + } + m_lCollapsingStarGUIDList.clear(); + } + + void JustSummoned(Creature* pSummoned) + { + if (pSummoned->GetEntry() == CREATURE_COLLAPSING_STAR) + { + Unit* pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0); + if (me->getVictim()) + pSummoned->AI()->AttackStart(pTarget ? pTarget : me->getVictim()); + m_lCollapsingStarGUIDList.push_back(pSummoned->GetGUID()); + } + } + + void SummonCollapsingStar(Unit* target) + { + DoScriptText(SAY_SUMMON_COLLAPSING_STAR, me); + me->SummonCreature(CREATURE_COLLAPSING_STAR,target->GetPositionX()+15.0,target->GetPositionY()+15.0,target->GetPositionZ(),0, TEMPSUMMON_TIMED_DESPAWN, 100000); + DoScriptText(SAY_BLACK_HOLE, me); + me->SummonCreature(CREATURE_BLACK_HOLE,target->GetPositionX()+15.0,target->GetPositionY()+15.0,target->GetPositionZ(),0, TEMPSUMMON_TIMED_DESPAWN, 27000); + } + + void UpdateAI(const uint32 diff) + { + //Return since we have no target + if (!UpdateVictim()) + return; + + if ((me->GetHealth()*100 / me->GetMaxHealth()) < 20 && Phase == 1) + { + Phase = 2; + DoScriptText(SAY_PHASE_2, me); + } + + if ((me->GetHealth()*100 / me->GetMaxHealth()) < 2) + { + me->SummonGameObject(GAMEOBJECT_GIVE_OF_THE_OBSERVER, 1634.258667, -295.101166,417.321381,0,0,0,0,0,-10); + + DoScriptText(SAY_DEATH_1, me); + DoScriptText(SAY_DEATH_2, me); + DoScriptText(SAY_DEATH_3, me); + DoScriptText(SAY_DEATH_4, me); + + me->DisappearAndDie(); + + if (pInstance) + pInstance->SetData(TYPE_ALGALON, DONE); + } + + if (Phase == 1) + { + if (!Summon) + { + if (uiPhase_timer <= diff) + { + switch(uiStep) + { + case 1: DoScriptText(SAY_SUMMON1, m_creature); break; JumpToNextStep(3000); + case 2: DoScriptText(SAY_SUMMON2, m_creature); break; JumpToNextStep(3000); + case 3: DoScriptText(SAY_SUMMON3, m_creature); break; JumpToNextStep(3000); + case 4: DoScriptText(SAY_ENGADED_FOR_FIRTS_TIME, m_creature); break; JumpToNextStep(3000); + case 5: DoScriptText(SAY_AGGRO, m_creature); break; + case 6: m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); break; + case 7: m_creature->SetReactState(REACT_AGGRESSIVE); break; + } + }else uiPhase_timer -= diff; + } + + if(QuantumStrike_Timer <= diff) + { + DoCast(me->getVictim(), m_bIsHeroicMode ? H_SPELL_QUANTUM_STRIKE : SPELL_QUANTUM_STRIKE, true); + + QuantumStrike_Timer = 4000 + rand()%10000; + }else QuantumStrike_Timer -= diff; + + if(BigBang_Timer <= diff) + { + DoScriptText(RAND(SAY_BIG_BANG_1,SAY_BIG_BANG_2), me); + DoCast(me->getVictim(), m_bIsHeroicMode ? H_SPELL_BIG_BANG : SPELL_BIG_BANG, true); + + BigBang_Timer = 90000; + }else BigBang_Timer -= diff; + + if(Ascend_Timer <= diff) + { + DoCast(me->getVictim(),SPELL_ASCEND, true); + + Ascend_Timer = 480000; + }else Ascend_Timer -= diff; + + if(PhasePunch_Timer <= diff) + { + DoCast(me->getVictim(),SPELL_PHASE_PUNCH, true); + + PhasePunch_Timer = 8000; + }else PhasePunch_Timer -= diff; + + if(CosmicSmash_Timer <= diff) + { + DoCast(SelectUnit(SELECT_TARGET_RANDOM, 0), m_bIsHeroicMode ? H_SPELL_COSMIC_SMASH : SPELL_COSMIC_SMASH, true); + + CosmicSmash_Timer = urand(30000, 60000); + }else CosmicSmash_Timer -= diff; + + if(Berserk_Timer <= diff) + { + DoScriptText(SAY_BERSERK, me); + DoCast(me->getVictim(),SPELL_BERSERK, true); + + Berserk_Timer = 360000; + }else Berserk_Timer -= diff; + + DoMeleeAttackIfReady(); + + EnterEvadeIfOutOfCombatArea(diff); + } + + if (Phase == 2) + { + if (Enrage) + { + if (Ascend_Timer <= diff) + { + DoCast(me, SPELL_ASCEND); + DoScriptText(SAY_BERSERK, me); + Ascend_Timer = 360000 + rand()%5000; + Enrage = false; + } else Ascend_Timer -= diff; + } + } + + DoMeleeAttackIfReady(); + } +}; +//Collapsing Star +struct mob_collapsing_starAI : public ScriptedAI +{ + mob_collapsing_starAI(Creature *pCreature) : ScriptedAI(pCreature) + { + pInstance = (ScriptedInstance*)pCreature->GetInstanceData(); + Reset(); + } + + ScriptedInstance* pInstance; + + uint32 BlackHoleExplosion_Timer; + + void Reset() + { + BlackHoleExplosion_Timer = 0; + } + + void UpdateAI(const uint32 diff) + { + if (!UpdateVictim()) + return; + + if(BlackHoleExplosion_Timer <= diff) + { + me->CastSpell(me, SPELL_BLACK_HOLE_EXPLOSION, false); + BlackHoleExplosion_Timer = 0; + }else BlackHoleExplosion_Timer -= diff; + } +}; + +CreatureAI* GetAI_boss_algalon(Creature* pCreature) +{ + return new boss_algalonAI(pCreature); +} + +CreatureAI* GetAI_mob_collapsing_star(Creature* pCreature) +{ + return new mob_collapsing_starAI(pCreature); +} + +void AddSC_boss_Algalon() +{ + Script *newscript; + + newscript = new Script; + newscript->Name = "boss_algalon"; + newscript->GetAI = &GetAI_boss_algalon; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "mob_collapsing_star"; + newscript->GetAI = &GetAI_mob_collapsing_star; + newscript->RegisterSelf(); +} diff --git a/src/scripts/outland/boss_doomlord_kazzak.cpp b/src/scripts/outland/boss_doomlord_kazzak.cpp index 7b7d22a395a..2d2339d2c26 100644 --- a/src/scripts/outland/boss_doomlord_kazzak.cpp +++ b/src/scripts/outland/boss_doomlord_kazzak.cpp @@ -23,18 +23,18 @@ EndScriptData */ #include "ScriptedPch.h" -#define SAY_INTRO -1000375 //signed for 3465 -#define SAY_AGGRO1 -1000376 //signed for 3465 -#define SAY_AGGRO2 -1000377 //signed for 3465 -#define SAY_SURPREME1 -1000378 //signed for 3465 -#define SAY_SURPREME2 -1000379 //signed for 3465 -#define SAY_KILL1 -1000380 //signed for 3465 -#define SAY_KILL2 -1000381 //signed for 21027 -#define SAY_KILL3 -1000382 //signed for 21027 -#define SAY_DEATH -1000383 //signed for 21027 -#define EMOTE_FRENZY -1000384 //signed for 21027 -#define SAY_RAND1 -1000385 //signed for 21027 -#define SAY_RAND2 -1000386 //signed for 21027 +#define SAY_INTRO -1000147 +#define SAY_AGGRO1 -1000148 +#define SAY_AGGRO2 -1000149 +#define SAY_SURPREME1 -1000154 +#define SAY_SURPREME2 -1000149 +#define SAY_KILL1 -1000150 +#define SAY_KILL2 -1000151 +#define SAY_KILL3 -1000152 +#define SAY_DEATH -1000155 +#define EMOTE_FRENZY -1000151 +#define SAY_RAND1 -1000158 +#define SAY_RAND2 -1000157 #define SPELL_SHADOWVOLLEY 32963 #define SPELL_CLEAVE 31779 diff --git a/src/scripts/outland/boss_doomwalker.cpp b/src/scripts/outland/boss_doomwalker.cpp index e0db99ec196..761f9e22289 100644 --- a/src/scripts/outland/boss_doomwalker.cpp +++ b/src/scripts/outland/boss_doomwalker.cpp @@ -23,15 +23,15 @@ EndScriptData */ #include "ScriptedPch.h" -#define SAY_AGGRO -1000387 //signed for 21027 -#define SAY_EARTHQUAKE_1 -1000388 //signed for 21027 -#define SAY_EARTHQUAKE_2 -1000389 //signed for 21027 -#define SAY_OVERRUN_1 -1000390 //signed for 21027 -#define SAY_OVERRUN_2 -1000391 //signed for 5955 -#define SAY_SLAY_1 -1000392 //signed for 5955 -#define SAY_SLAY_2 -1000393 //signed for 5955 -#define SAY_SLAY_3 -1000394 //signed for 5955 -#define SAY_DEATH -1000395 //signed for 5955 +#define SAY_AGGRO -1000159 +#define SAY_EARTHQUAKE_1 -1000160 +#define SAY_EARTHQUAKE_2 -1000161 +#define SAY_OVERRUN_1 -1000162 +#define SAY_OVERRUN_2 -1000163 +#define SAY_SLAY_1 -1000164 +#define SAY_SLAY_2 -1000165 +#define SAY_SLAY_3 -1000166 +#define SAY_DEATH -1000167 #define SPELL_EARTHQUAKE 32686 #define SPELL_SUNDER_ARMOR 33661 diff --git a/src/shared/Database/SQLStorage.cpp b/src/shared/Database/SQLStorage.cpp index e36297ed35b..01b3e283250 100644 --- a/src/shared/Database/SQLStorage.cpp +++ b/src/shared/Database/SQLStorage.cpp @@ -27,17 +27,17 @@ extern DatabasePostgre WorldDatabase; extern DatabaseMysql WorldDatabase; #endif -const char CreatureInfosrcfmt[]="iiiiiiiiiisssiiiiiiiffiffiifiiiiiiiiiiffiiiiiiiiiiiiiiiiiiiiiiiisiifffliiiiiiiliiis"; -const char CreatureInfodstfmt[]="iiiiiiiiiisssiiiiiiiffiffiifiiiiiiiiiiffiiiiiiiiiiiiiiiiiiiiiiiisiifffliiiiiiiliiii"; +const char CreatureInfosrcfmt[]="iiiiiiiiiisssiiiiiiiffiffiifiiiiiiiiiiffiiiiiiiiiiiiiiiiiiiiiiiisiifffliiiiiiiliiisi"; +const char CreatureInfodstfmt[]="iiiiiiiiiisssiiiiiiiffiffiifiiiiiiiiiiffiiiiiiiiiiiiiiiiiiiiiiiisiifffliiiiiiiliiiii"; const char CreatureDataAddonInfofmt[]="iiiiiis"; const char CreatureModelfmt[]="iffbi"; const char CreatureInfoAddonInfofmt[]="iiiiiis"; const char EquipmentInfofmt[]="iiii"; -const char GameObjectInfosrcfmt[]="iiissssiifiiiiiiiiiiiiiiiiiiiiiiiiiiiiiis"; -const char GameObjectInfodstfmt[]="iiissssiifiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii"; -const char ItemPrototypesrcfmt[]="iiiisiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiffiffiiiiiiiiiifiiifiiiiiifiiiiiifiiiiiifiiiiiifiiiisiiiiiiiiiiiiiiiiiiiiiiiiifiiisiiii"; -const char ItemPrototypedstfmt[]="iiiisiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiffiffiiiiiiiiiifiiifiiiiiifiiiiiifiiiiiifiiiiiifiiiisiiiiiiiiiiiiiiiiiiiiiiiiifiiiiiiii"; -const char PageTextfmt[]="isi"; +const char GameObjectInfosrcfmt[]="iiissssiifiiiiiiiiiiiiiiiiiiiiiiiiiiiiiisi"; +const char GameObjectInfodstfmt[]="iiissssiifiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii"; +const char ItemPrototypesrcfmt[]="iiiisiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiffiffiiiiiiiiiifiiifiiiiiifiiiiiifiiiiiifiiiiiifiiiisiiiiiiiiiiiiiiiiiiiiiiiiifiiisiiiii"; +const char ItemPrototypedstfmt[]="iiiisiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiffiffiiiiiiiiiifiiifiiiiiifiiiiiifiiiiiifiiiiiifiiiisiiiiiiiiiiiiiiiiiiiiiiiiifiiiiiiiii"; +const char PageTextfmt[]="isii"; const char InstanceTemplatesrcfmt[]="iiiffffs"; const char InstanceTemplatedstfmt[]="iiiffffi"; diff --git a/src/trinitycore/trinitycore.conf.dist b/src/trinitycore/trinitycore.conf.dist index e8bfddbd39f..a812ec13abe 100644 --- a/src/trinitycore/trinitycore.conf.dist +++ b/src/trinitycore/trinitycore.conf.dist @@ -1686,6 +1686,19 @@ BattleGround.PremadeGroupWaitForMatch = 1800000 # Default: 1 (active) # 0 (finished) # +# Arena.ArenaStartRating +# Start arena team command rating +# Default: 1500 +# +# Arena.StartPersonalRating +# Start personal rating on entry in team +# Default: 1500 +# +# Arena.LK.ArenasEnable +# Enable or Disable new WoTLK Arenas: Ring of Valor and Dalaran Sewers. These arenas have a problem of Line of The Side. +# Default: 0 (Disable) +# 1 (Enable) +# ############################################################################### Arena.MaxRatingDifference = 150 @@ -1696,7 +1709,9 @@ Arena.QueueAnnouncer.Enable = 0 Arena.QueueAnnouncer.PlayerOnly = 0 Arena.ArenaSeason.ID = 1 Arena.ArenaSeason.InProgress = 1 - +Arena.ArenaStartRating = 0 +Arena.ArenaStartPersonalRating = 0 +Arena.LK.ArenasEnable = 0 ############################################################################### # NETWORK CONFIG diff --git a/src/trinityrealm/AuthCodes.h b/src/trinityrealm/AuthCodes.h index db0f1d8196a..3cc373ed6e7 100644 --- a/src/trinityrealm/AuthCodes.h +++ b/src/trinityrealm/AuthCodes.h @@ -72,8 +72,13 @@ enum LoginResult //2.4.3 build 8606 //3.1.3 build 9947 //3.1.3 build 10146 Chinese build +//3.2.2a build 10505 +//3.3.0a build 11159 +//3.3.2 build 11403 -#define POST_BC_ACCEPTED_CLIENT_BUILD {10505, 10146, 9947, 8606, 0} +//original code +#define EXPECTED_TRINITY_CLIENT_BUILD {10571, 10505, 10146, 9947, 8606, 5875, 6005, 0} + +#define POST_BC_ACCEPTED_CLIENT_BUILD {11403, 11159, 10571, 10505, 10146, 9947, 8606, 0} //Maybe wrong? #define PRE_BC_ACCEPTED_CLIENT_BUILD {5875, 6005, 0} #define POST_BC_EXP_FLAG 0x2 diff --git a/src/trinityrealm/AuthSocket.cpp b/src/trinityrealm/AuthSocket.cpp index b5fe5f040c1..c9b88833667 100644 --- a/src/trinityrealm/AuthSocket.cpp +++ b/src/trinityrealm/AuthSocket.cpp @@ -361,6 +361,11 @@ bool AuthSocket::_HandleLogonChallenge() buf[buf.size() - 1] = 0; sAuthLogonChallenge_C *ch = (sAuthLogonChallenge_C*)&buf[0]; + ///- Read the remaining of the packet + ibuf.Read((char *)&buf[4], remaining); + DEBUG_LOG("[AuthChallenge] got full packet, %#04x bytes", ch->size); + DEBUG_LOG("[AuthChallenge] name(%d): '%s'", ch->I_len, ch->I); + // BigEndian code, nop in little endian case // size already converted EndianConvert(*((uint32*)(&ch->gamename[0]))); @@ -371,11 +376,6 @@ bool AuthSocket::_HandleLogonChallenge() EndianConvert(ch->timezone_bias); EndianConvert(ch->ip); - ///- Read the remaining of the packet - ibuf.Read((char *)&buf[4], remaining); - DEBUG_LOG("[AuthChallenge] got full packet, %#04x bytes", ch->size); - DEBUG_LOG("[AuthChallenge] name(%d): '%s'", ch->I_len, ch->I); - ByteBuffer pkt; _login = (const char*)ch->I; @@ -410,7 +410,7 @@ bool AuthSocket::_HandleLogonChallenge() ///- Get the account details from the account table // No SQL injection (escaped user name) - result = + result = loginDatabase.PQuery("SELECT a.sha_pass_hash,a.id,a.locked,a.last_ip,aa.gmlevel,a.v,a.s " "FROM account a " "LEFT JOIN account_access aa " |