diff --git a/src/server/apps/worldserver/worldserver.conf.dist b/src/server/apps/worldserver/worldserver.conf.dist index 4343176bd518f8..1a82df43d6b7b3 100644 --- a/src/server/apps/worldserver/worldserver.conf.dist +++ b/src/server/apps/worldserver/worldserver.conf.dist @@ -4944,6 +4944,18 @@ NpcBot.WanderingBots.Continents.Maps = 0,1,530,571 NpcBot.WanderingBots.Continents.XPGain = 1.0 +# +# NpcBot.WanderingBots.MaxItemLevel.Levels +# Description: Maximum item ilevel to generate for wandering bots per level bracket: +# 0-9, 10-19, 20,29, ... , 70-79, 80+. +# Note: If item generation attempt fails becuse of item ilevel restriction +# the item will be generated again with this restriction ignored +# Example: 0,0,0,0,0,0,0,0,200 makes level 80+ wandering bots only generate +# items of ilevel 200 or less +# Default: 0,0,0,0,0,0,0,0,0 + +NpcBot.WanderingBots.MaxItemLevel.Levels = 0,0,0,0,0,0,0,0,0 + # # NpcBot.WanderingBots.BG.Enable # Description: Allow wandering bots generation for Battlegrounds. diff --git a/src/server/game/AI/NpcBots/botdatamgr.cpp b/src/server/game/AI/NpcBots/botdatamgr.cpp index ce7171a47fb449..2ed3a0ff6311ba 100644 --- a/src/server/game/AI/NpcBots/botdatamgr.cpp +++ b/src/server/game/AI/NpcBots/botdatamgr.cpp @@ -2166,11 +2166,18 @@ Item* BotDataMgr::GenerateWanderingBotItem(uint8 slot, uint8 botclass, uint8 lev { ItemIdVector validVec; validVec.reserve(itemIdVec->size()); - for (uint32 iid : *itemIdVec) + uint32 maxItemLevel = BotMgr::GetBotWandererMaxItemLevel(level); + for (uint32 maxLvl : { maxItemLevel, static_cast(0) }) { - ItemTemplate const* proto = sObjectMgr->GetItemTemplate(iid); - if (check(proto)) - validVec.push_back(iid); + if (!validVec.empty()) + break; + + for (uint32 iid : *itemIdVec) + { + ItemTemplate const* proto = sObjectMgr->GetItemTemplate(iid); + if ((!maxLvl || proto->ItemLevel <= maxLvl) && check(proto)) + validVec.push_back(iid); + } } if (!validVec.empty()) diff --git a/src/server/game/AI/NpcBots/botmgr.cpp b/src/server/game/AI/NpcBots/botmgr.cpp index 302ef516410140..2f72b51c759498 100644 --- a/src/server/game/AI/NpcBots/botmgr.cpp +++ b/src/server/game/AI/NpcBots/botmgr.cpp @@ -189,6 +189,7 @@ std::vector _mult_hp_levels; std::vector _mult_mp_levels; LvlBrackets _max_npcbots; PctBrackets _botwanderer_pct_level_brackets; +ItemLvlBrackets _botwanderer_itemlvl_level_brackets; std::vector _disabled_instance_maps; std::vector _enabled_wander_node_maps; @@ -599,6 +600,19 @@ void BotMgr::LoadConfig(bool reload) _disabled_instance_maps.push_back(uval); } + _botwanderer_itemlvl_level_brackets = {}; + std::string itemlevel_by_levels = sConfigMgr->GetStringDefault("NpcBot.WanderingBots.MaxItemLevel.Levels", "0,0,0,0,0,0,0,0,0"); + std::vector tok8 = Bcore::Tokenize(itemlevel_by_levels, ',', false); + ASSERT(tok8.size() == BracketsCount, "NpcBot.WanderingBots.MaxItemLevel.Levels must have exactly %u values", uint32(BracketsCount)); + for (decltype(tok8)::size_type i = 0; i != tok8.size(); ++i) + { + Optional val = Bcore::StringTo(tok8[i]); + if (val == std::nullopt) + BOT_LOG_ERROR("server.loading", "NpcBot.WanderingBots.MaxItemLevel.Levels contains invalid uint32 value '{}', set to default", tok8[i]); + uint32 uval = val.value_or(uint32(0)); + _botwanderer_itemlvl_level_brackets[i] = uval; + } + //limits _mountLevel100 = std::max(_mountLevel100, _mountLevel60); RoundToInterval(_mult_dmg_physical, 0.1f, 10.f); @@ -3117,6 +3131,10 @@ PctBrackets BotMgr::GetBotWandererLevelBrackets() { return _botwanderer_pct_level_brackets; } +uint32 BotMgr::GetBotWandererMaxItemLevel(uint8 level) +{ + return _botwanderer_itemlvl_level_brackets[std::min(BracketsCount - 1, level / 10)]; +} float BotMgr::GetBotDamageModByClass(uint8 botclass) { switch (botclass) diff --git a/src/server/game/AI/NpcBots/botmgr.h b/src/server/game/AI/NpcBots/botmgr.h index abf987f4f0bc1d..3973adf235c72f 100644 --- a/src/server/game/AI/NpcBots/botmgr.h +++ b/src/server/game/AI/NpcBots/botmgr.h @@ -99,6 +99,7 @@ template using BotBrackets = std::array; typedef BotBrackets LvlBrackets; typedef BotBrackets PctBrackets; +typedef BotBrackets ItemLvlBrackets; class AC_GAME_API BotMgr { @@ -174,6 +175,7 @@ class AC_GAME_API BotMgr static float GetBotWandererSpeedMod(); static float GetBotWandererXPGainMod(); static PctBrackets GetBotWandererLevelBrackets(); + static uint32 GetBotWandererMaxItemLevel(uint8 level); static float GetBotDamageModByClass(uint8 botclass); static float GetBotDamageModByLevel(uint8 botlevel); static float GetBotHealingModByLevel(uint8 botlevel);