Пример #1
0
        /// <summary>
        /// Searches nearby voxels for ores.
        /// </summary>
        /// <param name="position">Position of autopilot block</param>
        /// <param name="oreType">Ore types to search for</param>
        /// <param name="onComplete">Invoked iff an ore is found</param>
        /// <returns>true if an ore is found</returns>
        private bool GetOreLocations(Vector3D position, byte[] oreType, OreSearchComplete onComplete)
        {
            Log.DebugLog("entered GetOreLocations()");

            using (l_getOreLocations.AcquireExclusiveUsing())
            {
                BoundingSphereD detection = new BoundingSphereD(m_oreDetector.GetPosition(), m_maxRange);
                m_nearbyVoxel.Clear();
                MyGamePruningStructure.GetAllVoxelMapsInSphere(ref detection, m_nearbyVoxel);

                IOrderedEnumerable <MyVoxelBase> sorted = m_nearbyVoxel.OrderBy(voxel => Vector3D.DistanceSquared(voxel.GetCentre(), position));

                foreach (IMyVoxelBase nearbyMap in sorted)
                {
                    if (nearbyMap is IMyVoxelMap || nearbyMap is MyPlanet)
                    {
                        VoxelData data;
                        using (l_voxelData.AcquireExclusiveUsing())
                        {
                            if (!m_voxelData.TryGetValue(nearbyMap.EntityId, out data))
                            {
                                data = new VoxelData(m_oreDetector, nearbyMap, m_maxRange);
                                m_voxelData.Add(nearbyMap.EntityId, data);
                            }
                        }
                        if (data.NeedsUpdate)
                        {
                            Log.DebugLog("Data needs to be updated for " + nearbyMap.getBestName());
                            data.Read();
                        }
                        else
                        {
                            Log.DebugLog("Old data OK for " + nearbyMap.getBestName());
                        }

                        IEnumerable <Vector3D> positions;
                        byte foundOre;
                        if (data.GetRandom(oreType, ref position, out foundOre, out positions))
                        {
                            //Log.DebugLog("PositionLeftBottomCorner: " + nearbyMap.PositionLeftBottomCorner + ", worldPosition: " + closest + ", distance: " + Vector3D.Distance(position, closest));
                            string oreName = MyDefinitionManager.Static.GetVoxelMaterialDefinition(foundOre).MinedOre;
                            onComplete(true, nearbyMap, oreName, positions);
                            m_nearbyVoxel.Clear();
                            return(true);
                        }
                        else
                        {
                            Log.DebugLog("No ore found");
                        }
                    }
                }

                m_nearbyVoxel.Clear();
                return(false);
            }
        }
Пример #2
0
        /// <summary>
        /// Searches nearby voxels for ores.
        /// </summary>
        /// <param name="position">Position of autopilot block</param>
        /// <param name="oreType">Ore types to search for</param>
        /// <param name="onComplete">Invoked iff an ore is found</param>
        /// <returns>true iff an ore is found</returns>
        private bool GetOreLocations(Vector3D position, byte[] oreType, OreSearchComplete onComplete)
        {
            m_logger.debugLog("entered GetOreLocations()");

            BoundingSphereD detection = new BoundingSphereD(m_oreDetector.GetPosition(), m_maxRange);
            m_nearbyVoxel.Clear();
            MyGamePruningStructure.GetAllVoxelMapsInSphere(ref detection, m_nearbyVoxel);

            IOrderedEnumerable<MyVoxelBase> sorted = m_nearbyVoxel.OrderBy(voxel => Vector3D.DistanceSquared(voxel.GetCentre(), position));

            foreach (IMyVoxelBase nearbyMap in sorted)
            {
                if (nearbyMap is IMyVoxelMap || nearbyMap is MyPlanet)
                {
                    VoxelData data;
                    using (l_voxelData.AcquireExclusiveUsing())
                        if (!m_voxelData.TryGetValue(nearbyMap, out data))
                        {
                            data = new VoxelData(m_oreDetector, nearbyMap, m_maxRange);
                            m_voxelData.Add(nearbyMap, data);
                        }

                    if (data.NeedsUpdate)
                    {
                        m_logger.debugLog("Data needs to be updated for " + nearbyMap.getBestName());
                        data.Read();
                    }
                    else
                        m_logger.debugLog("Old data OK for " + nearbyMap.getBestName());

                    Vector3D closest;
                    byte foundOre;
                    if (data.GetClosest(oreType, ref position, out closest, out foundOre))
                    {
                        m_logger.debugLog("PositionLeftBottomCorner: " + nearbyMap.PositionLeftBottomCorner + ", worldPosition: " + closest + ", distance: " + Vector3D.Distance(position, closest));
                        string oreName = MyDefinitionManager.Static.GetVoxelMaterialDefinition(foundOre).MinedOre;
                        onComplete(true, closest, nearbyMap, oreName);
                        m_nearbyVoxel.Clear();
                        return true;
                    }
                }
            }

            m_nearbyVoxel.Clear();
            return false;
        }
Пример #3
0
        /// <summary>
        /// Search every possible ore detector for materials.
        /// </summary>
        /// <param name="requester">Must be able to control OreDetector and have same NetworkStorage</param>
        /// <param name="oreType">Voxel materials to search for</param>
        public static void SearchForMaterial(ShipControllerBlock requester, byte[] oreType, OreSearchComplete onComplete)
        {
            Vector3D     position = requester.CubeBlock.GetPosition();
            RelayStorage storage  = requester.NetworkStorage;

            Static.m_thread.EnqueueAction(() => {
                List <OreDetector> oreDetectors = ResourcePool <List <OreDetector> > .Get();
                Registrar.ForEach((OreDetector detector) => {
                    if (detector.Block.IsWorking && requester.CubeBlock.canControlBlock(detector.Block) && detector.m_netClient.GetStorage() == storage)
                    {
                        oreDetectors.Add(detector);
                    }
                });

                IOrderedEnumerable <OreDetector> sorted = oreDetectors.OrderBy(detector => Vector3D.DistanceSquared(position, detector.Block.GetPosition()));

                foreach (OreDetector detector in sorted)
                {
                    if (detector.GetOreLocations(position, oreType, onComplete))
                    {
                        return;
                    }
                }

                oreDetectors.Clear();
                ResourcePool <List <OreDetector> > .Return(oreDetectors);

                onComplete(false, null, null, null);
            });
        }
Пример #4
0
        /// <summary>
        /// Search every possible ore detector for materials.
        /// </summary>
        /// <param name="requester">Must be able to control OreDetector and have same NetworkStorage</param>
        /// <param name="oreType">Voxel materials to search for</param>
        public static void SearchForMaterial(ShipControllerBlock requester, byte[] oreType, OreSearchComplete onComplete)
        {
            Vector3D position = requester.CubeBlock.GetPosition();
            RelayStorage storage = requester.NetworkStorage;

            m_thread.EnqueueAction(() => {
                List<OreDetector> oreDetectors = ResourcePool<List<OreDetector>>.Get();
                Registrar.ForEach((OreDetector detector) => {
                    if (detector.Block.IsWorking && requester.CubeBlock.canControlBlock(detector.Block) && detector.m_netClient.GetStorage() == storage)
                        oreDetectors.Add(detector);
                });

                IOrderedEnumerable<OreDetector> sorted = oreDetectors.OrderBy(detector => Vector3D.DistanceSquared(position, detector.Block.GetPosition()));

                foreach (OreDetector detector in sorted)
                    if (detector.GetOreLocations(position, oreType, onComplete))
                        return;

                oreDetectors.Clear();
                ResourcePool<List<OreDetector>>.Return(oreDetectors);

                onComplete(false, Vector3D.Zero, null, null);
            });
        }