public NaniteOreDetector(IMyFunctionalBlock entity)
        {
            m_block             = entity as IMyOreDetector;
            m_lastUpdate        = DateTime.MinValue;
            m_scanStart         = DateTime.MinValue;
            m_scanEnd           = DateTime.MinValue;
            m_lock              = new FastResourceLock();
            m_oreListCache      = new StringBuilder();
            m_detectorState     = DetectorStates.Disabled;
            m_lastDetectorState = DetectorStates.Disabled;

            m_block.Components.TryGet(out Sink);
            ResourceInfo = new MyResourceSinkInfo()
            {
                ResourceTypeId    = MyResourceDistributorComponent.ElectricityId,
                MaxRequiredInput  = 0f,
                RequiredInputFunc = () => (m_block.Enabled && m_block.IsFunctional) ? _power : 0f
            };
            Sink.RemoveType(ref ResourceInfo.ResourceTypeId);
            Sink.Init(MyStringHash.GetOrCompute("Utility"), ResourceInfo);
            Sink.AddType(ref ResourceInfo);

            m_effects.Add(new OreDetectorEffect((MyCubeBlock)m_block));

            if (!NaniteConstructionManager.OreDetectors.ContainsKey(entity.EntityId))
            {
                NaniteConstructionManager.OreDetectors.Add(entity.EntityId, this);
            }
        }
        private void UpdateDeposits(ref BoundingSphereD sphere)
        { // Invoked in a parallel task
            foreach (OreDeposit value in m_depositGroupsByEntity.Values)
            {
                value.UpdateDeposits(ref sphere, m_block.EntityId, this);
            }

            var initialTasks = m_depositGroupsByEntity.Sum((x) => x.Value.InitialTasks);

            if (initialTasks != 0)
            {
                var processedTasks = m_depositGroupsByEntity.Sum((x) => x.Value.ProcessedTasks);

                MyAPIGateway.Utilities.InvokeOnGameThread(() =>
                {
                    if (processedTasks == initialTasks)
                    {
                        m_detectorState = DetectorStates.ScanComplete;
                    }

                    else
                    {
                        m_detectorState = DetectorStates.Scanning;
                    }

                    if (m_detectorState != m_lastDetectorState)
                    {
                        m_lastDetectorState = m_detectorState;
                        MessageHub.SendToPlayerInSyncRange(new MessageOreDetectorStateChange()
                        {
                            EntityId = m_block.EntityId,
                            State    = m_lastDetectorState,
                        }, m_block.GetPosition());
                    }
                });
            }
        }
        public void UpdateStatus()
        {
            if (!m_block.Enabled || !m_block.IsFunctional || !Sink.IsPoweredByType(MyResourceDistributorComponent.ElectricityId) || m_tooCloseToOtherDetector)
            {
                m_detectorState = DetectorStates.Disabled;
            }

            else if (m_depositGroupsByEntity.Count == 0)
            {
                m_detectorState = DetectorStates.Enabled;
            }

            if (m_detectorState != m_lastDetectorState || m_tooCloseToOtherDetector != m_tooCloseOld)
            {
                m_tooCloseOld       = m_tooCloseToOtherDetector;
                m_lastDetectorState = m_detectorState;
                MessageHub.SendToPlayerInSyncRange(new MessageOreDetectorStateChange()
                {
                    EntityId = m_block.EntityId,
                    State    = m_lastDetectorState,
                    TooClose = m_tooCloseToOtherDetector
                }, m_block.GetPosition());
            }
        }