mirror of
https://github.com/mangosfour/server.git
synced 2025-12-13 04:37:00 +00:00
Many, many cmangos Cata commits applied
The following commits were either applied or found not to be applicable:
This commit is contained in:
parent
32a26f44c7
commit
a800f3b1ad
100 changed files with 2385 additions and 1305 deletions
|
|
@ -213,32 +213,32 @@ BattleGround::BattleGround()
|
||||||
m_MapId = 0;
|
m_MapId = 0;
|
||||||
m_Map = NULL;
|
m_Map = NULL;
|
||||||
|
|
||||||
m_TeamStartLocX[BG_TEAM_ALLIANCE] = 0;
|
m_TeamStartLocX[TEAM_INDEX_ALLIANCE] = 0;
|
||||||
m_TeamStartLocX[BG_TEAM_HORDE] = 0;
|
m_TeamStartLocX[TEAM_INDEX_HORDE] = 0;
|
||||||
|
|
||||||
m_TeamStartLocY[BG_TEAM_ALLIANCE] = 0;
|
m_TeamStartLocY[TEAM_INDEX_ALLIANCE] = 0;
|
||||||
m_TeamStartLocY[BG_TEAM_HORDE] = 0;
|
m_TeamStartLocY[TEAM_INDEX_HORDE] = 0;
|
||||||
|
|
||||||
m_TeamStartLocZ[BG_TEAM_ALLIANCE] = 0;
|
m_TeamStartLocZ[TEAM_INDEX_ALLIANCE] = 0;
|
||||||
m_TeamStartLocZ[BG_TEAM_HORDE] = 0;
|
m_TeamStartLocZ[TEAM_INDEX_HORDE] = 0;
|
||||||
|
|
||||||
m_TeamStartLocO[BG_TEAM_ALLIANCE] = 0;
|
m_TeamStartLocO[TEAM_INDEX_ALLIANCE] = 0;
|
||||||
m_TeamStartLocO[BG_TEAM_HORDE] = 0;
|
m_TeamStartLocO[TEAM_INDEX_HORDE] = 0;
|
||||||
|
|
||||||
m_ArenaTeamIds[BG_TEAM_ALLIANCE] = 0;
|
m_ArenaTeamIds[TEAM_INDEX_ALLIANCE] = 0;
|
||||||
m_ArenaTeamIds[BG_TEAM_HORDE] = 0;
|
m_ArenaTeamIds[TEAM_INDEX_HORDE] = 0;
|
||||||
|
|
||||||
m_ArenaTeamRatingChanges[BG_TEAM_ALLIANCE] = 0;
|
m_ArenaTeamRatingChanges[TEAM_INDEX_ALLIANCE] = 0;
|
||||||
m_ArenaTeamRatingChanges[BG_TEAM_HORDE] = 0;
|
m_ArenaTeamRatingChanges[TEAM_INDEX_HORDE] = 0;
|
||||||
|
|
||||||
m_BgRaids[BG_TEAM_ALLIANCE] = NULL;
|
m_BgRaids[TEAM_INDEX_ALLIANCE] = NULL;
|
||||||
m_BgRaids[BG_TEAM_HORDE] = NULL;
|
m_BgRaids[TEAM_INDEX_HORDE] = NULL;
|
||||||
|
|
||||||
m_PlayersCount[BG_TEAM_ALLIANCE] = 0;
|
m_PlayersCount[TEAM_INDEX_ALLIANCE] = 0;
|
||||||
m_PlayersCount[BG_TEAM_HORDE] = 0;
|
m_PlayersCount[TEAM_INDEX_HORDE] = 0;
|
||||||
|
|
||||||
m_TeamScores[BG_TEAM_ALLIANCE] = 0;
|
m_TeamScores[TEAM_INDEX_ALLIANCE] = 0;
|
||||||
m_TeamScores[BG_TEAM_HORDE] = 0;
|
m_TeamScores[TEAM_INDEX_HORDE] = 0;
|
||||||
|
|
||||||
m_PrematureCountDown = false;
|
m_PrematureCountDown = false;
|
||||||
m_PrematureCountDownTimer = 0;
|
m_PrematureCountDownTimer = 0;
|
||||||
|
|
@ -459,6 +459,14 @@ void BattleGround::Update(uint32 diff)
|
||||||
/*********************************************************/
|
/*********************************************************/
|
||||||
/*** BATTLEGROUND ENDING SYSTEM ***/
|
/*** BATTLEGROUND ENDING SYSTEM ***/
|
||||||
/*********************************************************/
|
/*********************************************************/
|
||||||
|
if (GetStatus() == STATUS_IN_PROGRESS && isArena())
|
||||||
|
{
|
||||||
|
// after 45 minutes without one team losing, the arena closes with no winner and -16 rating change for both
|
||||||
|
if (m_StartTime > uint32(m_StartDelayTimes[BG_STARTING_EVENT_FIRST] + ARENA_FORCED_DRAW))
|
||||||
|
{
|
||||||
|
EndBattleGround(TEAM_NONE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (GetStatus() == STATUS_WAIT_LEAVE)
|
if (GetStatus() == STATUS_WAIT_LEAVE)
|
||||||
{
|
{
|
||||||
|
|
@ -485,7 +493,7 @@ void BattleGround::Update(uint32 diff)
|
||||||
|
|
||||||
void BattleGround::SetTeamStartLoc(Team team, float X, float Y, float Z, float O)
|
void BattleGround::SetTeamStartLoc(Team team, float X, float Y, float Z, float O)
|
||||||
{
|
{
|
||||||
BattleGroundTeamIndex teamIdx = GetTeamIndexByTeamId(team);
|
PvpTeamIndex teamIdx = GetTeamIndexByTeamId(team);
|
||||||
m_TeamStartLocX[teamIdx] = X;
|
m_TeamStartLocX[teamIdx] = X;
|
||||||
m_TeamStartLocY[teamIdx] = Y;
|
m_TeamStartLocY[teamIdx] = Y;
|
||||||
m_TeamStartLocZ[teamIdx] = Z;
|
m_TeamStartLocZ[teamIdx] = Z;
|
||||||
|
|
@ -1322,18 +1330,20 @@ void BattleGround::AddOrSetPlayerToCorrectBgGroup(Player* plr, ObjectGuid plr_gu
|
||||||
}
|
}
|
||||||
|
|
||||||
// This method should be called when player logs into running battleground
|
// This method should be called when player logs into running battleground
|
||||||
void BattleGround::EventPlayerLoggedIn(Player* player, ObjectGuid plr_guid)
|
void BattleGround::EventPlayerLoggedIn(Player* player)
|
||||||
{
|
{
|
||||||
|
ObjectGuid playerGuid = player->GetObjectGuid();
|
||||||
|
|
||||||
// player is correct pointer
|
// player is correct pointer
|
||||||
for (OfflineQueue::iterator itr = m_OfflineQueue.begin(); itr != m_OfflineQueue.end(); ++itr)
|
for (OfflineQueue::iterator itr = m_OfflineQueue.begin(); itr != m_OfflineQueue.end(); ++itr)
|
||||||
{
|
{
|
||||||
if (*itr == plr_guid)
|
if (*itr == playerGuid)
|
||||||
{
|
{
|
||||||
m_OfflineQueue.erase(itr);
|
m_OfflineQueue.erase(itr);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
m_Players[plr_guid].OfflineRemoveTime = 0;
|
m_Players[playerGuid].OfflineRemoveTime = 0;
|
||||||
PlayerAddedToBGCheckIfBGIsRunning(player);
|
PlayerAddedToBGCheckIfBGIsRunning(player);
|
||||||
// if battleground is starting, then add preparation aura
|
// if battleground is starting, then add preparation aura
|
||||||
// we don't have to do that, because preparation aura isn't removed when player logs out
|
// we don't have to do that, because preparation aura isn't removed when player logs out
|
||||||
|
|
@ -1783,7 +1793,7 @@ WorldSafeLocsEntry const* BattleGround::GetClosestGraveYard(Player* player)
|
||||||
|
|
||||||
bool BattleGround::IsTeamScoreInRange(Team team, uint32 minScore, uint32 maxScore) const
|
bool BattleGround::IsTeamScoreInRange(Team team, uint32 minScore, uint32 maxScore) const
|
||||||
{
|
{
|
||||||
BattleGroundTeamIndex team_idx = GetTeamIndexByTeamId(team);
|
PvpTeamIndex team_idx = GetTeamIndexByTeamId(team);
|
||||||
uint32 score = (m_TeamScores[team_idx] < 0) ? 0 : uint32(m_TeamScores[team_idx]);
|
uint32 score = (m_TeamScores[team_idx] < 0) ? 0 : uint32(m_TeamScores[team_idx]);
|
||||||
return score >= minScore && score <= maxScore;
|
return score >= minScore && score <= maxScore;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -112,13 +112,14 @@ enum BattleGroundTimeIntervals
|
||||||
{
|
{
|
||||||
RESURRECTION_INTERVAL = 30000, // ms
|
RESURRECTION_INTERVAL = 30000, // ms
|
||||||
INVITATION_REMIND_TIME = 20000, // ms
|
INVITATION_REMIND_TIME = 20000, // ms
|
||||||
INVITE_ACCEPT_WAIT_TIME = 40000, // ms
|
INVITE_ACCEPT_WAIT_TIME = 60000, // ms
|
||||||
TIME_TO_AUTOREMOVE = 120000, // ms
|
TIME_TO_AUTOREMOVE = 120000, // ms
|
||||||
MAX_OFFLINE_TIME = 300, // secs
|
MAX_OFFLINE_TIME = 300, // secs
|
||||||
RESPAWN_ONE_DAY = 86400, // secs
|
RESPAWN_ONE_DAY = 86400, // secs
|
||||||
RESPAWN_IMMEDIATELY = 0, // secs
|
RESPAWN_IMMEDIATELY = 0, // secs
|
||||||
BUFF_RESPAWN_TIME = 180, // secs
|
BUFF_RESPAWN_TIME = 180, // secs
|
||||||
ARENA_SPAWN_BUFF_OBJECTS = 90000, // ms - 90sec after start
|
ARENA_SPAWN_BUFF_OBJECTS = 90000, // ms - 90sec after start
|
||||||
|
ARENA_FORCED_DRAW = 2700000, // ms - 45min after start
|
||||||
BATTLEGROUND_COUNTDOWN_MAX = 120, // secs
|
BATTLEGROUND_COUNTDOWN_MAX = 120, // secs
|
||||||
ARENA_COUNTDOWN_MAX = 60, // secs
|
ARENA_COUNTDOWN_MAX = 60, // secs
|
||||||
};
|
};
|
||||||
|
|
@ -212,14 +213,6 @@ enum BattleGroundType
|
||||||
TYPE_ARENA = 4
|
TYPE_ARENA = 4
|
||||||
};
|
};
|
||||||
|
|
||||||
enum BattleGroundTeamIndex
|
|
||||||
{
|
|
||||||
BG_TEAM_ALLIANCE = 0,
|
|
||||||
BG_TEAM_HORDE = 1
|
|
||||||
};
|
|
||||||
|
|
||||||
#define BG_TEAMS_COUNT 2
|
|
||||||
|
|
||||||
enum BattleGroundStartingEvents
|
enum BattleGroundStartingEvents
|
||||||
{
|
{
|
||||||
BG_STARTING_EVENT_NONE = 0x00,
|
BG_STARTING_EVENT_NONE = 0x00,
|
||||||
|
|
@ -432,7 +425,7 @@ class BattleGround
|
||||||
void SetTeamStartLoc(Team team, float X, float Y, float Z, float O);
|
void SetTeamStartLoc(Team team, float X, float Y, float Z, float O);
|
||||||
void GetTeamStartLoc(Team team, float& X, float& Y, float& Z, float& O) const
|
void GetTeamStartLoc(Team team, float& X, float& Y, float& Z, float& O) const
|
||||||
{
|
{
|
||||||
BattleGroundTeamIndex idx = GetTeamIndexByTeamId(team);
|
PvpTeamIndex idx = GetTeamIndexByTeamId(team);
|
||||||
X = m_TeamStartLocX[idx];
|
X = m_TeamStartLocX[idx];
|
||||||
Y = m_TeamStartLocY[idx];
|
Y = m_TeamStartLocY[idx];
|
||||||
Z = m_TeamStartLocZ[idx];
|
Z = m_TeamStartLocZ[idx];
|
||||||
|
|
@ -477,7 +470,7 @@ class BattleGround
|
||||||
|
|
||||||
virtual void UpdatePlayerScore(Player* Source, uint32 type, uint32 value);
|
virtual void UpdatePlayerScore(Player* Source, uint32 type, uint32 value);
|
||||||
|
|
||||||
static BattleGroundTeamIndex GetTeamIndexByTeamId(Team team) { return team == ALLIANCE ? BG_TEAM_ALLIANCE : BG_TEAM_HORDE; }
|
static PvpTeamIndex GetTeamIndexByTeamId(Team team) { return team == ALLIANCE ? TEAM_INDEX_ALLIANCE : TEAM_INDEX_HORDE; }
|
||||||
uint32 GetPlayersCountByTeam(Team team) const { return m_PlayersCount[GetTeamIndexByTeamId(team)]; }
|
uint32 GetPlayersCountByTeam(Team team) const { return m_PlayersCount[GetTeamIndexByTeamId(team)]; }
|
||||||
uint32 GetAlivePlayersCountByTeam(Team team) const; // used in arenas to correctly handle death in spirit of redemption / last stand etc. (killer = killed) cases
|
uint32 GetAlivePlayersCountByTeam(Team team) const; // used in arenas to correctly handle death in spirit of redemption / last stand etc. (killer = killed) cases
|
||||||
void UpdatePlayersCountByTeam(Team team, bool remove)
|
void UpdatePlayersCountByTeam(Team team, bool remove)
|
||||||
|
|
@ -518,7 +511,7 @@ class BattleGround
|
||||||
virtual void EventPlayerDroppedFlag(Player* /*player*/) {}
|
virtual void EventPlayerDroppedFlag(Player* /*player*/) {}
|
||||||
virtual void EventPlayerClickedOnFlag(Player* /*player*/, GameObject* /*target_obj*/) {}
|
virtual void EventPlayerClickedOnFlag(Player* /*player*/, GameObject* /*target_obj*/) {}
|
||||||
virtual void EventPlayerCapturedFlag(Player* /*player*/) {}
|
virtual void EventPlayerCapturedFlag(Player* /*player*/) {}
|
||||||
void EventPlayerLoggedIn(Player* player, ObjectGuid plr_guid);
|
void EventPlayerLoggedIn(Player* player);
|
||||||
void EventPlayerLoggedOut(Player* player);
|
void EventPlayerLoggedOut(Player* player);
|
||||||
|
|
||||||
/* Death related */
|
/* Death related */
|
||||||
|
|
@ -563,11 +556,11 @@ class BattleGround
|
||||||
Team GetPlayerTeam(ObjectGuid guid);
|
Team GetPlayerTeam(ObjectGuid guid);
|
||||||
uint32 GetRemainingTime() const { return m_EndTime; }
|
uint32 GetRemainingTime() const { return m_EndTime; }
|
||||||
static Team GetOtherTeam(Team team) { return team ? ((team == ALLIANCE) ? HORDE : ALLIANCE) : TEAM_NONE; }
|
static Team GetOtherTeam(Team team) { return team ? ((team == ALLIANCE) ? HORDE : ALLIANCE) : TEAM_NONE; }
|
||||||
static BattleGroundTeamIndex GetOtherTeamIndex(BattleGroundTeamIndex teamIdx) { return teamIdx == BG_TEAM_ALLIANCE ? BG_TEAM_HORDE : BG_TEAM_ALLIANCE; }
|
static PvpTeamIndex GetOtherTeamIndex(PvpTeamIndex teamIdx) { return teamIdx == TEAM_INDEX_ALLIANCE ? TEAM_INDEX_HORDE : TEAM_INDEX_ALLIANCE; }
|
||||||
bool IsPlayerInBattleGround(ObjectGuid guid);
|
bool IsPlayerInBattleGround(ObjectGuid guid);
|
||||||
|
|
||||||
/* virtual score-array - get's used in bg-subclasses */
|
/* virtual score-array - get's used in bg-subclasses */
|
||||||
int32 m_TeamScores[BG_TEAMS_COUNT];
|
int32 m_TeamScores[PVP_TEAM_COUNT];
|
||||||
|
|
||||||
struct EventObjects
|
struct EventObjects
|
||||||
{
|
{
|
||||||
|
|
@ -640,15 +633,15 @@ class BattleGround
|
||||||
uint32 m_InvitedHorde;
|
uint32 m_InvitedHorde;
|
||||||
|
|
||||||
/* Raid Group */
|
/* Raid Group */
|
||||||
Group* m_BgRaids[BG_TEAMS_COUNT]; // 0 - alliance, 1 - horde
|
Group* m_BgRaids[PVP_TEAM_COUNT]; // 0 - alliance, 1 - horde
|
||||||
|
|
||||||
/* Players count by team */
|
/* Players count by team */
|
||||||
uint32 m_PlayersCount[BG_TEAMS_COUNT];
|
uint32 m_PlayersCount[PVP_TEAM_COUNT];
|
||||||
|
|
||||||
/* Arena team ids by team */
|
/* Arena team ids by team */
|
||||||
uint32 m_ArenaTeamIds[BG_TEAMS_COUNT];
|
uint32 m_ArenaTeamIds[PVP_TEAM_COUNT];
|
||||||
|
|
||||||
int32 m_ArenaTeamRatingChanges[BG_TEAMS_COUNT];
|
int32 m_ArenaTeamRatingChanges[PVP_TEAM_COUNT];
|
||||||
|
|
||||||
/* Limits */
|
/* Limits */
|
||||||
uint32 m_LevelMin;
|
uint32 m_LevelMin;
|
||||||
|
|
@ -661,10 +654,10 @@ class BattleGround
|
||||||
/* Start location */
|
/* Start location */
|
||||||
uint32 m_MapId;
|
uint32 m_MapId;
|
||||||
BattleGroundMap* m_Map;
|
BattleGroundMap* m_Map;
|
||||||
float m_TeamStartLocX[BG_TEAMS_COUNT];
|
float m_TeamStartLocX[PVP_TEAM_COUNT];
|
||||||
float m_TeamStartLocY[BG_TEAMS_COUNT];
|
float m_TeamStartLocY[PVP_TEAM_COUNT];
|
||||||
float m_TeamStartLocZ[BG_TEAMS_COUNT];
|
float m_TeamStartLocZ[PVP_TEAM_COUNT];
|
||||||
float m_TeamStartLocO[BG_TEAMS_COUNT];
|
float m_TeamStartLocO[PVP_TEAM_COUNT];
|
||||||
};
|
};
|
||||||
|
|
||||||
// helper functions for world state list fill
|
// helper functions for world state list fill
|
||||||
|
|
|
||||||
|
|
@ -53,7 +53,7 @@ void BattleGroundAB::Update(uint32 diff)
|
||||||
|
|
||||||
if (GetStatus() == STATUS_IN_PROGRESS)
|
if (GetStatus() == STATUS_IN_PROGRESS)
|
||||||
{
|
{
|
||||||
int team_points[BG_TEAMS_COUNT] = { 0, 0 };
|
int team_points[PVP_TEAM_COUNT] = { 0, 0 };
|
||||||
|
|
||||||
for (uint8 node = 0; node < BG_AB_NODES_MAX; ++node)
|
for (uint8 node = 0; node < BG_AB_NODES_MAX; ++node)
|
||||||
{
|
{
|
||||||
|
|
@ -100,13 +100,13 @@ void BattleGroundAB::Update(uint32 diff)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (uint8 team = 0; team < BG_TEAMS_COUNT; ++team)
|
for (uint8 team = 0; team < PVP_TEAM_COUNT; ++team)
|
||||||
if (m_Nodes[node] == team + BG_AB_NODE_TYPE_OCCUPIED)
|
if (m_Nodes[node] == team + BG_AB_NODE_TYPE_OCCUPIED)
|
||||||
++team_points[team];
|
++team_points[team];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Accumulate points
|
// Accumulate points
|
||||||
for (uint8 team = 0; team < BG_TEAMS_COUNT; ++team)
|
for (uint8 team = 0; team < PVP_TEAM_COUNT; ++team)
|
||||||
{
|
{
|
||||||
int points = team_points[team];
|
int points = team_points[team];
|
||||||
if (!points)
|
if (!points)
|
||||||
|
|
@ -120,17 +120,17 @@ void BattleGroundAB::Update(uint32 diff)
|
||||||
m_ReputationScoreTics[team] += BG_AB_TickPoints[points];
|
m_ReputationScoreTics[team] += BG_AB_TickPoints[points];
|
||||||
if (m_ReputationScoreTics[team] >= m_ReputationTics)
|
if (m_ReputationScoreTics[team] >= m_ReputationTics)
|
||||||
{
|
{
|
||||||
(team == BG_TEAM_ALLIANCE) ? RewardReputationToTeam(509, 10, ALLIANCE) : RewardReputationToTeam(510, 10, HORDE);
|
(team == TEAM_INDEX_ALLIANCE) ? RewardReputationToTeam(509, 10, ALLIANCE) : RewardReputationToTeam(510, 10, HORDE);
|
||||||
m_ReputationScoreTics[team] -= m_ReputationTics;
|
m_ReputationScoreTics[team] -= m_ReputationTics;
|
||||||
}
|
}
|
||||||
if (m_honorScoreTicks[team] >= m_honorTicks)
|
if (m_honorScoreTicks[team] >= m_honorTicks)
|
||||||
{
|
{
|
||||||
RewardHonorToTeam(GetBonusHonorFromKill(1), (team == BG_TEAM_ALLIANCE) ? ALLIANCE : HORDE);
|
RewardHonorToTeam(GetBonusHonorFromKill(1), (team == TEAM_INDEX_ALLIANCE) ? ALLIANCE : HORDE);
|
||||||
m_honorScoreTicks[team] -= m_honorTicks;
|
m_honorScoreTicks[team] -= m_honorTicks;
|
||||||
}
|
}
|
||||||
if (!m_IsInformedNearVictory && m_TeamScores[team] > BG_AB_WARNING_NEAR_VICTORY_SCORE)
|
if (!m_IsInformedNearVictory && m_TeamScores[team] > BG_AB_WARNING_NEAR_VICTORY_SCORE)
|
||||||
{
|
{
|
||||||
if (team == BG_TEAM_ALLIANCE)
|
if (team == TEAM_INDEX_ALLIANCE)
|
||||||
SendMessageToAll(LANG_BG_AB_A_NEAR_VICTORY, CHAT_MSG_BG_SYSTEM_NEUTRAL);
|
SendMessageToAll(LANG_BG_AB_A_NEAR_VICTORY, CHAT_MSG_BG_SYSTEM_NEUTRAL);
|
||||||
else
|
else
|
||||||
SendMessageToAll(LANG_BG_AB_H_NEAR_VICTORY, CHAT_MSG_BG_SYSTEM_NEUTRAL);
|
SendMessageToAll(LANG_BG_AB_H_NEAR_VICTORY, CHAT_MSG_BG_SYSTEM_NEUTRAL);
|
||||||
|
|
@ -140,24 +140,24 @@ void BattleGroundAB::Update(uint32 diff)
|
||||||
|
|
||||||
if (m_TeamScores[team] > BG_AB_MAX_TEAM_SCORE)
|
if (m_TeamScores[team] > BG_AB_MAX_TEAM_SCORE)
|
||||||
m_TeamScores[team] = BG_AB_MAX_TEAM_SCORE;
|
m_TeamScores[team] = BG_AB_MAX_TEAM_SCORE;
|
||||||
if (team == BG_TEAM_ALLIANCE)
|
if (team == TEAM_INDEX_ALLIANCE)
|
||||||
UpdateWorldState(BG_AB_OP_RESOURCES_ALLY, m_TeamScores[team]);
|
UpdateWorldState(BG_AB_OP_RESOURCES_ALLY, m_TeamScores[team]);
|
||||||
if (team == BG_TEAM_HORDE)
|
if (team == TEAM_INDEX_HORDE)
|
||||||
UpdateWorldState(BG_AB_OP_RESOURCES_HORDE, m_TeamScores[team]);
|
UpdateWorldState(BG_AB_OP_RESOURCES_HORDE, m_TeamScores[team]);
|
||||||
|
|
||||||
// update achievement flags
|
// update achievement flags
|
||||||
// we increased m_TeamScores[team] so we just need to check if it is 500 more than other teams resources
|
// we increased m_TeamScores[team] so we just need to check if it is 500 more than other teams resources
|
||||||
// horde will be a bit disadvantaged, but we can assume that points aren't updated for both team in same Update() call
|
// horde will be a bit disadvantaged, but we can assume that points aren't updated for both team in same Update() call
|
||||||
uint8 otherTeam = (team + 1) % BG_TEAMS_COUNT;
|
uint8 otherTeam = (team + 1) % PVP_TEAM_COUNT;
|
||||||
if (m_TeamScores[team] > m_TeamScores[otherTeam] + 500)
|
if (m_TeamScores[team] > m_TeamScores[otherTeam] + 500)
|
||||||
m_TeamScores500Disadvantage[otherTeam] = true;
|
m_TeamScores500Disadvantage[otherTeam] = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test win condition
|
// Test win condition
|
||||||
if (m_TeamScores[BG_TEAM_ALLIANCE] >= BG_AB_MAX_TEAM_SCORE)
|
if (m_TeamScores[TEAM_INDEX_ALLIANCE] >= BG_AB_MAX_TEAM_SCORE)
|
||||||
EndBattleGround(ALLIANCE);
|
EndBattleGround(ALLIANCE);
|
||||||
if (m_TeamScores[BG_TEAM_HORDE] >= BG_AB_MAX_TEAM_SCORE)
|
if (m_TeamScores[TEAM_INDEX_HORDE] >= BG_AB_MAX_TEAM_SCORE)
|
||||||
EndBattleGround(HORDE);
|
EndBattleGround(HORDE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -277,8 +277,8 @@ void BattleGroundAB::FillInitialWorldStates(WorldPacket& data, uint32& count)
|
||||||
// Team scores
|
// Team scores
|
||||||
FillInitialWorldState(data, count, BG_AB_OP_RESOURCES_MAX, BG_AB_MAX_TEAM_SCORE);
|
FillInitialWorldState(data, count, BG_AB_OP_RESOURCES_MAX, BG_AB_MAX_TEAM_SCORE);
|
||||||
FillInitialWorldState(data, count, BG_AB_OP_RESOURCES_WARNING, BG_AB_WARNING_NEAR_VICTORY_SCORE);
|
FillInitialWorldState(data, count, BG_AB_OP_RESOURCES_WARNING, BG_AB_WARNING_NEAR_VICTORY_SCORE);
|
||||||
FillInitialWorldState(data, count, BG_AB_OP_RESOURCES_ALLY, m_TeamScores[BG_TEAM_ALLIANCE]);
|
FillInitialWorldState(data, count, BG_AB_OP_RESOURCES_ALLY, m_TeamScores[TEAM_INDEX_ALLIANCE]);
|
||||||
FillInitialWorldState(data, count, BG_AB_OP_RESOURCES_HORDE, m_TeamScores[BG_TEAM_HORDE]);
|
FillInitialWorldState(data, count, BG_AB_OP_RESOURCES_HORDE, m_TeamScores[TEAM_INDEX_HORDE]);
|
||||||
|
|
||||||
// other unknown
|
// other unknown
|
||||||
FillInitialWorldState(data, count, 0x745, 0x2); // 37 1861 unk
|
FillInitialWorldState(data, count, 0x745, 0x2); // 37 1861 unk
|
||||||
|
|
@ -333,7 +333,7 @@ void BattleGroundAB::EventPlayerClickedOnFlag(Player* source, GameObject* target
|
||||||
return;
|
return;
|
||||||
BG_AB_Nodes node = BG_AB_Nodes(event);
|
BG_AB_Nodes node = BG_AB_Nodes(event);
|
||||||
|
|
||||||
BattleGroundTeamIndex teamIndex = GetTeamIndexByTeamId(source->GetTeam());
|
PvpTeamIndex teamIndex = GetTeamIndexByTeamId(source->GetTeam());
|
||||||
|
|
||||||
// Check if player really could use this banner, not cheated
|
// Check if player really could use this banner, not cheated
|
||||||
if (!(m_Nodes[node] == 0 || teamIndex == m_Nodes[node] % 2))
|
if (!(m_Nodes[node] == 0 || teamIndex == m_Nodes[node] % 2))
|
||||||
|
|
@ -376,7 +376,7 @@ void BattleGroundAB::EventPlayerClickedOnFlag(Player* source, GameObject* target
|
||||||
_SendNodeUpdate(node);
|
_SendNodeUpdate(node);
|
||||||
m_NodeTimers[node] = BG_AB_FLAG_CAPTURING_TIME;
|
m_NodeTimers[node] = BG_AB_FLAG_CAPTURING_TIME;
|
||||||
|
|
||||||
if (teamIndex == BG_TEAM_ALLIANCE)
|
if (teamIndex == TEAM_INDEX_ALLIANCE)
|
||||||
SendMessage2ToAll(LANG_BG_AB_NODE_ASSAULTED, CHAT_MSG_BG_SYSTEM_ALLIANCE, source, _GetNodeNameId(node));
|
SendMessage2ToAll(LANG_BG_AB_NODE_ASSAULTED, CHAT_MSG_BG_SYSTEM_ALLIANCE, source, _GetNodeNameId(node));
|
||||||
else
|
else
|
||||||
SendMessage2ToAll(LANG_BG_AB_NODE_ASSAULTED, CHAT_MSG_BG_SYSTEM_HORDE, source, _GetNodeNameId(node));
|
SendMessage2ToAll(LANG_BG_AB_NODE_ASSAULTED, CHAT_MSG_BG_SYSTEM_HORDE, source, _GetNodeNameId(node));
|
||||||
|
|
@ -391,14 +391,14 @@ void BattleGroundAB::EventPlayerClickedOnFlag(Player* source, GameObject* target
|
||||||
_CreateBanner(node, BG_AB_NODE_TYPE_OCCUPIED, teamIndex, true);
|
_CreateBanner(node, BG_AB_NODE_TYPE_OCCUPIED, teamIndex, true);
|
||||||
_SendNodeUpdate(node);
|
_SendNodeUpdate(node);
|
||||||
m_NodeTimers[node] = 0;
|
m_NodeTimers[node] = 0;
|
||||||
_NodeOccupied(node, (teamIndex == BG_TEAM_ALLIANCE) ? ALLIANCE : HORDE);
|
_NodeOccupied(node, (teamIndex == TEAM_INDEX_ALLIANCE) ? ALLIANCE : HORDE);
|
||||||
|
|
||||||
if (teamIndex == BG_TEAM_ALLIANCE)
|
if (teamIndex == TEAM_INDEX_ALLIANCE)
|
||||||
SendMessage2ToAll(LANG_BG_AB_NODE_DEFENDED, CHAT_MSG_BG_SYSTEM_ALLIANCE, source, _GetNodeNameId(node));
|
SendMessage2ToAll(LANG_BG_AB_NODE_DEFENDED, CHAT_MSG_BG_SYSTEM_ALLIANCE, source, _GetNodeNameId(node));
|
||||||
else
|
else
|
||||||
SendMessage2ToAll(LANG_BG_AB_NODE_DEFENDED, CHAT_MSG_BG_SYSTEM_HORDE, source, _GetNodeNameId(node));
|
SendMessage2ToAll(LANG_BG_AB_NODE_DEFENDED, CHAT_MSG_BG_SYSTEM_HORDE, source, _GetNodeNameId(node));
|
||||||
}
|
}
|
||||||
sound = (teamIndex == BG_TEAM_ALLIANCE) ? BG_AB_SOUND_NODE_ASSAULTED_ALLIANCE : BG_AB_SOUND_NODE_ASSAULTED_HORDE;
|
sound = (teamIndex == TEAM_INDEX_ALLIANCE) ? BG_AB_SOUND_NODE_ASSAULTED_ALLIANCE : BG_AB_SOUND_NODE_ASSAULTED_HORDE;
|
||||||
}
|
}
|
||||||
// If node is occupied, change to enemy-contested
|
// If node is occupied, change to enemy-contested
|
||||||
else
|
else
|
||||||
|
|
@ -411,18 +411,18 @@ void BattleGroundAB::EventPlayerClickedOnFlag(Player* source, GameObject* target
|
||||||
_SendNodeUpdate(node);
|
_SendNodeUpdate(node);
|
||||||
m_NodeTimers[node] = BG_AB_FLAG_CAPTURING_TIME;
|
m_NodeTimers[node] = BG_AB_FLAG_CAPTURING_TIME;
|
||||||
|
|
||||||
if (teamIndex == BG_TEAM_ALLIANCE)
|
if (teamIndex == TEAM_INDEX_ALLIANCE)
|
||||||
SendMessage2ToAll(LANG_BG_AB_NODE_ASSAULTED, CHAT_MSG_BG_SYSTEM_ALLIANCE, source, _GetNodeNameId(node));
|
SendMessage2ToAll(LANG_BG_AB_NODE_ASSAULTED, CHAT_MSG_BG_SYSTEM_ALLIANCE, source, _GetNodeNameId(node));
|
||||||
else
|
else
|
||||||
SendMessage2ToAll(LANG_BG_AB_NODE_ASSAULTED, CHAT_MSG_BG_SYSTEM_HORDE, source, _GetNodeNameId(node));
|
SendMessage2ToAll(LANG_BG_AB_NODE_ASSAULTED, CHAT_MSG_BG_SYSTEM_HORDE, source, _GetNodeNameId(node));
|
||||||
|
|
||||||
sound = (teamIndex == BG_TEAM_ALLIANCE) ? BG_AB_SOUND_NODE_ASSAULTED_ALLIANCE : BG_AB_SOUND_NODE_ASSAULTED_HORDE;
|
sound = (teamIndex == TEAM_INDEX_ALLIANCE) ? BG_AB_SOUND_NODE_ASSAULTED_ALLIANCE : BG_AB_SOUND_NODE_ASSAULTED_HORDE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If node is occupied again, send "X has taken the Y" msg.
|
// If node is occupied again, send "X has taken the Y" msg.
|
||||||
if (m_Nodes[node] >= BG_AB_NODE_TYPE_OCCUPIED)
|
if (m_Nodes[node] >= BG_AB_NODE_TYPE_OCCUPIED)
|
||||||
{
|
{
|
||||||
if (teamIndex == BG_TEAM_ALLIANCE)
|
if (teamIndex == TEAM_INDEX_ALLIANCE)
|
||||||
SendMessage2ToAll(LANG_BG_AB_NODE_TAKEN, CHAT_MSG_BG_SYSTEM_ALLIANCE, NULL, LANG_BG_ALLY, _GetNodeNameId(node));
|
SendMessage2ToAll(LANG_BG_AB_NODE_TAKEN, CHAT_MSG_BG_SYSTEM_ALLIANCE, NULL, LANG_BG_ALLY, _GetNodeNameId(node));
|
||||||
else
|
else
|
||||||
SendMessage2ToAll(LANG_BG_AB_NODE_TAKEN, CHAT_MSG_BG_SYSTEM_HORDE, NULL, LANG_BG_HORDE, _GetNodeNameId(node));
|
SendMessage2ToAll(LANG_BG_AB_NODE_TAKEN, CHAT_MSG_BG_SYSTEM_HORDE, NULL, LANG_BG_HORDE, _GetNodeNameId(node));
|
||||||
|
|
@ -435,7 +435,7 @@ void BattleGroundAB::Reset()
|
||||||
// call parent's class reset
|
// call parent's class reset
|
||||||
BattleGround::Reset();
|
BattleGround::Reset();
|
||||||
|
|
||||||
for (uint8 i = 0; i < BG_TEAMS_COUNT; ++i)
|
for (uint8 i = 0; i < PVP_TEAM_COUNT; ++i)
|
||||||
{
|
{
|
||||||
m_TeamScores[i] = 0;
|
m_TeamScores[i] = 0;
|
||||||
m_lastTick[i] = 0;
|
m_lastTick[i] = 0;
|
||||||
|
|
@ -477,7 +477,7 @@ void BattleGroundAB::EndBattleGround(Team winner)
|
||||||
|
|
||||||
WorldSafeLocsEntry const* BattleGroundAB::GetClosestGraveYard(Player* player)
|
WorldSafeLocsEntry const* BattleGroundAB::GetClosestGraveYard(Player* player)
|
||||||
{
|
{
|
||||||
BattleGroundTeamIndex teamIndex = GetTeamIndexByTeamId(player->GetTeam());
|
PvpTeamIndex teamIndex = GetTeamIndexByTeamId(player->GetTeam());
|
||||||
|
|
||||||
// Is there any occupied node for this team?
|
// Is there any occupied node for this team?
|
||||||
std::vector<uint8> nodes;
|
std::vector<uint8> nodes;
|
||||||
|
|
|
||||||
|
|
@ -153,6 +153,10 @@ class BattleGroundABScore : public BattleGroundScore
|
||||||
public:
|
public:
|
||||||
BattleGroundABScore(): BasesAssaulted(0), BasesDefended(0) {};
|
BattleGroundABScore(): BasesAssaulted(0), BasesDefended(0) {};
|
||||||
virtual ~BattleGroundABScore() {};
|
virtual ~BattleGroundABScore() {};
|
||||||
|
|
||||||
|
uint32 GetAttr1() const { return BasesAssaulted; }
|
||||||
|
uint32 GetAttr2() const { return BasesDefended; }
|
||||||
|
|
||||||
uint32 BasesAssaulted;
|
uint32 BasesAssaulted;
|
||||||
uint32 BasesDefended;
|
uint32 BasesDefended;
|
||||||
};
|
};
|
||||||
|
|
@ -207,13 +211,13 @@ class BattleGroundAB : public BattleGround
|
||||||
uint8 m_prevNodes[BG_AB_NODES_MAX]; // used for performant wordlstate-updating
|
uint8 m_prevNodes[BG_AB_NODES_MAX]; // used for performant wordlstate-updating
|
||||||
BG_AB_BannerTimer m_BannerTimers[BG_AB_NODES_MAX];
|
BG_AB_BannerTimer m_BannerTimers[BG_AB_NODES_MAX];
|
||||||
uint32 m_NodeTimers[BG_AB_NODES_MAX];
|
uint32 m_NodeTimers[BG_AB_NODES_MAX];
|
||||||
uint32 m_lastTick[BG_TEAMS_COUNT];
|
uint32 m_lastTick[PVP_TEAM_COUNT];
|
||||||
uint32 m_honorScoreTicks[BG_TEAMS_COUNT];
|
uint32 m_honorScoreTicks[PVP_TEAM_COUNT];
|
||||||
uint32 m_ReputationScoreTics[BG_TEAMS_COUNT];
|
uint32 m_ReputationScoreTics[PVP_TEAM_COUNT];
|
||||||
bool m_IsInformedNearVictory;
|
bool m_IsInformedNearVictory;
|
||||||
uint32 m_honorTicks;
|
uint32 m_honorTicks;
|
||||||
uint32 m_ReputationTics;
|
uint32 m_ReputationTics;
|
||||||
// need for achievements
|
// need for achievements
|
||||||
bool m_TeamScores500Disadvantage[BG_TEAMS_COUNT];
|
bool m_TeamScores500Disadvantage[PVP_TEAM_COUNT];
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -78,7 +78,7 @@ void BattleGroundAV::HandleKillUnit(Creature* creature, Player* killer)
|
||||||
return;
|
return;
|
||||||
RewardReputationToTeam(BG_AV_FACTION_H, m_RepCaptain, HORDE);
|
RewardReputationToTeam(BG_AV_FACTION_H, m_RepCaptain, HORDE);
|
||||||
RewardHonorToTeam(GetBonusHonorFromKill(BG_AV_KILL_CAPTAIN), HORDE);
|
RewardHonorToTeam(GetBonusHonorFromKill(BG_AV_KILL_CAPTAIN), HORDE);
|
||||||
UpdateScore(BG_TEAM_ALLIANCE, (-1) * BG_AV_RES_CAPTAIN);
|
UpdateScore(TEAM_INDEX_ALLIANCE, (-1) * BG_AV_RES_CAPTAIN);
|
||||||
// spawn destroyed aura
|
// spawn destroyed aura
|
||||||
SpawnEvent(BG_AV_NodeEventCaptainDead_A, 0, true);
|
SpawnEvent(BG_AV_NodeEventCaptainDead_A, 0, true);
|
||||||
break;
|
break;
|
||||||
|
|
@ -87,7 +87,7 @@ void BattleGroundAV::HandleKillUnit(Creature* creature, Player* killer)
|
||||||
return;
|
return;
|
||||||
RewardReputationToTeam(BG_AV_FACTION_A, m_RepCaptain, ALLIANCE);
|
RewardReputationToTeam(BG_AV_FACTION_A, m_RepCaptain, ALLIANCE);
|
||||||
RewardHonorToTeam(GetBonusHonorFromKill(BG_AV_KILL_CAPTAIN), ALLIANCE);
|
RewardHonorToTeam(GetBonusHonorFromKill(BG_AV_KILL_CAPTAIN), ALLIANCE);
|
||||||
UpdateScore(BG_TEAM_HORDE, (-1) * BG_AV_RES_CAPTAIN);
|
UpdateScore(TEAM_INDEX_HORDE, (-1) * BG_AV_RES_CAPTAIN);
|
||||||
// spawn destroyed aura
|
// spawn destroyed aura
|
||||||
SpawnEvent(BG_AV_NodeEventCaptainDead_H, 0, true);
|
SpawnEvent(BG_AV_NodeEventCaptainDead_H, 0, true);
|
||||||
break;
|
break;
|
||||||
|
|
@ -211,10 +211,10 @@ void BattleGroundAV::HandleQuestComplete(uint32 questid, Player* player)
|
||||||
RewardReputationToTeam((player->GetTeam() == ALLIANCE) ? BG_AV_FACTION_A : BG_AV_FACTION_H, reputation, player->GetTeam());
|
RewardReputationToTeam((player->GetTeam() == ALLIANCE) ? BG_AV_FACTION_A : BG_AV_FACTION_H, reputation, player->GetTeam());
|
||||||
}
|
}
|
||||||
|
|
||||||
void BattleGroundAV::UpdateScore(BattleGroundTeamIndex teamIdx, int32 points)
|
void BattleGroundAV::UpdateScore(PvpTeamIndex teamIdx, int32 points)
|
||||||
{
|
{
|
||||||
// note: to remove reinforcements points must be negative, for adding reinforcements points must be positive
|
// note: to remove reinforcements points must be negative, for adding reinforcements points must be positive
|
||||||
MANGOS_ASSERT(teamIdx == BG_TEAM_ALLIANCE || teamIdx == BG_TEAM_HORDE);
|
MANGOS_ASSERT(teamIdx == TEAM_INDEX_ALLIANCE || teamIdx == TEAM_INDEX_HORDE);
|
||||||
m_TeamScores[teamIdx] += points; // m_TeamScores is int32 - so no problems here
|
m_TeamScores[teamIdx] += points; // m_TeamScores is int32 - so no problems here
|
||||||
|
|
||||||
if (points < 0)
|
if (points < 0)
|
||||||
|
|
@ -223,17 +223,17 @@ void BattleGroundAV::UpdateScore(BattleGroundTeamIndex teamIdx, int32 points)
|
||||||
{
|
{
|
||||||
m_TeamScores[teamIdx] = 0;
|
m_TeamScores[teamIdx] = 0;
|
||||||
// other team will win:
|
// other team will win:
|
||||||
EndBattleGround((teamIdx == BG_TEAM_ALLIANCE) ? HORDE : ALLIANCE);
|
EndBattleGround((teamIdx == TEAM_INDEX_ALLIANCE) ? HORDE : ALLIANCE);
|
||||||
}
|
}
|
||||||
else if (!m_IsInformedNearLose[teamIdx] && m_TeamScores[teamIdx] < BG_AV_SCORE_NEAR_LOSE)
|
else if (!m_IsInformedNearLose[teamIdx] && m_TeamScores[teamIdx] < BG_AV_SCORE_NEAR_LOSE)
|
||||||
{
|
{
|
||||||
SendMessageToAll((teamIdx == BG_TEAM_HORDE) ? LANG_BG_AV_H_NEAR_LOSE : LANG_BG_AV_A_NEAR_LOSE, CHAT_MSG_BG_SYSTEM_NEUTRAL);
|
SendMessageToAll((teamIdx == TEAM_INDEX_HORDE) ? LANG_BG_AV_H_NEAR_LOSE : LANG_BG_AV_A_NEAR_LOSE, CHAT_MSG_BG_SYSTEM_NEUTRAL);
|
||||||
PlaySoundToAll(BG_AV_SOUND_NEAR_LOSE);
|
PlaySoundToAll(BG_AV_SOUND_NEAR_LOSE);
|
||||||
m_IsInformedNearLose[teamIdx] = true;
|
m_IsInformedNearLose[teamIdx] = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// must be called here, else it could display a negative value
|
// must be called here, else it could display a negative value
|
||||||
UpdateWorldState(((teamIdx == BG_TEAM_HORDE) ? BG_AV_Horde_Score : BG_AV_Alliance_Score), m_TeamScores[teamIdx]);
|
UpdateWorldState(((teamIdx == TEAM_INDEX_HORDE) ? BG_AV_Horde_Score : BG_AV_Alliance_Score), m_TeamScores[teamIdx]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BattleGroundAV::Update(uint32 diff)
|
void BattleGroundAV::Update(uint32 diff)
|
||||||
|
|
@ -251,7 +251,7 @@ void BattleGroundAV::Update(uint32 diff)
|
||||||
m_Mine_Timer[mine] -= diff;
|
m_Mine_Timer[mine] -= diff;
|
||||||
if (m_Mine_Timer[mine] <= 0)
|
if (m_Mine_Timer[mine] <= 0)
|
||||||
{
|
{
|
||||||
UpdateScore(BattleGroundTeamIndex(m_Mine_Owner[mine]), WORLD_STATE_ADD);
|
UpdateScore(PvpTeamIndex(m_Mine_Owner[mine]), WORLD_STATE_ADD);
|
||||||
m_Mine_Timer[mine] = BG_AV_MINE_TICK_TIMER;
|
m_Mine_Timer[mine] = BG_AV_MINE_TICK_TIMER;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -296,18 +296,18 @@ void BattleGroundAV::AddPlayer(Player* plr)
|
||||||
void BattleGroundAV::EndBattleGround(Team winner)
|
void BattleGroundAV::EndBattleGround(Team winner)
|
||||||
{
|
{
|
||||||
// calculate bonuskills for both teams:
|
// calculate bonuskills for both teams:
|
||||||
uint32 tower_survived[BG_TEAMS_COUNT] = {0, 0};
|
uint32 tower_survived[PVP_TEAM_COUNT] = {0, 0};
|
||||||
uint32 graves_owned[BG_TEAMS_COUNT] = {0, 0};
|
uint32 graves_owned[PVP_TEAM_COUNT] = {0, 0};
|
||||||
uint32 mines_owned[BG_TEAMS_COUNT] = {0, 0};
|
uint32 mines_owned[PVP_TEAM_COUNT] = {0, 0};
|
||||||
// towers all not destroyed:
|
// towers all not destroyed:
|
||||||
for (BG_AV_Nodes i = BG_AV_NODES_DUNBALDAR_SOUTH; i <= BG_AV_NODES_STONEHEART_BUNKER; ++i)
|
for (BG_AV_Nodes i = BG_AV_NODES_DUNBALDAR_SOUTH; i <= BG_AV_NODES_STONEHEART_BUNKER; ++i)
|
||||||
if (m_Nodes[i].State == POINT_CONTROLLED)
|
if (m_Nodes[i].State == POINT_CONTROLLED)
|
||||||
if (m_Nodes[i].TotalOwner == BG_AV_TEAM_ALLIANCE)
|
if (m_Nodes[i].TotalOwner == BG_AV_TEAM_ALLIANCE)
|
||||||
++tower_survived[BG_TEAM_ALLIANCE];
|
++tower_survived[TEAM_INDEX_ALLIANCE];
|
||||||
for (BG_AV_Nodes i = BG_AV_NODES_ICEBLOOD_TOWER; i <= BG_AV_NODES_FROSTWOLF_WTOWER; ++i)
|
for (BG_AV_Nodes i = BG_AV_NODES_ICEBLOOD_TOWER; i <= BG_AV_NODES_FROSTWOLF_WTOWER; ++i)
|
||||||
if (m_Nodes[i].State == POINT_CONTROLLED)
|
if (m_Nodes[i].State == POINT_CONTROLLED)
|
||||||
if (m_Nodes[i].TotalOwner == BG_AV_TEAM_HORDE)
|
if (m_Nodes[i].TotalOwner == BG_AV_TEAM_HORDE)
|
||||||
++tower_survived[BG_TEAM_HORDE];
|
++tower_survived[TEAM_INDEX_HORDE];
|
||||||
|
|
||||||
// graves all controlled
|
// graves all controlled
|
||||||
for (BG_AV_Nodes i = BG_AV_NODES_FIRSTAID_STATION; i < BG_AV_NODES_MAX; ++i)
|
for (BG_AV_Nodes i = BG_AV_NODES_FIRSTAID_STATION; i < BG_AV_NODES_MAX; ++i)
|
||||||
|
|
@ -319,9 +319,9 @@ void BattleGroundAV::EndBattleGround(Team winner)
|
||||||
++mines_owned[m_Mine_Owner[i]];
|
++mines_owned[m_Mine_Owner[i]];
|
||||||
|
|
||||||
// now we have the values give the honor/reputation to the teams:
|
// now we have the values give the honor/reputation to the teams:
|
||||||
Team team[BG_TEAMS_COUNT] = { ALLIANCE, HORDE };
|
Team team[PVP_TEAM_COUNT] = { ALLIANCE, HORDE };
|
||||||
uint32 faction[BG_TEAMS_COUNT] = { BG_AV_FACTION_A, BG_AV_FACTION_H };
|
uint32 faction[PVP_TEAM_COUNT] = { BG_AV_FACTION_A, BG_AV_FACTION_H };
|
||||||
for (uint8 i = 0; i < BG_TEAMS_COUNT; ++i)
|
for (uint8 i = 0; i < PVP_TEAM_COUNT; ++i)
|
||||||
{
|
{
|
||||||
if (tower_survived[i])
|
if (tower_survived[i])
|
||||||
{
|
{
|
||||||
|
|
@ -417,8 +417,8 @@ void BattleGroundAV::EventPlayerDestroyedPoint(BG_AV_Nodes node)
|
||||||
DEBUG_LOG("BattleGroundAV: player destroyed point node %i", node);
|
DEBUG_LOG("BattleGroundAV: player destroyed point node %i", node);
|
||||||
|
|
||||||
MANGOS_ASSERT(m_Nodes[node].Owner != BG_AV_TEAM_NEUTRAL)
|
MANGOS_ASSERT(m_Nodes[node].Owner != BG_AV_TEAM_NEUTRAL)
|
||||||
BattleGroundTeamIndex ownerTeamIdx = BattleGroundTeamIndex(m_Nodes[node].Owner);
|
PvpTeamIndex ownerTeamIdx = PvpTeamIndex(m_Nodes[node].Owner);
|
||||||
Team ownerTeam = ownerTeamIdx == BG_TEAM_ALLIANCE ? ALLIANCE : HORDE;
|
Team ownerTeam = ownerTeamIdx == TEAM_INDEX_ALLIANCE ? ALLIANCE : HORDE;
|
||||||
|
|
||||||
// despawn banner
|
// despawn banner
|
||||||
DestroyNode(node);
|
DestroyNode(node);
|
||||||
|
|
@ -531,7 +531,7 @@ void BattleGroundAV::EventPlayerDefendsPoint(Player* player, BG_AV_Nodes node)
|
||||||
{
|
{
|
||||||
MANGOS_ASSERT(GetStatus() == STATUS_IN_PROGRESS);
|
MANGOS_ASSERT(GetStatus() == STATUS_IN_PROGRESS);
|
||||||
|
|
||||||
BattleGroundTeamIndex teamIdx = GetTeamIndexByTeamId(player->GetTeam());
|
PvpTeamIndex teamIdx = GetTeamIndexByTeamId(player->GetTeam());
|
||||||
|
|
||||||
if (m_Nodes[node].Owner == BattleGroundAVTeamIndex(teamIdx) || m_Nodes[node].State != POINT_ASSAULTED)
|
if (m_Nodes[node].Owner == BattleGroundAVTeamIndex(teamIdx) || m_Nodes[node].State != POINT_ASSAULTED)
|
||||||
return;
|
return;
|
||||||
|
|
@ -559,7 +559,7 @@ void BattleGroundAV::EventPlayerDefendsPoint(Player* player, BG_AV_Nodes node)
|
||||||
{
|
{
|
||||||
SendYell2ToAll(LANG_BG_AV_TOWER_DEFENDED, LANG_UNIVERSAL, GetSingleCreatureGuid(BG_AV_HERALD, 0),
|
SendYell2ToAll(LANG_BG_AV_TOWER_DEFENDED, LANG_UNIVERSAL, GetSingleCreatureGuid(BG_AV_HERALD, 0),
|
||||||
GetNodeName(node),
|
GetNodeName(node),
|
||||||
(teamIdx == BG_TEAM_ALLIANCE) ? LANG_BG_ALLY : LANG_BG_HORDE);
|
(teamIdx == TEAM_INDEX_ALLIANCE) ? LANG_BG_ALLY : LANG_BG_HORDE);
|
||||||
UpdatePlayerScore(player, SCORE_TOWERS_DEFENDED, 1);
|
UpdatePlayerScore(player, SCORE_TOWERS_DEFENDED, 1);
|
||||||
PlaySoundToAll(BG_AV_SOUND_BOTH_TOWER_DEFEND);
|
PlaySoundToAll(BG_AV_SOUND_BOTH_TOWER_DEFEND);
|
||||||
}
|
}
|
||||||
|
|
@ -567,17 +567,17 @@ void BattleGroundAV::EventPlayerDefendsPoint(Player* player, BG_AV_Nodes node)
|
||||||
{
|
{
|
||||||
SendYell2ToAll(LANG_BG_AV_GRAVE_DEFENDED, LANG_UNIVERSAL, GetSingleCreatureGuid(BG_AV_HERALD, 0),
|
SendYell2ToAll(LANG_BG_AV_GRAVE_DEFENDED, LANG_UNIVERSAL, GetSingleCreatureGuid(BG_AV_HERALD, 0),
|
||||||
GetNodeName(node),
|
GetNodeName(node),
|
||||||
(teamIdx == BG_TEAM_ALLIANCE) ? LANG_BG_ALLY : LANG_BG_HORDE);
|
(teamIdx == TEAM_INDEX_ALLIANCE) ? LANG_BG_ALLY : LANG_BG_HORDE);
|
||||||
UpdatePlayerScore(player, SCORE_GRAVEYARDS_DEFENDED, 1);
|
UpdatePlayerScore(player, SCORE_GRAVEYARDS_DEFENDED, 1);
|
||||||
// update the statistic for the defending player
|
// update the statistic for the defending player
|
||||||
PlaySoundToAll((teamIdx == BG_TEAM_ALLIANCE) ? BG_AV_SOUND_ALLIANCE_GOOD : BG_AV_SOUND_HORDE_GOOD);
|
PlaySoundToAll((teamIdx == TEAM_INDEX_ALLIANCE) ? BG_AV_SOUND_ALLIANCE_GOOD : BG_AV_SOUND_HORDE_GOOD);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void BattleGroundAV::EventPlayerAssaultsPoint(Player* player, BG_AV_Nodes node)
|
void BattleGroundAV::EventPlayerAssaultsPoint(Player* player, BG_AV_Nodes node)
|
||||||
{
|
{
|
||||||
// TODO implement quest 7101, 7081
|
// TODO implement quest 7101, 7081
|
||||||
BattleGroundTeamIndex teamIdx = GetTeamIndexByTeamId(player->GetTeam());
|
PvpTeamIndex teamIdx = GetTeamIndexByTeamId(player->GetTeam());
|
||||||
DEBUG_LOG("BattleGroundAV: player assaults node %i", node);
|
DEBUG_LOG("BattleGroundAV: player assaults node %i", node);
|
||||||
if (m_Nodes[node].Owner == BattleGroundAVTeamIndex(teamIdx) || BattleGroundAVTeamIndex(teamIdx) == m_Nodes[node].TotalOwner)
|
if (m_Nodes[node].Owner == BattleGroundAVTeamIndex(teamIdx) || BattleGroundAVTeamIndex(teamIdx) == m_Nodes[node].TotalOwner)
|
||||||
return;
|
return;
|
||||||
|
|
@ -590,19 +590,19 @@ void BattleGroundAV::EventPlayerAssaultsPoint(Player* player, BG_AV_Nodes node)
|
||||||
{
|
{
|
||||||
SendYell2ToAll(LANG_BG_AV_TOWER_ASSAULTED, LANG_UNIVERSAL, GetSingleCreatureGuid(BG_AV_HERALD, 0),
|
SendYell2ToAll(LANG_BG_AV_TOWER_ASSAULTED, LANG_UNIVERSAL, GetSingleCreatureGuid(BG_AV_HERALD, 0),
|
||||||
GetNodeName(node),
|
GetNodeName(node),
|
||||||
(teamIdx == BG_TEAM_ALLIANCE) ? LANG_BG_ALLY : LANG_BG_HORDE);
|
(teamIdx == TEAM_INDEX_ALLIANCE) ? LANG_BG_ALLY : LANG_BG_HORDE);
|
||||||
UpdatePlayerScore(player, SCORE_TOWERS_ASSAULTED, 1);
|
UpdatePlayerScore(player, SCORE_TOWERS_ASSAULTED, 1);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
SendYell2ToAll(LANG_BG_AV_GRAVE_ASSAULTED, LANG_UNIVERSAL, GetSingleCreatureGuid(BG_AV_HERALD, 0),
|
SendYell2ToAll(LANG_BG_AV_GRAVE_ASSAULTED, LANG_UNIVERSAL, GetSingleCreatureGuid(BG_AV_HERALD, 0),
|
||||||
GetNodeName(node),
|
GetNodeName(node),
|
||||||
(teamIdx == BG_TEAM_ALLIANCE) ? LANG_BG_ALLY : LANG_BG_HORDE);
|
(teamIdx == TEAM_INDEX_ALLIANCE) ? LANG_BG_ALLY : LANG_BG_HORDE);
|
||||||
// update the statistic for the assaulting player
|
// update the statistic for the assaulting player
|
||||||
UpdatePlayerScore(player, SCORE_GRAVEYARDS_ASSAULTED, 1);
|
UpdatePlayerScore(player, SCORE_GRAVEYARDS_ASSAULTED, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
PlaySoundToAll((teamIdx == BG_TEAM_ALLIANCE) ? BG_AV_SOUND_ALLIANCE_ASSAULTS : BG_AV_SOUND_HORDE_ASSAULTS);
|
PlaySoundToAll((teamIdx == TEAM_INDEX_ALLIANCE) ? BG_AV_SOUND_ALLIANCE_ASSAULTS : BG_AV_SOUND_HORDE_ASSAULTS);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BattleGroundAV::FillInitialWorldStates(WorldPacket& data, uint32& count)
|
void BattleGroundAV::FillInitialWorldStates(WorldPacket& data, uint32& count)
|
||||||
|
|
@ -623,8 +623,8 @@ void BattleGroundAV::FillInitialWorldStates(WorldPacket& data, uint32& count)
|
||||||
if (m_Nodes[BG_AV_NODES_SNOWFALL_GRAVE].Owner == BG_AV_TEAM_NEUTRAL) // cause neutral teams aren't handled generic
|
if (m_Nodes[BG_AV_NODES_SNOWFALL_GRAVE].Owner == BG_AV_TEAM_NEUTRAL) // cause neutral teams aren't handled generic
|
||||||
FillInitialWorldState(data, count, AV_SNOWFALL_N, WORLD_STATE_ADD);
|
FillInitialWorldState(data, count, AV_SNOWFALL_N, WORLD_STATE_ADD);
|
||||||
|
|
||||||
FillInitialWorldState(data, count, BG_AV_Alliance_Score, m_TeamScores[BG_TEAM_ALLIANCE]);
|
FillInitialWorldState(data, count, BG_AV_Alliance_Score, m_TeamScores[TEAM_INDEX_ALLIANCE]);
|
||||||
FillInitialWorldState(data, count, BG_AV_Horde_Score, m_TeamScores[BG_TEAM_HORDE]);
|
FillInitialWorldState(data, count, BG_AV_Horde_Score, m_TeamScores[TEAM_INDEX_HORDE]);
|
||||||
if (GetStatus() == STATUS_IN_PROGRESS) // only if game is running the teamscores are displayed
|
if (GetStatus() == STATUS_IN_PROGRESS) // only if game is running the teamscores are displayed
|
||||||
{
|
{
|
||||||
FillInitialWorldState(data, count, BG_AV_SHOW_A_SCORE, WORLD_STATE_ADD);
|
FillInitialWorldState(data, count, BG_AV_SHOW_A_SCORE, WORLD_STATE_ADD);
|
||||||
|
|
@ -718,7 +718,7 @@ uint32 BattleGroundAV::GetNodeName(BG_AV_Nodes node) const
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void BattleGroundAV::AssaultNode(BG_AV_Nodes node, BattleGroundTeamIndex teamIdx)
|
void BattleGroundAV::AssaultNode(BG_AV_Nodes node, PvpTeamIndex teamIdx)
|
||||||
{
|
{
|
||||||
MANGOS_ASSERT(m_Nodes[node].TotalOwner != BattleGroundAVTeamIndex(teamIdx));
|
MANGOS_ASSERT(m_Nodes[node].TotalOwner != BattleGroundAVTeamIndex(teamIdx));
|
||||||
MANGOS_ASSERT(m_Nodes[node].Owner != BattleGroundAVTeamIndex(teamIdx));
|
MANGOS_ASSERT(m_Nodes[node].Owner != BattleGroundAVTeamIndex(teamIdx));
|
||||||
|
|
@ -758,7 +758,7 @@ void BattleGroundAV::InitNode(BG_AV_Nodes node, BattleGroundAVTeamIndex teamIdx,
|
||||||
m_ActiveEvents[node + BG_AV_NODES_MAX] = teamIdx * BG_AV_MAX_GRAVETYPES;
|
m_ActiveEvents[node + BG_AV_NODES_MAX] = teamIdx * BG_AV_MAX_GRAVETYPES;
|
||||||
}
|
}
|
||||||
|
|
||||||
void BattleGroundAV::DefendNode(BG_AV_Nodes node, BattleGroundTeamIndex teamIdx)
|
void BattleGroundAV::DefendNode(BG_AV_Nodes node, PvpTeamIndex teamIdx)
|
||||||
{
|
{
|
||||||
MANGOS_ASSERT(m_Nodes[node].TotalOwner == BattleGroundAVTeamIndex(teamIdx));
|
MANGOS_ASSERT(m_Nodes[node].TotalOwner == BattleGroundAVTeamIndex(teamIdx));
|
||||||
MANGOS_ASSERT(m_Nodes[node].Owner != BattleGroundAVTeamIndex(teamIdx));
|
MANGOS_ASSERT(m_Nodes[node].Owner != BattleGroundAVTeamIndex(teamIdx));
|
||||||
|
|
@ -785,7 +785,7 @@ void BattleGroundAV::Reset()
|
||||||
m_RepSurviveTower = (isBGWeekend) ? BG_AV_REP_SURVIVING_TOWER_HOLIDAY : BG_AV_REP_SURVIVING_TOWER;
|
m_RepSurviveTower = (isBGWeekend) ? BG_AV_REP_SURVIVING_TOWER_HOLIDAY : BG_AV_REP_SURVIVING_TOWER;
|
||||||
m_RepOwnedMine = (isBGWeekend) ? BG_AV_REP_OWNED_MINE_HOLIDAY : BG_AV_REP_OWNED_MINE;
|
m_RepOwnedMine = (isBGWeekend) ? BG_AV_REP_OWNED_MINE_HOLIDAY : BG_AV_REP_OWNED_MINE;
|
||||||
|
|
||||||
for (uint8 i = 0; i < BG_TEAMS_COUNT; ++i)
|
for (uint8 i = 0; i < PVP_TEAM_COUNT; ++i)
|
||||||
{
|
{
|
||||||
for (uint8 j = 0; j < 9; ++j) // 9 quests getting tracked
|
for (uint8 j = 0; j < 9; ++j) // 9 quests getting tracked
|
||||||
m_Team_QuestStatus[i][j] = 0;
|
m_Team_QuestStatus[i][j] = 0;
|
||||||
|
|
|
||||||
|
|
@ -208,13 +208,13 @@ enum BG_AV_WorldStates
|
||||||
AV_SNOWFALL_N = 1966,
|
AV_SNOWFALL_N = 1966,
|
||||||
};
|
};
|
||||||
|
|
||||||
// special version with more wide values range that BattleGroundTeamIndex
|
// special version with more wide values range that PvpTeamIndex
|
||||||
// BattleGroundAVTeamIndex <- BattleGroundTeamIndex cast safe
|
// BattleGroundAVTeamIndex <- PvpTeamIndex cast safe
|
||||||
// BattleGroundAVTeamIndex -> BattleGroundTeamIndex cast safe and array with BG_TEAMS_COUNT elements must checked != BG_AV_TEAM_NEUTRAL before used
|
// BattleGroundAVTeamIndex -> PvpTeamIndex cast safe and array with PVP_TEAM_COUNT elements must checked != BG_AV_TEAM_NEUTRAL before used
|
||||||
enum BattleGroundAVTeamIndex
|
enum BattleGroundAVTeamIndex
|
||||||
{
|
{
|
||||||
BG_AV_TEAM_ALLIANCE = BG_TEAM_ALLIANCE,
|
BG_AV_TEAM_ALLIANCE = TEAM_INDEX_ALLIANCE,
|
||||||
BG_AV_TEAM_HORDE = BG_TEAM_HORDE,
|
BG_AV_TEAM_HORDE = TEAM_INDEX_HORDE,
|
||||||
BG_AV_TEAM_NEUTRAL = 2, // this is the neutral owner of snowfall
|
BG_AV_TEAM_NEUTRAL = 2, // this is the neutral owner of snowfall
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -311,6 +311,13 @@ class BattleGroundAVScore : public BattleGroundScore
|
||||||
public:
|
public:
|
||||||
BattleGroundAVScore() : GraveyardsAssaulted(0), GraveyardsDefended(0), TowersAssaulted(0), TowersDefended(0), SecondaryObjectives(0) {};
|
BattleGroundAVScore() : GraveyardsAssaulted(0), GraveyardsDefended(0), TowersAssaulted(0), TowersDefended(0), SecondaryObjectives(0) {};
|
||||||
virtual ~BattleGroundAVScore() {};
|
virtual ~BattleGroundAVScore() {};
|
||||||
|
|
||||||
|
uint32 GetAttr1() const { return GraveyardsAssaulted; }
|
||||||
|
uint32 GetAttr2() const { return GraveyardsDefended; }
|
||||||
|
uint32 GetAttr3() const { return TowersAssaulted; }
|
||||||
|
uint32 GetAttr4() const { return TowersDefended; }
|
||||||
|
uint32 GetAttr5() const { return SecondaryObjectives; }
|
||||||
|
|
||||||
uint32 GraveyardsAssaulted;
|
uint32 GraveyardsAssaulted;
|
||||||
uint32 GraveyardsDefended;
|
uint32 GraveyardsDefended;
|
||||||
uint32 TowersAssaulted;
|
uint32 TowersAssaulted;
|
||||||
|
|
@ -337,7 +344,7 @@ class BattleGroundAV : public BattleGround
|
||||||
virtual void Reset() override;
|
virtual void Reset() override;
|
||||||
|
|
||||||
/*general stuff*/
|
/*general stuff*/
|
||||||
void UpdateScore(BattleGroundTeamIndex teamIdx, int32 points);
|
void UpdateScore(PvpTeamIndex teamIdx, int32 points);
|
||||||
void UpdatePlayerScore(Player* source, uint32 type, uint32 value) override;
|
void UpdatePlayerScore(Player* source, uint32 type, uint32 value) override;
|
||||||
|
|
||||||
/*handle stuff*/ // these are functions which get called from extern scripts
|
/*handle stuff*/ // these are functions which get called from extern scripts
|
||||||
|
|
@ -358,10 +365,10 @@ class BattleGroundAV : public BattleGround
|
||||||
void EventPlayerDefendsPoint(Player* player, BG_AV_Nodes node);
|
void EventPlayerDefendsPoint(Player* player, BG_AV_Nodes node);
|
||||||
void EventPlayerDestroyedPoint(BG_AV_Nodes node);
|
void EventPlayerDestroyedPoint(BG_AV_Nodes node);
|
||||||
|
|
||||||
void AssaultNode(BG_AV_Nodes node, BattleGroundTeamIndex teamIdx);
|
void AssaultNode(BG_AV_Nodes node, PvpTeamIndex teamIdx);
|
||||||
void DestroyNode(BG_AV_Nodes node);
|
void DestroyNode(BG_AV_Nodes node);
|
||||||
void InitNode(BG_AV_Nodes node, BattleGroundAVTeamIndex teamIdx, bool tower);
|
void InitNode(BG_AV_Nodes node, BattleGroundAVTeamIndex teamIdx, bool tower);
|
||||||
void DefendNode(BG_AV_Nodes node, BattleGroundTeamIndex teamIdx);
|
void DefendNode(BG_AV_Nodes node, PvpTeamIndex teamIdx);
|
||||||
|
|
||||||
void PopulateNode(BG_AV_Nodes node);
|
void PopulateNode(BG_AV_Nodes node);
|
||||||
|
|
||||||
|
|
@ -378,7 +385,7 @@ class BattleGroundAV : public BattleGround
|
||||||
void UpdateNodeWorldState(BG_AV_Nodes node);
|
void UpdateNodeWorldState(BG_AV_Nodes node);
|
||||||
|
|
||||||
/*variables */
|
/*variables */
|
||||||
uint32 m_Team_QuestStatus[BG_TEAMS_COUNT][9]; // [x][y] x=team y=questcounter
|
uint32 m_Team_QuestStatus[PVP_TEAM_COUNT][9]; // [x][y] x=team y=questcounter
|
||||||
|
|
||||||
BG_AV_NodeInfo m_Nodes[BG_AV_NODES_MAX];
|
BG_AV_NodeInfo m_Nodes[BG_AV_NODES_MAX];
|
||||||
|
|
||||||
|
|
@ -388,7 +395,7 @@ class BattleGroundAV : public BattleGround
|
||||||
int32 m_Mine_Timer[BG_AV_MAX_MINES];
|
int32 m_Mine_Timer[BG_AV_MAX_MINES];
|
||||||
uint32 m_Mine_Reclaim_Timer[BG_AV_MAX_MINES];
|
uint32 m_Mine_Reclaim_Timer[BG_AV_MAX_MINES];
|
||||||
|
|
||||||
bool m_IsInformedNearLose[BG_TEAMS_COUNT];
|
bool m_IsInformedNearLose[PVP_TEAM_COUNT];
|
||||||
|
|
||||||
uint32 m_HonorMapComplete;
|
uint32 m_HonorMapComplete;
|
||||||
uint32 m_RepTowerDestruction;
|
uint32 m_RepTowerDestruction;
|
||||||
|
|
|
||||||
|
|
@ -72,6 +72,28 @@ void BattleGroundEY::Update(uint32 diff)
|
||||||
else
|
else
|
||||||
m_flagRespawnTimer -= diff;
|
m_flagRespawnTimer -= diff;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// workaround for Fel Reaver Ruins flag capture needed on 3.3.5 only
|
||||||
|
// the original areatrigger (4514) is covered by a bigger one (4515) and is not triggered on client side
|
||||||
|
if (IsFlagPickedUp())
|
||||||
|
{
|
||||||
|
if (m_felReaverFlagTimer < diff)
|
||||||
|
{
|
||||||
|
Player* flagCarrier = sObjectMgr.GetPlayer(GetFlagCarrierGuid());
|
||||||
|
if (flagCarrier)
|
||||||
|
{
|
||||||
|
if (m_towerOwner[NODE_FEL_REAVER_RUINS] == flagCarrier->GetTeam())
|
||||||
|
{
|
||||||
|
// coords and range taken from DBC of areatrigger (4514)
|
||||||
|
if (flagCarrier->GetDistance(2044.0f, 1729.729f, 1190.03f) <= 3.0f)
|
||||||
|
EventPlayerCapturedFlag(flagCarrier, NODE_FEL_REAVER_RUINS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
m_felReaverFlagTimer = EY_FEL_REAVER_FLAG_UPDATE_TIME;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
m_felReaverFlagTimer -= diff;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void BattleGroundEY::StartingEventOpenDoors()
|
void BattleGroundEY::StartingEventOpenDoors()
|
||||||
|
|
@ -85,7 +107,7 @@ void BattleGroundEY::StartingEventOpenDoors()
|
||||||
|
|
||||||
void BattleGroundEY::AddPoints(Team team, uint32 points)
|
void BattleGroundEY::AddPoints(Team team, uint32 points)
|
||||||
{
|
{
|
||||||
BattleGroundTeamIndex team_index = GetTeamIndexByTeamId(team);
|
PvpTeamIndex team_index = GetTeamIndexByTeamId(team);
|
||||||
m_TeamScores[team_index] += points;
|
m_TeamScores[team_index] += points;
|
||||||
m_honorScoreTicks[team_index] += points;
|
m_honorScoreTicks[team_index] += points;
|
||||||
if (m_honorScoreTicks[team_index] >= m_honorTicks)
|
if (m_honorScoreTicks[team_index] >= m_honorTicks)
|
||||||
|
|
@ -231,7 +253,7 @@ void BattleGroundEY::ProcessCaptureEvent(GameObject* go, uint32 towerId, Team te
|
||||||
SendMessageToAll(message, CHAT_MSG_BG_SYSTEM_ALLIANCE);
|
SendMessageToAll(message, CHAT_MSG_BG_SYSTEM_ALLIANCE);
|
||||||
|
|
||||||
// spawn gameobjects
|
// spawn gameobjects
|
||||||
SpawnEvent(towerId, BG_TEAM_ALLIANCE, true);
|
SpawnEvent(towerId, TEAM_INDEX_ALLIANCE, true);
|
||||||
}
|
}
|
||||||
else if (team == HORDE)
|
else if (team == HORDE)
|
||||||
{
|
{
|
||||||
|
|
@ -242,7 +264,7 @@ void BattleGroundEY::ProcessCaptureEvent(GameObject* go, uint32 towerId, Team te
|
||||||
SendMessageToAll(message, CHAT_MSG_BG_SYSTEM_HORDE);
|
SendMessageToAll(message, CHAT_MSG_BG_SYSTEM_HORDE);
|
||||||
|
|
||||||
// spawn gameobjects
|
// spawn gameobjects
|
||||||
SpawnEvent(towerId, BG_TEAM_HORDE, true);
|
SpawnEvent(towerId, TEAM_INDEX_HORDE, true);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -310,15 +332,15 @@ void BattleGroundEY::Reset()
|
||||||
// call parent's class reset
|
// call parent's class reset
|
||||||
BattleGround::Reset();
|
BattleGround::Reset();
|
||||||
|
|
||||||
m_TeamScores[BG_TEAM_ALLIANCE] = 0;
|
m_TeamScores[TEAM_INDEX_ALLIANCE] = 0;
|
||||||
m_TeamScores[BG_TEAM_HORDE] = 0;
|
m_TeamScores[TEAM_INDEX_HORDE] = 0;
|
||||||
|
|
||||||
m_towersAlliance = 0;
|
m_towersAlliance = 0;
|
||||||
m_towersHorde = 0;
|
m_towersHorde = 0;
|
||||||
|
|
||||||
m_honorTicks = BattleGroundMgr::IsBGWeekend(GetTypeID()) ? EY_WEEKEND_HONOR_INTERVAL : EY_NORMAL_HONOR_INTERVAL;
|
m_honorTicks = BattleGroundMgr::IsBGWeekend(GetTypeID()) ? EY_WEEKEND_HONOR_INTERVAL : EY_NORMAL_HONOR_INTERVAL;
|
||||||
m_honorScoreTicks[BG_TEAM_ALLIANCE] = 0;
|
m_honorScoreTicks[TEAM_INDEX_ALLIANCE] = 0;
|
||||||
m_honorScoreTicks[BG_TEAM_HORDE] = 0;
|
m_honorScoreTicks[TEAM_INDEX_HORDE] = 0;
|
||||||
|
|
||||||
m_flagState = EY_FLAG_STATE_ON_BASE;
|
m_flagState = EY_FLAG_STATE_ON_BASE;
|
||||||
m_flagCarrier.Clear();
|
m_flagCarrier.Clear();
|
||||||
|
|
@ -326,6 +348,7 @@ void BattleGroundEY::Reset()
|
||||||
|
|
||||||
m_flagRespawnTimer = 0;
|
m_flagRespawnTimer = 0;
|
||||||
m_resourceUpdateTimer = 0;
|
m_resourceUpdateTimer = 0;
|
||||||
|
m_felReaverFlagTimer = 0;
|
||||||
|
|
||||||
m_towerWorldState[NODE_BLOOD_ELF_TOWER] = WORLD_STATE_EY_BLOOD_ELF_TOWER_NEUTRAL;
|
m_towerWorldState[NODE_BLOOD_ELF_TOWER] = WORLD_STATE_EY_BLOOD_ELF_TOWER_NEUTRAL;
|
||||||
m_towerWorldState[NODE_FEL_REAVER_RUINS] = WORLD_STATE_EY_FEL_REAVER_RUINS_NEUTRAL;
|
m_towerWorldState[NODE_FEL_REAVER_RUINS] = WORLD_STATE_EY_FEL_REAVER_RUINS_NEUTRAL;
|
||||||
|
|
@ -512,8 +535,8 @@ void BattleGroundEY::FillInitialWorldStates(WorldPacket& data, uint32& count)
|
||||||
FillInitialWorldState(data, count, WORLD_STATE_EY_TOWER_COUNT_ALLIANCE, m_towersAlliance);
|
FillInitialWorldState(data, count, WORLD_STATE_EY_TOWER_COUNT_ALLIANCE, m_towersAlliance);
|
||||||
FillInitialWorldState(data, count, WORLD_STATE_EY_TOWER_COUNT_HORDE, m_towersHorde);
|
FillInitialWorldState(data, count, WORLD_STATE_EY_TOWER_COUNT_HORDE, m_towersHorde);
|
||||||
|
|
||||||
FillInitialWorldState(data, count, WORLD_STATE_EY_RESOURCES_ALLIANCE, m_TeamScores[BG_TEAM_ALLIANCE]);
|
FillInitialWorldState(data, count, WORLD_STATE_EY_RESOURCES_ALLIANCE, m_TeamScores[TEAM_INDEX_ALLIANCE]);
|
||||||
FillInitialWorldState(data, count, WORLD_STATE_EY_RESOURCES_HORDE, m_TeamScores[BG_TEAM_HORDE]);
|
FillInitialWorldState(data, count, WORLD_STATE_EY_RESOURCES_HORDE, m_TeamScores[TEAM_INDEX_HORDE]);
|
||||||
|
|
||||||
// tower world states
|
// tower world states
|
||||||
FillInitialWorldState(data, count, WORLD_STATE_EY_BLOOD_ELF_TOWER_ALLIANCE, m_towerOwner[NODE_BLOOD_ELF_TOWER] == ALLIANCE);
|
FillInitialWorldState(data, count, WORLD_STATE_EY_BLOOD_ELF_TOWER_ALLIANCE, m_towerOwner[NODE_BLOOD_ELF_TOWER] == ALLIANCE);
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,7 @@ class BattleGround;
|
||||||
|
|
||||||
#define EY_FLAG_RESPAWN_TIME (10 * IN_MILLISECONDS) //10 seconds
|
#define EY_FLAG_RESPAWN_TIME (10 * IN_MILLISECONDS) //10 seconds
|
||||||
#define EY_RESOURCES_UPDATE_TIME (2 * IN_MILLISECONDS) //2 seconds
|
#define EY_RESOURCES_UPDATE_TIME (2 * IN_MILLISECONDS) //2 seconds
|
||||||
|
#define EY_FEL_REAVER_FLAG_UPDATE_TIME (1 * IN_MILLISECONDS) //1 second
|
||||||
|
|
||||||
enum EYWorldStates
|
enum EYWorldStates
|
||||||
{
|
{
|
||||||
|
|
@ -305,9 +306,10 @@ class BattleGroundEY : public BattleGround
|
||||||
ObjectGuid m_towers[EY_NODES_MAX];
|
ObjectGuid m_towers[EY_NODES_MAX];
|
||||||
|
|
||||||
uint32 m_honorTicks;
|
uint32 m_honorTicks;
|
||||||
uint32 m_honorScoreTicks[BG_TEAMS_COUNT];
|
uint32 m_honorScoreTicks[PVP_TEAM_COUNT];
|
||||||
|
|
||||||
uint32 m_flagRespawnTimer;
|
uint32 m_flagRespawnTimer;
|
||||||
uint32 m_resourceUpdateTimer;
|
uint32 m_resourceUpdateTimer;
|
||||||
|
uint32 m_felReaverFlagTimer;
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -59,7 +59,7 @@ INSTANTIATE_SINGLETON_1(BattleGroundMgr);
|
||||||
|
|
||||||
BattleGroundQueue::BattleGroundQueue()
|
BattleGroundQueue::BattleGroundQueue()
|
||||||
{
|
{
|
||||||
for (uint8 i = 0; i < BG_TEAMS_COUNT; ++i)
|
for (uint8 i = 0; i < PVP_TEAM_COUNT; ++i)
|
||||||
{
|
{
|
||||||
for (uint8 j = 0; j < MAX_BATTLEGROUND_BRACKETS; ++j)
|
for (uint8 j = 0; j < MAX_BATTLEGROUND_BRACKETS; ++j)
|
||||||
{
|
{
|
||||||
|
|
@ -175,7 +175,7 @@ GroupQueueInfo* BattleGroundQueue::AddGroup(Player* leader, Group* grp, BattleGr
|
||||||
// compute index (if group is premade or joined a rated match) to queues
|
// compute index (if group is premade or joined a rated match) to queues
|
||||||
uint32 index = 0;
|
uint32 index = 0;
|
||||||
if (!isRated && !isPremade)
|
if (!isRated && !isPremade)
|
||||||
index += BG_TEAMS_COUNT; // BG_QUEUE_PREMADE_* -> BG_QUEUE_NORMAL_*
|
index += PVP_TEAM_COUNT; // BG_QUEUE_PREMADE_* -> BG_QUEUE_NORMAL_*
|
||||||
|
|
||||||
if (ginfo->GroupTeam == HORDE)
|
if (ginfo->GroupTeam == HORDE)
|
||||||
++index; // BG_QUEUE_*_ALLIANCE -> BG_QUEUE_*_HORDE
|
++index; // BG_QUEUE_*_ALLIANCE -> BG_QUEUE_*_HORDE
|
||||||
|
|
@ -260,16 +260,16 @@ GroupQueueInfo* BattleGroundQueue::AddGroup(Player* leader, Group* grp, BattleGr
|
||||||
void BattleGroundQueue::PlayerInvitedToBGUpdateAverageWaitTime(GroupQueueInfo* ginfo, BattleGroundBracketId bracket_id)
|
void BattleGroundQueue::PlayerInvitedToBGUpdateAverageWaitTime(GroupQueueInfo* ginfo, BattleGroundBracketId bracket_id)
|
||||||
{
|
{
|
||||||
uint32 timeInQueue = WorldTimer::getMSTimeDiff(ginfo->JoinTime, WorldTimer::getMSTime());
|
uint32 timeInQueue = WorldTimer::getMSTimeDiff(ginfo->JoinTime, WorldTimer::getMSTime());
|
||||||
uint8 team_index = BG_TEAM_ALLIANCE; // default set to BG_TEAM_ALLIANCE - or non rated arenas!
|
uint8 team_index = TEAM_INDEX_ALLIANCE; // default set to TEAM_INDEX_ALLIANCE - or non rated arenas!
|
||||||
if (ginfo->arenaType == ARENA_TYPE_NONE)
|
if (ginfo->arenaType == ARENA_TYPE_NONE)
|
||||||
{
|
{
|
||||||
if (ginfo->GroupTeam == HORDE)
|
if (ginfo->GroupTeam == HORDE)
|
||||||
team_index = BG_TEAM_HORDE;
|
team_index = TEAM_INDEX_HORDE;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (ginfo->IsRated)
|
if (ginfo->IsRated)
|
||||||
team_index = BG_TEAM_HORDE; // for rated arenas use BG_TEAM_HORDE
|
team_index = TEAM_INDEX_HORDE; // for rated arenas use TEAM_INDEX_HORDE
|
||||||
}
|
}
|
||||||
|
|
||||||
// store pointer to arrayindex of player that was added first
|
// store pointer to arrayindex of player that was added first
|
||||||
|
|
@ -287,16 +287,16 @@ void BattleGroundQueue::PlayerInvitedToBGUpdateAverageWaitTime(GroupQueueInfo* g
|
||||||
|
|
||||||
uint32 BattleGroundQueue::GetAverageQueueWaitTime(GroupQueueInfo* ginfo, BattleGroundBracketId bracket_id)
|
uint32 BattleGroundQueue::GetAverageQueueWaitTime(GroupQueueInfo* ginfo, BattleGroundBracketId bracket_id)
|
||||||
{
|
{
|
||||||
uint8 team_index = BG_TEAM_ALLIANCE; // default set to BG_TEAM_ALLIANCE - or non rated arenas!
|
uint8 team_index = TEAM_INDEX_ALLIANCE; // default set to TEAM_INDEX_ALLIANCE - or non rated arenas!
|
||||||
if (ginfo->arenaType == ARENA_TYPE_NONE)
|
if (ginfo->arenaType == ARENA_TYPE_NONE)
|
||||||
{
|
{
|
||||||
if (ginfo->GroupTeam == HORDE)
|
if (ginfo->GroupTeam == HORDE)
|
||||||
team_index = BG_TEAM_HORDE;
|
team_index = TEAM_INDEX_HORDE;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (ginfo->IsRated)
|
if (ginfo->IsRated)
|
||||||
team_index = BG_TEAM_HORDE; // for rated arenas use BG_TEAM_HORDE
|
team_index = TEAM_INDEX_HORDE; // for rated arenas use TEAM_INDEX_HORDE
|
||||||
}
|
}
|
||||||
// check if there is enought values(we always add values > 0)
|
// check if there is enought values(we always add values > 0)
|
||||||
if (m_WaitTimes[team_index][bracket_id][COUNT_OF_PLAYERS_TO_AVERAGE_WAIT_TIME - 1])
|
if (m_WaitTimes[team_index][bracket_id][COUNT_OF_PLAYERS_TO_AVERAGE_WAIT_TIME - 1])
|
||||||
|
|
@ -526,13 +526,13 @@ void BattleGroundQueue::FillPlayersToBG(BattleGround* bg, BattleGroundBracketId
|
||||||
uint32 aliCount = m_QueuedGroups[bracket_id][BG_QUEUE_NORMAL_ALLIANCE].size();
|
uint32 aliCount = m_QueuedGroups[bracket_id][BG_QUEUE_NORMAL_ALLIANCE].size();
|
||||||
// index to queue which group is current
|
// index to queue which group is current
|
||||||
uint32 aliIndex = 0;
|
uint32 aliIndex = 0;
|
||||||
for (; aliIndex < aliCount && m_SelectionPools[BG_TEAM_ALLIANCE].AddGroup((*Ali_itr), aliFree); ++aliIndex)
|
for (; aliIndex < aliCount && m_SelectionPools[TEAM_INDEX_ALLIANCE].AddGroup((*Ali_itr), aliFree); ++aliIndex)
|
||||||
++Ali_itr;
|
++Ali_itr;
|
||||||
// the same thing for horde
|
// the same thing for horde
|
||||||
GroupsQueueType::const_iterator Horde_itr = m_QueuedGroups[bracket_id][BG_QUEUE_NORMAL_HORDE].begin();
|
GroupsQueueType::const_iterator Horde_itr = m_QueuedGroups[bracket_id][BG_QUEUE_NORMAL_HORDE].begin();
|
||||||
uint32 hordeCount = m_QueuedGroups[bracket_id][BG_QUEUE_NORMAL_HORDE].size();
|
uint32 hordeCount = m_QueuedGroups[bracket_id][BG_QUEUE_NORMAL_HORDE].size();
|
||||||
uint32 hordeIndex = 0;
|
uint32 hordeIndex = 0;
|
||||||
for (; hordeIndex < hordeCount && m_SelectionPools[BG_TEAM_HORDE].AddGroup((*Horde_itr), hordeFree); ++hordeIndex)
|
for (; hordeIndex < hordeCount && m_SelectionPools[TEAM_INDEX_HORDE].AddGroup((*Horde_itr), hordeFree); ++hordeIndex)
|
||||||
++Horde_itr;
|
++Horde_itr;
|
||||||
|
|
||||||
// if ofc like BG queue invitation is set in config, then we are happy
|
// if ofc like BG queue invitation is set in config, then we are happy
|
||||||
|
|
@ -548,45 +548,45 @@ void BattleGroundQueue::FillPlayersToBG(BattleGround* bg, BattleGroundBracketId
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// At first we need to compare free space in bg and our selection pool
|
// At first we need to compare free space in bg and our selection pool
|
||||||
int32 diffAli = aliFree - int32(m_SelectionPools[BG_TEAM_ALLIANCE].GetPlayerCount());
|
int32 diffAli = aliFree - int32(m_SelectionPools[TEAM_INDEX_ALLIANCE].GetPlayerCount());
|
||||||
int32 diffHorde = hordeFree - int32(m_SelectionPools[BG_TEAM_HORDE].GetPlayerCount());
|
int32 diffHorde = hordeFree - int32(m_SelectionPools[TEAM_INDEX_HORDE].GetPlayerCount());
|
||||||
while (abs(diffAli - diffHorde) > 1 && (m_SelectionPools[BG_TEAM_HORDE].GetPlayerCount() > 0 || m_SelectionPools[BG_TEAM_ALLIANCE].GetPlayerCount() > 0))
|
while (abs(diffAli - diffHorde) > 1 && (m_SelectionPools[TEAM_INDEX_HORDE].GetPlayerCount() > 0 || m_SelectionPools[TEAM_INDEX_ALLIANCE].GetPlayerCount() > 0))
|
||||||
{
|
{
|
||||||
// each cycle execution we need to kick at least 1 group
|
// each cycle execution we need to kick at least 1 group
|
||||||
if (diffAli < diffHorde)
|
if (diffAli < diffHorde)
|
||||||
{
|
{
|
||||||
// kick alliance group, add to pool new group if needed
|
// kick alliance group, add to pool new group if needed
|
||||||
if (m_SelectionPools[BG_TEAM_ALLIANCE].KickGroup(diffHorde - diffAli))
|
if (m_SelectionPools[TEAM_INDEX_ALLIANCE].KickGroup(diffHorde - diffAli))
|
||||||
{
|
{
|
||||||
for (; aliIndex < aliCount && m_SelectionPools[BG_TEAM_ALLIANCE].AddGroup((*Ali_itr), (aliFree >= diffHorde) ? aliFree - diffHorde : 0); ++aliIndex)
|
for (; aliIndex < aliCount && m_SelectionPools[TEAM_INDEX_ALLIANCE].AddGroup((*Ali_itr), (aliFree >= diffHorde) ? aliFree - diffHorde : 0); ++aliIndex)
|
||||||
++Ali_itr;
|
++Ali_itr;
|
||||||
}
|
}
|
||||||
// if ali selection is already empty, then kick horde group, but if there are less horde than ali in bg - break;
|
// if ali selection is already empty, then kick horde group, but if there are less horde than ali in bg - break;
|
||||||
if (!m_SelectionPools[BG_TEAM_ALLIANCE].GetPlayerCount())
|
if (!m_SelectionPools[TEAM_INDEX_ALLIANCE].GetPlayerCount())
|
||||||
{
|
{
|
||||||
if (aliFree <= diffHorde + 1)
|
if (aliFree <= diffHorde + 1)
|
||||||
break;
|
break;
|
||||||
m_SelectionPools[BG_TEAM_HORDE].KickGroup(diffHorde - diffAli);
|
m_SelectionPools[TEAM_INDEX_HORDE].KickGroup(diffHorde - diffAli);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// kick horde group, add to pool new group if needed
|
// kick horde group, add to pool new group if needed
|
||||||
if (m_SelectionPools[BG_TEAM_HORDE].KickGroup(diffAli - diffHorde))
|
if (m_SelectionPools[TEAM_INDEX_HORDE].KickGroup(diffAli - diffHorde))
|
||||||
{
|
{
|
||||||
for (; hordeIndex < hordeCount && m_SelectionPools[BG_TEAM_HORDE].AddGroup((*Horde_itr), (hordeFree >= diffAli) ? hordeFree - diffAli : 0); ++hordeIndex)
|
for (; hordeIndex < hordeCount && m_SelectionPools[TEAM_INDEX_HORDE].AddGroup((*Horde_itr), (hordeFree >= diffAli) ? hordeFree - diffAli : 0); ++hordeIndex)
|
||||||
++Horde_itr;
|
++Horde_itr;
|
||||||
}
|
}
|
||||||
if (!m_SelectionPools[BG_TEAM_HORDE].GetPlayerCount())
|
if (!m_SelectionPools[TEAM_INDEX_HORDE].GetPlayerCount())
|
||||||
{
|
{
|
||||||
if (hordeFree <= diffAli + 1)
|
if (hordeFree <= diffAli + 1)
|
||||||
break;
|
break;
|
||||||
m_SelectionPools[BG_TEAM_ALLIANCE].KickGroup(diffAli - diffHorde);
|
m_SelectionPools[TEAM_INDEX_ALLIANCE].KickGroup(diffAli - diffHorde);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// count diffs after small update
|
// count diffs after small update
|
||||||
diffAli = aliFree - int32(m_SelectionPools[BG_TEAM_ALLIANCE].GetPlayerCount());
|
diffAli = aliFree - int32(m_SelectionPools[TEAM_INDEX_ALLIANCE].GetPlayerCount());
|
||||||
diffHorde = hordeFree - int32(m_SelectionPools[BG_TEAM_HORDE].GetPlayerCount());
|
diffHorde = hordeFree - int32(m_SelectionPools[TEAM_INDEX_HORDE].GetPlayerCount());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -610,12 +610,12 @@ bool BattleGroundQueue::CheckPremadeMatch(BattleGroundBracketId bracket_id, uint
|
||||||
|
|
||||||
if (ali_group != m_QueuedGroups[bracket_id][BG_QUEUE_PREMADE_ALLIANCE].end() && horde_group != m_QueuedGroups[bracket_id][BG_QUEUE_PREMADE_HORDE].end())
|
if (ali_group != m_QueuedGroups[bracket_id][BG_QUEUE_PREMADE_ALLIANCE].end() && horde_group != m_QueuedGroups[bracket_id][BG_QUEUE_PREMADE_HORDE].end())
|
||||||
{
|
{
|
||||||
m_SelectionPools[BG_TEAM_ALLIANCE].AddGroup((*ali_group), MaxPlayersPerTeam);
|
m_SelectionPools[TEAM_INDEX_ALLIANCE].AddGroup((*ali_group), MaxPlayersPerTeam);
|
||||||
m_SelectionPools[BG_TEAM_HORDE].AddGroup((*horde_group), MaxPlayersPerTeam);
|
m_SelectionPools[TEAM_INDEX_HORDE].AddGroup((*horde_group), MaxPlayersPerTeam);
|
||||||
// add groups/players from normal queue to size of bigger group
|
// add groups/players from normal queue to size of bigger group
|
||||||
uint32 maxPlayers = std::max(m_SelectionPools[BG_TEAM_ALLIANCE].GetPlayerCount(), m_SelectionPools[BG_TEAM_HORDE].GetPlayerCount());
|
uint32 maxPlayers = std::max(m_SelectionPools[TEAM_INDEX_ALLIANCE].GetPlayerCount(), m_SelectionPools[TEAM_INDEX_HORDE].GetPlayerCount());
|
||||||
GroupsQueueType::const_iterator itr;
|
GroupsQueueType::const_iterator itr;
|
||||||
for (uint8 i = 0; i < BG_TEAMS_COUNT; ++i)
|
for (uint8 i = 0; i < PVP_TEAM_COUNT; ++i)
|
||||||
{
|
{
|
||||||
for (itr = m_QueuedGroups[bracket_id][BG_QUEUE_NORMAL_ALLIANCE + i].begin(); itr != m_QueuedGroups[bracket_id][BG_QUEUE_NORMAL_ALLIANCE + i].end(); ++itr)
|
for (itr = m_QueuedGroups[bracket_id][BG_QUEUE_NORMAL_ALLIANCE + i].begin(); itr != m_QueuedGroups[bracket_id][BG_QUEUE_NORMAL_ALLIANCE + i].end(); ++itr)
|
||||||
{
|
{
|
||||||
|
|
@ -633,7 +633,7 @@ bool BattleGroundQueue::CheckPremadeMatch(BattleGroundBracketId bracket_id, uint
|
||||||
// if first is invited to BG and seconds timer expired, but we can ignore it, because players have only 80 seconds to click to enter bg
|
// if first is invited to BG and seconds timer expired, but we can ignore it, because players have only 80 seconds to click to enter bg
|
||||||
// and when they click or after 80 seconds the queue info is removed from queue
|
// and when they click or after 80 seconds the queue info is removed from queue
|
||||||
uint32 time_before = WorldTimer::getMSTime() - sWorld.getConfig(CONFIG_UINT32_BATTLEGROUND_PREMADE_GROUP_WAIT_FOR_MATCH);
|
uint32 time_before = WorldTimer::getMSTime() - sWorld.getConfig(CONFIG_UINT32_BATTLEGROUND_PREMADE_GROUP_WAIT_FOR_MATCH);
|
||||||
for (uint8 i = 0; i < BG_TEAMS_COUNT; ++i)
|
for (uint8 i = 0; i < PVP_TEAM_COUNT; ++i)
|
||||||
{
|
{
|
||||||
if (!m_QueuedGroups[bracket_id][BG_QUEUE_PREMADE_ALLIANCE + i].empty())
|
if (!m_QueuedGroups[bracket_id][BG_QUEUE_PREMADE_ALLIANCE + i].empty())
|
||||||
{
|
{
|
||||||
|
|
@ -653,8 +653,8 @@ bool BattleGroundQueue::CheckPremadeMatch(BattleGroundBracketId bracket_id, uint
|
||||||
// this method tries to create battleground or arena with MinPlayersPerTeam against MinPlayersPerTeam
|
// this method tries to create battleground or arena with MinPlayersPerTeam against MinPlayersPerTeam
|
||||||
bool BattleGroundQueue::CheckNormalMatch(BattleGround* bg_template, BattleGroundBracketId bracket_id, uint32 minPlayers, uint32 maxPlayers)
|
bool BattleGroundQueue::CheckNormalMatch(BattleGround* bg_template, BattleGroundBracketId bracket_id, uint32 minPlayers, uint32 maxPlayers)
|
||||||
{
|
{
|
||||||
GroupsQueueType::const_iterator itr_team[BG_TEAMS_COUNT];
|
GroupsQueueType::const_iterator itr_team[PVP_TEAM_COUNT];
|
||||||
for (uint8 i = 0; i < BG_TEAMS_COUNT; ++i)
|
for (uint8 i = 0; i < PVP_TEAM_COUNT; ++i)
|
||||||
{
|
{
|
||||||
itr_team[i] = m_QueuedGroups[bracket_id][BG_QUEUE_NORMAL_ALLIANCE + i].begin();
|
itr_team[i] = m_QueuedGroups[bracket_id][BG_QUEUE_NORMAL_ALLIANCE + i].begin();
|
||||||
for (; itr_team[i] != m_QueuedGroups[bracket_id][BG_QUEUE_NORMAL_ALLIANCE + i].end(); ++(itr_team[i]))
|
for (; itr_team[i] != m_QueuedGroups[bracket_id][BG_QUEUE_NORMAL_ALLIANCE + i].end(); ++(itr_team[i]))
|
||||||
|
|
@ -668,43 +668,43 @@ bool BattleGroundQueue::CheckNormalMatch(BattleGround* bg_template, BattleGround
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// try to invite same number of players - this cycle may cause longer wait time even if there are enough players in queue, but we want ballanced bg
|
// try to invite same number of players - this cycle may cause longer wait time even if there are enough players in queue, but we want ballanced bg
|
||||||
uint32 j = BG_TEAM_ALLIANCE;
|
uint32 j = TEAM_INDEX_ALLIANCE;
|
||||||
if (m_SelectionPools[BG_TEAM_HORDE].GetPlayerCount() < m_SelectionPools[BG_TEAM_ALLIANCE].GetPlayerCount())
|
if (m_SelectionPools[TEAM_INDEX_HORDE].GetPlayerCount() < m_SelectionPools[TEAM_INDEX_ALLIANCE].GetPlayerCount())
|
||||||
j = BG_TEAM_HORDE;
|
j = TEAM_INDEX_HORDE;
|
||||||
if (sWorld.getConfig(CONFIG_UINT32_BATTLEGROUND_INVITATION_TYPE) != 0
|
if (sWorld.getConfig(CONFIG_UINT32_BATTLEGROUND_INVITATION_TYPE) != 0
|
||||||
&& m_SelectionPools[BG_TEAM_HORDE].GetPlayerCount() >= minPlayers && m_SelectionPools[BG_TEAM_ALLIANCE].GetPlayerCount() >= minPlayers)
|
&& m_SelectionPools[TEAM_INDEX_HORDE].GetPlayerCount() >= minPlayers && m_SelectionPools[TEAM_INDEX_ALLIANCE].GetPlayerCount() >= minPlayers)
|
||||||
{
|
{
|
||||||
// we will try to invite more groups to team with less players indexed by j
|
// we will try to invite more groups to team with less players indexed by j
|
||||||
++(itr_team[j]); // this will not cause a crash, because for cycle above reached break;
|
++(itr_team[j]); // this will not cause a crash, because for cycle above reached break;
|
||||||
for (; itr_team[j] != m_QueuedGroups[bracket_id][BG_QUEUE_NORMAL_ALLIANCE + j].end(); ++(itr_team[j]))
|
for (; itr_team[j] != m_QueuedGroups[bracket_id][BG_QUEUE_NORMAL_ALLIANCE + j].end(); ++(itr_team[j]))
|
||||||
{
|
{
|
||||||
if (!(*(itr_team[j]))->IsInvitedToBGInstanceGUID)
|
if (!(*(itr_team[j]))->IsInvitedToBGInstanceGUID)
|
||||||
if (!m_SelectionPools[j].AddGroup(*(itr_team[j]), m_SelectionPools[(j + 1) % BG_TEAMS_COUNT].GetPlayerCount()))
|
if (!m_SelectionPools[j].AddGroup(*(itr_team[j]), m_SelectionPools[(j + 1) % PVP_TEAM_COUNT].GetPlayerCount()))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// do not allow to start bg with more than 2 players more on 1 faction
|
// do not allow to start bg with more than 2 players more on 1 faction
|
||||||
if (abs((int32)(m_SelectionPools[BG_TEAM_HORDE].GetPlayerCount() - m_SelectionPools[BG_TEAM_ALLIANCE].GetPlayerCount())) > 2)
|
if (abs((int32)(m_SelectionPools[TEAM_INDEX_HORDE].GetPlayerCount() - m_SelectionPools[TEAM_INDEX_ALLIANCE].GetPlayerCount())) > 2)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// allow 1v0 if debug bg
|
// allow 1v0 if debug bg
|
||||||
if (sBattleGroundMgr.isTesting() && bg_template->isBattleGround() && (m_SelectionPools[BG_TEAM_ALLIANCE].GetPlayerCount() || m_SelectionPools[BG_TEAM_HORDE].GetPlayerCount()))
|
if (sBattleGroundMgr.isTesting() && bg_template->isBattleGround() && (m_SelectionPools[TEAM_INDEX_ALLIANCE].GetPlayerCount() || m_SelectionPools[TEAM_INDEX_HORDE].GetPlayerCount()))
|
||||||
return true;
|
return true;
|
||||||
// return true if there are enough players in selection pools - enable to work .debug bg command correctly
|
// return true if there are enough players in selection pools - enable to work .debug bg command correctly
|
||||||
return m_SelectionPools[BG_TEAM_ALLIANCE].GetPlayerCount() >= minPlayers && m_SelectionPools[BG_TEAM_HORDE].GetPlayerCount() >= minPlayers;
|
return m_SelectionPools[TEAM_INDEX_ALLIANCE].GetPlayerCount() >= minPlayers && m_SelectionPools[TEAM_INDEX_HORDE].GetPlayerCount() >= minPlayers;
|
||||||
}
|
}
|
||||||
|
|
||||||
// this method will check if we can invite players to same faction skirmish match
|
// this method will check if we can invite players to same faction skirmish match
|
||||||
bool BattleGroundQueue::CheckSkirmishForSameFaction(BattleGroundBracketId bracket_id, uint32 minPlayersPerTeam)
|
bool BattleGroundQueue::CheckSkirmishForSameFaction(BattleGroundBracketId bracket_id, uint32 minPlayersPerTeam)
|
||||||
{
|
{
|
||||||
if (m_SelectionPools[BG_TEAM_ALLIANCE].GetPlayerCount() < minPlayersPerTeam && m_SelectionPools[BG_TEAM_HORDE].GetPlayerCount() < minPlayersPerTeam)
|
if (m_SelectionPools[TEAM_INDEX_ALLIANCE].GetPlayerCount() < minPlayersPerTeam && m_SelectionPools[TEAM_INDEX_HORDE].GetPlayerCount() < minPlayersPerTeam)
|
||||||
return false;
|
return false;
|
||||||
BattleGroundTeamIndex teamIdx = BG_TEAM_ALLIANCE;
|
PvpTeamIndex teamIdx = TEAM_INDEX_ALLIANCE;
|
||||||
BattleGroundTeamIndex otherTeamIdx = BG_TEAM_HORDE;
|
PvpTeamIndex otherTeamIdx = TEAM_INDEX_HORDE;
|
||||||
Team otherTeamId = HORDE;
|
Team otherTeamId = HORDE;
|
||||||
if (m_SelectionPools[BG_TEAM_HORDE].GetPlayerCount() == minPlayersPerTeam)
|
if (m_SelectionPools[TEAM_INDEX_HORDE].GetPlayerCount() == minPlayersPerTeam)
|
||||||
{
|
{
|
||||||
teamIdx = BG_TEAM_HORDE;
|
teamIdx = TEAM_INDEX_HORDE;
|
||||||
otherTeamIdx = BG_TEAM_ALLIANCE;
|
otherTeamIdx = TEAM_INDEX_ALLIANCE;
|
||||||
otherTeamId = ALLIANCE;
|
otherTeamId = ALLIANCE;
|
||||||
}
|
}
|
||||||
// clear other team's selection
|
// clear other team's selection
|
||||||
|
|
@ -782,16 +782,16 @@ void BattleGroundQueue::Update(BattleGroundTypeId bgTypeId, BattleGroundBracketI
|
||||||
// and iterator is invalid
|
// and iterator is invalid
|
||||||
|
|
||||||
// clear selection pools
|
// clear selection pools
|
||||||
m_SelectionPools[BG_TEAM_ALLIANCE].Init();
|
m_SelectionPools[TEAM_INDEX_ALLIANCE].Init();
|
||||||
m_SelectionPools[BG_TEAM_HORDE].Init();
|
m_SelectionPools[TEAM_INDEX_HORDE].Init();
|
||||||
|
|
||||||
// call a function that does the job for us
|
// call a function that does the job for us
|
||||||
FillPlayersToBG(bg, bracket_id);
|
FillPlayersToBG(bg, bracket_id);
|
||||||
|
|
||||||
// now everything is set, invite players
|
// now everything is set, invite players
|
||||||
for (GroupsQueueType::const_iterator citr = m_SelectionPools[BG_TEAM_ALLIANCE].SelectedGroups.begin(); citr != m_SelectionPools[BG_TEAM_ALLIANCE].SelectedGroups.end(); ++citr)
|
for (GroupsQueueType::const_iterator citr = m_SelectionPools[TEAM_INDEX_ALLIANCE].SelectedGroups.begin(); citr != m_SelectionPools[TEAM_INDEX_ALLIANCE].SelectedGroups.end(); ++citr)
|
||||||
InviteGroupToBG((*citr), bg, (*citr)->GroupTeam);
|
InviteGroupToBG((*citr), bg, (*citr)->GroupTeam);
|
||||||
for (GroupsQueueType::const_iterator citr = m_SelectionPools[BG_TEAM_HORDE].SelectedGroups.begin(); citr != m_SelectionPools[BG_TEAM_HORDE].SelectedGroups.end(); ++citr)
|
for (GroupsQueueType::const_iterator citr = m_SelectionPools[TEAM_INDEX_HORDE].SelectedGroups.begin(); citr != m_SelectionPools[TEAM_INDEX_HORDE].SelectedGroups.end(); ++citr)
|
||||||
InviteGroupToBG((*citr), bg, (*citr)->GroupTeam);
|
InviteGroupToBG((*citr), bg, (*citr)->GroupTeam);
|
||||||
|
|
||||||
if (!bg->HasFreeSlots())
|
if (!bg->HasFreeSlots())
|
||||||
|
|
@ -853,8 +853,8 @@ void BattleGroundQueue::Update(BattleGroundTypeId bgTypeId, BattleGroundBracketI
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
m_SelectionPools[BG_TEAM_ALLIANCE].Init();
|
m_SelectionPools[TEAM_INDEX_ALLIANCE].Init();
|
||||||
m_SelectionPools[BG_TEAM_HORDE].Init();
|
m_SelectionPools[TEAM_INDEX_HORDE].Init();
|
||||||
|
|
||||||
if (bg_template->isBattleGround())
|
if (bg_template->isBattleGround())
|
||||||
{
|
{
|
||||||
|
|
@ -869,14 +869,14 @@ void BattleGroundQueue::Update(BattleGroundTypeId bgTypeId, BattleGroundBracketI
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// invite those selection pools
|
// invite those selection pools
|
||||||
for (uint8 i = 0; i < BG_TEAMS_COUNT; ++i)
|
for (uint8 i = 0; i < PVP_TEAM_COUNT; ++i)
|
||||||
for (GroupsQueueType::const_iterator citr = m_SelectionPools[BG_TEAM_ALLIANCE + i].SelectedGroups.begin(); citr != m_SelectionPools[BG_TEAM_ALLIANCE + i].SelectedGroups.end(); ++citr)
|
for (GroupsQueueType::const_iterator citr = m_SelectionPools[TEAM_INDEX_ALLIANCE + i].SelectedGroups.begin(); citr != m_SelectionPools[TEAM_INDEX_ALLIANCE + i].SelectedGroups.end(); ++citr)
|
||||||
InviteGroupToBG((*citr), bg2, (*citr)->GroupTeam);
|
InviteGroupToBG((*citr), bg2, (*citr)->GroupTeam);
|
||||||
// start bg
|
// start bg
|
||||||
bg2->StartBattleGround();
|
bg2->StartBattleGround();
|
||||||
// clear structures
|
// clear structures
|
||||||
m_SelectionPools[BG_TEAM_ALLIANCE].Init();
|
m_SelectionPools[TEAM_INDEX_ALLIANCE].Init();
|
||||||
m_SelectionPools[BG_TEAM_HORDE].Init();
|
m_SelectionPools[TEAM_INDEX_HORDE].Init();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -896,8 +896,8 @@ void BattleGroundQueue::Update(BattleGroundTypeId bgTypeId, BattleGroundBracketI
|
||||||
}
|
}
|
||||||
|
|
||||||
// invite those selection pools
|
// invite those selection pools
|
||||||
for (uint8 i = 0; i < BG_TEAMS_COUNT; ++i)
|
for (uint8 i = 0; i < PVP_TEAM_COUNT; ++i)
|
||||||
for (GroupsQueueType::const_iterator citr = m_SelectionPools[BG_TEAM_ALLIANCE + i].SelectedGroups.begin(); citr != m_SelectionPools[BG_TEAM_ALLIANCE + i].SelectedGroups.end(); ++citr)
|
for (GroupsQueueType::const_iterator citr = m_SelectionPools[TEAM_INDEX_ALLIANCE + i].SelectedGroups.begin(); citr != m_SelectionPools[TEAM_INDEX_ALLIANCE + i].SelectedGroups.end(); ++citr)
|
||||||
InviteGroupToBG((*citr), bg2, (*citr)->GroupTeam);
|
InviteGroupToBG((*citr), bg2, (*citr)->GroupTeam);
|
||||||
// start bg
|
// start bg
|
||||||
bg2->StartBattleGround();
|
bg2->StartBattleGround();
|
||||||
|
|
@ -942,7 +942,7 @@ void BattleGroundQueue::Update(BattleGroundTypeId bgTypeId, BattleGroundBracketI
|
||||||
|
|
||||||
// we need to find 2 teams which will play next game
|
// we need to find 2 teams which will play next game
|
||||||
|
|
||||||
GroupsQueueType::iterator itr_team[BG_TEAMS_COUNT];
|
GroupsQueueType::iterator itr_team[PVP_TEAM_COUNT];
|
||||||
|
|
||||||
// optimalization : --- we dont need to use selection_pools - each update we select max 2 groups
|
// optimalization : --- we dont need to use selection_pools - each update we select max 2 groups
|
||||||
|
|
||||||
|
|
@ -967,40 +967,40 @@ void BattleGroundQueue::Update(BattleGroundTypeId bgTypeId, BattleGroundBracketI
|
||||||
// if we don't have, we must try to continue search in same queue
|
// if we don't have, we must try to continue search in same queue
|
||||||
// tmp variables are correctly set
|
// tmp variables are correctly set
|
||||||
// this code isn't much userfriendly - but it is supposed to continue search for mathing group in HORDE queue
|
// this code isn't much userfriendly - but it is supposed to continue search for mathing group in HORDE queue
|
||||||
if (m_SelectionPools[BG_TEAM_ALLIANCE].GetPlayerCount() == 0 && m_SelectionPools[BG_TEAM_HORDE].GetPlayerCount())
|
if (m_SelectionPools[TEAM_INDEX_ALLIANCE].GetPlayerCount() == 0 && m_SelectionPools[TEAM_INDEX_HORDE].GetPlayerCount())
|
||||||
{
|
{
|
||||||
itr_team[BG_TEAM_ALLIANCE] = itr_team[BG_TEAM_HORDE];
|
itr_team[TEAM_INDEX_ALLIANCE] = itr_team[TEAM_INDEX_HORDE];
|
||||||
++itr_team[BG_TEAM_ALLIANCE];
|
++itr_team[TEAM_INDEX_ALLIANCE];
|
||||||
for (; itr_team[BG_TEAM_ALLIANCE] != m_QueuedGroups[bracket_id][BG_QUEUE_PREMADE_HORDE].end(); ++(itr_team[BG_TEAM_ALLIANCE]))
|
for (; itr_team[TEAM_INDEX_ALLIANCE] != m_QueuedGroups[bracket_id][BG_QUEUE_PREMADE_HORDE].end(); ++(itr_team[TEAM_INDEX_ALLIANCE]))
|
||||||
{
|
{
|
||||||
if (!(*itr_team[BG_TEAM_ALLIANCE])->IsInvitedToBGInstanceGUID
|
if (!(*itr_team[TEAM_INDEX_ALLIANCE])->IsInvitedToBGInstanceGUID
|
||||||
&& (((*itr_team[BG_TEAM_ALLIANCE])->ArenaTeamRating >= arenaMinRating && (*itr_team[BG_TEAM_ALLIANCE])->ArenaTeamRating <= arenaMaxRating)
|
&& (((*itr_team[TEAM_INDEX_ALLIANCE])->ArenaTeamRating >= arenaMinRating && (*itr_team[TEAM_INDEX_ALLIANCE])->ArenaTeamRating <= arenaMaxRating)
|
||||||
|| (*itr_team[BG_TEAM_ALLIANCE])->JoinTime < discardTime))
|
|| (*itr_team[TEAM_INDEX_ALLIANCE])->JoinTime < discardTime))
|
||||||
{
|
{
|
||||||
m_SelectionPools[BG_TEAM_ALLIANCE].AddGroup((*itr_team[BG_TEAM_ALLIANCE]), MaxPlayersPerTeam);
|
m_SelectionPools[TEAM_INDEX_ALLIANCE].AddGroup((*itr_team[TEAM_INDEX_ALLIANCE]), MaxPlayersPerTeam);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// this code isn't much userfriendly - but it is supposed to continue search for mathing group in ALLIANCE queue
|
// this code isn't much userfriendly - but it is supposed to continue search for mathing group in ALLIANCE queue
|
||||||
if (m_SelectionPools[BG_TEAM_HORDE].GetPlayerCount() == 0 && m_SelectionPools[BG_TEAM_ALLIANCE].GetPlayerCount())
|
if (m_SelectionPools[TEAM_INDEX_HORDE].GetPlayerCount() == 0 && m_SelectionPools[TEAM_INDEX_ALLIANCE].GetPlayerCount())
|
||||||
{
|
{
|
||||||
itr_team[BG_TEAM_HORDE] = itr_team[BG_TEAM_ALLIANCE];
|
itr_team[TEAM_INDEX_HORDE] = itr_team[TEAM_INDEX_ALLIANCE];
|
||||||
++itr_team[BG_TEAM_HORDE];
|
++itr_team[TEAM_INDEX_HORDE];
|
||||||
for (; itr_team[BG_TEAM_HORDE] != m_QueuedGroups[bracket_id][BG_QUEUE_PREMADE_ALLIANCE].end(); ++(itr_team[BG_TEAM_HORDE]))
|
for (; itr_team[TEAM_INDEX_HORDE] != m_QueuedGroups[bracket_id][BG_QUEUE_PREMADE_ALLIANCE].end(); ++(itr_team[TEAM_INDEX_HORDE]))
|
||||||
{
|
{
|
||||||
if (!(*itr_team[BG_TEAM_HORDE])->IsInvitedToBGInstanceGUID
|
if (!(*itr_team[TEAM_INDEX_HORDE])->IsInvitedToBGInstanceGUID
|
||||||
&& (((*itr_team[BG_TEAM_HORDE])->ArenaTeamRating >= arenaMinRating && (*itr_team[BG_TEAM_HORDE])->ArenaTeamRating <= arenaMaxRating)
|
&& (((*itr_team[TEAM_INDEX_HORDE])->ArenaTeamRating >= arenaMinRating && (*itr_team[TEAM_INDEX_HORDE])->ArenaTeamRating <= arenaMaxRating)
|
||||||
|| (*itr_team[BG_TEAM_HORDE])->JoinTime < discardTime))
|
|| (*itr_team[TEAM_INDEX_HORDE])->JoinTime < discardTime))
|
||||||
{
|
{
|
||||||
m_SelectionPools[BG_TEAM_HORDE].AddGroup((*itr_team[BG_TEAM_HORDE]), MaxPlayersPerTeam);
|
m_SelectionPools[TEAM_INDEX_HORDE].AddGroup((*itr_team[TEAM_INDEX_HORDE]), MaxPlayersPerTeam);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// if we have 2 teams, then start new arena and invite players!
|
// if we have 2 teams, then start new arena and invite players!
|
||||||
if (m_SelectionPools[BG_TEAM_ALLIANCE].GetPlayerCount() && m_SelectionPools[BG_TEAM_HORDE].GetPlayerCount())
|
if (m_SelectionPools[TEAM_INDEX_ALLIANCE].GetPlayerCount() && m_SelectionPools[TEAM_INDEX_HORDE].GetPlayerCount())
|
||||||
{
|
{
|
||||||
BattleGround* arena = sBattleGroundMgr.CreateNewBattleGround(bgTypeId, bracketEntry, arenaType, true);
|
BattleGround* arena = sBattleGroundMgr.CreateNewBattleGround(bgTypeId, bracketEntry, arenaType, true);
|
||||||
if (!arena)
|
if (!arena)
|
||||||
|
|
@ -1009,28 +1009,28 @@ void BattleGroundQueue::Update(BattleGroundTypeId bgTypeId, BattleGroundBracketI
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
(*(itr_team[BG_TEAM_ALLIANCE]))->OpponentsTeamRating = (*(itr_team[BG_TEAM_HORDE]))->ArenaTeamRating;
|
(*(itr_team[TEAM_INDEX_ALLIANCE]))->OpponentsTeamRating = (*(itr_team[TEAM_INDEX_HORDE]))->ArenaTeamRating;
|
||||||
DEBUG_LOG("setting oposite teamrating for team %u to %u", (*(itr_team[BG_TEAM_ALLIANCE]))->ArenaTeamId, (*(itr_team[BG_TEAM_ALLIANCE]))->OpponentsTeamRating);
|
DEBUG_LOG("setting oposite teamrating for team %u to %u", (*(itr_team[TEAM_INDEX_ALLIANCE]))->ArenaTeamId, (*(itr_team[TEAM_INDEX_ALLIANCE]))->OpponentsTeamRating);
|
||||||
(*(itr_team[BG_TEAM_HORDE]))->OpponentsTeamRating = (*(itr_team[BG_TEAM_ALLIANCE]))->ArenaTeamRating;
|
(*(itr_team[TEAM_INDEX_HORDE]))->OpponentsTeamRating = (*(itr_team[TEAM_INDEX_ALLIANCE]))->ArenaTeamRating;
|
||||||
DEBUG_LOG("setting oposite teamrating for team %u to %u", (*(itr_team[BG_TEAM_HORDE]))->ArenaTeamId, (*(itr_team[BG_TEAM_HORDE]))->OpponentsTeamRating);
|
DEBUG_LOG("setting oposite teamrating for team %u to %u", (*(itr_team[TEAM_INDEX_HORDE]))->ArenaTeamId, (*(itr_team[TEAM_INDEX_HORDE]))->OpponentsTeamRating);
|
||||||
// now we must move team if we changed its faction to another faction queue, because then we will spam log by errors in Queue::RemovePlayer
|
// now we must move team if we changed its faction to another faction queue, because then we will spam log by errors in Queue::RemovePlayer
|
||||||
if ((*(itr_team[BG_TEAM_ALLIANCE]))->GroupTeam != ALLIANCE)
|
if ((*(itr_team[TEAM_INDEX_ALLIANCE]))->GroupTeam != ALLIANCE)
|
||||||
{
|
{
|
||||||
// add to alliance queue
|
// add to alliance queue
|
||||||
m_QueuedGroups[bracket_id][BG_QUEUE_PREMADE_ALLIANCE].push_front(*(itr_team[BG_TEAM_ALLIANCE]));
|
m_QueuedGroups[bracket_id][BG_QUEUE_PREMADE_ALLIANCE].push_front(*(itr_team[TEAM_INDEX_ALLIANCE]));
|
||||||
// erase from horde queue
|
// erase from horde queue
|
||||||
m_QueuedGroups[bracket_id][BG_QUEUE_PREMADE_HORDE].erase(itr_team[BG_TEAM_ALLIANCE]);
|
m_QueuedGroups[bracket_id][BG_QUEUE_PREMADE_HORDE].erase(itr_team[TEAM_INDEX_ALLIANCE]);
|
||||||
itr_team[BG_TEAM_ALLIANCE] = m_QueuedGroups[bracket_id][BG_QUEUE_PREMADE_ALLIANCE].begin();
|
itr_team[TEAM_INDEX_ALLIANCE] = m_QueuedGroups[bracket_id][BG_QUEUE_PREMADE_ALLIANCE].begin();
|
||||||
}
|
}
|
||||||
if ((*(itr_team[BG_TEAM_HORDE]))->GroupTeam != HORDE)
|
if ((*(itr_team[TEAM_INDEX_HORDE]))->GroupTeam != HORDE)
|
||||||
{
|
{
|
||||||
m_QueuedGroups[bracket_id][BG_QUEUE_PREMADE_HORDE].push_front(*(itr_team[BG_TEAM_HORDE]));
|
m_QueuedGroups[bracket_id][BG_QUEUE_PREMADE_HORDE].push_front(*(itr_team[TEAM_INDEX_HORDE]));
|
||||||
m_QueuedGroups[bracket_id][BG_QUEUE_PREMADE_ALLIANCE].erase(itr_team[BG_TEAM_HORDE]);
|
m_QueuedGroups[bracket_id][BG_QUEUE_PREMADE_ALLIANCE].erase(itr_team[TEAM_INDEX_HORDE]);
|
||||||
itr_team[BG_TEAM_HORDE] = m_QueuedGroups[bracket_id][BG_QUEUE_PREMADE_HORDE].begin();
|
itr_team[TEAM_INDEX_HORDE] = m_QueuedGroups[bracket_id][BG_QUEUE_PREMADE_HORDE].begin();
|
||||||
}
|
}
|
||||||
|
|
||||||
InviteGroupToBG(*(itr_team[BG_TEAM_ALLIANCE]), arena, ALLIANCE);
|
InviteGroupToBG(*(itr_team[TEAM_INDEX_ALLIANCE]), arena, ALLIANCE);
|
||||||
InviteGroupToBG(*(itr_team[BG_TEAM_HORDE]), arena, HORDE);
|
InviteGroupToBG(*(itr_team[TEAM_INDEX_HORDE]), arena, HORDE);
|
||||||
|
|
||||||
DEBUG_LOG("Starting rated arena match!");
|
DEBUG_LOG("Starting rated arena match!");
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -134,12 +134,12 @@ class BattleGroundQueue
|
||||||
};
|
};
|
||||||
|
|
||||||
// one selection pool for horde, other one for alliance
|
// one selection pool for horde, other one for alliance
|
||||||
SelectionPool m_SelectionPools[BG_TEAMS_COUNT];
|
SelectionPool m_SelectionPools[PVP_TEAM_COUNT];
|
||||||
|
|
||||||
bool InviteGroupToBG(GroupQueueInfo* ginfo, BattleGround* bg, Team side);
|
bool InviteGroupToBG(GroupQueueInfo* ginfo, BattleGround* bg, Team side);
|
||||||
uint32 m_WaitTimes[BG_TEAMS_COUNT][MAX_BATTLEGROUND_BRACKETS][COUNT_OF_PLAYERS_TO_AVERAGE_WAIT_TIME];
|
uint32 m_WaitTimes[PVP_TEAM_COUNT][MAX_BATTLEGROUND_BRACKETS][COUNT_OF_PLAYERS_TO_AVERAGE_WAIT_TIME];
|
||||||
uint32 m_WaitTimeLastPlayer[BG_TEAMS_COUNT][MAX_BATTLEGROUND_BRACKETS];
|
uint32 m_WaitTimeLastPlayer[PVP_TEAM_COUNT][MAX_BATTLEGROUND_BRACKETS];
|
||||||
uint32 m_SumOfWaitTimes[BG_TEAMS_COUNT][MAX_BATTLEGROUND_BRACKETS];
|
uint32 m_SumOfWaitTimes[PVP_TEAM_COUNT][MAX_BATTLEGROUND_BRACKETS];
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
||||||
|
|
@ -48,52 +48,52 @@ void BattleGroundWS::Update(uint32 diff)
|
||||||
|
|
||||||
if (GetStatus() == STATUS_IN_PROGRESS)
|
if (GetStatus() == STATUS_IN_PROGRESS)
|
||||||
{
|
{
|
||||||
if (m_FlagState[BG_TEAM_ALLIANCE] == BG_WS_FLAG_STATE_WAIT_RESPAWN)
|
if (m_FlagState[TEAM_INDEX_ALLIANCE] == BG_WS_FLAG_STATE_WAIT_RESPAWN)
|
||||||
{
|
{
|
||||||
m_FlagsTimer[BG_TEAM_ALLIANCE] -= diff;
|
m_FlagsTimer[TEAM_INDEX_ALLIANCE] -= diff;
|
||||||
|
|
||||||
if (m_FlagsTimer[BG_TEAM_ALLIANCE] < 0)
|
if (m_FlagsTimer[TEAM_INDEX_ALLIANCE] < 0)
|
||||||
{
|
{
|
||||||
m_FlagsTimer[BG_TEAM_ALLIANCE] = 0;
|
m_FlagsTimer[TEAM_INDEX_ALLIANCE] = 0;
|
||||||
RespawnFlag(ALLIANCE, true);
|
RespawnFlag(ALLIANCE, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (m_FlagState[BG_TEAM_ALLIANCE] == BG_WS_FLAG_STATE_ON_GROUND)
|
if (m_FlagState[TEAM_INDEX_ALLIANCE] == BG_WS_FLAG_STATE_ON_GROUND)
|
||||||
{
|
{
|
||||||
m_FlagsDropTimer[BG_TEAM_ALLIANCE] -= diff;
|
m_FlagsDropTimer[TEAM_INDEX_ALLIANCE] -= diff;
|
||||||
|
|
||||||
if (m_FlagsDropTimer[BG_TEAM_ALLIANCE] < 0)
|
if (m_FlagsDropTimer[TEAM_INDEX_ALLIANCE] < 0)
|
||||||
{
|
{
|
||||||
m_FlagsDropTimer[BG_TEAM_ALLIANCE] = 0;
|
m_FlagsDropTimer[TEAM_INDEX_ALLIANCE] = 0;
|
||||||
RespawnDroppedFlag(ALLIANCE);
|
RespawnDroppedFlag(ALLIANCE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (m_FlagState[BG_TEAM_HORDE] == BG_WS_FLAG_STATE_WAIT_RESPAWN)
|
if (m_FlagState[TEAM_INDEX_HORDE] == BG_WS_FLAG_STATE_WAIT_RESPAWN)
|
||||||
{
|
{
|
||||||
m_FlagsTimer[BG_TEAM_HORDE] -= diff;
|
m_FlagsTimer[TEAM_INDEX_HORDE] -= diff;
|
||||||
|
|
||||||
if (m_FlagsTimer[BG_TEAM_HORDE] < 0)
|
if (m_FlagsTimer[TEAM_INDEX_HORDE] < 0)
|
||||||
{
|
{
|
||||||
m_FlagsTimer[BG_TEAM_HORDE] = 0;
|
m_FlagsTimer[TEAM_INDEX_HORDE] = 0;
|
||||||
RespawnFlag(HORDE, true);
|
RespawnFlag(HORDE, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (m_FlagState[BG_TEAM_HORDE] == BG_WS_FLAG_STATE_ON_GROUND)
|
if (m_FlagState[TEAM_INDEX_HORDE] == BG_WS_FLAG_STATE_ON_GROUND)
|
||||||
{
|
{
|
||||||
m_FlagsDropTimer[BG_TEAM_HORDE] -= diff;
|
m_FlagsDropTimer[TEAM_INDEX_HORDE] -= diff;
|
||||||
|
|
||||||
if (m_FlagsDropTimer[BG_TEAM_HORDE] < 0)
|
if (m_FlagsDropTimer[TEAM_INDEX_HORDE] < 0)
|
||||||
{
|
{
|
||||||
m_FlagsDropTimer[BG_TEAM_HORDE] = 0;
|
m_FlagsDropTimer[TEAM_INDEX_HORDE] = 0;
|
||||||
RespawnDroppedFlag(HORDE);
|
RespawnDroppedFlag(HORDE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_EndTimer <= diff)
|
if (m_EndTimer <= diff)
|
||||||
{
|
{
|
||||||
if (m_TeamScores[BG_TEAM_ALLIANCE] > m_TeamScores[BG_TEAM_HORDE])
|
if (m_TeamScores[TEAM_INDEX_ALLIANCE] > m_TeamScores[TEAM_INDEX_HORDE])
|
||||||
EndBattleGround(ALLIANCE);
|
EndBattleGround(ALLIANCE);
|
||||||
else if (m_TeamScores[BG_TEAM_ALLIANCE] < m_TeamScores[BG_TEAM_HORDE])
|
else if (m_TeamScores[TEAM_INDEX_ALLIANCE] < m_TeamScores[TEAM_INDEX_HORDE])
|
||||||
EndBattleGround(HORDE);
|
EndBattleGround(HORDE);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -141,13 +141,13 @@ void BattleGroundWS::RespawnFlag(Team team, bool captured)
|
||||||
if (team == ALLIANCE)
|
if (team == ALLIANCE)
|
||||||
{
|
{
|
||||||
DEBUG_LOG("Respawn Alliance flag");
|
DEBUG_LOG("Respawn Alliance flag");
|
||||||
m_FlagState[BG_TEAM_ALLIANCE] = BG_WS_FLAG_STATE_ON_BASE;
|
m_FlagState[TEAM_INDEX_ALLIANCE] = BG_WS_FLAG_STATE_ON_BASE;
|
||||||
SpawnEvent(WS_EVENT_FLAG_A, 0, true);
|
SpawnEvent(WS_EVENT_FLAG_A, 0, true);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
DEBUG_LOG("Respawn Horde flag");
|
DEBUG_LOG("Respawn Horde flag");
|
||||||
m_FlagState[BG_TEAM_HORDE] = BG_WS_FLAG_STATE_ON_BASE;
|
m_FlagState[TEAM_INDEX_HORDE] = BG_WS_FLAG_STATE_ON_BASE;
|
||||||
SpawnEvent(WS_EVENT_FLAG_H, 0, true);
|
SpawnEvent(WS_EVENT_FLAG_H, 0, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -197,11 +197,11 @@ void BattleGroundWS::EventPlayerCapturedFlag(Player* source)
|
||||||
return;
|
return;
|
||||||
ClearHordeFlagCarrier(); // must be before aura remove to prevent 2 events (drop+capture) at the same time
|
ClearHordeFlagCarrier(); // must be before aura remove to prevent 2 events (drop+capture) at the same time
|
||||||
// horde flag in base (but not respawned yet)
|
// horde flag in base (but not respawned yet)
|
||||||
m_FlagState[BG_TEAM_HORDE] = BG_WS_FLAG_STATE_WAIT_RESPAWN;
|
m_FlagState[TEAM_INDEX_HORDE] = BG_WS_FLAG_STATE_WAIT_RESPAWN;
|
||||||
// Drop Horde Flag from Player
|
// Drop Horde Flag from Player
|
||||||
source->RemoveAurasDueToSpell(BG_WS_SPELL_WARSONG_FLAG);
|
source->RemoveAurasDueToSpell(BG_WS_SPELL_WARSONG_FLAG);
|
||||||
if (m_TeamScores[BG_TEAM_ALLIANCE] < BG_WS_MAX_TEAM_SCORE)
|
if (m_TeamScores[TEAM_INDEX_ALLIANCE] < BG_WS_MAX_TEAM_SCORE)
|
||||||
m_TeamScores[BG_TEAM_ALLIANCE] += 1;
|
m_TeamScores[TEAM_INDEX_ALLIANCE] += 1;
|
||||||
PlaySoundToAll(BG_WS_SOUND_FLAG_CAPTURED_ALLIANCE);
|
PlaySoundToAll(BG_WS_SOUND_FLAG_CAPTURED_ALLIANCE);
|
||||||
RewardReputationToTeam(890, m_ReputationCapture, ALLIANCE);
|
RewardReputationToTeam(890, m_ReputationCapture, ALLIANCE);
|
||||||
}
|
}
|
||||||
|
|
@ -211,11 +211,11 @@ void BattleGroundWS::EventPlayerCapturedFlag(Player* source)
|
||||||
return;
|
return;
|
||||||
ClearAllianceFlagCarrier(); // must be before aura remove to prevent 2 events (drop+capture) at the same time
|
ClearAllianceFlagCarrier(); // must be before aura remove to prevent 2 events (drop+capture) at the same time
|
||||||
// alliance flag in base (but not respawned yet)
|
// alliance flag in base (but not respawned yet)
|
||||||
m_FlagState[BG_TEAM_ALLIANCE] = BG_WS_FLAG_STATE_WAIT_RESPAWN;
|
m_FlagState[TEAM_INDEX_ALLIANCE] = BG_WS_FLAG_STATE_WAIT_RESPAWN;
|
||||||
// Drop Alliance Flag from Player
|
// Drop Alliance Flag from Player
|
||||||
source->RemoveAurasDueToSpell(BG_WS_SPELL_SILVERWING_FLAG);
|
source->RemoveAurasDueToSpell(BG_WS_SPELL_SILVERWING_FLAG);
|
||||||
if (m_TeamScores[BG_TEAM_HORDE] < BG_WS_MAX_TEAM_SCORE)
|
if (m_TeamScores[TEAM_INDEX_HORDE] < BG_WS_MAX_TEAM_SCORE)
|
||||||
m_TeamScores[BG_TEAM_HORDE] += 1;
|
m_TeamScores[TEAM_INDEX_HORDE] += 1;
|
||||||
PlaySoundToAll(BG_WS_SOUND_FLAG_CAPTURED_HORDE);
|
PlaySoundToAll(BG_WS_SOUND_FLAG_CAPTURED_HORDE);
|
||||||
RewardReputationToTeam(889, m_ReputationCapture, HORDE);
|
RewardReputationToTeam(889, m_ReputationCapture, HORDE);
|
||||||
}
|
}
|
||||||
|
|
@ -237,9 +237,9 @@ void BattleGroundWS::EventPlayerCapturedFlag(Player* source)
|
||||||
UpdatePlayerScore(source, SCORE_FLAG_CAPTURES, 1); // +1 flag captures
|
UpdatePlayerScore(source, SCORE_FLAG_CAPTURES, 1); // +1 flag captures
|
||||||
|
|
||||||
Team winner = TEAM_NONE;
|
Team winner = TEAM_NONE;
|
||||||
if (m_TeamScores[BG_TEAM_ALLIANCE] == BG_WS_MAX_TEAM_SCORE)
|
if (m_TeamScores[TEAM_INDEX_ALLIANCE] == BG_WS_MAX_TEAM_SCORE)
|
||||||
winner = ALLIANCE;
|
winner = ALLIANCE;
|
||||||
else if (m_TeamScores[BG_TEAM_HORDE] == BG_WS_MAX_TEAM_SCORE)
|
else if (m_TeamScores[TEAM_INDEX_HORDE] == BG_WS_MAX_TEAM_SCORE)
|
||||||
winner = HORDE;
|
winner = HORDE;
|
||||||
|
|
||||||
if (winner)
|
if (winner)
|
||||||
|
|
@ -296,7 +296,7 @@ void BattleGroundWS::EventPlayerDroppedFlag(Player* source)
|
||||||
{
|
{
|
||||||
ClearHordeFlagCarrier();
|
ClearHordeFlagCarrier();
|
||||||
source->RemoveAurasDueToSpell(BG_WS_SPELL_WARSONG_FLAG);
|
source->RemoveAurasDueToSpell(BG_WS_SPELL_WARSONG_FLAG);
|
||||||
m_FlagState[BG_TEAM_HORDE] = BG_WS_FLAG_STATE_ON_GROUND;
|
m_FlagState[TEAM_INDEX_HORDE] = BG_WS_FLAG_STATE_ON_GROUND;
|
||||||
source->CastSpell(source, BG_WS_SPELL_WARSONG_FLAG_DROPPED, true);
|
source->CastSpell(source, BG_WS_SPELL_WARSONG_FLAG_DROPPED, true);
|
||||||
set = true;
|
set = true;
|
||||||
}
|
}
|
||||||
|
|
@ -309,7 +309,7 @@ void BattleGroundWS::EventPlayerDroppedFlag(Player* source)
|
||||||
{
|
{
|
||||||
ClearAllianceFlagCarrier();
|
ClearAllianceFlagCarrier();
|
||||||
source->RemoveAurasDueToSpell(BG_WS_SPELL_SILVERWING_FLAG);
|
source->RemoveAurasDueToSpell(BG_WS_SPELL_SILVERWING_FLAG);
|
||||||
m_FlagState[BG_TEAM_ALLIANCE] = BG_WS_FLAG_STATE_ON_GROUND;
|
m_FlagState[TEAM_INDEX_ALLIANCE] = BG_WS_FLAG_STATE_ON_GROUND;
|
||||||
source->CastSpell(source, BG_WS_SPELL_SILVERWING_FLAG_DROPPED, true);
|
source->CastSpell(source, BG_WS_SPELL_SILVERWING_FLAG_DROPPED, true);
|
||||||
set = true;
|
set = true;
|
||||||
}
|
}
|
||||||
|
|
@ -354,7 +354,7 @@ void BattleGroundWS::EventPlayerClickedOnFlag(Player* source, GameObject* target
|
||||||
PlaySoundToAll(BG_WS_SOUND_ALLIANCE_FLAG_PICKED_UP);
|
PlaySoundToAll(BG_WS_SOUND_ALLIANCE_FLAG_PICKED_UP);
|
||||||
SpawnEvent(WS_EVENT_FLAG_A, 0, false);
|
SpawnEvent(WS_EVENT_FLAG_A, 0, false);
|
||||||
SetAllianceFlagCarrier(source->GetObjectGuid());
|
SetAllianceFlagCarrier(source->GetObjectGuid());
|
||||||
m_FlagState[BG_TEAM_ALLIANCE] = BG_WS_FLAG_STATE_ON_PLAYER;
|
m_FlagState[TEAM_INDEX_ALLIANCE] = BG_WS_FLAG_STATE_ON_PLAYER;
|
||||||
// update world state to show correct flag carrier
|
// update world state to show correct flag carrier
|
||||||
UpdateFlagState(HORDE, BG_WS_FLAG_STATE_ON_PLAYER);
|
UpdateFlagState(HORDE, BG_WS_FLAG_STATE_ON_PLAYER);
|
||||||
UpdateWorldState(BG_WS_FLAG_UNK_ALLIANCE, 1);
|
UpdateWorldState(BG_WS_FLAG_UNK_ALLIANCE, 1);
|
||||||
|
|
@ -370,7 +370,7 @@ void BattleGroundWS::EventPlayerClickedOnFlag(Player* source, GameObject* target
|
||||||
PlaySoundToAll(BG_WS_SOUND_HORDE_FLAG_PICKED_UP);
|
PlaySoundToAll(BG_WS_SOUND_HORDE_FLAG_PICKED_UP);
|
||||||
SpawnEvent(WS_EVENT_FLAG_H, 0, false);
|
SpawnEvent(WS_EVENT_FLAG_H, 0, false);
|
||||||
SetHordeFlagCarrier(source->GetObjectGuid());
|
SetHordeFlagCarrier(source->GetObjectGuid());
|
||||||
m_FlagState[BG_TEAM_HORDE] = BG_WS_FLAG_STATE_ON_PLAYER;
|
m_FlagState[TEAM_INDEX_HORDE] = BG_WS_FLAG_STATE_ON_PLAYER;
|
||||||
// update world state to show correct flag carrier
|
// update world state to show correct flag carrier
|
||||||
UpdateFlagState(ALLIANCE, BG_WS_FLAG_STATE_ON_PLAYER);
|
UpdateFlagState(ALLIANCE, BG_WS_FLAG_STATE_ON_PLAYER);
|
||||||
UpdateWorldState(BG_WS_FLAG_UNK_HORDE, 1);
|
UpdateWorldState(BG_WS_FLAG_UNK_HORDE, 1);
|
||||||
|
|
@ -397,7 +397,7 @@ void BattleGroundWS::EventPlayerClickedOnFlag(Player* source, GameObject* target
|
||||||
SpawnEvent(WS_EVENT_FLAG_A, 0, false);
|
SpawnEvent(WS_EVENT_FLAG_A, 0, false);
|
||||||
SetAllianceFlagCarrier(source->GetObjectGuid());
|
SetAllianceFlagCarrier(source->GetObjectGuid());
|
||||||
source->CastSpell(source, BG_WS_SPELL_SILVERWING_FLAG, true);
|
source->CastSpell(source, BG_WS_SPELL_SILVERWING_FLAG, true);
|
||||||
m_FlagState[BG_TEAM_ALLIANCE] = BG_WS_FLAG_STATE_ON_PLAYER;
|
m_FlagState[TEAM_INDEX_ALLIANCE] = BG_WS_FLAG_STATE_ON_PLAYER;
|
||||||
UpdateFlagState(HORDE, BG_WS_FLAG_STATE_ON_PLAYER);
|
UpdateFlagState(HORDE, BG_WS_FLAG_STATE_ON_PLAYER);
|
||||||
UpdateWorldState(BG_WS_FLAG_UNK_ALLIANCE, 1);
|
UpdateWorldState(BG_WS_FLAG_UNK_ALLIANCE, 1);
|
||||||
}
|
}
|
||||||
|
|
@ -425,7 +425,7 @@ void BattleGroundWS::EventPlayerClickedOnFlag(Player* source, GameObject* target
|
||||||
SpawnEvent(WS_EVENT_FLAG_H, 0, false);
|
SpawnEvent(WS_EVENT_FLAG_H, 0, false);
|
||||||
SetHordeFlagCarrier(source->GetObjectGuid());
|
SetHordeFlagCarrier(source->GetObjectGuid());
|
||||||
source->CastSpell(source, BG_WS_SPELL_WARSONG_FLAG, true);
|
source->CastSpell(source, BG_WS_SPELL_WARSONG_FLAG, true);
|
||||||
m_FlagState[BG_TEAM_HORDE] = BG_WS_FLAG_STATE_ON_PLAYER;
|
m_FlagState[TEAM_INDEX_HORDE] = BG_WS_FLAG_STATE_ON_PLAYER;
|
||||||
UpdateFlagState(ALLIANCE, BG_WS_FLAG_STATE_ON_PLAYER);
|
UpdateFlagState(ALLIANCE, BG_WS_FLAG_STATE_ON_PLAYER);
|
||||||
UpdateWorldState(BG_WS_FLAG_UNK_HORDE, 1);
|
UpdateWorldState(BG_WS_FLAG_UNK_HORDE, 1);
|
||||||
}
|
}
|
||||||
|
|
@ -478,9 +478,9 @@ void BattleGroundWS::UpdateFlagState(Team team, uint32 value)
|
||||||
void BattleGroundWS::UpdateTeamScore(Team team)
|
void BattleGroundWS::UpdateTeamScore(Team team)
|
||||||
{
|
{
|
||||||
if (team == ALLIANCE)
|
if (team == ALLIANCE)
|
||||||
UpdateWorldState(BG_WS_FLAG_CAPTURES_ALLIANCE, m_TeamScores[BG_TEAM_ALLIANCE]);
|
UpdateWorldState(BG_WS_FLAG_CAPTURES_ALLIANCE, m_TeamScores[TEAM_INDEX_ALLIANCE]);
|
||||||
else
|
else
|
||||||
UpdateWorldState(BG_WS_FLAG_CAPTURES_HORDE, m_TeamScores[BG_TEAM_HORDE]);
|
UpdateWorldState(BG_WS_FLAG_CAPTURES_HORDE, m_TeamScores[TEAM_INDEX_HORDE]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BattleGroundWS::HandleAreaTrigger(Player* source, uint32 trigger)
|
void BattleGroundWS::HandleAreaTrigger(Player* source, uint32 trigger)
|
||||||
|
|
@ -501,12 +501,12 @@ void BattleGroundWS::HandleAreaTrigger(Player* source, uint32 trigger)
|
||||||
case 3709: // Horde elixir of berserk spawn
|
case 3709: // Horde elixir of berserk spawn
|
||||||
break;
|
break;
|
||||||
case 3646: // Alliance Flag spawn
|
case 3646: // Alliance Flag spawn
|
||||||
if (m_FlagState[BG_TEAM_HORDE] && !m_FlagState[BG_TEAM_ALLIANCE])
|
if (m_FlagState[TEAM_INDEX_HORDE] && !m_FlagState[TEAM_INDEX_ALLIANCE])
|
||||||
if (GetHordeFlagCarrierGuid() == source->GetObjectGuid())
|
if (GetHordeFlagCarrierGuid() == source->GetObjectGuid())
|
||||||
EventPlayerCapturedFlag(source);
|
EventPlayerCapturedFlag(source);
|
||||||
break;
|
break;
|
||||||
case 3647: // Horde Flag spawn
|
case 3647: // Horde Flag spawn
|
||||||
if (m_FlagState[BG_TEAM_ALLIANCE] && !m_FlagState[BG_TEAM_HORDE])
|
if (m_FlagState[TEAM_INDEX_ALLIANCE] && !m_FlagState[TEAM_INDEX_HORDE])
|
||||||
if (GetAllianceFlagCarrierGuid() == source->GetObjectGuid())
|
if (GetAllianceFlagCarrierGuid() == source->GetObjectGuid())
|
||||||
EventPlayerCapturedFlag(source);
|
EventPlayerCapturedFlag(source);
|
||||||
break;
|
break;
|
||||||
|
|
@ -532,7 +532,7 @@ void BattleGroundWS::Reset()
|
||||||
m_ActiveEvents[WS_EVENT_FLAG_A] = BG_EVENT_NONE;
|
m_ActiveEvents[WS_EVENT_FLAG_A] = BG_EVENT_NONE;
|
||||||
m_ActiveEvents[WS_EVENT_FLAG_H] = BG_EVENT_NONE;
|
m_ActiveEvents[WS_EVENT_FLAG_H] = BG_EVENT_NONE;
|
||||||
|
|
||||||
for (uint8 i = 0; i < BG_TEAMS_COUNT; ++i)
|
for (uint8 i = 0; i < PVP_TEAM_COUNT; ++i)
|
||||||
{
|
{
|
||||||
m_DroppedFlagGuid[i].Clear();
|
m_DroppedFlagGuid[i].Clear();
|
||||||
m_FlagState[i] = BG_WS_FLAG_STATE_ON_BASE;
|
m_FlagState[i] = BG_WS_FLAG_STATE_ON_BASE;
|
||||||
|
|
@ -620,31 +620,31 @@ WorldSafeLocsEntry const* BattleGroundWS::GetClosestGraveYard(Player* player)
|
||||||
|
|
||||||
void BattleGroundWS::FillInitialWorldStates(WorldPacket& data, uint32& count)
|
void BattleGroundWS::FillInitialWorldStates(WorldPacket& data, uint32& count)
|
||||||
{
|
{
|
||||||
FillInitialWorldState(data, count, BG_WS_FLAG_CAPTURES_ALLIANCE, m_TeamScores[BG_TEAM_ALLIANCE]);
|
FillInitialWorldState(data, count, BG_WS_FLAG_CAPTURES_ALLIANCE, m_TeamScores[TEAM_INDEX_ALLIANCE]);
|
||||||
FillInitialWorldState(data, count, BG_WS_FLAG_CAPTURES_HORDE, m_TeamScores[BG_TEAM_HORDE]);
|
FillInitialWorldState(data, count, BG_WS_FLAG_CAPTURES_HORDE, m_TeamScores[TEAM_INDEX_HORDE]);
|
||||||
|
|
||||||
if (m_FlagState[BG_TEAM_ALLIANCE] == BG_WS_FLAG_STATE_ON_GROUND)
|
if (m_FlagState[TEAM_INDEX_ALLIANCE] == BG_WS_FLAG_STATE_ON_GROUND)
|
||||||
FillInitialWorldState(data, count, BG_WS_FLAG_UNK_ALLIANCE, -1);
|
FillInitialWorldState(data, count, BG_WS_FLAG_UNK_ALLIANCE, -1);
|
||||||
else if (m_FlagState[BG_TEAM_ALLIANCE] == BG_WS_FLAG_STATE_ON_PLAYER)
|
else if (m_FlagState[TEAM_INDEX_ALLIANCE] == BG_WS_FLAG_STATE_ON_PLAYER)
|
||||||
FillInitialWorldState(data, count, BG_WS_FLAG_UNK_ALLIANCE, 1);
|
FillInitialWorldState(data, count, BG_WS_FLAG_UNK_ALLIANCE, 1);
|
||||||
else
|
else
|
||||||
FillInitialWorldState(data, count, BG_WS_FLAG_UNK_ALLIANCE, 0);
|
FillInitialWorldState(data, count, BG_WS_FLAG_UNK_ALLIANCE, 0);
|
||||||
|
|
||||||
if (m_FlagState[BG_TEAM_HORDE] == BG_WS_FLAG_STATE_ON_GROUND)
|
if (m_FlagState[TEAM_INDEX_HORDE] == BG_WS_FLAG_STATE_ON_GROUND)
|
||||||
FillInitialWorldState(data, count, BG_WS_FLAG_UNK_HORDE, -1);
|
FillInitialWorldState(data, count, BG_WS_FLAG_UNK_HORDE, -1);
|
||||||
else if (m_FlagState[BG_TEAM_HORDE] == BG_WS_FLAG_STATE_ON_PLAYER)
|
else if (m_FlagState[TEAM_INDEX_HORDE] == BG_WS_FLAG_STATE_ON_PLAYER)
|
||||||
FillInitialWorldState(data, count, BG_WS_FLAG_UNK_HORDE, 1);
|
FillInitialWorldState(data, count, BG_WS_FLAG_UNK_HORDE, 1);
|
||||||
else
|
else
|
||||||
FillInitialWorldState(data, count, BG_WS_FLAG_UNK_HORDE, 0);
|
FillInitialWorldState(data, count, BG_WS_FLAG_UNK_HORDE, 0);
|
||||||
|
|
||||||
FillInitialWorldState(data, count, BG_WS_FLAG_CAPTURES_MAX, BG_WS_MAX_TEAM_SCORE);
|
FillInitialWorldState(data, count, BG_WS_FLAG_CAPTURES_MAX, BG_WS_MAX_TEAM_SCORE);
|
||||||
|
|
||||||
if (m_FlagState[BG_TEAM_HORDE] == BG_WS_FLAG_STATE_ON_PLAYER)
|
if (m_FlagState[TEAM_INDEX_HORDE] == BG_WS_FLAG_STATE_ON_PLAYER)
|
||||||
FillInitialWorldState(data, count, BG_WS_FLAG_STATE_HORDE, 2);
|
FillInitialWorldState(data, count, BG_WS_FLAG_STATE_HORDE, 2);
|
||||||
else
|
else
|
||||||
FillInitialWorldState(data, count, BG_WS_FLAG_STATE_HORDE, 1);
|
FillInitialWorldState(data, count, BG_WS_FLAG_STATE_HORDE, 1);
|
||||||
|
|
||||||
if (m_FlagState[BG_TEAM_ALLIANCE] == BG_WS_FLAG_STATE_ON_PLAYER)
|
if (m_FlagState[TEAM_INDEX_ALLIANCE] == BG_WS_FLAG_STATE_ON_PLAYER)
|
||||||
FillInitialWorldState(data, count, BG_WS_FLAG_STATE_ALLIANCE, 2);
|
FillInitialWorldState(data, count, BG_WS_FLAG_STATE_ALLIANCE, 2);
|
||||||
else
|
else
|
||||||
FillInitialWorldState(data, count, BG_WS_FLAG_STATE_ALLIANCE, 1);
|
FillInitialWorldState(data, count, BG_WS_FLAG_STATE_ALLIANCE, 1);
|
||||||
|
|
|
||||||
|
|
@ -87,6 +87,10 @@ class BattleGroundWGScore : public BattleGroundScore
|
||||||
public:
|
public:
|
||||||
BattleGroundWGScore() : FlagCaptures(0), FlagReturns(0) {};
|
BattleGroundWGScore() : FlagCaptures(0), FlagReturns(0) {};
|
||||||
virtual ~BattleGroundWGScore() {};
|
virtual ~BattleGroundWGScore() {};
|
||||||
|
|
||||||
|
uint32 GetAttr1() const { return FlagCaptures; }
|
||||||
|
uint32 GetAttr2() const { return FlagReturns; }
|
||||||
|
|
||||||
uint32 FlagCaptures;
|
uint32 FlagCaptures;
|
||||||
uint32 FlagReturns;
|
uint32 FlagReturns;
|
||||||
};
|
};
|
||||||
|
|
@ -154,10 +158,10 @@ class BattleGroundWS : public BattleGround
|
||||||
ObjectGuid m_flagCarrierAlliance;
|
ObjectGuid m_flagCarrierAlliance;
|
||||||
ObjectGuid m_flagCarrierHorde;
|
ObjectGuid m_flagCarrierHorde;
|
||||||
|
|
||||||
ObjectGuid m_DroppedFlagGuid[BG_TEAMS_COUNT];
|
ObjectGuid m_DroppedFlagGuid[PVP_TEAM_COUNT];
|
||||||
uint8 m_FlagState[BG_TEAMS_COUNT];
|
uint8 m_FlagState[PVP_TEAM_COUNT];
|
||||||
int32 m_FlagsTimer[BG_TEAMS_COUNT];
|
int32 m_FlagsTimer[PVP_TEAM_COUNT];
|
||||||
int32 m_FlagsDropTimer[BG_TEAMS_COUNT];
|
int32 m_FlagsDropTimer[PVP_TEAM_COUNT];
|
||||||
|
|
||||||
uint32 m_ReputationCapture;
|
uint32 m_ReputationCapture;
|
||||||
uint32 m_HonorWinKills;
|
uint32 m_HonorWinKills;
|
||||||
|
|
|
||||||
|
|
@ -50,6 +50,7 @@
|
||||||
#include "Util.h"
|
#include "Util.h"
|
||||||
#include "GridNotifiers.h"
|
#include "GridNotifiers.h"
|
||||||
#include "GridNotifiersImpl.h"
|
#include "GridNotifiersImpl.h"
|
||||||
|
#include "CellImpl.h"
|
||||||
#include "WaypointMovementGenerator.h"
|
#include "WaypointMovementGenerator.h"
|
||||||
#include <cctype>
|
#include <cctype>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
|
||||||
|
|
@ -6101,9 +6101,7 @@ bool ChatHandler::HandleGMFlyCommand(char* args)
|
||||||
if (!target)
|
if (!target)
|
||||||
target = m_session->GetPlayer();
|
target = m_session->GetPlayer();
|
||||||
|
|
||||||
WorldPacket data;
|
target->SetCanFly(value);
|
||||||
target->BuildMoveSetCanFlyPacket(&data, value, 0);
|
|
||||||
target->SendMessageToSet(&data, true);
|
|
||||||
PSendSysMessage(LANG_COMMAND_FLYMODE_STATUS, GetNameLink(target).c_str(), args);
|
PSendSysMessage(LANG_COMMAND_FLYMODE_STATUS, GetNameLink(target).c_str(), args);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
@ -7310,6 +7308,64 @@ bool ChatHandler::HandleMmapTestArea(char* args)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// use ".mmap testheight 10" selecting any creature/player
|
||||||
|
bool ChatHandler::HandleMmapTestHeight(char* args)
|
||||||
|
{
|
||||||
|
float radius = 0.0f;
|
||||||
|
ExtractFloat(&args, radius);
|
||||||
|
if (radius > 40.0f)
|
||||||
|
radius = 40.0f;
|
||||||
|
|
||||||
|
Unit* unit = getSelectedUnit();
|
||||||
|
|
||||||
|
Player* player = m_session->GetPlayer();
|
||||||
|
if (!unit)
|
||||||
|
unit = player;
|
||||||
|
|
||||||
|
if (unit->GetTypeId() == TYPEID_UNIT)
|
||||||
|
{
|
||||||
|
if (radius < 0.1f)
|
||||||
|
radius = static_cast<Creature*>(unit)->GetRespawnRadius();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (unit->GetTypeId() != TYPEID_PLAYER)
|
||||||
|
{
|
||||||
|
PSendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (radius < 0.1f)
|
||||||
|
{
|
||||||
|
PSendSysMessage("Provided spawn radius for %s is too small. Using 5.0f instead.", unit->GetGuidStr().c_str());
|
||||||
|
radius = 5.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
float gx, gy, gz;
|
||||||
|
unit->GetPosition(gx, gy, gz);
|
||||||
|
|
||||||
|
Creature* summoned = unit->SummonCreature(VISUAL_WAYPOINT, gx, gy, gz + 0.5f, 0, TEMPSUMMON_TIMED_DESPAWN, 20000);
|
||||||
|
summoned->CastSpell(summoned, 8599, false);
|
||||||
|
uint32 tries = 1;
|
||||||
|
uint32 successes = 0;
|
||||||
|
uint32 startTime = WorldTimer::getMSTime();
|
||||||
|
for (; tries < 500; ++tries)
|
||||||
|
{
|
||||||
|
unit->GetPosition(gx, gy, gz);
|
||||||
|
if (unit->GetMap()->GetReachableRandomPosition(unit, gx, gy, gz, radius))
|
||||||
|
{
|
||||||
|
unit->SummonCreature(VISUAL_WAYPOINT, gx, gy, gz, 0, TEMPSUMMON_TIMED_DESPAWN, 15000);
|
||||||
|
++successes;
|
||||||
|
if (successes >= 100)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
uint32 genTime = WorldTimer::getMSTimeDiff(startTime, WorldTimer::getMSTime());
|
||||||
|
PSendSysMessage("Generated %u valid points for %u try in %ums.", successes, tries, genTime);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool ChatHandler::HandleServerResetAllRaidCommand(char* args)
|
bool ChatHandler::HandleServerResetAllRaidCommand(char* args)
|
||||||
{
|
{
|
||||||
PSendSysMessage("Global raid instances reset, all players in raid instances will be teleported to homebind!");
|
PSendSysMessage("Global raid instances reset, all players in raid instances will be teleported to homebind!");
|
||||||
|
|
|
||||||
|
|
@ -1117,10 +1117,10 @@ bool ChatHandler::HandleDebugSpellCoefsCommand(char* args)
|
||||||
char const* dotDamageStr = GetMangosString(LANG_DOT_DAMAGE);
|
char const* dotDamageStr = GetMangosString(LANG_DOT_DAMAGE);
|
||||||
|
|
||||||
PSendSysMessage(LANG_SPELLCOEFS, spellid, isDirectHeal ? directHealStr : directDamageStr,
|
PSendSysMessage(LANG_SPELLCOEFS, spellid, isDirectHeal ? directHealStr : directDamageStr,
|
||||||
direct_calc, direct_calc * 1.88f, bonus ? bonus->direct_damage : 0.0f, bonus ? bonus->ap_bonus : 0.0f);
|
direct_calc, direct_calc * SCALE_SPELLPOWER_HEALING, bonus ? bonus->direct_damage : 0.0f, bonus ? bonus->ap_bonus : 0.0f);
|
||||||
PSendSysMessage(LANG_SPELLCOEFS, spellid, isDotHeal ? dotHealStr : dotDamageStr,
|
PSendSysMessage(LANG_SPELLCOEFS, spellid, isDotHeal ? dotHealStr : dotDamageStr,
|
||||||
dot_calc, dot_calc * 1.88f, bonus ? bonus->dot_damage : 0.0f, bonus ? bonus->ap_dot_bonus : 0.0f);
|
dot_calc, dot_calc * SCALE_SPELLPOWER_HEALING, bonus ? bonus->dot_damage : 0.0f, bonus ? bonus->ap_dot_bonus : 0.0f);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -118,7 +118,7 @@ template<>
|
||||||
void ConfusedMovementGenerator<Player>::Finalize(Player& unit)
|
void ConfusedMovementGenerator<Player>::Finalize(Player& unit)
|
||||||
{
|
{
|
||||||
unit.clearUnitState(UNIT_STAT_CONFUSED | UNIT_STAT_CONFUSED_MOVE);
|
unit.clearUnitState(UNIT_STAT_CONFUSED | UNIT_STAT_CONFUSED_MOVE);
|
||||||
unit.StopMoving();
|
unit.StopMoving(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
|
|
|
||||||
|
|
@ -37,16 +37,17 @@
|
||||||
template<class T>
|
template<class T>
|
||||||
void FleeingMovementGenerator<T>::_setTargetLocation(T& owner)
|
void FleeingMovementGenerator<T>::_setTargetLocation(T& owner)
|
||||||
{
|
{
|
||||||
if (!&owner)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// ignore in case other no reaction state
|
// ignore in case other no reaction state
|
||||||
if (owner.hasUnitState((UNIT_STAT_CAN_NOT_REACT | UNIT_STAT_NOT_MOVE) & ~UNIT_STAT_FLEEING))
|
if (owner.hasUnitState((UNIT_STAT_CAN_NOT_REACT | UNIT_STAT_NOT_MOVE) & ~UNIT_STAT_FLEEING))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
float x, y, z;
|
float x, y, z;
|
||||||
if (!_getPoint(owner, x, y, z))
|
if (!_getPoint(owner, x, y, z))
|
||||||
|
{
|
||||||
|
// random point not found recheck later
|
||||||
|
i_nextCheckTime.Reset(50);
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
owner.addUnitState(UNIT_STAT_FLEEING_MOVE);
|
owner.addUnitState(UNIT_STAT_FLEEING_MOVE);
|
||||||
|
|
||||||
|
|
@ -55,7 +56,8 @@ void FleeingMovementGenerator<T>::_setTargetLocation(T& owner)
|
||||||
path.calculate(x, y, z);
|
path.calculate(x, y, z);
|
||||||
if (path.getPathType() & PATHFIND_NOPATH)
|
if (path.getPathType() & PATHFIND_NOPATH)
|
||||||
{
|
{
|
||||||
i_nextCheckTime.Reset(urand(1000, 1500));
|
// path not found recheck later
|
||||||
|
i_nextCheckTime.Reset(50);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -69,9 +71,6 @@ void FleeingMovementGenerator<T>::_setTargetLocation(T& owner)
|
||||||
template<class T>
|
template<class T>
|
||||||
bool FleeingMovementGenerator<T>::_getPoint(T& owner, float& x, float& y, float& z)
|
bool FleeingMovementGenerator<T>::_getPoint(T& owner, float& x, float& y, float& z)
|
||||||
{
|
{
|
||||||
if (!&owner)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
float dist_from_caster, angle_to_caster;
|
float dist_from_caster, angle_to_caster;
|
||||||
if (Unit* fright = ObjectAccessor::GetUnit(owner, i_frightGuid))
|
if (Unit* fright = ObjectAccessor::GetUnit(owner, i_frightGuid))
|
||||||
{
|
{
|
||||||
|
|
@ -109,12 +108,23 @@ bool FleeingMovementGenerator<T>::_getPoint(T& owner, float& x, float& y, float&
|
||||||
|
|
||||||
x = curr_x + dist * cos(angle);
|
x = curr_x + dist * cos(angle);
|
||||||
y = curr_y + dist * sin(angle);
|
y = curr_y + dist * sin(angle);
|
||||||
z = curr_z;
|
z = curr_z + 0.5f;
|
||||||
|
|
||||||
|
// try to fix z
|
||||||
|
if (!owner.GetMap()->GetHeightInRange(owner.GetPhaseMask(), x, y, z))
|
||||||
|
return false;
|
||||||
|
|
||||||
if (owner.GetTypeId() == TYPEID_PLAYER)
|
if (owner.GetTypeId() == TYPEID_PLAYER)
|
||||||
owner.GetMap()->GetHitPosition(curr_x, curr_y, curr_z, x, y, z, owner.GetPhaseMask(), -0.1f);
|
{
|
||||||
|
// check any collision
|
||||||
owner.UpdateAllowedPositionZ(x, y, z);
|
float testZ = z + 0.5f; // needed to avoid some false positive hit detection of terrain or passable little object
|
||||||
|
if (owner.GetMap()->GetHitPosition(curr_x, curr_y, curr_z + 0.5f, x, y, testZ, owner.GetPhaseMask(), -0.1f))
|
||||||
|
{
|
||||||
|
z = testZ;
|
||||||
|
if (!owner.GetMap()->GetHeightInRange(owner.GetPhaseMask(), x, y, z))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -509,6 +509,16 @@ void MotionMaster::MoveJump(float x, float y, float z, float horizontalSpeed, fl
|
||||||
Mutate(new EffectMovementGenerator(id));
|
Mutate(new EffectMovementGenerator(id));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MotionMaster::MoveDestination(float x, float y, float z, float o, float horizontalSpeed, float max_height, Unit* target)
|
||||||
|
{
|
||||||
|
Movement::MoveSplineInit init(*m_owner);
|
||||||
|
init.MoveTo(x, y, z);
|
||||||
|
init.SetParabolic(max_height, 0);
|
||||||
|
init.SetVelocity(horizontalSpeed);
|
||||||
|
target ? init.SetFacing(target) : init.SetFacing(o);
|
||||||
|
init.Launch();
|
||||||
|
}
|
||||||
|
|
||||||
void MotionMaster::MoveFall()
|
void MotionMaster::MoveFall()
|
||||||
{
|
{
|
||||||
// use larger distance for vmap height search than in most other cases
|
// use larger distance for vmap height search than in most other cases
|
||||||
|
|
|
||||||
|
|
@ -117,6 +117,7 @@ class MotionMaster : private std::stack<MovementGenerator*>
|
||||||
void MoveTaxiFlight(uint32 path, uint32 pathnode);
|
void MoveTaxiFlight(uint32 path, uint32 pathnode);
|
||||||
void MoveDistract(uint32 timeLimit);
|
void MoveDistract(uint32 timeLimit);
|
||||||
void MoveJump(float x, float y, float z, float horizontalSpeed, float max_height, uint32 id = 0);
|
void MoveJump(float x, float y, float z, float horizontalSpeed, float max_height, uint32 id = 0);
|
||||||
|
void MoveDestination(float x, float y, float z, float o, float horizontalSpeed, float max_height, Unit* target = nullptr);
|
||||||
void MoveFall();
|
void MoveFall();
|
||||||
void MoveFlyOrLand(uint32 id, float x, float y, float z, bool liftOff);
|
void MoveFlyOrLand(uint32 id, float x, float y, float z, bool liftOff);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -333,6 +333,7 @@ void FlightPathMovementGenerator::Finalize(Player& player)
|
||||||
|
|
||||||
player.Unmount();
|
player.Unmount();
|
||||||
player.RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE | UNIT_FLAG_TAXI_FLIGHT);
|
player.RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE | UNIT_FLAG_TAXI_FLIGHT);
|
||||||
|
player.SetClientControl(&player, 1);
|
||||||
|
|
||||||
if (player.m_taxi.empty())
|
if (player.m_taxi.empty())
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -55,7 +55,7 @@ AggressorAI::MoveInLineOfSight(Unit* u)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (m_creature->CanInitiateAttack() && u->IsTargetableForAttack() &&
|
if (m_creature->CanInitiateAttack() && u->IsTargetableForAttack() &&
|
||||||
m_creature->IsHostileTo(u) && u->isInAccessablePlaceFor(m_creature))
|
m_creature->IsHostileTo(u) && u->IsInAccessablePlaceFor(m_creature))
|
||||||
{
|
{
|
||||||
float attackRadius = m_creature->GetAttackDistance(u);
|
float attackRadius = m_creature->GetAttackDistance(u);
|
||||||
if (m_creature->IsWithinDistInMap(u, attackRadius) && m_creature->IsWithinLOSInMap(u))
|
if (m_creature->IsWithinDistInMap(u, attackRadius) && m_creature->IsWithinLOSInMap(u))
|
||||||
|
|
|
||||||
|
|
@ -208,6 +208,10 @@ void Creature::AddToWorld()
|
||||||
{ GetMap()->GetObjectsStore().insert<Creature>(GetObjectGuid(), (Creature*)this); }
|
{ GetMap()->GetObjectsStore().insert<Creature>(GetObjectGuid(), (Creature*)this); }
|
||||||
|
|
||||||
Unit::AddToWorld();
|
Unit::AddToWorld();
|
||||||
|
|
||||||
|
// Make active if required
|
||||||
|
if (sWorld.isForceLoadMap(GetMapId()) || (GetCreatureInfo()->ExtraFlags & CREATURE_EXTRA_FLAG_ACTIVE))
|
||||||
|
SetActiveObjectState(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Creature::RemoveFromWorld()
|
void Creature::RemoveFromWorld()
|
||||||
|
|
@ -384,7 +388,14 @@ bool Creature::InitEntry(uint32 Entry, CreatureData const* data /*=NULL*/, GameE
|
||||||
UpdateSpeed(MOVE_WALK, false);
|
UpdateSpeed(MOVE_WALK, false);
|
||||||
UpdateSpeed(MOVE_RUN, false);
|
UpdateSpeed(MOVE_RUN, false);
|
||||||
|
|
||||||
SetLevitate(cinfo->InhabitType & INHABIT_AIR);
|
SetLevitate((cinfo->InhabitType & INHABIT_AIR) != 0); // TODO: may not be correct to send opcode at this point (already handled by UPDATE_OBJECT createObject)
|
||||||
|
|
||||||
|
// check if we need to add swimming movement. TODO: i thing movement flags should be computed automatically at each movement of creature so we need a sort of UpdateMovementFlags() method
|
||||||
|
if (cinfo->InhabitType & INHABIT_WATER && // check inhabit type water
|
||||||
|
!(cinfo->ExtraFlags & CREATURE_EXTRA_FLAG_WALK_IN_WATER) && // check if creature is forced to walk (crabs, giant,...)
|
||||||
|
data && // check if there is data to get creature spawn pos
|
||||||
|
GetMap()->GetTerrain()->IsSwimmable(data->posX, data->posY, data->posZ, minfo->bounding_radius)) // check if creature is in water and have enough space to swim
|
||||||
|
m_movementInfo.AddMovementFlag(MOVEFLAG_SWIMMING); // add swimming movement
|
||||||
|
|
||||||
// checked at loading
|
// checked at loading
|
||||||
m_defaultMovementType = MovementGeneratorType(cinfo->MovementType);
|
m_defaultMovementType = MovementGeneratorType(cinfo->MovementType);
|
||||||
|
|
@ -485,8 +496,10 @@ uint32 Creature::ChooseDisplayId(const CreatureInfo* cinfo, const CreatureData*
|
||||||
// if mod2 use mod2 unless mod2 has modelid_alt_model (then both by 50%-chance)
|
// if mod2 use mod2 unless mod2 has modelid_alt_model (then both by 50%-chance)
|
||||||
// if mod1 use mod1
|
// if mod1 use mod1
|
||||||
|
|
||||||
// model selected here may be replaced with other_gender using own function
|
// The follow decision tree needs to be updated if MAX_CREATURE_MODEL is changed.
|
||||||
|
static_assert(MAX_CREATURE_MODEL == 4, "Need to update model selection code for new or removed model fields");
|
||||||
|
|
||||||
|
// model selected here may be replaced with other_gender using own function
|
||||||
if (cinfo->ModelId[3] && cinfo->ModelId[2] && cinfo->ModelId[1] && cinfo->ModelId[0])
|
if (cinfo->ModelId[3] && cinfo->ModelId[2] && cinfo->ModelId[1] && cinfo->ModelId[0])
|
||||||
{
|
{
|
||||||
display_id = cinfo->ModelId[urand(0, 3)];
|
display_id = cinfo->ModelId[urand(0, 3)];
|
||||||
|
|
@ -1159,6 +1172,9 @@ void Creature::SaveToDB(uint32 mapid, uint8 spawnMask, uint32 phaseMask)
|
||||||
CreatureInfo const* cinfo = GetCreatureInfo();
|
CreatureInfo const* cinfo = GetCreatureInfo();
|
||||||
if (cinfo)
|
if (cinfo)
|
||||||
{
|
{
|
||||||
|
// The following if-else assumes that there are 4 model fields and needs updating if this is changed.
|
||||||
|
static_assert(MAX_CREATURE_MODEL == 4, "Need to update custom model check for new/removed model fields.");
|
||||||
|
|
||||||
if (displayId != cinfo->ModelId[0] && displayId != cinfo->ModelId[1] &&
|
if (displayId != cinfo->ModelId[0] && displayId != cinfo->ModelId[1] &&
|
||||||
displayId != cinfo->ModelId[2] && displayId != cinfo->ModelId[3])
|
displayId != cinfo->ModelId[2] && displayId != cinfo->ModelId[3])
|
||||||
{
|
{
|
||||||
|
|
@ -1765,6 +1781,35 @@ bool Creature::IsImmuneToSpellEffect(SpellEntry const* spellInfo, SpellEffectInd
|
||||||
return Unit::IsImmuneToSpellEffect(spellInfo, index, castOnSelf);
|
return Unit::IsImmuneToSpellEffect(spellInfo, index, castOnSelf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Set loot status. Also handle remove corpse timer
|
||||||
|
void Creature::SetLootStatus(CreatureLootStatus status)
|
||||||
|
{
|
||||||
|
if (status <= m_lootStatus)
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_lootStatus = status;
|
||||||
|
switch (status)
|
||||||
|
{
|
||||||
|
case CREATURE_LOOT_STATUS_LOOTED:
|
||||||
|
if (m_creatureInfo->SkinningLootId)
|
||||||
|
SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_SKINNABLE);
|
||||||
|
else
|
||||||
|
RemoveFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE);
|
||||||
|
break;
|
||||||
|
case CREATURE_LOOT_STATUS_SKINNED:
|
||||||
|
m_corpseDecayTimer = 0; // remove corpse at next update
|
||||||
|
RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_SKINNABLE);
|
||||||
|
RemoveFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE);
|
||||||
|
break;
|
||||||
|
case CREATURE_LOOT_STATUS_SKIN_AVAILABLE:
|
||||||
|
SetFlag(UNIT_FIELD_FLAGS, UNIT_DYNFLAG_LOOTABLE);
|
||||||
|
RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_SKINNABLE);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// return true if this creature is tapped by the player or by a member of his group.
|
// return true if this creature is tapped by the player or by a member of his group.
|
||||||
bool Creature::IsTappedBy(Player const* player) const
|
bool Creature::IsTappedBy(Player const* player) const
|
||||||
{
|
{
|
||||||
|
|
@ -2038,7 +2083,7 @@ bool Creature::IsOutOfThreatArea(Unit* pVictim) const
|
||||||
if (!pVictim->IsTargetableForAttack())
|
if (!pVictim->IsTargetableForAttack())
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if (!pVictim->isInAccessablePlaceFor(this))
|
if (!pVictim->IsInAccessablePlaceFor(this))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if (!pVictim->IsVisibleForOrDetect(this, this, false))
|
if (!pVictim->IsVisibleForOrDetect(this, this, false))
|
||||||
|
|
@ -2771,6 +2816,54 @@ void Creature::SetLevitate(bool enable)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Creature::SetSwim(bool enable)
|
||||||
|
{
|
||||||
|
if (enable)
|
||||||
|
m_movementInfo.AddMovementFlag(MOVEFLAG_SWIMMING);
|
||||||
|
else
|
||||||
|
m_movementInfo.RemoveMovementFlag(MOVEFLAG_SWIMMING);
|
||||||
|
|
||||||
|
WorldPacket data(enable ? SMSG_SPLINE_MOVE_START_SWIM : SMSG_SPLINE_MOVE_STOP_SWIM);
|
||||||
|
data << GetPackGUID();
|
||||||
|
SendMessageToSet(&data, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Creature::SetCanFly(bool enable)
|
||||||
|
{
|
||||||
|
if (enable)
|
||||||
|
m_movementInfo.AddMovementFlag(MOVEFLAG_CAN_FLY);
|
||||||
|
else
|
||||||
|
m_movementInfo.RemoveMovementFlag(MOVEFLAG_CAN_FLY);
|
||||||
|
|
||||||
|
WorldPacket data(enable ? SMSG_SPLINE_MOVE_SET_FLYING : SMSG_SPLINE_MOVE_UNSET_FLYING, 9);
|
||||||
|
data << GetPackGUID();
|
||||||
|
SendMessageToSet(&data, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Creature::SetFeatherFall(bool enable)
|
||||||
|
{
|
||||||
|
if (enable)
|
||||||
|
m_movementInfo.AddMovementFlag(MOVEFLAG_SAFE_FALL);
|
||||||
|
else
|
||||||
|
m_movementInfo.RemoveMovementFlag(MOVEFLAG_SAFE_FALL);
|
||||||
|
|
||||||
|
WorldPacket data(enable ? SMSG_SPLINE_MOVE_FEATHER_FALL : SMSG_SPLINE_MOVE_NORMAL_FALL);
|
||||||
|
data << GetPackGUID();
|
||||||
|
SendMessageToSet(&data, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Creature::SetHover(bool enable)
|
||||||
|
{
|
||||||
|
if (enable)
|
||||||
|
m_movementInfo.AddMovementFlag(MOVEFLAG_HOVER);
|
||||||
|
else
|
||||||
|
m_movementInfo.RemoveMovementFlag(MOVEFLAG_HOVER);
|
||||||
|
|
||||||
|
WorldPacket data(enable ? SMSG_SPLINE_MOVE_SET_HOVER : SMSG_SPLINE_MOVE_UNSET_HOVER, 9);
|
||||||
|
data << GetPackGUID();
|
||||||
|
SendMessageToSet(&data, false);
|
||||||
|
}
|
||||||
|
|
||||||
void Creature::SetRoot(bool enable)
|
void Creature::SetRoot(bool enable)
|
||||||
{
|
{
|
||||||
if (enable)
|
if (enable)
|
||||||
|
|
|
||||||
|
|
@ -542,11 +542,11 @@ class Creature : public Unit
|
||||||
void SetCorpseDelay(uint32 delay) { m_corpseDelay = delay; }
|
void SetCorpseDelay(uint32 delay) { m_corpseDelay = delay; }
|
||||||
uint32 GetCorpseDelay() const { return m_corpseDelay; }
|
uint32 GetCorpseDelay() const { return m_corpseDelay; }
|
||||||
bool IsRacialLeader() const { return GetCreatureInfo()->RacialLeader; }
|
bool IsRacialLeader() const { return GetCreatureInfo()->RacialLeader; }
|
||||||
bool IsCivilian() const { return GetCreatureInfo()->ExtraFlags & CREATURE_EXTRA_FLAG_CIVILIAN; }
|
bool IsCivilian() const { return (GetCreatureInfo()->ExtraFlags & CREATURE_EXTRA_FLAG_CIVILIAN) != 0; }
|
||||||
bool IsGuard() const { return GetCreatureInfo()->ExtraFlags & CREATURE_EXTRA_FLAG_GUARD; }
|
bool IsGuard() const { return (GetCreatureInfo()->ExtraFlags & CREATURE_EXTRA_FLAG_GUARD) != 0; }
|
||||||
|
|
||||||
bool CanWalk() const { return GetCreatureInfo()->InhabitType & INHABIT_GROUND; }
|
bool CanWalk() const { return (GetCreatureInfo()->InhabitType & INHABIT_GROUND) != 0; }
|
||||||
bool CanSwim() const { return GetCreatureInfo()->InhabitType & INHABIT_WATER; }
|
bool CanSwim() const { return (GetCreatureInfo()->InhabitType & INHABIT_WATER) != 0; }
|
||||||
bool IsSwimming() const { return (m_movementInfo.HasMovementFlag((MovementFlags)(MOVEFLAG_SWIMMING))); }
|
bool IsSwimming() const { return (m_movementInfo.HasMovementFlag((MovementFlags)(MOVEFLAG_SWIMMING))); }
|
||||||
bool CanFly() const { return (GetCreatureInfo()->InhabitType & INHABIT_AIR) || (GetByteValue(UNIT_FIELD_BYTES_1, 3) & UNIT_BYTE1_FLAG_FLY_ANIM) || m_movementInfo.HasMovementFlag((MovementFlags)(MOVEFLAG_LEVITATING | MOVEFLAG_CAN_FLY)); }
|
bool CanFly() const { return (GetCreatureInfo()->InhabitType & INHABIT_AIR) || (GetByteValue(UNIT_FIELD_BYTES_1, 3) & UNIT_BYTE1_FLAG_FLY_ANIM) || m_movementInfo.HasMovementFlag((MovementFlags)(MOVEFLAG_LEVITATING | MOVEFLAG_CAN_FLY)); }
|
||||||
bool IsFlying() const { return (m_movementInfo.HasMovementFlag((MovementFlags)(MOVEFLAG_FLYING | MOVEFLAG_LEVITATING))); }
|
bool IsFlying() const { return (m_movementInfo.HasMovementFlag((MovementFlags)(MOVEFLAG_FLYING | MOVEFLAG_LEVITATING))); }
|
||||||
|
|
@ -560,6 +560,7 @@ class Creature : public Unit
|
||||||
|
|
||||||
bool IsImmuneToSpell(SpellEntry const* spellInfo, bool castOnSelf) override;
|
bool IsImmuneToSpell(SpellEntry const* spellInfo, bool castOnSelf) override;
|
||||||
bool IsImmuneToSpellEffect(SpellEntry const* spellInfo, SpellEffectIndex index, bool castOnSelf) const override;
|
bool IsImmuneToSpellEffect(SpellEntry const* spellInfo, SpellEffectIndex index, bool castOnSelf) const override;
|
||||||
|
void SetLootStatus(CreatureLootStatus status);
|
||||||
bool IsTappedBy(Player const* player) const;
|
bool IsTappedBy(Player const* player) const;
|
||||||
|
|
||||||
bool IsElite() const
|
bool IsElite() const
|
||||||
|
|
@ -591,6 +592,10 @@ class Creature : public Unit
|
||||||
|
|
||||||
void SetWalk(bool enable, bool asDefault = true);
|
void SetWalk(bool enable, bool asDefault = true);
|
||||||
void SetLevitate(bool enable);
|
void SetLevitate(bool enable);
|
||||||
|
void SetSwim(bool enable) override;
|
||||||
|
void SetCanFly(bool enable) override;
|
||||||
|
void SetFeatherFall(bool enable) override;
|
||||||
|
void SetHover(bool enable) override;
|
||||||
void SetRoot(bool enable) override;
|
void SetRoot(bool enable) override;
|
||||||
void SetWaterWalk(bool enable) override;
|
void SetWaterWalk(bool enable) override;
|
||||||
|
|
||||||
|
|
@ -818,6 +823,7 @@ class Creature : public Unit
|
||||||
uint32 m_lootMoney;
|
uint32 m_lootMoney;
|
||||||
ObjectGuid m_lootRecipientGuid; // player who will have rights for looting if m_lootGroupRecipient==0 or group disbanded
|
ObjectGuid m_lootRecipientGuid; // player who will have rights for looting if m_lootGroupRecipient==0 or group disbanded
|
||||||
uint32 m_lootGroupRecipientId; // group who will have rights for looting if set and exist
|
uint32 m_lootGroupRecipientId; // group who will have rights for looting if set and exist
|
||||||
|
CreatureLootStatus m_lootStatus; // loot status (used to know when we could loot, pickpocket or skin)
|
||||||
|
|
||||||
/// Timers
|
/// Timers
|
||||||
uint32 m_corpseDecayTimer; // (msecs)timer for death or corpse disappearance
|
uint32 m_corpseDecayTimer; // (msecs)timer for death or corpse disappearance
|
||||||
|
|
|
||||||
|
|
@ -182,6 +182,7 @@ inline bool IsTimerBasedEvent(EventAI_Type type)
|
||||||
case EVENT_T_MISSING_AURA:
|
case EVENT_T_MISSING_AURA:
|
||||||
case EVENT_T_TARGET_MISSING_AURA:
|
case EVENT_T_TARGET_MISSING_AURA:
|
||||||
case EVENT_T_RANGE:
|
case EVENT_T_RANGE:
|
||||||
|
case EVENT_T_ENERGY:
|
||||||
return true;
|
return true;
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -276,6 +277,13 @@ bool CreatureEventAI::ProcessEvent(CreatureEventAIHolder& pHolder, Unit* pAction
|
||||||
pHolder.UpdateRepeatTimer(m_creature, event.spell_hit.repeatMin, event.spell_hit.repeatMax);
|
pHolder.UpdateRepeatTimer(m_creature, event.spell_hit.repeatMin, event.spell_hit.repeatMax);
|
||||||
break;
|
break;
|
||||||
case EVENT_T_RANGE:
|
case EVENT_T_RANGE:
|
||||||
|
if (!m_creature->IsInCombat() || !m_creature->getVictim() || !m_creature->IsInMap(m_creature->getVictim()))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// DISCUSS TODO - Likely replace IsInRange check with CombatReach checks (as used rather for such checks)
|
||||||
|
if (!m_creature->IsInRange(m_creature->getVictim(), (float)event.range.minDist, (float)event.range.maxDist))
|
||||||
|
return false;
|
||||||
|
|
||||||
// Repeat Timers
|
// Repeat Timers
|
||||||
pHolder.UpdateRepeatTimer(m_creature, event.range.repeatMin, event.range.repeatMax);
|
pHolder.UpdateRepeatTimer(m_creature, event.range.repeatMin, event.range.repeatMax);
|
||||||
break;
|
break;
|
||||||
|
|
@ -394,6 +402,9 @@ bool CreatureEventAI::ProcessEvent(CreatureEventAIHolder& pHolder, Unit* pAction
|
||||||
break;
|
break;
|
||||||
case EVENT_T_AURA:
|
case EVENT_T_AURA:
|
||||||
{
|
{
|
||||||
|
if (!m_creature->IsInCombat())
|
||||||
|
return false;
|
||||||
|
|
||||||
SpellAuraHolder* holder = m_creature->GetSpellAuraHolder(event.buffed.spellId);
|
SpellAuraHolder* holder = m_creature->GetSpellAuraHolder(event.buffed.spellId);
|
||||||
if (!holder || holder->GetStackAmount() < event.buffed.amount)
|
if (!holder || holder->GetStackAmount() < event.buffed.amount)
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -419,6 +430,9 @@ bool CreatureEventAI::ProcessEvent(CreatureEventAIHolder& pHolder, Unit* pAction
|
||||||
}
|
}
|
||||||
case EVENT_T_MISSING_AURA:
|
case EVENT_T_MISSING_AURA:
|
||||||
{
|
{
|
||||||
|
if (!m_creature->IsInCombat())
|
||||||
|
return false;
|
||||||
|
|
||||||
SpellAuraHolder* holder = m_creature->GetSpellAuraHolder(event.buffed.spellId);
|
SpellAuraHolder* holder = m_creature->GetSpellAuraHolder(event.buffed.spellId);
|
||||||
if (holder && holder->GetStackAmount() >= event.buffed.amount)
|
if (holder && holder->GetStackAmount() >= event.buffed.amount)
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -444,6 +458,21 @@ bool CreatureEventAI::ProcessEvent(CreatureEventAIHolder& pHolder, Unit* pAction
|
||||||
}
|
}
|
||||||
case EVENT_T_RECEIVE_AI_EVENT:
|
case EVENT_T_RECEIVE_AI_EVENT:
|
||||||
break;
|
break;
|
||||||
|
case EVENT_T_ENERGY:
|
||||||
|
{
|
||||||
|
if (!m_creature->IsInCombat() || !m_creature->GetMaxPower(POWER_ENERGY))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
uint32 perc = (m_creature->GetPower(POWER_ENERGY) * 100) / m_creature->GetMaxPower(POWER_ENERGY);
|
||||||
|
|
||||||
|
if (perc > event.percent_range.percentMax || perc < event.percent_range.percentMin)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
LOG_PROCESS_EVENT;
|
||||||
|
// Repeat Timers
|
||||||
|
pHolder.UpdateRepeatTimer(m_creature, event.percent_range.repeatMin, event.percent_range.repeatMax);
|
||||||
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
sLog.outErrorEventAI("Creature %u using Event %u has invalid Event Type(%u), missing from ProcessEvent() Switch.", m_creature->GetEntry(), pHolder.Event.event_id, pHolder.Event.event_type);
|
sLog.outErrorEventAI("Creature %u using Event %u has invalid Event Type(%u), missing from ProcessEvent() Switch.", m_creature->GetEntry(), pHolder.Event.event_id, pHolder.Event.event_type);
|
||||||
break;
|
break;
|
||||||
|
|
@ -478,7 +507,7 @@ bool CreatureEventAI::ProcessEvent(CreatureEventAIHolder& pHolder, Unit* pAction
|
||||||
if (count)
|
if (count)
|
||||||
{
|
{
|
||||||
// select action number from found amount
|
// select action number from found amount
|
||||||
uint32 idx = urand(0, count - 1);
|
uint32 idx = rnd % count;
|
||||||
|
|
||||||
// find selected action, skipping not used
|
// find selected action, skipping not used
|
||||||
uint32 j = 0;
|
uint32 j = 0;
|
||||||
|
|
@ -520,17 +549,17 @@ void CreatureEventAI::ProcessAction(CreatureEventAI_Action const& action, uint32
|
||||||
if (action.type == ACTION_T_TEXT)
|
if (action.type == ACTION_T_TEXT)
|
||||||
{
|
{
|
||||||
if (action.text.TextId[1] && action.text.TextId[2])
|
if (action.text.TextId[1] && action.text.TextId[2])
|
||||||
textId = action.text.TextId[urand(0, 2)];
|
textId = action.text.TextId[rnd % 3];
|
||||||
else if (action.text.TextId[1] && urand(0, 1))
|
else if (action.text.TextId[1] && (rnd % 2))
|
||||||
textId = action.text.TextId[1];
|
textId = action.text.TextId[1];
|
||||||
else
|
else
|
||||||
textId = action.text.TextId[0];
|
textId = action.text.TextId[0];
|
||||||
}
|
}
|
||||||
// ACTION_T_CHANCED_TEXT, chance hits
|
// ACTION_T_CHANCED_TEXT, chance hits
|
||||||
else if (urand(0, 99) < action.chanced_text.chance)
|
else if ((rnd % 100) < action.chanced_text.chance)
|
||||||
{
|
{
|
||||||
if (action.chanced_text.TextId[0] && action.chanced_text.TextId[1])
|
if (action.chanced_text.TextId[0] && action.chanced_text.TextId[1])
|
||||||
textId = action.chanced_text.TextId[urand(0, 1)];
|
textId = action.chanced_text.TextId[rnd % 2];
|
||||||
else
|
else
|
||||||
textId = action.chanced_text.TextId[0];
|
textId = action.chanced_text.TextId[0];
|
||||||
}
|
}
|
||||||
|
|
@ -839,9 +868,9 @@ void CreatureEventAI::ProcessAction(CreatureEventAI_Action const& action, uint32
|
||||||
|
|
||||||
Creature* pCreature = NULL;
|
Creature* pCreature = NULL;
|
||||||
if ((*i).second.SpawnTimeSecs)
|
if ((*i).second.SpawnTimeSecs)
|
||||||
pCreature = m_creature->SummonCreature(action.summon_id.creatureId, (*i).second.position_x, (*i).second.position_y, (*i).second.position_z, (*i).second.orientation, TEMPSUMMON_TIMED_OOC_OR_DEAD_DESPAWN, (*i).second.SpawnTimeSecs);
|
pCreature = m_creature->SummonCreature(action.summon_id.creatureId, i->second.position_x, i->second.position_y, i->second.position_z, i->second.orientation, TEMPSUMMON_TIMED_OOC_OR_DEAD_DESPAWN, i->second.SpawnTimeSecs);
|
||||||
else
|
else
|
||||||
pCreature = m_creature->SummonCreature(action.summon_id.creatureId, (*i).second.position_x, (*i).second.position_y, (*i).second.position_z, (*i).second.orientation, TEMPSUMMON_TIMED_OOC_DESPAWN, 0);
|
pCreature = m_creature->SummonCreature(action.summon_id.creatureId, i->second.position_x, i->second.position_y, i->second.position_z, i->second.orientation, TEMPSUMMON_TIMED_OOC_DESPAWN, 0);
|
||||||
|
|
||||||
if (!pCreature)
|
if (!pCreature)
|
||||||
sLog.outErrorEventAI("failed to spawn creature %u. EventId %d.Creature %d", action.summon_id.creatureId, EventId, m_creature->GetEntry());
|
sLog.outErrorEventAI("failed to spawn creature %u. EventId %d.Creature %d", action.summon_id.creatureId, EventId, m_creature->GetEntry());
|
||||||
|
|
@ -1035,29 +1064,26 @@ void CreatureEventAI::Reset()
|
||||||
{
|
{
|
||||||
m_EventUpdateTime = EVENT_UPDATE_TIME;
|
m_EventUpdateTime = EVENT_UPDATE_TIME;
|
||||||
m_EventDiff = 0;
|
m_EventDiff = 0;
|
||||||
|
|
||||||
m_throwAIEventStep = 0;
|
m_throwAIEventStep = 0;
|
||||||
|
|
||||||
// Reset all events to enabled
|
// Reset all events to enabled
|
||||||
for (CreatureEventAIList::iterator i = m_CreatureEventAIList.begin(); i != m_CreatureEventAIList.end(); ++i)
|
for (CreatureEventAIList::iterator i = m_CreatureEventAIList.begin(); i != m_CreatureEventAIList.end(); ++i)
|
||||||
{
|
{
|
||||||
CreatureEventAI_Event const& event = (*i).Event;
|
CreatureEventAI_Event const& event = i->Event;
|
||||||
switch (event.event_type)
|
switch (event.event_type)
|
||||||
{
|
{
|
||||||
// Reset all out of combat timers
|
// Reset all out of combat timers
|
||||||
case EVENT_T_TIMER_OOC:
|
case EVENT_T_TIMER_OOC:
|
||||||
{
|
{
|
||||||
if ((*i).UpdateRepeatTimer(m_creature, event.timer.initialMin, event.timer.initialMax))
|
if (i->UpdateRepeatTimer(m_creature, event.timer.initialMin, event.timer.initialMax))
|
||||||
(*i).Enabled = true;
|
i->Enabled = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
|
// TODO: enable below code line / verify this is correct to enable events previously disabled (ex. aggro yell), instead of enable this in void Aggro()
|
||||||
|
//i->Enabled = true;
|
||||||
|
//i->Time = 0;
|
||||||
break;
|
break;
|
||||||
// default:
|
|
||||||
// TODO: enable below code line / verify this is correct to enable events previously disabled (ex. aggro yell), instead of enable this in void Aggro()
|
|
||||||
//(*i).Enabled = true;
|
|
||||||
//(*i).Time = 0;
|
|
||||||
// break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1066,7 +1092,7 @@ void CreatureEventAI::JustReachedHome()
|
||||||
{
|
{
|
||||||
for (CreatureEventAIList::iterator i = m_CreatureEventAIList.begin(); i != m_CreatureEventAIList.end(); ++i)
|
for (CreatureEventAIList::iterator i = m_CreatureEventAIList.begin(); i != m_CreatureEventAIList.end(); ++i)
|
||||||
{
|
{
|
||||||
if ((*i).Event.event_type == EVENT_T_REACHED_HOME)
|
if (i->Event.event_type == EVENT_T_REACHED_HOME)
|
||||||
ProcessEvent(*i);
|
ProcessEvent(*i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1079,18 +1105,16 @@ void CreatureEventAI::EnterEvadeMode()
|
||||||
m_creature->DeleteThreatList();
|
m_creature->DeleteThreatList();
|
||||||
m_creature->CombatStop(true);
|
m_creature->CombatStop(true);
|
||||||
|
|
||||||
if (m_creature->IsAlive())
|
// only alive creatures that are not on transport can return to home position
|
||||||
|
if (m_creature->IsAlive() && !m_creature->IsBoarded())
|
||||||
m_creature->GetMotionMaster()->MoveTargetedHome();
|
m_creature->GetMotionMaster()->MoveTargetedHome();
|
||||||
|
|
||||||
m_creature->SetLootRecipient(NULL);
|
m_creature->SetLootRecipient(nullptr);
|
||||||
|
|
||||||
if (m_bEmptyList)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// Handle Evade events
|
// Handle Evade events
|
||||||
for (CreatureEventAIList::iterator i = m_CreatureEventAIList.begin(); i != m_CreatureEventAIList.end(); ++i)
|
for (CreatureEventAIList::iterator i = m_CreatureEventAIList.begin(); i != m_CreatureEventAIList.end(); ++i)
|
||||||
{
|
{
|
||||||
if ((*i).Event.event_type == EVENT_T_EVADE)
|
if (i->Event.event_type == EVENT_T_EVADE)
|
||||||
ProcessEvent(*i);
|
ProcessEvent(*i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1112,7 +1136,7 @@ void CreatureEventAI::JustDied(Unit* killer)
|
||||||
// Handle On Death events
|
// Handle On Death events
|
||||||
for (CreatureEventAIList::iterator i = m_CreatureEventAIList.begin(); i != m_CreatureEventAIList.end(); ++i)
|
for (CreatureEventAIList::iterator i = m_CreatureEventAIList.begin(); i != m_CreatureEventAIList.end(); ++i)
|
||||||
{
|
{
|
||||||
if ((*i).Event.event_type == EVENT_T_DEATH)
|
if (i->Event.event_type == EVENT_T_DEATH)
|
||||||
ProcessEvent(*i, killer);
|
ProcessEvent(*i, killer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1127,7 +1151,7 @@ void CreatureEventAI::KilledUnit(Unit* victim)
|
||||||
|
|
||||||
for (CreatureEventAIList::iterator i = m_CreatureEventAIList.begin(); i != m_CreatureEventAIList.end(); ++i)
|
for (CreatureEventAIList::iterator i = m_CreatureEventAIList.begin(); i != m_CreatureEventAIList.end(); ++i)
|
||||||
{
|
{
|
||||||
if ((*i).Event.event_type == EVENT_T_KILL)
|
if (i->Event.event_type == EVENT_T_KILL)
|
||||||
ProcessEvent(*i, victim);
|
ProcessEvent(*i, victim);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1136,7 +1160,7 @@ void CreatureEventAI::JustSummoned(Creature* pUnit)
|
||||||
{
|
{
|
||||||
for (CreatureEventAIList::iterator i = m_CreatureEventAIList.begin(); i != m_CreatureEventAIList.end(); ++i)
|
for (CreatureEventAIList::iterator i = m_CreatureEventAIList.begin(); i != m_CreatureEventAIList.end(); ++i)
|
||||||
{
|
{
|
||||||
if ((*i).Event.event_type == EVENT_T_SUMMONED_UNIT)
|
if (i->Event.event_type == EVENT_T_SUMMONED_UNIT)
|
||||||
ProcessEvent(*i, pUnit);
|
ProcessEvent(*i, pUnit);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1145,7 +1169,7 @@ void CreatureEventAI::SummonedCreatureJustDied(Creature* pUnit)
|
||||||
{
|
{
|
||||||
for (CreatureEventAIList::iterator i = m_CreatureEventAIList.begin(); i != m_CreatureEventAIList.end(); ++i)
|
for (CreatureEventAIList::iterator i = m_CreatureEventAIList.begin(); i != m_CreatureEventAIList.end(); ++i)
|
||||||
{
|
{
|
||||||
if ((*i).Event.event_type == EVENT_T_SUMMONED_JUST_DIED)
|
if (i->Event.event_type == EVENT_T_SUMMONED_JUST_DIED)
|
||||||
ProcessEvent(*i, pUnit);
|
ProcessEvent(*i, pUnit);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1154,12 +1178,12 @@ void CreatureEventAI::SummonedCreatureDespawn(Creature* pUnit)
|
||||||
{
|
{
|
||||||
for (CreatureEventAIList::iterator i = m_CreatureEventAIList.begin(); i != m_CreatureEventAIList.end(); ++i)
|
for (CreatureEventAIList::iterator i = m_CreatureEventAIList.begin(); i != m_CreatureEventAIList.end(); ++i)
|
||||||
{
|
{
|
||||||
if ((*i).Event.event_type == EVENT_T_SUMMONED_JUST_DESPAWN)
|
if (i->Event.event_type == EVENT_T_SUMMONED_JUST_DESPAWN)
|
||||||
ProcessEvent(*i, pUnit);
|
ProcessEvent(*i, pUnit);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CreatureEventAI::ReceiveAIEvent(AIEventType eventType, Creature* pSender, Unit* pInvoker, uint32 miscValue)
|
void CreatureEventAI::ReceiveAIEvent(AIEventType eventType, Creature* pSender, Unit* pInvoker, uint32 /*miscValue*/)
|
||||||
{
|
{
|
||||||
MANGOS_ASSERT(pSender);
|
MANGOS_ASSERT(pSender);
|
||||||
|
|
||||||
|
|
@ -1169,29 +1193,29 @@ void CreatureEventAI::ReceiveAIEvent(AIEventType eventType, Creature* pSender, U
|
||||||
itr->Event.receiveAIEvent.eventType == eventType && (!itr->Event.receiveAIEvent.senderEntry || itr->Event.receiveAIEvent.senderEntry == pSender->GetEntry()))
|
itr->Event.receiveAIEvent.eventType == eventType && (!itr->Event.receiveAIEvent.senderEntry || itr->Event.receiveAIEvent.senderEntry == pSender->GetEntry()))
|
||||||
ProcessEvent(*itr, pInvoker, pSender);
|
ProcessEvent(*itr, pInvoker, pSender);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CreatureEventAI::EnterCombat(Unit* enemy)
|
void CreatureEventAI::EnterCombat(Unit* enemy)
|
||||||
{
|
{
|
||||||
// Check for on combat start events
|
// Check for on combat start events
|
||||||
for (CreatureEventAIList::iterator i = m_CreatureEventAIList.begin(); i != m_CreatureEventAIList.end(); ++i)
|
for (CreatureEventAIList::iterator i = m_CreatureEventAIList.begin(); i != m_CreatureEventAIList.end(); ++i)
|
||||||
{
|
{
|
||||||
CreatureEventAI_Event const& event = (*i).Event;
|
CreatureEventAI_Event const& event = i->Event;
|
||||||
switch (event.event_type)
|
switch (event.event_type)
|
||||||
{
|
{
|
||||||
case EVENT_T_AGGRO:
|
case EVENT_T_AGGRO:
|
||||||
(*i).Enabled = true;
|
i->Enabled = true;
|
||||||
ProcessEvent(*i, enemy);
|
ProcessEvent(*i, enemy);
|
||||||
break;
|
break;
|
||||||
// Reset all in combat timers
|
// Reset all in combat timers
|
||||||
case EVENT_T_TIMER_IN_COMBAT:
|
case EVENT_T_TIMER_IN_COMBAT:
|
||||||
if ((*i).UpdateRepeatTimer(m_creature, event.timer.initialMin, event.timer.initialMax))
|
if (i->UpdateRepeatTimer(m_creature, event.timer.initialMin, event.timer.initialMax))
|
||||||
(*i).Enabled = true;
|
i->Enabled = true;
|
||||||
break;
|
break;
|
||||||
// All normal events need to be re-enabled and their time set to 0
|
// All normal events need to be re-enabled and their time set to 0
|
||||||
default:
|
default:
|
||||||
(*i).Enabled = true;
|
i->Enabled = true;
|
||||||
(*i).Time = 0;
|
i->Time = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1221,21 +1245,21 @@ void CreatureEventAI::MoveInLineOfSight(Unit* who)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Check for OOC LOS Event
|
// Check for OOC LOS Event
|
||||||
if (!m_creature->getVictim())
|
if (m_HasOOCLoSEvent && !m_creature->getVictim())
|
||||||
{
|
{
|
||||||
for (CreatureEventAIList::iterator itr = m_CreatureEventAIList.begin(); itr != m_CreatureEventAIList.end(); ++itr)
|
for (CreatureEventAIList::iterator itr = m_CreatureEventAIList.begin(); itr != m_CreatureEventAIList.end(); ++itr)
|
||||||
{
|
{
|
||||||
if ((*itr).Event.event_type == EVENT_T_OOC_LOS)
|
if (itr->Event.event_type == EVENT_T_OOC_LOS)
|
||||||
{
|
{
|
||||||
// can trigger if closer than fMaxAllowedRange
|
// can trigger if closer than fMaxAllowedRange
|
||||||
float fMaxAllowedRange = (float)(*itr).Event.ooc_los.maxRange;
|
float fMaxAllowedRange = (float)itr->Event.ooc_los.maxRange;
|
||||||
|
|
||||||
// if range is ok and we are actually in LOS
|
// if friendly event && who is not hostile OR hostile event && who is hostile
|
||||||
if (m_creature->IsWithinDistInMap(who, fMaxAllowedRange) && m_creature->IsWithinLOSInMap(who))
|
if ((itr->Event.ooc_los.noHostile && !m_creature->IsHostileTo(who)) ||
|
||||||
|
((!itr->Event.ooc_los.noHostile) && m_creature->IsHostileTo(who)))
|
||||||
{
|
{
|
||||||
// if friendly event&&who is not hostile OR hostile event&&who is hostile
|
// if range is ok and we are actually in LOS
|
||||||
if (((*itr).Event.ooc_los.noHostile && !m_creature->IsHostileTo(who)) ||
|
if (m_creature->IsWithinDistInMap(who, fMaxAllowedRange) && m_creature->IsWithinLOSInMap(who))
|
||||||
((!(*itr).Event.ooc_los.noHostile) && m_creature->IsHostileTo(who)))
|
|
||||||
ProcessEvent(*itr, who);
|
ProcessEvent(*itr, who);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1246,7 +1270,7 @@ void CreatureEventAI::MoveInLineOfSight(Unit* who)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (m_creature->CanInitiateAttack() && who->IsTargetableForAttack() &&
|
if (m_creature->CanInitiateAttack() && who->IsTargetableForAttack() &&
|
||||||
m_creature->IsHostileTo(who) && who->isInAccessablePlaceFor(m_creature))
|
m_creature->IsHostileTo(who) && who->IsInAccessablePlaceFor(m_creature))
|
||||||
{
|
{
|
||||||
if (!m_creature->CanFly() && m_creature->GetDistanceZ(who) > CREATURE_Z_ATTACK_RANGE)
|
if (!m_creature->CanFly() && m_creature->GetDistanceZ(who) > CREATURE_Z_ATTACK_RANGE)
|
||||||
return;
|
return;
|
||||||
|
|
@ -1271,10 +1295,10 @@ void CreatureEventAI::MoveInLineOfSight(Unit* who)
|
||||||
void CreatureEventAI::SpellHit(Unit* pUnit, const SpellEntry* pSpell)
|
void CreatureEventAI::SpellHit(Unit* pUnit, const SpellEntry* pSpell)
|
||||||
{
|
{
|
||||||
for (CreatureEventAIList::iterator i = m_CreatureEventAIList.begin(); i != m_CreatureEventAIList.end(); ++i)
|
for (CreatureEventAIList::iterator i = m_CreatureEventAIList.begin(); i != m_CreatureEventAIList.end(); ++i)
|
||||||
if ((*i).Event.event_type == EVENT_T_SPELLHIT)
|
if (i->Event.event_type == EVENT_T_SPELLHIT)
|
||||||
// If spell id matches (or no spell id) & if spell school matches (or no spell school)
|
// If spell id matches (or no spell id) & if spell school matches (or no spell school)
|
||||||
if (!(*i).Event.spell_hit.spellId || pSpell->Id == (*i).Event.spell_hit.spellId)
|
if (!i->Event.spell_hit.spellId || pSpell->Id == i->Event.spell_hit.spellId)
|
||||||
if (pSpell->SchoolMask & (*i).Event.spell_hit.schoolMask)
|
if (pSpell->SchoolMask & i->Event.spell_hit.schoolMask)
|
||||||
ProcessEvent(*i, pUnit);
|
ProcessEvent(*i, pUnit);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1292,55 +1316,28 @@ void CreatureEventAI::UpdateAI(const uint32 diff)
|
||||||
for (CreatureEventAIList::iterator i = m_CreatureEventAIList.begin(); i != m_CreatureEventAIList.end(); ++i)
|
for (CreatureEventAIList::iterator i = m_CreatureEventAIList.begin(); i != m_CreatureEventAIList.end(); ++i)
|
||||||
{
|
{
|
||||||
// Decrement Timers
|
// Decrement Timers
|
||||||
if ((*i).Time)
|
if (i->Time)
|
||||||
{
|
{
|
||||||
if ((*i).Time > m_EventDiff)
|
if (i->Time > m_EventDiff)
|
||||||
{
|
{
|
||||||
// Do not decrement timers if event cannot trigger in this phase
|
// Do not decrement timers if event cannot trigger in this phase
|
||||||
if (!((*i).Event.event_inverse_phase_mask & (1 << m_Phase)))
|
if (!(i->Event.event_inverse_phase_mask & (1 << m_Phase)))
|
||||||
(*i).Time -= m_EventDiff;
|
i->Time -= m_EventDiff;
|
||||||
|
|
||||||
// Skip processing of events that have time remaining
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
else (*i).Time = 0;
|
else
|
||||||
|
i->Time = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Events that are updated every EVENT_UPDATE_TIME
|
// Skip processing of events that have time remaining or are disabled
|
||||||
switch ((*i).Event.event_type)
|
if (!(i->Enabled) || i->Time)
|
||||||
{
|
continue;
|
||||||
case EVENT_T_TIMER_OOC:
|
|
||||||
case EVENT_T_TIMER_GENERIC:
|
|
||||||
ProcessEvent(*i);
|
|
||||||
break;
|
|
||||||
case EVENT_T_TIMER_IN_COMBAT:
|
|
||||||
case EVENT_T_MANA:
|
|
||||||
case EVENT_T_HP:
|
|
||||||
case EVENT_T_TARGET_HP:
|
|
||||||
case EVENT_T_TARGET_CASTING:
|
|
||||||
case EVENT_T_FRIENDLY_HP:
|
|
||||||
case EVENT_T_AURA:
|
|
||||||
case EVENT_T_TARGET_AURA:
|
|
||||||
case EVENT_T_MISSING_AURA:
|
|
||||||
case EVENT_T_TARGET_MISSING_AURA:
|
|
||||||
if (Combat)
|
|
||||||
ProcessEvent(*i);
|
|
||||||
break;
|
|
||||||
case EVENT_T_RANGE:
|
|
||||||
if (Combat)
|
|
||||||
{
|
|
||||||
if (m_creature->getVictim() && m_creature->IsInMap(m_creature->getVictim()))
|
|
||||||
if (m_creature->IsInRange(m_creature->getVictim(), (float)(*i).Event.range.minDist, (float)(*i).Event.range.maxDist))
|
|
||||||
ProcessEvent(*i);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_EventDiff = 0;
|
if (IsTimerBasedEvent(i->Event.event_type))
|
||||||
m_EventUpdateTime = EVENT_UPDATE_TIME;
|
ProcessEvent(*i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_EventDiff = 0;
|
||||||
|
m_EventUpdateTime = EVENT_UPDATE_TIME;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -1348,9 +1345,23 @@ void CreatureEventAI::UpdateAI(const uint32 diff)
|
||||||
m_EventUpdateTime -= diff;
|
m_EventUpdateTime -= diff;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Melee Auto-Attack (recheck m_creature->getVictim in case of combat state was changed while processing events)
|
// Melee Auto-Attack (getVictim might be nullptr as result of timer based events and actions)
|
||||||
if (Combat && m_MeleeEnabled && m_creature->getVictim())
|
if (Combat && m_creature->getVictim())
|
||||||
DoMeleeAttackIfReady();
|
{
|
||||||
|
// Update creature dynamic movement position before doing anything else
|
||||||
|
if (m_DynamicMovement)
|
||||||
|
{
|
||||||
|
if (!m_creature->hasUnitState(UNIT_STAT_CAN_NOT_REACT) && !m_creature->IsNonMeleeSpellCasted(false))
|
||||||
|
{
|
||||||
|
if (m_LastSpellMaxRange && m_creature->IsInRange(m_creature->getVictim(), 0, (m_LastSpellMaxRange / 1.5f)))
|
||||||
|
SetCombatMovement(false, true);
|
||||||
|
else
|
||||||
|
SetCombatMovement(true, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (m_MeleeEnabled)
|
||||||
|
DoMeleeAttackIfReady();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CreatureEventAI::IsVisible(Unit* pl) const
|
bool CreatureEventAI::IsVisible(Unit* pl) const
|
||||||
|
|
@ -1478,12 +1489,12 @@ void CreatureEventAI::ReceiveEmote(Player* pPlayer, uint32 text_emote)
|
||||||
{
|
{
|
||||||
for (CreatureEventAIList::iterator itr = m_CreatureEventAIList.begin(); itr != m_CreatureEventAIList.end(); ++itr)
|
for (CreatureEventAIList::iterator itr = m_CreatureEventAIList.begin(); itr != m_CreatureEventAIList.end(); ++itr)
|
||||||
{
|
{
|
||||||
if ((*itr).Event.event_type == EVENT_T_RECEIVE_EMOTE)
|
if (itr->Event.event_type == EVENT_T_RECEIVE_EMOTE)
|
||||||
{
|
{
|
||||||
if ((*itr).Event.receive_emote.emoteId != text_emote)
|
if (itr->Event.receive_emote.emoteId != text_emote)
|
||||||
return;
|
continue;
|
||||||
|
|
||||||
PlayerCondition pcon(0, (*itr).Event.receive_emote.condition, (*itr).Event.receive_emote.conditionValue1, (*itr).Event.receive_emote.conditionValue2);
|
PlayerCondition pcon(0, itr->Event.receive_emote.condition, itr->Event.receive_emote.conditionValue1, itr->Event.receive_emote.conditionValue2);
|
||||||
if (pcon.Meets(pPlayer, m_creature->GetMap(), m_creature, CONDITION_FROM_EVENTAI))
|
if (pcon.Meets(pPlayer, m_creature->GetMap(), m_creature, CONDITION_FROM_EVENTAI))
|
||||||
{
|
{
|
||||||
DEBUG_FILTER_LOG(LOG_FILTER_AI_AND_MOVEGENSS, "CreatureEventAI: ReceiveEmote CreatureEventAI: Condition ok, processing");
|
DEBUG_FILTER_LOG(LOG_FILTER_AI_AND_MOVEGENSS, "CreatureEventAI: ReceiveEmote CreatureEventAI: Condition ok, processing");
|
||||||
|
|
|
||||||
|
|
@ -70,6 +70,7 @@ enum EventAI_Type
|
||||||
EVENT_T_TARGET_MISSING_AURA = 28, // Param1 = SpellID, Param2 = Number of time stacked expected, Param3/4 Repeat Min/Max
|
EVENT_T_TARGET_MISSING_AURA = 28, // Param1 = SpellID, Param2 = Number of time stacked expected, Param3/4 Repeat Min/Max
|
||||||
EVENT_T_TIMER_GENERIC = 29, // InitialMin, InitialMax, RepeatMin, RepeatMax
|
EVENT_T_TIMER_GENERIC = 29, // InitialMin, InitialMax, RepeatMin, RepeatMax
|
||||||
EVENT_T_RECEIVE_AI_EVENT = 30, // AIEventType, Sender-Entry, unused, unused
|
EVENT_T_RECEIVE_AI_EVENT = 30, // AIEventType, Sender-Entry, unused, unused
|
||||||
|
EVENT_T_ENERGY = 31, // EnergyMax%, EnergyMin%, RepeatMin, RepeatMax
|
||||||
|
|
||||||
EVENT_T_END,
|
EVENT_T_END,
|
||||||
};
|
};
|
||||||
|
|
@ -467,6 +468,7 @@ struct CreatureEventAI_Event
|
||||||
// EVENT_T_MANA = 3
|
// EVENT_T_MANA = 3
|
||||||
// EVENT_T_TARGET_HP = 12
|
// EVENT_T_TARGET_HP = 12
|
||||||
// EVENT_T_TARGET_MANA = 18
|
// EVENT_T_TARGET_MANA = 18
|
||||||
|
// EVENT_T_ENERGY = 31
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
uint32 percentMax;
|
uint32 percentMax;
|
||||||
|
|
|
||||||
|
|
@ -90,7 +90,7 @@ void CreatureEventAIMgr::CheckUnusedAITexts()
|
||||||
sLog.outErrorEventAI("Entry %i in table `creature_ai_texts` but not used in EventAI scripts.", *itr);
|
sLog.outErrorEventAI("Entry %i in table `creature_ai_texts` but not used in EventAI scripts.", *itr);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Helper function to check if a target-suite is suitable for the event-type
|
/// Helper function to check if a target-type is suitable for the event-type
|
||||||
bool IsValidTargetType(EventAI_Type eventType, EventAI_ActionType actionType, uint32 targetType, uint32 eventId, uint8 action)
|
bool IsValidTargetType(EventAI_Type eventType, EventAI_ActionType actionType, uint32 targetType, uint32 eventId, uint8 action)
|
||||||
{
|
{
|
||||||
switch (targetType)
|
switch (targetType)
|
||||||
|
|
@ -327,6 +327,7 @@ void CreatureEventAIMgr::LoadCreatureEventAI_Scripts()
|
||||||
case EVENT_T_MANA:
|
case EVENT_T_MANA:
|
||||||
case EVENT_T_TARGET_HP:
|
case EVENT_T_TARGET_HP:
|
||||||
case EVENT_T_TARGET_MANA:
|
case EVENT_T_TARGET_MANA:
|
||||||
|
case EVENT_T_ENERGY:
|
||||||
if (temp.percent_range.percentMax > 100)
|
if (temp.percent_range.percentMax > 100)
|
||||||
sLog.outErrorEventAI("Creature %u are using percentage event(%u) with param2 (MinPercent) > 100. Event will never trigger! ", temp.creature_id, i);
|
sLog.outErrorEventAI("Creature %u are using percentage event(%u) with param2 (MinPercent) > 100. Event will never trigger! ", temp.creature_id, i);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1269,8 +1269,11 @@ void GameObject::Use(Unit* user)
|
||||||
player->RewardPlayerAndGroupAtCast(this);
|
player->RewardPlayerAndGroupAtCast(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (scriptReturnValue)
|
// activate script
|
||||||
{ return; }
|
if (!scriptReturnValue)
|
||||||
|
GetMap()->ScriptsStart(sGameObjectScripts, GetGUIDLow(), spellCaster, this);
|
||||||
|
else
|
||||||
|
return;
|
||||||
|
|
||||||
// cast this spell later if provided
|
// cast this spell later if provided
|
||||||
spellId = info->goober.spellId;
|
spellId = info->goober.spellId;
|
||||||
|
|
@ -2382,6 +2385,23 @@ void GameObject::ForceGameObjectHealth(int32 diff, Unit* caster)
|
||||||
SetGoAnimProgress(GetMaxHealth() ? m_useTimes * 255 / GetMaxHealth() : 255);
|
SetGoAnimProgress(GetMaxHealth() ? m_useTimes * 255 / GetMaxHealth() : 255);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float GameObject::GetInteractionDistance()
|
||||||
|
{
|
||||||
|
switch (GetGoType())
|
||||||
|
{
|
||||||
|
// TODO: find out how the client calculates the maximal usage distance to spellless working
|
||||||
|
// gameobjects like guildbanks and mailboxes - 10.0 is a just an abitrary chosen number
|
||||||
|
case GAMEOBJECT_TYPE_GUILD_BANK:
|
||||||
|
case GAMEOBJECT_TYPE_MAILBOX:
|
||||||
|
return 10.0f;
|
||||||
|
case GAMEOBJECT_TYPE_FISHINGHOLE:
|
||||||
|
case GAMEOBJECT_TYPE_FISHINGNODE:
|
||||||
|
return 20.0f + CONTACT_DISTANCE; // max spell range
|
||||||
|
default:
|
||||||
|
return INTERACTION_DISTANCE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
uint32 GameObject::GetScriptId()
|
uint32 GameObject::GetScriptId()
|
||||||
{
|
{
|
||||||
return sScriptMgr.GetBoundScriptId(SCRIPTED_GAMEOBJECT, -int32(GetGUIDLow())) ? sScriptMgr.GetBoundScriptId(SCRIPTED_GAMEOBJECT, -int32(GetGUIDLow())) : sScriptMgr.GetBoundScriptId(SCRIPTED_GAMEOBJECT, GetEntry());
|
return sScriptMgr.GetBoundScriptId(SCRIPTED_GAMEOBJECT, -int32(GetGUIDLow())) ? sScriptMgr.GetBoundScriptId(SCRIPTED_GAMEOBJECT, -int32(GetGUIDLow())) : sScriptMgr.GetBoundScriptId(SCRIPTED_GAMEOBJECT, GetEntry());
|
||||||
|
|
|
||||||
|
|
@ -842,6 +842,11 @@ class GameObject : public WorldObject
|
||||||
ObjectGuid m_lootRecipientGuid; // player who will have rights for looting if m_lootGroupRecipient==0 or group disbanded
|
ObjectGuid m_lootRecipientGuid; // player who will have rights for looting if m_lootGroupRecipient==0 or group disbanded
|
||||||
uint32 m_lootGroupRecipientId; // group who will have rights for looting if set and exist
|
uint32 m_lootGroupRecipientId; // group who will have rights for looting if set and exist
|
||||||
|
|
||||||
|
// Used for chest type
|
||||||
|
bool m_isInUse; // only one player at time are allowed to open chest
|
||||||
|
time_t m_reStockTimer; // timer to refill the chest
|
||||||
|
time_t m_despawnTimer; // timer to despawn the chest if something changed in it
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void SwitchDoorOrButton(bool activate, bool alternative = false);
|
void SwitchDoorOrButton(bool activate, bool alternative = false);
|
||||||
void TickCapturePoint();
|
void TickCapturePoint();
|
||||||
|
|
|
||||||
|
|
@ -48,7 +48,7 @@ void GuardAI::MoveInLineOfSight(Unit* u)
|
||||||
|
|
||||||
if (!m_creature->getVictim() && u->IsTargetableForAttack() &&
|
if (!m_creature->getVictim() && u->IsTargetableForAttack() &&
|
||||||
(u->IsHostileToPlayers() || m_creature->IsHostileTo(u) /*|| u->getVictim() && m_creature->IsFriendlyTo(u->getVictim())*/) &&
|
(u->IsHostileToPlayers() || m_creature->IsHostileTo(u) /*|| u->getVictim() && m_creature->IsFriendlyTo(u->getVictim())*/) &&
|
||||||
u->isInAccessablePlaceFor(m_creature))
|
u->IsInAccessablePlaceFor(m_creature))
|
||||||
{
|
{
|
||||||
float attackRadius = m_creature->GetAttackDistance(u);
|
float attackRadius = m_creature->GetAttackDistance(u);
|
||||||
if (m_creature->IsWithinDistInMap(u, attackRadius))
|
if (m_creature->IsWithinDistInMap(u, attackRadius))
|
||||||
|
|
|
||||||
|
|
@ -332,7 +332,7 @@ bool LootStoreItem::IsValid(LootStore const& store, uint32 entry) const
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (maxcount < mincountOrRef) // wrong max count
|
if (maxcount < (uint32)mincountOrRef) // wrong max count
|
||||||
{
|
{
|
||||||
sLog.outErrorDb("Table '%s' entry %d item %d: max count (%u) less that min count (%i) - skipped", store.GetName(), entry, itemid, uint32(maxcount), mincountOrRef);
|
sLog.outErrorDb("Table '%s' entry %d item %d: max count (%u) less that min count (%i) - skipped", store.GetName(), entry, itemid, uint32(maxcount), mincountOrRef);
|
||||||
return false;
|
return false;
|
||||||
|
|
|
||||||
|
|
@ -70,7 +70,9 @@ enum LootType
|
||||||
|
|
||||||
LOOT_FISHINGHOLE = 20, // unsupported by client, sending LOOT_FISHING instead
|
LOOT_FISHINGHOLE = 20, // unsupported by client, sending LOOT_FISHING instead
|
||||||
LOOT_FISHING_FAIL = 21, // unsupported by client, sending LOOT_FISHING instead
|
LOOT_FISHING_FAIL = 21, // unsupported by client, sending LOOT_FISHING instead
|
||||||
LOOT_INSIGNIA = 22 // unsupported by client, sending LOOT_CORPSE instead
|
LOOT_INSIGNIA = 22, // unsupported by client, sending LOOT_CORPSE instead
|
||||||
|
LOOT_MAIL = 23,
|
||||||
|
LOOT_SPELL = 24,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum LootSlotType
|
enum LootSlotType
|
||||||
|
|
|
||||||
|
|
@ -664,19 +664,37 @@ void Object::BuildValuesUpdate(uint8 updatetype, ByteBuffer* data, UpdateMask* u
|
||||||
{
|
{
|
||||||
*data << (m_uint32Values[index] & ~UNIT_FLAG_NOT_SELECTABLE);
|
*data << (m_uint32Values[index] & ~UNIT_FLAG_NOT_SELECTABLE);
|
||||||
}
|
}
|
||||||
// hide lootable animation for unallowed players
|
/* Hide loot animation for players that aren't permitted to loot the corpse */
|
||||||
else if (index == UNIT_DYNAMIC_FLAGS && GetTypeId() == TYPEID_UNIT)
|
else if (index == UNIT_DYNAMIC_FLAGS && GetTypeId() == TYPEID_UNIT)
|
||||||
{
|
{
|
||||||
|
uint32 send_value = m_uint32Values[index];
|
||||||
|
|
||||||
|
/* Initiate pointer to creature so we can check loot */
|
||||||
|
if (Creature* my_creature = (Creature*)this)
|
||||||
|
/* If the creature is NOT fully looted */
|
||||||
|
if (!my_creature->loot.isLooted())
|
||||||
|
/* If the lootable flag is NOT set */
|
||||||
|
if (!(send_value & UNIT_DYNFLAG_LOOTABLE))
|
||||||
|
{
|
||||||
|
/* Update it on the creature */
|
||||||
|
my_creature->SetFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE);
|
||||||
|
/* Update it in the packet */
|
||||||
|
send_value = send_value | UNIT_DYNFLAG_LOOTABLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If we're not allowed to loot the target, destroy the lootable flag */
|
||||||
if (!target->isAllowedToLoot((Creature*)this))
|
if (!target->isAllowedToLoot((Creature*)this))
|
||||||
*data << (m_uint32Values[index] & ~(UNIT_DYNFLAG_LOOTABLE | UNIT_DYNFLAG_TAPPED_BY_PLAYER));
|
if (send_value & UNIT_DYNFLAG_LOOTABLE)
|
||||||
else
|
{ send_value = send_value & ~UNIT_DYNFLAG_LOOTABLE; }
|
||||||
{
|
|
||||||
// flag only for original loot recipent
|
/* If we are allowed to loot it and mob is tapped by us, destroy the tapped flag */
|
||||||
if (target->GetObjectGuid() == ((Creature*)this)->GetLootRecipientGuid())
|
bool is_tapped = target->IsTappedByMeOrMyGroup((Creature*)this);
|
||||||
*data << m_uint32Values[index];
|
|
||||||
else
|
/* If the creature has tapped flag but is tapped by us, remove the flag */
|
||||||
*data << (m_uint32Values[index] & ~(UNIT_DYNFLAG_TAPPED | UNIT_DYNFLAG_TAPPED_BY_PLAYER));
|
if (send_value & UNIT_DYNFLAG_TAPPED && is_tapped)
|
||||||
}
|
{ send_value = send_value & ~UNIT_DYNFLAG_TAPPED; }
|
||||||
|
|
||||||
|
*data << send_value;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -1479,8 +1497,11 @@ void WorldObject::UpdateGroundPositionZ(float x, float y, float& z) const
|
||||||
{ z = new_z + 0.05f; } // just to be sure that we are not a few pixel under the surface
|
{ z = new_z + 0.05f; } // just to be sure that we are not a few pixel under the surface
|
||||||
}
|
}
|
||||||
|
|
||||||
void WorldObject::UpdateAllowedPositionZ(float x, float y, float& z) const
|
void WorldObject::UpdateAllowedPositionZ(float x, float y, float& z, Map* atMap /*=nullptr*/) const
|
||||||
{
|
{
|
||||||
|
if (!atMap)
|
||||||
|
atMap = GetMap();
|
||||||
|
|
||||||
switch (GetTypeId())
|
switch (GetTypeId())
|
||||||
{
|
{
|
||||||
case TYPEID_UNIT:
|
case TYPEID_UNIT:
|
||||||
|
|
@ -1492,21 +1513,21 @@ void WorldObject::UpdateAllowedPositionZ(float x, float y, float& z) const
|
||||||
bool canSwim = ((Creature const*)this)->CanSwim();
|
bool canSwim = ((Creature const*)this)->CanSwim();
|
||||||
float ground_z = z;
|
float ground_z = z;
|
||||||
float max_z = canSwim
|
float max_z = canSwim
|
||||||
? GetTerrain()->GetWaterOrGroundLevel(x, y, z, &ground_z, !((Unit const*)this)->HasAuraType(SPELL_AURA_WATER_WALK))
|
? atMap->GetTerrain()->GetWaterOrGroundLevel(x, y, z, &ground_z, !((Unit const*)this)->HasAuraType(SPELL_AURA_WATER_WALK))
|
||||||
: ((ground_z = GetMap()->GetHeight(GetPhaseMask(), x, y, z)));
|
: ((ground_z = atMap->GetHeight(GetPhaseMask(), x, y, z)));
|
||||||
if (max_z > INVALID_HEIGHT)
|
if (max_z > INVALID_HEIGHT)
|
||||||
{
|
{
|
||||||
if (z > max_z)
|
if (z > max_z)
|
||||||
{ z = max_z; }
|
z = max_z;
|
||||||
else if (z < ground_z)
|
else if (z < ground_z)
|
||||||
{ z = ground_z; }
|
z = ground_z;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
float ground_z = GetMap()->GetHeight(GetPhaseMask(), x, y, z);
|
float ground_z = atMap->GetHeight(GetPhaseMask(), x, y, z);
|
||||||
if (z < ground_z)
|
if (z < ground_z)
|
||||||
{ z = ground_z; }
|
z = ground_z;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -1516,18 +1537,18 @@ void WorldObject::UpdateAllowedPositionZ(float x, float y, float& z) const
|
||||||
if (!((Player const*)this)->CanFly())
|
if (!((Player const*)this)->CanFly())
|
||||||
{
|
{
|
||||||
float ground_z = z;
|
float ground_z = z;
|
||||||
float max_z = GetTerrain()->GetWaterOrGroundLevel(x, y, z, &ground_z, !((Unit const*)this)->HasAuraType(SPELL_AURA_WATER_WALK));
|
float max_z = atMap->GetTerrain()->GetWaterOrGroundLevel(x, y, z, &ground_z, !((Unit const*)this)->HasAuraType(SPELL_AURA_WATER_WALK));
|
||||||
if (max_z > INVALID_HEIGHT)
|
if (max_z > INVALID_HEIGHT)
|
||||||
{
|
{
|
||||||
if (z > max_z)
|
if (z > max_z)
|
||||||
{ z = max_z; }
|
z = max_z;
|
||||||
else if (z < ground_z)
|
else if (z < ground_z)
|
||||||
{ z = ground_z; }
|
z = ground_z;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
float ground_z = GetMap()->GetHeight(GetPhaseMask(), x, y, z);
|
float ground_z = atMap->GetHeight(GetPhaseMask(), x, y, z);
|
||||||
if (z < ground_z)
|
if (z < ground_z)
|
||||||
z = ground_z;
|
z = ground_z;
|
||||||
}
|
}
|
||||||
|
|
@ -1535,9 +1556,9 @@ void WorldObject::UpdateAllowedPositionZ(float x, float y, float& z) const
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
float ground_z = GetMap()->GetHeight(GetPhaseMask(), x, y, z);
|
float ground_z = atMap->GetHeight(GetPhaseMask(), x, y, z);
|
||||||
if (ground_z > INVALID_HEIGHT)
|
if (ground_z > INVALID_HEIGHT)
|
||||||
{ z = ground_z; }
|
z = ground_z;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1914,9 +1935,9 @@ void WorldObject::GetNearPoint(WorldObject const* searcher, float& x, float& y,
|
||||||
if (!sWorld.getConfig(CONFIG_BOOL_DETECT_POS_COLLISION))
|
if (!sWorld.getConfig(CONFIG_BOOL_DETECT_POS_COLLISION))
|
||||||
{
|
{
|
||||||
if (searcher)
|
if (searcher)
|
||||||
searcher->UpdateAllowedPositionZ(x, y, z); // update to LOS height if available
|
searcher->UpdateAllowedPositionZ(x, y, z, GetMap()); // update to LOS height if available
|
||||||
else
|
else
|
||||||
{ UpdateGroundPositionZ(x, y, z); }
|
UpdateGroundPositionZ(x, y, z);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1942,12 +1963,12 @@ void WorldObject::GetNearPoint(WorldObject const* searcher, float& x, float& y,
|
||||||
if (selector.CheckOriginalAngle())
|
if (selector.CheckOriginalAngle())
|
||||||
{
|
{
|
||||||
if (searcher)
|
if (searcher)
|
||||||
searcher->UpdateAllowedPositionZ(x, y, z); // update to LOS height if available
|
searcher->UpdateAllowedPositionZ(x, y, z, GetMap()); // update to LOS height if available
|
||||||
else
|
else
|
||||||
{ UpdateGroundPositionZ(x, y, z); }
|
UpdateGroundPositionZ(x, y, z);
|
||||||
|
|
||||||
if (fabs(init_z - z) < dist && IsWithinLOS(x, y, z))
|
if (fabs(init_z - z) < dist && IsWithinLOS(x, y, z))
|
||||||
{ return; }
|
return;
|
||||||
|
|
||||||
first_los_conflict = true; // first point have LOS problems
|
first_los_conflict = true; // first point have LOS problems
|
||||||
}
|
}
|
||||||
|
|
@ -1964,12 +1985,12 @@ void WorldObject::GetNearPoint(WorldObject const* searcher, float& x, float& y,
|
||||||
z = GetPositionZ();
|
z = GetPositionZ();
|
||||||
|
|
||||||
if (searcher)
|
if (searcher)
|
||||||
searcher->UpdateAllowedPositionZ(x, y, z); // update to LOS height if available
|
searcher->UpdateAllowedPositionZ(x, y, z, GetMap()); // update to LOS height if available
|
||||||
else
|
else
|
||||||
{ UpdateGroundPositionZ(x, y, z); }
|
UpdateGroundPositionZ(x, y, z);
|
||||||
|
|
||||||
if (fabs(init_z - z) < dist && IsWithinLOS(x, y, z))
|
if (fabs(init_z - z) < dist && IsWithinLOS(x, y, z))
|
||||||
{ return; }
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// BAD NEWS: not free pos (or used or have LOS problems)
|
// BAD NEWS: not free pos (or used or have LOS problems)
|
||||||
|
|
@ -1980,9 +2001,9 @@ void WorldObject::GetNearPoint(WorldObject const* searcher, float& x, float& y,
|
||||||
y = first_y;
|
y = first_y;
|
||||||
|
|
||||||
if (searcher)
|
if (searcher)
|
||||||
searcher->UpdateAllowedPositionZ(x, y, z); // update to LOS height if available
|
searcher->UpdateAllowedPositionZ(x, y, z, GetMap()); // update to LOS height if available
|
||||||
else
|
else
|
||||||
{ UpdateGroundPositionZ(x, y, z); }
|
UpdateGroundPositionZ(x, y, z);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1996,12 +2017,12 @@ void WorldObject::GetNearPoint(WorldObject const* searcher, float& x, float& y,
|
||||||
z = GetPositionZ();
|
z = GetPositionZ();
|
||||||
|
|
||||||
if (searcher)
|
if (searcher)
|
||||||
searcher->UpdateAllowedPositionZ(x, y, z); // update to LOS height if available
|
searcher->UpdateAllowedPositionZ(x, y, z, GetMap()); // update to LOS height if available
|
||||||
else
|
else
|
||||||
{ UpdateGroundPositionZ(x, y, z); }
|
UpdateGroundPositionZ(x, y, z);
|
||||||
|
|
||||||
if (fabs(init_z - z) < dist && IsWithinLOS(x, y, z))
|
if (fabs(init_z - z) < dist && IsWithinLOS(x, y, z))
|
||||||
{ return; }
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// BAD BAD NEWS: all found pos (free and used) have LOS problem :(
|
// BAD BAD NEWS: all found pos (free and used) have LOS problem :(
|
||||||
|
|
@ -2009,9 +2030,9 @@ void WorldObject::GetNearPoint(WorldObject const* searcher, float& x, float& y,
|
||||||
y = first_y;
|
y = first_y;
|
||||||
|
|
||||||
if (searcher)
|
if (searcher)
|
||||||
searcher->UpdateAllowedPositionZ(x, y, z); // update to LOS height if available
|
searcher->UpdateAllowedPositionZ(x, y, z, GetMap());// update to LOS height if available
|
||||||
else
|
else
|
||||||
{ UpdateGroundPositionZ(x, y, z); }
|
UpdateGroundPositionZ(x, y, z);
|
||||||
}
|
}
|
||||||
|
|
||||||
void WorldObject::SetPhaseMask(uint32 newPhaseMask, bool update)
|
void WorldObject::SetPhaseMask(uint32 newPhaseMask, bool update)
|
||||||
|
|
|
||||||
|
|
@ -536,7 +536,7 @@ class WorldObject : public Object
|
||||||
|
|
||||||
bool IsPositionValid() const;
|
bool IsPositionValid() const;
|
||||||
void UpdateGroundPositionZ(float x, float y, float& z) const;
|
void UpdateGroundPositionZ(float x, float y, float& z) const;
|
||||||
void UpdateAllowedPositionZ(float x, float y, float& z) const;
|
void UpdateAllowedPositionZ(float x, float y, float& z, Map* atMap = nullptr) const;
|
||||||
|
|
||||||
void GetRandomPoint(float x, float y, float z, float distance, float& rand_x, float& rand_y, float& rand_z) const;
|
void GetRandomPoint(float x, float y, float z, float distance, float& rand_x, float& rand_y, float& rand_z) const;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1438,7 +1438,7 @@ void ObjectMgr::LoadCreatures()
|
||||||
|
|
||||||
if (cInfo->RegenerateStats & REGEN_FLAG_HEALTH && data.curhealth < cInfo->MinLevelHealth)
|
if (cInfo->RegenerateStats & REGEN_FLAG_HEALTH && data.curhealth < cInfo->MinLevelHealth)
|
||||||
{
|
{
|
||||||
sLog.outErrorDb("Table `creature` have creature (GUID: %u Entry: %u) with `creature_template`.`RegenHealth`=1 and low current health (%u), `creature_template`.`MinLevelHealth`=%u.", guid, data.id, data.curhealth, cInfo->MinLevelHealth);
|
sLog.outErrorDb("Table `creature` have creature (GUID: %u Entry: %u) with `creature_template`.`RegenerateStats` & REGEN_FLAG_HEALTH and low current health (%u), `creature_template`.`MinLevelHealth`=%u.", guid, data.id, data.curhealth, cInfo->MinLevelHealth);
|
||||||
data.curhealth = cInfo->MinLevelHealth;
|
data.curhealth = cInfo->MinLevelHealth;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1491,8 +1491,13 @@ void ObjectMgr::LoadCreatures()
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gameEvent == 0 && GuidPoolId == 0 && EntryPoolId == 0) // if not this is to be managed by GameEvent System or Pool system
|
if (gameEvent == 0 && GuidPoolId == 0 && EntryPoolId == 0) // if not this is to be managed by GameEvent System or Pool system
|
||||||
|
{
|
||||||
AddCreatureToGrid(guid, &data);
|
AddCreatureToGrid(guid, &data);
|
||||||
|
|
||||||
|
if (cInfo->ExtraFlags & CREATURE_EXTRA_FLAG_ACTIVE)
|
||||||
|
m_activeCreatures.insert(ActiveCreatureGuidsOnMap::value_type(data.mapid, guid));
|
||||||
|
}
|
||||||
|
|
||||||
++count;
|
++count;
|
||||||
}
|
}
|
||||||
while (result->NextRow());
|
while (result->NextRow());
|
||||||
|
|
@ -7580,9 +7585,9 @@ void ObjectMgr::LoadCreatureQuestRelations()
|
||||||
{
|
{
|
||||||
CreatureInfo const* cInfo = GetCreatureTemplate(itr->first);
|
CreatureInfo const* cInfo = GetCreatureTemplate(itr->first);
|
||||||
if (!cInfo)
|
if (!cInfo)
|
||||||
sLog.outErrorDb("Table `creature_questrelation` have data for nonexistent creature entry (%u) and existing quest %u", itr->first, itr->second);
|
sLog.outErrorDb("Table `creature_involvedrelation` have data for nonexistent creature entry (%u) and existing quest %u", itr->first, itr->second);
|
||||||
else if (!(cInfo->NpcFlags & UNIT_NPC_FLAG_QUESTGIVER))
|
else if (!(cInfo->NpcFlags & UNIT_NPC_FLAG_QUESTGIVER))
|
||||||
sLog.outErrorDb("Table `creature_questrelation` has creature entry (%u) for quest %u, but NpcFlags does not include UNIT_NPC_FLAG_QUESTGIVER", itr->first, itr->second);
|
sLog.outErrorDb("Table `creature_involvedrelation` has creature entry (%u) for quest %u, but NpcFlags does not include UNIT_NPC_FLAG_QUESTGIVER", itr->first, itr->second);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -9400,6 +9405,7 @@ void ObjectMgr::LoadTrainerTemplates()
|
||||||
|
|
||||||
// post loading check
|
// post loading check
|
||||||
std::set<uint32> trainer_ids;
|
std::set<uint32> trainer_ids;
|
||||||
|
bool hasErrored = false;
|
||||||
|
|
||||||
for (CacheTrainerSpellMap::const_iterator tItr = m_mCacheTrainerTemplateSpellMap.begin(); tItr != m_mCacheTrainerTemplateSpellMap.end(); ++tItr)
|
for (CacheTrainerSpellMap::const_iterator tItr = m_mCacheTrainerTemplateSpellMap.begin(); tItr != m_mCacheTrainerTemplateSpellMap.end(); ++tItr)
|
||||||
trainer_ids.insert(tItr->first);
|
trainer_ids.insert(tItr->first);
|
||||||
|
|
@ -9408,18 +9414,21 @@ void ObjectMgr::LoadTrainerTemplates()
|
||||||
{
|
{
|
||||||
if (CreatureInfo const* cInfo = sCreatureStorage.LookupEntry<CreatureInfo>(i))
|
if (CreatureInfo const* cInfo = sCreatureStorage.LookupEntry<CreatureInfo>(i))
|
||||||
{
|
{
|
||||||
if (cInfo->TrainerTemplateId)
|
|
||||||
{
|
|
||||||
if (m_mCacheTrainerTemplateSpellMap.find(cInfo->TrainerTemplateId) != m_mCacheTrainerTemplateSpellMap.end())
|
if (m_mCacheTrainerTemplateSpellMap.find(cInfo->TrainerTemplateId) != m_mCacheTrainerTemplateSpellMap.end())
|
||||||
trainer_ids.erase(cInfo->TrainerTemplateId);
|
trainer_ids.erase(cInfo->TrainerTemplateId);
|
||||||
else
|
else
|
||||||
sLog.outErrorDb("Creature (Entry: %u) has trainer_id = %u for nonexistent trainer template", cInfo->Entry, cInfo->TrainerTemplateId);
|
{
|
||||||
}
|
sLog.outErrorDb("Creature (Entry: %u) has TrainerTemplateId = %u for nonexistent trainer template", cInfo->Entry, cInfo->TrainerTemplateId);
|
||||||
|
hasErrored = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (std::set<uint32>::const_iterator tItr = trainer_ids.begin(); tItr != trainer_ids.end(); ++tItr)
|
for (std::set<uint32>::const_iterator tItr = trainer_ids.begin(); tItr != trainer_ids.end(); ++tItr)
|
||||||
sLog.outErrorDb("Table `npc_trainer_template` has trainer template %u not used by any trainers ", *tItr);
|
sLog.outErrorDb("Table `npc_trainer_template` has trainer template %u not used by any trainers ", *tItr);
|
||||||
|
|
||||||
|
if (hasErrored || !trainer_ids.empty()) // Append extra line in case of reported errors
|
||||||
|
sLog.outString();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ObjectMgr::LoadVendors(char const* tableName, bool isTemplates)
|
void ObjectMgr::LoadVendors(char const* tableName, bool isTemplates)
|
||||||
|
|
@ -9497,7 +9506,7 @@ void ObjectMgr::LoadVendorTemplates()
|
||||||
if (m_mCacheVendorTemplateItemMap.find(cInfo->VendorTemplateId) != m_mCacheVendorTemplateItemMap.end())
|
if (m_mCacheVendorTemplateItemMap.find(cInfo->VendorTemplateId) != m_mCacheVendorTemplateItemMap.end())
|
||||||
vendor_ids.erase(cInfo->VendorTemplateId);
|
vendor_ids.erase(cInfo->VendorTemplateId);
|
||||||
else
|
else
|
||||||
sLog.outErrorDb("Creature (Entry: %u) has vendor_id = %u for nonexistent vendor template", cInfo->Entry, cInfo->VendorTemplateId);
|
sLog.outErrorDb("Creature (Entry: %u) has VendorTemplateId = %u for nonexistent vendor template", cInfo->Entry, cInfo->VendorTemplateId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -9506,6 +9515,56 @@ void ObjectMgr::LoadVendorTemplates()
|
||||||
sLog.outErrorDb("Table `npc_vendor_template` has vendor template %u not used by any vendors ", *vItr);
|
sLog.outErrorDb("Table `npc_vendor_template` has vendor template %u not used by any vendors ", *vItr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* This function is supposed to take care of three things:
|
||||||
|
* 1) Load Transports on Map or on Continents
|
||||||
|
* 2) Load Active Npcs on Map or Continents
|
||||||
|
* 3) Load Everything dependend on config setting LoadAllGridsOnMaps
|
||||||
|
*
|
||||||
|
* This function is currently WIP, hence parts exist only as draft.
|
||||||
|
*/
|
||||||
|
void ObjectMgr::LoadActiveEntities(Map* _map)
|
||||||
|
{
|
||||||
|
// Special case on startup - load continents
|
||||||
|
if (!_map)
|
||||||
|
{
|
||||||
|
uint32 continents[] = {0, 1, 530, 571};
|
||||||
|
for (int i = 0; i < countof(continents); ++i)
|
||||||
|
{
|
||||||
|
_map = sMapMgr.FindMap(continents[i]);
|
||||||
|
if (!_map)
|
||||||
|
_map = sMapMgr.CreateMap(continents[i], nullptr);
|
||||||
|
|
||||||
|
if (_map)
|
||||||
|
LoadActiveEntities(_map);
|
||||||
|
else
|
||||||
|
sLog.outError("ObjectMgr::LoadActiveEntities - Unable to create Map %u", continents[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load active objects for _map
|
||||||
|
if (sWorld.isForceLoadMap(_map->GetId()))
|
||||||
|
{
|
||||||
|
for (CreatureDataMap::const_iterator itr = mCreatureDataMap.begin(); itr != mCreatureDataMap.end(); ++itr)
|
||||||
|
{
|
||||||
|
if (itr->second.mapid == _map->GetId())
|
||||||
|
_map->ForceLoadGrid(itr->second.posX, itr->second.posY);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else // Normal case - Load all npcs that are active
|
||||||
|
{
|
||||||
|
std::pair<ActiveCreatureGuidsOnMap::const_iterator, ActiveCreatureGuidsOnMap::const_iterator> bounds = m_activeCreatures.equal_range(_map->GetId());
|
||||||
|
for (ActiveCreatureGuidsOnMap::const_iterator itr = bounds.first; itr != bounds.second; ++itr)
|
||||||
|
{
|
||||||
|
CreatureData const& data = mCreatureDataMap[itr->second];
|
||||||
|
_map->ForceLoadGrid(data.posX, data.posY);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load Transports on Map _map
|
||||||
|
}
|
||||||
|
|
||||||
void ObjectMgr::LoadNpcGossips()
|
void ObjectMgr::LoadNpcGossips()
|
||||||
{
|
{
|
||||||
m_mCacheNpcTextIdMap.clear();
|
m_mCacheNpcTextIdMap.clear();
|
||||||
|
|
@ -9568,11 +9627,9 @@ void ObjectMgr::LoadGossipMenu(std::set<uint32>& gossipScriptSet)
|
||||||
if (!result)
|
if (!result)
|
||||||
{
|
{
|
||||||
BarGoLink bar(1);
|
BarGoLink bar(1);
|
||||||
|
|
||||||
bar.step();
|
bar.step();
|
||||||
|
|
||||||
sLog.outString();
|
|
||||||
sLog.outErrorDb(">> Loaded gossip_menu, table is empty!");
|
sLog.outErrorDb(">> Loaded gossip_menu, table is empty!");
|
||||||
|
sLog.outString();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -9631,20 +9688,25 @@ void ObjectMgr::LoadGossipMenu(std::set<uint32>& gossipScriptSet)
|
||||||
|
|
||||||
delete result;
|
delete result;
|
||||||
|
|
||||||
sLog.outString();
|
|
||||||
sLog.outString(">> Loaded %u gossip_menu entries", count);
|
|
||||||
|
|
||||||
// post loading tests
|
// post loading tests
|
||||||
for (uint32 i = 1; i < sCreatureStorage.GetMaxEntry(); ++i)
|
for (uint32 i = 1; i < sCreatureStorage.GetMaxEntry(); ++i)
|
||||||
|
{
|
||||||
if (CreatureInfo const* cInfo = sCreatureStorage.LookupEntry<CreatureInfo>(i))
|
if (CreatureInfo const* cInfo = sCreatureStorage.LookupEntry<CreatureInfo>(i))
|
||||||
if (cInfo->GossipMenuId)
|
if (cInfo->GossipMenuId)
|
||||||
if (m_mGossipMenusMap.find(cInfo->GossipMenuId) == m_mGossipMenusMap.end())
|
if (m_mGossipMenusMap.find(cInfo->GossipMenuId) == m_mGossipMenusMap.end())
|
||||||
sLog.outErrorDb("Creature (Entry: %u) has gossip_menu_id = %u for nonexistent menu", cInfo->Entry, cInfo->GossipMenuId);
|
sLog.outErrorDb("Creature (Entry: %u) has GossipMenuId = %u for nonexistent menu", cInfo->Entry, cInfo->GossipMenuId);
|
||||||
|
}
|
||||||
|
|
||||||
for (SQLStorageBase::SQLSIterator<GameObjectInfo> itr = sGOStorage.getDataBegin<GameObjectInfo>(); itr < sGOStorage.getDataEnd<GameObjectInfo>(); ++itr)
|
if (!sLog.HasLogFilter(LOG_FILTER_DB_STRICTED_CHECK))
|
||||||
if (uint32 menuid = itr->GetGossipMenuId())
|
{
|
||||||
if (m_mGossipMenusMap.find(menuid) == m_mGossipMenusMap.end())
|
for (SQLStorageBase::SQLSIterator<GameObjectInfo> itr = sGOStorage.getDataBegin<GameObjectInfo>(); itr < sGOStorage.getDataEnd<GameObjectInfo>(); ++itr)
|
||||||
ERROR_DB_STRICT_LOG("Gameobject (Entry: %u) has gossip_menu_id = %u for nonexistent menu", itr->id, menuid);
|
if (uint32 menuid = itr->GetGossipMenuId())
|
||||||
|
if (m_mGossipMenusMap.find(menuid) == m_mGossipMenusMap.end())
|
||||||
|
sLog.outErrorDb("Gameobject (Entry: %u) has gossip_menu_id = %u for nonexistent menu", itr->id, menuid);
|
||||||
|
}
|
||||||
|
|
||||||
|
sLog.outString(">> Loaded %u gossip_menu entries", count);
|
||||||
|
sLog.outString();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ObjectMgr::LoadGossipMenuItems(std::set<uint32>& gossipScriptSet)
|
void ObjectMgr::LoadGossipMenuItems(std::set<uint32>& gossipScriptSet)
|
||||||
|
|
@ -9660,11 +9722,9 @@ void ObjectMgr::LoadGossipMenuItems(std::set<uint32>& gossipScriptSet)
|
||||||
if (!result)
|
if (!result)
|
||||||
{
|
{
|
||||||
BarGoLink bar(1);
|
BarGoLink bar(1);
|
||||||
|
|
||||||
bar.step();
|
bar.step();
|
||||||
|
|
||||||
sLog.outString();
|
|
||||||
sLog.outErrorDb(">> Loaded gossip_menu_option, table is empty!");
|
sLog.outErrorDb(">> Loaded gossip_menu_option, table is empty!");
|
||||||
|
sLog.outString();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -9770,7 +9830,7 @@ void ObjectMgr::LoadGossipMenuItems(std::set<uint32>& gossipScriptSet)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (found_menu_uses && !found_flags_uses)
|
if (found_menu_uses && !found_flags_uses)
|
||||||
sLog.outErrorDb("Table gossip_menu_option for menu %u, id %u has `npc_option_NpcFlags` = %u but creatures using this menu does not have corresponding`NpcFlags`. Option will not accessible in game.", gMenuItem.menu_id, gMenuItem.id, gMenuItem.npc_option_NpcFlags);
|
sLog.outErrorDb("Table gossip_menu_option for menu %u, id %u has `npc_option_npcflag` = %u but creatures using this menu does not have corresponding `NpcFlags`. Option will not accessible in game.", gMenuItem.menu_id, gMenuItem.id, gMenuItem.npc_option_NpcFlags);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gMenuItem.action_poi_id && !GetPointOfInterest(gMenuItem.action_poi_id))
|
if (gMenuItem.action_poi_id && !GetPointOfInterest(gMenuItem.action_poi_id))
|
||||||
|
|
@ -9804,7 +9864,6 @@ void ObjectMgr::LoadGossipMenuItems(std::set<uint32>& gossipScriptSet)
|
||||||
m_mGossipMenuItemsMap.insert(GossipMenuItemsMap::value_type(gMenuItem.menu_id, gMenuItem));
|
m_mGossipMenuItemsMap.insert(GossipMenuItemsMap::value_type(gMenuItem.menu_id, gMenuItem));
|
||||||
|
|
||||||
++count;
|
++count;
|
||||||
|
|
||||||
}
|
}
|
||||||
while (result->NextRow());
|
while (result->NextRow());
|
||||||
|
|
||||||
|
|
@ -9816,8 +9875,8 @@ void ObjectMgr::LoadGossipMenuItems(std::set<uint32>& gossipScriptSet)
|
||||||
sLog.outErrorDb("Table `gossip_menu` contain unused (in creature or GO or menu options) menu id %u.", *itr);
|
sLog.outErrorDb("Table `gossip_menu` contain unused (in creature or GO or menu options) menu id %u.", *itr);
|
||||||
}
|
}
|
||||||
|
|
||||||
sLog.outString();
|
|
||||||
sLog.outString(">> Loaded %u gossip_menu_option entries", count);
|
sLog.outString(">> Loaded %u gossip_menu_option entries", count);
|
||||||
|
sLog.outString();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ObjectMgr::LoadGossipMenus()
|
void ObjectMgr::LoadGossipMenus()
|
||||||
|
|
|
||||||
|
|
@ -831,6 +831,9 @@ class ObjectMgr
|
||||||
void LoadTrainerTemplates();
|
void LoadTrainerTemplates();
|
||||||
void LoadTrainers() { LoadTrainers("npc_trainer", false); }
|
void LoadTrainers() { LoadTrainers("npc_trainer", false); }
|
||||||
|
|
||||||
|
/// @param _map Map* of the map for which to load active entities. If nullptr active entities on continents are loaded
|
||||||
|
void LoadActiveEntities(Map* _map);
|
||||||
|
|
||||||
void LoadVehicleAccessory();
|
void LoadVehicleAccessory();
|
||||||
|
|
||||||
std::string GeneratePetName(uint32 entry);
|
std::string GeneratePetName(uint32 entry);
|
||||||
|
|
@ -1340,10 +1343,13 @@ class ObjectMgr
|
||||||
HalfNameMap PetHalfName0;
|
HalfNameMap PetHalfName0;
|
||||||
HalfNameMap PetHalfName1;
|
HalfNameMap PetHalfName1;
|
||||||
|
|
||||||
|
typedef std::multimap<uint32 /*mapId*/, uint32 /*guid*/> ActiveCreatureGuidsOnMap;
|
||||||
|
|
||||||
// Array to store creature stats, Max creature level + 1 (for data alignement with in game level)
|
// Array to store creature stats, Max creature level + 1 (for data alignement with in game level)
|
||||||
CreatureClassLvlStats m_creatureClassLvlStats[DEFAULT_MAX_CREATURE_LEVEL + 1][MAX_CREATURE_CLASS][MAX_EXPANSION + 1];
|
CreatureClassLvlStats m_creatureClassLvlStats[DEFAULT_MAX_CREATURE_LEVEL + 1][MAX_CREATURE_CLASS][MAX_EXPANSION + 1];
|
||||||
|
|
||||||
MapObjectGuids mMapObjectGuids;
|
MapObjectGuids mMapObjectGuids;
|
||||||
|
ActiveCreatureGuidsOnMap m_activeCreatures;
|
||||||
CreatureDataMap mCreatureDataMap;
|
CreatureDataMap mCreatureDataMap;
|
||||||
CreatureLocaleMap mCreatureLocaleMap;
|
CreatureLocaleMap mCreatureLocaleMap;
|
||||||
GameObjectDataMap mGameObjectDataMap;
|
GameObjectDataMap mGameObjectDataMap;
|
||||||
|
|
|
||||||
|
|
@ -504,6 +504,7 @@ void Pet::SetDeathState(DeathState s) // overwrite virtual
|
||||||
RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_STUNNED);
|
RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_STUNNED);
|
||||||
CastPetAuras(true);
|
CastPetAuras(true);
|
||||||
}
|
}
|
||||||
|
CastOwnerTalentAuras();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Pet::Update(uint32 update_diff, uint32 diff)
|
void Pet::Update(uint32 update_diff, uint32 diff)
|
||||||
|
|
@ -2091,6 +2092,40 @@ void Pet::SynchronizeLevelWithOwner()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Pet::SetModeFlags(PetModeFlags mode)
|
||||||
|
{
|
||||||
|
m_petModeFlags = mode;
|
||||||
|
|
||||||
|
Unit* owner = GetOwner();
|
||||||
|
if (!owner || owner->GetTypeId() != TYPEID_PLAYER)
|
||||||
|
return;
|
||||||
|
|
||||||
|
WorldPacket data(SMSG_PET_MODE, 12);
|
||||||
|
data << GetObjectGuid();
|
||||||
|
data << uint32(m_petModeFlags);
|
||||||
|
((Player*)owner)->GetSession()->SendPacket(&data);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Pet::SetStayPosition(bool stay)
|
||||||
|
{
|
||||||
|
if (stay)
|
||||||
|
{
|
||||||
|
m_stayPosX = GetPositionX();
|
||||||
|
m_stayPosY = GetPositionY();
|
||||||
|
m_stayPosZ = GetPositionZ();
|
||||||
|
m_stayPosO = GetOrientation();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_stayPosX = 0;
|
||||||
|
m_stayPosY = 0;
|
||||||
|
m_stayPosZ = 0;
|
||||||
|
m_stayPosO = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_stayPosSet = stay;
|
||||||
|
}
|
||||||
|
|
||||||
void Pet::ApplyModeFlags(PetModeFlags mode, bool apply)
|
void Pet::ApplyModeFlags(PetModeFlags mode, bool apply)
|
||||||
{
|
{
|
||||||
if (apply)
|
if (apply)
|
||||||
|
|
|
||||||
|
|
@ -206,6 +206,7 @@ class Pet : public Creature
|
||||||
bool CanTakeMoreActiveSpells(uint32 SpellIconID);
|
bool CanTakeMoreActiveSpells(uint32 SpellIconID);
|
||||||
void ToggleAutocast(uint32 spellid, bool apply);
|
void ToggleAutocast(uint32 spellid, bool apply);
|
||||||
|
|
||||||
|
void SetModeFlags(PetModeFlags mode);
|
||||||
void ApplyModeFlags(PetModeFlags mode, bool apply);
|
void ApplyModeFlags(PetModeFlags mode, bool apply);
|
||||||
PetModeFlags GetModeFlags() const { return m_petModeFlags; }
|
PetModeFlags GetModeFlags() const { return m_petModeFlags; }
|
||||||
|
|
||||||
|
|
@ -231,6 +232,25 @@ class Pet : public Creature
|
||||||
bool removeSpell(uint32 spell_id, bool learn_prev, bool clear_ab = true);
|
bool removeSpell(uint32 spell_id, bool learn_prev, bool clear_ab = true);
|
||||||
void CleanupActionBar();
|
void CleanupActionBar();
|
||||||
|
|
||||||
|
bool m_retreating;
|
||||||
|
|
||||||
|
void SetIsRetreating(bool retreating = false) { m_retreating = retreating; }
|
||||||
|
bool GetIsRetreating() { return m_retreating; }
|
||||||
|
|
||||||
|
bool m_stayPosSet;
|
||||||
|
float m_stayPosX;
|
||||||
|
float m_stayPosY;
|
||||||
|
float m_stayPosZ;
|
||||||
|
float m_stayPosO;
|
||||||
|
|
||||||
|
void SetStayPosition(bool stay = false);
|
||||||
|
bool IsStayPosSet() { return m_stayPosSet; }
|
||||||
|
|
||||||
|
float GetStayPosX() { return m_stayPosX; }
|
||||||
|
float GetStayPosY() { return m_stayPosY; }
|
||||||
|
float GetStayPosZ() { return m_stayPosZ; }
|
||||||
|
float GetStayPosO() { return m_stayPosO; }
|
||||||
|
|
||||||
PetSpellMap m_spells;
|
PetSpellMap m_spells;
|
||||||
AutoSpellList m_autospells;
|
AutoSpellList m_autospells;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -60,7 +60,7 @@ void PetAI::MoveInLineOfSight(Unit* u)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (u->IsTargetableForAttack() && m_creature->IsHostileTo(u) &&
|
if (u->IsTargetableForAttack() && m_creature->IsHostileTo(u) &&
|
||||||
u->isInAccessablePlaceFor(m_creature))
|
u->IsInAccessablePlaceFor(m_creature))
|
||||||
{
|
{
|
||||||
float attackRadius = m_creature->GetAttackDistance(u);
|
float attackRadius = m_creature->GetAttackDistance(u);
|
||||||
if (m_creature->IsWithinDistInMap(u, attackRadius) && m_creature->GetDistanceZ(u) <= CREATURE_Z_ATTACK_RANGE)
|
if (m_creature->IsWithinDistInMap(u, attackRadius) && m_creature->GetDistanceZ(u) <= CREATURE_Z_ATTACK_RANGE)
|
||||||
|
|
|
||||||
|
|
@ -346,6 +346,12 @@ void TradeData::SetMoney(uint64 money)
|
||||||
if (m_money == money)
|
if (m_money == money)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (money > m_player->GetMoney())
|
||||||
|
{
|
||||||
|
m_player->GetSession()->SendTradeStatus(TRADE_STATUS_CLOSE_WINDOW);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
m_money = money;
|
m_money = money;
|
||||||
|
|
||||||
SetAccepted(false);
|
SetAccepted(false);
|
||||||
|
|
@ -1264,19 +1270,17 @@ void Player::Update(uint32 update_diff, uint32 p_time)
|
||||||
RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_ENTER_PVP_COMBAT);
|
RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_ENTER_PVP_COMBAT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}// Speed collect rest bonus (section/in hour)
|
||||||
|
|
||||||
if (HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_RESTING))
|
if (HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_RESTING))
|
||||||
{
|
{
|
||||||
if (roll_chance_i(3) && GetTimeInnEnter() > 0) // Freeze update
|
if (GetTimeInnEnter() > 0) // Freeze update
|
||||||
{
|
{
|
||||||
time_t time_inn = time(NULL) - GetTimeInnEnter();
|
time_t time_inn = now - GetTimeInnEnter();
|
||||||
if (time_inn >= 10) // Freeze update
|
if (time_inn >= 10) // Freeze update
|
||||||
{
|
{
|
||||||
float bubble = 0.125f * sWorld.getConfig(CONFIG_FLOAT_RATE_REST_INGAME);
|
SetRestBonus(GetRestBonus() + ComputeRest(time_inn));
|
||||||
// Speed collect rest bonus (section/in hour)
|
UpdateInnerTime(now);
|
||||||
SetRestBonus(float(GetRestBonus() + time_inn * (GetUInt32Value(PLAYER_NEXT_LEVEL_XP) / 72000) * bubble));
|
|
||||||
UpdateInnerTime(time(NULL));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -2888,7 +2892,7 @@ void Player::InitStatsForLevel(bool reapplyMods)
|
||||||
RemoveFlag(PLAYER_FLAGS, PLAYER_FLAGS_AFK | PLAYER_FLAGS_DND | PLAYER_FLAGS_GM | PLAYER_FLAGS_GHOST);
|
RemoveFlag(PLAYER_FLAGS, PLAYER_FLAGS_AFK | PLAYER_FLAGS_DND | PLAYER_FLAGS_GM | PLAYER_FLAGS_GHOST);
|
||||||
|
|
||||||
RemoveStandFlags(UNIT_STAND_FLAGS_ALL); // one form stealth modified bytes
|
RemoveStandFlags(UNIT_STAND_FLAGS_ALL); // one form stealth modified bytes
|
||||||
RemoveByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP | UNIT_BYTE2_FLAG_SANCTUARY);
|
RemoveByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP | UNIT_BYTE2_FLAG_SUPPORTABLE);
|
||||||
|
|
||||||
// restore if need some important flags
|
// restore if need some important flags
|
||||||
SetUInt32Value(PLAYER_FIELD_BYTES2, 0); // flags empty by default
|
SetUInt32Value(PLAYER_FIELD_BYTES2, 0); // flags empty by default
|
||||||
|
|
@ -4147,14 +4151,14 @@ void Player::BuildCreateUpdateBlockForPlayer(UpdateData* data, Player* target) c
|
||||||
{
|
{
|
||||||
for (int i = 0; i < EQUIPMENT_SLOT_END; ++i)
|
for (int i = 0; i < EQUIPMENT_SLOT_END; ++i)
|
||||||
{
|
{
|
||||||
if (m_items[i] == NULL)
|
if (m_items[i] == nullptr)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
m_items[i]->BuildCreateUpdateBlockForPlayer(data, target);
|
m_items[i]->BuildCreateUpdateBlockForPlayer(data, target);
|
||||||
}
|
}
|
||||||
for (int i = INVENTORY_SLOT_BAG_START; i < BANK_SLOT_BAG_END; ++i)
|
for (int i = INVENTORY_SLOT_BAG_START; i < BANK_SLOT_BAG_END; ++i)
|
||||||
{
|
{
|
||||||
if (m_items[i] == NULL)
|
if (m_items[i] == nullptr)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
m_items[i]->BuildCreateUpdateBlockForPlayer(data, target);
|
m_items[i]->BuildCreateUpdateBlockForPlayer(data, target);
|
||||||
|
|
@ -4555,6 +4559,38 @@ void Player::SetWaterWalk(bool enable)
|
||||||
GetSession()->SendPacket(&data);
|
GetSession()->SendPacket(&data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Player::SetLevitate(bool enable)
|
||||||
|
{
|
||||||
|
WorldPacket data;
|
||||||
|
BuildMoveLevitatePacket(&data, enable, 0);
|
||||||
|
GetSession()->SendPacket(&data);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Player::SetCanFly(bool enable)
|
||||||
|
{
|
||||||
|
WorldPacket data;
|
||||||
|
BuildMoveSetCanFlyPacket(&data, enable, 0);
|
||||||
|
GetSession()->SendPacket(&data);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Player::SetFeatherFall(bool enable)
|
||||||
|
{
|
||||||
|
WorldPacket data;
|
||||||
|
BuildMoveFeatherFallPacket(&data, enable, 0);
|
||||||
|
SendMessageToSet(&data, true);
|
||||||
|
|
||||||
|
// start fall from current height
|
||||||
|
if (!enable)
|
||||||
|
SetFallInformation(0, GetPositionZ());
|
||||||
|
}
|
||||||
|
|
||||||
|
void Player::SetHover(bool enable)
|
||||||
|
{
|
||||||
|
WorldPacket data;
|
||||||
|
BuildMoveHoverPacket(&data, enable, 0);
|
||||||
|
GetSession()->SendPacket(&data);
|
||||||
|
}
|
||||||
|
|
||||||
/* Preconditions:
|
/* Preconditions:
|
||||||
- a resurrectable corpse must not be loaded for the player (only bones)
|
- a resurrectable corpse must not be loaded for the player (only bones)
|
||||||
- the player must be in world
|
- the player must be in world
|
||||||
|
|
@ -6184,9 +6220,6 @@ bool Player::SetPosition(float x, float y, float z, float orientation, bool tele
|
||||||
// group update
|
// group update
|
||||||
if (GetGroup() && (old_x != x || old_y != y))
|
if (GetGroup() && (old_x != x || old_y != y))
|
||||||
SetGroupUpdateFlag(GROUP_UPDATE_FLAG_POSITION);
|
SetGroupUpdateFlag(GROUP_UPDATE_FLAG_POSITION);
|
||||||
|
|
||||||
if (GetTrader() && !IsWithinDistInMap(GetTrader(), INTERACTION_DISTANCE))
|
|
||||||
GetSession()->SendCancelTrade(); // will close both side trade windows
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_positionStatusUpdateTimer) // Update position's state only on interval
|
if (m_positionStatusUpdateTimer) // Update position's state only on interval
|
||||||
|
|
@ -6966,13 +6999,13 @@ void Player::UpdateZone(uint32 newZone, uint32 newArea)
|
||||||
|
|
||||||
if (zone->flags & AREA_FLAG_SANCTUARY) // in sanctuary
|
if (zone->flags & AREA_FLAG_SANCTUARY) // in sanctuary
|
||||||
{
|
{
|
||||||
SetByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_SANCTUARY);
|
SetByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_SUPPORTABLE);
|
||||||
if (sWorld.IsFFAPvPRealm())
|
if (sWorld.IsFFAPvPRealm())
|
||||||
SetFFAPvP(false);
|
SetFFAPvP(false);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
RemoveByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_SANCTUARY);
|
RemoveByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_SUPPORTABLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (zone->flags & AREA_FLAG_CAPITAL) // in capital city
|
if (zone->flags & AREA_FLAG_CAPITAL) // in capital city
|
||||||
|
|
@ -7483,9 +7516,9 @@ void Player::ApplyItemEquipSpell(Item* item, bool apply, bool form_change)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// at un-apply remove all spells (not only at-apply, so any at-use active affects from item and etc)
|
// at un-apply remove all spells (not only at-apply, so any at-use active affects from item and etc)
|
||||||
// except with at-use with negative charges, so allow consuming item spells (including with extra flag that prevent consume really)
|
// except on form change and with at-use with negative charges, so allow consuming item spells (including with extra flag that prevent consume really)
|
||||||
// applied to player after item remove from equip slot
|
// applied to player after item remove from equip slot
|
||||||
if (spellData.SpellTrigger == ITEM_SPELLTRIGGER_ON_USE && spellData.SpellCharges < 0)
|
if (spellData.SpellTrigger == ITEM_SPELLTRIGGER_ON_USE && (form_change || spellData.SpellCharges < 0))
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -14004,6 +14037,10 @@ bool Player::SatisfyQuestPreviousQuest(Quest const* qInfo, bool msg) const
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
// each-from-all exclusive group ( < 0)
|
// each-from-all exclusive group ( < 0)
|
||||||
|
// given a group with 2+ quests, and one of those has a branch that is not restricted by the group, return true
|
||||||
|
if (qInfo->GetPrevQuestId() != 0 && qPrevInfo->GetNextQuestId() != qInfo->GetPrevQuestId())
|
||||||
|
return true;
|
||||||
|
|
||||||
// can be start if only all quests in prev quest exclusive group completed and rewarded
|
// can be start if only all quests in prev quest exclusive group completed and rewarded
|
||||||
ExclusiveQuestGroupsMapBounds bounds = sObjectMgr.GetExclusiveQuestGroupsMapBounds(qPrevInfo->GetExclusiveGroup());
|
ExclusiveQuestGroupsMapBounds bounds = sObjectMgr.GetExclusiveQuestGroupsMapBounds(qPrevInfo->GetExclusiveGroup());
|
||||||
|
|
||||||
|
|
@ -14037,6 +14074,11 @@ bool Player::SatisfyQuestPreviousQuest(Quest const* qInfo, bool msg) const
|
||||||
if (qPrevInfo->GetExclusiveGroup() >= 0)
|
if (qPrevInfo->GetExclusiveGroup() >= 0)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
// each-from-all exclusive group ( < 0)
|
||||||
|
// given a group with 2+ quests, and one of those has a branch that is not restricted by the group, return true
|
||||||
|
if (qInfo->GetPrevQuestId() != 0 && qPrevInfo->GetNextQuestId() != abs(qInfo->GetPrevQuestId()))
|
||||||
|
return true;
|
||||||
|
|
||||||
// each-from-all exclusive group ( < 0)
|
// each-from-all exclusive group ( < 0)
|
||||||
// can be start if only all quests in prev quest exclusive group active
|
// can be start if only all quests in prev quest exclusive group active
|
||||||
ExclusiveQuestGroupsMapBounds bounds = sObjectMgr.GetExclusiveQuestGroupsMapBounds(qPrevInfo->GetExclusiveGroup());
|
ExclusiveQuestGroupsMapBounds bounds = sObjectMgr.GetExclusiveQuestGroupsMapBounds(qPrevInfo->GetExclusiveGroup());
|
||||||
|
|
@ -15494,7 +15536,7 @@ bool Player::LoadFromDB(ObjectGuid guid, SqlQueryHolder* holder)
|
||||||
m_bgData.bgTypeID = currentBg->GetTypeID(); // bg data not marked as modified
|
m_bgData.bgTypeID = currentBg->GetTypeID(); // bg data not marked as modified
|
||||||
|
|
||||||
// join player to battleground group
|
// join player to battleground group
|
||||||
currentBg->EventPlayerLoggedIn(this, GetObjectGuid());
|
currentBg->EventPlayerLoggedIn(this);
|
||||||
currentBg->AddOrSetPlayerToCorrectBgGroup(this, GetObjectGuid(), m_bgData.bgTeam);
|
currentBg->AddOrSetPlayerToCorrectBgGroup(this, GetObjectGuid(), m_bgData.bgTeam);
|
||||||
|
|
||||||
SetInviteForBattleGroundQueueType(bgQueueTypeId, currentBg->GetInstanceID());
|
SetInviteForBattleGroundQueueType(bgQueueTypeId, currentBg->GetInstanceID());
|
||||||
|
|
@ -15722,17 +15764,7 @@ bool Player::LoadFromDB(ObjectGuid guid, SqlQueryHolder* holder)
|
||||||
m_rest_bonus = fields[21].GetFloat();
|
m_rest_bonus = fields[21].GetFloat();
|
||||||
|
|
||||||
if (time_diff > 0)
|
if (time_diff > 0)
|
||||||
{
|
SetRestBonus(GetRestBonus() + ComputeRest(time_diff, true, (fields[23].GetInt32() > 0)));
|
||||||
// speed collect rest bonus in offline, in logout, far from tavern, city (section/in hour)
|
|
||||||
float bubble0 = 0.031f;
|
|
||||||
// speed collect rest bonus in offline, in logout, in tavern, city (section/in hour)
|
|
||||||
float bubble1 = 0.125f;
|
|
||||||
float bubble = fields[23].GetUInt32() > 0
|
|
||||||
? bubble1 * sWorld.getConfig(CONFIG_FLOAT_RATE_REST_OFFLINE_IN_TAVERN_OR_CITY)
|
|
||||||
: bubble0 * sWorld.getConfig(CONFIG_FLOAT_RATE_REST_OFFLINE_IN_WILDERNESS);
|
|
||||||
|
|
||||||
SetRestBonus(GetRestBonus() + time_diff * ((float)GetUInt32Value(PLAYER_NEXT_LEVEL_XP) / 72000)*bubble);
|
|
||||||
}
|
|
||||||
|
|
||||||
// load skills after InitStatsForLevel because it triggering aura apply also
|
// load skills after InitStatsForLevel because it triggering aura apply also
|
||||||
_LoadSkills(holder->GetResult(PLAYER_LOGIN_QUERY_LOADSKILLS));
|
_LoadSkills(holder->GetResult(PLAYER_LOGIN_QUERY_LOADSKILLS));
|
||||||
|
|
@ -15933,6 +15965,43 @@ bool Player::LoadFromDB(ObjectGuid guid, SqlQueryHolder* holder)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Player::IsTappedByMeOrMyGroup(Creature* creature)
|
||||||
|
{
|
||||||
|
/* Nobody tapped the monster (solo kill by another NPC) */
|
||||||
|
if (!creature->HasFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_TAPPED))
|
||||||
|
{ return false; }
|
||||||
|
|
||||||
|
/* If there is a loot recipient, assign it to recipient */
|
||||||
|
if (Player* recipient = creature->GetLootRecipient())
|
||||||
|
{
|
||||||
|
/* See if we're in a group */
|
||||||
|
if (Group* plr_group = recipient->GetGroup())
|
||||||
|
{
|
||||||
|
/* Recipient is in a group... but is it ours? */
|
||||||
|
if (Group* my_group = GetGroup())
|
||||||
|
{
|
||||||
|
/* Check groups are the same */
|
||||||
|
if (plr_group != my_group)
|
||||||
|
{ return false; } // Cheater, deny loot
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{ return false; } // We're not in a group, probably cheater
|
||||||
|
|
||||||
|
/* We're in the looters group, so mob is tapped by us */
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
/* We're not in a group, check to make sure we're the recipient (prevent cheaters) */
|
||||||
|
else if (recipient == this)
|
||||||
|
{ return true; }
|
||||||
|
}
|
||||||
|
else
|
||||||
|
/* Don't know what happened to the recipient, probably disconnected
|
||||||
|
* Either way, it isn't us, so mark as tapped */
|
||||||
|
{ return false; }
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
bool Player::isAllowedToLoot(Creature* creature)
|
bool Player::isAllowedToLoot(Creature* creature)
|
||||||
{
|
{
|
||||||
// never tapped by any (mob solo kill)
|
// never tapped by any (mob solo kill)
|
||||||
|
|
@ -21716,6 +21785,123 @@ void Player::SetTitle(CharTitlesEntry const* title, bool lost)
|
||||||
GetSession()->SendPacket(&data);
|
GetSession()->SendPacket(&data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Player::UpdateRuneRegen(RuneType rune)
|
||||||
|
{
|
||||||
|
if (rune >= RUNE_DEATH)
|
||||||
|
return;
|
||||||
|
|
||||||
|
RuneType actualRune = rune;
|
||||||
|
float cooldown = RUNE_BASE_COOLDOWN;
|
||||||
|
for (uint8 i = 0; i < MAX_RUNES; i += 2)
|
||||||
|
{
|
||||||
|
if (GetBaseRune(i) != rune)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
uint32 cd = GetRuneCooldown(i);
|
||||||
|
uint32 secondRuneCd = GetRuneCooldown(i + 1);
|
||||||
|
if (!cd && !secondRuneCd)
|
||||||
|
actualRune = GetCurrentRune(i);
|
||||||
|
else if (secondRuneCd && (cd > secondRuneCd || !cd))
|
||||||
|
{
|
||||||
|
cooldown = GetBaseRuneCooldown(i + 1);
|
||||||
|
actualRune = GetCurrentRune(i + 1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cooldown = GetBaseRuneCooldown(i);
|
||||||
|
actualRune = GetCurrentRune(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
float auraMod = 1.0f;
|
||||||
|
Unit::AuraList const& regenAuras = GetAurasByType(SPELL_AURA_MOD_POWER_REGEN_PERCENT);
|
||||||
|
for (Unit::AuraList::const_iterator i = regenAuras.begin(); i != regenAuras.end(); ++i)
|
||||||
|
if ((*i)->GetMiscValue() == POWER_RUNE && (*i)->GetSpellEffect()->EffectMiscValueB == rune)
|
||||||
|
auraMod *= (100.0f + (*i)->GetModifier()->m_amount) / 100.0f;
|
||||||
|
|
||||||
|
// Unholy Presence
|
||||||
|
if (Aura* aura = GetAura(48265, EFFECT_INDEX_0))
|
||||||
|
auraMod *= (100.0f + aura->GetModifier()->m_amount) / 100.0f;
|
||||||
|
|
||||||
|
// Runic Corruption
|
||||||
|
if (Aura* aura = GetAura(51460, EFFECT_INDEX_0))
|
||||||
|
auraMod *= (100.0f + aura->GetModifier()->m_amount) / 100.0f;
|
||||||
|
|
||||||
|
float hastePct = (100.0f - GetRatingBonusValue(CR_HASTE_MELEE)) / 100.0f;
|
||||||
|
if (hastePct < 0)
|
||||||
|
hastePct = 1.0f;
|
||||||
|
|
||||||
|
cooldown *= hastePct / auraMod;
|
||||||
|
|
||||||
|
float value = float(1 * IN_MILLISECONDS) / cooldown;
|
||||||
|
SetFloatValue(PLAYER_RUNE_REGEN_1 + uint8(actualRune), value);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Player::UpdateRuneRegen()
|
||||||
|
{
|
||||||
|
for (uint8 i = 0; i < NUM_RUNE_TYPES; ++i)
|
||||||
|
UpdateRuneRegen(RuneType(i));
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8 Player::GetRuneCooldownFraction(uint8 index) const
|
||||||
|
{
|
||||||
|
uint16 baseCd = GetBaseRuneCooldown(index);
|
||||||
|
if (!baseCd || !GetRuneCooldown(index))
|
||||||
|
return 255;
|
||||||
|
else if (baseCd == GetRuneCooldown(index))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return uint8(float(baseCd - GetRuneCooldown(index)) / baseCd * 255);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Player::AddRuneByAuraEffect(uint8 index, RuneType newType, Aura const* aura)
|
||||||
|
{
|
||||||
|
// Item - Death Knight T11 DPS 4P Bonus
|
||||||
|
if (newType == RUNE_DEATH && HasAura(90459))
|
||||||
|
CastSpell(this, 90507, true); // Death Eater
|
||||||
|
|
||||||
|
SetRuneConvertAura(index, aura); ConvertRune(index, newType);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Player::RemoveRunesByAuraEffect(Aura const* aura)
|
||||||
|
{
|
||||||
|
for (uint8 i = 0; i < MAX_RUNES; ++i)
|
||||||
|
{
|
||||||
|
if (m_runes->runes[i].ConvertAura == aura)
|
||||||
|
{
|
||||||
|
ConvertRune(i, GetBaseRune(i));
|
||||||
|
SetRuneConvertAura(i, NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Player::RestoreBaseRune(uint8 index)
|
||||||
|
{
|
||||||
|
Aura const* aura = m_runes->runes[index].ConvertAura;
|
||||||
|
// If rune was converted by a non-pasive aura that still active we should keep it converted
|
||||||
|
if (aura && !IsPassiveSpell(aura->GetSpellProto()))
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Blood of the North
|
||||||
|
if (aura->GetId() == 54637 && HasAura(54637))
|
||||||
|
return;
|
||||||
|
|
||||||
|
ConvertRune(index, GetBaseRune(index));
|
||||||
|
SetRuneConvertAura(index, NULL);
|
||||||
|
// Don't drop passive talents providing rune convertion
|
||||||
|
if (!aura || aura->GetModifier()->m_auraname != SPELL_AURA_CONVERT_RUNE)
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (uint8 i = 0; i < MAX_RUNES; ++i)
|
||||||
|
if (aura == m_runes->runes[i].ConvertAura)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (Unit* target = aura->GetTarget())
|
||||||
|
target->RemoveSpellAuraHolder(const_cast<Aura*>(aura)->GetHolder());
|
||||||
|
}
|
||||||
|
|
||||||
void Player::ConvertRune(uint8 index, RuneType newType)
|
void Player::ConvertRune(uint8 index, RuneType newType)
|
||||||
{
|
{
|
||||||
SetCurrentRune(index, newType);
|
SetCurrentRune(index, newType);
|
||||||
|
|
@ -21749,7 +21935,7 @@ void Player::ResyncRunes()
|
||||||
for (uint32 i = 0; i < MAX_RUNES; ++i)
|
for (uint32 i = 0; i < MAX_RUNES; ++i)
|
||||||
{
|
{
|
||||||
data << uint8(GetCurrentRune(i)); // rune type
|
data << uint8(GetCurrentRune(i)); // rune type
|
||||||
data << uint8(255 - (GetRuneCooldown(i) * 51)); // passed cooldown time (0-255)
|
data << uint8(GetRuneCooldownFraction(i));
|
||||||
}
|
}
|
||||||
GetSession()->SendPacket(&data);
|
GetSession()->SendPacket(&data);
|
||||||
}
|
}
|
||||||
|
|
@ -21761,16 +21947,6 @@ void Player::AddRunePower(uint8 index)
|
||||||
GetSession()->SendPacket(&data);
|
GetSession()->SendPacket(&data);
|
||||||
}
|
}
|
||||||
|
|
||||||
static RuneType runeSlotTypes[MAX_RUNES] =
|
|
||||||
{
|
|
||||||
/*0*/ RUNE_BLOOD,
|
|
||||||
/*1*/ RUNE_BLOOD,
|
|
||||||
/*2*/ RUNE_UNHOLY,
|
|
||||||
/*3*/ RUNE_UNHOLY,
|
|
||||||
/*4*/ RUNE_FROST,
|
|
||||||
/*5*/ RUNE_FROST
|
|
||||||
};
|
|
||||||
|
|
||||||
void Player::InitRunes()
|
void Player::InitRunes()
|
||||||
{
|
{
|
||||||
if (getClass() != CLASS_DEATH_KNIGHT)
|
if (getClass() != CLASS_DEATH_KNIGHT)
|
||||||
|
|
@ -24066,6 +24242,77 @@ bool Player::FitArmorSpecializationRules(SpellEntry const * spellProto) const
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float Player::ComputeRest(time_t timePassed, bool offline /*= false*/, bool inRestPlace /*= false*/)
|
||||||
|
{
|
||||||
|
// Every 8h in resting zone we gain a bubble
|
||||||
|
// A bubble is 5% of the total xp so there is 20 bubbles
|
||||||
|
// So we gain (total XP/20 every 8h) (8h = 288800 sec)
|
||||||
|
// (TotalXP/20)/28800; simplified to (TotalXP/576000) per second
|
||||||
|
// Client automatically double the value sent so we have to divide it by 2
|
||||||
|
// So final formula (TotalXP/1152000)
|
||||||
|
float bonus = timePassed * (GetUInt32Value(PLAYER_NEXT_LEVEL_XP) / 1152000.0f); // Get the gained rest xp for given second
|
||||||
|
if (!offline)
|
||||||
|
bonus *= sWorld.getConfig(CONFIG_FLOAT_RATE_REST_INGAME); // Apply the custom setting
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (inRestPlace)
|
||||||
|
bonus *= sWorld.getConfig(CONFIG_FLOAT_RATE_REST_OFFLINE_IN_TAVERN_OR_CITY);
|
||||||
|
else
|
||||||
|
bonus *= sWorld.getConfig(CONFIG_FLOAT_RATE_REST_OFFLINE_IN_WILDERNESS) / 4.0f; // bonus is reduced by 4 when not in rest place
|
||||||
|
}
|
||||||
|
return bonus;
|
||||||
|
}
|
||||||
|
|
||||||
|
float Player::GetCollisionHeight(bool mounted) const
|
||||||
|
{
|
||||||
|
if (mounted)
|
||||||
|
{
|
||||||
|
// mounted case
|
||||||
|
CreatureDisplayInfoEntry const* mountDisplayInfo = sCreatureDisplayInfoStore.LookupEntry(GetUInt32Value(UNIT_FIELD_MOUNTDISPLAYID));
|
||||||
|
if (!mountDisplayInfo)
|
||||||
|
return GetCollisionHeight(false);
|
||||||
|
|
||||||
|
CreatureModelDataEntry const* mountModelData = sCreatureModelDataStore.LookupEntry(mountDisplayInfo->ModelId);
|
||||||
|
if (!mountModelData)
|
||||||
|
return GetCollisionHeight(false);
|
||||||
|
|
||||||
|
CreatureDisplayInfoEntry const* displayInfo = sCreatureDisplayInfoStore.LookupEntry(GetNativeDisplayId());
|
||||||
|
if (!displayInfo)
|
||||||
|
{
|
||||||
|
sLog.outError("GetCollisionHeight::Unable to find CreatureDisplayInfoEntry for %u", GetNativeDisplayId());
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
CreatureModelDataEntry const* modelData = sCreatureModelDataStore.LookupEntry(displayInfo->ModelId);
|
||||||
|
if (!modelData)
|
||||||
|
{
|
||||||
|
sLog.outError("GetCollisionHeight::Unable to find CreatureModelDataEntry for %u", displayInfo->ModelId);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
float scaleMod = GetObjectScale(); // 99% sure about this
|
||||||
|
|
||||||
|
return scaleMod * mountModelData->MountHeight + modelData->CollisionHeight * 0.5f;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// use native model collision height in dismounted case
|
||||||
|
CreatureDisplayInfoEntry const* displayInfo = sCreatureDisplayInfoStore.LookupEntry(GetNativeDisplayId());
|
||||||
|
if (!displayInfo)
|
||||||
|
{
|
||||||
|
sLog.outError("GetCollisionHeight::Unable to find CreatureDisplayInfoEntry for %u", GetNativeDisplayId());
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
CreatureModelDataEntry const* modelData = sCreatureModelDataStore.LookupEntry(displayInfo->ModelId);
|
||||||
|
if (!modelData)
|
||||||
|
{
|
||||||
|
sLog.outError("GetCollisionHeight::Unable to find CreatureModelDataEntry for %u", displayInfo->ModelId);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return modelData->CollisionHeight;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Player::SendPetitionSignResult(ObjectGuid petitionGuid, Player* player, uint32 result)
|
void Player::SendPetitionSignResult(ObjectGuid petitionGuid, Player* player, uint32 result)
|
||||||
{
|
{
|
||||||
WorldPacket data(SMSG_PETITION_SIGN_RESULTS, 8 + 8 + 4);
|
WorldPacket data(SMSG_PETITION_SIGN_RESULTS, 8 + 8 + 4);
|
||||||
|
|
|
||||||
|
|
@ -353,7 +353,12 @@ struct Areas
|
||||||
};
|
};
|
||||||
|
|
||||||
#define MAX_RUNES 6
|
#define MAX_RUNES 6
|
||||||
#define RUNE_COOLDOWN (2*5*IN_MILLISECONDS) // msec
|
|
||||||
|
enum RuneCooldowns
|
||||||
|
{
|
||||||
|
RUNE_BASE_COOLDOWN = 10000,
|
||||||
|
RUNE_MISS_COOLDOWN = 1500 // cooldown applied on runes when the spell misses
|
||||||
|
};
|
||||||
|
|
||||||
enum RuneType
|
enum RuneType
|
||||||
{
|
{
|
||||||
|
|
@ -364,17 +369,30 @@ enum RuneType
|
||||||
NUM_RUNE_TYPES = 4
|
NUM_RUNE_TYPES = 4
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static RuneType runeSlotTypes[MAX_RUNES] =
|
||||||
|
{
|
||||||
|
/*0*/ RUNE_BLOOD,
|
||||||
|
/*1*/ RUNE_BLOOD,
|
||||||
|
/*2*/ RUNE_UNHOLY,
|
||||||
|
/*3*/ RUNE_UNHOLY,
|
||||||
|
/*4*/ RUNE_FROST,
|
||||||
|
/*5*/ RUNE_FROST
|
||||||
|
};
|
||||||
|
|
||||||
struct RuneInfo
|
struct RuneInfo
|
||||||
{
|
{
|
||||||
uint8 BaseRune;
|
uint8 BaseRune;
|
||||||
uint8 CurrentRune;
|
uint8 CurrentRune;
|
||||||
|
uint16 BaseCooldown;
|
||||||
uint16 Cooldown; // msec
|
uint16 Cooldown; // msec
|
||||||
|
Aura const* ConvertAura;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Runes
|
struct Runes
|
||||||
{
|
{
|
||||||
RuneInfo runes[MAX_RUNES];
|
RuneInfo runes[MAX_RUNES];
|
||||||
uint8 runeState; // mask of available runes
|
uint8 runeState; // mask of available runes
|
||||||
|
uint32 lastUsedRuneMask;
|
||||||
|
|
||||||
void SetRuneState(uint8 index, bool set = true)
|
void SetRuneState(uint8 index, bool set = true)
|
||||||
{
|
{
|
||||||
|
|
@ -1191,6 +1209,15 @@ class Player : public Unit
|
||||||
}
|
}
|
||||||
void SetRestBonus(float rest_bonus_new);
|
void SetRestBonus(float rest_bonus_new);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief: compute rest bonus
|
||||||
|
* \param: time_t timePassed > time from last check
|
||||||
|
* \param: bool offline > is the player was offline?
|
||||||
|
* \param: bool inRestPlace > if it was offline, is the player was in city/tavern/inn?
|
||||||
|
* \returns: float
|
||||||
|
**/
|
||||||
|
float ComputeRest(time_t timePassed, bool offline = false, bool inRestPlace = false);
|
||||||
|
|
||||||
RestType GetRestType() const
|
RestType GetRestType() const
|
||||||
{
|
{
|
||||||
return rest_type;
|
return rest_type;
|
||||||
|
|
@ -1539,6 +1566,9 @@ class Player : public Unit
|
||||||
void AddTimedQuest(uint32 quest_id) { m_timedquests.insert(quest_id); }
|
void AddTimedQuest(uint32 quest_id) { m_timedquests.insert(quest_id); }
|
||||||
void RemoveTimedQuest(uint32 quest_id) { m_timedquests.erase(quest_id); }
|
void RemoveTimedQuest(uint32 quest_id) { m_timedquests.erase(quest_id); }
|
||||||
|
|
||||||
|
//! Return collision height sent to client
|
||||||
|
float GetCollisionHeight(bool mounted) const;
|
||||||
|
|
||||||
/*********************************************************/
|
/*********************************************************/
|
||||||
/*** LOAD SYSTEM ***/
|
/*** LOAD SYSTEM ***/
|
||||||
/*********************************************************/
|
/*********************************************************/
|
||||||
|
|
@ -2058,6 +2088,10 @@ class Player : public Unit
|
||||||
StopMirrorTimer(FIRE_TIMER);
|
StopMirrorTimer(FIRE_TIMER);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SetLevitate(bool enable) override;
|
||||||
|
void SetCanFly(bool enable) override;
|
||||||
|
void SetFeatherFall(bool enable) override;
|
||||||
|
void SetHover(bool enable) override;
|
||||||
void SetRoot(bool enable) override;
|
void SetRoot(bool enable) override;
|
||||||
void SetWaterWalk(bool enable) override;
|
void SetWaterWalk(bool enable) override;
|
||||||
|
|
||||||
|
|
@ -2371,6 +2405,7 @@ class Player : public Unit
|
||||||
bool isMoving() const { return m_movementInfo.HasMovementFlag(movementFlagsMask); }
|
bool isMoving() const { return m_movementInfo.HasMovementFlag(movementFlagsMask); }
|
||||||
bool isMovingOrTurning() const { return m_movementInfo.HasMovementFlag(movementOrTurningFlagsMask); }
|
bool isMovingOrTurning() const { return m_movementInfo.HasMovementFlag(movementOrTurningFlagsMask); }
|
||||||
|
|
||||||
|
bool CanSwim() const { return true; }
|
||||||
bool CanFly() const { return m_movementInfo.HasMovementFlag(MOVEFLAG_CAN_FLY); }
|
bool CanFly() const { return m_movementInfo.HasMovementFlag(MOVEFLAG_CAN_FLY); }
|
||||||
bool IsFlying() const { return m_movementInfo.HasMovementFlag(MOVEFLAG_FLYING); }
|
bool IsFlying() const { return m_movementInfo.HasMovementFlag(MOVEFLAG_FLYING); }
|
||||||
bool IsFreeFlying() const { return HasAuraType(SPELL_AURA_MOD_FLIGHT_SPEED_MOUNTED) || HasAuraType(SPELL_AURA_FLY); }
|
bool IsFreeFlying() const { return HasAuraType(SPELL_AURA_MOD_FLIGHT_SPEED_MOUNTED) || HasAuraType(SPELL_AURA_FLY); }
|
||||||
|
|
@ -2498,7 +2533,8 @@ class Player : public Unit
|
||||||
|
|
||||||
GridReference<Player>& GetGridRef() { return m_gridRef; }
|
GridReference<Player>& GetGridRef() { return m_gridRef; }
|
||||||
MapReference& GetMapRef() { return m_mapRef; }
|
MapReference& GetMapRef() { return m_mapRef; }
|
||||||
|
|
||||||
|
bool IsTappedByMeOrMyGroup(Creature* creature);
|
||||||
bool isAllowedToLoot(Creature* creature);
|
bool isAllowedToLoot(Creature* creature);
|
||||||
|
|
||||||
DeclinedName const* GetDeclinedNames() const { return m_declinedname; }
|
DeclinedName const* GetDeclinedNames() const { return m_declinedname; }
|
||||||
|
|
@ -2508,10 +2544,22 @@ class Player : public Unit
|
||||||
RuneType GetBaseRune(uint8 index) const { return RuneType(m_runes->runes[index].BaseRune); }
|
RuneType GetBaseRune(uint8 index) const { return RuneType(m_runes->runes[index].BaseRune); }
|
||||||
RuneType GetCurrentRune(uint8 index) const { return RuneType(m_runes->runes[index].CurrentRune); }
|
RuneType GetCurrentRune(uint8 index) const { return RuneType(m_runes->runes[index].CurrentRune); }
|
||||||
uint16 GetRuneCooldown(uint8 index) const { return m_runes->runes[index].Cooldown; }
|
uint16 GetRuneCooldown(uint8 index) const { return m_runes->runes[index].Cooldown; }
|
||||||
|
uint16 GetBaseRuneCooldown(uint8 index) const { return m_runes->runes[index].BaseCooldown; }
|
||||||
|
uint8 GetRuneCooldownFraction(uint8 index) const;
|
||||||
|
void UpdateRuneRegen(RuneType rune);
|
||||||
|
void UpdateRuneRegen();
|
||||||
bool IsBaseRuneSlotsOnCooldown(RuneType runeType) const;
|
bool IsBaseRuneSlotsOnCooldown(RuneType runeType) const;
|
||||||
|
void ClearLastUsedRuneMask() { m_runes->lastUsedRuneMask = 0; }
|
||||||
|
bool IsLastUsedRune(uint8 index) const { return (m_runes->lastUsedRuneMask & (1 << index)) != 0; }
|
||||||
|
void SetLastUsedRune(RuneType type) { m_runes->lastUsedRuneMask |= 1 << uint32(type); }
|
||||||
void SetBaseRune(uint8 index, RuneType baseRune) { m_runes->runes[index].BaseRune = baseRune; }
|
void SetBaseRune(uint8 index, RuneType baseRune) { m_runes->runes[index].BaseRune = baseRune; }
|
||||||
void SetCurrentRune(uint8 index, RuneType currentRune) { m_runes->runes[index].CurrentRune = currentRune; }
|
void SetCurrentRune(uint8 index, RuneType currentRune) { m_runes->runes[index].CurrentRune = currentRune; }
|
||||||
void SetRuneCooldown(uint8 index, uint16 cooldown) { m_runes->runes[index].Cooldown = cooldown; m_runes->SetRuneState(index, (cooldown == 0) ? true : false); }
|
void SetRuneCooldown(uint8 index, uint16 cooldown) { m_runes->runes[index].Cooldown = cooldown; m_runes->SetRuneState(index, (cooldown == 0) ? true : false); }
|
||||||
|
void SetBaseRuneCooldown(uint8 index, uint16 cooldown) { m_runes->runes[index].BaseCooldown = cooldown; }
|
||||||
|
void SetRuneConvertAura(uint8 index, Aura const* aura) { m_runes->runes[index].ConvertAura = aura; }
|
||||||
|
void AddRuneByAuraEffect(uint8 index, RuneType newType, Aura const* aura);
|
||||||
|
void RemoveRunesByAuraEffect(Aura const* aura);
|
||||||
|
void RestoreBaseRune(uint8 index);
|
||||||
void ConvertRune(uint8 index, RuneType newType);
|
void ConvertRune(uint8 index, RuneType newType);
|
||||||
bool ActivateRunes(RuneType type, uint32 count);
|
bool ActivateRunes(RuneType type, uint32 count);
|
||||||
void ResyncRunes();
|
void ResyncRunes();
|
||||||
|
|
|
||||||
|
|
@ -811,6 +811,7 @@ bool IsPositiveEffect(SpellEntry const* spellproto, SpellEffectIndex effIndex)
|
||||||
case 13139: // net-o-matic special effect
|
case 13139: // net-o-matic special effect
|
||||||
case 23445: // evil twin
|
case 23445: // evil twin
|
||||||
case 35679: // Protectorate Demolitionist
|
case 35679: // Protectorate Demolitionist
|
||||||
|
case 37695: // Stanky
|
||||||
case 38637: // Nether Exhaustion (red)
|
case 38637: // Nether Exhaustion (red)
|
||||||
case 38638: // Nether Exhaustion (green)
|
case 38638: // Nether Exhaustion (green)
|
||||||
case 38639: // Nether Exhaustion (blue)
|
case 38639: // Nether Exhaustion (blue)
|
||||||
|
|
@ -843,6 +844,7 @@ bool IsPositiveEffect(SpellEntry const* spellproto, SpellEffectIndex effIndex)
|
||||||
return false;
|
return false;
|
||||||
break;
|
break;
|
||||||
case SPELL_AURA_MOD_DAMAGE_TAKEN: // dependent from bas point sign (positive -> negative)
|
case SPELL_AURA_MOD_DAMAGE_TAKEN: // dependent from bas point sign (positive -> negative)
|
||||||
|
case SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN:
|
||||||
if (spellEffect->CalculateSimpleValue() < 0)
|
if (spellEffect->CalculateSimpleValue() < 0)
|
||||||
return true;
|
return true;
|
||||||
// let check by target modes (for Amplify Magic cases/etc)
|
// let check by target modes (for Amplify Magic cases/etc)
|
||||||
|
|
@ -1406,8 +1408,8 @@ struct DoSpellProcEvent
|
||||||
else
|
else
|
||||||
++count;
|
++count;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool HasEntry(uint32 spellId) { return spe_map.count(spellId) > 0; }
|
bool HasEntry(uint32 spellId) { return spe_map.find(spellId) != spe_map.end(); }
|
||||||
bool SetStateToEntry(uint32 spellId) { return (state = spe_map.find(spellId)) != spe_map.end(); }
|
bool SetStateToEntry(uint32 spellId) { return (state = spe_map.find(spellId)) != spe_map.end(); }
|
||||||
SpellProcEventMap& spe_map;
|
SpellProcEventMap& spe_map;
|
||||||
SpellProcEventMap::const_iterator state;
|
SpellProcEventMap::const_iterator state;
|
||||||
|
|
@ -1694,7 +1696,7 @@ void SpellMgr::LoadSpellBonuses()
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
direct_calc = CalculateDefaultCoefficient(spell, SPELL_DIRECT_DAMAGE) * (isHeal ? 1.88f : 1.0f);
|
direct_calc = CalculateDefaultCoefficient(spell, SPELL_DIRECT_DAMAGE) * (isHeal ? SCALE_SPELLPOWER_HEALING : 1.0f);
|
||||||
direct_diff = std::abs(sbe.direct_damage - direct_calc);
|
direct_diff = std::abs(sbe.direct_damage - direct_calc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1716,7 +1718,7 @@ void SpellMgr::LoadSpellBonuses()
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
dot_calc = CalculateDefaultCoefficient(spell, DOT) * (isHeal ? 1.88f : 1.0f);
|
dot_calc = CalculateDefaultCoefficient(spell, DOT) * (isHeal ? SCALE_SPELLPOWER_HEALING : 1.0f);
|
||||||
dot_diff = std::abs(sbe.dot_damage - dot_calc);
|
dot_diff = std::abs(sbe.dot_damage - dot_calc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2874,7 +2876,7 @@ SpellEntry const* SpellMgr::SelectAuraRankForLevel(SpellEntry const* spellInfo,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// if found appropriate level
|
// if found appropriate level
|
||||||
if (level + 10 >= spellInfo->GetSpellLevel())
|
if (level + 10 >= nextSpellInfo->GetSpellLevel())
|
||||||
return nextSpellInfo;
|
return nextSpellInfo;
|
||||||
|
|
||||||
// one rank less then
|
// one rank less then
|
||||||
|
|
@ -3562,7 +3564,7 @@ void SpellMgr::LoadSpellScriptTarget()
|
||||||
{
|
{
|
||||||
if (itr->spellId == 30427 && !cInfo->SkinningLootId)
|
if (itr->spellId == 30427 && !cInfo->SkinningLootId)
|
||||||
{
|
{
|
||||||
sLog.outErrorDb("Table `spell_script_target` has creature %u as a target of spellid 30427, but this creature has no skinLootid. Gas extraction will not work!", cInfo->Entry);
|
sLog.outErrorDb("Table `spell_script_target` has creature %u as a target of spellid 30427, but this creature has no SkinningLootId. Gas extraction will not work!", cInfo->Entry);
|
||||||
sSpellScriptTargetStorage.EraseEntry(itr->spellId);
|
sSpellScriptTargetStorage.EraseEntry(itr->spellId);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -976,8 +976,8 @@ uint32 Unit::DealDamage(Unit* pVictim, uint32 damage, CleanDamage const* cleanDa
|
||||||
{
|
{
|
||||||
SpellEntry const* shareSpell = (*itr)->GetSpellProto();
|
SpellEntry const* shareSpell = (*itr)->GetSpellProto();
|
||||||
uint32 shareDamage = uint32(damage*(*itr)->GetModifier()->m_amount / 100.0f);
|
uint32 shareDamage = uint32(damage*(*itr)->GetModifier()->m_amount / 100.0f);
|
||||||
DealDamageMods(shareTarget, shareDamage, NULL);
|
DealDamageMods(shareTarget, shareDamage, nullptr);
|
||||||
DealDamage(shareTarget, shareDamage, 0, damagetype, GetSpellSchoolMask(shareSpell), shareSpell, false);
|
DealDamage(shareTarget, shareDamage, nullptr, damagetype, GetSpellSchoolMask(shareSpell), shareSpell, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1681,9 +1681,11 @@ void Unit::CalculateSpellDamage(SpellNonMeleeDamage* damageInfo, int32 damage, S
|
||||||
{ return; }
|
{ return; }
|
||||||
|
|
||||||
if (!this || !pVictim)
|
if (!this || !pVictim)
|
||||||
{ return; }
|
return;
|
||||||
if (!this->IsAlive() || !pVictim->IsAlive())
|
|
||||||
{ return; }
|
// units which are not alive cannot deal damage except for dying creatures
|
||||||
|
if ((!this->IsAlive() || !pVictim->IsAlive()) && (this->GetTypeId() != TYPEID_UNIT || this->getDeathState() != DEAD))
|
||||||
|
return;
|
||||||
|
|
||||||
// Check spell crit chance
|
// Check spell crit chance
|
||||||
bool crit = IsSpellCrit(pVictim, spellInfo, damageSchoolMask, attackType);
|
bool crit = IsSpellCrit(pVictim, spellInfo, damageSchoolMask, attackType);
|
||||||
|
|
@ -3521,7 +3523,7 @@ SpellMissInfo Unit::SpellHitResult(Unit* pVictim, SpellEntry const* spell, bool
|
||||||
return SPELL_MISS_EVADE;
|
return SPELL_MISS_EVADE;
|
||||||
|
|
||||||
// Check for immune
|
// Check for immune
|
||||||
if (pVictim->IsImmuneToSpell(spell, this == pVictim))
|
if (pVictim->IsImmuneToSpell(spell, this == pVictim) && !spell->HasAttribute(SPELL_ATTR_UNAFFECTED_BY_INVULNERABILITY))
|
||||||
return SPELL_MISS_IMMUNE;
|
return SPELL_MISS_IMMUNE;
|
||||||
|
|
||||||
// All positive spells can`t miss
|
// All positive spells can`t miss
|
||||||
|
|
@ -3530,7 +3532,7 @@ SpellMissInfo Unit::SpellHitResult(Unit* pVictim, SpellEntry const* spell, bool
|
||||||
return SPELL_MISS_NONE;
|
return SPELL_MISS_NONE;
|
||||||
|
|
||||||
// Check for immune
|
// Check for immune
|
||||||
if (pVictim->IsImmunedToDamage(GetSpellSchoolMask(spell)))
|
if (pVictim->IsImmunedToDamage(GetSpellSchoolMask(spell)) && !spell->HasAttribute(SPELL_ATTR_UNAFFECTED_BY_INVULNERABILITY))
|
||||||
return SPELL_MISS_IMMUNE;
|
return SPELL_MISS_IMMUNE;
|
||||||
|
|
||||||
// Try victim reflect spell
|
// Try victim reflect spell
|
||||||
|
|
@ -4027,7 +4029,7 @@ void Unit::SetFacingToObject(WorldObject* pObject)
|
||||||
SetFacingTo(GetAngle(pObject));
|
SetFacingTo(GetAngle(pObject));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Unit::isInAccessablePlaceFor(Creature const* c) const
|
bool Unit::IsInAccessablePlaceFor(Creature const* c) const
|
||||||
{
|
{
|
||||||
if (IsInWater())
|
if (IsInWater())
|
||||||
return c->CanSwim();
|
return c->CanSwim();
|
||||||
|
|
@ -5875,7 +5877,7 @@ bool Unit::IsHostileTo(Unit const* unit) const
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Sanctuary
|
// Sanctuary
|
||||||
if (pTarget->HasByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_SANCTUARY) && pTester->HasByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_SANCTUARY))
|
if (pTarget->HasByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_SUPPORTABLE) && pTester->HasByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_SUPPORTABLE))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// PvP FFA state
|
// PvP FFA state
|
||||||
|
|
@ -5987,7 +5989,7 @@ bool Unit::IsFriendlyTo(Unit const* unit) const
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
// Sanctuary
|
// Sanctuary
|
||||||
if (pTarget->HasByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_SANCTUARY) && pTester->HasByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_SANCTUARY))
|
if (pTarget->HasByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_SUPPORTABLE) && pTester->HasByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_SUPPORTABLE))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
// PvP FFA state
|
// PvP FFA state
|
||||||
|
|
@ -6661,6 +6663,17 @@ void Unit::EnergizeBySpell(Unit* pVictim, uint32 SpellID, uint32 Damage, Powers
|
||||||
pVictim->ModifyPower(powertype, Damage);
|
pVictim->ModifyPower(powertype, Damage);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Calculate spell coefficents and level penalties for spell/melee damage or heal
|
||||||
|
*
|
||||||
|
* this is the caster of the spell/ melee attacker
|
||||||
|
* @param spellProto SpellEntry of the used spell
|
||||||
|
* @param total current value onto which the Bonus and level penalty will be calculated
|
||||||
|
* @param benefit additional benefit from ie spellpower-auras
|
||||||
|
* @param ap_benefit additional melee attackpower benefit from auras
|
||||||
|
* @param damagetype what kind of damage
|
||||||
|
* @param donePart calculate for done or taken
|
||||||
|
* @param defCoeffMod default coefficient for additional scaling (i.e. normal player healing SCALE_SPELLPOWER_HEALING)
|
||||||
|
*/
|
||||||
int32 Unit::SpellBonusWithCoeffs(SpellEntry const* spellProto, int32 total, int32 benefit, int32 ap_benefit, DamageEffectType damagetype, bool donePart, float defCoeffMod)
|
int32 Unit::SpellBonusWithCoeffs(SpellEntry const* spellProto, int32 total, int32 benefit, int32 ap_benefit, DamageEffectType damagetype, bool donePart, float defCoeffMod)
|
||||||
{
|
{
|
||||||
// Distribute Damage over multiple effects, reduce by AoE
|
// Distribute Damage over multiple effects, reduce by AoE
|
||||||
|
|
@ -7119,7 +7132,7 @@ uint32 Unit::SpellDamageBonusTaken(Unit* pCaster, SpellEntry const* spellProto,
|
||||||
int32 TakenAdvertisedBenefit = SpellBaseDamageBonusTaken(GetSpellSchoolMask(spellProto));
|
int32 TakenAdvertisedBenefit = SpellBaseDamageBonusTaken(GetSpellSchoolMask(spellProto));
|
||||||
|
|
||||||
// apply benefit affected by spell power implicit coeffs and spell level penalties
|
// apply benefit affected by spell power implicit coeffs and spell level penalties
|
||||||
TakenTotal = SpellBonusWithCoeffs(spellProto, TakenTotal, TakenAdvertisedBenefit, 0, damagetype, false);
|
TakenTotal = pCaster->SpellBonusWithCoeffs(spellProto, TakenTotal, TakenAdvertisedBenefit, 0, damagetype, false);
|
||||||
|
|
||||||
float tmpDamage = (int32(pdamage) + TakenTotal * int32(stack)) * TakenTotalMod;
|
float tmpDamage = (int32(pdamage) + TakenTotal * int32(stack)) * TakenTotalMod;
|
||||||
|
|
||||||
|
|
@ -7568,7 +7581,7 @@ uint32 Unit::SpellHealingBonusDone(Unit* pVictim, SpellEntry const* spellProto,
|
||||||
int32 DoneAdvertisedBenefit = SpellBaseHealingBonusDone(GetSpellSchoolMask(spellProto));
|
int32 DoneAdvertisedBenefit = SpellBaseHealingBonusDone(GetSpellSchoolMask(spellProto));
|
||||||
|
|
||||||
// apply ap bonus and benefit affected by spell power implicit coeffs and spell level penalties
|
// apply ap bonus and benefit affected by spell power implicit coeffs and spell level penalties
|
||||||
DoneTotal = SpellBonusWithCoeffs(spellProto, DoneTotal, DoneAdvertisedBenefit, 0, damagetype, true, 1.88f);
|
DoneTotal = SpellBonusWithCoeffs(spellProto, DoneTotal, DoneAdvertisedBenefit, 0, damagetype, true, SCALE_SPELLPOWER_HEALING);
|
||||||
|
|
||||||
// use float as more appropriate for negative values and percent applying
|
// use float as more appropriate for negative values and percent applying
|
||||||
float heal = (healamount + DoneTotal * int32(stack)) * DoneTotalMod;
|
float heal = (healamount + DoneTotal * int32(stack)) * DoneTotalMod;
|
||||||
|
|
@ -7612,7 +7625,7 @@ uint32 Unit::SpellHealingBonusTaken(Unit* pCaster, SpellEntry const* spellProto,
|
||||||
int32 TakenAdvertisedBenefit = SpellBaseHealingBonusTaken(GetSpellSchoolMask(spellProto));
|
int32 TakenAdvertisedBenefit = SpellBaseHealingBonusTaken(GetSpellSchoolMask(spellProto));
|
||||||
|
|
||||||
// apply benefit affected by spell power implicit coeffs and spell level penalties
|
// apply benefit affected by spell power implicit coeffs and spell level penalties
|
||||||
TakenTotal = SpellBonusWithCoeffs(spellProto, TakenTotal, TakenAdvertisedBenefit, 0, damagetype, false, 1.88f);
|
TakenTotal = pCaster->SpellBonusWithCoeffs(spellProto, TakenTotal, TakenAdvertisedBenefit, 0, damagetype, false, SCALE_SPELLPOWER_HEALING);
|
||||||
|
|
||||||
AuraList const& mHealingGet = GetAurasByType(SPELL_AURA_MOD_HEALING_RECEIVED);
|
AuraList const& mHealingGet = GetAurasByType(SPELL_AURA_MOD_HEALING_RECEIVED);
|
||||||
for (AuraList::const_iterator i = mHealingGet.begin(); i != mHealingGet.end(); ++i)
|
for (AuraList::const_iterator i = mHealingGet.begin(); i != mHealingGet.end(); ++i)
|
||||||
|
|
@ -8155,7 +8168,7 @@ uint32 Unit::MeleeDamageBonusTaken(Unit* pCaster, uint32 pdamage, WeaponAttackTy
|
||||||
if (!isWeaponDamageBasedSpell)
|
if (!isWeaponDamageBasedSpell)
|
||||||
{
|
{
|
||||||
// apply benefit affected by spell power implicit coeffs and spell level penalties
|
// apply benefit affected by spell power implicit coeffs and spell level penalties
|
||||||
TakenFlat = SpellBonusWithCoeffs(spellProto, 0, TakenFlat, 0, damagetype, false);
|
TakenFlat = pCaster->SpellBonusWithCoeffs(spellProto, 0, TakenFlat, 0, damagetype, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
float tmpDamage = float(int32(pdamage) + TakenFlat * int32(stack)) * TakenPercent;
|
float tmpDamage = float(int32(pdamage) + TakenFlat * int32(stack)) * TakenPercent;
|
||||||
|
|
@ -8257,6 +8270,10 @@ void Unit::Mount(uint32 mount, uint32 spellId)
|
||||||
pet->ApplyModeFlags(PET_MODE_DISABLE_ACTIONS, true);
|
pet->ApplyModeFlags(PET_MODE_DISABLE_ACTIONS, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float height = ((Player*)this)->GetCollisionHeight(true);
|
||||||
|
if (height)
|
||||||
|
SendCollisionHeightUpdate(height);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -8284,9 +8301,17 @@ void Unit::Unmount(bool from_aura)
|
||||||
if (GetTypeId() == TYPEID_PLAYER)
|
if (GetTypeId() == TYPEID_PLAYER)
|
||||||
{
|
{
|
||||||
if (Pet* pet = GetPet())
|
if (Pet* pet = GetPet())
|
||||||
pet->ApplyModeFlags(PET_MODE_DISABLE_ACTIONS, false);
|
{
|
||||||
|
// Get reaction state and display appropriately
|
||||||
|
if (CharmInfo* charmInfo = pet->GetCharmInfo())
|
||||||
|
pet->SetModeFlags(PetModeFlags(charmInfo->GetReactState() | charmInfo->GetCommandState() * 0x100));
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{ ((Player*)this)->ResummonPetTemporaryUnSummonedIfAny(); }
|
((Player*)this)->ResummonPetTemporaryUnSummonedIfAny();
|
||||||
|
|
||||||
|
float height = ((Player*)this)->GetCollisionHeight(false);
|
||||||
|
if (height)
|
||||||
|
SendCollisionHeightUpdate(height);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -8687,8 +8712,23 @@ bool Unit::IsVisibleForOrDetect(Unit const* u, WorldObject const* viewPoint, boo
|
||||||
if (m_Visibility == VISIBILITY_OFF)
|
if (m_Visibility == VISIBILITY_OFF)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
// grouped players should always see stealthed party members
|
||||||
|
if (GetTypeId() == TYPEID_PLAYER && u->GetTypeId() == TYPEID_PLAYER)
|
||||||
|
if (((Player*)this)->IsGroupVisibleFor(((Player*)u)) && u->IsFriendlyTo(this))
|
||||||
|
return true;
|
||||||
|
|
||||||
// raw invisibility
|
// raw invisibility
|
||||||
bool invisible = (m_invisibilityMask != 0 || u->m_invisibilityMask != 0);
|
bool invisible = (m_invisibilityMask != 0 || u->m_invisibilityMask != 0);
|
||||||
|
if (u->GetTypeId() == TYPEID_PLAYER) // if object is player with mover, use its visibility masks, so that an invisible player MCing a creature can see stuff
|
||||||
|
{
|
||||||
|
if (Player* player = (Player*)u)
|
||||||
|
{
|
||||||
|
if (Unit* mover=player->GetMover())
|
||||||
|
{
|
||||||
|
invisible= (m_invisibilityMask != 0 || mover->m_invisibilityMask != 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// detectable invisibility case
|
// detectable invisibility case
|
||||||
if (invisible && (
|
if (invisible && (
|
||||||
|
|
@ -8705,35 +8745,18 @@ bool Unit::IsVisibleForOrDetect(Unit const* u, WorldObject const* viewPoint, boo
|
||||||
// special cases for always overwrite invisibility/stealth
|
// special cases for always overwrite invisibility/stealth
|
||||||
if (invisible || m_Visibility == VISIBILITY_GROUP_STEALTH)
|
if (invisible || m_Visibility == VISIBILITY_GROUP_STEALTH)
|
||||||
{
|
{
|
||||||
// non-hostile case
|
if (u->IsHostileTo(this))
|
||||||
if (!u->IsHostileTo(this))
|
|
||||||
{
|
|
||||||
// player see other player with stealth/invisibility only if he in same group or raid or same team (raid/team case dependent from conf setting)
|
|
||||||
if (GetTypeId() == TYPEID_PLAYER && u->GetTypeId() == TYPEID_PLAYER)
|
|
||||||
{
|
|
||||||
if (((Player*)this)->IsGroupVisibleFor(((Player*)u)))
|
|
||||||
return true;
|
|
||||||
|
|
||||||
// else apply same rules as for hostile case (detecting check for stealth)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// hostile case
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
// Hunter mark functionality
|
// Hunter mark functionality
|
||||||
AuraList const& auras = GetAurasByType(SPELL_AURA_MOD_STALKED);
|
AuraList const& auras = GetAurasByType(SPELL_AURA_MOD_STALKED);
|
||||||
for (AuraList::const_iterator iter = auras.begin(); iter != auras.end(); ++iter)
|
for (AuraList::const_iterator iter = auras.begin(); iter != auras.end(); ++iter)
|
||||||
if ((*iter)->GetCasterGuid() == u->GetObjectGuid())
|
if ((*iter)->GetCasterGuid() == u->GetObjectGuid())
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
// else apply detecting check for stealth
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// none other cases for detect invisibility, so invisible
|
// none other cases for detect invisibility, so invisible
|
||||||
if (invisible)
|
if (invisible)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// else apply stealth detecting check
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// unit got in stealth in this moment and must ignore old detected state
|
// unit got in stealth in this moment and must ignore old detected state
|
||||||
|
|
@ -9518,7 +9541,7 @@ bool Unit::SelectHostileTarget()
|
||||||
for (AuraList::const_reverse_iterator aura = tauntAuras.rbegin(); aura != tauntAuras.rend(); ++aura)
|
for (AuraList::const_reverse_iterator aura = tauntAuras.rbegin(); aura != tauntAuras.rend(); ++aura)
|
||||||
{
|
{
|
||||||
if ((caster = (*aura)->GetCaster()) && caster->IsInMap(this) &&
|
if ((caster = (*aura)->GetCaster()) && caster->IsInMap(this) &&
|
||||||
caster->IsTargetableForAttack() && caster->isInAccessablePlaceFor((Creature*)this) &&
|
caster->IsTargetableForAttack() && caster->IsInAccessablePlaceFor((Creature*)this) &&
|
||||||
!IsSecondChoiceTarget(caster, true))
|
!IsSecondChoiceTarget(caster, true))
|
||||||
{
|
{
|
||||||
target = caster;
|
target = caster;
|
||||||
|
|
@ -9581,7 +9604,7 @@ bool Unit::SelectHostileTarget()
|
||||||
{
|
{
|
||||||
for (AttackerSet::const_iterator itr = m_attackers.begin(); itr != m_attackers.end(); ++itr)
|
for (AttackerSet::const_iterator itr = m_attackers.begin(); itr != m_attackers.end(); ++itr)
|
||||||
{
|
{
|
||||||
if ((*itr)->IsInMap(this) && (*itr)->IsTargetableForAttack() && (*itr)->isInAccessablePlaceFor((Creature*)this))
|
if ((*itr)->IsInMap(this) && (*itr)->IsTargetableForAttack() && (*itr)->IsInAccessablePlaceFor((Creature*)this))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -12156,3 +12179,59 @@ void Unit::BuildMoveFeatherFallPacket(WorldPacket* data, bool apply, uint32 valu
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Unit::BuildMoveHoverPacket(WorldPacket* data, bool apply, uint32 value)
|
||||||
|
{
|
||||||
|
ObjectGuid guid = GetObjectGuid();
|
||||||
|
|
||||||
|
if (apply)
|
||||||
|
{
|
||||||
|
data->Initialize(SMSG_MOVE_SET_HOVER, 8 + 4 + 1);
|
||||||
|
data->WriteGuidMask<1, 4, 2, 3, 0, 5, 6, 7>(guid);
|
||||||
|
data->WriteGuidBytes<5, 4, 1, 2, 3, 6, 0, 7>(guid);
|
||||||
|
*data << uint32(0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
data->Initialize(SMSG_MOVE_UNSET_HOVER, 8 + 4 + 1);
|
||||||
|
data->WriteGuidMask<4, 6, 3, 1, 2, 7, 5, 0>(guid);
|
||||||
|
data->WriteGuidBytes<4, 5, 3, 6, 7, 1, 2, 0>(guid);
|
||||||
|
*data << uint32(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Unit::BuildMoveLevitatePacket(WorldPacket* data, bool apply, uint32 value)
|
||||||
|
{
|
||||||
|
ObjectGuid guid = GetObjectGuid();
|
||||||
|
|
||||||
|
if (apply)
|
||||||
|
{
|
||||||
|
data->Initialize(SMSG_MOVE_GRAVITY_ENABLE);
|
||||||
|
data->WriteGuidMask<1, 4, 7, 5, 2, 0, 3, 6>(GetObjectGuid());
|
||||||
|
data->WriteGuidBytes<3>(GetObjectGuid());
|
||||||
|
*data << uint32(value);
|
||||||
|
data->WriteGuidBytes<7, 6, 4, 0, 1, 5, 2>(GetObjectGuid());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
data->Initialize(SMSG_MOVE_GRAVITY_DISABLE);
|
||||||
|
data->WriteGuidMask<0, 1, 5, 7, 6, 4, 3, 2>(GetObjectGuid());
|
||||||
|
data->WriteGuidBytes<7, 2, 0>(GetObjectGuid());
|
||||||
|
*data << uint32(value);
|
||||||
|
data->WriteGuidBytes<5, 1, 3, 4, 6>(GetObjectGuid());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Unit::SendCollisionHeightUpdate(float height)
|
||||||
|
{
|
||||||
|
if (GetTypeId() == TYPEID_PLAYER)
|
||||||
|
{
|
||||||
|
WorldPacket data(SMSG_MOVE_SET_COLLISION_HGT, GetPackGUID().size() + 4 + 4);
|
||||||
|
data.WriteGuidMask<6, 1, 4, 7, 5, 2, 0, 3>(GetObjectGuid());
|
||||||
|
data.WriteGuidBytes<6, 0, 4, 3, 5>(GetObjectGuid());
|
||||||
|
data << uint32(sWorld.GetGameTime()); // Packet counter
|
||||||
|
data.WriteGuidBytes<1, 2, 7>(GetObjectGuid());
|
||||||
|
data << ((Player*)this)->GetCollisionHeight(true);
|
||||||
|
((Player*)this)->GetSession()->SendPacket(&data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -150,6 +150,8 @@ enum SpellFacingFlags
|
||||||
#define BASE_ATTACK_TIME 2000
|
#define BASE_ATTACK_TIME 2000
|
||||||
#define BASE_BLOCK_DAMAGE_PERCENT 30
|
#define BASE_BLOCK_DAMAGE_PERCENT 30
|
||||||
|
|
||||||
|
#define SCALE_SPELLPOWER_HEALING 1.88f
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* byte value (UNIT_FIELD_BYTES_1,0).
|
* byte value (UNIT_FIELD_BYTES_1,0).
|
||||||
*
|
*
|
||||||
|
|
@ -225,9 +227,9 @@ enum UnitPVPStateFlags
|
||||||
UNIT_BYTE2_FLAG_PVP = 0x01,
|
UNIT_BYTE2_FLAG_PVP = 0x01,
|
||||||
UNIT_BYTE2_FLAG_UNK1 = 0x02,
|
UNIT_BYTE2_FLAG_UNK1 = 0x02,
|
||||||
UNIT_BYTE2_FLAG_FFA_PVP = 0x04,
|
UNIT_BYTE2_FLAG_FFA_PVP = 0x04,
|
||||||
UNIT_BYTE2_FLAG_SANCTUARY = 0x08,
|
UNIT_BYTE2_FLAG_SUPPORTABLE = 0x08, // allows for being targeted for healing/bandaging by friendlies
|
||||||
UNIT_BYTE2_FLAG_UNK4 = 0x10,
|
UNIT_BYTE2_FLAG_AURAS = 0x10, // show possitive auras as positive, and allow its dispel
|
||||||
UNIT_BYTE2_FLAG_UNK5 = 0x20,
|
UNIT_BYTE2_FLAG_UNK5 = 0x20, // show negative auras as positive, *not* allowing dispel (at least for pets)
|
||||||
UNIT_BYTE2_FLAG_UNK6 = 0x40,
|
UNIT_BYTE2_FLAG_UNK6 = 0x40,
|
||||||
UNIT_BYTE2_FLAG_UNK7 = 0x80
|
UNIT_BYTE2_FLAG_UNK7 = 0x80
|
||||||
};
|
};
|
||||||
|
|
@ -596,7 +598,7 @@ enum UnitFlags
|
||||||
UNIT_FLAG_PVP = 0x00001000, // changed in 3.0.3
|
UNIT_FLAG_PVP = 0x00001000, // changed in 3.0.3
|
||||||
UNIT_FLAG_SILENCED = 0x00002000, // silenced, 2.1.1
|
UNIT_FLAG_SILENCED = 0x00002000, // silenced, 2.1.1
|
||||||
UNIT_FLAG_UNK_14 = 0x00004000, // 2.0.8
|
UNIT_FLAG_UNK_14 = 0x00004000, // 2.0.8
|
||||||
UNIT_FLAG_UNK_15 = 0x00008000,
|
UNIT_FLAG_UNK_15 = 0x00008000, // related to jerky movement in water?
|
||||||
UNIT_FLAG_UNK_16 = 0x00010000, // removes attackable icon
|
UNIT_FLAG_UNK_16 = 0x00010000, // removes attackable icon
|
||||||
UNIT_FLAG_PACIFIED = 0x00020000, // 3.0.3 ok
|
UNIT_FLAG_PACIFIED = 0x00020000, // 3.0.3 ok
|
||||||
UNIT_FLAG_STUNNED = 0x00040000, // 3.0.3 ok
|
UNIT_FLAG_STUNNED = 0x00040000, // 3.0.3 ok
|
||||||
|
|
@ -2399,7 +2401,7 @@ class Unit : public WorldObject
|
||||||
|
|
||||||
virtual bool IsInWater() const;
|
virtual bool IsInWater() const;
|
||||||
virtual bool IsUnderWater() const;
|
virtual bool IsUnderWater() const;
|
||||||
bool isInAccessablePlaceFor(Creature const* c) const;
|
bool IsInAccessablePlaceFor(Creature const* c) const;
|
||||||
|
|
||||||
void SendHealSpellLog(Unit* pVictim, uint32 SpellID, uint32 Damage, uint32 OverHeal, bool critical = false, uint32 absorb = 0);
|
void SendHealSpellLog(Unit* pVictim, uint32 SpellID, uint32 Damage, uint32 OverHeal, bool critical = false, uint32 absorb = 0);
|
||||||
void SendEnergizeSpellLog(Unit* pVictim, uint32 SpellID, uint32 Damage, Powers powertype);
|
void SendEnergizeSpellLog(Unit* pVictim, uint32 SpellID, uint32 Damage, Powers powertype);
|
||||||
|
|
@ -2656,6 +2658,12 @@ class Unit : public WorldObject
|
||||||
bool IsLevitating() const { return m_movementInfo.HasMovementFlag(MOVEFLAG_LEVITATING); }
|
bool IsLevitating() const { return m_movementInfo.HasMovementFlag(MOVEFLAG_LEVITATING); }
|
||||||
bool IsWalking() const { return m_movementInfo.HasMovementFlag(MOVEFLAG_WALK_MODE); }
|
bool IsWalking() const { return m_movementInfo.HasMovementFlag(MOVEFLAG_WALK_MODE); }
|
||||||
bool IsRooted() const { return m_movementInfo.HasMovementFlag(MOVEFLAG_ROOT); }
|
bool IsRooted() const { return m_movementInfo.HasMovementFlag(MOVEFLAG_ROOT); }
|
||||||
|
|
||||||
|
virtual void SetLevitate(bool /*enabled*/) {}
|
||||||
|
virtual void SetSwim(bool /*enabled*/) {}
|
||||||
|
virtual void SetCanFly(bool /*enabled*/) {}
|
||||||
|
virtual void SetFeatherFall(bool /*enabled*/) {}
|
||||||
|
virtual void SetHover(bool /*enabled*/) {}
|
||||||
virtual void SetRoot(bool /*enabled*/) {}
|
virtual void SetRoot(bool /*enabled*/) {}
|
||||||
/**
|
/**
|
||||||
* Changes this \ref Unit s ability to walk on water.
|
* Changes this \ref Unit s ability to walk on water.
|
||||||
|
|
@ -3327,6 +3335,7 @@ class Unit : public WorldObject
|
||||||
|
|
||||||
// at any changes to Scale and/or displayId
|
// at any changes to Scale and/or displayId
|
||||||
void UpdateModelData();
|
void UpdateModelData();
|
||||||
|
void SendCollisionHeightUpdate(float height);
|
||||||
|
|
||||||
DynamicObject* GetDynObject(uint32 spellId, SpellEffectIndex effIndex);
|
DynamicObject* GetDynObject(uint32 spellId, SpellEffectIndex effIndex);
|
||||||
DynamicObject* GetDynObject(uint32 spellId);
|
DynamicObject* GetDynObject(uint32 spellId);
|
||||||
|
|
@ -3485,6 +3494,9 @@ class Unit : public WorldObject
|
||||||
|
|
||||||
bool IsLinkingEventTrigger() const { return m_isCreatureLinkingTrigger; }
|
bool IsLinkingEventTrigger() const { return m_isCreatureLinkingTrigger; }
|
||||||
|
|
||||||
|
virtual bool CanSwim() const = 0;
|
||||||
|
virtual bool CanFly() const = 0;
|
||||||
|
|
||||||
bool IsSplineEnabled() const;
|
bool IsSplineEnabled() const;
|
||||||
|
|
||||||
bool IsInWorgenForm(bool inPermanent = false) const;
|
bool IsInWorgenForm(bool inPermanent = false) const;
|
||||||
|
|
@ -3496,6 +3508,8 @@ class Unit : public WorldObject
|
||||||
void BuildSendPlayVisualPacket(WorldPacket* data, uint32 value, bool impact);
|
void BuildSendPlayVisualPacket(WorldPacket* data, uint32 value, bool impact);
|
||||||
void BuildMoveSetCanFlyPacket(WorldPacket* data, bool apply, uint32 value);
|
void BuildMoveSetCanFlyPacket(WorldPacket* data, bool apply, uint32 value);
|
||||||
void BuildMoveFeatherFallPacket(WorldPacket* data, bool apply, uint32 value);
|
void BuildMoveFeatherFallPacket(WorldPacket* data, bool apply, uint32 value);
|
||||||
|
void BuildMoveHoverPacket(WorldPacket* data, bool apply, uint32 value);
|
||||||
|
void BuildMoveLevitatePacket(WorldPacket* data, bool apply, uint32 value);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
explicit Unit();
|
explicit Unit();
|
||||||
|
|
|
||||||
|
|
@ -148,7 +148,7 @@ void HostileReference::updateOnlineStatus()
|
||||||
!getTarget()->IsTaxiFlying()))
|
!getTarget()->IsTaxiFlying()))
|
||||||
{
|
{
|
||||||
Creature* creature = (Creature*) getSourceUnit();
|
Creature* creature = (Creature*) getSourceUnit();
|
||||||
online = getTarget()->isInAccessablePlaceFor(creature);
|
online = getTarget()->IsInAccessablePlaceFor(creature);
|
||||||
if (!online)
|
if (!online)
|
||||||
{
|
{
|
||||||
if (creature->AI()->canReachByRangeAttack(getTarget()))
|
if (creature->AI()->canReachByRangeAttack(getTarget()))
|
||||||
|
|
|
||||||
|
|
@ -86,7 +86,8 @@ DBCStorage <CinematicSequencesEntry> sCinematicSequencesStore(CinematicSequences
|
||||||
DBCStorage <CreatureDisplayInfoEntry> sCreatureDisplayInfoStore(CreatureDisplayInfofmt);
|
DBCStorage <CreatureDisplayInfoEntry> sCreatureDisplayInfoStore(CreatureDisplayInfofmt);
|
||||||
DBCStorage <CreatureDisplayInfoExtraEntry> sCreatureDisplayInfoExtraStore(CreatureDisplayInfoExtrafmt);
|
DBCStorage <CreatureDisplayInfoExtraEntry> sCreatureDisplayInfoExtraStore(CreatureDisplayInfoExtrafmt);
|
||||||
DBCStorage <CreatureFamilyEntry> sCreatureFamilyStore(CreatureFamilyfmt);
|
DBCStorage <CreatureFamilyEntry> sCreatureFamilyStore(CreatureFamilyfmt);
|
||||||
DBCStorage <CreatureSpellDataEntry> sCreatureSpellDataStore(CreatureSpellDatafmt);
|
DBCStorage <CreatureModelDataEntry> sCreatureModelDataStore(CreatureModelDatafmt);
|
||||||
|
DBCStorage <CreatureSpellDataEntry> sCreatureSpellDataStore(CreatureSpellDatafmt); // sCreatureModelDataStore
|
||||||
DBCStorage <CreatureTypeEntry> sCreatureTypeStore(CreatureTypefmt);
|
DBCStorage <CreatureTypeEntry> sCreatureTypeStore(CreatureTypefmt);
|
||||||
DBCStorage <CurrencyTypesEntry> sCurrencyTypesStore(CurrencyTypesfmt);
|
DBCStorage <CurrencyTypesEntry> sCurrencyTypesStore(CurrencyTypesfmt);
|
||||||
|
|
||||||
|
|
@ -511,21 +512,22 @@ void LoadDBCStores(const std::string& dataPath)
|
||||||
sChrClassXPowerTypesStore[entry->classId][entry->power] = index;
|
sChrClassXPowerTypesStore[entry->classId][entry->power] = index;
|
||||||
sChrClassXPowerIndexStore[entry->classId][index] = entry->power;
|
sChrClassXPowerIndexStore[entry->classId][index] = entry->power;
|
||||||
}
|
}
|
||||||
LoadDBC(availableDbcLocales, bar, bad_dbc_files, sChrRacesStore, dbcPath, "ChrRaces.dbc");
|
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sChrRacesStore, dbcPath,"ChrRaces.dbc");
|
||||||
LoadDBC(availableDbcLocales, bar, bad_dbc_files, sCinematicSequencesStore, dbcPath, "CinematicSequences.dbc");
|
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sCinematicSequencesStore, dbcPath,"CinematicSequences.dbc");
|
||||||
LoadDBC(availableDbcLocales, bar, bad_dbc_files, sCreatureDisplayInfoStore, dbcPath, "CreatureDisplayInfo.dbc");
|
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sCreatureDisplayInfoStore, dbcPath,"CreatureDisplayInfo.dbc");
|
||||||
LoadDBC(availableDbcLocales, bar, bad_dbc_files, sCreatureDisplayInfoExtraStore, dbcPath, "CreatureDisplayInfoExtra.dbc");
|
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sCreatureDisplayInfoExtraStore,dbcPath,"CreatureDisplayInfoExtra.dbc");
|
||||||
LoadDBC(availableDbcLocales, bar, bad_dbc_files, sCreatureFamilyStore, dbcPath, "CreatureFamily.dbc");
|
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sCreatureFamilyStore, dbcPath,"CreatureFamily.dbc");
|
||||||
LoadDBC(availableDbcLocales, bar, bad_dbc_files, sCreatureSpellDataStore, dbcPath, "CreatureSpellData.dbc");
|
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sCreatureModelDataStore, dbcPath,"CreatureModelData.dbc");
|
||||||
LoadDBC(availableDbcLocales, bar, bad_dbc_files, sCreatureTypeStore, dbcPath, "CreatureType.dbc");
|
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sCreatureSpellDataStore, dbcPath,"CreatureSpellData.dbc");
|
||||||
LoadDBC(availableDbcLocales, bar, bad_dbc_files, sCurrencyTypesStore, dbcPath, "CurrencyTypes.dbc");
|
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sCreatureTypeStore, dbcPath,"CreatureType.dbc");
|
||||||
LoadDBC(availableDbcLocales, bar, bad_dbc_files, sDestructibleModelDataStore, dbcPath, "DestructibleModelData.dbc");
|
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sCurrencyTypesStore, dbcPath,"CurrencyTypes.dbc");
|
||||||
LoadDBC(availableDbcLocales, bar, bad_dbc_files, sDungeonEncounterStore, dbcPath, "DungeonEncounter.dbc");
|
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sDestructibleModelDataStore,dbcPath,"DestructibleModelData.dbc");
|
||||||
LoadDBC(availableDbcLocales, bar, bad_dbc_files, sDurabilityCostsStore, dbcPath, "DurabilityCosts.dbc");
|
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sDungeonEncounterStore, dbcPath,"DungeonEncounter.dbc");
|
||||||
LoadDBC(availableDbcLocales, bar, bad_dbc_files, sDurabilityQualityStore, dbcPath, "DurabilityQuality.dbc");
|
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sDurabilityCostsStore, dbcPath,"DurabilityCosts.dbc");
|
||||||
LoadDBC(availableDbcLocales, bar, bad_dbc_files, sEmotesStore, dbcPath, "Emotes.dbc");
|
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sDurabilityQualityStore, dbcPath,"DurabilityQuality.dbc");
|
||||||
LoadDBC(availableDbcLocales, bar, bad_dbc_files, sEmotesTextStore, dbcPath, "EmotesText.dbc");
|
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sEmotesStore, dbcPath,"Emotes.dbc");
|
||||||
LoadDBC(availableDbcLocales, bar, bad_dbc_files, sFactionStore, dbcPath, "Faction.dbc");
|
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sEmotesTextStore, dbcPath,"EmotesText.dbc");
|
||||||
|
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sFactionStore, dbcPath,"Faction.dbc");
|
||||||
for (uint32 i = 0; i < sFactionStore.GetNumRows(); ++i)
|
for (uint32 i = 0; i < sFactionStore.GetNumRows(); ++i)
|
||||||
{
|
{
|
||||||
FactionEntry const* faction = sFactionStore.LookupEntry(i);
|
FactionEntry const* faction = sFactionStore.LookupEntry(i);
|
||||||
|
|
@ -1004,6 +1006,87 @@ uint32 GetVirtualMapForMapAndZone(uint32 mapid, uint32 zoneId)
|
||||||
return mapid;
|
return mapid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ContentLevels GetContentLevelsForMap(uint32 mapid)
|
||||||
|
{
|
||||||
|
MapEntry const* mapEntry = sMapStore.LookupEntry(mapid);
|
||||||
|
if (!mapEntry)
|
||||||
|
return CONTENT_1_60;
|
||||||
|
|
||||||
|
// exceptions for 648 - Goblin Starter area and 654 - Worgen Starter area
|
||||||
|
if (mapid == 648 || mapid == 654)
|
||||||
|
return CONTENT_1_60;
|
||||||
|
|
||||||
|
switch (mapEntry->Expansion())
|
||||||
|
{
|
||||||
|
default: return CONTENT_1_60;
|
||||||
|
case 1: return CONTENT_61_70;
|
||||||
|
case 2: return CONTENT_71_80;
|
||||||
|
case 3: return CONTENT_81_85;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ChatChannelsEntry const* GetChannelEntryFor(uint32 channel_id)
|
||||||
|
{
|
||||||
|
// not sorted, numbering index from 0
|
||||||
|
for (uint32 i = 0; i < sChatChannelsStore.GetNumRows(); ++i)
|
||||||
|
{
|
||||||
|
ChatChannelsEntry const* ch = sChatChannelsStore.LookupEntry(i);
|
||||||
|
if (ch && ch->ChannelID == channel_id)
|
||||||
|
return ch;
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IsTotemCategoryCompatiableWith(uint32 itemTotemCategoryId, uint32 requiredTotemCategoryId)
|
||||||
|
{
|
||||||
|
if (requiredTotemCategoryId==0)
|
||||||
|
return true;
|
||||||
|
if (itemTotemCategoryId==0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
TotemCategoryEntry const* itemEntry = sTotemCategoryStore.LookupEntry(itemTotemCategoryId);
|
||||||
|
if (!itemEntry)
|
||||||
|
return false;
|
||||||
|
TotemCategoryEntry const* reqEntry = sTotemCategoryStore.LookupEntry(requiredTotemCategoryId);
|
||||||
|
if (!reqEntry)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (itemEntry->categoryType!=reqEntry->categoryType)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return (itemEntry->categoryMask & reqEntry->categoryMask)==reqEntry->categoryMask;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Zone2MapCoordinates(float& x, float& y, uint32 zone)
|
||||||
|
{
|
||||||
|
WorldMapAreaEntry const* maEntry = sWorldMapAreaStore.LookupEntry(zone);
|
||||||
|
|
||||||
|
// if not listed then map coordinates (instance)
|
||||||
|
if (!maEntry || maEntry->x2 == maEntry->x1 || maEntry->y2 == maEntry->y1)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
std::swap(x, y); // at client map coords swapped
|
||||||
|
x = x * ((maEntry->x2-maEntry->x1) / 100) + maEntry->x1;
|
||||||
|
y = y * ((maEntry->y2-maEntry->y1) / 100) + maEntry->y1; // client y coord from top to down
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Map2ZoneCoordinates(float& x,float& y,uint32 zone)
|
||||||
|
{
|
||||||
|
WorldMapAreaEntry const* maEntry = sWorldMapAreaStore.LookupEntry(zone);
|
||||||
|
|
||||||
|
// if not listed then map coordinates (instance)
|
||||||
|
if (!maEntry || maEntry->x2 == maEntry->x1 || maEntry->y2 == maEntry->y1)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
x = (x-maEntry->x1)/((maEntry->x2-maEntry->x1)/100);
|
||||||
|
y = (y-maEntry->y1)/((maEntry->y2-maEntry->y1)/100); // client y coord from top to down
|
||||||
|
std::swap(x,y); // client have map coords swapped
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
ContentLevels GetContentLevelsForMapAndZone(uint32 mapId, uint32 zoneId)
|
ContentLevels GetContentLevelsForMapAndZone(uint32 mapId, uint32 zoneId)
|
||||||
{
|
{
|
||||||
MapEntry const* mapEntry = sMapStore.LookupEntry(mapId);
|
MapEntry const* mapEntry = sMapStore.LookupEntry(mapId);
|
||||||
|
|
@ -1042,109 +1125,6 @@ ContentLevels GetContentLevelsForMapAndZone(uint32 mapId, uint32 zoneId)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ChatChannelsEntry const* GetChannelEntryFor(uint32 channel_id)
|
|
||||||
{
|
|
||||||
// not sorted, numbering index from 0
|
|
||||||
for (uint32 i = 0; i < sChatChannelsStore.GetNumRows(); ++i)
|
|
||||||
{
|
|
||||||
ChatChannelsEntry const* ch = sChatChannelsStore.LookupEntry(i);
|
|
||||||
if (ch && ch->ChannelID == channel_id)
|
|
||||||
return ch;
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
static ChatChannelsEntry worldCh = { 26, 4, "world" };
|
|
||||||
|
|
||||||
ChatChannelsEntry const* GetChannelEntryFor(const std::string& name)
|
|
||||||
{
|
|
||||||
// not sorted, numbering index from 0
|
|
||||||
for (uint32 i = 0; i < sChatChannelsStore.GetNumRows(); ++i)
|
|
||||||
{
|
|
||||||
ChatChannelsEntry const* ch = sChatChannelsStore.LookupEntry(i);
|
|
||||||
if (ch)
|
|
||||||
{
|
|
||||||
// need to remove %s from entryName if it exists before we match
|
|
||||||
std::string entryName(ch->pattern[0]);
|
|
||||||
std::size_t removeString = entryName.find("%s");
|
|
||||||
|
|
||||||
if (removeString != std::string::npos)
|
|
||||||
entryName.replace(removeString, 2, "");
|
|
||||||
|
|
||||||
if (name.find(entryName) != std::string::npos)
|
|
||||||
return ch;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool compare = true; // hack for world channel, TODO smth!
|
|
||||||
std::string world = "world";
|
|
||||||
for (uint8 i = 0; i < name.length(); ++i)
|
|
||||||
{
|
|
||||||
if (tolower(name[i]) != world[i])
|
|
||||||
{
|
|
||||||
compare = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (compare)
|
|
||||||
return &worldCh;
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
bool IsTotemCategoryCompatiableWith(uint32 itemTotemCategoryId, uint32 requiredTotemCategoryId)
|
|
||||||
{
|
|
||||||
if (requiredTotemCategoryId == 0)
|
|
||||||
return true;
|
|
||||||
if (itemTotemCategoryId == 0)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
TotemCategoryEntry const* itemEntry = sTotemCategoryStore.LookupEntry(itemTotemCategoryId);
|
|
||||||
if (!itemEntry)
|
|
||||||
return false;
|
|
||||||
TotemCategoryEntry const* reqEntry = sTotemCategoryStore.LookupEntry(requiredTotemCategoryId);
|
|
||||||
if (!reqEntry)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (itemEntry->categoryType != reqEntry->categoryType)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return (itemEntry->categoryMask & reqEntry->categoryMask) == reqEntry->categoryMask;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Zone2MapCoordinates(float& x, float& y, uint32 zone)
|
|
||||||
{
|
|
||||||
WorldMapAreaEntry const* maEntry = sWorldMapAreaStore.LookupEntry(zone);
|
|
||||||
|
|
||||||
// if not listed then map coordinates (instance)
|
|
||||||
if (!maEntry || maEntry->x2 == maEntry->x1 || maEntry->y2 == maEntry->y1)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
std::swap(x, y); // at client map coords swapped
|
|
||||||
x = x * ((maEntry->x2 - maEntry->x1) / 100) + maEntry->x1;
|
|
||||||
y = y * ((maEntry->y2 - maEntry->y1) / 100) + maEntry->y1; // client y coord from top to down
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Map2ZoneCoordinates(float& x, float& y, uint32 zone)
|
|
||||||
{
|
|
||||||
WorldMapAreaEntry const* maEntry = sWorldMapAreaStore.LookupEntry(zone);
|
|
||||||
|
|
||||||
// if not listed then map coordinates (instance)
|
|
||||||
if (!maEntry || maEntry->x2 == maEntry->x1 || maEntry->y2 == maEntry->y1)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
x = (x - maEntry->x1) / ((maEntry->x2 - maEntry->x1) / 100);
|
|
||||||
y = (y - maEntry->y1) / ((maEntry->y2 - maEntry->y1) / 100); // client y coord from top to down
|
|
||||||
std::swap(x, y); // client have map coords swapped
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
MapDifficultyEntry const* GetMapDifficultyData(uint32 mapId, Difficulty difficulty)
|
MapDifficultyEntry const* GetMapDifficultyData(uint32 mapId, Difficulty difficulty)
|
||||||
{
|
{
|
||||||
MapDifficultyMap::const_iterator itr = sMapDifficultyMap.find(MAKE_PAIR32(mapId, difficulty));
|
MapDifficultyMap::const_iterator itr = sMapDifficultyMap.find(MAKE_PAIR32(mapId, difficulty));
|
||||||
|
|
|
||||||
|
|
@ -141,6 +141,7 @@ extern DBCStorage <CinematicSequencesEntry> sCinematicSequencesStore;
|
||||||
extern DBCStorage <CreatureDisplayInfoEntry> sCreatureDisplayInfoStore;
|
extern DBCStorage <CreatureDisplayInfoEntry> sCreatureDisplayInfoStore;
|
||||||
extern DBCStorage <CreatureDisplayInfoExtraEntry>sCreatureDisplayInfoExtraStore;
|
extern DBCStorage <CreatureDisplayInfoExtraEntry>sCreatureDisplayInfoExtraStore;
|
||||||
extern DBCStorage <CreatureFamilyEntry> sCreatureFamilyStore;
|
extern DBCStorage <CreatureFamilyEntry> sCreatureFamilyStore;
|
||||||
|
extern DBCStorage <CreatureModelDataEntry> sCreatureModelDataStore;
|
||||||
extern DBCStorage <CreatureSpellDataEntry> sCreatureSpellDataStore;
|
extern DBCStorage <CreatureSpellDataEntry> sCreatureSpellDataStore;
|
||||||
extern DBCStorage <CreatureTypeEntry> sCreatureTypeStore;
|
extern DBCStorage <CreatureTypeEntry> sCreatureTypeStore;
|
||||||
extern DBCStorage <CurrencyTypesEntry> sCurrencyTypesStore;
|
extern DBCStorage <CurrencyTypesEntry> sCurrencyTypesStore;
|
||||||
|
|
|
||||||
|
|
@ -751,19 +751,19 @@ struct CinematicSequencesEntry
|
||||||
struct CreatureDisplayInfoEntry
|
struct CreatureDisplayInfoEntry
|
||||||
{
|
{
|
||||||
uint32 Displayid; // 0 m_ID
|
uint32 Displayid; // 0 m_ID
|
||||||
// 1 m_modelID
|
uint32 ModelId; // 1 m_modelID
|
||||||
// 2 m_soundID
|
// 2 m_soundID
|
||||||
uint32 ExtendedDisplayInfoID; // 3 m_extendedDisplayInfoID -> CreatureDisplayInfoExtraEntry::DisplayExtraId
|
uint32 ExtendedDisplayInfoID; // 3 m_extendedDisplayInfoID -> CreatureDisplayInfoExtraEntry::DisplayExtraId
|
||||||
float Scale; // 4 m_creatureModelScale
|
float Scale; // 4 m_creatureModelScale
|
||||||
// 5 m_creatureModelAlpha
|
// 5 m_creatureModelAlpha
|
||||||
// 6-8 m_textureVariation[3]
|
// 6-8 m_textureVariation[3]
|
||||||
// 9 m_portraitTextureName
|
// 9 m_portraitTextureName
|
||||||
// 10 m_sizeClass
|
// 10 m_sizeClass
|
||||||
// 11 m_bloodID
|
// 11 m_bloodID
|
||||||
// 12 m_NPCSoundID
|
// 12 m_NPCSoundID
|
||||||
// 13 m_particleColorID
|
// 13 m_particleColorID
|
||||||
// 14 m_creatureGeosetData
|
// 14 m_creatureGeosetData
|
||||||
// 15 m_objectEffectPackageID
|
// 15 m_objectEffectPackageID
|
||||||
// 16 all 0
|
// 16 all 0
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -797,6 +797,28 @@ struct CreatureFamilyEntry
|
||||||
// 11 m_iconFile
|
// 11 m_iconFile
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct CreatureModelDataEntry
|
||||||
|
{
|
||||||
|
uint32 Id; // 0
|
||||||
|
//uint32 Flags; // 1
|
||||||
|
//char* ModelPath // 2
|
||||||
|
//uint32 InhabitType; // 3 model inhabit type
|
||||||
|
//float Scale; // 4 Used in calculation of unit collision data
|
||||||
|
//int32 Unk2 // 5
|
||||||
|
//int32 Unk3 // 6
|
||||||
|
//uint32 Unk4 // 7
|
||||||
|
//uint32 Unk5 // 8
|
||||||
|
//float Unk6 // 9
|
||||||
|
//uint32 Unk7 // 10
|
||||||
|
//float Unk8 // 11
|
||||||
|
//uint32 Unk9 // 12
|
||||||
|
//uint32 Unk10 // 13
|
||||||
|
//float CollisionWidth; // 14
|
||||||
|
float CollisionHeight; // 15
|
||||||
|
float MountHeight; // 16 Used in calculation of unit collision data when mounted
|
||||||
|
//float Unks[14] // 17-30
|
||||||
|
};
|
||||||
|
|
||||||
#define MAX_CREATURE_SPELL_DATA_SLOT 4
|
#define MAX_CREATURE_SPELL_DATA_SLOT 4
|
||||||
|
|
||||||
struct CreatureSpellDataEntry
|
struct CreatureSpellDataEntry
|
||||||
|
|
@ -861,7 +883,7 @@ struct DestructibleModelDataEntry
|
||||||
// uint32 unk17; // 17
|
// uint32 unk17; // 17
|
||||||
// uint32 unk18; // 18
|
// uint32 unk18; // 18
|
||||||
// uint32 unk19; // 19
|
// uint32 unk19; // 19
|
||||||
//uint32 smokeDisplayId; // 20
|
uint32 smokeDisplayId; // 20
|
||||||
// uint32 unk21; // 21
|
// uint32 unk21; // 21
|
||||||
// uint32 unk22; // 22
|
// uint32 unk22; // 22
|
||||||
// uint32 unk23; // 23
|
// uint32 unk23; // 23
|
||||||
|
|
@ -1380,7 +1402,6 @@ struct MapEntry
|
||||||
MapID == 509 || MapID == 534 || MapID == 560 || // AhnQiraj, HyjalPast, HillsbradPast
|
MapID == 509 || MapID == 534 || MapID == 560 || // AhnQiraj, HyjalPast, HillsbradPast
|
||||||
MapID == 568 || MapID == 580 || MapID == 595 || // ZulAman, Sunwell Plateau, Culling of Stratholme
|
MapID == 568 || MapID == 580 || MapID == 595 || // ZulAman, Sunwell Plateau, Culling of Stratholme
|
||||||
MapID == 603 || MapID == 615 || MapID == 616 || // Ulduar, The Obsidian Sanctum, The Eye Of Eternity
|
MapID == 603 || MapID == 615 || MapID == 616 || // Ulduar, The Obsidian Sanctum, The Eye Of Eternity
|
||||||
MapID == 603 || MapID == 615 || MapID == 616 || // Ulduar, The Obsidian Sanctum, The Eye Of Eternity
|
|
||||||
MapID == 631 || MapID == 658 || MapID == 724 || // Icecrown Citadel, Pit of Saron, Ruby Sanctum
|
MapID == 631 || MapID == 658 || MapID == 724 || // Icecrown Citadel, Pit of Saron, Ruby Sanctum
|
||||||
MapID == 644 || MapID == 720 || MapID == 721 || // Halls of Origination, Firelands
|
MapID == 644 || MapID == 720 || MapID == 721 || // Halls of Origination, Firelands
|
||||||
MapID == 734 || MapID == 755 || MapID == 859 || // Ahn'Qiraj Terrace, Lost City of Tol'Vir, Zul'Gurub
|
MapID == 734 || MapID == 755 || MapID == 859 || // Ahn'Qiraj Terrace, Lost City of Tol'Vir, Zul'Gurub
|
||||||
|
|
@ -1723,81 +1744,89 @@ struct ClassFamilyMask
|
||||||
// SpellAuraOptions.dbc
|
// SpellAuraOptions.dbc
|
||||||
struct SpellAuraOptionsEntry
|
struct SpellAuraOptionsEntry
|
||||||
{
|
{
|
||||||
//uint32 Id; // 0 m_ID
|
//uint32 Id; // 0 m_ID
|
||||||
uint32 StackAmount; // 51 m_cumulativeAura
|
uint32 StackAmount; // 1 m_cumulativeAura
|
||||||
uint32 procChance; // 38 m_procChance
|
uint32 procChance; // 2 m_procChance
|
||||||
uint32 procCharges; // 39 m_procCharges
|
uint32 procCharges; // 3 m_procCharges
|
||||||
uint32 procFlags; // 37 m_procTypeMask
|
uint32 procFlags; // 4 m_procTypeMask
|
||||||
};
|
};
|
||||||
|
|
||||||
// SpellAuraRestrictions.dbc
|
// SpellAuraRestrictions.dbc
|
||||||
struct SpellAuraRestrictionsEntry
|
struct SpellAuraRestrictionsEntry
|
||||||
{
|
{
|
||||||
//uint32 Id; // 0 m_ID
|
//uint32 Id; // 0 m_ID
|
||||||
uint32 CasterAuraState; // 21 m_casterAuraState
|
uint32 CasterAuraState; // 1 m_casterAuraState
|
||||||
uint32 TargetAuraState; // 22 m_targetAuraState
|
uint32 TargetAuraState; // 2 m_targetAuraState
|
||||||
uint32 CasterAuraStateNot; // 23 m_excludeCasterAuraState
|
uint32 CasterAuraStateNot; // 3 m_excludeCasterAuraState
|
||||||
uint32 TargetAuraStateNot; // 24 m_excludeTargetAuraState
|
uint32 TargetAuraStateNot; // 4 m_excludeTargetAuraState
|
||||||
uint32 casterAuraSpell; // 25 m_casterAuraSpell
|
uint32 casterAuraSpell; // 5 m_casterAuraSpell
|
||||||
uint32 targetAuraSpell; // 26 m_targetAuraSpell
|
uint32 targetAuraSpell; // 6 m_targetAuraSpell
|
||||||
uint32 excludeCasterAuraSpell; // 27 m_excludeCasterAuraSpell
|
uint32 excludeCasterAuraSpell; // 7 m_excludeCasterAuraSpell
|
||||||
uint32 excludeTargetAuraSpell; // 28 m_excludeTargetAuraSpell
|
uint32 excludeTargetAuraSpell; // 8 m_excludeTargetAuraSpell
|
||||||
};
|
};
|
||||||
|
|
||||||
// SpellCastingRequirements.dbc
|
// SpellCastingRequirements.dbc
|
||||||
struct SpellCastingRequirementsEntry
|
struct SpellCastingRequirementsEntry
|
||||||
{
|
{
|
||||||
//uint32 Id; // 0 m_ID
|
//uint32 Id; // 0 m_ID
|
||||||
uint32 FacingCasterFlags; // 20 m_facingCasterFlags
|
uint32 FacingCasterFlags; // 1 m_facingCasterFlags
|
||||||
//uint32 MinFactionId; // 159 m_minFactionID not used
|
//uint32 MinFactionId; // 2 m_minFactionID not used
|
||||||
//uint32 MinReputation; // 160 m_minReputation not used
|
//uint32 MinReputation; // 3 m_minReputation not used
|
||||||
int32 AreaGroupId; // 164 m_requiredAreaGroupId
|
int32 AreaGroupId; // 4 m_requiredAreaGroupId
|
||||||
//uint32 RequiredAuraVision; // 161 m_requiredAuraVision not used
|
//uint32 RequiredAuraVision; // 5 m_requiredAuraVision not used
|
||||||
uint32 RequiresSpellFocus; // 19 m_requiresSpellFocus
|
uint32 RequiresSpellFocus; // 6 m_requiresSpellFocus
|
||||||
|
};
|
||||||
|
|
||||||
|
// SpellCastTimes.dbc
|
||||||
|
struct SpellCastTimesEntry
|
||||||
|
{
|
||||||
|
uint32 ID; // 0 m_ID
|
||||||
|
int32 CastTime; // 1 m_base
|
||||||
|
float CastTimePerLevel; // 2 m_perLevel
|
||||||
|
int32 MinCastTime; // 3 m_minimum
|
||||||
};
|
};
|
||||||
|
|
||||||
// SpellCategories.dbc
|
// SpellCategories.dbc
|
||||||
struct SpellCategoriesEntry
|
struct SpellCategoriesEntry
|
||||||
{
|
{
|
||||||
//uint32 Id; // 0 m_ID
|
//uint32 Id; // 0 m_ID
|
||||||
uint32 Category; // 1 m_category
|
uint32 Category; // 1 m_category
|
||||||
uint32 DmgClass; // 153 m_defenseType
|
uint32 DmgClass; // 2 m_defenseType
|
||||||
uint32 Dispel; // 2 m_dispelType
|
uint32 Dispel; // 3 m_dispelType
|
||||||
uint32 Mechanic; // 3 m_mechanic
|
uint32 Mechanic; // 4 m_mechanic
|
||||||
uint32 PreventionType; // 154 m_preventionType
|
uint32 PreventionType; // 5 m_preventionType
|
||||||
uint32 StartRecoveryCategory; // 145 m_startRecoveryCategory
|
uint32 StartRecoveryCategory; // 6 m_startRecoveryCategory
|
||||||
};
|
};
|
||||||
|
|
||||||
// SpellClassOptions.dbc
|
// SpellClassOptions.dbc
|
||||||
struct SpellClassOptionsEntry
|
struct SpellClassOptionsEntry
|
||||||
{
|
{
|
||||||
//uint32 Id; // 0 m_ID
|
//uint32 Id; // 0 m_ID
|
||||||
//uint32 modalNextSpell; // 50 m_modalNextSpell not used
|
//uint32 modalNextSpell; // 1 m_modalNextSpell not used
|
||||||
ClassFamilyMask SpellFamilyFlags; // 149-151 m_spellClassMask NOTE: size is 12 bytes!!!
|
ClassFamilyMask SpellFamilyFlags; // 2-4 m_spellClassMask NOTE: size is 12 bytes!!!
|
||||||
uint32 SpellFamilyName; // 148 m_spellClassSet
|
uint32 SpellFamilyName; // 5 m_spellClassSet
|
||||||
//char* Description; // 6 4.0.0
|
//char* Description; // 6 4.0.0
|
||||||
|
|
||||||
// helpers
|
// helpers
|
||||||
|
|
||||||
bool IsFitToFamilyMask(uint64 familyFlags, uint32 familyFlags2 = 0) const
|
bool IsFitToFamilyMask(uint64 familyFlags, uint32 familyFlags2 = 0) const
|
||||||
{
|
{
|
||||||
return SpellFamilyFlags.IsFitToFamilyMask(familyFlags, familyFlags2);
|
return SpellFamilyFlags.IsFitToFamilyMask(familyFlags, familyFlags2);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsFitToFamily(SpellFamily family, uint64 familyFlags, uint32 familyFlags2 = 0) const
|
bool IsFitToFamily(SpellFamily family, uint64 familyFlags, uint32 familyFlags2 = 0) const
|
||||||
{
|
{
|
||||||
return SpellFamily(SpellFamilyName) == family && IsFitToFamilyMask(familyFlags, familyFlags2);
|
return SpellFamily(SpellFamilyName) == family && IsFitToFamilyMask(familyFlags, familyFlags2);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsFitToFamilyMask(ClassFamilyMask const& mask) const
|
bool IsFitToFamilyMask(ClassFamilyMask const& mask) const
|
||||||
{
|
{
|
||||||
return SpellFamilyFlags.IsFitToFamilyMask(mask);
|
return SpellFamilyFlags.IsFitToFamilyMask(mask);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsFitToFamily(SpellFamily family, ClassFamilyMask const& mask) const
|
bool IsFitToFamily(SpellFamily family, ClassFamilyMask const& mask) const
|
||||||
{
|
{
|
||||||
return SpellFamily(SpellFamilyName) == family && IsFitToFamilyMask(mask);
|
return SpellFamily(SpellFamilyName) == family && IsFitToFamilyMask(mask);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// catch wrong uses
|
// catch wrong uses
|
||||||
|
|
@ -1808,10 +1837,10 @@ struct SpellClassOptionsEntry
|
||||||
// SpellCooldowns.dbc
|
// SpellCooldowns.dbc
|
||||||
struct SpellCooldownsEntry
|
struct SpellCooldownsEntry
|
||||||
{
|
{
|
||||||
//uint32 Id; // 0 m_ID
|
//uint32 Id; // 0 m_ID
|
||||||
uint32 CategoryRecoveryTime; // 31 m_categoryRecoveryTime
|
uint32 CategoryRecoveryTime; // 1 m_categoryRecoveryTime
|
||||||
uint32 RecoveryTime; // 30 m_recoveryTime
|
uint32 RecoveryTime; // 2 m_recoveryTime
|
||||||
uint32 StartRecoveryTime; // 146 m_startRecoveryTime
|
uint32 StartRecoveryTime; // 3 m_startRecoveryTime
|
||||||
};
|
};
|
||||||
|
|
||||||
// SpellEffect.dbc
|
// SpellEffect.dbc
|
||||||
|
|
@ -1841,7 +1870,8 @@ struct SpellEffectEntry
|
||||||
uint32 EffectImplicitTargetB; // 23 m_implicitTargetB
|
uint32 EffectImplicitTargetB; // 23 m_implicitTargetB
|
||||||
uint32 EffectSpellId; // 24 m_spellId - spell.dbc
|
uint32 EffectSpellId; // 24 m_spellId - spell.dbc
|
||||||
uint32 EffectIndex; // 25 m_spellEffectIdx
|
uint32 EffectIndex; // 25 m_spellEffectIdx
|
||||||
// uint32 unk; // 26 4.2.0 only 0 or 1
|
//uint32 unk; // 26 4.2.0 only 0 or 1
|
||||||
|
|
||||||
// helpers
|
// helpers
|
||||||
|
|
||||||
int32 CalculateSimpleValue() const { return EffectBasePoints; }
|
int32 CalculateSimpleValue() const { return EffectBasePoints; }
|
||||||
|
|
@ -1858,66 +1888,138 @@ struct SpellEffectEntry
|
||||||
// SpellEquippedItems.dbc
|
// SpellEquippedItems.dbc
|
||||||
struct SpellEquippedItemsEntry
|
struct SpellEquippedItemsEntry
|
||||||
{
|
{
|
||||||
//uint32 Id; // 0 m_ID
|
//uint32 Id; // 0 m_ID
|
||||||
int32 EquippedItemClass; // 70 m_equippedItemClass (value)
|
int32 EquippedItemClass; // 1 m_equippedItemClass (value)
|
||||||
int32 EquippedItemInventoryTypeMask; // 72 m_equippedItemInvTypes (mask)
|
int32 EquippedItemInventoryTypeMask; // 2 m_equippedItemInvTypes (mask)
|
||||||
int32 EquippedItemSubClassMask; // 71 m_equippedItemSubclass (mask)
|
int32 EquippedItemSubClassMask; // 3 m_equippedItemSubclass (mask)
|
||||||
|
};
|
||||||
|
|
||||||
|
// SpellFocusObject.dbc
|
||||||
|
struct SpellFocusObjectEntry
|
||||||
|
{
|
||||||
|
uint32 ID; // 0 m_ID
|
||||||
|
//char* Name; // 1 m_name_lang
|
||||||
};
|
};
|
||||||
|
|
||||||
// SpellInterrupts.dbc
|
// SpellInterrupts.dbc
|
||||||
struct SpellInterruptsEntry
|
struct SpellInterruptsEntry
|
||||||
{
|
{
|
||||||
//uint32 Id; // 0 m_ID
|
//uint32 Id; // 0 m_ID
|
||||||
uint32 AuraInterruptFlags; // 33 m_auraInterruptFlags
|
uint32 AuraInterruptFlags; // 1 m_auraInterruptFlags
|
||||||
//uint32 // 34 4.0.0
|
//uint32 // 2 4.0.0
|
||||||
uint32 ChannelInterruptFlags; // 35 m_channelInterruptFlags
|
uint32 ChannelInterruptFlags; // 3 m_channelInterruptFlags
|
||||||
//uint32 // 36 4.0.0
|
//uint32 // 4 4.0.0
|
||||||
uint32 InterruptFlags; // 32 m_interruptFlags
|
uint32 InterruptFlags; // 5 m_interruptFlags
|
||||||
|
};
|
||||||
|
|
||||||
|
// SpellItemEnchantment.dbc
|
||||||
|
struct SpellItemEnchantmentEntry
|
||||||
|
{
|
||||||
|
uint32 ID; // 0 m_ID
|
||||||
|
//uint32 charges; // 1 m_charges
|
||||||
|
uint32 type[3]; // 2-4 m_effect[3]
|
||||||
|
uint32 amount[3]; // 5-7 m_effectPointsMin[3]
|
||||||
|
//uint32 amount2[3] // 8-10 m_effectPointsMax[3]
|
||||||
|
uint32 spellid[3]; // 11-13 m_effectArg[3]
|
||||||
|
DBCString description; // 14 m_name_lang
|
||||||
|
uint32 aura_id; // 15 m_itemVisual
|
||||||
|
uint32 slot; // 16 m_flags
|
||||||
|
uint32 GemID; // 17 m_src_itemID
|
||||||
|
uint32 EnchantmentCondition; // 18 m_condition_id
|
||||||
|
uint32 requiredSkill; // 19 m_requiredSkillID
|
||||||
|
uint32 requiredSkillValue; // 20 m_requiredSkillRank
|
||||||
|
uint32 requiredLevel; // 21 m_requiredLevel - 3.1
|
||||||
|
// 22 new in 3.1
|
||||||
|
};
|
||||||
|
|
||||||
|
// SpellItemEnchantmentCondition.dbc
|
||||||
|
struct SpellItemEnchantmentConditionEntry
|
||||||
|
{
|
||||||
|
uint32 ID; // 0 m_ID
|
||||||
|
uint8 Color[5]; // 1-5 m_lt_operandType[5]
|
||||||
|
//uint32 LT_Operand[5]; // 6-10 m_lt_operand[5]
|
||||||
|
uint8 Comparator[5]; // 11-15 m_operator[5]
|
||||||
|
uint8 CompareColor[5]; // 15-20 m_rt_operandType[5]
|
||||||
|
uint32 Value[5]; // 21-25 m_rt_operand[5]
|
||||||
|
//uint8 Logic[5] // 25-30 m_logic[5]
|
||||||
};
|
};
|
||||||
|
|
||||||
// SpellLevels.dbc
|
// SpellLevels.dbc
|
||||||
struct SpellLevelsEntry
|
struct SpellLevelsEntry
|
||||||
{
|
{
|
||||||
//uint32 Id; // 0 m_ID
|
//uint32 Id; // 0 m_ID
|
||||||
uint32 baseLevel; // 41 m_baseLevel
|
uint32 baseLevel; // 1 m_baseLevel
|
||||||
uint32 maxLevel; // 40 m_maxLevel
|
uint32 maxLevel; // 2 m_maxLevel
|
||||||
uint32 spellLevel; // 42 m_spellLevel
|
uint32 spellLevel; // 3 m_spellLevel
|
||||||
};
|
};
|
||||||
|
|
||||||
// SpellPower.dbc
|
// SpellPower.dbc
|
||||||
struct SpellPowerEntry
|
struct SpellPowerEntry
|
||||||
{
|
{
|
||||||
//uint32 Id; // 0 - m_ID
|
//uint32 Id; // 0 - m_ID
|
||||||
uint32 manaCost; // 1 - m_manaCost
|
uint32 manaCost; // 1 - m_manaCost
|
||||||
uint32 manaCostPerlevel; // 2 - m_manaCostPerLevel
|
uint32 manaCostPerlevel; // 2 - m_manaCostPerLevel
|
||||||
uint32 ManaCostPercentage; // 3 - m_manaCostPct
|
uint32 ManaCostPercentage; // 3 - m_manaCostPct
|
||||||
uint32 manaPerSecond; // 4 - m_manaPerSecond
|
uint32 manaPerSecond; // 4 - m_manaPerSecond
|
||||||
//uint32 PowerDisplayId; // 5 - m_powerDisplayID - id from PowerDisplay.dbc, new in 3.1
|
uint32 manaPerSecondPerLevel; // 5 m_manaPerSecondPerLevel
|
||||||
//uint32 unk1; // 6 - 4.0.0
|
//uint32 PowerDisplayId; // 6 - m_powerDisplayID - id from PowerDisplay.dbc, new in 3.1
|
||||||
//unk // 7 - 4.3.0
|
float ManaCostPercentageFloat; // 7 4.3.0
|
||||||
|
};
|
||||||
|
|
||||||
|
// SpellRadius.dbc
|
||||||
|
struct SpellRadiusEntry
|
||||||
|
{
|
||||||
|
uint32 ID; // 0 m_ID
|
||||||
|
float Radius; // 1 m_radius
|
||||||
|
float RadiusPerLevel; // 2 m_radiusPerLevel
|
||||||
|
float RadiusMax; // 3 m_radiusMax
|
||||||
|
};
|
||||||
|
|
||||||
|
// SpellRange.dbc
|
||||||
|
struct SpellRangeEntry
|
||||||
|
{
|
||||||
|
uint32 ID; // 0 m_ID
|
||||||
|
float minRange; // 1 m_rangeMin[2]
|
||||||
|
float minRangeFriendly; // 2
|
||||||
|
float maxRange; // 3 m_rangeMax[2]
|
||||||
|
float maxRangeFriendly; // 4
|
||||||
|
uint32 type; // 5 m_flags
|
||||||
|
//char* Name; // 6-21 m_displayName_lang
|
||||||
|
//char* ShortName; // 23-38 m_displayNameShort_lang
|
||||||
};
|
};
|
||||||
|
|
||||||
// SpellReagents.dbc
|
// SpellReagents.dbc
|
||||||
struct SpellReagentsEntry
|
struct SpellReagentsEntry
|
||||||
{
|
{
|
||||||
//uint32 Id; // 0 m_ID
|
//uint32 Id; // 0 m_ID
|
||||||
int32 Reagent[MAX_SPELL_REAGENTS]; // 54-61 m_reagent
|
int32 Reagent[MAX_SPELL_REAGENTS]; // 54-61 m_reagent
|
||||||
uint32 ReagentCount[MAX_SPELL_REAGENTS]; // 62-69 m_reagentCount
|
uint32 ReagentCount[MAX_SPELL_REAGENTS]; // 62-69 m_reagentCount
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// SpellRuneCost.dbc
|
||||||
|
struct SpellRuneCostEntry
|
||||||
|
{
|
||||||
|
uint32 ID; // 0 m_ID
|
||||||
|
uint32 RuneCost[3]; // 1-3 m_blood m_unholy m_frost (0=blood, 1=frost, 2=unholy)
|
||||||
|
uint32 runePowerGain; // 4 m_runicPower
|
||||||
|
|
||||||
|
bool NoRuneCost() const { return RuneCost[0] == 0 && RuneCost[1] == 0 && RuneCost[2] == 0; }
|
||||||
|
bool NoRunicPowerGain() const { return runePowerGain == 0; }
|
||||||
|
};
|
||||||
|
|
||||||
// SpellScaling.dbc
|
// SpellScaling.dbc
|
||||||
struct SpellScalingEntry
|
struct SpellScalingEntry
|
||||||
{
|
{
|
||||||
//uint32 Id; // 0 m_ID
|
//uint32 Id; // 0 m_ID
|
||||||
int32 castTimeMin; // 1
|
uint32 castTimeMin; // 1
|
||||||
int32 castTimeMax; // 2
|
uint32 castTimeMax; // 2
|
||||||
int32 castScalingMaxLevel; // 3
|
uint32 castScalingMaxLevel; // 3
|
||||||
int32 playerClass; // 4 (index * 100) + charLevel => gtSpellScaling.dbc
|
uint32 playerClass; // 4 (index * 100) + charLevel => gtSpellScaling.dbc
|
||||||
float coeff1[3]; // 5-7
|
float coeff1[3]; // 5-7
|
||||||
float coeff2[3]; // 8-10
|
float coeff2[3]; // 8-10
|
||||||
float coeff3[3]; // 11-13
|
float coeff3[3]; // 11-13
|
||||||
float coefBase; // 14 some coefficient, mostly 1.0f
|
float coefBase; // 14 some coefficient, mostly 1.0f
|
||||||
int32 coefLevelBase; // 15 some level
|
uint32 coefLevelBase; // 15 some level
|
||||||
|
|
||||||
bool IsScalableEffect(SpellEffectIndex i) const { return coeff1[i] != 0.0f; };
|
bool IsScalableEffect(SpellEffectIndex i) const { return coeff1[i] != 0.0f; };
|
||||||
};
|
};
|
||||||
|
|
@ -1925,18 +2027,37 @@ struct SpellScalingEntry
|
||||||
// SpellShapeshift.dbc
|
// SpellShapeshift.dbc
|
||||||
struct SpellShapeshiftEntry
|
struct SpellShapeshiftEntry
|
||||||
{
|
{
|
||||||
//uint32 Id; // 0 m_ID
|
//uint32 Id; // 0 m_ID
|
||||||
uint32 StancesNot; // 13 m_shapeshiftMask
|
uint32 StancesNot; // 1 m_shapeshiftMask
|
||||||
// uint32 unk_320_2; // 14 3.2.0
|
// uint32 unk_320_2; // 2 3.2.0
|
||||||
uint32 Stances; // 15 m_shapeshiftExclude
|
uint32 Stances; // 3 m_shapeshiftExclude
|
||||||
// uint32 unk_320_3; // 16 3.2.0
|
// uint32 unk_320_3; // 4 3.2.0
|
||||||
// uint32 StanceBarOrder; // 155 m_stanceBarOrder not used
|
// uint32 StanceBarOrder; // 5 m_stanceBarOrder not used
|
||||||
|
};
|
||||||
|
|
||||||
|
// SpellShapeshiftForm.dbc
|
||||||
|
struct SpellShapeshiftFormEntry
|
||||||
|
{
|
||||||
|
uint32 ID; // 0 m_ID
|
||||||
|
//uint32 buttonPosition; // 1 m_bonusActionBar
|
||||||
|
//char* Name; // 2 m_name_lang
|
||||||
|
uint32 flags1; // 3 m_flags
|
||||||
|
int32 creatureType; // 4 m_creatureType <=0 humanoid, other normal creature types
|
||||||
|
//uint32 unk1; // 5 m_attackIconID
|
||||||
|
uint32 attackSpeed; // 6 m_combatRoundTime
|
||||||
|
uint32 modelID_A; // 7 m_creatureDisplayID[4]
|
||||||
|
uint32 modelID_H; // 8
|
||||||
|
//uint32 unk3; // 9 unused always 0
|
||||||
|
//uint32 unk4; // 10 unused always 0
|
||||||
|
uint32 spellId[8]; // 11-18 m_presetSpellID[8]
|
||||||
|
//uint32 unk5; // 19 unused, !=0 for flight forms
|
||||||
|
//uint32 unk6; // 20
|
||||||
};
|
};
|
||||||
|
|
||||||
// SpellTargetRestrictions.dbc
|
// SpellTargetRestrictions.dbc
|
||||||
struct SpellTargetRestrictionsEntry
|
struct SpellTargetRestrictionsEntry
|
||||||
{
|
{
|
||||||
//uint32 Id; // 0 m_ID
|
//uint32 Id; // 0 m_ID
|
||||||
float MaxTargetRadius; // 1 - m_maxTargetRadius
|
float MaxTargetRadius; // 1 - m_maxTargetRadius
|
||||||
uint32 MaxAffectedTargets; // 1 - m_maxTargets
|
uint32 MaxAffectedTargets; // 1 - m_maxTargets
|
||||||
uint32 MaxTargetLevel; // 2 - m_maxTargetLevel
|
uint32 MaxTargetLevel; // 2 - m_maxTargetLevel
|
||||||
|
|
@ -1947,9 +2068,9 @@ struct SpellTargetRestrictionsEntry
|
||||||
// SpellTotems.dbc
|
// SpellTotems.dbc
|
||||||
struct SpellTotemsEntry
|
struct SpellTotemsEntry
|
||||||
{
|
{
|
||||||
//uint32 Id; // 0 m_ID
|
//uint32 Id; // 0 m_ID
|
||||||
uint32 TotemCategory[MAX_SPELL_TOTEM_CATEGORIES]; // 162-163 m_requiredTotemCategoryID
|
uint32 TotemCategory[MAX_SPELL_TOTEM_CATEGORIES]; // 1 2 m_requiredTotemCategoryID
|
||||||
uint32 Totem[MAX_SPELL_TOTEMS]; // 52-53 m_totem
|
uint32 Totem[MAX_SPELL_TOTEMS]; // 3 4 m_totem
|
||||||
};
|
};
|
||||||
|
|
||||||
// Spell.dbc
|
// Spell.dbc
|
||||||
|
|
@ -2116,68 +2237,6 @@ struct SpellEntry
|
||||||
#define LOADED_SPELLDBC_FIELD_POS_EQUIPPED_ITEM_CLASS 65 // Must be converted to -1
|
#define LOADED_SPELLDBC_FIELD_POS_EQUIPPED_ITEM_CLASS 65 // Must be converted to -1
|
||||||
#define LOADED_SPELLDBC_FIELD_POS_SPELLNAME_0 132 // Links to "MaNGOS server-side spell"
|
#define LOADED_SPELLDBC_FIELD_POS_SPELLNAME_0 132 // Links to "MaNGOS server-side spell"
|
||||||
|
|
||||||
struct SpellCastTimesEntry
|
|
||||||
{
|
|
||||||
uint32 ID; // 0 m_ID
|
|
||||||
int32 CastTime; // 1 m_base
|
|
||||||
float CastTimePerLevel; // 2 m_perLevel
|
|
||||||
int32 MinCastTime; // 3 m_minimum
|
|
||||||
};
|
|
||||||
|
|
||||||
struct SpellFocusObjectEntry
|
|
||||||
{
|
|
||||||
uint32 ID; // 0 m_ID
|
|
||||||
//char* Name; // 1 m_name_lang
|
|
||||||
};
|
|
||||||
|
|
||||||
struct SpellRadiusEntry
|
|
||||||
{
|
|
||||||
uint32 ID; // 0 m_ID
|
|
||||||
float Radius; // 1 m_radius
|
|
||||||
// 2 m_radiusPerLevel
|
|
||||||
//float RadiusMax; // 3 m_radiusMax
|
|
||||||
};
|
|
||||||
|
|
||||||
struct SpellRangeEntry
|
|
||||||
{
|
|
||||||
uint32 ID; // 0 m_ID
|
|
||||||
float minRange; // 1 m_rangeMin[2]
|
|
||||||
float minRangeFriendly; // 2
|
|
||||||
float maxRange; // 3 m_rangeMax[2]
|
|
||||||
float maxRangeFriendly; // 4
|
|
||||||
//uint32 Flags; // 5 m_flags
|
|
||||||
//char* Name; // 6-21 m_displayName_lang
|
|
||||||
//char* ShortName; // 23-38 m_displayNameShort_lang
|
|
||||||
};
|
|
||||||
|
|
||||||
struct SpellRuneCostEntry
|
|
||||||
{
|
|
||||||
uint32 ID; // 0 m_ID
|
|
||||||
uint32 RuneCost[3]; // 1-3 m_blood m_unholy m_frost (0=blood, 1=frost, 2=unholy)
|
|
||||||
uint32 runePowerGain; // 4 m_runicPower
|
|
||||||
|
|
||||||
bool NoRuneCost() const { return RuneCost[0] == 0 && RuneCost[1] == 0 && RuneCost[2] == 0; }
|
|
||||||
bool NoRunicPowerGain() const { return runePowerGain == 0; }
|
|
||||||
};
|
|
||||||
|
|
||||||
struct SpellShapeshiftFormEntry
|
|
||||||
{
|
|
||||||
uint32 ID; // 0 m_ID
|
|
||||||
//uint32 buttonPosition; // 1 m_bonusActionBar
|
|
||||||
//char* Name; // 2 m_name_lang
|
|
||||||
uint32 flags1; // 3 m_flags
|
|
||||||
int32 creatureType; // 4 m_creatureType <=0 humanoid, other normal creature types
|
|
||||||
//uint32 unk1; // 5 m_attackIconID
|
|
||||||
uint32 attackSpeed; // 6 m_combatRoundTime
|
|
||||||
uint32 modelID_A; // 7 m_creatureDisplayID[4]
|
|
||||||
uint32 modelID_H; // 8
|
|
||||||
//uint32 unk3; // 9 unused always 0
|
|
||||||
//uint32 unk4; // 10 unused always 0
|
|
||||||
uint32 spellId[8]; // 11-18 m_presetSpellID[8]
|
|
||||||
//uint32 unk5; // 19 unused, !=0 for flight forms
|
|
||||||
//uint32 unk6; // 20
|
|
||||||
};
|
|
||||||
|
|
||||||
struct SpellDifficultyEntry
|
struct SpellDifficultyEntry
|
||||||
{
|
{
|
||||||
uint32 ID; // 0 m_ID
|
uint32 ID; // 0 m_ID
|
||||||
|
|
@ -2190,36 +2249,6 @@ struct SpellDurationEntry
|
||||||
int32 Duration[3]; // m_duration, m_durationPerLevel, m_maxDuration
|
int32 Duration[3]; // m_duration, m_durationPerLevel, m_maxDuration
|
||||||
};
|
};
|
||||||
|
|
||||||
struct SpellItemEnchantmentEntry
|
|
||||||
{
|
|
||||||
uint32 ID; // 0 m_ID
|
|
||||||
//uint32 charges; // 1 m_charges
|
|
||||||
uint32 type[3]; // 2-4 m_effect[3]
|
|
||||||
uint32 amount[3]; // 5-7 m_effectPointsMin[3]
|
|
||||||
//uint32 amount2[3] // 8-10 m_effectPointsMax[3]
|
|
||||||
uint32 spellid[3]; // 11-13 m_effectArg[3]
|
|
||||||
DBCString description; // 14 m_name_lang
|
|
||||||
uint32 aura_id; // 15 m_itemVisual
|
|
||||||
uint32 slot; // 16 m_flags
|
|
||||||
uint32 GemID; // 17 m_src_itemID
|
|
||||||
uint32 EnchantmentCondition; // 18 m_condition_id
|
|
||||||
//uint32 requiredSkill; // 19 m_requiredSkillID
|
|
||||||
//uint32 requiredSkillValue; // 20 m_requiredSkillRank
|
|
||||||
// 21 new in 3.1
|
|
||||||
// 22 new in 3.1
|
|
||||||
};
|
|
||||||
|
|
||||||
struct SpellItemEnchantmentConditionEntry
|
|
||||||
{
|
|
||||||
uint32 ID; // 0 m_ID
|
|
||||||
uint8 Color[5]; // 1-5 m_lt_operandType[5]
|
|
||||||
//uint32 LT_Operand[5]; // 6-10 m_lt_operand[5]
|
|
||||||
uint8 Comparator[5]; // 11-15 m_operator[5]
|
|
||||||
uint8 CompareColor[5]; // 15-20 m_rt_operandType[5]
|
|
||||||
uint32 Value[5]; // 21-25 m_rt_operand[5]
|
|
||||||
//uint8 Logic[5] // 25-30 m_logic[5]
|
|
||||||
};
|
|
||||||
|
|
||||||
struct SummonPropertiesEntry
|
struct SummonPropertiesEntry
|
||||||
{
|
{
|
||||||
uint32 Id; // 0 m_id
|
uint32 Id; // 0 m_id
|
||||||
|
|
|
||||||
|
|
@ -44,11 +44,12 @@ const char ChrClassesEntryfmt[]="nixsxxxixiiiii";
|
||||||
const char ChrRacesEntryfmt[]="nxixiixixxxxixsxxxxxixxx";
|
const char ChrRacesEntryfmt[]="nxixiixixxxxixsxxxxxixxx";
|
||||||
const char ChrClassesXPowerTypesfmt[]="nii";
|
const char ChrClassesXPowerTypesfmt[]="nii";
|
||||||
const char CinematicSequencesEntryfmt[] = "nxxxxxxxxx";
|
const char CinematicSequencesEntryfmt[] = "nxxxxxxxxx";
|
||||||
const char CreatureDisplayInfofmt[]="nxxifxxxxxxxxxxxx";
|
const char CreatureDisplayInfofmt[]="nixifxxxxxxxxxxxx";
|
||||||
const char CreatureDisplayInfoExtrafmt[] = "nixxxxxxxxxxxxxxxxxxx";
|
const char CreatureDisplayInfoExtrafmt[] = "nixxxxxxxxxxxxxxxxxxx";
|
||||||
const char CreatureFamilyfmt[]="nfifiiiiixsx";
|
const char CreatureFamilyfmt[]="nfifiiiiixsx";
|
||||||
|
const char CreatureModelDatafmt[] = "nxxxxxxxxxxxxxxffxxxxxxxxxxxxxx";
|
||||||
const char CreatureSpellDatafmt[] = "niiiixxxx";
|
const char CreatureSpellDatafmt[] = "niiiixxxx";
|
||||||
const char DestructibleModelDataFmt[] = "nixxxixxxxixxxxixxxxxxxx";
|
const char DestructibleModelDataFmt[] = "nixxxixxxxixxxxixxxxixxx";
|
||||||
const char DungeonEncounterfmt[]="niiiisxx";
|
const char DungeonEncounterfmt[]="niiiisxx";
|
||||||
const char CreatureTypefmt[]="nxx";
|
const char CreatureTypefmt[]="nxx";
|
||||||
const char CurrencyTypesfmt[]="nisxxxxiiix";
|
const char CurrencyTypesfmt[]="nisxxxxiiix";
|
||||||
|
|
|
||||||
|
|
@ -856,14 +856,14 @@ void InitializeOpcodes()
|
||||||
//OPCODE(SMSG_SPLINE_SET_SWIM_BACK_SPEED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
|
//OPCODE(SMSG_SPLINE_SET_SWIM_BACK_SPEED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
|
||||||
//OPCODE(SMSG_SPLINE_SET_TURN_RATE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
|
//OPCODE(SMSG_SPLINE_SET_TURN_RATE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
|
||||||
OPCODE(SMSG_SPLINE_MOVE_UNROOT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
|
OPCODE(SMSG_SPLINE_MOVE_UNROOT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
|
||||||
//OPCODE(SMSG_SPLINE_MOVE_FEATHER_FALL, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
|
OPCODE(SMSG_SPLINE_MOVE_FEATHER_FALL, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
|
||||||
//OPCODE(SMSG_SPLINE_MOVE_NORMAL_FALL, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
|
OPCODE(SMSG_SPLINE_MOVE_NORMAL_FALL, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
|
||||||
OPCODE(SMSG_SPLINE_MOVE_SET_HOVER, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
|
OPCODE(SMSG_SPLINE_MOVE_SET_HOVER, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
|
||||||
OPCODE(SMSG_SPLINE_MOVE_UNSET_HOVER, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
|
OPCODE(SMSG_SPLINE_MOVE_UNSET_HOVER, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
|
||||||
OPCODE(SMSG_SPLINE_MOVE_WATER_WALK, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
|
OPCODE(SMSG_SPLINE_MOVE_WATER_WALK, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
|
||||||
OPCODE(SMSG_SPLINE_MOVE_LAND_WALK, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
|
OPCODE(SMSG_SPLINE_MOVE_LAND_WALK, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
|
||||||
OPCODE(SMSG_SPLINE_MOVE_START_SWIM, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
|
OPCODE(SMSG_SPLINE_MOVE_START_SWIM, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
|
||||||
//OPCODE(SMSG_SPLINE_MOVE_STOP_SWIM, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
|
OPCODE(SMSG_SPLINE_MOVE_STOP_SWIM, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
|
||||||
OPCODE(SMSG_SPLINE_MOVE_SET_RUN_MODE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
|
OPCODE(SMSG_SPLINE_MOVE_SET_RUN_MODE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
|
||||||
OPCODE(SMSG_SPLINE_MOVE_SET_WALK_MODE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
|
OPCODE(SMSG_SPLINE_MOVE_SET_WALK_MODE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
|
||||||
//OPCODE(CMSG_GM_NUKE_ACCOUNT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
|
//OPCODE(CMSG_GM_NUKE_ACCOUNT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
|
||||||
|
|
@ -1268,7 +1268,7 @@ void InitializeOpcodes()
|
||||||
OPCODE(SMSG_SERVER_FIRST_ACHIEVEMENT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
|
OPCODE(SMSG_SERVER_FIRST_ACHIEVEMENT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
|
||||||
OPCODE(SMSG_PET_LEARNED_SPELL, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
|
OPCODE(SMSG_PET_LEARNED_SPELL, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
|
||||||
OPCODE(SMSG_PET_REMOVED_SPELL, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
|
OPCODE(SMSG_PET_REMOVED_SPELL, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
|
||||||
OPCODE(CMSG_CHANGE_SEATS_ON_CONTROLLED_VEHICLE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleChangeSeatsOnControlledVehicle );
|
OPCODE(CMSG_CHANGE_SEATS_ON_CONTROLLED_VEHICLE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleChangeSeatsOnControlledVehicle );
|
||||||
OPCODE(CMSG_HEARTH_AND_RESURRECT, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleHearthandResurrect );
|
OPCODE(CMSG_HEARTH_AND_RESURRECT, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleHearthandResurrect );
|
||||||
OPCODE(SMSG_ON_CANCEL_EXPECTED_RIDE_VEHICLE_AURA, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
|
OPCODE(SMSG_ON_CANCEL_EXPECTED_RIDE_VEHICLE_AURA, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
|
||||||
OPCODE(SMSG_CRITERIA_DELETED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
|
OPCODE(SMSG_CRITERIA_DELETED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
|
||||||
|
|
@ -1319,9 +1319,9 @@ void InitializeOpcodes()
|
||||||
//OPCODE(CMSG_START_BATTLEFIELD_CHEAT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
|
//OPCODE(CMSG_START_BATTLEFIELD_CHEAT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
|
||||||
//OPCODE(CMSG_END_BATTLEFIELD_CHEAT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
|
//OPCODE(CMSG_END_BATTLEFIELD_CHEAT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
|
||||||
//OPCODE(SMSG_COMPOUND_MOVE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
|
//OPCODE(SMSG_COMPOUND_MOVE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
|
||||||
OPCODE(SMSG_MOVE_GRAVITY_DISABLE, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
|
OPCODE(SMSG_MOVE_GRAVITY_DISABLE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
|
||||||
OPCODE(CMSG_MOVE_GRAVITY_DISABLE_ACK, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
|
OPCODE(CMSG_MOVE_GRAVITY_DISABLE_ACK, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
|
||||||
OPCODE(SMSG_MOVE_GRAVITY_ENABLE, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
|
OPCODE(SMSG_MOVE_GRAVITY_ENABLE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
|
||||||
OPCODE(CMSG_MOVE_GRAVITY_ENABLE_ACK, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
|
OPCODE(CMSG_MOVE_GRAVITY_ENABLE_ACK, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
|
||||||
//OPCODE(MSG_MOVE_GRAVITY_CHNG, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
|
//OPCODE(MSG_MOVE_GRAVITY_CHNG, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
|
||||||
OPCODE(SMSG_SPLINE_MOVE_GRAVITY_DISABLE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
|
OPCODE(SMSG_SPLINE_MOVE_GRAVITY_DISABLE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
|
||||||
|
|
@ -1392,7 +1392,7 @@ void InitializeOpcodes()
|
||||||
//OPCODE(SMSG_SEND_ALL_COMBAT_LOG, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
|
//OPCODE(SMSG_SEND_ALL_COMBAT_LOG, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
|
||||||
OPCODE(SMSG_OPEN_LFG_DUNGEON_FINDER, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
|
OPCODE(SMSG_OPEN_LFG_DUNGEON_FINDER, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
|
||||||
OPCODE(SMSG_MOVE_SET_COLLISION_HGT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
|
OPCODE(SMSG_MOVE_SET_COLLISION_HGT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
|
||||||
//OPCODE(CMSG_MOVE_SET_COLLISION_HGT_ACK, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
|
OPCODE(CMSG_MOVE_SET_COLLISION_HGT_ACK, STATUS_UNHANDLED,PROCESS_INPLACE, &WorldSession::Handle_NULL );
|
||||||
//OPCODE(MSG_MOVE_SET_COLLISION_HGT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
|
//OPCODE(MSG_MOVE_SET_COLLISION_HGT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
|
||||||
//OPCODE(CMSG_CLEAR_RANDOM_BG_WIN_TIME, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
|
//OPCODE(CMSG_CLEAR_RANDOM_BG_WIN_TIME, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
|
||||||
//OPCODE(CMSG_CLEAR_HOLIDAY_BG_WIN_TIME, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
|
//OPCODE(CMSG_CLEAR_HOLIDAY_BG_WIN_TIME, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
|
||||||
|
|
|
||||||
|
|
@ -840,8 +840,8 @@ enum Opcodes
|
||||||
SMSG_SPLINE_SET_SWIM_BACK_SPEED = 0x1303,
|
SMSG_SPLINE_SET_SWIM_BACK_SPEED = 0x1303,
|
||||||
SMSG_SPLINE_SET_TURN_RATE = 0x1304,
|
SMSG_SPLINE_SET_TURN_RATE = 0x1304,
|
||||||
SMSG_SPLINE_MOVE_UNROOT = 0x75B6, // 4.3.4 15595
|
SMSG_SPLINE_MOVE_UNROOT = 0x75B6, // 4.3.4 15595
|
||||||
SMSG_SPLINE_MOVE_FEATHER_FALL = 0x1306,
|
SMSG_SPLINE_MOVE_FEATHER_FALL = 0x3DA5, // 4.3.4 15595
|
||||||
SMSG_SPLINE_MOVE_NORMAL_FALL = 0x1307,
|
SMSG_SPLINE_MOVE_NORMAL_FALL = 0x38B2, // 4.3.4 15595
|
||||||
SMSG_SPLINE_MOVE_SET_HOVER = 0x14B6, // 4.3.4 15595
|
SMSG_SPLINE_MOVE_SET_HOVER = 0x14B6, // 4.3.4 15595
|
||||||
SMSG_SPLINE_MOVE_UNSET_HOVER = 0x7DA5, // 4.3.4 15595
|
SMSG_SPLINE_MOVE_UNSET_HOVER = 0x7DA5, // 4.3.4 15595
|
||||||
SMSG_SPLINE_MOVE_WATER_WALK = 0x50A2, // 4.3.4 15595
|
SMSG_SPLINE_MOVE_WATER_WALK = 0x50A2, // 4.3.4 15595
|
||||||
|
|
@ -1238,7 +1238,7 @@ enum Opcodes
|
||||||
CMSG_REMOVE_GLYPH = 0x148B,
|
CMSG_REMOVE_GLYPH = 0x148B,
|
||||||
CMSG_DUMP_OBJECTS = 0x148C,
|
CMSG_DUMP_OBJECTS = 0x148C,
|
||||||
SMSG_DUMP_OBJECTS_DATA = 0x148D,
|
SMSG_DUMP_OBJECTS_DATA = 0x148D,
|
||||||
CMSG_DISMISS_CRITTER = 0x4227,
|
CMSG_DISMISS_CRITTER = 0x4227, // 4.3.4 15595
|
||||||
SMSG_NOTIFY_DEST_LOC_SPELL_CAST = 0x148F,
|
SMSG_NOTIFY_DEST_LOC_SPELL_CAST = 0x148F,
|
||||||
CMSG_AUCTION_LIST_PENDING_SALES = 0x2C17, // 4.3.4 15595
|
CMSG_AUCTION_LIST_PENDING_SALES = 0x2C17, // 4.3.4 15595
|
||||||
SMSG_AUCTION_LIST_PENDING_SALES = 0x6A27, // 4.3.4 15595
|
SMSG_AUCTION_LIST_PENDING_SALES = 0x6A27, // 4.3.4 15595
|
||||||
|
|
@ -1264,9 +1264,9 @@ enum Opcodes
|
||||||
CMSG_SET_BREATH = 0x14A5,
|
CMSG_SET_BREATH = 0x14A5,
|
||||||
CMSG_QUERY_VEHICLE_STATUS = 0x14A6,
|
CMSG_QUERY_VEHICLE_STATUS = 0x14A6,
|
||||||
SMSG_BATTLEGROUND_INFO_THROTTLED = 0x14A7,
|
SMSG_BATTLEGROUND_INFO_THROTTLED = 0x14A7,
|
||||||
SMSG_SET_VEHICLE_REC_ID = 0x14A8,
|
SMSG_SET_VEHICLE_REC_ID = 0x4115, // 4.3.4 15595
|
||||||
CMSG_RIDE_VEHICLE_INTERACT = 0x14A9,
|
CMSG_RIDE_VEHICLE_INTERACT = 0x2705, // 4.3.4 15595
|
||||||
CMSG_CONTROLLER_EJECT_PASSENGER = 0x14AA,
|
CMSG_CONTROLLER_EJECT_PASSENGER = 0x6927, // 4.3.4 15595
|
||||||
SMSG_PET_GUIDS = 0x2D26, // 4.3.4 15595
|
SMSG_PET_GUIDS = 0x2D26, // 4.3.4 15595
|
||||||
SMSG_CLIENTCACHE_VERSION = 0x2734, // 4.3.4 15595
|
SMSG_CLIENTCACHE_VERSION = 0x2734, // 4.3.4 15595
|
||||||
CMSG_CHANGE_GDF_ARENA_RATING = 0x14AD,
|
CMSG_CHANGE_GDF_ARENA_RATING = 0x14AD,
|
||||||
|
|
@ -1376,7 +1376,7 @@ enum Opcodes
|
||||||
SMSG_SEND_ALL_COMBAT_LOG = 0x1515,
|
SMSG_SEND_ALL_COMBAT_LOG = 0x1515,
|
||||||
SMSG_OPEN_LFG_DUNGEON_FINDER = 0x0412, // 4.3.4 15595
|
SMSG_OPEN_LFG_DUNGEON_FINDER = 0x0412, // 4.3.4 15595
|
||||||
SMSG_MOVE_SET_COLLISION_HGT = 0x11B0, // 4.3.4 15595
|
SMSG_MOVE_SET_COLLISION_HGT = 0x11B0, // 4.3.4 15595
|
||||||
CMSG_MOVE_SET_COLLISION_HGT_ACK = 0x1518,
|
CMSG_MOVE_SET_COLLISION_HGT_ACK = 0x7114, // 4.3.4 15595
|
||||||
MSG_MOVE_SET_COLLISION_HGT = 0x1519,
|
MSG_MOVE_SET_COLLISION_HGT = 0x1519,
|
||||||
CMSG_CLEAR_RANDOM_BG_WIN_TIME = 0x151A,
|
CMSG_CLEAR_RANDOM_BG_WIN_TIME = 0x151A,
|
||||||
CMSG_CLEAR_HOLIDAY_BG_WIN_TIME = 0x151B,
|
CMSG_CLEAR_HOLIDAY_BG_WIN_TIME = 0x151B,
|
||||||
|
|
|
||||||
|
|
@ -451,7 +451,7 @@ enum SpellAttributesEx4
|
||||||
|
|
||||||
enum SpellAttributesEx5
|
enum SpellAttributesEx5
|
||||||
{
|
{
|
||||||
SPELL_ATTR_EX5_UNK0 = 0x00000001,// 0
|
SPELL_ATTR_EX5_CAN_CHANNEL_WHEN_MOVING = 0x00000001,// 0 don't interrupt channeling spells when moving
|
||||||
SPELL_ATTR_EX5_NO_REAGENT_WHILE_PREP = 0x00000002,// 1 not need reagents if UNIT_FLAG_PREPARATION
|
SPELL_ATTR_EX5_NO_REAGENT_WHILE_PREP = 0x00000002,// 1 not need reagents if UNIT_FLAG_PREPARATION
|
||||||
SPELL_ATTR_EX5_UNK2 = 0x00000004,// 2 removed at enter arena (e.g. 31850 since 3.3.3)
|
SPELL_ATTR_EX5_UNK2 = 0x00000004,// 2 removed at enter arena (e.g. 31850 since 3.3.3)
|
||||||
SPELL_ATTR_EX5_USABLE_WHILE_STUNNED = 0x00000008,// 3 usable while stunned
|
SPELL_ATTR_EX5_USABLE_WHILE_STUNNED = 0x00000008,// 3 usable while stunned
|
||||||
|
|
@ -3792,4 +3792,14 @@ enum TeleportLocation
|
||||||
TELEPORT_LOCATION_BG_ENTRY_POINT = 1,
|
TELEPORT_LOCATION_BG_ENTRY_POINT = 1,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// For Loot system
|
||||||
|
enum CreatureLootStatus
|
||||||
|
{
|
||||||
|
CREATURE_LOOT_STATUS_NONE = 0,
|
||||||
|
CREATURE_LOOT_STATUS_PICKPOCKETED = 1,
|
||||||
|
CREATURE_LOOT_STATUS_LOOTED = 2,
|
||||||
|
CREATURE_LOOT_STATUS_SKIN_AVAILABLE = 3,
|
||||||
|
CREATURE_LOOT_STATUS_SKINNED = 4
|
||||||
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -677,6 +677,7 @@ class WorldSession
|
||||||
void HandleGossipHelloOpcode(WorldPacket& recvPacket);
|
void HandleGossipHelloOpcode(WorldPacket& recvPacket);
|
||||||
void HandleGossipSelectOptionOpcode(WorldPacket& recvPacket);
|
void HandleGossipSelectOptionOpcode(WorldPacket& recvPacket);
|
||||||
void HandleSpiritHealerActivateOpcode(WorldPacket& recvPacket);
|
void HandleSpiritHealerActivateOpcode(WorldPacket& recvPacket);
|
||||||
|
void HandleReturnToGraveyardOpcode(WorldPacket& recvPacket);
|
||||||
void HandleNpcTextQueryOpcode(WorldPacket& recvPacket);
|
void HandleNpcTextQueryOpcode(WorldPacket& recvPacket);
|
||||||
void HandleBinderActivateOpcode(WorldPacket& recvPacket);
|
void HandleBinderActivateOpcode(WorldPacket& recvPacket);
|
||||||
void HandleListStabledPetsOpcode(WorldPacket& recvPacket);
|
void HandleListStabledPetsOpcode(WorldPacket& recvPacket);
|
||||||
|
|
|
||||||
|
|
@ -232,6 +232,7 @@ bool AccountMgr::CheckPassword(uint32 accid, std::string passwd)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
normalizeString(passwd);
|
normalizeString(passwd);
|
||||||
|
normalizeString(username);
|
||||||
|
|
||||||
QueryResult* result = LoginDatabase.PQuery("SELECT 1 FROM account WHERE id='%u' AND sha_pass_hash='%s'", accid, CalculateShaPassHash(username, passwd).c_str());
|
QueryResult* result = LoginDatabase.PQuery("SELECT 1 FROM account WHERE id='%u' AND sha_pass_hash='%s'", accid, CalculateShaPassHash(username, passwd).c_str());
|
||||||
if (result)
|
if (result)
|
||||||
|
|
|
||||||
|
|
@ -40,15 +40,22 @@ void WorldSession::HandleInspectArenaTeamsOpcode(WorldPacket& recv_data)
|
||||||
recv_data >> guid;
|
recv_data >> guid;
|
||||||
DEBUG_LOG("Inspect Arena stats %s", guid.GetString().c_str());
|
DEBUG_LOG("Inspect Arena stats %s", guid.GetString().c_str());
|
||||||
|
|
||||||
if (Player* plr = sObjectMgr.GetPlayer(guid))
|
Player* player = sObjectMgr.GetPlayer(guid);
|
||||||
|
if (!player)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!_player->IsWithinDistInMap(player, INSPECT_DISTANCE, false))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (_player->IsHostileTo(player))
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (uint8 i = 0; i < MAX_ARENA_SLOT; ++i)
|
||||||
{
|
{
|
||||||
for (uint8 i = 0; i < MAX_ARENA_SLOT; ++i)
|
if (uint32 a_id = player->GetArenaTeamId(i))
|
||||||
{
|
{
|
||||||
if (uint32 a_id = plr->GetArenaTeamId(i))
|
if (ArenaTeam* arenaTeam = sObjectMgr.GetArenaTeamById(a_id))
|
||||||
{
|
arenaTeam->InspectStats(this, player->GetObjectGuid());
|
||||||
if (ArenaTeam* at = sObjectMgr.GetArenaTeamById(a_id))
|
|
||||||
at->InspectStats(this, plr->GetObjectGuid());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -311,7 +311,7 @@ ChatCommand* ChatHandler::getCommandTable()
|
||||||
{ "setphase", SEC_GAMEMASTER, false, &ChatHandler::HandleGameObjectPhaseCommand, "", NULL },
|
{ "setphase", SEC_GAMEMASTER, false, &ChatHandler::HandleGameObjectPhaseCommand, "", NULL },
|
||||||
{ "target", SEC_GAMEMASTER, false, &ChatHandler::HandleGameObjectTargetCommand, "", NULL },
|
{ "target", SEC_GAMEMASTER, false, &ChatHandler::HandleGameObjectTargetCommand, "", NULL },
|
||||||
{ "turn", SEC_GAMEMASTER, false, &ChatHandler::HandleGameObjectTurnCommand, "", NULL },
|
{ "turn", SEC_GAMEMASTER, false, &ChatHandler::HandleGameObjectTurnCommand, "", NULL },
|
||||||
{ NULL, 0, false, NULL, "", NULL }
|
{ nullptr, 0, false, NULL, "", NULL }
|
||||||
};
|
};
|
||||||
|
|
||||||
static ChatCommand guildCommandTable[] =
|
static ChatCommand guildCommandTable[] =
|
||||||
|
|
@ -413,6 +413,7 @@ ChatCommand* ChatHandler::getCommandTable()
|
||||||
{ "loadedtiles", SEC_GAMEMASTER, false, &ChatHandler::HandleMmapLoadedTilesCommand, "", NULL },
|
{ "loadedtiles", SEC_GAMEMASTER, false, &ChatHandler::HandleMmapLoadedTilesCommand, "", NULL },
|
||||||
{ "stats", SEC_GAMEMASTER, false, &ChatHandler::HandleMmapStatsCommand, "", NULL },
|
{ "stats", SEC_GAMEMASTER, false, &ChatHandler::HandleMmapStatsCommand, "", NULL },
|
||||||
{ "testarea", SEC_GAMEMASTER, false, &ChatHandler::HandleMmapTestArea, "", NULL },
|
{ "testarea", SEC_GAMEMASTER, false, &ChatHandler::HandleMmapTestArea, "", NULL },
|
||||||
|
{ "testheight", SEC_GAMEMASTER, false, &ChatHandler::HandleMmapTestHeight, "", NULL },
|
||||||
{ "", SEC_ADMINISTRATOR, false, &ChatHandler::HandleMmap, "", NULL },
|
{ "", SEC_ADMINISTRATOR, false, &ChatHandler::HandleMmap, "", NULL },
|
||||||
{ NULL, 0, false, NULL, "", NULL }
|
{ NULL, 0, false, NULL, "", NULL }
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -639,6 +639,7 @@ class ChatHandler
|
||||||
bool HandleMmapStatsCommand(char* args);
|
bool HandleMmapStatsCommand(char* args);
|
||||||
bool HandleMmap(char* args);
|
bool HandleMmap(char* args);
|
||||||
bool HandleMmapTestArea(char* args);
|
bool HandleMmapTestArea(char* args);
|
||||||
|
bool HandleMmapTestHeight(char* args);
|
||||||
|
|
||||||
//! Development Commands
|
//! Development Commands
|
||||||
bool HandleSaveAllCommand(char* args);
|
bool HandleSaveAllCommand(char* args);
|
||||||
|
|
|
||||||
|
|
@ -173,7 +173,14 @@ void CreatureLinkingMgr::LoadFromDB()
|
||||||
delete result;
|
delete result;
|
||||||
}
|
}
|
||||||
|
|
||||||
// This function is used to check if a DB-Entry is valid
|
/** This function is used to check if a DB-Entry is valid
|
||||||
|
*
|
||||||
|
* @param byEntry: is the first parameter of the function a npc entry or a npc guid?
|
||||||
|
* @param slaveEntry: dependend on byEntry param this is either the slave's npc-entry or the npc-guid
|
||||||
|
* @param pTmp: Information about the CreatureLinking of the npc. Note that this information may be changed in some cases
|
||||||
|
*
|
||||||
|
* In case of checking by entry and in case of linked spawning and searchRange == 0, pTmp will be changed to keep information about the (unique!) master's db-guid
|
||||||
|
*/
|
||||||
bool CreatureLinkingMgr::IsLinkingEntryValid(uint32 slaveEntry, CreatureLinkingInfo* pTmp, bool byEntry)
|
bool CreatureLinkingMgr::IsLinkingEntryValid(uint32 slaveEntry, CreatureLinkingInfo* pTmp, bool byEntry)
|
||||||
{
|
{
|
||||||
// Basic checks first
|
// Basic checks first
|
||||||
|
|
@ -238,14 +245,22 @@ bool CreatureLinkingMgr::IsLinkingEntryValid(uint32 slaveEntry, CreatureLinkingI
|
||||||
// Check for uniqueness of mob whom is followed, on whom spawning is dependend
|
// Check for uniqueness of mob whom is followed, on whom spawning is dependend
|
||||||
if (pTmp->searchRange == 0 && pTmp->linkingFlag & (FLAG_FOLLOW | FLAG_CANT_SPAWN_IF_BOSS_DEAD | FLAG_CANT_SPAWN_IF_BOSS_ALIVE))
|
if (pTmp->searchRange == 0 && pTmp->linkingFlag & (FLAG_FOLLOW | FLAG_CANT_SPAWN_IF_BOSS_DEAD | FLAG_CANT_SPAWN_IF_BOSS_ALIVE))
|
||||||
{
|
{
|
||||||
// Painfully slow, needs better idea
|
QueryResult* result = WorldDatabase.PQuery("SELECT guid FROM creature WHERE id=%u AND map=%u LIMIT 2", pTmp->masterId, pTmp->mapId);
|
||||||
QueryResult* result = WorldDatabase.PQuery("SELECT COUNT(guid) FROM creature WHERE id=%u AND map=%u", pTmp->masterId, pTmp->mapId);
|
if (!result)
|
||||||
if (result)
|
|
||||||
{
|
{
|
||||||
if ((*result)[0].GetUInt32() > 1)
|
sLog.outErrorDb("`creature_linking_template` has FLAG_FOLLOW, but no master, (entry: %u, map: %u, master: %u)", slaveEntry, pTmp->mapId, pTmp->masterId);
|
||||||
sLog.outErrorDb("`creature_linking_template` has FLAG_FOLLOW, but non unique master, (entry: %u, map: %u, master: %u)", slaveEntry, pTmp->mapId, pTmp->masterId);
|
return false;
|
||||||
delete result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (result->GetRowCount() > 1)
|
||||||
|
{
|
||||||
|
sLog.outErrorDb("`creature_linking_template` has FLAG_FOLLOW, but non unique master, (entry: %u, map: %u, master: %u)", slaveEntry, pTmp->mapId, pTmp->masterId);
|
||||||
|
delete result;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
Field* fields = result->Fetch();
|
||||||
|
pTmp->masterDBGuid = fields[0].GetUInt32();
|
||||||
|
delete result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -265,7 +280,7 @@ enum EventMask
|
||||||
};
|
};
|
||||||
|
|
||||||
// This functions checks if the NPC has linked NPCs for dynamic action
|
// This functions checks if the NPC has linked NPCs for dynamic action
|
||||||
bool CreatureLinkingMgr::IsLinkedEventTrigger(Creature* pCreature)
|
bool CreatureLinkingMgr::IsLinkedEventTrigger(Creature* pCreature) const
|
||||||
{
|
{
|
||||||
// Entry case
|
// Entry case
|
||||||
if (m_eventTriggers.find(pCreature->GetEntry()) != m_eventTriggers.end())
|
if (m_eventTriggers.find(pCreature->GetEntry()) != m_eventTriggers.end())
|
||||||
|
|
@ -284,37 +299,43 @@ bool CreatureLinkingMgr::IsLinkedEventTrigger(Creature* pCreature)
|
||||||
|
|
||||||
// This function check if the NPC is a master to other NPCs
|
// This function check if the NPC is a master to other NPCs
|
||||||
// return true only for masters stored by entry - this prevents adding them to master-holder maps
|
// return true only for masters stored by entry - this prevents adding them to master-holder maps
|
||||||
bool CreatureLinkingMgr::IsLinkedMaster(Creature* pCreature)
|
bool CreatureLinkingMgr::IsLinkedMaster(Creature* pCreature) const
|
||||||
{
|
{
|
||||||
return m_eventTriggers.find(pCreature->GetEntry()) != m_eventTriggers.end();
|
return m_eventTriggers.find(pCreature->GetEntry()) != m_eventTriggers.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
// This function checks if the spawning of this NPC is dependend on other NPCs
|
// This function checks if the spawning of this NPC is dependend on other NPCs
|
||||||
bool CreatureLinkingMgr::IsSpawnedByLinkedMob(Creature* pCreature)
|
bool CreatureLinkingMgr::IsSpawnedByLinkedMob(Creature* pCreature) const
|
||||||
|
{
|
||||||
|
return IsSpawnedByLinkedMob(GetLinkedTriggerInformation(pCreature));
|
||||||
|
}
|
||||||
|
bool CreatureLinkingMgr::IsSpawnedByLinkedMob(CreatureLinkingInfo const* pInfo) const
|
||||||
{
|
{
|
||||||
CreatureLinkingInfo const* pInfo = CreatureLinkingMgr::GetLinkedTriggerInformation(pCreature);
|
|
||||||
|
|
||||||
return pInfo && pInfo->linkingFlag & (FLAG_CANT_SPAWN_IF_BOSS_DEAD | FLAG_CANT_SPAWN_IF_BOSS_ALIVE) && (pInfo->masterDBGuid || pInfo->searchRange);
|
return pInfo && pInfo->linkingFlag & (FLAG_CANT_SPAWN_IF_BOSS_DEAD | FLAG_CANT_SPAWN_IF_BOSS_ALIVE) && (pInfo->masterDBGuid || pInfo->searchRange);
|
||||||
}
|
}
|
||||||
|
|
||||||
// This gives the information of a linked NPC (describes action when its ActionTrigger triggers)
|
// This gives the information of a linked NPC (describes action when its ActionTrigger triggers)
|
||||||
// Depends of the map
|
// Depends of the map
|
||||||
CreatureLinkingInfo const* CreatureLinkingMgr::GetLinkedTriggerInformation(Creature* pCreature)
|
CreatureLinkingInfo const* CreatureLinkingMgr::GetLinkedTriggerInformation(Creature* pCreature) const
|
||||||
|
{
|
||||||
|
return GetLinkedTriggerInformation(pCreature->GetEntry(), pCreature->GetGUIDLow(), pCreature->GetMapId());
|
||||||
|
}
|
||||||
|
CreatureLinkingInfo const* CreatureLinkingMgr::GetLinkedTriggerInformation(uint32 entry, uint32 lowGuid, uint32 mapId) const
|
||||||
{
|
{
|
||||||
// guid case
|
// guid case
|
||||||
CreatureLinkingMapBounds bounds = m_creatureLinkingGuidMap.equal_range(pCreature->GetGUIDLow());
|
CreatureLinkingMapBounds bounds = m_creatureLinkingGuidMap.equal_range(lowGuid);
|
||||||
for (CreatureLinkingMap::const_iterator iter = bounds.first; iter != bounds.second; ++iter)
|
for (CreatureLinkingMap::const_iterator iter = bounds.first; iter != bounds.second;)
|
||||||
return &(iter->second);
|
return &(iter->second);
|
||||||
|
|
||||||
// entry case
|
// entry case
|
||||||
bounds = m_creatureLinkingMap.equal_range(pCreature->GetEntry());
|
bounds = m_creatureLinkingMap.equal_range(entry);
|
||||||
for (CreatureLinkingMap::const_iterator iter = bounds.first; iter != bounds.second; ++iter)
|
for (CreatureLinkingMap::const_iterator iter = bounds.first; iter != bounds.second; ++iter)
|
||||||
{
|
{
|
||||||
if (iter->second.mapId == pCreature->GetMapId())
|
if (iter->second.mapId == mapId)
|
||||||
return &(iter->second);
|
return &(iter->second);
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Function to add slave-NPCs to the holder
|
// Function to add slave-NPCs to the holder
|
||||||
|
|
@ -384,7 +405,7 @@ void CreatureLinkingHolder::AddMasterToHolder(Creature* pCreature)
|
||||||
|
|
||||||
// Check, if already stored
|
// Check, if already stored
|
||||||
BossGuidMapBounds bounds = m_masterGuid.equal_range(pCreature->GetEntry());
|
BossGuidMapBounds bounds = m_masterGuid.equal_range(pCreature->GetEntry());
|
||||||
for (BossGuidMap::iterator itr = bounds.first; itr != bounds.second; ++itr)
|
for (BossGuidMap::const_iterator itr = bounds.first; itr != bounds.second; ++itr)
|
||||||
if (itr->second == pCreature->GetObjectGuid())
|
if (itr->second == pCreature->GetObjectGuid())
|
||||||
return; // Already added
|
return; // Already added
|
||||||
|
|
||||||
|
|
@ -432,11 +453,11 @@ void CreatureLinkingHolder::DoCreatureLinkingEvent(CreatureLinkingEvent eventTyp
|
||||||
{
|
{
|
||||||
if (pInfo->linkingFlag & reverseEventFlagFilter)
|
if (pInfo->linkingFlag & reverseEventFlagFilter)
|
||||||
{
|
{
|
||||||
Creature* pMaster = NULL;
|
Creature* pMaster = nullptr;
|
||||||
if (pInfo->mapId != INVALID_MAP_ID) // entry case
|
if (pInfo->mapId != INVALID_MAP_ID) // entry case
|
||||||
{
|
{
|
||||||
BossGuidMapBounds finds = m_masterGuid.equal_range(pInfo->masterId);
|
BossGuidMapBounds finds = m_masterGuid.equal_range(pInfo->masterId);
|
||||||
for (BossGuidMap::iterator itr = finds.first; itr != finds.second; ++itr)
|
for (BossGuidMap::const_iterator itr = finds.first; itr != finds.second; ++itr)
|
||||||
{
|
{
|
||||||
pMaster = pSource->GetMap()->GetCreature(itr->second);
|
pMaster = pSource->GetMap()->GetCreature(itr->second);
|
||||||
if (pMaster && IsSlaveInRangeOfBoss(pSource, pMaster, pInfo->searchRange))
|
if (pMaster && IsSlaveInRangeOfBoss(pSource, pMaster, pInfo->searchRange))
|
||||||
|
|
@ -589,49 +610,93 @@ void CreatureLinkingHolder::SetFollowing(Creature* pWho, Creature* pWhom)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Function to check if a slave belongs to a boss by range-issue
|
// Function to check if a slave belongs to a boss by range-issue
|
||||||
bool CreatureLinkingHolder::IsSlaveInRangeOfBoss(Creature* pSlave, Creature* pBoss, uint16 searchRange)
|
bool CreatureLinkingHolder::IsSlaveInRangeOfBoss(Creature const* pSlave, Creature const* pBoss, uint16 searchRange) const
|
||||||
|
{
|
||||||
|
float sX, sY, sZ;
|
||||||
|
pSlave->GetRespawnCoord(sX, sY, sZ);
|
||||||
|
return IsSlaveInRangeOfBoss(pBoss, sX, sY, searchRange);
|
||||||
|
}
|
||||||
|
bool CreatureLinkingHolder::IsSlaveInRangeOfBoss(Creature const* pBoss, float sX, float sY, uint16 searchRange) const
|
||||||
{
|
{
|
||||||
if (!searchRange)
|
if (!searchRange)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
// Do some calculations
|
// Do some calculations
|
||||||
float sX, sY, sZ, mX, mY, mZ;
|
float mX, mY, mZ, dx, dy;
|
||||||
pSlave->GetRespawnCoord(sX, sY, sZ);
|
|
||||||
pBoss->GetRespawnCoord(mX, mY, mZ);
|
pBoss->GetRespawnCoord(mX, mY, mZ);
|
||||||
|
|
||||||
float dx, dy;
|
|
||||||
dx = sX - mX;
|
dx = sX - mX;
|
||||||
dy = sY - mY;
|
dy = sY - mY;
|
||||||
|
|
||||||
return dx * dx + dy * dy < searchRange * searchRange;
|
return dx * dx + dy * dy < searchRange * searchRange;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// helper function to check if a lowguid can respawn
|
||||||
|
bool CreatureLinkingHolder::IsRespawnReady(uint32 dbLowGuid, Map* _map) const
|
||||||
|
{
|
||||||
|
time_t respawnTime = _map->GetPersistentState()->GetCreatureRespawnTime(dbLowGuid);
|
||||||
|
return (!respawnTime || respawnTime <= time(nullptr)) && CanSpawn(dbLowGuid, _map, nullptr, 0.0f, 0.0f);
|
||||||
|
}
|
||||||
|
|
||||||
// Function to check if a passive spawning condition is met
|
// Function to check if a passive spawning condition is met
|
||||||
bool CreatureLinkingHolder::CanSpawn(Creature* pCreature)
|
bool CreatureLinkingHolder::CanSpawn(Creature* pCreature) const
|
||||||
{
|
{
|
||||||
CreatureLinkingInfo const* pInfo = sCreatureLinkingMgr.GetLinkedTriggerInformation(pCreature);
|
CreatureLinkingInfo const* pInfo = sCreatureLinkingMgr.GetLinkedTriggerInformation(pCreature);
|
||||||
if (!pInfo)
|
if (!pInfo)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
float sx, sy, sz;
|
||||||
|
pCreature->GetRespawnCoord(sx, sy, sz);
|
||||||
|
return CanSpawn(0, pCreature->GetMap(), pInfo, sx, sy);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Worker function to check if a spawning condition is met
|
||||||
|
*
|
||||||
|
* This function is used directly from above function, and for recursive use
|
||||||
|
* in case of recursive use it is used only on _map with information of lowGuid.
|
||||||
|
*
|
||||||
|
* @param lowGuid (only relevant in case of recursive uses) -- db-guid of the npc that is checked
|
||||||
|
* @param _map Map on which things are checked
|
||||||
|
* @param pInfo (only shipped in case of initial use) -- used as marker of first use, also in first use filled directly
|
||||||
|
* @param sx, sy (spawn position of the checked npc with initial use)
|
||||||
|
*/
|
||||||
|
bool CreatureLinkingHolder::CanSpawn(uint32 lowGuid, Map* _map, CreatureLinkingInfo const* pInfo, float sx, float sy) const
|
||||||
|
{
|
||||||
|
if (!pInfo) // Prepare data for recursive use
|
||||||
|
{
|
||||||
|
CreatureData const* data = sObjectMgr.GetCreatureData(lowGuid);
|
||||||
|
if (!data)
|
||||||
|
return true;
|
||||||
|
pInfo = sCreatureLinkingMgr.GetLinkedTriggerInformation(data->id, lowGuid, data->mapid);
|
||||||
|
if (!pInfo)
|
||||||
|
return true;
|
||||||
|
// Has lowGuid npc actually spawning linked?
|
||||||
|
if (!sCreatureLinkingMgr.IsSpawnedByLinkedMob(pInfo))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
sx = data->posX; // Fill position data
|
||||||
|
sy = data->posY;
|
||||||
|
}
|
||||||
|
|
||||||
if (pInfo->searchRange == 0) // Map wide case
|
if (pInfo->searchRange == 0) // Map wide case
|
||||||
{
|
{
|
||||||
if (!pInfo->masterDBGuid)
|
if (!pInfo->masterDBGuid)
|
||||||
return false; // This should never happen
|
return false; // This should never happen
|
||||||
|
|
||||||
if (pInfo->linkingFlag & FLAG_CANT_SPAWN_IF_BOSS_DEAD)
|
if (pInfo->linkingFlag & FLAG_CANT_SPAWN_IF_BOSS_DEAD)
|
||||||
return pCreature->GetMap()->GetPersistentState()->GetCreatureRespawnTime(pInfo->masterDBGuid) == 0;
|
return IsRespawnReady(pInfo->masterDBGuid, _map);
|
||||||
else if (pInfo->linkingFlag & FLAG_CANT_SPAWN_IF_BOSS_ALIVE)
|
else if (pInfo->linkingFlag & FLAG_CANT_SPAWN_IF_BOSS_ALIVE)
|
||||||
return pCreature->GetMap()->GetPersistentState()->GetCreatureRespawnTime(pInfo->masterDBGuid) > 0;
|
return !IsRespawnReady(pInfo->masterDBGuid, _map);
|
||||||
else
|
else
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Search for nearby master
|
// Search for nearby master
|
||||||
BossGuidMapBounds finds = m_masterGuid.equal_range(pInfo->masterId);
|
BossGuidMapBounds finds = m_masterGuid.equal_range(pInfo->masterId);
|
||||||
for (BossGuidMap::iterator itr = finds.first; itr != finds.second; ++itr)
|
for (BossGuidMap::const_iterator itr = finds.first; itr != finds.second; ++itr)
|
||||||
{
|
{
|
||||||
Creature* pMaster = pCreature->GetMap()->GetCreature(itr->second);
|
Creature* pMaster = _map->GetCreature(itr->second);
|
||||||
if (pMaster && IsSlaveInRangeOfBoss(pCreature, pMaster, pInfo->searchRange))
|
if (pMaster && IsSlaveInRangeOfBoss(pMaster, sx, sy, pInfo->searchRange))
|
||||||
{
|
{
|
||||||
if (pInfo->linkingFlag & FLAG_CANT_SPAWN_IF_BOSS_DEAD)
|
if (pInfo->linkingFlag & FLAG_CANT_SPAWN_IF_BOSS_DEAD)
|
||||||
return pMaster->IsAlive();
|
return pMaster->IsAlive();
|
||||||
|
|
@ -652,11 +717,11 @@ bool CreatureLinkingHolder::TryFollowMaster(Creature* pCreature)
|
||||||
if (!pInfo || !(pInfo->linkingFlag & FLAG_FOLLOW))
|
if (!pInfo || !(pInfo->linkingFlag & FLAG_FOLLOW))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
Creature* pMaster = NULL;
|
Creature* pMaster = nullptr;
|
||||||
if (pInfo->mapId != INVALID_MAP_ID) // entry case
|
if (pInfo->mapId != INVALID_MAP_ID) // entry case
|
||||||
{
|
{
|
||||||
BossGuidMapBounds finds = m_masterGuid.equal_range(pInfo->masterId);
|
BossGuidMapBounds finds = m_masterGuid.equal_range(pInfo->masterId);
|
||||||
for (BossGuidMap::iterator itr = finds.first; itr != finds.second; ++itr)
|
for (BossGuidMap::const_iterator itr = finds.first; itr != finds.second; ++itr)
|
||||||
{
|
{
|
||||||
pMaster = pCreature->GetMap()->GetCreature(itr->second);
|
pMaster = pCreature->GetMap()->GetCreature(itr->second);
|
||||||
if (pMaster && IsSlaveInRangeOfBoss(pCreature, pMaster, pInfo->searchRange))
|
if (pMaster && IsSlaveInRangeOfBoss(pCreature, pMaster, pInfo->searchRange))
|
||||||
|
|
|
||||||
|
|
@ -48,6 +48,7 @@
|
||||||
|
|
||||||
class Unit;
|
class Unit;
|
||||||
class Creature;
|
class Creature;
|
||||||
|
class Map;
|
||||||
|
|
||||||
// enum on which Events an action for linked NPCs can trigger
|
// enum on which Events an action for linked NPCs can trigger
|
||||||
enum CreatureLinkingEvent
|
enum CreatureLinkingEvent
|
||||||
|
|
@ -111,17 +112,19 @@ class CreatureLinkingMgr
|
||||||
|
|
||||||
public: // Accessors
|
public: // Accessors
|
||||||
// This functions checks if the NPC triggers actions for other NPCs
|
// This functions checks if the NPC triggers actions for other NPCs
|
||||||
bool IsLinkedEventTrigger(Creature* pCreature);
|
bool IsLinkedEventTrigger(Creature* pCreature) const;
|
||||||
|
|
||||||
// This function checks if the NPC is a master NPC.
|
// This function checks if the NPC is a master NPC.
|
||||||
bool IsLinkedMaster(Creature* pCreature);
|
bool IsLinkedMaster(Creature* pCreature) const;
|
||||||
|
|
||||||
// This function checks if the spawning of this NPC is dependend on other NPCs
|
// This function checks if the spawning of this NPC is dependend on other NPCs
|
||||||
bool IsSpawnedByLinkedMob(Creature* pCreature);
|
bool IsSpawnedByLinkedMob(Creature* pCreature) const;
|
||||||
|
bool IsSpawnedByLinkedMob(CreatureLinkingInfo const* pInfo) const;
|
||||||
|
|
||||||
// This gives the information of a linked NPC (describes action when its ActionTrigger triggers)
|
// This gives the information of a linked NPC (describes action when its ActionTrigger triggers)
|
||||||
// Depends of the map
|
// Depends of the map
|
||||||
CreatureLinkingInfo const* GetLinkedTriggerInformation(Creature* pCreature);
|
CreatureLinkingInfo const* GetLinkedTriggerInformation(Creature* pCreature) const;
|
||||||
|
CreatureLinkingInfo const* GetLinkedTriggerInformation(uint32 entry, uint32 lowGuid, uint32 mapId) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
typedef std::multimap < uint32 /*slaveEntry*/, CreatureLinkingInfo > CreatureLinkingMap;
|
typedef std::multimap < uint32 /*slaveEntry*/, CreatureLinkingInfo > CreatureLinkingMap;
|
||||||
|
|
@ -162,7 +165,7 @@ class CreatureLinkingHolder
|
||||||
void DoCreatureLinkingEvent(CreatureLinkingEvent eventType, Creature* pSource, Unit* pEnemy = NULL);
|
void DoCreatureLinkingEvent(CreatureLinkingEvent eventType, Creature* pSource, Unit* pEnemy = NULL);
|
||||||
|
|
||||||
// Function to check if a passive spawning condition is met
|
// Function to check if a passive spawning condition is met
|
||||||
bool CanSpawn(Creature* pCreature);
|
bool CanSpawn(Creature* pCreature) const;
|
||||||
|
|
||||||
// This function lets a slave refollow his master
|
// This function lets a slave refollow his master
|
||||||
bool TryFollowMaster(Creature* pCreature);
|
bool TryFollowMaster(Creature* pCreature);
|
||||||
|
|
@ -185,7 +188,7 @@ class CreatureLinkingHolder
|
||||||
typedef std::multimap < uint32 /*masterEntryOrGuid*/, InfoAndGuids > HolderMap;
|
typedef std::multimap < uint32 /*masterEntryOrGuid*/, InfoAndGuids > HolderMap;
|
||||||
typedef std::pair<HolderMap::iterator, HolderMap::iterator> HolderMapBounds;
|
typedef std::pair<HolderMap::iterator, HolderMap::iterator> HolderMapBounds;
|
||||||
typedef std::multimap < uint32 /*Entry*/, ObjectGuid > BossGuidMap;
|
typedef std::multimap < uint32 /*Entry*/, ObjectGuid > BossGuidMap;
|
||||||
typedef std::pair<BossGuidMap::iterator, BossGuidMap::iterator> BossGuidMapBounds;
|
typedef std::pair<BossGuidMap::const_iterator, BossGuidMap::const_iterator> BossGuidMapBounds;
|
||||||
|
|
||||||
// Helper function, to process a slave list
|
// Helper function, to process a slave list
|
||||||
void ProcessSlaveGuidList(CreatureLinkingEvent eventType, Creature* pSource, uint32 flag, uint16 searchRange, GuidList& slaveGuidList, Unit* pEnemy);
|
void ProcessSlaveGuidList(CreatureLinkingEvent eventType, Creature* pSource, uint32 flag, uint16 searchRange, GuidList& slaveGuidList, Unit* pEnemy);
|
||||||
|
|
@ -194,7 +197,12 @@ class CreatureLinkingHolder
|
||||||
// Helper function to set following
|
// Helper function to set following
|
||||||
void SetFollowing(Creature* pWho, Creature* pWhom);
|
void SetFollowing(Creature* pWho, Creature* pWhom);
|
||||||
// Helper function to return if a slave is in range of a boss
|
// Helper function to return if a slave is in range of a boss
|
||||||
bool IsSlaveInRangeOfBoss(Creature* pSlave, Creature* pBoss, uint16 searchRange);
|
bool IsSlaveInRangeOfBoss(Creature const* pSlave, Creature const* pBoss, uint16 searchRange) const;
|
||||||
|
bool IsSlaveInRangeOfBoss(Creature const* pBoss, float slaveX, float slaveY, uint16 searchRange) const;
|
||||||
|
// Another helper function
|
||||||
|
bool IsRespawnReady(uint32 dbLowGuid, Map* _map) const;
|
||||||
|
// Helper function for recursive spawning-checks of an additional linked
|
||||||
|
bool CanSpawn(uint32 lowGuid, Map* _map, CreatureLinkingInfo const* pInfo, float sx, float sy) const;
|
||||||
|
|
||||||
// Storage of Data (boss, flag, searchRange, GuidList) for action triggering
|
// Storage of Data (boss, flag, searchRange, GuidList) for action triggering
|
||||||
HolderMap m_holderMap;
|
HolderMap m_holderMap;
|
||||||
|
|
|
||||||
|
|
@ -174,7 +174,7 @@ namespace MaNGOS
|
||||||
|
|
||||||
inline bool IsValidMapCoord(float c)
|
inline bool IsValidMapCoord(float c)
|
||||||
{
|
{
|
||||||
return finite(c) && (std::fabs(c) <= MAP_HALFSIZE - 0.5);
|
return std::isfinite(c) && (std::fabs(c) <= MAP_HALFSIZE - 0.5);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool IsValidMapCoord(float x, float y)
|
inline bool IsValidMapCoord(float x, float y)
|
||||||
|
|
@ -184,12 +184,12 @@ namespace MaNGOS
|
||||||
|
|
||||||
inline bool IsValidMapCoord(float x, float y, float z)
|
inline bool IsValidMapCoord(float x, float y, float z)
|
||||||
{
|
{
|
||||||
return IsValidMapCoord(x, y) && finite(z);
|
return IsValidMapCoord(x, y) && std::isfinite(z);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool IsValidMapCoord(float x, float y, float z, float o)
|
inline bool IsValidMapCoord(float x, float y, float z, float o)
|
||||||
{
|
{
|
||||||
return IsValidMapCoord(x, y, z) && finite(o);
|
return IsValidMapCoord(x, y, z) && std::isfinite(o);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -42,6 +42,9 @@ char const* MAP_AREA_MAGIC = "AREA";
|
||||||
char const* MAP_HEIGHT_MAGIC = "MHGT";
|
char const* MAP_HEIGHT_MAGIC = "MHGT";
|
||||||
char const* MAP_LIQUID_MAGIC = "MLIQ";
|
char const* MAP_LIQUID_MAGIC = "MLIQ";
|
||||||
|
|
||||||
|
static uint16 holetab_h[4] = { 0x1111, 0x2222, 0x4444, 0x8888 };
|
||||||
|
static uint16 holetab_v[4] = { 0x000F, 0x00F0, 0x0F00, 0xF000 };
|
||||||
|
|
||||||
GridMap::GridMap()
|
GridMap::GridMap()
|
||||||
{
|
{
|
||||||
m_flags = 0;
|
m_flags = 0;
|
||||||
|
|
@ -1061,6 +1064,23 @@ bool TerrainInfo::IsInWater(float x, float y, float pZ, GridMapLiquidData* data)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// check if creature is in water and have enough space to swim
|
||||||
|
bool TerrainInfo::IsSwimmable(float x, float y, float pZ, float radius /*= 1.5f*/, GridMapLiquidData* data /*= 0*/) const
|
||||||
|
{
|
||||||
|
// Check surface in x, y point for liquid
|
||||||
|
if (const_cast<TerrainInfo*>(this)->GetGrid(x, y))
|
||||||
|
{
|
||||||
|
GridMapLiquidData liquid_status;
|
||||||
|
GridMapLiquidData* liquid_ptr = data ? data : &liquid_status;
|
||||||
|
if (getLiquidStatus(x, y, pZ, MAP_ALL_LIQUIDS, liquid_ptr))
|
||||||
|
{
|
||||||
|
if (liquid_ptr->level - liquid_ptr->depth_level > radius) // is unit have enough space to swim
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
bool TerrainInfo::IsUnderWater(float x, float y, float z) const
|
bool TerrainInfo::IsUnderWater(float x, float y, float z) const
|
||||||
{
|
{
|
||||||
if (const_cast<TerrainInfo*>(this)->GetGrid(x, y))
|
if (const_cast<TerrainInfo*>(this)->GetGrid(x, y))
|
||||||
|
|
|
||||||
|
|
@ -231,6 +231,7 @@ class TerrainInfo : public Referencable<AtomicLong>
|
||||||
float GetWaterLevel(float x, float y, float z, float* pGround = NULL) const;
|
float GetWaterLevel(float x, float y, float z, float* pGround = NULL) const;
|
||||||
float GetWaterOrGroundLevel(float x, float y, float z, float* pGround = NULL, bool swim = false) const;
|
float GetWaterOrGroundLevel(float x, float y, float z, float* pGround = NULL, bool swim = false) const;
|
||||||
bool IsInWater(float x, float y, float z, GridMapLiquidData* data = 0) const;
|
bool IsInWater(float x, float y, float z, GridMapLiquidData* data = 0) const;
|
||||||
|
bool IsSwimmable(float x, float y, float pZ, float radius = 1.5f, GridMapLiquidData* data = nullptr) const;
|
||||||
bool IsUnderWater(float x, float y, float z) const;
|
bool IsUnderWater(float x, float y, float z) const;
|
||||||
|
|
||||||
GridMapLiquidStatus getLiquidStatus(float x, float y, float z, uint8 ReqLiquidType, GridMapLiquidData* data = 0) const;
|
GridMapLiquidStatus getLiquidStatus(float x, float y, float z, uint8 ReqLiquidType, GridMapLiquidData* data = 0) const;
|
||||||
|
|
|
||||||
|
|
@ -57,7 +57,9 @@ enum LootMethod
|
||||||
ROUND_ROBIN = 1,
|
ROUND_ROBIN = 1,
|
||||||
MASTER_LOOT = 2,
|
MASTER_LOOT = 2,
|
||||||
GROUP_LOOT = 3,
|
GROUP_LOOT = 3,
|
||||||
NEED_BEFORE_GREED = 4
|
NEED_BEFORE_GREED = 4,
|
||||||
|
|
||||||
|
NOT_GROUP_TYPE_LOOT = 5 // internal use only
|
||||||
};
|
};
|
||||||
|
|
||||||
enum RollVote
|
enum RollVote
|
||||||
|
|
|
||||||
|
|
@ -71,7 +71,7 @@ bool WorldSession::CheckMailBox(ObjectGuid guid)
|
||||||
Creature* creature = GetPlayer()->GetNPCIfCanInteractWith(guid, UNIT_NPC_FLAG_NONE);
|
Creature* creature = GetPlayer()->GetNPCIfCanInteractWith(guid, UNIT_NPC_FLAG_NONE);
|
||||||
if (!creature)
|
if (!creature)
|
||||||
{
|
{
|
||||||
DEBUG_LOG("%s not found or %s can't interact with him.", creature->GetGuidStr().c_str(), GetPlayer()->GetGuidStr().c_str());
|
DEBUG_LOG("%s not found or %s can't interact with him.", guid.GetString().c_str(), GetPlayer()->GetGuidStr().c_str());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -298,12 +298,15 @@ bool Map::EnsureGridLoaded(const Cell& cell)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Map::LoadGrid(const Cell& cell, bool no_unload)
|
void Map::ForceLoadGrid(float x, float y)
|
||||||
{
|
{
|
||||||
EnsureGridLoaded(cell);
|
if (!IsLoaded(x, y))
|
||||||
|
{
|
||||||
if (no_unload)
|
CellPair p = MaNGOS::ComputeCellPair(x, y);
|
||||||
|
Cell cell(p);
|
||||||
|
EnsureGridLoadedAtEnter(cell);
|
||||||
getNGrid(cell.GridX(), cell.GridY())->setUnloadExplicitLock(true);
|
getNGrid(cell.GridX(), cell.GridY())->setUnloadExplicitLock(true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Map::Add(Player* player)
|
bool Map::Add(Player* player)
|
||||||
|
|
@ -2116,6 +2119,61 @@ bool Map::GetHitPosition(float srcX, float srcY, float srcZ, float& destX, float
|
||||||
return result0 || result1;
|
return result0 || result1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Find an height within a reasonable range of provided Z. This method may fail so we have to handle that case.
|
||||||
|
bool Map::GetHeightInRange(uint32 phasemask, float x, float y, float& z, float maxSearchDist /*= 4.0f*/) const
|
||||||
|
{
|
||||||
|
float height, vmapHeight, mapHeight;
|
||||||
|
vmapHeight = VMAP_INVALID_HEIGHT_VALUE;
|
||||||
|
|
||||||
|
VMAP::IVMapManager* vmgr = VMAP::VMapFactory::createOrGetVMapManager();
|
||||||
|
if (!vmgr->isLineOfSightCalcEnabled())
|
||||||
|
vmgr = nullptr;
|
||||||
|
|
||||||
|
if (vmgr)
|
||||||
|
{
|
||||||
|
// pure vmap search
|
||||||
|
vmapHeight = vmgr->getHeight(i_id, x, y, z + 2.0f, maxSearchDist + 2.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
// find raw height from .map file on X,Y coordinates
|
||||||
|
if (GridMap* gmap = const_cast<TerrainInfo*>(m_TerrainData)->GetGrid(x, y)) // TODO:: find a way to remove that const_cast
|
||||||
|
mapHeight = gmap->getHeight(x, y);
|
||||||
|
|
||||||
|
float diffMaps = fabs(fabs(z) - fabs(mapHeight));
|
||||||
|
float diffVmaps = fabs(fabs(z) - fabs(vmapHeight));
|
||||||
|
if (diffVmaps < maxSearchDist)
|
||||||
|
{
|
||||||
|
if (diffMaps < maxSearchDist)
|
||||||
|
{
|
||||||
|
// well we simply have to take the highest as normally there we cannot be on top of cavern is maxSearchDist is not too big
|
||||||
|
if (vmapHeight > mapHeight)
|
||||||
|
height = vmapHeight;
|
||||||
|
else
|
||||||
|
height = mapHeight;
|
||||||
|
|
||||||
|
//sLog.outString("vmap %5.4f, map %5.4f, height %5.4f", vmapHeight, mapHeight, height);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//sLog.outString("vmap %5.4f", vmapHeight);
|
||||||
|
height = vmapHeight;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (diffMaps < maxSearchDist)
|
||||||
|
{
|
||||||
|
//sLog.outString("map %5.4f", mapHeight);
|
||||||
|
height = mapHeight;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
z = std::max<float>(height, m_dyn_tree.getHeight(x, y, height + 1.0f, maxSearchDist, phasemask));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
float Map::GetHeight(uint32 phasemask, float x, float y, float z) const
|
float Map::GetHeight(uint32 phasemask, float x, float y, float z) const
|
||||||
{
|
{
|
||||||
float staticHeight = m_TerrainData->GetHeightStatic(x, y, z);
|
float staticHeight = m_TerrainData->GetHeightStatic(x, y, z);
|
||||||
|
|
|
||||||
|
|
@ -157,7 +157,7 @@ class Map : public GridRefManager<NGridType>
|
||||||
|
|
||||||
bool GetUnloadLock(const GridPair& p) const { return getNGrid(p.x_coord, p.y_coord)->getUnloadLock(); }
|
bool GetUnloadLock(const GridPair& p) const { return getNGrid(p.x_coord, p.y_coord)->getUnloadLock(); }
|
||||||
void SetUnloadLock(const GridPair& p, bool on) { getNGrid(p.x_coord, p.y_coord)->setUnloadExplicitLock(on); }
|
void SetUnloadLock(const GridPair& p, bool on) { getNGrid(p.x_coord, p.y_coord)->setUnloadExplicitLock(on); }
|
||||||
void LoadGrid(const Cell& cell, bool no_unload = false);
|
void ForceLoadGrid(float x, float y);
|
||||||
bool UnloadGrid(const uint32& x, const uint32& y, bool pForce);
|
bool UnloadGrid(const uint32& x, const uint32& y, bool pForce);
|
||||||
virtual void UnloadAll(bool pForce);
|
virtual void UnloadAll(bool pForce);
|
||||||
|
|
||||||
|
|
@ -194,7 +194,6 @@ class Map : public GridRefManager<NGridType>
|
||||||
MapDifficultyEntry const* GetMapDifficulty() const; // dependent from map difficulty
|
MapDifficultyEntry const* GetMapDifficulty() const; // dependent from map difficulty
|
||||||
|
|
||||||
bool Instanceable() const { return i_mapEntry && i_mapEntry->Instanceable(); }
|
bool Instanceable() const { return i_mapEntry && i_mapEntry->Instanceable(); }
|
||||||
// NOTE: this duplicate of Instanceable(), but Instanceable() can be changed when BG also will be instanceable
|
|
||||||
bool IsDungeon() const { return i_mapEntry && i_mapEntry->IsDungeon(); }
|
bool IsDungeon() const { return i_mapEntry && i_mapEntry->IsDungeon(); }
|
||||||
bool IsRaid() const { return i_mapEntry && i_mapEntry->IsRaid(); }
|
bool IsRaid() const { return i_mapEntry && i_mapEntry->IsRaid(); }
|
||||||
bool IsHeroic() const { return IsRaid() ? i_spawnMode >= RAID_DIFFICULTY_10MAN_HEROIC : i_spawnMode >= DUNGEON_DIFFICULTY_HEROIC; }
|
bool IsHeroic() const { return IsRaid() ? i_spawnMode >= RAID_DIFFICULTY_10MAN_HEROIC : i_spawnMode >= DUNGEON_DIFFICULTY_HEROIC; }
|
||||||
|
|
@ -203,6 +202,7 @@ class Map : public GridRefManager<NGridType>
|
||||||
bool IsBattleGround() const { return i_mapEntry && i_mapEntry->IsBattleGround(); }
|
bool IsBattleGround() const { return i_mapEntry && i_mapEntry->IsBattleGround(); }
|
||||||
bool IsBattleArena() const { return i_mapEntry && i_mapEntry->IsBattleArena(); }
|
bool IsBattleArena() const { return i_mapEntry && i_mapEntry->IsBattleArena(); }
|
||||||
bool IsBattleGroundOrArena() const { return i_mapEntry && i_mapEntry->IsBattleGroundOrArena(); }
|
bool IsBattleGroundOrArena() const { return i_mapEntry && i_mapEntry->IsBattleGroundOrArena(); }
|
||||||
|
bool IsContinent() const { return i_mapEntry && i_mapEntry->IsContinent(); }
|
||||||
|
|
||||||
// can't be NULL for loaded map
|
// can't be NULL for loaded map
|
||||||
MapPersistentState* GetPersistentState() const { return m_persistentState; }
|
MapPersistentState* GetPersistentState() const { return m_persistentState; }
|
||||||
|
|
|
||||||
|
|
@ -92,30 +92,30 @@ void MapManager::InitializeVisibilityDistanceInfo()
|
||||||
(*iter).second->InitVisibilityDistance();
|
(*iter).second->InitVisibilityDistance();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// @param id - MapId of the to be created map. @param obj WorldObject for which the map is to be created. Must be player for Instancable maps.
|
||||||
Map* MapManager::CreateMap(uint32 id, const WorldObject* obj)
|
Map* MapManager::CreateMap(uint32 id, const WorldObject* obj)
|
||||||
{
|
{
|
||||||
MANGOS_ASSERT(obj);
|
|
||||||
// if(!obj->IsInWorld()) sLog.outError("GetMap: called for map %d with object (typeid %d, guid %d, mapid %d, instanceid %d) who is not in world!", id, obj->GetTypeId(), obj->GetGUIDLow(), obj->GetMapId(), obj->GetInstanceId());
|
|
||||||
Guard _guard(*this);
|
Guard _guard(*this);
|
||||||
|
|
||||||
Map* m = NULL;
|
Map* m = nullptr;
|
||||||
|
|
||||||
const MapEntry* entry = sMapStore.LookupEntry(id);
|
const MapEntry* entry = sMapStore.LookupEntry(id);
|
||||||
if (!entry)
|
if (!entry)
|
||||||
return NULL;
|
return nullptr;
|
||||||
|
|
||||||
if (entry->Instanceable())
|
if (entry->Instanceable())
|
||||||
{
|
{
|
||||||
MANGOS_ASSERT(obj->GetTypeId() == TYPEID_PLAYER);
|
MANGOS_ASSERT(obj && obj->GetTypeId() == TYPEID_PLAYER);
|
||||||
// create DungeonMap object
|
// create DungeonMap object
|
||||||
if (obj->GetTypeId() == TYPEID_PLAYER)
|
m = CreateInstance(id, (Player*)obj);
|
||||||
m = CreateInstance(id, (Player*)obj);
|
// Load active objects for this map
|
||||||
|
sObjectMgr.LoadActiveEntities(m);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// create regular non-instanceable map
|
// create regular non-instanceable map
|
||||||
m = FindMap(id);
|
m = FindMap(id);
|
||||||
if (m == NULL)
|
if (m == nullptr)
|
||||||
{
|
{
|
||||||
m = new WorldMap(id, i_gridCleanUpDelay);
|
m = new WorldMap(id, i_gridCleanUpDelay);
|
||||||
// add map into container
|
// add map into container
|
||||||
|
|
|
||||||
|
|
@ -94,7 +94,6 @@ class MapManager : public MaNGOS::Singleton<MapManager, MaNGOS::ClassLevelLockab
|
||||||
i_timer.Reset();
|
i_timer.Reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
// void LoadGrid(int mapid, int instId, float x, float y, const WorldObject* obj, bool no_unload = false);
|
|
||||||
void UnloadAll();
|
void UnloadAll();
|
||||||
|
|
||||||
static bool ExistMapAndVMap(uint32 mapid, float x, float y);
|
static bool ExistMapAndVMap(uint32 mapid, float x, float y);
|
||||||
|
|
|
||||||
|
|
@ -280,7 +280,6 @@ void WorldSession::HandleLogoutRequestOpcode(WorldPacket & /*recv_data*/)
|
||||||
|
|
||||||
// Can not logout if...
|
// Can not logout if...
|
||||||
if (GetPlayer()->IsInCombat() || //...is in combat
|
if (GetPlayer()->IsInCombat() || //...is in combat
|
||||||
GetPlayer()->duel || //...is in Duel
|
|
||||||
//...is jumping ...is falling
|
//...is jumping ...is falling
|
||||||
GetPlayer()->m_movementInfo.HasMovementFlag(MovementFlags(MOVEFLAG_FALLING | MOVEFLAG_FALLINGFAR)))
|
GetPlayer()->m_movementInfo.HasMovementFlag(MovementFlags(MOVEFLAG_FALLING | MOVEFLAG_FALLINGFAR)))
|
||||||
{
|
{
|
||||||
|
|
@ -1082,12 +1081,16 @@ void WorldSession::HandleInspectOpcode(WorldPacket& recv_data)
|
||||||
recv_data >> guid;
|
recv_data >> guid;
|
||||||
DEBUG_LOG("Inspected guid is %s", guid.GetString().c_str());
|
DEBUG_LOG("Inspected guid is %s", guid.GetString().c_str());
|
||||||
|
|
||||||
_player->SetSelectionGuid(guid);
|
|
||||||
|
|
||||||
Player* plr = sObjectMgr.GetPlayer(guid);
|
Player* plr = sObjectMgr.GetPlayer(guid);
|
||||||
if (!plr) // wrong player
|
if (!plr) // wrong player
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (!_player->IsWithinDistInMap(plr, INSPECT_DISTANCE, false))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (_player->IsHostileTo(plr))
|
||||||
|
return;
|
||||||
|
|
||||||
WorldPacket data(SMSG_INSPECT_RESULTS, 50);
|
WorldPacket data(SMSG_INSPECT_RESULTS, 50);
|
||||||
data << plr->GetObjectGuid();
|
data << plr->GetObjectGuid();
|
||||||
|
|
||||||
|
|
@ -1119,13 +1122,18 @@ void WorldSession::HandleInspectHonorStatsOpcode(WorldPacket& recv_data)
|
||||||
recv_data.ReadGuidBytes<4, 7, 0, 5, 1, 6, 2, 3>(guid);
|
recv_data.ReadGuidBytes<4, 7, 0, 5, 1, 6, 2, 3>(guid);
|
||||||
|
|
||||||
Player* player = sObjectMgr.GetPlayer(guid);
|
Player* player = sObjectMgr.GetPlayer(guid);
|
||||||
|
|
||||||
if (!player)
|
if (!player)
|
||||||
{
|
{
|
||||||
sLog.outError("InspectHonorStats: WTF, player not found...");
|
sLog.outError("InspectHonorStats: WTF, player not found...");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!_player->IsWithinDistInMap(player, INSPECT_DISTANCE, false))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (_player->IsHostileTo(player))
|
||||||
|
return;
|
||||||
|
|
||||||
WorldPacket data(SMSG_INSPECT_HONOR_STATS, 18);
|
WorldPacket data(SMSG_INSPECT_HONOR_STATS, 18);
|
||||||
data.WriteGuidMask<4, 3, 6, 2, 5, 0, 7, 1>(player->GetObjectGuid());
|
data.WriteGuidMask<4, 3, 6, 2, 5, 0, 7, 1>(player->GetObjectGuid());
|
||||||
data << uint8(0); // rank
|
data << uint8(0); // rank
|
||||||
|
|
@ -1520,8 +1528,17 @@ void WorldSession::HandleQueryInspectAchievementsOpcode(WorldPacket& recv_data)
|
||||||
|
|
||||||
recv_data >> guid.ReadAsPacked();
|
recv_data >> guid.ReadAsPacked();
|
||||||
|
|
||||||
if (Player* player = sObjectMgr.GetPlayer(guid))
|
Player* player = sObjectMgr.GetPlayer(guid);
|
||||||
player->GetAchievementMgr().SendRespondInspectAchievements(_player);
|
if (!player)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!_player->IsWithinDistInMap(player, INSPECT_DISTANCE, false))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (_player->IsHostileTo(player))
|
||||||
|
return;
|
||||||
|
|
||||||
|
player->GetAchievementMgr().SendRespondInspectAchievements(_player);
|
||||||
}
|
}
|
||||||
|
|
||||||
void WorldSession::HandleUITimeRequestOpcode(WorldPacket& /*recv_data*/)
|
void WorldSession::HandleUITimeRequestOpcode(WorldPacket& /*recv_data*/)
|
||||||
|
|
|
||||||
|
|
@ -477,6 +477,20 @@ void WorldSession::SendSpiritResurrect()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void WorldSession::HandleReturnToGraveyardOpcode(WorldPacket& recv_data)
|
||||||
|
{
|
||||||
|
Corpse* corpse = _player->GetCorpse();
|
||||||
|
if (!corpse)
|
||||||
|
return;
|
||||||
|
|
||||||
|
WorldSafeLocsEntry const* corpseGrave = sObjectMgr.GetClosestGraveYard(corpse->GetPositionX(), corpse->GetPositionY(),
|
||||||
|
corpse->GetPositionZ(), corpse->GetMapId(), _player->GetTeam());
|
||||||
|
if (!corpseGrave)
|
||||||
|
return;
|
||||||
|
|
||||||
|
_player->TeleportTo(corpseGrave->map_id, corpseGrave->x, corpseGrave->y, corpseGrave->z, _player->GetOrientation());
|
||||||
|
}
|
||||||
|
|
||||||
void WorldSession::HandleBinderActivateOpcode(WorldPacket& recv_data)
|
void WorldSession::HandleBinderActivateOpcode(WorldPacket& recv_data)
|
||||||
{
|
{
|
||||||
ObjectGuid npcGuid;
|
ObjectGuid npcGuid;
|
||||||
|
|
|
||||||
|
|
@ -43,6 +43,10 @@ void WorldSession::HandleLearnTalentOpcode(WorldPacket& recv_data)
|
||||||
_player->SendTalentsInfoData(false);
|
_player->SendTalentsInfoData(false);
|
||||||
else
|
else
|
||||||
sLog.outError("WorldSession::HandleLearnTalentOpcode: learn talent %u rank %u failed for %s (account %u)", talent_id, requested_rank, GetPlayerName(), GetAccountId());
|
sLog.outError("WorldSession::HandleLearnTalentOpcode: learn talent %u rank %u failed for %s (account %u)", talent_id, requested_rank, GetPlayerName(), GetAccountId());
|
||||||
|
|
||||||
|
// if player has a pet, update owner talent auras
|
||||||
|
if (_player->GetPet())
|
||||||
|
_player->GetPet()->CastOwnerTalentAuras();
|
||||||
}
|
}
|
||||||
|
|
||||||
void WorldSession::HandleLearnPreviewTalents(WorldPacket& recvPacket)
|
void WorldSession::HandleLearnPreviewTalents(WorldPacket& recvPacket)
|
||||||
|
|
@ -84,6 +88,10 @@ void WorldSession::HandleLearnPreviewTalents(WorldPacket& recvPacket)
|
||||||
}
|
}
|
||||||
|
|
||||||
_player->SendTalentsInfoData(false);
|
_player->SendTalentsInfoData(false);
|
||||||
|
|
||||||
|
// if player has a pet, update owner talent auras
|
||||||
|
if (_player->GetPet())
|
||||||
|
_player->GetPet()->CastOwnerTalentAuras();
|
||||||
}
|
}
|
||||||
|
|
||||||
void WorldSession::HandleTalentWipeConfirmOpcode(WorldPacket& recv_data)
|
void WorldSession::HandleTalentWipeConfirmOpcode(WorldPacket& recv_data)
|
||||||
|
|
@ -99,9 +107,8 @@ void WorldSession::HandleTalentWipeConfirmOpcode(WorldPacket& recv_data)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// remove fake death
|
if (!unit->CanTrainAndResetTalentsOf(_player))
|
||||||
if (GetPlayer()->hasUnitState(UNIT_STAT_DIED))
|
return;
|
||||||
GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH);
|
|
||||||
|
|
||||||
if (!(_player->resetTalents()))
|
if (!(_player->resetTalents()))
|
||||||
{
|
{
|
||||||
|
|
@ -114,6 +121,8 @@ void WorldSession::HandleTalentWipeConfirmOpcode(WorldPacket& recv_data)
|
||||||
|
|
||||||
_player->SendTalentsInfoData(false);
|
_player->SendTalentsInfoData(false);
|
||||||
unit->CastSpell(_player, 14867, true); // spell: "Untalent Visual Effect"
|
unit->CastSpell(_player, 14867, true); // spell: "Untalent Visual Effect"
|
||||||
|
if (_player->GetPet())
|
||||||
|
_player->GetPet()->CastOwnerTalentAuras();
|
||||||
}
|
}
|
||||||
|
|
||||||
void WorldSession::HandleUnlearnSkillOpcode(WorldPacket& recv_data)
|
void WorldSession::HandleUnlearnSkillOpcode(WorldPacket& recv_data)
|
||||||
|
|
|
||||||
|
|
@ -519,10 +519,10 @@ void Spell::FillTargetMap()
|
||||||
// targets for TARGET_SCRIPT_COORDINATES (A) and TARGET_SCRIPT
|
// targets for TARGET_SCRIPT_COORDINATES (A) and TARGET_SCRIPT
|
||||||
// for TARGET_FOCUS_OR_SCRIPTED_GAMEOBJECT (A) all is checked in Spell::CheckCast and in Spell::CheckItem
|
// for TARGET_FOCUS_OR_SCRIPTED_GAMEOBJECT (A) all is checked in Spell::CheckCast and in Spell::CheckItem
|
||||||
// filled in Spell::CheckCast call
|
// filled in Spell::CheckCast call
|
||||||
if(spellEffect->EffectImplicitTargetA == TARGET_SCRIPT_COORDINATES ||
|
if (spellEffect->EffectImplicitTargetA == TARGET_SCRIPT_COORDINATES ||
|
||||||
spellEffect->EffectImplicitTargetA == TARGET_SCRIPT ||
|
spellEffect->EffectImplicitTargetA == TARGET_FOCUS_OR_SCRIPTED_GAMEOBJECT ||
|
||||||
spellEffect->EffectImplicitTargetA == TARGET_FOCUS_OR_SCRIPTED_GAMEOBJECT ||
|
(spellEffect->EffectImplicitTargetA == TARGET_SCRIPT && spellEffect->EffectImplicitTargetB != TARGET_SELF) ||
|
||||||
(spellEffect->EffectImplicitTargetB == TARGET_SCRIPT && spellEffect->EffectImplicitTargetA != TARGET_SELF))
|
(spellEffect->EffectImplicitTargetB == TARGET_SCRIPT && spellEffect->EffectImplicitTargetA != TARGET_SELF))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// TODO: find a way so this is not needed?
|
// TODO: find a way so this is not needed?
|
||||||
|
|
@ -571,8 +571,9 @@ void Spell::FillTargetMap()
|
||||||
case TARGET_SELF:
|
case TARGET_SELF:
|
||||||
switch(spellEffect->EffectImplicitTargetB)
|
switch(spellEffect->EffectImplicitTargetB)
|
||||||
{
|
{
|
||||||
case TARGET_NONE:
|
case TARGET_NONE: // Fill Target based on A only
|
||||||
case TARGET_EFFECT_SELECT:
|
case TARGET_EFFECT_SELECT:
|
||||||
|
case TARGET_SCRIPT: // B-target only used with CheckCast here
|
||||||
SetTargetMap(SpellEffectIndex(i), spellEffect->EffectImplicitTargetA, tmpUnitLists[i /*==effToIndex[i]*/]);
|
SetTargetMap(SpellEffectIndex(i), spellEffect->EffectImplicitTargetA, tmpUnitLists[i /*==effToIndex[i]*/]);
|
||||||
break;
|
break;
|
||||||
case TARGET_AREAEFFECT_INSTANT: // use B case that not dependent from from A in fact
|
case TARGET_AREAEFFECT_INSTANT: // use B case that not dependent from from A in fact
|
||||||
|
|
@ -716,6 +717,17 @@ void Spell::FillTargetMap()
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case TARGET_SCRIPT:
|
||||||
|
switch (spellEffect->EffectImplicitTargetB)
|
||||||
|
{
|
||||||
|
case TARGET_SELF:
|
||||||
|
// Fill target based on B only, A is only used with CheckCast here.
|
||||||
|
SetTargetMap(SpellEffectIndex(i), spellEffect->EffectImplicitTargetB, tmpUnitLists[i /*==effToIndex[i]*/]);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
switch(spellEffect->EffectImplicitTargetB)
|
switch(spellEffect->EffectImplicitTargetB)
|
||||||
{
|
{
|
||||||
|
|
@ -3273,6 +3285,9 @@ void Spell::cast(bool skipCheck)
|
||||||
// Chaos Bane strength buff
|
// Chaos Bane strength buff
|
||||||
else if (m_spellInfo->Id == 71904)
|
else if (m_spellInfo->Id == 71904)
|
||||||
AddTriggeredSpell(73422);
|
AddTriggeredSpell(73422);
|
||||||
|
// Weak Alcohol
|
||||||
|
else if (m_spellInfo->SpellIconID == 1306 && m_spellInfo->SpellVisual[0] == 11359)
|
||||||
|
AddTriggeredSpell(51655); // BOTM - Create Empty Brew Bottle
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SPELLFAMILY_MAGE:
|
case SPELLFAMILY_MAGE:
|
||||||
|
|
@ -3710,14 +3725,20 @@ void Spell::update(uint32 difftime)
|
||||||
SpellEffectEntry const* spellEffect = m_spellInfo->GetSpellEffect(EFFECT_INDEX_0);
|
SpellEffectEntry const* spellEffect = m_spellInfo->GetSpellEffect(EFFECT_INDEX_0);
|
||||||
SpellInterruptsEntry const* spellInterrupts = m_spellInfo->GetSpellInterrupts();
|
SpellInterruptsEntry const* spellInterrupts = m_spellInfo->GetSpellInterrupts();
|
||||||
|
|
||||||
// check if the player caster has moved before the spell finished
|
if (m_CastItemGuid && !m_CastItem)
|
||||||
if ((m_caster->GetTypeId() == TYPEID_PLAYER && m_timer != 0) &&
|
{
|
||||||
|
cancel();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// check if the player or unit caster has moved before the spell finished (exclude casting on vehicles)
|
||||||
|
if (((m_caster->GetTypeId() == TYPEID_PLAYER || m_caster->GetTypeId() == TYPEID_UNIT) && m_timer != 0) &&
|
||||||
(m_castPositionX != m_caster->GetPositionX() || m_castPositionY != m_caster->GetPositionY() || m_castPositionZ != m_caster->GetPositionZ()) &&
|
(m_castPositionX != m_caster->GetPositionX() || m_castPositionY != m_caster->GetPositionY() || m_castPositionZ != m_caster->GetPositionZ()) &&
|
||||||
((spellEffect && spellEffect->Effect != SPELL_EFFECT_STUCK) || !((Player*)m_caster)->m_movementInfo.HasMovementFlag(MOVEFLAG_FALLINGFAR)) &&
|
((spellEffect && spellEffect->Effect != SPELL_EFFECT_STUCK) || !((Player*)m_caster)->m_movementInfo.HasMovementFlag(MOVEFLAG_FALLINGFAR)) &&
|
||||||
!m_caster->HasAffectedAura(SPELL_AURA_ALLOW_CAST_WHILE_MOVING, m_spellInfo))
|
!m_caster->HasAffectedAura(SPELL_AURA_ALLOW_CAST_WHILE_MOVING, m_spellInfo))
|
||||||
{
|
{
|
||||||
// always cancel for channeled spells
|
// always cancel for channeled spells
|
||||||
if (m_spellState == SPELL_STATE_CASTING)
|
if (m_spellState == SPELL_STATE_CASTING && !m_spellInfo->HasAttribute(SPELL_ATTR_EX5_CAN_CHANNEL_WHEN_MOVING))
|
||||||
cancel();
|
cancel();
|
||||||
// don't cancel for melee, autorepeat, triggered and instant spells
|
// don't cancel for melee, autorepeat, triggered and instant spells
|
||||||
else if(!IsNextMeleeSwingSpell() && !IsAutoRepeat() && !m_IsTriggeredSpell && (spellInterrupts && spellInterrupts->InterruptFlags & SPELL_INTERRUPT_FLAG_MOVEMENT))
|
else if(!IsNextMeleeSwingSpell() && !IsAutoRepeat() && !m_IsTriggeredSpell && (spellInterrupts && spellInterrupts->InterruptFlags & SPELL_INTERRUPT_FLAG_MOVEMENT))
|
||||||
|
|
@ -3743,16 +3764,20 @@ void Spell::update(uint32 difftime)
|
||||||
{
|
{
|
||||||
if (m_timer > 0)
|
if (m_timer > 0)
|
||||||
{
|
{
|
||||||
if (m_caster->GetTypeId() == TYPEID_PLAYER)
|
if (m_caster->GetTypeId() == TYPEID_PLAYER || m_caster->GetTypeId() == TYPEID_UNIT)
|
||||||
{
|
{
|
||||||
// check if player has jumped before the channeling finished
|
// check if player has jumped before the channeling finished
|
||||||
if (((Player*)m_caster)->m_movementInfo.HasMovementFlag(MOVEFLAG_FALLING) &&
|
if (m_caster->m_movementInfo.HasMovementFlag(MOVEFLAG_FALLING) &&
|
||||||
!m_caster->HasAffectedAura(SPELL_AURA_ALLOW_CAST_WHILE_MOVING, m_spellInfo))
|
!m_caster->HasAffectedAura(SPELL_AURA_ALLOW_CAST_WHILE_MOVING, m_spellInfo))
|
||||||
cancel();
|
cancel();
|
||||||
|
|
||||||
// check for incapacitating player states
|
// check for incapacitating player states
|
||||||
if (m_caster->hasUnitState(UNIT_STAT_CAN_NOT_REACT))
|
if (m_caster->hasUnitState(UNIT_STAT_CAN_NOT_REACT))
|
||||||
cancel();
|
{
|
||||||
|
// certain channel spells are not interrupted
|
||||||
|
if (!m_spellInfo->HasAttribute(SPELL_ATTR_EX_CHANNELED_1) && !m_spellInfo->HasAttribute(SPELL_ATTR_EX3_UNK28))
|
||||||
|
cancel();
|
||||||
|
}
|
||||||
|
|
||||||
// check if player has turned if flag is set
|
// check if player has turned if flag is set
|
||||||
if( spellInterrupts && (spellInterrupts->ChannelInterruptFlags & CHANNEL_FLAG_TURNING) && m_castOrientation != m_caster->GetOrientation() )
|
if( spellInterrupts && (spellInterrupts->ChannelInterruptFlags & CHANNEL_FLAG_TURNING) && m_castOrientation != m_caster->GetOrientation() )
|
||||||
|
|
@ -3790,7 +3815,7 @@ void Spell::update(uint32 difftime)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
Unit* unit = m_caster->GetObjectGuid() == target.targetGUID ? m_caster : ObjectAccessor::GetUnit(*m_caster, target.targetGUID);
|
Unit* unit = m_caster->GetObjectGuid() == target.targetGUID ? m_caster : ObjectAccessor::GetUnit(*m_caster, target.targetGUID);
|
||||||
if (unit == NULL)
|
if (unit == nullptr)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
p->RewardPlayerAndGroupAtCast(unit, m_spellInfo->Id);
|
p->RewardPlayerAndGroupAtCast(unit, m_spellInfo->Id);
|
||||||
|
|
@ -4082,7 +4107,7 @@ void Spell::SendSpellStart()
|
||||||
data << uint8(m_runesState);
|
data << uint8(m_runesState);
|
||||||
data << uint8(caster->GetRunesState());
|
data << uint8(caster->GetRunesState());
|
||||||
for (uint8 i = 0; i < MAX_RUNES; ++i)
|
for (uint8 i = 0; i < MAX_RUNES; ++i)
|
||||||
data << uint8(255 - ((caster->GetRuneCooldown(i) / REGEN_TIME_FULL) * 51));
|
data << uint8(caster->GetRuneCooldownFraction(i));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -4702,6 +4727,7 @@ void Spell::TakePower()
|
||||||
if (m_spellInfo->powerType == POWER_HEALTH)
|
if (m_spellInfo->powerType == POWER_HEALTH)
|
||||||
{
|
{
|
||||||
m_caster->ModifyHealth(-(int32)m_powerCost);
|
m_caster->ModifyHealth(-(int32)m_powerCost);
|
||||||
|
m_caster->SendSpellNonMeleeDamageLog(m_caster, m_spellInfo->Id, m_powerCost, GetSpellSchoolMask(m_spellInfo), 0, 0, false, 0, false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -4740,14 +4766,14 @@ void Spell::TakePower()
|
||||||
|
|
||||||
if (powerType == POWER_RUNE)
|
if (powerType == POWER_RUNE)
|
||||||
{
|
{
|
||||||
CheckOrTakeRunePower(hit);
|
TakeRunePower(hit);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_caster->ModifyPower(powerType, -(int32)m_powerCost);
|
m_caster->ModifyPower(powerType, -(int32)m_powerCost);
|
||||||
}
|
}
|
||||||
|
|
||||||
SpellCastResult Spell::CheckOrTakeRunePower(bool take)
|
SpellCastResult Spell::CheckRunePower()
|
||||||
{
|
{
|
||||||
if (m_caster->GetTypeId() != TYPEID_PLAYER)
|
if (m_caster->GetTypeId() != TYPEID_PLAYER)
|
||||||
return SPELL_CAST_OK;
|
return SPELL_CAST_OK;
|
||||||
|
|
@ -4758,83 +4784,127 @@ SpellCastResult Spell::CheckOrTakeRunePower(bool take)
|
||||||
return SPELL_CAST_OK;
|
return SPELL_CAST_OK;
|
||||||
|
|
||||||
SpellRuneCostEntry const* src = sSpellRuneCostStore.LookupEntry(m_spellInfo->runeCostID);
|
SpellRuneCostEntry const* src = sSpellRuneCostStore.LookupEntry(m_spellInfo->runeCostID);
|
||||||
if (!src || (src->NoRuneCost() && (!take || src->NoRunicPowerGain())))
|
|
||||||
|
if (!src)
|
||||||
return SPELL_CAST_OK;
|
return SPELL_CAST_OK;
|
||||||
|
|
||||||
m_runesState = plr->GetRunesState(); // store previous state
|
if (src->NoRuneCost())
|
||||||
|
return SPELL_CAST_OK;
|
||||||
|
|
||||||
int32 runeCost[NUM_RUNE_TYPES]; // blood, frost, unholy, death
|
// at this moment for rune cost exist only no cost mods, and no percent mods
|
||||||
|
int32 runeCost[NUM_RUNE_TYPES]; // blood, frost, unholy, death
|
||||||
// init cost data and apply mods
|
for (uint32 i = 0; i < RUNE_DEATH; ++i)
|
||||||
for (uint8 i = 0; i < RUNE_DEATH; ++i)
|
|
||||||
{
|
{
|
||||||
runeCost[i] = src->RuneCost[i];
|
runeCost[i] = src->RuneCost[i];
|
||||||
if (Player* modOwner = plr->GetSpellModOwner())
|
if (Player* modOwner = m_caster->GetSpellModOwner())
|
||||||
modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_COST, runeCost[i], this);
|
modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_COST, runeCost[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
runeCost[RUNE_DEATH] = MAX_RUNES; // calculated later
|
runeCost[RUNE_DEATH] = MAX_RUNES; // calculated later
|
||||||
|
|
||||||
// scan non-death runes (death rune not used explicitly in rune costs)
|
for (uint32 i = 0; i < MAX_RUNES; ++i)
|
||||||
for (uint8 i = 0; i < MAX_RUNES; ++i)
|
|
||||||
{
|
{
|
||||||
// already used
|
|
||||||
if (plr->GetRuneCooldown(i) != 0)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
RuneType rune = plr->GetCurrentRune(i);
|
RuneType rune = plr->GetCurrentRune(i);
|
||||||
if (plr->GetRuneCooldown(i) == 0 && runeCost[rune] > 0)
|
if (!plr->GetRuneCooldown(i) && runeCost[rune] > 0)
|
||||||
|
--runeCost[rune];
|
||||||
|
}
|
||||||
|
|
||||||
|
for (uint32 i = 0; i < RUNE_DEATH; ++i)
|
||||||
|
if (runeCost[i] > 0)
|
||||||
|
runeCost[RUNE_DEATH] += runeCost[i];
|
||||||
|
|
||||||
|
if (runeCost[RUNE_DEATH] > MAX_RUNES)
|
||||||
|
return SPELL_FAILED_NO_POWER; // not sure if result code is correct
|
||||||
|
|
||||||
|
return SPELL_CAST_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Spell::TakeRunePower(bool hit)
|
||||||
|
{
|
||||||
|
if (m_caster->GetTypeId() != TYPEID_PLAYER)
|
||||||
|
return;
|
||||||
|
|
||||||
|
Player* plr = (Player*)m_caster;
|
||||||
|
|
||||||
|
if (plr->getClass() != CLASS_DEATH_KNIGHT)
|
||||||
|
return;
|
||||||
|
|
||||||
|
SpellRuneCostEntry const* src = sSpellRuneCostStore.LookupEntry(m_spellInfo->runeCostID);
|
||||||
|
|
||||||
|
if (!src)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (src->NoRuneCost() && src->NoRunicPowerGain())
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_runesState = plr->GetRunesState(); // store previous state
|
||||||
|
|
||||||
|
// at this moment for rune cost exist only no cost mods, and no percent mods
|
||||||
|
int32 runeCost[NUM_RUNE_TYPES]; // blood, frost, unholy, death
|
||||||
|
for (uint32 i = 0; i < RUNE_DEATH; ++i)
|
||||||
|
{
|
||||||
|
runeCost[i] = src->RuneCost[i];
|
||||||
|
if (Player* modOwner = m_caster->GetSpellModOwner())
|
||||||
|
modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_COST, runeCost[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
runeCost[RUNE_DEATH] = 0; // calculated later
|
||||||
|
|
||||||
|
plr->ClearLastUsedRuneMask();
|
||||||
|
|
||||||
|
for (uint32 i = 0; i < MAX_RUNES; ++i)
|
||||||
|
{
|
||||||
|
RuneType rune = plr->GetCurrentRune(i);
|
||||||
|
if (!plr->GetRuneCooldown(i) && runeCost[rune] > 0)
|
||||||
{
|
{
|
||||||
RuneType rune = plr->GetCurrentRune(i);
|
uint16 baseCd = hit ? uint16(RUNE_BASE_COOLDOWN) : uint16(RUNE_MISS_COOLDOWN);
|
||||||
if (runeCost[rune] <= 0)
|
plr->SetBaseRuneCooldown(i, baseCd);
|
||||||
continue;
|
plr->SetRuneCooldown(i, baseCd);
|
||||||
|
plr->SetLastUsedRune(rune);
|
||||||
// already used
|
|
||||||
if (plr->GetRuneCooldown(i) != 0)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (take)
|
|
||||||
plr->SetRuneCooldown(i, RUNE_COOLDOWN); // 5*2=10 sec
|
|
||||||
|
|
||||||
--runeCost[rune];
|
--runeCost[rune];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// collect all not counted rune costs to death runes cost
|
runeCost[RUNE_DEATH] = runeCost[RUNE_BLOOD] + runeCost[RUNE_UNHOLY] + runeCost[RUNE_FROST];
|
||||||
for (uint8 i = 0; i < RUNE_DEATH; ++i)
|
|
||||||
if (runeCost[i] > 0)
|
|
||||||
runeCost[RUNE_DEATH] += runeCost[i];
|
|
||||||
|
|
||||||
// scan death runes
|
|
||||||
if (runeCost[RUNE_DEATH] > 0)
|
if (runeCost[RUNE_DEATH] > 0)
|
||||||
{
|
{
|
||||||
for (uint8 i = 0; i < MAX_RUNES; ++i)
|
for (uint32 i = 0; i < MAX_RUNES; ++i)
|
||||||
{
|
{
|
||||||
RuneType rune = plr->GetCurrentRune(i);
|
RuneType rune = plr->GetCurrentRune(i);
|
||||||
if (!plr->GetRuneCooldown(i) && rune == RUNE_DEATH)
|
if (!plr->GetRuneCooldown(i) && rune == RUNE_DEATH)
|
||||||
{
|
{
|
||||||
plr->SetRuneCooldown(i, RUNE_COOLDOWN); // 5*2=10 sec
|
uint16 baseCd = hit ? uint16(RUNE_BASE_COOLDOWN) : uint16(RUNE_MISS_COOLDOWN);
|
||||||
runeCost[rune]--;
|
plr->SetBaseRuneCooldown(i, baseCd);
|
||||||
|
plr->SetRuneCooldown(i, baseCd);
|
||||||
|
plr->SetLastUsedRune(rune);
|
||||||
|
--runeCost[rune];
|
||||||
|
|
||||||
if (take)
|
// keep Death Rune type if missed
|
||||||
plr->ConvertRune(i, plr->GetBaseRune(i));
|
if (hit)
|
||||||
|
plr->RestoreBaseRune(i);
|
||||||
|
|
||||||
if (runeCost[RUNE_DEATH] == 0)
|
if (runeCost[RUNE_DEATH] == 0)
|
||||||
return SPELL_FAILED_NO_POWER;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (take)
|
if (hit)
|
||||||
{
|
{
|
||||||
// you can gain some runic power when use runes
|
// you can gain some runic power when use runes
|
||||||
float rp = float(src->runePowerGain);
|
int32 rp = int32(src->runePowerGain);
|
||||||
rp *= sWorld.getConfig(CONFIG_FLOAT_RATE_POWER_RUNICPOWER_INCOME);
|
if (rp)
|
||||||
plr->ModifyPower(POWER_RUNIC_POWER, (int32)rp);
|
{
|
||||||
}
|
if (Player* modOwner = m_caster->GetSpellModOwner())
|
||||||
|
modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_COST, rp);
|
||||||
|
|
||||||
return SPELL_CAST_OK;
|
rp = int32(sWorld.getConfig(CONFIG_FLOAT_RATE_POWER_RUNICPOWER_INCOME) * rp);
|
||||||
|
rp += m_caster->GetTotalAuraModifier(SPELL_AURA_MOD_RUNIC_POWER_REGEN) * rp / 100;
|
||||||
|
if (rp > 0)
|
||||||
|
plr->ModifyPower(POWER_RUNIC_POWER, (int32)rp);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Spell::TakeReagents()
|
void Spell::TakeReagents()
|
||||||
|
|
@ -5437,12 +5507,12 @@ SpellCastResult Spell::CheckCast(bool strict)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (spellEffect->EffectImplicitTargetA == TARGET_SCRIPT ||
|
if (spellEffect->EffectImplicitTargetA == TARGET_SCRIPT ||
|
||||||
(spellEffect->EffectImplicitTargetB == TARGET_SCRIPT && spellEffect->EffectImplicitTargetA != TARGET_SELF) ||
|
spellEffect->EffectImplicitTargetB == TARGET_SCRIPT ||
|
||||||
spellEffect->EffectImplicitTargetA == TARGET_SCRIPT_COORDINATES ||
|
spellEffect->EffectImplicitTargetA == TARGET_SCRIPT_COORDINATES ||
|
||||||
spellEffect->EffectImplicitTargetB == TARGET_SCRIPT_COORDINATES ||
|
spellEffect->EffectImplicitTargetB == TARGET_SCRIPT_COORDINATES ||
|
||||||
spellEffect->EffectImplicitTargetA == TARGET_FOCUS_OR_SCRIPTED_GAMEOBJECT)
|
spellEffect->EffectImplicitTargetA == TARGET_FOCUS_OR_SCRIPTED_GAMEOBJECT ||
|
||||||
|
spellEffect->EffectImplicitTargetB == TARGET_FOCUS_OR_SCRIPTED_GAMEOBJECT)
|
||||||
{
|
{
|
||||||
|
|
||||||
SQLMultiStorage::SQLMSIteratorBounds<SpellTargetEntry> bounds = sSpellScriptTargetStorage.getBounds<SpellTargetEntry>(m_spellInfo->Id);
|
SQLMultiStorage::SQLMSIteratorBounds<SpellTargetEntry> bounds = sSpellScriptTargetStorage.getBounds<SpellTargetEntry>(m_spellInfo->Id);
|
||||||
|
|
||||||
if (bounds.first == bounds.second)
|
if (bounds.first == bounds.second)
|
||||||
|
|
@ -5453,13 +5523,17 @@ SpellCastResult Spell::CheckCast(bool strict)
|
||||||
if (spellEffect->EffectImplicitTargetA == TARGET_SCRIPT_COORDINATES || spellEffect->EffectImplicitTargetB == TARGET_SCRIPT_COORDINATES)
|
if (spellEffect->EffectImplicitTargetA == TARGET_SCRIPT_COORDINATES || spellEffect->EffectImplicitTargetB == TARGET_SCRIPT_COORDINATES)
|
||||||
sLog.outErrorDb("Spell entry %u, effect %i has EffectImplicitTargetA/EffectImplicitTargetB = TARGET_SCRIPT_COORDINATES, but gameobject or creature are not defined in `spell_script_target`", m_spellInfo->Id, j);
|
sLog.outErrorDb("Spell entry %u, effect %i has EffectImplicitTargetA/EffectImplicitTargetB = TARGET_SCRIPT_COORDINATES, but gameobject or creature are not defined in `spell_script_target`", m_spellInfo->Id, j);
|
||||||
|
|
||||||
if (spellEffect->EffectImplicitTargetA == TARGET_FOCUS_OR_SCRIPTED_GAMEOBJECT)
|
if (spellEffect->EffectImplicitTargetA == TARGET_FOCUS_OR_SCRIPTED_GAMEOBJECT || spellEffect->EffectImplicitTargetB == TARGET_FOCUS_OR_SCRIPTED_GAMEOBJECT)
|
||||||
sLog.outErrorDb("Spell entry %u, effect %i has EffectImplicitTargetA/EffectImplicitTargetB = TARGET_FOCUS_OR_SCRIPTED_GAMEOBJECT, but gameobject are not defined in `spell_script_target`", m_spellInfo->Id, j);
|
sLog.outErrorDb("Spell entry %u, effect %i has EffectImplicitTargetA/EffectImplicitTargetB = TARGET_FOCUS_OR_SCRIPTED_GAMEOBJECT, but gameobject are not defined in `spell_script_target`", m_spellInfo->Id, j);
|
||||||
}
|
}
|
||||||
|
|
||||||
SpellRangeEntry const* srange = sSpellRangeStore.LookupEntry(m_spellInfo->rangeIndex);
|
SpellRangeEntry const* srange = sSpellRangeStore.LookupEntry(m_spellInfo->rangeIndex);
|
||||||
float range = GetSpellMaxRange(srange);
|
float range = GetSpellMaxRange(srange);
|
||||||
|
|
||||||
|
// override range with default when it's not provided
|
||||||
|
if (!range)
|
||||||
|
range = m_caster->GetMap()->IsDungeon() ? DEFAULT_VISIBILITY_INSTANCE : DEFAULT_VISIBILITY_DISTANCE;
|
||||||
|
|
||||||
Creature* targetExplicit = NULL; // used for cases where a target is provided (by script for example)
|
Creature* targetExplicit = NULL; // used for cases where a target is provided (by script for example)
|
||||||
Creature* creatureScriptTarget = NULL;
|
Creature* creatureScriptTarget = NULL;
|
||||||
GameObject* goScriptTarget = NULL;
|
GameObject* goScriptTarget = NULL;
|
||||||
|
|
@ -5905,12 +5979,6 @@ SpellCastResult Spell::CheckCast(bool strict)
|
||||||
if (ReqValue > skillValue)
|
if (ReqValue > skillValue)
|
||||||
return SPELL_FAILED_LOW_CASTLEVEL;
|
return SPELL_FAILED_LOW_CASTLEVEL;
|
||||||
|
|
||||||
// chance for fail at orange skinning attempt
|
|
||||||
if ((m_selfContainer && (*m_selfContainer) == this) &&
|
|
||||||
skillValue < sWorld.GetConfigMaxSkillValue() &&
|
|
||||||
(ReqValue < 0 ? 0 : ReqValue) > irand(skillValue - 25, skillValue + 37))
|
|
||||||
return SPELL_FAILED_TRY_AGAIN;
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SPELL_EFFECT_OPEN_LOCK:
|
case SPELL_EFFECT_OPEN_LOCK:
|
||||||
|
|
@ -5962,9 +6030,10 @@ SpellCastResult Spell::CheckCast(bool strict)
|
||||||
if (res != SPELL_CAST_OK)
|
if (res != SPELL_CAST_OK)
|
||||||
return res;
|
return res;
|
||||||
|
|
||||||
// chance for fail at orange mining/herb/LockPicking gathering attempt
|
// Failing gathering attempt for mining and herbalism was removed in patch 3.1.0: http://wowwiki.wikia.com/wiki/Patch_3.1.0
|
||||||
|
// chance for fail at orange LockPicking gathering attempt
|
||||||
// second check prevent fail at rechecks
|
// second check prevent fail at rechecks
|
||||||
if (skillId != SKILL_NONE && (!m_selfContainer || ((*m_selfContainer) != this)))
|
if (m_spellState != SPELL_STATE_CREATED && skillId != SKILL_NONE && skillId != SKILL_HERBALISM && skillId != SKILL_MINING )
|
||||||
{
|
{
|
||||||
bool canFailAtMax = skillId != SKILL_HERBALISM && skillId != SKILL_MINING;
|
bool canFailAtMax = skillId != SKILL_HERBALISM && skillId != SKILL_MINING;
|
||||||
|
|
||||||
|
|
@ -5972,7 +6041,6 @@ SpellCastResult Spell::CheckCast(bool strict)
|
||||||
if ((canFailAtMax || skillValue < sWorld.GetConfigMaxSkillValue()) && reqSkillValue > irand(skillValue - 25, skillValue + 37))
|
if ((canFailAtMax || skillValue < sWorld.GetConfigMaxSkillValue()) && reqSkillValue > irand(skillValue - 25, skillValue + 37))
|
||||||
return SPELL_FAILED_TRY_AGAIN;
|
return SPELL_FAILED_TRY_AGAIN;
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
case SPELL_EFFECT_SUMMON_DEAD_PET:
|
case SPELL_EFFECT_SUMMON_DEAD_PET:
|
||||||
{
|
{
|
||||||
|
|
@ -6823,7 +6891,7 @@ SpellCastResult Spell::CheckPower()
|
||||||
// check rune cost only if a spell has PowerType == POWER_RUNE
|
// check rune cost only if a spell has PowerType == POWER_RUNE
|
||||||
if (m_spellInfo->powerType == POWER_RUNE)
|
if (m_spellInfo->powerType == POWER_RUNE)
|
||||||
{
|
{
|
||||||
SpellCastResult failReason = CheckOrTakeRunePower(false);
|
SpellCastResult failReason = CheckRunePower();
|
||||||
if (failReason != SPELL_CAST_OK)
|
if (failReason != SPELL_CAST_OK)
|
||||||
return failReason;
|
return failReason;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -235,10 +235,12 @@ inline ByteBuffer& operator>> (ByteBuffer& buf, SpellCastTargetsReader const& ta
|
||||||
|
|
||||||
enum SpellState
|
enum SpellState
|
||||||
{
|
{
|
||||||
SPELL_STATE_PREPARING = 0, // cast time delay period, non channeled spell
|
SPELL_STATE_CREATED = 0, // just created
|
||||||
SPELL_STATE_CASTING = 1, // channeled time period spell casting state
|
SPELL_STATE_STARTING = 1, // doing initial check
|
||||||
SPELL_STATE_FINISHED = 2, // cast finished to success or fail
|
SPELL_STATE_PREPARING = 2, // cast time delay period, non channeled spell
|
||||||
SPELL_STATE_DELAYED = 3 // spell casted but need time to hit target(s)
|
SPELL_STATE_CASTING = 3, // channeled time period spell casting state
|
||||||
|
SPELL_STATE_FINISHED = 4, // cast finished to success or fail
|
||||||
|
SPELL_STATE_DELAYED = 5 // spell casted but need time to hit target(s)
|
||||||
};
|
};
|
||||||
|
|
||||||
enum SpellTargets
|
enum SpellTargets
|
||||||
|
|
@ -396,6 +398,7 @@ class Spell
|
||||||
void cast(bool skipCheck = false);
|
void cast(bool skipCheck = false);
|
||||||
void finish(bool ok = true);
|
void finish(bool ok = true);
|
||||||
void TakePower();
|
void TakePower();
|
||||||
|
void TakeRunePower(bool hit);
|
||||||
void TakeAmmo();
|
void TakeAmmo();
|
||||||
void TakeReagents();
|
void TakeReagents();
|
||||||
void TakeCastItem();
|
void TakeCastItem();
|
||||||
|
|
@ -413,7 +416,7 @@ class Spell
|
||||||
SpellCastResult CheckItems();
|
SpellCastResult CheckItems();
|
||||||
SpellCastResult CheckRange(bool strict);
|
SpellCastResult CheckRange(bool strict);
|
||||||
SpellCastResult CheckPower();
|
SpellCastResult CheckPower();
|
||||||
SpellCastResult CheckOrTakeRunePower(bool take);
|
SpellCastResult CheckRunePower();
|
||||||
SpellCastResult CheckCasterAuras() const;
|
SpellCastResult CheckCasterAuras() const;
|
||||||
|
|
||||||
int32 CalculateDamage(SpellEffectIndex i, Unit* target) { return m_caster->CalculateSpellDamage(target, m_spellInfo, i, &m_currentBasePoints[i]); }
|
int32 CalculateDamage(SpellEffectIndex i, Unit* target) { return m_caster->CalculateSpellDamage(target, m_spellInfo, i, &m_currentBasePoints[i]); }
|
||||||
|
|
@ -455,6 +458,8 @@ class Spell
|
||||||
SpellEntry const* m_triggeredBySpellInfo;
|
SpellEntry const* m_triggeredBySpellInfo;
|
||||||
SpellInterruptsEntry const* m_spellInterrupts;
|
SpellInterruptsEntry const* m_spellInterrupts;
|
||||||
int32 m_currentBasePoints[MAX_EFFECT_INDEX]; // cache SpellEntry::CalculateSimpleValue and use for set custom base points
|
int32 m_currentBasePoints[MAX_EFFECT_INDEX]; // cache SpellEntry::CalculateSimpleValue and use for set custom base points
|
||||||
|
|
||||||
|
ObjectGuid m_CastItemGuid;
|
||||||
Item* m_CastItem;
|
Item* m_CastItem;
|
||||||
uint8 m_cast_count;
|
uint8 m_cast_count;
|
||||||
uint32 m_glyphIndex;
|
uint32 m_glyphIndex;
|
||||||
|
|
|
||||||
|
|
@ -363,7 +363,7 @@ pAuraHandler AuraHandler[TOTAL_AURAS] =
|
||||||
&Aura::HandleNULL, //297 14 spells in 4.3.4
|
&Aura::HandleNULL, //297 14 spells in 4.3.4
|
||||||
&Aura::HandleUnused, //298 6 spells in 4.3.4
|
&Aura::HandleUnused, //298 6 spells in 4.3.4
|
||||||
&Aura::HandleUnused, //299 unused (3.2.2a-4.3.4)
|
&Aura::HandleUnused, //299 unused (3.2.2a-4.3.4)
|
||||||
&Aura::HandleNULL, //300 21 spells (share damage?)
|
&Aura::HandleNoImmediateEffect, //300 SPELL_AURA_SHARE_DAMAGE_PCT 21 spells
|
||||||
&Aura::HandleNULL, //301 SPELL_AURA_HEAL_ABSORB 31 spells
|
&Aura::HandleNULL, //301 SPELL_AURA_HEAL_ABSORB 31 spells
|
||||||
&Aura::HandleUnused, //302 unused (3.2.2a-4.3.4)
|
&Aura::HandleUnused, //302 unused (3.2.2a-4.3.4)
|
||||||
&Aura::HandleNULL, //303 35 spells increases damage done vs. creature type
|
&Aura::HandleNULL, //303 35 spells increases damage done vs. creature type
|
||||||
|
|
@ -510,7 +510,8 @@ Aura::~Aura()
|
||||||
}
|
}
|
||||||
|
|
||||||
AreaAura::AreaAura(SpellEntry const* spellproto, SpellEffectIndex eff, int32* currentBasePoints, SpellAuraHolder* holder, Unit* target,
|
AreaAura::AreaAura(SpellEntry const* spellproto, SpellEffectIndex eff, int32* currentBasePoints, SpellAuraHolder* holder, Unit* target,
|
||||||
Unit* caster, Item* castItem) : Aura(spellproto, eff, currentBasePoints, holder, target, caster, castItem)
|
Unit* caster, Item* castItem, uint32 originalRankSpellId)
|
||||||
|
: Aura(spellproto, eff, currentBasePoints, holder, target, caster, castItem), m_originalRankSpellId(originalRankSpellId)
|
||||||
{
|
{
|
||||||
m_isAreaAura = true;
|
m_isAreaAura = true;
|
||||||
|
|
||||||
|
|
@ -751,18 +752,26 @@ void AreaAura::Update(uint32 diff)
|
||||||
// flag for selection is need apply aura to current iteration target
|
// flag for selection is need apply aura to current iteration target
|
||||||
bool apply = true;
|
bool apply = true;
|
||||||
|
|
||||||
|
SpellEntry const* actualSpellInfo;
|
||||||
|
if (GetCasterGuid() == (*tIter)->GetObjectGuid()) // if caster is same as target then no need to change rank of the spell
|
||||||
|
actualSpellInfo = GetSpellProto();
|
||||||
|
else
|
||||||
|
actualSpellInfo = sSpellMgr.SelectAuraRankForLevel(GetSpellProto(), (*tIter)->getLevel()); // use spell id according level of the target
|
||||||
|
if (!actualSpellInfo)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
Unit::SpellAuraHolderBounds spair = (*tIter)->GetSpellAuraHolderBounds(actualSpellInfo->Id);
|
||||||
// we need ignore present caster self applied are auras sometime
|
// we need ignore present caster self applied are auras sometime
|
||||||
// in cases if this only auras applied for spell effect
|
// in cases if this only auras applied for spell effect
|
||||||
Unit::SpellAuraHolderBounds spair = (*tIter)->GetSpellAuraHolderBounds(GetId());
|
|
||||||
for (Unit::SpellAuraHolderMap::const_iterator i = spair.first; i != spair.second; ++i)
|
for (Unit::SpellAuraHolderMap::const_iterator i = spair.first; i != spair.second; ++i)
|
||||||
{
|
{
|
||||||
if (i->second->IsDeleted())
|
if (i->second->IsDeleted())
|
||||||
{ continue; }
|
continue;
|
||||||
|
|
||||||
Aura* aur = i->second->GetAuraByEffectIndex(m_effIndex);
|
Aura* aur = i->second->GetAuraByEffectIndex(m_effIndex);
|
||||||
|
|
||||||
if (!aur)
|
if (!aur)
|
||||||
{ continue; }
|
continue;
|
||||||
|
|
||||||
switch (m_areaAuraType)
|
switch (m_areaAuraType)
|
||||||
{
|
{
|
||||||
|
|
@ -773,7 +782,7 @@ void AreaAura::Update(uint32 diff)
|
||||||
break;
|
break;
|
||||||
case AREA_AURA_RAID:
|
case AREA_AURA_RAID:
|
||||||
// non caster self-casted auras (stacked from diff. casters)
|
// non caster self-casted auras (stacked from diff. casters)
|
||||||
if (aur->GetModifier()->m_auraname != SPELL_AURA_NONE || i->second->GetCasterGuid() == GetCasterGuid())
|
if (aur->GetModifier()->m_auraname != SPELL_AURA_NONE || i->second->GetCasterGuid() == GetCasterGuid())
|
||||||
apply = false;
|
apply = false;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|
@ -787,43 +796,41 @@ void AreaAura::Update(uint32 diff)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!apply)
|
if (!apply)
|
||||||
{ continue; }
|
continue;
|
||||||
|
|
||||||
// Skip some targets (TODO: Might require better checks, also unclear how the actual caster must/can be handled)
|
// Skip some targets (TODO: Might require better checks, also unclear how the actual caster must/can be handled)
|
||||||
if (GetSpellProto()->HasAttribute(SPELL_ATTR_EX3_TARGET_ONLY_PLAYER) && (*tIter)->GetTypeId() != TYPEID_PLAYER)
|
if (actualSpellInfo->HasAttribute(SPELL_ATTR_EX3_TARGET_ONLY_PLAYER) && (*tIter)->GetTypeId() != TYPEID_PLAYER)
|
||||||
{ continue; }
|
continue;
|
||||||
|
|
||||||
if (SpellEntry const* actualSpellInfo = sSpellMgr.SelectAuraRankForLevel(GetSpellProto(), (*tIter)->getLevel()))
|
int32 actualBasePoints = m_currentBasePoints;
|
||||||
|
// recalculate basepoints for lower rank (all AreaAura spell not use custom basepoints?)
|
||||||
|
if (actualSpellInfo != GetSpellProto())
|
||||||
|
actualBasePoints = actualSpellInfo->CalculateSimpleValue(m_effIndex);
|
||||||
|
|
||||||
|
SpellAuraHolder* holder = (*tIter)->GetSpellAuraHolder(actualSpellInfo->Id, GetCasterGuid());
|
||||||
|
|
||||||
|
bool addedToExisting = true;
|
||||||
|
if (!holder)
|
||||||
{
|
{
|
||||||
int32 actualBasePoints = m_currentBasePoints;
|
holder = CreateSpellAuraHolder(actualSpellInfo, (*tIter), caster);
|
||||||
// recalculate basepoints for lower rank (all AreaAura spell not use custom basepoints?)
|
addedToExisting = false;
|
||||||
if (actualSpellInfo != GetSpellProto())
|
|
||||||
{ actualBasePoints = actualSpellInfo->CalculateSimpleValue(m_effIndex); }
|
|
||||||
|
|
||||||
SpellAuraHolder* holder = (*tIter)->GetSpellAuraHolder(actualSpellInfo->Id, GetCasterGuid());
|
|
||||||
|
|
||||||
bool addedToExisting = true;
|
|
||||||
if (!holder)
|
|
||||||
{
|
|
||||||
holder = CreateSpellAuraHolder(actualSpellInfo, (*tIter), caster);
|
|
||||||
addedToExisting = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
holder->SetAuraDuration(GetAuraDuration());
|
|
||||||
|
|
||||||
AreaAura* aur = new AreaAura(actualSpellInfo, m_effIndex, &actualBasePoints, holder, (*tIter), caster, NULL);
|
|
||||||
holder->AddAura(aur, m_effIndex);
|
|
||||||
|
|
||||||
if (addedToExisting)
|
|
||||||
{
|
|
||||||
(*tIter)->AddAuraToModList(aur);
|
|
||||||
holder->SetInUse(true);
|
|
||||||
aur->ApplyModifier(true, true);
|
|
||||||
holder->SetInUse(false);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
(*tIter)->AddSpellAuraHolder(holder);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
holder->SetAuraDuration(GetAuraDuration());
|
||||||
|
|
||||||
|
AreaAura* aur = new AreaAura(actualSpellInfo, m_effIndex, &actualBasePoints, holder, (*tIter), caster, nullptr, GetSpellProto()->Id);
|
||||||
|
holder->AddAura(aur, m_effIndex);
|
||||||
|
|
||||||
|
if (addedToExisting)
|
||||||
|
{
|
||||||
|
(*tIter)->AddAuraToModList(aur);
|
||||||
|
holder->SetInUse(true);
|
||||||
|
aur->ApplyModifier(true, true);
|
||||||
|
holder->SetInUse(false);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
(*tIter)->AddSpellAuraHolder(holder);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Aura::Update(diff);
|
Aura::Update(diff);
|
||||||
|
|
@ -832,6 +839,7 @@ void AreaAura::Update(uint32 diff)
|
||||||
{
|
{
|
||||||
Unit* caster = GetCaster();
|
Unit* caster = GetCaster();
|
||||||
Unit* target = GetTarget();
|
Unit* target = GetTarget();
|
||||||
|
uint32 originalRankSpellId = m_originalRankSpellId ? m_originalRankSpellId : GetId(); // caster may have different spell id if target has lower level
|
||||||
|
|
||||||
Aura::Update(diff);
|
Aura::Update(diff);
|
||||||
|
|
||||||
|
|
@ -839,9 +847,10 @@ void AreaAura::Update(uint32 diff)
|
||||||
// or caster is isolated or caster no longer has the aura
|
// or caster is isolated or caster no longer has the aura
|
||||||
// or caster is (no longer) friendly
|
// or caster is (no longer) friendly
|
||||||
bool needFriendly = (m_areaAuraType == AREA_AURA_ENEMY ? false : true);
|
bool needFriendly = (m_areaAuraType == AREA_AURA_ENEMY ? false : true);
|
||||||
if (!caster || caster->hasUnitState(UNIT_STAT_ISOLATED) ||
|
if (!caster ||
|
||||||
!caster->IsWithinDistInMap(target, m_radius) ||
|
caster->hasUnitState(UNIT_STAT_ISOLATED) ||
|
||||||
!caster->HasAura(GetId(), GetEffIndex()) ||
|
!caster->HasAura(originalRankSpellId, GetEffIndex()) ||
|
||||||
|
!caster->IsWithinDistInMap(target, m_radius) ||
|
||||||
caster->IsFriendlyTo(target) != needFriendly
|
caster->IsFriendlyTo(target) != needFriendly
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
|
@ -854,29 +863,29 @@ void AreaAura::Update(uint32 diff)
|
||||||
{
|
{
|
||||||
Player* check = caster->GetCharmerOrOwnerPlayerOrPlayerItself();
|
Player* check = caster->GetCharmerOrOwnerPlayerOrPlayerItself();
|
||||||
|
|
||||||
Group* pGroup = check ? check->GetGroup() : NULL;
|
Group* pGroup = check ? check->GetGroup() : nullptr;
|
||||||
if (pGroup)
|
if (pGroup)
|
||||||
{
|
{
|
||||||
Player* checkTarget = target->GetCharmerOrOwnerPlayerOrPlayerItself();
|
Player* checkTarget = target->GetCharmerOrOwnerPlayerOrPlayerItself();
|
||||||
if (!checkTarget || !pGroup->SameSubGroup(check, checkTarget))
|
if (!checkTarget || !pGroup->SameSubGroup(check, checkTarget))
|
||||||
{ target->RemoveSingleAuraFromSpellAuraHolder(GetId(), GetEffIndex(), GetCasterGuid()); }
|
target->RemoveSingleAuraFromSpellAuraHolder(GetId(), GetEffIndex(), GetCasterGuid());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{ target->RemoveSingleAuraFromSpellAuraHolder(GetId(), GetEffIndex(), GetCasterGuid()); }
|
target->RemoveSingleAuraFromSpellAuraHolder(GetId(), GetEffIndex(), GetCasterGuid());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (m_areaAuraType == AREA_AURA_RAID) // TODO: fix me!
|
else if (m_areaAuraType == AREA_AURA_RAID) // Check if on same raid group
|
||||||
{
|
{
|
||||||
// not check group if target == owner or target == pet
|
// not check group if target == owner or target == pet
|
||||||
if (caster->GetCharmerOrOwnerGuid() != target->GetObjectGuid() && caster->GetObjectGuid() != target->GetCharmerOrOwnerGuid())
|
if (caster->GetCharmerOrOwnerGuid() != target->GetObjectGuid() && caster->GetObjectGuid() != target->GetCharmerOrOwnerGuid())
|
||||||
{
|
{
|
||||||
Player* check = caster->GetCharmerOrOwnerPlayerOrPlayerItself();
|
Player* check = caster->GetCharmerOrOwnerPlayerOrPlayerItself();
|
||||||
|
|
||||||
Group* pGroup = check ? check->GetGroup() : NULL;
|
Group* pGroup = check ? check->GetGroup() : nullptr;
|
||||||
if (pGroup)
|
if (pGroup)
|
||||||
{
|
{
|
||||||
Player* checkTarget = target->GetCharmerOrOwnerPlayerOrPlayerItself();
|
Player* checkTarget = target->GetCharmerOrOwnerPlayerOrPlayerItself();
|
||||||
if (!checkTarget)
|
if (!checkTarget || !checkTarget->GetGroup() || checkTarget->GetGroup()->GetId() != pGroup->GetId())
|
||||||
target->RemoveSingleAuraFromSpellAuraHolder(GetId(), GetEffIndex(), GetCasterGuid());
|
target->RemoveSingleAuraFromSpellAuraHolder(GetId(), GetEffIndex(), GetCasterGuid());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
@ -886,7 +895,7 @@ void AreaAura::Update(uint32 diff)
|
||||||
else if (m_areaAuraType == AREA_AURA_PET || m_areaAuraType == AREA_AURA_OWNER)
|
else if (m_areaAuraType == AREA_AURA_PET || m_areaAuraType == AREA_AURA_OWNER)
|
||||||
{
|
{
|
||||||
if (target->GetObjectGuid() != caster->GetCharmerOrOwnerGuid())
|
if (target->GetObjectGuid() != caster->GetCharmerOrOwnerGuid())
|
||||||
{ target->RemoveSingleAuraFromSpellAuraHolder(GetId(), GetEffIndex(), GetCasterGuid()); }
|
target->RemoveSingleAuraFromSpellAuraHolder(GetId(), GetEffIndex(), GetCasterGuid());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1191,7 +1200,7 @@ void Aura::TriggerSpell()
|
||||||
{
|
{
|
||||||
int32 damageForTick[8] = { 500, 500, 1000, 1000, 2000, 2000, 3000, 5000 };
|
int32 damageForTick[8] = { 500, 500, 1000, 1000, 2000, 2000, 3000, 5000 };
|
||||||
triggerTarget->CastCustomSpell(triggerTarget, 19698, &damageForTick[GetAuraTicks() - 1], nullptr, nullptr, true, nullptr);
|
triggerTarget->CastCustomSpell(triggerTarget, 19698, &damageForTick[GetAuraTicks() - 1], nullptr, nullptr, true, nullptr);
|
||||||
return;
|
return;;
|
||||||
}
|
}
|
||||||
|
|
||||||
// // Frostwolf Muzzle DND
|
// // Frostwolf Muzzle DND
|
||||||
|
|
@ -3526,62 +3535,18 @@ void Aura::HandleAuraFeatherFall(bool apply, bool Real)
|
||||||
{
|
{
|
||||||
// only at real add/remove aura
|
// only at real add/remove aura
|
||||||
if (!Real)
|
if (!Real)
|
||||||
{ return; }
|
return;
|
||||||
Unit* target = GetTarget();
|
|
||||||
WorldPacket data;
|
|
||||||
target->BuildMoveFeatherFallPacket(&data, apply, 0);
|
|
||||||
target->SendMessageToSet(&data, true);
|
|
||||||
|
|
||||||
// start fall from current height
|
GetTarget()->SetFeatherFall(apply);
|
||||||
if (!apply && target->GetTypeId() == TYPEID_PLAYER)
|
|
||||||
((Player*)target)->SetFallInformation(0, target->GetPositionZ());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Aura::HandleAuraHover(bool apply, bool Real)
|
void Aura::HandleAuraHover(bool apply, bool Real)
|
||||||
{
|
{
|
||||||
// only at real add/remove aura
|
// only at real add/remove aura
|
||||||
if (!Real)
|
if (!Real)
|
||||||
{ return; }
|
return;
|
||||||
|
|
||||||
WorldPacket data;
|
GetTarget()->SetHover(apply);
|
||||||
if (apply)
|
|
||||||
{
|
|
||||||
GetTarget()->m_movementInfo.AddMovementFlag(MOVEFLAG_HOVER);
|
|
||||||
if (GetTarget()->GetTypeId() == TYPEID_PLAYER)
|
|
||||||
{
|
|
||||||
data.Initialize(SMSG_MOVE_SET_HOVER, 8 + 4 + 1);
|
|
||||||
data.WriteGuidMask<1, 4, 2, 3, 0, 5, 6, 7>(GetTarget()->GetObjectGuid());
|
|
||||||
data.WriteGuidBytes<5, 4, 1, 2, 3, 6, 0, 7>(GetTarget()->GetObjectGuid());
|
|
||||||
data << uint32(0);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
data.Initialize(SMSG_SPLINE_MOVE_SET_HOVER, 8 + 4 + 1);
|
|
||||||
data.WriteGuidMask<3, 7, 0, 1, 4, 6, 2, 5>(GetTarget()->GetObjectGuid());
|
|
||||||
data.WriteGuidBytes<2, 4, 3, 1, 7, 0, 5, 6>(GetTarget()->GetObjectGuid());
|
|
||||||
GetTarget()->SetByteFlag(UNIT_FIELD_BYTES_1, 3, UNIT_BYTE1_FLAG_FLY_ANIM);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
GetTarget()->m_movementInfo.RemoveMovementFlag(MOVEFLAG_HOVER);
|
|
||||||
data.Initialize(GetTarget()->GetTypeId() == TYPEID_PLAYER ? SMSG_MOVE_UNSET_HOVER : SMSG_SPLINE_MOVE_UNSET_HOVER, 8+4);
|
|
||||||
if (GetTarget()->GetTypeId() == TYPEID_PLAYER)
|
|
||||||
{
|
|
||||||
data.Initialize(SMSG_MOVE_UNSET_HOVER, 8 + 4 + 1);
|
|
||||||
data.WriteGuidMask<4, 6, 3, 1, 2, 7, 5, 0>(GetTarget()->GetObjectGuid());
|
|
||||||
data.WriteGuidBytes<4, 5, 3, 6, 7, 1, 2, 0>(GetTarget()->GetObjectGuid());
|
|
||||||
data << uint32(0);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
data.Initialize(SMSG_SPLINE_MOVE_UNSET_HOVER, 8 + 4 + 1);
|
|
||||||
data.WriteGuidMask<6, 7, 4, 0, 3, 1, 5, 2>(GetTarget()->GetObjectGuid());
|
|
||||||
data.WriteGuidBytes<4, 5, 3, 0, 2, 7, 6, 1>(GetTarget()->GetObjectGuid());
|
|
||||||
GetTarget()->RemoveByteFlag(UNIT_FIELD_BYTES_1, 3, UNIT_BYTE1_FLAG_FLY_ANIM);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
GetTarget()->SendMessageToSet(&data, true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Aura::HandleWaterBreathing(bool /*apply*/, bool /*Real*/)
|
void Aura::HandleWaterBreathing(bool /*apply*/, bool /*Real*/)
|
||||||
|
|
@ -4069,8 +4034,7 @@ void Aura::HandleAuraTransform(bool apply, bool Real)
|
||||||
if (Unit* caster = GetCaster())
|
if (Unit* caster = GetCaster())
|
||||||
if (caster->HasAura(52648)) // Glyph of the Penguin
|
if (caster->HasAura(52648)) // Glyph of the Penguin
|
||||||
model_id = 26452;
|
model_id = 26452;
|
||||||
else
|
else if (caster->HasAura(57927)) // Glyph of the Monkey
|
||||||
if (caster->HasAura(57927)) // Glyph of the Monkey
|
|
||||||
model_id = 21362;
|
model_id = 21362;
|
||||||
|
|
||||||
target->SetDisplayId(model_id);
|
target->SetDisplayId(model_id);
|
||||||
|
|
@ -5209,9 +5173,7 @@ void Aura::HandleAuraModIncreaseFlightSpeed(bool apply, bool Real)
|
||||||
// Enable Fly mode for flying mounts
|
// Enable Fly mode for flying mounts
|
||||||
if (m_modifier.m_auraname == SPELL_AURA_MOD_FLIGHT_SPEED_MOUNTED)
|
if (m_modifier.m_auraname == SPELL_AURA_MOD_FLIGHT_SPEED_MOUNTED)
|
||||||
{
|
{
|
||||||
WorldPacket data;
|
target->SetCanFly(apply);
|
||||||
target->BuildMoveSetCanFlyPacket(&data, apply, 0);
|
|
||||||
target->SendMessageToSet(&data, true);
|
|
||||||
|
|
||||||
// Players on flying mounts must be immune to polymorph
|
// Players on flying mounts must be immune to polymorph
|
||||||
if (target->GetTypeId() == TYPEID_PLAYER)
|
if (target->GetTypeId() == TYPEID_PLAYER)
|
||||||
|
|
@ -7109,10 +7071,7 @@ void Aura::HandleAuraAllowFlight(bool apply, bool Real)
|
||||||
if (!Real)
|
if (!Real)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// allow fly
|
GetTarget()->SetCanFly(apply);
|
||||||
WorldPacket data;
|
|
||||||
GetTarget()->BuildMoveSetCanFlyPacket(&data, apply, 0);
|
|
||||||
GetTarget()->SendMessageToSet(&data, true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Aura::HandleModRating(bool apply, bool Real)
|
void Aura::HandleModRating(bool apply, bool Real)
|
||||||
|
|
|
||||||
|
|
@ -545,13 +545,14 @@ class Aura
|
||||||
class AreaAura : public Aura
|
class AreaAura : public Aura
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
AreaAura(SpellEntry const* spellproto, SpellEffectIndex eff, int32* currentBasePoints, SpellAuraHolder* holder, Unit* target, Unit* caster = NULL, Item* castItem = NULL);
|
AreaAura(SpellEntry const* spellproto, SpellEffectIndex eff, int32* currentBasePoints, SpellAuraHolder* holder, Unit* target, Unit* caster = nullptr, Item* castItem = nullptr, uint32 originalRankSpellId = 0);
|
||||||
~AreaAura();
|
~AreaAura();
|
||||||
protected:
|
protected:
|
||||||
void Update(uint32 diff) override;
|
void Update(uint32 diff) override;
|
||||||
private:
|
private:
|
||||||
float m_radius;
|
float m_radius;
|
||||||
AreaAuraType m_areaAuraType;
|
AreaAuraType m_areaAuraType;
|
||||||
|
uint32 m_originalRankSpellId;
|
||||||
};
|
};
|
||||||
|
|
||||||
class PersistentAreaAura : public Aura
|
class PersistentAreaAura : public Aura
|
||||||
|
|
|
||||||
|
|
@ -222,7 +222,7 @@ pEffect SpellEffects[TOTAL_SPELL_EFFECTS] =
|
||||||
&Spell::EffectQuestOffer, //150 SPELL_EFFECT_QUEST_OFFER
|
&Spell::EffectQuestOffer, //150 SPELL_EFFECT_QUEST_OFFER
|
||||||
&Spell::EffectTriggerRitualOfSummoning, //151 SPELL_EFFECT_TRIGGER_SPELL_2
|
&Spell::EffectTriggerRitualOfSummoning, //151 SPELL_EFFECT_TRIGGER_SPELL_2
|
||||||
&Spell::EffectNULL, //152 SPELL_EFFECT_152 summon Refer-a-Friend
|
&Spell::EffectNULL, //152 SPELL_EFFECT_152 summon Refer-a-Friend
|
||||||
&Spell::EffectNULL, //153 SPELL_EFFECT_CREATE_PET misc value is creature entry
|
&Spell::EffectCreateTamedPet, //153 SPELL_EFFECT_CREATE_PET misc value is creature entry
|
||||||
&Spell::EffectTeachTaxiNode, //154 SPELL_EFFECT_TEACH_TAXI_NODE single spell: Teach River's Heart Taxi Path
|
&Spell::EffectTeachTaxiNode, //154 SPELL_EFFECT_TEACH_TAXI_NODE single spell: Teach River's Heart Taxi Path
|
||||||
&Spell::EffectTitanGrip, //155 SPELL_EFFECT_TITAN_GRIP Allows you to equip two-handed axes, maces and swords in one hand, but you attack $49152s1% slower than normal.
|
&Spell::EffectTitanGrip, //155 SPELL_EFFECT_TITAN_GRIP Allows you to equip two-handed axes, maces and swords in one hand, but you attack $49152s1% slower than normal.
|
||||||
&Spell::EffectEnchantItemPrismatic, //156 SPELL_EFFECT_ENCHANT_ITEM_PRISMATIC
|
&Spell::EffectEnchantItemPrismatic, //156 SPELL_EFFECT_ENCHANT_ITEM_PRISMATIC
|
||||||
|
|
@ -4191,17 +4191,12 @@ void Spell::EffectTriggerSpell(SpellEffectEntry const* effect)
|
||||||
pet->CastSpell(pet, 28305, true);
|
pet->CastSpell(pet, 28305, true);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
case 53258: // Empower Rune Weapon
|
case 58832: // Mirror Image
|
||||||
{
|
{
|
||||||
// remove cooldown of frost/death, undead/blood activated in main spell
|
// Glyph of Mirror Image
|
||||||
if (unitTarget->GetTypeId() == TYPEID_PLAYER)
|
if (m_caster->HasAura(63093))
|
||||||
{
|
m_caster->CastSpell(m_caster, 65047, true, m_CastItem, nullptr, m_originalCasterGUID);
|
||||||
bool res1 = ((Player*)unitTarget)->ActivateRunes(RUNE_FROST, 2);
|
break;
|
||||||
bool res2 = ((Player*)unitTarget)->ActivateRunes(RUNE_DEATH, 2);
|
|
||||||
if (res1 || res2)
|
|
||||||
((Player*)unitTarget)->ResyncRunes();
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -4339,7 +4334,11 @@ void Spell::EffectJump(SpellEffectEntry const* effect)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_caster->NearTeleportTo(x, y, z, o, true); // TODO Implement this as jump movement?
|
// Try to normalize Z coord because GetContactPoint do nothing with Z axis
|
||||||
|
m_caster->UpdateAllowedPositionZ(x, y, z);
|
||||||
|
|
||||||
|
float speed = m_spellInfo->speed ? m_spellInfo->speed : 27.0f;
|
||||||
|
m_caster->GetMotionMaster()->MoveDestination(x, y, z, o, speed, 2.5f);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Spell::EffectTeleportUnits(SpellEffectEntry const* effect) // TODO - Use target settings for this effect!
|
void Spell::EffectTeleportUnits(SpellEffectEntry const* effect) // TODO - Use target settings for this effect!
|
||||||
|
|
@ -6629,56 +6628,45 @@ void Spell::EffectSummonPet(SpellEffectEntry const* effect)
|
||||||
{
|
{
|
||||||
uint32 petentry = effect->EffectMiscValue;
|
uint32 petentry = effect->EffectMiscValue;
|
||||||
|
|
||||||
Pet* OldSummon = m_caster->GetPet();
|
|
||||||
|
|
||||||
// if pet requested type already exist
|
|
||||||
if (OldSummon)
|
|
||||||
{
|
|
||||||
if ((petentry == 0 || OldSummon->GetEntry() == petentry) && OldSummon->getPetType() != SUMMON_PET)
|
|
||||||
{
|
|
||||||
// pet in corpse state can't be summoned
|
|
||||||
if (OldSummon->IsDead())
|
|
||||||
return;
|
|
||||||
|
|
||||||
OldSummon->GetMap()->Remove((Creature*)OldSummon, false);
|
|
||||||
|
|
||||||
float px, py, pz;
|
|
||||||
m_caster->GetClosePoint(px, py, pz, OldSummon->GetObjectBoundingRadius());
|
|
||||||
|
|
||||||
OldSummon->Relocate(px, py, pz, OldSummon->GetOrientation());
|
|
||||||
m_caster->GetMap()->Add((Creature*)OldSummon);
|
|
||||||
|
|
||||||
if (m_caster->GetTypeId() == TYPEID_PLAYER && OldSummon->isControlled())
|
|
||||||
{
|
|
||||||
((Player*)m_caster)->PetSpellInitialize();
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_caster->GetTypeId() == TYPEID_PLAYER)
|
|
||||||
OldSummon->Unsummon(OldSummon->getPetType() == HUNTER_PET ? PET_SAVE_AS_DELETED : PET_SAVE_NOT_IN_SLOT, m_caster);
|
|
||||||
else
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
CreatureInfo const* cInfo = ObjectMgr::GetCreatureTemplate(petentry);
|
|
||||||
|
|
||||||
// == 0 in case call current pet, check only real summon case
|
|
||||||
if (petentry && !cInfo)
|
|
||||||
{
|
|
||||||
sLog.outErrorDb("EffectSummonPet: creature entry %u not found for spell %u.", petentry, m_spellInfo->Id);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Pet* NewSummon = new Pet;
|
Pet* NewSummon = new Pet;
|
||||||
|
|
||||||
// petentry==0 for hunter "call pet" (current pet summoned if any)
|
if (m_caster->GetTypeId() == TYPEID_PLAYER)
|
||||||
if (m_caster->GetTypeId() == TYPEID_PLAYER && NewSummon->LoadPetFromDB((Player*)m_caster, petentry))
|
|
||||||
return;
|
|
||||||
|
|
||||||
// not error in case fail hunter call pet
|
|
||||||
if (!petentry)
|
|
||||||
{
|
{
|
||||||
|
switch(m_caster->getClass())
|
||||||
|
{
|
||||||
|
case CLASS_HUNTER:
|
||||||
|
{
|
||||||
|
// Everything already taken care of, we are only here because we loaded pet from db successfully
|
||||||
|
delete NewSummon;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
if (Pet* OldSummon = m_caster->GetPet())
|
||||||
|
OldSummon->Unsummon(PET_SAVE_NOT_IN_SLOT, m_caster);
|
||||||
|
|
||||||
|
// Load pet from db; if any to load
|
||||||
|
if (NewSummon->LoadPetFromDB((Player*)m_caster, petentry))
|
||||||
|
{
|
||||||
|
NewSummon->SetHealth(NewSummon->GetMaxHealth());
|
||||||
|
NewSummon->SetPower(POWER_MANA, NewSummon->GetMaxPower(POWER_MANA));
|
||||||
|
|
||||||
|
NewSummon->SavePetToDB(PET_SAVE_AS_CURRENT);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
NewSummon->setPetType(SUMMON_PET);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
NewSummon->setPetType(GUARDIAN_PET);
|
||||||
|
|
||||||
|
CreatureInfo const* cInfo = petentry ? ObjectMgr::GetCreatureTemplate(petentry) : nullptr;
|
||||||
|
if (!cInfo)
|
||||||
|
{
|
||||||
|
sLog.outErrorDb("EffectSummonPet: creature entry %u not found for spell %u.", petentry, m_spellInfo->Id);
|
||||||
delete NewSummon;
|
delete NewSummon;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -6695,69 +6683,65 @@ void Spell::EffectSummonPet(SpellEffectEntry const* effect)
|
||||||
|
|
||||||
NewSummon->SetRespawnCoord(pos);
|
NewSummon->SetRespawnCoord(pos);
|
||||||
|
|
||||||
uint32 petlevel = m_caster->getLevel();
|
// Level of pet summoned
|
||||||
NewSummon->setPetType(SUMMON_PET);
|
uint32 level = std::max(m_caster->getLevel() + effect->EffectMultipleValue, 1.0f);
|
||||||
|
|
||||||
uint32 faction = m_caster->getFaction();
|
|
||||||
if (m_caster->GetTypeId() == TYPEID_UNIT)
|
|
||||||
{
|
|
||||||
if (((Creature*)m_caster)->IsTotem())
|
|
||||||
NewSummon->GetCharmInfo()->SetReactState(REACT_AGGRESSIVE);
|
|
||||||
else
|
|
||||||
NewSummon->GetCharmInfo()->SetReactState(REACT_DEFENSIVE);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
NewSummon->GetCharmInfo()->SetReactState(REACT_DEFENSIVE);
|
||||||
NewSummon->SetOwnerGuid(m_caster->GetObjectGuid());
|
NewSummon->SetOwnerGuid(m_caster->GetObjectGuid());
|
||||||
NewSummon->SetCreatorGuid(m_caster->GetObjectGuid());
|
NewSummon->SetCreatorGuid(m_caster->GetObjectGuid());
|
||||||
NewSummon->SetUInt32Value(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_NONE);
|
NewSummon->setFaction(m_caster->getFaction());
|
||||||
NewSummon->setFaction(faction);
|
NewSummon->SetUInt32Value(UNIT_FIELD_PET_NAME_TIMESTAMP, uint32(time(nullptr)));
|
||||||
NewSummon->SetUInt32Value(UNIT_FIELD_PET_NAME_TIMESTAMP, uint32(time(NULL)));
|
|
||||||
NewSummon->SetUInt32Value(UNIT_FIELD_PETEXPERIENCE, 0);
|
|
||||||
NewSummon->SetUInt32Value(UNIT_FIELD_PETNEXTLEVELEXP, 1000);
|
|
||||||
NewSummon->SetUInt32Value(UNIT_CREATED_BY_SPELL, m_spellInfo->Id);
|
NewSummon->SetUInt32Value(UNIT_CREATED_BY_SPELL, m_spellInfo->Id);
|
||||||
|
|
||||||
NewSummon->GetCharmInfo()->SetPetNumber(pet_number, true);
|
NewSummon->InitStatsForLevel(level);
|
||||||
// this enables pet details window (Shift+P)
|
|
||||||
|
|
||||||
if (m_caster->IsPvP())
|
|
||||||
NewSummon->SetPvP(true);
|
|
||||||
|
|
||||||
if (m_caster->IsFFAPvP())
|
|
||||||
NewSummon->SetFFAPvP(true);
|
|
||||||
|
|
||||||
NewSummon->InitStatsForLevel(petlevel, m_caster);
|
|
||||||
NewSummon->InitPetCreateSpells();
|
NewSummon->InitPetCreateSpells();
|
||||||
NewSummon->InitLevelupSpellsForLevel();
|
NewSummon->InitLevelupSpellsForLevel();
|
||||||
NewSummon->InitTalentForLevel();
|
NewSummon->InitTalentForLevel();
|
||||||
|
|
||||||
if (m_caster->GetTypeId() == TYPEID_PLAYER && NewSummon->getPetType() == SUMMON_PET)
|
|
||||||
{
|
|
||||||
// generate new name for summon pet
|
|
||||||
std::string new_name = sObjectMgr.GeneratePetName(petentry);
|
|
||||||
if (!new_name.empty())
|
|
||||||
NewSummon->SetName(new_name);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (NewSummon->getPetType() == HUNTER_PET)
|
|
||||||
{
|
|
||||||
NewSummon->RemoveByteFlag(UNIT_FIELD_BYTES_2, 2, UNIT_CAN_BE_RENAMED);
|
|
||||||
NewSummon->SetByteFlag(UNIT_FIELD_BYTES_2, 2, UNIT_CAN_BE_ABANDONED);
|
|
||||||
}
|
|
||||||
|
|
||||||
NewSummon->AIM_Initialize();
|
|
||||||
NewSummon->SetHealth(NewSummon->GetMaxHealth());
|
|
||||||
NewSummon->SetPower(POWER_MANA, NewSummon->GetMaxPower(POWER_MANA));
|
|
||||||
|
|
||||||
map->Add((Creature*)NewSummon);
|
map->Add((Creature*)NewSummon);
|
||||||
|
NewSummon->AIM_Initialize();
|
||||||
|
|
||||||
m_caster->SetPet(NewSummon);
|
m_caster->SetPet(NewSummon);
|
||||||
DEBUG_LOG("New Pet has guid %u", NewSummon->GetGUIDLow());
|
DEBUG_LOG("New Pet has guid %u", NewSummon->GetGUIDLow());
|
||||||
|
|
||||||
if (m_caster->GetTypeId() == TYPEID_PLAYER)
|
if (m_caster->GetTypeId() == TYPEID_PLAYER)
|
||||||
{
|
{
|
||||||
|
NewSummon->SetUInt32Value(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_NONE);
|
||||||
|
|
||||||
|
NewSummon->SetByteValue(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_SUPPORTABLE | UNIT_BYTE2_FLAG_AURAS);
|
||||||
|
NewSummon->SetUInt32Value(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE);
|
||||||
|
|
||||||
|
NewSummon->GetCharmInfo()->SetPetNumber(pet_number, true);
|
||||||
|
|
||||||
|
// generate new name for summon pet
|
||||||
|
NewSummon->SetName(sObjectMgr.GeneratePetName(petentry));
|
||||||
|
|
||||||
|
if (m_caster->IsPvP())
|
||||||
|
NewSummon->SetPvP(true);
|
||||||
|
|
||||||
|
if (m_caster->IsFFAPvP())
|
||||||
|
NewSummon->SetFFAPvP(true);
|
||||||
|
|
||||||
NewSummon->SavePetToDB(PET_SAVE_AS_CURRENT);
|
NewSummon->SavePetToDB(PET_SAVE_AS_CURRENT);
|
||||||
((Player*)m_caster)->PetSpellInitialize();
|
((Player*)m_caster)->PetSpellInitialize();
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Notify Summoner
|
||||||
|
if (m_originalCaster && (m_originalCaster != m_caster)
|
||||||
|
&& (m_originalCaster->GetTypeId() == TYPEID_UNIT) && ((Creature*)m_originalCaster)->AI())
|
||||||
|
{
|
||||||
|
((Creature*)m_originalCaster)->AI()->JustSummoned(NewSummon);
|
||||||
|
if (m_originalCaster->IsInCombat() && !(NewSummon->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PASSIVE)))
|
||||||
|
((Creature*)NewSummon)->AI()->AttackStart(m_originalCaster->getAttackerForHelper());
|
||||||
|
}
|
||||||
|
else if ((m_caster->GetTypeId() == TYPEID_UNIT) && ((Creature*)m_caster)->AI())
|
||||||
|
{
|
||||||
|
((Creature*)m_caster)->AI()->JustSummoned(NewSummon);
|
||||||
|
if (m_caster->IsInCombat() && !(NewSummon->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PASSIVE)))
|
||||||
|
((Creature*)NewSummon)->AI()->AttackStart(m_caster->getAttackerForHelper());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Spell::EffectLearnPetSpell(SpellEffectEntry const* effect)
|
void Spell::EffectLearnPetSpell(SpellEffectEntry const* effect)
|
||||||
|
|
@ -11490,8 +11474,8 @@ void Spell::EffectActivateRune(SpellEffectEntry const* effect)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
int32 count = damage; // max amount of reset runes
|
int32 count = damage; // max amount of reset runes
|
||||||
if (plr->ActivateRunes(RuneType(effect->EffectMiscValue), count))
|
|
||||||
plr->ResyncRunes();
|
plr->ResyncRunes();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Spell::EffectTitanGrip(SpellEffectEntry const* effect)
|
void Spell::EffectTitanGrip(SpellEffectEntry const* effect)
|
||||||
|
|
|
||||||
|
|
@ -186,6 +186,14 @@ void WorldSession::HandleActivateTaxiExpressOpcode(WorldPacket& recv_data)
|
||||||
{
|
{
|
||||||
uint32 node;
|
uint32 node;
|
||||||
recv_data >> node;
|
recv_data >> node;
|
||||||
|
|
||||||
|
if (!_player->m_taxi.IsTaximaskNodeKnown(node) && !_player->IsTaxiCheater())
|
||||||
|
{
|
||||||
|
SendActivateTaxiReply(ERR_TAXINOTVISITED);
|
||||||
|
recv_data.rpos(recv_data.wpos()); // prevent additional spam at rejected packet
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
nodes.push_back(node);
|
nodes.push_back(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -282,5 +290,14 @@ void WorldSession::HandleActivateTaxiOpcode(WorldPacket& recv_data)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!_player->IsTaxiCheater())
|
||||||
|
{
|
||||||
|
if (!_player->m_taxi.IsTaximaskNodeKnown(nodes[0]) || !_player->m_taxi.IsTaximaskNodeKnown(nodes[1]))
|
||||||
|
{
|
||||||
|
SendActivateTaxiReply(ERR_TAXINOTVISITED);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
GetPlayer()->ActivateTaxiPathTo(nodes, npc);
|
GetPlayer()->ActivateTaxiPathTo(nodes, npc);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -101,12 +101,16 @@ void WorldSession::HandleChangeSeatsOnControlledVehicle(WorldPacket& recvPacket)
|
||||||
DEBUG_LOG("WORLD: Received opcode CMSG_CHANGE_SEATS_ON_CONTROLLED_VEHICLE");
|
DEBUG_LOG("WORLD: Received opcode CMSG_CHANGE_SEATS_ON_CONTROLLED_VEHICLE");
|
||||||
recvPacket.hexlike();
|
recvPacket.hexlike();
|
||||||
|
|
||||||
|
ObjectGuid srcVehicleGuid;
|
||||||
MovementInfo movementInfo;
|
MovementInfo movementInfo;
|
||||||
|
ObjectGuid destVehicleGuid;
|
||||||
|
uint8 seat;
|
||||||
|
|
||||||
recvPacket >> movementInfo; // Not used at the moment
|
recvPacket >> movementInfo;
|
||||||
ObjectGuid srcVehicleGuid = movementInfo.GetGuid();
|
|
||||||
ObjectGuid destVehicleGuid = movementInfo.GetGuid2();
|
srcVehicleGuid = movementInfo.GetGuid();
|
||||||
uint8 seat = movementInfo.GetByteParam();
|
destVehicleGuid = movementInfo.GetGuid2();
|
||||||
|
seat = movementInfo.GetByteParam();
|
||||||
|
|
||||||
TransportInfo* transportInfo = _player->GetTransportInfo();
|
TransportInfo* transportInfo = _player->GetTransportInfo();
|
||||||
if (!transportInfo || !transportInfo->IsOnVehicle())
|
if (!transportInfo || !transportInfo->IsOnVehicle())
|
||||||
|
|
|
||||||
|
|
@ -34,6 +34,7 @@
|
||||||
#include "Log.h"
|
#include "Log.h"
|
||||||
// #include "ObjectMgr.h" // chucky delete ?
|
// #include "ObjectMgr.h" // chucky delete ?
|
||||||
#include "Util.h"
|
#include "Util.h"
|
||||||
|
#include "ProgressBar.h"
|
||||||
#ifdef ENABLE_ELUNA
|
#ifdef ENABLE_ELUNA
|
||||||
#include "LuaEngine.h"
|
#include "LuaEngine.h"
|
||||||
#endif /* ENABLE_ELUNA */
|
#endif /* ENABLE_ELUNA */
|
||||||
|
|
@ -154,8 +155,8 @@ bool Weather::ReGenerate()
|
||||||
uint32 chance1 = m_weatherChances->data[season].rainChance;
|
uint32 chance1 = m_weatherChances->data[season].rainChance;
|
||||||
uint32 chance2 = chance1 + m_weatherChances->data[season].snowChance;
|
uint32 chance2 = chance1 + m_weatherChances->data[season].snowChance;
|
||||||
uint32 chance3 = chance2 + m_weatherChances->data[season].stormChance;
|
uint32 chance3 = chance2 + m_weatherChances->data[season].stormChance;
|
||||||
|
|
||||||
uint32 rnd = urand(0, 99);
|
uint32 rnd = urand(1, 100);
|
||||||
if (rnd <= chance1)
|
if (rnd <= chance1)
|
||||||
{
|
{
|
||||||
m_type = WEATHER_TYPE_RAIN;
|
m_type = WEATHER_TYPE_RAIN;
|
||||||
|
|
|
||||||
|
|
@ -144,19 +144,17 @@ World::~World()
|
||||||
// it is assumed that no other thread is accessing this data when the destructor is called. therefore, no locks are necessary
|
// it is assumed that no other thread is accessing this data when the destructor is called. therefore, no locks are necessary
|
||||||
|
|
||||||
///- Empty the kicked session set
|
///- Empty the kicked session set
|
||||||
std::for_each(m_sessions.begin(), m_sessions.end(), [](const SessionMap::value_type &p) { delete p.second; });
|
for (auto const session : m_sessions)
|
||||||
m_sessions.clear();
|
delete session.second;
|
||||||
|
|
||||||
std::for_each(m_cliCommandQueue.begin(), m_cliCommandQueue.end(), [](const CliCommandHolder *p) { delete p; });
|
for (auto const cliCommand : m_cliCommandQueue)
|
||||||
m_cliCommandQueue.clear();
|
delete cliCommand;
|
||||||
|
|
||||||
std::for_each(m_sessionAddQueue.begin(), m_sessionAddQueue.end(), [](const WorldSession *s) { delete s; });
|
for (auto const session : m_sessionAddQueue)
|
||||||
m_sessionAddQueue.clear();
|
delete session;
|
||||||
|
|
||||||
VMAP::VMapFactory::clear();
|
VMAP::VMapFactory::clear();
|
||||||
MMAP::MMapFactory::clear();
|
MMAP::MMapFactory::clear();
|
||||||
|
|
||||||
delete m_configForceLoadMapIds;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Cleanups before world stop
|
/// Cleanups before world stop
|
||||||
|
|
@ -577,6 +575,17 @@ void World::LoadConfigSettings(bool reload)
|
||||||
setConfig(CONFIG_BOOL_ADDON_CHANNEL, "AddonChannel", true);
|
setConfig(CONFIG_BOOL_ADDON_CHANNEL, "AddonChannel", true);
|
||||||
setConfig(CONFIG_BOOL_CLEAN_CHARACTER_DB, "CleanCharacterDB", true);
|
setConfig(CONFIG_BOOL_CLEAN_CHARACTER_DB, "CleanCharacterDB", true);
|
||||||
setConfig(CONFIG_BOOL_GRID_UNLOAD, "GridUnload", true);
|
setConfig(CONFIG_BOOL_GRID_UNLOAD, "GridUnload", true);
|
||||||
|
|
||||||
|
std::string forceLoadGridOnMaps = sConfig.GetStringDefault("LoadAllGridsOnMaps", "");
|
||||||
|
if (!forceLoadGridOnMaps.empty())
|
||||||
|
{
|
||||||
|
unsigned int pos = 0;
|
||||||
|
unsigned int id;
|
||||||
|
VMAP::VMapFactory::chompAndTrim(forceLoadGridOnMaps);
|
||||||
|
while (VMAP::VMapFactory::getNextId(forceLoadGridOnMaps, pos, id))
|
||||||
|
m_configForceLoadMapIds.insert(id);
|
||||||
|
}
|
||||||
|
|
||||||
setConfig(CONFIG_UINT32_INTERVAL_SAVE, "PlayerSave.Interval", 15 * MINUTE * IN_MILLISECONDS);
|
setConfig(CONFIG_UINT32_INTERVAL_SAVE, "PlayerSave.Interval", 15 * MINUTE * IN_MILLISECONDS);
|
||||||
setConfigMinMax(CONFIG_UINT32_MIN_LEVEL_STAT_SAVE, "PlayerSave.Stats.MinLevel", 0, 0, MAX_LEVEL);
|
setConfigMinMax(CONFIG_UINT32_MIN_LEVEL_STAT_SAVE, "PlayerSave.Stats.MinLevel", 0, 0, MAX_LEVEL);
|
||||||
setConfig(CONFIG_BOOL_STATS_SAVE_ONLY_ON_LOGOUT, "PlayerSave.Stats.SaveOnlyOnLogout", true);
|
setConfig(CONFIG_BOOL_STATS_SAVE_ONLY_ON_LOGOUT, "PlayerSave.Stats.SaveOnlyOnLogout", true);
|
||||||
|
|
@ -635,7 +644,7 @@ void World::LoadConfigSettings(bool reload)
|
||||||
if (configNoReload(reload, CONFIG_UINT32_MAX_PLAYER_LEVEL, "MaxPlayerLevel", DEFAULT_MAX_LEVEL))
|
if (configNoReload(reload, CONFIG_UINT32_MAX_PLAYER_LEVEL, "MaxPlayerLevel", DEFAULT_MAX_LEVEL))
|
||||||
{ setConfigMinMax(CONFIG_UINT32_MAX_PLAYER_LEVEL, "MaxPlayerLevel", DEFAULT_MAX_LEVEL, 1, DEFAULT_MAX_LEVEL); }
|
{ setConfigMinMax(CONFIG_UINT32_MAX_PLAYER_LEVEL, "MaxPlayerLevel", DEFAULT_MAX_LEVEL, 1, DEFAULT_MAX_LEVEL); }
|
||||||
|
|
||||||
setConfigMinMax(CONFIG_UINT32_START_PLAYER_LEVEL, "StartPlayerLevel", 1, 1, getConfig(CONFIG_UINT32_MAX_PLAYER_LEVEL));
|
setConfigMinMax(CONFIG_UINT32_START_PLAYER_LEVEL, "StartPlayerLevel", 1, 1, (uint32)getConfig(CONFIG_UINT32_MAX_PLAYER_LEVEL));
|
||||||
setConfigMinMax(CONFIG_UINT32_START_HEROIC_PLAYER_LEVEL, "StartHeroicPlayerLevel", 55, 1, getConfig(CONFIG_UINT32_MAX_PLAYER_LEVEL));
|
setConfigMinMax(CONFIG_UINT32_START_HEROIC_PLAYER_LEVEL, "StartHeroicPlayerLevel", 55, 1, getConfig(CONFIG_UINT32_MAX_PLAYER_LEVEL));
|
||||||
|
|
||||||
setConfigMinMax(CONFIG_UINT64_START_PLAYER_MONEY, "StartPlayerMoney", 0, 0, MAX_MONEY_AMOUNT);
|
setConfigMinMax(CONFIG_UINT64_START_PLAYER_MONEY, "StartPlayerMoney", 0, 0, MAX_MONEY_AMOUNT);
|
||||||
|
|
@ -787,6 +796,7 @@ void World::LoadConfigSettings(bool reload)
|
||||||
setConfig(CONFIG_BOOL_BATTLEGROUND_CAST_DESERTER, "Battleground.CastDeserter", true);
|
setConfig(CONFIG_BOOL_BATTLEGROUND_CAST_DESERTER, "Battleground.CastDeserter", true);
|
||||||
setConfigMinMax(CONFIG_UINT32_BATTLEGROUND_QUEUE_ANNOUNCER_JOIN, "Battleground.QueueAnnouncer.Join", 0, 0, 2);
|
setConfigMinMax(CONFIG_UINT32_BATTLEGROUND_QUEUE_ANNOUNCER_JOIN, "Battleground.QueueAnnouncer.Join", 0, 0, 2);
|
||||||
setConfig(CONFIG_BOOL_BATTLEGROUND_QUEUE_ANNOUNCER_START, "Battleground.QueueAnnouncer.Start", false);
|
setConfig(CONFIG_BOOL_BATTLEGROUND_QUEUE_ANNOUNCER_START, "Battleground.QueueAnnouncer.Start", false);
|
||||||
|
setConfig(CONFIG_BOOL_BATTLEGROUND_SCORE_STATISTICS, "Battleground.ScoreStatistics", false);
|
||||||
setConfig(CONFIG_UINT32_BATTLEGROUND_INVITATION_TYPE, "Battleground.InvitationType", 0);
|
setConfig(CONFIG_UINT32_BATTLEGROUND_INVITATION_TYPE, "Battleground.InvitationType", 0);
|
||||||
setConfig(CONFIG_UINT32_BATTLEGROUND_PREMATURE_FINISH_TIMER, "BattleGround.PrematureFinishTimer", 5 * MINUTE * IN_MILLISECONDS);
|
setConfig(CONFIG_UINT32_BATTLEGROUND_PREMATURE_FINISH_TIMER, "BattleGround.PrematureFinishTimer", 5 * MINUTE * IN_MILLISECONDS);
|
||||||
setConfig(CONFIG_UINT32_BATTLEGROUND_PREMADE_GROUP_WAIT_FOR_MATCH, "BattleGround.PremadeGroupWaitForMatch", 30 * MINUTE * IN_MILLISECONDS);
|
setConfig(CONFIG_UINT32_BATTLEGROUND_PREMADE_GROUP_WAIT_FOR_MATCH, "BattleGround.PremadeGroupWaitForMatch", 30 * MINUTE * IN_MILLISECONDS);
|
||||||
|
|
|
||||||
|
|
@ -612,6 +612,9 @@ class World
|
||||||
/// Get a server configuration element (see #eConfigBoolValues)
|
/// Get a server configuration element (see #eConfigBoolValues)
|
||||||
bool getConfig(eConfigBoolValues index) const { return m_configBoolValues[index]; }
|
bool getConfig(eConfigBoolValues index) const { return m_configBoolValues[index]; }
|
||||||
|
|
||||||
|
/// Get configuration about force-loaded maps
|
||||||
|
bool isForceLoadMap(uint32 id) const { return m_configForceLoadMapIds.find(id) != m_configForceLoadMapIds.end(); }
|
||||||
|
|
||||||
/// Are we on a "Player versus Player" server?
|
/// Are we on a "Player versus Player" server?
|
||||||
bool IsPvPRealm() { return (getConfig(CONFIG_UINT32_GAME_TYPE) == REALM_TYPE_PVP || getConfig(CONFIG_UINT32_GAME_TYPE) == REALM_TYPE_RPPVP || getConfig(CONFIG_UINT32_GAME_TYPE) == REALM_TYPE_FFA_PVP); }
|
bool IsPvPRealm() { return (getConfig(CONFIG_UINT32_GAME_TYPE) == REALM_TYPE_PVP || getConfig(CONFIG_UINT32_GAME_TYPE) == REALM_TYPE_RPPVP || getConfig(CONFIG_UINT32_GAME_TYPE) == REALM_TYPE_FFA_PVP); }
|
||||||
bool IsFFAPvPRealm() { return getConfig(CONFIG_UINT32_GAME_TYPE) == REALM_TYPE_FFA_PVP; }
|
bool IsFFAPvPRealm() { return getConfig(CONFIG_UINT32_GAME_TYPE) == REALM_TYPE_FFA_PVP; }
|
||||||
|
|
@ -766,9 +769,10 @@ class World
|
||||||
|
|
||||||
// used versions
|
// used versions
|
||||||
std::string m_DBVersion;
|
std::string m_DBVersion;
|
||||||
|
std::string m_CreatureEventAIVersion;
|
||||||
|
|
||||||
// List of Maps that should be force-loaded on startup
|
// List of Maps that should be force-loaded on startup
|
||||||
std::set<uint32>* m_configForceLoadMapIds;
|
std::set<uint32> m_configForceLoadMapIds;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern uint32 realmID;
|
extern uint32 realmID;
|
||||||
|
|
|
||||||
|
|
@ -171,7 +171,7 @@ namespace Movement
|
||||||
{
|
{
|
||||||
// mix existing state into new
|
// mix existing state into new
|
||||||
args.flags.walkmode = unit.m_movementInfo.HasMovementFlag(MOVEFLAG_WALK_MODE);
|
args.flags.walkmode = unit.m_movementInfo.HasMovementFlag(MOVEFLAG_WALK_MODE);
|
||||||
args.flags.flying = unit.m_movementInfo.HasMovementFlag((MovementFlags)(MOVEFLAG_FLYING | MOVEFLAG_LEVITATING));
|
args.flags.flying = unit.m_movementInfo.HasMovementFlag((MovementFlags)(MOVEFLAG_CAN_FLY | MOVEFLAG_FLYING | MOVEFLAG_LEVITATING));
|
||||||
}
|
}
|
||||||
|
|
||||||
void MoveSplineInit::SetFacing(const Unit* target)
|
void MoveSplineInit::SetFacing(const Unit* target)
|
||||||
|
|
|
||||||
|
|
@ -43,7 +43,7 @@ namespace Movement
|
||||||
* @brief Initializes and launches spline movement
|
* @brief Initializes and launches spline movement
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
class MoveSplineInit
|
class MANGOS_DLL_SPEC MoveSplineInit
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,7 @@ using namespace G3D;
|
||||||
|
|
||||||
namespace VMAP
|
namespace VMAP
|
||||||
{
|
{
|
||||||
void chompAndTrim(std::string& str)
|
void VMapFactory::chompAndTrim(std::string& str)
|
||||||
{
|
{
|
||||||
while (str.length() > 0)
|
while (str.length() > 0)
|
||||||
{
|
{
|
||||||
|
|
@ -64,7 +64,7 @@ namespace VMAP
|
||||||
//===============================================
|
//===============================================
|
||||||
// result false, if no more id are found
|
// result false, if no more id are found
|
||||||
|
|
||||||
bool getNextId(const std::string& pString, unsigned int& pStartPos, unsigned int& pId)
|
bool VMapFactory::getNextId(const std::string& pString, unsigned int& pStartPos, unsigned int& pId)
|
||||||
{
|
{
|
||||||
bool result = false;
|
bool result = false;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
|
||||||
|
|
@ -43,6 +43,9 @@ namespace VMAP
|
||||||
|
|
||||||
static void preventSpellsFromBeingTestedForLoS(const char* pSpellIdString);
|
static void preventSpellsFromBeingTestedForLoS(const char* pSpellIdString);
|
||||||
static bool checkSpellForLoS(unsigned int pSpellId);
|
static bool checkSpellForLoS(unsigned int pSpellId);
|
||||||
|
|
||||||
|
static void chompAndTrim(std::string& str);
|
||||||
|
static bool getNextId(const std::string& pString, unsigned int& pStartPos, unsigned int& pId);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -113,6 +113,12 @@ BindIP = "0.0.0.0"
|
||||||
# Default: 1 (unload grids)
|
# Default: 1 (unload grids)
|
||||||
# 0 (do not unload grids)
|
# 0 (do not unload grids)
|
||||||
#
|
#
|
||||||
|
# LoadAllGridsOnMaps
|
||||||
|
# Load grids of maps at server startup (if you have lot memory you can try it to have a living world always loaded)
|
||||||
|
# This also allow ALL creatures on the given maps to update their grid without any player around.
|
||||||
|
# Default: "" (don't load all grids at startup)
|
||||||
|
# "mapId1[,mapId2[..]]" (DO load all grids on the given maps- Experimental and very resource consumming)
|
||||||
|
#
|
||||||
# GridCleanUpDelay
|
# GridCleanUpDelay
|
||||||
# Grid clean up delay (in milliseconds)
|
# Grid clean up delay (in milliseconds)
|
||||||
# Default: 300000 (5 min)
|
# Default: 300000 (5 min)
|
||||||
|
|
@ -207,6 +213,7 @@ PlayerLimit = 100
|
||||||
SaveRespawnTimeImmediately = 1
|
SaveRespawnTimeImmediately = 1
|
||||||
MaxOverspeedPings = 2
|
MaxOverspeedPings = 2
|
||||||
GridUnload = 1
|
GridUnload = 1
|
||||||
|
LoadAllGridsOnMaps = ""
|
||||||
GridCleanUpDelay = 300000
|
GridCleanUpDelay = 300000
|
||||||
MapUpdateInterval = 100
|
MapUpdateInterval = 100
|
||||||
ChangeWeatherInterval = 600000
|
ChangeWeatherInterval = 600000
|
||||||
|
|
@ -1487,6 +1494,11 @@ Death.Ghost.RunSpeed.Battleground = 1.0
|
||||||
# 1 (send to joined player only)
|
# 1 (send to joined player only)
|
||||||
# 2 (send to all players)
|
# 2 (send to all players)
|
||||||
#
|
#
|
||||||
|
# Battleground.ScoreStatistics
|
||||||
|
# Enable Battleground scores storage in database
|
||||||
|
# Default: 0 (disable)
|
||||||
|
# 1 (enable)
|
||||||
|
#
|
||||||
# Battleground.QueueAnnouncer.Start
|
# Battleground.QueueAnnouncer.Start
|
||||||
# Enable queue announcer posting to chat at BG start
|
# Enable queue announcer posting to chat at BG start
|
||||||
# Default: 0 (disable)
|
# Default: 0 (disable)
|
||||||
|
|
@ -1512,6 +1524,7 @@ Death.Ghost.RunSpeed.Battleground = 1.0
|
||||||
Battleground.CastDeserter = 1
|
Battleground.CastDeserter = 1
|
||||||
Battleground.QueueAnnouncer.Join = 0
|
Battleground.QueueAnnouncer.Join = 0
|
||||||
Battleground.QueueAnnouncer.Start = 0
|
Battleground.QueueAnnouncer.Start = 0
|
||||||
|
Battleground.ScoreStatistics = 0
|
||||||
Battleground.InvitationType = 0
|
Battleground.InvitationType = 0
|
||||||
BattleGround.PrematureFinishTimer = 300000
|
BattleGround.PrematureFinishTimer = 300000
|
||||||
BattleGround.PremadeGroupWaitForMatch = 1800000
|
BattleGround.PremadeGroupWaitForMatch = 1800000
|
||||||
|
|
|
||||||
|
|
@ -105,7 +105,7 @@ namespace LuaUnit
|
||||||
Creature* creature = Eluna::CHECKOBJ<Creature>(L, 2);
|
Creature* creature = Eluna::CHECKOBJ<Creature>(L, 2);
|
||||||
|
|
||||||
#ifndef TRINITY
|
#ifndef TRINITY
|
||||||
Eluna::Push(L, unit->isInAccessablePlaceFor(creature));
|
Eluna::Push(L, unit->IsInAccessablePlaceFor(creature));
|
||||||
#else
|
#else
|
||||||
Eluna::Push(L, unit->isInAccessiblePlaceFor(creature));
|
Eluna::Push(L, unit->isInAccessiblePlaceFor(creature));
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -1707,12 +1707,12 @@ namespace LuaUnit
|
||||||
|
|
||||||
if (apply)
|
if (apply)
|
||||||
{
|
{
|
||||||
unit->SetByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_SANCTUARY);
|
unit->SetByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_SUPPORTABLE);
|
||||||
unit->CombatStop();
|
unit->CombatStop();
|
||||||
unit->CombatStopWithPets();
|
unit->CombatStopWithPets();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
unit->RemoveByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_SANCTUARY);
|
unit->RemoveByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_SUPPORTABLE);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -184,7 +184,7 @@ bool npc_escortAI::AssistPlayerInCombat(Unit* pWho)
|
||||||
|
|
||||||
void npc_escortAI::MoveInLineOfSight(Unit* pWho)
|
void npc_escortAI::MoveInLineOfSight(Unit* pWho)
|
||||||
{
|
{
|
||||||
if (pWho->IsTargetableForAttack() && pWho->isInAccessablePlaceFor(m_creature))
|
if (pWho->IsTargetableForAttack() && pWho->IsInAccessablePlaceFor(m_creature))
|
||||||
{
|
{
|
||||||
// AssistPlayerInCombat can start attack, so return if true
|
// AssistPlayerInCombat can start attack, so return if true
|
||||||
if (HasEscortState(STATE_ESCORT_ESCORTING) && AssistPlayerInCombat(pWho))
|
if (HasEscortState(STATE_ESCORT_ESCORTING) && AssistPlayerInCombat(pWho))
|
||||||
|
|
|
||||||
|
|
@ -122,7 +122,7 @@ bool FollowerAI::AssistPlayerInCombat(Unit* pWho)
|
||||||
|
|
||||||
void FollowerAI::MoveInLineOfSight(Unit* pWho)
|
void FollowerAI::MoveInLineOfSight(Unit* pWho)
|
||||||
{
|
{
|
||||||
if (pWho->IsTargetableForAttack() && pWho->isInAccessablePlaceFor(m_creature))
|
if (pWho->IsTargetableForAttack() && pWho->IsInAccessablePlaceFor(m_creature))
|
||||||
{
|
{
|
||||||
// AssistPlayerInCombat can start attack, so return if true
|
// AssistPlayerInCombat can start attack, so return if true
|
||||||
if (HasFollowState(STATE_FOLLOW_INPROGRESS) && AssistPlayerInCombat(pWho))
|
if (HasFollowState(STATE_FOLLOW_INPROGRESS) && AssistPlayerInCombat(pWho))
|
||||||
|
|
|
||||||
|
|
@ -56,7 +56,7 @@ void ScriptedPetAI::MoveInLineOfSight(Unit* pWho)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_creature->CanInitiateAttack() && pWho->IsTargetableForAttack() &&
|
if (m_creature->CanInitiateAttack() && pWho->IsTargetableForAttack() &&
|
||||||
m_creature->IsHostileTo(pWho) && pWho->isInAccessablePlaceFor(m_creature))
|
m_creature->IsHostileTo(pWho) && pWho->IsInAccessablePlaceFor(m_creature))
|
||||||
{
|
{
|
||||||
if (!m_creature->CanFly() && m_creature->GetDistanceZ(pWho) > CREATURE_Z_ATTACK_RANGE)
|
if (!m_creature->CanFly() && m_creature->GetDistanceZ(pWho) > CREATURE_Z_ATTACK_RANGE)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -74,7 +74,7 @@ bool ScriptedAI::IsVisible(Unit* pWho) const
|
||||||
void ScriptedAI::MoveInLineOfSight(Unit* pWho)
|
void ScriptedAI::MoveInLineOfSight(Unit* pWho)
|
||||||
{
|
{
|
||||||
if (m_creature->CanInitiateAttack() && pWho->IsTargetableForAttack() &&
|
if (m_creature->CanInitiateAttack() && pWho->IsTargetableForAttack() &&
|
||||||
m_creature->IsHostileTo(pWho) && pWho->isInAccessablePlaceFor(m_creature))
|
m_creature->IsHostileTo(pWho) && pWho->IsInAccessablePlaceFor(m_creature))
|
||||||
{
|
{
|
||||||
if (!m_creature->CanFly() && m_creature->GetDistanceZ(pWho) > CREATURE_Z_ATTACK_RANGE)
|
if (!m_creature->CanFly() && m_creature->GetDistanceZ(pWho) > CREATURE_Z_ATTACK_RANGE)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -59,14 +59,14 @@ struct npc_ragged_john : public CreatureScript
|
||||||
{
|
{
|
||||||
if (who->HasAura(16468, EFFECT_INDEX_0))
|
if (who->HasAura(16468, EFFECT_INDEX_0))
|
||||||
{
|
{
|
||||||
if (who->GetTypeId() == TYPEID_PLAYER && m_creature->IsWithinDistInMap(who, 15) && who->isInAccessablePlaceFor(m_creature))
|
if (who->GetTypeId() == TYPEID_PLAYER && m_creature->IsWithinDistInMap(who, 15) && who->IsInAccessablePlaceFor(m_creature))
|
||||||
{
|
{
|
||||||
DoCastSpellIfCan(who, 16472);
|
DoCastSpellIfCan(who, 16472);
|
||||||
((Player*)who)->AreaExploredOrEventHappens(4866);
|
((Player*)who)->AreaExploredOrEventHappens(4866);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!m_creature->getVictim() && who->IsTargetableForAttack() && (m_creature->IsHostileTo(who)) && who->isInAccessablePlaceFor(m_creature))
|
if (!m_creature->getVictim() && who->IsTargetableForAttack() && (m_creature->IsHostileTo(who)) && who->IsInAccessablePlaceFor(m_creature))
|
||||||
{
|
{
|
||||||
if (!m_creature->CanFly() && m_creature->GetDistanceZ(who) > CREATURE_Z_ATTACK_RANGE)
|
if (!m_creature->CanFly() && m_creature->GetDistanceZ(who) > CREATURE_Z_ATTACK_RANGE)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -1247,7 +1247,7 @@ struct horde_defender : public CreatureScript
|
||||||
void MoveInLineOfSight(Unit* u) override
|
void MoveInLineOfSight(Unit* u) override
|
||||||
{
|
{
|
||||||
if (m_creature->CanInitiateAttack() && u->IsTargetableForAttack() &&
|
if (m_creature->CanInitiateAttack() && u->IsTargetableForAttack() &&
|
||||||
m_creature->IsHostileTo(u) && u->isInAccessablePlaceFor(m_creature))
|
m_creature->IsHostileTo(u) && u->IsInAccessablePlaceFor(m_creature))
|
||||||
{
|
{
|
||||||
float attackRadius = 38.0f;
|
float attackRadius = 38.0f;
|
||||||
if (m_creature->IsWithinDistInMap(u, attackRadius) && m_creature->IsWithinLOSInMap(u))
|
if (m_creature->IsWithinDistInMap(u, attackRadius) && m_creature->IsWithinLOSInMap(u))
|
||||||
|
|
@ -1330,7 +1330,7 @@ struct kolkar_invader : public CreatureScript
|
||||||
void MoveInLineOfSight(Unit* u) override
|
void MoveInLineOfSight(Unit* u) override
|
||||||
{
|
{
|
||||||
if (m_creature->CanInitiateAttack() && u->IsTargetableForAttack() &&
|
if (m_creature->CanInitiateAttack() && u->IsTargetableForAttack() &&
|
||||||
m_creature->IsHostileTo(u) && u->isInAccessablePlaceFor(m_creature))
|
m_creature->IsHostileTo(u) && u->IsInAccessablePlaceFor(m_creature))
|
||||||
{
|
{
|
||||||
float attackRadius = 38.0f;
|
float attackRadius = 38.0f;
|
||||||
if (m_creature->IsWithinDistInMap(u, attackRadius) && m_creature->IsWithinLOSInMap(u))
|
if (m_creature->IsWithinDistInMap(u, attackRadius) && m_creature->IsWithinLOSInMap(u))
|
||||||
|
|
|
||||||
|
|
@ -100,7 +100,7 @@ struct boss_talon_king_ikiss : public CreatureScript
|
||||||
|
|
||||||
void MoveInLineOfSight(Unit* pWho) override
|
void MoveInLineOfSight(Unit* pWho) override
|
||||||
{
|
{
|
||||||
if (!m_creature->getVictim() && pWho->IsTargetableForAttack() && (m_creature->IsHostileTo(pWho)) && pWho->isInAccessablePlaceFor(m_creature))
|
if (!m_creature->getVictim() && pWho->IsTargetableForAttack() && (m_creature->IsHostileTo(pWho)) && pWho->IsInAccessablePlaceFor(m_creature))
|
||||||
{
|
{
|
||||||
if (!m_bIntro && m_creature->IsWithinDistInMap(pWho, 100.0f))
|
if (!m_bIntro && m_creature->IsWithinDistInMap(pWho, 100.0f))
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -179,9 +179,12 @@ struct npc_ancestral_wolf : public CreatureScript
|
||||||
|
|
||||||
void Reset() override
|
void Reset() override
|
||||||
{
|
{
|
||||||
m_creature->CastSpell(m_creature, SPELL_ANCESTRAL_WOLF_BUFF, true);
|
DoCastSpellIfCan(m_creature, SPELL_ANCESTRAL_WOLF_BUFF);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AttackStart(Unit* /*pWho*/) override { }
|
||||||
|
void MoveInLineOfSight(Unit* /*pWho*/) override { }
|
||||||
|
|
||||||
void WaypointReached(uint32 uiPointId) override
|
void WaypointReached(uint32 uiPointId) override
|
||||||
{
|
{
|
||||||
switch (uiPointId)
|
switch (uiPointId)
|
||||||
|
|
|
||||||
|
|
@ -72,7 +72,7 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <math.h>
|
#include <cmath>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
@ -172,7 +172,7 @@ typedef off_t ACE_OFF_T;
|
||||||
* @param f
|
* @param f
|
||||||
* @return float
|
* @return float
|
||||||
*/
|
*/
|
||||||
inline float finiteAlways(float f) { return finite(f) ? f : 0.0f; }
|
inline float finiteAlways(float f) { return std::isfinite(f) ? f : 0.0f; }
|
||||||
|
|
||||||
#define atol(a) strtoul( a, NULL, 10)
|
#define atol(a) strtoul( a, NULL, 10)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -65,7 +65,7 @@ uint32 WorldTimer::getMSTime_internal(bool savetime /*= false*/)
|
||||||
// calculate time diff between two world ticks
|
// calculate time diff between two world ticks
|
||||||
// special case: curr_time < old_time - we suppose that our time has not ticked at all
|
// special case: curr_time < old_time - we suppose that our time has not ticked at all
|
||||||
// this should be constant value otherwise it is possible that our time can start ticking backwards until next world tick!!!
|
// this should be constant value otherwise it is possible that our time can start ticking backwards until next world tick!!!
|
||||||
uint64 diff = 0;
|
ACE_UINT64 diff = 0;
|
||||||
(currTime - g_SystemTickTime).msec(diff);
|
(currTime - g_SystemTickTime).msec(diff);
|
||||||
|
|
||||||
// lets calculate current world time
|
// lets calculate current world time
|
||||||
|
|
|
||||||
|
|
@ -33,11 +33,11 @@
|
||||||
|
|
||||||
#define CHAR_DB_VERSION_NR 21
|
#define CHAR_DB_VERSION_NR 21
|
||||||
#define CHAR_DB_STRUCTURE_NR 2
|
#define CHAR_DB_STRUCTURE_NR 2
|
||||||
#define CHAR_DB_CONTENT_NR 1
|
#define CHAR_DB_CONTENT_NR 2
|
||||||
#define CHAR_DB_UPDATE_DESCRIPTION "match_client_limits"
|
#define CHAR_DB_UPDATE_DESCRIPTION "match_client_limits"
|
||||||
|
|
||||||
#define WORLD_DB_VERSION_NR 21
|
#define WORLD_DB_VERSION_NR 21
|
||||||
#define WORLD_DB_STRUCTURE_NR 1
|
#define WORLD_DB_STRUCTURE_NR 2
|
||||||
#define WORLD_DB_CONTENT_NR 0
|
#define WORLD_DB_CONTENT_NR 3
|
||||||
#define WORLD_DB_UPDATE_DESCRIPTION "script_binding populated"
|
#define WORLD_DB_UPDATE_DESCRIPTION "script_binding populated"
|
||||||
#endif // __REVISION_H__
|
#endif // __REVISION_H__
|
||||||
|
|
|
||||||
|
|
@ -67,19 +67,11 @@ else()
|
||||||
target_link_libraries(${EXECUTABLE_NAME} ACE)
|
target_link_libraries(${EXECUTABLE_NAME} ACE)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
target_link_libraries(${EXECUTABLE_NAME} g3dlite vmap detour recast zlib shared)
|
|
||||||
|
|
||||||
if(UNIX)
|
if(UNIX)
|
||||||
if(CMAKE_SYSTEM_NAME MATCHES "FreeBSD")
|
target_link_libraries(${EXECUTABLE_NAME} rt)
|
||||||
set(EXECUTABLE_LINK_FLAGS "-Wl,--no-as-needed -lrt -pthread ${EXECUTABLE_LINK_FLAGS}")
|
|
||||||
elseif(CMAKE_SYSTEM_NAME MATCHES "Linux")
|
|
||||||
set(EXECUTABLE_LINK_FLAGS "-Wl,--no-as-needed -ldl -pthread -lrt ${EXECUTABLE_LINK_FLAGS}")
|
|
||||||
endif()
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(APPLE)
|
target_link_libraries(${EXECUTABLE_NAME} g3dlite vmap detour recast zlib shared)
|
||||||
set(EXECUTABLE_LINK_FLAGS "-framework CoreServices ${EXECUTABLE_LINK_FLAGS}")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
#Output the compiled exes to build/bin/$(Configuration)/tools directory on windows by default
|
#Output the compiled exes to build/bin/$(Configuration)/tools directory on windows by default
|
||||||
if(WIN32)
|
if(WIN32)
|
||||||
|
|
|
||||||
|
|
@ -47,22 +47,20 @@ else()
|
||||||
target_link_libraries(${EXECUTABLE_NAME} ACE)
|
target_link_libraries(${EXECUTABLE_NAME} ACE)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if(UNIX)
|
||||||
|
target_link_libraries(${EXECUTABLE_NAME} rt dl)
|
||||||
|
endif()
|
||||||
|
|
||||||
target_link_libraries(${EXECUTABLE_NAME} vmap g3dlite zlib)
|
target_link_libraries(${EXECUTABLE_NAME} vmap g3dlite zlib)
|
||||||
|
|
||||||
set(EXECUTABLE_LINK_FLAGS "")
|
set(EXECUTABLE_LINK_FLAGS "")
|
||||||
|
|
||||||
if(UNIX)
|
if(UNIX)
|
||||||
if(CMAKE_SYSTEM_NAME MATCHES "FreeBSD")
|
if(CMAKE_C_COMPILER MATCHES "clang" OR CMAKE_C_COMPILER_ID STREQUAL "Clang")
|
||||||
set(EXECUTABLE_LINK_FLAGS "-Wl,--no-as-needed -lrt -pthread ${EXECUTABLE_LINK_FLAGS}")
|
set(EXECUTABLE_LINK_FLAGS "-pthread${EXECUTABLE_LINK_FLAGS}")
|
||||||
elseif(CMAKE_SYSTEM_NAME MATCHES "Linux")
|
|
||||||
set(EXECUTABLE_LINK_FLAGS "-Wl,--no-as-needed -ldl -pthread -lrt ${EXECUTABLE_LINK_FLAGS}")
|
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(APPLE)
|
|
||||||
set(EXECUTABLE_LINK_FLAGS "-framework CoreServices ${EXECUTABLE_LINK_FLAGS}")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
set_target_properties(${EXECUTABLE_NAME} PROPERTIES LINK_FLAGS "${EXECUTABLE_LINK_FLAGS}")
|
set_target_properties(${EXECUTABLE_NAME} PROPERTIES LINK_FLAGS "${EXECUTABLE_LINK_FLAGS}")
|
||||||
|
|
||||||
#Output the compiled exes to build/bin/$(Configuration)/tools directory on windows by default
|
#Output the compiled exes to build/bin/$(Configuration)/tools directory on windows by default
|
||||||
|
|
|
||||||
|
|
@ -43,7 +43,7 @@ add_executable(${EXECUTABLE_NAME} ${EXECUTABLE_SRCS}
|
||||||
${CMAKE_SOURCE_DIR}/src/tools/Extractor_projects/shared/ExtractorCommon.cpp
|
${CMAKE_SOURCE_DIR}/src/tools/Extractor_projects/shared/ExtractorCommon.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
target_link_libraries(${EXECUTABLE_NAME} StormLib loadlib bzip2 zlib)
|
target_link_libraries(${EXECUTABLE_NAME} loadlib bzip2 zlib StormLib)
|
||||||
|
|
||||||
#Output the compiled exes to build/bin/$(Configuration)/tools directory on windows by default
|
#Output the compiled exes to build/bin/$(Configuration)/tools directory on windows by default
|
||||||
if(WIN32)
|
if(WIN32)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue