mirror of
https://github.com/mod-playerbots/mod-playerbots
synced 2025-11-29 15:58:20 +08:00
Merge branch 'master' into move_backwards
This commit is contained in:
@@ -12,8 +12,8 @@ class WotlkDungeonOccActionContext : public NamedObjectContext<Action>
|
||||
creators["avoid unstable sphere"] = &WotlkDungeonOccActionContext::avoid_unstable_sphere;
|
||||
creators["mount drake"] = &WotlkDungeonOccActionContext::mount_drake;
|
||||
creators["dismount drake"] = &WotlkDungeonOccActionContext::dismount_drake;
|
||||
creators["fly drake"] = &WotlkDungeonOccActionContext::fly_drake;
|
||||
creators["drake attack"] = &WotlkDungeonOccActionContext::drake_attack;
|
||||
creators["occ fly drake"] = &WotlkDungeonOccActionContext::occ_fly_drake;
|
||||
creators["occ drake attack"] = &WotlkDungeonOccActionContext::occ_drake_attack;
|
||||
creators["avoid arcane explosion"] = &WotlkDungeonOccActionContext::avoid_arcane_explosion;
|
||||
creators["time bomb spread"] = &WotlkDungeonOccActionContext::time_bomb_spread;
|
||||
}
|
||||
@@ -21,8 +21,8 @@ class WotlkDungeonOccActionContext : public NamedObjectContext<Action>
|
||||
static Action* avoid_unstable_sphere(PlayerbotAI* ai) { return new AvoidUnstableSphereAction(ai); }
|
||||
static Action* mount_drake(PlayerbotAI* ai) { return new MountDrakeAction(ai); }
|
||||
static Action* dismount_drake(PlayerbotAI* ai) { return new DismountDrakeAction(ai); }
|
||||
static Action* fly_drake(PlayerbotAI* ai) { return new OccFlyDrakeAction(ai); }
|
||||
static Action* drake_attack(PlayerbotAI* ai) { return new OccDrakeAttackAction(ai); }
|
||||
static Action* occ_fly_drake(PlayerbotAI* ai) { return new OccFlyDrakeAction(ai); }
|
||||
static Action* occ_drake_attack(PlayerbotAI* ai) { return new OccDrakeAttackAction(ai); }
|
||||
static Action* avoid_arcane_explosion(PlayerbotAI* ai) { return new AvoidArcaneExplosionAction(ai); }
|
||||
static Action* time_bomb_spread(PlayerbotAI* ai) { return new TimeBombSpreadAction(ai); }
|
||||
};
|
||||
|
||||
@@ -15,9 +15,9 @@ void WotlkDungeonOccStrategy::InitTriggers(std::vector<TriggerNode*> &triggers)
|
||||
triggers.push_back(new TriggerNode("drake dismount",
|
||||
NextAction::array(0, new NextAction("dismount drake", ACTION_RAID + 5), nullptr)));
|
||||
triggers.push_back(new TriggerNode("group flying",
|
||||
NextAction::array(0, new NextAction("fly drake", ACTION_NORMAL + 1), nullptr)));
|
||||
NextAction::array(0, new NextAction("occ fly drake", ACTION_NORMAL + 1), nullptr)));
|
||||
triggers.push_back(new TriggerNode("drake combat",
|
||||
NextAction::array(0, new NextAction("drake attack", ACTION_NORMAL + 5), nullptr)));
|
||||
NextAction::array(0, new NextAction("occ drake attack", ACTION_NORMAL + 5), nullptr)));
|
||||
|
||||
// Varos Cloudstrider
|
||||
// Seems to be no way to identify the marked cores, may need to hook boss AI..
|
||||
|
||||
@@ -14,8 +14,8 @@ public:
|
||||
creators["malygos target"] = &RaidEoEActionContext::target;
|
||||
// creators["pull power spark"] = &RaidEoEActionContext::pull_power_spark;
|
||||
// creators["kill power spark"] = &RaidEoEActionContext::kill_power_spark;
|
||||
creators["fly drake"] = &RaidEoEActionContext::fly_drake;
|
||||
creators["drake attack"] = &RaidEoEActionContext::drake_attack;
|
||||
creators["eoe fly drake"] = &RaidEoEActionContext::eoe_fly_drake;
|
||||
creators["eoe drake attack"] = &RaidEoEActionContext::eoe_drake_attack;
|
||||
}
|
||||
|
||||
private:
|
||||
@@ -23,8 +23,8 @@ private:
|
||||
static Action* target(PlayerbotAI* ai) { return new MalygosTargetAction(ai); }
|
||||
// static Action* pull_power_spark(PlayerbotAI* ai) { return new PullPowerSparkAction(ai); }
|
||||
// static Action* kill_power_spark(PlayerbotAI* ai) { return new KillPowerSparkAction(ai); }
|
||||
static Action* fly_drake(PlayerbotAI* ai) { return new EoEFlyDrakeAction(ai); }
|
||||
static Action* drake_attack(PlayerbotAI* ai) { return new EoEDrakeAttackAction(ai); }
|
||||
static Action* eoe_fly_drake(PlayerbotAI* ai) { return new EoEFlyDrakeAction(ai); }
|
||||
static Action* eoe_drake_attack(PlayerbotAI* ai) { return new EoEDrakeAttackAction(ai); }
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -14,9 +14,9 @@ void RaidEoEStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||
// NextAction::array(0, new NextAction("kill power spark", ACTION_RAID + 3), nullptr)));
|
||||
|
||||
triggers.push_back(new TriggerNode("group flying",
|
||||
NextAction::array(0, new NextAction("fly drake", ACTION_NORMAL + 1), nullptr)));
|
||||
NextAction::array(0, new NextAction("eoe fly drake", ACTION_NORMAL + 1), nullptr)));
|
||||
triggers.push_back(new TriggerNode("drake combat",
|
||||
NextAction::array(0, new NextAction("drake attack", ACTION_NORMAL + 5), nullptr)));
|
||||
NextAction::array(0, new NextAction("eoe drake attack", ACTION_NORMAL + 5), nullptr)));
|
||||
}
|
||||
|
||||
void RaidEoEStrategy::InitMultipliers(std::vector<Multiplier*> &multipliers)
|
||||
|
||||
@@ -44,40 +44,64 @@ void ArmsWarriorStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||
GenericWarriorStrategy::InitTriggers(triggers);
|
||||
|
||||
triggers.push_back(new TriggerNode("enemy out of melee",
|
||||
NextAction::array(0, new NextAction("charge", ACTION_MOVE + 9), nullptr)));
|
||||
triggers.push_back(new TriggerNode(
|
||||
"battle stance", NextAction::array(0, new NextAction("battle stance", ACTION_HIGH + 9), nullptr)));
|
||||
NextAction::array(0, new NextAction("charge", ACTION_MOVE + 10), nullptr)));
|
||||
|
||||
triggers.push_back(new TriggerNode("battle stance",
|
||||
NextAction::array(0, new NextAction("battle stance", ACTION_HIGH + 10), nullptr)));
|
||||
|
||||
triggers.push_back(new TriggerNode("battle shout",
|
||||
NextAction::array(0, new NextAction("battle shout", ACTION_HIGH + 8), nullptr)));
|
||||
triggers.push_back(new TriggerNode(
|
||||
"mortal strike", NextAction::array(0, new NextAction("mortal strike", ACTION_HIGH + 1), nullptr)));
|
||||
NextAction::array(0, new NextAction("battle shout", ACTION_HIGH + 9), nullptr)));
|
||||
|
||||
triggers.push_back(new TriggerNode("rend",
|
||||
NextAction::array(0, new NextAction("rend", ACTION_HIGH + 8), nullptr)));
|
||||
|
||||
triggers.push_back(new TriggerNode("rend on attacker",
|
||||
NextAction::array(0, new NextAction("rend on attacker", ACTION_HIGH + 8), nullptr)));
|
||||
|
||||
triggers.push_back(new TriggerNode("mortal strike",
|
||||
NextAction::array(0, new NextAction("mortal strike", ACTION_HIGH + 3), nullptr)));
|
||||
|
||||
triggers.push_back(new TriggerNode("target critical health",
|
||||
NextAction::array(0, new NextAction("execute", ACTION_HIGH + 4), nullptr)));
|
||||
triggers.push_back(
|
||||
new TriggerNode("sudden death", NextAction::array(0, new NextAction("execute", ACTION_HIGH + 4), nullptr)));
|
||||
triggers.push_back(
|
||||
new TriggerNode("hamstring", NextAction::array(0, new NextAction("piercing howl", ACTION_HIGH), nullptr)));
|
||||
triggers.push_back(
|
||||
new TriggerNode("overpower", NextAction::array(0, new NextAction("overpower", ACTION_HIGH + 3), nullptr)));
|
||||
NextAction::array(0, new NextAction("execute", ACTION_HIGH + 5), nullptr)));
|
||||
|
||||
triggers.push_back(new TriggerNode("sudden death",
|
||||
NextAction::array(0, new NextAction("execute", ACTION_HIGH + 5), nullptr)));
|
||||
|
||||
triggers.push_back(new TriggerNode("hamstring",
|
||||
NextAction::array(0, new NextAction("piercing howl", ACTION_HIGH), nullptr)));
|
||||
|
||||
triggers.push_back(new TriggerNode("overpower",
|
||||
NextAction::array(0, new NextAction("overpower", ACTION_HIGH + 4), nullptr)));
|
||||
|
||||
triggers.push_back(new TriggerNode("taste for blood",
|
||||
NextAction::array(0, new NextAction("overpower", ACTION_HIGH + 3), nullptr)));
|
||||
triggers.push_back(new TriggerNode(
|
||||
"victory rush", NextAction::array(0, new NextAction("victory rush", ACTION_INTERRUPT), nullptr)));
|
||||
triggers.push_back(new TriggerNode(
|
||||
"high rage available", NextAction::array(0, new NextAction("heroic strike", ACTION_HIGH + 10), nullptr)));
|
||||
triggers.push_back(new TriggerNode("medium rage available",
|
||||
NextAction::array(0, new NextAction("slam", ACTION_HIGH + 1),
|
||||
new NextAction("thunder clap", ACTION_HIGH),
|
||||
nullptr)));
|
||||
NextAction::array(0, new NextAction("overpower", ACTION_HIGH + 4), nullptr)));
|
||||
|
||||
triggers.push_back(new TriggerNode("victory rush",
|
||||
NextAction::array(0, new NextAction("victory rush", ACTION_INTERRUPT), nullptr)));
|
||||
|
||||
triggers.push_back(new TriggerNode("high rage available",
|
||||
NextAction::array(0, new NextAction("heroic strike", ACTION_HIGH),
|
||||
new NextAction("slam", ACTION_HIGH + 1),
|
||||
nullptr)));
|
||||
// triggers.push_back(new TriggerNode("medium rage available",
|
||||
// NextAction::array(0, new NextAction("slam", ACTION_HIGH + 1),
|
||||
// new NextAction("thunder clap", ACTION_HIGH),
|
||||
// nullptr)));
|
||||
triggers.push_back(
|
||||
new TriggerNode("bloodrage", NextAction::array(0, new NextAction("bloodrage", ACTION_HIGH + 2), nullptr)));
|
||||
|
||||
triggers.push_back(
|
||||
new TriggerNode("death wish", NextAction::array(0, new NextAction("death wish", ACTION_HIGH + 2), nullptr)));
|
||||
triggers.push_back(new TriggerNode("rend", NextAction::array(0, new NextAction("rend", ACTION_HIGH + 5), nullptr)));
|
||||
triggers.push_back(new TriggerNode(
|
||||
"rend on attacker", NextAction::array(0, new NextAction("rend on attacker", ACTION_HIGH + 5), nullptr)));
|
||||
|
||||
triggers.push_back(new TriggerNode(
|
||||
"critical health", NextAction::array(0, new NextAction("intimidating shout", ACTION_EMERGENCY), nullptr)));
|
||||
triggers.push_back(new TriggerNode("medium aoe",
|
||||
NextAction::array(0, new NextAction("thunder clap", ACTION_HIGH + 2), nullptr)));
|
||||
|
||||
// triggers.push_back(new TriggerNode("medium aoe",
|
||||
// NextAction::array(0, new NextAction("thunder clap", ACTION_HIGH + 2), nullptr)));
|
||||
/*
|
||||
triggers.push_back(new TriggerNode("medium aoe",
|
||||
NextAction::array(0, new NextAction("sweeping strikes", ACTION_HIGH + 7),
|
||||
new NextAction("bladestorm", ACTION_HIGH + 6),
|
||||
nullptr)));
|
||||
*/
|
||||
}
|
||||
|
||||
@@ -68,12 +68,14 @@ void FuryWarriorStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||
// snare target", ACTION_HIGH), nullptr)));
|
||||
triggers.push_back(
|
||||
new TriggerNode("bloodthirst", NextAction::array(0, new NextAction("bloodthirst", ACTION_HIGH + 7), nullptr)));
|
||||
triggers.push_back(
|
||||
new TriggerNode("whirlwind", NextAction::array(0, new NextAction("whirlwind", ACTION_HIGH + 6), nullptr)));
|
||||
triggers.push_back(
|
||||
new TriggerNode("instant slam", NextAction::array(0, new NextAction("slam", ACTION_HIGH + 5), nullptr)));
|
||||
triggers.push_back(
|
||||
new TriggerNode("bloodrage", NextAction::array(0, new NextAction("bloodrage", ACTION_HIGH + 2), nullptr)));
|
||||
triggers.push_back(new TriggerNode("medium rage available",
|
||||
NextAction::array(0, new NextAction("heroic strike", ACTION_HIGH + 1), NULL)));
|
||||
NextAction::array(0, new NextAction("heroic strike", ACTION_DEFAULT + 0.1f), NULL)));
|
||||
// triggers.push_back(new TriggerNode("berserker rage", NextAction::array(0, new NextAction("berserker rage",
|
||||
// ACTION_HIGH + 2), nullptr))); triggers.push_back(new TriggerNode("light aoe", NextAction::array(0,
|
||||
// new NextAction("whirlwind", ACTION_HIGH + 2),
|
||||
|
||||
@@ -47,11 +47,16 @@ void WarrirorAoeStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||
// triggers.push_back(new TriggerNode("thunder clap on snare target", NextAction::array(0, new NextAction("thunder
|
||||
// clap on snare target", ACTION_HIGH + 3), nullptr))); triggers.push_back(new TriggerNode("thunder clap",
|
||||
// NextAction::array(0, new NextAction("thunder clap", ACTION_HIGH + 10), nullptr)));
|
||||
/* triggers.push_back(new TriggerNode(
|
||||
"medium aoe", NextAction::array(0, new NextAction("sweeping strikes", ACTION_HIGH + 7),
|
||||
new NextAction("bladestorm", ACTION_HIGH + 6),
|
||||
nullptr)));
|
||||
*/
|
||||
triggers.push_back(new TriggerNode(
|
||||
"light aoe", NextAction::array(0, new NextAction("thunder clap", ACTION_HIGH + 5),
|
||||
"light aoe", NextAction::array(0, new NextAction("sweeping strikes", ACTION_HIGH + 7),
|
||||
new NextAction("bladestorm", ACTION_HIGH + 6),
|
||||
new NextAction("thunder clap", ACTION_HIGH + 5),
|
||||
new NextAction("shockwave", ACTION_HIGH + 4),
|
||||
new NextAction("sweeping strikes", ACTION_HIGH + 3),
|
||||
new NextAction("bladestorm", ACTION_HIGH + 3),
|
||||
// new NextAction("whirlwind", ACTION_HIGH + 2),
|
||||
new NextAction("demoralizing shout without life time check", ACTION_HIGH + 1),
|
||||
new NextAction("cleave", ACTION_HIGH), nullptr)));
|
||||
@@ -60,4 +65,5 @@ void WarrirorAoeStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||
NextAction::array(0, new NextAction("shockwave on snare target", ACTION_HIGH + 5), nullptr)));
|
||||
// triggers.push_back(new TriggerNode("high rage available", NextAction::array(0, new NextAction("whirlwind",
|
||||
// ACTION_HIGH + 10), nullptr)));
|
||||
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@ public:
|
||||
creators["heroic throw taunt"] = &heroic_throw_taunt;
|
||||
creators["taunt"] = &taunt;
|
||||
creators["taunt spell"] = &taunt;
|
||||
creators["vigilance"] = &vigilance;
|
||||
}
|
||||
|
||||
private:
|
||||
@@ -41,6 +42,14 @@ private:
|
||||
/*A*/ NextAction::array(0, new NextAction("heroic throw taunt"), nullptr),
|
||||
/*C*/ nullptr);
|
||||
}
|
||||
|
||||
static ActionNode* vigilance(PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode("vigilance",
|
||||
/*P*/ nullptr,
|
||||
/*A*/ nullptr,
|
||||
/*C*/ nullptr);
|
||||
}
|
||||
};
|
||||
|
||||
TankWarriorStrategy::TankWarriorStrategy(PlayerbotAI* botAI) : GenericWarriorStrategy(botAI)
|
||||
@@ -59,6 +68,9 @@ void TankWarriorStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||
{
|
||||
GenericWarriorStrategy::InitTriggers(triggers);
|
||||
|
||||
triggers.push_back(new TriggerNode(
|
||||
"vigilance",
|
||||
NextAction::array(0, new NextAction("vigilance", ACTION_HIGH + 7), nullptr)));
|
||||
triggers.push_back(
|
||||
new TriggerNode("enemy out of melee", NextAction::array(0, new NextAction("heroic throw", ACTION_MOVE + 11),
|
||||
new NextAction("charge", ACTION_MOVE + 10), nullptr)));
|
||||
@@ -77,7 +89,9 @@ void TankWarriorStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||
triggers.push_back(
|
||||
new TriggerNode("sunder armor", NextAction::array(0, new NextAction("devastate", ACTION_HIGH + 2), nullptr)));
|
||||
triggers.push_back(new TriggerNode("medium rage available",
|
||||
NextAction::array(0, new NextAction("shield slam", ACTION_HIGH + 1), nullptr)));
|
||||
NextAction::array(0, new NextAction("shield slam", ACTION_HIGH + 2),
|
||||
new NextAction("devastate", ACTION_HIGH + 1),
|
||||
nullptr)));
|
||||
triggers.push_back(new TriggerNode(
|
||||
"shield block", NextAction::array(0, new NextAction("shield block", ACTION_INTERRUPT + 1), nullptr)));
|
||||
triggers.push_back(
|
||||
@@ -117,7 +131,7 @@ void TankWarriorStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||
triggers.push_back(new TriggerNode("protect party member",
|
||||
NextAction::array(0, new NextAction("intervene", ACTION_EMERGENCY), nullptr)));
|
||||
triggers.push_back(new TriggerNode(
|
||||
"high rage available", NextAction::array(0, new NextAction("heroic strike", ACTION_HIGH + 1), nullptr)));
|
||||
"high rage available", NextAction::array(0, new NextAction("heroic strike", ACTION_HIGH), nullptr)));
|
||||
triggers.push_back(new TriggerNode("medium rage available",
|
||||
NextAction::array(0, new NextAction("thunder clap", ACTION_HIGH + 1), nullptr)));
|
||||
}
|
||||
|
||||
@@ -12,3 +12,92 @@ bool CastSunderArmorAction::isUseful()
|
||||
Aura* aura = botAI->GetAura("sunder armor", GetTarget(), false, true);
|
||||
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;
|
||||
};
|
||||
|
||||
class CastVigilanceAction : public BuffOnPartyAction
|
||||
{
|
||||
public:
|
||||
CastVigilanceAction(PlayerbotAI* botAI) : BuffOnPartyAction(botAI, "vigilance") {}
|
||||
|
||||
Value<Unit*>* GetTargetValue() override;
|
||||
bool Execute(Event event) override;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -78,6 +78,7 @@ public:
|
||||
creators["thunder clap on snare target"] = &WarriorTriggerFactoryInternal::thunder_clap_on_snare_target;
|
||||
creators["thunder clap"] = &WarriorTriggerFactoryInternal::thunder_clap;
|
||||
creators["bloodthirst"] = &WarriorTriggerFactoryInternal::bloodthirst;
|
||||
creators["whirlwind"] = &WarriorTriggerFactoryInternal::whirlwind;
|
||||
creators["berserker rage"] = &WarriorTriggerFactoryInternal::berserker_rage;
|
||||
creators["pummel on enemy healer"] = &WarriorTriggerFactoryInternal::pummel_on_enemy_healer;
|
||||
creators["pummel"] = &WarriorTriggerFactoryInternal::pummel;
|
||||
@@ -98,6 +99,8 @@ public:
|
||||
creators["intercept and far enemy"] = &WarriorTriggerFactoryInternal::intercept_and_far_enemy;
|
||||
creators["intercept and rage"] = &WarriorTriggerFactoryInternal::intercept_and_rage;
|
||||
// creators["slam"] = &WarriorTriggerFactoryInternal::slam;
|
||||
|
||||
creators["vigilance"] = &WarriorTriggerFactoryInternal::vigilance;
|
||||
}
|
||||
|
||||
private:
|
||||
@@ -157,6 +160,7 @@ private:
|
||||
}
|
||||
static Trigger* berserker_rage(PlayerbotAI* botAI) { return new BerserkerRageBuffTrigger(botAI); }
|
||||
static Trigger* bloodthirst(PlayerbotAI* botAI) { return new BloodthirstBuffTrigger(botAI); }
|
||||
static Trigger* whirlwind(PlayerbotAI* botAI) { return new WhirlwindTrigger(botAI); }
|
||||
static Trigger* thunder_clap_on_snare_target(PlayerbotAI* botAI) { return new ThunderClapSnareTrigger(botAI); }
|
||||
static Trigger* thunder_clap(PlayerbotAI* botAI) { return new ThunderClapTrigger(botAI); }
|
||||
static Trigger* mortal_strike(PlayerbotAI* botAI) { return new MortalStrikeDebuffTrigger(botAI); }
|
||||
@@ -166,6 +170,8 @@ private:
|
||||
static Trigger* revenge(PlayerbotAI* botAI) { return new RevengeAvailableTrigger(botAI); }
|
||||
static Trigger* sunder_armor(PlayerbotAI* botAI) { return new SunderArmorDebuffTrigger(botAI); }
|
||||
// static Trigger* slam(PlayerbotAI* ai) { return new SlamTrigger(ai); }
|
||||
|
||||
static Trigger* vigilance(PlayerbotAI* botAI) { return new VigilanceTrigger(botAI); }
|
||||
};
|
||||
|
||||
class WarriorAiObjectContextInternal : public NamedObjectContext<Action>
|
||||
@@ -235,6 +241,7 @@ public:
|
||||
creators["heroic throw"] = &WarriorAiObjectContextInternal::heroic_throw;
|
||||
creators["heroic throw on snare target"] = &WarriorAiObjectContextInternal::heroic_throw_on_snare_target;
|
||||
creators["shattering throw"] = &WarriorAiObjectContextInternal::shattering_throw;
|
||||
creators["vigilance"] = &WarriorAiObjectContextInternal::vigilance;
|
||||
}
|
||||
|
||||
private:
|
||||
@@ -304,6 +311,7 @@ private:
|
||||
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* bladestorm(PlayerbotAI* botAI) { return new CastBladestormAction(botAI); }
|
||||
static Action* vigilance(PlayerbotAI* botAI) { return new CastVigilanceAction(botAI); }
|
||||
};
|
||||
|
||||
WarriorAiObjectContext::WarriorAiObjectContext(PlayerbotAI* botAI) : AiObjectContext(botAI)
|
||||
|
||||
@@ -12,3 +12,75 @@ bool BloodrageBuffTrigger::IsActive()
|
||||
return AI_VALUE2(uint8, "health", "self target") >= sPlayerbotAIConfig->mediumHealth &&
|
||||
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
|
||||
}
|
||||
|
||||
@@ -45,6 +45,7 @@ DEBUFF_TRIGGER(ShockwaveTrigger, "shockwave");
|
||||
BOOST_TRIGGER(DeathWishTrigger, "death wish");
|
||||
BOOST_TRIGGER(RecklessnessTrigger, "recklessness");
|
||||
BUFF_TRIGGER(BloodthirstBuffTrigger, "bloodthirst");
|
||||
BUFF_TRIGGER(WhirlwindTrigger, "whirlwind");
|
||||
BUFF_TRIGGER(BerserkerRageBuffTrigger, "berserker rage");
|
||||
INTERRUPT_HEALER_TRIGGER(ShieldBashInterruptEnemyHealerSpellTrigger, "shield bash");
|
||||
INTERRUPT_TRIGGER(ShieldBashInterruptSpellTrigger, "shield bash");
|
||||
@@ -63,6 +64,14 @@ public:
|
||||
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
|
||||
// {
|
||||
// public:
|
||||
|
||||
Reference in New Issue
Block a user