Add stuck fallback for rpg move far (#914)

This commit is contained in:
Yunfan Li
2025-01-26 19:03:34 +08:00
committed by GitHub
parent 44734db421
commit 05db6f67b4
3 changed files with 48 additions and 22 deletions

View File

@@ -38,10 +38,11 @@ bool NewRpgStatusUpdateAction::Execute(Event event)
// if ((!info.lastNearNpc || info.lastNearNpc + setNpcInterval < getMSTime()) && roll <= 30) // if ((!info.lastNearNpc || info.lastNearNpc + setNpcInterval < getMSTime()) && roll <= 30)
if (roll <= 30) if (roll <= 30)
{ {
info.lastNearNpc = getMSTime();
GuidVector possibleTargets = AI_VALUE(GuidVector, "possible rpg targets"); GuidVector possibleTargets = AI_VALUE(GuidVector, "possible rpg targets");
if (!possibleTargets.empty()) if (!possibleTargets.empty())
{ {
info.Reset();
info.lastNearNpc = getMSTime();
info.status = NewRpgStatus::NEAR_NPC; info.status = NewRpgStatus::NEAR_NPC;
return true; return true;
} }
@@ -52,6 +53,7 @@ bool NewRpgStatusUpdateAction::Execute(Event event)
WorldPosition pos = SelectRandomInnKeeperPos(); WorldPosition pos = SelectRandomInnKeeperPos();
if (pos != WorldPosition() && bot->GetExactDist(pos) > 50.0f) if (pos != WorldPosition() && bot->GetExactDist(pos) > 50.0f)
{ {
info.Reset();
info.lastGoInnKeeper = getMSTime(); info.lastGoInnKeeper = getMSTime();
info.status = NewRpgStatus::GO_INNKEEPER; info.status = NewRpgStatus::GO_INNKEEPER;
info.innKeeperPos = pos; info.innKeeperPos = pos;
@@ -64,6 +66,7 @@ bool NewRpgStatusUpdateAction::Execute(Event event)
WorldPosition pos = SelectRandomGrindPos(); WorldPosition pos = SelectRandomGrindPos();
if (pos != WorldPosition()) if (pos != WorldPosition())
{ {
info.Reset();
info.lastGoGrind = getMSTime(); info.lastGoGrind = getMSTime();
info.status = NewRpgStatus::GO_GRIND; info.status = NewRpgStatus::GO_GRIND;
info.grindPos = pos; info.grindPos = pos;
@@ -71,6 +74,7 @@ bool NewRpgStatusUpdateAction::Execute(Event event)
} }
} }
// IDLE -> REST // IDLE -> REST
info.Reset();
info.status = NewRpgStatus::REST; info.status = NewRpgStatus::REST;
info.lastRest = getMSTime(); info.lastRest = getMSTime();
bot->SetStandState(UNIT_STAND_STATE_SIT); bot->SetStandState(UNIT_STAND_STATE_SIT);
@@ -83,22 +87,12 @@ bool NewRpgStatusUpdateAction::Execute(Event event)
// GO_GRIND -> NEAR_RANDOM // GO_GRIND -> NEAR_RANDOM
if (bot->GetExactDist(originalPos) < 10.0f) if (bot->GetExactDist(originalPos) < 10.0f)
{ {
info.Reset();
info.status = NewRpgStatus::NEAR_RANDOM; info.status = NewRpgStatus::NEAR_RANDOM;
info.lastNearRandom = getMSTime(); info.lastNearRandom = getMSTime();
info.grindPos = WorldPosition(); info.grindPos = WorldPosition();
return true; return true;
} }
// // just choose another grindPos
// if (!info.lastGoGrind || info.lastGoGrind + setGrindInterval < getMSTime())
// {
// WorldPosition pos = SelectRandomGrindPos();
// if (pos == WorldPosition())
// break;
// info.status = NewRpgStatus::GO_GRIND;
// info.lastGoGrind = getMSTime();
// info.grindPos = pos;
// return true;
// }
break; break;
} }
case NewRpgStatus::GO_INNKEEPER: case NewRpgStatus::GO_INNKEEPER:
@@ -108,6 +102,7 @@ bool NewRpgStatusUpdateAction::Execute(Event event)
// GO_INNKEEPER -> NEAR_NPC // GO_INNKEEPER -> NEAR_NPC
if (bot->GetExactDist(originalPos) < 10.0f) if (bot->GetExactDist(originalPos) < 10.0f)
{ {
info.Reset();
info.lastNearNpc = getMSTime(); info.lastNearNpc = getMSTime();
info.status = NewRpgStatus::NEAR_NPC; info.status = NewRpgStatus::NEAR_NPC;
info.innKeeperPos = WorldPosition(); info.innKeeperPos = WorldPosition();
@@ -120,6 +115,7 @@ bool NewRpgStatusUpdateAction::Execute(Event event)
// NEAR_RANDOM -> IDLE // NEAR_RANDOM -> IDLE
if (info.lastNearRandom + statusNearRandomDuration < getMSTime()) if (info.lastNearRandom + statusNearRandomDuration < getMSTime())
{ {
info.Reset();
info.status = NewRpgStatus::IDLE; info.status = NewRpgStatus::IDLE;
return true; return true;
} }
@@ -129,6 +125,7 @@ bool NewRpgStatusUpdateAction::Execute(Event event)
{ {
if (info.lastNearNpc + statusNearNpcDuration < getMSTime()) if (info.lastNearNpc + statusNearNpcDuration < getMSTime())
{ {
info.Reset();
info.status = NewRpgStatus::IDLE; info.status = NewRpgStatus::IDLE;
return true; return true;
} }
@@ -139,6 +136,7 @@ bool NewRpgStatusUpdateAction::Execute(Event event)
// REST -> IDLE // REST -> IDLE
if (info.lastRest + statusRestDuration < getMSTime()) if (info.lastRest + statusRestDuration < getMSTime())
{ {
info.Reset();
info.status = NewRpgStatus::IDLE; info.status = NewRpgStatus::IDLE;
return true; return true;
} }
@@ -173,7 +171,7 @@ WorldPosition NewRpgStatusUpdateAction::SelectRandomGrindPos()
lo_prepared_locs.push_back(loc); lo_prepared_locs.push_back(loc);
} }
} }
WorldPosition dest; WorldPosition dest{};
if (urand(1, 100) <= 50 && !hi_prepared_locs.empty()) if (urand(1, 100) <= 50 && !hi_prepared_locs.empty())
{ {
uint32 idx = urand(0, hi_prepared_locs.size() - 1); uint32 idx = urand(0, hi_prepared_locs.size() - 1);
@@ -211,7 +209,7 @@ WorldPosition NewRpgStatusUpdateAction::SelectRandomInnKeeperPos()
prepared_locs.push_back(loc); prepared_locs.push_back(loc);
} }
} }
WorldPosition dest; WorldPosition dest{};
if (!prepared_locs.empty()) if (!prepared_locs.empty())
{ {
uint32 idx = urand(0, prepared_locs.size() - 1); uint32 idx = urand(0, prepared_locs.size() - 1);
@@ -225,6 +223,9 @@ WorldPosition NewRpgStatusUpdateAction::SelectRandomInnKeeperPos()
bool NewRpgGoFarAwayPosAction::MoveFarTo(WorldPosition dest) bool NewRpgGoFarAwayPosAction::MoveFarTo(WorldPosition dest)
{ {
if (dest == WorldPosition())
return false;
float dis = bot->GetExactDist(dest); float dis = bot->GetExactDist(dest);
if (dis < pathFinderDis) if (dis < pathFinderDis)
{ {
@@ -238,6 +239,27 @@ bool NewRpgGoFarAwayPosAction::MoveFarTo(WorldPosition dest)
return false; return false;
} }
// stuck check
float disToDest = bot->GetDistance(dest);
if (disToDest + 1.0f < botAI->rpgInfo.nearestMoveFarDis)
{
botAI->rpgInfo.nearestMoveFarDis = disToDest;
botAI->rpgInfo.stuckTs = getMSTime();
botAI->rpgInfo.stuckAttempts = 0;
}
else if (++botAI->rpgInfo.stuckAttempts >= 10 && botAI->rpgInfo.stuckTs + stuckTime < getMSTime())
{
// Unfortunately we've been stuck here for over 5 mins, fallback to teleporting directly to the destination
botAI->rpgInfo.stuckTs = getMSTime();
botAI->rpgInfo.stuckAttempts = 0;
const AreaTableEntry* entry = sAreaTableStore.LookupEntry(bot->GetZoneId());
std::string zone_name = PlayerbotAI::GetLocalizedAreaName(entry);
LOG_DEBUG("playerbots", "[New Rpg] Teleport {} from ({},{},{},{}) to ({},{},{},{}) as it stuck when moving far - Zone: {} ({})", bot->GetName(),
bot->GetPositionX(), bot->GetPositionY(), bot->GetPositionZ(), bot->GetMapId(),
dest.GetPositionX(), dest.GetPositionY(), dest.GetPositionZ(), dest.getMapId(), bot->GetZoneId(), zone_name);
return bot->TeleportTo(dest);
}
float minDelta = M_PI; float minDelta = M_PI;
const float x = bot->GetPositionX(); const float x = bot->GetPositionX();
const float y = bot->GetPositionY(); const float y = bot->GetPositionY();
@@ -254,12 +276,11 @@ bool NewRpgGoFarAwayPosAction::MoveFarTo(WorldPosition dest)
float dx = x + cos(angle) * dis; float dx = x + cos(angle) * dis;
float dy = y + sin(angle) * dis; float dy = y + sin(angle) * dis;
float dz = z + 0.5f; float dz = z + 0.5f;
bot->UpdateAllowedPositionZ(dx, dy, dz);
PathGenerator path(bot); PathGenerator path(bot);
path.CalculatePath(dx, dy, dz); path.CalculatePath(dx, dy, dz);
PathType type = path.GetPathType(); PathType type = path.GetPathType();
uint32 typeOk = PATHFIND_NORMAL | PATHFIND_INCOMPLETE | PATHFIND_FARFROMPOLY;
bool canReach = type == PATHFIND_NORMAL; bool canReach = !(type & (~typeOk));
if (canReach && fabs(delta) <= minDelta) if (canReach && fabs(delta) <= minDelta)
{ {
@@ -275,9 +296,6 @@ bool NewRpgGoFarAwayPosAction::MoveFarTo(WorldPosition dest)
{ {
return MoveTo(bot->GetMapId(), rx, ry, rz, false, false, false, true); return MoveTo(bot->GetMapId(), rx, ry, rz, false, false, false, true);
} }
// don't fallback to direct move
// float angle = bot->GetAngle(&dest);
// return MoveTo(bot->GetMapId(), x + cos(angle) * pathFinderDis, y + sin(angle) * pathFinderDis, z);
return false; return false;
} }

View File

@@ -39,7 +39,8 @@ public:
protected: protected:
// WorldPosition dest; // WorldPosition dest;
float pathFinderDis = 70.0f; // path finder const float pathFinderDis = 70.0f; // path finder
const uint32 stuckTime = 5 * 60 * 1000;
}; };
class NewRpgGoGrindAction : public NewRpgGoFarAwayPosAction class NewRpgGoGrindAction : public NewRpgGoFarAwayPosAction

View File

@@ -43,7 +43,10 @@ struct NewRpgInfo
uint32 lastNearRandom{0}; uint32 lastNearRandom{0};
// NewRpgStatus::REST // NewRpgStatus::REST
uint32 lastRest{0}; uint32 lastRest{0};
// MOVE_FAR
float nearestMoveFarDis{FLT_MAX};
uint32 stuckTs{0};
uint32 stuckAttempts{0};
std::string ToString() std::string ToString()
{ {
std::stringstream out; std::stringstream out;
@@ -82,6 +85,10 @@ struct NewRpgInfo
} }
return out.str(); return out.str();
} }
void Reset()
{
*this = NewRpgInfo();
}
}; };
class NewRpgStrategy : public Strategy class NewRpgStrategy : public Strategy