Merge branch 'liyunfan1223:master' into master

This commit is contained in:
Atidote
2024-08-05 16:23:19 +02:00
committed by GitHub
16 changed files with 184 additions and 107 deletions

View File

@@ -18,31 +18,31 @@ bool CheckMountStateAction::Execute(Event event)
AI_VALUE2(bool, "combat", "self target") ? (AI_VALUE(uint8, "attacker count") > 0 ? false : true) : true;
bool enemy = AI_VALUE(Unit*, "enemy player target");
// ignore grind target in BG or bots will dismount near any creature (eg: the rams in AV)
bool dps = (AI_VALUE(Unit*, "dps target") || (!bot->InBattleground() && AI_VALUE(Unit*, "grind target")));
bool fartarget =
(enemy && sServerFacade->IsDistanceGreaterThan(AI_VALUE2(float, "distance", "enemy player target"), 40.0f)) ||
(dps && sServerFacade->IsDistanceGreaterThan(AI_VALUE2(float, "distance", "dps target"), 50.0f));
bool dps = AI_VALUE(Unit*, "dps target");
// bool fartarget = (enemy && sServerFacade->IsDistanceGreaterThan(AI_VALUE2(float, "distance", "enemy player
// target"), 40.0f)) ||
// (dps && sServerFacade->IsDistanceGreaterThan(AI_VALUE2(float, "distance", "dps target"), 50.0f));
bool attackdistance = false;
bool chasedistance = false;
// bool chasedistance = false;
float attack_distance = 35.0f;
if (PlayerbotAI::IsMelee(bot))
{
attack_distance = 10.0f;
attack_distance = 5.0f;
}
else
{
attack_distance = 40.0f;
attack_distance = 30.0f;
}
if (enemy)
attack_distance /= 2;
// if (enemy)
// attack_distance /= 2;
if (dps || enemy)
{
attackdistance = (enemy || dps) && sServerFacade->IsDistanceLessThan(
AI_VALUE2(float, "distance", "current target"), attack_distance);
chasedistance =
enemy && sServerFacade->IsDistanceGreaterThan(AI_VALUE2(float, "distance", "enemy player target"), 45.0f) &&
AI_VALUE2(bool, "moving", "enemy player 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)
@@ -94,8 +94,7 @@ bool CheckMountStateAction::Execute(Event event)
}
}
if (bot->InBattleground() && !attackdistance && (noattackers || fartarget) && !bot->IsInCombat() &&
!bot->IsMounted())
if (bot->InBattleground() && !attackdistance && noattackers && !bot->IsInCombat() && !bot->IsMounted())
{
if (bot->GetBattlegroundTypeId() == BATTLEGROUND_WS)
{

View File

@@ -29,7 +29,8 @@ bool FollowAction::Execute(Event event)
if (Formation::IsNullLocation(loc) || loc.GetMapId() == -1)
return false;
moved = MoveTo(loc.GetMapId(), loc.GetPositionX(), loc.GetPositionY(), loc.GetPositionZ());
moved = MoveTo(loc.GetMapId(), loc.GetPositionX(), loc.GetPositionY(), loc.GetPositionZ(), false, false, false,
true);
}
if (Pet* pet = bot->GetPet())

View File

@@ -94,15 +94,21 @@ bool MoveToRpgTargetAction::Execute(Event event)
x += cos(angle) * INTERACTION_DISTANCE * distance;
y += sin(angle) * INTERACTION_DISTANCE * distance;
if (!wo->GetMap()->CheckCollisionAndGetValidCoords(wo, wo->GetPositionX(), wo->GetPositionY(), wo->GetPositionZ(),
x, y, z))
{
x = wo->GetPositionX();
y = wo->GetPositionY();
z = wo->GetPositionZ();
}
// WaitForReach(distance);
bool couldMove = false;
if (bot->IsWithinLOS(x, y, z))
couldMove = MoveNear(mapId, x, y, z, 0);
else
couldMove = MoveTo(mapId, x, y, z);
// if (bot->IsWithinLOS(x, y, z))
// couldMove = MoveNear(mapId, x, y, z, 0);
// else
couldMove = MoveTo(mapId, x, y, z, false, false, false, true);
if (!couldMove && WorldPosition(mapId, x, y, z).distance(bot) > INTERACTION_DISTANCE)
{

View File

@@ -12,6 +12,7 @@
#include "Event.h"
#include "FleeManager.h"
#include "G3D/Vector3.h"
#include "GameObject.h"
#include "Geometry.h"
#include "LastMovementValue.h"
@@ -68,7 +69,7 @@ void MovementAction::JumpTo(uint32 mapId, float x, float y, float z)
botAI->SetNextCheckDelay(1000);
mm.Clear();
mm.MoveJump(x, y, z, speed, speed, 1);
AI_VALUE(LastMovement&, "last movement").Set(mapId, x, y, z, bot->GetOrientation());
AI_VALUE(LastMovement&, "last movement").Set(mapId, x, y, z, bot->GetOrientation(), 1000);
}
bool MovementAction::MoveNear(uint32 mapId, float x, float y, float z, float distance)
@@ -160,13 +161,22 @@ bool MovementAction::MoveToLOS(WorldObject* target, bool ranged)
return false;
}
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)
{
UpdateMovementState();
if (!IsMovingAllowed(mapId, x, y, z))
{
return false;
}
if (IsDuplicateMove(mapId, x, y, z))
{
return false;
}
if (IsWaitingForLastMove())
{
return false;
}
// if (bot->Unit::IsFalling()) {
// bot->Say("I'm falling!, flag:" + std::to_string(bot->m_movementInfo.GetMovementFlags()), LANG_UNIVERSAL);
// return false;
@@ -177,17 +187,16 @@ bool MovementAction::MoveTo(uint32 mapId, float x, float y, float z, bool idle,
// if (bot->Unit::IsFalling()) {
// bot->Say("I'm falling", LANG_UNIVERSAL);
// }
bool generatePath = !bot->HasAuraType(SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED) && !bot->IsFlying() &&
!bot->HasUnitMovementFlag(MOVEMENTFLAG_SWIMMING) && !bot->IsInWater();
// !bot->HasAuraType(SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED) &&
bool generatePath = !bot->IsFlying() && !bot->isSwimming();
bool disableMoveSplinePath = sPlayerbotAIConfig->disableMoveSplinePath >= 2 ||
(sPlayerbotAIConfig->disableMoveSplinePath == 1 && bot->InBattleground());
if (disableMoveSplinePath || !generatePath)
if (exact_waypoint || disableMoveSplinePath || !generatePath)
{
float distance = bot->GetExactDist(x, y, z);
if (distance > sPlayerbotAIConfig->contactDistance)
{
WaitForReach(distance);
if (bot->IsSitState())
bot->SetStandState(UNIT_STAND_STATE_STAND);
@@ -199,7 +208,8 @@ bool MovementAction::MoveTo(uint32 mapId, float x, float y, float z, bool idle,
MotionMaster& mm = *bot->GetMotionMaster();
mm.Clear();
mm.MovePoint(mapId, x, y, z, generatePath);
AI_VALUE(LastMovement&, "last movement").Set(mapId, x, y, z, bot->GetOrientation());
float delay = std::min((float)sPlayerbotAIConfig->maxWaitForMove, 1000.0f * MoveDelay(distance));
AI_VALUE(LastMovement&, "last movement").Set(mapId, x, y, z, bot->GetOrientation(), delay);
return true;
}
}
@@ -215,8 +225,6 @@ bool MovementAction::MoveTo(uint32 mapId, float x, float y, float z, bool idle,
float distance = bot->GetExactDist(x, y, modifiedZ);
if (distance > sPlayerbotAIConfig->contactDistance)
{
WaitForReach(distance);
if (bot->IsSitState())
bot->SetStandState(UNIT_STAND_STATE_STAND);
@@ -229,7 +237,9 @@ bool MovementAction::MoveTo(uint32 mapId, float x, float y, float z, bool idle,
mm.Clear();
mm.MoveSplinePath(&path);
AI_VALUE(LastMovement&, "last movement").Set(mapId, x, y, z, bot->GetOrientation());
// mm.MoveSplinePath(&path);
float delay = std::min((float)sPlayerbotAIConfig->maxWaitForMove, 1000.0f * MoveDelay(distance));
AI_VALUE(LastMovement&, "last movement").Set(mapId, x, y, z, bot->GetOrientation(), delay);
return true;
}
}
@@ -777,28 +787,34 @@ bool MovementAction::ReachCombatTo(Unit* target, float distance)
float ty = target->GetPositionY();
float tz = target->GetPositionZ();
float combatDistance = bot->GetCombatReach() + target->GetCombatReach();
float distanceToTarget = bot->GetExactDist(target) - combatDistance;
float angle = bot->GetAngle(target);
float needToGo = distanceToTarget - distance;
distance += combatDistance;
float maxDistance = sPlayerbotAIConfig->spellDistance;
if (needToGo > 0 && needToGo > maxDistance)
needToGo = maxDistance;
else if (needToGo < 0 && needToGo < -maxDistance)
needToGo = -maxDistance;
if (target->HasUnitMovementFlag(MOVEMENTFLAG_FORWARD)) // target is moving forward, predict the position
{
float needToGo = bot->GetExactDist(target) - distance;
float timeToGo = MoveDelay(abs(needToGo)) + sPlayerbotAIConfig->reactDelay;
float targetMoveDist = timeToGo * target->GetSpeed(MOVE_RUN);
targetMoveDist = std::min(5.0f, targetMoveDist);
tx += targetMoveDist * cos(target->GetOrientation());
ty += targetMoveDist * sin(target->GetOrientation());
if (!target->GetMap()->CheckCollisionAndGetValidCoords(target, target->GetPositionX(), target->GetPositionY(),
target->GetPositionZ(), tx, ty, tz))
{
// disable prediction if position is invalid
tx = target->GetPositionX();
ty = target->GetPositionY();
tz = target->GetPositionZ();
}
}
float dx = cos(angle) * needToGo + bx;
float dy = sin(angle) * needToGo + by;
float dz; // = std::max(bz, tz); // calc accurate z position to avoid stuck
if (distanceToTarget > CONTACT_DISTANCE)
{
dz = bz + (tz - bz) * (needToGo / distanceToTarget);
}
else
{
dz = tz;
}
return MoveTo(target->GetMapId(), dx, dy, dz);
PathGenerator path(bot);
path.CalculatePath(tx, ty, tz, false);
PathType type = path.GetPathType();
if (type != PATHFIND_NORMAL && type != PATHFIND_INCOMPLETE)
return false;
path.ShortenPathUntilDist(G3D::Vector3(tx, ty, tz), distance);
G3D::Vector3 endPos = path.GetPath().back();
return MoveTo(target->GetMapId(), endPos.x, endPos.y, endPos.z);
}
float MovementAction::GetFollowAngle()
@@ -847,6 +863,29 @@ bool MovementAction::IsMovingAllowed(uint32 mapId, float x, float y, float z)
return IsMovingAllowed();
}
bool MovementAction::IsDuplicateMove(uint32 mapId, float x, float y, float z)
{
LastMovement& lastMove = *context->GetValue<LastMovement&>("last movement");
// heuristic 5s
if (lastMove.msTime + sPlayerbotAIConfig->maxWaitForMove < getMSTime() ||
lastMove.lastMoveShort.GetExactDist(x, y, z) > 0.01f)
return false;
return true;
}
bool MovementAction::IsWaitingForLastMove()
{
LastMovement& lastMove = *context->GetValue<LastMovement&>("last movement");
// heuristic 5s
if (lastMove.lastdelayTime + lastMove.msTime > getMSTime())
return true;
return false;
}
bool MovementAction::IsMovingAllowed()
{
// do not allow if not vehicle driver
@@ -878,7 +917,7 @@ void MovementAction::UpdateMovementState()
{
bot->SetSwim(true);
}
else
else if (!bot->Unit::IsInWater())
{
bot->SetSwim(false);
}
@@ -1529,13 +1568,14 @@ const Movement::PointsArray MovementAction::SearchForBestPath(float x, float y,
gen.CalculatePath(x, y, tempZ);
Movement::PointsArray result = gen.GetPath();
float min_length = gen.getPathLength();
if ((gen.GetPathType() & PATHFIND_NORMAL) && abs(tempZ - z) < 0.5f)
int typeOk = PATHFIND_NORMAL | PATHFIND_INCOMPLETE;
if ((gen.GetPathType() & typeOk) && abs(tempZ - z) < 0.5f)
{
modified_z = tempZ;
return result;
}
// Start searching
if (gen.GetPathType() & PATHFIND_NORMAL)
if (gen.GetPathType() & typeOk)
{
modified_z = tempZ;
found = true;
@@ -1550,7 +1590,7 @@ const Movement::PointsArray MovementAction::SearchForBestPath(float x, float y,
}
PathGenerator gen(bot);
gen.CalculatePath(x, y, tempZ);
if ((gen.GetPathType() & PATHFIND_NORMAL) && gen.getPathLength() < min_length)
if ((gen.GetPathType() & typeOk) && gen.getPathLength() < min_length)
{
found = true;
min_length = gen.getPathLength();
@@ -1567,7 +1607,7 @@ const Movement::PointsArray MovementAction::SearchForBestPath(float x, float y,
}
PathGenerator gen(bot);
gen.CalculatePath(x, y, tempZ);
if ((gen.GetPathType() & PATHFIND_NORMAL) && gen.getPathLength() < min_length)
if ((gen.GetPathType() & typeOk) && gen.getPathLength() < min_length)
{
found = true;
min_length = gen.getPathLength();
@@ -2285,12 +2325,15 @@ bool MoveRandomAction::Execute(Event event)
float angle = (float)rand_norm() * static_cast<float>(M_PI);
x += urand(0, distance) * cos(angle);
y += urand(0, distance) * sin(angle);
bot->UpdateGroundPositionZ(x, y, z);
if (!bot->GetMap()->CheckCollisionAndGetValidCoords(bot, bot->GetPositionX(), bot->GetPositionY(),
bot->GetPositionZ(), x, y, z))
{
continue;
}
if (map->IsInWater(bot->GetPhaseMask(), x, y, z, bot->GetCollisionHeight()))
continue;
bool moved = MoveTo(bot->GetMapId(), x, y, z);
bool moved = MoveTo(bot->GetMapId(), x, y, z, false, false, false, true);
if (moved)
return true;
}

View File

@@ -27,7 +27,7 @@ protected:
bool MoveNear(uint32 mapId, float x, float y, float z, float distance = sPlayerbotAIConfig->contactDistance);
bool MoveToLOS(WorldObject* target, bool ranged = false);
bool MoveTo(uint32 mapId, float x, float y, float z, bool idle = false, bool react = false,
bool normal_only = false);
bool normal_only = false, bool exact_waypoint = false);
bool MoveTo(Unit* target, float distance = 0.0f);
bool MoveNear(WorldObject* target, float distance = sPlayerbotAIConfig->contactDistance);
float GetFollowAngle();
@@ -39,6 +39,8 @@ protected:
void WaitForReach(float distance);
bool IsMovingAllowed(Unit* target);
bool IsMovingAllowed(uint32 mapId, float x, float y, float z);
bool IsDuplicateMove(uint32 mapId, float x, float y, float z);
bool IsWaitingForLastMove();
bool IsMovingAllowed();
bool Flee(Unit* target);
void ClearIdleState();