mirror of
https://github.com/mod-playerbots/mod-playerbots
synced 2025-11-29 15:58:20 +08:00
avoid AOE strategy (WIP)
This commit is contained in:
@@ -108,6 +108,7 @@ class StrategyContext : public NamedObjectContext<Strategy>
|
||||
creators["group"] = &StrategyContext::group;
|
||||
creators["guild"] = &StrategyContext::guild;
|
||||
creators["grind"] = &StrategyContext::grind;
|
||||
creators["avoid aoe"] = &StrategyContext::avoid_aoe;
|
||||
}
|
||||
|
||||
private:
|
||||
@@ -166,6 +167,7 @@ class StrategyContext : public NamedObjectContext<Strategy>
|
||||
static Strategy* group(PlayerbotAI* botAI) { return new GroupStrategy(botAI); }
|
||||
static Strategy* guild (PlayerbotAI* botAI) { return new GuildStrategy(botAI); }
|
||||
static Strategy* grind(PlayerbotAI* botAI) { return new GrindingStrategy(botAI); }
|
||||
static Strategy* avoid_aoe(PlayerbotAI* botAI) { return new AvoidAoeStrategy(botAI); }
|
||||
};
|
||||
|
||||
class MovementStrategyContext : public NamedObjectContext<Strategy>
|
||||
|
||||
@@ -14,3 +14,61 @@ void CombatStrategy::InitTriggers(std::vector<TriggerNode*> &triggers)
|
||||
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)));
|
||||
}
|
||||
|
||||
|
||||
AvoidAoeStrategy::AvoidAoeStrategy(PlayerbotAI* botAI) : Strategy(botAI)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
class AvoidAoeStrategyMultiplier : public Multiplier
|
||||
{
|
||||
public:
|
||||
AvoidAoeStrategyMultiplier(PlayerbotAI* botAI) : Multiplier(botAI, "run away on area debuff") {}
|
||||
|
||||
public:
|
||||
virtual float GetValue(Action* action);
|
||||
|
||||
private:
|
||||
};
|
||||
|
||||
float AvoidAoeStrategyMultiplier::GetValue(Action* action)
|
||||
{
|
||||
if (!action)
|
||||
return 1.0f;
|
||||
|
||||
std::string name = action->getName();
|
||||
if (name == "follow" || name == "co" || name == "nc" || name == "drop target")
|
||||
return 1.0f;
|
||||
|
||||
uint32 spellId = AI_VALUE2(uint32, "spell id", name);
|
||||
const SpellInfo* const pSpellInfo = sSpellMgr->GetSpellInfo(spellId);
|
||||
if (!pSpellInfo) return 1.0f;
|
||||
|
||||
if (spellId && pSpellInfo->Targets & TARGET_FLAG_DEST_LOCATION)
|
||||
return 1.0f;
|
||||
else if (spellId && pSpellInfo->Targets & TARGET_FLAG_SOURCE_LOCATION)
|
||||
return 1.0f;
|
||||
|
||||
uint32 castTime = pSpellInfo->CalcCastTime();
|
||||
|
||||
if (AI_VALUE2(bool, "has area debuff", "self target") && spellId && castTime > 0)
|
||||
{
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
return 1.0f;
|
||||
}
|
||||
|
||||
|
||||
void AvoidAoeStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||
{
|
||||
triggers.push_back(new TriggerNode(
|
||||
"has area debuff",
|
||||
NextAction::array(0, new NextAction("flee", ACTION_EMERGENCY + 5), NULL)));
|
||||
}
|
||||
|
||||
void AvoidAoeStrategy::InitMultipliers(std::vector<Multiplier*>& multipliers)
|
||||
{
|
||||
multipliers.push_back(new AvoidAoeStrategyMultiplier(botAI));
|
||||
}
|
||||
@@ -18,4 +18,13 @@ class CombatStrategy : public Strategy
|
||||
uint32 GetType() const override { return STRATEGY_TYPE_COMBAT; }
|
||||
};
|
||||
|
||||
class AvoidAoeStrategy : public Strategy
|
||||
{
|
||||
public:
|
||||
explicit AvoidAoeStrategy(PlayerbotAI* ai);
|
||||
const std::string getName() override { return "avoid aoe"; }
|
||||
void InitMultipliers(std::vector<Multiplier*>& multipliers) override;
|
||||
void InitTriggers(std::vector<TriggerNode*>& triggers) override;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -508,3 +508,8 @@ bool IsFallingFarTrigger::IsActive()
|
||||
{
|
||||
return bot->HasUnitMovementFlag(MOVEMENTFLAG_FALLING_FAR);
|
||||
}
|
||||
|
||||
bool HasAreaDebuffTrigger::IsActive()
|
||||
{
|
||||
return AI_VALUE2(bool, "has area debuff", "self target");
|
||||
}
|
||||
|
||||
@@ -702,4 +702,12 @@ class IsFallingFarTrigger : public Trigger
|
||||
bool IsActive() override;
|
||||
};
|
||||
|
||||
|
||||
class HasAreaDebuffTrigger : public Trigger {
|
||||
public:
|
||||
HasAreaDebuffTrigger(PlayerbotAI* botAI) : Trigger(botAI, "have area debuff") {}
|
||||
|
||||
bool IsActive() override;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -77,6 +77,9 @@ class TriggerContext : public NamedObjectContext<Trigger>
|
||||
creators["medium aoe"] = &TriggerContext::MediumAoe;
|
||||
creators["high aoe"] = &TriggerContext::HighAoe;
|
||||
|
||||
creators["has area debuff"] = &TriggerContext::HasAreaDebuff;
|
||||
|
||||
|
||||
creators["enemy out of melee"] = &TriggerContext::EnemyOutOfMelee;
|
||||
creators["enemy out of spell"] = &TriggerContext::EnemyOutOfSpell;
|
||||
creators["enemy too close for spell"] = &TriggerContext::enemy_too_close_for_spell;
|
||||
@@ -224,6 +227,7 @@ class TriggerContext : public NamedObjectContext<Trigger>
|
||||
static Trigger* LightAoe(PlayerbotAI* botAI) { return new LightAoeTrigger(botAI); }
|
||||
static Trigger* MediumAoe(PlayerbotAI* botAI) { return new MediumAoeTrigger(botAI); }
|
||||
static Trigger* HighAoe(PlayerbotAI* botAI) { return new HighAoeTrigger(botAI); }
|
||||
static Trigger* HasAreaDebuff(PlayerbotAI* botAI) { return new HasAreaDebuffTrigger(botAI); }
|
||||
static Trigger* LoseAggro(PlayerbotAI* botAI) { return new LoseAggroTrigger(botAI); }
|
||||
static Trigger* HasAggro(PlayerbotAI* botAI) { return new HasAggroTrigger(botAI); }
|
||||
static Trigger* LowHealth(PlayerbotAI* botAI) { return new LowHealthTrigger(botAI); }
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include "AoeValues.h"
|
||||
#include "Playerbots.h"
|
||||
#include "ServerFacade.h"
|
||||
#include "SpellAuraEffects.h"
|
||||
|
||||
GuidVector FindMaxDensity(Player* bot)
|
||||
{
|
||||
@@ -85,3 +86,34 @@ uint8 AoeCountValue::Calculate()
|
||||
{
|
||||
return FindMaxDensity(bot).size();
|
||||
}
|
||||
|
||||
bool HasAreaDebuffValue::Calculate()
|
||||
{
|
||||
for (uint32 auraType = SPELL_AURA_BIND_SIGHT; auraType < TOTAL_AURAS; auraType++)
|
||||
{
|
||||
Unit::AuraEffectList const& auras = botAI->GetBot()->GetAuraEffectsByType((AuraType)auraType);
|
||||
|
||||
if (auras.empty())
|
||||
continue;
|
||||
|
||||
for (AuraEffect const* aurEff : auras)
|
||||
{
|
||||
SpellInfo const* proto = aurEff->GetSpellInfo();
|
||||
|
||||
if (!proto)
|
||||
continue;
|
||||
|
||||
uint32 trigger_spell_id = proto->Effects[aurEff->GetEffIndex()].TriggerSpell;
|
||||
if (trigger_spell_id == 29767) //Overload
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return (!proto->IsPositive() && aurEff->IsPeriodic() && proto->HasAreaAuraEffect());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
@@ -7,6 +7,7 @@
|
||||
|
||||
#include "Object.h"
|
||||
#include "Value.h"
|
||||
#include "AiObjectContext.h"
|
||||
|
||||
class PlayerbotAI;
|
||||
|
||||
@@ -26,4 +27,18 @@ class AoeCountValue : public CalculatedValue<uint8>
|
||||
uint8 Calculate() override;
|
||||
};
|
||||
|
||||
class HasAreaDebuffValue : public BoolCalculatedValue, public Qualified
|
||||
{
|
||||
public:
|
||||
HasAreaDebuffValue(PlayerbotAI* botAI) : BoolCalculatedValue(botAI) {}
|
||||
|
||||
Unit* GetTarget()
|
||||
{
|
||||
AiObjectContext* ctx = AiObject::context;
|
||||
|
||||
return ctx->GetValue<Unit*>(qualifier)->Get();
|
||||
}
|
||||
virtual bool Calculate();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -283,6 +283,8 @@ class ValueContext : public NamedObjectContext<UntypedValue>
|
||||
creators["RTSC selected"] = &ValueContext::RTSC_selected;
|
||||
creators["RTSC next spell action"] = &ValueContext::RTSC_next_spell_action;
|
||||
creators["RTSC saved location"] = &ValueContext::RTSC_saved_location;
|
||||
|
||||
creators["has area debuff"] = &ValueContext::has_area_debuff;
|
||||
}
|
||||
|
||||
private:
|
||||
@@ -471,6 +473,8 @@ class ValueContext : public NamedObjectContext<UntypedValue>
|
||||
static UntypedValue* RTSC_selected(PlayerbotAI* botAI) { return new RTSCSelectedValue(botAI); }
|
||||
static UntypedValue* RTSC_next_spell_action(PlayerbotAI* botAI) { return new RTSCNextSpellActionValue(botAI); }
|
||||
static UntypedValue* RTSC_saved_location(PlayerbotAI* botAI) { return new RTSCSavedLocationValue(botAI); }
|
||||
|
||||
static UntypedValue* has_area_debuff(PlayerbotAI* botAI) { return new HasAreaDebuffValue(botAI); }
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user