예제 #1
0
        private static bool IntersectsVoxelSurface(OrientedBoundingBoxD box)
        {
            var data = VoxelData;

            using (PoolManager.Get(out List <MyEntity> entities))
            {
                MyGamePruningStructure.GetTopmostEntitiesInBox(box.GetAABB(), entities, MyEntityQueryType.Static);
                foreach (var ent in entities)
                {
                    if (ent is MyVoxelBase voxel && !(ent is MyVoxelPhysics))
                    {
                        var invWorld      = voxel.PositionComp.WorldMatrixInvScaled;
                        var storageBounds = BoundingBoxD.CreateInvalid();
                        var voxelOffset   = (voxel.Size >> 1) + voxel.StorageMin;
                        var storageObb    = box;
                        storageObb.Transform(invWorld);
                        storageObb.HalfExtent /= voxel.VoxelSize;
                        storageObb.Center      = storageObb.Center / voxel.VoxelSize + voxelOffset;
                        storageBounds.Include(storageObb.GetAABB());

                        var storageMin = Vector3I.Max(Vector3I.Floor(storageBounds.Min), voxel.StorageMin);
                        var storageMax = Vector3I.Min(Vector3I.Ceiling(storageBounds.Max), voxel.StorageMax);
                        var localBox   = new BoundingBoxI(storageMin, storageMax);
                        localBox.Inflate(1);
                        var floatBox = new BoundingBox(localBox);
                        if (voxel.IntersectStorage(ref floatBox) == ContainmentType.Disjoint)
                        {
                            continue;
                        }
                        data.Resize(storageMin, storageMax);
                        voxel.Storage.ReadRange(data, MyStorageDataTypeFlags.Content, 0, storageMin, storageMax);
                        foreach (var pt in new BoundingBoxI(Vector3I.Zero, storageMax - storageMin).EnumeratePoints())
                        {
                            var voxelBox    = new BoundingBoxD(storageMin + pt, storageMin + pt + 1);
                            var containment = storageObb.Contains(ref voxelBox);
                            if (containment == ContainmentType.Disjoint)
                            {
                                continue;
                            }
                            var tmpPt   = pt;
                            var index   = data.ComputeLinear(ref tmpPt);
                            var content = data.Content(index);
                            if (containment == ContainmentType.Intersects && content >= 127)
                            {
                                return(true);
                            }
                            if (containment == ContainmentType.Contains && content > 0)
                            {
                                return(true);
                            }
                        }
                    }
                }
            }

            return(false);
        }
예제 #2
0
 public static void NotifyVoxelChanged(MyVoxelBase.OperationType type, MyVoxelBase voxelMap, ref BoundingBoxD cutOutBox)
 {
     cutOutBox.Inflate((double)0.25);
     MyGamePruningStructure.GetTopmostEntitiesInBox(ref cutOutBox, m_overlapList, MyEntityQueryType.Both);
     if (MyFakes.ENABLE_BLOCKS_IN_VOXELS_TEST)
     {
         foreach (MyEntity entity in m_overlapList)
         {
             if (Sync.IsServer)
             {
                 MyCubeGrid grid = entity as MyCubeGrid;
                 if ((grid != null) && grid.IsStatic)
                 {
                     if ((grid.Physics != null) && (grid.Physics.Shape != null))
                     {
                         grid.Physics.Shape.RecalculateConnectionsToWorld(grid.GetBlocks());
                     }
                     if (type == MyVoxelBase.OperationType.Cut)
                     {
                         grid.TestDynamic = MyCubeGrid.MyTestDynamicReason.GridSplit;
                     }
                 }
             }
             MyPhysicsBody physics = entity.Physics as MyPhysicsBody;
             if (((physics != null) && !physics.IsStatic) && (physics.RigidBody != null))
             {
                 physics.RigidBody.Activate();
             }
         }
     }
     m_overlapList.Clear();
     if (Sync.IsServer)
     {
         MyPlanetEnvironmentComponent component = voxelMap.Components.Get <MyPlanetEnvironmentComponent>();
         if (component != null)
         {
             component.GetSectorsInRange(ref cutOutBox, m_overlapList);
             using (List <MyEntity> .Enumerator enumerator = m_overlapList.GetEnumerator())
             {
                 while (enumerator.MoveNext())
                 {
                     ((MyEnvironmentSector)enumerator.Current).DisableItemsInBox(ref cutOutBox);
                 }
             }
             m_overlapList.Clear();
         }
     }
 }
예제 #3
0
        internal void WebMonitor()
        {
            try
            {
                _workData.DoIt(this);
                MyAPIGateway.Parallel.For(0, _workData.ShieldCnt, x =>
                {
                    var s    = _workData.ShieldList[x];
                    var tick = _workData.Tick;
                    if (s.MarkedForClose || !s.Warming)
                    {
                        return;
                    }
                    var reInforce = s.DsState.State.ReInforce;
                    if (!IsServer)
                    {
                        if (reInforce != s.ReInforcedShield)
                        {
                            lock (s.SubLock) foreach (var sub in s.ShieldComp.SubGrids)
                                {
                                    _entRefreshQueue.Enqueue(sub);
                                }
                            s.ReInforcedShield = reInforce;
                        }

                        if (EntSlotTick && RefreshCycle == s.MonitorSlot)
                        {
                            var newSubClient = false;

                            var monitorListClient = ListMyEntityPool.Get();

                            MonitorRefreshTasks(x, ref monitorListClient, reInforce, ref newSubClient);

                            monitorListClient.Clear();
                            ListMyEntityPool.Return(monitorListClient);
                        }
                        s.TicksWithNoActivity = 0;
                        s.LastWokenTick       = tick;
                        s.Asleep = false;
                        return;
                    }

                    bool shieldActive;
                    lock (ActiveShields) shieldActive = ActiveShields.Contains(s);

                    if (s.LostPings > 59)
                    {
                        if (shieldActive)
                        {
                            if (Enforced.Debug >= 2)
                            {
                                Log.Line("Logic Paused by lost pings");
                            }
                            lock (ActiveShields) ActiveShields.Remove(s);
                            s.WasPaused = true;
                        }
                        s.Asleep = false;
                        return;
                    }
                    if (Enforced.Debug >= 2 && s.LostPings > 0)
                    {
                        Log.Line($"Lost Logic Pings:{s.LostPings}");
                    }

                    if (shieldActive)
                    {
                        s.LostPings++;
                    }

                    if (s.Asleep && EmpStore.Count != 0 && Vector3D.DistanceSquared(s.DetectionCenter, EmpWork.EpiCenter) <= SyncDistSqr)
                    {
                        s.TicksWithNoActivity = 0;
                        s.LastWokenTick       = tick;
                        s.Asleep = false;
                        return;
                    }

                    if (!shieldActive && s.LostPings > 59)
                    {
                        s.Asleep = true;
                        return;
                    }

                    var newSub = false;

                    var monitorList = ListMyEntityPool.Get();
                    if (EntSlotTick && RefreshCycle == s.MonitorSlot)
                    {
                        MonitorRefreshTasks(x, ref monitorList, reInforce, ref newSub);
                    }

                    if (reInforce)
                    {
                        return;
                    }
                    if (tick < s.LastWokenTick + 400 || s.Missiles.Count > 0)
                    {
                        s.Asleep = false;
                        return;
                    }

                    if (s.GridIsMobile && s.MyGrid.Physics.IsMoving)
                    {
                        s.LastWokenTick = tick;
                        s.Asleep        = false;
                        return;
                    }

                    if (!s.PlayerByShield && !s.MoverByShield && !s.NewEntByShield)
                    {
                        if (s.TicksWithNoActivity++ % EntCleanCycle == 0)
                        {
                            s.EntCleanUpTime = true;
                        }
                        if (shieldActive && !s.WasPaused && tick > 1200)
                        {
                            if (Enforced.Debug >= 2)
                            {
                                Log.Line($"Logic Paused by monitor");
                            }
                            lock (ActiveShields) ActiveShields.Remove(s);
                            s.WasPaused           = true;
                            s.Asleep              = false;
                            s.TicksWithNoActivity = 0;
                            s.LastWokenTick       = tick;
                        }
                        else
                        {
                            s.Asleep = true;
                        }
                        return;
                    }

                    var intersect = false;
                    if (!(EntSlotTick && RefreshCycle == s.MonitorSlot))
                    {
                        MyGamePruningStructure.GetTopmostEntitiesInBox(ref s.WebBox, monitorList, MyEntityQueryType.Dynamic);
                    }
                    for (int i = 0; i < monitorList.Count; i++)
                    {
                        var ent = monitorList[i];

                        if (ent.Physics == null || ent.Physics.IsPhantom || !(ent is MyCubeGrid || ent is IMyCharacter || ent is IMyMeteor))
                        {
                            continue;
                        }
                        if (ent.Physics.IsMoving)
                        {
                            if (s.WebBox.Intersects(ent.PositionComp.WorldAABB))
                            {
                                intersect = true;
                                break;
                            }
                        }
                    }

                    monitorList.Clear();
                    ListMyEntityPool.Return(monitorList);

                    if (!intersect)
                    {
                        s.Asleep = true;
                        return;
                    }
                    s.TicksWithNoActivity = 0;
                    s.LastWokenTick       = tick;
                    s.Asleep = false;
                });

                if (_workData.Tick % 180 == 0 && _workData.Tick > 1199)
                {
                    _entRefreshTmpList.Clear();
                    _entRefreshTmpList.AddRange(_globalEntTmp.Where(info => _workData.Tick - 540 > info.Value));
                    foreach (var dict in _entRefreshTmpList)
                    {
                        var ent = dict.Key;
                        _entRefreshQueue.Enqueue(ent);
                        uint value;
                        _globalEntTmp.TryRemove(ent, out value);
                    }
                }
                _workData.Clean();
            }
            catch (Exception ex) { Log.Line($"Exception in WebMonitor: {ex}"); }
        }
예제 #4
0
        internal void MonitorRefreshTasks(int x, ref List <MyEntity> monitorList, bool reInforce, ref bool newSub)
        {
            var s = _workData.ShieldList[x];

            if (reInforce)
            {
                var newMode = !s.ReInforcedShield;
                if (!newMode)
                {
                    return;
                }

                HashSet <MyCubeGrid> subs;
                lock (s.SubLock)
                {
                    subs = SetMyCubeGridPool.Get();
                    subs.UnionWith(s.ShieldComp.SubGrids);
                }
                foreach (var sub in subs)
                {
                    if (!_globalEntTmp.ContainsKey(sub))
                    {
                        newSub = true;
                    }
                    _entRefreshQueue.Enqueue(sub);
                    if (!s.WasPaused)
                    {
                        _globalEntTmp[sub] = _workData.Tick;
                    }
                }
                subs.Clear();
                SetMyCubeGridPool.Return(subs);

                s.ReInforcedShield    = true;
                s.TicksWithNoActivity = 0;
                s.LastWokenTick       = _workData.Tick;
                s.Asleep = false;
            }
            else
            {
                var newMode = false;
                if (s.ReInforcedShield)
                {
                    HashSet <MyCubeGrid> subs;
                    lock (s.SubLock)
                    {
                        subs = SetMyCubeGridPool.Get();
                        subs.UnionWith(s.ShieldComp.SubGrids);
                    }
                    foreach (var sub in subs)
                    {
                        _entRefreshQueue.Enqueue(sub);
                        if (!s.WasPaused)
                        {
                            _globalEntTmp[sub] = _workData.Tick;
                        }
                    }
                    subs.Clear();
                    SetMyCubeGridPool.Return(subs);

                    //if (Enforced.Debug >= 2) Log.Line($"found Reinforce");
                    s.ReInforcedShield    = false;
                    s.TicksWithNoActivity = 0;
                    s.LastWokenTick       = _workData.Tick;
                    s.Asleep = false;
                    newMode  = true;
                }

                if (!newMode)
                {
                    var foundNewEnt   = false;
                    var disableVoxels = Enforced.DisableVoxelSupport == 1 || s.ShieldComp.Modulator == null || s.ShieldComp.Modulator.ModSet.Settings.ModulateVoxels;
                    MyGamePruningStructure.GetTopmostEntitiesInBox(ref s.WebBox, monitorList);
                    if (!s.WasPaused)
                    {
                        foreach (var ent in monitorList)
                        {
                            var voxel = ent as MyVoxelBase;
                            if (ent == null || ent.MarkedForClose || (voxel == null && (ent.Physics == null || ent.Physics.IsPhantom || ent.DefinitionId == null)) || (!s.GridIsMobile && voxel != null) || (disableVoxels && voxel != null) || (voxel != null && voxel != voxel.RootVoxel))
                            {
                                continue;
                            }

                            if (ent is IMyFloatingObject || ent is IMyEngineerToolBase || !s.WebSphere.Intersects(ent.PositionComp.WorldVolume))
                            {
                                continue;
                            }

                            if (CustomCollision.NewObbPointsInShield(ent, s.DetectMatrixOutsideInv) > 0)
                            {
                                if (!_globalEntTmp.ContainsKey(ent))
                                {
                                    foundNewEnt = true;
                                    s.Asleep    = false;
                                }

                                _globalEntTmp[ent] = _workData.Tick;
                            }
                            s.NewEntByShield = foundNewEnt;
                        }
                    }
                    else
                    {
                        s.NewEntByShield = false;
                    }

                    if (!s.NewEntByShield)
                    {
                        var foundPlayer = false;
                        foreach (var player in Players.Values)
                        {
                            var character = player.Character;
                            if (character == null)
                            {
                                continue;
                            }

                            if (Vector3D.DistanceSquared(character.PositionComp.WorldMatrixRef.Translation, s.DetectionCenter) < SyncDistSqr)
                            {
                                foundPlayer = true;
                                break;
                            }
                        }
                        s.PlayerByShield = foundPlayer;
                    }
                    if (!s.PlayerByShield)
                    {
                        s.MoverByShield = false;
                        var newMover = false;

                        var moverList = ListMyEntityPool.Get();
                        MyGamePruningStructure.GetTopMostEntitiesInBox(ref s.ShieldBox3K, moverList, MyEntityQueryType.Dynamic);
                        for (int i = 0; i < moverList.Count; i++)
                        {
                            var ent = moverList[i];

                            var meteor = ent as IMyMeteor;
                            if (meteor != null)
                            {
                                if (CustomCollision.FutureIntersect(s, ent, s.DetectMatrixOutside, s.DetectMatrixOutsideInv))
                                {
                                    if (Enforced.Debug >= 2)
                                    {
                                        Log.Line($"[Future Intersecting Meteor] distance from shieldCenter: {Vector3D.Distance(s.DetectionCenter, ent.WorldMatrix.Translation)} - waking:");
                                    }
                                    newMover = true;
                                    break;
                                }
                                continue;
                            }

                            if (!(ent.Physics == null || ent.Physics.IsPhantom || ent is MyCubeGrid || ent is IMyCharacter))
                            {
                                continue;
                            }
                            var entPos = ent.PositionComp.WorldAABB.Center;

                            var keyFound = s.EntsByMe.ContainsKey(ent);
                            if (keyFound)
                            {
                                if (!s.EntsByMe[ent].Pos.Equals(entPos, 1e-3))
                                {
                                    MoverInfo moverInfo;
                                    s.EntsByMe.TryRemove(ent, out moverInfo);
                                    s.EntsByMe.TryAdd(ent, new MoverInfo(entPos, _workData.Tick));
                                    if (moverInfo.CreationTick == _workData.Tick - 1)
                                    {
                                        if (Enforced.Debug >= 3 && s.WasPaused)
                                        {
                                            Log.Line($"[Moved] Ent:{ent.DebugName} - howMuch:{Vector3D.Distance(entPos, s.EntsByMe[ent].Pos)} - ShieldId [{s.Shield.EntityId}]");
                                        }
                                        newMover = true;
                                    }
                                    break;
                                }
                            }
                            else
                            {
                                if (Enforced.Debug >= 3)
                                {
                                    Log.Line($"[NewMover] Ent:{ent.DebugName} - ShieldId [{s.Shield.EntityId}]");
                                }
                                s.EntsByMe.TryAdd(ent, new MoverInfo(entPos, _workData.Tick));
                            }
                        }
                        moverList.Clear();
                        ListMyEntityPool.Return(moverList);

                        s.MoverByShield = newMover;
                    }

                    if (_workData.Tick < s.LastWokenTick + 400)
                    {
                        s.Asleep = false;
                        return;
                    }
                }

                if (s.EntCleanUpTime)
                {
                    s.EntCleanUpTime = false;
                    if (!s.EntsByMe.IsEmpty)
                    {
                        var entsByMeTmp = new List <KeyValuePair <MyEntity, MoverInfo> >();
                        entsByMeTmp.AddRange(s.EntsByMe.Where(info => !info.Key.InScene || _workData.Tick - info.Value.CreationTick > EntMaxTickAge));
                        for (int i = 0; i < entsByMeTmp.Count; i++)
                        {
                            MoverInfo mInfo;
                            s.EntsByMe.TryRemove(entsByMeTmp[i].Key, out mInfo);
                        }
                    }
                }
            }
        }
예제 #5
0
        internal void WebMonitor()
        {
            try
            {
                MyAPIGateway.Parallel.ForEach(FunctionalShields.Keys, s =>
                {
                    if (s.MarkedForClose || !s.Warming)
                    {
                        return;
                    }
                    var reInforce = s.DsState.State.ReInforce;
                    if (!IsServer)
                    {
                        if (reInforce != s.ReInforcedShield)
                        {
                            foreach (var sub in s.ShieldComp.SubGrids)
                            {
                                EntRefreshQueue.Enqueue(sub.Key);
                            }
                            s.ReInforcedShield = reInforce;
                        }

                        if (EntSlotTick && RefreshCycle == s.MonitorSlot)
                        {
                            var newSubClient = false;

                            var monitorListClient = ListMyEntityPool.Get();

                            MonitorRefreshTasks(s, ref monitorListClient, reInforce, ref newSubClient);

                            monitorListClient.Clear();
                            ListMyEntityPool.Return(monitorListClient);
                        }
                        s.TicksWithNoActivity = 0;
                        s.LastWokenTick       = Tick;
                        s.Asleep = false;
                        return;
                    }

                    var shieldActive = ActiveShields.ContainsKey(s);

                    if (s.LostPings > 59)
                    {
                        if (shieldActive)
                        {
                            if (Enforced.Debug >= 2)
                            {
                                Log.Line("Logic Paused by lost pings");
                            }

                            byte ignore;
                            ActiveShields.TryRemove(s, out ignore);
                            s.WasPaused = true;
                        }
                        s.Asleep = false;
                        return;
                    }
                    if (Enforced.Debug >= 2 && s.LostPings > 0)
                    {
                        Log.Line($"Lost Logic Pings:{s.LostPings}");
                    }

                    if (shieldActive)
                    {
                        s.LostPings++;
                    }

                    if (!shieldActive && s.LostPings > 59)
                    {
                        s.Asleep = true;
                        return;
                    }

                    var newSub = false;

                    var monitorList = ListMyEntityPool.Get();
                    if (EntSlotTick && RefreshCycle == s.MonitorSlot)
                    {
                        MonitorRefreshTasks(s, ref monitorList, reInforce, ref newSub);
                    }

                    if (reInforce)
                    {
                        return;
                    }
                    if (Tick < s.LastWokenTick + 400 || s.Missiles.Count > 0)
                    {
                        s.Asleep = false;
                        return;
                    }

                    if (s.GridIsMobile && s.MyGrid.Physics.IsMoving)
                    {
                        s.LastWokenTick = Tick;
                        s.Asleep        = false;
                        return;
                    }

                    if (!s.PlayerByShield && !s.MoverByShield && !s.NewEntByShield && s.MyGrid.OccupiedBlocks.Count == 0)
                    {
                        if (s.TicksWithNoActivity++ % EntCleanCycle == 0)
                        {
                            s.EntCleanUpTime = true;
                        }
                        if (shieldActive && !s.WasPaused && Tick > 1200)
                        {
                            if (Enforced.Debug >= 2)
                            {
                                Log.Line($"Logic Paused by monitor");
                            }
                            byte ignore;
                            ActiveShields.TryRemove(s, out ignore);
                            s.WasPaused           = true;
                            s.Asleep              = false;
                            s.TicksWithNoActivity = 0;
                            s.LastWokenTick       = Tick;
                        }
                        else
                        {
                            s.Asleep = true;
                        }
                        return;
                    }

                    var intersect = false;
                    if (!(EntSlotTick && RefreshCycle == s.MonitorSlot))
                    {
                        MyGamePruningStructure.GetTopmostEntitiesInBox(ref s.WebBox, monitorList, MyEntityQueryType.Dynamic);
                    }
                    for (int i = 0; i < monitorList.Count; i++)
                    {
                        var ent = monitorList[i];

                        if (ent.Physics == null || ent.Physics.IsPhantom || !(ent is MyCubeGrid || ent is IMyCharacter || ent is IMyMeteor))
                        {
                            continue;
                        }
                        if (ent.Physics.IsMoving)
                        {
                            if (s.WebBox.Intersects(ent.PositionComp.WorldAABB))
                            {
                                intersect = true;
                                break;
                            }
                        }
                    }

                    monitorList.Clear();
                    ListMyEntityPool.Return(monitorList);

                    if (!intersect)
                    {
                        s.Asleep = true;
                        return;
                    }
                    s.TicksWithNoActivity = 0;
                    s.LastWokenTick       = Tick;
                    s.Asleep = false;
                });

                if (Tick % 180 == 0 && Tick > 1199)
                {
                    foreach (var info in _globalEntTmp)
                    {
                        if (Tick - 540 > info.Value)
                        {
                            var ent = info.Key;
                            EntRefreshQueue.Enqueue(ent);
                            uint value;
                            _globalEntTmp.TryRemove(ent, out value);
                        }
                    }
                }
            }
            catch (Exception ex) { Log.Line($"Exception in WebMonitor: {ex}"); }
        }
예제 #6
0
        internal void WebMonitor()
        {
            try
            {
                while (Monitor)
                {
                    _autoResetEvent.WaitOne();
                    if (!Monitor)
                    {
                        break;
                    }
                    //if (Enforced.Debug >= 3 && EntSlotTick) Dsutil2.Sw.Restart();
                    _newFrame = false;
                    _workData.DoIt(new List <DefenseShields>(FunctionalShields.Keys), Tick);
                    MinScaler = _workData.MinScaler;
                    MyAPIGateway.Parallel.For(0, _workData.ShieldCnt, x =>
                    {
                        var s    = _workData.ShieldList[x];
                        var tick = _workData.Tick;
                        if (_newFrame || s.MarkedForClose || !s.Warming)
                        {
                            return;
                        }
                        var reInforce = s.DsState.State.ReInforce;
                        if (!IsServer)
                        {
                            lock (s.GetCubesLock)
                            {
                                var cleanDistributor = s.MyGridDistributor != null && s.FuncTask.IsComplete && s.MyGridDistributor.SourcesEnabled != MyMultipleEnabledEnum.NoObjects;
                                if (cleanDistributor)
                                {
                                    s.GridCurrentPower = s.MyGridDistributor.TotalRequiredInputByType(MyResourceDistributorComponent.ElectricityId);
                                    s.GridMaxPower     = s.MyGridDistributor.MaxAvailableResourceByType(MyResourceDistributorComponent.ElectricityId);
                                }

                                if (reInforce != s.ReInforcedShield)
                                {
                                    //if (Enforced.Debug == 4) Log.Line("Client queuing entFresh for reinforced shield");
                                    foreach (var sub in s.ShieldComp.GetSubGrids)
                                    {
                                        _entRefreshQueue.Enqueue(sub);
                                    }
                                    s.ReInforcedShield = reInforce;
                                }
                            }
                            s.TicksWithNoActivity = 0;
                            s.LastWokenTick       = tick;
                            s.Asleep = false;
                            return;
                        }

                        var shieldActive = ActiveShields.ContainsKey(s);
                        if (s.LostPings > 59)
                        {
                            if (shieldActive)
                            {
                                if (Enforced.Debug >= 2)
                                {
                                    Log.Line("Logic Paused by lost pings");
                                }
                                bool value;
                                ActiveShields.TryRemove(s, out value);
                                s.WasPaused = true;
                            }
                            s.Asleep = false;
                            return;
                        }
                        //if (Enforced.Debug >= 2 && s.LostPings > 0) Log.Line($"Lost Logic Pings:{s.LostPings}");
                        if (shieldActive)
                        {
                            s.LostPings++;
                        }

                        lock (s.GetCubesLock)
                        {
                            var cleanDistributor = s.MyGridDistributor != null && s.FuncTask.IsComplete && s.MyGridDistributor.SourcesEnabled != MyMultipleEnabledEnum.NoObjects;
                            if (cleanDistributor)
                            {
                                s.GridCurrentPower = s.MyGridDistributor.TotalRequiredInputByType(MyResourceDistributorComponent.ElectricityId);
                                s.GridMaxPower     = s.MyGridDistributor.MaxAvailableResourceByType(MyResourceDistributorComponent.ElectricityId);
                            }
                        }

                        if (s.Asleep && EmpStore.Count != 0 && Vector3D.DistanceSquared(s.DetectionCenter, EmpWork.EpiCenter) <= SyncDistSqr)
                        {
                            s.TicksWithNoActivity = 0;
                            s.LastWokenTick       = tick;
                            s.Asleep = false;
                            return;
                        }

                        if (!shieldActive && s.LostPings > 59)
                        {
                            s.Asleep = true;
                            return;
                        }

                        List <MyEntity> monitorList = null;
                        var newSub = false;
                        if (!reInforce)
                        {
                            monitorList = new List <MyEntity>();
                        }
                        if (EntSlotTick && RefreshCycle == s.MonitorSlot)
                        {
                            MonitorRefreshTasks(x, ref monitorList, reInforce, ref newSub);
                        }

                        if (reInforce)
                        {
                            return;
                        }

                        if (tick < s.LastWokenTick + 400 || s.ShieldComp.GridIsMoving || s.Missiles.Count > 0)
                        {
                            if (s.ShieldComp.GridIsMoving)
                            {
                                s.LastWokenTick = tick;
                            }
                            s.Asleep = false;
                            return;
                        }
                        if (!s.PlayerByShield && !s.MoverByShield && !s.NewEntByShield)
                        {
                            if (s.TicksWithNoActivity++ % EntCleanCycle == 0)
                            {
                                s.EntCleanUpTime = true;
                            }
                            if (tick > 1200 && !s.WasPaused)
                            {
                                if (Enforced.Debug >= 2)
                                {
                                    Log.Line($"Logic Paused by monitor");
                                }
                                bool value;
                                ActiveShields.TryRemove(s, out value);
                                s.WasPaused           = true;
                                s.Asleep              = false;
                                s.TicksWithNoActivity = 0;
                                s.LastWokenTick       = tick;
                            }
                            else
                            {
                                s.Asleep = true;
                            }
                            return;
                        }

                        var intersect = false;
                        if (!(EntSlotTick && RefreshCycle == s.MonitorSlot))
                        {
                            MyGamePruningStructure.GetTopmostEntitiesInBox(ref s.WebBox, monitorList, MyEntityQueryType.Dynamic);
                        }
                        for (int i = 0; i < monitorList.Count; i++)
                        {
                            var ent = monitorList[i];

                            if (ent.Physics == null || !(ent is MyCubeGrid || ent is IMyCharacter || ent is IMyMeteor))
                            {
                                continue;
                            }
                            if (ent.Physics.IsMoving)
                            {
                                if (s.WebBox.Intersects(ent.PositionComp.WorldAABB))
                                {
                                    intersect = true;
                                    break;
                                }
                            }
                        }

                        if (!intersect)
                        {
                            s.Asleep = true;
                            return;
                        }
                        s.TicksWithNoActivity = 0;
                        s.LastWokenTick       = tick;
                        s.Asleep = false;
                    });

                    if (_workData.Tick % 180 == 0 && _workData.Tick > 1199)
                    {
                        _entRefreshTmpList.Clear();
                        _entRefreshTmpList.AddRange(_globalEntTmp.Where(info => _workData.Tick - 540 > info.Value));
                        foreach (var dict in _entRefreshTmpList)
                        {
                            var ent = dict.Key;
                            _entRefreshQueue.Enqueue(ent);
                            uint value;
                            _globalEntTmp.TryRemove(ent, out value);
                        }
                    }
                    //if (Enforced.Debug >= 3 && EntSlotTick) Dsutil2.StopWatchReport("monitor", -1);
                }
            }
            catch (Exception ex) { Log.Line($"Exception in WebMonitor: {ex}"); }
        }
예제 #7
0
        internal void MonitorRefreshTasks(int x, ref List <MyEntity> monitorList, bool reInforce, ref bool newSub)
        {
            var s = _workData.ShieldList[x];

            if (reInforce)
            {
                HashSet <MyCubeGrid> subs;
                lock (s.GetCubesLock) subs = new HashSet <MyCubeGrid>(s.ShieldComp.GetSubGrids);
                var newMode = !s.ReInforcedShield;
                if (!newMode)
                {
                    return;
                }
                foreach (var sub in subs)
                {
                    //if (Enforced.Debug >= 2) Log.Line("Server queuing entFresh for reinforced shield");

                    if (!_globalEntTmp.ContainsKey(sub))
                    {
                        newSub = true;
                    }
                    _entRefreshQueue.Enqueue(sub);
                    if (!s.WasPaused)
                    {
                        _globalEntTmp[sub] = _workData.Tick;
                    }
                }

                s.ReInforcedShield    = true;
                s.TicksWithNoActivity = 0;
                s.LastWokenTick       = _workData.Tick;
                s.Asleep = false;
            }
            else
            {
                var newMode = false;
                if (s.ReInforcedShield)
                {
                    HashSet <MyCubeGrid> subs;
                    lock (s.GetCubesLock) subs = new HashSet <MyCubeGrid>(s.ShieldComp.GetSubGrids);
                    foreach (var sub in subs)
                    {
                        _entRefreshQueue.Enqueue(sub);
                        if (!s.WasPaused)
                        {
                            _globalEntTmp[sub] = _workData.Tick;
                        }
                    }
                    //if (Enforced.Debug >= 2) Log.Line($"found Reinforce");
                    s.ReInforcedShield    = false;
                    s.TicksWithNoActivity = 0;
                    s.LastWokenTick       = _workData.Tick;
                    s.Asleep = false;
                    newMode  = true;
                }

                if (!newMode)
                {
                    // var testMat = s.DetectMatrixOutside;
                    // var shape1 = new Sphere(Vector3D.Zero, 1.0).Transformed(testMat);
                    var foundNewEnt   = false;
                    var disableVoxels = Enforced.DisableVoxelSupport == 1 || s.ShieldComp.Modulator == null || s.ShieldComp.Modulator.ModSet.Settings.ModulateVoxels;
                    MyGamePruningStructure.GetTopmostEntitiesInBox(ref s.WebBox, monitorList);
                    foreach (var ent in monitorList)
                    {
                        var voxel = ent as MyVoxelBase;
                        if (ent == null || ent.MarkedForClose || (voxel == null && (ent.Physics == null || ent.DefinitionId == null)) || (!s.GridIsMobile && voxel != null) || (disableVoxels && voxel != null) || (voxel != null && voxel != voxel.RootVoxel))
                        {
                            continue;
                        }

                        if (ent is IMyFloatingObject || ent is IMyEngineerToolBase || !s.WebSphere.Intersects(ent.PositionComp.WorldVolume))
                        {
                            continue;
                        }

                        // var halfExtents = ent.PositionComp.LocalAABB.HalfExtents;
                        // if (halfExtents.X < 1) halfExtents.X = 10;
                        // if (halfExtents.Y < 1) halfExtents.Y = 10;
                        // if (halfExtents.Z < 1) halfExtents.Z = 10;
                        // var shape2 = new Box(-halfExtents, halfExtents).Transformed(ent.WorldMatrix);
                        // var test = Gjk.Intersects(ref shape1, ref shape2);
                        // Log.Line($"{ent.DebugName} - {test}");
                        if (CustomCollision.NewObbPointsInShield(ent, s.DetectMatrixOutsideInv) > 0)
                        {
                            if (!s.WasPaused && !_globalEntTmp.ContainsKey(ent))
                            {
                                foundNewEnt = true;
                                s.Asleep    = false;
                                //if (Enforced.Debug >= 2) Log.Line($"New entity");
                            }

                            if (!s.WasPaused)
                            {
                                _globalEntTmp[ent] = _workData.Tick;
                            }
                        }
                        s.NewEntByShield = foundNewEnt;
                    }
                    if (!s.NewEntByShield)
                    {
                        var foundPlayer = false;
                        foreach (var player in Players.Values)
                        {
                            var character = player.Character;
                            if (character == null)
                            {
                                continue;
                            }

                            if (Vector3D.DistanceSquared(character.PositionComp.WorldMatrix.Translation, s.DetectionCenter) < SyncDistSqr)
                            {
                                foundPlayer = true;
                                break;
                            }
                        }
                        s.PlayerByShield = foundPlayer;
                    }
                    if (!s.PlayerByShield)
                    {
                        s.MoverByShield = false;
                        var newMover  = false;
                        var moverList = new List <MyEntity>();

                        MyGamePruningStructure.GetTopMostEntitiesInBox(ref s.ShieldBox3K, moverList, MyEntityQueryType.Dynamic);
                        for (int i = 0; i < moverList.Count; i++)
                        {
                            var ent = moverList[i];

                            if (!(ent.Physics == null || ent is MyCubeGrid || ent is IMyCharacter || ent is IMyMeteor))
                            {
                                continue;
                            }
                            var entPos = ent.PositionComp.WorldMatrix.Translation;

                            var keyFound = s.EntsByMe.ContainsKey(ent);
                            if (keyFound)
                            {
                                if (!s.EntsByMe[ent].Pos.Equals(entPos, 1e-3))
                                {
                                    //if (Enforced.Debug >= 2) Log.Line($"[Moved] Ent:{ent.DebugName}");
                                    MoverInfo moverInfo;
                                    s.EntsByMe.TryRemove(ent, out moverInfo);
                                    s.EntsByMe.TryAdd(ent, new MoverInfo(entPos, _workData.Tick));
                                    newMover = true;
                                    break;
                                }
                            }
                            else
                            {
                                s.EntsByMe.TryAdd(ent, new MoverInfo(entPos, _workData.Tick));
                            }
                        }
                        s.MoverByShield = newMover;
                    }

                    if (_workData.Tick < s.LastWokenTick + 400)
                    {
                        s.Asleep = false;
                        return;
                    }
                }

                if (s.EntCleanUpTime)
                {
                    s.EntCleanUpTime = false;
                    if (!s.EntsByMe.IsEmpty)
                    {
                        var entsByMeTmp = new List <KeyValuePair <MyEntity, MoverInfo> >();
                        entsByMeTmp.AddRange(s.EntsByMe.Where(info => !info.Key.InScene || _workData.Tick - info.Value.CreationTick > EntMaxTickAge));
                        for (int i = 0; i < entsByMeTmp.Count; i++)
                        {
                            MoverInfo mInfo;
                            s.EntsByMe.TryRemove(entsByMeTmp[i].Key, out mInfo);
                        }
                    }
                }
            }
        }