diff --git a/src/strategy/warlock/WarlockActions.cpp b/src/strategy/warlock/WarlockActions.cpp index c57a21c2..b3b57871 100644 --- a/src/strategy/warlock/WarlockActions.cpp +++ b/src/strategy/warlock/WarlockActions.cpp @@ -145,9 +145,48 @@ bool CreateSoulShardAction::isUseful() uint32 currentShards = bot->GetItemCount(ITEM_SOUL_SHARD, false); // false = only bags const uint32 SHARD_CAP = 6; // adjust as needed - return currentShards < SHARD_CAP; + // Only allow if under cap AND there is space for a new shard + ItemPosCountVec dest; + uint32 count = 1; + bool hasSpace = (bot->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, ITEM_SOUL_SHARD, count) == EQUIP_ERR_OK); + + return (currentShards < SHARD_CAP) && hasSpace; } +bool CastCreateSoulstoneAction::isUseful() +{ + Player* bot = botAI->GetBot(); + if (!bot) + return false; + + // List of all Soulstone item IDs + static const std::vector soulstoneIds = { + 5232, // Minor Soulstone + 16892, // Lesser Soulstone + 16893, // Soulstone + 16895, // Greater Soulstone + 16896, // Major Soulstone + 22116, // Master Soulstone + 36895 // Demonic Soulstone + }; + + // Check if the bot already has any soulstone + for (uint32 id : soulstoneIds) + { + if (bot->GetItemCount(id, false) > 0) + return false; // Already has a soulstone + } + + // Only need to check one soulstone type for bag space (usually the highest-tier) + ItemPosCountVec dest; + uint32 count = 1; + // Use the last in the list (highest tier) + uint32 soulstoneToCreate = soulstoneIds.back(); + + bool hasSpace = (bot->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, soulstoneToCreate, count) == EQUIP_ERR_OK); + + return hasSpace; +} bool DestroySoulShardAction::Execute(Event event) { diff --git a/src/strategy/warlock/WarlockActions.h b/src/strategy/warlock/WarlockActions.h index 69530775..b3b7a3e2 100644 --- a/src/strategy/warlock/WarlockActions.h +++ b/src/strategy/warlock/WarlockActions.h @@ -84,6 +84,7 @@ class CastCreateSoulstoneAction : public CastBuffSpellAction { public: CastCreateSoulstoneAction(PlayerbotAI* botAI) : CastBuffSpellAction(botAI, "create soulstone") {} + bool isUseful() override; }; class UseSoulstoneSelfAction : public UseSpellItemAction diff --git a/src/strategy/warlock/WarlockAiObjectContext.cpp b/src/strategy/warlock/WarlockAiObjectContext.cpp index acd92a6d..7603a5e2 100644 --- a/src/strategy/warlock/WarlockAiObjectContext.cpp +++ b/src/strategy/warlock/WarlockAiObjectContext.cpp @@ -138,7 +138,7 @@ public: creators["no healthstone"] = &WarlockTriggerFactoryInternal::HasHealthstone; creators["no firestone"] = &WarlockTriggerFactoryInternal::HasFirestone; creators["no spellstone"] = &WarlockTriggerFactoryInternal::HasSpellstone; - creators["no soulstone"] = &WarlockTriggerFactoryInternal::HasSoulstone; + creators["no soulstone"] = &WarlockTriggerFactoryInternal::OutOfSoulstone; creators["firestone"] = &WarlockTriggerFactoryInternal::firestone; creators["spellstone"] = &WarlockTriggerFactoryInternal::spellstone; creators["soulstone"] = &WarlockTriggerFactoryInternal::soulstone; @@ -182,7 +182,7 @@ private: static Trigger* HasHealthstone(PlayerbotAI* botAI) { return new HasHealthstoneTrigger(botAI); } static Trigger* HasFirestone(PlayerbotAI* botAI) { return new HasFirestoneTrigger(botAI); } static Trigger* HasSpellstone(PlayerbotAI* botAI) { return new HasSpellstoneTrigger(botAI); } - static Trigger* HasSoulstone(PlayerbotAI* botAI) { return new HasSoulstoneTrigger(botAI); } + static Trigger* OutOfSoulstone(PlayerbotAI* botAI) { return new OutOfSoulstoneTrigger(botAI); } static Trigger* firestone(PlayerbotAI* botAI) { return new FirestoneTrigger(botAI); } static Trigger* spellstone(PlayerbotAI* botAI) { return new SpellstoneTrigger(botAI); } static Trigger* soulstone(PlayerbotAI* botAI) { return new SoulstoneTrigger(botAI); } diff --git a/src/strategy/warlock/WarlockTriggers.cpp b/src/strategy/warlock/WarlockTriggers.cpp index 7f414f2e..b9794935 100644 --- a/src/strategy/warlock/WarlockTriggers.cpp +++ b/src/strategy/warlock/WarlockTriggers.cpp @@ -7,6 +7,32 @@ #include "GenericTriggers.h" #include "Playerbots.h" +static const uint32 SOUL_SHARD_ITEM_ID = 6265; + +uint32 GetSoulShardCount(Player* bot) +{ + return bot->GetItemCount(SOUL_SHARD_ITEM_ID, false); // false = only bags +} + +// List of all Soulstone item IDs +static const std::vector soulstoneItemIds = { + 5232, // Minor Soulstone + 16892, // Lesser Soulstone + 16893, // Soulstone + 16895, // Greater Soulstone + 16896, // Major Soulstone + 22116, // Master Soulstone + 36895 // Demonic Soulstone +}; + +uint32 GetSoulstoneCount(Player* bot) +{ + uint32 count = 0; + for (uint32 id : soulstoneItemIds) + count += bot->GetItemCount(id, false); // false = only bags + return count; +} + bool SpellstoneTrigger::IsActive() { return BuffTrigger::IsActive() && AI_VALUE2(uint32, "item count", getName()) > 0; } bool FirestoneTrigger::IsActive() { return BuffTrigger::IsActive() && AI_VALUE2(uint32, "item count", getName()) > 0; } @@ -16,6 +42,12 @@ bool WarlockConjuredItemTrigger::IsActive() return ItemCountTrigger::IsActive() && AI_VALUE2(uint32, "item count", "soul shard") > 0; } +bool OutOfSoulShardsTrigger::IsActive() { return GetSoulShardCount(botAI->GetBot()) == 0; } + +bool TooManySoulShardsTrigger::IsActive() { return GetSoulShardCount(botAI->GetBot()) >= 6; } + +bool OutOfSoulstoneTrigger::IsActive() { return GetSoulstoneCount(botAI->GetBot()) == 0; } + // Checks if the target marked with the moon icon can be banished bool BanishTrigger::IsActive() { diff --git a/src/strategy/warlock/WarlockTriggers.h b/src/strategy/warlock/WarlockTriggers.h index ca85a999..e5ce9ad1 100644 --- a/src/strategy/warlock/WarlockTriggers.h +++ b/src/strategy/warlock/WarlockTriggers.h @@ -34,14 +34,14 @@ class OutOfSoulShardsTrigger : public Trigger { public: OutOfSoulShardsTrigger(PlayerbotAI* botAI) : Trigger(botAI, "no soul shard", 2) {} - bool IsActive() override { return AI_VALUE2(uint32, "item count", "soul shard") == 0; } + bool IsActive() override; }; class TooManySoulShardsTrigger : public Trigger { public: TooManySoulShardsTrigger(PlayerbotAI* botAI) : Trigger(botAI, "too many soul shards") {} - bool IsActive() override { return AI_VALUE2(uint32, "item count", "soul shard") >= 6; } + bool IsActive() override; }; class FirestoneTrigger : public BuffTrigger @@ -58,11 +58,11 @@ public: bool IsActive() override; }; -class HasSoulstoneTrigger : public Trigger +class OutOfSoulstoneTrigger : public Trigger { public: - HasSoulstoneTrigger(PlayerbotAI* botAI) : Trigger(botAI, "no soulstone") {} - bool IsActive() override { return AI_VALUE2(uint32, "item count", "soulstone") == 0; } + OutOfSoulstoneTrigger(PlayerbotAI* botAI) : Trigger(botAI, "no soulstone") {} + bool IsActive() override; }; class SoulstoneTrigger : public Trigger