Auto save mana strategy

This commit is contained in:
Yunfan Li
2024-03-23 18:11:46 +08:00
parent 68fdf57c3c
commit 5f31941820
18 changed files with 242 additions and 141 deletions

View File

@@ -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);
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)
if (!healingAction)
return 1.0f;
Unit* target = AI_VALUE(Unit*, "current target");
if (action->GetTarget() != target)
Unit* target = healingAction->GetTarget();
if (!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));
}

View File

@@ -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