mirror of
https://github.com/mod-playerbots/mod-playerbots
synced 2025-11-29 15:58:20 +08:00
Flee action, factory setting
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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"));
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
};
|
||||
|
||||
|
||||
@@ -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)));
|
||||
}
|
||||
|
||||
@@ -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)));*/
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)));
|
||||
}
|
||||
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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()
|
||||
|
||||
Reference in New Issue
Block a user