removed movementAction changed made due core movement changes

This commit is contained in:
bash
2025-11-24 11:55:03 +01:00
parent cf743a186a
commit cddd406b1c

View File

@@ -10,7 +10,6 @@
#include <iomanip>
#include <string>
#include "Corpse.h"
#include "Event.h"
#include "FleeManager.h"
#include "G3D/Vector3.h"
@@ -42,6 +41,7 @@
#include "Unit.h"
#include "Vehicle.h"
#include "WaypointMovementGenerator.h"
#include "Corpse.h"
MovementAction::MovementAction(PlayerbotAI* botAI, std::string const name) : Action(botAI, name)
{
@@ -192,23 +192,30 @@ bool MovementAction::MoveTo(uint32 mapId, float x, float y, float z, bool idle,
{
return false;
}
bool generatePath = !bot->IsFlying() && !bot->isSwimming();
bool disableMoveSplinePath =
sPlayerbotAIConfig->disableMoveSplinePath >= 2 ||
(sPlayerbotAIConfig->disableMoveSplinePath == 1 && bot->InBattleground());
bool disableMoveSplinePath = sPlayerbotAIConfig->disableMoveSplinePath >= 2 ||
(sPlayerbotAIConfig->disableMoveSplinePath == 1 && bot->InBattleground());
if (Vehicle* vehicle = bot->GetVehicle())
{
VehicleSeatEntry const* seat = vehicle->GetSeatForPassenger(bot);
Unit* vehicleBase = vehicle->GetBase();
generatePath = !vehicleBase || !vehicleBase->CanFly();
generatePath = vehicleBase->CanFly();
if (!vehicleBase || !seat || !seat->CanControl()) // is passenger and cant move anyway
return false;
float distance = vehicleBase->GetExactDist(x, y, z); // use vehicle distance, not bot
if (distance > 0.01f)
{
DoMovePoint(vehicleBase, x, y, z, generatePath, backwards);
MotionMaster& mm = *vehicleBase->GetMotionMaster(); // need to move vehicle, not bot
mm.Clear();
if (!backwards)
{
mm.MovePoint(0, x, y, z, generatePath);
}
else
{
mm.MovePointBackwards(0, x, y, z, generatePath);
}
float speed = backwards ? vehicleBase->GetSpeed(MOVE_RUN_BACK) : vehicleBase->GetSpeed(MOVE_RUN);
float delay = 1000.0f * (distance / speed);
if (lessDelay)
@@ -234,7 +241,16 @@ bool MovementAction::MoveTo(uint32 mapId, float x, float y, float z, bool idle,
// bot->CastStop();
// botAI->InterruptSpell();
// }
DoMovePoint(bot, x, y, z, generatePath, backwards);
MotionMaster& mm = *bot->GetMotionMaster();
mm.Clear();
if (!backwards)
{
mm.MovePoint(0, x, y, z, generatePath);
}
else
{
mm.MovePointBackwards(0, x, y, z, generatePath);
}
float delay = 1000.0f * MoveDelay(distance, backwards);
if (lessDelay)
{
@@ -252,7 +268,9 @@ bool MovementAction::MoveTo(uint32 mapId, float x, float y, float z, bool idle,
Movement::PointsArray path =
SearchForBestPath(x, y, z, modifiedZ, sPlayerbotAIConfig->maxMovementSearchTime, normal_only);
if (modifiedZ == INVALID_HEIGHT)
{
return false;
}
float distance = bot->GetExactDist(x, y, modifiedZ);
if (distance > 0.01f)
{
@@ -264,8 +282,17 @@ bool MovementAction::MoveTo(uint32 mapId, float x, float y, float z, bool idle,
// bot->CastStop();
// botAI->InterruptSpell();
// }
MotionMaster& mm = *bot->GetMotionMaster();
G3D::Vector3 endP = path.back();
DoMovePoint(bot, x, y, z, generatePath, backwards);
mm.Clear();
if (!backwards)
{
mm.MovePoint(0, x, y, z, generatePath);
}
else
{
mm.MovePointBackwards(0, x, y, z, generatePath);
}
float delay = 1000.0f * MoveDelay(distance, backwards);
if (lessDelay)
{
@@ -482,8 +509,7 @@ bool MovementAction::MoveTo(uint32 mapId, float x, float y, float z, bool idle,
// {
// AI_VALUE(LastMovement&, "last area trigger").lastAreaTrigger = entry;
// }
// else
// {
// else {
// LOG_DEBUG("playerbots", "!entry");
// return bot->TeleportTo(movePosition.getMapId(), movePosition.getX(), movePosition.getY(),
// movePosition.getZ(), movePosition.getO(), 0);
@@ -533,7 +559,9 @@ bool MovementAction::MoveTo(uint32 mapId, float x, float y, float z, bool idle,
// bool goTaxi = bot->ActivateTaxiPathTo({ tEntry->from, tEntry->to }, unit, 1);
// if (botAI->HasCheat(BotCheatMask::gold))
// {
// bot->SetMoney(botMoney);
// }
// LOG_DEBUG("playerbots", "goTaxi");
// return goTaxi;
// }
@@ -824,16 +852,15 @@ bool MovementAction::ReachCombatTo(Unit* target, float distance)
float deltaAngle = Position::NormalizeOrientation(targetOrientation - target->GetAngle(bot));
if (deltaAngle > M_PI)
deltaAngle -= 2.0f * M_PI; // -PI..PI
deltaAngle -= 2.0f * M_PI; // -PI..PI
// if target is moving forward and moving far away, predict the position
bool behind = fabs(deltaAngle) > M_PI_2;
if (target->HasUnitMovementFlag(MOVEMENTFLAG_FORWARD) && behind)
{
if (target->HasUnitMovementFlag(MOVEMENTFLAG_FORWARD) && behind) {
float predictDis = std::min(3.0f, target->GetObjectSize() * 2);
tx += cos(target->GetOrientation()) * predictDis;
ty += sin(target->GetOrientation()) * predictDis;
if (!target->GetMap()->CheckCollisionAndGetValidCoords(target, target->GetPositionX(), target->GetPositionY(),
target->GetPositionZ(), tx, ty, tz))
if (!target->GetMap()->CheckCollisionAndGetValidCoords(target, target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(),
tx, ty, tz))
{
tx = target->GetPositionX();
ty = target->GetPositionY();
@@ -951,8 +978,9 @@ bool MovementAction::IsMovingAllowed()
return false;
if (bot->isFrozen() || bot->IsPolymorphed() || (bot->isDead() && !bot->HasPlayerFlag(PLAYER_FLAGS_GHOST)) ||
bot->IsBeingTeleported() || bot->HasRootAura() || bot->HasSpiritOfRedemptionAura() || bot->HasConfuseAura() ||
bot->IsCharmed() || bot->HasStunAura() || bot->IsInFlight() || bot->HasUnitState(UNIT_STATE_LOST_CONTROL))
bot->IsBeingTeleported() || bot->HasRootAura() || bot->HasSpiritOfRedemptionAura() ||
bot->HasConfuseAura() || bot->IsCharmed() || bot->HasStunAura() ||
bot->IsInFlight() || bot->HasUnitState(UNIT_STATE_LOST_CONTROL))
return false;
if (bot->GetMotionMaster()->GetMotionSlotType(MOTION_SLOT_CONTROLLED) != NULL_MOTION_TYPE)
@@ -960,8 +988,7 @@ bool MovementAction::IsMovingAllowed()
return false;
}
// if (bot->HasUnitMovementFlag(MOVEMENTFLAG_FALLING))
// {
// if (bot->HasUnitMovementFlag(MOVEMENTFLAG_FALLING)) {
// return false;
// }
return bot->GetMotionMaster()->GetCurrentMovementGeneratorType() != FLIGHT_MOTION_TYPE;
@@ -971,95 +998,53 @@ bool MovementAction::Follow(Unit* target, float distance) { return Follow(target
void MovementAction::UpdateMovementState()
{
const bool isCurrentlyRestricted = // see if the bot is currently slowed, rooted, or otherwise unable to move
bot->isFrozen() ||
bot->IsPolymorphed() ||
bot->HasRootAura() ||
bot->HasStunAura() ||
bot->HasConfuseAura() ||
bot->HasUnitState(UNIT_STATE_LOST_CONTROL);
int8 botInLiquidState = bot->GetLiquidData().Status;
// no update movement flags while movement is current restricted.
if (!isCurrentlyRestricted && bot->IsAlive())
if (botInLiquidState == LIQUID_MAP_IN_WATER || botInLiquidState == LIQUID_MAP_UNDER_WATER)
{
// state flags
const auto master = botAI ? botAI->GetMaster() : nullptr; // real player or not
const bool masterIsFlying = master ? master->HasUnitMovementFlag(MOVEMENTFLAG_FLYING) : true;
const bool masterIsSwimming = master ? master->HasUnitMovementFlag(MOVEMENTFLAG_SWIMMING) : true;
const auto liquidState = bot->GetLiquidData().Status; // default LIQUID_MAP_NO_WATER
const float gZ = bot->GetMapWaterOrGroundLevel(bot->GetPositionX(), bot->GetPositionY(), bot->GetPositionZ());
const bool wantsToFly = bot->HasIncreaseMountedFlightSpeedAura() || bot->HasFlyAura();
const bool isFlying = bot->HasUnitMovementFlag(MOVEMENTFLAG_FLYING);
const bool isWaterArea = liquidState != LIQUID_MAP_NO_WATER;
const bool isUnderWater = liquidState == LIQUID_MAP_UNDER_WATER;
const bool isInWater = liquidState == LIQUID_MAP_IN_WATER;
const bool isWaterWalking = bot->HasUnitMovementFlag(MOVEMENTFLAG_WATERWALKING);
const bool isSwimming = bot->HasUnitMovementFlag(MOVEMENTFLAG_SWIMMING);
const bool wantsToWaterWalk = bot->HasWaterWalkAura();
const bool wantsToSwim = isInWater || isUnderWater;
const bool onGroundZ = (bot->GetPositionZ() < gZ + 1.f) && !isWaterArea;
bool movementFlagsUpdated = false;
// handle water state
if (isWaterArea && !isFlying)
{
// water walking
if (wantsToWaterWalk && !isWaterWalking && !masterIsSwimming)
{
bot->RemoveUnitMovementFlag(MOVEMENTFLAG_SWIMMING);
bot->AddUnitMovementFlag(MOVEMENTFLAG_WATERWALKING);
movementFlagsUpdated = true;
}
// swimming
else if (wantsToSwim && !isSwimming && masterIsSwimming)
{
bot->RemoveUnitMovementFlag(MOVEMENTFLAG_WATERWALKING);
bot->AddUnitMovementFlag(MOVEMENTFLAG_SWIMMING);
movementFlagsUpdated = true;
}
}
else if (isSwimming || isWaterWalking)
{
// reset water flags
bot->RemoveUnitMovementFlag(MOVEMENTFLAG_SWIMMING);
bot->RemoveUnitMovementFlag(MOVEMENTFLAG_WATERWALKING);
movementFlagsUpdated = true;
}
// handle flying state
if (wantsToFly && !isFlying && masterIsFlying)
{
bot->AddUnitMovementFlag(MOVEMENTFLAG_CAN_FLY);
bot->AddUnitMovementFlag(MOVEMENTFLAG_DISABLE_GRAVITY);
bot->AddUnitMovementFlag(MOVEMENTFLAG_FLYING);
movementFlagsUpdated = true;
}
else if ((!wantsToFly || onGroundZ) && isFlying)
{
bot->RemoveUnitMovementFlag(MOVEMENTFLAG_CAN_FLY);
bot->RemoveUnitMovementFlag(MOVEMENTFLAG_DISABLE_GRAVITY);
bot->RemoveUnitMovementFlag(MOVEMENTFLAG_FLYING);
movementFlagsUpdated = true;
}
// detect if movement restrictions have been lifted, CC just ended.
if (wasMovementRestricted)
movementFlagsUpdated = true; // refresh movement state to ensure animations play correctly
if (movementFlagsUpdated)
bot->SendMovementFlagUpdate();
bot->SetSwim(true);
}
else
{
bot->SetSwim(false);
}
// Save current state for the next check
bool onGround = bot->GetPositionZ() <
bot->GetMapWaterOrGroundLevel(bot->GetPositionX(), bot->GetPositionY(), bot->GetPositionZ()) + 1.0f;
// Keep bot->SendMovementFlagUpdate() withing the if statements to not intefere with bot behavior on ground/(shallow) waters
if (!bot->HasUnitMovementFlag(MOVEMENTFLAG_FLYING) &&
bot->HasAuraType(SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED) && !onGround)
{
bot->AddUnitMovementFlag(MOVEMENTFLAG_FLYING);
bot->SendMovementFlagUpdate();
}
else if (bot->HasUnitMovementFlag(MOVEMENTFLAG_FLYING) &&
(!bot->HasAuraType(SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED) || onGround))
{
bot->RemoveUnitMovementFlag(MOVEMENTFLAG_FLYING);
bot->SendMovementFlagUpdate();
}
// See if the bot is currently slowed, rooted, or otherwise unable to move
bool isCurrentlyRestricted = bot->isFrozen() || bot->IsPolymorphed() || bot->HasRootAura() || bot->HasStunAura() ||
bot->HasConfuseAura() || bot->HasUnitState(UNIT_STATE_LOST_CONTROL);
// Detect if movement restrictions have been lifted
if (wasMovementRestricted && !isCurrentlyRestricted && bot->IsAlive())
{
// CC just ended - refresh movement state to ensure animations play correctly
bot->SendMovementFlagUpdate();
}
// Save current state for the next check
wasMovementRestricted = isCurrentlyRestricted;
// Temporary speed increase in group
// if (botAI->HasRealPlayerMaster())
// {
// if (botAI->HasRealPlayerMaster()) {
// bot->SetSpeedRate(MOVE_RUN, 1.1f);
// }
// else
// {
// } else {
// bot->SetSpeedRate(MOVE_RUN, 1.0f);
// }
// check if target is not reachable (from Vmangos)
@@ -1068,7 +1053,7 @@ void MovementAction::UpdateMovementState()
// {
// if (Unit* pTarget = sServerFacade->GetChaseTarget(bot))
// {
// if (!bot->IsWithinMeleeRange(pTarget) && pTarget->IsCreature())
// if (!bot->IsWithinMeleeRange(pTarget) && pTarget->GetTypeId() == TYPEID_UNIT)
// {
// float angle = bot->GetAngle(pTarget);
// float distance = 5.0f;
@@ -1356,7 +1341,7 @@ float MovementAction::MoveDelay(float distance, bool backwards)
}
else
{
speed = backwards ? bot->GetSpeed(MOVE_RUN_BACK) : bot->GetSpeed(MOVE_RUN);
speed = backwards ? bot->GetSpeed(MOVE_RUN_BACK) :bot->GetSpeed(MOVE_RUN);
}
float delay = distance / speed;
return delay;
@@ -1386,7 +1371,8 @@ void MovementAction::SetNextMovementDelay(float delayMillis)
{
AI_VALUE(LastMovement&, "last movement")
.Set(bot->GetMapId(), bot->GetPositionX(), bot->GetPositionY(), bot->GetPositionZ(), bot->GetOrientation(),
delayMillis, MovementPriority::MOVEMENT_FORCED);
delayMillis,
MovementPriority::MOVEMENT_FORCED);
}
bool MovementAction::Flee(Unit* target)
@@ -1600,8 +1586,7 @@ bool MovementAction::MoveAway(Unit* target, float distance, bool backwards)
dz = bot->GetPositionZ();
exact = false;
}
if (MoveTo(target->GetMapId(), dx, dy, dz, false, false, true, exact, MovementPriority::MOVEMENT_COMBAT, false,
backwards))
if (MoveTo(target->GetMapId(), dx, dy, dz, false, false, true, exact, MovementPriority::MOVEMENT_COMBAT, false, backwards))
{
return true;
}
@@ -1623,8 +1608,7 @@ bool MovementAction::MoveAway(Unit* target, float distance, bool backwards)
dz = bot->GetPositionZ();
exact = false;
}
if (MoveTo(target->GetMapId(), dx, dy, dz, false, false, true, exact, MovementPriority::MOVEMENT_COMBAT, false,
backwards))
if (MoveTo(target->GetMapId(), dx, dy, dz, false, false, true, exact, MovementPriority::MOVEMENT_COMBAT, false, backwards))
{
return true;
}
@@ -1673,7 +1657,7 @@ bool MovementAction::Move(float angle, float distance)
float x = bot->GetPositionX() + cos(angle) * distance;
float y = bot->GetPositionY() + sin(angle) * distance;
// TODO do we need GetMapWaterOrGroundLevel() if we're using CheckCollisionAndGetValidCoords() ?
//TODO do we need GetMapWaterOrGroundLevel() if we're using CheckCollisionAndGetValidCoords() ?
float z = bot->GetMapWaterOrGroundLevel(x, y, bot->GetPositionZ());
if (z == -100000.0f || z == -200000.0f)
z = bot->GetPositionZ();
@@ -1696,8 +1680,7 @@ bool MovementAction::MoveInside(uint32 mapId, float x, float y, float z, float d
// float MovementAction::SearchBestGroundZForPath(float x, float y, float z, bool generatePath, float range, bool
// normal_only, float step)
// {
// if (!generatePath)
// {
// if (!generatePath) {
// return z;
// }
// float min_length = 100000.0f;
@@ -1708,12 +1691,10 @@ bool MovementAction::MoveInside(uint32 mapId, float x, float y, float z, float d
// modified_z = bot->GetMapWaterOrGroundLevel(x, y, z + delta);
// PathGenerator gen(bot);
// gen.CalculatePath(x, y, modified_z);
// if (gen.GetPathType() == PATHFIND_NORMAL && gen.getPathLength() < min_length)
// {
// if (gen.GetPathType() == PATHFIND_NORMAL && gen.getPathLength() < min_length) {
// min_length = gen.getPathLength();
// current_z = modified_z;
// if (abs(current_z - z) < 0.5f)
// {
// if (abs(current_z - z) < 0.5f) {
// return current_z;
// }
// }
@@ -1722,34 +1703,30 @@ bool MovementAction::MoveInside(uint32 mapId, float x, float y, float z, float d
// modified_z = bot->GetMapWaterOrGroundLevel(x, y, z + delta);
// PathGenerator gen(bot);
// gen.CalculatePath(x, y, modified_z);
// if (gen.GetPathType() == PATHFIND_NORMAL && gen.getPathLength() < min_length)
// {
// if (gen.GetPathType() == PATHFIND_NORMAL && gen.getPathLength() < min_length) {
// min_length = gen.getPathLength();
// current_z = modified_z;
// if (abs(current_z - z) < 0.5f)
// if (abs(current_z - z) < 0.5f) {
// return current_z;
// }
// }
// }
// for (delta = range / 2 + step; delta <= range; delta += 2) {
// modified_z = bot->GetMapWaterOrGroundLevel(x, y, z + delta);
// PathGenerator gen(bot);
// gen.CalculatePath(x, y, modified_z);
// if (gen.GetPathType() == PATHFIND_NORMAL && gen.getPathLength() < min_length)
// {
// if (gen.GetPathType() == PATHFIND_NORMAL && gen.getPathLength() < min_length) {
// min_length = gen.getPathLength();
// current_z = modified_z;
// if (abs(current_z - z) < 0.5f)
// {
// if (abs(current_z - z) < 0.5f) {
// return current_z;
// }
// }
// }
// if (current_z == INVALID_HEIGHT && normal_only)
// {
// if (current_z == INVALID_HEIGHT && normal_only) {
// return INVALID_HEIGHT;
// }
// if (current_z == INVALID_HEIGHT && !normal_only)
// {
// if (current_z == INVALID_HEIGHT && !normal_only) {
// return z;
// }
// return current_z;
@@ -1824,46 +1801,6 @@ const Movement::PointsArray MovementAction::SearchForBestPath(float x, float y,
return result;
}
void MovementAction::DoMovePoint(Unit* unit, float x, float y, float z, bool generatePath, bool backwards)
{
if (!unit)
return;
MotionMaster* mm = unit->GetMotionMaster();
if (!mm)
return;
// enable water walking
if (unit->HasUnitMovementFlag(MOVEMENTFLAG_WATERWALKING))
{
float gZ = unit->GetMapWaterOrGroundLevel(unit->GetPositionX(), unit->GetPositionY(), unit->GetPositionZ());
unit->UpdatePosition(unit->GetPositionX(), unit->GetPositionY(), gZ, false);
// z = gZ; no overwrite Z axe otherwise you cant steer the bots into swimming when water walking.
}
mm->Clear();
if (backwards)
{
mm->MovePointBackwards(
/*id*/ 0,
/*coords*/ x, y, z,
/*generatePath*/ generatePath,
/*forceDestination*/ false);
return;
}
else
{
mm->MovePoint(
/*id*/ 0,
/*coords*/ x, y, z,
/*forcedMovement*/ FORCED_MOVEMENT_NONE,
/*speed*/ 0.f,
/*orientation*/ 0.f,
/*generatePath*/ generatePath, // true => terrain path (2d mmap); false => straight spline (3d vmap)
/*forceDestination*/ false);
}
}
bool FleeAction::Execute(Event event)
{
return MoveAway(AI_VALUE(Unit*, "current target"), sPlayerbotAIConfig->fleeDistance, true);
@@ -1944,8 +1881,7 @@ bool AvoidAoeAction::AvoidAuraWithDynamicObj()
{
return false;
}
if (sPlayerbotAIConfig->aoeAvoidSpellWhitelist.find(spellInfo->Id) !=
sPlayerbotAIConfig->aoeAvoidSpellWhitelist.end())
if (sPlayerbotAIConfig->aoeAvoidSpellWhitelist.find(spellInfo->Id) != sPlayerbotAIConfig->aoeAvoidSpellWhitelist.end())
return false;
DynamicObject* dynOwner = aura->GetDynobjOwner();
@@ -2010,8 +1946,7 @@ bool AvoidAoeAction::AvoidGameObjectWithDamage()
continue;
}
if (sPlayerbotAIConfig->aoeAvoidSpellWhitelist.find(spellId) !=
sPlayerbotAIConfig->aoeAvoidSpellWhitelist.end())
if (sPlayerbotAIConfig->aoeAvoidSpellWhitelist.find(spellId) != sPlayerbotAIConfig->aoeAvoidSpellWhitelist.end())
continue;
const SpellInfo* spellInfo = sSpellMgr->GetSpellInfo(spellId);
@@ -2037,8 +1972,7 @@ bool AvoidAoeAction::AvoidGameObjectWithDamage()
lastTellTimer = time(NULL);
lastMoveTimer = getMSTime();
std::ostringstream out;
out << "I'm avoiding " << name.str() << " (" << spellInfo->Id << ")" << " Radius " << radius
<< " - [Trap]";
out << "I'm avoiding " << name.str() << " (" << spellInfo->Id << ")" << " Radius " << radius << " - [Trap]";
bot->Say(out.str(), LANG_UNIVERSAL);
}
return true;
@@ -2081,8 +2015,7 @@ bool AvoidAoeAction::AvoidUnitWithDamageAura()
sSpellMgr->GetSpellInfo(spellInfo->Effects[aurEff->GetEffIndex()].TriggerSpell);
if (!triggerSpellInfo)
continue;
if (sPlayerbotAIConfig->aoeAvoidSpellWhitelist.find(triggerSpellInfo->Id) !=
sPlayerbotAIConfig->aoeAvoidSpellWhitelist.end())
if (sPlayerbotAIConfig->aoeAvoidSpellWhitelist.find(triggerSpellInfo->Id) != sPlayerbotAIConfig->aoeAvoidSpellWhitelist.end())
return false;
for (int j = 0; j < MAX_SPELL_EFFECTS; j++)
{
@@ -2104,8 +2037,7 @@ bool AvoidAoeAction::AvoidUnitWithDamageAura()
lastTellTimer = time(NULL);
lastMoveTimer = getMSTime();
std::ostringstream out;
out << "I'm avoiding " << name.str() << " (" << triggerSpellInfo->Id << ")"
<< " Radius " << radius << " - [Unit Trigger]";
out << "I'm avoiding " << name.str() << " (" << triggerSpellInfo->Id << ")" << " Radius " << radius << " - [Unit Trigger]";
bot->Say(out.str(), LANG_UNIVERSAL);
}
}
@@ -2124,8 +2056,7 @@ Position MovementAction::BestPositionForMeleeToFlee(Position pos, float radius)
if (currentTarget)
{
// Normally, move to left or right is the best position
bool isTanking = (!currentTarget->isFrozen()
&& !currentTarget->HasRootAura()) && (currentTarget->GetVictim() == bot);
bool isTanking = (!currentTarget->isFrozen() && !currentTarget->HasRootAura()) && (currentTarget->GetVictim() == bot);
float angle = bot->GetAngle(currentTarget);
float angleLeft = angle + (float)M_PI / 2;
float angleRight = angle - (float)M_PI / 2;
@@ -2340,7 +2271,8 @@ bool CombatFormationMoveAction::isUseful()
bool CombatFormationMoveAction::Execute(Event event)
{
float dis = AI_VALUE(float, "disperse distance");
if (dis <= 0.0f || (!bot->IsInCombat() && botAI->HasStrategy("stay", BotState::BOT_STATE_NON_COMBAT)) ||
if (dis <= 0.0f ||
(!bot->IsInCombat() && botAI->HasStrategy("stay", BotState::BOT_STATE_NON_COMBAT)) ||
(bot->IsInCombat() && botAI->HasStrategy("stay", BotState::BOT_STATE_COMBAT)))
return false;
Player* playerToLeave = NearestGroupMember(dis);
@@ -2490,7 +2422,7 @@ bool TankFaceAction::Execute(Event event)
float deltaAngle = Position::NormalizeOrientation(averageAngle - target->GetAngle(bot));
if (deltaAngle > M_PI)
deltaAngle -= 2.0f * M_PI; // -PI..PI
deltaAngle -= 2.0f * M_PI; // -PI..PI
float tolerable = M_PI_2;
@@ -2501,13 +2433,12 @@ bool TankFaceAction::Execute(Event event)
float goodAngle2 = Position::NormalizeOrientation(averageAngle - M_PI * 3 / 5);
// if dist < bot->GetMeleeRange(target) / 2, target will move backward
float dist = std::max(bot->GetExactDist(target), bot->GetMeleeRange(target) / 2) - bot->GetCombatReach() -
target->GetCombatReach();
float dist = std::max(bot->GetExactDist(target), bot->GetMeleeRange(target) / 2) - bot->GetCombatReach() - target->GetCombatReach();
std::vector<Position> availablePos;
float x, y, z;
target->GetNearPoint(bot, x, y, z, 0.0f, dist, goodAngle1);
if (bot->GetMap()->CheckCollisionAndGetValidCoords(bot, bot->GetPositionX(), bot->GetPositionY(),
bot->GetPositionZ(), x, y, z))
if (bot->GetMap()->CheckCollisionAndGetValidCoords(bot, bot->GetPositionX(), bot->GetPositionY(), bot->GetPositionZ(),
x, y, z))
{
/// @todo: movement control now is a mess, prepare to rewrite
std::list<FleeInfo>& infoList = AI_VALUE(std::list<FleeInfo>&, "recently flee info");
@@ -2519,8 +2450,8 @@ bool TankFaceAction::Execute(Event event)
}
}
target->GetNearPoint(bot, x, y, z, 0.0f, dist, goodAngle2);
if (bot->GetMap()->CheckCollisionAndGetValidCoords(bot, bot->GetPositionX(), bot->GetPositionY(),
bot->GetPositionZ(), x, y, z))
if (bot->GetMap()->CheckCollisionAndGetValidCoords(bot, bot->GetPositionX(), bot->GetPositionY(), bot->GetPositionZ(),
x, y, z))
{
std::list<FleeInfo>& infoList = AI_VALUE(std::list<FleeInfo>&, "recently flee info");
Position pos(x, y, z);
@@ -2533,15 +2464,13 @@ bool TankFaceAction::Execute(Event event)
if (availablePos.empty())
return false;
Position nearest = GetNearestPosition(availablePos);
return MoveTo(bot->GetMapId(), nearest.GetPositionX(), nearest.GetPositionY(), nearest.GetPositionZ(), false, false,
false, true, MovementPriority::MOVEMENT_COMBAT);
return MoveTo(bot->GetMapId(), nearest.GetPositionX(), nearest.GetPositionY(), nearest.GetPositionZ(), false, false, false, true, MovementPriority::MOVEMENT_COMBAT);
}
bool RearFlankAction::isUseful()
{
Unit* target = AI_VALUE(Unit*, "current target");
if (!target)
return false;
if (!target) { return false; }
// Need to double the front angle check to account for mirrored angle.
bool inFront = target->HasInArc(2.f * minAngle, bot);
@@ -2555,8 +2484,7 @@ bool RearFlankAction::isUseful()
bool RearFlankAction::Execute(Event event)
{
Unit* target = AI_VALUE(Unit*, "current target");
if (!target)
return false;
if (!target) { return false; }
float angle = frand(minAngle, maxAngle);
float baseDistance = bot->GetMeleeRange(target) * 0.5f;
@@ -2575,8 +2503,8 @@ bool RearFlankAction::Execute(Event event)
destination = &rightFlank;
}
return MoveTo(bot->GetMapId(), destination->GetPositionX(), destination->GetPositionY(),
destination->GetPositionZ(), false, false, false, true, MovementPriority::MOVEMENT_COMBAT);
return MoveTo(bot->GetMapId(), destination->GetPositionX(), destination->GetPositionY(), destination->GetPositionZ(),
false, false, false, true, MovementPriority::MOVEMENT_COMBAT);
}
bool DisperseSetAction::Execute(Event event)
@@ -2704,8 +2632,9 @@ bool SetFacingTargetAction::isUseful() { return !AI_VALUE2(bool, "facing", "curr
bool SetFacingTargetAction::isPossible()
{
if (bot->isFrozen() || bot->IsPolymorphed() || (bot->isDead() && !bot->HasPlayerFlag(PLAYER_FLAGS_GHOST)) ||
bot->IsBeingTeleported() || bot->HasConfuseAura() || bot->IsCharmed() || bot->HasStunAura() ||
bot->IsInFlight() || bot->HasUnitState(UNIT_STATE_LOST_CONTROL))
bot->IsBeingTeleported() || bot->HasConfuseAura() || bot->IsCharmed() ||
bot->HasStunAura() || bot->IsInFlight() ||
bot->HasUnitState(UNIT_STATE_LOST_CONTROL))
return false;
return true;
@@ -2725,7 +2654,7 @@ bool SetBehindTargetAction::Execute(Event event)
float deltaAngle = Position::NormalizeOrientation(target->GetOrientation() - target->GetAngle(bot));
if (deltaAngle > M_PI)
deltaAngle -= 2.0f * M_PI; // -PI..PI
deltaAngle -= 2.0f * M_PI; // -PI..PI
float tolerable = M_PI_2;
@@ -2735,13 +2664,12 @@ bool SetBehindTargetAction::Execute(Event event)
float goodAngle1 = Position::NormalizeOrientation(target->GetOrientation() + M_PI * 3 / 5);
float goodAngle2 = Position::NormalizeOrientation(target->GetOrientation() - M_PI * 3 / 5);
float dist = std::max(bot->GetExactDist(target), bot->GetMeleeRange(target) / 2) - bot->GetCombatReach() -
target->GetCombatReach();
float dist = std::max(bot->GetExactDist(target), bot->GetMeleeRange(target) / 2) - bot->GetCombatReach() - target->GetCombatReach();
std::vector<Position> availablePos;
float x, y, z;
target->GetNearPoint(bot, x, y, z, 0.0f, dist, goodAngle1);
if (bot->GetMap()->CheckCollisionAndGetValidCoords(bot, bot->GetPositionX(), bot->GetPositionY(),
bot->GetPositionZ(), x, y, z))
if (bot->GetMap()->CheckCollisionAndGetValidCoords(bot, bot->GetPositionX(), bot->GetPositionY(), bot->GetPositionZ(),
x, y, z))
{
/// @todo: movement control now is a mess, prepare to rewrite
std::list<FleeInfo>& infoList = AI_VALUE(std::list<FleeInfo>&, "recently flee info");
@@ -2753,8 +2681,8 @@ bool SetBehindTargetAction::Execute(Event event)
}
}
target->GetNearPoint(bot, x, y, z, 0.0f, dist, goodAngle2);
if (bot->GetMap()->CheckCollisionAndGetValidCoords(bot, bot->GetPositionX(), bot->GetPositionY(),
bot->GetPositionZ(), x, y, z))
if (bot->GetMap()->CheckCollisionAndGetValidCoords(bot, bot->GetPositionX(), bot->GetPositionY(), bot->GetPositionZ(),
x, y, z))
{
std::list<FleeInfo>& infoList = AI_VALUE(std::list<FleeInfo>&, "recently flee info");
Position pos(x, y, z);
@@ -2767,8 +2695,7 @@ bool SetBehindTargetAction::Execute(Event event)
if (availablePos.empty())
return false;
Position nearest = GetNearestPosition(availablePos);
return MoveTo(bot->GetMapId(), nearest.GetPositionX(), nearest.GetPositionY(), nearest.GetPositionZ(), false, false,
false, true, MovementPriority::MOVEMENT_COMBAT);
return MoveTo(bot->GetMapId(), nearest.GetPositionX(), nearest.GetPositionY(), nearest.GetPositionZ(), false, false, false, true, MovementPriority::MOVEMENT_COMBAT);
}
bool MoveOutOfCollisionAction::Execute(Event event)
@@ -2839,7 +2766,7 @@ bool MoveFromGroupAction::Execute(Event event)
{
float distance = atoi(event.getParam().c_str());
if (!distance)
distance = 20.0f; // flee distance from config is too small for this
distance = 20.0f; // flee distance from config is too small for this
return MoveFromGroup(distance);
}
@@ -2850,7 +2777,7 @@ bool MoveAwayFromCreatureAction::Execute(Event event)
// Find all creatures with the specified Id
std::vector<Unit*> creatures;
for (auto const& guid : targets)
for (const auto& guid : targets)
{
Unit* unit = botAI->GetUnit(guid);
if (unit && (alive && unit->IsAlive()) && unit->GetEntry() == creatureId)
@@ -2922,7 +2849,10 @@ bool MoveAwayFromCreatureAction::Execute(Event event)
return false;
}
bool MoveAwayFromCreatureAction::isPossible() { return bot->CanFreeMove(); }
bool MoveAwayFromCreatureAction::isPossible()
{
return bot->CanFreeMove();
}
bool MoveAwayFromPlayerWithDebuffAction::Execute(Event event)
{
@@ -3009,4 +2939,7 @@ bool MoveAwayFromPlayerWithDebuffAction::Execute(Event event)
return false;
}
bool MoveAwayFromPlayerWithDebuffAction::isPossible() { return bot->CanFreeMove(); }
bool MoveAwayFromPlayerWithDebuffAction::isPossible()
{
return bot->CanFreeMove();
}