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")
return sPlayerbotAIConfig->healDistance;
if (type == "melee")
return sPlayerbotAIConfig->meleeDistance;
return 0;
}

View File

@@ -220,6 +220,11 @@ Value<Unit*>* CastDebuffSpellOnAttackerAction::GetTargetValue()
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)
{
range = botAI->GetRange("spell");

View File

@@ -63,6 +63,16 @@ class CastDebuffSpellOnAttackerAction : public CastAuraSpellAction
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
{
public:

View File

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

View File

@@ -15,16 +15,16 @@ BUFF_TRIGGER(ImprovedIcyTalonsTrigger, "improved icy talons");
DEBUFF_CHECKISOWNER_TRIGGER(PlagueStrikeDebuffTrigger, "blood plague");
DEBUFF_CHECKISOWNER_TRIGGER(IcyTouchDebuffTrigger, "frost fever");
class PlagueStrikeDebuffOnAttackerTrigger : public DebuffOnAttackerTrigger
class PlagueStrikeDebuffOnAttackerTrigger : public DebuffOnMeleeAttackerTrigger
{
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:
IcyTouchDebuffOnAttackerTrigger(PlayerbotAI* botAI) : DebuffOnAttackerTrigger(botAI, "frost fever", true) { }
IcyTouchDebuffOnAttackerTrigger(PlayerbotAI* botAI) : DebuffOnMeleeAttackerTrigger(botAI, "frost fever", true) { }
};
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("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 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 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),
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),

View File

@@ -23,5 +23,5 @@ void FrostMageStrategy::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)
{
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", 12.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("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("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);
}
Value<Unit*>* DebuffOnMeleeAttackerTrigger::GetTargetValue()
{
return context->GetValue<Unit*>("melee attacker without aura", spell);
}
bool NoAttackersTrigger::IsActive()
{
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"; }
};
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
{
public:

View File

@@ -8,19 +8,27 @@
Unit* AttackerWithoutAuraTargetValue::Calculate()
{
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)
{
Unit* unit = botAI->GetUnit(guid);
if (!unit || unit == target)
if (!unit || !unit->IsAlive())
continue;
if (bot->GetDistance(unit) > botAI->GetRange("spell"))
if (bot->GetDistance(unit) > botAI->GetRange(range))
continue;
if (!botAI->HasAura(qualifier, unit, false, true))
return unit;
if (unit->GetHealth() < max_health) {
continue;
}
return nullptr;
if (!botAI->HasAura(qualifier, unit, false, true)) {
max_health = unit->GetHealth();
result = unit;
}
}
return result;
}

View File

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

View File

@@ -116,6 +116,7 @@ class ValueContext : public NamedObjectContext<UntypedValue>
creators["log level"] = &ValueContext::log_level;
creators["party member without aura"] = &ValueContext::party_member_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 resurrect"] = &ValueContext::party_member_to_resurrect;
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* party_member_without_aura(PlayerbotAI* botAI) { return new PartyMemberWithoutAuraValue(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_resurrect(PlayerbotAI* botAI) { return new PartyMemberToResurrect(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("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 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)));
}

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("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 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)));
}

View File

@@ -28,7 +28,14 @@ BUFF_ACTION(CastCommandingShoutAction, "commanding shout");
MELEE_ACTION(CastHeroicStrikeAction, "heroic strike");
REACH_ACTION(CastChargeAction, "charge", 8.0f);
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);
SNARE_ACTION(CastThunderClapSnareAction, "thunder clap");
SNARE_ACTION(CastHamstringAction, "hamstring");

View File

@@ -6,6 +6,7 @@
#define _PLAYERBOT_WARRIORTRIGGERS_H
#include "GenericTriggers.h"
#include "PlayerbotAI.h"
BUFF_TRIGGER(BattleShoutTrigger, "battle shout");
BUFF_TRIGGER(BattleStanceTrigger, "battle stance");
@@ -16,7 +17,14 @@ BUFF_TRIGGER(CommandingShoutTrigger, "commanding shout");
DEBUFF_TRIGGER(DisarmDebuffTrigger, "disarm");
DEBUFF_TRIGGER(SunderArmorDebuffTrigger, "sunder armor");
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(OverpowerAvailableTrigger, "overpower");
BUFF_TRIGGER(RampageAvailableTrigger, "rampage");