diff --git a/conf/playerbots.conf.dist b/conf/playerbots.conf.dist index 45b98147..b9ff26be 100644 --- a/conf/playerbots.conf.dist +++ b/conf/playerbots.conf.dist @@ -87,7 +87,6 @@ AiPlayerbot.RandomBotShowCloak = 1 AiPlayerbot.DisableRandomLevels = 0 # Set randombots starting level here if "AiPlayerbot.DisableRandomLevels" enabled -# Recommended: 5+ AiPlayerbot.RandombotStartingLevel = 5 # Set kill XP rate for bots (default: 1) @@ -456,7 +455,7 @@ AiPlayerbot.GlobalCooldown = 500 AiPlayerbot.MaxWaitForMove = 5000 # Action expiration time -AiPlayerbot.ExpireActionTime = 500 +AiPlayerbot.ExpireActionTime = 5000 # Max dispel auras duration AiPlayerbot.DispelAuraDuration = 700 @@ -549,8 +548,8 @@ AiPlayerbot.PvpProhibitedZoneIds = "2255,656,2361,2362,2363,976,35,2268,3425,392 AiPlayerbot.RandomBotSpellIds = "54197" # Level diff between random bots and nearby creatures for random teleports -AiPlayerbot.randomBotTeleLowerLevel = 3 -AiPlayerbot.randomBotTeleHigerLevel = 1 +AiPlayerbot.RandomBotTeleLowerLevel = 3 +AiPlayerbot.RandomBotTeleHigherLevel = 1 # ID of spell to open lootable chests AiPlayerbot.OpenGoSpell = 6477 @@ -609,7 +608,7 @@ AiPlayerbot.BotCheats = "taxi" AiPlayerbot.RandomBotRandomPassword = 0 # Set RandomBotMaxLevel bots to RandomBotMinLevel or not -AiPlayerbot.DowngradeMaxLevelBot = 1 +AiPlayerbot.DowngradeMaxLevelBot = 0 ################################################################################## # # diff --git a/src/AiFactory.cpp b/src/AiFactory.cpp index ac1c7139..733da71d 100644 --- a/src/AiFactory.cpp +++ b/src/AiFactory.cpp @@ -552,7 +552,7 @@ void AiFactory::AddDefaultNonCombatStrategies(Player* player, PlayerbotAI* const if (sPlayerbotAIConfig->autoDoQuests) { - nonCombatEngine->addStrategy("travel"); + // nonCombatEngine->addStrategy("travel"); nonCombatEngine->addStrategy("rpg"); } else { nonCombatEngine->addStrategy("move random"); @@ -583,7 +583,7 @@ void AiFactory::AddDefaultNonCombatStrategies(Player* player, PlayerbotAI* const if (sPlayerbotAIConfig->autoDoQuests) { - nonCombatEngine->addStrategy("travel"); + // nonCombatEngine->addStrategy("travel"); nonCombatEngine->addStrategy("rpg"); } else { nonCombatEngine->addStrategy("move random"); diff --git a/src/PlayerbotAI.cpp b/src/PlayerbotAI.cpp index b42adbcb..0b0c410a 100644 --- a/src/PlayerbotAI.cpp +++ b/src/PlayerbotAI.cpp @@ -261,9 +261,7 @@ void PlayerbotAI::UpdateAI(uint32 elapsed, bool minimal) } bool min = minimal; - UpdateAIInternal(elapsed, min); - inCombat = bot->IsInCombat(); // test fix lags because of BG if (bot && !inCombat) @@ -272,6 +270,8 @@ void PlayerbotAI::UpdateAI(uint32 elapsed, bool minimal) if (HasRealPlayerMaster()) min = false; + + YieldThread(min); } @@ -1972,18 +1972,18 @@ bool PlayerbotAI::CanCastSpell(std::string const name, Unit* target, Item* itemT bool PlayerbotAI::CanCastSpell(uint32 spellid, Unit* target, bool checkHasSpell, Item* itemTarget) { if (!spellid) { - if (!sPlayerbotAIConfig->logInGroupOnly || bot->GetGroup()) { - LOG_DEBUG("playerbots", "Can cast spell failed. No spellid. - spellid: {}, bot name: {}", - spellid, bot->GetName()); - } + // if (!sPlayerbotAIConfig->logInGroupOnly || (bot->GetGroup() && HasRealPlayerMaster())) { + // LOG_DEBUG("playerbots", "Can cast spell failed. No spellid. - spellid: {}, bot name: {}", + // spellid, bot->GetName()); + // } return false; } if (bot->HasUnitState(UNIT_STATE_LOST_CONTROL)) { - if (!sPlayerbotAIConfig->logInGroupOnly || bot->GetGroup()) { - LOG_DEBUG("playerbots", "Can cast spell failed. Unit state lost control. - spellid: {}, bot name: {}", - spellid, bot->GetName()); - } + // if (!sPlayerbotAIConfig->logInGroupOnly || bot->GetGroup()) { + // LOG_DEBUG("playerbots", "Can cast spell failed. Unit state lost control. - spellid: {}, bot name: {}", + // spellid, bot->GetName()); + // } return false; } @@ -1991,19 +1991,19 @@ bool PlayerbotAI::CanCastSpell(uint32 spellid, Unit* target, bool checkHasSpell, if (!target) target = bot; - if (!sPlayerbotAIConfig->logInGroupOnly || bot->GetGroup()) - LOG_DEBUG("playerbots", "Can cast spell? - target name: {}, spellid: {}, bot name: {}", - target->GetName(), spellid, bot->GetName()); + // if (!sPlayerbotAIConfig->logInGroupOnly || bot->GetGroup()) + // LOG_DEBUG("playerbots", "Can cast spell? - target name: {}, spellid: {}, bot name: {}", + // target->GetName(), spellid, bot->GetName()); if (Pet* pet = bot->GetPet()) if (pet->HasSpell(spellid)) return true; if (checkHasSpell && !bot->HasSpell(spellid)) { - if (!sPlayerbotAIConfig->logInGroupOnly || bot->GetGroup()) { - LOG_DEBUG("playerbots", "Can cast spell failed. Bot not has spell. - target name: {}, spellid: {}, bot name: {}", - target->GetName(), spellid, bot->GetName()); - } + // if (!sPlayerbotAIConfig->logInGroupOnly || bot->GetGroup()) { + // LOG_DEBUG("playerbots", "Can cast spell failed. Bot not has spell. - target name: {}, spellid: {}, bot name: {}", + // target->GetName(), spellid, bot->GetName()); + // } return false; } @@ -2014,28 +2014,28 @@ bool PlayerbotAI::CanCastSpell(uint32 spellid, Unit* target, bool checkHasSpell, } if (bot->HasSpellCooldown(spellid)) { - if (!sPlayerbotAIConfig->logInGroupOnly || bot->GetGroup()) { - LOG_DEBUG("playerbots", "Can cast spell failed. Spell not has cooldown. - target name: {}, spellid: {}, bot name: {}", - target->GetName(), spellid, bot->GetName()); - } + // if (!sPlayerbotAIConfig->logInGroupOnly || bot->GetGroup()) { + // LOG_DEBUG("playerbots", "Can cast spell failed. Spell not has cooldown. - target name: {}, spellid: {}, bot name: {}", + // target->GetName(), spellid, bot->GetName()); + // } return false; } SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellid); if (!spellInfo) { - if (!sPlayerbotAIConfig->logInGroupOnly || bot->GetGroup()) { - LOG_DEBUG("playerbots", "Can cast spell failed. No spellInfo. - target name: {}, spellid: {}, bot name: {}", - target->GetName(), spellid, bot->GetName()); - } + // if (!sPlayerbotAIConfig->logInGroupOnly || bot->GetGroup()) { + // LOG_DEBUG("playerbots", "Can cast spell failed. No spellInfo. - target name: {}, spellid: {}, bot name: {}", + // target->GetName(), spellid, bot->GetName()); + // } return false; } uint32 CastingTime = !spellInfo->IsChanneled() ? spellInfo->CalcCastTime(bot) : spellInfo->GetDuration(); if (CastingTime && bot->isMoving()) { - if (!sPlayerbotAIConfig->logInGroupOnly || bot->GetGroup()) { - LOG_DEBUG("playerbots", "Casting time and bot is moving - target name: {}, spellid: {}, bot name: {}", - target->GetName(), spellid, bot->GetName()); - } + // if (!sPlayerbotAIConfig->logInGroupOnly || bot->GetGroup()) { + // LOG_DEBUG("playerbots", "Casting time and bot is moving - target name: {}, spellid: {}, bot name: {}", + // target->GetName(), spellid, bot->GetName()); + // } return false; } @@ -2059,10 +2059,10 @@ bool PlayerbotAI::CanCastSpell(uint32 spellid, Unit* target, bool checkHasSpell, // } if (target->IsImmunedToSpell(spellInfo)) { - if (!sPlayerbotAIConfig->logInGroupOnly || bot->GetGroup()) { - LOG_DEBUG("playerbots", "target is immuned to spell - target name: {}, spellid: {}, bot name: {}", - target->GetName(), spellid, bot->GetName()); - } + // if (!sPlayerbotAIConfig->logInGroupOnly || bot->GetGroup()) { + // LOG_DEBUG("playerbots", "target is immuned to spell - target name: {}, spellid: {}, bot name: {}", + // target->GetName(), spellid, bot->GetName()); + // } return false; } @@ -2081,10 +2081,10 @@ bool PlayerbotAI::CanCastSpell(uint32 spellid, Unit* target, bool checkHasSpell, // } if (bot != target && sServerFacade->GetDistance2d(bot, target) > sPlayerbotAIConfig->sightDistance) { - if (!sPlayerbotAIConfig->logInGroupOnly || bot->GetGroup()) { - LOG_DEBUG("playerbots", "target is out of sight distance - target name: {}, spellid: {}, bot name: {}", - target->GetName(), spellid, bot->GetName()); - } + // if (!sPlayerbotAIConfig->logInGroupOnly || bot->GetGroup()) { + // LOG_DEBUG("playerbots", "target is out of sight distance - target name: {}, spellid: {}, bot name: {}", + // target->GetName(), spellid, bot->GetName()); + // } return false; } } @@ -2100,12 +2100,12 @@ bool PlayerbotAI::CanCastSpell(uint32 spellid, Unit* target, bool checkHasSpell, SpellCastResult result = spell->CheckCast(true); delete spell; - if (!sPlayerbotAIConfig->logInGroupOnly || bot->GetGroup()) { - if (result != SPELL_FAILED_NOT_READY && result != SPELL_CAST_OK) { - LOG_DEBUG("playerbots", "CanCastSpell - target name: {}, spellid: {}, bot name: {}, result: {}", - target->GetName(), spellid, bot->GetName(), result); - } - } + // if (!sPlayerbotAIConfig->logInGroupOnly || bot->GetGroup()) { + // if (result != SPELL_FAILED_NOT_READY && result != SPELL_CAST_OK) { + // LOG_DEBUG("playerbots", "CanCastSpell - target name: {}, spellid: {}, bot name: {}, result: {}", + // target->GetName(), spellid, bot->GetName(), result); + // } + // } if (oldSel) bot->SetSelection(oldSel->GetGUID()); @@ -2286,10 +2286,10 @@ bool PlayerbotAI::CastSpell(uint32 spellId, Unit* target, Item* itemTarget) aiObjectContext->GetValue("stay time")->Set(0); if (bot->IsFlying() || bot->HasUnitState(UNIT_STATE_IN_FLIGHT)) { - if (!sPlayerbotAIConfig->logInGroupOnly || bot->GetGroup()) { - LOG_DEBUG("playerbots", "Spell cast is flying - target name: {}, spellid: {}, bot name: {}}", - target->GetName(), spellId, bot->GetName()); - } + // if (!sPlayerbotAIConfig->logInGroupOnly || bot->GetGroup()) { + // LOG_DEBUG("playerbots", "Spell cast is flying - target name: {}, spellid: {}, bot name: {}}", + // target->GetName(), spellId, bot->GetName()); + // } return false; } @@ -2316,10 +2316,10 @@ bool PlayerbotAI::CastSpell(uint32 spellId, Unit* target, Item* itemTarget) if (failWithDelay) { SetNextCheckDelay(sPlayerbotAIConfig->globalCoolDown); - if (!sPlayerbotAIConfig->logInGroupOnly || bot->GetGroup()) { - LOG_DEBUG("playerbots", "Spell cast fail with delay - target name: {}, spellid: {}, bot name: {}", - target->GetName(), spellId, bot->GetName()); - } + // if (!sPlayerbotAIConfig->logInGroupOnly || bot->GetGroup()) { + // LOG_DEBUG("playerbots", "Spell cast fail with delay - target name: {}, spellid: {}, bot name: {}", + // target->GetName(), spellId, bot->GetName()); + // } return false; } @@ -2335,10 +2335,10 @@ bool PlayerbotAI::CastSpell(uint32 spellId, Unit* target, Item* itemTarget) { bot->GetTradeData()->SetSpell(spellId); delete spell; - if (!sPlayerbotAIConfig->logInGroupOnly || bot->GetGroup()) { - LOG_DEBUG("playerbots", "Spell cast no item - target name: {}, spellid: {}, bot name: {}", - target->GetName(), spellId, bot->GetName()); - } + // if (!sPlayerbotAIConfig->logInGroupOnly || bot->GetGroup()) { + // LOG_DEBUG("playerbots", "Spell cast no item - target name: {}, spellid: {}, bot name: {}", + // target->GetName(), spellId, bot->GetName()); + // } return true; } } @@ -2400,10 +2400,10 @@ bool PlayerbotAI::CastSpell(uint32 spellId, Unit* target, Item* itemTarget) SpellCastResult result = spell->prepare(&targets); if (result != SPELL_CAST_OK) { - if (!sPlayerbotAIConfig->logInGroupOnly || bot->GetGroup()) { - LOG_DEBUG("playerbots", "Spell cast failed. - target name: {}, spellid: {}, bot name: {}, result: {}", - target->GetName(), spellId, bot->GetName(), result); - } + // if (!sPlayerbotAIConfig->logInGroupOnly || bot->GetGroup()) { + // LOG_DEBUG("playerbots", "Spell cast failed. - target name: {}, spellid: {}, bot name: {}, result: {}", + // target->GetName(), spellId, bot->GetName(), result); + // } return false; } // if (spellInfo->Effects[0].Effect == SPELL_EFFECT_OPEN_LOCK || spellInfo->Effects[0].Effect == SPELL_EFFECT_SKINNING) diff --git a/src/PlayerbotAIConfig.cpp b/src/PlayerbotAIConfig.cpp index 02d565c7..db30eda1 100644 --- a/src/PlayerbotAIConfig.cpp +++ b/src/PlayerbotAIConfig.cpp @@ -138,7 +138,7 @@ bool PlayerbotAIConfig::Initialize() randomBotMaxLevel = sConfigMgr->GetOption("AiPlayerbot.RandomBotMaxLevel", 80); randomBotLoginAtStartup = sConfigMgr->GetOption("AiPlayerbot.RandomBotLoginAtStartup", true); randomBotTeleLowerLevel = sConfigMgr->GetOption("AiPlayerbot.RandomBotTeleLowerLevel", 3); - randomBotTeleHigerLevel = sConfigMgr->GetOption("AiPlayerbot.RandomBotTeleHigerLevel", 1); + randomBotTeleHigherLevel = sConfigMgr->GetOption("AiPlayerbot.RandomBotTeleHigherLevel", 1); openGoSpell = sConfigMgr->GetOption("AiPlayerbot.OpenGoSpell", 6477); randomChangeMultiplier = sConfigMgr->GetOption("AiPlayerbot.RandomChangeMultiplier", 1.0); diff --git a/src/PlayerbotAIConfig.h b/src/PlayerbotAIConfig.h index 57639f76..94d39147 100644 --- a/src/PlayerbotAIConfig.h +++ b/src/PlayerbotAIConfig.h @@ -76,7 +76,7 @@ class PlayerbotAIConfig bool randomBotJoinBG; bool randomBotAutoJoinBG; bool randomBotLoginAtStartup; - uint32 randomBotTeleLowerLevel, randomBotTeleHigerLevel; + uint32 randomBotTeleLowerLevel, randomBotTeleHigherLevel; bool logInGroupOnly, logValuesPerTick; bool fleeingEnabled; bool summonAtInnkeepersEnabled; diff --git a/src/PlayerbotFactory.cpp b/src/PlayerbotFactory.cpp index 840f34d7..d31990ca 100644 --- a/src/PlayerbotFactory.cpp +++ b/src/PlayerbotFactory.cpp @@ -9,6 +9,7 @@ #include "GuildMgr.h" #include "MapMgr.h" #include "PetDefines.h" +#include "PlayerbotAIConfig.h" #include "Playerbots.h" #include "PerformanceMonitor.h" #include "PlayerbotDbStore.h" @@ -81,11 +82,7 @@ void PlayerbotFactory::Prepare() { if (!itemQuality) { - // if (level < 80) { itemQuality = ITEM_QUALITY_RARE; - // } else { - // itemQuality = ITEM_QUALITY_EPIC; - // } } if (bot->isDead()) @@ -93,16 +90,8 @@ void PlayerbotFactory::Prepare() bot->CombatStop(true); - if (!sPlayerbotAIConfig->disableRandomLevels) - { - bot->GiveLevel(level); - // bot->SetLevel(level); - } - else if (bot->getLevel() < sPlayerbotAIConfig->randombotStartingLevel) - { - bot->SetLevel(sPlayerbotAIConfig->randombotStartingLevel); - } - + bot->GiveLevel(level); + bot->SetUInt32Value(PLAYER_XP, 0); if (!sPlayerbotAIConfig->randomBotShowHelmet || !urand(0, 4)) { bot->SetFlag(PLAYER_FLAGS, PLAYER_FLAGS_HIDE_HELM); @@ -123,8 +112,6 @@ void PlayerbotFactory::Randomize(bool incremental) LOG_INFO("playerbots", "Preparing to {} randomize...", (incremental ? "incremental" : "full")); Prepare(); - // bot->SaveToDB(false, false); - // bot->SaveToDB(false, false); LOG_INFO("playerbots", "Resetting player..."); PerformanceMonitorOperation* pmo = sPerformanceMonitor->start(PERF_MON_RNDBOT, "PlayerbotFactory_Reset"); bot->resetTalents(true); @@ -163,14 +150,9 @@ void PlayerbotFactory::Randomize(bool incremental) InitQuests(specialQuestIds); // quest rewards boost bot level, so reduce back - if (!sPlayerbotAIConfig->disableRandomLevels) - { - bot->SetLevel(level); - } - else if (bot->getLevel() < sPlayerbotAIConfig->randombotStartingLevel) - { - bot->SetLevel(sPlayerbotAIConfig->randombotStartingLevel); - } + + bot->GiveLevel(level); + ClearInventory(); bot->SetUInt32Value(PLAYER_XP, 0); @@ -285,14 +267,14 @@ void PlayerbotFactory::Randomize(bool incremental) if (pmo) pmo->finish(); - // if (bot->getLevel() >= sPlayerbotAIConfig->minEnchantingBotLevel) - // { - // pmo = sPerformanceMonitor->start(PERF_MON_RNDBOT, "PlayerbotFactory_EnchantTemplate"); - // LOG_INFO("playerbots", "Initializing enchant templates..."); - // ApplyEnchantTemplate(); - // if (pmo) - // pmo->finish(); - // } + if (bot->getLevel() >= sPlayerbotAIConfig->minEnchantingBotLevel) + { + pmo = sPerformanceMonitor->start(PERF_MON_RNDBOT, "PlayerbotFactory_EnchantTemplate"); + LOG_INFO("playerbots", "Initializing enchant templates..."); + ApplyEnchantTemplate(); + if (pmo) + pmo->finish(); + } pmo = sPerformanceMonitor->start(PERF_MON_RNDBOT, "PlayerbotFactory_Inventory"); LOG_INFO("playerbots", "Initializing inventory..."); @@ -323,7 +305,10 @@ void PlayerbotFactory::Randomize(bool incremental) pmo->finish(); } - bot->RemovePet(nullptr, PET_SAVE_AS_CURRENT, true); + if (!incremental) { + bot->RemovePet(nullptr, PET_SAVE_AS_CURRENT, true); + bot->RemovePet(nullptr, PET_SAVE_NOT_IN_SLOT, true); + } if (bot->getLevel() >= 10) { pmo = sPerformanceMonitor->start(PERF_MON_RNDBOT, "PlayerbotFactory_Pet"); @@ -346,8 +331,9 @@ void PlayerbotFactory::Randomize(bool incremental) void PlayerbotFactory::Refresh() { - Prepare(); + // Prepare(); // InitEquipment(true); + ClearInventory(); InitAmmo(); InitFood(); InitReagents(); @@ -356,17 +342,12 @@ void PlayerbotFactory::Refresh() InitClassSpells(); InitAvailableSpells(); bot->DurabilityRepairAll(false, 1.0f, false); + if (bot->isDead()) + bot->ResurrectPlayer(1.0f, false); uint32 money = urand(level * 1000, level * 5 * 1000); if (bot->GetMoney() < money) bot->SetMoney(money); bot->SaveToDB(false, false); - - // Prepare(); - // InitAmmo(); - // InitFood(); - // InitPotions(); - - //bot->SaveToDB(); } void PlayerbotFactory::AddConsumables() @@ -656,6 +637,8 @@ void PlayerbotFactory::ClearSkills() void PlayerbotFactory::ClearEverything() { bot->SaveToDB(false, false); + bot->GiveLevel(bot->getClass() == CLASS_DEATH_KNIGHT ? sWorld->getIntConfig(CONFIG_START_HEROIC_PLAYER_LEVEL) : sWorld->getIntConfig(CONFIG_START_PLAYER_LEVEL)); + bot->SetUInt32Value(PLAYER_XP, 0); LOG_INFO("playerbots", "Resetting player..."); bot->resetTalents(true); bot->SaveToDB(false, false); @@ -1166,6 +1149,7 @@ void PlayerbotFactory::InitEquipmentNew(bool incremental) void PlayerbotFactory::InitEquipment(bool incremental) { + // todo(yunfan): to be refactored, too much time overhead DestroyItemsVisitor visitor(bot); IterateItems(&visitor, ITERATE_ALL_ITEMS); @@ -1218,7 +1202,7 @@ void PlayerbotFactory::InitEquipment(bool incremental) if (slot == EQUIPMENT_SLOT_OFFHAND && bot->getClass() == CLASS_ROGUE && proto->Class != ITEM_CLASS_WEAPON) continue; - + uint16 dest = 0; if (CanEquipUnseenItem(slot, dest, itemId)) items[slot].push_back(itemId); @@ -1234,13 +1218,11 @@ void PlayerbotFactory::InitEquipment(bool incremental) std::vector& ids = items[slot]; if (ids.empty()) { - sLog->outMessage("playerbot", LOG_LEVEL_DEBUG, "%s: no items to equip for slot %d", bot->GetName().c_str(), slot); continue; } Item* oldItem = bot->GetItemByPos(INVENTORY_SLOT_BAG_0, slot); if (incremental && !IsDesiredReplacement(oldItem)) { - sLog->outMessage("playerbot", LOG_LEVEL_DEBUG, "%s: doesn't desire to replace current slot %d", bot->GetName().c_str(), slot); continue; } @@ -1262,7 +1244,6 @@ void PlayerbotFactory::InitEquipment(bool incremental) } } if (bestItemForSlot == 0) { - // sLog->outMessage("playerbot", LOG_LEVEL_INFO, "%s: equip failed for slot %d(bestItemForSlot == 0))", bot->GetName().c_str(), slot); continue; } if (oldItem) @@ -1272,7 +1253,6 @@ void PlayerbotFactory::InitEquipment(bool incremental) } uint16 dest; if (!CanEquipUnseenItem(slot, dest, bestItemForSlot)) { - sLog->outMessage("playerbot", LOG_LEVEL_DEBUG, "%s: equip failed for slot %d", bot->GetName().c_str(), slot); continue; } Item* newItem = bot->EquipNewItem(dest, bestItemForSlot, true); diff --git a/src/RandomPlayerbotMgr.cpp b/src/RandomPlayerbotMgr.cpp index f5239185..31c195ba 100644 --- a/src/RandomPlayerbotMgr.cpp +++ b/src/RandomPlayerbotMgr.cpp @@ -942,8 +942,8 @@ bool RandomPlayerbotMgr::ProcessBot(Player* player) if (!teleport) { LOG_INFO("players", "Bot #{} <{}>: teleport for level and refresh", bot, player->GetName()); - RandomTeleportForLevel(player); Refresh(player); + RandomTeleportForLevel(player); uint32 time = urand(sPlayerbotAIConfig->minRandomBotTeleportInterval, sPlayerbotAIConfig->maxRandomBotTeleportInterval); ScheduleTeleport(bot, time); return true; @@ -1112,8 +1112,7 @@ void RandomPlayerbotMgr::PrepareTeleportCache() "WITH GroupedData AS ( " "SELECT " "MIN( c.guid ) guid, " - "( " - "AVG( t.maxlevel ) + AVG( t.minlevel )) / 2 lvl " + "(AVG( t.maxlevel ) + AVG( t.minlevel )) / 2 lvl " "FROM " "creature c " "INNER JOIN creature_template t ON c.id1 = t.entry " @@ -1122,12 +1121,12 @@ void RandomPlayerbotMgr::PrepareTeleportCache() "AND t.lootid != 0 " "AND t.unit_flags != 768 " "AND map IN ({}) " - "AND t.maxlevel != 1 " + "AND c.id1 != 32820 " "GROUP BY " "map, " - "ROUND( position_x / 250 ) * 250, " - "ROUND( position_y / 250 ) * 250, " - "ROUND( position_z / 5 ) * 5 " + "ROUND( position_x / 500 ), " + "ROUND( position_y / 500 ), " + "ROUND( position_z / 50 ) " "HAVING " "count(*) > 10 " "AND MAX( t.maxlevel ) - MIN( t.minlevel ) < 5 " @@ -1157,7 +1156,7 @@ void RandomPlayerbotMgr::PrepareTeleportCache() uint32 avg_level = fields[4].Get(); WorldLocation loc(mapId, x, y, z, 0); collected_locs++; - for (int32 level = (int32)avg_level - (int32)sPlayerbotAIConfig->randomBotTeleHigerLevel; level <= (int32)avg_level + (int32)sPlayerbotAIConfig->randomBotTeleLowerLevel; level++) { + for (int32 level = (int32)avg_level - (int32)sPlayerbotAIConfig->randomBotTeleHigherLevel; level <= (int32)avg_level + (int32)sPlayerbotAIConfig->randomBotTeleLowerLevel; level++) { if (level < 1 || level > maxLevel) { continue; } @@ -1167,36 +1166,38 @@ void RandomPlayerbotMgr::PrepareTeleportCache() } LOG_INFO("playerbots", "{} locations for level collected.", collected_locs); - LOG_INFO("playerbots", "Preparing RPG teleport caches for {} factions...", sFactionTemplateStore.GetNumRows()); - results = WorldDatabase.Query("SELECT map, position_x, position_y, position_z, r.race, r.minl, r.maxl FROM creature c INNER JOIN playerbots_rpg_races r ON c.id1 = r.entry " - "WHERE r.race < 15"); - if (results) - { - do - { - Field* fields = results->Fetch(); - uint16 mapId = fields[0].Get(); - float x = fields[1].Get(); - float y = fields[2].Get(); - float z = fields[3].Get(); - uint32 race = fields[4].Get(); - uint32 minl = fields[5].Get(); - uint32 maxl = fields[6].Get(); + // temporary only use locsPerLevelCache, so disable rpgLocsCacheLevel cache - for (uint32 level = 1; level < sPlayerbotAIConfig->randomBotMaxLevel + 1; level++) - { - if (level > maxl || level < minl) - continue; + // LOG_INFO("playerbots", "Preparing RPG teleport caches for {} factions...", sFactionTemplateStore.GetNumRows()); + // results = WorldDatabase.Query("SELECT map, position_x, position_y, position_z, r.race, r.minl, r.maxl FROM creature c INNER JOIN playerbots_rpg_races r ON c.id1 = r.entry " + // "WHERE r.race < 15"); + // if (results) + // { + // do + // { + // Field* fields = results->Fetch(); + // uint16 mapId = fields[0].Get(); + // float x = fields[1].Get(); + // float y = fields[2].Get(); + // float z = fields[3].Get(); + // uint32 race = fields[4].Get(); + // uint32 minl = fields[5].Get(); + // uint32 maxl = fields[6].Get(); - WorldLocation loc(mapId, x, y, z, 0); - for (uint32 r = 1; r < MAX_RACES; r++) - { - if (race == r || race == 0) - rpgLocsCacheLevel[r][level].push_back(loc); - } - } - } while (results->NextRow()); - } + // for (uint32 level = 1; level < sPlayerbotAIConfig->randomBotMaxLevel + 1; level++) + // { + // if (level > maxl || level < minl) + // continue; + + // WorldLocation loc(mapId, x, y, z, 0); + // for (uint32 r = 1; r < MAX_RACES; r++) + // { + // if (race == r || race == 0) + // rpgLocsCacheLevel[r][level].push_back(loc); + // } + // } + // } while (results->NextRow()); + // } } void RandomPlayerbotMgr::RandomTeleportForLevel(Player* bot) @@ -1254,12 +1255,12 @@ void RandomPlayerbotMgr::Randomize(Player* bot) if (bot->InBattleground()) return; - if (bot->getLevel() < 3) + if (bot->getLevel() < 2 || (bot->getLevel() < 56 && bot->getClass() == CLASS_DEATH_KNIGHT)) { RandomizeFirst(bot); - else if (bot->getLevel() < 57 && bot->getClass() == CLASS_DEATH_KNIGHT) - RandomizeFirst(bot); - else if (bot->getLevel() < sPlayerbotAIConfig->randomBotMaxLevel || !sPlayerbotAIConfig->downgradeMaxLevelBot) + } + else if (bot->getLevel() < sPlayerbotAIConfig->randomBotMaxLevel || !sPlayerbotAIConfig->downgradeMaxLevelBot) { IncreaseLevel(bot); + } else { RandomizeFirst(bot); } @@ -1274,7 +1275,10 @@ void RandomPlayerbotMgr::IncreaseLevel(Player* bot) PerformanceMonitorOperation* pmo = sPerformanceMonitor->start(PERF_MON_RNDBOT, "IncreaseLevel"); uint32 lastLevel = GetValue(bot, "level"); - uint32 level = bot->getLevel(); + uint8 level = bot->getLevel() + 1; + if (level > maxLevel) { + level = maxLevel; + } if (lastLevel != level) { PlayerbotFactory factory(bot, level); @@ -1314,6 +1318,12 @@ void RandomPlayerbotMgr::RandomizeFirst(Player* bot) level = urand(std::max(sPlayerbotAIConfig->randomBotMinLevel, sWorld->getIntConfig(CONFIG_START_HEROIC_PLAYER_LEVEL)), std::max(sWorld->getIntConfig(CONFIG_START_HEROIC_PLAYER_LEVEL), maxLevel)); } + if (sPlayerbotAIConfig->disableRandomLevels) { + level = bot->getClass() == CLASS_DEATH_KNIGHT ? + std::max(sPlayerbotAIConfig->randombotStartingLevel, sWorld->getIntConfig(CONFIG_START_HEROIC_PLAYER_LEVEL)) : + sPlayerbotAIConfig->randombotStartingLevel; + } + SetValue(bot, "level", level); PlayerbotFactory factory(bot, level); @@ -1336,7 +1346,6 @@ void RandomPlayerbotMgr::RandomizeFirst(Player* bot) // teleport to a random inn for bot level GET_PLAYERBOT_AI(bot)->Reset(true); -// RandomTeleportForRpg(bot); if (bot->GetGroup()) bot->RemoveFromGroup(); @@ -1345,6 +1354,41 @@ void RandomPlayerbotMgr::RandomizeFirst(Player* bot) pmo->finish(); } +void RandomPlayerbotMgr::RandomizeMin(Player* bot) +{ + PerformanceMonitorOperation* pmo = sPerformanceMonitor->start(PERF_MON_RNDBOT, "RandomizeMin"); + + uint32 level = sPlayerbotAIConfig->randomBotMinLevel; + + SetValue(bot, "level", level); + + PlayerbotFactory factory(bot, level); + factory.Randomize(false); + + uint32 randomTime = urand(sPlayerbotAIConfig->minRandomBotRandomizeTime, sPlayerbotAIConfig->maxRandomBotRandomizeTime); + uint32 inworldTime = urand(sPlayerbotAIConfig->minRandomBotInWorldTime, sPlayerbotAIConfig->maxRandomBotInWorldTime); + + PlayerbotsDatabasePreparedStatement* stmt = PlayerbotsDatabase.GetPreparedStatement(PLAYERBOTS_UPD_RANDOM_BOTS); + stmt->SetData(0, randomTime); + stmt->SetData(1, "bot_delete"); + stmt->SetData(2, bot->GetGUID().GetCounter()); + PlayerbotsDatabase.Execute(stmt); + + stmt = PlayerbotsDatabase.GetPreparedStatement(PLAYERBOTS_UPD_RANDOM_BOTS); + stmt->SetData(0, inworldTime); + stmt->SetData(1, "logout"); + stmt->SetData(2, bot->GetGUID().GetCounter()); + PlayerbotsDatabase.Execute(stmt); + + // teleport to a random inn for bot level + GET_PLAYERBOT_AI(bot)->Reset(true); + if (bot->GetGroup()) + bot->RemoveFromGroup(); + + if (pmo) + pmo->finish(); +} + void RandomPlayerbotMgr::Clear(Player* bot) { PlayerbotFactory factory(bot, bot->GetLevel()); @@ -1418,6 +1462,9 @@ void RandomPlayerbotMgr::Refresh(Player* bot) uint32 money = bot->GetMoney(); bot->SetMoney(money + 500 * sqrt(urand(1, bot->getLevel() * 5))); + if (bot->GetGroup()) + bot->RemoveFromGroup(); + if (pmo) pmo->finish(); } @@ -1660,12 +1707,13 @@ bool RandomPlayerbotMgr::HandlePlayerbotConsoleCommand(ChatHandler* handler, cha } std::map handlers; + // handlers["initmin"] = &RandomPlayerbotMgr::RandomizeMin; handlers["init"] = &RandomPlayerbotMgr::RandomizeFirst; handlers["clear"] = &RandomPlayerbotMgr::Clear; handlers["levelup"] = handlers["level"] = &RandomPlayerbotMgr::IncreaseLevel; handlers["refresh"] = &RandomPlayerbotMgr::Refresh; handlers["teleport"] = &RandomPlayerbotMgr::RandomTeleportForLevel; - handlers["rpg"] = &RandomPlayerbotMgr::RandomTeleportForRpg; + // handlers["rpg"] = &RandomPlayerbotMgr::RandomTeleportForRpg; handlers["revive"] = &RandomPlayerbotMgr::Revive; handlers["grind"] = &RandomPlayerbotMgr::RandomTeleport; handlers["change_strategy"] = &RandomPlayerbotMgr::ChangeStrategy; diff --git a/src/RandomPlayerbotMgr.h b/src/RandomPlayerbotMgr.h index 5af312bc..87640d72 100644 --- a/src/RandomPlayerbotMgr.h +++ b/src/RandomPlayerbotMgr.h @@ -49,6 +49,7 @@ class RandomPlayerbotMgr : public PlayerbotHolder void Randomize(Player* bot); void Clear(Player* bot); void RandomizeFirst(Player* bot); + void RandomizeMin(Player* bot); void IncreaseLevel(Player* bot); void ScheduleTeleport(uint32 bot, uint32 time = 0); void ScheduleChangeStrategy(uint32 bot, uint32 time = 0); diff --git a/src/strategy/Action.cpp b/src/strategy/Action.cpp index 62525ff6..3fd4a723 100644 --- a/src/strategy/Action.cpp +++ b/src/strategy/Action.cpp @@ -4,6 +4,7 @@ #include "Action.h" #include "Playerbots.h" +#include "Timer.h" uint32 NextAction::size(NextAction** actions) { @@ -101,11 +102,11 @@ Unit* Action::GetTarget() } ActionBasket::ActionBasket(ActionNode* action, float relevance, bool skipPrerequisites, Event event) : - action(action), relevance(relevance), skipPrerequisites(skipPrerequisites), event(event), created(time(nullptr)) + action(action), relevance(relevance), skipPrerequisites(skipPrerequisites), event(event), created(getMSTime()) { } -bool ActionBasket::isExpired(time_t secs) +bool ActionBasket::isExpired(uint32 msecs) { - return time(nullptr) - created >= secs; + return getMSTime() - created >= msecs; } diff --git a/src/strategy/Action.h b/src/strategy/Action.h index f67f9ed6..7069a5b3 100644 --- a/src/strategy/Action.h +++ b/src/strategy/Action.h @@ -109,14 +109,14 @@ class ActionBasket bool isSkipPrerequisites() { return skipPrerequisites; } void AmendRelevance(float k) { relevance *= k; } void setRelevance(float relevance) { this->relevance = relevance; } - bool isExpired(time_t secs); + bool isExpired(uint32 msecs); private: ActionNode* action; float relevance; bool skipPrerequisites; Event event; - time_t created; + uint32 created; }; #endif diff --git a/src/strategy/Engine.cpp b/src/strategy/Engine.cpp index 5ab29cac..e3602843 100644 --- a/src/strategy/Engine.cpp +++ b/src/strategy/Engine.cpp @@ -261,8 +261,8 @@ bool Engine::DoNextAction(Unit* unit, uint32 depth, bool minimal) lastRelevance = 0.0f; PushDefaultActions(); - if (queue.Peek() && depth < 2) - return DoNextAction(unit, depth + 1, minimal); + // if (queue.Peek() && depth < 1 && !minimal) + // return DoNextAction(unit, depth + 1, minimal); } // MEMORY FIX TEST @@ -640,7 +640,7 @@ void Engine::LogAction(char const* format, ...) else { Player* bot = botAI->GetBot(); - if (sPlayerbotAIConfig->logInGroupOnly && !bot->GetGroup()) + if (sPlayerbotAIConfig->logInGroupOnly && (!bot->GetGroup() || !botAI->HasRealPlayerMaster())) return; LOG_DEBUG("playerbots", "{} {}", bot->GetName().c_str(), buf); @@ -677,7 +677,7 @@ void Engine::LogValues() return; Player* bot = botAI->GetBot(); - if (sPlayerbotAIConfig->logInGroupOnly && !bot->GetGroup()) + if (sPlayerbotAIConfig->logInGroupOnly && (!bot->GetGroup() || !botAI->HasRealPlayerMaster())) return; std::string const text = botAI->GetAiObjectContext()->FormatValues(); diff --git a/src/strategy/Queue.cpp b/src/strategy/Queue.cpp index 91c46895..c70fccc7 100644 --- a/src/strategy/Queue.cpp +++ b/src/strategy/Queue.cpp @@ -86,7 +86,7 @@ void Queue::RemoveExpired() for (std::list::iterator iter = actions.begin(); iter != actions.end(); iter++) { ActionBasket* basket = *iter; - if (sPlayerbotAIConfig->expireActionTime && basket->isExpired(sPlayerbotAIConfig->expireActionTime / 1000)) + if (sPlayerbotAIConfig->expireActionTime && basket->isExpired(sPlayerbotAIConfig->expireActionTime)) expired.push_back(basket); } @@ -97,7 +97,6 @@ void Queue::RemoveExpired() if (ActionNode* action = basket->getAction()) { - // LOG_DEBUG("playerbots", "Action {} is expired", action->getName().c_str()); delete action; } diff --git a/src/strategy/Trigger.cpp b/src/strategy/Trigger.cpp index 2da7281e..564d1962 100644 --- a/src/strategy/Trigger.cpp +++ b/src/strategy/Trigger.cpp @@ -5,9 +5,10 @@ #include "Trigger.h" #include "Event.h" #include "Playerbots.h" +#include "Timer.h" Trigger::Trigger(PlayerbotAI* botAI, std::string const name, int32 checkInterval) : - AiNamedObject(botAI, name), checkInterval(checkInterval), lastCheckTime(time(nullptr) - rand() % checkInterval) + AiNamedObject(botAI, name), checkInterval(checkInterval == 1 ? 1 : (checkInterval < 100 ? checkInterval * 1000 : checkInterval)), lastCheckTime(0) { } @@ -38,7 +39,7 @@ bool Trigger::needCheck() if (checkInterval < 2) return true; - time_t now = time(nullptr); + uint32 now = getMSTime(); if (!lastCheckTime || now - lastCheckTime >= checkInterval) { lastCheckTime = now; diff --git a/src/strategy/Trigger.h b/src/strategy/Trigger.h index 46a03843..eeaaea97 100644 --- a/src/strategy/Trigger.h +++ b/src/strategy/Trigger.h @@ -33,7 +33,7 @@ class Trigger : public AiNamedObject protected: int32 checkInterval; - time_t lastCheckTime; + uint32 lastCheckTime; }; class TriggerNode diff --git a/src/strategy/Value.cpp b/src/strategy/Value.cpp index a9067b31..76f395ab 100644 --- a/src/strategy/Value.cpp +++ b/src/strategy/Value.cpp @@ -5,10 +5,10 @@ #include "Value.h" #include "PerformanceMonitor.h" #include "Playerbots.h" +#include "Timer.h" UnitCalculatedValue::UnitCalculatedValue(PlayerbotAI* botAI, std::string const name, int32 checkInterval) : CalculatedValue(botAI, name, checkInterval) { - lastCheckTime = time(nullptr) - checkInterval / 2; } std::string const UnitCalculatedValue::Format() @@ -47,7 +47,7 @@ std::string const FloatCalculatedValue::Format() CDPairCalculatedValue::CDPairCalculatedValue(PlayerbotAI* botAI, std::string const name, int32 checkInterval) : CalculatedValue(botAI, name, checkInterval) { - lastCheckTime = time(nullptr) - checkInterval / 2; + // lastCheckTime = getMSTime() - checkInterval / 2; } std::string const CDPairCalculatedValue::Format() @@ -65,7 +65,7 @@ std::string const CDPairCalculatedValue::Format() CDPairListCalculatedValue::CDPairListCalculatedValue(PlayerbotAI* botAI, std::string const name, int32 checkInterval) : CalculatedValue>(botAI, name, checkInterval) { - lastCheckTime = time(nullptr) - checkInterval / 2; + // lastCheckTime = time(nullptr) - checkInterval / 2; } std::string const CDPairListCalculatedValue::Format() @@ -84,7 +84,7 @@ std::string const CDPairListCalculatedValue::Format() ObjectGuidCalculatedValue::ObjectGuidCalculatedValue(PlayerbotAI* botAI, std::string const name, int32 checkInterval) : CalculatedValue(botAI, name, checkInterval) { - lastCheckTime = time(nullptr) - checkInterval / 2; + // lastCheckTime = time(nullptr) - checkInterval / 2; } std::string const ObjectGuidCalculatedValue::Format() @@ -96,7 +96,6 @@ std::string const ObjectGuidCalculatedValue::Format() ObjectGuidListCalculatedValue::ObjectGuidListCalculatedValue(PlayerbotAI* botAI, std::string const name, int32 checkInterval) : CalculatedValue(botAI, name, checkInterval) { - lastCheckTime = time(nullptr) - checkInterval / 2; } std::string const ObjectGuidListCalculatedValue::Format() diff --git a/src/strategy/Value.h b/src/strategy/Value.h index bff21d09..bf29d074 100644 --- a/src/strategy/Value.h +++ b/src/strategy/Value.h @@ -8,6 +8,7 @@ #include "AiObject.h" #include "ObjectGuid.h" #include "PerformanceMonitor.h" +#include "Timer.h" #include @@ -45,23 +46,28 @@ class CalculatedValue : public UntypedValue, public Value { public: CalculatedValue(PlayerbotAI* botAI, std::string const name = "value", uint32 checkInterval = 1) : UntypedValue(botAI, name), - checkInterval(checkInterval), lastCheckTime(0) { } + checkInterval(checkInterval == 1 ? 1 : (checkInterval < 100 ? checkInterval * 1000 : checkInterval)) /*turn s -> ms?*/, lastCheckTime(0) { } virtual ~CalculatedValue() { } T Get() override { - time_t now = time(nullptr); - if (!lastCheckTime || checkInterval < 2 || now - lastCheckTime >= checkInterval / 2) - { - lastCheckTime = now; - + if (checkInterval < 2) { PerformanceMonitorOperation* pmo = sPerformanceMonitor->start(PERF_MON_VALUE, this->getName(), this->context ? &this->context->performanceStack : nullptr); value = Calculate(); if (pmo) pmo->finish(); + } else { + time_t now = getMSTime(); + if (!lastCheckTime || now - lastCheckTime >= checkInterval) + { + lastCheckTime = now; + PerformanceMonitorOperation* pmo = sPerformanceMonitor->start(PERF_MON_VALUE, this->getName(), this->context ? &this->context->performanceStack : nullptr); + value = Calculate(); + if (pmo) + pmo->finish(); + } } - return value; } @@ -81,7 +87,7 @@ class CalculatedValue : public UntypedValue, public Value virtual T Calculate() = 0; uint32 checkInterval; - time_t lastCheckTime; + uint32 lastCheckTime; T value; }; diff --git a/src/strategy/actions/BuffAction.cpp b/src/strategy/actions/BuffAction.cpp index 6c7c4d2a..3def115c 100644 --- a/src/strategy/actions/BuffAction.cpp +++ b/src/strategy/actions/BuffAction.cpp @@ -38,7 +38,7 @@ class FindBuffVisitor : public IterateItemsVisitor return true; Item* itemForSpell = *GET_PLAYERBOT_AI(bot)->GetAiObjectContext()->GetValue("item for spell", spellId); - if (itemForSpell && itemForSpell->GetEnchantmentId(TEMP_ENCHANTMENT_SLOT)) + if (itemForSpell && itemForSpell->IsInWorld() && itemForSpell->GetEnchantmentId(TEMP_ENCHANTMENT_SLOT)) return true; if (items.find(proto->SubClass) == items.end()) diff --git a/src/strategy/actions/GenericSpellActions.cpp b/src/strategy/actions/GenericSpellActions.cpp index 817a5eeb..6f108ad1 100644 --- a/src/strategy/actions/GenericSpellActions.cpp +++ b/src/strategy/actions/GenericSpellActions.cpp @@ -63,10 +63,10 @@ bool CastSpellAction::Execute(Event event) bool CastSpellAction::isPossible() { if (botAI->IsInVehicle() && !botAI->IsInVehicle(false, false, true)) { - if (!sPlayerbotAIConfig->logInGroupOnly || bot->GetGroup()) { - LOG_DEBUG("playerbots", "Can cast spell failed. Vehicle. - bot name: {}", - bot->GetName()); - } + // if (!sPlayerbotAIConfig->logInGroupOnly || bot->GetGroup()) { + // LOG_DEBUG("playerbots", "Can cast spell failed. Vehicle. - bot name: {}", + // bot->GetName()); + // } return false; } @@ -75,10 +75,10 @@ bool CastSpellAction::isPossible() if (spell == "mount" && bot->IsInCombat()) { - if (!sPlayerbotAIConfig->logInGroupOnly || bot->GetGroup()) { - LOG_DEBUG("playerbots", "Can cast spell failed. Mount. - bot name: {}", - bot->GetName()); - } + // if (!sPlayerbotAIConfig->logInGroupOnly || bot->GetGroup()) { + // LOG_DEBUG("playerbots", "Can cast spell failed. Mount. - bot name: {}", + // bot->GetName()); + // } bot->Dismount(); return false; } diff --git a/src/strategy/actions/LeaveGroupAction.cpp b/src/strategy/actions/LeaveGroupAction.cpp index 381019ea..4414e152 100644 --- a/src/strategy/actions/LeaveGroupAction.cpp +++ b/src/strategy/actions/LeaveGroupAction.cpp @@ -4,6 +4,7 @@ #include "LeaveGroupAction.h" #include "Event.h" +#include "PlayerbotAIConfig.h" #include "Playerbots.h" bool LeaveGroupAction::Execute(Event event) @@ -153,5 +154,9 @@ bool LeaveFarAwayAction::isUseful() if (abs(int32(master->getLevel() - bot->getLevel())) > 4) return true; + if (bot->GetMapId() != master->GetMapId() || bot->GetDistance2d(master) >= 2 * sPlayerbotAIConfig->rpgDistance) { + return true; + } + return false; } diff --git a/src/strategy/actions/LootRollAction.cpp b/src/strategy/actions/LootRollAction.cpp index f97f3c24..7ccd7aef 100644 --- a/src/strategy/actions/LootRollAction.cpp +++ b/src/strategy/actions/LootRollAction.cpp @@ -26,21 +26,53 @@ bool LootRollAction::Execute(Event event) p >> rollType; //need,greed or pass on roll RollVote vote = PASS; - if (ItemTemplate const* proto = sObjectMgr->GetItemTemplate(guid.GetEntry())) - { - switch (proto->Class) - { - case ITEM_CLASS_WEAPON: - case ITEM_CLASS_ARMOR: - if (!QueryItemUsage(proto).empty()) - vote = NEED; - break; - default: - if (StoreLootAction::IsLootAllowed(guid.GetEntry(), botAI)) - vote = NEED; - break; - } - } + + // std::vector rolls = group->GetRolls(); + // bot->Say("guid:" + std::to_string(guid.GetCounter()) + + // "item entry:" + std::to_string(guid.GetEntry()), LANG_UNIVERSAL); + // for (std::vector::iterator i = rolls.begin(); i != rolls.end(); ++i) + // { + // if ((*i)->isValid() && (*i)->itemGUID == guid && (*i)->itemSlot == slot) + // { + // uint32 itemId = (*i)->itemid; + // bot->Say("item entry2:" + std::to_string(itemId), LANG_UNIVERSAL); + // ItemTemplate const *proto = sObjectMgr->GetItemTemplate(itemId); + // if (!proto) + // continue; + + // switch (proto->Class) + // { + // case ITEM_CLASS_WEAPON: + // case ITEM_CLASS_ARMOR: + // if (!QueryItemUsage(proto).empty()) + // vote = NEED; + // else if (bot->HasSkill(SKILL_ENCHANTING)) + // vote = DISENCHANT; + // break; + // default: + // if (StoreLootAction::IsLootAllowed(itemId, botAI)) + // vote = NEED; + // break; + // } + // break; + // } + // } + + // if (ItemTemplate const* proto = sObjectMgr->GetItemTemplate(guid.GetEntry())) + // { + // switch (proto->Class) + // { + // case ITEM_CLASS_WEAPON: + // case ITEM_CLASS_ARMOR: + // if (!QueryItemUsage(proto).empty()) + // vote = NEED; + // break; + // default: + // if (StoreLootAction::IsLootAllowed(guid.GetEntry(), botAI)) + // vote = NEED; + // break; + // } + // } switch (group->GetLootMethod()) { diff --git a/src/strategy/actions/MovementActions.cpp b/src/strategy/actions/MovementActions.cpp index 41e13f78..1a6eabaa 100644 --- a/src/strategy/actions/MovementActions.cpp +++ b/src/strategy/actions/MovementActions.cpp @@ -135,11 +135,10 @@ bool MovementAction::MoveTo(uint32 mapId, float x, float y, float z, bool idle, if (!IsMovingAllowed(mapId, x, y, z)) { return false; } - // if (bot->HasUnitMovementFlag(MOVEMENTFLAG_FALLING | MOVEMENTFLAG_FALLING_FAR)) { - // bot->Yell("I'm falling!", LANG_UNIVERSAL); + // if (bot->m_movementInfo.HasMovementFlag(MOVEMENTFLAG_FALLING | MOVEMENTFLAG_FALLING_SLOW | MOVEMENTFLAG_FALLING_FAR)) { + // bot->Say("I'm falling!, flag:" + std::to_string(bot->m_movementInfo.GetMovementFlags()), LANG_UNIVERSAL); // return false; // } - // bot->UpdateGroundPositionZ(x, y, z); z += 2.0f; bot->UpdateAllowedPositionZ(x, y, z); // z += 0.5f; @@ -158,11 +157,10 @@ bool MovementAction::MoveTo(uint32 mapId, float x, float y, float z, bool idle, } bool generatePath = !bot->HasAuraType(SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED) && - !bot->IsFlying() && !bot->IsUnderWater(); + !bot->IsFlying() && !bot->isSwimming(); MotionMaster &mm = *bot->GetMotionMaster(); mm.Clear(); mm.MovePoint(mapId, x, y, z, generatePath); - AI_VALUE(LastMovement&, "last movement").Set(mapId, x, y, z, bot->GetOrientation()); return true; } @@ -674,9 +672,11 @@ bool MovementAction::MoveTo(Unit* target, float distance) float dx = cos(angle) * needToGo + bx; float dy = sin(angle) * needToGo + by; - float dz = std::max(bz, tz); // calc accurate z position to avoid stuck + float dz; // = std::max(bz, tz); // calc accurate z position to avoid stuck if (distanceToTarget > CONTACT_DISTANCE) { - dz = std::max(dz, bz + (tz - bz) * (needToGo / distanceToTarget)); + dz = bz + (tz - bz) * (needToGo / distanceToTarget); + } else { + dz = tz; } return MoveTo(target->GetMapId(), dx, dy, dz); } diff --git a/src/strategy/druid/DruidTriggers.h b/src/strategy/druid/DruidTriggers.h index a45be4cf..280be700 100644 --- a/src/strategy/druid/DruidTriggers.h +++ b/src/strategy/druid/DruidTriggers.h @@ -13,7 +13,7 @@ class PlayerbotAI; class MarkOfTheWildOnPartyTrigger : public BuffOnPartyTrigger { public: - MarkOfTheWildOnPartyTrigger(PlayerbotAI* botAI) : BuffOnPartyTrigger(botAI, "mark of the wild", 2) { } + MarkOfTheWildOnPartyTrigger(PlayerbotAI* botAI) : BuffOnPartyTrigger(botAI, "mark of the wild", 2 * 2000) { } bool IsActive() override; }; @@ -21,7 +21,7 @@ class MarkOfTheWildOnPartyTrigger : public BuffOnPartyTrigger class MarkOfTheWildTrigger : public BuffTrigger { public: - MarkOfTheWildTrigger(PlayerbotAI* botAI) : BuffTrigger(botAI, "mark of the wild", 2) { } + MarkOfTheWildTrigger(PlayerbotAI* botAI) : BuffTrigger(botAI, "mark of the wild", 2 * 2000) { } bool IsActive() override; }; @@ -29,7 +29,7 @@ class MarkOfTheWildTrigger : public BuffTrigger class ThornsOnPartyTrigger : public BuffOnPartyTrigger { public: - ThornsOnPartyTrigger(PlayerbotAI* botAI) : BuffOnPartyTrigger(botAI, "thorns", 2) { } + ThornsOnPartyTrigger(PlayerbotAI* botAI) : BuffOnPartyTrigger(botAI, "thorns", 2 * 2000) { } bool IsActive() override; }; @@ -37,7 +37,7 @@ class ThornsOnPartyTrigger : public BuffOnPartyTrigger class ThornsTrigger : public BuffTrigger { public: - ThornsTrigger(PlayerbotAI* botAI) : BuffTrigger(botAI, "thorns", 2) { } + ThornsTrigger(PlayerbotAI* botAI) : BuffTrigger(botAI, "thorns", 2 * 2000) { } bool IsActive() override; }; @@ -68,10 +68,10 @@ class MoonfireTrigger : public DebuffTrigger bool IsActive() override; }; -class FaerieFireTrigger : public DebuffTrigger +class FaerieFireTrigger : public DebuffOnBossTrigger { public: - FaerieFireTrigger(PlayerbotAI* botAI) : DebuffTrigger(botAI, "faerie fire") { } + FaerieFireTrigger(PlayerbotAI* botAI) : DebuffOnBossTrigger(botAI, "faerie fire") { } }; class FaerieFireFeralTrigger : public DebuffTrigger diff --git a/src/strategy/generic/GroupStrategy.cpp b/src/strategy/generic/GroupStrategy.cpp index 05c16877..7f87e2e6 100644 --- a/src/strategy/generic/GroupStrategy.cpp +++ b/src/strategy/generic/GroupStrategy.cpp @@ -9,7 +9,7 @@ void GroupStrategy::InitTriggers(std::vector& triggers) { triggers.push_back(new TriggerNode("often", NextAction::array(0, new NextAction("invite nearby", 4.0f), nullptr))); triggers.push_back(new TriggerNode("random", NextAction::array(0, new NextAction("invite guild", 4.0f), nullptr))); - triggers.push_back(new TriggerNode("seldom", NextAction::array(0, new NextAction("leave far away", 4.0f), nullptr))); + triggers.push_back(new TriggerNode("often", NextAction::array(0, new NextAction("leave far away", 4.0f), nullptr))); triggers.push_back(new TriggerNode("seldom", NextAction::array(0, new NextAction("reset instances", 1.0f), nullptr))); } diff --git a/src/strategy/hunter/HunterActions.cpp b/src/strategy/hunter/HunterActions.cpp index 9ce55fea..31ac20b3 100644 --- a/src/strategy/hunter/HunterActions.cpp +++ b/src/strategy/hunter/HunterActions.cpp @@ -4,8 +4,14 @@ #include "HunterActions.h" #include "Event.h" +#include "GenericSpellActions.h" #include "Playerbots.h" +bool CastHuntersMarkAction::isUseful() +{ + return CastDebuffSpellAction::isUseful(); +} + bool CastViperStingAction::isUseful() { return AI_VALUE2(uint8, "mana", "self target") < 50 && AI_VALUE2(uint8, "mana", "current target") >= 30; diff --git a/src/strategy/hunter/HunterActions.h b/src/strategy/hunter/HunterActions.h index af04188d..01c8051b 100644 --- a/src/strategy/hunter/HunterActions.h +++ b/src/strategy/hunter/HunterActions.h @@ -11,9 +11,15 @@ class PlayerbotAI; class Unit; -BEGIN_RANGED_SPELL_ACTION(CastHuntersMarkAction, "hunter's mark") -END_SPELL_ACTION() +// BEGIN_RANGED_SPELL_ACTION(CastHuntersMarkAction, "hunter's mark") +// END_SPELL_ACTION() +class CastHuntersMarkAction : public CastDebuffSpellAction +{ + public: + CastHuntersMarkAction(PlayerbotAI* botAI) : CastDebuffSpellAction(botAI, "hunter's mark") { } + bool isUseful() override; +}; class CastAutoShotAction : public CastSpellAction { public: diff --git a/src/strategy/hunter/HunterTriggers.h b/src/strategy/hunter/HunterTriggers.h index 46aab8d9..2d43b311 100644 --- a/src/strategy/hunter/HunterTriggers.h +++ b/src/strategy/hunter/HunterTriggers.h @@ -67,10 +67,10 @@ class BlackArrowTrigger : public DebuffTrigger BlackArrowTrigger(PlayerbotAI* botAI) : DebuffTrigger(botAI, "black arrow", 1, true) { } }; -class HuntersMarkTrigger : public DebuffTrigger +class HuntersMarkTrigger : public DebuffOnBossTrigger { public: - HuntersMarkTrigger(PlayerbotAI* botAI) : DebuffTrigger(botAI, "hunter's mark") { } + HuntersMarkTrigger(PlayerbotAI* botAI) : DebuffOnBossTrigger(botAI, "hunter's mark") { } }; class FreezingTrapTrigger : public HasCcTargetTrigger diff --git a/src/strategy/mage/MageTriggers.h b/src/strategy/mage/MageTriggers.h index 3696180f..04ea5fb6 100644 --- a/src/strategy/mage/MageTriggers.h +++ b/src/strategy/mage/MageTriggers.h @@ -16,7 +16,7 @@ DEFLECT_TRIGGER(FrostWardTrigger, "frost ward"); class ArcaneIntellectOnPartyTrigger : public BuffOnPartyTrigger { public: - ArcaneIntellectOnPartyTrigger(PlayerbotAI* botAI) : BuffOnPartyTrigger(botAI, "arcane intellect", 2) { } + ArcaneIntellectOnPartyTrigger(PlayerbotAI* botAI) : BuffOnPartyTrigger(botAI, "arcane intellect", 2 * 2000) { } bool IsActive() override; }; @@ -24,7 +24,7 @@ class ArcaneIntellectOnPartyTrigger : public BuffOnPartyTrigger class ArcaneIntellectTrigger : public BuffTrigger { public: - ArcaneIntellectTrigger(PlayerbotAI* botAI) : BuffTrigger(botAI, "arcane intellect", 2) { } + ArcaneIntellectTrigger(PlayerbotAI* botAI) : BuffTrigger(botAI, "arcane intellect", 2 * 2000) { } bool IsActive() override; }; @@ -32,7 +32,7 @@ class ArcaneIntellectTrigger : public BuffTrigger class MageArmorTrigger : public BuffTrigger { public: - MageArmorTrigger(PlayerbotAI* botAI) : BuffTrigger(botAI, "mage armor", 5) { } + MageArmorTrigger(PlayerbotAI* botAI) : BuffTrigger(botAI, "mage armor", 5 * 2000) { } bool IsActive() override; }; diff --git a/src/strategy/paladin/PaladinTriggers.h b/src/strategy/paladin/PaladinTriggers.h index 60dfc1f0..8d700d13 100644 --- a/src/strategy/paladin/PaladinTriggers.h +++ b/src/strategy/paladin/PaladinTriggers.h @@ -75,13 +75,13 @@ INTERRUPT_TRIGGER(RepentanceInterruptTrigger, "repentance"); class BlessingOnPartyTrigger : public BuffOnPartyTrigger { public: - BlessingOnPartyTrigger(PlayerbotAI* botAI) : BuffOnPartyTrigger(botAI, "blessing of kings,blessing of might,blessing of wisdom", 2) { } + BlessingOnPartyTrigger(PlayerbotAI* botAI) : BuffOnPartyTrigger(botAI, "blessing of kings,blessing of might,blessing of wisdom", 2 * 2000) { } }; class BlessingTrigger : public BuffTrigger { public: - BlessingTrigger(PlayerbotAI* botAI) : BuffTrigger(botAI, "blessing of sanctuary", 2) { } + BlessingTrigger(PlayerbotAI* botAI) : BuffTrigger(botAI, "blessing of sanctuary", 2 * 2000) { } bool IsActive() override; }; @@ -202,18 +202,18 @@ public: class BlessingOfKingsOnPartyTrigger : public BuffOnPartyTrigger { public: - BlessingOfKingsOnPartyTrigger(PlayerbotAI* botAI) : BuffOnPartyTrigger(botAI, "blessing of kings", 2) { } + BlessingOfKingsOnPartyTrigger(PlayerbotAI* botAI) : BuffOnPartyTrigger(botAI, "blessing of kings", 2 * 2000) { } }; class BlessingOfWisdomOnPartyTrigger : public BuffOnPartyTrigger { public: - BlessingOfWisdomOnPartyTrigger(PlayerbotAI* botAI) : BuffOnPartyTrigger(botAI, "blessing of might,blessing of wisdom", 2) { } + BlessingOfWisdomOnPartyTrigger(PlayerbotAI* botAI) : BuffOnPartyTrigger(botAI, "blessing of might,blessing of wisdom", 2 * 2000) { } }; class BlessingOfMightOnPartyTrigger : public BuffOnPartyTrigger { public: - BlessingOfMightOnPartyTrigger(PlayerbotAI* botAI) : BuffOnPartyTrigger(botAI, "blessing of might,blessing of wisdom", 2) { } + BlessingOfMightOnPartyTrigger(PlayerbotAI* botAI) : BuffOnPartyTrigger(botAI, "blessing of might,blessing of wisdom", 2 * 2000) { } }; #endif diff --git a/src/strategy/priest/PriestTriggers.h b/src/strategy/priest/PriestTriggers.h index 717c4d90..7d529843 100644 --- a/src/strategy/priest/PriestTriggers.h +++ b/src/strategy/priest/PriestTriggers.h @@ -43,7 +43,7 @@ BOOST_TRIGGER_A(ShadowfiendTrigger, "shadowfiend"); class PowerWordFortitudeOnPartyTrigger : public BuffOnPartyTrigger { public: - PowerWordFortitudeOnPartyTrigger(PlayerbotAI* botAI) : BuffOnPartyTrigger(botAI, "power word: fortitude", 4) { } + PowerWordFortitudeOnPartyTrigger(PlayerbotAI* botAI) : BuffOnPartyTrigger(botAI, "power word: fortitude", 4 * 2000) { } bool IsActive() override; }; @@ -51,7 +51,7 @@ class PowerWordFortitudeOnPartyTrigger : public BuffOnPartyTrigger class PowerWordFortitudeTrigger : public BuffTrigger { public: - PowerWordFortitudeTrigger(PlayerbotAI* botAI) : BuffTrigger(botAI, "power word: fortitude", 4) { } + PowerWordFortitudeTrigger(PlayerbotAI* botAI) : BuffTrigger(botAI, "power word: fortitude", 4 * 2000) { } bool IsActive() override; }; @@ -59,7 +59,7 @@ class PowerWordFortitudeTrigger : public BuffTrigger class DivineSpiritOnPartyTrigger : public BuffOnPartyTrigger { public: - DivineSpiritOnPartyTrigger(PlayerbotAI* botAI) : BuffOnPartyTrigger(botAI, "divine spirit", 4) { } + DivineSpiritOnPartyTrigger(PlayerbotAI* botAI) : BuffOnPartyTrigger(botAI, "divine spirit", 4 * 2000) { } bool IsActive() override; }; @@ -67,7 +67,7 @@ class DivineSpiritOnPartyTrigger : public BuffOnPartyTrigger class DivineSpiritTrigger : public BuffTrigger { public: - DivineSpiritTrigger(PlayerbotAI* botAI) : BuffTrigger(botAI, "divine spirit", 4) { } + DivineSpiritTrigger(PlayerbotAI* botAI) : BuffTrigger(botAI, "divine spirit", 4 * 2000) { } bool IsActive() override; }; @@ -75,7 +75,7 @@ class DivineSpiritTrigger : public BuffTrigger class PrayerOfFortitudeTrigger : public BuffOnPartyTrigger { public: - PrayerOfFortitudeTrigger(PlayerbotAI* botAI) : BuffOnPartyTrigger(botAI, "prayer of fortitude", 3) { } + PrayerOfFortitudeTrigger(PlayerbotAI* botAI) : BuffOnPartyTrigger(botAI, "prayer of fortitude", 3 * 2000) { } bool IsActive() override; }; @@ -83,7 +83,7 @@ class PrayerOfFortitudeTrigger : public BuffOnPartyTrigger class PrayerOfSpiritTrigger : public BuffOnPartyTrigger { public: - PrayerOfSpiritTrigger(PlayerbotAI* botAI) : BuffOnPartyTrigger(botAI, "prayer of spirit", 2) { } + PrayerOfSpiritTrigger(PlayerbotAI* botAI) : BuffOnPartyTrigger(botAI, "prayer of spirit", 2 * 2000) { } bool IsActive() override; }; diff --git a/src/strategy/raids/naxxramas/RaidNaxxActions.cpp b/src/strategy/raids/naxxramas/RaidNaxxActions.cpp index 27c48ea4..7440817f 100644 --- a/src/strategy/raids/naxxramas/RaidNaxxActions.cpp +++ b/src/strategy/raids/naxxramas/RaidNaxxActions.cpp @@ -596,8 +596,10 @@ bool SapphironFlightPositionAction::MoveToNearestIcebolt() } if (playerWithIcebolt) { Unit* boss = AI_VALUE2(Unit*, "find target", "sapphiron"); - float angle = boss->GetAngle(playerWithIcebolt); - return MoveTo(NAXX_MAP_ID, playerWithIcebolt->GetPositionX() + cos(angle) * 3.0f, playerWithIcebolt->GetPositionY() + sin(angle) * 3.0f, helper.GENERIC_HEIGHT); + if (boss) { + float angle = boss->GetAngle(playerWithIcebolt); + return MoveTo(NAXX_MAP_ID, playerWithIcebolt->GetPositionX() + cos(angle) * 3.0f, playerWithIcebolt->GetPositionY() + sin(angle) * 3.0f, helper.GENERIC_HEIGHT); + } } return false; } diff --git a/src/strategy/raids/naxxramas/RaidNaxxBossHelper.h b/src/strategy/raids/naxxramas/RaidNaxxBossHelper.h index 86b6a82e..a43dd638 100644 --- a/src/strategy/raids/naxxramas/RaidNaxxBossHelper.h +++ b/src/strategy/raids/naxxramas/RaidNaxxBossHelper.h @@ -22,7 +22,7 @@ class GenericBossHelper : public AiObject { public: GenericBossHelper(PlayerbotAI* botAI, std::string name): AiObject(botAI), name_(name) {} virtual bool UpdateBossAI() { - if(unit_ && !unit_->IsInWorld()) { + if(unit_ && (!unit_->IsInWorld() || !unit_->IsAlive())) { unit_ = nullptr; } if (!unit_) { diff --git a/src/strategy/shaman/ShamanTriggers.h b/src/strategy/shaman/ShamanTriggers.h index 1b563d48..4dae65e0 100644 --- a/src/strategy/shaman/ShamanTriggers.h +++ b/src/strategy/shaman/ShamanTriggers.h @@ -14,7 +14,7 @@ class PlayerbotAI; class ShamanWeaponTrigger : public BuffTrigger { public: - ShamanWeaponTrigger(PlayerbotAI* botAI) : BuffTrigger(botAI, "rockbiter weapon", 2) { } + ShamanWeaponTrigger(PlayerbotAI* botAI) : BuffTrigger(botAI, "rockbiter weapon", 2 * 2000) { } bool IsActive() override; @@ -112,7 +112,7 @@ class WaterWalkingTrigger : public BuffTrigger class WaterBreathingTrigger : public BuffTrigger { public: - WaterBreathingTrigger(PlayerbotAI* botAI) : BuffTrigger(botAI, "water breathing", 5) { } + WaterBreathingTrigger(PlayerbotAI* botAI) : BuffTrigger(botAI, "water breathing", 5 * 2000) { } bool IsActive() override; }; @@ -120,7 +120,7 @@ class WaterBreathingTrigger : public BuffTrigger class WaterWalkingOnPartyTrigger : public BuffOnPartyTrigger { public: - WaterWalkingOnPartyTrigger(PlayerbotAI* botAI) : BuffOnPartyTrigger(botAI, "water walking on party", 2) { } + WaterWalkingOnPartyTrigger(PlayerbotAI* botAI) : BuffOnPartyTrigger(botAI, "water walking on party", 2 * 2000) { } bool IsActive() override; }; @@ -128,7 +128,7 @@ class WaterWalkingOnPartyTrigger : public BuffOnPartyTrigger class WaterBreathingOnPartyTrigger : public BuffOnPartyTrigger { public: - WaterBreathingOnPartyTrigger(PlayerbotAI* botAI) : BuffOnPartyTrigger(botAI, "water breathing on party", 2) { } + WaterBreathingOnPartyTrigger(PlayerbotAI* botAI) : BuffOnPartyTrigger(botAI, "water breathing on party", 2 * 2000) { } bool IsActive() override; }; diff --git a/src/strategy/triggers/CureTriggers.h b/src/strategy/triggers/CureTriggers.h index 527700a3..4632f154 100644 --- a/src/strategy/triggers/CureTriggers.h +++ b/src/strategy/triggers/CureTriggers.h @@ -13,7 +13,7 @@ class Unit; class NeedCureTrigger : public SpellTrigger { public: - NeedCureTrigger(PlayerbotAI* botAI, std::string const spell, uint32 dispelType) : SpellTrigger(botAI, spell, 2), dispelType(dispelType) { } + NeedCureTrigger(PlayerbotAI* botAI, std::string const spell, uint32 dispelType) : SpellTrigger(botAI, spell, 2 * 1000), dispelType(dispelType) { } std::string const GetTargetName() override { return "self target"; } bool IsActive() override; diff --git a/src/strategy/triggers/GenericTriggers.cpp b/src/strategy/triggers/GenericTriggers.cpp index 44781524..7877ed8b 100644 --- a/src/strategy/triggers/GenericTriggers.cpp +++ b/src/strategy/triggers/GenericTriggers.cpp @@ -8,6 +8,7 @@ #include "Playerbots.h" #include "SharedDefines.h" #include "TemporarySummon.h" +#include "Timer.h" #include bool LowManaTrigger::IsActive() @@ -204,6 +205,15 @@ bool DebuffTrigger::IsActive() return BuffTrigger::IsActive() && AI_VALUE2(uint8, "health", GetTargetName()) > life_bound; } +bool DebuffOnBossTrigger::IsActive() +{ + if (!DebuffTrigger::IsActive()) { + return false; + } + Creature *c = GetTarget()->ToCreature(); + return c && ((c->IsDungeonBoss()) || (c->isWorldBoss())); +} + bool SpellTrigger::IsActive() { return GetTarget(); @@ -224,16 +234,16 @@ bool SpellNoCooldownTrigger::IsActive() return !bot->HasSpellCooldown(spellId); } -RandomTrigger::RandomTrigger(PlayerbotAI* botAI, std::string const name, int32 probability) : Trigger(botAI, name), probability(probability), lastCheck(time(nullptr)) +RandomTrigger::RandomTrigger(PlayerbotAI* botAI, std::string const name, int32 probability) : Trigger(botAI, name), probability(probability), lastCheck(getMSTime()) { } bool RandomTrigger::IsActive() { - if (time(nullptr) - lastCheck < sPlayerbotAIConfig->repeatDelay / 1000) + if (getMSTime() - lastCheck < sPlayerbotAIConfig->repeatDelay) return false; - lastCheck = time(nullptr); + lastCheck = getMSTime(); int32 k = (int32)(probability / sPlayerbotAIConfig->randomChangeMultiplier); if (k < 1) k = 1; diff --git a/src/strategy/triggers/GenericTriggers.h b/src/strategy/triggers/GenericTriggers.h index 83b2f294..b25965de 100644 --- a/src/strategy/triggers/GenericTriggers.h +++ b/src/strategy/triggers/GenericTriggers.h @@ -314,6 +314,13 @@ class DebuffTrigger : public BuffTrigger float life_bound; }; +class DebuffOnBossTrigger : public DebuffTrigger +{ + public: + DebuffOnBossTrigger(PlayerbotAI* botAI, std::string const spell, int32 checkInterval = 1, bool checkIsOwner = false) : DebuffTrigger(botAI, spell, checkInterval, checkIsOwner) {} + bool IsActive() override; +}; + class DebuffOnAttackerTrigger : public DebuffTrigger { public: @@ -343,7 +350,7 @@ class RandomTrigger : public Trigger protected: int32 probability; - time_t lastCheck; + uint32 lastCheck; }; class AndTrigger : public Trigger @@ -415,7 +422,7 @@ END_TRIGGER() class NoPetTrigger : public Trigger { public: - NoPetTrigger(PlayerbotAI* botAI) : Trigger(botAI, "no pet", 5) { } + NoPetTrigger(PlayerbotAI* botAI) : Trigger(botAI, "no pet", 5 * 1000) { } virtual bool IsActive() override; }; @@ -423,7 +430,7 @@ class NoPetTrigger : public Trigger class HasPetTrigger : public Trigger { public: - HasPetTrigger(PlayerbotAI* ai) : Trigger(ai, "has pet", 5) {} + HasPetTrigger(PlayerbotAI* ai) : Trigger(ai, "has pet", 5 * 1000) {} virtual bool IsActive() override; }; @@ -431,7 +438,7 @@ public: class ItemCountTrigger : public Trigger { public: - ItemCountTrigger(PlayerbotAI* botAI, std::string const item, int32 count, int32 interval = 30) : Trigger(botAI, item, interval), item(item), count(count) { } + ItemCountTrigger(PlayerbotAI* botAI, std::string const item, int32 count, int32 interval = 30 * 1000) : Trigger(botAI, item, interval), item(item), count(count) { } bool IsActive() override; std::string const getName() override { return "item count"; } @@ -444,7 +451,7 @@ class ItemCountTrigger : public Trigger class AmmoCountTrigger : public ItemCountTrigger { public: - AmmoCountTrigger(PlayerbotAI* botAI, std::string const item, uint32 count = 1, int32 interval = 30) : ItemCountTrigger(botAI, item, count, interval) { } + AmmoCountTrigger(PlayerbotAI* botAI, std::string const item, uint32 count = 1, int32 interval = 30 * 1000) : ItemCountTrigger(botAI, item, count, interval) { } }; class HasAuraTrigger : public Trigger @@ -612,7 +619,7 @@ class InterruptEnemyHealerTrigger : public SpellTrigger class RandomBotUpdateTrigger : public RandomTrigger { public: - RandomBotUpdateTrigger(PlayerbotAI* botAI) : RandomTrigger(botAI, "random bot update", 30) { } + RandomBotUpdateTrigger(PlayerbotAI* botAI) : RandomTrigger(botAI, "random bot update", 30 * 1000) { } bool IsActive() override; }; @@ -620,7 +627,7 @@ class RandomBotUpdateTrigger : public RandomTrigger class NoNonBotPlayersAroundTrigger : public Trigger { public: - NoNonBotPlayersAroundTrigger(PlayerbotAI* botAI) : Trigger(botAI, "no non bot players around", 10) { } + NoNonBotPlayersAroundTrigger(PlayerbotAI* botAI) : Trigger(botAI, "no non bot players around", 10 * 1000) { } bool IsActive() override; }; @@ -628,7 +635,7 @@ class NoNonBotPlayersAroundTrigger : public Trigger class NewPlayerNearbyTrigger : public Trigger { public: - NewPlayerNearbyTrigger(PlayerbotAI* botAI) : Trigger(botAI, "new player nearby", 10) { } + NewPlayerNearbyTrigger(PlayerbotAI* botAI) : Trigger(botAI, "new player nearby", 10 * 1000) { } bool IsActive() override; }; @@ -644,7 +651,7 @@ class CollisionTrigger : public Trigger class StayTimeTrigger : public Trigger { public: - StayTimeTrigger(PlayerbotAI* botAI, uint32 delay, std::string const name) : Trigger(botAI, name, 5), delay(delay) { } + StayTimeTrigger(PlayerbotAI* botAI, uint32 delay, std::string const name) : Trigger(botAI, name, 5 * 1000), delay(delay) { } bool IsActive() override; @@ -667,7 +674,7 @@ class ReturnTrigger : public StayTimeTrigger class GiveItemTrigger : public Trigger { public: - GiveItemTrigger(PlayerbotAI* botAI, std::string const name, std::string const item) : Trigger(botAI, name, 2), item(item) { } + GiveItemTrigger(PlayerbotAI* botAI, std::string const name, std::string const item) : Trigger(botAI, name, 2 * 1000), item(item) { } bool IsActive() override; @@ -702,7 +709,7 @@ class IsMountedTrigger : public Trigger class CorpseNearTrigger : public Trigger { public: - CorpseNearTrigger(PlayerbotAI* botAI) : Trigger(botAI, "corpse near", 10) { } + CorpseNearTrigger(PlayerbotAI* botAI) : Trigger(botAI, "corpse near", 10 * 1000) { } bool IsActive() override; }; @@ -710,7 +717,7 @@ class CorpseNearTrigger : public Trigger class IsFallingTrigger : public Trigger { public: - IsFallingTrigger(PlayerbotAI* botAI) : Trigger(botAI, "falling", 10) { } + IsFallingTrigger(PlayerbotAI* botAI) : Trigger(botAI, "falling", 10 * 1000) { } bool IsActive() override; }; @@ -718,7 +725,7 @@ class IsFallingTrigger : public Trigger class IsFallingFarTrigger : public Trigger { public: - IsFallingFarTrigger(PlayerbotAI* botAI) : Trigger(botAI, "falling far", 10) { } + IsFallingFarTrigger(PlayerbotAI* botAI) : Trigger(botAI, "falling far", 10 * 1000) { } bool IsActive() override; }; diff --git a/src/strategy/triggers/LfgTriggers.h b/src/strategy/triggers/LfgTriggers.h index e72e8fa8..c1f7d0e4 100644 --- a/src/strategy/triggers/LfgTriggers.h +++ b/src/strategy/triggers/LfgTriggers.h @@ -12,7 +12,7 @@ class PlayerbotAI; class LfgProposalActiveTrigger : public Trigger { public: - LfgProposalActiveTrigger(PlayerbotAI* botAI) : Trigger(botAI, "lfg proposal active", 20) { } + LfgProposalActiveTrigger(PlayerbotAI* botAI) : Trigger(botAI, "lfg proposal active", 20 * 2000) { } bool IsActive() override; }; @@ -20,7 +20,7 @@ class LfgProposalActiveTrigger : public Trigger class UnknownDungeonTrigger : public Trigger { public: - UnknownDungeonTrigger(PlayerbotAI* botAI) : Trigger(botAI, "unknown dungeon", 20) { } + UnknownDungeonTrigger(PlayerbotAI* botAI) : Trigger(botAI, "unknown dungeon", 20 * 2000) { } bool IsActive() override; }; diff --git a/src/strategy/values/Arrow.cpp b/src/strategy/values/Arrow.cpp index e51752f9..22cbf619 100644 --- a/src/strategy/values/Arrow.cpp +++ b/src/strategy/values/Arrow.cpp @@ -43,7 +43,7 @@ WorldLocation ArrowFormation::GetLocationInternal() float x = master->GetPositionX() - masterUnit->GetX() + botUnit->GetX(); float y = master->GetPositionY() - masterUnit->GetY() + botUnit->GetY(); - float z = master->GetPositionZ(); + float z = master->GetPositionZ() + 5.0f; float ground = master->GetMap()->GetHeight(x, y, z + 0.5f); if (ground <= INVALID_HEIGHT) diff --git a/src/strategy/values/AttackersValue.h b/src/strategy/values/AttackersValue.h index ea1e745b..b475e92b 100644 --- a/src/strategy/values/AttackersValue.h +++ b/src/strategy/values/AttackersValue.h @@ -16,7 +16,7 @@ class Unit; class AttackersValue : public ObjectGuidListCalculatedValue { public: - AttackersValue(PlayerbotAI* botAI) : ObjectGuidListCalculatedValue(botAI, "attackers", 2) { } + AttackersValue(PlayerbotAI* botAI) : ObjectGuidListCalculatedValue(botAI, "attackers", 2 * 1000) { } GuidVector Calculate(); static bool IsPossibleTarget(Unit* attacker, Player* bot, float range = sPlayerbotAIConfig->sightDistance); diff --git a/src/strategy/values/EnemyPlayerValue.h b/src/strategy/values/EnemyPlayerValue.h index 20a0e026..2dfcb9f3 100644 --- a/src/strategy/values/EnemyPlayerValue.h +++ b/src/strategy/values/EnemyPlayerValue.h @@ -24,7 +24,7 @@ class NearestEnemyPlayersValue : public PossibleTargetsValue class EnemyPlayerValue : public UnitCalculatedValue { public: - EnemyPlayerValue(PlayerbotAI* botAI, std::string const name = "enemy player") : UnitCalculatedValue(botAI, name, 2) { } + EnemyPlayerValue(PlayerbotAI* botAI, std::string const name = "enemy player") : UnitCalculatedValue(botAI, name, 2 * 1000) { } Unit* Calculate() override; diff --git a/src/strategy/values/GroupValues.h b/src/strategy/values/GroupValues.h index 0df83eef..49ab3fb5 100644 --- a/src/strategy/values/GroupValues.h +++ b/src/strategy/values/GroupValues.h @@ -10,7 +10,7 @@ class PlayerbotAI; class GroupMembersValue : public ObjectGuidListCalculatedValue { public: - GroupMembersValue(PlayerbotAI* botAI) : ObjectGuidListCalculatedValue(botAI, "group members", 2) { } + GroupMembersValue(PlayerbotAI* botAI) : ObjectGuidListCalculatedValue(botAI, "group members", 2 * 1000) { } GuidVector Calculate() override; }; @@ -66,7 +66,7 @@ class GroupBoolORValue : public BoolCalculatedValue, public Qualified class GroupReadyValue : public BoolCalculatedValue, public Qualified { public: - GroupReadyValue(PlayerbotAI* botAI) : BoolCalculatedValue(botAI, "group ready", 2) { } + GroupReadyValue(PlayerbotAI* botAI) : BoolCalculatedValue(botAI, "group ready", 2 * 2000) { } bool Calculate()override; }; diff --git a/src/strategy/values/IsFacingValue.cpp b/src/strategy/values/IsFacingValue.cpp index 495bc920..8aa32c9b 100644 --- a/src/strategy/values/IsFacingValue.cpp +++ b/src/strategy/values/IsFacingValue.cpp @@ -11,5 +11,5 @@ bool IsFacingValue::Calculate() if (!target) return false; - return bot->HasInArc(CAST_ANGLE_IN_FRONT, target, sPlayerbotAIConfig->sightDistance); + return bot->HasInArc(CAST_ANGLE_IN_FRONT, target); } diff --git a/src/strategy/values/ItemForSpellValue.h b/src/strategy/values/ItemForSpellValue.h index da6e1942..525a9109 100644 --- a/src/strategy/values/ItemForSpellValue.h +++ b/src/strategy/values/ItemForSpellValue.h @@ -15,7 +15,7 @@ class SpellInfo; class ItemForSpellValue : public CalculatedValue, public Qualified { public: - ItemForSpellValue(PlayerbotAI* botAI, std::string const name = "item for spell") : CalculatedValue(botAI, name) { } + ItemForSpellValue(PlayerbotAI* botAI, std::string const name = "item for spell") : CalculatedValue(botAI, name, 1) { } Item* Calculate() override; diff --git a/src/strategy/values/LootValues.h b/src/strategy/values/LootValues.h index 5a6f5341..a1215f8a 100644 --- a/src/strategy/values/LootValues.h +++ b/src/strategy/values/LootValues.h @@ -59,7 +59,7 @@ typedef std::unordered_map> itemUsageMap; class EntryLootUsageValue : public CalculatedValue, public Qualified { public: - EntryLootUsageValue(PlayerbotAI* botAI) : CalculatedValue(botAI, "entry loot usage", 2) { } + EntryLootUsageValue(PlayerbotAI* botAI) : CalculatedValue(botAI, "entry loot usage", 2 * 1000) { } itemUsageMap Calculate() override; }; @@ -67,7 +67,7 @@ class EntryLootUsageValue : public CalculatedValue, public Qualifi class HasUpgradeValue : public BoolCalculatedValue, public Qualified { public: - HasUpgradeValue(PlayerbotAI* botAI) : BoolCalculatedValue(botAI, "has upgrade", 2) { } + HasUpgradeValue(PlayerbotAI* botAI) : BoolCalculatedValue(botAI, "has upgrade", 2 * 1000) { } bool Calculate() override; }; diff --git a/src/strategy/values/MaintenanceValues.h b/src/strategy/values/MaintenanceValues.h index 97c26dbe..57913a7e 100644 --- a/src/strategy/values/MaintenanceValues.h +++ b/src/strategy/values/MaintenanceValues.h @@ -12,7 +12,7 @@ class PlayerbotAI; class CanMoveAroundValue : public BoolCalculatedValue { public: - CanMoveAroundValue(PlayerbotAI* botAI) : BoolCalculatedValue(botAI, "can move around", 2) { } + CanMoveAroundValue(PlayerbotAI* botAI) : BoolCalculatedValue(botAI, "can move around", 2 * 2000) { } bool Calculate() override; }; @@ -20,7 +20,7 @@ class CanMoveAroundValue : public BoolCalculatedValue class ShouldHomeBindValue : public BoolCalculatedValue { public: - ShouldHomeBindValue(PlayerbotAI* botAI) : BoolCalculatedValue(botAI, "should home bind", 2) { } + ShouldHomeBindValue(PlayerbotAI* botAI) : BoolCalculatedValue(botAI, "should home bind", 2 * 2000) { } bool Calculate() override; }; @@ -28,7 +28,7 @@ class ShouldHomeBindValue : public BoolCalculatedValue class ShouldRepairValue : public BoolCalculatedValue { public: - ShouldRepairValue(PlayerbotAI* botAI) : BoolCalculatedValue(botAI,"should repair",2) { } + ShouldRepairValue(PlayerbotAI* botAI) : BoolCalculatedValue(botAI,"should repair",2 * 2000) { } bool Calculate() override; }; @@ -36,7 +36,7 @@ class ShouldRepairValue : public BoolCalculatedValue class CanRepairValue : public BoolCalculatedValue { public: - CanRepairValue(PlayerbotAI* botAI) : BoolCalculatedValue(botAI, "can repair",2) { } + CanRepairValue(PlayerbotAI* botAI) : BoolCalculatedValue(botAI, "can repair",2 * 2000) { } bool Calculate() override; }; @@ -44,7 +44,7 @@ class CanRepairValue : public BoolCalculatedValue class ShouldSellValue : public BoolCalculatedValue { public: - ShouldSellValue(PlayerbotAI* botAI) : BoolCalculatedValue(botAI, "should sell",2) { } + ShouldSellValue(PlayerbotAI* botAI) : BoolCalculatedValue(botAI, "should sell",2 * 2000) { } bool Calculate() override; }; @@ -52,7 +52,7 @@ class ShouldSellValue : public BoolCalculatedValue class CanSellValue : public BoolCalculatedValue { public: - CanSellValue(PlayerbotAI* botAI) : BoolCalculatedValue(botAI, "can sell",2) { } + CanSellValue(PlayerbotAI* botAI) : BoolCalculatedValue(botAI, "can sell",2 * 2000) { } bool Calculate() override; }; @@ -60,7 +60,7 @@ class CanSellValue : public BoolCalculatedValue class CanFightEqualValue: public BoolCalculatedValue { public: - CanFightEqualValue(PlayerbotAI* botAI) : BoolCalculatedValue(botAI, "can fight equal",2) { } + CanFightEqualValue(PlayerbotAI* botAI) : BoolCalculatedValue(botAI, "can fight equal",2 * 2000) { } bool Calculate() override; }; diff --git a/src/strategy/values/NearestGameObjects.h b/src/strategy/values/NearestGameObjects.h index 6b7c197c..73fec151 100644 --- a/src/strategy/values/NearestGameObjects.h +++ b/src/strategy/values/NearestGameObjects.h @@ -14,7 +14,7 @@ class NearestGameObjects : public ObjectGuidListCalculatedValue { public: NearestGameObjects(PlayerbotAI* botAI, float range = sPlayerbotAIConfig->sightDistance, bool ignoreLos = false, std::string const name = "nearest game objects") : - ObjectGuidListCalculatedValue(botAI, name), range(range) , ignoreLos(ignoreLos) { } + ObjectGuidListCalculatedValue(botAI, name, 2 * 1000), range(range) , ignoreLos(ignoreLos) { } protected: GuidVector Calculate() override; diff --git a/src/strategy/values/NearestUnitsValue.h b/src/strategy/values/NearestUnitsValue.h index 484faba8..7eeca734 100644 --- a/src/strategy/values/NearestUnitsValue.h +++ b/src/strategy/values/NearestUnitsValue.h @@ -15,7 +15,7 @@ class NearestUnitsValue : public ObjectGuidListCalculatedValue { public: NearestUnitsValue(PlayerbotAI* botAI, std::string const name = "nearest units", float range = sPlayerbotAIConfig->sightDistance, bool ignoreLos = false) : - ObjectGuidListCalculatedValue(botAI, name, 2), range(range), ignoreLos(ignoreLos) { } + ObjectGuidListCalculatedValue(botAI, name, 2 * 1000), range(range), ignoreLos(ignoreLos) { } GuidVector Calculate() override; diff --git a/src/strategy/values/PartyMemberToDispel.h b/src/strategy/values/PartyMemberToDispel.h index a145fa4f..36197ea9 100644 --- a/src/strategy/values/PartyMemberToDispel.h +++ b/src/strategy/values/PartyMemberToDispel.h @@ -14,7 +14,7 @@ class Unit; class PartyMemberToDispel : public PartyMemberValue, public Qualified { public: - PartyMemberToDispel(PlayerbotAI* botAI, std::string const name = "party member to dispel") : PartyMemberValue(botAI, name, 2), Qualified() { } + PartyMemberToDispel(PlayerbotAI* botAI, std::string const name = "party member to dispel") : PartyMemberValue(botAI, name, 2 * 1000), Qualified() { } protected: Unit* Calculate() override; diff --git a/src/strategy/values/PartyMemberValue.h b/src/strategy/values/PartyMemberValue.h index e3508b3d..ab9c97ef 100644 --- a/src/strategy/values/PartyMemberValue.h +++ b/src/strategy/values/PartyMemberValue.h @@ -38,7 +38,7 @@ class PartyMemberValue : public UnitCalculatedValue class PartyMemberMainTankValue : public PartyMemberValue { public: - PartyMemberMainTankValue(PlayerbotAI* botAI) : PartyMemberValue(botAI, "main tank member", 2) {} + PartyMemberMainTankValue(PlayerbotAI* botAI) : PartyMemberValue(botAI, "main tank member", 2 * 1000) {} virtual Unit* Calculate(); }; diff --git a/src/strategy/values/SpellCastUsefulValue.cpp b/src/strategy/values/SpellCastUsefulValue.cpp index ee7b5299..277eff43 100644 --- a/src/strategy/values/SpellCastUsefulValue.cpp +++ b/src/strategy/values/SpellCastUsefulValue.cpp @@ -40,7 +40,7 @@ bool SpellCastUsefulValue::Calculate() qualifier == "rockbiter weapon" || qualifier == "earthliving weapon" || qualifier == "spellstone") { if (Item* item = AI_VALUE2(Item*, "item for spell", spellid)) - if (item->GetEnchantmentId(TEMP_ENCHANTMENT_SLOT)) + if (item->IsInWorld() && item->GetEnchantmentId(TEMP_ENCHANTMENT_SLOT)) return false; } diff --git a/src/strategy/values/SpellIdValue.cpp b/src/strategy/values/SpellIdValue.cpp index f6cb6f81..0e7eef38 100644 --- a/src/strategy/values/SpellIdValue.cpp +++ b/src/strategy/values/SpellIdValue.cpp @@ -7,7 +7,7 @@ #include "Playerbots.h" #include "Vehicle.h" -SpellIdValue::SpellIdValue(PlayerbotAI* botAI) : CalculatedValue(botAI, "spell id") +SpellIdValue::SpellIdValue(PlayerbotAI* botAI) : CalculatedValue(botAI, "spell id", 20 * 1000) { } diff --git a/src/strategy/values/TargetValue.h b/src/strategy/values/TargetValue.h index 0182354e..b2cab18f 100644 --- a/src/strategy/values/TargetValue.h +++ b/src/strategy/values/TargetValue.h @@ -64,7 +64,7 @@ class TravelTargetValue : public ManualSetValue class LastLongMoveValue : public CalculatedValue { public: - LastLongMoveValue(PlayerbotAI* botAI) : CalculatedValue(botAI, "last long move", 30) { } + LastLongMoveValue(PlayerbotAI* botAI) : CalculatedValue(botAI, "last long move", 30 * 1000) { } WorldPosition Calculate() override; }; @@ -72,7 +72,7 @@ class LastLongMoveValue : public CalculatedValue class HomeBindValue : public CalculatedValue { public: - HomeBindValue(PlayerbotAI* botAI) : CalculatedValue(botAI, "home bind", 30) { } + HomeBindValue(PlayerbotAI* botAI) : CalculatedValue(botAI, "home bind", 30 * 1000) { } WorldPosition Calculate() override; }; @@ -101,7 +101,7 @@ class PullTargetValue : public ManualSetValue class FindTargetValue : public UnitCalculatedValue, public Qualified { public: - FindTargetValue(PlayerbotAI* ai) : UnitCalculatedValue(ai, "find target", 2) {} + FindTargetValue(PlayerbotAI* ai) : UnitCalculatedValue(ai, "find target", 2 * 1000) {} public: Unit* Calculate(); @@ -117,7 +117,7 @@ class FindBossTargetStrategy : public FindTargetStrategy class BossTargetValue : public TargetValue, public Qualified { public: - BossTargetValue(PlayerbotAI* ai) : TargetValue(ai, "boss target", 1) {} + BossTargetValue(PlayerbotAI* ai) : TargetValue(ai, "boss target", 2 * 1000) {} public: Unit* Calculate();