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) 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) if (!availableLoot.insert(guid).second)
return false; 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; return true;
} }

View File

@@ -960,6 +960,8 @@ void PlayerbotAI::ChangeEngine(BotState type)
case BOT_STATE_DEAD: case BOT_STATE_DEAD:
// LOG_DEBUG("playerbots", "=== {} DEAD ===", bot->GetName().c_str()); // LOG_DEBUG("playerbots", "=== {} DEAD ===", bot->GetName().c_str());
break; break;
default:
break;
} }
} }
} }
@@ -3123,7 +3125,7 @@ bool PlayerbotAI::HasAuraToDispel(Unit* target, uint32 dispelType)
#ifndef WIN32 #ifndef WIN32
inline int strcmpi(char const* s1, char const* s2) 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; return *s1 - *s2;
} }
#endif #endif
@@ -3951,6 +3953,8 @@ std::string const PlayerbotAI::HandleRemoteCommand(std::string const command)
case NeedMoneyFor::guild: case NeedMoneyFor::guild:
out << "guild"; out << "guild";
break; break;
default:
break;
} }
out << " | " << ChatHelper::formatMoney(AI_VALUE2(uint32, "free money for", i)) << " / " << ChatHelper::formatMoney(AI_VALUE2(uint32, "money needed for", i)) << "\n"; 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; // 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")); // LOG_DEBUG("playerbots", "Preparing to {} randomize...", (incremental ? "incremental" : "full"));
Prepare(); Prepare();
LOG_DEBUG("playerbots", "Resetting player..."); LOG_DEBUG("playerbots", "Resetting player...");
@@ -188,7 +188,7 @@ void PlayerbotFactory::Randomize(bool incremental)
ClearSkills(); ClearSkills();
// bot->SaveToDB(false, false); // bot->SaveToDB(false, false);
ClearSpells(); ClearSpells();
bot->SaveToDB(false, false); // bot->SaveToDB(false, false);
if (!incremental) if (!incremental)
{ {
ResetQuests(); ResetQuests();
@@ -196,12 +196,12 @@ void PlayerbotFactory::Randomize(bool incremental)
if (!sPlayerbotAIConfig->equipmentPersistence || level < sPlayerbotAIConfig->equipmentPersistenceLevel) { if (!sPlayerbotAIConfig->equipmentPersistence || level < sPlayerbotAIConfig->equipmentPersistenceLevel) {
ClearAllItems(); ClearAllItems();
} }
bot->SaveToDB(false, false); // bot->SaveToDB(false, false);
bot->GiveLevel(level); bot->GiveLevel(level);
bot->InitStatsForLevel(); bot->InitStatsForLevel();
CancelAuras(); CancelAuras();
bot->SaveToDB(false, false); // bot->SaveToDB(false, false);
if (pmo) if (pmo)
pmo->finish(); pmo->finish();
@@ -260,7 +260,7 @@ void PlayerbotFactory::Randomize(bool incremental)
pmo = sPerformanceMonitor->start(PERF_MON_RNDBOT, "PlayerbotFactory_Mounts"); pmo = sPerformanceMonitor->start(PERF_MON_RNDBOT, "PlayerbotFactory_Mounts");
LOG_DEBUG("playerbots", "Initializing mounts..."); LOG_DEBUG("playerbots", "Initializing mounts...");
InitMounts(); InitMounts();
bot->SaveToDB(false, false); // bot->SaveToDB(false, false);
if (pmo) if (pmo)
pmo->finish(); pmo->finish();
@@ -349,8 +349,8 @@ void PlayerbotFactory::Randomize(bool incremental)
pmo->finish(); pmo->finish();
LOG_DEBUG("playerbots", "Initializing glyphs..."); LOG_DEBUG("playerbots", "Initializing glyphs...");
bot->SaveToDB(false, false);
InitGlyphs(); InitGlyphs();
// bot->SaveToDB(false, false);
// pmo = sPerformanceMonitor->start(PERF_MON_RNDBOT, "PlayerbotFactory_Guilds"); // pmo = sPerformanceMonitor->start(PERF_MON_RNDBOT, "PlayerbotFactory_Guilds");
// LOG_INFO("playerbots", "Initializing guilds..."); // LOG_INFO("playerbots", "Initializing guilds...");
@@ -372,13 +372,14 @@ void PlayerbotFactory::Randomize(bool incremental)
if (!incremental) { if (!incremental) {
bot->RemovePet(nullptr, PET_SAVE_AS_CURRENT, true); bot->RemovePet(nullptr, PET_SAVE_AS_CURRENT, true);
bot->RemovePet(nullptr, PET_SAVE_NOT_IN_SLOT, true); bot->RemovePet(nullptr, PET_SAVE_NOT_IN_SLOT, true);
// bot->SaveToDB(false, false);
} }
if (bot->getLevel() >= 10) if (bot->getLevel() >= 10)
{ {
pmo = sPerformanceMonitor->start(PERF_MON_RNDBOT, "PlayerbotFactory_Pet"); pmo = sPerformanceMonitor->start(PERF_MON_RNDBOT, "PlayerbotFactory_Pet");
LOG_DEBUG("playerbots", "Initializing pet..."); LOG_DEBUG("playerbots", "Initializing pet...");
InitPet(); InitPet();
bot->SaveToDB(false, false); // bot->SaveToDB(false, false);
InitPetTalents(); InitPetTalents();
if (pmo) if (pmo)
pmo->finish(); pmo->finish();
@@ -1422,10 +1423,22 @@ void PlayerbotFactory::InitEquipment(bool incremental)
else if (blevel == 80) else if (blevel == 80)
delta = 9; 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) if (slot == EQUIPMENT_SLOT_TABARD || slot == EQUIPMENT_SLOT_BODY)
continue; 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; uint32 desiredQuality = itemQuality;
if (urand(0, 100) < 100 * sPlayerbotAIConfig->randomGearLoweringChance && desiredQuality > ITEM_QUALITY_NORMAL) { 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) if (slot == EQUIPMENT_SLOT_TABARD || slot == EQUIPMENT_SLOT_BODY)
continue; 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]; std::vector<uint32>& ids = items[slot];
if (ids.empty()) if (ids.empty())
@@ -2617,7 +2639,7 @@ void PlayerbotFactory::InitPotions()
uint32 itemId = sRandomItemMgr->GetRandomPotion(level, effect); uint32 itemId = sRandomItemMgr->GetRandomPotion(level, effect);
if (!itemId) 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; continue;
} }

View File

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

View File

@@ -4,6 +4,7 @@
#include "AcceptInvitationAction.h" #include "AcceptInvitationAction.h"
#include "Event.h" #include "Event.h"
#include "PlayerbotAIConfig.h"
#include "Playerbots.h" #include "Playerbots.h"
#include "PlayerbotSecurity.h" #include "PlayerbotSecurity.h"
@@ -42,7 +43,7 @@ bool AcceptInvitationAction::Execute(Event event)
botAI->TellMaster("Hello"); botAI->TellMaster("Hello");
if (sPlayerbotAIConfig->summonWhenGroup) { if (sPlayerbotAIConfig->summonWhenGroup && bot->GetDistance(inviter) > sPlayerbotAIConfig->sightDistance) {
Teleport(inviter, bot); Teleport(inviter, bot);
} }
return true; 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<Unit*>("current target")->Set(target);
context->GetValue<LootObjectStack*>("available loot")->Get()->Add(guid); 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)) { if (IsMovingAllowed() && !bot->HasInArc(CAST_ANGLE_IN_FRONT, target)) {
sServerFacade->SetFacingTo(bot, target); sServerFacade->SetFacingTo(bot, target);

View File

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

View File

@@ -78,7 +78,11 @@ class AvoidAoeAction : public MovementAction
bool AvoidAuraWithDynamicObj(); bool AvoidAuraWithDynamicObj();
bool AvoidGameObjectWithDamage(); bool AvoidGameObjectWithDamage();
bool AvoidUnitWithDamageAura(); 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 class RunAwayAction : public MovementAction

View File

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

View File

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

View File

@@ -79,7 +79,7 @@ void GenericHunterStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
{ {
CombatStrategy::InitTriggers(triggers); CombatStrategy::InitTriggers(triggers);
triggers.push_back(new TriggerNode("enemy is close", triggers.push_back(new TriggerNode("enemy within melee",
NextAction::array(0, NextAction::array(0,
new NextAction("wing clip", ACTION_HIGH + 1), new NextAction("wing clip", ACTION_HIGH + 1),
new NextAction("mongoose bite", ACTION_HIGH), 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("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("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("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("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))); 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() bool EnemyTooCloseForAutoShotTrigger::IsActive()
{ {
Unit* target = AI_VALUE(Unit*, "current target"); 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) // if (target->GetTarget() == bot->GetGUID() && !bot->GetGroup() && !target->HasUnitState(UNIT_STATE_ROOT) && GetSpeedInMotion(target) > GetSpeedInMotion(bot) * 0.65f)
return false; // return false;
bool isBoss = false; // bool isBoss = false;
bool isRaid = false; // bool isRaid = false;
float combatReach = bot->GetCombatReach() + target->GetCombatReach(); // float combatReach = bot->GetCombatReach() + target->GetCombatReach();
float targetDistance = sServerFacade->GetDistance2d(bot, target) + combatReach; // float targetDistance = sServerFacade->GetDistance2d(bot, target) + combatReach;
if (target->GetTypeId() == TYPEID_UNIT) // if (target->GetTypeId() == TYPEID_UNIT)
{ // {
Creature* creature = botAI->GetCreature(target->GetGUID()); // Creature* creature = botAI->GetCreature(target->GetGUID());
if (creature) // if (creature)
{ // {
isBoss = creature->isWorldBoss(); // isBoss = creature->isWorldBoss();
} // }
} // }
if (bot->GetMap() && bot->GetMap()->IsRaid()) // if (bot->GetMap() && bot->GetMap()->IsRaid())
isRaid = true; // isRaid = true;
return sServerFacade->IsDistanceLessOrEqualThan(targetDistance, 5.0f); // return sServerFacade->IsDistanceLessOrEqualThan(targetDistance, 5.0f);
} }
bool EnemyTooCloseForShootTrigger::IsActive() bool EnemyTooCloseForShootTrigger::IsActive()
@@ -128,6 +128,12 @@ bool EnemyIsCloseTrigger::IsActive()
return target && sServerFacade->IsDistanceLessOrEqualThan(AI_VALUE2(float, "distance", "current target"), sPlayerbotAIConfig->tooCloseDistance); 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() bool OutOfRangeTrigger::IsActive()
{ {
Unit* target = AI_VALUE(Unit*, GetTargetName()); Unit* target = AI_VALUE(Unit*, GetTargetName());

View File

@@ -50,6 +50,14 @@ class EnemyIsCloseTrigger : public Trigger
bool IsActive() override; bool IsActive() override;
}; };
class EnemyWithinMeleeTrigger : public Trigger
{
public:
EnemyWithinMeleeTrigger(PlayerbotAI* botAI) : Trigger(botAI, "enemy within melee") { }
bool IsActive() override;
};
class OutOfRangeTrigger : public Trigger class OutOfRangeTrigger : public Trigger
{ {
public: 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 auto shot"] = &TriggerContext::enemy_too_close_for_auto_shot;
creators["enemy too close for melee"] = &TriggerContext::enemy_too_close_for_melee; creators["enemy too close for melee"] = &TriggerContext::enemy_too_close_for_melee;
creators["enemy is close"] = &TriggerContext::enemy_is_close; 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["party member to heal out of spell range"] = &TriggerContext::party_member_to_heal_out_of_spell_range;
creators["combo points available"] = &TriggerContext::ComboPointsAvailable; 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_shoot(PlayerbotAI* botAI) { return new EnemyTooCloseForShootTrigger(botAI); }
static Trigger* enemy_too_close_for_melee(PlayerbotAI* botAI) { return new EnemyTooCloseForMeleeTrigger(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_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* 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* ComboPointsAvailable(PlayerbotAI* botAI) { return new ComboPointsAvailableTrigger(botAI); }
static Trigger* ComboPoints3Available(PlayerbotAI* botAI) { return new ComboPointsAvailableTrigger(botAI, 3); } 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::AuraApplicationMap& map = bot->GetAppliedAuras();
Unit::AuraEffectList const& aurasPeriodicDamage = bot->GetAuraEffectsByType(SPELL_AURA_PERIODIC_DAMAGE); 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& aurasPeriodicTriggerSpell = bot->GetAuraEffectsByType(SPELL_AURA_PERIODIC_TRIGGER_SPELL);
Unit::AuraEffectList const& aurasPeriodicTriggerWithValueSpell = bot->GetAuraEffectsByType(SPELL_AURA_PERIODIC_TRIGGER_SPELL_WITH_VALUE); 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) for (auto i = list.begin(); i != list.end(); ++i)
{ {
AuraEffect* aurEff = *i; AuraEffect* aurEff = *i;

View File

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

View File

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

View File

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

View File

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