mirror of
https://github.com/azerothcore/azerothcore-wotlk.git
synced 2025-11-10 21:04:26 +08:00
Compare commits
16 Commits
7ab2a5db6f
...
567d36c111
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
567d36c111 | ||
|
|
09e0343491 | ||
|
|
50965c2c3b | ||
|
|
6fb96fc69f | ||
|
|
758b74e805 | ||
|
|
3ad5e97206 | ||
|
|
ca6859a4e3 | ||
|
|
7d51c957f5 | ||
|
|
dc2379b89f | ||
|
|
4d445c4798 | ||
|
|
cd2fb530e1 | ||
|
|
cf776898fe | ||
|
|
459824ade5 | ||
|
|
6fd52b5e54 | ||
|
|
cf20fe23b9 | ||
|
|
38882cd5a2 |
@ -355,12 +355,18 @@ void Arena::EndBattleground(TeamId winnerTeamId)
|
||||
player->CastSpell(player, SPELL_LAST_MAN_STANDING, true);
|
||||
}
|
||||
|
||||
winnerArenaTeam->MemberWon(player, loserMatchmakerRating, winnerMatchmakerChange);
|
||||
if (!sScriptMgr->OnBeforeArenaTeamMemberUpdate(winnerArenaTeam, player, true, loserMatchmakerRating, winnerMatchmakerChange))
|
||||
{
|
||||
winnerArenaTeam->MemberWon(player, loserMatchmakerRating, winnerMatchmakerChange);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
loserArenaTeam->MemberLost(player, winnerMatchmakerRating, loserMatchmakerChange);
|
||||
if (!sScriptMgr->OnBeforeArenaTeamMemberUpdate(loserArenaTeam, player, false, winnerMatchmakerRating, loserMatchmakerChange))
|
||||
{
|
||||
loserArenaTeam->MemberLost(player, winnerMatchmakerRating, loserMatchmakerChange);
|
||||
}
|
||||
|
||||
// Arena lost => reset the win_rated_arena having the "no_lose" condition
|
||||
player->ResetAchievementCriteria(ACHIEVEMENT_CRITERIA_CONDITION_NO_LOSE, 0);
|
||||
|
||||
@ -966,12 +966,15 @@ void ArenaTeam::SaveToDB(bool forceMemberSave)
|
||||
stmt->SetData(6, itr->Guid.GetCounter());
|
||||
trans->Append(stmt);
|
||||
|
||||
stmt = CharacterDatabase.GetPreparedStatement(CHAR_REP_CHARACTER_ARENA_STATS);
|
||||
stmt->SetData(0, itr->Guid.GetCounter());
|
||||
stmt->SetData(1, GetSlot());
|
||||
stmt->SetData(2, itr->MatchMakerRating);
|
||||
stmt->SetData(3, itr->MaxMMR);
|
||||
trans->Append(stmt);
|
||||
if (sScriptMgr->CanSaveArenaStatsForMember(this, itr->Guid))
|
||||
{
|
||||
stmt = CharacterDatabase.GetPreparedStatement(CHAR_REP_CHARACTER_ARENA_STATS);
|
||||
stmt->SetData(0, itr->Guid.GetCounter());
|
||||
stmt->SetData(1, GetSlot());
|
||||
stmt->SetData(2, itr->MatchMakerRating);
|
||||
stmt->SetData(3, itr->MaxMMR);
|
||||
trans->Append(stmt);
|
||||
}
|
||||
}
|
||||
|
||||
CharacterDatabase.CommitTransaction(trans);
|
||||
|
||||
@ -434,15 +434,37 @@ void BattlegroundQueue::FillPlayersToBG(Battleground* bg, BattlegroundBracketId
|
||||
|
||||
//index to queue which group is current
|
||||
uint32 aliIndex = 0;
|
||||
for (; aliIndex < aliCount && m_SelectionPools[TEAM_ALLIANCE].AddGroup((*Ali_itr), aliFree); aliIndex++)
|
||||
for (; aliIndex < aliCount; aliIndex++)
|
||||
{
|
||||
if (!sScriptMgr->CanAddGroupToMatchingPool(this, (*Ali_itr), m_SelectionPools[TEAM_ALLIANCE].GetPlayerCount(), bg, bracket_id))
|
||||
{
|
||||
++Ali_itr;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!m_SelectionPools[TEAM_ALLIANCE].AddGroup((*Ali_itr), aliFree))
|
||||
break;
|
||||
|
||||
++Ali_itr;
|
||||
}
|
||||
|
||||
//the same thing for horde
|
||||
GroupsQueueType::const_iterator Horde_itr = m_QueuedGroups[bracket_id][BG_QUEUE_NORMAL_HORDE].begin();
|
||||
|
||||
uint32 hordeIndex = 0;
|
||||
for (; hordeIndex < hordeCount && m_SelectionPools[TEAM_HORDE].AddGroup((*Horde_itr), hordeFree); hordeIndex++)
|
||||
for (; hordeIndex < hordeCount; hordeIndex++)
|
||||
{
|
||||
if (!sScriptMgr->CanAddGroupToMatchingPool(this, (*Horde_itr), m_SelectionPools[TEAM_HORDE].GetPlayerCount(), bg, bracket_id))
|
||||
{
|
||||
++Horde_itr;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!m_SelectionPools[TEAM_HORDE].AddGroup((*Horde_itr), hordeFree))
|
||||
break;
|
||||
|
||||
++Horde_itr;
|
||||
}
|
||||
|
||||
//if ofc like BG queue invitation is set in config, then we are happy
|
||||
if (sWorld->getIntConfig(CONFIG_BATTLEGROUND_INVITATION_TYPE) == BG_QUEUE_INVITATION_TYPE_NO_BALANCE)
|
||||
@ -468,8 +490,19 @@ void BattlegroundQueue::FillPlayersToBG(Battleground* bg, BattlegroundBracketId
|
||||
//kick alliance group, add to pool new group if needed
|
||||
if (m_SelectionPools[TEAM_ALLIANCE].KickGroup(diffHorde - diffAli))
|
||||
{
|
||||
for (; aliIndex < aliCount && m_SelectionPools[TEAM_ALLIANCE].AddGroup((*Ali_itr), (aliFree >= diffHorde) ? aliFree - diffHorde : 0); aliIndex++)
|
||||
for (; aliIndex < aliCount; aliIndex++)
|
||||
{
|
||||
if (!sScriptMgr->CanAddGroupToMatchingPool(this, (*Ali_itr), m_SelectionPools[TEAM_ALLIANCE].GetPlayerCount(), bg, bracket_id))
|
||||
{
|
||||
++Ali_itr;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!m_SelectionPools[TEAM_ALLIANCE].AddGroup((*Ali_itr), (aliFree >= diffHorde) ? aliFree - diffHorde : 0))
|
||||
break;
|
||||
|
||||
++Ali_itr;
|
||||
}
|
||||
}
|
||||
|
||||
//if ali selection is already empty, then kick horde group, but if there are less horde than ali in bg - break;
|
||||
@ -486,8 +519,19 @@ void BattlegroundQueue::FillPlayersToBG(Battleground* bg, BattlegroundBracketId
|
||||
//kick horde group, add to pool new group if needed
|
||||
if (m_SelectionPools[TEAM_HORDE].KickGroup(diffAli - diffHorde))
|
||||
{
|
||||
for (; hordeIndex < hordeCount && m_SelectionPools[TEAM_HORDE].AddGroup((*Horde_itr), (hordeFree >= diffAli) ? hordeFree - diffAli : 0); hordeIndex++)
|
||||
for (; hordeIndex < hordeCount; hordeIndex++)
|
||||
{
|
||||
if (!sScriptMgr->CanAddGroupToMatchingPool(this, (*Horde_itr), m_SelectionPools[TEAM_HORDE].GetPlayerCount(), bg, bracket_id))
|
||||
{
|
||||
++Horde_itr;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!m_SelectionPools[TEAM_HORDE].AddGroup((*Horde_itr), (hordeFree >= diffAli) ? hordeFree - diffAli : 0))
|
||||
break;
|
||||
|
||||
++Horde_itr;
|
||||
}
|
||||
}
|
||||
|
||||
if (!m_SelectionPools[TEAM_HORDE].GetPlayerCount())
|
||||
@ -525,6 +569,12 @@ bool BattlegroundQueue::CheckPremadeMatch(BattlegroundBracketId bracket_id, uint
|
||||
// if found both groups
|
||||
if (ali_group != m_QueuedGroups[bracket_id][BG_QUEUE_PREMADE_ALLIANCE].end() && horde_group != m_QueuedGroups[bracket_id][BG_QUEUE_PREMADE_HORDE].end())
|
||||
{
|
||||
if (!sScriptMgr->CanAddGroupToMatchingPool(this, (*ali_group), 0, nullptr, bracket_id))
|
||||
return false;
|
||||
|
||||
if (!sScriptMgr->CanAddGroupToMatchingPool(this, (*horde_group), m_SelectionPools[TEAM_ALLIANCE].GetPlayerCount(), nullptr, bracket_id))
|
||||
return false;
|
||||
|
||||
m_SelectionPools[TEAM_ALLIANCE].AddGroup((*ali_group), MaxPlayersPerTeam);
|
||||
m_SelectionPools[TEAM_HORDE].AddGroup((*horde_group), MaxPlayersPerTeam);
|
||||
|
||||
@ -536,9 +586,14 @@ bool BattlegroundQueue::CheckPremadeMatch(BattlegroundBracketId bracket_id, uint
|
||||
{
|
||||
for (itr = m_QueuedGroups[bracket_id][BG_QUEUE_NORMAL_ALLIANCE + i].begin(); itr != m_QueuedGroups[bracket_id][BG_QUEUE_NORMAL_ALLIANCE + i].end(); ++itr)
|
||||
{
|
||||
//if itr can join BG and player count is less that maxPlayers, then add group to selectionpool
|
||||
if (!(*itr)->IsInvitedToBGInstanceGUID && !m_SelectionPools[i].AddGroup((*itr), maxPlayers))
|
||||
break;
|
||||
if (!(*itr)->IsInvitedToBGInstanceGUID)
|
||||
{
|
||||
if (!sScriptMgr->CanAddGroupToMatchingPool(this, (*itr), m_SelectionPools[i].GetPlayerCount(), nullptr, bracket_id))
|
||||
continue;
|
||||
|
||||
if (!m_SelectionPools[i].AddGroup((*itr), maxPlayers))
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -596,9 +651,12 @@ bool BattlegroundQueue::CheckNormalMatch(Battleground* bgTemplate, BattlegroundB
|
||||
{
|
||||
if (!(*(itr_team[i]))->IsInvitedToBGInstanceGUID)
|
||||
{
|
||||
m_SelectionPools[i].AddGroup(*(itr_team[i]), maxPlayers);
|
||||
if (m_SelectionPools[i].GetPlayerCount() >= minPlayers)
|
||||
break;
|
||||
if (sScriptMgr->CanAddGroupToMatchingPool(this, *(itr_team[i]), m_SelectionPools[i].GetPlayerCount(), bgTemplate, bracket_id))
|
||||
{
|
||||
m_SelectionPools[i].AddGroup(*(itr_team[i]), maxPlayers);
|
||||
if (m_SelectionPools[i].GetPlayerCount() >= minPlayers)
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -616,8 +674,13 @@ bool BattlegroundQueue::CheckNormalMatch(Battleground* bgTemplate, BattlegroundB
|
||||
for (; itr_team[j] != m_QueuedGroups[bracket_id][BG_QUEUE_NORMAL_ALLIANCE + j].end(); ++(itr_team[j]))
|
||||
{
|
||||
if (!(*(itr_team[j]))->IsInvitedToBGInstanceGUID)
|
||||
{
|
||||
if (!sScriptMgr->CanAddGroupToMatchingPool(this, *(itr_team[j]), m_SelectionPools[j].GetPlayerCount(), bgTemplate, bracket_id))
|
||||
continue;
|
||||
|
||||
if (!m_SelectionPools[j].AddGroup(*(itr_team[j]), m_SelectionPools[(j + 1) % PVP_TEAMS_COUNT].GetPlayerCount()))
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// do not allow to start bg with more than 2 players more on 1 faction
|
||||
@ -664,9 +727,14 @@ bool BattlegroundQueue::CheckSkirmishForSameFaction(BattlegroundBracketId bracke
|
||||
//invite players to other selection pool
|
||||
for (; itr_team2 != m_QueuedGroups[bracket_id][BG_QUEUE_NORMAL_ALLIANCE + static_cast<uint8>(teamIndex)].end(); ++itr_team2)
|
||||
{
|
||||
//if selection pool is full then break;
|
||||
if (!(*itr_team2)->IsInvitedToBGInstanceGUID && !m_SelectionPools[otherTeam].AddGroup(*itr_team2, minPlayersPerTeam))
|
||||
break;
|
||||
if (!(*itr_team2)->IsInvitedToBGInstanceGUID)
|
||||
{
|
||||
if (!sScriptMgr->CanAddGroupToMatchingPool(this, *itr_team2, m_SelectionPools[otherTeam].GetPlayerCount(), nullptr, bracket_id))
|
||||
continue;
|
||||
|
||||
if (!m_SelectionPools[otherTeam].AddGroup(*itr_team2, minPlayersPerTeam))
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (m_SelectionPools[otherTeam].GetPlayerCount() != minPlayersPerTeam)
|
||||
|
||||
@ -104,6 +104,16 @@ void ScriptMgr::OnBattlegroundCreate(Battleground* bg)
|
||||
CALL_ENABLED_HOOKS(AllBattlegroundScript, ALLBATTLEGROUNDHOOK_ON_BATTLEGROUND_CREATE, script->OnBattlegroundCreate(bg));
|
||||
}
|
||||
|
||||
bool ScriptMgr::CanAddGroupToMatchingPool(BattlegroundQueue* queue, GroupQueueInfo* group, uint32 poolPlayerCount, Battleground* bg, BattlegroundBracketId bracketId)
|
||||
{
|
||||
CALL_ENABLED_BOOLEAN_HOOKS(AllBattlegroundScript, ALLBATTLEGROUNDHOOK_CAN_ADD_GROUP_TO_MATCHING_POOL, !script->CanAddGroupToMatchingPool(queue, group, poolPlayerCount, bg, bracketId));
|
||||
}
|
||||
|
||||
bool ScriptMgr::GetPlayerMatchmakingRating(ObjectGuid playerGuid, BattlegroundTypeId bgTypeId, float& outRating)
|
||||
{
|
||||
CALL_ENABLED_BOOLEAN_HOOKS_WITH_DEFAULT_FALSE(AllBattlegroundScript, ALLBATTLEGROUNDHOOK_GET_PLAYER_MATCHMAKING_RATING, script->GetPlayerMatchmakingRating(playerGuid, bgTypeId, outRating));
|
||||
}
|
||||
|
||||
AllBattlegroundScript::AllBattlegroundScript(char const* name, std::vector<uint16> enabledHooks) :
|
||||
ScriptObject(name, ALLBATTLEGROUNDHOOK_END)
|
||||
{
|
||||
|
||||
@ -18,6 +18,7 @@
|
||||
#ifndef SCRIPT_OBJECT_ALL_BATTLEGROUND_SCRIPT_H_
|
||||
#define SCRIPT_OBJECT_ALL_BATTLEGROUND_SCRIPT_H_
|
||||
|
||||
#include "ObjectGuid.h"
|
||||
#include "ScriptObject.h"
|
||||
#include <vector>
|
||||
|
||||
@ -40,6 +41,8 @@ enum AllBattlegroundHook
|
||||
ALLBATTLEGROUNDHOOK_ON_BATTLEGROUND_END,
|
||||
ALLBATTLEGROUNDHOOK_ON_BATTLEGROUND_DESTROY,
|
||||
ALLBATTLEGROUNDHOOK_ON_BATTLEGROUND_CREATE,
|
||||
ALLBATTLEGROUNDHOOK_CAN_ADD_GROUP_TO_MATCHING_POOL,
|
||||
ALLBATTLEGROUNDHOOK_GET_PLAYER_MATCHMAKING_RATING,
|
||||
ALLBATTLEGROUNDHOOK_END
|
||||
};
|
||||
|
||||
@ -47,6 +50,9 @@ enum BattlegroundBracketId : uint8;
|
||||
enum BattlegroundTypeId : uint8;
|
||||
enum TeamId : uint8;
|
||||
|
||||
class BattlegroundQueue;
|
||||
struct GroupQueueInfo;
|
||||
|
||||
class AllBattlegroundScript : public ScriptObject
|
||||
{
|
||||
protected:
|
||||
@ -132,6 +138,34 @@ public:
|
||||
* @param bg Contains information about the Battleground
|
||||
*/
|
||||
virtual void OnBattlegroundCreate(Battleground* /*bg*/) { }
|
||||
|
||||
/**
|
||||
* @brief This hook runs before adding a group to the battleground matching pool
|
||||
*
|
||||
* Allows modules to filter groups based on custom criteria (e.g., MMR matching).
|
||||
* Called during FillPlayersToBG before each group is added to the SelectionPool.
|
||||
*
|
||||
* @param queue The battleground queue
|
||||
* @param group The group being considered for addition
|
||||
* @param poolPlayerCount Current number of players already in the selection pool
|
||||
* @param bg The battleground instance
|
||||
* @param bracketId The bracket ID
|
||||
* @return True to allow adding this group, false to skip it
|
||||
*/
|
||||
[[nodiscard]] virtual bool CanAddGroupToMatchingPool(BattlegroundQueue* /*queue*/, GroupQueueInfo* /*group*/, uint32 /*poolPlayerCount*/, Battleground* /*bg*/, BattlegroundBracketId /*bracketId*/) { return true; }
|
||||
|
||||
/**
|
||||
* @brief This hook allows modules to provide matchmaking rating for a player
|
||||
*
|
||||
* Modules implementing MMR systems can use this hook to provide player ratings
|
||||
* for use in matchmaking algorithms.
|
||||
*
|
||||
* @param playerGuid The player's GUID
|
||||
* @param bgTypeId The battleground type
|
||||
* @param outRating Reference to store the rating value
|
||||
* @return True if rating was provided, false otherwise
|
||||
*/
|
||||
[[nodiscard]] virtual bool GetPlayerMatchmakingRating(ObjectGuid /*playerGuid*/, BattlegroundTypeId /*bgTypeId*/, float& /*outRating*/) { return false; }
|
||||
};
|
||||
|
||||
// Compatibility for old scripts
|
||||
|
||||
@ -44,6 +44,16 @@ void ScriptMgr::OnArenaStart(Battleground* bg)
|
||||
CALL_ENABLED_HOOKS(ArenaScript, ARENAHOOK_ON_ARENA_START, script->OnArenaStart(bg));
|
||||
}
|
||||
|
||||
bool ScriptMgr::OnBeforeArenaTeamMemberUpdate(ArenaTeam* team, Player* player, bool won, uint32 opponentMatchmakerRating, int32 matchmakerChange)
|
||||
{
|
||||
CALL_ENABLED_BOOLEAN_HOOKS(ArenaScript, ARENAHOOK_ON_BEFORE_TEAM_MEMBER_UPDATE, !script->OnBeforeArenaTeamMemberUpdate(team, player, won, opponentMatchmakerRating, matchmakerChange));
|
||||
}
|
||||
|
||||
bool ScriptMgr::CanSaveArenaStatsForMember(ArenaTeam* team, ObjectGuid playerGuid)
|
||||
{
|
||||
CALL_ENABLED_BOOLEAN_HOOKS(ArenaScript, ARENAHOOK_CAN_SAVE_ARENA_STATS_FOR_MEMBER, !script->CanSaveArenaStatsForMember(team, playerGuid));
|
||||
}
|
||||
|
||||
ArenaScript::ArenaScript(const char* name, std::vector<uint16> enabledHooks)
|
||||
: ScriptObject(name, ARENAHOOK_END)
|
||||
{
|
||||
|
||||
@ -29,6 +29,8 @@ enum ArenaHook
|
||||
ARENAHOOK_CAN_SAVE_TO_DB,
|
||||
ARENAHOOK_ON_BEFORE_CHECK_WIN_CONDITION,
|
||||
ARENAHOOK_ON_ARENA_START,
|
||||
ARENAHOOK_ON_BEFORE_TEAM_MEMBER_UPDATE,
|
||||
ARENAHOOK_CAN_SAVE_ARENA_STATS_FOR_MEMBER,
|
||||
ARENAHOOK_END
|
||||
};
|
||||
|
||||
@ -51,6 +53,10 @@ public:
|
||||
[[nodiscard]] virtual bool CanSaveToDB(ArenaTeam* /*team*/) { return true; }
|
||||
|
||||
virtual void OnArenaStart(Battleground* /* bg */) { };
|
||||
|
||||
[[nodiscard]] virtual bool OnBeforeArenaTeamMemberUpdate(ArenaTeam* /*team*/, Player* /*player*/, bool /*won*/, uint32 /*opponentMatchmakerRating*/, int32 /*matchmakerChange*/) { return false; }
|
||||
|
||||
[[nodiscard]] virtual bool CanSaveArenaStatsForMember(ArenaTeam* /*team*/, ObjectGuid /*playerGuid*/) { return true; }
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@ -601,6 +601,8 @@ public: /* BGScript */
|
||||
void OnBattlegroundEnd(Battleground* bg, TeamId winnerTeamId);
|
||||
void OnBattlegroundDestroy(Battleground* bg);
|
||||
void OnBattlegroundCreate(Battleground* bg);
|
||||
bool CanAddGroupToMatchingPool(BattlegroundQueue* queue, GroupQueueInfo* group, uint32 poolPlayerCount, Battleground* bg, BattlegroundBracketId bracketId);
|
||||
bool GetPlayerMatchmakingRating(ObjectGuid playerGuid, BattlegroundTypeId bgTypeId, float& outRating);
|
||||
|
||||
public: /* Arena Team Script */
|
||||
void OnGetSlotByType(const uint32 type, uint8& slot);
|
||||
@ -658,6 +660,8 @@ public: /* ArenaScript */
|
||||
bool CanSaveToDB(ArenaTeam* team);
|
||||
bool OnBeforeArenaCheckWinConditions(Battleground* const bg);
|
||||
void OnArenaStart(Battleground* const bg);
|
||||
bool OnBeforeArenaTeamMemberUpdate(ArenaTeam* team, Player* player, bool won, uint32 opponentMatchmakerRating, int32 matchmakerChange);
|
||||
bool CanSaveArenaStatsForMember(ArenaTeam* team, ObjectGuid playerGuid);
|
||||
|
||||
public: /* MiscScript */
|
||||
|
||||
|
||||
@ -77,51 +77,52 @@ enum Misc
|
||||
DATA_SET_INSANITY_PHASE = 1,
|
||||
};
|
||||
|
||||
enum Events
|
||||
{
|
||||
EVENT_HERALD_MIND_FLAY = 1,
|
||||
EVENT_HERALD_SHADOW,
|
||||
EVENT_HERALD_SHIVER,
|
||||
};
|
||||
|
||||
const std::array<uint32, MAX_INSANITY_TARGETS> InsanitySpells = { SPELL_INSANITY_PHASING_1, SPELL_INSANITY_PHASING_2, SPELL_INSANITY_PHASING_3, SPELL_INSANITY_PHASING_4, SPELL_INSANITY_PHASING_5 };
|
||||
|
||||
struct boss_volazj : public BossAI
|
||||
{
|
||||
boss_volazj(Creature* pCreature) : BossAI(pCreature, DATA_HERALD_VOLAZJ),
|
||||
insanityTimes(0),
|
||||
insanityPhase(false)
|
||||
{ }
|
||||
|
||||
void InitializeAI() override
|
||||
{
|
||||
BossAI::InitializeAI();
|
||||
// Visible for all players in insanity
|
||||
me->SetPhaseMask((1 | 16 | 32 | 64 | 128 | 256), true);
|
||||
}
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
_Reset();
|
||||
insanityTimes = 0;
|
||||
insanityPhase = false;
|
||||
|
||||
me->RemoveUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
|
||||
me->SetControlled(false, UNIT_STATE_STUNNED);
|
||||
ResetPlayersPhaseMask();
|
||||
instance->DoStopTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, ACHIEV_QUICK_DEMISE_START_EVENT);
|
||||
me->SetPhaseMask((1 | 16 | 32 | 64 | 128 | 256), true);
|
||||
|
||||
ScheduleHealthCheckEvent({ 66, 33 }, [&]{
|
||||
scheduler.CancelAll();
|
||||
DoCastSelf(SPELL_INSANITY);
|
||||
}, false);
|
||||
}
|
||||
|
||||
void ScheduleTasks() override
|
||||
{
|
||||
ScheduleTimedEvent(8s, [&] {
|
||||
DoCastVictim(SPELL_MIND_FLAY);
|
||||
}, 20s);
|
||||
|
||||
ScheduleTimedEvent(5s, [&] {
|
||||
DoCastVictim(SPELL_SHADOW_BOLT_VOLLEY);
|
||||
}, 5s);
|
||||
|
||||
ScheduleTimedEvent(15s, [&] {
|
||||
DoCastRandomTarget(SPELL_SHIVER);
|
||||
}, 15s);
|
||||
}
|
||||
|
||||
void JustEngagedWith(Unit* /*who*/) override
|
||||
{
|
||||
_JustEngagedWith();
|
||||
events.ScheduleEvent(EVENT_HERALD_MIND_FLAY, 8s);
|
||||
events.ScheduleEvent(EVENT_HERALD_SHADOW, 5s);
|
||||
events.ScheduleEvent(EVENT_HERALD_SHIVER, 15s);
|
||||
Talk(SAY_AGGRO);
|
||||
DoCastSelf(SPELL_WHISPER_AGGRO);
|
||||
instance->DoStartTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, ACHIEV_QUICK_DEMISE_START_EVENT);
|
||||
me->SetInCombatWithZone();
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/) override
|
||||
@ -184,36 +185,13 @@ struct boss_volazj : public BossAI
|
||||
}
|
||||
}
|
||||
|
||||
void DamageTaken(Unit* /*attacker*/, uint32& damage, DamageEffectType /*damagetype*/, SpellSchoolMask /*damageSchoolMask*/) override
|
||||
{
|
||||
// Do not perform insanity recast if boss is casting Insanity already
|
||||
if (me->FindCurrentSpellBySpellId(SPELL_INSANITY))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// First insanity
|
||||
if (insanityTimes == 0 && me->HealthBelowPctDamaged(66, damage))
|
||||
{
|
||||
DoCastSelf(SPELL_INSANITY, false);
|
||||
++insanityTimes;
|
||||
}
|
||||
// Second insanity
|
||||
else if (insanityTimes == 1 && me->HealthBelowPctDamaged(33, damage))
|
||||
{
|
||||
me->InterruptNonMeleeSpells(false);
|
||||
DoCastSelf(SPELL_INSANITY, false);
|
||||
++insanityTimes;
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
//Return since we have no target
|
||||
if (!UpdateVictim())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
scheduler.Update(diff);
|
||||
|
||||
if (insanityPhase)
|
||||
{
|
||||
@ -226,53 +204,13 @@ struct boss_volazj : public BossAI
|
||||
me->RemoveUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
|
||||
me->SetControlled(false, UNIT_STATE_STUNNED);
|
||||
me->RemoveAurasDueToSpell(INSANITY_VISUAL);
|
||||
}
|
||||
|
||||
events.Update(diff);
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
while (uint32 const eventId = events.ExecuteEvent())
|
||||
{
|
||||
switch (eventId)
|
||||
{
|
||||
case EVENT_HERALD_MIND_FLAY:
|
||||
{
|
||||
DoCastVictim(SPELL_MIND_FLAY, false);
|
||||
events.Repeat(20s);
|
||||
break;
|
||||
}
|
||||
case EVENT_HERALD_SHADOW:
|
||||
{
|
||||
DoCastVictim(SPELL_SHADOW_BOLT_VOLLEY, false);
|
||||
events.Repeat(5s);
|
||||
break;
|
||||
}
|
||||
case EVENT_HERALD_SHIVER:
|
||||
{
|
||||
if (Unit* pTarget = SelectTarget(SelectTargetMethod::Random, 0, 0.0f, true))
|
||||
{
|
||||
DoCast(pTarget, SPELL_SHIVER, false);
|
||||
}
|
||||
|
||||
events.Repeat(15s);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
{
|
||||
return;
|
||||
}
|
||||
ScheduleTasks();
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
private:
|
||||
uint8 insanityTimes;
|
||||
bool insanityPhase; // Indicates if boss enter to insanity phase
|
||||
|
||||
uint32 GetPlrInsanityAuraId(uint32 phaseMask) const
|
||||
@ -312,6 +250,7 @@ private:
|
||||
bool CheckPhaseMinions()
|
||||
{
|
||||
summons.RemoveNotExisting();
|
||||
|
||||
if (summons.empty())
|
||||
{
|
||||
ResetPlayersPhaseMask();
|
||||
|
||||
@ -31,6 +31,26 @@ target_link_libraries(
|
||||
game-interface
|
||||
)
|
||||
|
||||
# Add module test sources if any modules registered tests
|
||||
get_property(MODULE_TEST_SOURCES GLOBAL PROPERTY ACORE_MODULE_TEST_SOURCES)
|
||||
get_property(MODULE_TEST_INCLUDES GLOBAL PROPERTY ACORE_MODULE_TEST_INCLUDES)
|
||||
|
||||
if(MODULE_TEST_SOURCES)
|
||||
target_sources(unit_tests PRIVATE ${MODULE_TEST_SOURCES})
|
||||
message(STATUS "Added module tests to unit_tests target")
|
||||
endif()
|
||||
|
||||
if(MODULE_TEST_INCLUDES)
|
||||
list(REMOVE_DUPLICATES MODULE_TEST_INCLUDES)
|
||||
target_include_directories(unit_tests PRIVATE ${MODULE_TEST_INCLUDES})
|
||||
message(STATUS "Added module test includes to unit_tests target")
|
||||
endif()
|
||||
|
||||
# Link modules library to tests so module code is available
|
||||
if(TARGET modules)
|
||||
target_link_libraries(unit_tests modules)
|
||||
endif()
|
||||
|
||||
add_test(
|
||||
NAME
|
||||
unit
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user