Skip to content

Commit 24c6534

Browse files
committed
Rogue combat strategy fixes
1 parent 46f8d75 commit 24c6534

10 files changed

Lines changed: 336 additions & 21 deletions

src/modules/Bots/playerbot/strategy/rogue/DpsRogueStrategy.cpp

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,9 +85,17 @@ void DpsRogueStrategy::InitTriggers(std::list<TriggerNode*> &triggers)
8585
MeleeCombatStrategy::InitTriggers(triggers);
8686

8787
triggers.push_back(new TriggerNode(
88-
"combo points available",
88+
"slice and dice",
89+
NextAction::array(0, new NextAction("slice and dice", ACTION_HIGH + 3), NULL)));
90+
91+
triggers.push_back(new TriggerNode(
92+
"combo points for target available",
8993
NextAction::array(0, new NextAction("rupture", ACTION_HIGH + 2), NULL)));
9094

95+
triggers.push_back(new TriggerNode(
96+
"expose armor",
97+
NextAction::array(0, new NextAction("expose armor", ACTION_HIGH + 1), NULL)));
98+
9199
triggers.push_back(new TriggerNode(
92100
"medium threat",
93101
NextAction::array(0, new NextAction("vanish", ACTION_HIGH), NULL)));

src/modules/Bots/playerbot/strategy/rogue/GenericRogueNonCombatStrategy.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,15 @@ void GenericRogueNonCombatStrategy::InitTriggers(std::list<TriggerNode*> &trigge
1111
{
1212
NonCombatStrategy::InitTriggers(triggers);
1313

14+
triggers.push_back(new TriggerNode(
15+
"attack",
16+
NextAction::array(0, new NextAction("begin ambush", 101.0f), NULL)));
17+
18+
triggers.push_back(new TriggerNode(
19+
"sap",
20+
NextAction::array(0, new NextAction("begin sap", ACTION_HIGH + 1), NULL)));
21+
22+
triggers.push_back(new TriggerNode(
23+
"stealth",
24+
NextAction::array(0, new NextAction("stealth", ACTION_NORMAL), NULL)));
1425
}

src/modules/Bots/playerbot/strategy/rogue/RogueActions.h

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,4 +60,121 @@ namespace ai
6060
public:
6161
CastKickOnEnemyHealerAction(PlayerbotAI* ai) : CastSpellOnEnemyHealerAction(ai, "kick") {}
6262
};
63+
64+
class CastStealthAction : public CastBuffSpellAction
65+
{
66+
public:
67+
CastStealthAction(PlayerbotAI* ai) : CastBuffSpellAction(ai, "stealth") {}
68+
};
69+
70+
class BeginSapAction : public Action
71+
{
72+
public:
73+
BeginSapAction(PlayerbotAI* ai) : Action(ai, "begin sap") {}
74+
75+
virtual bool Execute(Event event)
76+
{
77+
Player* master = ai->GetMaster();
78+
if (!master)
79+
return false;
80+
81+
ObjectGuid targetGuid = master->GetSelectionGuid();
82+
if (targetGuid.IsEmpty())
83+
return false;
84+
85+
Unit* target = ai->GetUnit(targetGuid);
86+
if (!target || !target->IsAlive())
87+
return false;
88+
89+
bot->SetSelectionGuid(targetGuid);
90+
context->GetValue<Unit*>("current target")->Set(target);
91+
ai->ChangeStrategy("+sap", BOT_STATE_NON_COMBAT);
92+
return true;
93+
}
94+
};
95+
96+
class EndSapAction : public Action
97+
{
98+
public:
99+
EndSapAction(PlayerbotAI* ai) : Action(ai, "end sap") {}
100+
101+
virtual bool isUseful()
102+
{
103+
Unit* target = AI_VALUE(Unit*, "current target");
104+
if (!target || !target->IsAlive())
105+
return true;
106+
if (ai->HasAura("sap", target))
107+
return true;
108+
if (bot->IsInCombat())
109+
return true;
110+
return false;
111+
}
112+
113+
virtual bool Execute(Event event)
114+
{
115+
Unit* target = AI_VALUE(Unit*, "current target");
116+
bool sapSucceeded = target && ai->HasAura("sap", target);
117+
if (sapSucceeded)
118+
{
119+
target->DeleteThreatList();
120+
target->CombatStop();
121+
bot->CombatStop();
122+
}
123+
bot->AttackStop();
124+
context->GetValue<Unit*>("current target")->Set(NULL);
125+
bot->SetSelectionGuid(ObjectGuid());
126+
ai->ChangeStrategy("-sap", BOT_STATE_NON_COMBAT);
127+
return true;
128+
}
129+
};
130+
131+
class BeginAmbushAction : public Action
132+
{
133+
public:
134+
BeginAmbushAction(PlayerbotAI* ai) : Action(ai, "begin ambush") {}
135+
136+
virtual bool Execute(Event event)
137+
{
138+
Player* master = ai->GetMaster();
139+
if (!master)
140+
return false;
141+
142+
ObjectGuid guid = master->GetSelectionGuid();
143+
if (guid.IsEmpty())
144+
return false;
145+
146+
Unit* target = ai->GetUnit(guid);
147+
if (!target || !target->IsAlive())
148+
return false;
149+
150+
if (bot->IsFriendlyTo(target))
151+
return false;
152+
153+
if (!bot->IsWithinLOSInMap(target))
154+
return false;
155+
156+
bot->SetSelectionGuid(guid);
157+
context->GetValue<Unit*>("current target")->Set(target);
158+
ai->ChangeStrategy("+ambush", BOT_STATE_NON_COMBAT);
159+
return true;
160+
}
161+
};
162+
163+
class RogueEndAmbushAction : public Action
164+
{
165+
public:
166+
RogueEndAmbushAction(PlayerbotAI* ai) : Action(ai, "end ambush") {}
167+
168+
virtual bool isUseful()
169+
{
170+
return bot->IsInCombat();
171+
}
172+
173+
virtual bool Execute(Event event)
174+
{
175+
ai->ChangeStrategy("-ambush", BOT_STATE_NON_COMBAT);
176+
ai->ChangeEngine(BOT_STATE_COMBAT);
177+
return true;
178+
}
179+
};
63180
}

src/modules/Bots/playerbot/strategy/rogue/RogueAiObjectContext.cpp

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,12 @@
22
#include "../../playerbot.h"
33
#include "RogueActions.h"
44
#include "RogueTriggers.h"
5+
#include "../triggers/ChatCommandTrigger.h"
56
#include "RogueAiObjectContext.h"
67
#include "DpsRogueStrategy.h"
78
#include "GenericRogueNonCombatStrategy.h"
8-
#include "../generic/PullStrategy.h"
9+
#include "RogueAmbushStrategy.h"
10+
#include "RogueSapStrategy.h"
911
#include "../NamedObjectContext.h"
1012

1113
using namespace ai;
@@ -24,13 +26,15 @@ namespace ai
2426
{
2527
creators["dps"] = &rogue::StrategyFactoryInternal::dps;
2628
creators["nc"] = &rogue::StrategyFactoryInternal::nc;
27-
creators["pull"] = &rogue::StrategyFactoryInternal::pull;
29+
creators["ambush"] = &rogue::StrategyFactoryInternal::ambush;
30+
creators["sap"] = &rogue::StrategyFactoryInternal::sap_strategy;
2831
}
2932

3033
private:
3134
static Strategy* dps(PlayerbotAI* ai) { return new DpsRogueStrategy(ai); }
3235
static Strategy* nc(PlayerbotAI* ai) { return new GenericRogueNonCombatStrategy(ai); }
33-
static Strategy* pull(PlayerbotAI* ai) { return new PullStrategy(ai, "shoot"); }
36+
static Strategy* ambush(PlayerbotAI* ai) { return new RogueAmbushStrategy(ai); }
37+
static Strategy* sap_strategy(PlayerbotAI* ai) { return new RogueSapStrategy(ai); }
3438
};
3539
};
3640
};
@@ -51,6 +55,9 @@ namespace ai
5155
creators["slice and dice"] = &TriggerFactoryInternal::slice_and_dice;
5256
creators["expose armor"] = &TriggerFactoryInternal::expose_armor;
5357
creators["kick on enemy healer"] = &TriggerFactoryInternal::kick_on_enemy_healer;
58+
creators["combo points for target available"] = &TriggerFactoryInternal::combo_points_for_target_available;
59+
creators["stealth"] = &TriggerFactoryInternal::stealth;
60+
creators["sap"] = &TriggerFactoryInternal::sap;
5461

5562
}
5663

@@ -60,6 +67,9 @@ namespace ai
6067
static Trigger* slice_and_dice(PlayerbotAI* ai) { return new SliceAndDiceTrigger(ai); }
6168
static Trigger* expose_armor(PlayerbotAI* ai) { return new ExposeArmorTrigger(ai); }
6269
static Trigger* kick_on_enemy_healer(PlayerbotAI* ai) { return new KickInterruptEnemyHealerSpellTrigger(ai); }
70+
static Trigger* combo_points_for_target_available(PlayerbotAI* ai) { return new ComboPointsForTargetAvailableTrigger(ai); }
71+
static Trigger* stealth(PlayerbotAI* ai) { return new StealthTrigger(ai); }
72+
static Trigger* sap(PlayerbotAI* ai) { return new ChatCommandTrigger(ai, "sap"); }
6373
};
6474
};
6575
};
@@ -90,6 +100,14 @@ namespace ai
90100
creators["backstab"] = &AiObjectContextInternal::backstab;
91101
creators["expose armor"] = &AiObjectContextInternal::expose_armor;
92102
creators["kick on enemy healer"] = &AiObjectContextInternal::kick_on_enemy_healer;
103+
creators["sap"] = &AiObjectContextInternal::sap;
104+
creators["begin sap"] = &AiObjectContextInternal::begin_sap;
105+
creators["end sap"] = &AiObjectContextInternal::end_sap;
106+
creators["garrote"] = &AiObjectContextInternal::garrote;
107+
creators["cheap shot"] = &AiObjectContextInternal::cheap_shot;
108+
creators["stealth"] = &AiObjectContextInternal::stealth;
109+
creators["begin ambush"] = &AiObjectContextInternal::begin_ambush;
110+
creators["end ambush"] = &AiObjectContextInternal::end_ambush;
93111
}
94112

95113
private:
@@ -107,6 +125,14 @@ namespace ai
107125
static Action* backstab(PlayerbotAI* ai) { return new CastBackstabAction(ai); }
108126
static Action* expose_armor(PlayerbotAI* ai) { return new CastExposeArmorAction(ai); }
109127
static Action* kick_on_enemy_healer(PlayerbotAI* ai) { return new CastKickOnEnemyHealerAction(ai); }
128+
static Action* sap(PlayerbotAI* ai) { return new CastSapAction(ai); }
129+
static Action* begin_sap(PlayerbotAI* ai) { return new BeginSapAction(ai); }
130+
static Action* end_sap(PlayerbotAI* ai) { return new EndSapAction(ai); }
131+
static Action* garrote(PlayerbotAI* ai) { return new CastGarroteAction(ai); }
132+
static Action* cheap_shot(PlayerbotAI* ai) { return new CastCheapShotAction(ai); }
133+
static Action* stealth(PlayerbotAI* ai) { return new CastStealthAction(ai); }
134+
static Action* begin_ambush(PlayerbotAI* ai) { return new BeginAmbushAction(ai); }
135+
static Action* end_ambush(PlayerbotAI* ai) { return new RogueEndAmbushAction(ai); }
110136
};
111137
};
112138
};
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
#pragma once
2+
3+
#include "../Strategy.h"
4+
5+
namespace ai
6+
{
7+
class RogueAmbushStrategy : public Strategy
8+
{
9+
public:
10+
RogueAmbushStrategy(PlayerbotAI* ai) : Strategy(ai) {}
11+
virtual string getName() { return "ambush"; }
12+
13+
virtual NextAction** getDefaultActions()
14+
{
15+
// Stealth first; once stealthed, cheap shot moves to target (via reach melee
16+
// prerequisite) and opens. End ambush fires once combat begins.
17+
return NextAction::array(0,
18+
new NextAction("stealth", 105.0f),
19+
new NextAction("reach melee", 104.5f),
20+
new NextAction("cheap shot", 104.0f),
21+
new NextAction("end ambush", 103.0f),
22+
new NextAction("sinister strike", 100.0f),
23+
NULL);
24+
}
25+
};
26+
}

src/modules/Bots/playerbot/strategy/rogue/RogueComboActions.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ namespace ai
99

1010
virtual bool isUseful()
1111
{
12-
return CastMeleeSpellAction::isUseful() && AI_VALUE2(uint8, "combo", "self target") < 5;
12+
return CastMeleeSpellAction::isUseful() && AI_VALUE2(uint8, "combo", "current target") < 5;
1313
}
1414
};
1515

src/modules/Bots/playerbot/strategy/rogue/RogueFinishingActions.h

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,34 +2,45 @@
22

33
namespace ai
44
{
5-
class CastEviscerateAction : public CastMeleeSpellAction
5+
class CastFinishingMoveAction : public CastMeleeSpellAction
66
{
77
public:
8-
CastEviscerateAction(PlayerbotAI* ai) : CastMeleeSpellAction(ai, "eviscerate") {}
8+
CastFinishingMoveAction(PlayerbotAI* ai, string name) : CastMeleeSpellAction(ai, name) {}
9+
10+
virtual bool isUseful()
11+
{
12+
return CastMeleeSpellAction::isUseful() && AI_VALUE2(uint8, "combo", "current target") >= 1;
13+
}
14+
};
15+
16+
class CastEviscerateAction : public CastFinishingMoveAction
17+
{
18+
public:
19+
CastEviscerateAction(PlayerbotAI* ai) : CastFinishingMoveAction(ai, "eviscerate") {}
920
};
1021

11-
class CastSliceAndDiceAction : public CastMeleeSpellAction
22+
class CastSliceAndDiceAction : public CastFinishingMoveAction
1223
{
1324
public:
14-
CastSliceAndDiceAction(PlayerbotAI* ai) : CastMeleeSpellAction(ai, "slice and dice") {}
25+
CastSliceAndDiceAction(PlayerbotAI* ai) : CastFinishingMoveAction(ai, "slice and dice") {}
1526
};
1627

17-
class CastExposeArmorAction : public CastMeleeSpellAction
28+
class CastExposeArmorAction : public CastFinishingMoveAction
1829
{
1930
public:
20-
CastExposeArmorAction(PlayerbotAI* ai) : CastMeleeSpellAction(ai, "expose armor") {}
31+
CastExposeArmorAction(PlayerbotAI* ai) : CastFinishingMoveAction(ai, "expose armor") {}
2132
};
2233

23-
class CastRuptureAction : public CastMeleeSpellAction
34+
class CastRuptureAction : public CastFinishingMoveAction
2435
{
2536
public:
26-
CastRuptureAction(PlayerbotAI* ai) : CastMeleeSpellAction(ai, "rupture") {}
37+
CastRuptureAction(PlayerbotAI* ai) : CastFinishingMoveAction(ai, "rupture") {}
2738
};
2839

29-
class CastKidneyShotAction : public CastMeleeSpellAction
40+
class CastKidneyShotAction : public CastFinishingMoveAction
3041
{
3142
public:
32-
CastKidneyShotAction(PlayerbotAI* ai) : CastMeleeSpellAction(ai, "kidney shot") {}
43+
CastKidneyShotAction(PlayerbotAI* ai) : CastFinishingMoveAction(ai, "kidney shot") {}
3344
};
3445

3546
}

src/modules/Bots/playerbot/strategy/rogue/RogueOpeningActions.h

Lines changed: 37 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,23 +2,54 @@
22

33
namespace ai
44
{
5-
class CastSapAction : public CastMeleeSpellAction
5+
class CastStealthedOpeningAction : public CastMeleeSpellAction
66
{
77
public:
8-
CastSapAction(PlayerbotAI* ai) : CastMeleeSpellAction(ai, "sap") {}
8+
CastStealthedOpeningAction(PlayerbotAI* ai, string name) : CastMeleeSpellAction(ai, name) {}
9+
10+
virtual bool isUseful()
11+
{
12+
return CastMeleeSpellAction::isUseful() && ai->HasAura("stealth", ai->GetBot());
13+
}
914
};
1015

11-
class CastGarroteAction : public CastMeleeSpellAction
16+
class CastSapAction : public CastStealthedOpeningAction
1217
{
1318
public:
14-
CastGarroteAction(PlayerbotAI* ai) : CastMeleeSpellAction(ai, "garrote") {}
19+
CastSapAction(PlayerbotAI* ai) : CastStealthedOpeningAction(ai, "sap") {}
20+
21+
virtual bool Execute(Event event)
22+
{
23+
bool result = CastStealthedOpeningAction::Execute(event);
24+
if (result)
25+
{
26+
Unit* sapTarget = GetTarget();
27+
if (sapTarget)
28+
{
29+
sapTarget->DeleteThreatList();
30+
sapTarget->CombatStop();
31+
}
32+
ai->GetBot()->ClearInCombat();
33+
}
34+
return result;
35+
}
1536
};
1637

38+
class CastGarroteAction : public CastStealthedOpeningAction
39+
{
40+
public:
41+
CastGarroteAction(PlayerbotAI* ai) : CastStealthedOpeningAction(ai, "garrote") {}
42+
43+
virtual bool isUseful()
44+
{
45+
return CastStealthedOpeningAction::isUseful() && AI_VALUE2(bool, "behind", "current target");
46+
}
47+
};
1748

18-
class CastCheapShotAction : public CastMeleeSpellAction
49+
class CastCheapShotAction : public CastStealthedOpeningAction
1950
{
2051
public:
21-
CastCheapShotAction(PlayerbotAI* ai) : CastMeleeSpellAction(ai, "cheap shot") {}
52+
CastCheapShotAction(PlayerbotAI* ai) : CastStealthedOpeningAction(ai, "cheap shot") {}
2253
};
2354

2455
}

0 commit comments

Comments
 (0)