diff --git a/conf/playerbots.conf.dist b/conf/playerbots.conf.dist index 9f80241b..f987fe79 100644 --- a/conf/playerbots.conf.dist +++ b/conf/playerbots.conf.dist @@ -822,8 +822,8 @@ AiPlayerbot.PremadeSpecLink.3.0.60 = 51200201505112243100511351 AiPlayerbot.PremadeSpecLink.3.0.80 = 51200201505112253100531351-015305021 AiPlayerbot.PremadeSpecName.3.1 = mm pve AiPlayerbot.PremadeSpecGlyph.3.1 = 42912,43350,42914,43351,43338,45732 -AiPlayerbot.PremadeSpecLink.3.1.60 = -005305111230013233125030151-5 -AiPlayerbot.PremadeSpecLink.3.1.80 = 502-005305131230013233135031351-5000002 +AiPlayerbot.PremadeSpecLink.3.1.60 = -015305101230013233125031051 +AiPlayerbot.PremadeSpecLink.3.1.80 = 502-035305101230013233135031351-5000002 AiPlayerbot.PremadeSpecName.3.2 = surv pve AiPlayerbot.PremadeSpecGlyph.3.2 = 42912,43350,45731,43351,43338,45732 AiPlayerbot.PremadeSpecLink.3.2.60 = --5000032500033330502135201311 @@ -977,7 +977,7 @@ AiPlayerbot.PremadeSpecLink.9.0.70 = 2350022001113510053500131151--55 AiPlayerbot.PremadeSpecLink.9.0.80 = 2350022001113510253500331151--5500000501 AiPlayerbot.PremadeSpecName.9.1 = emo pve AiPlayerbot.PremadeSpecGlyph.9.1 = 45785,43390,50077,43394,43393,42459 -AiPlayerbot.PremadeSpecLink.9.1.60 = -003203301135112530131201-55 +AiPlayerbot.PremadeSpecLink.9.1.60 = -003203301135112530135201051 AiPlayerbot.PremadeSpecLink.9.1.70 = -003203301135112530135201051-55 AiPlayerbot.PremadeSpecLink.9.1.80 = -003203301135112530135221351-55000005 AiPlayerbot.PremadeSpecName.9.2 = destro pve @@ -1177,11 +1177,11 @@ AiPlayerbot.RandomClassSpecIndex.8.2 = 2 # # -AiPlayerbot.RandomClassSpecProb.9.0 = 40 +AiPlayerbot.RandomClassSpecProb.9.0 = 45 AiPlayerbot.RandomClassSpecIndex.9.0 = 0 -AiPlayerbot.RandomClassSpecProb.9.1 = 40 +AiPlayerbot.RandomClassSpecProb.9.1 = 45 AiPlayerbot.RandomClassSpecIndex.9.1 = 1 -AiPlayerbot.RandomClassSpecProb.9.2 = 20 +AiPlayerbot.RandomClassSpecProb.9.2 = 10 AiPlayerbot.RandomClassSpecIndex.9.2 = 2 # diff --git a/src/PlayerbotAI.cpp b/src/PlayerbotAI.cpp index e80304be..5df7402b 100644 --- a/src/PlayerbotAI.cpp +++ b/src/PlayerbotAI.cpp @@ -5277,11 +5277,9 @@ InventoryResult PlayerbotAI::CanEquipItem(uint8 slot, uint16& dest, Item* pItem, if (pItem->IsBindedNotWith(bot)) return EQUIP_ERR_DONT_OWN_THAT_ITEM; - // Yunfan: skip it - // // check count of items (skip for auto move for same player from bank) - // InventoryResult res = bot->CanTakeMoreSimilarItems(pItem); - // if (res != EQUIP_ERR_OK) - // return res; + InventoryResult res = bot->CanTakeMoreSimilarItems(pItem); + if (res != EQUIP_ERR_OK) + return res; ScalingStatDistributionEntry const* ssd = pProto->ScalingStatDistribution @@ -5300,7 +5298,7 @@ InventoryResult PlayerbotAI::CanEquipItem(uint8 slot, uint16& dest, Item* pItem, if (!bot->CanUseAttackType(bot->GetAttackBySlot(eslot))) return EQUIP_ERR_NOT_WHILE_DISARMED; - InventoryResult res = bot->CanUseItem(pItem, not_loading); + res = bot->CanUseItem(pItem, not_loading); if (res != EQUIP_ERR_OK) return res; diff --git a/src/factory/PlayerbotFactory.cpp b/src/factory/PlayerbotFactory.cpp index a40e28a4..a2bca1b9 100644 --- a/src/factory/PlayerbotFactory.cpp +++ b/src/factory/PlayerbotFactory.cpp @@ -287,7 +287,7 @@ void PlayerbotFactory::Randomize(bool incremental) LOG_DEBUG("playerbots", "Initializing equipmemt..."); if (!sPlayerbotAIConfig->equipmentPersistence || bot->GetLevel() < sPlayerbotAIConfig->equipmentPersistenceLevel) { - InitEquipment(incremental); + InitEquipment(incremental, incremental ? false : true); } // bot->SaveToDB(false, false); if (pmo) @@ -951,7 +951,12 @@ void PlayerbotFactory::InitTalentsTree(bool increment /*false*/, bool use_templa } else { - uint32 point = urand(1, 100); + uint32 pointSum = 0; + for (int i = 0; i < MAX_SPECNO; i++) + { + pointSum += sPlayerbotAIConfig->randomClassSpecProb[cls][i]; + } + uint32 point = urand(1, pointSum); uint32 currentP = 0; int i; for (i = 0; i < MAX_SPECNO; i++) @@ -1356,7 +1361,8 @@ bool PlayerbotFactory::CanEquipItem(ItemTemplate const* proto) return true; uint32 requiredLevel = proto->RequiredLevel; - bool hasItem = bot->HasItemCount(proto->ItemId, 1, true); + // disable since bad performance + bool hasItem = bot->HasItemCount(proto->ItemId, 1, false); // bot->GetItemCount() // !requiredLevel -> it's a quest reward item if (!requiredLevel && hasItem) @@ -1573,10 +1579,13 @@ void PlayerbotFactory::InitEquipment(bool incremental, bool second_chance) { for (uint32 itemId : sRandomItemMgr->GetCachedEquipments(requiredLevel, inventoryType)) { - if (itemId == 46978) - { // shaman earth ring totem + if (itemId == 46978) // shaman earth ring totem + { continue; } + uint32 skipProb = 25; + if (urand(1, 100) <= skipProb) + continue; // disable next expansion gear if (sPlayerbotAIConfig->limitGearExpansion && bot->GetLevel() <= 60 && itemId >= 23728) @@ -1603,8 +1612,8 @@ void PlayerbotFactory::InitEquipment(bool incremental, bool second_chance) if (proto->Quality != desiredQuality) continue; - if (!CanEquipItem(proto)) - continue; + // if (!CanEquipItem(proto)) + // continue; if (proto->Class == ITEM_CLASS_ARMOR && (slot == EQUIPMENT_SLOT_HEAD || slot == EQUIPMENT_SLOT_SHOULDERS || @@ -1621,9 +1630,9 @@ void PlayerbotFactory::InitEquipment(bool incremental, bool second_chance) proto->Class != ITEM_CLASS_WEAPON) continue; - uint16 dest = 0; - if (CanEquipUnseenItem(slot, dest, itemId)) - items[slot].push_back(itemId); + // uint16 dest = 0; + // if (CanEquipUnseenItem(slot, dest, itemId)) + items[slot].push_back(itemId); } } if (items[slot].size() >= 25) @@ -1640,26 +1649,20 @@ void PlayerbotFactory::InitEquipment(bool incremental, bool second_chance) float bestScoreForSlot = -1; uint32 bestItemForSlot = 0; for (int index = 0; index < ids.size(); index++) - { - uint32 skipProb = 25; - if (urand(1, 100) <= skipProb) - continue; - + { uint32 newItemId = ids[index]; - uint16 dest; - ItemTemplate const* proto = sObjectMgr->GetItemTemplate(newItemId); - if (!CanEquipItem(proto)) - continue; - - if (!CanEquipUnseenItem(slot, dest, newItemId)) - continue; - float cur_score = calculator.CalculateItem(newItemId); if (cur_score > bestScoreForSlot) { + // delay heavy check to here + if (!CanEquipItem(proto)) + continue; + uint16 dest; + if (!CanEquipUnseenItem(slot, dest, newItemId)) + continue; bestScoreForSlot = cur_score; bestItemForSlot = newItemId; } @@ -1695,18 +1698,107 @@ void PlayerbotFactory::InitEquipment(bool incremental, bool second_chance) Item* newItem = bot->EquipNewItem(dest, bestItemForSlot, true); bot->AutoUnequipOffhandIfNeed(); - // bot->AutoUnequipOffhandIfNeed(); if (newItem) { newItem->AddToWorld(); newItem->AddToUpdateQueueOf(bot); } } - // secondary init for better equips - if (!incremental && !second_chance) - InitEquipment(incremental, true); - + // Secondary init for better equips + /// @todo: clean up duplicate code + if (!incremental && second_chance) + { + for (uint8 slot = 0; slot < EQUIPMENT_SLOT_END; ++slot) + { + if (slot == EQUIPMENT_SLOT_TABARD || slot == EQUIPMENT_SLOT_BODY) + continue; + if (level < 40 && (slot == EQUIPMENT_SLOT_TRINKET1 || slot == EQUIPMENT_SLOT_TRINKET2)) + continue; + + if (level < 30 && slot == EQUIPMENT_SLOT_NECK) + continue; + + if (level < 25 && slot == EQUIPMENT_SLOT_HEAD) + continue; + + if (level < 20 && (slot == EQUIPMENT_SLOT_FINGER1 || slot == EQUIPMENT_SLOT_FINGER2)) + continue; + + Item* oldItem = bot->GetItemByPos(INVENTORY_SLOT_BAG_0, slot); + + if (oldItem) + { + bot->DestroyItem(INVENTORY_SLOT_BAG_0, slot, true); + } + + oldItem = bot->GetItemByPos(INVENTORY_SLOT_BAG_0, slot); + + std::vector& ids = items[slot]; + if (ids.empty()) + { + continue; + } + + float bestScoreForSlot = -1; + uint32 bestItemForSlot = 0; + for (int index = 0; index < ids.size(); index++) + { + uint32 newItemId = ids[index]; + + ItemTemplate const* proto = sObjectMgr->GetItemTemplate(newItemId); + + float cur_score = calculator.CalculateItem(newItemId); + if (cur_score > bestScoreForSlot) + { + // delay heavy check to here + if (!CanEquipItem(proto)) + continue; + uint16 dest; + if (!CanEquipUnseenItem(slot, dest, newItemId)) + continue; + bestScoreForSlot = cur_score; + bestItemForSlot = newItemId; + } + } + + if (bestItemForSlot == 0) + { + continue; + } + uint16 dest; + if (!CanEquipUnseenItem(slot, dest, bestItemForSlot)) + { + continue; + } + + if (incremental && oldItem) + { + float old_score = calculator.CalculateItem(oldItem->GetEntry()); + if (bestScoreForSlot < 1.2f * old_score) + continue; + } + + if (oldItem) + { + uint8 bagIndex = oldItem->GetBagSlot(); + uint8 slot = oldItem->GetSlot(); + uint8 dstBag = NULL_BAG; + + WorldPacket packet(CMSG_AUTOSTORE_BAG_ITEM, 3); + packet << bagIndex << slot << dstBag; + bot->GetSession()->HandleAutoStoreBagItemOpcode(packet); + } + + Item* newItem = bot->EquipNewItem(dest, bestItemForSlot, true); + bot->AutoUnequipOffhandIfNeed(); + if (newItem) + { + newItem->AddToWorld(); + newItem->AddToUpdateQueueOf(bot); + } + } + } } bool PlayerbotFactory::IsDesiredReplacement(Item* item) @@ -1876,11 +1968,11 @@ void PlayerbotFactory::InitBags(bool destroyOld) continue; } Item* newItem = bot->EquipNewItem(dest, newItemId, true); - if (newItem) - { - newItem->AddToWorld(); - newItem->AddToUpdateQueueOf(bot); - } + // if (newItem) + // { + // newItem->AddToWorld(); + // newItem->AddToUpdateQueueOf(bot); + // } } } @@ -2254,6 +2346,7 @@ void PlayerbotFactory::InitAvailableSpells() trainerIdCache.push_back(trainerId); } } + uint32 learnedCounter = 0; for (uint32 trainerId : trainerIdCache) { TrainerSpellData const* trainer_spells = sObjectMgr->GetNpcTrainerSpells(trainerId); @@ -2297,7 +2390,6 @@ void PlayerbotFactory::InitAvailableSpells() { continue; } - if (tSpell->learnedSpell[0]) { bot->learnSpell(tSpell->learnedSpell[0], false); @@ -2307,6 +2399,8 @@ void PlayerbotFactory::InitAvailableSpells() botAI->CastSpell(tSpell->spell, bot); } } + if (++learnedCounter > 20) + break; } } diff --git a/src/factory/StatsWeightCalculator.cpp b/src/factory/StatsWeightCalculator.cpp index bf08e19e..c3a328f0 100644 --- a/src/factory/StatsWeightCalculator.cpp +++ b/src/factory/StatsWeightCalculator.cpp @@ -32,6 +32,15 @@ StatsWeightCalculator::StatsWeightCalculator(Player* player) : player_(player) cls = player->getClass(); tab = AiFactory::GetPlayerSpecTab(player); + if (cls == CLASS_DEATH_KNIGHT && tab == DEATHKNIGHT_TAB_UNHOLY) + hitOverflowType_ = CollectorType::SPELL; + else if (cls == CLASS_SHAMAN && tab == SHAMAN_TAB_ENHANCEMENT) + hitOverflowType_ = CollectorType::SPELL; + else if (cls == CLASS_ROGUE) + hitOverflowType_ = CollectorType::SPELL; + else + hitOverflowType_ = type_; + enable_overflow_penalty_ = true; enable_item_set_bonus_ = true; enable_quality_blend_ = true; @@ -515,7 +524,7 @@ void StatsWeightCalculator::ApplyOverflowPenalty(Player* player) float validPoints; // m_modMeleeHitChance = (float)GetTotalAuraModifier(SPELL_AURA_MOD_HIT_CHANCE); // m_modMeleeHitChance += GetRatingBonusValue(CR_HIT_MELEE); - if (GetHitOverflowType(player) == CollectorType::SPELL) + if (hitOverflowType_ == CollectorType::SPELL) { hit_current = player->GetTotalAuraModifier(SPELL_AURA_MOD_SPELL_HIT_CHANCE); hit_current += player->GetRatingBonusValue(CR_HIT_SPELL); @@ -525,7 +534,7 @@ void StatsWeightCalculator::ApplyOverflowPenalty(Player* player) else validPoints = 0; } - else if (GetHitOverflowType(player) == CollectorType::MELEE) + else if (hitOverflowType_ == CollectorType::MELEE) { hit_current = player->GetTotalAuraModifier(SPELL_AURA_MOD_HIT_CHANCE); hit_current += player->GetRatingBonusValue(CR_HIT_MELEE); @@ -613,18 +622,3 @@ void StatsWeightCalculator::ApplyWeightFinetune(Player* player) } } } - -CollectorType StatsWeightCalculator::GetHitOverflowType(Player* player) -{ - cls = player->getClass(); - tab = AiFactory::GetPlayerSpecTab(player); - if (cls == CLASS_DEATH_KNIGHT && tab == DEATHKNIGHT_TAB_UNHOLY) - return CollectorType::SPELL; - if (cls == CLASS_SHAMAN && tab == SHAMAN_TAB_ENHANCEMENT) - return CollectorType::SPELL; - if (cls == CLASS_ROGUE) - return CollectorType::SPELL; - - return type_; -} - \ No newline at end of file diff --git a/src/factory/StatsWeightCalculator.h b/src/factory/StatsWeightCalculator.h index f6f4bf7e..d65966ff 100644 --- a/src/factory/StatsWeightCalculator.h +++ b/src/factory/StatsWeightCalculator.h @@ -49,11 +49,11 @@ private: void ApplyOverflowPenalty(Player* player); void ApplyWeightFinetune(Player* player); - CollectorType GetHitOverflowType(Player* player); private: Player* player_; CollectorType type_; + CollectorType hitOverflowType_; std::unique_ptr collector_; uint8 cls; int tab;