Merge pull request #281 from liyunfan1223/dev0623

Dev0623
This commit is contained in:
Yunfan Li
2024-06-24 18:32:16 +08:00
committed by GitHub
19 changed files with 124 additions and 64 deletions

View File

@@ -249,16 +249,17 @@ bool LootObject::IsLootPossible(Player* bot)
bool LootObjectStack::Add(ObjectGuid guid)
{
if (availableLoot.size() >= MAX_LOOT_OBJECT_COUNT) {
availableLoot.shrink(time(nullptr) - 30);
}
if (availableLoot.size() >= MAX_LOOT_OBJECT_COUNT) {
availableLoot.clear();
}
if (!availableLoot.insert(guid).second)
return false;
if (availableLoot.size() < MAX_LOOT_OBJECT_COUNT)
return true;
std::vector<LootObject> ordered = OrderByDistance();
for (size_t i = MAX_LOOT_OBJECT_COUNT; i < ordered.size(); i++)
Remove(ordered[i].guid);
return true;
}

View File

@@ -960,6 +960,8 @@ void PlayerbotAI::ChangeEngine(BotState type)
case BOT_STATE_DEAD:
// LOG_DEBUG("playerbots", "=== {} DEAD ===", bot->GetName().c_str());
break;
default:
break;
}
}
}
@@ -3123,7 +3125,7 @@ bool PlayerbotAI::HasAuraToDispel(Unit* target, uint32 dispelType)
#ifndef WIN32
inline int strcmpi(char const* s1, char const* s2)
{
for (; *s1 && *s2 && (toupper(*s1) == toupper(*s2)); ++s1, ++s2);
for (; *s1 && *s2 && (toupper(*s1) == toupper(*s2)); ++s1, ++s2) {}
return *s1 - *s2;
}
#endif
@@ -3951,6 +3953,8 @@ std::string const PlayerbotAI::HandleRemoteCommand(std::string const command)
case NeedMoneyFor::guild:
out << "guild";
break;
default:
break;
}
out << " | " << ChatHelper::formatMoney(AI_VALUE2(uint32, "free money for", i)) << " / " << ChatHelper::formatMoney(AI_VALUE2(uint32, "money needed for", i)) << "\n";

View File

@@ -178,7 +178,7 @@ void PlayerbotFactory::Randomize(bool incremental)
// {
// return;
// }
LOG_INFO("playerbots", "{} randomizing {} (level {} class = {})...", (incremental ? "Incremental" : "Full"), bot->GetName().c_str(), bot->GetLevel(), bot->getClass());
LOG_INFO("playerbots", "{} randomizing {} (level {} class = {})...", (incremental ? "Incremental" : "Full"), bot->GetName().c_str(), level, bot->getClass());
// LOG_DEBUG("playerbots", "Preparing to {} randomize...", (incremental ? "incremental" : "full"));
Prepare();
LOG_DEBUG("playerbots", "Resetting player...");
@@ -188,7 +188,7 @@ void PlayerbotFactory::Randomize(bool incremental)
ClearSkills();
// bot->SaveToDB(false, false);
ClearSpells();
bot->SaveToDB(false, false);
// bot->SaveToDB(false, false);
if (!incremental)
{
ResetQuests();
@@ -196,12 +196,12 @@ void PlayerbotFactory::Randomize(bool incremental)
if (!sPlayerbotAIConfig->equipmentPersistence || level < sPlayerbotAIConfig->equipmentPersistenceLevel) {
ClearAllItems();
}
bot->SaveToDB(false, false);
// bot->SaveToDB(false, false);
bot->GiveLevel(level);
bot->InitStatsForLevel();
CancelAuras();
bot->SaveToDB(false, false);
// bot->SaveToDB(false, false);
if (pmo)
pmo->finish();
@@ -260,7 +260,7 @@ void PlayerbotFactory::Randomize(bool incremental)
pmo = sPerformanceMonitor->start(PERF_MON_RNDBOT, "PlayerbotFactory_Mounts");
LOG_DEBUG("playerbots", "Initializing mounts...");
InitMounts();
bot->SaveToDB(false, false);
// bot->SaveToDB(false, false);
if (pmo)
pmo->finish();
@@ -349,8 +349,8 @@ void PlayerbotFactory::Randomize(bool incremental)
pmo->finish();
LOG_DEBUG("playerbots", "Initializing glyphs...");
bot->SaveToDB(false, false);
InitGlyphs();
// bot->SaveToDB(false, false);
// pmo = sPerformanceMonitor->start(PERF_MON_RNDBOT, "PlayerbotFactory_Guilds");
// LOG_INFO("playerbots", "Initializing guilds...");
@@ -372,13 +372,14 @@ void PlayerbotFactory::Randomize(bool incremental)
if (!incremental) {
bot->RemovePet(nullptr, PET_SAVE_AS_CURRENT, true);
bot->RemovePet(nullptr, PET_SAVE_NOT_IN_SLOT, true);
// bot->SaveToDB(false, false);
}
if (bot->getLevel() >= 10)
{
pmo = sPerformanceMonitor->start(PERF_MON_RNDBOT, "PlayerbotFactory_Pet");
LOG_DEBUG("playerbots", "Initializing pet...");
InitPet();
bot->SaveToDB(false, false);
// bot->SaveToDB(false, false);
InitPetTalents();
if (pmo)
pmo->finish();
@@ -1422,10 +1423,22 @@ void PlayerbotFactory::InitEquipment(bool incremental)
else if (blevel == 80)
delta = 9;
for(uint8 slot = 0; slot < EQUIPMENT_SLOT_END; ++slot)
for (uint8 slot = 0; slot < EQUIPMENT_SLOT_END; ++slot)
{
if (slot == EQUIPMENT_SLOT_TABARD || slot == EQUIPMENT_SLOT_BODY)
continue;
if (level < 40 && (slot == EQUIPMENT_SLOT_TRINKET1 || slot == EQUIPMENT_SLOT_TRINKET2))
continue;
if (level < 30 && slot == EQUIPMENT_SLOT_NECK)
continue;
if (level < 25 && slot == EQUIPMENT_SLOT_HEAD)
continue;
if (level < 20 && (slot == EQUIPMENT_SLOT_FINGER1 || slot == EQUIPMENT_SLOT_FINGER2))
continue;
uint32 desiredQuality = itemQuality;
if (urand(0, 100) < 100 * sPlayerbotAIConfig->randomGearLoweringChance && desiredQuality > ITEM_QUALITY_NORMAL) {
@@ -1485,6 +1498,15 @@ void PlayerbotFactory::InitEquipment(bool incremental)
{
if (slot == EQUIPMENT_SLOT_TABARD || slot == EQUIPMENT_SLOT_BODY)
continue;
if (level < 40 && (slot == EQUIPMENT_SLOT_TRINKET1 || slot == EQUIPMENT_SLOT_TRINKET2))
continue;
if (level < 25 && slot == EQUIPMENT_SLOT_NECK)
continue;
if (level < 25 && slot == EQUIPMENT_SLOT_HEAD)
continue;
std::vector<uint32>& ids = items[slot];
if (ids.empty())
@@ -2617,7 +2639,7 @@ void PlayerbotFactory::InitPotions()
uint32 itemId = sRandomItemMgr->GetRandomPotion(level, effect);
if (!itemId)
{
LOG_INFO("playerbots", "No potions (type {}) available for bot {} ({} level)", effect, bot->GetName().c_str(), bot->getLevel());
// LOG_INFO("playerbots", "No potions (type {}) available for bot {} ({} level)", effect, bot->GetName().c_str(), bot->getLevel());
continue;
}

View File

@@ -1285,7 +1285,7 @@ void RandomPlayerbotMgr::PrepareTeleportCache()
"ROUND( position_z / 50), "
"t.entry "
"HAVING "
"count(*) > 10) AS g "
"count(*) > 7) AS g "
"INNER JOIN creature c ON g.guid = c.guid "
"INNER JOIN creature_template t on c.id1 = t.entry "
"ORDER BY "
@@ -1332,6 +1332,9 @@ void RandomPlayerbotMgr::PrepareTeleportCache()
"AND t.faction != 35 "
"AND t.faction != 474 "
"AND t.faction != 69 "
"AND t.entry != 30606 "
"AND t.entry != 30608 "
"AND t.faction != 69 "
"AND map IN ({}) "
"ORDER BY "
"t.minlevel;", sPlayerbotAIConfig->randomBotMapsAsString.c_str());
@@ -1347,7 +1350,7 @@ void RandomPlayerbotMgr::PrepareTeleportCache()
float z = fields[3].Get<float>();
float orient = fields[4].Get<float>();
uint32 level = fields[5].Get<uint32>();
WorldLocation loc(mapId, x + cos(orient) * 10.0f, y + sin(orient) * 10.0f, z, orient + M_PI);
WorldLocation loc(mapId, x + cos(orient) * 6.0f, y + sin(orient) * 6.0f, z + 2.0f, orient + M_PI);
collected_locs++;
for (int32 l = 1; l <= maxLevel; l++) {
if (l <= 60 && level >= 60) {
@@ -1524,7 +1527,7 @@ void RandomPlayerbotMgr::RandomizeFirst(Player* bot)
uint32 level;
if (sPlayerbotAIConfig->downgradeMaxLevelBot && bot->GetLevel() == sPlayerbotAIConfig->randomBotMaxLevel) {
if (sPlayerbotAIConfig->downgradeMaxLevelBot && bot->GetLevel() >= sPlayerbotAIConfig->randomBotMaxLevel) {
if (bot->getClass() == CLASS_DEATH_KNIGHT) {
level = sWorld->getIntConfig(CONFIG_START_HEROIC_PLAYER_LEVEL);
} else {
@@ -1532,7 +1535,7 @@ void RandomPlayerbotMgr::RandomizeFirst(Player* bot)
}
} else {
level = urand(sPlayerbotAIConfig->randomBotMinLevel, maxLevel);
if (urand(0, 100) < 100 * sPlayerbotAIConfig->randomBotMaxLevelChance)
if (urand(1, 100) < 100 * sPlayerbotAIConfig->randomBotMaxLevelChance)
level = maxLevel;
if (bot->getClass() == CLASS_DEATH_KNIGHT)

View File

@@ -4,6 +4,7 @@
#include "AcceptInvitationAction.h"
#include "Event.h"
#include "PlayerbotAIConfig.h"
#include "Playerbots.h"
#include "PlayerbotSecurity.h"
@@ -42,7 +43,7 @@ bool AcceptInvitationAction::Execute(Event event)
botAI->TellMaster("Hello");
if (sPlayerbotAIConfig->summonWhenGroup) {
if (sPlayerbotAIConfig->summonWhenGroup && bot->GetDistance(inviter) > sPlayerbotAIConfig->sightDistance) {
Teleport(inviter, bot);
}
return true;

View File

@@ -110,7 +110,8 @@ bool AttackAction::Attack(Unit* target, bool with_pet /*true*/)
context->GetValue<Unit*>("current target")->Set(target);
context->GetValue<LootObjectStack*>("available loot")->Get()->Add(guid);
bool attacked = bot->Attack(target, true);
bool melee = bot->IsWithinMeleeRange(target) || botAI->IsMelee(bot);
bot->Attack(target, melee);
if (IsMovingAllowed() && !bot->HasInArc(CAST_ANGLE_IN_FRONT, target)) {
sServerFacade->SetFacingTo(bot, target);

View File

@@ -1540,8 +1540,8 @@ bool AvoidAoeAction::AvoidAuraWithDynamicObj()
return false;
}
std::ostringstream name;
name << "[" << spellInfo->SpellName[0] << "] (aura)";
if (FleePostion(dynOwner->GetPosition(), radius, name.str())) {
name << spellInfo->SpellName[0]; // << "] (aura)";
if (FleePosition(dynOwner->GetPosition(), radius, name.str())) {
return true;
}
return false;
@@ -1591,8 +1591,8 @@ bool AvoidAoeAction::AvoidGameObjectWithDamage()
continue;
}
std::ostringstream name;
name << "[" << spellInfo->SpellName[0] << "] (object)";
if (FleePostion(go->GetPosition(), radius, name.str())) {
name << spellInfo->SpellName[0]; // << "] (object)";
if (FleePosition(go->GetPosition(), radius, name.str())) {
return true;
}
@@ -1633,8 +1633,8 @@ bool AvoidAoeAction::AvoidUnitWithDamageAura()
break;
}
std::ostringstream name;
name << "[" << triggerSpellInfo->SpellName[0] << "] (unit)";
if (FleePostion(unit->GetPosition(), radius, name.str())) {
name << triggerSpellInfo->SpellName[0]; //<< "] (unit)";
if (FleePosition(unit->GetPosition(), radius, name.str())) {
return true;
}
}
@@ -1645,7 +1645,7 @@ bool AvoidAoeAction::AvoidUnitWithDamageAura()
return false;
}
bool AvoidAoeAction::FleePostion(Position pos, float radius, std::string name)
bool AvoidAoeAction::FleePosition(Position pos, float radius, std::string name)
{
Unit* currentTarget = AI_VALUE(Unit*, "current target");
std::vector<float> possibleAngles;
@@ -1674,9 +1674,10 @@ bool AvoidAoeAction::FleePostion(Position pos, float radius, std::string name)
}
if (farestDis > 0.0f) {
if (MoveTo(bot->GetMapId(), bestPos.GetPositionX(), bestPos.GetPositionY(), bestPos.GetPositionZ(), false, false, true)) {
if (sPlayerbotAIConfig->tellWhenAvoidAoe) {
if (sPlayerbotAIConfig->tellWhenAvoidAoe && lastTellTimer < time(NULL) - 10) {
lastTellTimer = time(NULL);
std::ostringstream out;
out << "Avoiding spell " << name << "...";
out << "I'm avoiding " << name << "...";
bot->Say(out.str(), LANG_UNIVERSAL);
}
return true;

View File

@@ -78,7 +78,11 @@ class AvoidAoeAction : public MovementAction
bool AvoidAuraWithDynamicObj();
bool AvoidGameObjectWithDamage();
bool AvoidUnitWithDamageAura();
bool FleePostion(Position pos, float radius, std::string name);
// Position PositionForTank(Position pos, float radius);
// Position PositionForMelee(Position pos, float radius);
// Position PositionForRanged(Position pos, float radius);
bool FleePosition(Position pos, float radius, std::string name);
time_t lastTellTimer = 0;
};
class RunAwayAction : public MovementAction

View File

@@ -13,11 +13,12 @@ bool SetHomeAction::Execute(Event event)
ObjectGuid selection = bot->GetTarget();
bool isRpgAction = AI_VALUE(GuidPosition, "rpg target") == selection;
if (!isRpgAction)
if (!isRpgAction) {
if (master)
selection = master->GetTarget();
else
return false;
}
if (Unit* unit = botAI->GetUnit(selection))
if (unit->HasFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_INNKEEPER))

View File

@@ -35,7 +35,7 @@ bool TravelAction::Execute(Event event)
if (!newTarget->IsAlive())
continue;
if (!newTarget->GetEntry() != target->getDestination()->getEntry())
if (newTarget->GetEntry() == target->getDestination()->getEntry())
continue;
if (newTarget->IsInCombat())

View File

@@ -79,7 +79,7 @@ void GenericHunterStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
{
CombatStrategy::InitTriggers(triggers);
triggers.push_back(new TriggerNode("enemy is close",
triggers.push_back(new TriggerNode("enemy within melee",
NextAction::array(0,
new NextAction("wing clip", ACTION_HIGH + 1),
new NextAction("mongoose bite", ACTION_HIGH),
@@ -88,7 +88,7 @@ void GenericHunterStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
triggers.push_back(new TriggerNode("hunters pet medium health", NextAction::array(0, new NextAction("mend pet", ACTION_HIGH + 2), nullptr)));
// triggers.push_back(new TriggerNode("no ammo", NextAction::array(0, new NextAction("switch to melee", ACTION_HIGH + 1), new NextAction("say::no ammo", ACTION_HIGH), nullptr)));
triggers.push_back(new TriggerNode("aspect of the viper", NextAction::array(0, new NextAction("aspect of the viper", ACTION_HIGH), NULL)));
triggers.push_back(new TriggerNode("enemy too close for shoot", NextAction::array(0, new NextAction("flee", ACTION_MOVE + 9), nullptr)));
triggers.push_back(new TriggerNode("enemy too close for auto shot", NextAction::array(0, new NextAction("flee", ACTION_MOVE + 9), nullptr)));
triggers.push_back(new TriggerNode("misdirection on main tank", NextAction::array(0, new NextAction("misdirection on main tank", ACTION_HIGH + 7), NULL)));
triggers.push_back(new TriggerNode("tranquilizing shot", NextAction::array(0, new NextAction("tranquilizing shot", 61.0f), NULL)));

View File

@@ -52,29 +52,29 @@ bool EnemyTooCloseForSpellTrigger::IsActive()
bool EnemyTooCloseForAutoShotTrigger::IsActive()
{
Unit* target = AI_VALUE(Unit*, "current target");
if (!target)
return false;
return target && (target->GetVictim() != bot || target->isFrozen() || !target->CanFreeMove()) && bot->IsWithinMeleeRange(target);
if (target->GetTarget() == bot->GetGUID() && !bot->GetGroup() && !target->HasUnitState(UNIT_STATE_ROOT) && GetSpeedInMotion(target) > GetSpeedInMotion(bot) * 0.65f)
return false;
// if (target->GetTarget() == bot->GetGUID() && !bot->GetGroup() && !target->HasUnitState(UNIT_STATE_ROOT) && GetSpeedInMotion(target) > GetSpeedInMotion(bot) * 0.65f)
// return false;
bool isBoss = false;
bool isRaid = false;
float combatReach = bot->GetCombatReach() + target->GetCombatReach();
float targetDistance = sServerFacade->GetDistance2d(bot, target) + combatReach;
if (target->GetTypeId() == TYPEID_UNIT)
{
Creature* creature = botAI->GetCreature(target->GetGUID());
if (creature)
{
isBoss = creature->isWorldBoss();
}
}
// bool isBoss = false;
// bool isRaid = false;
// float combatReach = bot->GetCombatReach() + target->GetCombatReach();
// float targetDistance = sServerFacade->GetDistance2d(bot, target) + combatReach;
// if (target->GetTypeId() == TYPEID_UNIT)
// {
// Creature* creature = botAI->GetCreature(target->GetGUID());
// if (creature)
// {
// isBoss = creature->isWorldBoss();
// }
// }
if (bot->GetMap() && bot->GetMap()->IsRaid())
isRaid = true;
// if (bot->GetMap() && bot->GetMap()->IsRaid())
// isRaid = true;
return sServerFacade->IsDistanceLessOrEqualThan(targetDistance, 5.0f);
// return sServerFacade->IsDistanceLessOrEqualThan(targetDistance, 5.0f);
}
bool EnemyTooCloseForShootTrigger::IsActive()
@@ -128,6 +128,12 @@ bool EnemyIsCloseTrigger::IsActive()
return target && sServerFacade->IsDistanceLessOrEqualThan(AI_VALUE2(float, "distance", "current target"), sPlayerbotAIConfig->tooCloseDistance);
}
bool EnemyWithinMeleeTrigger::IsActive()
{
Unit* target = AI_VALUE(Unit*, "current target");
return target && bot->IsWithinMeleeRange(target);
}
bool OutOfRangeTrigger::IsActive()
{
Unit* target = AI_VALUE(Unit*, GetTargetName());

View File

@@ -50,6 +50,14 @@ class EnemyIsCloseTrigger : public Trigger
bool IsActive() override;
};
class EnemyWithinMeleeTrigger : public Trigger
{
public:
EnemyWithinMeleeTrigger(PlayerbotAI* botAI) : Trigger(botAI, "enemy within melee") { }
bool IsActive() override;
};
class OutOfRangeTrigger : public Trigger
{
public:

View File

@@ -87,6 +87,7 @@ class TriggerContext : public NamedObjectContext<Trigger>
creators["enemy too close for auto shot"] = &TriggerContext::enemy_too_close_for_auto_shot;
creators["enemy too close for melee"] = &TriggerContext::enemy_too_close_for_melee;
creators["enemy is close"] = &TriggerContext::enemy_is_close;
creators["enemy within melee"] = &TriggerContext::enemy_within_melee;
creators["party member to heal out of spell range"] = &TriggerContext::party_member_to_heal_out_of_spell_range;
creators["combo points available"] = &TriggerContext::ComboPointsAvailable;
@@ -278,6 +279,7 @@ class TriggerContext : public NamedObjectContext<Trigger>
static Trigger* enemy_too_close_for_shoot(PlayerbotAI* botAI) { return new EnemyTooCloseForShootTrigger(botAI); }
static Trigger* enemy_too_close_for_melee(PlayerbotAI* botAI) { return new EnemyTooCloseForMeleeTrigger(botAI); }
static Trigger* enemy_is_close(PlayerbotAI* botAI) { return new EnemyIsCloseTrigger(botAI); }
static Trigger* enemy_within_melee(PlayerbotAI* botAI) { return new EnemyWithinMeleeTrigger(botAI); }
static Trigger* party_member_to_heal_out_of_spell_range(PlayerbotAI* botAI) { return new PartyMemberToHealOutOfSpellRangeTrigger(botAI); }
static Trigger* ComboPointsAvailable(PlayerbotAI* botAI) { return new ComboPointsAvailableTrigger(botAI); }
static Trigger* ComboPoints3Available(PlayerbotAI* botAI) { return new ComboPointsAvailableTrigger(botAI, 3); }

View File

@@ -122,9 +122,10 @@ Aura* AreaDebuffValue::Calculate()
{
// Unit::AuraApplicationMap& map = bot->GetAppliedAuras();
Unit::AuraEffectList const& aurasPeriodicDamage = bot->GetAuraEffectsByType(SPELL_AURA_PERIODIC_DAMAGE);
Unit::AuraEffectList const& aurasPeriodicDamagePercent = bot->GetAuraEffectsByType(SPELL_AURA_PERIODIC_DAMAGE_PERCENT);
Unit::AuraEffectList const& aurasPeriodicTriggerSpell = bot->GetAuraEffectsByType(SPELL_AURA_PERIODIC_TRIGGER_SPELL);
Unit::AuraEffectList const& aurasPeriodicTriggerWithValueSpell = bot->GetAuraEffectsByType(SPELL_AURA_PERIODIC_TRIGGER_SPELL_WITH_VALUE);
for (const Unit::AuraEffectList& list : {aurasPeriodicDamage, aurasPeriodicTriggerSpell, aurasPeriodicTriggerWithValueSpell}) {
for (const Unit::AuraEffectList& list : {aurasPeriodicDamage, aurasPeriodicDamagePercent, aurasPeriodicTriggerSpell, aurasPeriodicTriggerWithValueSpell}) {
for (auto i = list.begin(); i != list.end(); ++i)
{
AuraEffect* aurEff = *i;

View File

@@ -35,7 +35,7 @@ GuidVector AttackersValue::Calculate()
}
}
if (Group* group = bot->GetGroup()) {
ObjectGuid skullGuid = group->GetTargetIcon(4);
ObjectGuid skullGuid = group->GetTargetIcon(7);
Unit* skullTarget = botAI->GetUnit(skullGuid);
if (skullTarget && IsValidTarget(skullTarget, bot)) {
targets.insert(skullTarget);

View File

@@ -196,11 +196,13 @@ ItemUsage ItemUsageValue::QueryItemUsageForEquip(ItemTemplate const* itemProto)
Item* oldItem = bot->GetItemByPos(dest);
//No item equiped
if (!oldItem)
if (!oldItem) {
if (shouldEquip)
return ITEM_USAGE_EQUIP;
else
else {
return ITEM_USAGE_BAD_EQUIP;
}
}
ItemTemplate const* oldItemProto = oldItem->GetTemplate();
float oldScore = PlayerbotFactory::CalculateItemScore(oldItemProto->ItemId, bot);
@@ -214,11 +216,13 @@ ItemUsage ItemUsageValue::QueryItemUsageForEquip(ItemTemplate const* itemProto)
}
// Bigger quiver
if (itemProto->Class == ITEM_CLASS_QUIVER)
if (!oldItem || oldItemProto->ContainerSlots < itemProto->ContainerSlots)
if (itemProto->Class == ITEM_CLASS_QUIVER) {
if (!oldItem || oldItemProto->ContainerSlots < itemProto->ContainerSlots) {
return ITEM_USAGE_EQUIP;
else
} else {
return ITEM_USAGE_NONE;
}
}
bool existingShouldEquip = true;
if (oldItemProto->Class == ITEM_CLASS_WEAPON && !sRandomItemMgr->CanEquipWeapon(bot->getClass(), oldItemProto))

View File

@@ -13,6 +13,7 @@ class PlayerbotAI;
class FindPlayerPredicate
{
public:
virtual ~FindPlayerPredicate() = default;
virtual bool Check(Unit* /*unit*/) = 0;
};

View File

@@ -104,7 +104,7 @@ bool FindTargetStrategy::IsHighPriority(Unit* attacker)
{
if (Group* group = botAI->GetBot()->GetGroup())
{
ObjectGuid guid = group->GetTargetIcon(4);
ObjectGuid guid = group->GetTargetIcon(7);
if (guid && attacker->GetGUID() == guid) {
return true;
}