Flee action, factory setting

This commit is contained in:
Yunfan Li
2023-05-29 11:45:18 +08:00
parent dc21fa9d41
commit 2ad567a1a8
22 changed files with 236 additions and 163 deletions

View File

@@ -482,12 +482,12 @@ AiPlayerbot.LootDelay = 1000
AiPlayerbot.FarDistance = 20.0
AiPlayerbot.SightDistance = 60.0
AiPlayerbot.SpellDistance = 26.0
AiPlayerbot.ShootDistance = 26.0
AiPlayerbot.ShootDistance = 5.0
AiPlayerbot.ReactDistance = 150.0
AiPlayerbot.GrindDistance = 75.0
AiPlayerbot.HealDistance = 20.0
AiPlayerbot.LootDistance = 15.0
AiPlayerbot.FleeDistance = 15.0
AiPlayerbot.FleeDistance = 5.0
AiPlayerbot.TooCloseDistance = 5.0
AiPlayerbot.MeleeDistance = 1.5
AiPlayerbot.FollowDistance = 1.5

View File

@@ -260,7 +260,7 @@ void AiFactory::AddDefaultCombatStrategies(Player* player, PlayerbotAI* const fa
if (!player->InBattleground())
{
engine->addStrategies("racials", "chat", "default", "potions", "cast time", "duel", nullptr);
engine->addStrategies("racials", "chat", "default", "cast time", "duel", nullptr);
}
switch (player->getClass())
@@ -270,16 +270,10 @@ void AiFactory::AddDefaultCombatStrategies(Player* player, PlayerbotAI* const fa
{
engine->addStrategies("dps", "shadow debuff", "shadow aoe", "threat", nullptr);
}
else if (tab == 0)
{
engine->addStrategies("holy", "shadow debuff", "shadow aoe", "threat", nullptr);
//if (player->getLevel() >= 4)
//engine->addStrategy("dps debuff");
}
else
engine->addStrategies("heal", "threat", nullptr);
engine->addStrategies("dps assist", "flee", "cure", "ranged", nullptr);
engine->addStrategies("dps assist", "cure", "ranged", nullptr);
break;
case CLASS_MAGE:
if (tab == 0)
@@ -289,7 +283,7 @@ void AiFactory::AddDefaultCombatStrategies(Player* player, PlayerbotAI* const fa
else
engine->addStrategies("frost", "frost aoe", "threat", "dps aoe", nullptr);
engine->addStrategies("dps", "dps assist", "flee", "cure", "ranged", nullptr);
engine->addStrategies("dps", "dps assist", "cure", "ranged", nullptr);
break;
case CLASS_WARRIOR:
if (tab == 2)
@@ -301,9 +295,9 @@ void AiFactory::AddDefaultCombatStrategies(Player* player, PlayerbotAI* const fa
break;
case CLASS_SHAMAN:
if (tab == 0)
engine->addStrategies("caster", "caster aoe", "bmana", "threat", "flee", "ranged", nullptr);
engine->addStrategies("caster", "caster aoe", "bmana", "threat", "ranged", nullptr);
else if (tab == 2)
engine->addStrategies("heal", "bmana", "flee", "ranged", nullptr);
engine->addStrategies("heal", "bmana", "ranged", nullptr);
else
engine->addStrategies("dps", "melee aoe", "bdps", "threat", "close", nullptr);
@@ -313,7 +307,7 @@ void AiFactory::AddDefaultCombatStrategies(Player* player, PlayerbotAI* const fa
if (tab == 1)
engine->addStrategies("tank", "tank assist", "bthreat", "cure", "baoe", "bstats", "close", nullptr);
else if (tab == 0)
engine->addStrategies("heal", "bmana", "dps assist", "cure", "flee", nullptr);
engine->addStrategies("heal", "bmana", "dps assist", "cure", nullptr);
else
engine->addStrategies("dps", "bdps", "dps assist", "cure", "close", nullptr);
@@ -330,21 +324,21 @@ void AiFactory::AddDefaultCombatStrategies(Player* player, PlayerbotAI* const fa
case CLASS_DRUID:
if (tab == 0)
{
engine->addStrategies("caster", "cure", "caster aoe", "threat", "flee", "dps assist", "ranged", nullptr);
engine->addStrategies("caster", "cure", "caster aoe", "threat", "dps assist", "ranged", nullptr);
if (player->getLevel() > 19)
engine->addStrategy("caster debuff");
}
else if (tab == 2)
engine->addStrategies("heal", "cure", "flee", "dps assist", "ranged", nullptr);
engine->addStrategies("heal", "cure", "dps assist", "ranged", nullptr);
else
{
engine->removeStrategy("ranged");
engine->removeStrategy("flee");
engine->addStrategies("bear", "tank assist", "flee", "close", nullptr);
engine->addStrategies("bear", "tank assist", "close", nullptr);
}
break;
case CLASS_HUNTER:
engine->addStrategies("dps", "bdps", "threat", "dps assist", "ranged", "pet", nullptr);
engine->addStrategies("dps", "aoe", "bdps", "threat", "dps assist", "ranged", nullptr);
if (player->getLevel() > 19)
engine->addStrategy("dps debuff");
break;
@@ -355,7 +349,7 @@ void AiFactory::AddDefaultCombatStrategies(Player* player, PlayerbotAI* const fa
if (player->getLevel() > 19)
engine->addStrategy("dps debuff");
engine->addStrategies("dps assist", "dps", "flee", "ranged", "pet", "threat", nullptr);
engine->addStrategies("dps assist", "dps", "aoe", "ranged", "pet", "threat", nullptr);
break;
case CLASS_DEATH_KNIGHT:
if (tab == 0)
@@ -365,7 +359,7 @@ void AiFactory::AddDefaultCombatStrategies(Player* player, PlayerbotAI* const fa
else
engine->addStrategies("unholy", "unholy aoe", "dps assist", "threat", nullptr);
engine->addStrategies("dps assist", "flee", "close", nullptr);
engine->addStrategies("dps assist", "close", nullptr);
break;
}
@@ -376,7 +370,7 @@ void AiFactory::AddDefaultCombatStrategies(Player* player, PlayerbotAI* const fa
{
engine->ChangeStrategy(sPlayerbotAIConfig->randomBotCombatStrategies);
engine->addStrategy("flee");
// engine->addStrategy("flee");
engine->addStrategy("boost");
if (player->getClass() == CLASS_WARLOCK)
@@ -493,7 +487,7 @@ void AiFactory::AddDefaultNonCombatStrategies(Player* player, PlayerbotAI* const
nonCombatEngine->addStrategies("barmor", nullptr);
break;
case CLASS_HUNTER:
nonCombatEngine->addStrategies("bdps", "dps assist", nullptr);
nonCombatEngine->addStrategies("bdps", "dps assist", "pet", nullptr);
break;
case CLASS_SHAMAN:
if (tab == 0 || tab == 2)

View File

@@ -1648,11 +1648,21 @@ bool PlayerbotAI::CanCastSpell(uint32 spellid, Unit* target, bool checkHasSpell,
if (pet->HasSpell(spellid))
return true;
if (checkHasSpell && !bot->HasSpell(spellid))
if (checkHasSpell && !bot->HasSpell(spellid)) {
if (!sPlayerbotAIConfig->logInGroupOnly || bot->GetGroup()) {
LOG_DEBUG("playerbots", "Can cast spell failed. Bot not has spell. - target name: {}, spellid: {}, bot name: {}",
target->GetName(), spellid, bot->GetName());
}
return false;
}
if (bot->HasSpellCooldown(spellid))
if (bot->HasSpellCooldown(spellid)) {
if (!sPlayerbotAIConfig->logInGroupOnly || bot->GetGroup()) {
LOG_DEBUG("playerbots", "Can cast spell failed. Spell not has cooldown. - target name: {}, spellid: {}, bot name: {}",
target->GetName(), spellid, bot->GetName());
}
return false;
}
SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellid);
if (!spellInfo)

View File

@@ -335,15 +335,7 @@ void PlayerbotFactory::Randomize(bool incremental)
pmo = sPerformanceMonitor->start(PERF_MON_RNDBOT, "PlayerbotFactory_Save");
LOG_INFO("playerbots", "Saving to DB...");
if (incremental)
{
uint32 money = bot->GetMoney();
bot->SetMoney(money + 1000 * sqrt(urand(1, level * 5)));
}
else
{
bot->SetMoney(10000 * sqrt(urand(1, level * 5)));
}
bot->SetMoney(urand(level * 100000, level * 5 * 100000));
bot->SaveToDB(false, false);
LOG_INFO("playerbots", "Done.");
if (pmo)
@@ -353,10 +345,25 @@ void PlayerbotFactory::Randomize(bool incremental)
void PlayerbotFactory::Refresh()
{
Prepare();
InitEquipment(true);
InitAmmo();
InitFood();
InitPotions();
InitReagents();
InitPotions();
InitTalents(true);
InitClassSpells();
InitAvailableSpells();
bot->DurabilityRepairAll(false, 1.0f, false);
uint32 money = urand(level * 1000, level * 5 * 1000);
if (bot->GetMoney() < money)
bot->SetMoney(money);
bot->SaveToDB(false, false);
// Prepare();
// InitAmmo();
// InitFood();
// InitPotions();
//bot->SaveToDB();
}
@@ -1731,12 +1738,13 @@ void PlayerbotFactory::SetRandomSkill(uint16 id)
uint32 maxValue = level * 5;
// do not let skill go beyond limit even if maxlevel > blizzlike
if (level > 60)
{
maxValue = (level + 10) * 5;
}
// if (level > 60)
// {
// maxValue = (level + 10) * 5;
// }
uint32 value = urand(maxValue - level, maxValue);
// uint32 value = urand(maxValue - level, maxValue);
uint32 value = maxValue;
uint32 curValue = bot->GetSkillValue(id);
uint16 step = bot->GetSkillValue(id) ? bot->GetSkillStep(id) : 1;

View File

@@ -3,6 +3,7 @@
*/
#include "CharacterPackets.h"
#include "Common.h"
#include "ObjectAccessor.h"
#include "ObjectMgr.h"
#include "PlayerbotMgr.h"
@@ -519,6 +520,10 @@ std::string const PlayerbotHolder::ProcessBotCommand(std::string const cmd, Obje
if (!bot)
return "bot not found";
if (!isRandomAccount || !isRandomBot) {
return "ERROR: You can not use this command on non-ramdom bot.";
}
if (Player* master = GET_PLAYERBOT_AI(bot)->GetMaster())
{
@@ -846,7 +851,7 @@ std::vector<std::string> PlayerbotHolder::HandlePlayerbotCommand(char const* arg
}
else if (master && member != master->GetGUID())
{
out << ProcessBotCommand(cmdStr, member, master->GetGUID(), master->GetSession()->GetSecurity() >= SEC_GAMEMASTER, master->GetSession()->GetAccountId(), master->GetGuildId());
out << ProcessBotCommand(cmdStr, member, master->GetGUID(), true, master->GetSession()->GetAccountId(), master->GetGuildId());
}
else if (!master)
{

View File

@@ -2195,7 +2195,7 @@ void RandomItemMgr::BuildAmmoCache()
uint32 RandomItemMgr::GetAmmo(uint32 level, uint32 subClass)
{
return ammoCache[(level - 1) / 10][subClass];
return ammoCache[level / 10][subClass];
}
void RandomItemMgr::BuildPotionCache()

View File

@@ -27,6 +27,16 @@ bool FollowAction::Execute(Event event)
moved = MoveTo(loc.GetMapId(), loc.GetPositionX(), loc.GetPositionY(), loc.GetPositionZ());
}
if (Pet* pet = bot->GetPet())
{
if (CreatureAI* creatureAI = ((Creature*)pet)->AI())
{
pet->SetReactState(REACT_PASSIVE);
pet->GetCharmInfo()->SetCommandState(COMMAND_FOLLOW);
pet->GetCharmInfo()->SetIsFollowing(true);
pet->AttackStop();
}
}
//if (moved)
//botAI->SetNextCheckDelay(sPlayerbotAIConfig->reactDelay);

View File

@@ -4,6 +4,7 @@
#include "MovementActions.h"
#include "MovementGenerator.h"
#include "PlayerbotAIConfig.h"
#include "TargetedMovementGenerator.h"
#include "Event.h"
#include "LastMovementValue.h"
@@ -1211,22 +1212,33 @@ void MovementAction::ClearIdleState()
context->GetValue<PositionMap&>("position")->Get()["random"].Reset();
}
bool MovementAction::MoveAway(Unit* target)
{
float angle = target->GetAngle(bot);
float dx = bot->GetPositionX() + cos(angle) * sPlayerbotAIConfig->fleeDistance;
float dy = bot->GetPositionY() + sin(angle) * sPlayerbotAIConfig->fleeDistance;
float dz = bot->GetPositionZ();
return MoveTo(target->GetMapId(), dx, dy, dz);
}
bool FleeAction::Execute(Event event)
{
return Flee(AI_VALUE(Unit*, "current target"));
// return Flee(AI_VALUE(Unit*, "current target"));
return MoveAway(AI_VALUE(Unit*, "current target"));
}
bool FleeWithPetAction::Execute(Event event)
{
// if (Pet* pet = bot->GetPet())
// {
// if (CreatureAI* creatureAI = ((Creature*)pet)->AI())
// {
// pet->SetReactState(REACT_PASSIVE);
// pet->GetCharmInfo()->SetCommandState(COMMAND_FOLLOW);
// pet->AttackStop();
// }
// }
if (Pet* pet = bot->GetPet())
{
if (CreatureAI* creatureAI = ((Creature*)pet)->AI())
{
pet->SetReactState(REACT_PASSIVE);
pet->GetCharmInfo()->SetCommandState(COMMAND_FOLLOW);
pet->GetCharmInfo()->SetIsFollowing(true);
pet->AttackStop();
}
}
return Flee(AI_VALUE(Unit*, "current target"));
}

View File

@@ -36,7 +36,7 @@ class MovementAction : public Action
bool Flee(Unit *target);
void ClearIdleState();
void UpdateMovementState();
bool MoveAway(Unit* target);
void CreateWp(Player* wpOwner, float x, float y, float z, float o, uint32 entry, bool important = false);
};

View File

@@ -10,5 +10,5 @@ void UseFoodStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
Strategy::InitTriggers(triggers);
triggers.push_back(new TriggerNode("low health", NextAction::array(0, new NextAction("food", 3.0f), nullptr)));
triggers.push_back(new TriggerNode("high mana", NextAction::array(0, new NextAction("drink", 3.0f), nullptr)));
triggers.push_back(new TriggerNode("low mana", NextAction::array(0, new NextAction("drink", 3.0f), nullptr)));
}

View File

@@ -11,50 +11,14 @@ class DpsHunterStrategyActionNodeFactory : public NamedObjectFactory<ActionNode>
DpsHunterStrategyActionNodeFactory()
{
creators["aimed shot"] = &aimed_shot;
creators["chimera shot"] = &chimera_shot;
creators["explosive shot"] = &explosive_shot;
creators["concussive shot"] = &concussive_shot;
creators["viper sting"] = &viper_sting;
}
private:
static ActionNode* viper_sting([[maybe_unused]] PlayerbotAI* botAI)
{
return new ActionNode ("viper sting",
/*P*/ nullptr,
/*A*/ NextAction::array(0, new NextAction("mana potion", 10.0f), nullptr),
/*C*/ nullptr);
}
static ActionNode* aimed_shot([[maybe_unused]] PlayerbotAI* botAI)
{
return new ActionNode ("aimed shot",
/*P*/ nullptr,
/*A*/ NextAction::array(0, new NextAction("chimera shot", 10.0f), nullptr),
/*C*/ nullptr);
}
static ActionNode* chimera_shot([[maybe_unused]] PlayerbotAI* botAI)
{
return new ActionNode ("chimera shot",
/*P*/ nullptr,
/*A*/ NextAction::array(0, new NextAction("arcane shot", 10.0f), nullptr),
/*C*/ nullptr);
}
static ActionNode* explosive_shot([[maybe_unused]] PlayerbotAI* botAI)
{
return new ActionNode ("explosive shot",
/*P*/ nullptr,
/*A*/ NextAction::array(0, new NextAction("aimed shot"), nullptr),
/*C*/ nullptr);
}
static ActionNode* concussive_shot([[maybe_unused]] PlayerbotAI* botAI)
{
return new ActionNode ("concussive shot",
/*P*/ nullptr,
/*A*/ nullptr,
/*A*/ NextAction::array(0, new NextAction("multi-shot", 10.0f), nullptr),
/*C*/ nullptr);
}
};
@@ -66,7 +30,16 @@ DpsHunterStrategy::DpsHunterStrategy(PlayerbotAI* botAI) : GenericHunterStrategy
NextAction** DpsHunterStrategy::getDefaultActions()
{
return NextAction::array(0, new NextAction("explosive shot", 11.0f), new NextAction("auto shot", 10.0f), new NextAction("auto attack", 9.0f), nullptr);
return NextAction::array(0,
new NextAction("kill shot", 16.0f),
new NextAction("chimera shot", 15.0f),
new NextAction("explosive shot", 15.0f),
new NextAction("aimed shot", 14.0f),
new NextAction("arcane shot", 13.0f),
new NextAction("steady shot", 12.0f),
new NextAction("auto shot", 10.0f),
NULL);
// return NextAction::array(0, new NextAction("explosive shot", 11.0f), new NextAction("auto shot", 10.0f), new NextAction("auto attack", 9.0f), nullptr);
}
void DpsHunterStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
@@ -77,6 +50,8 @@ void DpsHunterStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
triggers.push_back(new TriggerNode("low mana", NextAction::array(0, new NextAction("viper sting", 23), nullptr)));
triggers.push_back(new TriggerNode("hunter's mark", NextAction::array(0, new NextAction("hunter's mark", 19.0f), nullptr)));
triggers.push_back(new TriggerNode("concussive shot on snare target", NextAction::array(0, new NextAction("concussive shot", 20.0f), nullptr)));
triggers.push_back(new TriggerNode("no pet", NextAction::array(0, new NextAction("call pet", 21.0f), NULL)));
triggers.push_back(new TriggerNode("hunters pet low health", NextAction::array(0, new NextAction("mend pet", 21.0f), NULL)));
/*triggers.push_back(new TriggerNode("has aggro", NextAction::array(0, new NextAction("concussive shot", 20.0f), nullptr)));*/
}

View File

@@ -45,8 +45,8 @@ void GenericHunterNonCombatStrategy::InitTriggers(std::vector<TriggerNode*>& tri
triggers.push_back(new TriggerNode("trueshot aura", NextAction::array(0, new NextAction("trueshot aura", 2.0f), nullptr)));
triggers.push_back(new TriggerNode("often", NextAction::array(0, new NextAction("apply oil", 1.0f), nullptr)));
triggers.push_back(new TriggerNode("low ammo", NextAction::array(0, new NextAction("say::low ammo", ACTION_NORMAL), nullptr)));
triggers.push_back(new TriggerNode("no ammo", NextAction::array(0, new NextAction("switch to melee", ACTION_NORMAL + 1), new NextAction("say::no ammo", ACTION_NORMAL), nullptr)));
triggers.push_back(new TriggerNode("has ammo", NextAction::array(0, new NextAction("switch to ranged", ACTION_NORMAL), nullptr)));
// triggers.push_back(new TriggerNode("no ammo", NextAction::array(0, new NextAction("switch to melee", ACTION_NORMAL + 1), new NextAction("say::no ammo", ACTION_NORMAL), nullptr)));
// triggers.push_back(new TriggerNode("has ammo", NextAction::array(0, new NextAction("switch to ranged", ACTION_NORMAL), nullptr)));
}
void HunterPetStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)

View File

@@ -69,13 +69,13 @@ void GenericHunterStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
{
CombatStrategy::InitTriggers(triggers);
triggers.push_back(new TriggerNode("enemy too close for auto shot", NextAction::array(0, new NextAction("switch to melee", ACTION_HIGH), nullptr)));
// triggers.push_back(new TriggerNode("enemy too close for auto shot", NextAction::array(0, new NextAction("switch to melee", ACTION_HIGH), nullptr)));
triggers.push_back(new TriggerNode("enemy is close", NextAction::array(0, new NextAction("wing clip", ACTION_HIGH), nullptr)));
triggers.push_back(new TriggerNode("medium threat", NextAction::array(0, new NextAction("feign death", 35.0f), nullptr)));
triggers.push_back(new TriggerNode("hunters pet low health", NextAction::array(0, new NextAction("mend pet", ACTION_HIGH + 2), nullptr)));
triggers.push_back(new TriggerNode("switch to melee", NextAction::array(0, new NextAction("switch to melee", ACTION_HIGH + 1), nullptr)));
triggers.push_back(new TriggerNode("switch to ranged", NextAction::array(0, new NextAction("switch to ranged", ACTION_HIGH), nullptr)));
triggers.push_back(new TriggerNode("no ammo", NextAction::array(0, new NextAction("switch to melee", ACTION_HIGH + 1), new NextAction("say::no ammo", ACTION_HIGH), nullptr)));
// triggers.push_back(new TriggerNode("no ammo", NextAction::array(0, new NextAction("switch to melee", ACTION_HIGH + 1), new NextAction("say::no ammo", ACTION_HIGH), nullptr)));
triggers.push_back(new TriggerNode("aspect of the viper", NextAction::array(0, new NextAction("aspect of the viper", ACTION_HIGH), NULL)));
triggers.push_back(new TriggerNode("enemy too close for shoot", NextAction::array(0, new NextAction("flee", ACTION_HIGH + 3), NULL)));
}
NextAction** HunterBoostStrategy::getDefaultActions()

View File

@@ -62,12 +62,27 @@ END_SPELL_ACTION()
BEGIN_RANGED_SPELL_ACTION(CastScorpidStingAction, "scorpid sting")
END_SPELL_ACTION()
BEGIN_RANGED_SPELL_ACTION(CastSteadyShotAction, "steady shot")
END_SPELL_ACTION()
BEGIN_RANGED_SPELL_ACTION(CastKillShotAction, "kill shot")
END_SPELL_ACTION()
BEGIN_RANGED_SPELL_ACTION(CastTranquilizingShortAction, "tranquilizing shot")
END_SPELL_ACTION()
class CastAspectOfTheHawkAction : public CastBuffSpellAction
{
public:
CastAspectOfTheHawkAction(PlayerbotAI* botAI) : CastBuffSpellAction(botAI, "aspect of the hawk") { }
};
class CastAspectOfTheDragonhawkAction : public CastBuffSpellAction
{
public:
CastAspectOfTheDragonhawkAction(PlayerbotAI* botAI) : CastBuffSpellAction(botAI, "aspect of the dragonhawk") {}
};
class CastAspectOfTheWildAction : public CastBuffSpellAction
{
public:

View File

@@ -148,6 +148,10 @@ class HunterAiObjectContextInternal : public NamedObjectContext<Action>
creators["bestial wrath"] = &HunterAiObjectContextInternal::bestial_wrath;
creators["scare beast"] = &HunterAiObjectContextInternal::scare_beast;
creators["scare beast on cc"] = &HunterAiObjectContextInternal::scare_beast_on_cc;
creators["aspect of the dragonhawk"] = &HunterAiObjectContextInternal::aspect_of_the_dragonhawk;
creators["tranquilizing shot"] = &HunterAiObjectContextInternal::tranquilizing_shot;
creators["steady shot"] = &HunterAiObjectContextInternal::steady_shot;
creators["kill shot"] = &HunterAiObjectContextInternal::kill_shot;
}
private:
@@ -186,6 +190,10 @@ class HunterAiObjectContextInternal : public NamedObjectContext<Action>
static Action* aspect_of_the_cheetah(PlayerbotAI* botAI) { return new CastAspectOfTheCheetahAction(botAI); }
static Action* wing_clip(PlayerbotAI* botAI) { return new CastWingClipAction(botAI); }
static Action* raptor_strike(PlayerbotAI* botAI) { return new CastRaptorStrikeAction(botAI); }
static Action* aspect_of_the_dragonhawk(PlayerbotAI* ai) { return new CastAspectOfTheDragonhawkAction(ai); }
static Action* tranquilizing_shot(PlayerbotAI* ai) { return new CastTranquilizingShortAction(ai); }
static Action* steady_shot(PlayerbotAI* ai) { return new CastSteadyShotAction(ai); }
static Action* kill_shot(PlayerbotAI* ai) { return new CastKillShotAction(ai); }
};
HunterAiObjectContext::HunterAiObjectContext(PlayerbotAI* botAI) : AiObjectContext(botAI)

View File

@@ -7,6 +7,7 @@
void HunterBuffDpsStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
{
triggers.push_back(new TriggerNode("aspect of the hawk", NextAction::array(0, new NextAction("aspect of the dragonhawk", 90.0f), nullptr)));
triggers.push_back(new TriggerNode("aspect of the hawk", NextAction::array(0, new NextAction("aspect of the hawk", 90.0f), nullptr)));
}

View File

@@ -7,6 +7,14 @@
#include "Playerbots.h"
#include "ServerFacade.h"
bool HunterAspectOfTheHawkTrigger::IsActive()
{
Unit* target = GetTarget();
return SpellTrigger::IsActive() &&
!botAI->HasAura("aspect of the hawk", target) && !botAI->HasAura("aspect of the dragonhawk", target) &&
(!AI_VALUE2(bool, "has mana", "self target") || AI_VALUE2(uint8, "mana", "self target") > 70);
}
bool HunterNoStingsActiveTrigger::IsActive()
{
Unit* target = AI_VALUE(Unit*, "current target");
@@ -16,6 +24,8 @@ bool HunterNoStingsActiveTrigger::IsActive()
bool HuntersPetDeadTrigger::IsActive()
{
// Unit* pet = AI_VALUE(Unit*, "pet target");
// return pet && AI_VALUE2(bool, "dead", "pet target") && !AI_VALUE2(bool, "mounted", "self target");
return AI_VALUE(bool, "pet dead") && !AI_VALUE2(bool, "mounted", "self target");
}
@@ -32,7 +42,8 @@ bool HunterPetNotHappy::IsActive()
bool HunterAspectOfTheViperTrigger::IsActive()
{
return SpellTrigger::IsActive() && !botAI->HasAura(spell, GetTarget());
return SpellTrigger::IsActive() && !botAI->HasAura(spell, GetTarget()) &&
AI_VALUE2(uint8, "mana", "self target") < sPlayerbotAIConfig->lowMana;;
}
bool HunterAspectOfThePackTrigger::IsActive()

View File

@@ -24,6 +24,7 @@ class HunterAspectOfTheHawkTrigger : public BuffTrigger
{
public:
HunterAspectOfTheHawkTrigger(PlayerbotAI* botAI) : BuffTrigger(botAI, "aspect of the hawk") { }
bool IsActive() override;
};
class HunterAspectOfTheWildTrigger : public BuffTrigger

View File

@@ -13,19 +13,19 @@
#include "PullStrategy.h"
#include "Playerbots.h"
class StrategyFactoryInternal : public NamedObjectContext<Strategy>
class MageStrategyFactoryInternal : public NamedObjectContext<Strategy>
{
public:
StrategyFactoryInternal()
MageStrategyFactoryInternal()
{
creators["nc"] = &StrategyFactoryInternal::nc;
creators["pull"] = &StrategyFactoryInternal::pull;
creators["fire aoe"] = &StrategyFactoryInternal::fire_aoe;
creators["frost aoe"] = &StrategyFactoryInternal::frost_aoe;
creators["cure"] = &StrategyFactoryInternal::cure;
creators["buff"] = &StrategyFactoryInternal::buff;
creators["boost"] = &StrategyFactoryInternal::boost;
creators["cc"] = &StrategyFactoryInternal::cc;
creators["nc"] = &MageStrategyFactoryInternal::nc;
creators["pull"] = &MageStrategyFactoryInternal::pull;
creators["fire aoe"] = &MageStrategyFactoryInternal::fire_aoe;
creators["frost aoe"] = &MageStrategyFactoryInternal::frost_aoe;
creators["cure"] = &MageStrategyFactoryInternal::cure;
creators["buff"] = &MageStrategyFactoryInternal::buff;
creators["boost"] = &MageStrategyFactoryInternal::boost;
creators["cc"] = &MageStrategyFactoryInternal::cc;
}
private:
@@ -39,14 +39,14 @@ class StrategyFactoryInternal : public NamedObjectContext<Strategy>
static Strategy* cc(PlayerbotAI* botAI) { return new MageCcStrategy(botAI); }
};
class MageStrategyFactoryInternal : public NamedObjectContext<Strategy>
class MageCombatStrategyFactoryInternal : public NamedObjectContext<Strategy>
{
public:
MageStrategyFactoryInternal() : NamedObjectContext<Strategy>(false, true)
MageCombatStrategyFactoryInternal() : NamedObjectContext<Strategy>(false, true)
{
creators["frost"] = &MageStrategyFactoryInternal::frost;
creators["fire"] = &MageStrategyFactoryInternal::fire;
creators["arcane"] = &MageStrategyFactoryInternal::arcane;
creators["frost"] = &MageCombatStrategyFactoryInternal::frost;
creators["fire"] = &MageCombatStrategyFactoryInternal::fire;
creators["arcane"] = &MageCombatStrategyFactoryInternal::arcane;
}
private:
@@ -213,7 +213,7 @@ class MageAiObjectContextInternal : public NamedObjectContext<Action>
MageAiObjectContext::MageAiObjectContext(PlayerbotAI* botAI) : AiObjectContext(botAI)
{
strategyContexts.Add(new MageStrategyFactoryInternal());
strategyContexts.Add(new MageStrategyFactoryInternal());
strategyContexts.Add(new MageCombatStrategyFactoryInternal());
strategyContexts.Add(new MageBuffStrategyFactoryInternal());
actionContexts.Add(new MageAiObjectContextInternal());
triggerContexts.Add(new MageTriggerFactoryInternal());

View File

@@ -145,7 +145,23 @@ bool MyAttackerCountTrigger::IsActive()
bool AoeTrigger::IsActive()
{
return AI_VALUE2(bool, "combat", "self target") && AI_VALUE(uint8, "aoe count") >= amount && AI_VALUE(uint8, "attacker count") >= amount;
Unit* current_target = AI_VALUE(Unit*, "current target");
if (!current_target) {
return false;
}
GuidVector attackers = context->GetValue<GuidVector>("attackers")->Get();
int attackers_count = 0;
for (ObjectGuid const guid : attackers)
{
Unit* unit = botAI->GetUnit(guid);
if (!unit || !unit->IsAlive())
continue;
if (unit->GetExactDist2d(current_target) <= range) {
attackers_count++;
}
}
return attackers_count >= amount;
}
bool NoFoodTrigger::IsActive()

View File

@@ -225,19 +225,19 @@ class NoDrinkTrigger : public Trigger
class LightAoeTrigger : public AoeTrigger
{
public:
LightAoeTrigger(PlayerbotAI* botAI) : AoeTrigger(botAI, 2, 15.0f) { }
LightAoeTrigger(PlayerbotAI* botAI) : AoeTrigger(botAI, 2, 8.0f) { }
};
class MediumAoeTrigger : public AoeTrigger
{
public:
MediumAoeTrigger(PlayerbotAI* botAI) : AoeTrigger(botAI, 3, 17.0f) { }
MediumAoeTrigger(PlayerbotAI* botAI) : AoeTrigger(botAI, 3, 8.0f) { }
};
class HighAoeTrigger : public AoeTrigger
{
public:
HighAoeTrigger(PlayerbotAI* botAI) : AoeTrigger(botAI, 4, 20.0f) { }
HighAoeTrigger(PlayerbotAI* botAI) : AoeTrigger(botAI, 4, 8.0f) { }
};
class BuffTrigger : public SpellTrigger
@@ -413,7 +413,7 @@ END_TRIGGER()
class NoPetTrigger : public Trigger
{
public:
NoPetTrigger(PlayerbotAI* botAI) : Trigger(botAI, "no pet", 30) { }
NoPetTrigger(PlayerbotAI* botAI) : Trigger(botAI, "no pet", 5) { }
bool IsActive() override;
};

View File

@@ -15,33 +15,37 @@ static float GetSpeedInMotion(Unit* target)
bool EnemyTooCloseForSpellTrigger::IsActive()
{
Unit* target = AI_VALUE(Unit*, "current target");
if (target)
{
if (target->GetTarget() == bot->GetGUID() && !bot->GetGroup() && !target->HasUnitState(UNIT_STATE_ROOT) && GetSpeedInMotion(target) > GetSpeedInMotion(bot) * 0.65f)
return false;
return target && target->GetVictim() != bot &&
target->GetObjectSize() <= 10.0f &&
AI_VALUE2(float, "distance", "current target") <= sPlayerbotAIConfig->tooCloseDistance;
// Unit* target = AI_VALUE(Unit*, "current target");
// if (!target) {
// return false;
// }
bool isBoss = false;
bool isRaid = false;
float combatReach = bot->GetCombatReach() + target->GetCombatReach();
float targetDistance = sServerFacade->GetDistance2d(bot, target) + combatReach;
if (target->GetTypeId() == TYPEID_UNIT)
{
Creature* creature = botAI->GetCreature(target->GetGUID());
if (creature)
{
isBoss = creature->isWorldBoss();
}
}
// if (target->GetTarget() == bot->GetGUID() && !bot->GetGroup() && !target->HasUnitState(UNIT_STATE_ROOT) && GetSpeedInMotion(target) > GetSpeedInMotion(bot) * 0.65f)
// return false;
if (bot->GetMap() && bot->GetMap()->IsRaid())
isRaid = true;
// bool isBoss = false;
// bool isRaid = false;
// float combatReach = bot->GetCombatReach() + target->GetCombatReach();
// float targetDistance = sServerFacade->GetDistance2d(bot, target) + combatReach;
// if (target->GetTypeId() == TYPEID_UNIT)
// {
// Creature* creature = botAI->GetCreature(target->GetGUID());
// if (creature)
// {
// isBoss = creature->isWorldBoss();
// }
// }
// if (isBoss || isRaid)
// return sServerFacade->IsDistanceLessThan(targetDistance, (botAI->GetRange("spell") + combatReach) / 2);
// if (bot->GetMap() && bot->GetMap()->IsRaid())
// isRaid = true;
return sServerFacade->IsDistanceLessOrEqualThan(targetDistance, (botAI->GetRange("spell") + combatReach / 2));
}
return false;
// // if (isBoss || isRaid)
// // return sServerFacade->IsDistanceLessThan(targetDistance, (sPlayerbotAIConfig->tooCloseDistance + combatReach) / 2);
// return sServerFacade->IsDistanceLessOrEqualThan(targetDistance, (sPlayerbotAIConfig->tooCloseDistance + combatReach / 2));
}
bool EnemyTooCloseForAutoShotTrigger::IsActive()
@@ -75,32 +79,35 @@ bool EnemyTooCloseForAutoShotTrigger::IsActive()
bool EnemyTooCloseForShootTrigger::IsActive()
{
Unit* target = AI_VALUE(Unit*, "current target");
if (!target)
return false;
return target && target->GetVictim() != bot && AI_VALUE2(float, "distance", "current target") <= sPlayerbotAIConfig->shootDistance;
if (target->GetTarget() == bot->GetGUID() && !bot->GetGroup() && !target->HasUnitState(UNIT_STATE_ROOT) && GetSpeedInMotion(target) > GetSpeedInMotion(bot) * 0.65f)
return false;
// Unit* target = AI_VALUE(Unit*, "current target");
// if (!target)
// return false;
bool isBoss = false;
bool isRaid = false;
float combatReach = bot->GetCombatReach() + target->GetCombatReach();
float targetDistance = sServerFacade->GetDistance2d(bot, target) + combatReach;
if (target->GetTypeId() == TYPEID_UNIT)
{
Creature* creature = botAI->GetCreature(target->GetGUID());
if (creature)
{
isBoss = creature->isWorldBoss();
}
}
// if (target->GetTarget() == bot->GetGUID() && !bot->GetGroup() && !target->HasUnitState(UNIT_STATE_ROOT) && GetSpeedInMotion(target) > GetSpeedInMotion(bot) * 0.65f)
// return false;
if (bot->GetMap() && bot->GetMap()->IsRaid())
isRaid = true;
// bool isBoss = false;
// bool isRaid = false;
// float combatReach = bot->GetCombatReach() + target->GetCombatReach();
// float targetDistance = sServerFacade->GetDistance2d(bot, target) + combatReach;
// if (target->GetTypeId() == TYPEID_UNIT)
// {
// Creature* creature = botAI->GetCreature(target->GetGUID());
// if (creature)
// {
// isBoss = creature->isWorldBoss();
// }
// }
// if (isBoss || isRaid)
// return sServerFacade->IsDistanceLessThan(targetDistance, botAI->GetRange("shoot") + combatReach);
// if (bot->GetMap() && bot->GetMap()->IsRaid())
// isRaid = true;
return sServerFacade->IsDistanceLessOrEqualThan(targetDistance, (botAI->GetRange("shoot") + combatReach / 2));
// // if (isBoss || isRaid)
// // return sServerFacade->IsDistanceLessThan(targetDistance, botAI->GetRange("shoot") + combatReach);
// return sServerFacade->IsDistanceLessOrEqualThan(targetDistance, (botAI->GetRange("shoot") + combatReach / 2));
}
bool EnemyTooCloseForMeleeTrigger::IsActive()