public void CleanWebEnts() { AuthenticatedCache.Clear(); IgnoreCache.Clear(); _protectEntsTmp.Clear(); _protectEntsTmp.AddRange(ProtectedEntCache.Where(info => _tick - info.Value.LastTick > 180)); foreach (var protectedEnt in _protectEntsTmp) { ProtectedEntCache.Remove(protectedEnt.Key); } _webEntsTmp.Clear(); _webEntsTmp.AddRange(WebEnts.Where(info => _tick - info.Value.LastTick > 180)); foreach (var webent in _webEntsTmp) { EntIntersectInfo removedEnt; WebEnts.TryRemove(webent.Key, out removedEnt); EnemyShields.Remove(webent.Key); } }
public void WebEntities() { PruneList.Clear(); MyGamePruningStructure.GetTopMostEntitiesInBox(ref WebBox, PruneList); if (Missiles.Count > 0) { var missileBox = WebBox; foreach (var missile in Missiles) { if (missile.InScene && !missile.MarkedForClose && missileBox.Intersects(missile.PositionComp.WorldAABB)) { PruneList.Add(missile); } } } var shieldsStartIndex = PruneList.Count; foreach (var eShield in EnemyShields) { PruneList.Add(eShield); } var disableVoxels = Session.Enforced.DisableVoxelSupport == 1 || ShieldComp.Modulator == null || ShieldComp.Modulator.ModSet.Settings.ModulateVoxels; var voxelFound = false; var shieldFound = false; var entChanged = false; var iMoving = ShieldComp.GridIsMoving; var tick = Session.Instance.Tick; _enablePhysics = false; for (int i = 0; i < PruneList.Count; i++) { var ent = PruneList[i]; var entPhysics = ent.Physics; if (i < shieldsStartIndex) { var voxel = ent as MyVoxelBase; if (ent == null || (voxel == null && (entPhysics == null || entPhysics.IsPhantom || ent.DefinitionId == null)) || (voxel != null && (!iMoving || !GridIsMobile || disableVoxels || voxel != voxel.RootVoxel))) { continue; } bool quickReject; if (_isServer) { quickReject = ent is IMyEngineerToolBase || IgnoreCache.Contains(ent) || EnemyShields.Contains(ent) || FriendlyMissileCache.Contains(ent) || AuthenticatedCache.Contains(ent); } else { quickReject = (!(ent is MyCubeGrid) && voxel == null && !(ent is IMyCharacter)) || IgnoreCache.Contains(ent) || EnemyShields.Contains(ent) || AuthenticatedCache.Contains(ent); } var floater = ent as IMyFloatingObject; if (quickReject || floater != null && (!iMoving && Vector3.IsZero(entPhysics.LinearVelocity, 1e-2f)) || !WebSphere.Intersects(ent.PositionComp.WorldVolume)) { continue; } if (voxel != null) { if (VoxelsToIntersect.ContainsKey(voxel)) { VoxelsToIntersect[voxel]++; } else { VoxelsToIntersect[voxel] = 1; } voxelFound = true; entChanged = true; _enablePhysics = true; continue; } } Ent relation; ProtectCache protectedEnt; EntIntersectInfo entInfo = null; ProtectedEntCache.TryGetValue(ent, out protectedEnt); var refreshInfo = false; if (protectedEnt == null) { WebEnts.TryGetValue(ent, out entInfo); if (entInfo != null) { var last = entInfo.LastTick; var refresh = entInfo.RefreshTick; var refreshTick = tick - last > 180 || (tick - last == 180 && tick - refresh >= 3600) || (tick - last == 1 && tick - refresh >= 60); refreshInfo = refreshTick; if (refreshInfo || entInfo.RefreshNow) { entInfo.RefreshTick = tick; entInfo.Relation = EntType(ent); } relation = entInfo.Relation; entInfo.LastTick = tick; } else { relation = EntType(ent); } } else { var last = protectedEnt.LastTick; var refresh = protectedEnt.RefreshTick; var refreshTick = tick - last > 180 || (tick - last == 180 && tick - refresh >= 3600) || (tick - last == 1 && tick - refresh >= 60); refreshInfo = refreshTick; if (refreshInfo) { protectedEnt.RefreshTick = tick; protectedEnt.PreviousRelation = protectedEnt.Relation; protectedEnt.Relation = EntType(ent); } relation = protectedEnt.Relation; protectedEnt.LastTick = tick; } switch (relation) { case Ent.Authenticated: continue; case Ent.Ignore: case Ent.Friendly: case Ent.Protected: if (relation == Ent.Protected) { if (protectedEnt == null) { ProtectedEntCache[ent] = new ProtectCache(tick, tick, tick, relation, relation); } MyProtectors protectors; Session.Instance.GlobalProtect.TryGetValue(ent, out protectors); if (protectors == null) { protectors = Session.Instance.GlobalProtect[ent] = Session.ProtSets.Get(); protectors.Init(LogicSlot, tick); } if (protectors.Shields.Contains(this)) { continue; } protectors.Shields.Add(this); protectors.Shields.ApplyAdditions(); continue; } IgnoreCache.Add(ent); continue; } if (relation == Ent.Shielded) { shieldFound = true; } try { if (entInfo != null) { var interestingEnts = relation == Ent.Floater || relation == Ent.EnemyGrid || relation == Ent.NobodyGrid || relation == Ent.Shielded; if (entPhysics != null && entPhysics.IsMoving) { entChanged = true; } else if (entInfo.Touched || (refreshInfo && interestingEnts && !ent.PositionComp.LocalAABB.Equals(entInfo.Box))) { entInfo.RefreshTick = tick; entInfo.Box = ent.PositionComp.LocalAABB; entChanged = true; } _enablePhysics = true; if (refreshInfo) { if ((relation == Ent.EnemyGrid || relation == Ent.NobodyGrid) && entInfo.CacheBlockList.Count != (ent as MyCubeGrid).BlocksCount) { entInfo.RefreshNow = true; } } } else { if (relation == Ent.Other) { var entPast = -Vector3D.Normalize(entPhysics.LinearVelocity) * 6; var entTestLoc = ent.PositionComp.WorldVolume.Center + entPast; var centerStep = -Vector3D.Normalize(entTestLoc - DetectionCenter) * 2f; var counterDrift = centerStep + entTestLoc; if (CustomCollision.PointInShield(counterDrift, DetectMatrixOutsideInv)) { FriendlyMissileCache.Add(ent); continue; } } entChanged = true; _enablePhysics = true; ProtectedEntCache.Remove(ent); WebEnts.TryAdd(ent, new EntIntersectInfo(false, ent.PositionComp.LocalAABB, tick, tick, tick, relation)); } } catch (Exception ex) { Log.Line($"Exception in WebEntities entInfo: {ex}"); } } if (!_enablePhysics) { return; } ShieldMatrix = ShieldEnt.PositionComp.WorldMatrix; if ((_needPhysics && shieldFound) || !ShieldMatrix.EqualsFast(ref OldShieldMatrix)) { OldShieldMatrix = ShieldMatrix; if (shieldFound) { _needPhysics = false; Icosphere.ReturnPhysicsVerts(DetectMatrixOutside, ShieldComp.PhysicsOutside); } else { _needPhysics = true; } if (voxelFound) { Icosphere.ReturnPhysicsVerts(DetectMatrixOutside, ShieldComp.PhysicsOutsideLow); } } if (iMoving || entChanged) { Asleep = false; LastWokenTick = tick; Session.Instance.WebWrapper.Enqueue(this); Session.Instance.WebWrapperOn = true; } }