Reapply "Dungeon code cleanup"

This reverts commit 3f7f306124.
This commit is contained in:
Bobblybook
2024-10-20 15:59:42 +11:00
parent 3f7f306124
commit 159cd1ad71
16 changed files with 106 additions and 151 deletions

View File

@@ -12,12 +12,12 @@ bool ShatterSpreadAction::Execute(Event event)
GuidVector members = AI_VALUE(GuidVector, "group members"); GuidVector members = AI_VALUE(GuidVector, "group members");
for (auto& member : members) for (auto& member : members)
{ {
if (bot->GetGUID() == member) Unit* unit = botAI->GetUnit(member);
if (!unit || bot->GetGUID() == member)
{ {
continue; continue;
} }
if (!closestMember || if (!closestMember || bot->GetExactDist2d(unit) < bot->GetExactDist2d(closestMember))
bot->GetExactDist2d(botAI->GetUnit(member)) < bot->GetExactDist2d(closestMember))
{ {
closestMember = botAI->GetUnit(member); closestMember = botAI->GetUnit(member);
} }

View File

@@ -26,4 +26,5 @@ void WotlkDungeonHoSStrategy::InitTriggers(std::vector<TriggerNode*> &triggers)
void WotlkDungeonHoSStrategy::InitMultipliers(std::vector<Multiplier*> &multipliers) void WotlkDungeonHoSStrategy::InitMultipliers(std::vector<Multiplier*> &multipliers)
{ {
multipliers.push_back(new KrystallusMultiplier(botAI)); multipliers.push_back(new KrystallusMultiplier(botAI));
multipliers.push_back(new SjonnirMultiplier(botAI));
} }

View File

@@ -33,11 +33,12 @@ bool MoveFromWhirlwindAction::Execute(Event event)
default: default:
break; break;
} }
if (!boss || bot->GetExactDist2d(boss->GetPosition()) > targetDist) float bossDistance = bot->GetExactDist2d(boss->GetPosition());
if (!boss || bossDistance > targetDist)
{ {
return false; return false;
} }
return MoveAway(boss, targetDist - bot->GetExactDist2d(boss->GetPosition())); return MoveAway(boss, targetDist - bossDistance);
} }
bool FirebombSpreadAction::Execute(Event event) bool FirebombSpreadAction::Execute(Event event)
@@ -50,13 +51,16 @@ bool FirebombSpreadAction::Execute(Event event)
GuidVector members = AI_VALUE(GuidVector, "group members"); GuidVector members = AI_VALUE(GuidVector, "group members");
for (auto& member : members) for (auto& member : members)
{ {
if (bot->GetGUID() == member) Unit* unit = botAI->GetUnit(member);
if (!unit || bot->GetGUID() == member)
{ {
continue; continue;
} }
if (bot->GetExactDist2d(botAI->GetUnit(member)) < targetDist)
if (bot->GetExactDist2d(unit) < targetDist)
{ {
return MoveAway(botAI->GetUnit(member), targetDist); float bossDistance = bot->GetExactDist2d(boss->GetPosition());
return MoveAway(unit, targetDist - bossDistance);
} }
} }
return false; return false;
@@ -70,24 +74,22 @@ bool TelestraSplitTargetAction::Execute(Event event)
for (auto& attacker : attackers) for (auto& attacker : attackers)
{ {
Unit* npc = botAI->GetUnit(attacker); Unit* unit = botAI->GetUnit(attacker);
if (!npc) if (!unit) { continue; }
{
continue; switch (unit->GetEntry())
}
switch (npc->GetEntry())
{ {
// Focus arcane clone first // Focus arcane clone first
case NPC_ARCANE_MAGUS: case NPC_ARCANE_MAGUS:
splitTargets[0] = npc; splitTargets[0] = unit;
break; break;
// Then the frost clone // Then the frost clone
case NPC_FROST_MAGUS: case NPC_FROST_MAGUS:
splitTargets[1] = npc; splitTargets[1] = unit;
break; break;
// Fire clone last // Fire clone last
case NPC_FIRE_MAGUS: case NPC_FIRE_MAGUS:
splitTargets[2] = npc; splitTargets[2] = unit;
break; break;
} }
} }
@@ -139,11 +141,15 @@ bool ChaoticRiftTargetAction::Execute(Event event)
bool DodgeSpikesAction::isUseful() bool DodgeSpikesAction::isUseful()
{ {
Unit* boss = AI_VALUE2(Unit*, "find target", "ormorok the tree-shaper"); Unit* boss = AI_VALUE2(Unit*, "find target", "ormorok the tree-shaper");
if (!boss) { return false; }
return bot->GetExactDist2d(boss) > 0.5f; return bot->GetExactDist2d(boss) > 0.5f;
} }
bool DodgeSpikesAction::Execute(Event event) bool DodgeSpikesAction::Execute(Event event)
{ {
Unit* boss = AI_VALUE2(Unit*, "find target", "ormorok the tree-shaper"); Unit* boss = AI_VALUE2(Unit*, "find target", "ormorok the tree-shaper");
if (!boss) { return false; }
return Move(bot->GetAngle(boss), bot->GetExactDist2d(boss) - 0.3f); return Move(bot->GetAngle(boss), bot->GetExactDist2d(boss) - 0.3f);
} }

View File

@@ -7,22 +7,6 @@
#include "Playerbots.h" #include "Playerbots.h"
#include "NexusTriggers.h" #include "NexusTriggers.h"
#define ANGLE_45_DEG (static_cast<float>(M_PI) / 4.f)
#define ANGLE_90_DEG M_PI_2
#define ANGLE_120_DEG (2.f * static_cast<float>(M_PI) / 3.f)
// Slice of the circle that we want melee dps to attack from.
// Measured from boss orientation, on one side.
// Even though the breath cone is not the full 180 degrees,
// avoid melee dps from the front due to parry potential.
// Bots should learn good dps etiquette :)
#define DRAGON_MELEE_MIN_ANGLE ANGLE_90_DEG
// This leaves a danger zone of 60 degrees at the tail end on both sides.
// This is a total of 120 degrees tail arc that bots will avoid -
// number just happens to be the same in this case, but this is always measured from the front.
#define DRAGON_MELEE_MAX_ANGLE ANGLE_120_DEG
class MoveFromWhirlwindAction : public MovementAction class MoveFromWhirlwindAction : public MovementAction
{ {
public: public:

View File

@@ -77,10 +77,8 @@ float AnomalusMultiplier::GetValue(Action* action)
float OrmorokMultiplier::GetValue(Action* action) float OrmorokMultiplier::GetValue(Action* action)
{ {
Unit* boss = AI_VALUE2(Unit*, "find target", "ormorok the tree-shaper"); Unit* boss = AI_VALUE2(Unit*, "find target", "ormorok the tree-shaper");
if (!boss) if (!boss) { return 1.0f; }
{
return 1.0f;
}
// These are used for auto ranged repositioning, need to suppress so ranged dps don't ping-pong // These are used for auto ranged repositioning, need to suppress so ranged dps don't ping-pong
if (dynamic_cast<FleeAction*>(action)) if (dynamic_cast<FleeAction*>(action))
{ {

View File

@@ -39,13 +39,4 @@ class OrmorokMultiplier : public Multiplier
virtual float GetValue(Action* action); virtual float GetValue(Action* action);
}; };
class KeristraszaMultiplier : public Multiplier
{
public:
KeristraszaMultiplier(PlayerbotAI* ai) : Multiplier(ai, "keristrasza") {}
public:
virtual float GetValue(Action* action);
};
#endif #endif

View File

@@ -50,5 +50,4 @@ void WotlkDungeonNexStrategy::InitMultipliers(std::vector<Multiplier*> &multipli
multipliers.push_back(new TelestraMultiplier(botAI)); multipliers.push_back(new TelestraMultiplier(botAI));
multipliers.push_back(new AnomalusMultiplier(botAI)); multipliers.push_back(new AnomalusMultiplier(botAI));
multipliers.push_back(new OrmorokMultiplier(botAI)); multipliers.push_back(new OrmorokMultiplier(botAI));
// multipliers.push_back(new KeristraszaMultiplier(botAI));
} }

View File

@@ -42,22 +42,22 @@ bool AvoidShadowCrashAction::Execute(Event event)
{ {
// Could check all enemy units in range as it's possible to pull multiple of these mobs. // Could check all enemy units in range as it's possible to pull multiple of these mobs.
// They should really be killed 1 by 1, multipulls are messy so we just handle singles for now // They should really be killed 1 by 1, multipulls are messy so we just handle singles for now
Unit* npc = AI_VALUE2(Unit*, "find target", "forgotten one"); Unit* unit = AI_VALUE2(Unit*, "find target", "forgotten one");
Unit* victim = nullptr; Unit* victim = nullptr;
float radius = 10.0f; float radius = 10.0f;
float targetDist = radius + 2.0f; float targetDist = radius + 2.0f;
if (!npc) { return false; } if (!unit) { return false; }
// Actively move if targeted by a shadow crash. // Actively move if targeted by a shadow crash.
// Spell check not needed, they don't have any other non-instant casts // Spell check not needed, they don't have any other non-instant casts
if (npc->HasUnitState(UNIT_STATE_CASTING)) // && npc->FindCurrentSpellBySpellId(SPELL_SHADOW_CRASH)) if (unit->HasUnitState(UNIT_STATE_CASTING)) // && unit->FindCurrentSpellBySpellId(SPELL_SHADOW_CRASH))
{ {
// This doesn't seem to avoid casts very well, perhaps because this isn't checked while allies are casting. // This doesn't seem to avoid casts very well, perhaps because this isn't checked while allies are casting.
// TODO: Revisit if this is an issue in heroics, otherwise ignore shadow crashes for the most part. // TODO: Revisit if this is an issue in heroics, otherwise ignore shadow crashes for the most part.
victim = botAI->GetUnit(npc->GetTarget()); victim = botAI->GetUnit(unit->GetTarget());
if (victim && bot->GetExactDist2d(victim) < radius) if (victim && bot->GetExactDist2d(victim) < radius)
{ {
return MoveAway(victim, targetDist - bot->GetExactDist2d(victim)); return MoveAway(victim, targetDist - bot->GetExactDist2d(victim->GetPosition()));
} }
} }

View File

@@ -9,9 +9,10 @@
float ElderNadoxMultiplier::GetValue(Action* action) float ElderNadoxMultiplier::GetValue(Action* action)
{ {
Unit* boss = AI_VALUE2(Unit*, "find target", "elder nadox"); Unit* boss = AI_VALUE2(Unit*, "find target", "elder nadox");
Unit* guardian = AI_VALUE2(Unit*, "find target", "ahn'kahar guardian"); if (!boss) { return 1.0f; }
if (boss && guardian) Unit* guardian = AI_VALUE2(Unit*, "find target", "ahn'kahar guardian");
if (guardian)
{ {
if (dynamic_cast<DpsAssistAction*>(action)) if (dynamic_cast<DpsAssistAction*>(action))
{ {
@@ -24,7 +25,7 @@ float ElderNadoxMultiplier::GetValue(Action* action)
float JedogaShadowseekerMultiplier::GetValue(Action* action) float JedogaShadowseekerMultiplier::GetValue(Action* action)
{ {
Unit* boss = AI_VALUE2(Unit*, "find target", "jedoga shadowseeker"); Unit* boss = AI_VALUE2(Unit*, "find target", "jedoga shadowseeker");
// Unit* volunteer = AI_VALUE2(Unit*, "find target", "twilight volunteer"); if (!boss) { return 1.0f; }
Unit* volunteer = nullptr; Unit* volunteer = nullptr;
// Target is not findable from threat table using AI_VALUE2(), // Target is not findable from threat table using AI_VALUE2(),
@@ -41,7 +42,7 @@ float JedogaShadowseekerMultiplier::GetValue(Action* action)
} }
} }
if (boss && volunteer) if (volunteer)
{ {
if (dynamic_cast<DpsAssistAction*>(action)) if (dynamic_cast<DpsAssistAction*>(action))
{ {
@@ -53,9 +54,10 @@ float JedogaShadowseekerMultiplier::GetValue(Action* action)
float ForgottenOneMultiplier::GetValue(Action* action) float ForgottenOneMultiplier::GetValue(Action* action)
{ {
Unit* npc = AI_VALUE2(Unit*, "find target", "forgotten one"); Unit* unit = AI_VALUE2(Unit*, "find target", "forgotten one");
if (!unit) { return 1.0f; }
if (npc && bot->isMoving()) if (bot->isMoving())
{ {
if (dynamic_cast<MovementAction*>(action)) if (dynamic_cast<MovementAction*>(action))
{ {

View File

@@ -17,9 +17,9 @@ bool NadoxGuardianTrigger::IsActive()
bool JedogaVolunteerTrigger::IsActive() bool JedogaVolunteerTrigger::IsActive()
{ {
Unit* boss = AI_VALUE2(Unit*, "find target", "jedoga shadowseeker"); Unit* boss = AI_VALUE2(Unit*, "find target", "jedoga shadowseeker");
// Unit* volunteer = AI_VALUE2(Unit*, "find target", "twilight volunteer"); if (!boss) { return false; }
Unit* volunteer = nullptr;
// Target is not findable from threat table using AI_VALUE2(), // Volunteer is not findable from threat table using AI_VALUE2(),
// therefore need to search manually for the unit name // therefore need to search manually for the unit name
GuidVector targets = AI_VALUE(GuidVector, "possible targets no los"); GuidVector targets = AI_VALUE(GuidVector, "possible targets no los");
@@ -28,16 +28,16 @@ bool JedogaVolunteerTrigger::IsActive()
Unit* unit = botAI->GetUnit(*i); Unit* unit = botAI->GetUnit(*i);
if (unit && unit->GetEntry() == NPC_TWILIGHT_VOLUNTEER) if (unit && unit->GetEntry() == NPC_TWILIGHT_VOLUNTEER)
{ {
volunteer = unit; return true;
break;
} }
} }
return false;
return boss && volunteer;
} }
bool ShadowCrashTrigger::IsActive() bool ShadowCrashTrigger::IsActive()
{ {
if (botAI->IsMelee(bot)) { return false; } Unit* unit = AI_VALUE2(Unit*, "find target", "forgotten one");
return !botAI->IsMelee(bot) && AI_VALUE2(Unit*, "find target", "forgotten one"); if (!unit) { return false; }
return !botAI->IsMelee(bot);
} }

View File

@@ -14,7 +14,7 @@ bool AttackFrostTombAction::Execute(Event event)
for (auto i = targets.begin(); i != targets.end(); ++i) for (auto i = targets.begin(); i != targets.end(); ++i)
{ {
Unit* unit = botAI->GetUnit(*i); Unit* unit = botAI->GetUnit(*i);
if (unit && unit->GetName() == "Frost Tomb") if (unit && unit->GetEntry() == NPC_FROST_TOMB)
{ {
frostTomb = unit; frostTomb = unit;
break; break;
@@ -31,7 +31,9 @@ bool AttackFrostTombAction::Execute(Event event)
bool AttackDalronnAction::Execute(Event event) bool AttackDalronnAction::Execute(Event event)
{ {
Unit* boss = AI_VALUE2(Unit*, "find target", "dalronn the controller"); Unit* boss = AI_VALUE2(Unit*, "find target", "dalronn the controller");
if (!boss || AI_VALUE(Unit*, "current target") == boss) if (!boss) { return false; }
if (AI_VALUE(Unit*, "current target") == boss)
{ {
return false; return false;
} }
@@ -42,10 +44,7 @@ bool IngvarStopCastingAction::Execute(Event event)
{ {
// Doesn't work, this action gets queued behind the current spell instead of interrupting it // Doesn't work, this action gets queued behind the current spell instead of interrupting it
Unit* boss = AI_VALUE2(Unit*, "find target", "ingvar the plunderer"); Unit* boss = AI_VALUE2(Unit*, "find target", "ingvar the plunderer");
if (!boss) if (!boss) { return false; }
{
return false;
}
int32 my_spell_id = AI_VALUE(uint32, "active spell"); int32 my_spell_id = AI_VALUE(uint32, "active spell");
if (!my_spell_id || my_spell_id == 0) if (!my_spell_id || my_spell_id == 0)
@@ -54,10 +53,7 @@ bool IngvarStopCastingAction::Execute(Event event)
} }
Spell* spell = bot->FindCurrentSpellBySpellId(my_spell_id); Spell* spell = bot->FindCurrentSpellBySpellId(my_spell_id);
if (!spell) if (!spell) { return false; }
{
return false;
}
// bot->Yell("cancelling spell="+std::to_string(my_spell_id), LANG_UNIVERSAL); // bot->Yell("cancelling spell="+std::to_string(my_spell_id), LANG_UNIVERSAL);
bot->InterruptSpell(spell->GetCurrentContainer(), false, true, true); bot->InterruptSpell(spell->GetCurrentContainer(), false, true, true);
@@ -71,10 +67,7 @@ bool IngvarDodgeSmashAction::isUseful() { return !AI_VALUE2(bool, "behind", "cur
bool IngvarDodgeSmashAction::Execute(Event event) bool IngvarDodgeSmashAction::Execute(Event event)
{ {
Unit* boss = AI_VALUE2(Unit*, "find target", "ingvar the plunderer"); Unit* boss = AI_VALUE2(Unit*, "find target", "ingvar the plunderer");
if (!boss) if (!boss) { return false; }
{
return false;
}
float distance = bot->GetExactDist2d(boss->GetPosition()); float distance = bot->GetExactDist2d(boss->GetPosition());
// Extra units to move into the boss, instead of being just 1 pixel past his midpoint. // Extra units to move into the boss, instead of being just 1 pixel past his midpoint.
@@ -88,10 +81,7 @@ bool IngvarSmashReturnAction::isUseful() { return AI_VALUE2(bool, "behind", "cur
bool IngvarSmashReturnAction::Execute(Event event) bool IngvarSmashReturnAction::Execute(Event event)
{ {
Unit* boss = AI_VALUE2(Unit*, "find target", "ingvar the plunderer"); Unit* boss = AI_VALUE2(Unit*, "find target", "ingvar the plunderer");
if (!boss) if (!boss) { return false; }
{
return false;
}
float distance = bot->GetExactDist2d(boss->GetPosition()); float distance = bot->GetExactDist2d(boss->GetPosition());
return Move(bot->GetAngle(boss), distance + bot->GetMeleeReach()); return Move(bot->GetAngle(boss), distance + bot->GetMeleeReach());

View File

@@ -7,10 +7,8 @@
float PrinceKelesethMultiplier::GetValue(Action* action) float PrinceKelesethMultiplier::GetValue(Action* action)
{ {
Unit* boss = AI_VALUE2(Unit*, "find target", "prince keleseth"); Unit* boss = AI_VALUE2(Unit*, "find target", "prince keleseth");
if (!boss) if (!boss) { return 1.0f; }
{
return 1.0f;
}
if (dynamic_cast<DpsAssistAction*>(action)) if (dynamic_cast<DpsAssistAction*>(action))
{ {
return 0.0f; return 0.0f;
@@ -20,13 +18,9 @@ float PrinceKelesethMultiplier::GetValue(Action* action)
float SkarvaldAndDalronnMultiplier::GetValue(Action* action) float SkarvaldAndDalronnMultiplier::GetValue(Action* action)
{ {
// Unit* skarvald = AI_VALUE2(Unit*, "find target", "skarvald the constructor"); // Only need to deal with Dalronn here. If he's dead, just fall back to normal dps strat
Unit* dalronn = AI_VALUE2(Unit*, "find target", "dalronn the controller"); Unit* boss = AI_VALUE2(Unit*, "find target", "dalronn the controller");
if (!boss) { return 1.0f; }
if (!dalronn)
{
return 1.0f;
}
if (dynamic_cast<DpsAssistAction*>(action)) if (dynamic_cast<DpsAssistAction*>(action))
{ {
@@ -39,10 +33,7 @@ float IngvarThePlundererMultiplier::GetValue(Action* action)
{ {
Unit* boss = AI_VALUE2(Unit*, "find target", "ingvar the plunderer"); Unit* boss = AI_VALUE2(Unit*, "find target", "ingvar the plunderer");
bool isTank = botAI->IsTank(bot); bool isTank = botAI->IsTank(bot);
if (!boss) if (!boss) { return 1.0f; }
{
return 1.0f;
}
// Prevent movement actions overriding current movement, we're probably dodging a slam // Prevent movement actions overriding current movement, we're probably dodging a slam
if (isTank && bot->isMoving() && dynamic_cast<MovementAction*>(action)) if (isTank && bot->isMoving() && dynamic_cast<MovementAction*>(action))
@@ -60,10 +51,7 @@ float IngvarThePlundererMultiplier::GetValue(Action* action)
{ {
uint32 spellId = AI_VALUE2(uint32, "spell id", action->getName()); uint32 spellId = AI_VALUE2(uint32, "spell id", action->getName());
SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId); SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId);
if (!spellInfo) if (!spellInfo) { return 1.0f; }
{
return 1.0f;
}
uint32 castTime = spellInfo->CalcCastTime(bot); uint32 castTime = spellInfo->CalcCastTime(bot);
if (castTime != 0) if (castTime != 0)
@@ -73,10 +61,8 @@ float IngvarThePlundererMultiplier::GetValue(Action* action)
} }
} }
// Done with non-tank logic // Done with non-tank logic
if (!isTank) if (!isTank) { return 1.0f; }
{
return 1.0f;
}
// TANK ONLY // TANK ONLY
if (boss->FindCurrentSpellBySpellId(SPELL_SMASH) || if (boss->FindCurrentSpellBySpellId(SPELL_SMASH) ||
boss->FindCurrentSpellBySpellId(SPELL_DARK_SMASH)) boss->FindCurrentSpellBySpellId(SPELL_DARK_SMASH))

View File

@@ -9,7 +9,7 @@ bool KelesethFrostTombTrigger::IsActive()
for (auto& member : members) for (auto& member : members)
{ {
Unit* unit = botAI->GetUnit(member); Unit* unit = botAI->GetUnit(member);
if (unit && unit->HasAura(DEBUFF_FROST_TOMB)) if (unit && unit->HasAura(SPELL_FROST_TOMB))
{ {
return true; return true;
} }
@@ -19,21 +19,17 @@ bool KelesethFrostTombTrigger::IsActive()
bool DalronnNontankTrigger::IsActive() bool DalronnNontankTrigger::IsActive()
{ {
Unit* dalronn = AI_VALUE2(Unit*, "find target", "dalronn the controller"); Unit* boss = AI_VALUE2(Unit*, "find target", "dalronn the controller");
if (!dalronn) if (!boss) { return false; }
{
return false;
}
return !botAI->IsTank(bot); return !botAI->IsTank(bot);
} }
bool IngvarStaggeringRoarTrigger::IsActive() bool IngvarStaggeringRoarTrigger::IsActive()
{ {
Unit* boss = AI_VALUE2(Unit*, "find target", "ingvar the plunderer"); Unit* boss = AI_VALUE2(Unit*, "find target", "ingvar the plunderer");
if (!boss) if (!boss) { return false; }
{
return false;
}
if (boss->HasUnitState(UNIT_STATE_CASTING)) if (boss->HasUnitState(UNIT_STATE_CASTING))
{ {
if (boss->FindCurrentSpellBySpellId(SPELL_STAGGERING_ROAR)) if (boss->FindCurrentSpellBySpellId(SPELL_STAGGERING_ROAR))
@@ -47,16 +43,12 @@ bool IngvarStaggeringRoarTrigger::IsActive()
bool IngvarDreadfulRoarTrigger::IsActive() bool IngvarDreadfulRoarTrigger::IsActive()
{ {
Unit* boss = AI_VALUE2(Unit*, "find target", "ingvar the plunderer"); Unit* boss = AI_VALUE2(Unit*, "find target", "ingvar the plunderer");
if (!boss) if (!boss) { return false; }
if (boss->HasUnitState(UNIT_STATE_CASTING) &&
boss->FindCurrentSpellBySpellId(SPELL_DREADFUL_ROAR))
{ {
return false; return true;
}
if (boss->HasUnitState(UNIT_STATE_CASTING))
{
if (boss->FindCurrentSpellBySpellId(SPELL_DREADFUL_ROAR))
{
return true;
}
} }
return false; return false;
} }
@@ -64,10 +56,7 @@ bool IngvarDreadfulRoarTrigger::IsActive()
bool IngvarSmashTankTrigger::IsActive() bool IngvarSmashTankTrigger::IsActive()
{ {
Unit* boss = AI_VALUE2(Unit*, "find target", "ingvar the plunderer"); Unit* boss = AI_VALUE2(Unit*, "find target", "ingvar the plunderer");
if (!boss || !botAI->IsTank(bot)) if (!boss || !botAI->IsTank(bot)) { return false; }
{
return false;
}
if (boss->HasUnitState(UNIT_STATE_CASTING)) if (boss->HasUnitState(UNIT_STATE_CASTING))
{ {
@@ -86,20 +75,15 @@ bool IngvarSmashTankReturnTrigger::IsActive()
// if (!boss || !botAI->IsTank(bot) || boss->HasUnitState(UNIT_STATE_CASTING)) // if (!boss || !botAI->IsTank(bot) || boss->HasUnitState(UNIT_STATE_CASTING))
// Ignore casting state as Ingvar will sometimes chain-cast a roar after a smash.. // Ignore casting state as Ingvar will sometimes chain-cast a roar after a smash..
// We don't want this to prevent our tank from repositioning properly. // We don't want this to prevent our tank from repositioning properly.
if (!boss || !botAI->IsTank(bot)) if (!boss || !botAI->IsTank(bot)) { return false; }
{
return false;
}
return true; return true;
} }
bool NotBehindIngvarTrigger::IsActive() bool NotBehindIngvarTrigger::IsActive()
{ {
Unit* boss = AI_VALUE2(Unit*, "find target", "ingvar the plunderer"); Unit* boss = AI_VALUE2(Unit*, "find target", "ingvar the plunderer");
if (!boss || botAI->IsTank(bot)) if (!boss || botAI->IsTank(bot)) { return false; }
{
return false;
}
return AI_VALUE2(bool, "behind", "current target"); return AI_VALUE2(bool, "behind", "current target");
} }

View File

@@ -7,6 +7,8 @@ bool AttackErekemAction::Execute(Event event)
{ {
// Focus boss first, adds after // Focus boss first, adds after
Unit* boss = AI_VALUE2(Unit*, "find target", "erekem"); Unit* boss = AI_VALUE2(Unit*, "find target", "erekem");
if (!boss) { return false; }
if (AI_VALUE(Unit*, "current target") != boss) if (AI_VALUE(Unit*, "current target") != boss)
{ {
return Attack(boss); return Attack(boss);
@@ -19,6 +21,8 @@ bool AttackIchorGlobuleAction::Execute(Event event)
Unit* boss = AI_VALUE2(Unit*, "find target", "ichoron"); Unit* boss = AI_VALUE2(Unit*, "find target", "ichoron");
if (!boss) { return false; } if (!boss) { return false; }
Unit* currentTarget = AI_VALUE(Unit*, "current target");
// Tank prioritise boss if it's up // Tank prioritise boss if it's up
if (botAI->IsTank(bot) && !boss->HasAura(SPELL_DRAINED)) if (botAI->IsTank(bot) && !boss->HasAura(SPELL_DRAINED))
{ {
@@ -38,7 +42,6 @@ bool AttackIchorGlobuleAction::Execute(Event event)
Unit* unit = botAI->GetUnit(*i); Unit* unit = botAI->GetUnit(*i);
if (unit && unit->GetEntry() == NPC_ICHOR_GLOBULE) if (unit && unit->GetEntry() == NPC_ICHOR_GLOBULE)
{ {
Unit* currentTarget = AI_VALUE(Unit*, "current target");
// Check IDs here, NOT Unit* pointers: // Check IDs here, NOT Unit* pointers:
// Don't keep swapping between sentries. // Don't keep swapping between sentries.
// If we're already attacking one, don't retarget another // If we're already attacking one, don't retarget another
@@ -50,7 +53,7 @@ bool AttackIchorGlobuleAction::Execute(Event event)
} }
} }
// No ichor globules left alive, fall back to targeting boss // No ichor globules left alive, fall back to targeting boss
if (AI_VALUE(Unit*, "current target") != boss) if (currentTarget != boss)
{ {
return Attack(boss); return Attack(boss);
} }
@@ -62,6 +65,8 @@ bool AttackVoidSentryAction::Execute(Event event)
{ {
Unit* boss = AI_VALUE2(Unit*, "find target", "zuramat the obliterator"); Unit* boss = AI_VALUE2(Unit*, "find target", "zuramat the obliterator");
if (!boss) { return false; } if (!boss) { return false; }
Unit* currentTarget = AI_VALUE(Unit*, "current target");
// Target is not findable from threat table using AI_VALUE2(), // Target is not findable from threat table using AI_VALUE2(),
// therefore need to search manually for the unit name // therefore need to search manually for the unit name
@@ -73,7 +78,6 @@ bool AttackVoidSentryAction::Execute(Event event)
Unit* unit = botAI->GetUnit(*i); Unit* unit = botAI->GetUnit(*i);
if (unit && unit->GetEntry() == NPC_VOID_SENTRY) if (unit && unit->GetEntry() == NPC_VOID_SENTRY)
{ {
Unit* currentTarget = AI_VALUE(Unit*, "current target");
// Check IDs here, NOT Unit* pointers: // Check IDs here, NOT Unit* pointers:
// Don't keep swapping between sentries. // Don't keep swapping between sentries.
// If we're already attacking one, don't retarget another // If we're already attacking one, don't retarget another
@@ -85,7 +89,7 @@ bool AttackVoidSentryAction::Execute(Event event)
} }
} }
// No void sentries left alive, fall back to targeting boss // No void sentries left alive, fall back to targeting boss
if (AI_VALUE(Unit*, "current target") != boss) if (currentTarget != boss)
{ {
return Attack(boss); return Attack(boss);
} }

View File

@@ -8,8 +8,6 @@
#include "Playerbots.h" #include "Playerbots.h"
#include "VioletHoldTriggers.h" #include "VioletHoldTriggers.h"
// const Position NOVOS_PARTY_POSITION = Position(-378.852f, -760.349f, 28.587f);
class AttackErekemAction : public AttackAction class AttackErekemAction : public AttackAction
{ {
public: public:

View File

@@ -6,30 +6,42 @@
bool ErekemTargetTrigger::IsActive() bool ErekemTargetTrigger::IsActive()
{ {
return AI_VALUE2(Unit*, "find target", "erekem") && botAI->IsDps(bot); Unit* boss = AI_VALUE2(Unit*, "find target", "erekem");
if (!boss) { return false; }
return botAI->IsDps(bot);
} }
bool IchoronTargetTrigger::IsActive() bool IchoronTargetTrigger::IsActive()
{ {
return AI_VALUE2(Unit*, "find target", "ichoron") && !botAI->IsHeal(bot); Unit* boss = AI_VALUE2(Unit*, "find target", "ichoron");
if (!boss) { return false; }
return !botAI->IsHeal(bot);
} }
bool VoidShiftTrigger::IsActive() bool VoidShiftTrigger::IsActive()
{ {
Unit* boss = AI_VALUE2(Unit*, "find target", "zuramat the obliterator"); Unit* boss = AI_VALUE2(Unit*, "find target", "zuramat the obliterator");
return boss && bot->HasAura(SPELL_VOID_SHIFTED) && !botAI->IsHeal(bot); if (!boss) { return false; }
return bot->HasAura(SPELL_VOID_SHIFTED) && !botAI->IsHeal(bot);
} }
bool ShroudOfDarknessTrigger::IsActive() bool ShroudOfDarknessTrigger::IsActive()
{ {
Unit* boss = AI_VALUE2(Unit*, "find target", "zuramat the obliterator"); Unit* boss = AI_VALUE2(Unit*, "find target", "zuramat the obliterator");
return boss && boss->HasAura(SPELL_SHROUD_OF_DARKNESS); if (!boss) { return false; }
return boss->HasAura(SPELL_SHROUD_OF_DARKNESS);
} }
bool CyanigosaPositioningTrigger::IsActive() bool CyanigosaPositioningTrigger::IsActive()
{ {
Unit* boss = AI_VALUE2(Unit*, "find target", "cyanigosa"); Unit* boss = AI_VALUE2(Unit*, "find target", "cyanigosa");
if (!boss) { return false; }
// Include healers here for now, otherwise they stand in things // Include healers here for now, otherwise they stand in things
return boss && !botAI->IsTank(bot) && !botAI->IsRangedDps(bot); return !botAI->IsTank(bot) && !botAI->IsRangedDps(bot);
// return boss && botAI->IsMelee(bot) && !botAI->IsTank(bot); // return botAI->IsMelee(bot) && !botAI->IsTank(bot);
} }