mirror of
https://github.com/mod-playerbots/mod-playerbots.git
synced 2026-02-04 11:23:48 +00:00
Add stuck fallback for rpg move far (#914)
This commit is contained in:
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user