/// <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); } }
/// <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; }
/// <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); }); }
/// <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); }); }