mirror of
https://github.com/mod-playerbots/mod-playerbots.git
synced 2026-01-13 09:07:19 +00:00
Prot warriors cast vigilance when in a group (#825)
* Add Vigilance * Vigilance * Update WarriorTriggers.h * Update TankWarriorStrategy.cpp * Update WarriorAiObjectContext.cpp * Update WarriorTriggers.cpp * Update WarriorTriggers.h * Update WarriorTriggers.cpp Check for existence of Vigilance in raid already * Update WarriorActions.cpp Check for existence of Vigilance in raid already Apply to tanks, then highest gearscore DPS. * Update WarriorActions.cpp * Update WarriorActions.cpp * Update WarriorActions.cpp * Update WarriorActions.cpp * Added logout Bots keep assigning it to me and not maintank? Added logging to clarify * Update WarriorActions.cpp * Update WarriorActions.cpp * Update WarriorActions.cpp * Update WarriorActions.cpp * Update WarriorTriggers.cpp * Update WarriorTriggers.cpp * Update WarriorTriggers.cpp * Update WarriorActions.cpp * Update WarriorActions.cpp * Update WarriorTriggers.cpp * Update WarriorActions.cpp * Update WarriorActions.cpp * Removed Logs * Removed logs * Added check for spell in trigger * Update WarriorTriggers.cpp * !member->IsAlive() * !member->IsAlive()
This commit is contained in:
@@ -22,6 +22,7 @@ public:
|
|||||||
creators["heroic throw taunt"] = &heroic_throw_taunt;
|
creators["heroic throw taunt"] = &heroic_throw_taunt;
|
||||||
creators["taunt"] = &taunt;
|
creators["taunt"] = &taunt;
|
||||||
creators["taunt spell"] = &taunt;
|
creators["taunt spell"] = &taunt;
|
||||||
|
creators["vigilance"] = &vigilance;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -41,6 +42,14 @@ private:
|
|||||||
/*A*/ NextAction::array(0, new NextAction("heroic throw taunt"), nullptr),
|
/*A*/ NextAction::array(0, new NextAction("heroic throw taunt"), nullptr),
|
||||||
/*C*/ nullptr);
|
/*C*/ nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static ActionNode* vigilance(PlayerbotAI* botAI)
|
||||||
|
{
|
||||||
|
return new ActionNode("vigilance",
|
||||||
|
/*P*/ nullptr,
|
||||||
|
/*A*/ nullptr,
|
||||||
|
/*C*/ nullptr);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
TankWarriorStrategy::TankWarriorStrategy(PlayerbotAI* botAI) : GenericWarriorStrategy(botAI)
|
TankWarriorStrategy::TankWarriorStrategy(PlayerbotAI* botAI) : GenericWarriorStrategy(botAI)
|
||||||
@@ -59,6 +68,9 @@ void TankWarriorStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
|||||||
{
|
{
|
||||||
GenericWarriorStrategy::InitTriggers(triggers);
|
GenericWarriorStrategy::InitTriggers(triggers);
|
||||||
|
|
||||||
|
triggers.push_back(new TriggerNode(
|
||||||
|
"vigilance",
|
||||||
|
NextAction::array(0, new NextAction("vigilance", ACTION_HIGH + 7), nullptr)));
|
||||||
triggers.push_back(
|
triggers.push_back(
|
||||||
new TriggerNode("enemy out of melee", NextAction::array(0, new NextAction("heroic throw", ACTION_MOVE + 11),
|
new TriggerNode("enemy out of melee", NextAction::array(0, new NextAction("heroic throw", ACTION_MOVE + 11),
|
||||||
new NextAction("charge", ACTION_MOVE + 10), nullptr)));
|
new NextAction("charge", ACTION_MOVE + 10), nullptr)));
|
||||||
|
|||||||
@@ -12,3 +12,92 @@ bool CastSunderArmorAction::isUseful()
|
|||||||
Aura* aura = botAI->GetAura("sunder armor", GetTarget(), false, true);
|
Aura* aura = botAI->GetAura("sunder armor", GetTarget(), false, true);
|
||||||
return !aura || aura->GetStackAmount() < 5 || aura->GetDuration() <= 6000;
|
return !aura || aura->GetStackAmount() < 5 || aura->GetDuration() <= 6000;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Value<Unit*>* CastVigilanceAction::GetTargetValue()
|
||||||
|
{
|
||||||
|
Group* group = bot->GetGroup();
|
||||||
|
if (!group)
|
||||||
|
{
|
||||||
|
return new ManualSetValue<Unit*>(botAI, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
Player* currentVigilanceTarget = nullptr;
|
||||||
|
Player* mainTank = nullptr;
|
||||||
|
Player* assistTank1 = nullptr;
|
||||||
|
Player* assistTank2 = nullptr;
|
||||||
|
Player* highestGearScorePlayer = nullptr;
|
||||||
|
uint32 highestGearScore = 0;
|
||||||
|
|
||||||
|
// Iterate once through the group to gather all necessary information
|
||||||
|
for (GroupReference* ref = group->GetFirstMember(); ref; ref = ref->next())
|
||||||
|
{
|
||||||
|
Player* member = ref->GetSource();
|
||||||
|
if (!member || member == bot || !member->IsAlive())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// Check if member has Vigilance applied by the bot
|
||||||
|
if (!currentVigilanceTarget && botAI->HasAura("vigilance", member, false, true))
|
||||||
|
{
|
||||||
|
currentVigilanceTarget = member;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Identify Main Tank
|
||||||
|
if (!mainTank && botAI->IsMainTank(member))
|
||||||
|
{
|
||||||
|
mainTank = member;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Identify Assist Tanks
|
||||||
|
if (assistTank1 == nullptr && botAI->IsAssistTankOfIndex(member, 0))
|
||||||
|
{
|
||||||
|
assistTank1 = member;
|
||||||
|
}
|
||||||
|
else if (assistTank2 == nullptr && botAI->IsAssistTankOfIndex(member, 1))
|
||||||
|
{
|
||||||
|
assistTank2 = member;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Determine Highest Gear Score
|
||||||
|
uint32 gearScore = botAI->GetEquipGearScore(member, false, false);
|
||||||
|
if (gearScore > highestGearScore)
|
||||||
|
{
|
||||||
|
highestGearScore = gearScore;
|
||||||
|
highestGearScorePlayer = member;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Determine the highest-priority target
|
||||||
|
Player* highestPriorityTarget = mainTank ? mainTank :
|
||||||
|
(assistTank1 ? assistTank1 :
|
||||||
|
(assistTank2 ? assistTank2 : highestGearScorePlayer));
|
||||||
|
|
||||||
|
// If no valid target, return nullptr
|
||||||
|
if (!highestPriorityTarget)
|
||||||
|
{
|
||||||
|
return new ManualSetValue<Unit*>(botAI, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the current target is already the highest-priority target, do nothing
|
||||||
|
if (currentVigilanceTarget == highestPriorityTarget)
|
||||||
|
{
|
||||||
|
return new ManualSetValue<Unit*>(botAI, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Assign the new target
|
||||||
|
Unit* targetUnit = highestPriorityTarget->ToUnit();
|
||||||
|
if (targetUnit)
|
||||||
|
{
|
||||||
|
return new ManualSetValue<Unit*>(botAI, targetUnit);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new ManualSetValue<Unit*>(botAI, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CastVigilanceAction::Execute(Event event)
|
||||||
|
{
|
||||||
|
Unit* target = GetTarget();
|
||||||
|
if (!target || target == bot)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return botAI->CastSpell("vigilance", target);
|
||||||
|
}
|
||||||
|
|||||||
@@ -135,4 +135,13 @@ public:
|
|||||||
bool isUseful() override;
|
bool isUseful() override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class CastVigilanceAction : public BuffOnPartyAction
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CastVigilanceAction(PlayerbotAI* botAI) : BuffOnPartyAction(botAI, "vigilance") {}
|
||||||
|
|
||||||
|
Value<Unit*>* GetTargetValue() override;
|
||||||
|
bool Execute(Event event) override;
|
||||||
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -98,6 +98,8 @@ public:
|
|||||||
creators["intercept and far enemy"] = &WarriorTriggerFactoryInternal::intercept_and_far_enemy;
|
creators["intercept and far enemy"] = &WarriorTriggerFactoryInternal::intercept_and_far_enemy;
|
||||||
creators["intercept and rage"] = &WarriorTriggerFactoryInternal::intercept_and_rage;
|
creators["intercept and rage"] = &WarriorTriggerFactoryInternal::intercept_and_rage;
|
||||||
// creators["slam"] = &WarriorTriggerFactoryInternal::slam;
|
// creators["slam"] = &WarriorTriggerFactoryInternal::slam;
|
||||||
|
|
||||||
|
creators["vigilance"] = &WarriorTriggerFactoryInternal::vigilance;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -166,6 +168,8 @@ private:
|
|||||||
static Trigger* revenge(PlayerbotAI* botAI) { return new RevengeAvailableTrigger(botAI); }
|
static Trigger* revenge(PlayerbotAI* botAI) { return new RevengeAvailableTrigger(botAI); }
|
||||||
static Trigger* sunder_armor(PlayerbotAI* botAI) { return new SunderArmorDebuffTrigger(botAI); }
|
static Trigger* sunder_armor(PlayerbotAI* botAI) { return new SunderArmorDebuffTrigger(botAI); }
|
||||||
// static Trigger* slam(PlayerbotAI* ai) { return new SlamTrigger(ai); }
|
// static Trigger* slam(PlayerbotAI* ai) { return new SlamTrigger(ai); }
|
||||||
|
|
||||||
|
static Trigger* vigilance(PlayerbotAI* botAI) { return new VigilanceTrigger(botAI); }
|
||||||
};
|
};
|
||||||
|
|
||||||
class WarriorAiObjectContextInternal : public NamedObjectContext<Action>
|
class WarriorAiObjectContextInternal : public NamedObjectContext<Action>
|
||||||
@@ -235,6 +239,7 @@ public:
|
|||||||
creators["heroic throw"] = &WarriorAiObjectContextInternal::heroic_throw;
|
creators["heroic throw"] = &WarriorAiObjectContextInternal::heroic_throw;
|
||||||
creators["heroic throw on snare target"] = &WarriorAiObjectContextInternal::heroic_throw_on_snare_target;
|
creators["heroic throw on snare target"] = &WarriorAiObjectContextInternal::heroic_throw_on_snare_target;
|
||||||
creators["shattering throw"] = &WarriorAiObjectContextInternal::shattering_throw;
|
creators["shattering throw"] = &WarriorAiObjectContextInternal::shattering_throw;
|
||||||
|
creators["vigilance"] = &WarriorAiObjectContextInternal::vigilance;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -304,6 +309,7 @@ private:
|
|||||||
static Action* heroic_throw_on_snare_target(PlayerbotAI* botAI) { return new CastHeroicThrowSnareAction(botAI); }
|
static Action* heroic_throw_on_snare_target(PlayerbotAI* botAI) { return new CastHeroicThrowSnareAction(botAI); }
|
||||||
static Action* heroic_throw(PlayerbotAI* botAI) { return new CastHeroicThrowAction(botAI); }
|
static Action* heroic_throw(PlayerbotAI* botAI) { return new CastHeroicThrowAction(botAI); }
|
||||||
static Action* bladestorm(PlayerbotAI* botAI) { return new CastBladestormAction(botAI); }
|
static Action* bladestorm(PlayerbotAI* botAI) { return new CastBladestormAction(botAI); }
|
||||||
|
static Action* vigilance(PlayerbotAI* botAI) { return new CastVigilanceAction(botAI); }
|
||||||
};
|
};
|
||||||
|
|
||||||
WarriorAiObjectContext::WarriorAiObjectContext(PlayerbotAI* botAI) : AiObjectContext(botAI)
|
WarriorAiObjectContext::WarriorAiObjectContext(PlayerbotAI* botAI) : AiObjectContext(botAI)
|
||||||
|
|||||||
@@ -12,3 +12,75 @@ bool BloodrageBuffTrigger::IsActive()
|
|||||||
return AI_VALUE2(uint8, "health", "self target") >= sPlayerbotAIConfig->mediumHealth &&
|
return AI_VALUE2(uint8, "health", "self target") >= sPlayerbotAIConfig->mediumHealth &&
|
||||||
AI_VALUE2(uint8, "rage", "self target") < 20;
|
AI_VALUE2(uint8, "rage", "self target") < 20;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool VigilanceTrigger::IsActive()
|
||||||
|
{
|
||||||
|
if (!bot->HasSpell(50720))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Group* group = bot->GetGroup();
|
||||||
|
if (!group)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Player* currentVigilanceTarget = nullptr;
|
||||||
|
Player* mainTank = nullptr;
|
||||||
|
Player* assistTank1 = nullptr;
|
||||||
|
Player* assistTank2 = nullptr;
|
||||||
|
Player* highestGearScorePlayer = nullptr;
|
||||||
|
uint32 highestGearScore = 0;
|
||||||
|
|
||||||
|
// Iterate once through the group to gather all necessary information
|
||||||
|
for (GroupReference* ref = group->GetFirstMember(); ref; ref = ref->next())
|
||||||
|
{
|
||||||
|
Player* member = ref->GetSource();
|
||||||
|
if (!member || member == bot || !member->IsAlive())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// Check if member has Vigilance applied by the bot
|
||||||
|
if (!currentVigilanceTarget && botAI->HasAura("vigilance", member, false, true))
|
||||||
|
{
|
||||||
|
currentVigilanceTarget = member;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Identify Main Tank
|
||||||
|
if (!mainTank && botAI->IsMainTank(member))
|
||||||
|
{
|
||||||
|
mainTank = member;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Identify Assist Tanks
|
||||||
|
if (assistTank1 == nullptr && botAI->IsAssistTankOfIndex(member, 0))
|
||||||
|
{
|
||||||
|
assistTank1 = member;
|
||||||
|
}
|
||||||
|
else if (assistTank2 == nullptr && botAI->IsAssistTankOfIndex(member, 1))
|
||||||
|
{
|
||||||
|
assistTank2 = member;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Determine Highest Gear Score
|
||||||
|
uint32 gearScore = botAI->GetEquipGearScore(member, false, false);
|
||||||
|
if (gearScore > highestGearScore)
|
||||||
|
{
|
||||||
|
highestGearScore = gearScore;
|
||||||
|
highestGearScorePlayer = member;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Determine the highest-priority target
|
||||||
|
Player* highestPriorityTarget = mainTank ? mainTank :
|
||||||
|
(assistTank1 ? assistTank1 :
|
||||||
|
(assistTank2 ? assistTank2 : highestGearScorePlayer));
|
||||||
|
|
||||||
|
// Trigger if no Vigilance is active or the current target is not the highest-priority target
|
||||||
|
if (!currentVigilanceTarget || currentVigilanceTarget != highestPriorityTarget)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false; // No need to reassign Vigilance
|
||||||
|
}
|
||||||
|
|||||||
@@ -63,6 +63,14 @@ public:
|
|||||||
RendDebuffTrigger(PlayerbotAI* botAI) : DebuffTrigger(botAI, "rend", 1, true) {}
|
RendDebuffTrigger(PlayerbotAI* botAI) : DebuffTrigger(botAI, "rend", 1, true) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class VigilanceTrigger : public BuffOnPartyTrigger
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
VigilanceTrigger(PlayerbotAI* botAI) : BuffOnPartyTrigger(botAI, "vigilance") {}
|
||||||
|
|
||||||
|
bool IsActive() override;
|
||||||
|
};
|
||||||
|
|
||||||
// class SlamTrigger : public HasAuraTrigger
|
// class SlamTrigger : public HasAuraTrigger
|
||||||
// {
|
// {
|
||||||
// public:
|
// public:
|
||||||
|
|||||||
Reference in New Issue
Block a user