Ejemplo n.º 1
0
        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;
        }
Ejemplo n.º 2
0
        private void CubeGrid_OnBlockRemoved(IMySlimBlock obj)
        {
            IMyCubeBlock fatblock = obj.FatBlock;
            if (fatblock == null)
                return;

            myLogger.debugLog("block removed: " + obj.getBestName());
            myLogger.debugLog("block removed: " + obj.FatBlock.DefinitionDisplayNameText + "/" + obj.getBestName());
            lock_CubeBlocks.AcquireExclusive();
            try
            {
                // by type
                MyObjectBuilderType myOBtype = fatblock.BlockDefinition.TypeId;
                ListSnapshots<IMyCubeBlock> setBlocks_Type;
                if (!CubeBlocks_Type.TryGetValue(myOBtype, out setBlocks_Type))
                {
                    myLogger.debugLog("failed to get list of type: " + myOBtype);
                    return;
                }
                if (setBlocks_Type.Count == 1)
                    CubeBlocks_Type.Remove(myOBtype);
                else
                    setBlocks_Type.mutable().Remove(fatblock);

                // by definition
                IMyTerminalBlock asTerm = obj.FatBlock as IMyTerminalBlock;
                if (asTerm != null)
                    TerminalBlocks--;
            }
            catch (Exception e) { myLogger.alwaysLog("Exception: " + e, Logger.severity.ERROR); }
            finally { lock_CubeBlocks.ReleaseExclusive(); }
            myLogger.debugLog("leaving CubeGrid_OnBlockRemoved(): " + obj.getBestName());
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Find the closest damaged block that can be repaired; either the missing components are available or there are no missing components.
        /// </summary>
        /// <returns>The closest repairable block to the welders.</returns>
        private IMySlimBlock FindClosestRepairable()
        {
            Log.DebugLog("searching for closest repairable block");

            if (m_damagedBlocks.Count == 0)
            {
                if (m_projectedBlocks.Count != 0)
                {
                    ProjectedToDamaged();
                }
                if (m_damagedBlocks.Count == 0)
                {
                    GetDamagedBlocks();
                    if (m_damagedBlocks.Count == 0)
                    {
                        return(null);
                    }
                }
            }

            GetInventoryItems();

            IMySlimBlock        repairable = null;
            double              closest    = float.MaxValue;
            List <IMySlimBlock> removeList = null;

            foreach (IMySlimBlock slim in m_damagedBlocks)
            {
                if (slim.Closed())
                {
                    Log.DebugLog("slim closed: " + slim.getBestName());
                    continue;
                }

                if (slim.Damage() == 0f && ((MyCubeGrid)slim.CubeGrid).Projector == null)
                {
                    Log.DebugLog("already repaired: " + slim.getBestName(), Logger.severity.DEBUG);
                    if (removeList == null)
                    {
                        removeList = new List <IMySlimBlock>();
                    }
                    removeList.Add(slim);
                    continue;
                }

                Vector3D position;
                slim.ComputeWorldCenter(out position);
                double dist = Vector3D.DistanceSquared(m_controlBlock.CubeBlock.GetPosition(), position);

                if (dist < closest)
                {
                    m_components_missing.Clear();

                    if (slim.Damage() != 0f)
                    {
                        GetMissingComponents(slim);
                    }
                    else
                    {
                        // slim is projection
                        GetAllComponents(slim);
                    }

                    bool haveItem = false;

                    foreach (string component in m_components_missing.Keys)
                    {
                        if (m_components_inventory.ContainsKey(component))
                        {
                            haveItem = true;
                            break;
                        }
                    }

                    if (haveItem || m_components_missing.Count == 0)
                    {
                        repairable = slim;
                        closest    = dist;
                    }
                }
            }
            if (removeList != null)
            {
                foreach (IMySlimBlock remove in removeList)
                {
                    m_damagedBlocks.Remove(remove);
                }
            }

            Log.DebugLog(() => "closest repairable block: " + repairable.getBestName(), Logger.severity.DEBUG, condition: repairable != null);

            return(repairable);
        }
Ejemplo n.º 4
0
        /// <summary>
        /// <para>Test line segment between startPosition and targetPosition for obstructing entities.</para>
        /// <para>Tests for obstructing voxel map, character, or grid.</para>
        ///// <param name="shortTest">When checking voxels, shortens the line by 1 m, needed to interact with an entity that may be on the surface of the voxel.</param>
        /// </summary>
        public static bool Obstructed <Tobstruct, Tignore>(LineD line, IEnumerable <Tobstruct> potentialObstructions, IEnumerable <Tignore> ignoreList, bool checkVoxel = true, bool checkPlanet = DefaultCheckPlanet)     //, bool shortTest = true)
            where Tobstruct : IMyEntity
            where Tignore : IMyEntity
        {
            Profiler.StartProfileBlock();
            // Test each entity
            foreach (IMyEntity entity in potentialObstructions)
            {
                if (entity.Closed)
                {
                    continue;
                }

                if (ignoreList != null && ignoreList.Contains((Tignore)entity))
                {
                    continue;
                }

                IMyCharacter asChar = entity as IMyCharacter;
                if (asChar != null)
                {
                    double distance;
                    if (entity.WorldAABB.Intersects(ref line, out distance))
                    {
                        Logger.DebugLog("obstructed by character: " + entity.getBestName());
                        Profiler.EndProfileBlock();
                        return(true);
                    }
                    continue;
                }

                IMyCubeGrid asGrid = entity as IMyCubeGrid;
                if (asGrid != null)
                {
                    if (!asGrid.Save)
                    {
                        continue;
                    }

                    ICollection <Vector3I> allHitCells;

                    List <Vector3I> hitCells = new List <Vector3I>();
                    asGrid.RayCastCells(line.From, line.To, hitCells);

                    allHitCells = hitCells;

                    foreach (Vector3I pos in allHitCells)
                    {
                        IMySlimBlock slim = asGrid.GetCubeBlock(pos);
                        if (slim == null)
                        {
                            continue;
                        }

                        MyCubeBlock fatblock = (MyCubeBlock)slim.FatBlock;

                        if (fatblock != null)
                        {
                            if (ignoreList != null && ignoreList.Contains((Tignore)slim.FatBlock))
                            {
                                continue;
                            }

                            Dictionary <string, MyEntitySubpart> subparts = fatblock.Subparts;
                            if (subparts != null && subparts.Count != 0)
                            {
                                Vector3     gsPosition = pos * asGrid.GridSize;
                                BoundingBox gsAABB;
                                fatblock.CombinedAABB(out gsAABB);
                                if (gsAABB.Contains(gsPosition) == ContainmentType.Disjoint)
                                {
                                    continue;
                                }
                            }
                        }

                        Logger.DebugLog("obstructed by block: " + slim.getBestName() + " on " + slim.CubeGrid.DisplayName + ", id: " + slim.CubeGrid.EntityId);
                        Profiler.EndProfileBlock();
                        return(true);
                    }
                }
            }

            if (checkVoxel)
            {
                // Voxel Test
                MyVoxelBase hitVoxel;
                Vector3D    hitPosition;
                if (RayCastVoxels(line, out hitVoxel, out hitPosition, checkPlanet))
                {
                    Logger.DebugLog("obstructed by voxel: " + hitVoxel + " at " + hitPosition);
                    Profiler.EndProfileBlock();
                    return(true);
                }
            }

            // no obstruction found
            Profiler.EndProfileBlock();
            return(false);
        }
Ejemplo n.º 5
0
        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();
        }