Misdirection and tricks of the trade

This commit is contained in:
Yunfan Li
2024-09-04 20:08:44 +08:00
parent 484a2ae458
commit 406949f6dd
8 changed files with 34 additions and 6 deletions

View File

@@ -724,14 +724,14 @@ std::string const PlayerbotHolder::ProcessBotCommand(std::string const cmd, Obje
sPlayerbotAIConfig->autoInitEquipLevelLimitRatio; sPlayerbotAIConfig->autoInitEquipLevelLimitRatio;
PlayerbotFactory factory(bot, master->GetLevel(), ITEM_QUALITY_LEGENDARY, mixedGearScore); PlayerbotFactory factory(bot, master->GetLevel(), ITEM_QUALITY_LEGENDARY, mixedGearScore);
factory.Randomize(false); factory.Randomize(false);
return "ok, gear score limit: " + std::to_string(mixedGearScore / (ITEM_QUALITY_EPIC + 1)) + return "ok, gear score limit: " + std::to_string(mixedGearScore / PlayerbotAI::GetItemScoreMultiplier(ItemQualities(ITEM_QUALITY_EPIC))) +
"(for epic)"; "(for epic)";
} }
else if (cmd.starts_with("init=") && sscanf(cmd.c_str(), "init=%d", &gs) != -1) else if (cmd.starts_with("init=") && sscanf(cmd.c_str(), "init=%d", &gs) != -1)
{ {
PlayerbotFactory factory(bot, master->GetLevel(), ITEM_QUALITY_LEGENDARY, gs); PlayerbotFactory factory(bot, master->GetLevel(), ITEM_QUALITY_LEGENDARY, gs);
factory.Randomize(false); factory.Randomize(false);
return "ok, gear score limit: " + std::to_string(gs / (ITEM_QUALITY_EPIC + 1)) + "(for epic)"; return "ok, gear score limit: " + std::to_string(gs / PlayerbotAI::GetItemScoreMultiplier(ItemQualities(ITEM_QUALITY_EPIC))) + "(for epic)";
} }
} }

View File

@@ -45,7 +45,7 @@ NextAction** DpsHunterStrategy::getDefaultActions()
new NextAction("explosive shot", ACTION_DEFAULT + 0.6f), new NextAction("aimed shot", ACTION_DEFAULT + 0.5f), new NextAction("explosive shot", ACTION_DEFAULT + 0.6f), new NextAction("aimed shot", ACTION_DEFAULT + 0.5f),
new NextAction("silencing shot", ACTION_DEFAULT + 0.4f), new NextAction("silencing shot", ACTION_DEFAULT + 0.4f),
new NextAction("kill command", ACTION_DEFAULT + 0.3f), new NextAction("kill command", ACTION_DEFAULT + 0.3f),
new NextAction("arcane shot", ACTION_DEFAULT + 0.2f), // new NextAction("arcane shot", ACTION_DEFAULT + 0.2f),
new NextAction("steady shot", ACTION_DEFAULT + 0.1f), new NextAction("steady shot", ACTION_DEFAULT + 0.1f),
new NextAction("auto shot", ACTION_DEFAULT), nullptr); new NextAction("auto shot", ACTION_DEFAULT), nullptr);
} }

View File

@@ -95,7 +95,7 @@ void GenericHunterStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
triggers.push_back(new TriggerNode("enemy too close for auto shot", triggers.push_back(new TriggerNode("enemy too close for auto shot",
NextAction::array(0, new NextAction("flee", ACTION_MOVE + 9), nullptr))); NextAction::array(0, new NextAction("flee", ACTION_MOVE + 9), nullptr)));
triggers.push_back( triggers.push_back(
new TriggerNode("misdirection on main tank", new TriggerNode("low tank threat",
NextAction::array(0, new NextAction("misdirection on main tank", ACTION_HIGH + 7), NULL))); NextAction::array(0, new NextAction("misdirection on main tank", ACTION_HIGH + 7), NULL)));
triggers.push_back( triggers.push_back(
new TriggerNode("low health", NextAction::array(0, new NextAction("deterrence", ACTION_HIGH + 5), nullptr))); new TriggerNode("low health", NextAction::array(0, new NextAction("deterrence", ACTION_HIGH + 5), nullptr)));

View File

@@ -83,7 +83,7 @@ void AssassinationRogueStrategy::InitTriggers(std::vector<TriggerNode*>& trigger
new TriggerNode("medium aoe", NextAction::array(0, new NextAction("fan of knives", ACTION_NORMAL + 5), NULL))); new TriggerNode("medium aoe", NextAction::array(0, new NextAction("fan of knives", ACTION_NORMAL + 5), NULL)));
triggers.push_back(new TriggerNode( triggers.push_back(new TriggerNode(
"tricks of the trade on main tank", "low tank threat",
NextAction::array(0, new NextAction("tricks of the trade on main tank", ACTION_HIGH + 7), NULL))); NextAction::array(0, new NextAction("tricks of the trade on main tank", ACTION_HIGH + 7), NULL)));
triggers.push_back(new TriggerNode( triggers.push_back(new TriggerNode(

View File

@@ -141,7 +141,7 @@ void DpsRogueStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
NextAction::array(0, new NextAction("expose armor", ACTION_HIGH + 3), nullptr))); NextAction::array(0, new NextAction("expose armor", ACTION_HIGH + 3), nullptr)));
triggers.push_back(new TriggerNode( triggers.push_back(new TriggerNode(
"tricks of the trade on main tank", "low tank threat",
NextAction::array(0, new NextAction("tricks of the trade on main tank", ACTION_HIGH + 7), nullptr))); NextAction::array(0, new NextAction("tricks of the trade on main tank", ACTION_HIGH + 7), nullptr)));
} }

View File

@@ -14,6 +14,7 @@
#include "Playerbots.h" #include "Playerbots.h"
#include "SharedDefines.h" #include "SharedDefines.h"
#include "TemporarySummon.h" #include "TemporarySummon.h"
#include "ThreatMgr.h"
#include "Timer.h" #include "Timer.h"
bool LowManaTrigger::IsActive() bool LowManaTrigger::IsActive()
@@ -185,6 +186,22 @@ bool MyAttackerCountTrigger::IsActive()
return AI_VALUE2(bool, "combat", "self target") && AI_VALUE(uint8, "my attacker count") >= amount; return AI_VALUE2(bool, "combat", "self target") && AI_VALUE(uint8, "my attacker count") >= amount;
} }
bool LowTankThreatTrigger::IsActive()
{
Unit* mt = AI_VALUE(Unit*, "main tank");
if (!mt)
return false;
Unit* current_target = AI_VALUE(Unit*, "current target");
if (!current_target)
return false;
ThreatMgr& mgr = current_target->GetThreatMgr();
float threat = mgr.GetThreat(bot);
float tankThreat = mgr.GetThreat(mt);
return tankThreat == 0.0f || threat > tankThreat * 0.5f;
}
bool AoeTrigger::IsActive() bool AoeTrigger::IsActive()
{ {
Unit* current_target = AI_VALUE(Unit*, "current target"); Unit* current_target = AI_VALUE(Unit*, "current target");

View File

@@ -10,6 +10,7 @@
#include "HealthTriggers.h" #include "HealthTriggers.h"
#include "RangeTriggers.h" #include "RangeTriggers.h"
#include "Trigger.h"
class PlayerbotAI; class PlayerbotAI;
class Unit; class Unit;
@@ -248,6 +249,13 @@ public:
MediumThreatTrigger(PlayerbotAI* botAI) : MyAttackerCountTrigger(botAI, 2) {} MediumThreatTrigger(PlayerbotAI* botAI) : MyAttackerCountTrigger(botAI, 2) {}
}; };
class LowTankThreatTrigger : public Trigger
{
public:
LowTankThreatTrigger(PlayerbotAI* botAI) : Trigger(botAI, "low tank threat") {}
bool IsActive() override;
};
class AoeTrigger : public AttackerCountTrigger class AoeTrigger : public AttackerCountTrigger
{ {
public: public:

View File

@@ -102,6 +102,7 @@ public:
creators["combo points not full and high energy"] = &TriggerContext::ComboPointsNotFullAndHighEnergy; creators["combo points not full and high energy"] = &TriggerContext::ComboPointsNotFullAndHighEnergy;
creators["medium threat"] = &TriggerContext::MediumThreat; creators["medium threat"] = &TriggerContext::MediumThreat;
creators["low tank threat"] = &TriggerContext::low_tank_threat;
creators["dead"] = &TriggerContext::Dead; creators["dead"] = &TriggerContext::Dead;
creators["corpse near"] = &TriggerContext::corpse_near; creators["corpse near"] = &TriggerContext::corpse_near;
@@ -321,6 +322,8 @@ private:
static Trigger* ComboPointsNotFull(PlayerbotAI* botAI) { return new ComboPointsNotFullTrigger(botAI); } static Trigger* ComboPointsNotFull(PlayerbotAI* botAI) { return new ComboPointsNotFullTrigger(botAI); }
static Trigger* ComboPointsNotFullAndHighEnergy(PlayerbotAI* botAI) { return new TwoTriggers(botAI, "combo points not full", "high energy available"); } static Trigger* ComboPointsNotFullAndHighEnergy(PlayerbotAI* botAI) { return new TwoTriggers(botAI, "combo points not full", "high energy available"); }
static Trigger* MediumThreat(PlayerbotAI* botAI) { return new MediumThreatTrigger(botAI); } static Trigger* MediumThreat(PlayerbotAI* botAI) { return new MediumThreatTrigger(botAI); }
static Trigger* low_tank_threat(PlayerbotAI* botAI) { return new LowTankThreatTrigger(botAI); }
// static Trigger* MediumThreat(PlayerbotAI* botAI) { return new MediumThreatTrigger(botAI); }
static Trigger* Dead(PlayerbotAI* botAI) { return new DeadTrigger(botAI); } static Trigger* Dead(PlayerbotAI* botAI) { return new DeadTrigger(botAI); }
static Trigger* corpse_near(PlayerbotAI* botAI) { return new CorpseNearTrigger(botAI); } static Trigger* corpse_near(PlayerbotAI* botAI) { return new CorpseNearTrigger(botAI); }
static Trigger* PartyMemberDead(PlayerbotAI* botAI) { return new PartyMemberDeadTrigger(botAI); } static Trigger* PartyMemberDead(PlayerbotAI* botAI) { return new PartyMemberDeadTrigger(botAI); }