debuff on melee attackers

This commit is contained in:
Yunfan Li
2023-08-28 17:28:36 +08:00
parent 953f09364a
commit 1136b7bfdc
17 changed files with 88 additions and 22 deletions

View File

@@ -3717,6 +3717,9 @@ float PlayerbotAI::GetRange(std::string const type)
if (type == "heal") if (type == "heal")
return sPlayerbotAIConfig->healDistance; return sPlayerbotAIConfig->healDistance;
if (type == "melee")
return sPlayerbotAIConfig->meleeDistance;
return 0; return 0;
} }

View File

@@ -220,6 +220,11 @@ Value<Unit*>* CastDebuffSpellOnAttackerAction::GetTargetValue()
return context->GetValue<Unit*>("attacker without aura", spell); return context->GetValue<Unit*>("attacker without aura", spell);
} }
Value<Unit*>* CastDebuffSpellOnMeleeAttackerAction::GetTargetValue()
{
return context->GetValue<Unit*>("melee attacker without aura", spell);
}
CastBuffSpellAction::CastBuffSpellAction(PlayerbotAI* botAI, std::string const spell, bool checkIsOwner) : CastAuraSpellAction(botAI, spell, checkIsOwner) CastBuffSpellAction::CastBuffSpellAction(PlayerbotAI* botAI, std::string const spell, bool checkIsOwner) : CastAuraSpellAction(botAI, spell, checkIsOwner)
{ {
range = botAI->GetRange("spell"); range = botAI->GetRange("spell");

View File

@@ -63,6 +63,16 @@ class CastDebuffSpellOnAttackerAction : public CastAuraSpellAction
ActionThreatType getThreatType() override { return ActionThreatType::Aoe; } ActionThreatType getThreatType() override { return ActionThreatType::Aoe; }
}; };
class CastDebuffSpellOnMeleeAttackerAction : public CastAuraSpellAction
{
public:
CastDebuffSpellOnMeleeAttackerAction(PlayerbotAI* botAI, std::string const spell, bool isOwner = true) : CastAuraSpellAction(botAI, spell, isOwner) { }
Value<Unit*>* GetTargetValue() override;
std::string const getName() override { return spell + " on attacker"; }
ActionThreatType getThreatType() override { return ActionThreatType::Aoe; }
};
class CastBuffSpellAction : public CastAuraSpellAction class CastBuffSpellAction : public CastAuraSpellAction
{ {
public: public:

View File

@@ -104,20 +104,20 @@ class CastIcyTouchAction : public CastSpellAction
CastIcyTouchAction(PlayerbotAI* ai) : CastSpellAction(ai, "icy touch") {} CastIcyTouchAction(PlayerbotAI* ai) : CastSpellAction(ai, "icy touch") {}
}; };
class CastIcyTouchOnAttackerAction : public CastDebuffSpellOnAttackerAction class CastIcyTouchOnAttackerAction : public CastDebuffSpellOnMeleeAttackerAction
{ {
public: public:
CastIcyTouchOnAttackerAction(PlayerbotAI* botAI) : CastDebuffSpellOnAttackerAction(botAI, "icy touch", true) { } CastIcyTouchOnAttackerAction(PlayerbotAI* botAI) : CastDebuffSpellOnMeleeAttackerAction(botAI, "icy touch", true) { }
}; };
//debuff ps //debuff ps
BEGIN_DEBUFF_ACTION(CastPlagueStrikeAction, "plague strike") BEGIN_DEBUFF_ACTION(CastPlagueStrikeAction, "plague strike")
END_SPELL_ACTION() END_SPELL_ACTION()
class CastPlagueStrikeOnAttackerAction : public CastDebuffSpellOnAttackerAction class CastPlagueStrikeOnAttackerAction : public CastDebuffSpellOnMeleeAttackerAction
{ {
public: public:
CastPlagueStrikeOnAttackerAction(PlayerbotAI* botAI) : CastDebuffSpellOnAttackerAction(botAI, "plague strike", true) { } CastPlagueStrikeOnAttackerAction(PlayerbotAI* botAI) : CastDebuffSpellOnMeleeAttackerAction(botAI, "plague strike", true) { }
}; };
//debuff //debuff

View File

@@ -15,16 +15,16 @@ BUFF_TRIGGER(ImprovedIcyTalonsTrigger, "improved icy talons");
DEBUFF_CHECKISOWNER_TRIGGER(PlagueStrikeDebuffTrigger, "blood plague"); DEBUFF_CHECKISOWNER_TRIGGER(PlagueStrikeDebuffTrigger, "blood plague");
DEBUFF_CHECKISOWNER_TRIGGER(IcyTouchDebuffTrigger, "frost fever"); DEBUFF_CHECKISOWNER_TRIGGER(IcyTouchDebuffTrigger, "frost fever");
class PlagueStrikeDebuffOnAttackerTrigger : public DebuffOnAttackerTrigger class PlagueStrikeDebuffOnAttackerTrigger : public DebuffOnMeleeAttackerTrigger
{ {
public: public:
PlagueStrikeDebuffOnAttackerTrigger(PlayerbotAI* botAI) : DebuffOnAttackerTrigger(botAI, "blood plague", true) { } PlagueStrikeDebuffOnAttackerTrigger(PlayerbotAI* botAI) : DebuffOnMeleeAttackerTrigger(botAI, "blood plague", true) { }
}; };
class IcyTouchDebuffOnAttackerTrigger : public DebuffOnAttackerTrigger class IcyTouchDebuffOnAttackerTrigger : public DebuffOnMeleeAttackerTrigger
{ {
public: public:
IcyTouchDebuffOnAttackerTrigger(PlayerbotAI* botAI) : DebuffOnAttackerTrigger(botAI, "frost fever", true) { } IcyTouchDebuffOnAttackerTrigger(PlayerbotAI* botAI) : DebuffOnMeleeAttackerTrigger(botAI, "frost fever", true) { }
}; };
class DKPresenceTrigger : public BuffTrigger class DKPresenceTrigger : public BuffTrigger

View File

@@ -169,9 +169,9 @@ void GenericDKStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
triggers.push_back(new TriggerNode("low health", NextAction::array(0, new NextAction("icebound fortitude", ACTION_HIGH + 5), new NextAction("rune tap", ACTION_HIGH + 4), nullptr))); triggers.push_back(new TriggerNode("low health", NextAction::array(0, new NextAction("icebound fortitude", ACTION_HIGH + 5), new NextAction("rune tap", ACTION_HIGH + 4), nullptr)));
triggers.push_back(new TriggerNode("medium health", NextAction::array(0, new NextAction("rune tap", ACTION_NORMAL + 4), new NextAction("death strike", ACTION_NORMAL + 3), nullptr))); triggers.push_back(new TriggerNode("medium health", NextAction::array(0, new NextAction("rune tap", ACTION_NORMAL + 4), new NextAction("death strike", ACTION_NORMAL + 3), nullptr)));
triggers.push_back(new TriggerNode("icy touch", NextAction::array(0, new NextAction("icy touch", ACTION_HIGH + 1), nullptr))); triggers.push_back(new TriggerNode("icy touch", NextAction::array(0, new NextAction("icy touch", ACTION_HIGH + 1), nullptr)));
// triggers.push_back(new TriggerNode("icy touch on attacker", NextAction::array(0, new NextAction("icy touch on attacker", ACTION_HIGH + 1), nullptr))); triggers.push_back(new TriggerNode("icy touch on attacker", NextAction::array(0, new NextAction("icy touch on attacker", ACTION_HIGH + 1), nullptr)));
triggers.push_back(new TriggerNode("plague strike", NextAction::array(0, new NextAction("plague strike", ACTION_HIGH + 1), nullptr))); triggers.push_back(new TriggerNode("plague strike", NextAction::array(0, new NextAction("plague strike", ACTION_HIGH + 1), nullptr)));
// triggers.push_back(new TriggerNode("plague strike on attacker", NextAction::array(0, new NextAction("plague strike on attacker", ACTION_HIGH + 1), nullptr))); triggers.push_back(new TriggerNode("plague strike on attacker", NextAction::array(0, new NextAction("plague strike on attacker", ACTION_HIGH + 1), nullptr)));
triggers.push_back(new TriggerNode("high aoe", NextAction::array(0, new NextAction("unholy blight", ACTION_HIGH + 6), new NextAction("death and decay", ACTION_NORMAL + 5), triggers.push_back(new TriggerNode("high aoe", NextAction::array(0, new NextAction("unholy blight", ACTION_HIGH + 6), new NextAction("death and decay", ACTION_NORMAL + 5),
new NextAction("pestilence", ACTION_NORMAL + 4), new NextAction("blood boil", ACTION_NORMAL + 3), nullptr))); new NextAction("pestilence", ACTION_NORMAL + 4), new NextAction("blood boil", ACTION_NORMAL + 3), nullptr)));
triggers.push_back(new TriggerNode("medium aoe", NextAction::array(0, new NextAction("death and decay", ACTION_HIGH + 9), triggers.push_back(new TriggerNode("medium aoe", NextAction::array(0, new NextAction("death and decay", ACTION_HIGH + 9),

View File

@@ -23,5 +23,5 @@ void FrostMageStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
void FrostMageAoeStrategy::InitTriggers(std::vector<TriggerNode*>& triggers) void FrostMageAoeStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
{ {
triggers.push_back(new TriggerNode("medium aoe", NextAction::array(0, new NextAction("blizzard", 40.0f), nullptr))); triggers.push_back(new TriggerNode("light aoe", NextAction::array(0, new NextAction("blizzard", 40.0f), nullptr)));
} }

View File

@@ -44,8 +44,8 @@ void ShadowPriestAoeStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
void ShadowPriestDebuffStrategy::InitTriggers(std::vector<TriggerNode*>& triggers) void ShadowPriestDebuffStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
{ {
triggers.push_back(new TriggerNode("devouring plague", NextAction::array(0, new NextAction("devouring plague", 13.0f), nullptr))); triggers.push_back(new TriggerNode("devouring plague", NextAction::array(0, new NextAction("devouring plague", 13.0f), nullptr)));
triggers.push_back(new TriggerNode("vampiric touch", NextAction::array(0, new NextAction("vampiric touch", 11.0f), nullptr))); triggers.push_back(new TriggerNode("shadow word: pain", NextAction::array(0, new NextAction("shadow word: pain", 11.0f), nullptr)));
triggers.push_back(new TriggerNode("shadow word: pain", NextAction::array(0, new NextAction("shadow word: pain", 12.0f), nullptr))); triggers.push_back(new TriggerNode("vampiric touch", NextAction::array(0, new NextAction("vampiric touch", 12.0f), nullptr)));
// triggers.push_back(new TriggerNode("feedback", NextAction::array(0, new NextAction("feedback", 80.0f), nullptr))); // triggers.push_back(new TriggerNode("feedback", NextAction::array(0, new NextAction("feedback", 80.0f), nullptr)));
// triggers.push_back(new TriggerNode("hex of weakness", NextAction::array(0, new NextAction("hex of weakness", 10.0f), nullptr))); // triggers.push_back(new TriggerNode("hex of weakness", NextAction::array(0, new NextAction("hex of weakness", 10.0f), nullptr)));
} }

View File

@@ -136,6 +136,11 @@ Value<Unit*>* DebuffOnAttackerTrigger::GetTargetValue()
return context->GetValue<Unit*>("attacker without aura", spell); return context->GetValue<Unit*>("attacker without aura", spell);
} }
Value<Unit*>* DebuffOnMeleeAttackerTrigger::GetTargetValue()
{
return context->GetValue<Unit*>("melee attacker without aura", spell);
}
bool NoAttackersTrigger::IsActive() bool NoAttackersTrigger::IsActive()
{ {
return !AI_VALUE(Unit*, "current target") && AI_VALUE(uint8, "my attacker count") > 0; return !AI_VALUE(Unit*, "current target") && AI_VALUE(uint8, "my attacker count") > 0;

View File

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

View File

@@ -8,19 +8,27 @@
Unit* AttackerWithoutAuraTargetValue::Calculate() Unit* AttackerWithoutAuraTargetValue::Calculate()
{ {
GuidVector attackers = botAI->GetAiObjectContext()->GetValue<GuidVector >("attackers")->Get(); GuidVector attackers = botAI->GetAiObjectContext()->GetValue<GuidVector >("attackers")->Get();
Unit* target = botAI->GetAiObjectContext()->GetValue<Unit*>("current target")->Get(); // Unit* target = botAI->GetAiObjectContext()->GetValue<Unit*>("current target")->Get();
uint32 max_health = 0;
Unit* result = nullptr;
for (ObjectGuid const guid : attackers) for (ObjectGuid const guid : attackers)
{ {
Unit* unit = botAI->GetUnit(guid); Unit* unit = botAI->GetUnit(guid);
if (!unit || unit == target) if (!unit || !unit->IsAlive())
continue; continue;
if (bot->GetDistance(unit) > botAI->GetRange("spell")) if (bot->GetDistance(unit) > botAI->GetRange(range))
continue; continue;
if (!botAI->HasAura(qualifier, unit, false, true)) if (unit->GetHealth() < max_health) {
return unit; continue;
}
if (!botAI->HasAura(qualifier, unit, false, true)) {
max_health = unit->GetHealth();
result = unit;
}
} }
return nullptr; return result;
} }

View File

@@ -14,10 +14,17 @@ class Unit;
class AttackerWithoutAuraTargetValue : public UnitCalculatedValue, public Qualified class AttackerWithoutAuraTargetValue : public UnitCalculatedValue, public Qualified
{ {
public: public:
AttackerWithoutAuraTargetValue(PlayerbotAI* botAI) : UnitCalculatedValue(botAI, "attacker without aura") { } AttackerWithoutAuraTargetValue(PlayerbotAI* botAI, std::string range = "spell") : UnitCalculatedValue(botAI, "attacker without aura"), range(range) { }
protected: protected:
Unit* Calculate() override; Unit* Calculate() override;
std::string range;
};
class MeleeAttackerWithoutAuraTargetValue : public AttackerWithoutAuraTargetValue
{
public:
MeleeAttackerWithoutAuraTargetValue(PlayerbotAI* botAI) : AttackerWithoutAuraTargetValue(botAI, "melee") {}
}; };
#endif #endif

View File

@@ -116,6 +116,7 @@ class ValueContext : public NamedObjectContext<UntypedValue>
creators["log level"] = &ValueContext::log_level; creators["log level"] = &ValueContext::log_level;
creators["party member without aura"] = &ValueContext::party_member_without_aura; creators["party member without aura"] = &ValueContext::party_member_without_aura;
creators["attacker without aura"] = &ValueContext::attacker_without_aura; creators["attacker without aura"] = &ValueContext::attacker_without_aura;
creators["melee attacker without aura"] = &ValueContext::melee_attacker_without_aura;
creators["party member to heal"] = &ValueContext::party_member_to_heal; creators["party member to heal"] = &ValueContext::party_member_to_heal;
creators["party member to resurrect"] = &ValueContext::party_member_to_resurrect; creators["party member to resurrect"] = &ValueContext::party_member_to_resurrect;
creators["current target"] = &ValueContext::current_target; creators["current target"] = &ValueContext::current_target;
@@ -376,6 +377,7 @@ class ValueContext : public NamedObjectContext<UntypedValue>
static UntypedValue* nearest_adds(PlayerbotAI* botAI) { return new NearestAddsValue(botAI); } static UntypedValue* nearest_adds(PlayerbotAI* botAI) { return new NearestAddsValue(botAI); }
static UntypedValue* party_member_without_aura(PlayerbotAI* botAI) { return new PartyMemberWithoutAuraValue(botAI); } static UntypedValue* party_member_without_aura(PlayerbotAI* botAI) { return new PartyMemberWithoutAuraValue(botAI); }
static UntypedValue* attacker_without_aura(PlayerbotAI* botAI) { return new AttackerWithoutAuraTargetValue(botAI); } static UntypedValue* attacker_without_aura(PlayerbotAI* botAI) { return new AttackerWithoutAuraTargetValue(botAI); }
static UntypedValue* melee_attacker_without_aura(PlayerbotAI* botAI) { return new MeleeAttackerWithoutAuraTargetValue(botAI); }
static UntypedValue* party_member_to_heal(PlayerbotAI* botAI) { return new PartyMemberToHeal(botAI); } static UntypedValue* party_member_to_heal(PlayerbotAI* botAI) { return new PartyMemberToHeal(botAI); }
static UntypedValue* party_member_to_resurrect(PlayerbotAI* botAI) { return new PartyMemberToResurrect(botAI); } static UntypedValue* party_member_to_resurrect(PlayerbotAI* botAI) { return new PartyMemberToResurrect(botAI); }
static UntypedValue* party_member_to_dispel(PlayerbotAI* botAI) { return new PartyMemberToDispel(botAI); } static UntypedValue* party_member_to_dispel(PlayerbotAI* botAI) { return new PartyMemberToDispel(botAI); }

View File

@@ -54,5 +54,6 @@ void ArmsWarriorStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
triggers.push_back(new TriggerNode("bloodrage", NextAction::array(0, new NextAction("bloodrage", ACTION_HIGH + 2), nullptr))); triggers.push_back(new TriggerNode("bloodrage", NextAction::array(0, new NextAction("bloodrage", ACTION_HIGH + 2), nullptr)));
triggers.push_back(new TriggerNode("death wish", NextAction::array(0, new NextAction("death wish", ACTION_HIGH + 2), nullptr))); triggers.push_back(new TriggerNode("death wish", NextAction::array(0, new NextAction("death wish", ACTION_HIGH + 2), nullptr)));
triggers.push_back(new TriggerNode("rend", NextAction::array(0, new NextAction("rend", ACTION_HIGH + 5), nullptr))); triggers.push_back(new TriggerNode("rend", NextAction::array(0, new NextAction("rend", ACTION_HIGH + 5), nullptr)));
triggers.push_back(new TriggerNode("rend on attacker", NextAction::array(0, new NextAction("rend on attacker", ACTION_HIGH + 5), nullptr)));
triggers.push_back(new TriggerNode("critical health", NextAction::array(0, new NextAction("intimidating shout", ACTION_EMERGENCY), nullptr))); triggers.push_back(new TriggerNode("critical health", NextAction::array(0, new NextAction("intimidating shout", ACTION_EMERGENCY), nullptr)));
} }

View File

@@ -78,5 +78,6 @@ void TankWarriorStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
triggers.push_back(new TriggerNode("victory rush", NextAction::array(0, new NextAction("victory rush", ACTION_INTERRUPT), nullptr))); triggers.push_back(new TriggerNode("victory rush", NextAction::array(0, new NextAction("victory rush", ACTION_INTERRUPT), nullptr)));
triggers.push_back(new TriggerNode("sword and board", NextAction::array(0, new NextAction("shield slam", ACTION_INTERRUPT), nullptr))); triggers.push_back(new TriggerNode("sword and board", NextAction::array(0, new NextAction("shield slam", ACTION_INTERRUPT), nullptr)));
triggers.push_back(new TriggerNode("rend", NextAction::array(0, new NextAction("rend", ACTION_NORMAL + 1), nullptr))); triggers.push_back(new TriggerNode("rend", NextAction::array(0, new NextAction("rend", ACTION_NORMAL + 1), nullptr)));
triggers.push_back(new TriggerNode("rend on attacker", NextAction::array(0, new NextAction("rend on attacker", ACTION_NORMAL + 1), nullptr)));
triggers.push_back(new TriggerNode("protect party member", NextAction::array(0, new NextAction("intervene", ACTION_EMERGENCY), nullptr))); triggers.push_back(new TriggerNode("protect party member", NextAction::array(0, new NextAction("intervene", ACTION_EMERGENCY), nullptr)));
} }

View File

@@ -28,7 +28,14 @@ BUFF_ACTION(CastCommandingShoutAction, "commanding shout");
MELEE_ACTION(CastHeroicStrikeAction, "heroic strike"); MELEE_ACTION(CastHeroicStrikeAction, "heroic strike");
REACH_ACTION(CastChargeAction, "charge", 8.0f); REACH_ACTION(CastChargeAction, "charge", 8.0f);
DEBUFF_CHECKISOWNER_ACTION(CastRendAction, "rend"); DEBUFF_CHECKISOWNER_ACTION(CastRendAction, "rend");
DEBUFF_ENEMY_ACTION(CastRendOnAttackerAction, "rend"); // DEBUFF_ENEMY_ACTION(CastRendOnAttackerAction, "rend");
class CastRendOnAttackerAction : public CastDebuffSpellOnMeleeAttackerAction
{
public:
CastRendOnAttackerAction(PlayerbotAI* botAI) : CastDebuffSpellOnMeleeAttackerAction(botAI, "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");
SNARE_ACTION(CastHamstringAction, "hamstring"); SNARE_ACTION(CastHamstringAction, "hamstring");

View File

@@ -6,6 +6,7 @@
#define _PLAYERBOT_WARRIORTRIGGERS_H #define _PLAYERBOT_WARRIORTRIGGERS_H
#include "GenericTriggers.h" #include "GenericTriggers.h"
#include "PlayerbotAI.h"
BUFF_TRIGGER(BattleShoutTrigger, "battle shout"); BUFF_TRIGGER(BattleShoutTrigger, "battle shout");
BUFF_TRIGGER(BattleStanceTrigger, "battle stance"); BUFF_TRIGGER(BattleStanceTrigger, "battle stance");
@@ -16,7 +17,14 @@ BUFF_TRIGGER(CommandingShoutTrigger, "commanding shout");
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");
DEBUFF_ENEMY_TRIGGER(RendDebuffOnAttackerTrigger, "rend"); // DEBUFF_ENEMY_TRIGGER(RendDebuffOnAttackerTrigger, "rend");
class RendDebuffOnAttackerTrigger : public DebuffOnMeleeAttackerTrigger
{
public:
RendDebuffOnAttackerTrigger(PlayerbotAI* botAI) : DebuffOnMeleeAttackerTrigger(botAI, "rend") {}
};
CAN_CAST_TRIGGER(RevengeAvailableTrigger, "revenge"); CAN_CAST_TRIGGER(RevengeAvailableTrigger, "revenge");
CAN_CAST_TRIGGER(OverpowerAvailableTrigger, "overpower"); CAN_CAST_TRIGGER(OverpowerAvailableTrigger, "overpower");
BUFF_TRIGGER(RampageAvailableTrigger, "rampage"); BUFF_TRIGGER(RampageAvailableTrigger, "rampage");