diff --git a/src/PlayerbotFactory.cpp b/src/PlayerbotFactory.cpp index 21409f18..e8360991 100644 --- a/src/PlayerbotFactory.cpp +++ b/src/PlayerbotFactory.cpp @@ -136,6 +136,9 @@ void PlayerbotFactory::Init() continue; } ItemTemplate const* proto = sObjectMgr->GetItemTemplate(gemId); + if (proto->Flags & ITEM_FLAG_UNIQUE_EQUIPPABLE) { // unique gem + continue; + } if (!proto || !sGemPropertiesStore.LookupEntry(proto->GemProperties)) { continue; } @@ -2571,7 +2574,7 @@ void PlayerbotFactory::InitMounts() break; case RACE_NIGHTELF: slow = { 10789, 8394, 10793 }; - fast = { 24252, 63637, 22723 }; + fast = { 23219, 23220, 63637 }; break; case RACE_UNDEAD_PLAYER: slow = { 17463, 17464, 17462 }; @@ -2858,7 +2861,29 @@ void PlayerbotFactory::InitGlyphs(bool increment) if (!increment) { for (uint32 slotIndex = 0; slotIndex < MAX_GLYPH_SLOT_INDEX; ++slotIndex) { - bot->SetGlyph(slotIndex, 0, true); + uint32 glyph = bot->GetGlyph(slotIndex); + if (GlyphPropertiesEntry const* glyphEntry = sGlyphPropertiesStore.LookupEntry(glyph)) + { + bot->RemoveAurasDueToSpell(glyphEntry->SpellId); + + // Removed any triggered auras + Unit::AuraMap& ownedAuras = bot->GetOwnedAuras(); + for (Unit::AuraMap::iterator iter = ownedAuras.begin(); iter != ownedAuras.end();) + { + Aura* aura = iter->second; + if (SpellInfo const* triggeredByAuraSpellInfo = aura->GetTriggeredByAuraSpellInfo()) + { + if (triggeredByAuraSpellInfo->Id == glyphEntry->SpellId) + { + bot->RemoveOwnedAura(iter); + continue; + } + } + ++iter; + } + + bot->SetGlyph(slotIndex, 0, true); + } } } @@ -2957,6 +2982,8 @@ void PlayerbotFactory::InitGlyphs(bool increment) if (!glyph) { continue; } + GlyphPropertiesEntry const* glyphEntry = sGlyphPropertiesStore.LookupEntry(glyph); + bot->CastSpell(bot, glyphEntry->SpellId, TriggerCastFlags(TRIGGERED_FULL_MASK & ~(TRIGGERED_IGNORE_SHAPESHIFT | TRIGGERED_IGNORE_CASTER_AURASTATE))); bot->SetGlyph(realSlot, glyph, true); chosen.insert(glyph); } else { @@ -2990,7 +3017,9 @@ void PlayerbotFactory::InitGlyphs(bool increment) continue; chosen.insert(id); - + GlyphPropertiesEntry const* glyphEntry = sGlyphPropertiesStore.LookupEntry(id); + bot->CastSpell(bot, glyphEntry->SpellId, TriggerCastFlags(TRIGGERED_FULL_MASK & ~(TRIGGERED_IGNORE_SHAPESHIFT | TRIGGERED_IGNORE_CASTER_AURASTATE))); + bot->SetGlyph(realSlot, id, true); found = true; break; diff --git a/src/RandomItemMgr.cpp b/src/RandomItemMgr.cpp index c3b01ef5..1e1a18ab 100644 --- a/src/RandomItemMgr.cpp +++ b/src/RandomItemMgr.cpp @@ -2211,8 +2211,8 @@ void RandomItemMgr::BuildAmmoCache() { for (uint32 subClass = ITEM_SUBCLASS_ARROW; subClass <= ITEM_SUBCLASS_BULLET; subClass++) { - QueryResult results = WorldDatabase.Query("SELECT entry, Flags FROM item_template WHERE class = {} AND subclass = {} AND RequiredLevel <= {} AND stackable = 1000 " - "ORDER BY RequiredLevel DESC", ITEM_CLASS_PROJECTILE, subClass, level); + QueryResult results = WorldDatabase.Query("SELECT entry, Flags FROM item_template WHERE class = {} AND subclass = {} AND RequiredLevel <= {} " + "ORDER BY stackable DESC, RequiredLevel DESC", ITEM_CLASS_PROJECTILE, subClass, level); if (!results) continue; do { diff --git a/src/RandomPlayerbotFactory.cpp b/src/RandomPlayerbotFactory.cpp index e1fec407..b1dfae8b 100644 --- a/src/RandomPlayerbotFactory.cpp +++ b/src/RandomPlayerbotFactory.cpp @@ -375,7 +375,7 @@ void RandomPlayerbotFactory::CreateRandomBots() LOG_INFO("playerbots", "Creating random bot accounts..."); std::vector> account_creations; - bool account_creation = false; + int account_creation = 0; for (uint32 accountNumber = 0; accountNumber < sPlayerbotAIConfig->randomBotAccountCount; ++accountNumber) { std::ostringstream out; @@ -389,7 +389,7 @@ void RandomPlayerbotFactory::CreateRandomBots() { continue; } - account_creation = true; + account_creation++; std::string password = ""; if (sPlayerbotAIConfig->randomBotRandomPassword) { @@ -408,6 +408,7 @@ void RandomPlayerbotFactory::CreateRandomBots() if (account_creation) { /* wait for async accounts create to make character create correctly, same as account delete */ + LOG_INFO("playerbots", "Waiting for {} accounts loading into database...", account_creation); std::this_thread::sleep_for(10ms * sPlayerbotAIConfig->randomBotAccountCount); } @@ -418,7 +419,7 @@ void RandomPlayerbotFactory::CreateRandomBots() std::unordered_map> names; std::vector> playerBots; std::vector sessionBots; - bool bot_creation = false; + int bot_creation = 0; for (uint32 accountNumber = 0; accountNumber < sPlayerbotAIConfig->randomBotAccountCount; ++accountNumber) { std::ostringstream out; @@ -441,7 +442,6 @@ void RandomPlayerbotFactory::CreateRandomBots() { continue; } - bot_creation = true; LOG_INFO("playerbots", "Creating random bot characters for account: [{}/{}]", accountNumber + 1, sPlayerbotAIConfig->randomBotAccountCount); RandomPlayerbotFactory factory(accountId); @@ -462,19 +462,23 @@ void RandomPlayerbotFactory::CreateRandomBots() continue; } - if (cls != 10) + if (cls != 10) { if (Player* playerBot = factory.CreateRandomBot(session, cls, names)) { playerBot->SaveToDB(true, false); sCharacterCache->AddCharacterCacheEntry(playerBot->GetGUID(), accountId, playerBot->GetName(), playerBot->getGender(), playerBot->getRace(), playerBot->getClass(), playerBot->GetLevel()); playerBot->CleanupsBeforeDelete(); delete playerBot; + bot_creation++; + } else { + LOG_ERROR("playerbots", "Fail to create character for account {}", accountId); } + } } } if (bot_creation) { - LOG_INFO("playerbots", "Waiting for {} characters loading into database...", totalCharCount); + LOG_INFO("playerbots", "Waiting for {} characters loading into database...", bot_creation); /* wait for characters load into database, or characters will fail to loggin */ std::this_thread::sleep_for(10s); } diff --git a/src/RandomPlayerbotMgr.cpp b/src/RandomPlayerbotMgr.cpp index 639acd52..1a424d5e 100644 --- a/src/RandomPlayerbotMgr.cpp +++ b/src/RandomPlayerbotMgr.cpp @@ -1501,7 +1501,6 @@ void RandomPlayerbotMgr::Randomize(Player* bot) else { RandomizeFirst(bot); } - RandomTeleportForLevel(bot); } void RandomPlayerbotMgr::IncreaseLevel(Player* bot) @@ -1590,6 +1589,8 @@ void RandomPlayerbotMgr::RandomizeFirst(Player* bot) if (pmo) pmo->finish(); + + RandomTeleportForLevel(bot); } void RandomPlayerbotMgr::RandomizeMin(Player* bot) diff --git a/src/strategy/actions/UseMeetingStoneAction.cpp b/src/strategy/actions/UseMeetingStoneAction.cpp index 5380d6f9..3ef3b0b1 100644 --- a/src/strategy/actions/UseMeetingStoneAction.cpp +++ b/src/strategy/actions/UseMeetingStoneAction.cpp @@ -164,15 +164,15 @@ bool SummonAction::SummonUsingNpcs(Player* summoner, Player* player) bool SummonAction::Teleport(Player* summoner, Player* player) { Player* master = GetMaster(); - if (master->GetMap() && master->GetMap()->IsDungeon()) { - InstanceMap* map = master->GetMap()->ToInstanceMap(); - if (map) { - if (map->CannotEnter(player) == Map::CANNOT_ENTER_MAX_PLAYERS) { - botAI->TellError("I can not enter this dungeon"); - return false; - } - } - } + // if (master->GetMap() && master->GetMap()->IsDungeon()) { + // InstanceMap* map = master->GetMap()->ToInstanceMap(); + // if (map) { + // if (map->CannotEnter(player, true) == Map::CANNOT_ENTER_MAX_PLAYERS) { + // botAI->TellError("I can not enter this dungeon"); + // return false; + // } + // } + // } if (!summoner->IsBeingTeleported() && !player->IsBeingTeleported()) { float followAngle = GetFollowAngle(); diff --git a/src/strategy/deathknight/UnholyDKStrategy.cpp b/src/strategy/deathknight/UnholyDKStrategy.cpp index 5bc5f500..8edab828 100644 --- a/src/strategy/deathknight/UnholyDKStrategy.cpp +++ b/src/strategy/deathknight/UnholyDKStrategy.cpp @@ -72,12 +72,12 @@ UnholyDKStrategy::UnholyDKStrategy(PlayerbotAI* botAI) : GenericDKStrategy(botAI NextAction** UnholyDKStrategy::getDefaultActions() { return NextAction::array(0, - new NextAction("death and decay", ACTION_DEFAULT + 1.0f), - new NextAction("scourge strike", ACTION_DEFAULT + 0.8f), - new NextAction("horn of winter", ACTION_DEFAULT + 0.6f), - new NextAction("summon gargoyle", ACTION_DEFAULT + 0.4f), + new NextAction("death and decay", ACTION_DEFAULT + 0.5f), + new NextAction("horn of winter", ACTION_DEFAULT + 0.4f), + new NextAction("summon gargoyle", ACTION_DEFAULT + 0.3f), new NextAction("death coil", ACTION_DEFAULT + 0.2f), - new NextAction("melee", ACTION_DEFAULT), + new NextAction("scourge strike", ACTION_NORMAL + 0.1f), + new NextAction("melee", ACTION_DEFAULT), nullptr); } @@ -91,8 +91,8 @@ void UnholyDKStrategy::InitTriggers(std::vector& triggers) triggers.push_back(new TriggerNode("no desolation", NextAction::array(0, new NextAction("blood strike", ACTION_HIGH + 4), nullptr))); triggers.push_back(new TriggerNode("death and decay cooldown", NextAction::array(0, - new NextAction("ghoul frenzy", ACTION_DEFAULT + 5.0f), - new NextAction("scourge strike", ACTION_DEFAULT + 4.0f), + new NextAction("ghoul frenzy", ACTION_NORMAL + 5.0f), + new NextAction("scourge strike", ACTION_NORMAL + 4.0f), new NextAction("blood boil", ACTION_NORMAL + 3.0f), new NextAction("icy touch", ACTION_NORMAL + 2.0f), new NextAction("plague strike", ACTION_NORMAL + 1.0f),