mirror of
https://github.com/mod-playerbots/mod-playerbots
synced 2025-11-29 15:58:20 +08:00
resolve some comments + more
Formatting edits and improved Malchezaar
This commit is contained in:
@@ -18,7 +18,7 @@ namespace
|
|||||||
bool KarazhanAttumenTheHuntsmanStackBehindAction::Execute(Event event)
|
bool KarazhanAttumenTheHuntsmanStackBehindAction::Execute(Event event)
|
||||||
{
|
{
|
||||||
RaidKarazhanHelpers karazhanHelper(botAI);
|
RaidKarazhanHelpers karazhanHelper(botAI);
|
||||||
Unit* boss = karazhanHelper.GetFirstAliveUnitByEntry(NPC_ATTUMEN_THE_HUNTSMAN);
|
Unit* boss = karazhanHelper.GetFirstAliveUnitByEntry(NPC_ATTUMEN_THE_HUNTSMAN_MOUNTED);
|
||||||
|
|
||||||
float distance = 5.0f;
|
float distance = 5.0f;
|
||||||
float orientation = boss->GetOrientation() + M_PI;
|
float orientation = boss->GetOrientation() + M_PI;
|
||||||
@@ -34,12 +34,9 @@ bool KarazhanAttumenTheHuntsmanStackBehindAction::Execute(Event event)
|
|||||||
bool KarazhanAttumenTheHuntsmanStackBehindAction::isUseful()
|
bool KarazhanAttumenTheHuntsmanStackBehindAction::isUseful()
|
||||||
{
|
{
|
||||||
RaidKarazhanHelpers karazhanHelper(botAI);
|
RaidKarazhanHelpers karazhanHelper(botAI);
|
||||||
Unit* boss = karazhanHelper.GetFirstAliveUnitByEntry(NPC_ATTUMEN_THE_HUNTSMAN);
|
Unit* boss = karazhanHelper.GetFirstAliveUnitByEntry(NPC_ATTUMEN_THE_HUNTSMAN_MOUNTED);
|
||||||
|
|
||||||
if (boss && botAI->IsTank(bot) && botAI->HasAggro(boss) && boss->GetVictim() == bot)
|
return boss && !(botAI->IsTank(bot) && botAI->HasAggro(boss) && boss->GetVictim() == bot);
|
||||||
return false;
|
|
||||||
|
|
||||||
return boss != nullptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool KarazhanMoroesMarkTargetAction::Execute(Event event)
|
bool KarazhanMoroesMarkTargetAction::Execute(Event event)
|
||||||
@@ -70,7 +67,9 @@ bool KarazhanMaidenOfVirtuePositionBossAction::Execute(Event event)
|
|||||||
{
|
{
|
||||||
Player* member = itr->GetSource();
|
Player* member = itr->GetSource();
|
||||||
if (!member || !member->IsAlive() || !botAI->IsHeal(member) || !member->HasAura(SPELL_REPENTANCE))
|
if (!member || !member->IsAlive() || !botAI->IsHeal(member) || !member->HasAura(SPELL_REPENTANCE))
|
||||||
|
{
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
healer = member;
|
healer = member;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -82,9 +81,10 @@ bool KarazhanMaidenOfVirtuePositionBossAction::Execute(Event event)
|
|||||||
float targetX = healer->GetPositionX() + cos(angle) * 6.0f;
|
float targetX = healer->GetPositionX() + cos(angle) * 6.0f;
|
||||||
float targetY = healer->GetPositionY() + sin(angle) * 6.0f;
|
float targetY = healer->GetPositionY() + sin(angle) * 6.0f;
|
||||||
float targetZ = healer->GetPositionZ();
|
float targetZ = healer->GetPositionZ();
|
||||||
|
{
|
||||||
return MoveTo(bot->GetMapId(), targetX, targetY, targetZ, false, false, false, true,
|
return MoveTo(bot->GetMapId(), targetX, targetY, targetZ, false, false, false, true,
|
||||||
MovementPriority::MOVEMENT_COMBAT);
|
MovementPriority::MOVEMENT_COMBAT);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const float maxDistance = 3.0f;
|
const float maxDistance = 3.0f;
|
||||||
@@ -96,9 +96,10 @@ bool KarazhanMaidenOfVirtuePositionBossAction::Execute(Event event)
|
|||||||
float dY = KARAZHAN_MAIDEN_OF_VIRTUE_BOSS_POSITION.GetPositionY() - boss->GetPositionY();
|
float dY = KARAZHAN_MAIDEN_OF_VIRTUE_BOSS_POSITION.GetPositionY() - boss->GetPositionY();
|
||||||
float mX = KARAZHAN_MAIDEN_OF_VIRTUE_BOSS_POSITION.GetPositionX() + (dX / distanceToBossPosition) * maxDistance;
|
float mX = KARAZHAN_MAIDEN_OF_VIRTUE_BOSS_POSITION.GetPositionX() + (dX / distanceToBossPosition) * maxDistance;
|
||||||
float mY = KARAZHAN_MAIDEN_OF_VIRTUE_BOSS_POSITION.GetPositionY() + (dY / distanceToBossPosition) * maxDistance;
|
float mY = KARAZHAN_MAIDEN_OF_VIRTUE_BOSS_POSITION.GetPositionY() + (dY / distanceToBossPosition) * maxDistance;
|
||||||
|
{
|
||||||
return MoveTo(bot->GetMapId(), mX, mY,
|
return MoveTo(bot->GetMapId(), mX, mY,
|
||||||
bot->GetPositionZ(), false, false, false, false, MovementPriority::MOVEMENT_COMBAT, true, false);
|
bot->GetPositionZ(), false, false, false, false, MovementPriority::MOVEMENT_COMBAT, true, false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -121,8 +122,10 @@ bool KarazhanMaidenOfVirtuePositionRangedAction::Execute(Event event)
|
|||||||
{
|
{
|
||||||
Unit* member = botAI->GetUnit(memberGuid);
|
Unit* member = botAI->GetUnit(memberGuid);
|
||||||
|
|
||||||
if (!member || !botAI->IsRanged(member->ToPlayer()))
|
if (!member || !botAI->IsRanged(member->ToPlayer()))
|
||||||
|
{
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (member == bot)
|
if (member == bot)
|
||||||
break;
|
break;
|
||||||
@@ -137,12 +140,12 @@ bool KarazhanMaidenOfVirtuePositionRangedAction::Execute(Event event)
|
|||||||
|
|
||||||
float distance = bot->GetExactDist2d(KARAZHAN_MAIDEN_OF_VIRTUE_RANGED_POSITION[index]);
|
float distance = bot->GetExactDist2d(KARAZHAN_MAIDEN_OF_VIRTUE_RANGED_POSITION[index]);
|
||||||
const float maxDistance = 2.0f;
|
const float maxDistance = 2.0f;
|
||||||
|
|
||||||
if (distance > maxDistance)
|
if (distance > maxDistance)
|
||||||
|
{
|
||||||
return MoveTo(bot->GetMapId(), KARAZHAN_MAIDEN_OF_VIRTUE_RANGED_POSITION[index].GetPositionX(),
|
return MoveTo(bot->GetMapId(), KARAZHAN_MAIDEN_OF_VIRTUE_RANGED_POSITION[index].GetPositionX(),
|
||||||
KARAZHAN_MAIDEN_OF_VIRTUE_RANGED_POSITION[index].GetPositionY(), bot->GetPositionZ(), false,
|
KARAZHAN_MAIDEN_OF_VIRTUE_RANGED_POSITION[index].GetPositionY(), bot->GetPositionZ(), false,
|
||||||
false, false, false, MovementPriority::MOVEMENT_COMBAT, true, false);
|
false, false, false, MovementPriority::MOVEMENT_COMBAT, true, false);
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -173,11 +176,9 @@ bool KarazhanBigBadWolfPositionBossAction::Execute(Event event)
|
|||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return MoveTo(bot->GetMapId(), mX, mY, bot->GetPositionZ(), false, false, false, false,
|
return MoveTo(bot->GetMapId(), mX, mY, bot->GetPositionZ(), false, false, false, false,
|
||||||
MovementPriority::MOVEMENT_COMBAT, true, false);
|
MovementPriority::MOVEMENT_COMBAT, true, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -200,7 +201,6 @@ bool KarazhanBigBadWolfRunAwayAction::Execute(Event event)
|
|||||||
currentIndex = (currentIndex + 1) % 4;
|
currentIndex = (currentIndex + 1) % 4;
|
||||||
target = KARAZHAN_BIG_BAD_WOLF_RUN_POSITION[currentIndex];
|
target = KARAZHAN_BIG_BAD_WOLF_RUN_POSITION[currentIndex];
|
||||||
}
|
}
|
||||||
|
|
||||||
return MoveTo(bot->GetMapId(), target.GetPositionX(), target.GetPositionY(), target.GetPositionZ(),
|
return MoveTo(bot->GetMapId(), target.GetPositionX(), target.GetPositionY(), target.GetPositionZ(),
|
||||||
false, false, false, true, MovementPriority::MOVEMENT_FORCED);
|
false, false, false, true, MovementPriority::MOVEMENT_FORCED);
|
||||||
}
|
}
|
||||||
@@ -220,11 +220,17 @@ bool KarazhanRomuloAndJulianneMarkTargetAction::Execute(Event event)
|
|||||||
|
|
||||||
const int maxPctDifference = 10;
|
const int maxPctDifference = 10;
|
||||||
if (julianne->GetHealthPct() + maxPctDifference < romulo->GetHealthPct() || julianne->GetHealthPct() < 1.0f)
|
if (julianne->GetHealthPct() + maxPctDifference < romulo->GetHealthPct() || julianne->GetHealthPct() < 1.0f)
|
||||||
|
{
|
||||||
target = romulo;
|
target = romulo;
|
||||||
|
}
|
||||||
else if (romulo->GetHealthPct() + maxPctDifference < julianne->GetHealthPct() || romulo->GetHealthPct() < 1.0f)
|
else if (romulo->GetHealthPct() + maxPctDifference < julianne->GetHealthPct() || romulo->GetHealthPct() < 1.0f)
|
||||||
|
{
|
||||||
target = julianne;
|
target = julianne;
|
||||||
|
}
|
||||||
if (!target)
|
if (!target)
|
||||||
|
{
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
RaidKarazhanHelpers karazhanHelper(botAI);
|
RaidKarazhanHelpers karazhanHelper(botAI);
|
||||||
karazhanHelper.MarkTargetWithSkull(target);
|
karazhanHelper.MarkTargetWithSkull(target);
|
||||||
@@ -252,25 +258,33 @@ bool KarazhanWizardOfOzScorchStrawmanAction::Execute(Event event)
|
|||||||
{
|
{
|
||||||
Unit* strawman = AI_VALUE2(Unit*, "find target", "strawman");
|
Unit* strawman = AI_VALUE2(Unit*, "find target", "strawman");
|
||||||
if (!strawman || !strawman->IsAlive())
|
if (!strawman || !strawman->IsAlive())
|
||||||
|
{
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
Group* group = bot->GetGroup();
|
Group* group = bot->GetGroup();
|
||||||
if (!group)
|
if (!group)
|
||||||
|
{
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
for (GroupReference* itr = group->GetFirstMember(); itr != nullptr; itr = itr->next())
|
for (GroupReference* itr = group->GetFirstMember(); itr != nullptr; itr = itr->next())
|
||||||
{
|
{
|
||||||
Player* member = itr->GetSource();
|
Player* member = itr->GetSource();
|
||||||
if (!member || !member->IsAlive())
|
if (!member || !member->IsAlive())
|
||||||
|
{
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
if (member->getClass() != CLASS_MAGE)
|
if (member->getClass() != CLASS_MAGE)
|
||||||
|
{
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
PlayerbotAI* mageAI = sPlayerbotsMgr->GetPlayerbotAI(member);
|
PlayerbotAI* mageAI = sPlayerbotsMgr->GetPlayerbotAI(member);
|
||||||
if (!mageAI)
|
if (!mageAI)
|
||||||
|
{
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
if (mageAI->CanCastSpell("scorch", strawman))
|
if (mageAI->CanCastSpell("scorch", strawman))
|
||||||
{
|
{
|
||||||
mageAI->CastSpell("scorch", strawman);
|
mageAI->CastSpell("scorch", strawman);
|
||||||
@@ -283,7 +297,9 @@ bool KarazhanTheCuratorMarkTargetAction::Execute(Event event)
|
|||||||
{
|
{
|
||||||
Unit* target = AI_VALUE2(Unit*, "find target", "astral flare");
|
Unit* target = AI_VALUE2(Unit*, "find target", "astral flare");
|
||||||
if (!target || !target->IsAlive())
|
if (!target || !target->IsAlive())
|
||||||
|
{
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
RaidKarazhanHelpers karazhanHelper(botAI);
|
RaidKarazhanHelpers karazhanHelper(botAI);
|
||||||
karazhanHelper.MarkTargetWithSkull(target);
|
karazhanHelper.MarkTargetWithSkull(target);
|
||||||
@@ -294,7 +310,6 @@ bool KarazhanTheCuratorMarkTargetAction::Execute(Event event)
|
|||||||
bool KarazhanTheCuratorPositionBossAction::Execute(Event event)
|
bool KarazhanTheCuratorPositionBossAction::Execute(Event event)
|
||||||
{
|
{
|
||||||
Unit* boss = AI_VALUE2(Unit*, "find target", "the curator");
|
Unit* boss = AI_VALUE2(Unit*, "find target", "the curator");
|
||||||
|
|
||||||
const float maxDistance = 3.0f;
|
const float maxDistance = 3.0f;
|
||||||
const float distanceToBossPosition = boss->GetExactDist2d(KARAZHAN_THE_CURATOR_BOSS_POSITION);
|
const float distanceToBossPosition = boss->GetExactDist2d(KARAZHAN_THE_CURATOR_BOSS_POSITION);
|
||||||
|
|
||||||
@@ -302,13 +317,13 @@ bool KarazhanTheCuratorPositionBossAction::Execute(Event event)
|
|||||||
{
|
{
|
||||||
float dX = KARAZHAN_THE_CURATOR_BOSS_POSITION.GetPositionX() - boss->GetPositionX();
|
float dX = KARAZHAN_THE_CURATOR_BOSS_POSITION.GetPositionX() - boss->GetPositionX();
|
||||||
float dY = KARAZHAN_THE_CURATOR_BOSS_POSITION.GetPositionY() - boss->GetPositionY();
|
float dY = KARAZHAN_THE_CURATOR_BOSS_POSITION.GetPositionY() - boss->GetPositionY();
|
||||||
|
|
||||||
float mX = KARAZHAN_THE_CURATOR_BOSS_POSITION.GetPositionX() + (dX / distanceToBossPosition) * maxDistance;
|
float mX = KARAZHAN_THE_CURATOR_BOSS_POSITION.GetPositionX() + (dX / distanceToBossPosition) * maxDistance;
|
||||||
float mY = KARAZHAN_THE_CURATOR_BOSS_POSITION.GetPositionY() + (dY / distanceToBossPosition) * maxDistance;
|
float mY = KARAZHAN_THE_CURATOR_BOSS_POSITION.GetPositionY() + (dY / distanceToBossPosition) * maxDistance;
|
||||||
|
{
|
||||||
return MoveTo(bot->GetMapId(), mX, mY,
|
return MoveTo(bot->GetMapId(), mX, mY,
|
||||||
bot->GetPositionZ(), false, false, false, false, MovementPriority::MOVEMENT_COMBAT, true,
|
bot->GetPositionZ(), false, false, false, false, MovementPriority::MOVEMENT_COMBAT, true,
|
||||||
false);
|
false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -327,8 +342,9 @@ bool KarazhanTheCuratorSpreadRangedAction::Execute(Event event)
|
|||||||
Unit* nearestPlayer = karazhanHelper.GetNearestPlayerInRadius(minDistance);
|
Unit* nearestPlayer = karazhanHelper.GetNearestPlayerInRadius(minDistance);
|
||||||
|
|
||||||
if (nearestPlayer)
|
if (nearestPlayer)
|
||||||
|
{
|
||||||
return FleePosition(nearestPlayer->GetPosition(), minDistance);
|
return FleePosition(nearestPlayer->GetPosition(), minDistance);
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -343,11 +359,12 @@ bool KarazhanTerestianIllhoofMarkTargetAction::Execute(Event event)
|
|||||||
{
|
{
|
||||||
Unit* boss = AI_VALUE2(Unit*, "find target", "terestian illhoof");
|
Unit* boss = AI_VALUE2(Unit*, "find target", "terestian illhoof");
|
||||||
if (!boss)
|
if (!boss)
|
||||||
|
{
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
RaidKarazhanHelpers karazhanHelper(botAI);
|
RaidKarazhanHelpers karazhanHelper(botAI);
|
||||||
Unit* target = karazhanHelper.GetFirstAliveUnitByEntry(NPC_DEMON_CHAINS);
|
Unit* target = karazhanHelper.GetFirstAliveUnitByEntry(NPC_DEMON_CHAINS);
|
||||||
|
|
||||||
if (!target || !target->IsAlive())
|
if (!target || !target->IsAlive())
|
||||||
{
|
{
|
||||||
target = karazhanHelper.GetFirstAliveUnitByEntry(NPC_KILREK);
|
target = karazhanHelper.GetFirstAliveUnitByEntry(NPC_KILREK);
|
||||||
@@ -374,17 +391,15 @@ bool KarazhanShadeOfAranArcaneExplosionRunAwayAction::Execute(Event event)
|
|||||||
{
|
{
|
||||||
return MoveAway(boss, safeDistance - distance);
|
return MoveAway(boss, safeDistance - distance);
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool KarazhanShadeOfAranArcaneExplosionRunAwayAction::isUseful()
|
bool KarazhanShadeOfAranArcaneExplosionRunAwayAction::isUseful()
|
||||||
{
|
{
|
||||||
Unit* boss = AI_VALUE2(Unit*, "find target", "shade of aran");
|
Unit* boss = AI_VALUE2(Unit*, "find target", "shade of aran");
|
||||||
if (!boss || !boss->IsAlive())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return boss->HasUnitState(UNIT_STATE_CASTING) && boss->FindCurrentSpellBySpellId(SPELL_ARCANE_EXPLOSION);
|
return boss && boss->IsAlive() && boss->HasUnitState(UNIT_STATE_CASTING) &&
|
||||||
|
boss->FindCurrentSpellBySpellId(SPELL_ARCANE_EXPLOSION);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool KarazhanShadeOfAranFlameWreathStopMovementAction::Execute(Event event)
|
bool KarazhanShadeOfAranFlameWreathStopMovementAction::Execute(Event event)
|
||||||
@@ -395,8 +410,9 @@ bool KarazhanShadeOfAranFlameWreathStopMovementAction::Execute(Event event)
|
|||||||
AI_VALUE(LastMovement&, "last movement").Set(nullptr);
|
AI_VALUE(LastMovement&, "last movement").Set(nullptr);
|
||||||
bot->GetMotionMaster()->Clear();
|
bot->GetMotionMaster()->Clear();
|
||||||
if (bot->isMoving())
|
if (bot->isMoving())
|
||||||
|
{
|
||||||
bot->StopMoving();
|
bot->StopMoving();
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@@ -407,8 +423,9 @@ bool KarazhanShadeOfAranMarkConjuredElementalAction::Execute(Event event)
|
|||||||
RaidKarazhanHelpers karazhanHelper(botAI);
|
RaidKarazhanHelpers karazhanHelper(botAI);
|
||||||
Unit* boss = AI_VALUE2(Unit*, "find target", "shade of aran");
|
Unit* boss = AI_VALUE2(Unit*, "find target", "shade of aran");
|
||||||
if (!boss || !boss->IsAlive())
|
if (!boss || !boss->IsAlive())
|
||||||
|
{
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
Unit* target = karazhanHelper.GetFirstAliveUnitByEntry(NPC_CONJURED_ELEMENTAL);
|
Unit* target = karazhanHelper.GetFirstAliveUnitByEntry(NPC_CONJURED_ELEMENTAL);
|
||||||
if (!target || !target->IsAlive() || target->HasAura(SPELL_WARLOCK_BANISH))
|
if (!target || !target->IsAlive() || target->HasAura(SPELL_WARLOCK_BANISH))
|
||||||
{
|
{
|
||||||
@@ -430,23 +447,23 @@ bool KarazhanShadeOfAranSpreadRangedAction::Execute(Event event)
|
|||||||
float dX = bot->GetPositionX() - boss->GetPositionX();
|
float dX = bot->GetPositionX() - boss->GetPositionX();
|
||||||
float dY = bot->GetPositionY() - boss->GetPositionY();
|
float dY = bot->GetPositionY() - boss->GetPositionY();
|
||||||
float length = std::sqrt(dX * dX + dY * dY);
|
float length = std::sqrt(dX * dX + dY * dY);
|
||||||
|
|
||||||
dX /= length;
|
dX /= length;
|
||||||
dY /= length;
|
dY /= length;
|
||||||
|
|
||||||
float tX = boss->GetPositionX() + dX * maxBossDistance;
|
float tX = boss->GetPositionX() + dX * maxBossDistance;
|
||||||
float tY = boss->GetPositionY() + dY * maxBossDistance;
|
float tY = boss->GetPositionY() + dY * maxBossDistance;
|
||||||
|
{
|
||||||
return MoveTo(bot->GetMapId(), tX, tY, bot->GetPositionZ(), false, false, false, true,
|
return MoveTo(bot->GetMapId(), tX, tY, bot->GetPositionZ(), false, false, false, true,
|
||||||
MovementPriority::MOVEMENT_COMBAT);
|
MovementPriority::MOVEMENT_COMBAT);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const float minDistance = 5.0f;
|
const float minDistance = 5.0f;
|
||||||
RaidKarazhanHelpers karazhanHelper(botAI);
|
RaidKarazhanHelpers karazhanHelper(botAI);
|
||||||
Unit* nearestPlayer = karazhanHelper.GetNearestPlayerInRadius(minDistance);
|
Unit* nearestPlayer = karazhanHelper.GetNearestPlayerInRadius(minDistance);
|
||||||
if (nearestPlayer)
|
if (nearestPlayer)
|
||||||
|
{
|
||||||
return FleePosition(nearestPlayer->GetPosition(), minDistance);
|
return FleePosition(nearestPlayer->GetPosition(), minDistance);
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -454,7 +471,9 @@ bool KarazhanShadeOfAranSpreadRangedAction::isUseful()
|
|||||||
{
|
{
|
||||||
Unit* boss = AI_VALUE2(Unit*, "find target", "shade of aran");
|
Unit* boss = AI_VALUE2(Unit*, "find target", "shade of aran");
|
||||||
if (!boss || !boss->IsAlive())
|
if (!boss || !boss->IsAlive())
|
||||||
|
{
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
RaidKarazhanHelpers karazhanHelper(botAI);
|
RaidKarazhanHelpers karazhanHelper(botAI);
|
||||||
|
|
||||||
@@ -471,19 +490,27 @@ bool KarazhanNetherspiteBlockRedBeamAction::Execute(Event event)
|
|||||||
|
|
||||||
Group* group = bot->GetGroup();
|
Group* group = bot->GetGroup();
|
||||||
if (!group)
|
if (!group)
|
||||||
|
{
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
Player* eligibleTank = nullptr;
|
Player* eligibleTank = nullptr;
|
||||||
for (GroupReference* itr = group->GetFirstMember(); itr != nullptr; itr = itr->next())
|
for (GroupReference* itr = group->GetFirstMember(); itr != nullptr; itr = itr->next())
|
||||||
{
|
{
|
||||||
Player* member = itr->GetSource();
|
Player* member = itr->GetSource();
|
||||||
if (!member || !member->IsAlive())
|
if (!member || !member->IsAlive())
|
||||||
|
{
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
PlayerbotAI* memberAI = sPlayerbotsMgr->GetPlayerbotAI(member);
|
PlayerbotAI* memberAI = sPlayerbotsMgr->GetPlayerbotAI(member);
|
||||||
if (!memberAI || !memberAI->IsTank(member))
|
if (!memberAI || !memberAI->IsTank(member))
|
||||||
|
{
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
if (member->HasAura(SPELL_NETHER_EXHAUSTION_RED))
|
if (member->HasAura(SPELL_NETHER_EXHAUSTION_RED))
|
||||||
|
{
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
eligibleTank = member;
|
eligibleTank = member;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -522,8 +549,9 @@ bool KarazhanNetherspiteBlockRedBeamAction::Execute(Event event)
|
|||||||
float dy = py - by;
|
float dy = py - by;
|
||||||
float length = sqrt(dx*dx + dy*dy);
|
float length = sqrt(dx*dx + dy*dy);
|
||||||
if (length == 0.0f)
|
if (length == 0.0f)
|
||||||
|
{
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
dx /= length;
|
dx /= length;
|
||||||
dy /= length;
|
dy /= length;
|
||||||
float perpDx = -dy;
|
float perpDx = -dy;
|
||||||
@@ -549,8 +577,9 @@ bool KarazhanNetherspiteBlockRedBeamAction::isUseful()
|
|||||||
bool bossIsBanished = boss && boss->HasAura(SPELL_NETHERSPITE_BANISHED);
|
bool bossIsBanished = boss && boss->HasAura(SPELL_NETHERSPITE_BANISHED);
|
||||||
|
|
||||||
if (!boss || !redPortal)
|
if (!boss || !redPortal)
|
||||||
|
{
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
if (lastBossBanishState[botGuid] != bossIsBanished)
|
if (lastBossBanishState[botGuid] != bossIsBanished)
|
||||||
{
|
{
|
||||||
if (!bossIsBanished)
|
if (!bossIsBanished)
|
||||||
@@ -560,10 +589,10 @@ bool KarazhanNetherspiteBlockRedBeamAction::isUseful()
|
|||||||
}
|
}
|
||||||
lastBossBanishState[botGuid] = bossIsBanished;
|
lastBossBanishState[botGuid] = bossIsBanished;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bossIsBanished)
|
if (bossIsBanished)
|
||||||
|
{
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -606,7 +635,9 @@ bool KarazhanNetherspiteBlockBlueBeamAction::Execute(Event event)
|
|||||||
float dy = py - by;
|
float dy = py - by;
|
||||||
float length = sqrt(dx*dx + dy*dy);
|
float length = sqrt(dx*dx + dy*dy);
|
||||||
if (length == 0.0f)
|
if (length == 0.0f)
|
||||||
|
{
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
dx /= length;
|
dx /= length;
|
||||||
dy /= length;
|
dy /= length;
|
||||||
@@ -630,8 +661,9 @@ bool KarazhanNetherspiteBlockBlueBeamAction::Execute(Event event)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!outsideAllVoidZones)
|
if (!outsideAllVoidZones)
|
||||||
|
{
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
float distToIdeal = fabs(dist - 18.0f);
|
float distToIdeal = fabs(dist - 18.0f);
|
||||||
if (!found || distToIdeal < bestDist)
|
if (!found || distToIdeal < bestDist)
|
||||||
{
|
{
|
||||||
@@ -698,8 +730,9 @@ bool KarazhanNetherspiteBlockGreenBeamAction::Execute(Event event)
|
|||||||
float dy = py - by;
|
float dy = py - by;
|
||||||
float length = sqrt(dx*dx + dy*dy);
|
float length = sqrt(dx*dx + dy*dy);
|
||||||
if (length == 0.0f)
|
if (length == 0.0f)
|
||||||
|
{
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
dx /= length;
|
dx /= length;
|
||||||
dy /= length;
|
dy /= length;
|
||||||
float bestDist = 150.0f;
|
float bestDist = 150.0f;
|
||||||
@@ -722,8 +755,9 @@ bool KarazhanNetherspiteBlockGreenBeamAction::Execute(Event event)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!outsideAllVoidZones)
|
if (!outsideAllVoidZones)
|
||||||
|
{
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
float distToIdeal = fabs(dist - 18.0f);
|
float distToIdeal = fabs(dist - 18.0f);
|
||||||
if (!found || distToIdeal < bestDist)
|
if (!found || distToIdeal < bestDist)
|
||||||
{
|
{
|
||||||
@@ -771,27 +805,30 @@ bool KarazhanNetherspiteAvoidBeamAndVoidZoneAction::Execute(Event event)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct BeamAvoid { Unit* portal; float minDist, maxDist; };
|
struct BeamAvoid { Unit* portal; float minDist, maxDist; };
|
||||||
std::vector<BeamAvoid> beams;
|
std::vector<BeamAvoid> beams;
|
||||||
Unit* redPortal = bot->FindNearestCreature(NPC_RED_PORTAL, 150.0f);
|
Unit* redPortal = bot->FindNearestCreature(NPC_RED_PORTAL, 150.0f);
|
||||||
Unit* bluePortal = bot->FindNearestCreature(NPC_BLUE_PORTAL, 150.0f);
|
Unit* bluePortal = bot->FindNearestCreature(NPC_BLUE_PORTAL, 150.0f);
|
||||||
Unit* greenPortal = bot->FindNearestCreature(NPC_GREEN_PORTAL, 150.0f);
|
Unit* greenPortal = bot->FindNearestCreature(NPC_GREEN_PORTAL, 150.0f);
|
||||||
|
if (redPortal)
|
||||||
if (redPortal) {
|
{
|
||||||
float bx = boss->GetPositionX(), by = boss->GetPositionY();
|
float bx = boss->GetPositionX(), by = boss->GetPositionY();
|
||||||
float px = redPortal->GetPositionX(), py = redPortal->GetPositionY();
|
float px = redPortal->GetPositionX(), py = redPortal->GetPositionY();
|
||||||
float dx = px - bx, dy = py - by;
|
float dx = px - bx, dy = py - by;
|
||||||
float length = sqrt(dx*dx + dy*dy);
|
float length = sqrt(dx*dx + dy*dy);
|
||||||
beams.push_back({redPortal, 0.0f, length});
|
beams.push_back({redPortal, 0.0f, length});
|
||||||
}
|
}
|
||||||
if (bluePortal) {
|
if (bluePortal)
|
||||||
|
{
|
||||||
float bx = boss->GetPositionX(), by = boss->GetPositionY();
|
float bx = boss->GetPositionX(), by = boss->GetPositionY();
|
||||||
float px = bluePortal->GetPositionX(), py = bluePortal->GetPositionY();
|
float px = bluePortal->GetPositionX(), py = bluePortal->GetPositionY();
|
||||||
float dx = px - bx, dy = py - by;
|
float dx = px - bx, dy = py - by;
|
||||||
float length = sqrt(dx*dx + dy*dy);
|
float length = sqrt(dx*dx + dy*dy);
|
||||||
beams.push_back({bluePortal, 0.0f, length});
|
beams.push_back({bluePortal, 0.0f, length});
|
||||||
}
|
}
|
||||||
if (greenPortal) {
|
if (greenPortal)
|
||||||
|
{
|
||||||
float bx = boss->GetPositionX(), by = boss->GetPositionY();
|
float bx = boss->GetPositionX(), by = boss->GetPositionY();
|
||||||
float px = greenPortal->GetPositionX(), py = greenPortal->GetPositionY();
|
float px = greenPortal->GetPositionX(), py = greenPortal->GetPositionY();
|
||||||
float dx = px - bx, dy = py - by;
|
float dx = px - bx, dy = py - by;
|
||||||
@@ -806,8 +843,10 @@ bool KarazhanNetherspiteAvoidBeamAndVoidZoneAction::Execute(Event event)
|
|||||||
float px = beam.portal->GetPositionX(), py = beam.portal->GetPositionY();
|
float px = beam.portal->GetPositionX(), py = beam.portal->GetPositionY();
|
||||||
float dx = px - bx, dy = py - by;
|
float dx = px - bx, dy = py - by;
|
||||||
float length = sqrt(dx*dx + dy*dy);
|
float length = sqrt(dx*dx + dy*dy);
|
||||||
if (length == 0.0f) continue;
|
if (length == 0.0f)
|
||||||
|
{continue;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
dx /= length; dy /= length;
|
dx /= length; dy /= length;
|
||||||
float botdx = bot->GetPositionX() - bx, botdy = bot->GetPositionY() - by;
|
float botdx = bot->GetPositionX() - bx, botdy = bot->GetPositionY() - by;
|
||||||
float t = (botdx * dx + botdy * dy);
|
float t = (botdx * dx + botdy * dy);
|
||||||
@@ -821,7 +860,9 @@ bool KarazhanNetherspiteAvoidBeamAndVoidZoneAction::Execute(Event event)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!nearVoidZone && !nearBeam)
|
if (!nearVoidZone && !nearBeam)
|
||||||
|
{
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
const float minMoveDist = 3.0f, maxSearchDist = 20.0f, stepAngle = M_PI/18.0f, stepDist = 0.5f;
|
const float minMoveDist = 3.0f, maxSearchDist = 20.0f, stepAngle = M_PI/18.0f, stepDist = 0.5f;
|
||||||
float bossZ = boss->GetPositionZ();
|
float bossZ = boss->GetPositionZ();
|
||||||
@@ -836,8 +877,9 @@ bool KarazhanNetherspiteAvoidBeamAndVoidZoneAction::Execute(Event event)
|
|||||||
float cy = bot->GetPositionY() + sin(angle) * dist;
|
float cy = bot->GetPositionY() + sin(angle) * dist;
|
||||||
float cz = bossZ;
|
float cz = bossZ;
|
||||||
if (std::any_of(voidZones.begin(), voidZones.end(), [&](Unit* vz){ return Position(cx, cy, cz).GetExactDist2d(vz) < 4.0f; }))
|
if (std::any_of(voidZones.begin(), voidZones.end(), [&](Unit* vz){ return Position(cx, cy, cz).GetExactDist2d(vz) < 4.0f; }))
|
||||||
|
{
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
bool tooCloseToBeam = false;
|
bool tooCloseToBeam = false;
|
||||||
for (const auto& beam : beams)
|
for (const auto& beam : beams)
|
||||||
{
|
{
|
||||||
@@ -845,7 +887,10 @@ bool KarazhanNetherspiteAvoidBeamAndVoidZoneAction::Execute(Event event)
|
|||||||
float px = beam.portal->GetPositionX(), py = beam.portal->GetPositionY();
|
float px = beam.portal->GetPositionX(), py = beam.portal->GetPositionY();
|
||||||
float dx = px - bx, dy = py - by;
|
float dx = px - bx, dy = py - by;
|
||||||
float length = sqrt(dx*dx + dy*dy);
|
float length = sqrt(dx*dx + dy*dy);
|
||||||
if (length == 0.0f) continue;
|
if (length == 0.0f)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
dx /= length; dy /= length;
|
dx /= length; dy /= length;
|
||||||
float botdx = cx - bx, botdy = cy - by;
|
float botdx = cx - bx, botdy = cy - by;
|
||||||
float t = (botdx * dx + botdy * dy);
|
float t = (botdx * dx + botdy * dy);
|
||||||
@@ -857,11 +902,15 @@ bool KarazhanNetherspiteAvoidBeamAndVoidZoneAction::Execute(Event event)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (tooCloseToBeam) continue;
|
if (tooCloseToBeam)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
float moveDist = sqrt(pow(cx - bot->GetPositionX(), 2) + pow(cy - bot->GetPositionY(), 2));
|
float moveDist = sqrt(pow(cx - bot->GetPositionX(), 2) + pow(cy - bot->GetPositionY(), 2));
|
||||||
if (moveDist < minMoveDist) continue;
|
if (moveDist < minMoveDist)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if (!found || moveDist < bestDist)
|
if (!found || moveDist < bestDist)
|
||||||
{
|
{
|
||||||
bestCandidate = Position(cx, cy, cz);
|
bestCandidate = Position(cx, cy, cz);
|
||||||
@@ -873,9 +922,10 @@ bool KarazhanNetherspiteAvoidBeamAndVoidZoneAction::Execute(Event event)
|
|||||||
if (found && karazhanHelper.IsSafePosition(bestCandidate.GetPositionX(),
|
if (found && karazhanHelper.IsSafePosition(bestCandidate.GetPositionX(),
|
||||||
bestCandidate.GetPositionY(), bestCandidate.GetPositionZ(),
|
bestCandidate.GetPositionY(), bestCandidate.GetPositionZ(),
|
||||||
voidZones, 4.0f))
|
voidZones, 4.0f))
|
||||||
|
{
|
||||||
return MoveTo(bot->GetMapId(), bestCandidate.GetPositionX(), bestCandidate.GetPositionY(),
|
return MoveTo(bot->GetMapId(), bestCandidate.GetPositionX(), bestCandidate.GetPositionY(),
|
||||||
bestCandidate.GetPositionZ(), false, false, false, true, MovementPriority::MOVEMENT_COMBAT);
|
bestCandidate.GetPositionZ(), false, false, false, true, MovementPriority::MOVEMENT_COMBAT);
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -883,13 +933,15 @@ bool KarazhanNetherspiteAvoidBeamAndVoidZoneAction::isUseful()
|
|||||||
{
|
{
|
||||||
Unit* boss = AI_VALUE2(Unit*, "find target", "netherspite");
|
Unit* boss = AI_VALUE2(Unit*, "find target", "netherspite");
|
||||||
if (!boss || boss->HasAura(SPELL_NETHERSPITE_BANISHED))
|
if (!boss || boss->HasAura(SPELL_NETHERSPITE_BANISHED))
|
||||||
|
{
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
RaidKarazhanHelpers karazhanHelper(botAI);
|
RaidKarazhanHelpers karazhanHelper(botAI);
|
||||||
auto [redBlocker, greenBlocker, blueBlocker] = karazhanHelper.GetCurrentBeamBlockers();
|
auto [redBlocker, greenBlocker, blueBlocker] = karazhanHelper.GetCurrentBeamBlockers();
|
||||||
if (bot == redBlocker || bot == blueBlocker || bot == greenBlocker)
|
if (bot == redBlocker || bot == blueBlocker || bot == greenBlocker)
|
||||||
|
{
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -901,7 +953,9 @@ bool KarazhanNetherspiteBanishPhaseAvoidVoidZoneAction::Execute(Event event)
|
|||||||
for (Unit* vz : voidZones)
|
for (Unit* vz : voidZones)
|
||||||
{
|
{
|
||||||
if (vz->GetEntry() == NPC_VOID_ZONE && bot->GetExactDist2d(vz) < 4.0f)
|
if (vz->GetEntry() == NPC_VOID_ZONE && bot->GetExactDist2d(vz) < 4.0f)
|
||||||
|
{
|
||||||
return FleePosition(vz->GetPosition(), 4.0f);
|
return FleePosition(vz->GetPosition(), 4.0f);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -910,19 +964,21 @@ bool KarazhanNetherspiteBanishPhaseAvoidVoidZoneAction::isUseful()
|
|||||||
{
|
{
|
||||||
Unit* boss = AI_VALUE2(Unit*, "find target", "netherspite");
|
Unit* boss = AI_VALUE2(Unit*, "find target", "netherspite");
|
||||||
if (!boss || !boss->HasAura(SPELL_NETHERSPITE_BANISHED))
|
if (!boss || !boss->HasAura(SPELL_NETHERSPITE_BANISHED))
|
||||||
|
{
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
RaidKarazhanHelpers karazhanHelper(botAI);
|
RaidKarazhanHelpers karazhanHelper(botAI);
|
||||||
std::vector<Unit*> voidZones = karazhanHelper.GetAllVoidZones();
|
std::vector<Unit*> voidZones = karazhanHelper.GetAllVoidZones();
|
||||||
for (Unit* vz : voidZones)
|
for (Unit* vz : voidZones)
|
||||||
{
|
{
|
||||||
if (bot->GetExactDist2d(vz) < 4.0f)
|
if (bot->GetExactDist2d(vz) < 4.0f)
|
||||||
|
{
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// For Enfeebled bots to avoid Shadow Nova and all non-tank bots to avoid infernals
|
|
||||||
bool KarazhanPrinceMalchezaarNonTankAvoidHazardAction::Execute(Event event)
|
bool KarazhanPrinceMalchezaarNonTankAvoidHazardAction::Execute(Event event)
|
||||||
{
|
{
|
||||||
Unit* boss = AI_VALUE2(Unit*, "find target", "prince malchezaar");
|
Unit* boss = AI_VALUE2(Unit*, "find target", "prince malchezaar");
|
||||||
@@ -957,7 +1013,9 @@ bool KarazhanPrinceMalchezaarNonTankAvoidHazardAction::Execute(Event event)
|
|||||||
float y = bossY + dy * dist;
|
float y = bossY + dy * dist;
|
||||||
float destZ = bossZ;
|
float destZ = bossZ;
|
||||||
if (!bot->IsWithinLOS(x, y, destZ))
|
if (!bot->IsWithinLOS(x, y, destZ))
|
||||||
|
{
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
bool pathSafe = karazhanHelper.IsStraightPathSafe(Position(bx, by, bz), Position(x, y, destZ),
|
bool pathSafe = karazhanHelper.IsStraightPathSafe(Position(bx, by, bz), Position(x, y, destZ),
|
||||||
infernals, safeInfernalDistance, stepSize);
|
infernals, safeInfernalDistance, stepSize);
|
||||||
float moveDist = sqrt(pow(x - bx, 2) + pow(y - by, 2));
|
float moveDist = sqrt(pow(x - bx, 2) + pow(y - by, 2));
|
||||||
@@ -1011,7 +1069,9 @@ bool KarazhanPrinceMalchezaarNonTankAvoidHazardAction::Execute(Event event)
|
|||||||
float y = bossY + dy * dist;
|
float y = bossY + dy * dist;
|
||||||
float destZ = bossZ;
|
float destZ = bossZ;
|
||||||
if (!bot->IsWithinLOS(x, y, destZ))
|
if (!bot->IsWithinLOS(x, y, destZ))
|
||||||
|
{
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
bool pathSafe = karazhanHelper.IsStraightPathSafe(Position(bx, by, bz), Position(x, y, destZ),
|
bool pathSafe = karazhanHelper.IsStraightPathSafe(Position(bx, by, bz), Position(x, y, destZ),
|
||||||
infernals, safeInfernalDistance, stepSize);
|
infernals, safeInfernalDistance, stepSize);
|
||||||
float moveDist = sqrt(pow(x - bx, 2) + pow(y - by, 2));
|
float moveDist = sqrt(pow(x - bx, 2) + pow(y - by, 2));
|
||||||
@@ -1029,7 +1089,9 @@ bool KarazhanPrinceMalchezaarNonTankAvoidHazardAction::Execute(Event event)
|
|||||||
Position arcPoint = karazhanHelper.CalculateArcPoint(Position(bx, by, bz), Position(x, y, destZ),
|
Position arcPoint = karazhanHelper.CalculateArcPoint(Position(bx, by, bz), Position(x, y, destZ),
|
||||||
Position(bossX, bossY, bossZ));
|
Position(bossX, bossY, bossZ));
|
||||||
if (!bot->IsWithinLOS(arcPoint.GetPositionX(), arcPoint.GetPositionY(), arcPoint.GetPositionZ()))
|
if (!bot->IsWithinLOS(arcPoint.GetPositionX(), arcPoint.GetPositionY(), arcPoint.GetPositionZ()))
|
||||||
|
{
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
bool arcSafe = true;
|
bool arcSafe = true;
|
||||||
for (Unit* infernal : infernals)
|
for (Unit* infernal : infernals)
|
||||||
{
|
{
|
||||||
@@ -1075,7 +1137,6 @@ bool KarazhanPrinceMalchezaarNonTankAvoidHazardAction::isUseful()
|
|||||||
return boss && !(botAI->IsTank(bot) && botAI->HasAggro(boss) && boss->GetVictim() == bot);
|
return boss && !(botAI->IsTank(bot) && botAI->HasAggro(boss) && boss->GetVictim() == bot);
|
||||||
}
|
}
|
||||||
|
|
||||||
// For tank to avoid infernals (with buffer distance)
|
|
||||||
bool KarazhanPrinceMalchezaarTankAvoidHazardAction::Execute(Event event)
|
bool KarazhanPrinceMalchezaarTankAvoidHazardAction::Execute(Event event)
|
||||||
{
|
{
|
||||||
Unit* boss = AI_VALUE2(Unit*, "find target", "prince malchezaar");
|
Unit* boss = AI_VALUE2(Unit*, "find target", "prince malchezaar");
|
||||||
@@ -1117,7 +1178,9 @@ bool KarazhanPrinceMalchezaarTankAvoidHazardAction::Execute(Event event)
|
|||||||
float y = by + dy * dist;
|
float y = by + dy * dist;
|
||||||
float z = bz;
|
float z = bz;
|
||||||
if (!bot->IsWithinLOS(x, y, z))
|
if (!bot->IsWithinLOS(x, y, z))
|
||||||
|
{
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
bool safe = karazhanHelper.IsStraightPathSafe(Position(bx, by, bz), Position(x, y, z),
|
bool safe = karazhanHelper.IsStraightPathSafe(Position(bx, by, bz), Position(x, y, z),
|
||||||
infernals, safeInfernalDistance, stepSize);
|
infernals, safeInfernalDistance, stepSize);
|
||||||
float moveDist = sqrt(pow(x - bx, 2) + pow(y - by, 2));
|
float moveDist = sqrt(pow(x - bx, 2) + pow(y - by, 2));
|
||||||
@@ -1134,8 +1197,14 @@ bool KarazhanPrinceMalchezaarTankAvoidHazardAction::Execute(Event event)
|
|||||||
{
|
{
|
||||||
Position arcPoint = karazhanHelper.CalculateArcPoint(Position(bx, by, bz), Position(x, y, z),
|
Position arcPoint = karazhanHelper.CalculateArcPoint(Position(bx, by, bz), Position(x, y, z),
|
||||||
Position(bx, by, bz));
|
Position(bx, by, bz));
|
||||||
if (!bot->IsWithinLOS(arcPoint.GetPositionX(), arcPoint.GetPositionY(), arcPoint.GetPositionZ()))
|
float arcX = arcPoint.GetPositionX();
|
||||||
|
float arcY = arcPoint.GetPositionY();
|
||||||
|
float arcZ = arcPoint.GetPositionZ();
|
||||||
|
float arcDestX = arcX, arcDestY = arcY, arcDestZ = arcZ;
|
||||||
|
if (!bot->GetMap()->CheckCollisionAndGetValidCoords(bot, bx, by, bz, arcDestX, arcDestY, arcDestZ))
|
||||||
|
{
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
bool arcSafe = true;
|
bool arcSafe = true;
|
||||||
for (Unit* infernal : infernals)
|
for (Unit* infernal : infernals)
|
||||||
{
|
{
|
||||||
@@ -1164,6 +1233,7 @@ bool KarazhanPrinceMalchezaarTankAvoidHazardAction::Execute(Event event)
|
|||||||
{
|
{
|
||||||
bot->AttackStop();
|
bot->AttackStop();
|
||||||
bot->InterruptNonMeleeSpells(false);
|
bot->InterruptNonMeleeSpells(false);
|
||||||
|
|
||||||
return MoveTo(bot->GetMapId(), bestDestX, bestDestY, bestDestZ, false, false, false, true,
|
return MoveTo(bot->GetMapId(), bestDestX, bestDestY, bestDestZ, false, false, false, true,
|
||||||
MovementPriority::MOVEMENT_COMBAT);
|
MovementPriority::MOVEMENT_COMBAT);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -35,7 +35,9 @@ const Position KARAZHAN_THE_CURATOR_BOSS_POSITION = Position(-11139.463f, -1884.
|
|||||||
void RaidKarazhanHelpers::MarkTargetWithSkull(Unit* target)
|
void RaidKarazhanHelpers::MarkTargetWithSkull(Unit* target)
|
||||||
{
|
{
|
||||||
if (!target)
|
if (!target)
|
||||||
|
{
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (Group* group = bot->GetGroup())
|
if (Group* group = bot->GetGroup())
|
||||||
{
|
{
|
||||||
@@ -43,15 +45,21 @@ void RaidKarazhanHelpers::MarkTargetWithSkull(Unit* target)
|
|||||||
ObjectGuid skullGuid = group->GetTargetIcon(skullIconId);
|
ObjectGuid skullGuid = group->GetTargetIcon(skullIconId);
|
||||||
|
|
||||||
if (skullGuid != target->GetGUID())
|
if (skullGuid != target->GetGUID())
|
||||||
|
{
|
||||||
group->SetTargetIcon(skullIconId, bot->GetGUID(), target->GetGUID());
|
group->SetTargetIcon(skullIconId, bot->GetGUID(), target->GetGUID());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Unit* RaidKarazhanHelpers::GetFirstAliveUnit(const std::vector<Unit*>& units)
|
Unit* RaidKarazhanHelpers::GetFirstAliveUnit(const std::vector<Unit*>& units)
|
||||||
{
|
{
|
||||||
for (Unit* unit : units)
|
for (Unit* unit : units)
|
||||||
|
{
|
||||||
if (unit && unit->IsAlive())
|
if (unit && unit->IsAlive())
|
||||||
|
{
|
||||||
return unit;
|
return unit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
@@ -65,8 +73,11 @@ Unit* RaidKarazhanHelpers::GetFirstAliveUnitByEntry(uint32 entry)
|
|||||||
Unit* unit = botAI->GetUnit(npcGuid);
|
Unit* unit = botAI->GetUnit(npcGuid);
|
||||||
|
|
||||||
if (unit && unit->IsAlive() && unit->GetEntry() == entry)
|
if (unit && unit->IsAlive() && unit->GetEntry() == entry)
|
||||||
|
{
|
||||||
return unit;
|
return unit;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -79,10 +90,14 @@ Unit* RaidKarazhanHelpers::GetNearestPlayerInRadius(float radius)
|
|||||||
Player* member = itr->GetSource();
|
Player* member = itr->GetSource();
|
||||||
|
|
||||||
if (!member || !member->IsAlive() || member == bot)
|
if (!member || !member->IsAlive() || member == bot)
|
||||||
|
{
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (bot->GetExactDist2d(member) < radius)
|
if (bot->GetExactDist2d(member) < radius)
|
||||||
|
{
|
||||||
return member;
|
return member;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
@@ -92,12 +107,13 @@ bool RaidKarazhanHelpers::IsFlameWreathActive()
|
|||||||
{
|
{
|
||||||
Unit* boss = AI_VALUE2(Unit*, "find target", "shade of aran");
|
Unit* boss = AI_VALUE2(Unit*, "find target", "shade of aran");
|
||||||
if (!boss)
|
if (!boss)
|
||||||
|
{
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
Spell* currentSpell = boss->GetCurrentSpell(CURRENT_GENERIC_SPELL);
|
Spell* currentSpell = boss->GetCurrentSpell(CURRENT_GENERIC_SPELL);
|
||||||
if (currentSpell && currentSpell->m_spellInfo && currentSpell->m_spellInfo->Id == SPELL_FLAME_WREATH)
|
if (currentSpell && currentSpell->m_spellInfo && currentSpell->m_spellInfo->Id == SPELL_FLAME_WREATH)
|
||||||
{
|
{
|
||||||
bot->Yell("I will not move when Flame Wreath is cast or the raid blows up.", LANG_UNIVERSAL);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -107,9 +123,13 @@ bool RaidKarazhanHelpers::IsFlameWreathActive()
|
|||||||
{
|
{
|
||||||
Player* member = itr->GetSource();
|
Player* member = itr->GetSource();
|
||||||
if (!member || !member->IsAlive())
|
if (!member || !member->IsAlive())
|
||||||
|
{
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
if (member->HasAura(SPELL_AURA_FLAME_WREATH))
|
if (member->HasAura(SPELL_AURA_FLAME_WREATH))
|
||||||
|
{
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@@ -125,7 +145,9 @@ std::vector<Player*> RaidKarazhanHelpers::GetBlueBlockers()
|
|||||||
{
|
{
|
||||||
Player* member = itr->GetSource();
|
Player* member = itr->GetSource();
|
||||||
if (!member || !member->IsAlive() || !GET_PLAYERBOT_AI(member))
|
if (!member || !member->IsAlive() || !GET_PLAYERBOT_AI(member))
|
||||||
|
{
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
bool isDps = botAI->IsDps(member);
|
bool isDps = botAI->IsDps(member);
|
||||||
bool isWarrior = member->getClass() == CLASS_WARRIOR;
|
bool isWarrior = member->getClass() == CLASS_WARRIOR;
|
||||||
@@ -155,7 +177,9 @@ std::vector<Player*> RaidKarazhanHelpers::GetGreenBlockers()
|
|||||||
{
|
{
|
||||||
Player* member = itr->GetSource();
|
Player* member = itr->GetSource();
|
||||||
if (!member || !member->IsAlive() || !GET_PLAYERBOT_AI(member))
|
if (!member || !member->IsAlive() || !GET_PLAYERBOT_AI(member))
|
||||||
|
{
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
bool hasExhaustion = member->HasAura(SPELL_NETHER_EXHAUSTION_GREEN);
|
bool hasExhaustion = member->HasAura(SPELL_NETHER_EXHAUSTION_GREEN);
|
||||||
Aura* greenBuff = member->GetAura(SPELL_GREEN_BEAM_DEBUFF);
|
Aura* greenBuff = member->GetAura(SPELL_GREEN_BEAM_DEBUFF);
|
||||||
@@ -188,7 +212,9 @@ Position RaidKarazhanHelpers::GetPositionOnBeam(Unit* boss, Unit* portal, float
|
|||||||
float length = sqrt(dx*dx + dy*dy);
|
float length = sqrt(dx*dx + dy*dy);
|
||||||
|
|
||||||
if (length == 0.0f)
|
if (length == 0.0f)
|
||||||
|
{
|
||||||
return Position(bx, by, bz);
|
return Position(bx, by, bz);
|
||||||
|
}
|
||||||
|
|
||||||
dx /= length;
|
dx /= length;
|
||||||
dy /= length;
|
dy /= length;
|
||||||
@@ -213,26 +239,37 @@ std::tuple<Player*, Player*, Player*> RaidKarazhanHelpers::GetCurrentBeamBlocker
|
|||||||
{
|
{
|
||||||
Player* member = itr->GetSource();
|
Player* member = itr->GetSource();
|
||||||
if (!member || !member->IsAlive())
|
if (!member || !member->IsAlive())
|
||||||
|
{
|
||||||
continue;
|
continue;
|
||||||
PlayerbotAI* memberAI = sPlayerbotsMgr->GetPlayerbotAI(member);
|
}
|
||||||
if (!memberAI || !memberAI->IsTank(member))
|
if (!botAI->IsTank(member))
|
||||||
|
{
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
if (member->HasAura(SPELL_NETHER_EXHAUSTION_RED))
|
if (member->HasAura(SPELL_NETHER_EXHAUSTION_RED))
|
||||||
|
{
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
redBlockers.push_back(member);
|
redBlockers.push_back(member);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!redBlockers.empty())
|
if (!redBlockers.empty())
|
||||||
|
{
|
||||||
redBlocker = redBlockers.front();
|
redBlocker = redBlockers.front();
|
||||||
|
}
|
||||||
|
|
||||||
std::vector<Player*> greenBlockers = GetGreenBlockers();
|
std::vector<Player*> greenBlockers = GetGreenBlockers();
|
||||||
if (!greenBlockers.empty())
|
if (!greenBlockers.empty())
|
||||||
|
{
|
||||||
greenBlocker = greenBlockers.front();
|
greenBlocker = greenBlockers.front();
|
||||||
|
}
|
||||||
|
|
||||||
std::vector<Player*> blueBlockers = GetBlueBlockers();
|
std::vector<Player*> blueBlockers = GetBlueBlockers();
|
||||||
if (!blueBlockers.empty())
|
if (!blueBlockers.empty())
|
||||||
|
{
|
||||||
blueBlocker = blueBlockers.front();
|
blueBlocker = blueBlockers.front();
|
||||||
|
}
|
||||||
|
|
||||||
return std::make_tuple(redBlocker, greenBlocker, blueBlocker);
|
return std::make_tuple(redBlocker, greenBlocker, blueBlocker);
|
||||||
}
|
}
|
||||||
@@ -246,7 +283,9 @@ std::vector<Unit*> RaidKarazhanHelpers::GetAllVoidZones()
|
|||||||
{
|
{
|
||||||
Unit* unit = botAI->GetUnit(npcGuid);
|
Unit* unit = botAI->GetUnit(npcGuid);
|
||||||
if (!unit || unit->GetEntry() != NPC_VOID_ZONE)
|
if (!unit || unit->GetEntry() != NPC_VOID_ZONE)
|
||||||
|
{
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
float dist = bot->GetExactDist2d(unit);
|
float dist = bot->GetExactDist2d(unit);
|
||||||
if (dist < radius)
|
if (dist < radius)
|
||||||
@@ -265,7 +304,9 @@ bool RaidKarazhanHelpers::IsSafePosition(float x, float y, float z,
|
|||||||
float dist = std::sqrt(std::pow(x - hazard->GetPositionX(), 2) + std::pow(y - hazard->GetPositionY(), 2));
|
float dist = std::sqrt(std::pow(x - hazard->GetPositionX(), 2) + std::pow(y - hazard->GetPositionY(), 2));
|
||||||
|
|
||||||
if (dist < hazardRadius)
|
if (dist < hazardRadius)
|
||||||
|
{
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -280,7 +321,9 @@ std::vector<Unit*> RaidKarazhanHelpers::GetSpawnedInfernals() const
|
|||||||
Unit* unit = botAI->GetUnit(npcGuid);
|
Unit* unit = botAI->GetUnit(npcGuid);
|
||||||
|
|
||||||
if (unit && unit->GetEntry() == NPC_NETHERSPITE_INFERNAL)
|
if (unit && unit->GetEntry() == NPC_NETHERSPITE_INFERNAL)
|
||||||
|
{
|
||||||
infernals.push_back(unit);
|
infernals.push_back(unit);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return infernals;
|
return infernals;
|
||||||
}
|
}
|
||||||
@@ -295,7 +338,10 @@ bool RaidKarazhanHelpers::IsStraightPathSafe(const Position& start, const Positi
|
|||||||
float tz = target.GetPositionZ();
|
float tz = target.GetPositionZ();
|
||||||
float totalDist = std::sqrt(std::pow(tx - sx, 2) + std::pow(ty - sy, 2));
|
float totalDist = std::sqrt(std::pow(tx - sx, 2) + std::pow(ty - sy, 2));
|
||||||
if (totalDist == 0.0f)
|
if (totalDist == 0.0f)
|
||||||
|
{
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
for (float checkDist = 0.0f; checkDist <= totalDist; checkDist += stepSize)
|
for (float checkDist = 0.0f; checkDist <= totalDist; checkDist += stepSize)
|
||||||
{
|
{
|
||||||
float t = checkDist / totalDist;
|
float t = checkDist / totalDist;
|
||||||
@@ -306,56 +352,54 @@ bool RaidKarazhanHelpers::IsStraightPathSafe(const Position& start, const Positi
|
|||||||
{
|
{
|
||||||
float hazardDist = std::sqrt(std::pow(checkX - hazard->GetPositionX(), 2) + std::pow(checkY - hazard->GetPositionY(), 2));
|
float hazardDist = std::sqrt(std::pow(checkX - hazard->GetPositionX(), 2) + std::pow(checkY - hazard->GetPositionY(), 2));
|
||||||
if (hazardDist < hazardRadius)
|
if (hazardDist < hazardRadius)
|
||||||
|
{
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
Position RaidKarazhanHelpers::CalculateArcPoint(const Position& current, const Position& target, const Position& center)
|
Position RaidKarazhanHelpers::CalculateArcPoint(const Position& current, const Position& target, const Position& center)
|
||||||
{
|
{
|
||||||
float arcFraction = 0.25f;
|
float arcFraction = 0.25f;
|
||||||
// Calculate vectors from center to current position and target
|
|
||||||
float currentX = current.GetPositionX() - center.GetPositionX();
|
float currentX = current.GetPositionX() - center.GetPositionX();
|
||||||
float currentY = current.GetPositionY() - center.GetPositionY();
|
float currentY = current.GetPositionY() - center.GetPositionY();
|
||||||
float targetX = target.GetPositionX() - center.GetPositionX();
|
float targetX = target.GetPositionX() - center.GetPositionX();
|
||||||
float targetY = target.GetPositionY() - center.GetPositionY();
|
float targetY = target.GetPositionY() - center.GetPositionY();
|
||||||
|
|
||||||
// Calculate distances
|
|
||||||
float currentDist = std::sqrt(currentX * currentX + currentY * currentY);
|
float currentDist = std::sqrt(currentX * currentX + currentY * currentY);
|
||||||
float targetDist = std::sqrt(targetX * targetX + targetY * targetY);
|
float targetDist = std::sqrt(targetX * targetX + targetY * targetY);
|
||||||
if (currentDist == 0.0f || targetDist == 0.0f)
|
if (currentDist == 0.0f || targetDist == 0.0f)
|
||||||
|
{
|
||||||
return current;
|
return current;
|
||||||
|
}
|
||||||
|
|
||||||
// Normalize vectors
|
|
||||||
currentX /= currentDist;
|
currentX /= currentDist;
|
||||||
currentY /= currentDist;
|
currentY /= currentDist;
|
||||||
targetX /= targetDist;
|
targetX /= targetDist;
|
||||||
targetY /= targetDist;
|
targetY /= targetDist;
|
||||||
|
|
||||||
// Calculate dot product to find the angle between vectors
|
|
||||||
float dotProduct = currentX * targetX + currentY * targetY;
|
float dotProduct = currentX * targetX + currentY * targetY;
|
||||||
dotProduct = std::max(-1.0f, std::min(1.0f, dotProduct)); // Clamp to [-1, 1]
|
dotProduct = std::max(-1.0f, std::min(1.0f, dotProduct));
|
||||||
float angle = std::acos(dotProduct);
|
float angle = std::acos(dotProduct);
|
||||||
|
|
||||||
// Determine rotation direction (clockwise or counterclockwise)
|
|
||||||
float crossProduct = currentX * targetY - currentY * targetX;
|
float crossProduct = currentX * targetY - currentY * targetX;
|
||||||
float stepAngle = angle * arcFraction; // Move arcFraction along the arc
|
float stepAngle = angle * arcFraction;
|
||||||
if (crossProduct < 0)
|
if (crossProduct < 0)
|
||||||
stepAngle = -stepAngle; // Clockwise
|
{
|
||||||
|
stepAngle = -stepAngle;
|
||||||
|
}
|
||||||
|
|
||||||
// Calculate rotation matrix components
|
|
||||||
float cos_a = std::cos(stepAngle);
|
float cos_a = std::cos(stepAngle);
|
||||||
float sin_a = std::sin(stepAngle);
|
float sin_a = std::sin(stepAngle);
|
||||||
|
|
||||||
// Rotate current vector
|
|
||||||
float rotatedX = currentX * cos_a - currentY * sin_a;
|
float rotatedX = currentX * cos_a - currentY * sin_a;
|
||||||
float rotatedY = currentX * sin_a + currentY * cos_a;
|
float rotatedY = currentX * sin_a + currentY * cos_a;
|
||||||
|
|
||||||
// Smoothing: blend current and target radius
|
|
||||||
float desiredDist = currentDist * 0.9f + targetDist * 0.1f;
|
float desiredDist = currentDist * 0.9f + targetDist * 0.1f;
|
||||||
|
|
||||||
// Calculate the new position
|
|
||||||
return Position(center.GetPositionX() + rotatedX * desiredDist,
|
return Position(center.GetPositionX() + rotatedX * desiredDist,
|
||||||
center.GetPositionY() + rotatedY * desiredDist,
|
center.GetPositionY() + rotatedY * desiredDist,
|
||||||
current.GetPositionZ());
|
current.GetPositionZ());
|
||||||
|
|||||||
@@ -8,49 +8,49 @@
|
|||||||
enum KarazhanSpells
|
enum KarazhanSpells
|
||||||
{
|
{
|
||||||
// Maiden of Virtue
|
// Maiden of Virtue
|
||||||
SPELL_REPENTANCE = 29511,
|
SPELL_REPENTANCE = 29511,
|
||||||
|
|
||||||
// Opera Event
|
// Opera Event
|
||||||
SPELL_LITTLE_RED_RIDING_HOOD = 30756,
|
SPELL_LITTLE_RED_RIDING_HOOD = 30756,
|
||||||
|
|
||||||
// Shade of Aran
|
// Shade of Aran
|
||||||
SPELL_FLAME_WREATH = 30004,
|
SPELL_FLAME_WREATH = 30004,
|
||||||
SPELL_AURA_FLAME_WREATH = 29946,
|
SPELL_AURA_FLAME_WREATH = 29946,
|
||||||
SPELL_ARCANE_EXPLOSION = 29973,
|
SPELL_ARCANE_EXPLOSION = 29973,
|
||||||
SPELL_WARLOCK_BANISH = 18647, // Rank 2
|
SPELL_WARLOCK_BANISH = 18647, // Rank 2
|
||||||
|
|
||||||
// Netherspite
|
// Netherspite
|
||||||
SPELL_GREEN_BEAM_DEBUFF = 30422,
|
SPELL_GREEN_BEAM_DEBUFF = 30422,
|
||||||
SPELL_BLUE_BEAM_DEBUFF = 30423,
|
SPELL_BLUE_BEAM_DEBUFF = 30423,
|
||||||
SPELL_NETHER_EXHAUSTION_RED = 38637,
|
SPELL_NETHER_EXHAUSTION_RED = 38637,
|
||||||
SPELL_NETHER_EXHAUSTION_GREEN = 38638,
|
SPELL_NETHER_EXHAUSTION_GREEN = 38638,
|
||||||
SPELL_NETHER_EXHAUSTION_BLUE = 38639,
|
SPELL_NETHER_EXHAUSTION_BLUE = 38639,
|
||||||
SPELL_NETHERSPITE_BANISHED = 39833,
|
SPELL_NETHERSPITE_BANISHED = 39833,
|
||||||
|
|
||||||
// Prince Malchezaar
|
// Prince Malchezaar
|
||||||
SPELL_ENFEEBLE = 30843,
|
SPELL_ENFEEBLE = 30843,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum KarazhanNpcs
|
enum KarazhanNpcs
|
||||||
{
|
{
|
||||||
// Attumen the Huntsman
|
// Attumen the Huntsman
|
||||||
NPC_ATTUMEN_THE_HUNTSMAN = 16152, // Mounted ID
|
NPC_ATTUMEN_THE_HUNTSMAN_MOUNTED = 16152,
|
||||||
|
|
||||||
// Terestian Illhoof
|
// Terestian Illhoof
|
||||||
NPC_KILREK = 17229,
|
NPC_KILREK = 17229,
|
||||||
NPC_DEMON_CHAINS = 17248,
|
NPC_DEMON_CHAINS = 17248,
|
||||||
|
|
||||||
// Shade of Aran
|
// Shade of Aran
|
||||||
NPC_CONJURED_ELEMENTAL = 17167,
|
NPC_CONJURED_ELEMENTAL = 17167,
|
||||||
|
|
||||||
// Netherspite
|
// Netherspite
|
||||||
NPC_VOID_ZONE = 16697,
|
NPC_VOID_ZONE = 16697,
|
||||||
NPC_RED_PORTAL = 17369,
|
NPC_RED_PORTAL = 17369,
|
||||||
NPC_BLUE_PORTAL = 17368,
|
NPC_BLUE_PORTAL = 17368,
|
||||||
NPC_GREEN_PORTAL = 17367,
|
NPC_GREEN_PORTAL = 17367,
|
||||||
|
|
||||||
// Prince Malchezaar
|
// Prince Malchezaar
|
||||||
NPC_NETHERSPITE_INFERNAL = 17646,
|
NPC_NETHERSPITE_INFERNAL = 17646,
|
||||||
};
|
};
|
||||||
|
|
||||||
extern const Position KARAZHAN_MAIDEN_OF_VIRTUE_BOSS_POSITION;
|
extern const Position KARAZHAN_MAIDEN_OF_VIRTUE_BOSS_POSITION;
|
||||||
|
|||||||
@@ -19,13 +19,17 @@ float KarazhanBigBadWolfMultiplier::GetValue(Action* action)
|
|||||||
{
|
{
|
||||||
Unit* boss = AI_VALUE2(Unit*, "find target", "the big bad wolf");
|
Unit* boss = AI_VALUE2(Unit*, "find target", "the big bad wolf");
|
||||||
if (!boss)
|
if (!boss)
|
||||||
|
{
|
||||||
return 1.0f;
|
return 1.0f;
|
||||||
|
}
|
||||||
|
|
||||||
if (bot->HasAura(SPELL_LITTLE_RED_RIDING_HOOD))
|
if (bot->HasAura(SPELL_LITTLE_RED_RIDING_HOOD))
|
||||||
{
|
{
|
||||||
if ((dynamic_cast<MovementAction*>(action) && !dynamic_cast<KarazhanBigBadWolfRunAwayAction*>(action)) ||
|
if ((dynamic_cast<MovementAction*>(action) && !dynamic_cast<KarazhanBigBadWolfRunAwayAction*>(action)) ||
|
||||||
(dynamic_cast<AttackAction*>(action)))
|
(dynamic_cast<AttackAction*>(action)))
|
||||||
return 0.0f;
|
{
|
||||||
|
return 0.0f;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return 1.0f;
|
return 1.0f;
|
||||||
}
|
}
|
||||||
@@ -34,18 +38,24 @@ float KarazhanShadeOfAranMultiplier::GetValue(Action* action)
|
|||||||
{
|
{
|
||||||
Unit* boss = AI_VALUE2(Unit*, "find target", "shade of aran");
|
Unit* boss = AI_VALUE2(Unit*, "find target", "shade of aran");
|
||||||
if (!boss)
|
if (!boss)
|
||||||
|
{
|
||||||
return 1.0f;
|
return 1.0f;
|
||||||
|
}
|
||||||
|
|
||||||
if (boss->HasUnitState(UNIT_STATE_CASTING) && boss->FindCurrentSpellBySpellId(SPELL_ARCANE_EXPLOSION))
|
if (boss->HasUnitState(UNIT_STATE_CASTING) && boss->FindCurrentSpellBySpellId(SPELL_ARCANE_EXPLOSION))
|
||||||
{
|
{
|
||||||
if (IsChargeAction(action))
|
if (IsChargeAction(action))
|
||||||
|
{
|
||||||
return 0.0f;
|
return 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
if (dynamic_cast<MovementAction*>(action))
|
if (dynamic_cast<MovementAction*>(action))
|
||||||
{
|
{
|
||||||
const float safeDistance = 20.0f;
|
const float safeDistance = 20.0f;
|
||||||
if (bot->GetDistance2d(boss) >= safeDistance)
|
if (bot->GetDistance2d(boss) >= safeDistance)
|
||||||
|
{
|
||||||
return 0.0f;
|
return 0.0f;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -67,7 +77,9 @@ float KarazhanShadeOfAranMultiplier::GetValue(Action* action)
|
|||||||
if (flameWreathActive)
|
if (flameWreathActive)
|
||||||
{
|
{
|
||||||
if (dynamic_cast<MovementAction*>(action) || IsChargeAction(action))
|
if (dynamic_cast<MovementAction*>(action) || IsChargeAction(action))
|
||||||
|
{
|
||||||
return 0.0f;
|
return 0.0f;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return 1.0f;
|
return 1.0f;
|
||||||
}
|
}
|
||||||
@@ -76,7 +88,9 @@ float KarazhanNetherspiteBlueAndGreenBeamMultiplier::GetValue(Action* action)
|
|||||||
{
|
{
|
||||||
Unit* boss = AI_VALUE2(Unit*, "find target", "netherspite");
|
Unit* boss = AI_VALUE2(Unit*, "find target", "netherspite");
|
||||||
if (!boss || !boss->IsAlive())
|
if (!boss || !boss->IsAlive())
|
||||||
|
{
|
||||||
return 1.0f;
|
return 1.0f;
|
||||||
|
}
|
||||||
|
|
||||||
RaidKarazhanHelpers karazhanHelper(botAI);
|
RaidKarazhanHelpers karazhanHelper(botAI);
|
||||||
auto [redBlocker /*unused*/, greenBlocker, blueBlocker] = karazhanHelper.GetCurrentBeamBlockers();
|
auto [redBlocker /*unused*/, greenBlocker, blueBlocker] = karazhanHelper.GetCurrentBeamBlockers();
|
||||||
@@ -88,18 +102,25 @@ float KarazhanNetherspiteBlueAndGreenBeamMultiplier::GetValue(Action* action)
|
|||||||
|
|
||||||
bool inBeam = false;
|
bool inBeam = false;
|
||||||
for (Unit* portal : {bluePortal, greenPortal}) {
|
for (Unit* portal : {bluePortal, greenPortal}) {
|
||||||
if (!portal) continue;
|
if (!portal)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
float bx = boss->GetPositionX(), by = boss->GetPositionY();
|
float bx = boss->GetPositionX(), by = boss->GetPositionY();
|
||||||
float px = portal->GetPositionX(), py = portal->GetPositionY();
|
float px = portal->GetPositionX(), py = portal->GetPositionY();
|
||||||
float dx = px - bx, dy = py - by;
|
float dx = px - bx, dy = py - by;
|
||||||
float length = sqrt(dx*dx + dy*dy);
|
float length = sqrt(dx*dx + dy*dy);
|
||||||
if (length == 0.0f) continue;
|
if (length == 0.0f)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
dx /= length; dy /= length;
|
dx /= length; dy /= length;
|
||||||
float botdx = bot->GetPositionX() - bx, botdy = bot->GetPositionY() - by;
|
float botdx = bot->GetPositionX() - bx, botdy = bot->GetPositionY() - by;
|
||||||
float t = (botdx * dx + botdy * dy);
|
float t = (botdx * dx + botdy * dy);
|
||||||
float beamX = bx + dx * t, beamY = by + dy * t;
|
float beamX = bx + dx * t, beamY = by + dy * t;
|
||||||
float distToBeam = sqrt(pow(bot->GetPositionX() - beamX, 2) + pow(bot->GetPositionY() - beamY, 2));
|
float distToBeam = sqrt(pow(bot->GetPositionX() - beamX, 2) + pow(bot->GetPositionY() - beamY, 2));
|
||||||
if (distToBeam < 5.0f && t > 0.0f && t < length) {
|
if (distToBeam < 5.0f && t > 0.0f && t < length)
|
||||||
|
{
|
||||||
inBeam = true;
|
inBeam = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -118,7 +139,9 @@ float KarazhanNetherspiteBlueAndGreenBeamMultiplier::GetValue(Action* action)
|
|||||||
if (!inVoidZone)
|
if (!inVoidZone)
|
||||||
{
|
{
|
||||||
if (dynamic_cast<MovementAction*>(action) || IsChargeAction(action))
|
if (dynamic_cast<MovementAction*>(action) || IsChargeAction(action))
|
||||||
|
{
|
||||||
return 0.0f;
|
return 0.0f;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -129,7 +152,9 @@ float KarazhanNetherspiteRedBeamMultiplier::GetValue(Action* action)
|
|||||||
{
|
{
|
||||||
Unit* boss = AI_VALUE2(Unit*, "find target", "netherspite");
|
Unit* boss = AI_VALUE2(Unit*, "find target", "netherspite");
|
||||||
if (!boss || !boss->IsAlive())
|
if (!boss || !boss->IsAlive())
|
||||||
|
{
|
||||||
return 1.0f;
|
return 1.0f;
|
||||||
|
}
|
||||||
|
|
||||||
RaidKarazhanHelpers karazhanHelper(botAI);
|
RaidKarazhanHelpers karazhanHelper(botAI);
|
||||||
auto [redBlocker, greenBlocker /*unused*/, blueBlocker /*unused*/] = karazhanHelper.GetCurrentBeamBlockers();
|
auto [redBlocker, greenBlocker /*unused*/, blueBlocker /*unused*/] = karazhanHelper.GetCurrentBeamBlockers();
|
||||||
@@ -177,7 +202,9 @@ float KarazhanNetherspiteRedBeamMultiplier::GetValue(Action* action)
|
|||||||
if (distToTarget < positionTolerance)
|
if (distToTarget < positionTolerance)
|
||||||
{
|
{
|
||||||
if (dynamic_cast<MovementAction*>(action) || IsChargeAction(action))
|
if (dynamic_cast<MovementAction*>(action) || IsChargeAction(action))
|
||||||
|
{
|
||||||
return 0.0f;
|
return 0.0f;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -187,13 +214,14 @@ float KarazhanNetherspiteRedBeamMultiplier::GetValue(Action* action)
|
|||||||
float KarazhanPrinceMalchezaarMultiplier::GetValue(Action* action)
|
float KarazhanPrinceMalchezaarMultiplier::GetValue(Action* action)
|
||||||
{
|
{
|
||||||
Unit* boss = AI_VALUE2(Unit*, "find target", "prince malchezaar");
|
Unit* boss = AI_VALUE2(Unit*, "find target", "prince malchezaar");
|
||||||
if (!boss)
|
|
||||||
return 1.0f;
|
|
||||||
|
|
||||||
if (boss && bot->HasAura(SPELL_ENFEEBLE))
|
if (boss && botAI->IsMelee(bot) && bot->HasAura(SPELL_ENFEEBLE))
|
||||||
{
|
{
|
||||||
if (IsChargeAction(action))
|
if (dynamic_cast<KarazhanPrinceMalchezaarNonTankAvoidHazardAction*>(action))
|
||||||
return 0.0f;
|
{
|
||||||
|
return 1.0f;
|
||||||
|
}
|
||||||
|
return 0.0f;
|
||||||
}
|
}
|
||||||
return 1.0f;
|
return 1.0f;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,8 +6,9 @@
|
|||||||
bool KarazhanAttumenTheHuntsmanTrigger::IsActive()
|
bool KarazhanAttumenTheHuntsmanTrigger::IsActive()
|
||||||
{
|
{
|
||||||
RaidKarazhanHelpers helpers(botAI);
|
RaidKarazhanHelpers helpers(botAI);
|
||||||
Unit* boss = helpers.GetFirstAliveUnitByEntry(NPC_ATTUMEN_THE_HUNTSMAN);
|
Unit* boss = helpers.GetFirstAliveUnitByEntry(NPC_ATTUMEN_THE_HUNTSMAN_MOUNTED);
|
||||||
return boss != nullptr;
|
|
||||||
|
return boss && boss->IsAlive();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool KarazhanMoroesTrigger::IsActive()
|
bool KarazhanMoroesTrigger::IsActive()
|
||||||
@@ -20,36 +21,27 @@ bool KarazhanMoroesTrigger::IsActive()
|
|||||||
Unit* robin = AI_VALUE2(Unit*, "find target", "lord robin daris");
|
Unit* robin = AI_VALUE2(Unit*, "find target", "lord robin daris");
|
||||||
Unit* crispin = AI_VALUE2(Unit*, "find target", "lord crispin ference");
|
Unit* crispin = AI_VALUE2(Unit*, "find target", "lord crispin ference");
|
||||||
|
|
||||||
if ((!moroes || !moroes->IsAlive()) &&
|
return ((moroes && moroes->IsAlive()) ||
|
||||||
(!dorothea || !dorothea->IsAlive()) &&
|
(dorothea && dorothea->IsAlive()) ||
|
||||||
(!catriona || !catriona->IsAlive()) &&
|
(catriona && catriona->IsAlive()) ||
|
||||||
(!keira || !keira->IsAlive()) &&
|
(keira && keira->IsAlive()) ||
|
||||||
(!rafe || !rafe->IsAlive()) &&
|
(rafe && rafe->IsAlive()) ||
|
||||||
(!robin || !robin->IsAlive()) &&
|
(robin && robin->IsAlive()) ||
|
||||||
(!crispin || !crispin->IsAlive()))
|
(crispin && crispin->IsAlive()));
|
||||||
return false;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool KarazhanMaidenOfVirtueTrigger::IsActive()
|
bool KarazhanMaidenOfVirtueTrigger::IsActive()
|
||||||
{
|
{
|
||||||
Unit* boss = AI_VALUE2(Unit*, "find target", "maiden of virtue");
|
Unit* boss = AI_VALUE2(Unit*, "find target", "maiden of virtue");
|
||||||
|
|
||||||
if (!boss || !boss->IsAlive())
|
return boss && boss->IsAlive();
|
||||||
return false;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool KarazhanBigBadWolfTrigger::IsActive()
|
bool KarazhanBigBadWolfTrigger::IsActive()
|
||||||
{
|
{
|
||||||
Unit* boss = AI_VALUE2(Unit*, "find target", "the big bad wolf");
|
Unit* boss = AI_VALUE2(Unit*, "find target", "the big bad wolf");
|
||||||
|
|
||||||
if (!boss || !boss->IsAlive())
|
return boss && boss->IsAlive();
|
||||||
return false;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool KarazhanRomuloAndJulianneTrigger::IsActive()
|
bool KarazhanRomuloAndJulianneTrigger::IsActive()
|
||||||
@@ -57,10 +49,7 @@ bool KarazhanRomuloAndJulianneTrigger::IsActive()
|
|||||||
Unit* julianne = AI_VALUE2(Unit*, "find target", "julianne");
|
Unit* julianne = AI_VALUE2(Unit*, "find target", "julianne");
|
||||||
Unit* romulo = AI_VALUE2(Unit*, "find target", "romulo");
|
Unit* romulo = AI_VALUE2(Unit*, "find target", "romulo");
|
||||||
|
|
||||||
if (!julianne || !julianne->IsAlive() || !romulo || !romulo->IsAlive())
|
return julianne && julianne->IsAlive() && romulo && romulo->IsAlive();
|
||||||
return false;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool KarazhanWizardOfOzTrigger::IsActive()
|
bool KarazhanWizardOfOzTrigger::IsActive()
|
||||||
@@ -72,63 +61,45 @@ bool KarazhanWizardOfOzTrigger::IsActive()
|
|||||||
Unit* tinhead = AI_VALUE2(Unit*, "find target", "tinhead");
|
Unit* tinhead = AI_VALUE2(Unit*, "find target", "tinhead");
|
||||||
Unit* crone = AI_VALUE2(Unit*, "find target", "the crone");
|
Unit* crone = AI_VALUE2(Unit*, "find target", "the crone");
|
||||||
|
|
||||||
if (( !dorothee || !dorothee->IsAlive() ) &&
|
return ((dorothee && dorothee->IsAlive()) ||
|
||||||
( !tito || !tito->IsAlive() ) &&
|
(tito && tito->IsAlive()) ||
|
||||||
( !roar || !roar->IsAlive() ) &&
|
(roar && roar->IsAlive()) ||
|
||||||
( !strawman || !strawman->IsAlive() ) &&
|
(strawman && strawman->IsAlive()) ||
|
||||||
( !tinhead || !tinhead->IsAlive() ) &&
|
(tinhead && tinhead->IsAlive()) ||
|
||||||
( !crone || !crone->IsAlive() ))
|
(crone && crone->IsAlive()));
|
||||||
return false;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool KarazhanTheCuratorTrigger::IsActive()
|
bool KarazhanTheCuratorTrigger::IsActive()
|
||||||
{
|
{
|
||||||
Unit* boss = AI_VALUE2(Unit*, "find target", "the curator");
|
Unit* boss = AI_VALUE2(Unit*, "find target", "the curator");
|
||||||
|
|
||||||
if (!boss || !boss->IsAlive())
|
return boss && boss->IsAlive();
|
||||||
return false;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool KarazhanTerestianIllhoofTrigger::IsActive()
|
bool KarazhanTerestianIllhoofTrigger::IsActive()
|
||||||
{
|
{
|
||||||
Unit* boss = AI_VALUE2(Unit*, "find target", "terestian illhoof");
|
Unit* boss = AI_VALUE2(Unit*, "find target", "terestian illhoof");
|
||||||
|
|
||||||
if (!boss || !boss->IsAlive())
|
return boss && boss->IsAlive();
|
||||||
return false;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool KarazhanShadeOfAranTrigger::IsActive()
|
bool KarazhanShadeOfAranTrigger::IsActive()
|
||||||
{
|
{
|
||||||
Unit* boss = AI_VALUE2(Unit*, "find target", "shade of aran");
|
Unit* boss = AI_VALUE2(Unit*, "find target", "shade of aran");
|
||||||
|
|
||||||
if (!boss)
|
return boss && boss->IsAlive();
|
||||||
return false;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool KarazhanNetherspiteTrigger::IsActive()
|
bool KarazhanNetherspiteTrigger::IsActive()
|
||||||
{
|
{
|
||||||
Unit* boss = AI_VALUE2(Unit*, "find target", "netherspite");
|
Unit* boss = AI_VALUE2(Unit*, "find target", "netherspite");
|
||||||
|
|
||||||
if (!boss || !boss->IsAlive())
|
return boss && boss->IsAlive();
|
||||||
return false;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool KarazhanPrinceMalchezaarTrigger::IsActive()
|
bool KarazhanPrinceMalchezaarTrigger::IsActive()
|
||||||
{
|
{
|
||||||
Unit* boss = AI_VALUE2(Unit*, "find target", "prince malchezaar");
|
Unit* boss = AI_VALUE2(Unit*, "find target", "prince malchezaar");
|
||||||
|
|
||||||
if (!boss || !boss->IsAlive())
|
return boss && boss->IsAlive();
|
||||||
return false;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user