fix: bot stuck after drink or food && initialization customized

This commit is contained in:
Yunfan Li
2023-05-23 23:39:20 +08:00
parent 32da0c07c9
commit c16e587854
18 changed files with 247 additions and 119 deletions

View File

@@ -561,7 +561,7 @@ AiPlayerbot.MinRandomBotInWorldTime = 3600
AiPlayerbot.MaxRandomBotInWorldTime = 1209600
AiPlayerbot.MinRandomBotRandomizeTime = 7200
AiPlayerbot.MaxRandomRandomizeTime = 1209600
AiPlayerbot.RandomBotsPerInterval = 60
AiPlayerbot.RandomBotsPerInterval = 500
AiPlayerbot.MinRandomBotsPriceChangeInterval = 7200
AiPlayerbot.MaxRandomBotsPriceChangeInterval = 172800
AiPlayerbot.MinRandomBotChangeStrategyTime = 180

View File

@@ -91,39 +91,24 @@ uint8 AiFactory::GetPlayerSpecTab(Player* bot)
std::map<uint8, uint32> AiFactory::GetPlayerSpecTabs(Player* bot)
{
std::map<uint8, uint32> tabs;
for (uint32 i = 0; i < 3; i++)
tabs[i] = 0;
uint32 classMask = bot->getClassMask();
for (uint32 i = 0; i < sTalentStore.GetNumRows(); ++i)
std::map<uint8, uint32> tabs = {{0, 0}, {0, 0}, {0, 0}};
const PlayerTalentMap& talentMap = bot->GetTalentMap();
for (PlayerTalentMap::const_iterator i = talentMap.begin(); i != talentMap.end(); ++i)
{
TalentEntry const *talentInfo = sTalentStore.LookupEntry(i);
uint32 spellId = i->first;
TalentSpellPos const* talentPos = GetTalentSpellPos(spellId);
if(!talentPos)
continue;
TalentEntry const* talentInfo = sTalentStore.LookupEntry(talentPos->talent_id);
if (!talentInfo)
continue;
TalentTabEntry const *talentTabInfo = sTalentTabStore.LookupEntry(talentInfo->TalentTab);
if (!talentTabInfo)
continue;
if ((classMask & talentTabInfo->ClassMask) == 0)
continue;
uint32 maxRank = 0;
for (int32 rank = MAX_TALENT_RANK - 1; rank >= 0; --rank)
{
if (!talentInfo->RankID[rank])
continue;
uint32 spellid = talentInfo->RankID[rank];
if (spellid && bot->HasSpell(spellid))
maxRank = rank + 1;
}
tabs[talentTabInfo->tabpage] += maxRank;
uint32 const* talentTabIds = GetTalentTabPages(bot->getClass());
if (talentInfo->TalentTab == talentTabIds[0]) tabs[0]++;
if (talentInfo->TalentTab == talentTabIds[1]) tabs[1]++;
if (talentInfo->TalentTab == talentTabIds[2]) tabs[2]++;
}
return tabs;
}
@@ -554,7 +539,7 @@ void AiFactory::AddDefaultNonCombatStrategies(Player* player, PlayerbotAI* const
if (!player->InBattleground())
{
nonCombatEngine->addStrategies("nc", "food", "chat", "follow",
"default", "quest", "loot", "gather", "duel", "emote", "buff", "mount", nullptr);
"default", "quest", "loot", "gather", "duel", "buff", "mount", nullptr);
}
if ((facade->IsRealPlayer() || sRandomPlayerbotMgr->IsRandomBot(player)) && !player->InBattleground())
@@ -578,7 +563,7 @@ void AiFactory::AddDefaultNonCombatStrategies(Player* player, PlayerbotAI* const
nonCombatEngine->addStrategy("collision");
nonCombatEngine->addStrategy("grind");
// nonCombatEngine->addStrategy("group");
nonCombatEngine->addStrategy("guild");
// nonCombatEngine->addStrategy("guild");
if (sPlayerbotAIConfig->autoDoQuests)
{
@@ -607,7 +592,7 @@ void AiFactory::AddDefaultNonCombatStrategies(Player* player, PlayerbotAI* const
nonCombatEngine->addStrategy("collision");
nonCombatEngine->addStrategy("grind");
// nonCombatEngine->addStrategy("group");
nonCombatEngine->addStrategy("guild");
// nonCombatEngine->addStrategy("guild");
if (sPlayerbotAIConfig->autoDoQuests)
{
@@ -634,7 +619,7 @@ void AiFactory::AddDefaultNonCombatStrategies(Player* player, PlayerbotAI* const
// Battleground switch
if (player->InBattleground() && player->GetBattleground())
{
nonCombatEngine->addStrategies("nc", "chat", "default", "buff", "food", "mount", "pvp", "collision", "dps assist", "attack tagged", "emote", nullptr);
nonCombatEngine->addStrategies("nc", "chat", "default", "buff", "food", "mount", "pvp", "collision", "dps assist", "attack tagged", nullptr);
nonCombatEngine->removeStrategy("custom::say");
nonCombatEngine->removeStrategy("travel");
nonCombatEngine->removeStrategy("rpg");

View File

@@ -76,18 +76,19 @@ void PlayerbotFactory::Prepare()
{
if (!itemQuality)
{
if (level < 20)
itemQuality = urand(ITEM_QUALITY_NORMAL, ITEM_QUALITY_UNCOMMON);
else if (level < 40)
itemQuality = urand(ITEM_QUALITY_UNCOMMON, ITEM_QUALITY_RARE);
else if (level < 60)
itemQuality = urand(ITEM_QUALITY_UNCOMMON, ITEM_QUALITY_EPIC);
else if (level < 70)
itemQuality = urand(ITEM_QUALITY_RARE, ITEM_QUALITY_EPIC);
else if (level < 80)
itemQuality = urand(ITEM_QUALITY_RARE, ITEM_QUALITY_EPIC);
else
itemQuality = urand(ITEM_QUALITY_RARE, ITEM_QUALITY_EPIC);
itemQuality = ITEM_QUALITY_RARE;
// if (level < 20)
// itemQuality = urand(ITEM_QUALITY_NORMAL, ITEM_QUALITY_UNCOMMON);
// else if (level < 40)
// itemQuality = urand(ITEM_QUALITY_UNCOMMON, ITEM_QUALITY_RARE);
// else if (level < 60)
// itemQuality = urand(ITEM_QUALITY_UNCOMMON, ITEM_QUALITY_EPIC);
// else if (level < 70)
// itemQuality = urand(ITEM_QUALITY_RARE, ITEM_QUALITY_EPIC);
// else if (level < 80)
// itemQuality = urand(ITEM_QUALITY_RARE, ITEM_QUALITY_EPIC);
// else
// itemQuality = urand(ITEM_QUALITY_RARE, ITEM_QUALITY_EPIC);
}
if (bot->isDead())
@@ -177,6 +178,7 @@ void PlayerbotFactory::Randomize(bool incremental)
pmo = sPerformanceMonitor->start(PERF_MON_RNDBOT, "PlayerbotFactory_Spells1");
LOG_INFO("playerbots", "Initializing spells (step 1)...");
// InitClassSpells();
InitAvailableSpells();
if (pmo)
pmo->finish();
@@ -184,7 +186,7 @@ void PlayerbotFactory::Randomize(bool incremental)
LOG_INFO("playerbots", "Initializing skills (step 1)...");
pmo = sPerformanceMonitor->start(PERF_MON_RNDBOT, "PlayerbotFactory_Skills1");
InitSkills();
InitTradeSkills();
// InitTradeSkills();
if (pmo)
pmo->finish();
@@ -213,7 +215,7 @@ void PlayerbotFactory::Randomize(bool incremental)
pmo = sPerformanceMonitor->start(PERF_MON_RNDBOT, "PlayerbotFactory_Skills2");
LOG_INFO("playerbots", "Initializing skills (step 2)...");
UpdateTradeSkills();
// UpdateTradeSkills();
bot->SaveToDB(false, false);
if (pmo)
pmo->finish();
@@ -281,7 +283,7 @@ void PlayerbotFactory::Randomize(bool incremental)
pmo = sPerformanceMonitor->start(PERF_MON_RNDBOT, "PlayerbotFactory_Inventory");
LOG_INFO("playerbots", "Initializing inventory...");
InitInventory();
// InitInventory();
if (pmo)
pmo->finish();
@@ -1793,6 +1795,100 @@ void PlayerbotFactory::InitAvailableSpells()
bot->learnSpell(20271, false);
}
void PlayerbotFactory::InitClassSpells()
{
int32_t level = bot->getLevel();
switch (bot->getClass())
{
case CLASS_WARRIOR:
bot->learnSpell(78, false);
bot->learnSpell(2457, false);
if (level >= 10) {
bot->learnSpell(71, false); // Defensive Stance
bot->learnSpell(355, false); // Taunt
bot->learnSpell(7386, false); // Sunder Armor
}
if (level >= 30) {
bot->learnSpell(2458, false); // Berserker Stance
}
break;
case CLASS_PALADIN:
bot->learnSpell(21084, false);
bot->learnSpell(635, false);
if (level >= 12) {
bot->learnSpell(7328, false); // Redemption
}
break;
case CLASS_ROGUE:
bot->learnSpell(1752, false);
bot->learnSpell(2098, false);
break;
case CLASS_DEATH_KNIGHT:
bot->learnSpell(45477, false);
bot->learnSpell(47541, false);
bot->learnSpell(45462, false);
bot->learnSpell(45902, false);
//to leave DK starting area
bot->learnSpell(50977, false);
break;
case CLASS_HUNTER:
bot->learnSpell(2973, false);
bot->learnSpell(75, false);
if (level >= 10) {
bot->learnSpell(883, false); // call pet
bot->learnSpell(1515, false); // tame pet
bot->learnSpell(6991, false); // feed pet
bot->learnSpell(982, false); // revive pet
}
break;
case CLASS_PRIEST:
bot->learnSpell(585, false);
bot->learnSpell(2050, false);
break;
case CLASS_MAGE:
bot->learnSpell(133, false);
bot->learnSpell(168, false);
break;
case CLASS_WARLOCK:
bot->learnSpell(687, false);
bot->learnSpell(686, false);
if (level >= 10) {
bot->learnSpell(697, false); // summon voidwalker
}
if (level >= 20) {
bot->learnSpell(712, false); // summon succubus
}
if (level >= 30) {
bot->learnSpell(691, false); // summon felhunter
}
break;
case CLASS_DRUID:
bot->learnSpell(5176, false);
bot->learnSpell(5185, false);
if (level >= 10) {
bot->learnSpell(5487, false); // bear form
bot->learnSpell(6795, false); // Growl
bot->learnSpell(6807, false); // Maul
}
break;
case CLASS_SHAMAN:
bot->learnSpell(403, false);
bot->learnSpell(331, false);
if (level >= 4) {
bot->learnSpell(8071, false); // stoneskin totem
}
if (level >= 10) {
bot->learnSpell(3599, false); // searing totem
}
if (level >= 20) {
bot->learnSpell(5394, false); // healing stream totem
}
break;
default:
break;
}
}
void PlayerbotFactory::InitSpecialSpells()
{
for (std::vector<uint32>::iterator i = sPlayerbotAIConfig->randomBotSpellIds.begin(); i != sPlayerbotAIConfig->randomBotSpellIds.end(); ++i)
@@ -1800,6 +1896,11 @@ void PlayerbotFactory::InitSpecialSpells()
uint32 spellId = *i;
bot->learnSpell(spellId);
}
// to leave DK starting area
if (bot->getClass() == CLASS_DEATH_KNIGHT)
{
bot->learnSpell(50977, false);
}
}
void PlayerbotFactory::InitTalents(uint32 specNo)

View File

@@ -128,6 +128,7 @@ class PlayerbotFactory : public InventoryAction
void ClearSpells();
void ClearSkills();
void InitAvailableSpells();
void InitClassSpells();
void InitSpecialSpells();
void InitTalentsTree(bool incremental);
void InitTalents(uint32 specNo);

View File

@@ -152,7 +152,7 @@ RandomItemMgr::RandomItemMgr()
void RandomItemMgr::Init()
{
BuildItemInfoCache();
BuildEquipCache();
// BuildEquipCache();
BuildAmmoCache();
BuildPotionCache();
BuildFoodCache();
@@ -285,7 +285,7 @@ void RandomItemMgr::BuildRandomItemCache()
if (!proto)
continue;
LOG_INFO("playerbots", " [{}] {}", itemId, proto->Name1.c_str());
LOG_DEBUG("playerbots", " [{}] {}", itemId, proto->Name1.c_str());
}
}
}
@@ -332,30 +332,29 @@ bool RandomItemMgr::CanEquipItem(BotEquipKey key, ItemTemplate const* proto)
requiredLevel = key.level;
uint32 level = key.level;
uint32 delta = 2;
if (level < 15)
delta = urand(7, 15);
else if (proto->Class == ITEM_CLASS_WEAPON || proto->SubClass == ITEM_SUBCLASS_ARMOR_SHIELD)
delta = urand(2, 3);
else if (!(level % 10) || (level % 10) == 9)
delta = 2;
delta = 15;
else if (level < 40)
delta = urand(5, 10);
delta = 10; //urand(5, 10);
else if (level < 60)
delta = urand(3, 7);
delta = 6; // urand(3, 7);
else if (level < 70)
delta = urand(2, 5);
delta = 9; // urand(2, 5);
else if (level < 80)
delta = urand(2, 4);
delta = 9; // urand(2, 4);
else if (level == 80)
delta = 2; // urand(2, 4);
if (key.quality > ITEM_QUALITY_NORMAL && (requiredLevel > level || requiredLevel < level - delta))
return false;
for (uint32 gap = 60; gap <= 80; gap += 10)
{
if (level > gap && requiredLevel <= gap)
return false;
}
// for (uint32 gap = 60; gap <= 80; gap += 10)
// {
// if (level > gap && requiredLevel <= gap)
// return false;
// }
return true;
}
@@ -1026,7 +1025,7 @@ void RandomItemMgr::BuildItemInfoCache()
//statWeight.weight = statW;
// save item statWeight into ItemCache
cacheInfo.weights[statWeight.id] = statWeight.weight;
LOG_INFO("playerbots", "Item: {}, weight: {}, class: {}, spec: {}", proto->ItemId, statWeight.weight, clazz, m_weightScales[clazz][spec].info.name);
LOG_DEBUG("playerbots", "Item: {}, weight: {}, class: {}, spec: {}", proto->ItemId, statWeight.weight, clazz, m_weightScales[clazz][spec].info.name);
}
}
@@ -1051,7 +1050,7 @@ void RandomItemMgr::BuildItemInfoCache()
}
if (cacheInfo.team < TEAM_NEUTRAL)
LOG_INFO("playerbots", "Item: {}, team (item): {}", proto->ItemId, cacheInfo.team == TEAM_ALLIANCE ? "Alliance" : "Horde");
LOG_DEBUG("playerbots", "Item: {}, team (item): {}", proto->ItemId, cacheInfo.team == TEAM_ALLIANCE ? "Alliance" : "Horde");
// check min level
if (proto->RequiredLevel)
@@ -1062,7 +1061,7 @@ void RandomItemMgr::BuildItemInfoCache()
if (proto->Flags & ITEM_FLAG_NO_DISENCHANT)
{
cacheInfo.source = ITEM_SOURCE_PVP;
LOG_INFO("playerbots", "Item: {}, source: PvP Reward", proto->ItemId);
LOG_DEBUG("playerbots", "Item: {}, source: PvP Reward", proto->ItemId);
}
// check quests
@@ -1105,13 +1104,13 @@ void RandomItemMgr::BuildItemInfoCache()
else if (isHorde)
cacheInfo.team = TEAM_HORDE;
LOG_INFO("playerbots", "Item: {}, team (quest): {}", proto->ItemId, cacheInfo.team == TEAM_ALLIANCE ? "Alliance" : cacheInfo.team == TEAM_HORDE ? "Horde" : "Both");
LOG_INFO("playerbots", "Item: {}, source: quest {}, minlevel: {}", proto->ItemId, cacheInfo.sourceId, cacheInfo.minLevel);
LOG_DEBUG("playerbots", "Item: {}, team (quest): {}", proto->ItemId, cacheInfo.team == TEAM_ALLIANCE ? "Alliance" : cacheInfo.team == TEAM_HORDE ? "Horde" : "Both");
LOG_DEBUG("playerbots", "Item: {}, source: quest {}, minlevel: {}", proto->ItemId, cacheInfo.sourceId, cacheInfo.minLevel);
}
}
if (cacheInfo.minLevel)
LOG_INFO("playerbots", "Item: {}, minlevel: {}", proto->ItemId, cacheInfo.minLevel);
LOG_DEBUG("playerbots", "Item: {}, minlevel: {}", proto->ItemId, cacheInfo.minLevel);
// check vendors
if (cacheInfo.source == ITEM_SOURCE_NONE)
@@ -1121,7 +1120,7 @@ void RandomItemMgr::BuildItemInfoCache()
if (proto->ItemId == *i)
{
cacheInfo.source = ITEM_SOURCE_VENDOR;
LOG_INFO("playerbots", "Item: {} source: vendor", proto->ItemId);
LOG_DEBUG("playerbots", "Item: {} source: vendor", proto->ItemId);
break;
}
}
@@ -1149,12 +1148,12 @@ void RandomItemMgr::BuildItemInfoCache()
{
cacheInfo.source = ITEM_SOURCE_DROP;
cacheInfo.sourceId = creatures.front();
LOG_INFO("playerbots", "Item: {}, source: creature drop, ID: {}", proto->ItemId, creatures.front());
LOG_DEBUG("playerbots", "Item: {}, source: creature drop, ID: {}", proto->ItemId, creatures.front());
}
else
{
cacheInfo.source = ITEM_SOURCE_DROP;
LOG_INFO("playerbots", "Item: {}, source: creatures drop, number: {}", proto->ItemId, creatures.size());
LOG_DEBUG("playerbots", "Item: {}, source: creatures drop, number: {}", proto->ItemId, creatures.size());
}
}
}
@@ -1548,9 +1547,9 @@ uint32 RandomItemMgr::CalculateSingleStatWeight(uint8 playerclass, uint8 spec, s
if (stat == i->stat)
{
statWeight = i->weight * value;
if (statWeight)
LOG_INFO("playerbots", "stat: {}, val: {}, weight: {}, total: {}, class: {}, spec: {}",
stat, value, i->weight, statWeight, playerclass, m_weightScales[playerclass][spec].info.name);
// if (statWeight)
// LOG_INFO("playerbots", "stat: {}, val: {}, weight: {}, total: {}, class: {}, spec: {}",
// stat, value, i->weight, statWeight, playerclass, m_weightScales[playerclass][spec].info.name);
return statWeight;
}
}
@@ -2121,7 +2120,7 @@ void RandomItemMgr::BuildEquipCache()
equipCache[key] = items;
LOG_INFO("playerbots", "Equipment cache for class: {}, level {}, slot {}, quality {}: {} items",
LOG_DEBUG("playerbots", "Equipment cache for class: {}, level {}, slot {}, quality {}: {} items",
class_, level, slot, quality, items.size());
}
}
@@ -2134,8 +2133,36 @@ void RandomItemMgr::BuildEquipCache()
RandomItemList RandomItemMgr::Query(uint32 level, uint8 clazz, uint8 slot, uint32 quality)
{
// return equipCache[key];
BotEquipKey key(level, clazz, slot, quality);
return equipCache[key];
RandomItemList items;
ItemTemplateContainer const* itemTemplates = sObjectMgr->GetItemTemplateStore();
for (auto const& itr : *itemTemplates)
{
ItemTemplate const* proto = &itr.second;
if (!proto)
continue;
if (proto->Class != ITEM_CLASS_WEAPON && proto->Class != ITEM_CLASS_ARMOR && proto->Class != ITEM_CLASS_CONTAINER && proto->Class != ITEM_CLASS_PROJECTILE)
continue;
if (!CanEquipItem(key, proto))
continue;
if (proto->Class == ITEM_CLASS_ARMOR && (slot == EQUIPMENT_SLOT_HEAD || slot == EQUIPMENT_SLOT_SHOULDERS || slot == EQUIPMENT_SLOT_CHEST ||
slot == EQUIPMENT_SLOT_WAIST || slot == EQUIPMENT_SLOT_LEGS || slot == EQUIPMENT_SLOT_FEET || slot == EQUIPMENT_SLOT_WRISTS ||
slot == EQUIPMENT_SLOT_HANDS) && !CanEquipArmor(key.clazz, key.level, proto))
continue;
if (proto->Class == ITEM_CLASS_WEAPON && !CanEquipWeapon(key.clazz, proto))
continue;
if (slot == EQUIPMENT_SLOT_OFFHAND && key.clazz == CLASS_ROGUE && proto->Class != ITEM_CLASS_WEAPON)
continue;
items.push_back(itr.first);
}
return items;
}
void RandomItemMgr::BuildAmmoCache()
@@ -2238,7 +2265,7 @@ void RandomItemMgr::BuildPotionCache()
uint32 size = potionCache[level / 10][effect].size();
++counter;
LOG_INFO("server.loading", "Potion cache for level={}, effect={}: {} items", level, effect, size);
LOG_DEBUG("server.loading", "Potion cache for level={}, effect={}: {} items", level, effect, size);
}
}
@@ -2298,7 +2325,7 @@ void RandomItemMgr::BuildFoodCache()
uint32 category = categories[i];
uint32 size = foodCache[level / 10][category].size();
++counter;
LOG_INFO("server.loading", "Food cache for level={}, category={}: {} items", level, category, size);
LOG_DEBUG("server.loading", "Food cache for level={}, category={}: {} items", level, category, size);
}
}
@@ -2414,7 +2441,7 @@ void RandomItemMgr::BuildTradeCache()
for (uint32 level = 1; level <= maxLevel + 1; level += 10)
{
uint32 size = tradeCache[level / 10].size();
LOG_INFO("server.loading", "Trade cache for level={}: {} items", level, size);
LOG_DEBUG("server.loading", "Trade cache for level={}: {} items", level, size);
++counter;
}

View File

@@ -428,7 +428,7 @@ void RandomPlayerbotMgr::LoadBattleMastersCache()
bmTeam = TEAM_HORDE;
BattleMastersCache[bmTeam][BattlegroundTypeId(bgTypeId)].insert(BattleMastersCache[bmTeam][BattlegroundTypeId(bgTypeId)].end(), entry);
LOG_INFO("playerbots", "Cached Battmemaster #{} for BG Type {} ({})", entry, bgTypeId, bmTeam == TEAM_ALLIANCE ? "Alliance" : bmTeam == TEAM_HORDE ? "Horde" : "Neutral");
LOG_DEBUG("playerbots", "Cached Battmemaster #{} for BG Type {} ({})", entry, bgTypeId, bmTeam == TEAM_ALLIANCE ? "Alliance" : bmTeam == TEAM_HORDE ? "Horde" : "Neutral");
} while (result->NextRow());

View File

@@ -140,22 +140,11 @@ bool TalentSpec::CheckTalents(uint32 level, std::ostringstream* out)
//Set the talents for the bots to the current spec.
void TalentSpec::ApplyTalents(Player* bot, std::ostringstream* out)
{
for (auto& entry : talents)
for (uint8 rank = 0; rank < MAX_TALENT_RANK; ++rank)
{
uint32 spellId = entry.talentInfo->RankID[rank];
if (!spellId)
continue;
if (bot->HasSpell(spellId) && entry.rank - 1 != rank)
{
bot->removeSpell(spellId, false, false);
}
else if (!bot->HasSpell(spellId) && entry.rank - 1 == rank)
{
bot->learnSpell(spellId);
}
}
for (auto& entry : talents) {
if (entry.rank == 0)
continue;
bot->LearnTalent(entry.talentInfo->TalentID, entry.rank - 1);
}
}
//Returns a base talentlist for a class.

View File

@@ -643,7 +643,7 @@ void Engine::LogAction(char const* format, ...)
if (sPlayerbotAIConfig->logInGroupOnly && !bot->GetGroup())
return;
LOG_INFO("playerbots", "{} {} {} {}", bot->GetName().c_str(), buf, sPlayerbotAIConfig->logInGroupOnly, bot->GetGroup()->GetGroupType());
LOG_DEBUG("playerbots", "{} {}", bot->GetName().c_str(), buf);
}
}

View File

@@ -188,7 +188,7 @@ bool ChooseRpgTargetAction::Execute(Event event)
if (targets.empty())
{
LOG_INFO("playerbots", "{} can't choose RPG target: all {} are not available", bot->GetName().c_str(), possibleTargets.size());
LOG_DEBUG("playerbots", "{} can't choose RPG target: all {} are not available", bot->GetName().c_str(), possibleTargets.size());
RESET_AI_VALUE(GuidSet&, "ignore rpg target");
RESET_AI_VALUE(GuidPosition, "rpg target");
return false;

View File

@@ -23,7 +23,7 @@ bool FollowAction::Execute(Event event)
WorldLocation loc = formation->GetLocation();
if (Formation::IsNullLocation(loc) || loc.GetMapId() == -1)
return false;
moved = MoveTo(loc.GetMapId(), loc.GetPositionX(), loc.GetPositionY(), loc.GetPositionZ());
}

View File

@@ -128,7 +128,7 @@ bool MovementAction::MoveToLOS(WorldObject* target, bool ranged)
bool MovementAction::MoveTo(uint32 mapId, float x, float y, float z, bool idle, bool react)
{
UpdateMovementState();
LOG_DEBUG("playerbots", "IsMovingAllowed {}", IsMovingAllowed());
if (!IsMovingAllowed())
return false;
@@ -137,6 +137,7 @@ bool MovementAction::MoveTo(uint32 mapId, float x, float y, float z, bool idle,
if (Vehicle* vehicle = bot->GetVehicle())
{
VehicleSeatEntry const* seat = vehicle->GetSeatForPassenger(bot);
LOG_DEBUG("playerbots", "!seat || !seat->CanControl() {}", !seat || !seat->CanControl());
if (!seat || !seat->CanControl())
return false;
@@ -150,6 +151,7 @@ bool MovementAction::MoveTo(uint32 mapId, float x, float y, float z, bool idle,
time_t now = time(nullptr);
if (AI_VALUE(LastMovement&, "last movement").nextTeleport > now) // We can not teleport yet. Wait.
{
LOG_DEBUG("playerbots", "AI_VALUE(LastMovement&, \"last movement\").nextTeleport > now");
botAI->SetNextCheckDelay((AI_VALUE(LastMovement&, "last movement").nextTeleport - now) * 1000);
return true;
}
@@ -169,6 +171,7 @@ bool MovementAction::MoveTo(uint32 mapId, float x, float y, float z, bool idle,
if (!isVehicle && !IsMovingAllowed() && bot->isDead())
{
bot->StopMoving();
LOG_DEBUG("playerbots", "!isVehicle && !IsMovingAllowed() && bot->isDead()");
return false;
}
@@ -176,6 +179,7 @@ bool MovementAction::MoveTo(uint32 mapId, float x, float y, float z, bool idle,
{
if (!bot->HasUnitState(UNIT_STATE_IN_FLIGHT))
bot->StopMoving();
LOG_DEBUG("playerbots", "!isVehicle && bot->isMoving() && !IsMovingAllowed()");
return false;
}
@@ -194,6 +198,7 @@ bool MovementAction::MoveTo(uint32 mapId, float x, float y, float z, bool idle,
AI_VALUE(LastMovement&, "last movement").clear();
mover->StopMoving();
LOG_DEBUG("playerbots", "totalDistance < minDist");
return false;
}
@@ -222,6 +227,7 @@ bool MovementAction::MoveTo(uint32 mapId, float x, float y, float z, bool idle,
else
{
lastMove.future = std::async(&TravelNodeMap::getFullPath, startPosition, endPosition, bot);
LOG_DEBUG("playerbots", "lastMove.future = std::async(&TravelNodeMap::getFullPath, startPosition, endPosition, bot);");
return true;
}
}
@@ -240,6 +246,7 @@ bool MovementAction::MoveTo(uint32 mapId, float x, float y, float z, bool idle,
bot->StopMoving();
if (botAI->HasStrategy("debug move", BOT_STATE_NON_COMBAT))
botAI->TellMasterNoFacing("I have no path");
LOG_DEBUG("playerbots", "sServerFacade->IsDistanceGreaterThan(totalDistance, maxDist * 3)");
return false;
}
@@ -276,7 +283,7 @@ bool MovementAction::MoveTo(uint32 mapId, float x, float y, float z, bool idle,
if (botAI->HasStrategy("debug move", BOT_STATE_NON_COMBAT))
botAI->TellMasterNoFacing("Too far from path. Rebuilding.");
LOG_DEBUG("playerbots", "movePath.empty()");
return true;
}
@@ -318,8 +325,10 @@ bool MovementAction::MoveTo(uint32 mapId, float x, float y, float z, bool idle,
{
AI_VALUE(LastMovement&, "last area trigger").lastAreaTrigger = entry;
}
else
else {
LOG_DEBUG("playerbots", "!entry");
return bot->TeleportTo(movePosition.getMapId(), movePosition.getX(), movePosition.getY(), movePosition.getZ(), movePosition.getO(), 0);
}
}
if (pathType == TravelNodePathType::transport && entry)
@@ -331,6 +340,7 @@ bool MovementAction::MoveTo(uint32 mapId, float x, float y, float z, bool idle,
transport->AddPassenger(bot, true);
}
WaitForReach(100.0f);
LOG_DEBUG("playerbots", "pathType == TravelNodePathType::transport && entry");
return true;
}
@@ -367,7 +377,7 @@ bool MovementAction::MoveTo(uint32 mapId, float x, float y, float z, bool idle,
{
bot->SetMoney(botMoney);
}
LOG_DEBUG("playerbots", "goTaxi");
return goTaxi;
}
}
@@ -384,6 +394,7 @@ bool MovementAction::MoveTo(uint32 mapId, float x, float y, float z, bool idle,
{
movePath.clear();
AI_VALUE(LastMovement&, "last movement").setPath(movePath);
LOG_DEBUG("playerbots", "bot->HasSpellCooldown(8690)");
return false;
}
}
@@ -402,6 +413,7 @@ bool MovementAction::MoveTo(uint32 mapId, float x, float y, float z, bool idle,
if (botAI->HasStrategy("debug move", BOT_STATE_NON_COMBAT))
botAI->TellMasterNoFacing("No point. Rebuilding.");
LOG_DEBUG("playerbots", "!movePosition || movePosition.getMapId() != bot->GetMapId()");
return false;
}
@@ -465,7 +477,7 @@ bool MovementAction::MoveTo(uint32 mapId, float x, float y, float z, bool idle,
sPlayerbotAIConfig->log("bot_movement.csv", out.str().c_str());
}
LOG_DEBUG("playerbots", "({}, {}) -> ({}, {})", startPosition.getX(), startPosition.getY(), movePosition.getX(), movePosition.getY());
if (!react)
if (totalDistance > maxDist)
WaitForReach(startPosition.distance(movePosition) - 10.0f);
@@ -514,7 +526,7 @@ bool MovementAction::MoveTo(uint32 mapId, float x, float y, float z, bool idle,
time_t now = time(nullptr);
AI_VALUE(LastMovement&, "last movement").nextTeleport = now + (time_t)MoveDelay(startPosition.distance(movePosition));
LOG_DEBUG("playerbots", "totalDistance > maxDist && !detailedMove && !botAI->HasPlayerNearby(&movePosition)");
return bot->TeleportTo(movePosition.getMapId(), movePosition.getX(), movePosition.getY(), movePosition.getZ(), startPosition.getAngleTo(movePosition));
}
@@ -530,11 +542,13 @@ bool MovementAction::MoveTo(uint32 mapId, float x, float y, float z, bool idle,
bot->SetWalk(true);
bot->SendMovementFlagUpdate();
LOG_DEBUG("playerbots", "normal move? {} {} {}", !bot->HasAuraType(SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED) && !bot->HasAuraType(SPELL_AURA_FLY),
bot->HasUnitFlag(UNIT_FLAG_DISABLE_MOVE), bot->getStandState());
if (!bot->HasAuraType(SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED) && !bot->HasAuraType(SPELL_AURA_FLY))
{
bot->SetWalk(masterWalking);
bot->GetMotionMaster()->MovePoint(movePosition.getMapId(), movePosition.getX(), movePosition.getY(), movePosition.getZ(), generatePath);
LOG_DEBUG("playerbots", "Movepoint to ({}, {})", movePosition.getX(), movePosition.getY());
}
else
{
@@ -580,6 +594,7 @@ bool MovementAction::MoveTo(uint32 mapId, float x, float y, float z, bool idle,
}
bot->GetMotionMaster()->MovePoint(movePosition.getMapId(), Position(movePosition.getX(), movePosition.getY(), movePosition.getZ(), 0.f));
LOG_DEBUG("playerbots", "Movepoint to ({}, {})", movePosition.getX(), movePosition.getY());
}
AI_VALUE(LastMovement&, "last movement").setShort(movePosition);
@@ -587,6 +602,7 @@ bool MovementAction::MoveTo(uint32 mapId, float x, float y, float z, bool idle,
if (!idle)
ClearIdleState();
LOG_DEBUG("playerbots", "return true in the end");
return true;
}
@@ -990,8 +1006,9 @@ bool MovementAction::ChaseTo(WorldObject* obj, float distance, float angle)
botAI->InterruptSpell();
}
bot->GetMotionMaster()->Clear();
// bot->GetMotionMaster()->Clear();
bot->GetMotionMaster()->MoveChase((Unit*) obj, distance, angle);
WaitForReach(bot->GetExactDist2d(obj) - distance);
return true;
}

View File

@@ -29,8 +29,7 @@ bool DrinkAction::Execute(Event event)
botAI->SetNextCheckDelay(sPlayerbotAIConfig->globalCoolDown);
return false;
}
bot->AddUnitState(UNIT_STAND_STATE_SIT);
bot->SetStandState(UNIT_STAND_STATE_SIT);
botAI->InterruptSpell();
//float hp = bot->GetHealthPercent();
@@ -82,7 +81,7 @@ bool EatAction::Execute(Event event)
return false;
}
bot->AddUnitState(UNIT_STAND_STATE_SIT);
bot->SetStandState(UNIT_STAND_STATE_SIT);
botAI->InterruptSpell();
float hp = bot->GetHealthPct();

View File

@@ -124,7 +124,7 @@ bool AutoReleaseSpiritAction::isUseful()
bool RepopAction::Execute(Event event)
{
LOG_INFO("playerbots", "Bot {} {}:{} <{}> repops at graveyard", bot->GetGUID().ToString().c_str(), bot->GetTeamId() == TEAM_ALLIANCE ? "A" : "H", bot->getLevel(), bot->GetName().c_str());
LOG_DEBUG("playerbots", "Bot {} {}:{} <{}> repops at graveyard", bot->GetGUID().ToString().c_str(), bot->GetTeamId() == TEAM_ALLIANCE ? "A" : "H", bot->getLevel(), bot->GetName().c_str());
int64 deadTime;

View File

@@ -266,7 +266,7 @@ bool UseItemAction::UseItem(Item* item, ObjectGuid goGuid, Item* itemTarget, Uni
if (bot->IsInCombat())
return false;
bot->AddUnitState(UNIT_STAND_STATE_SIT);
bot->SetStandState(UNIT_STAND_STATE_SIT);
botAI->InterruptSpell();
float hp = bot->GetHealthPct();

View File

@@ -53,13 +53,13 @@ bool HunterHasAmmoTrigger::IsActive()
bool SwitchToRangedTrigger::IsActive()
{
Unit* target = AI_VALUE(Unit*, "current target");
return botAI->HasStrategy("close", BOT_STATE_COMBAT) && target && (target->GetVictim() != bot ||
return botAI->HasStrategy("close", BOT_STATE_COMBAT) && target && (target->GetVictim() != bot &&
sServerFacade->IsDistanceGreaterThan(AI_VALUE2(float, "distance", "current target"), 8.0f));
}
bool SwitchToMeleeTrigger::IsActive()
{
Unit* target = AI_VALUE(Unit*, "current target");
return botAI->HasStrategy("ranged", BOT_STATE_COMBAT) && target && (target->GetVictim() == bot ||
return botAI->HasStrategy("ranged", BOT_STATE_COMBAT) && target && (target->GetVictim() == bot &&
sServerFacade->IsDistanceLessOrEqualThan(AI_VALUE2(float, "distance", "current target"), 8.0f));
}

View File

@@ -135,9 +135,10 @@ bool AttackersValue::IsPossibleTarget(Unit* attacker, Player* bot, float range)
bool AttackersValue::IsValidTarget(Unit *attacker, Player *bot)
{
return IsPossibleTarget(attacker, bot) && (attacker->GetThreatMgr().getCurrentVictim() || attacker->GetGuidValue(UNIT_FIELD_TARGET) ||
return IsPossibleTarget(attacker, bot) && (attacker->GetThreatMgr().getCurrentVictim() || attacker->GetGuidValue(UNIT_FIELD_TARGET) ||
attacker->GetGUID().IsPlayer() || attacker->GetGUID() == GET_PLAYERBOT_AI(bot)->GetAiObjectContext()->GetValue<ObjectGuid>("pull target")->Get());
}
bool PossibleAddsValue::Calculate()
{
GuidVector possible = botAI->GetAiObjectContext()->GetValue<GuidVector >("possible targets no los")->Get();

View File

@@ -16,7 +16,7 @@ class Unit;
class AttackersValue : public ObjectGuidListCalculatedValue
{
public:
AttackersValue(PlayerbotAI* botAI) : ObjectGuidListCalculatedValue(botAI, "attackers", 2) { }
AttackersValue(PlayerbotAI* botAI) : ObjectGuidListCalculatedValue(botAI, "attackers", 1) { }
GuidVector Calculate();
static bool IsPossibleTarget(Unit* attacker, Player* bot, float range = sPlayerbotAIConfig->sightDistance);

View File

@@ -15,7 +15,15 @@ bool InvalidTargetValue::Calculate()
if (target && qualifier == "current target")
{
return !AttackersValue::IsValidTarget(target, bot);
return target->GetMapId() != bot->GetMapId() ||
!target->IsAlive() ||
target->IsPolymorphed() ||
target->IsCharmed() ||
target->isFeared() ||
target->HasUnitState(UNIT_STATE_ISOLATED) ||
target->IsFriendlyTo(bot) ||
!bot->IsWithinDistInMap(target, sPlayerbotAIConfig->sightDistance) ||
!bot->IsWithinLOSInMap(target);
}
return !target;