Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions src/game/WorldHandlers/SpellEffects.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2515,6 +2515,11 @@ void Spell::EffectOpenLock(SpellEffectIndex eff_idx)
itemTarget->SetFlag(ITEM_FIELD_FLAGS, ITEM_DYNFLAG_UNLOCKED);
}

if (gameObjTarget)
{
gameObjTarget->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_LOCKED);
}

SendLoot(guid, LOOT_SKINNING, LockType(m_spellInfo->EffectMiscValue[eff_idx]));

// not allow use skill grow at item base open
Expand Down
2 changes: 1 addition & 1 deletion src/modules/Bots/playerbot/PlayerbotAI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ PlayerbotAI::PlayerbotAI(Player* bot) :
//masterIncomingPacketHandlers.AddHandler(CMSG_GAMEOBJ_REPORT_USE, "use game object");
masterIncomingPacketHandlers.AddHandler(CMSG_AREATRIGGER, "area trigger");
masterIncomingPacketHandlers.AddHandler(CMSG_GAMEOBJ_USE, "use game object");
masterIncomingPacketHandlers.AddHandler(CMSG_LOOT_ROLL, "loot roll");
botOutgoingPacketHandlers.AddHandler(SMSG_LOOT_START_ROLL, "loot roll");
masterIncomingPacketHandlers.AddHandler(CMSG_GOSSIP_HELLO, "gossip hello");
masterIncomingPacketHandlers.AddHandler(CMSG_QUESTGIVER_HELLO, "gossip hello");
masterIncomingPacketHandlers.AddHandler(CMSG_QUESTGIVER_COMPLETE_QUEST, "complete quest");
Expand Down
11 changes: 5 additions & 6 deletions src/modules/Bots/playerbot/strategy/actions/AddLootAction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,11 @@ bool AddGatheringLootAction::AddLoot(ObjectGuid guid)
return false;
}

if (bot->GetMap()->IsDungeon() && loot.skillId != SKILL_LOCKPICKING)
{
return false;
}

if (!loot.IsLootPossible(bot))
{
return false;
Expand All @@ -76,12 +81,6 @@ bool AddGatheringLootAction::AddLoot(ObjectGuid guid)

bool AddGatheringLootAction::isUseful()
{
// Don't gather in dungeons or raids
if (bot->GetMap()->IsDungeon())
{
return false;
}

// NC gathering is a problem if you are supposed to be following
Player* master = ai->GetMaster();
if (master && bot->GetGroup())
Expand Down
19 changes: 18 additions & 1 deletion src/modules/Bots/playerbot/strategy/actions/LootAction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,23 @@ bool OpenLootAction::DoLoot(LootObject& lootObject)
}

bot->GetMotionMaster()->Clear();

if (go && go->GetGoState() == GO_STATE_ACTIVE)
{
if (bot->GetLootGuid() == lootObject.guid)
return false;

WorldPacket* const packet = new WorldPacket(CMSG_LOOT, 8);
*packet << lootObject.guid;
bot->GetSession()->QueuePacket(packet);
return true;
}

if (bot->IsNonMeleeSpellCasted(false))
{
return false;
}

if (lootObject.skillId == SKILL_MINING)
{
return bot->HasSkill(SKILL_MINING) ? ai->CastSpell(MINING, bot) : false;
Expand Down Expand Up @@ -286,7 +303,7 @@ bool StoreLootAction::Execute(Event event)
continue;
}

if (loot_type != LOOT_SKINNING && !IsLootAllowed(itemid))
if (!IsLootAllowed(itemid))
{
continue;
}
Expand Down
45 changes: 28 additions & 17 deletions src/modules/Bots/playerbot/strategy/actions/LootRollAction.cpp
Original file line number Diff line number Diff line change
@@ -1,22 +1,26 @@
#include "botpch.h"
#include "../../playerbot.h"
#include "LootRollAction.h"

#include "../values/ItemUsageValue.h"

using namespace ai;

bool LootRollAction::Execute(Event event)
{
Player *bot = QueryItemUsageAction::ai->GetBot();

WorldPacket p(event.getPacket()); //WorldPacket packet for CMSG_LOOT_ROLL, (8+4+1)
ObjectGuid guid;
WorldPacket p(event.getPacket());
ObjectGuid lootTargetGuid;
uint32 slot;
uint8 rollType;
p.rpos(0); //reset packet pointer
p >> guid; //guid of the item rolled
p >> slot; //number of players invited to roll
p >> rollType; //need,greed or pass on roll
uint32 itemid;
uint32 randomSuffix;
uint32 itemRandomPropId;
p.rpos(0);
p >> lootTargetGuid;
p >> slot;
p >> itemid;
p >> randomSuffix;
p >> itemRandomPropId;

Group* group = bot->GetGroup();
if (!group)
Expand All @@ -26,23 +30,30 @@ bool LootRollAction::Execute(Event event)

RollVote vote = ROLL_PASS;

ItemPrototype const *proto = sItemStorage.LookupEntry<ItemPrototype>(guid.GetEntry());
ItemPrototype const *proto = sItemStorage.LookupEntry<ItemPrototype>(itemid);
if (proto)
{
AiObjectContext* context = QueryItemUsageAction::context;
ostringstream out; out << itemid;
ItemUsage usage = AI_VALUE2(ItemUsage, "item usage", out.str());

switch (proto->Class)
{
case ITEM_CLASS_WEAPON:
case ITEM_CLASS_ARMOR:
if (QueryItemUsage(proto))
{
if (usage == ITEM_USAGE_EQUIP || usage == ITEM_USAGE_REPLACE)
vote = ROLL_NEED;
}
else if (bot->CanUseItem(proto) == EQUIP_ERR_OK && proto->Bonding != BIND_WHEN_PICKED_UP)
vote = ROLL_GREED;
break;
default:
if (IsLootAllowed(guid.GetEntry()))
{
if (usage == ITEM_USAGE_SKILL || usage == ITEM_USAGE_USE)
vote = ROLL_NEED;
else if (proto->StartQuest || proto->Bonding == BIND_QUEST_ITEM ||
proto->Bonding == BIND_QUEST_ITEM1 || proto->Class == ITEM_CLASS_QUEST)
vote = ROLL_NEED;
}
else if (proto->SellPrice > 0 && proto->Bonding != BIND_WHEN_PICKED_UP)
vote = ROLL_GREED;
break;
}
}
Expand All @@ -51,10 +62,10 @@ bool LootRollAction::Execute(Event event)
{
case MASTER_LOOT:
case FREE_FOR_ALL:
group->CountRollVote(bot, guid, slot, ROLL_PASS);
group->CountRollVote(bot, lootTargetGuid, slot, ROLL_PASS);
break;
default:
group->CountRollVote(bot, guid, slot, vote);
group->CountRollVote(bot, lootTargetGuid, slot, vote);
break;
}

Expand Down
75 changes: 75 additions & 0 deletions src/modules/Bots/playerbot/strategy/values/ItemUsageValue.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,63 @@ ItemUsage ItemUsageValue::QueryItemUsageForEquip(ItemPrototype const * item)
return ITEM_USAGE_NONE;
}

static bool IsClothMaterial(uint32 itemId, uint32 botSkill)
{
static std::map<uint32, uint32> firstAidMaterials;
static bool initialized = false;
if (!initialized)
{
initialized = true;
for (uint32 i = 0; i < sSkillLineAbilityStore.GetNumRows(); ++i)
{
SkillLineAbilityEntry const* entry = sSkillLineAbilityStore.LookupEntry(i);
if (!entry || entry->skillId != SKILL_FIRST_AID)
continue;
SpellEntry const* spell = sSpellStore.LookupEntry(entry->spellId);
if (!spell)
continue;
for (int r = 0; r < MAX_SPELL_REAGENTS; ++r)
{
if (spell->Reagent[r] <= 0)
continue;
uint32 reagentId = (uint32)spell->Reagent[r];
uint32 greyAt = entry->max_value;
auto it = firstAidMaterials.find(reagentId);
if (it == firstAidMaterials.end() || greyAt > it->second)
firstAidMaterials[reagentId] = greyAt;
}
}
}
auto it = firstAidMaterials.find(itemId);
if (it == firstAidMaterials.end())
return false;
return it->second == 0 || botSkill < it->second;
}

static bool IsSkillMaterial(uint32 skillId, uint32 itemId)
{
static std::map<uint32,std::set<uint32>> skillMaterials;
if (skillMaterials[skillId].size()==0)
{
for (uint32 i = 0; i < sSkillLineAbilityStore.GetNumRows(); ++i)
{
SkillLineAbilityEntry const* entry = sSkillLineAbilityStore.LookupEntry(i);
if (!entry || entry->skillId != skillId)
continue;
SpellEntry const* spell = sSpellStore.LookupEntry(entry->spellId);
if (!spell)
continue;
for (int r = 0; r < MAX_SPELL_REAGENTS; ++r)
{
if (spell->Reagent[r] <= 0)
continue;
skillMaterials[skillId].insert((uint32)spell->Reagent[r]);
}
}
}
return skillMaterials[skillId].count(itemId) > 0;
}

bool ItemUsageValue::IsItemUsefulForSkill(ItemPrototype const * proto)
{
switch (proto->Class)
Expand All @@ -99,6 +156,24 @@ bool ItemUsageValue::IsItemUsefulForSkill(ItemPrototype const * proto)
case ITEM_SUBCLASS_DEVICES:
return bot->HasSkill(SKILL_ENGINEERING);
}
if (bot->HasSkill(SKILL_FIRST_AID) && IsClothMaterial(proto->ItemId, bot->GetSkillValue(SKILL_FIRST_AID)))
return true;
if (bot->HasSkill(SKILL_HERBALISM) && IsSkillMaterial(SKILL_ALCHEMY, proto->ItemId))
return true;
if (bot->HasSkill(SKILL_ALCHEMY) && IsSkillMaterial(SKILL_ALCHEMY, proto->ItemId))
return true;
if (bot->HasSkill(SKILL_TAILORING) && IsSkillMaterial(SKILL_TAILORING, proto->ItemId))
return true;
if (bot->HasSkill(SKILL_SKINNING) && IsSkillMaterial(SKILL_LEATHERWORKING, proto->ItemId))
return true;
if (bot->HasSkill(SKILL_LEATHERWORKING) && IsSkillMaterial(SKILL_LEATHERWORKING, proto->ItemId))
return true;
if (bot->HasSkill(SKILL_MINING) && IsSkillMaterial(SKILL_MINING, proto->ItemId))
return true;
if (bot->HasSkill(SKILL_BLACKSMITHING) && IsSkillMaterial(SKILL_BLACKSMITHING, proto->ItemId))
return true;
if (bot->HasSkill(SKILL_ENGINEERING) && IsSkillMaterial(SKILL_ENGINEERING, proto->ItemId))
return true;
break;
case ITEM_CLASS_RECIPE:
{
Expand Down
Loading