debuff trigger and action, allow multiple spell

This commit is contained in:
Yunfan Li
2023-06-02 19:57:08 +08:00
parent 25da0af70e
commit a44b310c0a
32 changed files with 113 additions and 85 deletions

View File

@@ -1599,7 +1599,7 @@ bool IsRealAura(Player* bot, AuraEffect const* aurEff, Unit const* unit)
return false; return false;
} }
bool PlayerbotAI::HasAura(std::string const name, Unit* unit, bool maxStack, bool checkIsOwner, int maxAuraAmount) bool PlayerbotAI::HasAura(std::string const name, Unit* unit, bool maxStack, bool checkIsOwner, int maxAuraAmount, bool checkDuration)
{ {
if (!unit) if (!unit)
return false; return false;
@@ -1628,26 +1628,29 @@ bool PlayerbotAI::HasAura(std::string const name, Unit* unit, bool maxStack, boo
if (IsRealAura(bot, aurEff, unit)) if (IsRealAura(bot, aurEff, unit))
{ {
if (checkIsOwner && aurEff) if (checkIsOwner && aurEff) {
{
if (aurEff->GetCasterGUID() != bot->GetGUID()) if (aurEff->GetCasterGUID() != bot->GetGUID())
continue; continue;
} }
if (checkDuration && aurEff) {
if (aurEff->GetBase()->GetDuration() == -1) {
continue;
}
}
uint32 maxStackAmount = spellInfo->StackAmount; uint32 maxStackAmount = spellInfo->StackAmount;
uint32 maxProcCharges = spellInfo->ProcCharges; uint32 maxProcCharges = spellInfo->ProcCharges;
if (maxStack) if (maxStack) {
{
if (maxStackAmount && aurEff->GetBase()->GetStackAmount() >= maxStackAmount) if (maxStackAmount && aurEff->GetBase()->GetStackAmount() >= maxStackAmount)
auraAmount++; auraAmount++;
if (maxProcCharges && aurEff->GetBase()->GetCharges() >= maxProcCharges) if (maxProcCharges && aurEff->GetBase()->GetCharges() >= maxProcCharges)
auraAmount++; auraAmount++;
} else {
auraAmount++;
} }
auraAmount++;
if (maxAuraAmount < 0) if (maxAuraAmount < 0)
return auraAmount > 0; return auraAmount > 0;
} }

View File

@@ -366,7 +366,7 @@ class PlayerbotAI : public PlayerbotAIBase
virtual bool CanCastSpell(std::string const name, Unit* target, Item* itemTarget = nullptr); 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 CastSpell(std::string const name, Unit* target, Item* itemTarget = nullptr);
virtual bool HasAura(std::string const spellName, Unit* player, bool maxStack = false, bool checkIsOwner = false, int maxAmount = -1); virtual bool HasAura(std::string const spellName, Unit* player, bool maxStack = false, bool checkIsOwner = false, int maxAmount = -1, bool checkDuration = false);
virtual bool HasAnyAuraOf(Unit* player, ...); virtual bool HasAnyAuraOf(Unit* player, ...);
virtual bool IsInterruptableSpellCasting(Unit* player, std::string const spell); virtual bool IsInterruptableSpellCasting(Unit* player, std::string const spell);

View File

@@ -430,7 +430,7 @@ void PlayerbotHolder::OnBotLogin(Player* const bot)
uint32 accountId = bot->GetSession()->GetAccountId(); uint32 accountId = bot->GetSession()->GetAccountId();
bool isRandomAccount = sPlayerbotAIConfig->IsInRandomAccountList(accountId); bool isRandomAccount = sPlayerbotAIConfig->IsInRandomAccountList(accountId);
if (master && isRandomAccount) { if (master && isRandomAccount && master->GetLevel() < bot->GetLevel()) {
PlayerbotFactory factory(bot, master->getLevel()); PlayerbotFactory factory(bot, master->getLevel());
factory.Randomize(false); factory.Randomize(false);
} }

View File

@@ -91,6 +91,13 @@ class clazz : public DebuffTrigger \
clazz(PlayerbotAI* botAI) : DebuffTrigger(botAI, spell) { } \ clazz(PlayerbotAI* botAI) : DebuffTrigger(botAI, spell) { } \
} }
#define DEBUFF_CHECKISOWNER_TRIGGER(clazz, spell) \
class clazz : public DebuffTrigger \
{ \
public: \
clazz(PlayerbotAI* botAI) : DebuffTrigger(botAI, spell, 1, true) { } \
}
#define DEBUFF_TRIGGER_A(clazz, spell) \ #define DEBUFF_TRIGGER_A(clazz, spell) \
class clazz : public DebuffTrigger \ class clazz : public DebuffTrigger \
{ \ { \
@@ -359,6 +366,13 @@ class clazz : public CastDebuffSpellAction \
clazz(PlayerbotAI* botAI) : CastDebuffSpellAction(botAI, spell) { } \ clazz(PlayerbotAI* botAI) : CastDebuffSpellAction(botAI, spell) { } \
} }
#define DEBUFF_CHECKISOWNER_ACTION(clazz, spell) \
class clazz : public CastDebuffSpellAction \
{ \
public: \
clazz(PlayerbotAI* botAI) : CastDebuffSpellAction(botAI, spell, true) { } \
}
#define DEBUFF_ACTION_U(clazz, spell, useful) \ #define DEBUFF_ACTION_U(clazz, spell, useful) \
class clazz : public CastDebuffSpellAction \ class clazz : public CastDebuffSpellAction \
{ \ { \

View File

@@ -97,7 +97,7 @@ void Queue::RemoveExpired()
if (ActionNode* action = basket->getAction()) if (ActionNode* action = basket->getAction())
{ {
LOG_DEBUG("playerbots", "Action {} is expired", action->getName().c_str()); // LOG_DEBUG("playerbots", "Action {} is expired", action->getName().c_str());
delete action; delete action;
} }

View File

@@ -118,7 +118,7 @@ CastMeleeSpellAction::CastMeleeSpellAction(PlayerbotAI* botAI, std::string const
bool CastAuraSpellAction::isUseful() bool CastAuraSpellAction::isUseful()
{ {
return GetTarget() && (GetTarget() != nullptr) && (GetTarget() != nullptr) && CastSpellAction::isUseful() && !botAI->HasAura(spell, GetTarget(), true); return GetTarget() && (GetTarget() != nullptr) && (GetTarget() != nullptr) && CastSpellAction::isUseful() && !botAI->HasAura(spell, GetTarget(), true, isOwner);
} }
CastEnchantItemAction::CastEnchantItemAction(PlayerbotAI* botAI, std::string const spell) : CastSpellAction(botAI, spell) CastEnchantItemAction::CastEnchantItemAction(PlayerbotAI* botAI, std::string const spell) : CastSpellAction(botAI, spell)
@@ -135,7 +135,7 @@ bool CastEnchantItemAction::isPossible()
return spellId && AI_VALUE2(Item*, "item for spell", spellId); return spellId && AI_VALUE2(Item*, "item for spell", spellId);
} }
CastHealingSpellAction::CastHealingSpellAction(PlayerbotAI* botAI, std::string const spell, uint8 estAmount) : CastAuraSpellAction(botAI, spell), estAmount(estAmount) CastHealingSpellAction::CastHealingSpellAction(PlayerbotAI* botAI, std::string const spell, uint8 estAmount) : CastAuraSpellAction(botAI, spell, true), estAmount(estAmount)
{ {
range = botAI->GetRange("spell"); range = botAI->GetRange("spell");
} }

View File

@@ -56,7 +56,7 @@ class CastDebuffSpellAction : public CastAuraSpellAction
class CastDebuffSpellOnAttackerAction : public CastAuraSpellAction class CastDebuffSpellOnAttackerAction : public CastAuraSpellAction
{ {
public: public:
CastDebuffSpellOnAttackerAction(PlayerbotAI* botAI, std::string const spell, bool isOwner = false) : CastAuraSpellAction(botAI, spell, isOwner) { } CastDebuffSpellOnAttackerAction(PlayerbotAI* botAI, std::string const spell, bool isOwner = true) : CastAuraSpellAction(botAI, spell, isOwner) { }
Value<Unit*>* GetTargetValue() override; Value<Unit*>* GetTargetValue() override;
std::string const getName() override { return spell + " on attacker"; } std::string const getName() override { return spell + " on attacker"; }

View File

@@ -129,7 +129,7 @@ bool MovementAction::MoveToLOS(WorldObject* target, bool ranged)
bool MovementAction::MoveTo(uint32 mapId, float x, float y, float z, bool idle, bool react) bool MovementAction::MoveTo(uint32 mapId, float x, float y, float z, bool idle, bool react)
{ {
UpdateMovementState(); UpdateMovementState();
LOG_DEBUG("playerbots", "IsMovingAllowed {}", IsMovingAllowed()); // LOG_DEBUG("playerbots", "IsMovingAllowed {}", IsMovingAllowed());
if (!IsMovingAllowed()) if (!IsMovingAllowed())
return false; return false;
@@ -478,7 +478,7 @@ bool MovementAction::MoveTo(uint32 mapId, float x, float y, float z, bool idle,
sPlayerbotAIConfig->log("bot_movement.csv", out.str().c_str()); sPlayerbotAIConfig->log("bot_movement.csv", out.str().c_str());
} }
LOG_DEBUG("playerbots", "({}, {}) -> ({}, {})", startPosition.getX(), startPosition.getY(), movePosition.getX(), movePosition.getY()); // LOG_DEBUG("playerbots", "({}, {}) -> ({}, {})", startPosition.getX(), startPosition.getY(), movePosition.getX(), movePosition.getY());
if (!react) if (!react)
if (totalDistance > maxDist) if (totalDistance > maxDist)
WaitForReach(startPosition.distance(movePosition) - 10.0f); WaitForReach(startPosition.distance(movePosition) - 10.0f);
@@ -543,13 +543,13 @@ bool MovementAction::MoveTo(uint32 mapId, float x, float y, float z, bool idle,
bot->SetWalk(true); bot->SetWalk(true);
bot->SendMovementFlagUpdate(); bot->SendMovementFlagUpdate();
LOG_DEBUG("playerbots", "normal move? {} {} {}", !bot->HasAuraType(SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED) && !bot->HasAuraType(SPELL_AURA_FLY), // LOG_DEBUG("playerbots", "normal move? {} {} {}", !bot->HasAuraType(SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED) && !bot->HasAuraType(SPELL_AURA_FLY),
bot->HasUnitFlag(UNIT_FLAG_DISABLE_MOVE), bot->getStandState()); // bot->HasUnitFlag(UNIT_FLAG_DISABLE_MOVE), bot->getStandState());
if (!bot->HasAuraType(SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED) && !bot->HasAuraType(SPELL_AURA_FLY)) if (!bot->HasAuraType(SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED) && !bot->HasAuraType(SPELL_AURA_FLY))
{ {
bot->SetWalk(masterWalking); bot->SetWalk(masterWalking);
bot->GetMotionMaster()->MovePoint(movePosition.getMapId(), movePosition.getX(), movePosition.getY(), movePosition.getZ(), generatePath); bot->GetMotionMaster()->MovePoint(movePosition.getMapId(), movePosition.getX(), movePosition.getY(), movePosition.getZ(), generatePath);
LOG_DEBUG("playerbots", "Movepoint to ({}, {})", movePosition.getX(), movePosition.getY()); // LOG_DEBUG("playerbots", "Movepoint to ({}, {})", movePosition.getX(), movePosition.getY());
} }
else else
{ {

View File

@@ -94,7 +94,7 @@ END_SPELL_ACTION()
class CastIcyTouchOnAttackerAction : public CastDebuffSpellOnAttackerAction class CastIcyTouchOnAttackerAction : public CastDebuffSpellOnAttackerAction
{ {
public: public:
CastIcyTouchOnAttackerAction(PlayerbotAI* botAI) : CastDebuffSpellOnAttackerAction(botAI, "icy touch") { } CastIcyTouchOnAttackerAction(PlayerbotAI* botAI) : CastDebuffSpellOnAttackerAction(botAI, "icy touch", true) { }
}; };
//debuff ps //debuff ps
@@ -104,7 +104,7 @@ END_SPELL_ACTION()
class CastPlagueStrikeOnAttackerAction : public CastDebuffSpellOnAttackerAction class CastPlagueStrikeOnAttackerAction : public CastDebuffSpellOnAttackerAction
{ {
public: public:
CastPlagueStrikeOnAttackerAction(PlayerbotAI* botAI) : CastDebuffSpellOnAttackerAction(botAI, "plague strike") { } CastPlagueStrikeOnAttackerAction(PlayerbotAI* botAI) : CastDebuffSpellOnAttackerAction(botAI, "plague strike", true) { }
}; };
//debuff //debuff
@@ -114,7 +114,7 @@ END_SPELL_ACTION()
class CastMarkOfBloodOnAttackerAction : public CastDebuffSpellOnAttackerAction class CastMarkOfBloodOnAttackerAction : public CastDebuffSpellOnAttackerAction
{ {
public: public:
CastMarkOfBloodOnAttackerAction(PlayerbotAI* botAI) : CastDebuffSpellOnAttackerAction(botAI, "mark of blood") { } CastMarkOfBloodOnAttackerAction(PlayerbotAI* botAI) : CastDebuffSpellOnAttackerAction(botAI, "mark of blood", true) { }
}; };
class CastUnholyBlightAction : public CastBuffSpellAction class CastUnholyBlightAction : public CastBuffSpellAction

View File

@@ -12,19 +12,19 @@ class PlayerbotAI;
BUFF_TRIGGER(HornOfWinterTrigger, "horn of winter"); BUFF_TRIGGER(HornOfWinterTrigger, "horn of winter");
BUFF_TRIGGER(BoneShieldTrigger, "bone shield"); BUFF_TRIGGER(BoneShieldTrigger, "bone shield");
BUFF_TRIGGER(ImprovedIcyTalonsTrigger, "improved icy talons"); BUFF_TRIGGER(ImprovedIcyTalonsTrigger, "improved icy talons");
DEBUFF_TRIGGER(PlagueStrikeDebuffTrigger, "plague strike"); DEBUFF_CHECKISOWNER_TRIGGER(PlagueStrikeDebuffTrigger, "plague strike");
DEBUFF_TRIGGER(IcyTouchDebuffTrigger, "icy touch"); DEBUFF_CHECKISOWNER_TRIGGER(IcyTouchDebuffTrigger, "icy touch");
class PlagueStrikeDebuffOnAttackerTrigger : public DebuffOnAttackerTrigger class PlagueStrikeDebuffOnAttackerTrigger : public DebuffOnAttackerTrigger
{ {
public: public:
PlagueStrikeDebuffOnAttackerTrigger(PlayerbotAI* botAI) : DebuffOnAttackerTrigger(botAI, "plague strike") { } PlagueStrikeDebuffOnAttackerTrigger(PlayerbotAI* botAI) : DebuffOnAttackerTrigger(botAI, "plague strike", true) { }
}; };
class IcyTouchDebuffOnAttackerTrigger : public DebuffOnAttackerTrigger class IcyTouchDebuffOnAttackerTrigger : public DebuffOnAttackerTrigger
{ {
public: public:
IcyTouchDebuffOnAttackerTrigger(PlayerbotAI* botAI) : DebuffOnAttackerTrigger(botAI, "icy touch") { } IcyTouchDebuffOnAttackerTrigger(PlayerbotAI* botAI) : DebuffOnAttackerTrigger(botAI, "icy touch", true) { }
}; };
class DKPresenceTrigger : public BuffTrigger class DKPresenceTrigger : public BuffTrigger
@@ -68,13 +68,13 @@ class PestilenceTrigger : public DebuffTrigger
class BloodStrikeTrigger : public DebuffTrigger class BloodStrikeTrigger : public DebuffTrigger
{ {
public: public:
BloodStrikeTrigger(PlayerbotAI* botAI) : DebuffTrigger(botAI, "blood strike") { } BloodStrikeTrigger(PlayerbotAI* botAI) : DebuffTrigger(botAI, "blood strike", 1, true) { }
}; };
class HowlingBlastTrigger : public DebuffTrigger class HowlingBlastTrigger : public DebuffTrigger
{ {
public: public:
HowlingBlastTrigger(PlayerbotAI* botAI) : DebuffTrigger(botAI, "howling blast") { } HowlingBlastTrigger(PlayerbotAI* botAI) : DebuffTrigger(botAI, "howling blast", 1, true) { }
}; };
class MindFreezeInterruptSpellTrigger : public InterruptSpellTrigger class MindFreezeInterruptSpellTrigger : public InterruptSpellTrigger

View File

@@ -134,13 +134,13 @@ class CastHurricaneAction : public CastSpellAction
class CastMoonfireAction : public CastDebuffSpellAction class CastMoonfireAction : public CastDebuffSpellAction
{ {
public: public:
CastMoonfireAction(PlayerbotAI* botAI) : CastDebuffSpellAction(botAI, "moonfire") { } CastMoonfireAction(PlayerbotAI* botAI) : CastDebuffSpellAction(botAI, "moonfire", true) { }
}; };
class CastInsectSwarmAction : public CastDebuffSpellAction class CastInsectSwarmAction : public CastDebuffSpellAction
{ {
public: public:
CastInsectSwarmAction(PlayerbotAI* botAI) : CastDebuffSpellAction(botAI, "insect swarm") { } CastInsectSwarmAction(PlayerbotAI* botAI) : CastDebuffSpellAction(botAI, "insect swarm", true) { }
}; };
class CastStarfireAction : public CastSpellAction class CastStarfireAction : public CastSpellAction

View File

@@ -51,19 +51,19 @@ class OmenOfClarityTrigger : public BuffTrigger
class RakeTrigger : public DebuffTrigger class RakeTrigger : public DebuffTrigger
{ {
public: public:
RakeTrigger(PlayerbotAI* botAI) : DebuffTrigger(botAI, "rake") { } RakeTrigger(PlayerbotAI* botAI) : DebuffTrigger(botAI, "rake", 1, true) { }
}; };
class InsectSwarmTrigger : public DebuffTrigger class InsectSwarmTrigger : public DebuffTrigger
{ {
public: public:
InsectSwarmTrigger(PlayerbotAI* botAI) : DebuffTrigger(botAI, "insect swarm") { } InsectSwarmTrigger(PlayerbotAI* botAI) : DebuffTrigger(botAI, "insect swarm", 1, true) { }
}; };
class MoonfireTrigger : public DebuffTrigger class MoonfireTrigger : public DebuffTrigger
{ {
public: public:
MoonfireTrigger(PlayerbotAI* botAI) : DebuffTrigger(botAI, "moonfire") { } MoonfireTrigger(PlayerbotAI* botAI) : DebuffTrigger(botAI, "moonfire", 1, true) { }
bool IsActive() override; bool IsActive() override;
}; };

View File

@@ -10,7 +10,7 @@ void CombatStrategy::InitTriggers(std::vector<TriggerNode*> &triggers)
triggers.push_back(new TriggerNode("enemy out of spell", NextAction::array(0, new NextAction("reach spell", ACTION_MOVE + 11), nullptr))); triggers.push_back(new TriggerNode("enemy out of spell", NextAction::array(0, new NextAction("reach spell", ACTION_MOVE + 11), nullptr)));
triggers.push_back(new TriggerNode("invalid target", NextAction::array(0, new NextAction("drop target", 100), nullptr))); triggers.push_back(new TriggerNode("invalid target", NextAction::array(0, new NextAction("drop target", 100), nullptr)));
triggers.push_back(new TriggerNode("mounted", NextAction::array(0, new NextAction("check mount state", 54), nullptr))); triggers.push_back(new TriggerNode("mounted", NextAction::array(0, new NextAction("check mount state", 54), nullptr)));
triggers.push_back(new TriggerNode("out of react range", NextAction::array(0, new NextAction("flee to master", 55), nullptr))); // triggers.push_back(new TriggerNode("out of react range", NextAction::array(0, new NextAction("flee to master", 55), nullptr)));
triggers.push_back(new TriggerNode("combat stuck", NextAction::array(0, new NextAction("reset", 1.0f), nullptr))); triggers.push_back(new TriggerNode("combat stuck", NextAction::array(0, new NextAction("reset", 1.0f), nullptr)));
// triggers.push_back(new TriggerNode("combat long stuck", NextAction::array(0, new NextAction("hearthstone", 0.9f), new NextAction("repop", 0.8f), nullptr))); // triggers.push_back(new TriggerNode("combat long stuck", NextAction::array(0, new NextAction("hearthstone", 0.9f), new NextAction("repop", 0.8f), nullptr)));
} }

View File

@@ -12,5 +12,5 @@ NextAction** FollowMasterStrategy::getDefaultActions()
void FollowMasterStrategy::InitTriggers(std::vector<TriggerNode*>& triggers) void FollowMasterStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
{ {
triggers.push_back(new TriggerNode("out of react range", NextAction::array(0, new NextAction("flee to master", ACTION_HIGH), nullptr))); // triggers.push_back(new TriggerNode("out of react range", NextAction::array(0, new NextAction("flee to master", ACTION_HIGH), nullptr)));
} }

View File

@@ -6,11 +6,6 @@
#include "Event.h" #include "Event.h"
#include "Playerbots.h" #include "Playerbots.h"
bool CastSerpentStingAction::isUseful()
{
return AI_VALUE2(uint8, "health", "current target") > 50;
}
bool CastViperStingAction::isUseful() bool CastViperStingAction::isUseful()
{ {
return AI_VALUE2(uint8, "mana", "self target") < 50 && AI_VALUE2(uint8, "mana", "current target") >= 30; return AI_VALUE2(uint8, "mana", "self target") < 50 && AI_VALUE2(uint8, "mana", "current target") >= 30;

View File

@@ -5,6 +5,7 @@
#ifndef _PLAYERBOT_HUNTERACTIONS_H #ifndef _PLAYERBOT_HUNTERACTIONS_H
#define _PLAYERBOT_HUNTERACTIONS_H #define _PLAYERBOT_HUNTERACTIONS_H
#include "AiObject.h"
#include "GenericSpellActions.h" #include "GenericSpellActions.h"
class PlayerbotAI; class PlayerbotAI;
@@ -48,9 +49,7 @@ END_SPELL_ACTION()
BEGIN_RANGED_SPELL_ACTION(CastVolleyAction, "volley") BEGIN_RANGED_SPELL_ACTION(CastVolleyAction, "volley")
END_SPELL_ACTION() END_SPELL_ACTION()
BEGIN_RANGED_SPELL_ACTION(CastSerpentStingAction, "serpent sting") DEBUFF_CHECKISOWNER_ACTION(CastSerpentStingAction, "serpent sting");
bool isUseful() override;
END_SPELL_ACTION()
BEGIN_RANGED_SPELL_ACTION(CastWyvernStingAction, "wyvern sting") BEGIN_RANGED_SPELL_ACTION(CastWyvernStingAction, "wyvern sting")
END_SPELL_ACTION() END_SPELL_ACTION()
@@ -156,7 +155,7 @@ class CastReadinessAction : public CastBuffSpellAction
class CastBlackArrow : public CastDebuffSpellAction class CastBlackArrow : public CastDebuffSpellAction
{ {
public: public:
CastBlackArrow(PlayerbotAI* botAI) : CastDebuffSpellAction(botAI, "black arrow") { } CastBlackArrow(PlayerbotAI* botAI) : CastDebuffSpellAction(botAI, "black arrow", true) { }
}; };
class CastFreezingTrap : public CastDebuffSpellAction class CastFreezingTrap : public CastDebuffSpellAction
@@ -187,7 +186,7 @@ class CastRaptorStrikeAction : public CastMeleeSpellAction
class CastSerpentStingOnAttackerAction : public CastDebuffSpellOnAttackerAction class CastSerpentStingOnAttackerAction : public CastDebuffSpellOnAttackerAction
{ {
public: public:
CastSerpentStingOnAttackerAction(PlayerbotAI* botAI) : CastDebuffSpellOnAttackerAction(botAI, "serpent sting") { } CastSerpentStingOnAttackerAction(PlayerbotAI* botAI) : CastDebuffSpellOnAttackerAction(botAI, "serpent sting", true) { }
}; };
class FeedPetAction : public Action class FeedPetAction : public Action

View File

@@ -18,8 +18,10 @@ bool HunterAspectOfTheHawkTrigger::IsActive()
bool HunterNoStingsActiveTrigger::IsActive() bool HunterNoStingsActiveTrigger::IsActive()
{ {
Unit* target = AI_VALUE(Unit*, "current target"); Unit* target = AI_VALUE(Unit*, "current target");
return target && AI_VALUE2(uint8, "health", "current target") > 40 && !botAI->HasAura("serpent sting", target) && return target && AI_VALUE2(uint8, "health", "current target") > 15 &&
!botAI->HasAura("scorpid sting", target) && !botAI->HasAura("viper sting", target); !botAI->HasAura("serpent sting", target, false, true) &&
!botAI->HasAura("scorpid sting", target, false, true) &&
!botAI->HasAura("viper sting", target, false, true);
} }
bool HuntersPetDeadTrigger::IsActive() bool HuntersPetDeadTrigger::IsActive()

View File

@@ -6,11 +6,16 @@
#define _PLAYERBOT_HUNTERTRIGGERS_H #define _PLAYERBOT_HUNTERTRIGGERS_H
#include "GenericTriggers.h" #include "GenericTriggers.h"
#include "Trigger.h"
class PlayerbotAI; class PlayerbotAI;
BEGIN_TRIGGER(HunterNoStingsActiveTrigger, Trigger) class HunterNoStingsActiveTrigger : public Trigger
END_TRIGGER() {
public:
HunterNoStingsActiveTrigger(PlayerbotAI* botAI): Trigger(botAI, "no stings") {}
bool IsActive() override;
};
class AutoShotTrigger : public Trigger class AutoShotTrigger : public Trigger
{ {
@@ -58,7 +63,7 @@ END_TRIGGER()
class BlackArrowTrigger : public DebuffTrigger class BlackArrowTrigger : public DebuffTrigger
{ {
public: public:
BlackArrowTrigger(PlayerbotAI* botAI) : DebuffTrigger(botAI, "black arrow") { } BlackArrowTrigger(PlayerbotAI* botAI) : DebuffTrigger(botAI, "black arrow", 1, true) { }
}; };
class HuntersMarkTrigger : public DebuffTrigger class HuntersMarkTrigger : public DebuffTrigger
@@ -88,7 +93,7 @@ class TrueshotAuraTrigger : public BuffTrigger
class SerpentStingOnAttackerTrigger : public DebuffOnAttackerTrigger class SerpentStingOnAttackerTrigger : public DebuffOnAttackerTrigger
{ {
public: public:
SerpentStingOnAttackerTrigger(PlayerbotAI* botAI) : DebuffOnAttackerTrigger(botAI, "serpent sting") { } SerpentStingOnAttackerTrigger(PlayerbotAI* botAI) : DebuffOnAttackerTrigger(botAI, "serpent sting", true) { }
}; };
BEGIN_TRIGGER(HunterPetNotHappy, Trigger) BEGIN_TRIGGER(HunterPetNotHappy, Trigger)

View File

@@ -195,7 +195,7 @@ class CastSpellstealAction : public CastSpellAction
class CastLivingBombAction : public CastDebuffSpellAction class CastLivingBombAction : public CastDebuffSpellAction
{ {
public: public:
CastLivingBombAction(PlayerbotAI* botAI) : CastDebuffSpellAction(botAI, "living bomb") { } CastLivingBombAction(PlayerbotAI* botAI) : CastDebuffSpellAction(botAI, "living bomb", true) { }
}; };
class CastDragonsBreathAction : public CastSpellAction class CastDragonsBreathAction : public CastSpellAction

View File

@@ -40,19 +40,19 @@ class MageArmorTrigger : public BuffTrigger
class LivingBombTrigger : public DebuffTrigger class LivingBombTrigger : public DebuffTrigger
{ {
public: public:
LivingBombTrigger(PlayerbotAI* botAI) : DebuffTrigger(botAI, "living bomb") { } LivingBombTrigger(PlayerbotAI* botAI) : DebuffTrigger(botAI, "living bomb", 1, true) { }
}; };
class FireballTrigger : public DebuffTrigger class FireballTrigger : public DebuffTrigger
{ {
public: public:
FireballTrigger(PlayerbotAI* botAI) : DebuffTrigger(botAI, "fireball") { } FireballTrigger(PlayerbotAI* botAI) : DebuffTrigger(botAI, "fireball", 1, true) { }
}; };
class PyroblastTrigger : public DebuffTrigger class PyroblastTrigger : public DebuffTrigger
{ {
public: public:
PyroblastTrigger(PlayerbotAI* botAI) : DebuffTrigger(botAI, "pyroblast") { } PyroblastTrigger(PlayerbotAI* botAI) : DebuffTrigger(botAI, "pyroblast", 1, true) { }
}; };
class HotStreakTrigger : public HasAuraTrigger class HotStreakTrigger : public HasAuraTrigger

View File

@@ -66,13 +66,13 @@ CURE_PARTY_ACTION(CastCureDiseaseOnPartyAction, "cure disease", DISPEL_DISEASE);
CURE_ACTION(CastAbolishDiseaseAction, "abolish disease"); CURE_ACTION(CastAbolishDiseaseAction, "abolish disease");
CURE_PARTY_ACTION(CastAbolishDiseaseOnPartyAction, "abolish disease", DISPEL_DISEASE); CURE_PARTY_ACTION(CastAbolishDiseaseOnPartyAction, "abolish disease", DISPEL_DISEASE);
DEBUFF_ACTION(CastHolyFireAction, "holy fire"); DEBUFF_CHECKISOWNER_ACTION(CastHolyFireAction, "holy fire");
// shadow 2.4.3 // shadow 2.4.3
BUFF_ACTION(CastShadowfiendAction, "shadowfiend"); BUFF_ACTION(CastShadowfiendAction, "shadowfiend");
SPELL_ACTION(CastShadowWordDeathAction, "shadow word: death"); SPELL_ACTION(CastShadowWordDeathAction, "shadow word: death");
// shadow // shadow
DEBUFF_ACTION(CastPowerWordPainAction, "shadow word: pain"); DEBUFF_CHECKISOWNER_ACTION(CastPowerWordPainAction, "shadow word: pain");
DEBUFF_ENEMY_ACTION(CastPowerWordPainOnAttackerAction, "shadow word: pain"); DEBUFF_ENEMY_ACTION(CastPowerWordPainOnAttackerAction, "shadow word: pain");
SPELL_ACTION(CastMindBlastAction, "mind blast"); SPELL_ACTION(CastMindBlastAction, "mind blast");
SPELL_ACTION(CastPsychicScreamAction, "psychic scream"); SPELL_ACTION(CastPsychicScreamAction, "psychic scream");
@@ -89,10 +89,10 @@ BUFF_ACTION(CastShadowformAction, "shadowform");
SPELL_ACTION(CastSilenceAction, "silence"); SPELL_ACTION(CastSilenceAction, "silence");
ENEMY_HEALER_ACTION(CastSilenceOnEnemyHealerAction, "silence"); ENEMY_HEALER_ACTION(CastSilenceOnEnemyHealerAction, "silence");
// shadow talents 2.4.3 // shadow talents 2.4.3
DEBUFF_ACTION(CastVampiricTouchAction, "vampiric touch"); DEBUFF_CHECKISOWNER_ACTION(CastVampiricTouchAction, "vampiric touch");
// racials // racials
DEBUFF_ACTION(CastDevouringPlagueAction, "devouring plague"); DEBUFF_CHECKISOWNER_ACTION(CastDevouringPlagueAction, "devouring plague");
BUFF_ACTION(CastTouchOfWeaknessAction, "touch of weakness"); BUFF_ACTION(CastTouchOfWeaknessAction, "touch of weakness");
DEBUFF_ACTION(CastHexOfWeaknessAction, "hex of weakness"); DEBUFF_ACTION(CastHexOfWeaknessAction, "hex of weakness");
BUFF_ACTION(CastShadowguardAction, "shadowguard"); BUFF_ACTION(CastShadowguardAction, "shadowguard");

View File

@@ -10,11 +10,11 @@
class PlayerbotAI; class PlayerbotAI;
DEBUFF_TRIGGER(HolyFireTrigger, "holy fire"); DEBUFF_CHECKISOWNER_TRIGGER(HolyFireTrigger, "holy fire");
DEBUFF_TRIGGER(PowerWordPainTrigger, "shadow word: pain"); DEBUFF_CHECKISOWNER_TRIGGER(PowerWordPainTrigger, "shadow word: pain");
DEBUFF_ENEMY_TRIGGER(PowerWordPainOnAttackerTrigger, "shadow word: pain"); DEBUFF_ENEMY_TRIGGER(PowerWordPainOnAttackerTrigger, "shadow word: pain");
DEBUFF_TRIGGER(VampiricTouchTrigger, "vampiric touch"); DEBUFF_CHECKISOWNER_TRIGGER(VampiricTouchTrigger, "vampiric touch");
DEBUFF_TRIGGER(VampiricEmbraceTrigger, "vampiric embrace"); BUFF_TRIGGER(VampiricEmbraceTrigger, "vampiric embrace");
CURE_TRIGGER(DispelMagicTrigger, "dispel magic", DISPEL_MAGIC); CURE_TRIGGER(DispelMagicTrigger, "dispel magic", DISPEL_MAGIC);
CURE_PARTY_TRIGGER(DispelMagicPartyMemberTrigger, "dispel magic", DISPEL_MAGIC); CURE_PARTY_TRIGGER(DispelMagicPartyMemberTrigger, "dispel magic", DISPEL_MAGIC);
CURE_TRIGGER(CureDiseaseTrigger, "cure disease", DISPEL_DISEASE); CURE_TRIGGER(CureDiseaseTrigger, "cure disease", DISPEL_DISEASE);
@@ -30,7 +30,7 @@ INTERRUPT_TRIGGER(SilenceTrigger, "silence");
INTERRUPT_HEALER_TRIGGER(SilenceEnemyHealerTrigger, "silence"); INTERRUPT_HEALER_TRIGGER(SilenceEnemyHealerTrigger, "silence");
// racials // racials
DEBUFF_TRIGGER(DevouringPlagueTrigger, "devouring plague"); DEBUFF_CHECKISOWNER_TRIGGER(DevouringPlagueTrigger, "devouring plague");
BUFF_TRIGGER(TouchOfWeaknessTrigger, "touch of weakness"); BUFF_TRIGGER(TouchOfWeaknessTrigger, "touch of weakness");
DEBUFF_TRIGGER(HexOfWeaknessTrigger, "hex of weakness"); DEBUFF_TRIGGER(HexOfWeaknessTrigger, "hex of weakness");
BUFF_TRIGGER(ShadowguardTrigger, "shadowguard"); BUFF_TRIGGER(ShadowguardTrigger, "shadowguard");

View File

@@ -32,7 +32,7 @@ class AdrenalineRushTrigger : public BuffTrigger
class RuptureTrigger : public DebuffTrigger class RuptureTrigger : public DebuffTrigger
{ {
public: public:
RuptureTrigger(PlayerbotAI* botAI) : DebuffTrigger(botAI, "rupture") { } RuptureTrigger(PlayerbotAI* botAI) : DebuffTrigger(botAI, "rupture", 1, true) { }
}; };
class ExposeArmorTrigger : public DebuffTrigger class ExposeArmorTrigger : public DebuffTrigger

View File

@@ -291,13 +291,13 @@ class CastCleanseSpiritDiseaseOnPartyAction : public CurePartyMemberAction
class CastFlameShockAction : public CastDebuffSpellAction class CastFlameShockAction : public CastDebuffSpellAction
{ {
public: public:
CastFlameShockAction(PlayerbotAI* botAI) : CastDebuffSpellAction(botAI, "flame shock") { } CastFlameShockAction(PlayerbotAI* botAI) : CastDebuffSpellAction(botAI, "flame shock", true) { }
}; };
class CastEarthShockAction : public CastDebuffSpellAction class CastEarthShockAction : public CastDebuffSpellAction
{ {
public: public:
CastEarthShockAction(PlayerbotAI* botAI) : CastDebuffSpellAction(botAI, "earth shock") { } CastEarthShockAction(PlayerbotAI* botAI) : CastDebuffSpellAction(botAI, "earth shock", true) { }
}; };
class CastFrostShockAction : public CastSnareSpellAction class CastFrostShockAction : public CastSnareSpellAction

View File

@@ -33,7 +33,8 @@ bool ShamanWeaponTrigger::IsActive()
bool ShockTrigger::IsActive() bool ShockTrigger::IsActive()
{ {
return SpellTrigger::IsActive() && !botAI->HasAnyAuraOf(GetTarget(), "frost shock", "earth shock", "flame shock", nullptr); return SpellTrigger::IsActive() && !botAI->HasAura("flame shock", GetTarget(), false, true) &&
!botAI->HasAura("frost shock", GetTarget(), false, true);
} }
bool TotemTrigger::IsActive() bool TotemTrigger::IsActive()

View File

@@ -171,7 +171,7 @@ class PartyMemberCleanseSpiritDiseaseTrigger : public PartyMemberNeedCureTrigger
class ShockTrigger : public DebuffTrigger class ShockTrigger : public DebuffTrigger
{ {
public: public:
ShockTrigger(PlayerbotAI* botAI) : DebuffTrigger(botAI, "earth shock") { } ShockTrigger(PlayerbotAI* botAI) : DebuffTrigger(botAI, "earth shock", 1, true) { }
bool IsActive() override; bool IsActive() override;
}; };

View File

@@ -315,7 +315,7 @@ class DebuffTrigger : public BuffTrigger
class DebuffOnAttackerTrigger : public DebuffTrigger class DebuffOnAttackerTrigger : public DebuffTrigger
{ {
public: public:
DebuffOnAttackerTrigger(PlayerbotAI* botAI, std::string const spell) : DebuffTrigger(botAI, spell) { } DebuffOnAttackerTrigger(PlayerbotAI* botAI, std::string const spell, bool checkIsOwner = true) : DebuffTrigger(botAI, spell, 1, checkIsOwner) { }
Value<Unit*>* GetTargetValue() override; Value<Unit*>* GetTargetValue() override;
std::string const getName() override { return spell + " on attacker"; } std::string const getName() override { return spell + " on attacker"; }

View File

@@ -18,7 +18,7 @@ Unit* AttackerWithoutAuraTargetValue::Calculate()
if (bot->GetDistance(unit) > botAI->GetRange("spell")) if (bot->GetDistance(unit) > botAI->GetRange("spell"))
continue; continue;
if (!botAI->HasAura(qualifier, unit)) if (!botAI->HasAura(qualifier, unit, false, true))
return unit; return unit;
} }

View File

@@ -54,7 +54,7 @@ class CastDrainLifeAction : public CastSpellAction
class CastCurseOfAgonyAction : public CastDebuffSpellAction class CastCurseOfAgonyAction : public CastDebuffSpellAction
{ {
public: public:
CastCurseOfAgonyAction(PlayerbotAI* botAI) : CastDebuffSpellAction(botAI, "curse of agony") { } CastCurseOfAgonyAction(PlayerbotAI* botAI) : CastDebuffSpellAction(botAI, "curse of agony", true) { }
}; };
class CastCurseOfWeaknessAction : public CastDebuffSpellAction class CastCurseOfWeaknessAction : public CastDebuffSpellAction
@@ -66,19 +66,19 @@ class CastCurseOfWeaknessAction : public CastDebuffSpellAction
class CastCorruptionAction : public CastDebuffSpellAction class CastCorruptionAction : public CastDebuffSpellAction
{ {
public: public:
CastCorruptionAction(PlayerbotAI* botAI) : CastDebuffSpellAction(botAI, "corruption") { } CastCorruptionAction(PlayerbotAI* botAI) : CastDebuffSpellAction(botAI, "corruption", true) { }
}; };
class CastCorruptionOnAttackerAction : public CastDebuffSpellOnAttackerAction class CastCorruptionOnAttackerAction : public CastDebuffSpellOnAttackerAction
{ {
public: public:
CastCorruptionOnAttackerAction(PlayerbotAI* botAI) : CastDebuffSpellOnAttackerAction(botAI, "corruption") { } CastCorruptionOnAttackerAction(PlayerbotAI* botAI) : CastDebuffSpellOnAttackerAction(botAI, "corruption", true) { }
}; };
class CastCurseOfAgonyOnAttackerAction : public CastDebuffSpellOnAttackerAction class CastCurseOfAgonyOnAttackerAction : public CastDebuffSpellOnAttackerAction
{ {
public: public:
CastCurseOfAgonyOnAttackerAction(PlayerbotAI* botAI) : CastDebuffSpellOnAttackerAction(botAI, "curse of agony") { } CastCurseOfAgonyOnAttackerAction(PlayerbotAI* botAI) : CastDebuffSpellOnAttackerAction(botAI, "curse of agony", true) { }
}; };
class CastSummonVoidwalkerAction : public CastBuffSpellAction class CastSummonVoidwalkerAction : public CastBuffSpellAction
@@ -135,7 +135,7 @@ class CastBanishAction : public CastBuffSpellAction
class CastSeedOfCorruptionAction : public CastDebuffSpellAction class CastSeedOfCorruptionAction : public CastDebuffSpellAction
{ {
public: public:
CastSeedOfCorruptionAction(PlayerbotAI* botAI) : CastDebuffSpellAction(botAI, "seed of corruption") { } CastSeedOfCorruptionAction(PlayerbotAI* botAI) : CastDebuffSpellAction(botAI, "seed of corruption", true) { }
}; };
class CastRainOfFireAction : public CastSpellAction class CastRainOfFireAction : public CastSpellAction
@@ -153,7 +153,13 @@ class CastShadowfuryAction : public CastSpellAction
class CastImmolateAction : public CastDebuffSpellAction class CastImmolateAction : public CastDebuffSpellAction
{ {
public: public:
CastImmolateAction(PlayerbotAI* botAI) : CastDebuffSpellAction(botAI, "immolate") { } CastImmolateAction(PlayerbotAI* botAI) : CastDebuffSpellAction(botAI, "immolate", true) { }
};
class CastImmolateOnAttackerAction : public CastDebuffSpellOnAttackerAction
{
public:
CastImmolateOnAttackerAction(PlayerbotAI* botAI) : CastDebuffSpellOnAttackerAction(botAI, "immolate", true) { }
}; };
class CastConflagrateAction : public CastSpellAction class CastConflagrateAction : public CastSpellAction
@@ -203,7 +209,7 @@ class CastAmplifyCurseAction : public CastBuffSpellAction
class CastSiphonLifeAction : public CastDebuffSpellAction class CastSiphonLifeAction : public CastDebuffSpellAction
{ {
public: public:
CastSiphonLifeAction(PlayerbotAI* botAI) : CastDebuffSpellAction(botAI, "siphon life") { } CastSiphonLifeAction(PlayerbotAI* botAI) : CastDebuffSpellAction(botAI, "siphon life", true) { }
}; };
class CastSiphonLifeOnAttackerAction : public CastDebuffSpellOnAttackerAction class CastSiphonLifeOnAttackerAction : public CastDebuffSpellOnAttackerAction

View File

@@ -25,9 +25,9 @@ class SpellstoneTrigger : public BuffTrigger
bool IsActive() override; bool IsActive() override;
}; };
DEBUFF_TRIGGER(CurseOfAgonyTrigger, "curse of agony"); DEBUFF_CHECKISOWNER_TRIGGER(CurseOfAgonyTrigger, "curse of agony");
DEBUFF_TRIGGER(CorruptionTrigger, "corruption"); DEBUFF_CHECKISOWNER_TRIGGER(CorruptionTrigger, "corruption");
DEBUFF_TRIGGER(SiphonLifeTrigger, "siphon life"); DEBUFF_CHECKISOWNER_TRIGGER(SiphonLifeTrigger, "siphon life");
class CorruptionOnAttackerTrigger : public DebuffOnAttackerTrigger class CorruptionOnAttackerTrigger : public DebuffOnAttackerTrigger
{ {
@@ -47,7 +47,7 @@ class SiphonLifeOnAttackerTrigger : public DebuffOnAttackerTrigger
SiphonLifeOnAttackerTrigger(PlayerbotAI* botAI) : DebuffOnAttackerTrigger(botAI, "siphon life") { } SiphonLifeOnAttackerTrigger(PlayerbotAI* botAI) : DebuffOnAttackerTrigger(botAI, "siphon life") { }
}; };
DEBUFF_TRIGGER(ImmolateTrigger, "immolate"); DEBUFF_CHECKISOWNER_TRIGGER(ImmolateTrigger, "immolate");
class ShadowTranceTrigger : public HasAuraTrigger class ShadowTranceTrigger : public HasAuraTrigger
{ {

View File

@@ -27,7 +27,7 @@ BUFF_ACTION(CastCommandingShoutAction, "commanding shout");
// arms // arms
MELEE_ACTION(CastHeroicStrikeAction, "heroic strike"); MELEE_ACTION(CastHeroicStrikeAction, "heroic strike");
REACH_ACTION(CastChargeAction, "charge", 8.0f); REACH_ACTION(CastChargeAction, "charge", 8.0f);
DEBUFF_ACTION(CastRendAction, "rend"); DEBUFF_CHECKISOWNER_ACTION(CastRendAction, "rend");
DEBUFF_ENEMY_ACTION(CastRendOnAttackerAction, "rend"); DEBUFF_ENEMY_ACTION(CastRendOnAttackerAction, "rend");
DEBUFF_ACTION_R(CastThunderClapAction, "thunder clap", 8.0f); DEBUFF_ACTION_R(CastThunderClapAction, "thunder clap", 8.0f);
SNARE_ACTION(CastThunderClapSnareAction, "thunder clap"); SNARE_ACTION(CastThunderClapSnareAction, "thunder clap");

View File

@@ -13,8 +13,6 @@ BUFF_TRIGGER(DefensiveStanceTrigger, "defensive stance");
BUFF_TRIGGER(BerserkerStanceTrigger, "berserker stance"); BUFF_TRIGGER(BerserkerStanceTrigger, "berserker stance");
BUFF_TRIGGER(ShieldBlockTrigger, "shield block"); BUFF_TRIGGER(ShieldBlockTrigger, "shield block");
BUFF_TRIGGER(CommandingShoutTrigger, "commanding shout"); BUFF_TRIGGER(CommandingShoutTrigger, "commanding shout");
DEBUFF_TRIGGER(RendDebuffTrigger, "rend");
DEBUFF_TRIGGER(DisarmDebuffTrigger, "disarm"); DEBUFF_TRIGGER(DisarmDebuffTrigger, "disarm");
DEBUFF_TRIGGER(SunderArmorDebuffTrigger, "sunder armor"); DEBUFF_TRIGGER(SunderArmorDebuffTrigger, "sunder armor");
DEBUFF_TRIGGER(MortalStrikeDebuffTrigger, "mortal strike"); DEBUFF_TRIGGER(MortalStrikeDebuffTrigger, "mortal strike");
@@ -49,4 +47,9 @@ HAS_AURA_TRIGGER(SuddenDeathTrigger, "sudden death");
HAS_AURA_TRIGGER(SlamInstantTrigger, "slam!"); HAS_AURA_TRIGGER(SlamInstantTrigger, "slam!");
HAS_AURA_TRIGGER(TasteForBloodTrigger, "taste for blood"); HAS_AURA_TRIGGER(TasteForBloodTrigger, "taste for blood");
class RendDebuffTrigger : public DebuffTrigger
{
public:
RendDebuffTrigger(PlayerbotAI* botAI) : DebuffTrigger(botAI, "rend", 1, true) { }
};
#endif #endif