mirror of
https://github.com/mod-playerbots/mod-playerbots
synced 2025-11-29 15:58:20 +08:00
Improve druid cat spec
This commit is contained in:
@@ -996,7 +996,7 @@ AiPlayerbot.PremadeSpecLink.11.2.60 = --230033312031501531050013051
|
|||||||
AiPlayerbot.PremadeSpecLink.11.2.80 = 05320001--230033312031512531153313051
|
AiPlayerbot.PremadeSpecLink.11.2.80 = 05320001--230033312031512531153313051
|
||||||
AiPlayerbot.PremadeSpecName.11.3 = cat pve
|
AiPlayerbot.PremadeSpecName.11.3 = cat pve
|
||||||
AiPlayerbot.PremadeSpecGlyph.11.3 = 40902,43331,40901,43335,44922,45604
|
AiPlayerbot.PremadeSpecGlyph.11.3 = 40902,43331,40901,43335,44922,45604
|
||||||
AiPlayerbot.PremadeSpecLink.11.3.60 = -553202032322010052100030310501
|
AiPlayerbot.PremadeSpecLink.11.3.60 = -552202032322010053100030310501
|
||||||
AiPlayerbot.PremadeSpecLink.11.3.80 = -553202032322010053100030310511-205503012
|
AiPlayerbot.PremadeSpecLink.11.3.80 = -553202032322010053100030310511-205503012
|
||||||
|
|
||||||
#
|
#
|
||||||
@@ -1183,11 +1183,12 @@ AiPlayerbot.RandomClassSpecIndex.9.2 = 2
|
|||||||
|
|
||||||
AiPlayerbot.RandomClassSpecProb.11.0 = 20
|
AiPlayerbot.RandomClassSpecProb.11.0 = 20
|
||||||
AiPlayerbot.RandomClassSpecIndex.11.0 = 0
|
AiPlayerbot.RandomClassSpecIndex.11.0 = 0
|
||||||
AiPlayerbot.RandomClassSpecProb.11.1 = 40
|
AiPlayerbot.RandomClassSpecProb.11.1 = 30
|
||||||
AiPlayerbot.RandomClassSpecIndex.11.1 = 1
|
AiPlayerbot.RandomClassSpecIndex.11.1 = 1
|
||||||
AiPlayerbot.RandomClassSpecProb.11.2 = 40
|
AiPlayerbot.RandomClassSpecProb.11.2 = 30
|
||||||
AiPlayerbot.RandomClassSpecIndex.11.2 = 2
|
AiPlayerbot.RandomClassSpecIndex.11.2 = 2
|
||||||
|
AiPlayerbot.RandomClassSpecProb.11.3 = 20
|
||||||
|
AiPlayerbot.RandomClassSpecIndex.11.3 = 3
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
|
|||||||
@@ -71,7 +71,6 @@ uint8 AiFactory::GetPlayerSpecTab(Player* bot)
|
|||||||
max = tabs[i];
|
max = tabs[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return tab;
|
return tab;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -1998,6 +1998,10 @@ bool PlayerbotAI::IsDps(Player* player)
|
|||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
if (tab == DRUID_TAB_FERAL && !IsTank(player))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case CLASS_SHAMAN:
|
case CLASS_SHAMAN:
|
||||||
if (tab != SHAMAN_TAB_RESTORATION)
|
if (tab != SHAMAN_TAB_RESTORATION)
|
||||||
@@ -2792,8 +2796,8 @@ bool PlayerbotAI::CanCastSpell(uint32 spellid, Unit* target, bool checkHasSpell,
|
|||||||
}
|
}
|
||||||
|
|
||||||
uint32 CastingTime = !spellInfo->IsChanneled() ? spellInfo->CalcCastTime(bot) : spellInfo->GetDuration();
|
uint32 CastingTime = !spellInfo->IsChanneled() ? spellInfo->CalcCastTime(bot) : spellInfo->GetDuration();
|
||||||
bool interruptOnMove = spellInfo->InterruptFlags & SPELL_INTERRUPT_FLAG_MOVEMENT;
|
// bool interruptOnMove = spellInfo->InterruptFlags & SPELL_INTERRUPT_FLAG_MOVEMENT;
|
||||||
if ((CastingTime || interruptOnMove) && bot->isMoving())
|
if ((CastingTime || spellInfo->IsAutoRepeatRangedSpell()) && bot->isMoving())
|
||||||
{
|
{
|
||||||
if (!sPlayerbotAIConfig->logInGroupOnly || (bot->GetGroup() && HasRealPlayerMaster()))
|
if (!sPlayerbotAIConfig->logInGroupOnly || (bot->GetGroup() && HasRealPlayerMaster()))
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -329,15 +329,22 @@ bool PlayerbotAIConfig::Initialize()
|
|||||||
parsedSpecLinkOrder[cls][spec][level] = ParseTempTalentsOrder(cls, premadeSpecLink[cls][spec][level]);
|
parsedSpecLinkOrder[cls][spec][level] = ParseTempTalentsOrder(cls, premadeSpecLink[cls][spec][level]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (uint32 spec = 0; spec < 3; ++spec)
|
for (uint32 spec = 0; spec < MAX_SPECNO; ++spec)
|
||||||
{
|
{
|
||||||
std::ostringstream os;
|
std::ostringstream os;
|
||||||
os << "AiPlayerbot.RandomClassSpecProb." << cls << "." << spec;
|
os << "AiPlayerbot.RandomClassSpecProb." << cls << "." << spec;
|
||||||
randomClassSpecProb[cls][spec] = sConfigMgr->GetOption<uint32>(os.str().c_str(), 33);
|
uint32 def;
|
||||||
|
if (spec <= 1)
|
||||||
|
def = 33;
|
||||||
|
else if (spec == 2)
|
||||||
|
def = 34;
|
||||||
|
else
|
||||||
|
def = 0;
|
||||||
|
randomClassSpecProb[cls][spec] = sConfigMgr->GetOption<uint32>(os.str().c_str(), def, false);
|
||||||
os.str("");
|
os.str("");
|
||||||
os.clear();
|
os.clear();
|
||||||
os << "AiPlayerbot.RandomClassSpecIndex." << cls << "." << spec;
|
os << "AiPlayerbot.RandomClassSpecIndex." << cls << "." << spec;
|
||||||
randomClassSpecIndex[cls][spec] = sConfigMgr->GetOption<uint32>(os.str().c_str(), spec + 1);
|
randomClassSpecIndex[cls][spec] = sConfigMgr->GetOption<uint32>(os.str().c_str(), spec, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -878,14 +878,31 @@ void PlayerbotFactory::InitTalentsTree(bool increment /*false*/, bool use_templa
|
|||||||
uint32 total_tabs = tabs[0] + tabs[1] + tabs[2];
|
uint32 total_tabs = tabs[0] + tabs[1] + tabs[2];
|
||||||
if (increment && total_tabs != 0)
|
if (increment && total_tabs != 0)
|
||||||
{
|
{
|
||||||
|
/// @todo: match current talent with template
|
||||||
specTab = AiFactory::GetPlayerSpecTab(bot);
|
specTab = AiFactory::GetPlayerSpecTab(bot);
|
||||||
}
|
/// @todo: fix cat druid hardcode
|
||||||
|
if (bot->getClass() == CLASS_DRUID && specTab == DRUID_TAB_FERAL && bot->GetLevel() >= 20 && PlayerbotAI::IsDps(bot))
|
||||||
|
specTab = 3;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
uint32 point = urand(0, 100);
|
uint32 point = urand(1, 100);
|
||||||
uint32 p1 = sPlayerbotAIConfig->randomClassSpecProb[cls][0];
|
uint32 currentP = 0;
|
||||||
uint32 p2 = p1 + sPlayerbotAIConfig->randomClassSpecProb[cls][1];
|
int i;
|
||||||
specTab = point < p1 ? 0 : (point < p2 ? 1 : 2);
|
for (i = 0; i < MAX_SPECNO; i++)
|
||||||
|
{
|
||||||
|
currentP += sPlayerbotAIConfig->randomClassSpecProb[cls][i];
|
||||||
|
if (point <= currentP)
|
||||||
|
{
|
||||||
|
specTab = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (i == MAX_SPECNO)
|
||||||
|
{
|
||||||
|
specTab = 0;
|
||||||
|
LOG_ERROR("playerbots", "Fail to select spec num for bot {}! Set to 0.", bot->GetName());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (reset)
|
if (reset)
|
||||||
{
|
{
|
||||||
@@ -896,12 +913,13 @@ void PlayerbotFactory::InitTalentsTree(bool increment /*false*/, bool use_templa
|
|||||||
{
|
{
|
||||||
InitTalentsByTemplate(specTab);
|
InitTalentsByTemplate(specTab);
|
||||||
}
|
}
|
||||||
else
|
// always use template now
|
||||||
{
|
// else
|
||||||
InitTalents(specTab);
|
// {
|
||||||
if (bot->GetFreeTalentPoints())
|
// InitTalents(specTab);
|
||||||
InitTalents((specTab + 1) % 3);
|
// if (bot->GetFreeTalentPoints())
|
||||||
}
|
// InitTalents((specTab + 1) % 3);
|
||||||
|
// }
|
||||||
bot->SendTalentsInfoData(false);
|
bot->SendTalentsInfoData(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1433,7 +1451,7 @@ void Shuffle(std::vector<uint32>& items)
|
|||||||
void PlayerbotFactory::InitEquipment(bool incremental)
|
void PlayerbotFactory::InitEquipment(bool incremental)
|
||||||
{
|
{
|
||||||
std::unordered_map<uint8, std::vector<uint32>> items;
|
std::unordered_map<uint8, std::vector<uint32>> items;
|
||||||
int tab = AiFactory::GetPlayerSpecTab(bot);
|
// int tab = AiFactory::GetPlayerSpecTab(bot);
|
||||||
|
|
||||||
uint32 blevel = bot->GetLevel();
|
uint32 blevel = bot->GetLevel();
|
||||||
int32 delta = 2;
|
int32 delta = 2;
|
||||||
@@ -3062,6 +3080,9 @@ void PlayerbotFactory::InitGlyphs(bool increment)
|
|||||||
|
|
||||||
uint8 cls = bot->getClass();
|
uint8 cls = bot->getClass();
|
||||||
uint8 tab = AiFactory::GetPlayerSpecTab(bot);
|
uint8 tab = AiFactory::GetPlayerSpecTab(bot);
|
||||||
|
/// @todo: fix cat druid hardcode
|
||||||
|
if (bot->getClass() == CLASS_DRUID && tab == DRUID_TAB_FERAL && PlayerbotAI::IsDps(bot))
|
||||||
|
tab = 3;
|
||||||
std::list<uint32> glyphs;
|
std::list<uint32> glyphs;
|
||||||
ItemTemplateContainer const* itemTemplates = sObjectMgr->GetItemTemplateStore();
|
ItemTemplateContainer const* itemTemplates = sObjectMgr->GetItemTemplateStore();
|
||||||
for (ItemTemplateContainer::const_iterator i = itemTemplates->begin(); i != itemTemplates->end(); ++i)
|
for (ItemTemplateContainer::const_iterator i = itemTemplates->begin(); i != itemTemplates->end(); ++i)
|
||||||
|
|||||||
@@ -70,7 +70,7 @@ private:
|
|||||||
{
|
{
|
||||||
return new ActionNode("mangle (cat)",
|
return new ActionNode("mangle (cat)",
|
||||||
/*P*/ nullptr,
|
/*P*/ nullptr,
|
||||||
/*A*/ NextAction::array(0, new NextAction("claw"), nullptr),
|
/*A*/ nullptr,
|
||||||
/*C*/ nullptr);
|
/*C*/ nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -122,38 +122,49 @@ CatDpsDruidStrategy::CatDpsDruidStrategy(PlayerbotAI* botAI) : FeralDruidStrateg
|
|||||||
|
|
||||||
NextAction** CatDpsDruidStrategy::getDefaultActions()
|
NextAction** CatDpsDruidStrategy::getDefaultActions()
|
||||||
{
|
{
|
||||||
return NextAction::array(0, new NextAction("mangle (cat)", ACTION_DEFAULT + 0.1f), nullptr);
|
return NextAction::array(0, new NextAction("mangle (cat)", ACTION_DEFAULT + 0.3f),
|
||||||
|
new NextAction("shred", ACTION_DEFAULT + 0.2f), nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CatDpsDruidStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
void CatDpsDruidStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||||
{
|
{
|
||||||
FeralDruidStrategy::InitTriggers(triggers);
|
FeralDruidStrategy::InitTriggers(triggers);
|
||||||
|
|
||||||
|
// Default priority
|
||||||
|
triggers.push_back(new TriggerNode("high energy available",
|
||||||
|
NextAction::array(0, new NextAction("claw", ACTION_DEFAULT + 0.1f), nullptr)));
|
||||||
triggers.push_back(
|
triggers.push_back(
|
||||||
new TriggerNode("cat form", NextAction::array(0, new NextAction("cat form", ACTION_HIGH + 2), nullptr)));
|
new TriggerNode("faerie fire (feral)",
|
||||||
|
NextAction::array(0, new NextAction("faerie fire (feral)", ACTION_DEFAULT + 0.0f), nullptr)));
|
||||||
|
|
||||||
|
// Main spell
|
||||||
triggers.push_back(
|
triggers.push_back(
|
||||||
new TriggerNode("rake", NextAction::array(0, new NextAction("rake", ACTION_NORMAL + 5), nullptr)));
|
new TriggerNode("cat form", NextAction::array(0, new NextAction("cat form", ACTION_HIGH + 8), nullptr)));
|
||||||
|
|
||||||
|
triggers.push_back(new TriggerNode("tiger's fury",
|
||||||
|
NextAction::array(0, new NextAction("tiger's fury", ACTION_HIGH + 7), nullptr)));
|
||||||
|
triggers.push_back(
|
||||||
|
new TriggerNode("savage roar", NextAction::array(0, new NextAction("savage roar", ACTION_HIGH + 5), nullptr)));
|
||||||
|
triggers.push_back(new TriggerNode("combo points available",
|
||||||
|
NextAction::array(0, new NextAction("rip", ACTION_HIGH + 4), nullptr)));
|
||||||
triggers.push_back(new TriggerNode(
|
triggers.push_back(new TriggerNode(
|
||||||
"combo points available", NextAction::array(0, new NextAction("ferocious bite", ACTION_NORMAL + 9), nullptr)));
|
"combo points available", NextAction::array(0, new NextAction("ferocious bite", ACTION_HIGH + 3), nullptr)));
|
||||||
|
triggers.push_back(new TriggerNode("target with combo points almost dead",
|
||||||
|
NextAction::array(0, new NextAction("ferocious bite", ACTION_HIGH + 2), nullptr)));
|
||||||
|
triggers.push_back(new TriggerNode("rake", NextAction::array(0, new NextAction("rake", ACTION_HIGH + 2), nullptr)));
|
||||||
triggers.push_back(
|
triggers.push_back(
|
||||||
new TriggerNode("medium threat", NextAction::array(0, new NextAction("cower", ACTION_EMERGENCY + 1), nullptr)));
|
new TriggerNode("medium threat", NextAction::array(0, new NextAction("cower", ACTION_HIGH + 1), nullptr)));
|
||||||
|
|
||||||
|
// AOE
|
||||||
|
triggers.push_back(
|
||||||
|
new TriggerNode("medium aoe", NextAction::array(0, new NextAction("swipe (cat)", ACTION_HIGH + 3), nullptr)));
|
||||||
triggers.push_back(new TriggerNode(
|
triggers.push_back(new TriggerNode(
|
||||||
"faerie fire (feral)", NextAction::array(0, new NextAction("faerie fire (feral)", ACTION_HIGH), nullptr)));
|
"light aoe", NextAction::array(0, new NextAction("rake on attacker", ACTION_HIGH + 2), nullptr)));
|
||||||
|
// Reach target
|
||||||
triggers.push_back(new TriggerNode(
|
triggers.push_back(new TriggerNode(
|
||||||
"tiger's fury", NextAction::array(0, new NextAction("tiger's fury", ACTION_EMERGENCY + 1), nullptr)));
|
"enemy out of melee", NextAction::array(0, new NextAction("feral charge - cat", ACTION_HIGH + 9), nullptr)));
|
||||||
triggers.push_back(
|
triggers.push_back(
|
||||||
new TriggerNode("behind target", NextAction::array(0, new NextAction("pounce", ACTION_HIGH + 1), nullptr)));
|
new TriggerNode("enemy out of melee", NextAction::array(0, new NextAction("dash", ACTION_HIGH + 8), nullptr)));
|
||||||
// triggers.push_back(new TriggerNode("player has no flag", NextAction::array(0, new NextAction("prowl",
|
|
||||||
// ACTION_HIGH), nullptr))); triggers.push_back(new TriggerNode("enemy out of melee", NextAction::array(0, new
|
|
||||||
// NextAction("prowl", ACTION_INTERRUPT + 1), nullptr)));
|
|
||||||
triggers.push_back(
|
|
||||||
new TriggerNode("player has flag", NextAction::array(0, new NextAction("dash", ACTION_EMERGENCY), nullptr)));
|
|
||||||
triggers.push_back(new TriggerNode("enemy flagcarrier near",
|
|
||||||
NextAction::array(0, new NextAction("dash", ACTION_EMERGENCY), nullptr)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CatAoeDruidStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
void CatAoeDruidStrategy::InitTriggers(std::vector<TriggerNode*>& triggers) {}
|
||||||
{
|
|
||||||
triggers.push_back(
|
|
||||||
new TriggerNode("medium aoe", NextAction::array(0, new NextAction("swipe (cat)", ACTION_HIGH + 2), nullptr)));
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -83,6 +83,8 @@ public:
|
|||||||
creators["moonfire"] = &DruidTriggerFactoryInternal::moonfire;
|
creators["moonfire"] = &DruidTriggerFactoryInternal::moonfire;
|
||||||
creators["nature's grasp"] = &DruidTriggerFactoryInternal::natures_grasp;
|
creators["nature's grasp"] = &DruidTriggerFactoryInternal::natures_grasp;
|
||||||
creators["tiger's fury"] = &DruidTriggerFactoryInternal::tigers_fury;
|
creators["tiger's fury"] = &DruidTriggerFactoryInternal::tigers_fury;
|
||||||
|
creators["berserk"] = &DruidTriggerFactoryInternal::berserk;
|
||||||
|
creators["savage roar"] = &DruidTriggerFactoryInternal::savage_roar;
|
||||||
creators["rake"] = &DruidTriggerFactoryInternal::rake;
|
creators["rake"] = &DruidTriggerFactoryInternal::rake;
|
||||||
creators["mark of the wild"] = &DruidTriggerFactoryInternal::mark_of_the_wild;
|
creators["mark of the wild"] = &DruidTriggerFactoryInternal::mark_of_the_wild;
|
||||||
creators["mark of the wild on party"] = &DruidTriggerFactoryInternal::mark_of_the_wild_on_party;
|
creators["mark of the wild on party"] = &DruidTriggerFactoryInternal::mark_of_the_wild_on_party;
|
||||||
@@ -117,6 +119,8 @@ private:
|
|||||||
static Trigger* faerie_fire(PlayerbotAI* botAI) { return new FaerieFireTrigger(botAI); }
|
static Trigger* faerie_fire(PlayerbotAI* botAI) { return new FaerieFireTrigger(botAI); }
|
||||||
static Trigger* natures_grasp(PlayerbotAI* botAI) { return new NaturesGraspTrigger(botAI); }
|
static Trigger* natures_grasp(PlayerbotAI* botAI) { return new NaturesGraspTrigger(botAI); }
|
||||||
static Trigger* tigers_fury(PlayerbotAI* botAI) { return new TigersFuryTrigger(botAI); }
|
static Trigger* tigers_fury(PlayerbotAI* botAI) { return new TigersFuryTrigger(botAI); }
|
||||||
|
static Trigger* berserk(PlayerbotAI* botAI) { return new BerserkTrigger(botAI); }
|
||||||
|
static Trigger* savage_roar(PlayerbotAI* botAI) { return new SavageRoarTrigger(botAI); }
|
||||||
static Trigger* rake(PlayerbotAI* botAI) { return new RakeTrigger(botAI); }
|
static Trigger* rake(PlayerbotAI* botAI) { return new RakeTrigger(botAI); }
|
||||||
static Trigger* mark_of_the_wild(PlayerbotAI* botAI) { return new MarkOfTheWildTrigger(botAI); }
|
static Trigger* mark_of_the_wild(PlayerbotAI* botAI) { return new MarkOfTheWildTrigger(botAI); }
|
||||||
static Trigger* mark_of_the_wild_on_party(PlayerbotAI* botAI) { return new MarkOfTheWildOnPartyTrigger(botAI); }
|
static Trigger* mark_of_the_wild_on_party(PlayerbotAI* botAI) { return new MarkOfTheWildOnPartyTrigger(botAI); }
|
||||||
@@ -174,6 +178,7 @@ public:
|
|||||||
creators["mangle (cat)"] = &DruidAiObjectContextInternal::mangle_cat;
|
creators["mangle (cat)"] = &DruidAiObjectContextInternal::mangle_cat;
|
||||||
creators["swipe (cat)"] = &DruidAiObjectContextInternal::swipe_cat;
|
creators["swipe (cat)"] = &DruidAiObjectContextInternal::swipe_cat;
|
||||||
creators["rake"] = &DruidAiObjectContextInternal::rake;
|
creators["rake"] = &DruidAiObjectContextInternal::rake;
|
||||||
|
creators["rake on attacker"] = &DruidAiObjectContextInternal::rake_on_attacker;
|
||||||
creators["ferocious bite"] = &DruidAiObjectContextInternal::ferocious_bite;
|
creators["ferocious bite"] = &DruidAiObjectContextInternal::ferocious_bite;
|
||||||
creators["rip"] = &DruidAiObjectContextInternal::rip;
|
creators["rip"] = &DruidAiObjectContextInternal::rip;
|
||||||
creators["cower"] = &DruidAiObjectContextInternal::cower;
|
creators["cower"] = &DruidAiObjectContextInternal::cower;
|
||||||
@@ -188,6 +193,7 @@ public:
|
|||||||
creators["abolish poison on party"] = &DruidAiObjectContextInternal::abolish_poison_on_party;
|
creators["abolish poison on party"] = &DruidAiObjectContextInternal::abolish_poison_on_party;
|
||||||
creators["berserk"] = &DruidAiObjectContextInternal::berserk;
|
creators["berserk"] = &DruidAiObjectContextInternal::berserk;
|
||||||
creators["tiger's fury"] = &DruidAiObjectContextInternal::tigers_fury;
|
creators["tiger's fury"] = &DruidAiObjectContextInternal::tigers_fury;
|
||||||
|
creators["savage roar"] = &DruidAiObjectContextInternal::savage_roar;
|
||||||
creators["mark of the wild"] = &DruidAiObjectContextInternal::mark_of_the_wild;
|
creators["mark of the wild"] = &DruidAiObjectContextInternal::mark_of_the_wild;
|
||||||
creators["mark of the wild on party"] = &DruidAiObjectContextInternal::mark_of_the_wild_on_party;
|
creators["mark of the wild on party"] = &DruidAiObjectContextInternal::mark_of_the_wild_on_party;
|
||||||
creators["regrowth"] = &DruidAiObjectContextInternal::regrowth;
|
creators["regrowth"] = &DruidAiObjectContextInternal::regrowth;
|
||||||
@@ -257,6 +263,7 @@ private:
|
|||||||
static Action* mangle_cat(PlayerbotAI* botAI) { return new CastMangleCatAction(botAI); }
|
static Action* mangle_cat(PlayerbotAI* botAI) { return new CastMangleCatAction(botAI); }
|
||||||
static Action* swipe_cat(PlayerbotAI* botAI) { return new CastSwipeCatAction(botAI); }
|
static Action* swipe_cat(PlayerbotAI* botAI) { return new CastSwipeCatAction(botAI); }
|
||||||
static Action* rake(PlayerbotAI* botAI) { return new CastRakeAction(botAI); }
|
static Action* rake(PlayerbotAI* botAI) { return new CastRakeAction(botAI); }
|
||||||
|
static Action* rake_on_attacker(PlayerbotAI* botAI) { return new CastRakeOnMeleeAttackersAction(botAI); }
|
||||||
static Action* ferocious_bite(PlayerbotAI* botAI) { return new CastFerociousBiteAction(botAI); }
|
static Action* ferocious_bite(PlayerbotAI* botAI) { return new CastFerociousBiteAction(botAI); }
|
||||||
static Action* rip(PlayerbotAI* botAI) { return new CastRipAction(botAI); }
|
static Action* rip(PlayerbotAI* botAI) { return new CastRipAction(botAI); }
|
||||||
static Action* cower(PlayerbotAI* botAI) { return new CastCowerAction(botAI); }
|
static Action* cower(PlayerbotAI* botAI) { return new CastCowerAction(botAI); }
|
||||||
@@ -271,6 +278,7 @@ private:
|
|||||||
static Action* abolish_poison_on_party(PlayerbotAI* botAI) { return new CastAbolishPoisonOnPartyAction(botAI); }
|
static Action* abolish_poison_on_party(PlayerbotAI* botAI) { return new CastAbolishPoisonOnPartyAction(botAI); }
|
||||||
static Action* berserk(PlayerbotAI* botAI) { return new CastBerserkAction(botAI); }
|
static Action* berserk(PlayerbotAI* botAI) { return new CastBerserkAction(botAI); }
|
||||||
static Action* tigers_fury(PlayerbotAI* botAI) { return new CastTigersFuryAction(botAI); }
|
static Action* tigers_fury(PlayerbotAI* botAI) { return new CastTigersFuryAction(botAI); }
|
||||||
|
static Action* savage_roar(PlayerbotAI* botAI) { return new CastSavageRoarAction(botAI); }
|
||||||
static Action* mark_of_the_wild(PlayerbotAI* botAI) { return new CastMarkOfTheWildAction(botAI); }
|
static Action* mark_of_the_wild(PlayerbotAI* botAI) { return new CastMarkOfTheWildAction(botAI); }
|
||||||
static Action* mark_of_the_wild_on_party(PlayerbotAI* botAI) { return new CastMarkOfTheWildOnPartyAction(botAI); }
|
static Action* mark_of_the_wild_on_party(PlayerbotAI* botAI) { return new CastMarkOfTheWildOnPartyAction(botAI); }
|
||||||
static Action* regrowth(PlayerbotAI* botAI) { return new CastRegrowthAction(botAI); }
|
static Action* regrowth(PlayerbotAI* botAI) { return new CastRegrowthAction(botAI); }
|
||||||
|
|||||||
6
src/strategy/druid/DruidCatActions.cpp
Normal file
6
src/strategy/druid/DruidCatActions.cpp
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
#include "DruidCatActions.h"
|
||||||
|
|
||||||
|
bool CastMangleCatAction::isUseful()
|
||||||
|
{
|
||||||
|
return CastMeleeDebuffSpellAction::isUseful() && !botAI->HasAura("mangle (bear)", GetTarget(), false, isOwner);
|
||||||
|
}
|
||||||
@@ -35,10 +35,23 @@ public:
|
|||||||
CastTigersFuryAction(PlayerbotAI* botAI) : CastBuffSpellAction(botAI, "tiger's fury") {}
|
CastTigersFuryAction(PlayerbotAI* botAI) : CastBuffSpellAction(botAI, "tiger's fury") {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class CastSavageRoarAction : public CastBuffSpellAction
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CastSavageRoarAction(PlayerbotAI* botAI) : CastBuffSpellAction(botAI, "savage roar") {}
|
||||||
|
std::string const GetTargetName() override { return "current target"; }
|
||||||
|
};
|
||||||
|
|
||||||
class CastRakeAction : public CastDebuffSpellAction
|
class CastRakeAction : public CastDebuffSpellAction
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CastRakeAction(PlayerbotAI* botAI) : CastDebuffSpellAction(botAI, "rake") {}
|
CastRakeAction(PlayerbotAI* botAI) : CastDebuffSpellAction(botAI, "rake", true, 6.0f) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
class CastRakeOnMeleeAttackersAction : public CastDebuffSpellOnMeleeAttackerAction
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CastRakeOnMeleeAttackersAction(PlayerbotAI* botAI) : CastDebuffSpellOnMeleeAttackerAction(botAI, "rake", true, 6.0f) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
class CastClawAction : public CastMeleeSpellAction
|
class CastClawAction : public CastMeleeSpellAction
|
||||||
@@ -47,10 +60,11 @@ public:
|
|||||||
CastClawAction(PlayerbotAI* botAI) : CastMeleeSpellAction(botAI, "claw") {}
|
CastClawAction(PlayerbotAI* botAI) : CastMeleeSpellAction(botAI, "claw") {}
|
||||||
};
|
};
|
||||||
|
|
||||||
class CastMangleCatAction : public CastMeleeSpellAction
|
class CastMangleCatAction : public CastMeleeDebuffSpellAction
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CastMangleCatAction(PlayerbotAI* botAI) : CastMeleeSpellAction(botAI, "mangle (cat)") {}
|
CastMangleCatAction(PlayerbotAI* botAI) : CastMeleeDebuffSpellAction(botAI, "mangle (cat)", false, 0.0f) {}
|
||||||
|
bool isUseful() override;
|
||||||
};
|
};
|
||||||
|
|
||||||
class CastSwipeCatAction : public CastMeleeSpellAction
|
class CastSwipeCatAction : public CastMeleeSpellAction
|
||||||
@@ -65,10 +79,10 @@ public:
|
|||||||
CastFerociousBiteAction(PlayerbotAI* botAI) : CastMeleeSpellAction(botAI, "ferocious bite") {}
|
CastFerociousBiteAction(PlayerbotAI* botAI) : CastMeleeSpellAction(botAI, "ferocious bite") {}
|
||||||
};
|
};
|
||||||
|
|
||||||
class CastRipAction : public CastMeleeSpellAction
|
class CastRipAction : public CastMeleeDebuffSpellAction
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CastRipAction(PlayerbotAI* botAI) : CastMeleeSpellAction(botAI, "rip") {}
|
CastRipAction(PlayerbotAI* botAI) : CastMeleeDebuffSpellAction(botAI, "rip", true, 12.0f) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
class CastShredAction : public CastMeleeSpellAction
|
class CastShredAction : public CastMeleeSpellAction
|
||||||
|
|||||||
@@ -95,10 +95,22 @@ public:
|
|||||||
BashInterruptSpellTrigger(PlayerbotAI* botAI) : InterruptSpellTrigger(botAI, "bash") {}
|
BashInterruptSpellTrigger(PlayerbotAI* botAI) : InterruptSpellTrigger(botAI, "bash") {}
|
||||||
};
|
};
|
||||||
|
|
||||||
class TigersFuryTrigger : public BoostTrigger
|
class TigersFuryTrigger : public BuffTrigger
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
TigersFuryTrigger(PlayerbotAI* botAI) : BoostTrigger(botAI, "tiger's fury") {}
|
TigersFuryTrigger(PlayerbotAI* botAI) : BuffTrigger(botAI, "tiger's fury") {}
|
||||||
|
};
|
||||||
|
|
||||||
|
class BerserkTrigger : public BoostTrigger
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
BerserkTrigger(PlayerbotAI* botAI) : BoostTrigger(botAI, "berserk") {}
|
||||||
|
};
|
||||||
|
|
||||||
|
class SavageRoarTrigger : public BuffTrigger
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SavageRoarTrigger(PlayerbotAI* botAI) : BuffTrigger(botAI, "savage roar") {}
|
||||||
};
|
};
|
||||||
|
|
||||||
class NaturesGraspTrigger : public BoostTrigger
|
class NaturesGraspTrigger : public BoostTrigger
|
||||||
|
|||||||
@@ -112,4 +112,6 @@ void FeralDruidStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
|||||||
NextAction::array(0, new NextAction("dash", ACTION_EMERGENCY + 2), nullptr)));
|
NextAction::array(0, new NextAction("dash", ACTION_EMERGENCY + 2), nullptr)));
|
||||||
triggers.push_back(new TriggerNode("enemy flagcarrier near",
|
triggers.push_back(new TriggerNode("enemy flagcarrier near",
|
||||||
NextAction::array(0, new NextAction("dash", ACTION_EMERGENCY + 2), nullptr)));
|
NextAction::array(0, new NextAction("dash", ACTION_EMERGENCY + 2), nullptr)));
|
||||||
|
triggers.push_back(
|
||||||
|
new TriggerNode("berserk", NextAction::array(0, new NextAction("berserk", ACTION_HIGH + 6), nullptr)));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,3 +36,36 @@ Unit* AttackerWithoutAuraTargetValue::Calculate()
|
|||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Unit* MeleeAttackerWithoutAuraTargetValue::Calculate()
|
||||||
|
{
|
||||||
|
GuidVector attackers = botAI->GetAiObjectContext()->GetValue<GuidVector>("attackers")->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->IsAlive())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (!bot->IsWithinMeleeRange(unit))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (checkArc && !bot->HasInArc(CAST_ANGLE_IN_FRONT, unit))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (unit->GetHealth() < max_health)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!botAI->HasAura(qualifier, unit, false, true))
|
||||||
|
{
|
||||||
|
max_health = unit->GetHealth();
|
||||||
|
result = unit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|||||||
@@ -28,7 +28,9 @@ protected:
|
|||||||
class MeleeAttackerWithoutAuraTargetValue : public AttackerWithoutAuraTargetValue
|
class MeleeAttackerWithoutAuraTargetValue : public AttackerWithoutAuraTargetValue
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
MeleeAttackerWithoutAuraTargetValue(PlayerbotAI* botAI) : AttackerWithoutAuraTargetValue(botAI, "melee") {}
|
MeleeAttackerWithoutAuraTargetValue(PlayerbotAI* botAI, bool checkArc = true) : AttackerWithoutAuraTargetValue(botAI, "melee"), checkArc(checkArc) {}
|
||||||
|
Unit* Calculate() override;
|
||||||
|
bool checkArc;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -13,6 +13,9 @@ float ExpectedLifetimeValue::Calculate()
|
|||||||
return 0.0f;
|
return 0.0f;
|
||||||
}
|
}
|
||||||
float dps = AI_VALUE(float, "expected group dps");
|
float dps = AI_VALUE(float, "expected group dps");
|
||||||
|
bool aoePenalty = AI_VALUE(uint8, "attacker count") >= 3;
|
||||||
|
if (aoePenalty)
|
||||||
|
dps *= 0.75;
|
||||||
float res = target->GetHealth() / dps;
|
float res = target->GetHealth() / dps;
|
||||||
// bot->Say(target->GetName() + " lifetime: " + std::to_string(res), LANG_UNIVERSAL);
|
// bot->Say(target->GetName() + " lifetime: " + std::to_string(res), LANG_UNIVERSAL);
|
||||||
return res;
|
return res;
|
||||||
|
|||||||
Reference in New Issue
Block a user