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

@@ -20,17 +20,17 @@ jobs:
name: ${{ matrix.os }} name: ${{ matrix.os }}
steps: steps:
- name: Checkout AzerothCore - name: Checkout AzerothCore
uses: actions/checkout@v3 uses: actions/checkout@v4
with: with:
repository: 'liyunfan1223/azerothcore-wotlk' repository: 'liyunfan1223/azerothcore-wotlk'
ref: 'Playerbot' ref: 'Playerbot'
- name: Checkout Playerbot Module - name: Checkout Playerbot Module
uses: actions/checkout@v3 uses: actions/checkout@v4
with: with:
repository: 'liyunfan1223/mod-playerbots' repository: 'liyunfan1223/mod-playerbots'
path: 'modules/mod-playerbots' path: 'modules/mod-playerbots'
- name: Cache - name: Cache
uses: actions/cache@v3 uses: actions/cache@v4
with: with:
path: ~/Library/Caches/ccache path: ~/Library/Caches/ccache
key: ccache:${{ matrix.os }}:${{ github.ref }}:${{ github.sha }} key: ccache:${{ matrix.os }}:${{ github.ref }}:${{ github.sha }}

View File

@@ -697,6 +697,9 @@ AiPlayerbot.PvpProhibitedZoneIds = "2255,656,2361,2362,2363,976,35,2268,3425,392
# PvP Restricted Areas (bots don't pvp) # PvP Restricted Areas (bots don't pvp)
AiPlayerbot.PvpProhibitedAreaIds = "976,35,392" AiPlayerbot.PvpProhibitedAreaIds = "976,35,392"
# Improve react speed in battleground and arena (may cause lag)
AiPlayerbot.FastReactInBG = 1
# #
# #
# #

View File

@@ -30,6 +30,7 @@
#include "ObjectGuid.h" #include "ObjectGuid.h"
#include "PerformanceMonitor.h" #include "PerformanceMonitor.h"
#include "Player.h" #include "Player.h"
#include "PlayerbotAIConfig.h"
#include "PlayerbotDbStore.h" #include "PlayerbotDbStore.h"
#include "PlayerbotMgr.h" #include "PlayerbotMgr.h"
#include "Playerbots.h" #include "Playerbots.h"
@@ -342,10 +343,11 @@ void PlayerbotAI::UpdateAI(uint32 elapsed, bool minimal)
UpdateAIInternal(elapsed, min); UpdateAIInternal(elapsed, min);
inCombat = bot->IsInCombat(); inCombat = bot->IsInCombat();
// test fix lags because of BG // test fix lags because of BG
bool inBG = bot->InBattleground() || bot->InArena();
if (bot && !inCombat) if (bot && !inCombat)
min = true; min = true;
if (HasRealPlayerMaster()) if (HasRealPlayerMaster() || (sPlayerbotAIConfig->fastReactInBG && inBG))
min = false; min = false;
YieldThread(min); YieldThread(min);
@@ -1629,7 +1631,7 @@ bool PlayerbotAI::IsCaster(Player* player) { return IsRanged(player) && player->
bool PlayerbotAI::IsCombo(Player* player) bool PlayerbotAI::IsCombo(Player* player)
{ {
int tab = AiFactory::GetPlayerSpecTab(player); // int tab = AiFactory::GetPlayerSpecTab(player);
return player->getClass() == CLASS_ROGUE || return player->getClass() == CLASS_ROGUE ||
(player->getClass() == CLASS_DRUID && player->HasAura(768)); // cat druid (player->getClass() == CLASS_DRUID && player->HasAura(768)); // cat druid
} }
@@ -3020,8 +3022,8 @@ bool PlayerbotAI::CastSpell(uint32 spellId, Unit* target, Item* itemTarget)
return true; return true;
} }
aiObjectContext->GetValue<LastMovement&>("last movement")->Get().Set(nullptr); // aiObjectContext->GetValue<LastMovement&>("last movement")->Get().Set(nullptr);
aiObjectContext->GetValue<time_t>("stay time")->Set(0); // aiObjectContext->GetValue<time_t>("stay time")->Set(0);
if (bot->IsFlying() || bot->HasUnitState(UNIT_STATE_IN_FLIGHT)) if (bot->IsFlying() || bot->HasUnitState(UNIT_STATE_IN_FLIGHT))
{ {
@@ -3206,8 +3208,8 @@ bool PlayerbotAI::CastSpell(uint32 spellId, float x, float y, float z, Item* ite
return true; return true;
} }
aiObjectContext->GetValue<LastMovement&>("last movement")->Get().Set(nullptr); // aiObjectContext->GetValue<LastMovement&>("last movement")->Get().Set(nullptr);
aiObjectContext->GetValue<time_t>("stay time")->Set(0); // aiObjectContext->GetValue<time_t>("stay time")->Set(0);
MotionMaster& mm = *bot->GetMotionMaster(); MotionMaster& mm = *bot->GetMotionMaster();

View File

@@ -128,7 +128,7 @@ bool PlayerbotAIConfig::Initialize()
pvpProhibitedZoneIds); pvpProhibitedZoneIds);
LoadList<std::vector<uint32>>(sConfigMgr->GetOption<std::string>("AiPlayerbot.PvpProhibitedAreaIds", "976,35"), LoadList<std::vector<uint32>>(sConfigMgr->GetOption<std::string>("AiPlayerbot.PvpProhibitedAreaIds", "976,35"),
pvpProhibitedAreaIds); pvpProhibitedAreaIds);
fastReactInBG = sConfigMgr->GetOption<bool>("AiPlayerbot.FastReactInBG", true);
LoadList<std::vector<uint32>>( LoadList<std::vector<uint32>>(
sConfigMgr->GetOption<std::string>("AiPlayerbot.RandomBotQuestIds", "7848,3802,5505,6502,7761"), sConfigMgr->GetOption<std::string>("AiPlayerbot.RandomBotQuestIds", "7848,3802,5505,6502,7761"),
randomBotQuestIds); randomBotQuestIds);

View File

@@ -207,6 +207,7 @@ public:
std::vector<uint32> randomBotGuilds; std::vector<uint32> randomBotGuilds;
std::vector<uint32> pvpProhibitedZoneIds; std::vector<uint32> pvpProhibitedZoneIds;
std::vector<uint32> pvpProhibitedAreaIds; std::vector<uint32> pvpProhibitedAreaIds;
bool fastReactInBG;
bool randombotsWalkingRPG; bool randombotsWalkingRPG;
bool randombotsWalkingRPGInDoors; bool randombotsWalkingRPGInDoors;

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; 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) // 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 dps = AI_VALUE(Unit*, "dps target");
bool fartarget = // bool fartarget = (enemy && sServerFacade->IsDistanceGreaterThan(AI_VALUE2(float, "distance", "enemy player
(enemy && sServerFacade->IsDistanceGreaterThan(AI_VALUE2(float, "distance", "enemy player target"), 40.0f)) || // target"), 40.0f)) ||
(dps && sServerFacade->IsDistanceGreaterThan(AI_VALUE2(float, "distance", "dps target"), 50.0f)); // (dps && sServerFacade->IsDistanceGreaterThan(AI_VALUE2(float, "distance", "dps target"), 50.0f));
bool attackdistance = false; bool attackdistance = false;
bool chasedistance = false; // bool chasedistance = false;
float attack_distance = 35.0f; float attack_distance = 35.0f;
if (PlayerbotAI::IsMelee(bot)) if (PlayerbotAI::IsMelee(bot))
{ {
attack_distance = 10.0f; attack_distance = 5.0f;
} }
else else
{ {
attack_distance = 40.0f; attack_distance = 30.0f;
} }
if (enemy)
attack_distance /= 2; // if (enemy)
// attack_distance /= 2;
if (dps || enemy) if (dps || enemy)
{ {
attackdistance = (enemy || dps) && sServerFacade->IsDistanceLessThan( Unit* currentTarget = AI_VALUE(Unit*, "current target");
AI_VALUE2(float, "distance", "current target"), attack_distance); attackdistance =
chasedistance = (enemy || dps) && currentTarget &&
enemy && sServerFacade->IsDistanceGreaterThan(AI_VALUE2(float, "distance", "enemy player target"), 45.0f) && sServerFacade->IsDistanceLessThan(AI_VALUE2(float, "distance", "current target"), attack_distance);
AI_VALUE2(bool, "moving", "enemy player target");
} }
if (bot->IsMounted() && attackdistance) if (bot->IsMounted() && attackdistance)
@@ -94,8 +94,7 @@ bool CheckMountStateAction::Execute(Event event)
} }
} }
if (bot->InBattleground() && !attackdistance && (noattackers || fartarget) && !bot->IsInCombat() && if (bot->InBattleground() && !attackdistance && noattackers && !bot->IsInCombat() && !bot->IsMounted())
!bot->IsMounted())
{ {
if (bot->GetBattlegroundTypeId() == BATTLEGROUND_WS) if (bot->GetBattlegroundTypeId() == BATTLEGROUND_WS)
{ {

View File

@@ -29,7 +29,8 @@ bool FollowAction::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()); moved = MoveTo(loc.GetMapId(), loc.GetPositionX(), loc.GetPositionY(), loc.GetPositionZ(), false, false, false,
true);
} }
if (Pet* pet = bot->GetPet()) if (Pet* pet = bot->GetPet())

View File

@@ -94,15 +94,21 @@ 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;
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); // WaitForReach(distance);
bool couldMove = false; bool couldMove = false;
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); couldMove = MoveTo(mapId, x, y, z, false, false, false, true);
if (!couldMove && WorldPosition(mapId, x, y, z).distance(bot) > INTERACTION_DISTANCE) if (!couldMove && WorldPosition(mapId, x, y, z).distance(bot) > INTERACTION_DISTANCE)
{ {

View File

@@ -12,6 +12,7 @@
#include "Event.h" #include "Event.h"
#include "FleeManager.h" #include "FleeManager.h"
#include "G3D/Vector3.h"
#include "GameObject.h" #include "GameObject.h"
#include "Geometry.h" #include "Geometry.h"
#include "LastMovementValue.h" #include "LastMovementValue.h"
@@ -68,7 +69,7 @@ void MovementAction::JumpTo(uint32 mapId, float x, float y, float z)
botAI->SetNextCheckDelay(1000); botAI->SetNextCheckDelay(1000);
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()); 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) 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; 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(); UpdateMovementState();
if (!IsMovingAllowed(mapId, x, y, z)) if (!IsMovingAllowed(mapId, x, y, z))
{ {
return false; return false;
} }
if (IsDuplicateMove(mapId, x, y, z))
{
return false;
}
if (IsWaitingForLastMove())
{
return false;
}
// if (bot->Unit::IsFalling()) { // if (bot->Unit::IsFalling()) {
// bot->Say("I'm falling!, flag:" + std::to_string(bot->m_movementInfo.GetMovementFlags()), LANG_UNIVERSAL); // bot->Say("I'm falling!, flag:" + std::to_string(bot->m_movementInfo.GetMovementFlags()), LANG_UNIVERSAL);
// return false; // return false;
@@ -177,17 +187,16 @@ bool MovementAction::MoveTo(uint32 mapId, float x, float y, float z, bool idle,
// if (bot->Unit::IsFalling()) { // if (bot->Unit::IsFalling()) {
// bot->Say("I'm falling", LANG_UNIVERSAL); // bot->Say("I'm falling", LANG_UNIVERSAL);
// } // }
bool generatePath = !bot->HasAuraType(SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED) && !bot->IsFlying() && // !bot->HasAuraType(SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED) &&
!bot->HasUnitMovementFlag(MOVEMENTFLAG_SWIMMING) && !bot->IsInWater();
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());
if (disableMoveSplinePath || !generatePath) if (exact_waypoint || disableMoveSplinePath || !generatePath)
{ {
float distance = bot->GetExactDist(x, y, z); float distance = bot->GetExactDist(x, y, z);
if (distance > sPlayerbotAIConfig->contactDistance) if (distance > sPlayerbotAIConfig->contactDistance)
{ {
WaitForReach(distance);
if (bot->IsSitState()) if (bot->IsSitState())
bot->SetStandState(UNIT_STAND_STATE_STAND); 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(); MotionMaster& mm = *bot->GetMotionMaster();
mm.Clear(); mm.Clear();
mm.MovePoint(mapId, x, y, z, generatePath); 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; 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); float distance = bot->GetExactDist(x, y, modifiedZ);
if (distance > sPlayerbotAIConfig->contactDistance) if (distance > sPlayerbotAIConfig->contactDistance)
{ {
WaitForReach(distance);
if (bot->IsSitState()) if (bot->IsSitState())
bot->SetStandState(UNIT_STAND_STATE_STAND); 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.Clear();
mm.MoveSplinePath(&path); 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; return true;
} }
} }
@@ -777,28 +787,34 @@ bool MovementAction::ReachCombatTo(Unit* target, float distance)
float ty = target->GetPositionY(); float ty = target->GetPositionY();
float tz = target->GetPositionZ(); float tz = target->GetPositionZ();
float combatDistance = bot->GetCombatReach() + target->GetCombatReach(); float combatDistance = bot->GetCombatReach() + target->GetCombatReach();
float distanceToTarget = bot->GetExactDist(target) - combatDistance; distance += combatDistance;
float angle = bot->GetAngle(target);
float needToGo = distanceToTarget - distance;
float maxDistance = sPlayerbotAIConfig->spellDistance; if (target->HasUnitMovementFlag(MOVEMENTFLAG_FORWARD)) // target is moving forward, predict the position
if (needToGo > 0 && needToGo > maxDistance) {
needToGo = maxDistance; float needToGo = bot->GetExactDist(target) - distance;
else if (needToGo < 0 && needToGo < -maxDistance) float timeToGo = MoveDelay(abs(needToGo)) + sPlayerbotAIConfig->reactDelay;
needToGo = -maxDistance; 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; PathGenerator path(bot);
float dy = sin(angle) * needToGo + by; path.CalculatePath(tx, ty, tz, false);
float dz; // = std::max(bz, tz); // calc accurate z position to avoid stuck PathType type = path.GetPathType();
if (distanceToTarget > CONTACT_DISTANCE) if (type != PATHFIND_NORMAL && type != PATHFIND_INCOMPLETE)
{ return false;
dz = bz + (tz - bz) * (needToGo / distanceToTarget); path.ShortenPathUntilDist(G3D::Vector3(tx, ty, tz), distance);
} G3D::Vector3 endPos = path.GetPath().back();
else return MoveTo(target->GetMapId(), endPos.x, endPos.y, endPos.z);
{
dz = tz;
}
return MoveTo(target->GetMapId(), dx, dy, dz);
} }
float MovementAction::GetFollowAngle() float MovementAction::GetFollowAngle()
@@ -847,6 +863,29 @@ bool MovementAction::IsMovingAllowed(uint32 mapId, float x, float y, float z)
return IsMovingAllowed(); 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() bool MovementAction::IsMovingAllowed()
{ {
// do not allow if not vehicle driver // do not allow if not vehicle driver
@@ -878,7 +917,7 @@ void MovementAction::UpdateMovementState()
{ {
bot->SetSwim(true); bot->SetSwim(true);
} }
else else if (!bot->Unit::IsInWater())
{ {
bot->SetSwim(false); bot->SetSwim(false);
} }
@@ -1529,13 +1568,14 @@ const Movement::PointsArray MovementAction::SearchForBestPath(float x, float y,
gen.CalculatePath(x, y, tempZ); gen.CalculatePath(x, y, tempZ);
Movement::PointsArray result = gen.GetPath(); Movement::PointsArray result = gen.GetPath();
float min_length = gen.getPathLength(); 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; modified_z = tempZ;
return result; return result;
} }
// Start searching // Start searching
if (gen.GetPathType() & PATHFIND_NORMAL) if (gen.GetPathType() & typeOk)
{ {
modified_z = tempZ; modified_z = tempZ;
found = true; found = true;
@@ -1550,7 +1590,7 @@ const Movement::PointsArray MovementAction::SearchForBestPath(float x, float y,
} }
PathGenerator gen(bot); PathGenerator gen(bot);
gen.CalculatePath(x, y, tempZ); gen.CalculatePath(x, y, tempZ);
if ((gen.GetPathType() & PATHFIND_NORMAL) && gen.getPathLength() < min_length) if ((gen.GetPathType() & typeOk) && gen.getPathLength() < min_length)
{ {
found = true; found = true;
min_length = gen.getPathLength(); min_length = gen.getPathLength();
@@ -1567,7 +1607,7 @@ const Movement::PointsArray MovementAction::SearchForBestPath(float x, float y,
} }
PathGenerator gen(bot); PathGenerator gen(bot);
gen.CalculatePath(x, y, tempZ); gen.CalculatePath(x, y, tempZ);
if ((gen.GetPathType() & PATHFIND_NORMAL) && gen.getPathLength() < min_length) if ((gen.GetPathType() & typeOk) && gen.getPathLength() < min_length)
{ {
found = true; found = true;
min_length = gen.getPathLength(); min_length = gen.getPathLength();
@@ -2285,12 +2325,15 @@ bool MoveRandomAction::Execute(Event event)
float angle = (float)rand_norm() * static_cast<float>(M_PI); float angle = (float)rand_norm() * static_cast<float>(M_PI);
x += urand(0, distance) * cos(angle); x += urand(0, distance) * cos(angle);
y += urand(0, distance) * sin(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())) if (map->IsInWater(bot->GetPhaseMask(), x, y, z, bot->GetCollisionHeight()))
continue; continue;
bool moved = MoveTo(bot->GetMapId(), x, y, z); bool moved = MoveTo(bot->GetMapId(), x, y, z, false, false, false, true);
if (moved) if (moved)
return true; return true;
} }

View File

@@ -27,7 +27,7 @@ protected:
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);
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 normal_only = false, bool exact_waypoint = false);
bool MoveTo(Unit* target, float distance = 0.0f); bool MoveTo(Unit* target, float distance = 0.0f);
bool MoveNear(WorldObject* target, float distance = sPlayerbotAIConfig->contactDistance); bool MoveNear(WorldObject* target, float distance = sPlayerbotAIConfig->contactDistance);
float GetFollowAngle(); float GetFollowAngle();
@@ -39,6 +39,8 @@ protected:
void WaitForReach(float distance); void WaitForReach(float distance);
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 IsWaitingForLastMove();
bool IsMovingAllowed(); bool IsMovingAllowed();
bool Flee(Unit* target); bool Flee(Unit* target);
void ClearIdleState(); void ClearIdleState();

View File

@@ -239,7 +239,7 @@ private:
} }
static Trigger* medium_group_heal_occasion(PlayerbotAI* ai) static Trigger* medium_group_heal_occasion(PlayerbotAI* ai)
{ {
return new AoeInGroupTrigger(ai, "group heal occasion", "medium", 0.4); return new AoeInGroupTrigger(ai, "group heal occasion", "medium", 0.6);
} }
static Trigger* target_changed(PlayerbotAI* botAI) { return new TargetChangedTrigger(botAI); } static Trigger* target_changed(PlayerbotAI* botAI) { return new TargetChangedTrigger(botAI); }
static Trigger* swimming(PlayerbotAI* botAI) { return new IsSwimmingTrigger(botAI); } static Trigger* swimming(PlayerbotAI* botAI) { return new IsSwimmingTrigger(botAI); }

View File

@@ -48,8 +48,8 @@ WorldLocation ArrowFormation::GetLocationInternal()
float y = master->GetPositionY() - masterUnit->GetY() + botUnit->GetY(); float y = master->GetPositionY() - masterUnit->GetY() + botUnit->GetY();
float z = master->GetPositionZ(); float z = master->GetPositionZ();
float ground = master->GetMapHeight(x, y, z + 30.0f); if (!master->GetMap()->CheckCollisionAndGetValidCoords(master, master->GetPositionX(), master->GetPositionY(),
if (ground <= INVALID_HEIGHT) master->GetPositionZ(), x, y, z))
return Formation::NullLocation; return Formation::NullLocation;
// master->UpdateGroundPositionZ(x, y, z); // master->UpdateGroundPositionZ(x, y, z);
return WorldLocation(master->GetMapId(), x, y, z); return WorldLocation(master->GetMapId(), x, y, z);

View File

@@ -89,12 +89,9 @@ public:
float y = master->GetPositionY() + sin(angle) * range; float y = master->GetPositionY() + sin(angle) * range;
float z = master->GetPositionZ(); float z = master->GetPositionZ();
float ground = master->GetMapHeight(x, y, z + 30.0f); if (!master->GetMap()->CheckCollisionAndGetValidCoords(master, master->GetPositionX(), master->GetPositionY(),
if (ground <= INVALID_HEIGHT) master->GetPositionZ(), x, y, z))
return Formation::NullLocation; return Formation::NullLocation;
// z += CONTACT_DISTANCE;
// bot->UpdateAllowedPositionZ(x, y, z);
return WorldLocation(master->GetMapId(), x, y, z); return WorldLocation(master->GetMapId(), x, y, z);
} }
@@ -118,21 +115,39 @@ public:
time_t now = time(nullptr); time_t now = time(nullptr);
if (!lastChangeTime || now - lastChangeTime >= 3) if (!lastChangeTime || now - lastChangeTime >= 3)
{ {
lastChangeTime = now; Player* master = botAI->GetGroupMaster();
dx = (urand(0, 10) / 10.0 - 0.5) * sPlayerbotAIConfig->tooCloseDistance; if (!master)
dy = (urand(0, 10) / 10.0 - 0.5) * sPlayerbotAIConfig->tooCloseDistance; return WorldLocation();
dr = sqrt(dx * dx + dy * dy);
float range = sPlayerbotAIConfig->followDistance;
float angle = GetFollowAngle();
time_t now = time(nullptr);
if (!lastChangeTime || now - lastChangeTime >= 3)
{
lastChangeTime = now;
dx = (urand(0, 10) / 10.0 - 0.5) * sPlayerbotAIConfig->tooCloseDistance;
dy = (urand(0, 10) / 10.0 - 0.5) * sPlayerbotAIConfig->tooCloseDistance;
dr = sqrt(dx * dx + dy * dy);
}
float x = master->GetPositionX() + cos(angle) * range + dx;
float y = master->GetPositionY() + sin(angle) * range + dy;
float z = master->GetPositionZ();
if (!master->GetMap()->CheckCollisionAndGetValidCoords(
master, master->GetPositionX(), master->GetPositionY(), master->GetPositionZ(), x, y, z))
return Formation::NullLocation;
// bot->GetMap()->CheckCollisionAndGetValidCoords(bot, bot->GetPositionX(), bot->GetPositionY(),
// bot->GetPositionZ(), x, y, z);
return WorldLocation(master->GetMapId(), x, y, z);
} }
float x = master->GetPositionX() + cos(angle) * range + dx; float x = master->GetPositionX() + cos(angle) * range + dx;
float y = master->GetPositionY() + sin(angle) * range + dy; float y = master->GetPositionY() + sin(angle) * range + dy;
float z = master->GetPositionZ(); float z = master->GetPositionZ();
float ground = master->GetMapHeight(x, y, z + 30.0f); if (!master->GetMap()->CheckCollisionAndGetValidCoords(master, master->GetPositionX(), master->GetPositionY(),
if (ground <= INVALID_HEIGHT) master->GetPositionZ(), x, y, z))
return Formation::NullLocation; return Formation::NullLocation;
z += CONTACT_DISTANCE;
bot->UpdateAllowedPositionZ(x, y, z);
return WorldLocation(master->GetMapId(), x, y, z); return WorldLocation(master->GetMapId(), x, y, z);
} }
@@ -184,13 +199,10 @@ public:
float x = target->GetPositionX() + cos(angle) * range; float x = target->GetPositionX() + cos(angle) * range;
float y = target->GetPositionY() + sin(angle) * range; float y = target->GetPositionY() + sin(angle) * range;
float z = target->GetPositionZ(); float z = target->GetPositionZ();
float ground = target->GetMapHeight(x, y, z + 30.0f); if (!master->GetMap()->CheckCollisionAndGetValidCoords(master, master->GetPositionX(), master->GetPositionY(),
if (ground <= INVALID_HEIGHT) master->GetPositionZ(), x, y, z))
return Formation::NullLocation; return Formation::NullLocation;
z += CONTACT_DISTANCE;
bot->UpdateAllowedPositionZ(x, y, z);
return WorldLocation(bot->GetMapId(), x, y, z); return WorldLocation(bot->GetMapId(), x, y, z);
} }
}; };
@@ -350,16 +362,18 @@ public:
if (minDist) if (minDist)
{ {
z += CONTACT_DISTANCE; if (!master->GetMap()->CheckCollisionAndGetValidCoords(
bot->UpdateAllowedPositionZ(minX, minY, z); master, master->GetPositionX(), master->GetPositionY(), master->GetPositionZ(), x, y, z))
return Formation::NullLocation;
return WorldLocation(bot->GetMapId(), minX, minY, z); return WorldLocation(bot->GetMapId(), minX, minY, z);
} }
return Formation::NullLocation; return Formation::NullLocation;
} }
z += CONTACT_DISTANCE; if (!master->GetMap()->CheckCollisionAndGetValidCoords(master, master->GetPositionX(), master->GetPositionY(),
bot->UpdateAllowedPositionZ(x, y, z); master->GetPositionZ(), x, y, z))
return Formation::NullLocation;
return WorldLocation(bot->GetMapId(), x, y, z); return WorldLocation(bot->GetMapId(), x, y, z);
} }
}; };
@@ -618,12 +632,12 @@ WorldLocation MoveFormation::MoveSingleLine(std::vector<Player*> line, float dif
float lx = x + cos(angle) * radius; float lx = x + cos(angle) * radius;
float ly = y + sin(angle) * radius; float ly = y + sin(angle) * radius;
float lz = cz; float lz = cz;
float ground = bot->GetMapHeight(lx, ly, lz + 30.0f);
if (ground <= INVALID_HEIGHT) Player* master = botAI->GetMaster();
if (!master->GetMap()->CheckCollisionAndGetValidCoords(
master, master->GetPositionX(), master->GetPositionY(), master->GetPositionZ(), lx, ly, lz))
return Formation::NullLocation; return Formation::NullLocation;
lz += CONTACT_DISTANCE;
bot->UpdateAllowedPositionZ(lx, ly, lz);
return WorldLocation(bot->GetMapId(), lx, ly, lz); return WorldLocation(bot->GetMapId(), lx, ly, lz);
} }

View File

@@ -6,6 +6,7 @@
#include "LastMovementValue.h" #include "LastMovementValue.h"
#include "Playerbots.h" #include "Playerbots.h"
#include "Timer.h"
LastMovement::LastMovement() { clear(); } LastMovement::LastMovement() { clear(); }
@@ -38,17 +39,19 @@ void LastMovement::clear()
lastAreaTrigger = 0; lastAreaTrigger = 0;
lastFlee = 0; lastFlee = 0;
nextTeleport = 0; nextTeleport = 0;
msTime = 0;
lastdelayTime = 0;
} }
void LastMovement::Set(Unit* follow) void LastMovement::Set(Unit* follow)
{ {
Set(0, 0.0f, 0.0f, 0.0f, 0.0f); Set(0, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f);
setShort(WorldPosition()); setShort(WorldPosition());
setPath(TravelPath()); setPath(TravelPath());
lastFollow = follow; lastFollow = follow;
} }
void LastMovement::Set(uint32 mapId, float x, float y, float z, float ori) void LastMovement::Set(uint32 mapId, float x, float y, float z, float ori, float delayTime)
{ {
lastMoveToMapId = mapId; lastMoveToMapId = mapId;
lastMoveToX = x; lastMoveToX = x;
@@ -57,6 +60,8 @@ void LastMovement::Set(uint32 mapId, float x, float y, float z, float ori)
lastMoveToOri = ori; lastMoveToOri = ori;
lastFollow = nullptr; lastFollow = nullptr;
lastMoveShort = WorldPosition(mapId, x, y, z, ori); lastMoveShort = WorldPosition(mapId, x, y, z, ori);
msTime = getMSTime();
lastdelayTime = delayTime;
} }
void LastMovement::setShort(WorldPosition point) void LastMovement::setShort(WorldPosition point)

View File

@@ -35,7 +35,7 @@ public:
void clear(); void clear();
void Set(Unit* follow); void Set(Unit* follow);
void Set(uint32 mapId, float x, float y, float z, float ori); void Set(uint32 mapId, float x, float y, float z, float ori, float delayTime);
void setShort(WorldPosition point); void setShort(WorldPosition point);
void setPath(TravelPath path); void setPath(TravelPath path);
@@ -50,7 +50,9 @@ public:
float lastMoveToY; float lastMoveToY;
float lastMoveToZ; float lastMoveToZ;
float lastMoveToOri; float lastMoveToOri;
float lastdelayTime;
WorldPosition lastMoveShort; WorldPosition lastMoveShort;
uint32 msTime;
TravelPath lastPath; TravelPath lastPath;
time_t nextTeleport; time_t nextTeleport;
std::future<TravelPath> future; std::future<TravelPath> future;

View File

@@ -82,8 +82,7 @@ bool PartyMemberToHeal::Check(Unit* player)
// sServerFacade->GetDistance2d(bot, player) < (player->IsPlayer() && botAI->IsTank((Player*)player) ? 50.0f // sServerFacade->GetDistance2d(bot, player) < (player->IsPlayer() && botAI->IsTank((Player*)player) ? 50.0f
// : 40.0f); // : 40.0f);
return player->GetMapId() == bot->GetMapId() && !player->IsCharmed() && return player->GetMapId() == bot->GetMapId() && !player->IsCharmed() &&
bot->GetDistance2d(player) < sPlayerbotAIConfig->healDistance * 2 && bot->GetDistance2d(player) < sPlayerbotAIConfig->healDistance * 2 && bot->IsWithinLOSInMap(player);
bot->IsWithinLOS(player->GetPositionX(), player->GetPositionY(), player->GetPositionZ());
} }
Unit* PartyMemberToProtect::Calculate() Unit* PartyMemberToProtect::Calculate()