mirror of
https://github.com/mod-playerbots/mod-playerbots
synced 2025-11-29 15:58:20 +08:00
fix loot
This commit is contained in:
@@ -116,8 +116,12 @@ AiPlayerbot.RandomBotSayWithoutMaster = 0
|
||||
|
||||
# Automation
|
||||
|
||||
# Bots keep looting when group loop method is free for all
|
||||
# Default: 0 (disabled)
|
||||
AiPlayerbot.FreeMethodLoot = 0
|
||||
|
||||
# Bots pick their quest reward (yes = picks first useful item, no = list all rewards, ask = pick useful item and lists if multiple)
|
||||
AiPlayerbot.AutoPickReward = yes
|
||||
AiPlayerbot.AutoPickReward = no
|
||||
|
||||
# Bots equip upgrades (Bots will equip any item obtained from looting or a quest if they are upgrades)
|
||||
# Default: 0 (disabled)
|
||||
@@ -158,9 +162,9 @@ AiPlayerbot.AutoTeleportForLevel = 1
|
||||
# Default: 1 (enabled)
|
||||
AiPlayerbot.AutoPickTalents = 1
|
||||
|
||||
# Bot automatically upgrade equipments on levelup, may cause lagging
|
||||
# Default: 0 (enabled)
|
||||
AiPlayerbot.AutoUpgradeEquip = 0
|
||||
# Bot automatically upgrade equipments on levelup
|
||||
# Default: 1 (enabled)
|
||||
AiPlayerbot.AutoUpgradeEquip = 1
|
||||
|
||||
# Random Bots will pick quests on their own and try to complete
|
||||
# Default: 1 (enabled)
|
||||
|
||||
@@ -206,11 +206,11 @@ bool LootObject::IsLootPossible(Player* bot)
|
||||
|
||||
if (abs(GetWorldObject(bot)->GetPositionZ() - bot->GetPositionZ()) > INTERACTION_DISTANCE)
|
||||
return false;
|
||||
|
||||
|
||||
Creature* creature = botAI->GetCreature(guid);
|
||||
if (creature && creature->getDeathState() == CORPSE)
|
||||
{
|
||||
if (!creature->loot.hasItemFor(bot) && skillId != SKILL_SKINNING)
|
||||
if (!bot->isAllowedToLoot(creature) && skillId != SKILL_SKINNING)
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -290,7 +290,7 @@ std::vector<LootObject> LootObjectStack::OrderByDistance(float maxDistance)
|
||||
LootObject lootObject(bot, guid);
|
||||
if (!lootObject.IsLootPossible(bot))
|
||||
continue;
|
||||
|
||||
|
||||
float distance = bot->GetDistance(lootObject.GetWorldObject(bot));
|
||||
if (!maxDistance || distance <= maxDistance)
|
||||
sortedMap[distance] = lootObject;
|
||||
|
||||
@@ -306,6 +306,7 @@ bool PlayerbotAIConfig::Initialize()
|
||||
randomBotPreQuests = sConfigMgr->GetOption<bool>("AiPlayerbot.PreQuests", true);
|
||||
|
||||
// SPP automation
|
||||
freeMethodLoot = sConfigMgr->GetOption<bool>("AiPlayerbot.FreeMethodLoot", false);
|
||||
autoPickReward = sConfigMgr->GetOption<std::string>("AiPlayerbot.AutoPickReward", "yes");
|
||||
autoEquipUpgradeLoot = sConfigMgr->GetOption<bool>("AiPlayerbot.AutoEquipUpgradeLoot", true);
|
||||
syncQuestWithPlayer = sConfigMgr->GetOption<bool>("AiPlayerbot.SyncQuestWithPlayer", false);
|
||||
|
||||
@@ -143,6 +143,7 @@ class PlayerbotAIConfig
|
||||
uint32 playerbotsXPrate;
|
||||
uint32 botActiveAlone;
|
||||
|
||||
bool freeMethodLoot;
|
||||
std::string autoPickReward;
|
||||
bool autoEquipUpgradeLoot;
|
||||
bool syncQuestWithPlayer;
|
||||
|
||||
@@ -3043,7 +3043,9 @@ float PlayerbotFactory::CalculateItemScore(uint32 item_id, Player* bot)
|
||||
+ defense * 0.25 + dodge * 0.25 + armor * 0.5 + stamina * 1.5
|
||||
+ hit * 1 + crit * 1 + haste * 0.5 + expertise * 3;
|
||||
}
|
||||
if (proto->Class == ITEM_CLASS_ARMOR && NotSameArmorType(proto->SubClass, bot))
|
||||
// penalty for different type armor
|
||||
if (proto->Class == ITEM_CLASS_ARMOR && proto->SubClass >= ITEM_SUBCLASS_ARMOR_CLOTH &&
|
||||
proto->SubClass <= ITEM_SUBCLASS_ARMOR_PLATE && NotSameArmorType(proto->SubClass, bot))
|
||||
{
|
||||
score *= 0.8;
|
||||
}
|
||||
@@ -3087,8 +3089,7 @@ float PlayerbotFactory::CalculateItemScore(uint32 item_id, Player* bot)
|
||||
score *= 0.1;
|
||||
}
|
||||
}
|
||||
return (0.0001 + score) * itemLevel * (quality + 1);
|
||||
// return score;
|
||||
return (0.0001 + score) * itemLevel * (quality + 1);
|
||||
}
|
||||
|
||||
bool PlayerbotFactory::IsShieldTank(Player* bot)
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include "LootStrategyValue.h"
|
||||
#include "LootObjectStack.h"
|
||||
#include "GuildTaskMgr.h"
|
||||
#include "PlayerbotAIConfig.h"
|
||||
#include "Playerbots.h"
|
||||
#include "ServerFacade.h"
|
||||
|
||||
@@ -31,6 +32,10 @@ bool LootAction::Execute(Event event)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool LootAction::isUseful() {
|
||||
return sPlayerbotAIConfig->freeMethodLoot || !bot->GetGroup() || bot->GetGroup()->GetLootMethod() != FREE_FOR_ALL;
|
||||
}
|
||||
|
||||
enum ProfessionSpells
|
||||
{
|
||||
ALCHEMY = 2259,
|
||||
@@ -406,9 +411,9 @@ bool StoreLootAction::Execute(Event event)
|
||||
if (proto->Quality >= ITEM_QUALITY_RARE && !urand(0, 1) && botAI->HasStrategy("emote", BOT_STATE_NON_COMBAT))
|
||||
botAI->PlayEmote(TEXT_EMOTE_CHEER);
|
||||
|
||||
std::ostringstream out;
|
||||
out << "Looting " << chat->FormatItem(proto);
|
||||
botAI->TellMasterNoFacing(out.str());
|
||||
// std::ostringstream out;
|
||||
// out << "Looting " << chat->FormatItem(proto);
|
||||
// botAI->TellMasterNoFacing(out.str());
|
||||
|
||||
//ItemUsage usage = AI_VALUE2(ItemUsage, "item usage", proto->ItemId);
|
||||
//LOG_ERROR("playerbots", "Bot {} is looting {} {} for usage {}.", bot->GetName().c_str(), itemcount, proto->Name1.c_str(), usage);
|
||||
@@ -442,10 +447,7 @@ bool StoreLootAction::IsLootAllowed(uint32 itemid, PlayerbotAI* botAI)
|
||||
|
||||
if (proto->StartQuest)
|
||||
{
|
||||
if (sPlayerbotAIConfig->syncQuestWithPlayer)
|
||||
return false; //Quest is autocomplete for the bot so no item needed.
|
||||
else
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
|
||||
for (uint8 slot = 0; slot < MAX_QUEST_LOG_SIZE; ++slot)
|
||||
@@ -459,14 +461,13 @@ bool StoreLootAction::IsLootAllowed(uint32 itemid, PlayerbotAI* botAI)
|
||||
{
|
||||
if (quest->RequiredItemId[i] == itemid)
|
||||
{
|
||||
if (quest->RequiredItemId[i] == itemid && AI_VALUE2(uint32, "item count", proto->Name1) < quest->RequiredItemCount[i])
|
||||
if (AI_VALUE2(uint32, "item count", proto->Name1) < quest->RequiredItemCount[i])
|
||||
{
|
||||
if (botAI->GetMaster() && sPlayerbotAIConfig->syncQuestWithPlayer)
|
||||
return false; //Quest is autocomplete for the bot so no item needed.
|
||||
}
|
||||
|
||||
if (AI_VALUE2(uint32, "item count", proto->Name1) < quest->RequiredItemCount[i])
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@ class LootAction : public MovementAction
|
||||
LootAction(PlayerbotAI* botAI) : MovementAction(botAI, "loot") { }
|
||||
|
||||
bool Execute(Event event) override;
|
||||
bool isUseful() override;
|
||||
};
|
||||
|
||||
class OpenLootAction : public MovementAction
|
||||
|
||||
@@ -78,7 +78,7 @@ ItemUsage ItemUsageValue::Calculate()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (bot->GetGuildId() && sGuildTaskMgr->IsGuildTaskItem(itemId, bot->GetGuildId()))
|
||||
return ITEM_USAGE_GUILD_TASK;
|
||||
|
||||
@@ -202,13 +202,13 @@ ItemUsage ItemUsageValue::QueryItemUsageForEquip(ItemTemplate const* itemProto)
|
||||
return ITEM_USAGE_BAD_EQUIP;
|
||||
|
||||
ItemTemplate const* oldItemProto = oldItem->GetTemplate();
|
||||
float oldScore = PlayerbotFactory::CalculateItemScore(oldItemProto->ItemId, bot);
|
||||
if (oldItem)
|
||||
{
|
||||
// uint32 oldStatWeight = sRandomItemMgr->GetLiveStatWeight(bot, oldItemProto->ItemId);
|
||||
float oldScore = PlayerbotFactory::CalculateItemScore(oldItemProto->ItemId, bot);
|
||||
if (itemScore || oldScore)
|
||||
{
|
||||
shouldEquip = itemScore >= oldScore * 1.5;
|
||||
shouldEquip = itemScore > oldScore * 1.1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -226,17 +226,17 @@ ItemUsage ItemUsageValue::QueryItemUsageForEquip(ItemTemplate const* itemProto)
|
||||
if (oldItemProto->Class == ITEM_CLASS_ARMOR && !sRandomItemMgr->CanEquipArmor(bot->getClass(), bot->getLevel(), oldItemProto))
|
||||
existingShouldEquip = false;
|
||||
|
||||
uint32 oldItemPower = sRandomItemMgr->GetLiveStatWeight(bot, oldItemProto->ItemId);
|
||||
uint32 newItemPower = sRandomItemMgr->GetLiveStatWeight(bot, itemProto->ItemId);
|
||||
// uint32 oldItemPower = sRandomItemMgr->GetLiveStatWeight(bot, oldItemProto->ItemId);
|
||||
// uint32 newItemPower = sRandomItemMgr->GetLiveStatWeight(bot, itemProto->ItemId);
|
||||
|
||||
//Compare items based on item level, quality or itemId.
|
||||
bool isBetter = false;
|
||||
if (newItemPower > oldItemPower)
|
||||
isBetter = true;
|
||||
else if (newItemPower == oldItemPower && itemProto->Quality > oldItemProto->Quality)
|
||||
isBetter = true;
|
||||
else if (newItemPower == oldItemPower && itemProto->Quality == oldItemProto->Quality && itemProto->ItemId > oldItemProto->ItemId)
|
||||
if (itemScore > oldScore)
|
||||
isBetter = true;
|
||||
// else if (newItemPower == oldScore && itemProto->Quality > oldItemProto->Quality)
|
||||
// isBetter = true;
|
||||
// else if (newItemPower == oldScore && itemProto->Quality == oldItemProto->Quality && itemProto->ItemId > oldItemProto->ItemId)
|
||||
// isBetter = true;
|
||||
|
||||
Item* item = CurrentItem(itemProto);
|
||||
bool itemIsBroken = item && item->GetUInt32Value(ITEM_FIELD_DURABILITY) == 0 && item->GetUInt32Value(ITEM_FIELD_MAXDURABILITY) > 0;
|
||||
|
||||
Reference in New Issue
Block a user