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

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