Skip to content

Commit 00cb177

Browse files
authored
Fix: Allow bots to duel in PVP prohibited areas (mod-playerbots#1906)
Noticed that if you ask a bot to duel in a PVP prohibited area, it will accept, and do nothing. I thought about making the bot reject the request, but if you (the real player) want to duel with it, the duel should happen. This is just a minor fix to allow bots to duel if you ask them to in such areas. Tested with bots in party, random bots of the same faction, and random bots of the opposite faction. All behaved the same before and after fix. An example place to test is Zim'Torga in Zul'Drak which is by default is a PVP prohibited area. - Before fix, you challenge a bot, they accept and turn red, then they either just stay where they are or wander off. - After fix, bot attacks you within the PVP prohibited area when the duel starts.
1 parent 5f697e8 commit 00cb177

3 files changed

Lines changed: 19 additions & 24 deletions

File tree

src/strategy/actions/AttackAction.cpp

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -15,20 +15,19 @@
1515
#include "SharedDefines.h"
1616
#include "Unit.h"
1717

18-
bool AttackAction::Execute(Event event)
18+
bool AttackAction::Execute(Event /*event*/)
1919
{
2020
Unit* target = GetTarget();
2121
if (!target)
2222
return false;
2323

2424
if (!target->IsInWorld())
25-
{
2625
return false;
27-
}
26+
2827
return Attack(target);
2928
}
3029

31-
bool AttackMyTargetAction::Execute(Event event)
30+
bool AttackMyTargetAction::Execute(Event /*event*/)
3231
{
3332
Player* master = GetMaster();
3433
if (!master)
@@ -51,7 +50,7 @@ bool AttackMyTargetAction::Execute(Event event)
5150
return result;
5251
}
5352

54-
bool AttackAction::Attack(Unit* target, bool with_pet /*true*/)
53+
bool AttackAction::Attack(Unit* target, bool /*with_pet*/ /*true*/)
5554
{
5655
Unit* oldTarget = context->GetValue<Unit*>("current target")->Get();
5756
bool shouldMelee = bot->IsWithinMeleeRange(target) || botAI->IsMelee(bot);
@@ -81,11 +80,13 @@ bool AttackAction::Attack(Unit* target, bool with_pet /*true*/)
8180
{
8281
if (verbose)
8382
botAI->TellError(std::string(target->GetName()) + " is no longer in the world.");
83+
8484
return false;
8585
}
8686

87-
// Check if bot OR target is in prohibited zone/area
87+
// Check if bot OR target is in prohibited zone/area (skip for duels)
8888
if ((target->IsPlayer() || target->IsPet()) &&
89+
(!bot->duel || bot->duel->Opponent != target) &&
8990
(sPlayerbotAIConfig->IsPvpProhibited(bot->GetZoneId(), bot->GetAreaId()) ||
9091
sPlayerbotAIConfig->IsPvpProhibited(target->GetZoneId(), target->GetAreaId())))
9192
{
@@ -99,27 +100,31 @@ bool AttackAction::Attack(Unit* target, bool with_pet /*true*/)
99100
{
100101
if (verbose)
101102
botAI->TellError(std::string(target->GetName()) + " is friendly to me.");
103+
102104
return false;
103105
}
104106

105107
if (target->isDead())
106108
{
107109
if (verbose)
108110
botAI->TellError(std::string(target->GetName()) + " is dead.");
111+
109112
return false;
110113
}
111114

112115
if (!bot->IsWithinLOSInMap(target))
113116
{
114117
if (verbose)
115118
botAI->TellError(std::string(target->GetName()) + " is not in my sight.");
119+
116120
return false;
117121
}
118122

119123
if (sameTarget && inCombat && sameAttackMode)
120124
{
121125
if (verbose)
122126
botAI->TellError("I am already attacking " + std::string(target->GetName()) + ".");
127+
123128
return false;
124129
}
125130

@@ -155,9 +160,8 @@ bool AttackAction::Attack(Unit* target, bool with_pet /*true*/)
155160
}
156161

157162
if (IsMovingAllowed() && !bot->HasInArc(CAST_ANGLE_IN_FRONT, target))
158-
{
159163
sServerFacade->SetFacingTo(bot, target);
160-
}
164+
161165
botAI->ChangeEngine(BOT_STATE_COMBAT);
162166

163167
bot->Attack(target, shouldMelee);
@@ -187,4 +191,4 @@ bool AttackAction::Attack(Unit* target, bool with_pet /*true*/)
187191

188192
bool AttackDuelOpponentAction::isUseful() { return AI_VALUE(Unit*, "duel target"); }
189193

190-
bool AttackDuelOpponentAction::Execute(Event event) { return Attack(AI_VALUE(Unit*, "duel target")); }
194+
bool AttackDuelOpponentAction::Execute(Event /*event*/) { return Attack(AI_VALUE(Unit*, "duel target")); }

src/strategy/actions/PetsAction.cpp

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,7 @@ bool PetsAction::Execute(Event event)
1818
// Extract the command parameter from the event (e.g., "aggressive", "defensive", "attack", etc.)
1919
std::string param = event.getParam();
2020
if (param.empty() && !defaultCmd.empty())
21-
{
2221
param = defaultCmd;
23-
}
2422

2523
if (param.empty())
2624
{
@@ -129,9 +127,7 @@ bool PetsAction::Execute(Event event)
129127
{
130128
ObjectGuid masterTargetGuid = master->GetTarget();
131129
if (!masterTargetGuid.IsEmpty())
132-
{
133130
targetUnit = botAI->GetUnit(masterTargetGuid);
134-
}
135131
}
136132

137133
// If no valid target is selected, show an error and return.
@@ -156,8 +152,9 @@ bool PetsAction::Execute(Event event)
156152
botAI->TellError(text);
157153
return false;
158154
}
159-
if (sPlayerbotAIConfig->IsPvpProhibited(bot->GetZoneId(), bot->GetAreaId())
160-
&& (targetUnit->IsPlayer() || targetUnit->IsPet()))
155+
if (sPlayerbotAIConfig->IsPvpProhibited(bot->GetZoneId(), bot->GetAreaId()) &&
156+
(targetUnit->IsPlayer() || targetUnit->IsPet()) &&
157+
(!bot->duel || bot->duel->Opponent != targetUnit))
161158
{
162159
std::string text = sPlayerbotTextMgr->GetBotTextOrDefault(
163160
"pet_pvp_prohibited_error", "I cannot command my pet to attack players in PvP prohibited areas.", {});

src/strategy/values/AttackersValue.cpp

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -33,18 +33,14 @@ GuidVector AttackersValue::Calculate()
3333
{
3434
Unit* unit = botAI->GetUnit(target);
3535
if (unit && IsValidTarget(unit, bot))
36-
{
3736
targets.insert(unit);
38-
}
3937
}
4038
if (Group* group = bot->GetGroup())
4139
{
4240
ObjectGuid skullGuid = group->GetTargetIcon(7);
4341
Unit* skullTarget = botAI->GetUnit(skullGuid);
4442
if (skullTarget && IsValidTarget(skullTarget, bot))
45-
{
4643
targets.insert(skullTarget);
47-
}
4844
}
4945

5046
for (Unit* unit : targets)
@@ -61,9 +57,7 @@ GuidVector AttackersValue::Calculate()
6157
{
6258
Unit* unit = botAI->GetUnit(guid);
6359
if (unit && unit->IsPlayer() && IsValidTarget(unit, bot))
64-
{
6560
result.push_back(unit->GetGUID());
66-
}
6761
}
6862
}
6963

@@ -110,9 +104,8 @@ void AttackersValue::AddAttackersOf(Player* player, std::unordered_set<Unit*>& t
110104

111105
if (player->IsValidAttackTarget(attacker) &&
112106
player->GetDistance2d(attacker) < sPlayerbotAIConfig->sightDistance)
113-
{
114107
targets.insert(attacker);
115-
}
108+
116109
ref = ref->next();
117110
}
118111
}
@@ -180,8 +173,9 @@ bool AttackersValue::IsPossibleTarget(Unit* attacker, Player* bot, float /*range
180173
if (!bot->CanSeeOrDetect(attacker))
181174
return false;
182175

183-
// PvP prohibition checks
176+
// PvP prohibition checks (skip for duels)
184177
if ((attacker->GetGUID().IsPlayer() || attacker->GetGUID().IsPet()) &&
178+
(!bot->duel || bot->duel->Opponent != attacker) &&
185179
(sPlayerbotAIConfig->IsPvpProhibited(attacker->GetZoneId(), attacker->GetAreaId()) ||
186180
sPlayerbotAIConfig->IsPvpProhibited(bot->GetZoneId(), bot->GetAreaId())))
187181
{

0 commit comments

Comments
 (0)