Movement priority

This commit is contained in:
Yunfan Li
2024-08-14 18:23:24 +08:00
parent 765d0305ef
commit 7b0bb20078
12 changed files with 216 additions and 183 deletions

View File

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

View File

@@ -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;

View File

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

View File

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

View File

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

View File

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

View File

@@ -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;

View File

@@ -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)
{
}

View File

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

View File

@@ -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;
}

View File

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

View File

@@ -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;