mirror of
https://github.com/mod-playerbots/mod-playerbots
synced 2025-11-29 15:58:20 +08:00
Mage improvement (fire mage aoe)
This commit is contained in:
@@ -31,7 +31,7 @@ private:
|
|||||||
{
|
{
|
||||||
return new ActionNode("arcane barrage",
|
return new ActionNode("arcane barrage",
|
||||||
/*P*/ nullptr,
|
/*P*/ nullptr,
|
||||||
/*A*/ NextAction::array(0, new NextAction("arcane missiles"), nullptr),
|
/*A*/ nullptr,
|
||||||
/*C*/ nullptr);
|
/*C*/ nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -59,8 +59,10 @@ ArcaneMageStrategy::ArcaneMageStrategy(PlayerbotAI* botAI) : GenericMageStrategy
|
|||||||
|
|
||||||
NextAction** ArcaneMageStrategy::getDefaultActions()
|
NextAction** ArcaneMageStrategy::getDefaultActions()
|
||||||
{
|
{
|
||||||
return NextAction::array(0, new NextAction("arcane blast", ACTION_DEFAULT + 0.1f),
|
return NextAction::array(0, new NextAction("arcane blast", ACTION_DEFAULT + 0.3f),
|
||||||
new NextAction("shoot", ACTION_DEFAULT), NULL);
|
// new NextAction("arcane barrage", ACTION_DEFAULT + 0.2f), // cast during movement
|
||||||
|
new NextAction("fire blast", ACTION_DEFAULT + 0.1f), // cast during movement
|
||||||
|
new NextAction("shoot", ACTION_DEFAULT), nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ArcaneMageStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
void ArcaneMageStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||||
|
|||||||
@@ -9,7 +9,8 @@
|
|||||||
|
|
||||||
NextAction** FireMageStrategy::getDefaultActions()
|
NextAction** FireMageStrategy::getDefaultActions()
|
||||||
{
|
{
|
||||||
return NextAction::array(0, new NextAction("fireball", ACTION_DEFAULT + 0.1f),
|
return NextAction::array(0, new NextAction("fireball", ACTION_DEFAULT + 0.2f),
|
||||||
|
new NextAction("fire blast", ACTION_DEFAULT + 0.1f), // cast during movement
|
||||||
new NextAction("shoot", ACTION_DEFAULT), NULL);
|
new NextAction("shoot", ACTION_DEFAULT), NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -23,6 +24,8 @@ void FireMageStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
|||||||
new TriggerNode("hot streak", NextAction::array(0, new NextAction("pyroblast", 25.0f), nullptr)));
|
new TriggerNode("hot streak", NextAction::array(0, new NextAction("pyroblast", 25.0f), nullptr)));
|
||||||
triggers.push_back(
|
triggers.push_back(
|
||||||
new TriggerNode("combustion", NextAction::array(0, new NextAction("combustion", 50.0f), nullptr)));
|
new TriggerNode("combustion", NextAction::array(0, new NextAction("combustion", 50.0f), nullptr)));
|
||||||
|
triggers.push_back(
|
||||||
|
new TriggerNode("living bomb", NextAction::array(0, new NextAction("living bomb", 19.0f), nullptr)));
|
||||||
// triggers.push_back(new TriggerNode("enemy too close for spell", NextAction::array(0, new NextAction("dragon's
|
// triggers.push_back(new TriggerNode("enemy too close for spell", NextAction::array(0, new NextAction("dragon's
|
||||||
// breath", 70.0f), nullptr)));
|
// breath", 70.0f), nullptr)));
|
||||||
}
|
}
|
||||||
@@ -30,7 +33,10 @@ void FireMageStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
|||||||
void FireMageAoeStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
void FireMageAoeStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||||
{
|
{
|
||||||
triggers.push_back(
|
triggers.push_back(
|
||||||
new TriggerNode("medium aoe", NextAction::array(0, new NextAction("flamestrike", 20.0f), nullptr)));
|
new TriggerNode("medium aoe", NextAction::array(0,
|
||||||
triggers.push_back(
|
new NextAction("dragon's breath", 24.0f),
|
||||||
new TriggerNode("living bomb", NextAction::array(0, new NextAction("living bomb", 25.0f), nullptr)));
|
new NextAction("flamestrike", 23.0f),
|
||||||
|
new NextAction("blast wave", 22.0f),
|
||||||
|
new NextAction("living bomb on attackers", 21.0f),
|
||||||
|
new NextAction("blizzard", 20.0f), nullptr)));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ private:
|
|||||||
{
|
{
|
||||||
return new ActionNode("fire blast",
|
return new ActionNode("fire blast",
|
||||||
/*P*/ nullptr,
|
/*P*/ nullptr,
|
||||||
/*A*/ NextAction::array(0, new NextAction("scorch"), nullptr),
|
/*A*/ nullptr,
|
||||||
/*C*/ nullptr);
|
/*C*/ nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -115,16 +115,16 @@ private:
|
|||||||
{
|
{
|
||||||
return new ActionNode("dragon's breath",
|
return new ActionNode("dragon's breath",
|
||||||
/*P*/ nullptr,
|
/*P*/ nullptr,
|
||||||
/*A*/ NextAction::array(0, new NextAction("blast wave"), nullptr),
|
/*A*/ nullptr,
|
||||||
/*C*/ NextAction::array(0, new NextAction("flamestrike", 71.0f), nullptr));
|
/*C*/ nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
static ActionNode* blast_wave([[maybe_unused]] PlayerbotAI* botAI)
|
static ActionNode* blast_wave([[maybe_unused]] PlayerbotAI* botAI)
|
||||||
{
|
{
|
||||||
return new ActionNode("blast wave",
|
return new ActionNode("blast wave",
|
||||||
/*P*/ nullptr,
|
/*P*/ nullptr,
|
||||||
/*A*/ NextAction::array(0, new NextAction("frost nova"), nullptr),
|
/*A*/ nullptr,
|
||||||
/*C*/ NextAction::array(0, new NextAction("flamestrike", 71.0f), nullptr));
|
/*C*/ nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
static ActionNode* remove_curse([[maybe_unused]] PlayerbotAI* botAI)
|
static ActionNode* remove_curse([[maybe_unused]] PlayerbotAI* botAI)
|
||||||
|
|||||||
@@ -12,6 +12,9 @@ Value<Unit*>* CastPolymorphAction::GetTargetValue() { return context->GetValue<U
|
|||||||
|
|
||||||
bool CastFrostNovaAction::isUseful()
|
bool CastFrostNovaAction::isUseful()
|
||||||
{
|
{
|
||||||
|
Unit* target = AI_VALUE(Unit*, "current target");
|
||||||
|
if (target && target->ToCreature() && target->ToCreature()->HasMechanicTemplateImmunity(1 << (MECHANIC_FREEZE - 1)))
|
||||||
|
return false;
|
||||||
return sServerFacade->IsDistanceLessOrEqualThan(AI_VALUE2(float, "distance", GetTargetName()), 10.f);
|
return sServerFacade->IsDistanceLessOrEqualThan(AI_VALUE2(float, "distance", GetTargetName()), 10.f);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -21,3 +24,22 @@ bool CastConeOfColdAction::isUseful()
|
|||||||
bool targetClose = sServerFacade->IsDistanceLessOrEqualThan(AI_VALUE2(float, "distance", GetTargetName()), 10.f);
|
bool targetClose = sServerFacade->IsDistanceLessOrEqualThan(AI_VALUE2(float, "distance", GetTargetName()), 10.f);
|
||||||
return facingTarget && targetClose;
|
return facingTarget && targetClose;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CastDragonsBreathAction::isUseful()
|
||||||
|
{
|
||||||
|
Unit* target = AI_VALUE(Unit*, "current target");
|
||||||
|
if (!target)
|
||||||
|
return false;
|
||||||
|
bool facingTarget = AI_VALUE2(bool, "facing", "current target");
|
||||||
|
bool targetClose = bot->IsWithinCombatRange(target, 10.0f);
|
||||||
|
return facingTarget && targetClose;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CastBlastWaveAction::isUseful()
|
||||||
|
{
|
||||||
|
Unit* target = AI_VALUE(Unit*, "current target");
|
||||||
|
if (!target)
|
||||||
|
return false;
|
||||||
|
bool targetClose = bot->IsWithinCombatRange(target, 10.0f);
|
||||||
|
return targetClose;
|
||||||
|
}
|
||||||
@@ -57,10 +57,10 @@ public:
|
|||||||
CastPyroblastAction(PlayerbotAI* botAI) : CastSpellAction(botAI, "pyroblast") {}
|
CastPyroblastAction(PlayerbotAI* botAI) : CastSpellAction(botAI, "pyroblast") {}
|
||||||
};
|
};
|
||||||
|
|
||||||
class CastFlamestrikeAction : public CastSpellAction
|
class CastFlamestrikeAction : public CastDebuffSpellAction
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CastFlamestrikeAction(PlayerbotAI* botAI) : CastSpellAction(botAI, "flamestrike") {}
|
CastFlamestrikeAction(PlayerbotAI* botAI) : CastDebuffSpellAction(botAI, "flamestrike", true, 0.0f) {}
|
||||||
ActionThreatType getThreatType() override { return ActionThreatType::Aoe; }
|
ActionThreatType getThreatType() override { return ActionThreatType::Aoe; }
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -243,11 +243,18 @@ public:
|
|||||||
CastLivingBombAction(PlayerbotAI* botAI) : CastDebuffSpellAction(botAI, "living bomb", true) {}
|
CastLivingBombAction(PlayerbotAI* botAI) : CastDebuffSpellAction(botAI, "living bomb", true) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class CastLivingBombOnAttackersAction : public CastDebuffSpellOnAttackerAction
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CastLivingBombOnAttackersAction(PlayerbotAI* botAI) : CastDebuffSpellOnAttackerAction(botAI, "living bomb", true) {}
|
||||||
|
};
|
||||||
|
|
||||||
class CastDragonsBreathAction : public CastSpellAction
|
class CastDragonsBreathAction : public CastSpellAction
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CastDragonsBreathAction(PlayerbotAI* botAI) : CastSpellAction(botAI, "dragon's breath") {}
|
CastDragonsBreathAction(PlayerbotAI* botAI) : CastSpellAction(botAI, "dragon's breath") {}
|
||||||
ActionThreatType getThreatType() override { return ActionThreatType::Aoe; }
|
ActionThreatType getThreatType() override { return ActionThreatType::Aoe; }
|
||||||
|
bool isUseful() override;
|
||||||
};
|
};
|
||||||
|
|
||||||
class CastBlastWaveAction : public CastSpellAction
|
class CastBlastWaveAction : public CastSpellAction
|
||||||
@@ -255,6 +262,7 @@ class CastBlastWaveAction : public CastSpellAction
|
|||||||
public:
|
public:
|
||||||
CastBlastWaveAction(PlayerbotAI* botAI) : CastSpellAction(botAI, "blast wave") {}
|
CastBlastWaveAction(PlayerbotAI* botAI) : CastSpellAction(botAI, "blast wave") {}
|
||||||
ActionThreatType getThreatType() override { return ActionThreatType::Aoe; }
|
ActionThreatType getThreatType() override { return ActionThreatType::Aoe; }
|
||||||
|
bool isUseful() override;
|
||||||
};
|
};
|
||||||
|
|
||||||
class CastInvisibilityAction : public CastBuffSpellAction
|
class CastInvisibilityAction : public CastBuffSpellAction
|
||||||
|
|||||||
@@ -184,6 +184,7 @@ public:
|
|||||||
creators["polymorph"] = &MageAiObjectContextInternal::polymorph;
|
creators["polymorph"] = &MageAiObjectContextInternal::polymorph;
|
||||||
creators["spellsteal"] = &MageAiObjectContextInternal::spellsteal;
|
creators["spellsteal"] = &MageAiObjectContextInternal::spellsteal;
|
||||||
creators["living bomb"] = &MageAiObjectContextInternal::living_bomb;
|
creators["living bomb"] = &MageAiObjectContextInternal::living_bomb;
|
||||||
|
creators["living bomb on attackers"] = &MageAiObjectContextInternal::living_bomb_on_attackers;
|
||||||
creators["dragon's breath"] = &MageAiObjectContextInternal::dragons_breath;
|
creators["dragon's breath"] = &MageAiObjectContextInternal::dragons_breath;
|
||||||
creators["blast wave"] = &MageAiObjectContextInternal::blast_wave;
|
creators["blast wave"] = &MageAiObjectContextInternal::blast_wave;
|
||||||
creators["invisibility"] = &MageAiObjectContextInternal::invisibility;
|
creators["invisibility"] = &MageAiObjectContextInternal::invisibility;
|
||||||
@@ -242,6 +243,7 @@ private:
|
|||||||
static Action* polymorph(PlayerbotAI* botAI) { return new CastPolymorphAction(botAI); }
|
static Action* polymorph(PlayerbotAI* botAI) { return new CastPolymorphAction(botAI); }
|
||||||
static Action* spellsteal(PlayerbotAI* botAI) { return new CastSpellstealAction(botAI); }
|
static Action* spellsteal(PlayerbotAI* botAI) { return new CastSpellstealAction(botAI); }
|
||||||
static Action* living_bomb(PlayerbotAI* botAI) { return new CastLivingBombAction(botAI); }
|
static Action* living_bomb(PlayerbotAI* botAI) { return new CastLivingBombAction(botAI); }
|
||||||
|
static Action* living_bomb_on_attackers(PlayerbotAI* botAI) { return new CastLivingBombOnAttackersAction(botAI); }
|
||||||
static Action* dragons_breath(PlayerbotAI* botAI) { return new CastDragonsBreathAction(botAI); }
|
static Action* dragons_breath(PlayerbotAI* botAI) { return new CastDragonsBreathAction(botAI); }
|
||||||
static Action* blast_wave(PlayerbotAI* botAI) { return new CastBlastWaveAction(botAI); }
|
static Action* blast_wave(PlayerbotAI* botAI) { return new CastBlastWaveAction(botAI); }
|
||||||
static Action* invisibility(PlayerbotAI* botAI) { return new CastInvisibilityAction(botAI); }
|
static Action* invisibility(PlayerbotAI* botAI) { return new CastInvisibilityAction(botAI); }
|
||||||
|
|||||||
@@ -33,6 +33,17 @@ bool FingersOfFrostSingleTrigger::IsActive()
|
|||||||
return (aura && aura->GetCharges() == 1);
|
return (aura && aura->GetCharges() == 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ArcaneBlastStackTrigger::IsActive()
|
||||||
|
{
|
||||||
|
Aura* aura = botAI->GetAura(getName(), GetTarget(), false, true, 3);
|
||||||
|
if (!aura)
|
||||||
|
return false;
|
||||||
|
if (aura->GetStackAmount() >= 4)
|
||||||
|
return true;
|
||||||
|
bool hasMissileBarrage = botAI->HasAura(44401, bot);
|
||||||
|
return hasMissileBarrage;
|
||||||
|
}
|
||||||
|
|
||||||
bool FrostNovaOnTargetTrigger::IsActive()
|
bool FrostNovaOnTargetTrigger::IsActive()
|
||||||
{
|
{
|
||||||
Unit* target = GetTarget();
|
Unit* target = GetTarget();
|
||||||
|
|||||||
@@ -171,6 +171,7 @@ class ArcaneBlastStackTrigger : public HasAuraStackTrigger
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ArcaneBlastStackTrigger(PlayerbotAI* botAI) : HasAuraStackTrigger(botAI, "arcane blast", 3, 1) {}
|
ArcaneBlastStackTrigger(PlayerbotAI* botAI) : HasAuraStackTrigger(botAI, "arcane blast", 3, 1) {}
|
||||||
|
bool IsActive() override;
|
||||||
};
|
};
|
||||||
|
|
||||||
class MirrorImageTrigger : public BoostTrigger
|
class MirrorImageTrigger : public BoostTrigger
|
||||||
|
|||||||
@@ -15,10 +15,10 @@ ShadowPriestStrategy::ShadowPriestStrategy(PlayerbotAI* botAI) : GenericPriestSt
|
|||||||
|
|
||||||
NextAction** ShadowPriestStrategy::getDefaultActions()
|
NextAction** ShadowPriestStrategy::getDefaultActions()
|
||||||
{
|
{
|
||||||
return NextAction::array(0, new NextAction("mind blast", ACTION_DEFAULT + 0.2f),
|
return NextAction::array(0, new NextAction("mind blast", ACTION_DEFAULT + 0.3f),
|
||||||
// new NextAction("shadow word: death", 12.0f),
|
new NextAction("mind flay", ACTION_DEFAULT + 0.2f),
|
||||||
new NextAction("mind flay", ACTION_DEFAULT + 0.1f),
|
new NextAction("shadow word: death", ACTION_DEFAULT + 0.1f), // cast during movement
|
||||||
new NextAction("shoot", ACTION_DEFAULT), NULL);
|
new NextAction("shoot", ACTION_DEFAULT), nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShadowPriestStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
void ShadowPriestStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||||
|
|||||||
@@ -41,7 +41,9 @@ CasterShamanStrategy::CasterShamanStrategy(PlayerbotAI* botAI) : GenericShamanSt
|
|||||||
NextAction** CasterShamanStrategy::getDefaultActions()
|
NextAction** CasterShamanStrategy::getDefaultActions()
|
||||||
{
|
{
|
||||||
return NextAction::array(0, new NextAction("lava burst", ACTION_DEFAULT + 0.2f),
|
return NextAction::array(0, new NextAction("lava burst", ACTION_DEFAULT + 0.2f),
|
||||||
new NextAction("lightning bolt", ACTION_DEFAULT), NULL);
|
new NextAction("lightning bolt", ACTION_DEFAULT + 0.1f),
|
||||||
|
// new NextAction("earth shock", ACTION_DEFAULT), // cast during movement
|
||||||
|
nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CasterShamanStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
void CasterShamanStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||||
|
|||||||
@@ -302,7 +302,7 @@ public:
|
|||||||
class FlameShockTrigger : public DebuffTrigger
|
class FlameShockTrigger : public DebuffTrigger
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
FlameShockTrigger(PlayerbotAI* ai) : DebuffTrigger(ai, "flame shock", 1, true) {}
|
FlameShockTrigger(PlayerbotAI* ai) : DebuffTrigger(ai, "flame shock", 1, true, 6.0f) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
class WrathOfAirTotemTrigger : public TotemTrigger
|
class WrathOfAirTotemTrigger : public TotemTrigger
|
||||||
|
|||||||
@@ -618,8 +618,8 @@ public:
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string const GetTargetName() { return "self target"; }
|
std::string const GetTargetName() override { return "self target"; }
|
||||||
virtual bool IsActive();
|
bool IsActive() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int stack;
|
int stack;
|
||||||
|
|||||||
@@ -49,8 +49,8 @@ DpsWarlockStrategy::DpsWarlockStrategy(PlayerbotAI* botAI) : GenericWarlockStrat
|
|||||||
NextAction** DpsWarlockStrategy::getDefaultActions()
|
NextAction** DpsWarlockStrategy::getDefaultActions()
|
||||||
{
|
{
|
||||||
return NextAction::array(
|
return NextAction::array(
|
||||||
0, new NextAction("haunt", ACTION_DEFAULT + 0.3f), new NextAction("demonic empowerment", ACTION_DEFAULT + 0.2f),
|
0, new NextAction("haunt", ACTION_DEFAULT + 0.4f), new NextAction("demonic empowerment", ACTION_DEFAULT + 0.3f),
|
||||||
new NextAction("shadow bolt", ACTION_DEFAULT + 0.1f), new NextAction("shoot", ACTION_DEFAULT), nullptr);
|
new NextAction("shadow bolt", ACTION_DEFAULT + 0.2f), new NextAction("shoot", ACTION_DEFAULT), nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DpsWarlockStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
void DpsWarlockStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||||
@@ -71,6 +71,10 @@ void DpsWarlockStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
|||||||
|
|
||||||
triggers.push_back(new TriggerNode("decimation", NextAction::array(0, new NextAction("soul fire", 16.0f), NULL)));
|
triggers.push_back(new TriggerNode("decimation", NextAction::array(0, new NextAction("soul fire", 16.0f), NULL)));
|
||||||
|
|
||||||
|
// cast during movement
|
||||||
|
triggers.push_back(
|
||||||
|
new TriggerNode("high mana", NextAction::array(0, new NextAction("life tap", ACTION_DEFAULT + 0.1f), nullptr)));
|
||||||
|
|
||||||
triggers.push_back(new TriggerNode("life tap glyph buff", NextAction::array(0, new NextAction("life tap", 28.0f), NULL)));
|
triggers.push_back(new TriggerNode("life tap glyph buff", NextAction::array(0, new NextAction("life tap", 28.0f), NULL)));
|
||||||
|
|
||||||
triggers.push_back(
|
triggers.push_back(
|
||||||
|
|||||||
Reference in New Issue
Block a user