mirror of
https://github.com/mod-playerbots/mod-playerbots
synced 2025-11-29 15:58:20 +08:00
Fix bot chest looting exploits in ICC and Halls of Stone (#1280)
- Prevent bots from looting Gunship Armory chest in ICC before the event ends (#1162) - Fix bots being able to loot Tribunal Cache in Halls of Stone multiple times (#1200) - Ensure bots do not attempt to loot Deathbringer's Cache in ICC before it is available Three chests (Gunship Armory, Tribunal Cache, Deathbringer's Cache) were tested and now behave as expected: bots will not approach or attempt to loot chests while they are unlootable, even if players move close to them. Closes #1162, #1200
This commit is contained in:
@@ -85,7 +85,7 @@ void LootObject::Refresh(Player* bot, ObjectGuid lootGUID)
|
|||||||
bool hasAnyQuestItems = false;
|
bool hasAnyQuestItems = false;
|
||||||
|
|
||||||
GameObjectQuestItemList const* items = sObjectMgr->GetGameObjectQuestItemList(go->GetEntry());
|
GameObjectQuestItemList const* items = sObjectMgr->GetGameObjectQuestItemList(go->GetEntry());
|
||||||
for (int i = 0; i < MAX_GAMEOBJECT_QUEST_ITEMS; i++)
|
for (size_t i = 0; i < MAX_GAMEOBJECT_QUEST_ITEMS; i++)
|
||||||
{
|
{
|
||||||
if (!items || i >= items->size())
|
if (!items || i >= items->size())
|
||||||
break;
|
break;
|
||||||
@@ -297,6 +297,11 @@ bool LootObject::IsLootPossible(Player* bot)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Prevent bot from running to chests that are unlootable (e.g. Gunship Armory before completing the event)
|
||||||
|
GameObject* go = botAI->GetGameObject(guid);
|
||||||
|
if (go && go->HasFlag(GAMEOBJECT_FLAGS, GO_FLAG_INTERACT_COND | GO_FLAG_NOT_SELECTABLE))
|
||||||
|
return false;
|
||||||
|
|
||||||
if (skillId == SKILL_NONE)
|
if (skillId == SKILL_NONE)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ public:
|
|||||||
LootObject() : skillId(0), reqSkillValue(0), reqItem(0) {}
|
LootObject() : skillId(0), reqSkillValue(0), reqItem(0) {}
|
||||||
LootObject(Player* bot, ObjectGuid guid);
|
LootObject(Player* bot, ObjectGuid guid);
|
||||||
LootObject(LootObject const& other);
|
LootObject(LootObject const& other);
|
||||||
|
LootObject& operator=(LootObject const& other) = default;
|
||||||
|
|
||||||
bool IsEmpty() { return !guid; }
|
bool IsEmpty() { return !guid; }
|
||||||
bool IsLootPossible(Player* bot);
|
bool IsLootPossible(Player* bot);
|
||||||
|
|||||||
@@ -18,7 +18,7 @@
|
|||||||
#include "GuildMgr.h"
|
#include "GuildMgr.h"
|
||||||
#include "BroadcastHelper.h"
|
#include "BroadcastHelper.h"
|
||||||
|
|
||||||
bool LootAction::Execute(Event event)
|
bool LootAction::Execute(Event /*event*/)
|
||||||
{
|
{
|
||||||
if (!AI_VALUE(bool, "has available loot"))
|
if (!AI_VALUE(bool, "has available loot"))
|
||||||
return false;
|
return false;
|
||||||
@@ -61,7 +61,7 @@ enum ProfessionSpells
|
|||||||
TAILORING = 3908
|
TAILORING = 3908
|
||||||
};
|
};
|
||||||
|
|
||||||
bool OpenLootAction::Execute(Event event)
|
bool OpenLootAction::Execute(Event /*event*/)
|
||||||
{
|
{
|
||||||
LootObject lootObject = AI_VALUE(LootObject, "loot target");
|
LootObject lootObject = AI_VALUE(LootObject, "loot target");
|
||||||
bool result = DoLoot(lootObject);
|
bool result = DoLoot(lootObject);
|
||||||
@@ -70,7 +70,6 @@ bool OpenLootAction::Execute(Event event)
|
|||||||
AI_VALUE(LootObjectStack*, "available loot")->Remove(lootObject.guid);
|
AI_VALUE(LootObjectStack*, "available loot")->Remove(lootObject.guid);
|
||||||
context->GetValue<LootObject>("loot target")->Set(LootObject());
|
context->GetValue<LootObject>("loot target")->Set(LootObject());
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -131,6 +130,14 @@ bool OpenLootAction::DoLoot(LootObject& lootObject)
|
|||||||
if (go && (go->GetGoState() != GO_STATE_READY))
|
if (go && (go->GetGoState() != GO_STATE_READY))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
// This prevents dungeon chests like Tribunal Chest (Halls of Stone) from being ninja'd by the bots
|
||||||
|
if (go && go->HasFlag(GAMEOBJECT_FLAGS, GO_FLAG_INTERACT_COND))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// This prevents raid chests like Gunship Armory (ICC) from being ninja'd by the bots
|
||||||
|
if (go && go->HasFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE))
|
||||||
|
return false;
|
||||||
|
|
||||||
if (lootObject.skillId == SKILL_MINING)
|
if (lootObject.skillId == SKILL_MINING)
|
||||||
return botAI->HasSkill(SKILL_MINING) ? botAI->CastSpell(MINING, bot) : false;
|
return botAI->HasSkill(SKILL_MINING) ? botAI->CastSpell(MINING, bot) : false;
|
||||||
|
|
||||||
@@ -189,7 +196,7 @@ uint32 OpenLootAction::GetOpeningSpell(LootObject& lootObject, GameObject* go)
|
|||||||
return sPlayerbotAIConfig->openGoSpell;
|
return sPlayerbotAIConfig->openGoSpell;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool OpenLootAction::CanOpenLock(LootObject& lootObject, SpellInfo const* spellInfo, GameObject* go)
|
bool OpenLootAction::CanOpenLock(LootObject& /*lootObject*/, SpellInfo const* spellInfo, GameObject* go)
|
||||||
{
|
{
|
||||||
for (uint8 effIndex = 0; effIndex <= EFFECT_2; effIndex++)
|
for (uint8 effIndex = 0; effIndex <= EFFECT_2; effIndex++)
|
||||||
{
|
{
|
||||||
@@ -205,8 +212,6 @@ bool OpenLootAction::CanOpenLock(LootObject& lootObject, SpellInfo const* spellI
|
|||||||
if (!lockInfo)
|
if (!lockInfo)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
bool reqKey = false; // some locks not have reqs
|
|
||||||
|
|
||||||
for (uint8 j = 0; j < 8; ++j)
|
for (uint8 j = 0; j < 8; ++j)
|
||||||
{
|
{
|
||||||
switch (lockInfo->Type[j])
|
switch (lockInfo->Type[j])
|
||||||
@@ -369,7 +374,6 @@ bool StoreLootAction::Execute(Event event)
|
|||||||
uint32 itemcount;
|
uint32 itemcount;
|
||||||
uint8 lootslot_type;
|
uint8 lootslot_type;
|
||||||
uint8 itemindex;
|
uint8 itemindex;
|
||||||
bool grab = false;
|
|
||||||
|
|
||||||
p >> itemindex;
|
p >> itemindex;
|
||||||
p >> itemid;
|
p >> itemid;
|
||||||
@@ -506,7 +510,7 @@ bool StoreLootAction::IsLootAllowed(uint32 itemid, PlayerbotAI* botAI)
|
|||||||
return canLoot;
|
return canLoot;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ReleaseLootAction::Execute(Event event)
|
bool ReleaseLootAction::Execute(Event /*event*/)
|
||||||
{
|
{
|
||||||
GuidVector gos = context->GetValue<GuidVector>("nearest game objects")->Get();
|
GuidVector gos = context->GetValue<GuidVector>("nearest game objects")->Get();
|
||||||
for (ObjectGuid const guid : gos)
|
for (ObjectGuid const guid : gos)
|
||||||
|
|||||||
Reference in New Issue
Block a user