mirror of
https://github.com/mod-playerbots/mod-playerbots.git
synced 2026-01-13 00:58:33 +00:00
Movement priority
This commit is contained in:
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user