public override void Move() { if (m_targetSlim.Closed()) { Log.DebugLog("target block closed: " + m_targetSlim.getBestName(), Logger.severity.INFO); m_navSet.OnTaskComplete_NavEngage(); EnableWelders(false); return; } m_targetSlim.ComputeWorldCenter(out m_targetWorld); if (m_stage == Stage.Retreat) { Retreat(); return; } float offsetSquared = m_offset + OffsetAdd + OffsetAdd; offsetSquared *= offsetSquared; if (Vector3.DistanceSquared(m_welder.WorldPosition, m_targetWorld) > offsetSquared) { EnableWelders(false); if (m_closestEmptyNeighbour.HasValue && Globals.UpdateCount > m_timeout_start) { Log.DebugLog("failed to start, dropping neighbour: " + m_closestEmptyNeighbour, Logger.severity.DEBUG); if (m_emptyNeighbours.Count > 1) { m_emptyNeighbours.Remove(m_closestEmptyNeighbour.Value); m_closestEmptyNeighbour = null; } else { Log.DebugLog("tried every empty neighbour, giving up", Logger.severity.INFO); EnableWelders(false); m_stage = Stage.Retreat; return; } } if (!m_closestEmptyNeighbour.HasValue) { GetClosestEmptyNeighbour(); if (!m_closestEmptyNeighbour.HasValue) { Log.DebugLog("tried every empty neighbour, giving up", Logger.severity.INFO); EnableWelders(false); m_stage = Stage.Retreat; return; } m_timeout_start = Globals.UpdateCount + TimeoutStart; Vector3D from = m_realGrid.GridIntegerToWorld(m_closestEmptyNeighbour.Value); m_lineUp.From = m_lineUp.To + (from - m_lineUp.To) * 100d; } Vector3 closestPoint = m_lineUp.ClosestPoint(m_welder.WorldPosition); if (Vector3.DistanceSquared(m_welder.WorldPosition, closestPoint) > 1f || m_navSet.Settings_Current.DistanceAngle > 0.1f) { m_stage = Stage.Lineup; Destination dest = Destination.FromWorld(m_realGrid, m_lineUp.ClosestPoint(m_welder.WorldPosition)); m_pathfinder.MoveTo(destinations: dest); return; } else // linedup up { m_stage = Stage.Approach; } } else // near target { m_stage = Stage.Weld; EnableWelders(true); } MoveToTarget(); }