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();
        }
Ejemplo n.º 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 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);
            }
        }
Ejemplo n.º 3
0
        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);
                                    }
                           });
        }
Ejemplo n.º 4
0
        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;
        }
Ejemplo n.º 5
0
 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();
     }
 }
Ejemplo n.º 6
0
        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);
        }
Ejemplo n.º 7
0
        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();
        }
Ejemplo n.º 9
0
        /// <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);
        }
Ejemplo n.º 10
0
        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());
            }
        }
Ejemplo n.º 12
0
        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);
        }