public void Update(Vector3D position, bool checkControl = true) { Clear(); if (!SetRelayedRequest && checkControl && !OnCheckControl()) { m_depositGroupsByEntity.Clear(); return; } SetRelayedRequest = false; var sphere = new BoundingSphereD(position, DetectionRadius); MyGamePruningStructure.GetAllVoxelMapsInSphere(ref sphere, m_inRangeCache); { // Find voxel maps which went out of range and then remove them. foreach (var voxelMap in m_depositGroupsByEntity.Keys) { if (!m_inRangeCache.Contains(voxelMap)) { m_notInRangeCache.Add(voxelMap); } } foreach (var notInRange in m_notInRangeCache) { m_depositGroupsByEntity.Remove(notInRange); } m_notInRangeCache.Clear(); } { // Add voxel maps which came into range. foreach (var voxelMap in m_inRangeCache) { if (!m_depositGroupsByEntity.ContainsKey(voxelMap)) { m_depositGroupsByEntity.Add(voxelMap, new MyOreDepositGroup(voxelMap)); } } m_inRangeCache.Clear(); } // Update deposit queries using current detection sphere. foreach (var entry in m_depositGroupsByEntity) { var voxelMap = entry.Key; var group = entry.Value; group.UpdateDeposits(ref sphere); foreach (var deposit in group.Deposits) { if (deposit != null) { MyHud.OreMarkers.RegisterMarker(deposit); } } } m_inRangeCache.Clear(); }
/// <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); } }
void GetCloseVoxels() { List <MyVoxelBase> voxels = new List <MyVoxelBase>(); BoundingSphereD LookupSphere = new BoundingSphereD(Position, Grid.WorldVolume.Radius * 8); MyGamePruningStructure.GetAllVoxelMapsInSphere(ref LookupSphere, voxels); ClosestRoids.Clear(); voxels.ForEach(vxl => { if (!vxl.IsOfType <MyPlanet>()) { ClosestRoids.Add(vxl as IMyVoxelMap); } }); }
public Miner(Pathfinder pathfinder, byte[] oreTargets) : base(pathfinder) { m_oreTargets = oreTargets; CubeGridCache cache = CubeGridCache.GetFor(m_controlBlock.CubeGrid); if (cache == null) { return; } if (cache.CountByType(typeof(MyObjectBuilder_Drill)) == 0) { Logger.DebugLog("No drills", Logger.severity.WARNING); return; } // if a drill has been chosen by player, use it PseudoBlock navBlock = m_navSet.Settings_Current.NavigationBlock; MultiBlock <MyObjectBuilder_Drill> navDrill = navBlock.Block is IMyShipDrill ? new MultiBlock <MyObjectBuilder_Drill>(navBlock.Block) : navDrill = new MultiBlock <MyObjectBuilder_Drill>(() => m_mover.Block.CubeGrid); if (navDrill.FunctionalBlocks == 0) { Logger.DebugLog("no working drills", Logger.severity.WARNING); return; } m_navSet.Settings_Task_NavRot.NavigatorMover = this; m_navSet.Settings_Task_NavRot.NavigationBlock = navDrill; BoundingSphereD nearby = new BoundingSphereD(navDrill.WorldPosition, m_controlBlock.CubeGrid.LocalVolume.Radius * 2d); List <MyVoxelBase> nearbyVoxels = new List <MyVoxelBase>(); MyGamePruningStructure.GetAllVoxelMapsInSphere(ref nearby, nearbyVoxels); foreach (MyVoxelBase voxel in nearbyVoxels) { if ((voxel is IMyVoxelMap || voxel is MyPlanet) && voxel.ContainsOrIntersects(ref nearby)) { Log.DebugLog("near a voxel, escape first", Logger.severity.DEBUG); m_stage = Stage.Mining; new EscapeMiner(m_pathfinder, voxel); return; } } m_stage = Stage.GetDeposit; }
public void Update(Vector3D position, long detectorId, bool checkControl = true) { if ((!this.SetRelayedRequest & checkControl) && !this.OnCheckControl()) { this.Clear(); } else { this.SetRelayedRequest = false; BoundingSphereD sphere = new BoundingSphereD(position, (double)this.DetectionRadius); MyGamePruningStructure.GetAllVoxelMapsInSphere(ref sphere, m_inRangeCache); this.RemoveVoxelMapsOutOfRange(); this.AddVoxelMapsInRange(); this.UpdateDeposits(ref sphere, detectorId); m_inRangeCache.Clear(); } }
private bool FieldShapeBlocked() { ModulatorGridComponent modComp; MyGrid.Components.TryGet(out modComp); if (ShieldComp.Modulator == null || ShieldComp.Modulator.ModSet.Settings.ModulateVoxels || Session.Enforced.DisableVoxelSupport == 1) { return(false); } var pruneSphere = new BoundingSphereD(DetectionCenter, BoundingRange); var pruneList = new List <MyVoxelBase>(); MyGamePruningStructure.GetAllVoxelMapsInSphere(ref pruneSphere, pruneList); if (pruneList.Count == 0) { return(false); } MobileUpdate(); Icosphere.ReturnPhysicsVerts(DetectMatrixOutside, ShieldComp.PhysicsOutsideLow); foreach (var voxel in pruneList) { if (voxel.RootVoxel == null || voxel != voxel.RootVoxel) { continue; } if (!CustomCollision.VoxelContact(ShieldComp.PhysicsOutsideLow, voxel)) { continue; } Shield.Enabled = false; DsState.State.FieldBlocked = true; DsState.State.Message = true; if (Session.Enforced.Debug == 3) { Log.Line($"Field blocked: - ShieldId [{Shield.EntityId}]"); } return(true); } DsState.State.FieldBlocked = false; return(false); }
public static bool IntersectsVoxel(ref CapsuleD capsule, out MyVoxelBase hitVoxel, out Vector3D hitPosition, bool checkPlanet, double capsuleLength = -1d) { Profiler.StartProfileBlock(); if (capsuleLength < 0) { Vector3D.Distance(ref capsule.P0, ref capsule.P1, out capsuleLength); } double halfLength = capsuleLength * 0.5d; Vector3D temp; Vector3D.Add(ref capsule.P0, ref capsule.P1, out temp); Vector3D middle; Vector3D.Multiply(ref temp, 0.5d, out middle); double radius = halfLength + capsule.Radius; BoundingSphereD worldSphere = new BoundingSphereD() { Center = middle, Radius = radius }; List <MyVoxelBase> voxels = ResourcePool <List <MyVoxelBase> > .Get(); MyGamePruningStructure.GetAllVoxelMapsInSphere(ref worldSphere, voxels); foreach (MyVoxelBase voxel in voxels) { if ((voxel is MyVoxelMap || voxel is MyPlanet && checkPlanet) && Intersects(ref capsule, voxel, out hitPosition, capsuleLength)) { hitVoxel = voxel; voxels.Clear(); ResourcePool.Return(voxels); Profiler.EndProfileBlock(); return(true); } } voxels.Clear(); ResourcePool.Return(voxels); hitVoxel = null; hitPosition = Vector3.Invalid; Profiler.EndProfileBlock(); return(false); }
public void Update(Vector3D position, bool checkControl = true) { if (!SetRelayedRequest && checkControl && !OnCheckControl()) { Clear(); return; } Clear(); SetRelayedRequest = false; var sphere = new BoundingSphereD(position, DetectionRadius); MyGamePruningStructure.GetAllVoxelMapsInSphere(ref sphere, m_inRangeCache); RemoveVoxelMapsOutOfRange(); AddVoxelMapsInRange(); UpdateDeposits(ref sphere); m_inRangeCache.Clear(); }
/// <summary> /// Estimates the proximity between a given capsule and any voxel. /// </summary> /// <param name="capsule">The capsule to test for intersection, the points must be at least one metre apart.</param> public static double ProximityToVoxel(ref CapsuleD capsule, out MyVoxelBase hitVoxel, out Vector3D hitPosition, bool checkPlanet, double capsuleLength = -1d) { Profiler.StartProfileBlock(); if (capsuleLength < 0) { Vector3D.Distance(ref capsule.P0, ref capsule.P1, out capsuleLength); } double halfLength = capsuleLength * 0.5d; Vector3D temp; Vector3D.Add(ref capsule.P0, ref capsule.P1, out temp); Vector3D middle; Vector3D.Multiply(ref temp, 0.5d, out middle); double radius = halfLength + capsule.Radius; BoundingSphereD worldSphere = new BoundingSphereD() { Center = middle, Radius = radius }; List <MyVoxelBase> voxels = ResourcePool <List <MyVoxelBase> > .Get(); MyGamePruningStructure.GetAllVoxelMapsInSphere(ref worldSphere, voxels); double closestProx = double.MaxValue; hitPosition = Globals.Invalid; foreach (MyVoxelBase voxel in voxels) { if (voxel is MyVoxelMap || voxel is MyPlanet && checkPlanet) { if (voxel is MyPlanet) { LineSegmentD line; ResourcePool.Get(out line); line.From = capsule.P0; line.To = capsule.P1; double minDistSq = line.DistanceSquared(voxel.GetCentre()); double maxPlanetRadius = ((MyPlanet)voxel).MaximumRadius; ResourcePool.Return(line); if (minDistSq > maxPlanetRadius * maxPlanetRadius) { Logger.DebugLog("Skip planet from: " + line.From + ", to: " + line.To + ", planet centre: " + voxel.GetCentre() + ", min dist sq to centre: " + minDistSq + ", max planet radius: " + maxPlanetRadius); continue; } Logger.DebugLog("Check planet from: " + line.From + ", to: " + line.To + ", planet centre: " + voxel.GetCentre() + ", min dist sq to centre: " + minDistSq + ", max planet radius: " + maxPlanetRadius); } double proximity = Proximity(ref capsule, voxel, ref hitPosition, capsuleLength); if (proximity < closestProx) { Logger.TraceLog("proximity is less than closest. proximity: " + proximity + ", closest: " + closestProx); closestProx = proximity; } if (closestProx < 1d) { Logger.TraceLog("closest under 1: " + closestProx); hitVoxel = voxel; voxels.Clear(); ResourcePool.Return(voxels); Profiler.EndProfileBlock(); return(closestProx); } } } voxels.Clear(); ResourcePool.Return(voxels); hitVoxel = null; Profiler.EndProfileBlock(); return(closestProx); }
public MinerVoxel(Mover mover, byte[] OreTargets) : base(mover) { this.m_logger = new Logger(m_controlBlock.CubeBlock, () => m_state.ToString()); this.OreTargets = OreTargets; // get blocks var cache = CubeGridCache.GetFor(m_controlBlock.CubeGrid); var allDrills = cache.GetBlocksOfType(typeof(MyObjectBuilder_Drill)); if (allDrills == null || allDrills.Count == 0) { m_logger.debugLog("No Drills!", Logger.severity.INFO); return; } // if a drill has been chosen by player, use it PseudoBlock navBlock = m_navSet.Settings_Current.NavigationBlock; if (navBlock.Block is IMyShipDrill) { m_navDrill = new MultiBlock <MyObjectBuilder_Drill>(navBlock.Block); } else { m_navDrill = new MultiBlock <MyObjectBuilder_Drill>(() => m_mover.Block.CubeGrid); } if (m_navDrill.FunctionalBlocks == 0) { m_logger.debugLog("no working drills", Logger.severity.INFO); return; } m_longestDimension = m_controlBlock.CubeGrid.GetLongestDim(); m_navSet.Settings_Task_NavRot.NavigatorMover = this; // check for currently touching voxel, usually resume from save BoundingSphereD nearby = new BoundingSphereD(m_navDrill.WorldPosition, m_longestDimension * 4d); List <MyVoxelBase> nearbyVoxels = new List <MyVoxelBase>(); MyGamePruningStructure.GetAllVoxelMapsInSphere(ref nearby, nearbyVoxels); foreach (MyVoxelBase voxel in nearbyVoxels) { // skip planet physics, ship should be near planet as well if (voxel is IMyVoxelMap || voxel is MyPlanet) { m_logger.debugLog("near a voxel, escape first", Logger.severity.DEBUG); m_targetVoxel = voxel; m_state = State.Mining_Escape; var setLevel = m_navSet.GetSettingsLevel(AllNavigationSettings.SettingsLevelName.NavMove); setLevel.IgnoreAsteroid = true; setLevel.SpeedTarget = 1f; return; } } m_state = State.GetTarget; }
public void CheckScan() { // Invoked on a parallel thread in LargeNaniteOreDetecotrLogic if (!m_block.Enabled || !m_block.IsFunctional || !Sink.IsPoweredByType(MyResourceDistributorComponent.ElectricityId)) { MyAPIGateway.Utilities.InvokeOnGameThread(() => { m_depositGroupsByEntity.Clear(); m_inRangeCache.Clear(); }); return; } CheckIsTooCloseToOtherDetector(); if (m_tooCloseToOtherDetector) { MyAPIGateway.Utilities.InvokeOnGameThread(() => { m_depositGroupsByEntity.Clear(); m_inRangeCache.Clear(); m_block.Enabled = false; }); return; } Vector3D position = m_block.GetPosition(); BoundingSphereD sphere = new BoundingSphereD(position, Range); MyGamePruningStructure.GetAllVoxelMapsInSphere(ref sphere, m_inRangeCache); RemoveVoxelMapsOutOfRange(); AddVoxelMapsInRange(); UpdateDeposits(ref sphere); m_inRangeCache.Clear(); int totalInitialTasks = m_depositGroupsByEntity.Sum((x) => x.Value.InitialTasks); int totalProcessedTasks = m_depositGroupsByEntity.Sum((x) => x.Value.ProcessedTasks); float scanProgress = 0f; if (totalInitialTasks != 0) { scanProgress = (float)totalProcessedTasks / (float)totalInitialTasks; } if (scanProgress != m_scanProgress) { m_scanProgress = scanProgress; MessageHub.SendToPlayerInSyncRange(new MessageOreDetectorScanProgress() { EntityId = m_block.EntityId, Progress = m_scanProgress }, m_block.GetPosition()); } StringBuilder oreListCache = new StringBuilder(); foreach (var item in m_depositGroupsByEntity.SelectMany((x) => x.Value.Materials.GetMaterialList()).GroupBy((x) => x.Material.MinedOre)) { oreListCache.Append($"- {item.Key}: {item.Sum((x) => x.Count)}\n"); } if (oreListCache != m_oreListCache) { m_oreListCache = oreListCache; MessageHub.SendToPlayerInSyncRange(new MessageOreDetectorScanComplete() { EntityId = m_block.EntityId, OreListCache = m_oreListCache.ToString() }, m_block.GetPosition()); } }
public VoxelLander(Pathfinder pathfinder, bool planet, PseudoBlock landBlock = null) : base(pathfinder) { this.m_landBlock = landBlock ?? m_navSet.Settings_Current.LandingBlock; this.m_targetType = planet ? "Planet" : "Asteroid"; if (this.m_landBlock == null) { Log.DebugLog("No landing block", Logger.severity.INFO); return; } IMyLandingGear asGear = m_landBlock.Block as IMyLandingGear; if (asGear != null) { ITerminalProperty <bool> autolock = asGear.GetProperty("Autolock") as ITerminalProperty <bool>; Log.DebugLog("autolock == null", Logger.severity.FATAL, condition: autolock == null); if (!autolock.GetValue(asGear)) { autolock.SetValue(asGear, true); } } Vector3D currentPostion = m_landBlock.WorldPosition; MyVoxelBase closest = null; if (planet) { closest = MyPlanetExtensions.GetClosestPlanet(m_landBlock.WorldPosition); if (closest == null) { Log.DebugLog("No planets in the world", Logger.severity.WARNING); return; } } else { BoundingSphereD search = new BoundingSphereD(currentPostion, 10000d); List <MyVoxelBase> nearby = new List <MyVoxelBase>(); MyGamePruningStructure.GetAllVoxelMapsInSphere(ref search, nearby); double closestDistSquared = double.MaxValue; foreach (MyVoxelBase voxel in nearby) { if (!(voxel is MyVoxelMap)) { continue; } double distSquared = Vector3D.DistanceSquared(currentPostion, voxel.GetCentre()); if (distSquared < closestDistSquared) { closestDistSquared = distSquared; closest = voxel; } } if (closest == null) { Log.DebugLog("No asteroids nearby", Logger.severity.WARNING); return; } } Vector3D end = closest.GetCentre(); MyVoxelBase hitVoxel; Vector3D hitPosition; if (!RayCast.RayCastVoxels(ref currentPostion, ref end, out hitVoxel, out hitPosition)) { throw new Exception("Failed to intersect voxel"); } m_targetPostion = Destination.FromWorld(hitVoxel, hitPosition); m_navSet.Settings_Task_NavRot.NavigatorMover = this; m_navSet.Settings_Task_NavRot.IgnoreAsteroid = true; Log.DebugLog("Landing on " + m_targetType + " at " + m_targetPostion, Logger.severity.DEBUG); }