mirror of
https://github.com/mod-playerbots/mod-playerbots
synced 2025-11-29 15:58:20 +08:00
Movement priority
This commit is contained in:
@@ -405,14 +405,15 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
class RecentlyFleeInfo : public ManualSetValue<std::list<FleeInfo>>
|
||||
class RecentlyFleeInfo : public ManualSetValue<std::list<FleeInfo>&>
|
||||
{
|
||||
public:
|
||||
RecentlyFleeInfo(PlayerbotAI* botAI, std::list<FleeInfo> defaultValue = {},
|
||||
std::string const name = "recently flee info")
|
||||
: ManualSetValue<std::list<FleeInfo>>(botAI, defaultValue, name)
|
||||
RecentlyFleeInfo(PlayerbotAI* botAI, std::string const name = "recently flee info")
|
||||
: ManualSetValue<std::list<FleeInfo>&>(botAI, data, name)
|
||||
{
|
||||
}
|
||||
private:
|
||||
std::list<FleeInfo> data = {};
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -7,9 +7,12 @@
|
||||
|
||||
#include "CreatureAI.h"
|
||||
#include "Event.h"
|
||||
#include "LastMovementValue.h"
|
||||
#include "LootObjectStack.h"
|
||||
#include "PlayerbotAI.h"
|
||||
#include "Playerbots.h"
|
||||
#include "ServerFacade.h"
|
||||
#include "SharedDefines.h"
|
||||
#include "Unit.h"
|
||||
|
||||
bool AttackAction::Execute(Event event)
|
||||
@@ -109,13 +112,24 @@ bool AttackAction::Attack(Unit* target, bool with_pet /*true*/)
|
||||
bot->SetSelection(target->GetGUID());
|
||||
|
||||
Unit* oldTarget = context->GetValue<Unit*>("current target")->Get();
|
||||
|
||||
if (oldTarget == target && botAI->GetState() == BOT_STATE_COMBAT && bot->GetVictim() == target)
|
||||
return false;
|
||||
|
||||
context->GetValue<Unit*>("old target")->Set(oldTarget);
|
||||
|
||||
context->GetValue<Unit*>("current target")->Set(target);
|
||||
context->GetValue<LootObjectStack*>("available loot")->Get()->Add(guid);
|
||||
|
||||
LastMovement& lastMovement = AI_VALUE(LastMovement&, "last movement");
|
||||
if (lastMovement.priority < MovementPriority::MOVEMENT_COMBAT && bot->isMoving())
|
||||
{
|
||||
AI_VALUE(LastMovement&, "last movement").clear();
|
||||
bot->GetMotionMaster()->Clear(false);
|
||||
bot->StopMoving();
|
||||
}
|
||||
|
||||
bool melee = bot->IsWithinMeleeRange(target) || botAI->IsMelee(bot);
|
||||
bot->Attack(target, melee);
|
||||
|
||||
if (IsMovingAllowed() && !bot->HasInArc(CAST_ANGLE_IN_FRONT, target))
|
||||
{
|
||||
@@ -123,10 +137,7 @@ bool AttackAction::Attack(Unit* target, bool with_pet /*true*/)
|
||||
}
|
||||
botAI->ChangeEngine(BOT_STATE_COMBAT);
|
||||
|
||||
if (!bot->GetVictim())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
bot->Attack(target, melee);
|
||||
/* prevent pet dead immediately in group */
|
||||
// if (bot->GetMap()->IsDungeon() && bot->GetGroup() && !target->IsInCombat()) {
|
||||
// with_pet = false;
|
||||
|
||||
@@ -32,7 +32,7 @@ bool FollowChatShortcutAction::Execute(Event event)
|
||||
if (!master)
|
||||
return false;
|
||||
|
||||
botAI->Reset();
|
||||
// botAI->Reset();
|
||||
botAI->ChangeStrategy("+follow,-passive,-grind", BOT_STATE_NON_COMBAT);
|
||||
botAI->ChangeStrategy("-follow,-passive,-grind", BOT_STATE_COMBAT);
|
||||
botAI->GetAiObjectContext()->GetValue<GuidVector>("prioritized targets")->Set({});
|
||||
@@ -57,7 +57,9 @@ bool FollowChatShortcutAction::Execute(Event event)
|
||||
if (Formation::IsNullLocation(loc) || loc.GetMapId() == -1)
|
||||
return false;
|
||||
|
||||
moved = MoveTo(loc.GetMapId(), loc.GetPositionX(), loc.GetPositionY(), loc.GetPositionZ());
|
||||
MovementPriority priority = botAI->GetState() == BOT_STATE_COMBAT ? MovementPriority::MOVEMENT_COMBAT : MovementPriority::MOVEMENT_NORMAL;
|
||||
moved = MoveTo(loc.GetMapId(), loc.GetPositionX(), loc.GetPositionY(), loc.GetPositionZ(), false, false, false,
|
||||
true, priority);
|
||||
}
|
||||
|
||||
if (moved)
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include "BattlegroundWS.h"
|
||||
#include "Event.h"
|
||||
#include "PlayerbotAI.h"
|
||||
#include "PlayerbotAIConfig.h"
|
||||
#include "Playerbots.h"
|
||||
#include "ServerFacade.h"
|
||||
#include "SpellAuraEffects.h"
|
||||
@@ -17,35 +18,46 @@ bool CheckMountStateAction::Execute(Event event)
|
||||
bool noattackers =
|
||||
AI_VALUE2(bool, "combat", "self target") ? (AI_VALUE(uint8, "attacker count") > 0 ? false : true) : true;
|
||||
bool enemy = AI_VALUE(Unit*, "enemy player target");
|
||||
// ignore grind target in BG or bots will dismount near any creature (eg: the rams in AV)
|
||||
bool dps = AI_VALUE(Unit*, "dps target");
|
||||
// bool fartarget = (enemy && sServerFacade->IsDistanceGreaterThan(AI_VALUE2(float, "distance", "enemy player
|
||||
// target"), 40.0f)) ||
|
||||
// (dps && sServerFacade->IsDistanceGreaterThan(AI_VALUE2(float, "distance", "dps target"), 50.0f));
|
||||
bool attackdistance = false;
|
||||
bool shouldDismount = false;
|
||||
bool shouldMount = false;
|
||||
// bool chasedistance = false;
|
||||
float attack_distance = 35.0f;
|
||||
float attack_distance;
|
||||
float mount_distance;
|
||||
if (PlayerbotAI::IsMelee(bot))
|
||||
{
|
||||
attack_distance = 5.0f;
|
||||
attack_distance = sPlayerbotAIConfig->meleeDistance + 2.0f;
|
||||
mount_distance = sPlayerbotAIConfig->meleeDistance + 10.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
attack_distance = 30.0f;
|
||||
attack_distance = sPlayerbotAIConfig->spellDistance + 2.0f;
|
||||
mount_distance = sPlayerbotAIConfig->spellDistance + 10.0f;
|
||||
}
|
||||
|
||||
// if (enemy)
|
||||
// attack_distance /= 2;
|
||||
|
||||
if (dps || enemy)
|
||||
{
|
||||
Unit* currentTarget = AI_VALUE(Unit*, "current target");
|
||||
attackdistance =
|
||||
(enemy || dps) && currentTarget &&
|
||||
sServerFacade->IsDistanceLessThan(AI_VALUE2(float, "distance", "current target"), attack_distance);
|
||||
}
|
||||
|
||||
if (bot->IsMounted() && attackdistance)
|
||||
if (currentTarget)
|
||||
{
|
||||
float combatReach = bot->GetCombatReach() + currentTarget->GetCombatReach();
|
||||
attack_distance += combatReach;
|
||||
float disToTarget = bot->GetExactDist(currentTarget);
|
||||
shouldDismount = disToTarget <= attack_distance;
|
||||
}
|
||||
else
|
||||
shouldDismount = false;
|
||||
|
||||
if (currentTarget)
|
||||
{
|
||||
float combatReach = bot->GetCombatReach() + currentTarget->GetCombatReach();
|
||||
mount_distance += combatReach;
|
||||
float disToTarget = bot->GetExactDist(currentTarget);
|
||||
shouldMount = disToTarget > mount_distance;
|
||||
}
|
||||
else
|
||||
shouldMount = true;
|
||||
|
||||
if (bot->IsMounted() && shouldDismount)
|
||||
{
|
||||
WorldPacket emptyPacket;
|
||||
bot->GetSession()->HandleCancelMountAuraOpcode(emptyPacket);
|
||||
@@ -59,7 +71,7 @@ bool CheckMountStateAction::Execute(Event event)
|
||||
return false;
|
||||
|
||||
// bool farFromMaster = sServerFacade->GetDistance2d(bot, master) > sPlayerbotAIConfig->sightDistance;
|
||||
if (master->IsMounted() && !bot->IsMounted() && noattackers && !attackdistance && !bot->IsInCombat() &&
|
||||
if (master->IsMounted() && !bot->IsMounted() && noattackers && shouldMount && !bot->IsInCombat() &&
|
||||
botAI->GetState() != BOT_STATE_COMBAT)
|
||||
{
|
||||
return Mount();
|
||||
@@ -71,16 +83,6 @@ bool CheckMountStateAction::Execute(Event event)
|
||||
bot->GetSession()->HandleCancelMountAuraOpcode(emptyPacket);
|
||||
return true;
|
||||
}
|
||||
// if (!bot->IsMounted() && (chasedistance || (farFromMaster && botAI->HasStrategy("follow",
|
||||
// BOT_STATE_NON_COMBAT))) && !bot->IsInCombat() && !dps)
|
||||
// return Mount();
|
||||
|
||||
// if (!bot->IsFlying() && ((!farFromMaster && !master->IsMounted()) || attackdistance) && bot->IsMounted())
|
||||
// {
|
||||
// WorldPacket emptyPacket;
|
||||
// bot->GetSession()->HandleCancelMountAuraOpcode(emptyPacket);
|
||||
// return true;
|
||||
// }
|
||||
|
||||
return false;
|
||||
}
|
||||
@@ -88,13 +90,13 @@ bool CheckMountStateAction::Execute(Event event)
|
||||
// For random bots
|
||||
if (!bot->InBattleground() && !master)
|
||||
{
|
||||
if (!bot->IsMounted() && noattackers && !attackdistance && !bot->IsInCombat())
|
||||
if (!bot->IsMounted() && noattackers && shouldMount && !bot->IsInCombat())
|
||||
{
|
||||
return Mount();
|
||||
}
|
||||
}
|
||||
|
||||
if (bot->InBattleground() && !attackdistance && noattackers && !bot->IsInCombat() && !bot->IsMounted())
|
||||
if (bot->InBattleground() && shouldMount && noattackers && !bot->IsInCombat() && !bot->IsMounted())
|
||||
{
|
||||
if (bot->GetBattlegroundTypeId() == BATTLEGROUND_WS)
|
||||
{
|
||||
@@ -108,24 +110,7 @@ bool CheckMountStateAction::Execute(Event event)
|
||||
return Mount();
|
||||
}
|
||||
|
||||
// if (!bot->InBattleground())
|
||||
// {
|
||||
// if (AI_VALUE(GuidPosition, "rpg target"))
|
||||
// {
|
||||
// if (sServerFacade->IsDistanceGreaterThan(AI_VALUE2(float, "distance", "rpg target"),
|
||||
// sPlayerbotAIConfig->farDistance) && noattackers && !dps && !enemy)
|
||||
// return Mount();
|
||||
// }
|
||||
|
||||
// if (((!AI_VALUE(GuidVector, "possible rpg targets").empty()) && noattackers && !dps && !enemy) && urand(0,
|
||||
// 100) > 50)
|
||||
// return Mount();
|
||||
// }
|
||||
|
||||
// if (!bot->IsMounted() && !attackdistance && (fartarget || chasedistance))
|
||||
// return Mount();
|
||||
|
||||
if (!bot->IsFlying() && attackdistance && bot->IsMounted() && (enemy || dps || (!noattackers && bot->IsInCombat())))
|
||||
if (!bot->IsFlying() && shouldDismount && bot->IsMounted() && (enemy || dps || (!noattackers && bot->IsInCombat())))
|
||||
{
|
||||
WorldPacket emptyPacket;
|
||||
bot->GetSession()->HandleCancelMountAuraOpcode(emptyPacket);
|
||||
|
||||
@@ -9,6 +9,8 @@
|
||||
|
||||
#include "Event.h"
|
||||
#include "Formations.h"
|
||||
#include "LastMovementValue.h"
|
||||
#include "PlayerbotAI.h"
|
||||
#include "Playerbots.h"
|
||||
#include "ServerFacade.h"
|
||||
#include "SharedDefines.h"
|
||||
@@ -29,24 +31,14 @@ bool FollowAction::Execute(Event event)
|
||||
if (Formation::IsNullLocation(loc) || loc.GetMapId() == -1)
|
||||
return false;
|
||||
|
||||
MovementPriority priority = botAI->GetState() == BOT_STATE_COMBAT ? MovementPriority::MOVEMENT_COMBAT : MovementPriority::MOVEMENT_NORMAL;
|
||||
moved = MoveTo(loc.GetMapId(), loc.GetPositionX(), loc.GetPositionY(), loc.GetPositionZ(), false, false, false,
|
||||
true);
|
||||
true, priority);
|
||||
}
|
||||
|
||||
if (Pet* pet = bot->GetPet())
|
||||
{
|
||||
if (CreatureAI* creatureAI = ((Creature*)pet)->AI())
|
||||
{
|
||||
pet->SetReactState(REACT_PASSIVE);
|
||||
pet->GetCharmInfo()->SetIsCommandFollow(true);
|
||||
pet->GetCharmInfo()->IsReturning();
|
||||
pet->GetMotionMaster()->MoveFollow(bot, PET_FOLLOW_DIST, pet->GetFollowAngle());
|
||||
// pet->GetCharmInfo()->SetCommandState(COMMAND_FOLLOW);
|
||||
// pet->GetCharmInfo()->SetIsFollowing(true);
|
||||
// pet->AttackStop();
|
||||
// pet->GetCharmInfo()->IsReturning();
|
||||
// pet->GetMotionMaster()->MoveFollow(bot, PET_FOLLOW_DIST, pet->GetFollowAngle());
|
||||
}
|
||||
botAI->PetFollow();
|
||||
}
|
||||
// if (moved)
|
||||
// botAI->SetNextCheckDelay(sPlayerbotAIConfig->reactDelay);
|
||||
|
||||
@@ -94,12 +94,14 @@ bool MoveToRpgTargetAction::Execute(Event event)
|
||||
|
||||
x += cos(angle) * INTERACTION_DISTANCE * distance;
|
||||
y += sin(angle) * INTERACTION_DISTANCE * distance;
|
||||
bool exact = true;
|
||||
if (!wo->GetMap()->CheckCollisionAndGetValidCoords(wo, wo->GetPositionX(), wo->GetPositionY(), wo->GetPositionZ(),
|
||||
x, y, z))
|
||||
{
|
||||
x = wo->GetPositionX();
|
||||
y = wo->GetPositionY();
|
||||
z = wo->GetPositionZ();
|
||||
exact = false;
|
||||
}
|
||||
// WaitForReach(distance);
|
||||
|
||||
@@ -108,7 +110,7 @@ bool MoveToRpgTargetAction::Execute(Event event)
|
||||
// if (bot->IsWithinLOS(x, y, z))
|
||||
// couldMove = MoveNear(mapId, x, y, z, 0);
|
||||
// else
|
||||
couldMove = MoveTo(mapId, x, y, z, false, false, false, true);
|
||||
couldMove = MoveTo(mapId, x, y, z, false, false, false, exact);
|
||||
|
||||
if (!couldMove && WorldPosition(mapId, x, y, z).distance(bot) > INTERACTION_DISTANCE)
|
||||
{
|
||||
|
||||
@@ -61,23 +61,37 @@ void MovementAction::CreateWp(Player* wpOwner, float x, float y, float z, float
|
||||
wpCreature->SetObjectScale(0.5f);
|
||||
}
|
||||
|
||||
void MovementAction::JumpTo(uint32 mapId, float x, float y, float z)
|
||||
bool MovementAction::JumpTo(uint32 mapId, float x, float y, float z, MovementPriority priority)
|
||||
{
|
||||
UpdateMovementState();
|
||||
if (!IsMovingAllowed(mapId, x, y, z))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (IsDuplicateMove(mapId, x, y, z))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (IsWaitingForLastMove(priority))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
float botZ = bot->GetPositionZ();
|
||||
float speed = bot->GetSpeed(MOVE_RUN);
|
||||
MotionMaster& mm = *bot->GetMotionMaster();
|
||||
mm.Clear();
|
||||
mm.MoveJump(x, y, z, speed, speed, 1);
|
||||
AI_VALUE(LastMovement&, "last movement").Set(mapId, x, y, z, bot->GetOrientation(), 1000);
|
||||
AI_VALUE(LastMovement&, "last movement").Set(mapId, x, y, z, bot->GetOrientation(), 1000, priority);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool MovementAction::MoveNear(uint32 mapId, float x, float y, float z, float distance)
|
||||
bool MovementAction::MoveNear(uint32 mapId, float x, float y, float z, float distance, MovementPriority priority)
|
||||
{
|
||||
float angle = GetFollowAngle();
|
||||
return MoveTo(mapId, x + cos(angle) * distance, y + sin(angle) * distance, z);
|
||||
return MoveTo(mapId, x + cos(angle) * distance, y + sin(angle) * distance, z, false, false, false, false, priority);
|
||||
}
|
||||
|
||||
bool MovementAction::MoveNear(WorldObject* target, float distance)
|
||||
bool MovementAction::MoveNear(WorldObject* target, float distance, MovementPriority priority)
|
||||
{
|
||||
if (!target)
|
||||
return false;
|
||||
@@ -99,7 +113,7 @@ bool MovementAction::MoveNear(WorldObject* target, float distance)
|
||||
if (!bot->IsWithinLOS(x, y, z))
|
||||
continue;
|
||||
|
||||
bool moved = MoveTo(target->GetMapId(), x, y, z);
|
||||
bool moved = MoveTo(target->GetMapId(), x, y, z, false, false, false, false, priority);
|
||||
if (moved)
|
||||
return true;
|
||||
}
|
||||
@@ -161,7 +175,7 @@ bool MovementAction::MoveToLOS(WorldObject* target, bool ranged)
|
||||
}
|
||||
|
||||
bool MovementAction::MoveTo(uint32 mapId, float x, float y, float z, bool idle, bool react, bool normal_only,
|
||||
bool exact_waypoint)
|
||||
bool exact_waypoint, MovementPriority priority)
|
||||
{
|
||||
UpdateMovementState();
|
||||
if (!IsMovingAllowed(mapId, x, y, z))
|
||||
@@ -172,21 +186,10 @@ bool MovementAction::MoveTo(uint32 mapId, float x, float y, float z, bool idle,
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (IsWaitingForLastMove())
|
||||
if (IsWaitingForLastMove(priority))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// if (bot->Unit::IsFalling()) {
|
||||
// bot->Say("I'm falling!, flag:" + std::to_string(bot->m_movementInfo.GetMovementFlags()), LANG_UNIVERSAL);
|
||||
// return false;
|
||||
// }
|
||||
// if (bot->m_movementInfo.HasMovementFlag(MOVEMENTFLAG_SWIMMING)) {
|
||||
// bot->Say("I'm swimming", LANG_UNIVERSAL);
|
||||
// }
|
||||
// if (bot->Unit::IsFalling()) {
|
||||
// bot->Say("I'm falling", LANG_UNIVERSAL);
|
||||
// }
|
||||
bool generatePath = !bot->IsFlying() && !bot->isSwimming();
|
||||
bool disableMoveSplinePath = sPlayerbotAIConfig->disableMoveSplinePath >= 2 ||
|
||||
(sPlayerbotAIConfig->disableMoveSplinePath == 1 && bot->InBattleground());
|
||||
@@ -202,11 +205,11 @@ bool MovementAction::MoveTo(uint32 mapId, float x, float y, float z, bool idle,
|
||||
{
|
||||
MotionMaster& mm = *vehicleBase->GetMotionMaster(); // need to move vehicle, not bot
|
||||
mm.Clear();
|
||||
mm.MovePoint(mapId, x, y, z, generatePath);
|
||||
float delay = 1000.0f * (distance / vehicleBase->GetSpeed(MOVE_RUN)) - sPlayerbotAIConfig->reactDelay;
|
||||
mm.MovePoint(0, x, y, z, generatePath);
|
||||
float delay = 1000.0f * (distance / vehicleBase->GetSpeed(MOVE_RUN));
|
||||
delay = std::max(.0f, delay);
|
||||
delay = std::min((float)sPlayerbotAIConfig->maxWaitForMove, delay);
|
||||
AI_VALUE(LastMovement&, "last movement").Set(mapId, x, y, z, bot->GetOrientation(), delay);
|
||||
AI_VALUE(LastMovement&, "last movement").Set(mapId, x, y, z, bot->GetOrientation(), delay, priority);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -225,11 +228,11 @@ bool MovementAction::MoveTo(uint32 mapId, float x, float y, float z, bool idle,
|
||||
}
|
||||
MotionMaster& mm = *bot->GetMotionMaster();
|
||||
mm.Clear();
|
||||
mm.MovePoint(mapId, x, y, z, generatePath);
|
||||
float delay = 1000.0f * MoveDelay(distance) - sPlayerbotAIConfig->reactDelay;
|
||||
mm.MovePoint(0, x, y, z, generatePath);
|
||||
float delay = 1000.0f * MoveDelay(distance);
|
||||
delay = std::max(.0f, delay);
|
||||
delay = std::min((float)sPlayerbotAIConfig->maxWaitForMove, delay);
|
||||
AI_VALUE(LastMovement&, "last movement").Set(mapId, x, y, z, bot->GetOrientation(), delay);
|
||||
AI_VALUE(LastMovement&, "last movement").Set(mapId, x, y, z, bot->GetOrientation(), delay, priority);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -254,14 +257,13 @@ bool MovementAction::MoveTo(uint32 mapId, float x, float y, float z, bool idle,
|
||||
botAI->InterruptSpell();
|
||||
}
|
||||
MotionMaster& mm = *bot->GetMotionMaster();
|
||||
|
||||
G3D::Vector3 endP = path.back();
|
||||
mm.Clear();
|
||||
mm.MoveSplinePath(&path);
|
||||
// mm.MoveSplinePath(&path);
|
||||
float delay = 1000.0f * MoveDelay(distance) - sPlayerbotAIConfig->reactDelay;
|
||||
mm.MovePoint(0, endP.x, endP.y, endP.z, generatePath);
|
||||
float delay = 1000.0f * MoveDelay(distance);
|
||||
delay = std::max(.0f, delay);
|
||||
delay = std::min((float)sPlayerbotAIConfig->maxWaitForMove, delay);
|
||||
AI_VALUE(LastMovement&, "last movement").Set(mapId, x, y, z, bot->GetOrientation(), delay);
|
||||
AI_VALUE(LastMovement&, "last movement").Set(mapId, x, y, z, bot->GetOrientation(), delay, priority);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -759,7 +761,7 @@ bool MovementAction::MoveTo(uint32 mapId, float x, float y, float z, bool idle,
|
||||
// return true;
|
||||
}
|
||||
|
||||
bool MovementAction::MoveTo(Unit* target, float distance)
|
||||
bool MovementAction::MoveTo(Unit* target, float distance, MovementPriority priority)
|
||||
{
|
||||
if (!IsMovingAllowed(target))
|
||||
return false;
|
||||
@@ -793,7 +795,7 @@ bool MovementAction::MoveTo(Unit* target, float distance)
|
||||
{
|
||||
dz = tz;
|
||||
}
|
||||
return MoveTo(target->GetMapId(), dx, dy, dz);
|
||||
return MoveTo(target->GetMapId(), dx, dy, dz, false, false, false, false, priority);
|
||||
}
|
||||
|
||||
bool MovementAction::ReachCombatTo(Unit* target, float distance)
|
||||
@@ -813,6 +815,7 @@ bool MovementAction::ReachCombatTo(Unit* target, float distance)
|
||||
|
||||
if (target->HasUnitMovementFlag(MOVEMENTFLAG_FORWARD)) // target is moving forward, predict the position
|
||||
{
|
||||
|
||||
float needToGo = bot->GetExactDist(target) - distance;
|
||||
float timeToGo = MoveDelay(abs(needToGo)) + sPlayerbotAIConfig->reactDelay / 1000.0f;
|
||||
float targetMoveDist = timeToGo * target->GetSpeed(MOVE_RUN);
|
||||
@@ -845,7 +848,7 @@ bool MovementAction::ReachCombatTo(Unit* target, float distance)
|
||||
return false;
|
||||
path.ShortenPathUntilDist(G3D::Vector3(tx, ty, tz), distance);
|
||||
G3D::Vector3 endPos = path.GetPath().back();
|
||||
return MoveTo(target->GetMapId(), endPos.x, endPos.y, endPos.z);
|
||||
return MoveTo(target->GetMapId(), endPos.x, endPos.y, endPos.z, false, false, false, false, MovementPriority::MOVEMENT_COMBAT);
|
||||
}
|
||||
|
||||
float MovementAction::GetFollowAngle()
|
||||
@@ -909,10 +912,13 @@ bool MovementAction::IsDuplicateMove(uint32 mapId, float x, float y, float z)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool MovementAction::IsWaitingForLastMove()
|
||||
bool MovementAction::IsWaitingForLastMove(MovementPriority priority)
|
||||
{
|
||||
LastMovement& lastMove = *context->GetValue<LastMovement&>("last movement");
|
||||
|
||||
if (priority > lastMove.priority)
|
||||
return false;
|
||||
|
||||
// heuristic 5s
|
||||
if (lastMove.lastdelayTime + lastMove.msTime > getMSTime())
|
||||
return true;
|
||||
@@ -1216,7 +1222,7 @@ bool MovementAction::Follow(Unit* target, float distance, float angle)
|
||||
botAI->InterruptSpell();
|
||||
}
|
||||
|
||||
AI_VALUE(LastMovement&, "last movement").Set(target);
|
||||
// AI_VALUE(LastMovement&, "last movement").Set(target);
|
||||
ClearIdleState();
|
||||
|
||||
if (bot->GetMotionMaster()->GetCurrentMovementGeneratorType() == FOLLOW_MOTION_TYPE)
|
||||
@@ -1506,7 +1512,17 @@ bool MovementAction::MoveAway(Unit* target)
|
||||
float dx = bot->GetPositionX() + cos(angle) * sPlayerbotAIConfig->fleeDistance;
|
||||
float dy = bot->GetPositionY() + sin(angle) * sPlayerbotAIConfig->fleeDistance;
|
||||
float dz = bot->GetPositionZ();
|
||||
if (MoveTo(target->GetMapId(), dx, dy, dz, false, false, true))
|
||||
bool exact = true;
|
||||
if (!bot->GetMap()->CheckCollisionAndGetValidCoords(bot, bot->GetPositionX(), bot->GetPositionY(),
|
||||
bot->GetPositionZ(), dx, dy, dz))
|
||||
{
|
||||
// disable prediction if position is invalid
|
||||
dx = bot->GetPositionX() + cos(angle) * sPlayerbotAIConfig->fleeDistance;
|
||||
dy = bot->GetPositionY() + sin(angle) * sPlayerbotAIConfig->fleeDistance;
|
||||
dz = bot->GetPositionZ();
|
||||
exact = false;
|
||||
}
|
||||
if (MoveTo(target->GetMapId(), dx, dy, dz, false, false, true, exact, MovementPriority::MOVEMENT_COMBAT))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
@@ -1514,11 +1530,21 @@ bool MovementAction::MoveAway(Unit* target)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
exact = true;
|
||||
angle = init_angle - delta;
|
||||
dx = bot->GetPositionX() + cos(angle) * sPlayerbotAIConfig->fleeDistance;
|
||||
dy = bot->GetPositionY() + sin(angle) * sPlayerbotAIConfig->fleeDistance;
|
||||
dz = bot->GetPositionZ();
|
||||
if (MoveTo(target->GetMapId(), dx, dy, dz, false, false, true))
|
||||
if (!bot->GetMap()->CheckCollisionAndGetValidCoords(bot, bot->GetPositionX(), bot->GetPositionY(),
|
||||
bot->GetPositionZ(), dx, dy, dz))
|
||||
{
|
||||
// disable prediction if position is invalid
|
||||
dx = bot->GetPositionX() + cos(angle) * sPlayerbotAIConfig->fleeDistance;
|
||||
dy = bot->GetPositionY() + sin(angle) * sPlayerbotAIConfig->fleeDistance;
|
||||
dz = bot->GetPositionZ();
|
||||
exact = false;
|
||||
}
|
||||
if (MoveTo(target->GetMapId(), dx, dy, dz, false, false, true, exact, MovementPriority::MOVEMENT_COMBAT))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
@@ -1526,13 +1552,13 @@ bool MovementAction::MoveAway(Unit* target)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool MovementAction::MoveInside(uint32 mapId, float x, float y, float z, float distance)
|
||||
bool MovementAction::MoveInside(uint32 mapId, float x, float y, float z, float distance, MovementPriority priority)
|
||||
{
|
||||
if (bot->GetDistance2d(x, y) <= distance)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return MoveNear(mapId, x, y, z, distance);
|
||||
return MoveNear(mapId, x, y, z, distance, priority);
|
||||
}
|
||||
|
||||
// float MovementAction::SearchBestGroundZForPath(float x, float y, float z, bool generatePath, float range, bool
|
||||
@@ -1678,13 +1704,7 @@ bool FleeWithPetAction::Execute(Event event)
|
||||
{
|
||||
if (Pet* pet = bot->GetPet())
|
||||
{
|
||||
if (CreatureAI* creatureAI = ((Creature*)pet)->AI())
|
||||
{
|
||||
pet->SetReactState(REACT_PASSIVE);
|
||||
pet->GetCharmInfo()->SetIsCommandFollow(true);
|
||||
pet->GetCharmInfo()->IsReturning();
|
||||
pet->GetMotionMaster()->MoveFollow(bot, PET_FOLLOW_DIST, pet->GetFollowAngle());
|
||||
}
|
||||
botAI->PetFollow();
|
||||
}
|
||||
|
||||
return Flee(AI_VALUE(Unit*, "current target"));
|
||||
@@ -1929,7 +1949,7 @@ Position MovementAction::BestPositionForMeleeToFlee(Position pos, float radius)
|
||||
for (CheckAngle& checkAngle : possibleAngles)
|
||||
{
|
||||
float angle = checkAngle.angle;
|
||||
auto& infoList = AI_VALUE_REF(std::list<FleeInfo>, "recently flee info");
|
||||
std::list<FleeInfo>& infoList = AI_VALUE(std::list<FleeInfo>&, "recently flee info");
|
||||
if (!CheckLastFlee(angle, infoList))
|
||||
{
|
||||
continue;
|
||||
@@ -1985,7 +2005,7 @@ Position MovementAction::BestPositionForRangedToFlee(Position pos, float radius)
|
||||
for (CheckAngle& checkAngle : possibleAngles)
|
||||
{
|
||||
float angle = checkAngle.angle;
|
||||
auto& infoList = AI_VALUE_REF(std::list<FleeInfo>, "recently flee info");
|
||||
std::list<FleeInfo>& infoList = AI_VALUE(std::list<FleeInfo>&, "recently flee info");
|
||||
if (!CheckLastFlee(angle, infoList))
|
||||
{
|
||||
continue;
|
||||
@@ -2032,9 +2052,9 @@ bool MovementAction::FleePosition(Position pos, float radius)
|
||||
if (bestPos != Position())
|
||||
{
|
||||
if (MoveTo(bot->GetMapId(), bestPos.GetPositionX(), bestPos.GetPositionY(), bestPos.GetPositionZ(), false,
|
||||
false, true))
|
||||
false, true, false, MovementPriority::MOVEMENT_COMBAT))
|
||||
{
|
||||
auto& infoList = AI_VALUE_REF(std::list<FleeInfo>, "recently flee info");
|
||||
std::list<FleeInfo>& infoList = AI_VALUE(std::list<FleeInfo>&, "recently flee info");
|
||||
uint32 curTS = getMSTime();
|
||||
while (!infoList.empty())
|
||||
{
|
||||
@@ -2346,10 +2366,10 @@ bool MoveOutOfCollisionAction::isUseful()
|
||||
|
||||
bool MoveRandomAction::Execute(Event event)
|
||||
{
|
||||
float distance = sPlayerbotAIConfig->tooCloseDistance + sPlayerbotAIConfig->grindDistance * urand(3, 10) / 10.0f;
|
||||
float distance = sPlayerbotAIConfig->tooCloseDistance + urand(10, 30);
|
||||
|
||||
Map* map = bot->GetMap();
|
||||
for (int i = 0; i < 10; ++i)
|
||||
for (int i = 0; i < 3; ++i)
|
||||
{
|
||||
float x = bot->GetPositionX();
|
||||
float y = bot->GetPositionY();
|
||||
@@ -2362,11 +2382,7 @@ bool MoveRandomAction::Execute(Event event)
|
||||
float oz = z;
|
||||
if (!bot->GetMap()->CheckCollisionAndGetValidCoords(bot, bot->GetPositionX(), bot->GetPositionY(),
|
||||
bot->GetPositionZ(), x, y, z))
|
||||
{
|
||||
x = ox;
|
||||
y = oy;
|
||||
z = oz;
|
||||
}
|
||||
continue;
|
||||
if (map->IsInWater(bot->GetPhaseMask(), x, y, z, bot->GetCollisionHeight()))
|
||||
continue;
|
||||
|
||||
@@ -2385,7 +2401,7 @@ bool MoveInsideAction::Execute(Event event) { return MoveInside(bot->GetMapId(),
|
||||
bool RotateAroundTheCenterPointAction::Execute(Event event)
|
||||
{
|
||||
uint32 next_point = GetCurrWaypoint();
|
||||
if (MoveTo(bot->GetMapId(), waypoints[next_point].first, waypoints[next_point].second, bot->GetPositionZ()))
|
||||
if (MoveTo(bot->GetMapId(), waypoints[next_point].first, waypoints[next_point].second, bot->GetPositionZ(), false, false, false, false, MovementPriority::MOVEMENT_COMBAT))
|
||||
{
|
||||
call_counters += 1;
|
||||
return true;
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include <cmath>
|
||||
|
||||
#include "Action.h"
|
||||
#include "LastMovementValue.h"
|
||||
#include "PlayerbotAIConfig.h"
|
||||
|
||||
class Player;
|
||||
@@ -17,19 +18,20 @@ class Unit;
|
||||
class WorldObject;
|
||||
class Position;
|
||||
|
||||
|
||||
class MovementAction : public Action
|
||||
{
|
||||
public:
|
||||
MovementAction(PlayerbotAI* botAI, std::string const name);
|
||||
|
||||
protected:
|
||||
void JumpTo(uint32 mapId, float x, float y, float z);
|
||||
bool MoveNear(uint32 mapId, float x, float y, float z, float distance = sPlayerbotAIConfig->contactDistance);
|
||||
bool JumpTo(uint32 mapId, float x, float y, float z, MovementPriority priority = MovementPriority::MOVEMENT_NORMAL);
|
||||
bool MoveNear(uint32 mapId, float x, float y, float z, float distance = sPlayerbotAIConfig->contactDistance, MovementPriority priority = MovementPriority::MOVEMENT_NORMAL);
|
||||
bool MoveToLOS(WorldObject* target, bool ranged = false);
|
||||
bool MoveTo(uint32 mapId, float x, float y, float z, bool idle = false, bool react = false,
|
||||
bool normal_only = false, bool exact_waypoint = false);
|
||||
bool MoveTo(Unit* target, float distance = 0.0f);
|
||||
bool MoveNear(WorldObject* target, float distance = sPlayerbotAIConfig->contactDistance);
|
||||
bool normal_only = false, bool exact_waypoint = false, MovementPriority priority = MovementPriority::MOVEMENT_NORMAL);
|
||||
bool MoveTo(Unit* target, float distance = 0.0f, MovementPriority priority = MovementPriority::MOVEMENT_NORMAL);
|
||||
bool MoveNear(WorldObject* target, float distance = sPlayerbotAIConfig->contactDistance, MovementPriority priority = MovementPriority::MOVEMENT_NORMAL);
|
||||
float GetFollowAngle();
|
||||
bool Follow(Unit* target, float distance = sPlayerbotAIConfig->followDistance);
|
||||
bool Follow(Unit* target, float distance, float angle);
|
||||
@@ -40,13 +42,13 @@ protected:
|
||||
bool IsMovingAllowed(Unit* target);
|
||||
bool IsMovingAllowed(uint32 mapId, float x, float y, float z);
|
||||
bool IsDuplicateMove(uint32 mapId, float x, float y, float z);
|
||||
bool IsWaitingForLastMove();
|
||||
bool IsWaitingForLastMove(MovementPriority priority);
|
||||
bool IsMovingAllowed();
|
||||
bool Flee(Unit* target);
|
||||
void ClearIdleState();
|
||||
void UpdateMovementState();
|
||||
bool MoveAway(Unit* target);
|
||||
bool MoveInside(uint32 mapId, float x, float y, float z, float distance = sPlayerbotAIConfig->followDistance);
|
||||
bool MoveInside(uint32 mapId, float x, float y, float z, float distance = sPlayerbotAIConfig->followDistance, MovementPriority priority = MovementPriority::MOVEMENT_NORMAL);
|
||||
void CreateWp(Player* wpOwner, float x, float y, float z, float o, uint32 entry, bool important = false);
|
||||
Position BestPositionForMeleeToFlee(Position pos, float radius);
|
||||
Position BestPositionForRangedToFlee(Position pos, float radius);
|
||||
@@ -94,7 +96,7 @@ class AvoidAoeAction : public MovementAction
|
||||
{
|
||||
public:
|
||||
AvoidAoeAction(PlayerbotAI* botAI, int moveInterval = 1000)
|
||||
: MovementAction(botAI, "avoid aoe"), moveInterval(moveInterval)
|
||||
: MovementAction(botAI, "aaoe"), moveInterval(moveInterval)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -87,7 +87,7 @@ bool SummonAction::Execute(Event event)
|
||||
if (master->GetSession()->GetSecurity() >= SEC_PLAYER)
|
||||
{
|
||||
// botAI->GetAiObjectContext()->GetValue<GuidVector>("prioritized targets")->Set({});
|
||||
SET_AI_VALUE(std::list<FleeInfo>, "recently flee info", {});
|
||||
AI_VALUE(std::list<FleeInfo>&, "recently flee info").clear();
|
||||
return Teleport(master, bot);
|
||||
}
|
||||
|
||||
@@ -215,10 +215,12 @@ bool SummonAction::Teleport(Player* summoner, Player* player)
|
||||
bool revive =
|
||||
sPlayerbotAIConfig->reviveBotWhenSummoned == 2 ||
|
||||
(sPlayerbotAIConfig->reviveBotWhenSummoned == 1 && !master->IsInCombat() && master->IsAlive());
|
||||
|
||||
if (bot->isDead() && revive)
|
||||
{
|
||||
bot->ResurrectPlayer(1.0f, false);
|
||||
botAI->TellMasterNoFacing("I live, again!");
|
||||
botAI->GetAiObjectContext()->GetValue<GuidVector>("prioritized targets")->Set({});
|
||||
}
|
||||
|
||||
player->GetMotionMaster()->Clear();
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
|
||||
#include "RaidNaxxActions.h"
|
||||
|
||||
#include "LastMovementValue.h"
|
||||
#include "ObjectGuid.h"
|
||||
#include "PlayerbotAIConfig.h"
|
||||
#include "Playerbots.h"
|
||||
@@ -23,7 +24,7 @@ bool GrobbulusGoBehindAction::Execute(Event event)
|
||||
float z = boss->GetPositionZ();
|
||||
float rx = x + cos(orientation) * distance;
|
||||
float ry = y + sin(orientation) * distance;
|
||||
return MoveTo(bot->GetMapId(), rx, ry, z);
|
||||
return MoveTo(bot->GetMapId(), rx, ry, z, false, false, false, false, MovementPriority::MOVEMENT_COMBAT);
|
||||
}
|
||||
|
||||
uint32 RotateAroundTheCenterPointAction::FindNearestWaypoint()
|
||||
@@ -91,7 +92,7 @@ bool HeiganDanceMeleeAction::Execute(Event event)
|
||||
}
|
||||
assert(curr_safe >= 0 && curr_safe <= 3);
|
||||
return MoveInside(bot->GetMapId(), waypoints[curr_safe].first, waypoints[curr_safe].second, bot->GetPositionZ(),
|
||||
botAI->IsMainTank(bot) ? 0 : 0);
|
||||
botAI->IsMainTank(bot) ? 0 : 0, MovementPriority::MOVEMENT_COMBAT);
|
||||
}
|
||||
|
||||
bool HeiganDanceRangedAction::Execute(Event event)
|
||||
@@ -99,10 +100,10 @@ bool HeiganDanceRangedAction::Execute(Event event)
|
||||
CalculateSafe();
|
||||
if (prev_phase != 1)
|
||||
{
|
||||
return MoveTo(bot->GetMapId(), platform.first, platform.second, 276.54f);
|
||||
return MoveTo(bot->GetMapId(), platform.first, platform.second, 276.54f, false, false, false, false, MovementPriority::MOVEMENT_COMBAT);
|
||||
}
|
||||
botAI->InterruptSpell();
|
||||
return MoveInside(bot->GetMapId(), waypoints[curr_safe].first, waypoints[curr_safe].second, bot->GetPositionZ(), 0);
|
||||
return MoveInside(bot->GetMapId(), waypoints[curr_safe].first, waypoints[curr_safe].second, bot->GetPositionZ(), 0, MovementPriority::MOVEMENT_COMBAT);
|
||||
}
|
||||
|
||||
bool ThaddiusAttackNearestPetAction::isUseful()
|
||||
@@ -128,7 +129,7 @@ bool ThaddiusAttackNearestPetAction::Execute(Event event)
|
||||
Unit* target = helper.GetNearestPet();
|
||||
if (!bot->IsWithinLOSInMap(target))
|
||||
{
|
||||
return MoveTo(target);
|
||||
return MoveTo(target, 0, MovementPriority::MOVEMENT_COMBAT);
|
||||
}
|
||||
if (AI_VALUE(Unit*, "current target") != target)
|
||||
{
|
||||
@@ -137,12 +138,12 @@ bool ThaddiusAttackNearestPetAction::Execute(Event event)
|
||||
if (botAI->IsTank(bot) && AI_VALUE2(bool, "has aggro", "current target"))
|
||||
{
|
||||
std::pair<float, float> posForTank = helper.PetPhaseGetPosForTank();
|
||||
return MoveTo(533, posForTank.first, posForTank.second, helper.tankPosZ);
|
||||
return MoveTo(533, posForTank.first, posForTank.second, helper.tankPosZ, false, false, false, false, MovementPriority::MOVEMENT_COMBAT);
|
||||
}
|
||||
if (botAI->IsRanged(bot))
|
||||
{
|
||||
std::pair<float, float> posForRanged = helper.PetPhaseGetPosForRanged();
|
||||
return MoveTo(533, posForRanged.first, posForRanged.second, helper.tankPosZ);
|
||||
return MoveTo(533, posForRanged.first, posForRanged.second, helper.tankPosZ, false, false, false, false, MovementPriority::MOVEMENT_COMBAT);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -170,22 +171,28 @@ bool ThaddiusMoveToPlatformAction::Execute(Event event)
|
||||
{
|
||||
if (is_left)
|
||||
{
|
||||
if (!MoveTo(bot->GetMapId(), position[0].first, position[0].second, high_z))
|
||||
if (!MoveTo(bot->GetMapId(), position[0].first, position[0].second, high_z, false, false, false, false, MovementPriority::MOVEMENT_COMBAT))
|
||||
{
|
||||
bot->TeleportTo(bot->GetMapId(), position[2].first, position[2].second, low_z, bot->GetOrientation());
|
||||
float distance = bot->GetExactDist2d(position[0].first, position[0].second);
|
||||
if (distance < sPlayerbotAIConfig->contactDistance)
|
||||
JumpTo(bot->GetMapId(), position[2].first, position[2].second, low_z, MovementPriority::MOVEMENT_COMBAT);
|
||||
// bot->TeleportTo(bot->GetMapId(), position[2].first, position[2].second, low_z, bot->GetOrientation());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!MoveTo(bot->GetMapId(), position[1].first, position[1].second, high_z))
|
||||
if (!MoveTo(bot->GetMapId(), position[1].first, position[1].second, high_z, false, false, false, false, MovementPriority::MOVEMENT_COMBAT))
|
||||
{
|
||||
bot->TeleportTo(bot->GetMapId(), position[3].first, position[3].second, low_z, bot->GetOrientation());
|
||||
float distance = bot->GetExactDist2d(position[1].first, position[1].second);
|
||||
if (distance < sPlayerbotAIConfig->contactDistance)
|
||||
JumpTo(bot->GetMapId(), position[3].first, position[3].second, low_z, MovementPriority::MOVEMENT_COMBAT);
|
||||
// bot->TeleportTo(bot->GetMapId(), position[3].first, position[3].second, low_z, bot->GetOrientation());
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return MoveTo(bot->GetMapId(), position[4].first, position[4].second, low_z);
|
||||
return MoveTo(bot->GetMapId(), position[4].first, position[4].second, low_z, false, false, false, false, MovementPriority::MOVEMENT_COMBAT);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -225,7 +232,7 @@ bool ThaddiusMovePolarityAction::Execute(Event event)
|
||||
idx = 2;
|
||||
}
|
||||
idx = idx * 2 + botAI->IsRanged(bot);
|
||||
return MoveTo(bot->GetMapId(), position[idx].first, position[idx].second, bot->GetPositionZ());
|
||||
return MoveTo(bot->GetMapId(), position[idx].first, position[idx].second, bot->GetPositionZ(), false, false, false, false, MovementPriority::MOVEMENT_COMBAT);
|
||||
}
|
||||
|
||||
bool RazuviousUseObedienceCrystalAction::Execute(Event event)
|
||||
@@ -322,7 +329,7 @@ bool RazuviousUseObedienceCrystalAction::Execute(Event event)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (MoveTo(unit))
|
||||
if (MoveTo(unit, 0.0f, MovementPriority::MOVEMENT_COMBAT))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
@@ -352,7 +359,7 @@ bool RazuviousUseObedienceCrystalAction::Execute(Event event)
|
||||
{
|
||||
if (bot->GetDistance2d(target) > sPlayerbotAIConfig->spellDistance)
|
||||
{
|
||||
return MoveNear(target, sPlayerbotAIConfig->spellDistance);
|
||||
return MoveNear(target, sPlayerbotAIConfig->spellDistance, MovementPriority::MOVEMENT_COMBAT);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -396,7 +403,7 @@ bool HorsemanAttractAlternativelyAction::Execute(Event event)
|
||||
}
|
||||
helper.CalculatePosToGo(bot);
|
||||
auto [posX, posY] = helper.CurrentAttractPos();
|
||||
if (MoveTo(bot->GetMapId(), posX, posY, helper.posZ))
|
||||
if (MoveTo(bot->GetMapId(), posX, posY, helper.posZ, false, false, false, false, MovementPriority::MOVEMENT_COMBAT))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
@@ -444,7 +451,7 @@ bool HorsemanAttactInOrderAction::Execute(Event event)
|
||||
}
|
||||
if (!bot->IsWithinLOSInMap(target))
|
||||
{
|
||||
return MoveNear(target, 22.0f);
|
||||
return MoveNear(target, 22.0f, MovementPriority::MOVEMENT_COMBAT);
|
||||
}
|
||||
return Attack(target);
|
||||
}
|
||||
@@ -461,7 +468,7 @@ bool SapphironGroundPositionAction::Execute(Event event)
|
||||
{
|
||||
if (AI_VALUE2(bool, "has aggro", "current target"))
|
||||
{
|
||||
return MoveTo(NAXX_MAP_ID, helper.mainTankPos.first, helper.mainTankPos.second, helper.GENERIC_HEIGHT);
|
||||
return MoveTo(NAXX_MAP_ID, helper.mainTankPos.first, helper.mainTankPos.second, helper.GENERIC_HEIGHT, false, false, false, false, MovementPriority::MOVEMENT_COMBAT);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -485,14 +492,14 @@ bool SapphironGroundPositionAction::Execute(Event event)
|
||||
distance = 5.0f;
|
||||
}
|
||||
return MoveTo(NAXX_MAP_ID, helper.center.first + cos(angle) * distance,
|
||||
helper.center.second + sin(angle) * distance, helper.GENERIC_HEIGHT);
|
||||
helper.center.second + sin(angle) * distance, helper.GENERIC_HEIGHT, false, false, false, false, MovementPriority::MOVEMENT_COMBAT);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::vector<float> dest;
|
||||
if (helper.FindPosToAvoidChill(dest))
|
||||
{
|
||||
return MoveTo(NAXX_MAP_ID, dest[0], dest[1], dest[2]);
|
||||
return MoveTo(NAXX_MAP_ID, dest[0], dest[1], dest[2], false, false, false, false, MovementPriority::MOVEMENT_COMBAT);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
@@ -513,7 +520,7 @@ bool SapphironFlightPositionAction::Execute(Event event)
|
||||
std::vector<float> dest;
|
||||
if (helper.FindPosToAvoidChill(dest))
|
||||
{
|
||||
return MoveTo(NAXX_MAP_ID, dest[0], dest[1], dest[2]);
|
||||
return MoveTo(NAXX_MAP_ID, dest[0], dest[1], dest[2], false, false, false, false, MovementPriority::MOVEMENT_COMBAT);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
@@ -548,7 +555,7 @@ bool SapphironFlightPositionAction::MoveToNearestIcebolt()
|
||||
{
|
||||
float angle = boss->GetAngle(playerWithIcebolt);
|
||||
return MoveTo(NAXX_MAP_ID, playerWithIcebolt->GetPositionX() + cos(angle) * 3.0f,
|
||||
playerWithIcebolt->GetPositionY() + sin(angle) * 3.0f, helper.GENERIC_HEIGHT);
|
||||
playerWithIcebolt->GetPositionY() + sin(angle) * 3.0f, helper.GENERIC_HEIGHT, false, false, false, false, MovementPriority::MOVEMENT_COMBAT);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
@@ -679,7 +686,7 @@ bool KelthuzadPositionAction::Execute(Event event)
|
||||
{
|
||||
if (AI_VALUE(Unit*, "current target") == nullptr)
|
||||
{
|
||||
return MoveInside(NAXX_MAP_ID, helper.center.first, helper.center.second, bot->GetPositionZ(), 3.0f);
|
||||
return MoveInside(NAXX_MAP_ID, helper.center.first, helper.center.second, bot->GetPositionZ(), 3.0f, MovementPriority::MOVEMENT_COMBAT);
|
||||
}
|
||||
}
|
||||
else if (helper.IsPhaseTwo())
|
||||
@@ -692,7 +699,7 @@ bool KelthuzadPositionAction::Execute(Event event)
|
||||
{
|
||||
if (AI_VALUE2(bool, "has aggro", "current target"))
|
||||
{
|
||||
return MoveTo(NAXX_MAP_ID, helper.tank_pos.first, helper.tank_pos.second, bot->GetPositionZ());
|
||||
return MoveTo(NAXX_MAP_ID, helper.tank_pos.first, helper.tank_pos.second, bot->GetPositionZ(), false, false, false, false, MovementPriority::MOVEMENT_COMBAT);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -715,7 +722,7 @@ bool KelthuzadPositionAction::Execute(Event event)
|
||||
float dx, dy;
|
||||
dx = helper.center.first + cos(angle) * distance;
|
||||
dy = helper.center.second + sin(angle) * distance;
|
||||
return MoveTo(NAXX_MAP_ID, dx, dy, bot->GetPositionZ());
|
||||
return MoveTo(NAXX_MAP_ID, dx, dy, bot->GetPositionZ(), false, false, false, false, MovementPriority::MOVEMENT_COMBAT);
|
||||
}
|
||||
else if (botAI->IsTank(bot))
|
||||
{
|
||||
@@ -725,7 +732,7 @@ bool KelthuzadPositionAction::Execute(Event event)
|
||||
botAI->IsAssistTank(cur_tar->GetVictim()->ToPlayer()))
|
||||
{
|
||||
return MoveTo(NAXX_MAP_ID, helper.assist_tank_pos.first, helper.assist_tank_pos.second,
|
||||
bot->GetPositionZ());
|
||||
bot->GetPositionZ(), false, false, false, false, MovementPriority::MOVEMENT_COMBAT);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -747,7 +754,7 @@ bool KelthuzadPositionAction::Execute(Event event)
|
||||
}
|
||||
dx = shadow_fissure->GetPositionX() + cos(angle) * 10.0f;
|
||||
dy = shadow_fissure->GetPositionY() + sin(angle) * 10.0f;
|
||||
return MoveTo(NAXX_MAP_ID, dx, dy, bot->GetPositionZ());
|
||||
return MoveTo(NAXX_MAP_ID, dx, dy, bot->GetPositionZ(), false, false, false, false, MovementPriority::MOVEMENT_COMBAT);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
@@ -846,11 +853,11 @@ bool AnubrekhanPositionAction::Execute(Event event)
|
||||
next_point = nearest;
|
||||
}
|
||||
return MoveTo(bot->GetMapId(), waypoints[next_point].first, waypoints[next_point].second,
|
||||
bot->GetPositionZ());
|
||||
bot->GetPositionZ(), false, false, false, false, MovementPriority::MOVEMENT_COMBAT);
|
||||
}
|
||||
else
|
||||
{
|
||||
return MoveInside(533, 3272.49f, -3476.27f, bot->GetPositionZ(), 3.0f);
|
||||
return MoveInside(533, 3272.49f, -3476.27f, bot->GetPositionZ(), 3.0f, MovementPriority::MOVEMENT_COMBAT);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
@@ -964,12 +971,12 @@ bool GluthPositionAction::Execute(Event event)
|
||||
if (raid25)
|
||||
{
|
||||
return MoveTo(NAXX_MAP_ID, helper.mainTankPos25.first, helper.mainTankPos25.second,
|
||||
bot->GetPositionZ());
|
||||
bot->GetPositionZ(), false, false, false, false, MovementPriority::MOVEMENT_COMBAT);
|
||||
}
|
||||
else
|
||||
{
|
||||
return MoveTo(NAXX_MAP_ID, helper.mainTankPos10.first, helper.mainTankPos10.second,
|
||||
bot->GetPositionZ());
|
||||
bot->GetPositionZ(), false, false, false, false, MovementPriority::MOVEMENT_COMBAT);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -978,7 +985,7 @@ bool GluthPositionAction::Execute(Event event)
|
||||
if (helper.BeforeDecimate())
|
||||
{
|
||||
return MoveTo(bot->GetMapId(), helper.beforeDecimatePos.first, helper.beforeDecimatePos.second,
|
||||
bot->GetPositionZ());
|
||||
bot->GetPositionZ(), false, false, false, false, MovementPriority::MOVEMENT_COMBAT);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -987,7 +994,7 @@ bool GluthPositionAction::Execute(Event event)
|
||||
uint32 nearest = FindNearestWaypoint();
|
||||
uint32 next_point = (nearest + 1) % intervals;
|
||||
return MoveTo(bot->GetMapId(), waypoints[next_point].first, waypoints[next_point].second,
|
||||
bot->GetPositionZ());
|
||||
bot->GetPositionZ(), false, false, false, false, MovementPriority::MOVEMENT_COMBAT);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -998,19 +1005,19 @@ bool GluthPositionAction::Execute(Event event)
|
||||
if (botAI->GetClassIndex(bot, CLASS_HUNTER) == 0)
|
||||
{
|
||||
return MoveInside(NAXX_MAP_ID, helper.leftSlowDownPos.first, helper.leftSlowDownPos.second,
|
||||
bot->GetPositionZ(), 0.0f);
|
||||
bot->GetPositionZ(), 0.0f, MovementPriority::MOVEMENT_COMBAT);
|
||||
}
|
||||
if (botAI->GetClassIndex(bot, CLASS_HUNTER) == 1)
|
||||
{
|
||||
return MoveInside(NAXX_MAP_ID, helper.rightSlowDownPos.first, helper.rightSlowDownPos.second,
|
||||
bot->GetPositionZ(), 0.0f);
|
||||
bot->GetPositionZ(), 0.0f, MovementPriority::MOVEMENT_COMBAT);
|
||||
}
|
||||
}
|
||||
return MoveInside(NAXX_MAP_ID, helper.rangedPos.first, helper.rangedPos.second, bot->GetPositionZ(), 3.0f);
|
||||
return MoveInside(NAXX_MAP_ID, helper.rangedPos.first, helper.rangedPos.second, bot->GetPositionZ(), 3.0f, MovementPriority::MOVEMENT_COMBAT);
|
||||
}
|
||||
else if (botAI->IsHeal(bot))
|
||||
{
|
||||
return MoveInside(NAXX_MAP_ID, helper.healPos.first, helper.healPos.second, bot->GetPositionZ(), 0.0f);
|
||||
return MoveInside(NAXX_MAP_ID, helper.healPos.first, helper.healPos.second, bot->GetPositionZ(), 0.0f, MovementPriority::MOVEMENT_COMBAT);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -1051,12 +1058,12 @@ bool LoathebPositionAction::Execute(Event event)
|
||||
{
|
||||
if (AI_VALUE2(bool, "has aggro", "boss target"))
|
||||
{
|
||||
return MoveTo(533, helper.mainTankPos.first, helper.mainTankPos.second, bot->GetPositionZ());
|
||||
return MoveTo(533, helper.mainTankPos.first, helper.mainTankPos.second, bot->GetPositionZ(), false, false, false, false, MovementPriority::MOVEMENT_COMBAT);
|
||||
}
|
||||
}
|
||||
else if (botAI->IsRanged(bot))
|
||||
{
|
||||
return MoveInside(533, helper.rangePos.first, helper.rangePos.second, bot->GetPositionZ(), 1.0f);
|
||||
return MoveInside(533, helper.rangePos.first, helper.rangePos.second, bot->GetPositionZ(), 1.0f, MovementPriority::MOVEMENT_COMBAT);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@ LastMovement::LastMovement(LastMovement& other)
|
||||
lastMoveShort = other.lastMoveShort;
|
||||
nextTeleport = other.nextTeleport;
|
||||
lastPath = other.lastPath;
|
||||
priority = other.priority;
|
||||
}
|
||||
|
||||
void LastMovement::clear()
|
||||
@@ -41,6 +42,7 @@ void LastMovement::clear()
|
||||
nextTeleport = 0;
|
||||
msTime = 0;
|
||||
lastdelayTime = 0;
|
||||
priority = MovementPriority::MOVEMENT_NORMAL;
|
||||
}
|
||||
|
||||
void LastMovement::Set(Unit* follow)
|
||||
@@ -51,7 +53,7 @@ void LastMovement::Set(Unit* follow)
|
||||
lastFollow = follow;
|
||||
}
|
||||
|
||||
void LastMovement::Set(uint32 mapId, float x, float y, float z, float ori, float delayTime)
|
||||
void LastMovement::Set(uint32 mapId, float x, float y, float z, float ori, float delayTime, MovementPriority pri)
|
||||
{
|
||||
lastMoveToMapId = mapId;
|
||||
lastMoveToX = x;
|
||||
@@ -62,6 +64,7 @@ void LastMovement::Set(uint32 mapId, float x, float y, float z, float ori, float
|
||||
lastMoveShort = WorldPosition(mapId, x, y, z, ori);
|
||||
msTime = getMSTime();
|
||||
lastdelayTime = delayTime;
|
||||
priority = pri;
|
||||
}
|
||||
|
||||
void LastMovement::setShort(WorldPosition point)
|
||||
|
||||
@@ -13,6 +13,15 @@
|
||||
class PlayerbotAI;
|
||||
class Unit;
|
||||
|
||||
// High priority movement can override the previous low priority one
|
||||
enum class MovementPriority
|
||||
{
|
||||
MOVEMENT_IDLE,
|
||||
MOVEMENT_NORMAL,
|
||||
MOVEMENT_COMBAT,
|
||||
MOVEMENT_FORCED
|
||||
};
|
||||
|
||||
class LastMovement
|
||||
{
|
||||
public:
|
||||
@@ -28,14 +37,14 @@ public:
|
||||
lastMoveShort = other.lastMoveShort;
|
||||
lastPath = other.lastPath;
|
||||
nextTeleport = other.nextTeleport;
|
||||
|
||||
priority = other.priority;
|
||||
return *this;
|
||||
};
|
||||
|
||||
void clear();
|
||||
|
||||
void Set(Unit* follow);
|
||||
void Set(uint32 mapId, float x, float y, float z, float ori, float delayTime);
|
||||
void Set(uint32 mapId, float x, float y, float z, float ori, float delayTime, MovementPriority priority = MovementPriority::MOVEMENT_NORMAL);
|
||||
|
||||
void setShort(WorldPosition point);
|
||||
void setPath(TravelPath path);
|
||||
@@ -53,6 +62,7 @@ public:
|
||||
float lastdelayTime;
|
||||
WorldPosition lastMoveShort;
|
||||
uint32 msTime;
|
||||
MovementPriority priority;
|
||||
TravelPath lastPath;
|
||||
time_t nextTeleport;
|
||||
std::future<TravelPath> future;
|
||||
|
||||
Reference in New Issue
Block a user