diff --git a/src/PlayerbotAI.cpp b/src/PlayerbotAI.cpp index 2f50ffee..763c19af 100644 --- a/src/PlayerbotAI.cpp +++ b/src/PlayerbotAI.cpp @@ -1520,7 +1520,7 @@ bool IsRealAura(Player* bot, AuraEffect const* aurEff, Unit const* unit) return false; } -bool PlayerbotAI::HasAura(std::string const name, Unit* unit, bool maxStack) +bool PlayerbotAI::HasAura(std::string const name, Unit* unit, bool maxStack, bool checkIsOwner, int maxAuraAmount) { if (!unit) return false; @@ -1531,6 +1531,8 @@ bool PlayerbotAI::HasAura(std::string const name, Unit* unit, bool maxStack) wstrToLower(wnamepart); + int auraAmount = 0; + for (uint32 auraType = SPELL_AURA_BIND_SIGHT; auraType < TOTAL_AURAS; auraType++) { Unit::AuraEffectList const& auras = unit->GetAuraEffectsByType((AuraType)auraType); @@ -1547,12 +1549,37 @@ bool PlayerbotAI::HasAura(std::string const name, Unit* unit, bool maxStack) if (IsRealAura(bot, aurEff, unit)) { + if (checkIsOwner && aurEff) + { + if (aurEff->GetCasterGUID() != bot->GetGUID()) + continue; + } uint32 maxStackAmount = spellInfo->StackAmount; - return maxStack && maxStackAmount ? aurEff->GetBase()->GetStackAmount() >= maxStackAmount : true; + uint32 maxProcCharges = spellInfo->ProcCharges; + + + if (maxStack) + { + if (maxStackAmount && aurEff->GetBase()->GetStackAmount() >= maxStackAmount) + auraAmount++; + + if (maxProcCharges && aurEff->GetBase()->GetCharges() >= maxProcCharges) + auraAmount++; + } + + auraAmount++; + + if (maxAuraAmount < 0) + return auraAmount > 0; } } } + if (maxAuraAmount >= 0) + { + return auraAmount == maxAuraAmount || (auraAmount > 0 && auraAmount <= maxAuraAmount); + } + return false; } diff --git a/src/PlayerbotAI.h b/src/PlayerbotAI.h index f76cb32e..28817ebd 100644 --- a/src/PlayerbotAI.h +++ b/src/PlayerbotAI.h @@ -305,7 +305,7 @@ class PlayerbotAI : public PlayerbotAIBase virtual bool CanCastSpell(std::string const name, Unit* target, Item* itemTarget = nullptr); virtual bool CastSpell(std::string const name, Unit* target, Item* itemTarget = nullptr); - virtual bool HasAura(std::string const spellName, Unit* player, bool maxStack = false); + virtual bool HasAura(std::string const spellName, Unit* player, bool maxStack = false, bool checkIsOwner = false, int maxAmount = -1); virtual bool HasAnyAuraOf(Unit* player, ...); virtual bool IsInterruptableSpellCasting(Unit* player, std::string const spell); diff --git a/src/strategy/actions/GenericSpellActions.h b/src/strategy/actions/GenericSpellActions.h index 20322dbe..98e98ee3 100644 --- a/src/strategy/actions/GenericSpellActions.h +++ b/src/strategy/actions/GenericSpellActions.h @@ -33,9 +33,12 @@ class CastSpellAction : public Action class CastAuraSpellAction : public CastSpellAction { public: - CastAuraSpellAction(PlayerbotAI* botAI, std::string const spell) : CastSpellAction(botAI, spell) { } + CastAuraSpellAction(PlayerbotAI* botAI, std::string const spell, bool isOwner = false) : CastSpellAction(botAI, spell) { this->isOwner = isOwner; } bool isUseful() override; + + protected: + bool isOwner; }; class CastMeleeSpellAction : public CastSpellAction @@ -47,13 +50,13 @@ class CastMeleeSpellAction : public CastSpellAction class CastDebuffSpellAction : public CastAuraSpellAction { public: - CastDebuffSpellAction(PlayerbotAI* botAI, std::string const spell) : CastAuraSpellAction(botAI, spell) { } + CastDebuffSpellAction(PlayerbotAI* botAI, std::string const spell, bool isOwner = false) : CastAuraSpellAction(botAI, spell, isOwner) { } }; class CastDebuffSpellOnAttackerAction : public CastAuraSpellAction { public: - CastDebuffSpellOnAttackerAction(PlayerbotAI* botAI, std::string const spell) : CastAuraSpellAction(botAI, spell) { } + CastDebuffSpellOnAttackerAction(PlayerbotAI* botAI, std::string const spell, bool isOwner = false) : CastAuraSpellAction(botAI, spell, isOwner) { } Value* GetTargetValue() override; std::string const getName() override { return spell + " on attacker"; } diff --git a/src/strategy/triggers/GenericTriggers.cpp b/src/strategy/triggers/GenericTriggers.cpp index 72a6c01a..68087ab6 100644 --- a/src/strategy/triggers/GenericTriggers.cpp +++ b/src/strategy/triggers/GenericTriggers.cpp @@ -102,7 +102,7 @@ bool OutNumberedTrigger::IsActive() bool BuffTrigger::IsActive() { Unit* target = GetTarget(); - return SpellTrigger::IsActive() && !botAI->HasAura(spell, target, true); + return SpellTrigger::IsActive() && !botAI->HasAura(spell, target, false, checkIsOwner); } Value* BuffOnPartyTrigger::GetTargetValue() diff --git a/src/strategy/triggers/GenericTriggers.h b/src/strategy/triggers/GenericTriggers.h index 94dffaec..46d617a3 100644 --- a/src/strategy/triggers/GenericTriggers.h +++ b/src/strategy/triggers/GenericTriggers.h @@ -243,11 +243,14 @@ class HighAoeTrigger : public AoeTrigger class BuffTrigger : public SpellTrigger { public: - BuffTrigger(PlayerbotAI* botAI, std::string const spell, int32 checkInterval = 1) : SpellTrigger(botAI, spell, checkInterval) { } + BuffTrigger(PlayerbotAI* botAI, std::string const spell, int32 checkInterval = 1, bool checkIsOwner = false) : SpellTrigger(botAI, spell, checkInterval) { this->checkIsOwner = checkIsOwner; } public: std::string const GetTargetName() override { return "self target"; } bool IsActive() override; + + protected: + bool checkIsOwner; }; class BuffOnPartyTrigger : public BuffTrigger @@ -303,7 +306,7 @@ class TargetInSightTrigger : public Trigger class DebuffTrigger : public BuffTrigger { public: - DebuffTrigger(PlayerbotAI* botAI, std::string const spell, int32 checkInterval = 1) : BuffTrigger(botAI, spell, checkInterval) { } + DebuffTrigger(PlayerbotAI* botAI, std::string const spell, int32 checkInterval = 1, bool checkIsOwner = false) : BuffTrigger(botAI, spell, checkInterval, checkIsOwner) { } std::string const GetTargetName() override { return "current target"; } bool IsActive() override;