private void MoveToTarget() { Log.DebugLog("moving to target in wrong stage", Logger.severity.FATAL, condition: m_stage != Stage.Approach && m_stage != Stage.Weld); if ((Globals.UpdateCount - m_lastWeld) > 1200ul) { Log.DebugLog("failed to repair block"); EnableWelders(false); m_stage = Stage.Retreat; return; } if (m_weldProjection) { // check for slim being placed IMySlimBlock placed = m_realGrid.GetCubeBlock(m_targetCell); if (placed != null) { Log.DebugLog("projected target placed", Logger.severity.DEBUG); m_weldProjection = false; m_targetSlim = placed; } } // check for weld float damage = m_targetSlim.Damage(); foreach (Vector3I cell in m_neighbours) { IMySlimBlock slim = m_realGrid.GetCubeBlock(cell); if (slim != null) { damage += slim.Damage(); } } if (damage < m_damage) { m_lastWeld = Globals.UpdateCount; } m_damage = damage; if (!m_weldProjection && m_targetSlim.Damage() == 0f && (Globals.UpdateCount - m_lastWeld) > 120ul) { Log.DebugLog("target block repaired: " + m_targetSlim.getBestName(), Logger.severity.DEBUG); EnableWelders(false); m_stage = Stage.Retreat; return; } else { float offset = m_stage == Stage.Weld ? m_offset : m_offset + OffsetAdd; Vector3D welderFromTarget = m_controlBlock.CubeBlock.GetPosition() - m_targetWorld; welderFromTarget.Normalize(); Destination dest = Destination.FromWorld(m_realGrid, m_targetWorld + welderFromTarget * offset); m_pathfinder.MoveTo(destinations: dest); } }
private void Retreat() { float minDist = m_offset + 10f; minDist *= minDist; if (Vector3D.DistanceSquared(m_welder.WorldPosition, m_targetWorld) > minDist) { Log.DebugLog("moved away from: " + m_targetSlim.getBestName(), Logger.severity.DEBUG); if (!m_weldProjection && m_targetSlim.Damage() < m_slimTarget_initDmg) { Log.DebugLog("assuming ship ran out of components, damage: " + m_targetSlim.Damage(), condition: m_targetSlim.Damage() != 0f); m_navSet.OnTaskComplete_NavEngage(); m_mover.StopMove(); m_mover.StopRotate(); return; } else { Log.DebugLog("no welding done, trying another approach"); if (m_emptyNeighbours.Count > 1) { // if we were very close when we started, no neighbour would have been chosen if (m_closestEmptyNeighbour.HasValue) { m_emptyNeighbours.Remove(m_closestEmptyNeighbour.Value); m_closestEmptyNeighbour = null; } m_stage = Stage.Lineup; return; } else { Log.DebugLog("tried every empty neighbour, giving up", Logger.severity.INFO); m_navSet.OnTaskComplete_NavEngage(); m_mover.StopMove(); m_mover.StopRotate(); return; } } } Vector3D direction = m_welder.WorldPosition - m_targetWorld; direction.Normalize(); Destination dest = Destination.FromWorld(m_realGrid, m_welder.WorldPosition + direction * 10d); m_pathfinder.MoveTo(destinations: dest); }
public WeldBlock(Pathfinder pathfinder, AllNavigationSettings navSet, PseudoBlock welder, IMySlimBlock block) : base(pathfinder) { this.m_offset = welder.Block.LocalAABB.GetLongestDim() * 0.5f; // this works for default welders, may not work if mod has an exotic design this.m_welder = welder; this.m_targetSlim = block; this.m_timeout_start = Globals.UpdateCount + TimeoutStart; IMyCubeBlock Projector = ((MyCubeGrid)block.CubeGrid).Projector; if (Projector != null) { this.m_weldProjection = true; this.m_otherGrid = Projector.CubeGrid; this.m_slimTarget_initDmg = 1f; this.m_targetCell = Projector.CubeGrid.WorldToGridInteger(block.CubeGrid.GridIntegerToWorld(block.Position)); } else { this.m_weldProjection = false; this.m_slimTarget_initDmg = block.Damage(); this.m_targetCell = block.Position; } m_navSet.Settings_Task_NavEngage.NavigatorMover = this; m_navSet.Settings_Task_NavEngage.NavigatorRotator = this; m_navSet.Settings_Task_NavEngage.DestinationEntity = m_realGrid; IEnumerator <Vector3I> neighbours = this.m_targetSlim.ForEachNeighbourCell(); while (neighbours.MoveNext()) { Vector3I cell = m_weldProjection ? Projector.CubeGrid.WorldToGridInteger(block.CubeGrid.GridIntegerToWorld(neighbours.Current)) : neighbours.Current; m_neighbours.Add(cell); if (this.m_realGrid.GetCubeBlock(cell) == null) { m_emptyNeighbours.Add(cell); } } m_targetSlim.ComputeWorldCenter(out m_targetWorld); m_lineUp.To = m_targetWorld; }
public WeldBlock(Mover mover, AllNavigationSettings navSet, PseudoBlock welder, IMySlimBlock block) : base(mover, navSet) { this.m_logger = new Logger(GetType().Name, () => mover.Block.CubeGrid.DisplayName, () => block.getBestName(), () => m_stage.ToString()); this.m_offset = welder.Block.LocalAABB.GetLongestDim() * 0.5f; // this works for default welders, may not work if mod has an exotic design this.m_welder = welder; this.m_targetSlim = block; this.m_timeout_start = Globals.UpdateCount + TimeoutStart; IMyCubeBlock Projector = ((MyCubeGrid)block.CubeGrid).Projector; if (Projector != null) { this.m_weldProjection = true; this.m_otherGrid = Projector.CubeGrid; this.m_slimTarget_initDmg = 1f; this.m_targetCell = Projector.CubeGrid.WorldToGridInteger(block.CubeGrid.GridIntegerToWorld(block.Position)); } else { this.m_weldProjection = false; this.m_slimTarget_initDmg = block.Damage(); this.m_targetCell = block.Position; } m_navSet.Settings_Task_NavEngage.NavigatorMover = this; m_navSet.Settings_Task_NavEngage.NavigatorRotator = this; m_navSet.Settings_Task_NavEngage.DestinationEntity = m_realGrid; IEnumerator<Vector3I> neighbours = this.m_targetSlim.ForEachNeighbourCell(); while (neighbours.MoveNext()) { Vector3I cell = m_weldProjection ? Projector.CubeGrid.WorldToGridInteger(block.CubeGrid.GridIntegerToWorld(neighbours.Current)) : neighbours.Current; m_neighbours.Add(cell); if (this.m_realGrid.GetCubeBlock(cell) == null) m_emptyNeighbours.Add(cell); } m_targetSlim.ComputeWorldCenter(out m_targetWorld); m_lineUp.To = m_targetWorld; }