Skip to content

Commit 085e127

Browse files
authored
Merge pull request mod-playerbots#2467 from mod-playerbots/test-staging
Merge test-staging into master
2 parents f989976 + a76f2ca commit 085e127

36 files changed

Lines changed: 361 additions & 299 deletions

src/Ai/Base/Actions/CheckMountStateAction.cpp

Lines changed: 28 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include "SpellAuraEffects.h"
1818

1919
static constexpr uint32 SPELL_COLD_WEATHER_FLYING = 54197;
20+
static constexpr float PARACHUTE_LAND_THRESHOLD = 15.0f;
2021

2122
// Define the static map / init bool for caching bot preferred mount data globally
2223
std::unordered_map<uint32, PreferredMountCache> CheckMountStateAction::mountCache;
@@ -61,6 +62,21 @@ MountData CollectMountData(const Player* bot)
6162

6263
bool CheckMountStateAction::Execute(Event /*event*/)
6364
{
65+
// Forced flight dismount:
66+
// Bots get stale flight movement flags after a forced dismount (e.g: Dalaran) because the post landing dismount cleanup
67+
// needs MSG_MOVE_FALL_LAND (a client opcode) and client movement packets. The stale flags cause the bot to be stuck with
68+
// the parachute, or even keep the bot hovering indefinitely and block MMAP routing.
69+
// Note: Without MSG_MOVE_FALL_LAND, HandleFall doesn't trigger, meaning bots don't get fall damage in forced dismounts anyway,
70+
// so the parachute usage here is more of an immersion feature.
71+
if (bot->HasFeatherFallAura())
72+
{
73+
float floorZ = bot->GetMapHeight(bot->GetPositionX(), bot->GetPositionY(), bot->GetPositionZ());
74+
if (floorZ != INVALID_HEIGHT && floorZ != VMAP_INVALID_HEIGHT_VALUE &&
75+
bot->GetPositionZ() - floorZ <= PARACHUTE_LAND_THRESHOLD)
76+
bot->RemoveAurasByType(SPELL_AURA_FEATHER_FALL);
77+
}
78+
ClearStaleFlightFlags();
79+
6480
// Determine if there are no attackers
6581
bool noAttackers = !AI_VALUE2(bool, "combat", "self target") || !AI_VALUE(uint8, "attacker count");
6682
bool enemy = AI_VALUE(Unit*, "enemy player target");
@@ -204,7 +220,7 @@ bool CheckMountStateAction::Mount()
204220
// Get bot mount data
205221
MountData mountData = CollectMountData(bot);
206222
int32 masterMountType = GetMountType(master);
207-
int32 masterSpeed = CalculateMasterMountSpeed(master, mountData);
223+
int32 masterSpeed = CalculateMasterMountSpeed(master);
208224

209225
// Try shapeshift
210226
if (TryForms(master, masterMountType, masterSpeed))
@@ -234,14 +250,17 @@ void CheckMountStateAction::Dismount()
234250
WorldPacket emptyPacket;
235251
bot->GetSession()->HandleCancelMountAuraOpcode(emptyPacket);
236252

237-
bool const wantsFly = bot->HasIncreaseMountedFlightSpeedAura() || bot->HasFlyAura();
238-
bool const isWaterWalking = bot->HasUnitMovementFlag(MOVEMENTFLAG_WATERWALKING);
239-
bool const isFlying = bot->HasUnitMovementFlag(MOVEMENTFLAG_FLYING);
240-
bool const hasGravityDisabled = bot->HasUnitMovementFlag(MOVEMENTFLAG_DISABLE_GRAVITY);
241-
if (!wantsFly && !isWaterWalking && (isFlying || hasGravityDisabled))
253+
ClearStaleFlightFlags();
254+
}
255+
256+
void CheckMountStateAction::ClearStaleFlightFlags()
257+
{
258+
if (bot->HasIncreaseMountedFlightSpeedAura() || bot->HasFlyAura())
259+
return;
260+
261+
if (bot->HasUnitMovementFlag(MOVEMENTFLAG_FLYING | MOVEMENTFLAG_DISABLE_GRAVITY))
242262
{
243-
bot->RemoveUnitMovementFlag(
244-
MOVEMENTFLAG_FLYING | MOVEMENTFLAG_CAN_FLY | MOVEMENTFLAG_DISABLE_GRAVITY);
263+
bot->RemoveUnitMovementFlag(MOVEMENTFLAG_FLYING | MOVEMENTFLAG_DISABLE_GRAVITY | MOVEMENTFLAG_CAN_FLY);
245264
if (!bot->IsRooted())
246265
bot->SendMovementFlagUpdate();
247266
}
@@ -490,7 +509,7 @@ static bool BotCanUseFlyingMount(Player const* bot)
490509
return true;
491510
}
492511

493-
int32 CheckMountStateAction::CalculateMasterMountSpeed(Player* master, const MountData& mountData) const
512+
int32 CheckMountStateAction::CalculateMasterMountSpeed(Player* master) const
494513
{
495514
// Check riding skill and level requirements
496515
int32 ridingSkill = bot->GetPureSkillValue(SKILL_RIDING);

src/Ai/Base/Actions/CheckMountStateAction.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,9 +53,10 @@ class CheckMountStateAction : public UseItemAction
5353
float CalculateDismountDistance() const;
5454
float CalculateMountDistance() const;
5555
void Dismount();
56+
void ClearStaleFlightFlags();
5657
bool ShouldFollowMasterMountState(Player* master, bool noAttackers, bool shouldMount) const;
5758
bool ShouldDismountForMaster(Player* master) const;
58-
int32 CalculateMasterMountSpeed(Player* master, const MountData& mountData) const;
59+
int32 CalculateMasterMountSpeed(Player* master) const;
5960
bool CheckForSwiftMount() const;
6061
std::map<uint32, std::map<int32, std::vector<uint32>>> GetAllMountSpells() const;
6162
bool TryForms(Player* master, int32 masterMountType, int32 masterSpeed) const;

src/Ai/Base/Actions/TameAction.cpp

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -422,10 +422,9 @@ bool TameAction::RenamePet(const std::string& newName)
422422

423423
// Remove the current pet and (re-)cast Call Pet spell if the bot is a hunter
424424
bot->RemovePet(nullptr, PET_SAVE_AS_CURRENT, true);
425-
if (bot->getClass() == CLASS_HUNTER && bot->HasSpell(883))
426-
{
427-
bot->CastSpell(bot, 883, true);
428-
}
425+
constexpr uint32 SPELL_CALL_PET = 883;
426+
if (bot->getClass() == CLASS_HUNTER && bot->HasSpell(SPELL_CALL_PET))
427+
bot->CastSpell(bot, SPELL_CALL_PET, true);
429428

430429
return true;
431430
}

src/Ai/Base/Actions/TradeStatusExtendedAction.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,9 +67,10 @@ bool TradeStatusExtendedAction::Execute(Event event)
6767
return false;
6868
}
6969

70-
if (bot->getClass() == CLASS_ROGUE && bot->HasSpell(1804) && lockbox->IsLocked()) // Pick Lock spell
70+
constexpr uint32 SPELL_PICK_LOCK = 1804;
71+
if (bot->getClass() == CLASS_ROGUE && bot->HasSpell(SPELL_PICK_LOCK) && lockbox->IsLocked())
7172
{
72-
// botAI->CastSpell(1804, bot, lockbox); // Attempt to cast Pick Lock on the lockbox
73+
// botAI->CastSpell(SPELL_PICK_LOCK, bot, lockbox); // Attempt to cast Pick Lock on the lockbox
7374
botAI->DoSpecificAction("unlock traded item");
7475
botAI->SetNextCheckDelay(4000); // Delay before accepting trade
7576
}

src/Ai/Base/Trigger/BossAuraTriggers.cpp

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,7 @@ bool BossFireResistanceTrigger::IsActive()
2323
return false;
2424

2525
// Check if bot have fire resistance aura
26-
if (bot->HasAura(SPELL_FIRE_RESISTANCE_AURA_RANK_5) || bot->HasAura(SPELL_FIRE_RESISTANCE_AURA_RANK_4) ||
27-
bot->HasAura(SPELL_FIRE_RESISTANCE_AURA_RANK_3) || bot->HasAura(SPELL_FIRE_RESISTANCE_AURA_RANK_2) ||
28-
bot->HasAura(SPELL_FIRE_RESISTANCE_AURA_RANK_1))
26+
if (botAI->HasAura("fire resistance aura", bot))
2927
return false;
3028

3129
// Check if bot dont have already have fire resistance strategy
@@ -76,9 +74,7 @@ bool BossFrostResistanceTrigger::IsActive()
7674
return false;
7775

7876
// Check if bot have frost resistance aura
79-
if (bot->HasAura(SPELL_FROST_RESISTANCE_AURA_RANK_5) || bot->HasAura(SPELL_FROST_RESISTANCE_AURA_RANK_4) ||
80-
bot->HasAura(SPELL_FROST_RESISTANCE_AURA_RANK_3) || bot->HasAura(SPELL_FROST_RESISTANCE_AURA_RANK_2) ||
81-
bot->HasAura(SPELL_FROST_RESISTANCE_AURA_RANK_1))
77+
if (botAI->HasAura("frost resistance aura", bot))
8278
return false;
8379

8480
// Check if bot dont have already have frost resistance strategy
@@ -133,8 +129,7 @@ bool BossNatureResistanceTrigger::IsActive()
133129
return false;
134130

135131
// Check if bot have nature resistance aura
136-
if (bot->HasAura(SPELL_ASPECT_OF_THE_WILD_RANK_4) || bot->HasAura(SPELL_ASPECT_OF_THE_WILD_RANK_3) ||
137-
bot->HasAura(SPELL_ASPECT_OF_THE_WILD_RANK_2) || bot->HasAura(SPELL_ASPECT_OF_THE_WILD_RANK_1))
132+
if (botAI->HasAura("aspect of the wild", bot))
138133
return false;
139134

140135
// Check if bot dont have already setted nature resistance aura
@@ -184,11 +179,7 @@ bool BossShadowResistanceTrigger::IsActive()
184179
return false;
185180

186181
// Check if bot have shadow resistance aura
187-
if (bot->HasAura(SPELL_SHADOW_RESISTANCE_AURA_RANK_5) ||
188-
bot->HasAura(SPELL_SHADOW_RESISTANCE_AURA_RANK_4) ||
189-
bot->HasAura(SPELL_SHADOW_RESISTANCE_AURA_RANK_3) ||
190-
bot->HasAura(SPELL_SHADOW_RESISTANCE_AURA_RANK_2) ||
191-
bot->HasAura(SPELL_SHADOW_RESISTANCE_AURA_RANK_1))
182+
if (botAI->HasAura("shadow resistance aura", bot))
192183
return false;
193184

194185
// Check if bot dont have already have shadow resistance strategy

src/Ai/Class/Dk/Strategy/DeathKnightPullStrategy.cpp

Lines changed: 5 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -5,38 +5,26 @@
55

66
#include "DeathKnightPullStrategy.h"
77

8-
#include "AiObjectContext.h"
98
#include "Player.h"
109
#include "PlayerbotAI.h"
1110
#include "Playerbots.h"
1211

1312
std::string DeathKnightPullStrategy::GetPullActionName() const
1413
{
15-
Player* bot = botAI->GetBot();
1614
Unit* target = GetTarget();
17-
if (!bot || !target ||
15+
if (!target ||
1816
(!botAI->HasStrategy("blood", BOT_STATE_COMBAT) && !botAI->HasStrategy("blood", BOT_STATE_NON_COMBAT)))
1917
{
2018
return PullStrategy::GetPullActionName();
2119
}
2220

23-
uint32 const deathGripSpellId = botAI->GetAiObjectContext()->GetValue<uint32>("spell id", "death grip")->Get();
24-
if (deathGripSpellId && bot->HasSpell(deathGripSpellId) &&
25-
botAI->CanCastSpell(deathGripSpellId, target))
26-
{
21+
if (botAI->CanCastSpell("death grip", target))
2722
return "death grip";
28-
}
2923

30-
uint32 const icyTouchSpellId = botAI->GetAiObjectContext()->GetValue<uint32>("spell id", "icy touch")->Get();
31-
if (!icyTouchSpellId || !bot->HasSpell(icyTouchSpellId) ||
32-
!botAI->CanCastSpell(icyTouchSpellId, target))
24+
if (!botAI->CanCastSpell("icy touch", target) &&
25+
botAI->CanCastSpell("dark command", target))
3326
{
34-
uint32 const darkCommandSpellId = botAI->GetAiObjectContext()->GetValue<uint32>("spell id", "dark command")->Get();
35-
if (darkCommandSpellId && bot->HasSpell(darkCommandSpellId) &&
36-
botAI->CanCastSpell(darkCommandSpellId, target))
37-
{
38-
return "dark command";
39-
}
27+
return "dark command";
4028
}
4129

4230
return PullStrategy::GetPullActionName();

src/Ai/Class/Druid/Action/DruidShapeshiftActions.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,9 +50,10 @@ bool CastCancelDruidAction::Execute(Event /*event*/)
5050
return true;
5151
}
5252

53-
bool CastCancelDruidAction::isUseful() { return botAI->HasAura(auraId, bot); }
53+
bool CastCancelDruidAction::isUseful() { return bot->HasAura(auraId); }
5454

5555
bool CastTreeFormAction::isUseful()
5656
{
57-
return GetTarget() && CastSpellAction::isUseful() && !botAI->HasAura(33891, bot);
57+
constexpr uint32 SPELL_TREE_OF_LIFE = 33891;
58+
return GetTarget() && CastSpellAction::isUseful() && !bot->HasAura(SPELL_TREE_OF_LIFE);
5859
}

src/Ai/Class/Druid/DruidTriggers.cpp

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,11 @@ bool ThornsTrigger::IsActive() { return BuffTrigger::IsActive() && !botAI->HasAu
2828

2929
bool BearFormTrigger::IsActive() { return !botAI->HasAnyAuraOf(bot, "bear form", "dire bear form", nullptr); }
3030

31-
bool TreeFormTrigger::IsActive() { return !botAI->HasAura(33891, bot); }
31+
bool TreeFormTrigger::IsActive()
32+
{
33+
constexpr uint32 SPELL_TREE_OF_LIFE = 33891;
34+
return !bot->HasAura(SPELL_TREE_OF_LIFE);
35+
}
3236

3337
bool CatFormTrigger::IsActive() { return !botAI->HasAura("cat form", bot); }
3438

@@ -43,8 +47,11 @@ bool ProwlTrigger::IsActive()
4347
if (botAI->HasAura("prowl", bot) || bot->IsInCombat())
4448
return false;
4549

46-
uint32 prowlId = botAI->GetAiObjectContext()->GetValue<uint32>("spell id", "prowl")->Get();
47-
if (!prowlId || !bot->HasSpell(prowlId) || bot->HasSpellCooldown(prowlId))
50+
if (!botAI->HasSpell("prowl"))
51+
return false;
52+
53+
uint32 const prowlId = AI_VALUE2(uint32, "spell id", "prowl");
54+
if (bot->HasSpellCooldown(prowlId))
4855
return false;
4956

5057
float distance = 30.f;

src/Ai/Class/Druid/DruidTriggers.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -393,14 +393,14 @@ class FerociousBiteTimeTrigger : public Trigger
393393
class FerociousBiteExecuteTrigger : public Trigger
394394
{
395395
public:
396-
FerociousBiteExecuteTrigger(PlayerbotAI* ai) : Trigger(ai, "ferocious bite execute") {}
396+
FerociousBiteExecuteTrigger(PlayerbotAI* botAI) : Trigger(botAI, "ferocious bite execute") {}
397397
bool IsActive() override
398398
{
399399
Unit* target = AI_VALUE(Unit*, "current target");
400400
if (!target || !target->IsAlive())
401401
return false;
402402

403-
if (!AI_VALUE2(uint32, "spell id", "ferocious bite"))
403+
if (!botAI->HasSpell("ferocious bite"))
404404
return false;
405405

406406
if (AI_VALUE2(uint8, "combo", "current target") < 1)

src/Ai/Class/Druid/Strategy/DruidPullStrategy.cpp

Lines changed: 10 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -5,34 +5,23 @@
55

66
#include "DruidPullStrategy.h"
77

8-
#include "AiObjectContext.h"
9-
#include "Player.h"
108
#include "PlayerbotAI.h"
119
#include "Playerbots.h"
1210

1311
std::string DruidPullStrategy::GetPullActionName() const
1412
{
15-
Player* bot = botAI->GetBot();
16-
std::string actionName = PullStrategy::GetPullActionName();
17-
if (!bot)
18-
return actionName;
19-
20-
uint32 const faerieFireFeralId = botAI->GetAiObjectContext()->GetValue<uint32>("spell id", "faerie fire (feral)")->Get();
21-
if (faerieFireFeralId && bot->HasSpell(faerieFireFeralId) &&
22-
(botAI->HasStrategy("bear", BOT_STATE_COMBAT) || botAI->HasStrategy("cat", BOT_STATE_COMBAT)))
23-
{
24-
actionName = "faerie fire (feral)";
25-
}
13+
std::string const pullActionName = PullStrategy::GetPullActionName();
14+
std::string const actionName =
15+
botAI->HasSpell("faerie fire (feral)") &&
16+
(botAI->HasStrategy("bear", BOT_STATE_COMBAT) || botAI->HasStrategy("cat", BOT_STATE_COMBAT))
17+
? "faerie fire (feral)" : pullActionName;
2618

2719
Unit* target = GetTarget();
28-
uint32 const faerieFireSpellId = botAI->GetAiObjectContext()->GetValue<uint32>("spell id", actionName)->Get();
29-
if (target && (!faerieFireSpellId || !bot->HasSpell(faerieFireSpellId) ||
30-
!botAI->CanCastSpell(faerieFireSpellId, target)))
31-
{
32-
uint32 const growlSpellId = botAI->GetAiObjectContext()->GetValue<uint32>("spell id", "growl")->Get();
33-
if (growlSpellId && bot->HasSpell(growlSpellId) && botAI->CanCastSpell(growlSpellId, target))
34-
return "growl";
35-
}
20+
if (!target)
21+
return actionName;
22+
23+
if (!botAI->CanCastSpell(actionName, target) && botAI->CanCastSpell("growl", target))
24+
return "growl";
3625

3726
return actionName;
3827
}

0 commit comments

Comments
 (0)