mirror of
https://github.com/mod-playerbots/mod-playerbots
synced 2025-11-29 15:58:20 +08:00
Auto save mana strategy
This commit is contained in:
@@ -306,6 +306,16 @@ AiPlayerbot.LowMana = 15
|
||||
AiPlayerbot.MediumMana = 40
|
||||
|
||||
# Random bot default strategies (applied after defaults)
|
||||
|
||||
# Enable healer bot save mana
|
||||
# Default: 1 (enable)
|
||||
AiPlayerbot.AutoSaveMana = 1
|
||||
|
||||
# Healer bot save mana threshold
|
||||
# Default: 100 (full)
|
||||
AiPlayerbot.SaveManaThreshold = 100
|
||||
|
||||
|
||||
AiPlayerbot.RandomBotCombatStrategies = "+dps,+dps assist,-threat"
|
||||
# AiPlayerbot.RandomBotNonCombatStrategies = "+grind,+loot,+rpg,+custom::say"
|
||||
AiPlayerbot.RandomBotNonCombatStrategies = ""
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#include "BattlegroundMgr.h"
|
||||
#include "Item.h"
|
||||
#include "PlayerbotAI.h"
|
||||
#include "PlayerbotAIConfig.h"
|
||||
#include "Playerbots.h"
|
||||
#include "Engine.h"
|
||||
#include "Group.h"
|
||||
@@ -273,8 +274,9 @@ void AiFactory::AddDefaultCombatStrategies(Player* player, PlayerbotAI* const fa
|
||||
{
|
||||
engine->addStrategies("dps", "shadow debuff", "shadow aoe", "threat", nullptr);
|
||||
}
|
||||
else
|
||||
else {
|
||||
engine->addStrategies("heal", "threat", nullptr);
|
||||
}
|
||||
|
||||
engine->addStrategies("dps assist", "cure", nullptr);
|
||||
break;
|
||||
@@ -362,6 +364,9 @@ void AiFactory::AddDefaultCombatStrategies(Player* player, PlayerbotAI* const fa
|
||||
engine->addStrategy("boost");
|
||||
engine->addStrategy("dps assist");
|
||||
engine->removeStrategy("threat");
|
||||
if (sPlayerbotAIConfig->autoSaveMana) {
|
||||
engine->addStrategy("auto save mana");
|
||||
}
|
||||
// engine-
|
||||
switch (player->getClass()) {
|
||||
case CLASS_PRIEST: {
|
||||
@@ -426,7 +431,7 @@ void AiFactory::AddDefaultCombatStrategies(Player* player, PlayerbotAI* const fa
|
||||
engine->addStrategy("arena");
|
||||
}
|
||||
|
||||
engine->addStrategies("boost", "racials", "chat", "default", "aoe", "potions", "conserve mana", "cast time", "dps assist", nullptr);
|
||||
engine->addStrategies("boost", "racials", "chat", "default", "aoe", "potions", "cast time", "dps assist", nullptr);
|
||||
engine->removeStrategy("custom::say");
|
||||
engine->removeStrategy("flee");
|
||||
engine->removeStrategy("threat");
|
||||
@@ -603,6 +608,9 @@ void AiFactory::AddDefaultNonCombatStrategies(Player* player, PlayerbotAI* const
|
||||
nonCombatEngine->addStrategy("pvp");
|
||||
nonCombatEngine->ChangeStrategy(sPlayerbotAIConfig->nonCombatStrategies);
|
||||
}
|
||||
if (sPlayerbotAIConfig->autoSaveMana) {
|
||||
nonCombatEngine->addStrategy("auto save mana");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -88,6 +88,8 @@ bool PlayerbotAIConfig::Initialize()
|
||||
almostFullHealth = sConfigMgr->GetOption<int32>("AiPlayerbot.AlmostFullHealth", 85);
|
||||
lowMana = sConfigMgr->GetOption<int32>("AiPlayerbot.LowMana", 15);
|
||||
mediumMana = sConfigMgr->GetOption<int32>("AiPlayerbot.MediumMana", 40);
|
||||
autoSaveMana = sConfigMgr->GetOption<bool>("AiPlayerbot.AutoSaveMana", true);
|
||||
saveManaThreshold = sConfigMgr->GetOption<int32>("AiPlayerbot.SaveManaThreshold", 100);
|
||||
|
||||
randomGearLoweringChance = sConfigMgr->GetOption<float>("AiPlayerbot.RandomGearLoweringChance", 0.15f);
|
||||
randomBotMaxLevelChance = sConfigMgr->GetOption<float>("AiPlayerbot.RandomBotMaxLevelChance", 0.15f);
|
||||
|
||||
@@ -23,6 +23,16 @@ enum class BotCheatMask : uint32
|
||||
maxMask = 32
|
||||
};
|
||||
|
||||
enum class HealingManaEfficiency : uint8
|
||||
{
|
||||
VERY_LOW = 1,
|
||||
LOW = 2,
|
||||
MEDIUM = 4,
|
||||
HIGH = 8,
|
||||
VERY_HIGH = 16,
|
||||
SUPERIOR = 32
|
||||
};
|
||||
|
||||
#define MAX_SPECNO 20
|
||||
|
||||
class PlayerbotAIConfig
|
||||
@@ -51,6 +61,8 @@ class PlayerbotAIConfig
|
||||
aoeRadius, rpgDistance, targetPosRecalcDistance, farDistance, healDistance, aggroDistance;
|
||||
uint32 criticalHealth, lowHealth, mediumHealth, almostFullHealth;
|
||||
uint32 lowMana, mediumMana;
|
||||
bool autoSaveMana;
|
||||
uint32 saveManaThreshold;
|
||||
|
||||
uint32 openGoSpell;
|
||||
bool randomBotAutologin;
|
||||
|
||||
@@ -121,7 +121,7 @@ void PlayerbotFactory::Init()
|
||||
// continue;
|
||||
|
||||
enchantSpellIdCache.push_back(id);
|
||||
LOG_INFO("playerbots", "Add {} to enchantment spells", id);
|
||||
// LOG_INFO("playerbots", "Add {} to enchantment spells", id);
|
||||
}
|
||||
}
|
||||
LOG_INFO("playerbots", "Loading {} enchantment spells", enchantSpellIdCache.size());
|
||||
|
||||
@@ -302,14 +302,14 @@ class clazz : public CastHealingSpellAction \
|
||||
bool isUseful() override { return useful; } \
|
||||
}
|
||||
|
||||
#define HEAL_PARTY_ACTION(clazz, spell) \
|
||||
#define HEAL_PARTY_ACTION(clazz, spell, estAmount, manaEfficiency) \
|
||||
class clazz : public HealPartyMemberAction \
|
||||
{ \
|
||||
public: \
|
||||
clazz(PlayerbotAI* botAI) : HealPartyMemberAction(botAI, spell) { } \
|
||||
clazz(PlayerbotAI* botAI) : HealPartyMemberAction(botAI, spell, estAmount, manaEfficiency) { } \
|
||||
}
|
||||
|
||||
#define AOE_HEAL_ACTION(clazz, spell) \
|
||||
#define AOE_HEAL_ACTION(clazz, spell, estAmount, manaEfficiency) \
|
||||
class clazz : public CastAoeHealSpellAction \
|
||||
{ \
|
||||
public: \
|
||||
|
||||
@@ -58,7 +58,8 @@ class StrategyContext : public NamedObjectContext<Strategy>
|
||||
creators["gather"] = &StrategyContext::gather;
|
||||
creators["emote"] = &StrategyContext::emote;
|
||||
creators["passive"] = &StrategyContext::passive;
|
||||
creators["conserve mana"] = &StrategyContext::conserve_mana;
|
||||
// creators["conserve mana"] = &StrategyContext::conserve_mana;
|
||||
creators["auto save mana"] = &StrategyContext::auto_save_mana;
|
||||
creators["food"] = &StrategyContext::food;
|
||||
creators["chat"] = &StrategyContext::chat;
|
||||
creators["default"] = &StrategyContext::world_packet;
|
||||
@@ -131,7 +132,8 @@ class StrategyContext : public NamedObjectContext<Strategy>
|
||||
static Strategy* gather(PlayerbotAI* botAI) { return new GatherStrategy(botAI); }
|
||||
static Strategy* emote(PlayerbotAI* botAI) { return new EmoteStrategy(botAI); }
|
||||
static Strategy* passive(PlayerbotAI* botAI) { return new PassiveStrategy(botAI); }
|
||||
static Strategy* conserve_mana(PlayerbotAI* botAI) { return new ConserveManaStrategy(botAI); }
|
||||
// static Strategy* conserve_mana(PlayerbotAI* botAI) { return new ConserveManaStrategy(botAI); }
|
||||
static Strategy* auto_save_mana(PlayerbotAI* botAI) { return new HealerAutoSaveManaStrategy(botAI); }
|
||||
static Strategy* food(PlayerbotAI* botAI) { return new UseFoodStrategy(botAI); }
|
||||
static Strategy* chat(PlayerbotAI* botAI) { return new ChatCommandHandlerStrategy(botAI); }
|
||||
static Strategy* world_packet(PlayerbotAI* botAI) { return new WorldPacketHandlerStrategy(botAI); }
|
||||
|
||||
@@ -151,7 +151,8 @@ bool CastEnchantItemAction::isPossible()
|
||||
return spellId && AI_VALUE2(Item*, "item for spell", spellId);
|
||||
}
|
||||
|
||||
CastHealingSpellAction::CastHealingSpellAction(PlayerbotAI* botAI, std::string const spell, uint8 estAmount) : CastAuraSpellAction(botAI, spell, true), estAmount(estAmount)
|
||||
CastHealingSpellAction::CastHealingSpellAction(PlayerbotAI* botAI, std::string const spell, uint8 estAmount, HealingManaEfficiency manaEfficiency)
|
||||
: CastAuraSpellAction(botAI, spell, true), estAmount(estAmount), manaEfficiency(manaEfficiency)
|
||||
{
|
||||
range = botAI->GetRange("heal");
|
||||
}
|
||||
|
||||
@@ -98,20 +98,23 @@ class CastEnchantItemAction : public CastSpellAction
|
||||
class CastHealingSpellAction : public CastAuraSpellAction
|
||||
{
|
||||
public:
|
||||
CastHealingSpellAction(PlayerbotAI* botAI, std::string const spell, uint8 estAmount = 15.0f);
|
||||
CastHealingSpellAction(PlayerbotAI* botAI, std::string const spell, uint8 estAmount = 15.0f, HealingManaEfficiency manaEfficiency = HealingManaEfficiency::MEDIUM);
|
||||
|
||||
std::string const GetTargetName() override { return "self target"; }
|
||||
bool isUseful() override;
|
||||
ActionThreatType getThreatType() override { return ActionThreatType::Aoe; }
|
||||
|
||||
protected:
|
||||
// Yunfan: Mana efficiency tell the bot how to save mana. The higher the better.
|
||||
HealingManaEfficiency manaEfficiency;
|
||||
uint8 estAmount;
|
||||
|
||||
// protected:
|
||||
};
|
||||
|
||||
class CastAoeHealSpellAction : public CastHealingSpellAction
|
||||
{
|
||||
public:
|
||||
CastAoeHealSpellAction(PlayerbotAI* botAI, std::string const spell, uint8 estAmount = 15.0f) : CastHealingSpellAction(botAI, spell, estAmount) { }
|
||||
CastAoeHealSpellAction(PlayerbotAI* botAI, std::string const spell, uint8 estAmount = 15.0f, HealingManaEfficiency manaEfficiency = HealingManaEfficiency::MEDIUM)
|
||||
: CastHealingSpellAction(botAI, spell, estAmount, manaEfficiency) { }
|
||||
|
||||
std::string const GetTargetName() override { return "party member to heal"; }
|
||||
bool isUseful() override;
|
||||
@@ -142,8 +145,8 @@ class PartyMemberActionNameSupport
|
||||
class HealPartyMemberAction : public CastHealingSpellAction, public PartyMemberActionNameSupport
|
||||
{
|
||||
public:
|
||||
HealPartyMemberAction(PlayerbotAI* botAI, std::string const spell, uint8 estAmount = 15.0f) :
|
||||
CastHealingSpellAction(botAI, spell, estAmount), PartyMemberActionNameSupport(spell) { }
|
||||
HealPartyMemberAction(PlayerbotAI* botAI, std::string const spell, uint8 estAmount = 15.0f, HealingManaEfficiency manaEfficiency = HealingManaEfficiency::MEDIUM) :
|
||||
CastHealingSpellAction(botAI, spell, estAmount, manaEfficiency), PartyMemberActionNameSupport(spell) { }
|
||||
|
||||
std::string const GetTargetName() override { return "party member to heal"; }
|
||||
std::string const getName() override { return PartyMemberActionNameSupport::getName(); }
|
||||
|
||||
@@ -46,19 +46,19 @@ class CastHealingTouchAction : public CastHealingSpellAction
|
||||
class CastRejuvenationOnPartyAction : public HealPartyMemberAction
|
||||
{
|
||||
public:
|
||||
CastRejuvenationOnPartyAction(PlayerbotAI* botAI) : HealPartyMemberAction(botAI, "rejuvenation") { }
|
||||
CastRejuvenationOnPartyAction(PlayerbotAI* botAI) : HealPartyMemberAction(botAI, "rejuvenation", 15.0f, HealingManaEfficiency::VERY_HIGH) { }
|
||||
};
|
||||
|
||||
class CastRegrowthOnPartyAction : public HealPartyMemberAction
|
||||
{
|
||||
public:
|
||||
CastRegrowthOnPartyAction(PlayerbotAI* botAI) : HealPartyMemberAction(botAI, "regrowth") { }
|
||||
CastRegrowthOnPartyAction(PlayerbotAI* botAI) : HealPartyMemberAction(botAI, "regrowth", 35.0f, HealingManaEfficiency::HIGH) { }
|
||||
};
|
||||
|
||||
class CastHealingTouchOnPartyAction : public HealPartyMemberAction
|
||||
{
|
||||
public:
|
||||
CastHealingTouchOnPartyAction(PlayerbotAI* botAI) : HealPartyMemberAction(botAI, "healing touch") { }
|
||||
CastHealingTouchOnPartyAction(PlayerbotAI* botAI) : HealPartyMemberAction(botAI, "healing touch", 50.0f, HealingManaEfficiency::LOW) { }
|
||||
};
|
||||
|
||||
class CastReviveAction : public ResurrectPartyMemberAction
|
||||
@@ -242,7 +242,7 @@ class CastInnervateAction : public CastSpellAction
|
||||
class CastTranquilityAction : public CastAoeHealSpellAction
|
||||
{
|
||||
public:
|
||||
CastTranquilityAction(PlayerbotAI* botAI) : CastAoeHealSpellAction(botAI, "tranquility") { }
|
||||
CastTranquilityAction(PlayerbotAI* botAI) : CastAoeHealSpellAction(botAI, "tranquility", 15.0f, HealingManaEfficiency::MEDIUM) { }
|
||||
};
|
||||
|
||||
class CastNaturesSwiftnessAction : public CastBuffSpellAction
|
||||
@@ -254,19 +254,19 @@ class CastNaturesSwiftnessAction : public CastBuffSpellAction
|
||||
class CastWildGrowthOnPartyAction : public HealPartyMemberAction
|
||||
{
|
||||
public:
|
||||
CastWildGrowthOnPartyAction(PlayerbotAI* ai) : HealPartyMemberAction(ai, "wild growth") {}
|
||||
CastWildGrowthOnPartyAction(PlayerbotAI* ai) : HealPartyMemberAction(ai, "wild growth", 15.0f, HealingManaEfficiency::VERY_HIGH) {}
|
||||
};
|
||||
|
||||
class CastPartySwiftmendAction : public HealPartyMemberAction
|
||||
{
|
||||
public:
|
||||
CastPartySwiftmendAction(PlayerbotAI* ai) : HealPartyMemberAction(ai, "swiftmend") {}
|
||||
CastPartySwiftmendAction(PlayerbotAI* ai) : HealPartyMemberAction(ai, "swiftmend", 15.0f, HealingManaEfficiency::MEDIUM) {}
|
||||
};
|
||||
|
||||
class CastPartyNourishAction : public HealPartyMemberAction
|
||||
{
|
||||
public:
|
||||
CastPartyNourishAction(PlayerbotAI* ai) : HealPartyMemberAction(ai, "nourish") {}
|
||||
CastPartyNourishAction(PlayerbotAI* ai) : HealPartyMemberAction(ai, "nourish", 25.0f, HealingManaEfficiency::LOW) {}
|
||||
};
|
||||
|
||||
class CastDruidRemoveCurseOnPartyAction : public CurePartyMemberAction
|
||||
|
||||
@@ -5,83 +5,122 @@
|
||||
#include "ConserveManaStrategy.h"
|
||||
#include "GenericSpellActions.h"
|
||||
#include "LastSpellCastValue.h"
|
||||
#include "PlayerbotAIConfig.h"
|
||||
#include "Playerbots.h"
|
||||
|
||||
float ConserveManaMultiplier::GetValue(Action* action)
|
||||
// float ConserveManaMultiplier::GetValue(Action* action)
|
||||
// {
|
||||
// if (!action)
|
||||
// return 1.0f;
|
||||
|
||||
// uint8 health = AI_VALUE2(uint8, "health", "self target");
|
||||
// uint8 targetHealth = AI_VALUE2(uint8, "health", "current target");
|
||||
// uint8 mana = AI_VALUE2(uint8, "mana", "self target");
|
||||
// bool hasMana = AI_VALUE2(bool, "has mana", "self target");
|
||||
// bool mediumMana = hasMana && mana < sPlayerbotAIConfig->mediumMana;
|
||||
|
||||
// if (health < sPlayerbotAIConfig->lowHealth)
|
||||
// return 1.0f;
|
||||
|
||||
// Unit* target = AI_VALUE(Unit*, "current target");
|
||||
// if (action->GetTarget() != target)
|
||||
// return 1.0f;
|
||||
|
||||
// CastSpellAction* spellAction = dynamic_cast<CastSpellAction*>(action);
|
||||
// if (!spellAction)
|
||||
// return 1.0f;
|
||||
|
||||
// std::string const spell = spellAction->getName();
|
||||
// uint32 spellId = AI_VALUE2(uint32, "spell id", spell);
|
||||
// SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId);
|
||||
// if (!spellInfo || spellInfo->PowerType != POWER_MANA)
|
||||
// return 1.0f;
|
||||
|
||||
// if (mediumMana && dynamic_cast<CastBuffSpellAction*>(action))
|
||||
// return 0.0f;
|
||||
|
||||
// if (target && ((int)target->getLevel() - (int)bot->getLevel()) >= 0)
|
||||
// return 1.0f;
|
||||
|
||||
// return 1.0f;
|
||||
// }
|
||||
|
||||
// float SaveManaMultiplier::GetValue(Action* action)
|
||||
// {
|
||||
// if (!action)
|
||||
// return 1.0f;
|
||||
|
||||
// if (action->GetTarget() != AI_VALUE(Unit*, "current target"))
|
||||
// return 1.0f;
|
||||
|
||||
// double saveLevel = AI_VALUE(double, "mana save level");
|
||||
// if (saveLevel <= 1.0)
|
||||
// return 1.0f;
|
||||
|
||||
// CastSpellAction* spellAction = dynamic_cast<CastSpellAction*>(action);
|
||||
// if (!spellAction)
|
||||
// return 1.0f;
|
||||
|
||||
// std::string const spell = spellAction->getName();
|
||||
// uint32 spellId = AI_VALUE2(uint32, "spell id", spell);
|
||||
// SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId);
|
||||
// if (!spellInfo || spellInfo->PowerType != POWER_MANA)
|
||||
// return 1.0f;
|
||||
|
||||
// int32 cost = spellInfo->ManaCost;
|
||||
// if (!cost)
|
||||
// return 1.0f;
|
||||
|
||||
// time_t lastCastTime = AI_VALUE2(time_t, "last spell cast time", spell);
|
||||
// if (!lastCastTime)
|
||||
// return 1.0f;
|
||||
|
||||
// time_t elapsed = time(nullptr) - lastCastTime;
|
||||
// if ((double)elapsed < 10 * saveLevel)
|
||||
// return 0.0f;
|
||||
|
||||
// return 1.0f;
|
||||
// }
|
||||
|
||||
// void ConserveManaStrategy::InitMultipliers(std::vector<Multiplier*>& multipliers)
|
||||
// {
|
||||
// multipliers.push_back(new ConserveManaMultiplier(botAI));
|
||||
// }
|
||||
|
||||
float HealerAutoSaveManaMultiplier::GetValue(Action* action)
|
||||
{
|
||||
if (!action)
|
||||
uint8 mana = bot->GetPowerPct(Powers::POWER_MANA);
|
||||
if (mana > sPlayerbotAIConfig->saveManaThreshold)
|
||||
return 1.0f;
|
||||
CastHealingSpellAction* healingAction = dynamic_cast<CastHealingSpellAction*>(action);
|
||||
|
||||
if (!healingAction)
|
||||
return 1.0f;
|
||||
|
||||
uint8 health = AI_VALUE2(uint8, "health", "self target");
|
||||
uint8 targetHealth = AI_VALUE2(uint8, "health", "current target");
|
||||
uint8 mana = AI_VALUE2(uint8, "mana", "self target");
|
||||
bool hasMana = AI_VALUE2(bool, "has mana", "self target");
|
||||
bool mediumMana = hasMana && mana < sPlayerbotAIConfig->mediumMana;
|
||||
|
||||
if (health < sPlayerbotAIConfig->lowHealth)
|
||||
Unit* target = healingAction->GetTarget();
|
||||
if (!target)
|
||||
return 1.0f;
|
||||
|
||||
Unit* target = AI_VALUE(Unit*, "current target");
|
||||
if (action->GetTarget() != target)
|
||||
return 1.0f;
|
||||
|
||||
CastSpellAction* spellAction = dynamic_cast<CastSpellAction*>(action);
|
||||
if (!spellAction)
|
||||
return 1.0f;
|
||||
|
||||
std::string const spell = spellAction->getName();
|
||||
uint32 spellId = AI_VALUE2(uint32, "spell id", spell);
|
||||
SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId);
|
||||
if (!spellInfo || spellInfo->PowerType != POWER_MANA)
|
||||
return 1.0f;
|
||||
|
||||
if (mediumMana && dynamic_cast<CastBuffSpellAction*>(action))
|
||||
return 0.0f;
|
||||
|
||||
if (target && ((int)target->getLevel() - (int)bot->getLevel()) >= 0)
|
||||
return 1.0f;
|
||||
|
||||
bool isTank = target->ToPlayer() ? botAI->IsTank(target->ToPlayer()) : false;
|
||||
uint8 health = target->GetHealthPct();
|
||||
HealingManaEfficiency manaEfficiency = healingAction->manaEfficiency;
|
||||
uint8 estAmount = healingAction->estAmount;
|
||||
uint8 lossAmount = 100 - health;
|
||||
if (isTank) {
|
||||
estAmount /= 1.5; // tanks have more health
|
||||
if (health >= sPlayerbotAIConfig->mediumHealth && (lossAmount < estAmount || manaEfficiency <= HealingManaEfficiency::MEDIUM))
|
||||
return 0.0f;
|
||||
if (health >= sPlayerbotAIConfig->lowHealth && (lossAmount < estAmount || manaEfficiency <= HealingManaEfficiency::LOW))
|
||||
return 0.0f;
|
||||
} else {
|
||||
if (health >= sPlayerbotAIConfig->mediumHealth && (lossAmount < estAmount || manaEfficiency <= HealingManaEfficiency::MEDIUM))
|
||||
return 0.0f;
|
||||
if (lossAmount < estAmount || manaEfficiency <= HealingManaEfficiency::LOW)
|
||||
return 0.0f;
|
||||
}
|
||||
return 1.0f;
|
||||
}
|
||||
|
||||
float SaveManaMultiplier::GetValue(Action* action)
|
||||
void HealerAutoSaveManaStrategy::InitMultipliers(std::vector<Multiplier*>& multipliers)
|
||||
{
|
||||
if (!action)
|
||||
return 1.0f;
|
||||
|
||||
if (action->GetTarget() != AI_VALUE(Unit*, "current target"))
|
||||
return 1.0f;
|
||||
|
||||
double saveLevel = AI_VALUE(double, "mana save level");
|
||||
if (saveLevel <= 1.0)
|
||||
return 1.0f;
|
||||
|
||||
CastSpellAction* spellAction = dynamic_cast<CastSpellAction*>(action);
|
||||
if (!spellAction)
|
||||
return 1.0f;
|
||||
|
||||
std::string const spell = spellAction->getName();
|
||||
uint32 spellId = AI_VALUE2(uint32, "spell id", spell);
|
||||
SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId);
|
||||
if (!spellInfo || spellInfo->PowerType != POWER_MANA)
|
||||
return 1.0f;
|
||||
|
||||
int32 cost = spellInfo->ManaCost;
|
||||
if (!cost)
|
||||
return 1.0f;
|
||||
|
||||
time_t lastCastTime = AI_VALUE2(time_t, "last spell cast time", spell);
|
||||
if (!lastCastTime)
|
||||
return 1.0f;
|
||||
|
||||
time_t elapsed = time(nullptr) - lastCastTime;
|
||||
if ((double)elapsed < 10 * saveLevel)
|
||||
return 0.0f;
|
||||
|
||||
return 1.0f;
|
||||
}
|
||||
|
||||
void ConserveManaStrategy::InitMultipliers(std::vector<Multiplier*>& multipliers)
|
||||
{
|
||||
multipliers.push_back(new ConserveManaMultiplier(botAI));
|
||||
multipliers.push_back(new HealerAutoSaveManaMultiplier(botAI));
|
||||
}
|
||||
@@ -9,29 +9,57 @@
|
||||
|
||||
class PlayerbotAI;
|
||||
|
||||
class ConserveManaMultiplier : public Multiplier
|
||||
// Yunfan: deprecate old save mana method.
|
||||
|
||||
// class ConserveManaMultiplier : public Multiplier
|
||||
// {
|
||||
// public:
|
||||
// ConserveManaMultiplier(PlayerbotAI* botAI) : Multiplier(botAI, "conserve mana") { }
|
||||
|
||||
// float GetValue(Action* action) override;
|
||||
// };
|
||||
|
||||
// class SaveManaMultiplier : public Multiplier
|
||||
// {
|
||||
// public:
|
||||
// SaveManaMultiplier(PlayerbotAI* botAI) : Multiplier(botAI, "save mana") { }
|
||||
|
||||
// float GetValue(Action* action) override;
|
||||
// };
|
||||
|
||||
// class ConserveManaStrategy : public Strategy
|
||||
// {
|
||||
// public:
|
||||
// ConserveManaStrategy(PlayerbotAI* botAI) : Strategy(botAI) { }
|
||||
|
||||
// void InitMultipliers(std::vector<Multiplier*>& multipliers) override;
|
||||
// std::string const getName() override { return "conserve mana"; }
|
||||
// };
|
||||
|
||||
// class HealerSaveManaStrategy : public Strategy
|
||||
// {
|
||||
// public:
|
||||
// HealerSaveManaStrategy(PlayerbotAI* botAI) : Strategy(botAI) { }
|
||||
|
||||
// void InitMultipliers(std::vector<Multiplier*>& multipliers) override;
|
||||
// std::string const getName() override { return "healer save mana"; }
|
||||
// };
|
||||
|
||||
class HealerAutoSaveManaMultiplier : public Multiplier
|
||||
{
|
||||
public:
|
||||
ConserveManaMultiplier(PlayerbotAI* botAI) : Multiplier(botAI, "conserve mana") { }
|
||||
HealerAutoSaveManaMultiplier(PlayerbotAI* botAI) : Multiplier(botAI, "auto save mana") { }
|
||||
|
||||
float GetValue(Action* action) override;
|
||||
};
|
||||
|
||||
class SaveManaMultiplier : public Multiplier
|
||||
class HealerAutoSaveManaStrategy : public Strategy
|
||||
{
|
||||
public:
|
||||
SaveManaMultiplier(PlayerbotAI* botAI) : Multiplier(botAI, "save mana") { }
|
||||
|
||||
float GetValue(Action* action) override;
|
||||
};
|
||||
|
||||
class ConserveManaStrategy : public Strategy
|
||||
{
|
||||
public:
|
||||
ConserveManaStrategy(PlayerbotAI* botAI) : Strategy(botAI) { }
|
||||
HealerAutoSaveManaStrategy(PlayerbotAI* botAI) : Strategy(botAI) { }
|
||||
|
||||
void InitMultipliers(std::vector<Multiplier*>& multipliers) override;
|
||||
std::string const getName() override { return "conserve mana"; }
|
||||
std::string const getName() override { return "auto save mana"; }
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -39,7 +39,6 @@ BUFF_ACTION(CastCrusaderAuraAction, "crusader aura");
|
||||
BUFF_ACTION(CastSanctityAuraAction, "sanctity aura");
|
||||
|
||||
SPELL_ACTION(CastHolyShockAction, "holy shock");
|
||||
HEAL_PARTY_ACTION(CastHolyShockOnPartyAction, "holy shock");
|
||||
|
||||
// consecration
|
||||
MELEE_ACTION(CastConsecrationAction, "consecration");
|
||||
@@ -168,10 +167,16 @@ class CastHolyLightAction : public CastHealingSpellAction
|
||||
CastHolyLightAction(PlayerbotAI* botAI) : CastHealingSpellAction(botAI, "holy light") { }
|
||||
};
|
||||
|
||||
class CastHolyShockOnPartyAction : public HealPartyMemberAction
|
||||
{
|
||||
public:
|
||||
CastHolyShockOnPartyAction(PlayerbotAI* botAI) : HealPartyMemberAction(botAI, "holy shock", 25.0f, HealingManaEfficiency::MEDIUM) { }
|
||||
};
|
||||
|
||||
class CastHolyLightOnPartyAction : public HealPartyMemberAction
|
||||
{
|
||||
public:
|
||||
CastHolyLightOnPartyAction(PlayerbotAI* botAI) : HealPartyMemberAction(botAI, "holy light") { }
|
||||
CastHolyLightOnPartyAction(PlayerbotAI* botAI) : HealPartyMemberAction(botAI, "holy light", 50.0f, HealingManaEfficiency::HIGH) { }
|
||||
};
|
||||
|
||||
class CastFlashOfLightAction : public CastHealingSpellAction
|
||||
@@ -183,7 +188,7 @@ class CastFlashOfLightAction : public CastHealingSpellAction
|
||||
class CastFlashOfLightOnPartyAction : public HealPartyMemberAction
|
||||
{
|
||||
public:
|
||||
CastFlashOfLightOnPartyAction(PlayerbotAI* botAI) : HealPartyMemberAction(botAI, "flash of light") { }
|
||||
CastFlashOfLightOnPartyAction(PlayerbotAI* botAI) : HealPartyMemberAction(botAI, "flash of light", 15.0f, HealingManaEfficiency::LOW) { }
|
||||
};
|
||||
|
||||
class CastLayOnHandsAction : public CastHealingSpellAction
|
||||
|
||||
@@ -39,12 +39,12 @@ Unit* CastPowerWordShieldOnAlmostFullHealthBelow::GetTarget()
|
||||
if (player->GetDistance2d(bot) > sPlayerbotAIConfig->spellDistance) {
|
||||
continue;
|
||||
}
|
||||
if (botAI->HasAnyAuraOf(player, "weakened soul", "power word: shield", NULL)) {
|
||||
if (botAI->HasAnyAuraOf(player, "weakened soul", "power word: shield", nullptr)) {
|
||||
continue;
|
||||
}
|
||||
return player;
|
||||
}
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool CastPowerWordShieldOnAlmostFullHealthBelow::isUseful()
|
||||
@@ -64,7 +64,7 @@ bool CastPowerWordShieldOnAlmostFullHealthBelow::isUseful()
|
||||
if (player->GetDistance2d(bot) > sPlayerbotAIConfig->spellDistance) {
|
||||
continue;
|
||||
}
|
||||
if (botAI->HasAnyAuraOf(player, "weakened soul", "power word: shield", NULL)) {
|
||||
if (botAI->HasAnyAuraOf(player, "weakened soul", "power word: shield", nullptr)) {
|
||||
continue;
|
||||
}
|
||||
return true;
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#define _PLAYERBOT_PRIESTACTIONS_H
|
||||
|
||||
#include "GenericSpellActions.h"
|
||||
#include "PlayerbotAIConfig.h"
|
||||
#include "Playerbots.h"
|
||||
|
||||
class PlayerbotAI;
|
||||
@@ -15,7 +16,7 @@ BUFF_ACTION(CastPowerWordFortitudeAction, "power word: fortitude");
|
||||
BUFF_PARTY_ACTION(CastPowerWordFortitudeOnPartyAction, "power word: fortitude");
|
||||
BUFF_PARTY_ACTION(CastPrayerOfFortitudeOnPartyAction, "prayer of fortitude");
|
||||
BUFF_ACTION(CastPowerWordShieldAction, "power word: shield");
|
||||
HEAL_PARTY_ACTION(CastPowerWordShieldOnPartyAction, "power word: shield");
|
||||
|
||||
BUFF_ACTION(CastInnerFireAction, "inner fire");
|
||||
CURE_ACTION(CastDispelMagicAction, "dispel magic");
|
||||
CURE_PARTY_ACTION(CastDispelMagicOnPartyAction, "dispel magic", DISPEL_MAGIC);
|
||||
@@ -39,22 +40,21 @@ PROTECT_ACTION(CastPainSuppressionProtectAction, "pain suppression");
|
||||
|
||||
// holy
|
||||
HEAL_ACTION(CastLesserHealAction, "lesser heal");
|
||||
HEAL_PARTY_ACTION(CastLesserHealOnPartyAction, "lesser heal");
|
||||
HEAL_ACTION(CastHealAction, "heal");
|
||||
HEAL_PARTY_ACTION(CastHealOnPartyAction, "heal");
|
||||
HEAL_ACTION(CastGreaterHealAction, "greater heal");
|
||||
HEAL_PARTY_ACTION(CastGreaterHealOnPartyAction, "greater heal");
|
||||
HEAL_ACTION(CastFlashHealAction, "flash heal");
|
||||
HEAL_PARTY_ACTION(CastFlashHealOnPartyAction, "flash heal");
|
||||
HEAL_ACTION(CastRenewAction, "renew");
|
||||
HEAL_PARTY_ACTION(CastRenewOnPartyAction, "renew");
|
||||
// holy 2.4.3
|
||||
HEAL_PARTY_ACTION(CastPrayerOfMendingAction, "prayer of mending");
|
||||
HEAL_PARTY_ACTION(CastBindingHealAction, "binding heal");
|
||||
|
||||
HEAL_PARTY_ACTION(CastPrayerOfHealingAction, "prayer of healing");
|
||||
AOE_HEAL_ACTION(CastLightwellAction, "lightwell");
|
||||
AOE_HEAL_ACTION(CastCircleOfHealingAction, "circle of healing");
|
||||
HEAL_PARTY_ACTION(CastLesserHealOnPartyAction, "lesser heal", 50.0f, HealingManaEfficiency::MEDIUM);
|
||||
HEAL_PARTY_ACTION(CastHealOnPartyAction, "heal", 50.0f, HealingManaEfficiency::MEDIUM);
|
||||
HEAL_PARTY_ACTION(CastGreaterHealOnPartyAction, "greater heal", 50.0f, HealingManaEfficiency::MEDIUM);
|
||||
HEAL_PARTY_ACTION(CastPowerWordShieldOnPartyAction, "power word: shield", 15.0f, HealingManaEfficiency::VERY_HIGH);
|
||||
HEAL_PARTY_ACTION(CastFlashHealOnPartyAction, "flash heal", 15.0f, HealingManaEfficiency::LOW);
|
||||
HEAL_PARTY_ACTION(CastRenewOnPartyAction, "renew", 15.0f, HealingManaEfficiency::VERY_HIGH);
|
||||
HEAL_PARTY_ACTION(CastPrayerOfMendingAction, "prayer of mending", 15.0f, HealingManaEfficiency::MEDIUM);
|
||||
HEAL_PARTY_ACTION(CastBindingHealAction, "binding heal", 15.0f, HealingManaEfficiency::MEDIUM);
|
||||
HEAL_PARTY_ACTION(CastPrayerOfHealingAction, "prayer of healing", 15.0f, HealingManaEfficiency::MEDIUM);
|
||||
AOE_HEAL_ACTION(CastCircleOfHealingAction, "circle of healing", 15.0f, HealingManaEfficiency::HIGH);
|
||||
AOE_HEAL_ACTION(CastLightwellAction, "lightwell", 15.0f, HealingManaEfficiency::MEDIUM);
|
||||
|
||||
SPELL_ACTION(CastSmiteAction, "smite");
|
||||
SPELL_ACTION(CastHolyNovaAction, "holy nova");
|
||||
@@ -126,7 +126,7 @@ public:
|
||||
class CastPenanceOnPartyAction : public HealPartyMemberAction
|
||||
{
|
||||
public:
|
||||
CastPenanceOnPartyAction(PlayerbotAI* ai) : HealPartyMemberAction(ai, "penance") {}
|
||||
CastPenanceOnPartyAction(PlayerbotAI* ai) : HealPartyMemberAction(ai, "penance", 25.0f, HealingManaEfficiency::HIGH) {}
|
||||
};
|
||||
|
||||
class CastHymnOfHopeAction : public CastSpellAction
|
||||
@@ -152,7 +152,7 @@ public:
|
||||
|
||||
class CastPowerWordShieldOnAlmostFullHealthBelow : public HealPartyMemberAction {
|
||||
public:
|
||||
CastPowerWordShieldOnAlmostFullHealthBelow(PlayerbotAI* ai) : HealPartyMemberAction(ai, "power word: shield") {}
|
||||
CastPowerWordShieldOnAlmostFullHealthBelow(PlayerbotAI* ai) : HealPartyMemberAction(ai, "power word: shield", 15.0f, HealingManaEfficiency::HIGH) {}
|
||||
bool isUseful() override;
|
||||
Unit* GetTarget() override;
|
||||
};
|
||||
|
||||
@@ -18,7 +18,6 @@ class GenericShamanStrategyActionNodeFactory : public NamedObjectFactory<ActionN
|
||||
creators["lesser healing wave on party"] = &lesser_healing_wave_on_party;
|
||||
creators["chain heal"] = &chain_heal;
|
||||
creators["riptide"] = &riptide;
|
||||
creators["chain heal on party"] = &chain_heal_on_party;
|
||||
creators["riptide on party"] = &riptide_on_party;
|
||||
creators["earth shock"] = &earth_shock;
|
||||
}
|
||||
@@ -88,14 +87,6 @@ class GenericShamanStrategyActionNodeFactory : public NamedObjectFactory<ActionN
|
||||
/*C*/ nullptr);
|
||||
}
|
||||
|
||||
static ActionNode* chain_heal_on_party([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode ("chain heal on party",
|
||||
/*P*/ nullptr,
|
||||
/*A*/ NextAction::array(0, new NextAction("lesser healing wave on party"), nullptr),
|
||||
/*C*/ nullptr);
|
||||
}
|
||||
|
||||
static ActionNode* riptide_on_party([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode ("riptide on party",
|
||||
|
||||
@@ -21,7 +21,7 @@ class CastLesserHealingWaveAction : public CastHealingSpellAction
|
||||
class CastLesserHealingWaveOnPartyAction : public HealPartyMemberAction
|
||||
{
|
||||
public:
|
||||
CastLesserHealingWaveOnPartyAction(PlayerbotAI* botAI) : HealPartyMemberAction(botAI, "lesser healing wave") { }
|
||||
CastLesserHealingWaveOnPartyAction(PlayerbotAI* botAI) : HealPartyMemberAction(botAI, "lesser healing wave", 25.0f, HealingManaEfficiency::LOW) { }
|
||||
};
|
||||
|
||||
class CastHealingWaveAction : public CastHealingSpellAction
|
||||
@@ -33,13 +33,13 @@ class CastHealingWaveAction : public CastHealingSpellAction
|
||||
class CastHealingWaveOnPartyAction : public HealPartyMemberAction
|
||||
{
|
||||
public:
|
||||
CastHealingWaveOnPartyAction(PlayerbotAI* botAI) : HealPartyMemberAction(botAI, "healing wave") { }
|
||||
CastHealingWaveOnPartyAction(PlayerbotAI* botAI) : HealPartyMemberAction(botAI, "healing wave", 50.0f, HealingManaEfficiency::MEDIUM) { }
|
||||
};
|
||||
|
||||
class CastChainHealAction : public CastAoeHealSpellAction
|
||||
{
|
||||
public:
|
||||
CastChainHealAction(PlayerbotAI* botAI) : CastAoeHealSpellAction(botAI, "chain heal") { }
|
||||
CastChainHealAction(PlayerbotAI* botAI) : CastAoeHealSpellAction(botAI, "chain heal", 15.0f, HealingManaEfficiency::HIGH) { }
|
||||
};
|
||||
|
||||
class CastRiptideAction : public CastHealingSpellAction
|
||||
@@ -51,7 +51,7 @@ class CastRiptideAction : public CastHealingSpellAction
|
||||
class CastRiptideOnPartyAction : public HealPartyMemberAction
|
||||
{
|
||||
public:
|
||||
CastRiptideOnPartyAction(PlayerbotAI* botAI) : HealPartyMemberAction(botAI, "riptide") { }
|
||||
CastRiptideOnPartyAction(PlayerbotAI* botAI) : HealPartyMemberAction(botAI, "riptide", 15.0f, HealingManaEfficiency::VERY_HIGH) { }
|
||||
};
|
||||
|
||||
class CastEarthShieldAction : public CastBuffSpellAction
|
||||
|
||||
@@ -91,7 +91,7 @@ class CasterFindTargetSmartStrategy : public FindTargetStrategy
|
||||
return true;
|
||||
}
|
||||
int32_t level = GetIntervalLevel(new_unit);
|
||||
if (level % 10 == 2 || level % 10 == 0) {
|
||||
if (level % 10 == 2 || level % 10 == 1) {
|
||||
return new_time < old_time;
|
||||
}
|
||||
// dont switch targets when all of them with low health
|
||||
@@ -110,10 +110,10 @@ class CasterFindTargetSmartStrategy : public FindTargetStrategy
|
||||
float attackRange = botAI->IsRanged(botAI->GetBot()) ? sPlayerbotAIConfig->spellDistance : sPlayerbotAIConfig->meleeDistance;
|
||||
attackRange += 5.0f;
|
||||
int level = dis < attackRange ? 10 : 0;
|
||||
if (time >= 5 && time <= 20) {
|
||||
if (time >= 3 && time <= 20) {
|
||||
return level + 2;
|
||||
}
|
||||
if (time < 5) {
|
||||
if (time > 20) {
|
||||
return level + 1;
|
||||
}
|
||||
return level;
|
||||
|
||||
Reference in New Issue
Block a user