private void OnEntityRemove(MyEntity myEntity) { if (Environment.CurrentManagedThreadId == 1) { MyProtectors protector; if (GlobalProtect.TryGetValue(myEntity, out protector)) { foreach (var s in protector.Shields.Keys) { ProtectCache cache; if (s.ProtectedEntCache.TryRemove(myEntity, out cache)) { ProtectCachePool.Return(cache); } } EntRefreshQueue.Enqueue(myEntity); } } }
internal void MonitorRefreshTasks(DefenseShields s, ref List <MyEntity> monitorList, bool reInforce, ref bool newSub) { if (reInforce) { var newMode = !s.ReInforcedShield; if (!newMode) { return; } foreach (var sub in s.ShieldComp.SubGrids.Keys) { if (!_globalEntTmp.ContainsKey(sub)) { newSub = true; } EntRefreshQueue.Enqueue(sub); if (!s.WasPaused) { _globalEntTmp[sub] = Tick; } } s.ReInforcedShield = true; s.TicksWithNoActivity = 0; s.LastWokenTick = Tick; s.Asleep = false; } else { var newMode = false; if (s.ReInforcedShield) { foreach (var sub in s.ShieldComp.SubGrids.Keys) { EntRefreshQueue.Enqueue(sub); if (!s.WasPaused) { _globalEntTmp[sub] = Tick; } } s.ReInforcedShield = false; s.TicksWithNoActivity = 0; s.LastWokenTick = 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] = 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, Tick)); if (moverInfo.CreationTick == 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, Tick)); } } moverList.Clear(); ListMyEntityPool.Return(moverList); s.MoverByShield = newMover; } if (Tick < s.LastWokenTick + 400) { s.Asleep = false; return; } } if (s.EntCleanUpTime) { s.EntCleanUpTime = false; foreach (var info in s.EntsByMe) { if (!info.Key.InScene || info.Key.MarkedForClose || Tick - info.Value.CreationTick > EntMaxTickAge) { MoverInfo mInfo; s.EntsByMe.TryRemove(info.Key, out mInfo); } } } } }
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}"); } }