From 5fcba45e80e5f22edc35257c52732237c4e29902 Mon Sep 17 00:00:00 2001 From: bash Date: Sat, 30 May 2026 23:29:51 +0200 Subject: [PATCH] feat(Core/Travel): Emit NODE_TELEPORT for teleport-spell edges; add HandleSpecialMovement consumer --- src/Ai/Base/Actions/MovementActions.cpp | 31 ++++++++++++++++++++++++- src/Mgr/Travel/TravelNode.cpp | 8 +++++++ 2 files changed, 38 insertions(+), 1 deletion(-) diff --git a/src/Ai/Base/Actions/MovementActions.cpp b/src/Ai/Base/Actions/MovementActions.cpp index 6eaa5ecd0..17c927cd9 100644 --- a/src/Ai/Base/Actions/MovementActions.cpp +++ b/src/Ai/Base/Actions/MovementActions.cpp @@ -3283,7 +3283,36 @@ bool MovementAction::HandleSpecialMovement(TravelPath& path) return bot->ActivateTaxiPathTo(route, flightMaster, 0); } - // NODE_TELEPORT consumer not yet re-added; falls through. + case PathNodeType::NODE_TELEPORT: + { + if (!next.entry) + return false; + + // Can't cast while flying — let the bot land first. + bool const canCastNow = !bot->IsFlying(); + + // Hearthstone (item 8690) — fire if available and not flying high. + if (next.entry == 8690) + { + if (canCastNow) + return botAI->DoSpecificAction("hearthstone", + Event("move action"), true); + return false; + } + + // Other teleport spells: dismount, drop shapeshift, queue cast. + // Skipped while flying high — caller's next-tick walk handles + // the descent. + if (!canCastNow) + return false; + if (bot->IsMounted()) + bot->Dismount(); + botAI->RemoveShapeshift(); + return botAI->DoSpecificAction( + "cast", + Event("rpg action", std::to_string(next.entry)), true); + } + default: return false; } diff --git a/src/Mgr/Travel/TravelNode.cpp b/src/Mgr/Travel/TravelNode.cpp index 3d887758c..86c2e0b7e 100644 --- a/src/Mgr/Travel/TravelNode.cpp +++ b/src/Mgr/Travel/TravelNode.cpp @@ -1217,6 +1217,14 @@ TravelPath TravelNodeRoute::BuildPath(std::vector pathToStart, st // Full taxi waypoint route; same reasoning as transport. travelPath.addPath(nodePath->GetPath(), PathNodeType::NODE_FLIGHTPATH, nodePath->getPathObject()); } + else if (nodePath->getPathType() == TravelNodePathType::teleportSpell) + { + // Hearthstone or spell-cast teleport edge: emit a paired + // NODE_TELEPORT (entry = exit) so HandleSpecialMovement can + // dispatch the cast when the head reaches the entry point. + travelPath.addPoint(*prevNode->getPosition(), PathNodeType::NODE_TELEPORT, nodePath->getPathObject()); + travelPath.addPoint(*node->getPosition(), PathNodeType::NODE_TELEPORT, nodePath->getPathObject()); + } else { std::vector path = nodePath->GetPath();