mirror of
https://github.com/liyunfan1223/mod-playerbots.git
synced 2026-06-20 15:39:25 +02:00
refactor(Core/Travel): Simplify transport config to TransportSkipRide bool; drop mode-0 deck-walk approximations
This commit is contained in:
parent
f90f365e94
commit
6079863fce
@ -1038,14 +1038,15 @@ AiPlayerbot.EnableNewRpgStrategy = 1
|
|||||||
# Default: 0 (disabled)
|
# Default: 0 (disabled)
|
||||||
AiPlayerbot.EnableTravelNodes = 0
|
AiPlayerbot.EnableTravelNodes = 0
|
||||||
|
|
||||||
# Transport handling mode (travel node graph only):
|
# Transport ride mode (travel node graph only):
|
||||||
# 0 = bot walks to dock, boards transport, rides, walks off (fully physical)
|
# 0 = bot walks to dock, teleport-snaps onto transport, rides, teleport-snaps off
|
||||||
# 1 = same as 0, but if walk-on/off fails the boarding teleports the bot
|
# 1 = bot teleports directly across the transport route, skipping the ride
|
||||||
# 2 = bot teleports across the route, skipping the ride entirely
|
# Default 0 is the visible behavior. Set to 1 for invisible/random-bot mass
|
||||||
# Reference default is 0; raise only if invisible/random-bot mass travel
|
# travel performance — the bot never actually boards anything.
|
||||||
# performance becomes an issue.
|
# (AC has no transport-surface mmap, so an on-deck walking mode can't be
|
||||||
|
# faithfully implemented; the on-board phase always teleport-snaps.)
|
||||||
# Default: 0
|
# Default: 0
|
||||||
AiPlayerbot.TransportTeleportType = 0
|
AiPlayerbot.TransportSkipRide = 0
|
||||||
|
|
||||||
# Control probability weights for RPG status of bots. Takes effect only when the status meets its premise.
|
# Control probability weights for RPG status of bots. Takes effect only when the status meets its premise.
|
||||||
# Sum of weights need not be 100. Set to 0 to disable the status.
|
# Sum of weights need not be 100. Set to 0 to disable the status.
|
||||||
|
|||||||
@ -3145,20 +3145,12 @@ bool MovementAction::WaitForTransport()
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Disembark: head is the transport node where we should get off,
|
// Disembark: head is the transport node where we should get off,
|
||||||
// next is the world-position dock to land at. Reference UseTransport
|
// next is the world-position dock to land at.
|
||||||
// with doTeleport=(transportTeleportType > 0) routes to either
|
|
||||||
// MoveOffTransport-teleport (mode 1+) or MoveOffTransport-walk (mode 0).
|
|
||||||
PathNodePoint const& dock = path[0];
|
|
||||||
if (path.size() < 2)
|
if (path.size() < 2)
|
||||||
return true; // no telePoint to land at; keep waiting
|
return true; // no telePoint to land at; keep waiting
|
||||||
PathNodePoint const& tele = path[1];
|
PathNodePoint const& tele = path[1];
|
||||||
(void)dock; // kept for reference parity (UseTransport signature)
|
|
||||||
|
|
||||||
transport->RemovePassenger(bot);
|
transport->RemovePassenger(bot);
|
||||||
|
|
||||||
if (sPlayerbotAIConfig.transportTeleportType > 0)
|
|
||||||
{
|
|
||||||
// Mode 1+: teleport directly to exit.
|
|
||||||
bot->StopMovingOnCurrentPos();
|
bot->StopMovingOnCurrentPos();
|
||||||
bool const teleported = bot->TeleportTo(tele.point.GetMapId(),
|
bool const teleported = bot->TeleportTo(tele.point.GetMapId(),
|
||||||
tele.point.GetPositionX(),
|
tele.point.GetPositionX(),
|
||||||
@ -3167,25 +3159,6 @@ bool MovementAction::WaitForTransport()
|
|||||||
bot->GetOrientation());
|
bot->GetOrientation());
|
||||||
if (!teleported)
|
if (!teleported)
|
||||||
return true; // try again next tick
|
return true; // try again next tick
|
||||||
lastMove.lastTransportEntry = 0;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Mode 0: NearTeleportTo current world position (drops bot off
|
|
||||||
// transport plane to world coords without unloading client), then
|
|
||||||
// walk to the exit position. Matches reference MoveOffTransport
|
|
||||||
// with doTeleport=false.
|
|
||||||
bot->NearTeleportTo(bot->GetPositionX(), bot->GetPositionY(),
|
|
||||||
bot->GetPositionZ(), bot->GetOrientation());
|
|
||||||
|
|
||||||
if (MotionMaster* mm = bot->GetMotionMaster())
|
|
||||||
{
|
|
||||||
mm->Clear();
|
|
||||||
mm->MovePoint(0, tele.point.GetPositionX(),
|
|
||||||
tele.point.GetPositionY(),
|
|
||||||
tele.point.GetPositionZ(),
|
|
||||||
FORCED_MOVEMENT_RUN, 0.0f, 0.0f, true, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
lastMove.lastTransportEntry = 0;
|
lastMove.lastTransportEntry = 0;
|
||||||
return false;
|
return false;
|
||||||
@ -3274,10 +3247,7 @@ bool MovementAction::HandleSpecialMovement(TravelPath& path)
|
|||||||
case PathNodeType::NODE_TRANSPORT:
|
case PathNodeType::NODE_TRANSPORT:
|
||||||
{
|
{
|
||||||
// Disembark: head is a transport node and bot is on one.
|
// Disembark: head is a transport node and bot is on one.
|
||||||
// Reference dispatch: MoveOffTransport(exit, doTeleport) where
|
// RemovePassenger + TeleportTo the next-step world position.
|
||||||
// doTeleport = (transportTeleportType > 0). Mode 1+ teleports
|
|
||||||
// straight to exit; mode 0 NearTeleports off transport plane
|
|
||||||
// then walks to exit.
|
|
||||||
if (!hasNext)
|
if (!hasNext)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@ -3287,9 +3257,6 @@ bool MovementAction::HandleSpecialMovement(TravelPath& path)
|
|||||||
|
|
||||||
PathNodePoint const& dst = path[1];
|
PathNodePoint const& dst = path[1];
|
||||||
transport->RemovePassenger(bot);
|
transport->RemovePassenger(bot);
|
||||||
|
|
||||||
if (sPlayerbotAIConfig.transportTeleportType > 0)
|
|
||||||
{
|
|
||||||
bot->StopMovingOnCurrentPos();
|
bot->StopMovingOnCurrentPos();
|
||||||
bool const teleported = bot->TeleportTo(dst.point.GetMapId(),
|
bool const teleported = bot->TeleportTo(dst.point.GetMapId(),
|
||||||
dst.point.GetPositionX(),
|
dst.point.GetPositionX(),
|
||||||
@ -3300,24 +3267,6 @@ bool MovementAction::HandleSpecialMovement(TravelPath& path)
|
|||||||
return teleported;
|
return teleported;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Mode 0: NearTeleportTo current world pos (drops bot off
|
|
||||||
// transport plane without unloading the client), then walk
|
|
||||||
// to the exit.
|
|
||||||
bot->NearTeleportTo(bot->GetPositionX(), bot->GetPositionY(),
|
|
||||||
bot->GetPositionZ(), bot->GetOrientation());
|
|
||||||
|
|
||||||
if (MotionMaster* mm = bot->GetMotionMaster())
|
|
||||||
{
|
|
||||||
mm->Clear();
|
|
||||||
mm->MovePoint(0, dst.point.GetPositionX(),
|
|
||||||
dst.point.GetPositionY(),
|
|
||||||
dst.point.GetPositionZ(),
|
|
||||||
FORCED_MOVEMENT_RUN, 0.0f, 0.0f, true, false);
|
|
||||||
}
|
|
||||||
AI_VALUE(LastMovement&, "last movement").lastTransportEntry = 0;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -3527,87 +3476,29 @@ bool MovementAction::BoardTransport(Transport* transport)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Teleport-onto mode (transportTeleportType >= 1): skip the walk-toward
|
// Bot off transport: find a boarding edge and teleport-snap directly
|
||||||
// phase and jump directly to a boarding edge. Matches reference's
|
// onto it, then AddPassenger. We can't walk on the deck (no transport-
|
||||||
// MoveOnTransport(doTeleport=true) — PlayerRelocation + AddPassenger.
|
// surface mmap), so the snap-board is the only universal approach.
|
||||||
if (sPlayerbotAIConfig.transportTeleportType >= 1)
|
|
||||||
{
|
|
||||||
float edgeX, edgeY, edgeZ;
|
float edgeX, edgeY, edgeZ;
|
||||||
if (FindBoardingPointOnTransport(map, transport, transport,
|
if (!FindBoardingPointOnTransport(map, transport, transport,
|
||||||
transport->GetPositionX(), transport->GetPositionY(),
|
transport->GetPositionX(), transport->GetPositionY(),
|
||||||
transport->GetPositionZ(),
|
transport->GetPositionZ(),
|
||||||
bot->GetPositionX(), bot->GetPositionY(), bot->GetPositionZ(),
|
bot->GetPositionX(), bot->GetPositionY(), bot->GetPositionZ(),
|
||||||
edgeX, edgeY, edgeZ))
|
edgeX, edgeY, edgeZ))
|
||||||
{
|
{
|
||||||
if (bot->TeleportTo(map->GetId(), edgeX, edgeY, edgeZ, bot->GetOrientation()))
|
// No boarding edge found — wait a tick. Caller's WaitForReach
|
||||||
{
|
// upstream throttles the retry.
|
||||||
transport->AddPassenger(bot, true);
|
EmitDebugMove("Transport:board", "no-edge",
|
||||||
bot->StopMovingOnCurrentPos();
|
|
||||||
EmitDebugMove("Transport:board", "teleport-skip-walk",
|
|
||||||
edgeX, edgeY, edgeZ);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Fall through to mode-0 if no boarding point — better than refusing.
|
|
||||||
}
|
|
||||||
|
|
||||||
// Mode 0: reference MoveOnTransport(doTeleport=false) — AddPassenger
|
|
||||||
// FIRST (snaps bot onto transport plane), then walk a path on deck.
|
|
||||||
// We don't have RandomPointOnTrans / transport-surface mmap, so when
|
|
||||||
// the bot is within INTERACTION_DISTANCE of the transport's boarding
|
|
||||||
// edge we approximate: AddPassenger + MovePoint toward the transport
|
|
||||||
// center as a "deck destination." Bot motion is then transport-
|
|
||||||
// relative because of the AddPassenger.
|
|
||||||
float boardX = transport->GetPositionX();
|
|
||||||
float boardY = transport->GetPositionY();
|
|
||||||
float boardZ = transport->GetPositionZ();
|
|
||||||
|
|
||||||
float edgeX, edgeY, edgeZ;
|
|
||||||
bool haveEdge = FindBoardingPointOnTransport(map, transport, transport,
|
|
||||||
transport->GetPositionX(), transport->GetPositionY(),
|
transport->GetPositionX(), transport->GetPositionY(),
|
||||||
transport->GetPositionZ(), bot->GetPositionX(), bot->GetPositionY(),
|
transport->GetPositionZ());
|
||||||
bot->GetPositionZ(), edgeX, edgeY, edgeZ);
|
|
||||||
if (haveEdge)
|
|
||||||
{
|
|
||||||
boardX = edgeX;
|
|
||||||
boardY = edgeY;
|
|
||||||
boardZ = edgeZ;
|
|
||||||
}
|
|
||||||
|
|
||||||
float const dxBoard = bot->GetPositionX() - boardX;
|
|
||||||
float const dyBoard = bot->GetPositionY() - boardY;
|
|
||||||
bool const nearBoardingPoint =
|
|
||||||
(dxBoard * dxBoard + dyBoard * dyBoard) <
|
|
||||||
INTERACTION_DISTANCE * INTERACTION_DISTANCE;
|
|
||||||
|
|
||||||
if (nearBoardingPoint)
|
|
||||||
{
|
|
||||||
// Snap onto transport plane, then walk a short deck path so the
|
|
||||||
// bot is visibly on the boat (mirrors reference mode-0 deck walk).
|
|
||||||
transport->AddPassenger(bot, true);
|
|
||||||
if (MotionMaster* mm = bot->GetMotionMaster())
|
|
||||||
{
|
|
||||||
if (!bot->IsStandState())
|
|
||||||
bot->SetStandState(UNIT_STAND_STATE_STAND);
|
|
||||||
mm->Clear();
|
|
||||||
mm->MovePoint(0, transport->GetPositionX(), transport->GetPositionY(),
|
|
||||||
transport->GetPositionZ(),
|
|
||||||
FORCED_MOVEMENT_RUN, 0.0f, 0.0f, false, false);
|
|
||||||
}
|
|
||||||
EmitDebugMove("Transport:board", "snap-and-deck-walk",
|
|
||||||
boardX, boardY, boardZ);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Too far to snap — walk toward boarding edge.
|
|
||||||
if (MotionMaster* mm = bot->GetMotionMaster())
|
|
||||||
{
|
|
||||||
if (!bot->IsStandState())
|
|
||||||
bot->SetStandState(UNIT_STAND_STATE_STAND);
|
|
||||||
mm->MovePoint(0, boardX, boardY, boardZ,
|
|
||||||
FORCED_MOVEMENT_NONE, 0.0f, 0.0f, false, false);
|
|
||||||
EmitDebugMove("Transport:walk", "approach-boarding", boardX, boardY, boardZ);
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!bot->TeleportTo(map->GetId(), edgeX, edgeY, edgeZ, bot->GetOrientation()))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
transport->AddPassenger(bot, true);
|
||||||
|
bot->StopMovingOnCurrentPos();
|
||||||
|
EmitDebugMove("Transport:board", "snap", edgeX, edgeY, edgeZ);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|||||||
@ -927,9 +927,9 @@ bool TravelPath::UpcommingSpecialMovement(WorldPosition startPos,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Walk-on / teleport-to-transport boarding mode (modes 0 and 1).
|
// Board-and-ride mode (transportSkipRide == false). Cut to dock if
|
||||||
// Cut to dock if off-transport, traverse to disembark if on-transport.
|
// off-transport, traverse to disembark if on-transport.
|
||||||
if (sPlayerbotAIConfig.transportTeleportType < 2 &&
|
if (!sPlayerbotAIConfig.transportSkipRide &&
|
||||||
startP->type == PathNodeType::NODE_TRANSPORT)
|
startP->type == PathNodeType::NODE_TRANSPORT)
|
||||||
{
|
{
|
||||||
uint32 const entry = nextP->entry;
|
uint32 const entry = nextP->entry;
|
||||||
@ -954,11 +954,11 @@ bool TravelPath::UpcommingSpecialMovement(WorldPosition startPos,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Teleport-across mode (mode 2): bot is approaching a transport
|
// Skip-ride mode (transportSkipRide == true): bot is approaching a
|
||||||
// node — walk forward to find the first non-transport node (the
|
// transport node — walk forward to find the first non-transport node
|
||||||
// disembark side), cut to prevP (last transport node) so
|
// (the disembark side), cut to prevP (last transport node) so
|
||||||
// HandleSpecialMovement teleports the bot across directly.
|
// HandleSpecialMovement teleports the bot across directly.
|
||||||
if (sPlayerbotAIConfig.transportTeleportType == 2 &&
|
if (sPlayerbotAIConfig.transportSkipRide &&
|
||||||
nextP->type == PathNodeType::NODE_TRANSPORT)
|
nextP->type == PathNodeType::NODE_TRANSPORT)
|
||||||
{
|
{
|
||||||
for (auto p = std::next(startP); p != fullPath.end(); ++p)
|
for (auto p = std::next(startP); p != fullPath.end(); ++p)
|
||||||
|
|||||||
@ -88,7 +88,7 @@ bool PlayerbotAIConfig::Initialize()
|
|||||||
|
|
||||||
farDistance = sConfigMgr->GetOption<float>("AiPlayerbot.FarDistance", 20.0f);
|
farDistance = sConfigMgr->GetOption<float>("AiPlayerbot.FarDistance", 20.0f);
|
||||||
sightDistance = sConfigMgr->GetOption<float>("AiPlayerbot.SightDistance", 100.0f);
|
sightDistance = sConfigMgr->GetOption<float>("AiPlayerbot.SightDistance", 100.0f);
|
||||||
transportTeleportType = sConfigMgr->GetOption<uint32>("AiPlayerbot.TransportTeleportType", 0);
|
transportSkipRide = sConfigMgr->GetOption<bool>("AiPlayerbot.TransportSkipRide", false);
|
||||||
spellDistance = sConfigMgr->GetOption<float>("AiPlayerbot.SpellDistance", 28.5f);
|
spellDistance = sConfigMgr->GetOption<float>("AiPlayerbot.SpellDistance", 28.5f);
|
||||||
shootDistance = sConfigMgr->GetOption<float>("AiPlayerbot.ShootDistance", 5.0f);
|
shootDistance = sConfigMgr->GetOption<float>("AiPlayerbot.ShootDistance", 5.0f);
|
||||||
healDistance = sConfigMgr->GetOption<float>("AiPlayerbot.HealDistance", 38.5f);
|
healDistance = sConfigMgr->GetOption<float>("AiPlayerbot.HealDistance", 38.5f);
|
||||||
|
|||||||
@ -93,11 +93,12 @@ public:
|
|||||||
bool randomBotGuildNearby, randomBotInvitePlayer, inviteChat;
|
bool randomBotGuildNearby, randomBotInvitePlayer, inviteChat;
|
||||||
uint32 globalCoolDown, reactDelay, maxWaitForMove, disableMoveSplinePath, expireActionTime,
|
uint32 globalCoolDown, reactDelay, maxWaitForMove, disableMoveSplinePath, expireActionTime,
|
||||||
dispelAuraDuration, passiveDelay, repeatDelay, errorDelay, rpgDelay, sitDelay, returnDelay, lootDelay;
|
dispelAuraDuration, passiveDelay, repeatDelay, errorDelay, rpgDelay, sitDelay, returnDelay, lootDelay;
|
||||||
// Transport handling mode (matches reference `transportTeleportType`):
|
// Transport handling:
|
||||||
// 0 = walk on board, walk off (default, fully physical)
|
// false (default) = teleport-board, ride the transport, teleport-disembark
|
||||||
// 1 = walk on board, but UseTransport teleports on/off if walk fails
|
// true = skip the ride entirely (teleport directly across)
|
||||||
// 2 = skip the ride entirely — teleport directly across the route
|
// AC has no transport-surface mmap so an in-deck walking mode can't be
|
||||||
uint32 transportTeleportType;
|
// faithfully implemented — the on-board phase always teleport-snaps.
|
||||||
|
bool transportSkipRide;
|
||||||
bool dynamicReactDelay;
|
bool dynamicReactDelay;
|
||||||
float sightDistance, spellDistance, reactDistance, grindDistance, lootDistance, shootDistance, fleeDistance,
|
float sightDistance, spellDistance, reactDistance, grindDistance, lootDistance, shootDistance, fleeDistance,
|
||||||
tooCloseDistance, meleeDistance, followDistance, whisperDistance, contactDistance, aoeRadius, rpgDistance,
|
tooCloseDistance, meleeDistance, followDistance, whisperDistance, contactDistance, aoeRadius, rpgDistance,
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user