Skip to content

Commit 66f4c41

Browse files
committed
Natural Hunterbot strategies
1 parent 46f8d75 commit 66f4c41

6 files changed

Lines changed: 140 additions & 2 deletions

File tree

src/modules/Bots/playerbot/strategy/hunter/GenericHunterNonCombatStrategy.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ class GenericHunterNonCombatStrategyActionNodeFactory : public NamedObjectFactor
1313
creators["rapid fire"] = &rapid_fire;
1414
creators["boost"] = &rapid_fire;
1515
creators["aspect of the pack"] = &aspect_of_the_pack;
16+
creators["aspect of the viper"] = &aspect_of_the_viper;
1617
}
1718
private:
1819
static ActionNode* rapid_fire(PlayerbotAI* ai)
@@ -29,6 +30,14 @@ class GenericHunterNonCombatStrategyActionNodeFactory : public NamedObjectFactor
2930
/*A*/ NextAction::array(0, new NextAction("aspect of the cheetah"), NULL),
3031
/*C*/ NULL);
3132
}
33+
// aspect of the viper doesn't exist in Vanilla 1.12 - fall back to drinking
34+
static ActionNode* aspect_of_the_viper(PlayerbotAI* ai)
35+
{
36+
return new ActionNode ("aspect of the viper",
37+
/*P*/ NULL,
38+
/*A*/ NextAction::array(0, new NextAction("drink"), NULL),
39+
/*C*/ NULL);
40+
}
3241
};
3342

3443
GenericHunterNonCombatStrategy::GenericHunterNonCombatStrategy(PlayerbotAI* ai) : NonCombatStrategy(ai)

src/modules/Bots/playerbot/strategy/hunter/GenericHunterStrategy.cpp

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,15 @@ void GenericHunterStrategy::InitTriggers(std::list<TriggerNode*> &triggers)
5050

5151
triggers.push_back(new TriggerNode(
5252
"enemy too close for spell",
53-
NextAction::array(0, new NextAction("wing clip", 50.0f), new NextAction("flee",49.0f), new NextAction("concussive shot", 48.0f), NULL)));
53+
NextAction::array(0,
54+
new NextAction("intimidation", 52.0f),
55+
new NextAction("wing clip", 51.0f),
56+
new NextAction("hunter ensure ranged position", 50.0f),
57+
new NextAction("mongoose bite", 49.5f),
58+
new NextAction("disengage", 49.0f),
59+
new NextAction("hunter melee", 48.5f),
60+
new NextAction("flee", 48.0f),
61+
NULL)));
5462

5563
triggers.push_back(new TriggerNode(
5664
"medium threat",
@@ -63,4 +71,9 @@ void GenericHunterStrategy::InitTriggers(std::list<TriggerNode*> &triggers)
6371
triggers.push_back(new TriggerNode(
6472
"rapid fire",
6573
NextAction::array(0, new NextAction("rapid fire", 55.0f), NULL)));
74+
75+
triggers.push_back(new TriggerNode(
76+
"bestial wrath",
77+
NextAction::array(0, new NextAction("bestial wrath", 55.0f), NULL)));
78+
6679
}

src/modules/Bots/playerbot/strategy/hunter/HunterActions.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,3 +24,27 @@ Value<Unit*>* CastFreezingTrap::GetTargetValue()
2424
{
2525
return context->GetValue<Unit*>("cc target", "freezing trap");
2626
}
27+
28+
bool CastIntimidationAction::isUseful()
29+
{
30+
return CastSpellAction::isUseful() && AI_VALUE(Unit*, "pet target") != NULL;
31+
}
32+
33+
bool HunterMeleeAction::isUseful()
34+
{
35+
// Only swing if enemy is already in our face AND targeting us.
36+
// Perhaps in the future a ranged/melee hunter strategy would be nice.
37+
Unit* target = AI_VALUE(Unit*, "current target");
38+
if (!target || !target->IsAlive()) return false;
39+
bool victim = target->getVictim() == bot;
40+
float dist = AI_VALUE2(float, "distance", "current target");
41+
return victim && dist <= ATTACK_DISTANCE;
42+
}
43+
44+
bool HunterMeleeAction::Execute(Event event)
45+
{
46+
Unit* target = AI_VALUE(Unit*, "current target");
47+
if (!target) return false;
48+
bot->Attack(target, true);
49+
return true;
50+
}

src/modules/Bots/playerbot/strategy/hunter/HunterActions.h

Lines changed: 64 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,8 @@ namespace ai
120120
CastWingClipAction(PlayerbotAI* ai) : CastMeleeSpellAction(ai, "wing clip") {}
121121
virtual bool isUseful()
122122
{
123-
return CastMeleeSpellAction::isUseful() && !ai->HasAura(spell, GetTarget());
123+
Unit* target = GetTarget();
124+
return target && target->IsAlive() && CastMeleeSpellAction::isUseful() && !ai->HasAura(spell, target);
124125
}
125126
};
126127

@@ -129,4 +130,66 @@ namespace ai
129130
public:
130131
CastSerpentStingOnAttackerAction(PlayerbotAI* ai) : CastDebuffSpellOnAttackerAction(ai, "serpent sting") {}
131132
};
133+
134+
BEGIN_MELEE_SPELL_ACTION(CastDisengageAction, "disengage")
135+
END_SPELL_ACTION()
136+
137+
BEGIN_MELEE_SPELL_ACTION(CastImmolationTrapAction, "immolation trap")
138+
END_SPELL_ACTION()
139+
140+
BEGIN_MELEE_SPELL_ACTION(CastFrostTrapAction, "frost trap")
141+
END_SPELL_ACTION()
142+
143+
BEGIN_MELEE_SPELL_ACTION(CastExplosiveTrapAction, "explosive trap")
144+
END_SPELL_ACTION()
145+
146+
BEGIN_RANGED_SPELL_ACTION(CastScatterShotAction, "scatter shot")
147+
END_SPELL_ACTION()
148+
149+
class CastBestialWrathAction : public CastAuraSpellAction
150+
{
151+
public:
152+
CastBestialWrathAction(PlayerbotAI* ai) : CastAuraSpellAction(ai, "bestial wrath") {}
153+
virtual string GetTargetName() { return "pet target"; }
154+
virtual bool isUseful() { return CastAuraSpellAction::isUseful() && AI_VALUE(Unit*, "pet target") != NULL; }
155+
};
156+
157+
class CastMongooseBiteAction : public CastMeleeSpellAction
158+
{
159+
public:
160+
CastMongooseBiteAction(PlayerbotAI* ai) : CastMeleeSpellAction(ai, "mongoose bite") {}
161+
virtual bool isPossible() { return bot->HasAuraState(AURA_STATE_DEFENSE) && CastMeleeSpellAction::isPossible(); }
162+
};
163+
164+
class CastIntimidationAction : public CastSpellAction
165+
{
166+
public:
167+
CastIntimidationAction(PlayerbotAI* ai) : CastSpellAction(ai, "intimidation") {}
168+
virtual bool isUseful();
169+
};
170+
171+
class HunterMeleeAction : public Action
172+
{
173+
public:
174+
HunterMeleeAction(PlayerbotAI* ai) : Action(ai, "hunter melee") {}
175+
virtual bool Execute(Event event);
176+
virtual bool isUseful();
177+
};
178+
179+
class HunterEnsureRangedPositionAction : public MovementAction
180+
{
181+
public:
182+
HunterEnsureRangedPositionAction(PlayerbotAI* ai) : MovementAction(ai, "hunter ensure ranged position") {}
183+
virtual bool Execute(Event event)
184+
{
185+
return MoveTo(AI_VALUE(Unit*, "current target"), sPlayerbotAIConfig.spellDistance);
186+
}
187+
virtual bool isUseful()
188+
{
189+
Unit* target = AI_VALUE(Unit*, "current target");
190+
if (!target || !target->IsAlive()) return false;
191+
return target->getVictim() != bot &&
192+
bot->GetDistance(target) < sPlayerbotAIConfig.spellDistance;
193+
}
194+
};
132195
}

src/modules/Bots/playerbot/strategy/hunter/HunterAiObjectContext.cpp

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ namespace ai
7676
creators["freezing trap"] = &TriggerFactoryInternal::freezing_trap;
7777
creators["aspect of the pack"] = &TriggerFactoryInternal::aspect_of_the_pack;
7878
creators["rapid fire"] = &TriggerFactoryInternal::rapid_fire;
79+
creators["bestial wrath"] = &TriggerFactoryInternal::bestial_wrath;
7980
creators["aspect of the hawk"] = &TriggerFactoryInternal::aspect_of_the_hawk;
8081
creators["aspect of the wild"] = &TriggerFactoryInternal::aspect_of_the_wild;
8182
creators["aspect of the viper"] = &TriggerFactoryInternal::aspect_of_the_viper;
@@ -95,6 +96,7 @@ namespace ai
9596
static Trigger* freezing_trap(PlayerbotAI* ai) { return new FreezingTrapTrigger(ai); }
9697
static Trigger* aspect_of_the_pack(PlayerbotAI* ai) { return new HunterAspectOfThePackTrigger(ai); }
9798
static Trigger* rapid_fire(PlayerbotAI* ai) { return new RapidFireTrigger(ai); }
99+
static Trigger* bestial_wrath(PlayerbotAI* ai) { return new BestialWrathTrigger(ai); }
98100
static Trigger* aspect_of_the_hawk(PlayerbotAI* ai) { return new HunterAspectOfTheHawkTrigger(ai); }
99101
static Trigger* aspect_of_the_wild(PlayerbotAI* ai) { return new HunterAspectOfTheWildTrigger(ai); }
100102
};
@@ -141,6 +143,16 @@ namespace ai
141143
creators["trueshot aura"] = &AiObjectContextInternal::trueshot_aura;
142144
creators["feign death"] = &AiObjectContextInternal::feign_death;
143145
creators["wing clip"] = &AiObjectContextInternal::wing_clip;
146+
creators["disengage"] = &AiObjectContextInternal::disengage;
147+
creators["immolation trap"] = &AiObjectContextInternal::immolation_trap;
148+
creators["frost trap"] = &AiObjectContextInternal::frost_trap;
149+
creators["explosive trap"] = &AiObjectContextInternal::explosive_trap;
150+
creators["scatter shot"] = &AiObjectContextInternal::scatter_shot;
151+
creators["bestial wrath"] = &AiObjectContextInternal::bestial_wrath;
152+
creators["mongoose bite"] = &AiObjectContextInternal::mongoose_bite;
153+
creators["intimidation"] = &AiObjectContextInternal::intimidation;
154+
creators["hunter melee"] = &AiObjectContextInternal::hunter_melee;
155+
creators["hunter ensure ranged position"] = &AiObjectContextInternal::hunter_ensure_ranged_position;
144156
}
145157

146158
private:
@@ -167,6 +179,16 @@ namespace ai
167179
static Action* rapid_fire(PlayerbotAI* ai) { return new CastRapidFireAction(ai); }
168180
static Action* aspect_of_the_hawk(PlayerbotAI* ai) { return new CastAspectOfTheHawkAction(ai); }
169181
static Action* aspect_of_the_wild(PlayerbotAI* ai) { return new CastAspectOfTheWildAction(ai); }
182+
static Action* disengage(PlayerbotAI* ai) { return new CastDisengageAction(ai); }
183+
static Action* immolation_trap(PlayerbotAI* ai) { return new CastImmolationTrapAction(ai); }
184+
static Action* frost_trap(PlayerbotAI* ai) { return new CastFrostTrapAction(ai); }
185+
static Action* explosive_trap(PlayerbotAI* ai) { return new CastExplosiveTrapAction(ai); }
186+
static Action* scatter_shot(PlayerbotAI* ai) { return new CastScatterShotAction(ai); }
187+
static Action* bestial_wrath(PlayerbotAI* ai) { return new CastBestialWrathAction(ai); }
188+
static Action* mongoose_bite(PlayerbotAI* ai) { return new CastMongooseBiteAction(ai); }
189+
static Action* intimidation(PlayerbotAI* ai) { return new CastIntimidationAction(ai); }
190+
static Action* hunter_melee(PlayerbotAI* ai) { return new HunterMeleeAction(ai); }
191+
static Action* hunter_ensure_ranged_position(PlayerbotAI* ai) { return new HunterEnsureRangedPositionAction(ai); }
170192
static Action* aspect_of_the_pack(PlayerbotAI* ai) { return new CastAspectOfThePackAction(ai); }
171193
static Action* aspect_of_the_cheetah(PlayerbotAI* ai) { return new CastAspectOfTheCheetahAction(ai); }
172194
static Action* wing_clip(PlayerbotAI* ai) { return new CastWingClipAction(ai); }

src/modules/Bots/playerbot/strategy/hunter/HunterTriggers.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,12 @@ namespace ai
7272
RapidFireTrigger(PlayerbotAI* ai) : BoostTrigger(ai, "rapid fire") {}
7373
};
7474

75+
class BestialWrathTrigger : public BoostTrigger
76+
{
77+
public:
78+
BestialWrathTrigger(PlayerbotAI* ai) : BoostTrigger(ai, "bestial wrath") {}
79+
};
80+
7581
class TrueshotAuraTrigger : public BuffTrigger
7682
{
7783
public:
@@ -83,4 +89,5 @@ namespace ai
8389
public:
8490
SerpentStingOnAttackerTrigger(PlayerbotAI* ai) : DebuffOnAttackerTrigger(ai, "serpent sting") {}
8591
};
92+
8693
}

0 commit comments

Comments
 (0)