/// <summary> /// Interpolates the position of the given Unit along the Path given the elapsed flight time. /// </summary> /// <param name="elapsedTime">Time that elapsed since the given unit passed by the last PathVertex</param> internal static void InterpolatePosition(Unit unit, int elapsedTime) { var latestNode = unit.LatestTaxiPathNode; unit.taxiTime += elapsedTime; if (latestNode.Next == null) { // must not happen unit.CancelTaxiFlight(); return; } while (latestNode.Next.Value.TimeFromStart <= unit.taxiTime) { // arrived at a node //if (unit is Character) //{ // var chr = (Character) unit; // chr.SendSystemMessage("[{0}] Node: {1} yards ({2} millis)", // (int)RealmServer.RunTime.TotalMilliseconds, // latestNode.Next.Value.DistFromStart, // latestNode.Next.Value.TimeFromStart); //} latestNode = latestNode.Next; unit.LatestTaxiPathNode = latestNode; if (latestNode.Next == null) { // Finished this Path if (IsNormalSpeed) { unit.m_TaxiMovementTimer.Stop(); } else { ContinueFlight(unit); } return; } } var prevPathNode = latestNode.Value; var nextPathNode = latestNode.Next.Value; // time in millis since we passed the last node var timeDelta = unit.taxiTime - latestNode.Value.TimeFromStart; var pos = prevPathNode.Pos + (((nextPathNode.Pos - prevPathNode.Pos) * timeDelta) / nextPathNode.TimeFromPrevious); unit.Map.MoveObject(unit, ref pos); }
/// <summary> /// Send character down the next leg of a multi-hop trip. /// </summary> internal static void ContinueFlight(Unit unit) { if (unit.LatestTaxiPathNode == null) { //throw new InvalidOperationException("Tried to continue Taxi-flight of Unit which did not start flying."); return; } var latestVertex = unit.LatestTaxiPathNode.Value; var current = latestVertex.Path.To; if (unit.m_TaxiMovementTimer.IsRunning && !unit.IsInRadius(current.Position, AirSpeed)) { return; } var done = false; // Are we at the end of the line? if (unit.TaxiPaths.Count < 2) { done = true; } else { var arrivalPath = unit.TaxiPaths.Dequeue(); if (arrivalPath.To != current) { unit.CancelTaxiFlight(); return; } var destPath = unit.TaxiPaths.Peek(); if (current != destPath.From) { unit.CancelTaxiFlight(); return; } } if (!done) { // One stop on a multi-stop ride FlyUnit(unit, false); } else { if (IsNormalSpeed) { unit.Map.MoveObject(unit, latestVertex.Pos); } else { // Client doesn't seem to display the movement fast enough // so we have to speed it up by teleporting unit.TeleportTo(latestVertex.Pos); } unit.CancelTaxiFlight(); } }