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); }
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; } }
public void Draw(int onCount, bool sphereOnCamera) { _onCount = onCount; var renderId = MyGrid.Render.GetRenderObjectID(); var percent = DsState.State.ShieldPercent; var reInforce = DsState.State.ReInforce; var hitAnim = !reInforce && DsSet.Settings.HitWaveAnimation; var refreshAnim = !reInforce && DsSet.Settings.RefreshAnimation; Vector3D impactPos; lock (HandlerImpact) impactPos = HandlerImpact.Active ? ComputeHandlerImpact() : WorldImpactPosition; var intersected = WorldImpactPosition != Vector3D.NegativeInfinity && impactPos != Vector3D.Zero; WorldImpactPosition = impactPos; var activeVisible = DetermineVisualState(reInforce); WorldImpactPosition = Vector3D.NegativeInfinity; var kineticHit = EnergyHit == HitType.Kinetic; _localImpactPosition = Vector3D.NegativeInfinity; if (impactPos != Vector3D.NegativeInfinity && (kineticHit && KineticCoolDown < 0 || EnergyHit == HitType.Energy && EnergyCoolDown < 0)) { if (_isServer && WebDamage && GridIsMobile) { Vector3 pointVel; var gridCenter = MyGrid.PositionComp.WorldAABB.Center; MyGrid.Physics.GetVelocityAtPointLocal(ref gridCenter, out pointVel); impactPos += (Vector3D)pointVel * Session.TwoStep; } if (kineticHit) { KineticCoolDown = 0; } else if (EnergyHit == HitType.Energy) { EnergyCoolDown = 0; } if (EnergyHit != HitType.Other) { HitParticleStart(impactPos, intersected); } var cubeBlockLocalMatrix = MyGrid.PositionComp.LocalMatrix; var referenceWorldPosition = cubeBlockLocalMatrix.Translation; var worldDirection = impactPos - referenceWorldPosition; var localPosition = Vector3D.TransformNormal(worldDirection, MatrixD.Transpose(cubeBlockLocalMatrix)); _localImpactPosition = localPosition; } EnergyHit = HitType.Kinetic; if (DsState.State.Online) { var prevlod = _prevLod; var lod = CalculateLod(_onCount); if (_shapeChanged || _updateRender || lod != prevlod) { _updateRender = false; _shapeChanged = false; Icosphere.CalculateTransform(ShieldShapeMatrix, lod); if (!GridIsMobile) { Icosphere.ReturnPhysicsVerts(DetectionMatrix, ShieldComp.PhysicsOutside); } } Icosphere.ComputeEffects(ShieldShapeMatrix, _localImpactPosition, _shellPassive, _shellActive, prevlod, percent, activeVisible, refreshAnim); } else if (_shapeChanged) { _updateRender = true; } if (hitAnim && sphereOnCamera && DsState.State.Online) { Icosphere.Draw(renderId); } }
public void Draw(int onCount, bool sphereOnCamera) { _onCount = onCount; var renderId = MyGrid.Render.GetRenderObjectID(); var percent = DsState.State.ShieldPercent; var reInforce = DsState.State.ReInforce; var hitAnim = !reInforce && DsSet.Settings.HitWaveAnimation; var refreshAnim = !reInforce && DsSet.Settings.RefreshAnimation; var activeVisible = DetermineVisualState(reInforce); var impactPos = WorldImpactPosition; var webEffect = WebDamage && BulletCoolDown > -1 && WebCoolDown < 0; _localImpactPosition = Vector3D.NegativeInfinity; if (impactPos != Vector3D.NegativeInfinity && (BulletCoolDown < 0 || webEffect)) { if (webEffect) { WebCoolDown = 0; HitParticleStart(); } else { if (WebDamage) { WebCoolDown = 0; } BulletCoolDown = 0; HitParticleStart(); var cubeBlockLocalMatrix = MyGrid.PositionComp.LocalMatrix; var referenceWorldPosition = cubeBlockLocalMatrix.Translation; var worldDirection = impactPos - referenceWorldPosition; var localPosition = Vector3D.TransformNormal(worldDirection, MatrixD.Transpose(cubeBlockLocalMatrix)); _localImpactPosition = localPosition; } } WorldImpactPosition = Vector3D.NegativeInfinity; WebDamage = false; if (IsWorking) { var prevlod = _prevLod; var lod = CalculateLod(_onCount); if (_shapeChanged || _updateRender || lod != prevlod) { Icosphere.CalculateTransform(ShieldShapeMatrix, lod); if (!GridIsMobile) { Icosphere.ReturnPhysicsVerts(DetectionMatrix, ShieldComp.PhysicsOutside); } } Icosphere.ComputeEffects(ShieldShapeMatrix, _localImpactPosition, _shellPassive, _shellActive, prevlod, percent, activeVisible, refreshAnim); } if (hitAnim && sphereOnCamera && IsWorking) { Icosphere.Draw(renderId); } _updateRender = false; _shapeChanged = false; }
public void Draw(int onCount, bool sphereOnCamera) { _onCount = onCount; var renderId = MyGrid.Render.GetRenderObjectID(); var percent = DsState.State.ShieldPercent; var reInforce = DsState.State.ReInforce; //var hitAnim = !reInforce && DsSet.Settings.HitWaveAnimation; Vector3D impactPos; lock (HandlerImpact) impactPos = HandlerImpact.Active ? ComputeHandlerImpact() : WorldImpactPosition; var intersected = WorldImpactPosition != Vector3D.NegativeInfinity && impactPos != Vector3D.Zero; WorldImpactPosition = impactPos; var activeVisible = DetermineVisualState(reInforce); WorldImpactPosition = Vector3D.NegativeInfinity; var vanillaHit = EnergyHit != HitType.Other; var kineticHit = EnergyHit == HitType.Kinetic; _localImpactPosition = Vector3D.NegativeInfinity; if (impactPos != Vector3D.NegativeInfinity && (kineticHit && KineticCoolDown < 0 || EnergyHit == HitType.Energy && EnergyCoolDown < 0 || EnergyHit == HitType.Other)) { if (_isServer && WebDamage && GridIsMobile) { Vector3 pointVel; var gridCenter = DetectionCenter; MyGrid.Physics.GetVelocityAtPointLocal(ref gridCenter, out pointVel); impactPos += (Vector3D)pointVel * Session.TwoStep; } if (kineticHit) { KineticCoolDown = 0; } else if (EnergyHit == HitType.Energy) { EnergyCoolDown = 0; } if (EnergyHit != HitType.Other) { HitParticleStart(impactPos, intersected); } var cubeBlockLocalMatrix = MyGrid.PositionComp.LocalMatrixRef; var referenceWorldPosition = cubeBlockLocalMatrix.Translation; var worldDirection = impactPos - referenceWorldPosition; var localPosition = Vector3D.TransformNormal(worldDirection, MatrixD.Transpose(cubeBlockLocalMatrix)); _localImpactPosition = localPosition; } EnergyHit = HitType.Kinetic; if (DsState.State.Online) { var prevlod = _prevLod; var lod = CalculateLod(_onCount); if (_shapeChanged || _updateRender || lod != prevlod) { _updateRender = false; _shapeChanged = false; Icosphere.CalculateTransform(ShieldShapeMatrix, lod); if (!GridIsMobile) { Icosphere.ReturnPhysicsVerts(DetectionMatrix, ShieldComp.PhysicsOutside); } } Icosphere.ComputeEffects(this, _localImpactPosition, prevlod, percent, activeVisible); } else if (_shapeChanged) { _updateRender = true; } var startPulse = Session.Instance.Tick20 && _toggle; var updated = Session.Instance.Tick300 || startPulse; var wasPulsing = _sidePulsing; if (updated && ShellActive != null && RedirectVisualUpdate()) { UpdateShieldRedirectVisuals(); } if (ShellActive != null && _sidePulsing) { SidePulseRender(); } if (wasPulsing && !_sidePulsing) { ClearSidePulse(); } if (sphereOnCamera && DsState.State.Online && Session.Instance.Settings.ClientConfig.ShowHitRings || vanillaHit) { Icosphere.Draw(renderId, this); } }