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