public void CleanWebEnts() { AuthenticatedCache.Clear(); IgnoreCache.Clear(); foreach (var info in ProtectedEntCache) { if (_tick - info.Value.LastTick > 180) { ProtectCache cache; if (ProtectedEntCache.TryRemove(info.Key, out cache)) { Session.Instance.EntRefreshQueue.Enqueue(info.Key); Session.Instance.ProtectCachePool.Return(cache); Session.Instance.FastRefresh = true; } } } foreach (var webent in WebEnts) { if (_tick - webent.Value.LastTick > 180) { EntIntersectInfo removedEnt; WebEnts.TryRemove(webent.Key, out removedEnt); Session.Instance.EntIntersectInfoPool.Return(removedEnt); EnemyShields.Remove(webent.Key); } } }
private void GridIntersect(MyEntity ent) { var grid = (MyCubeGrid)ent; if (grid == null) { return; } EntIntersectInfo entInfo; WebEnts.TryGetValue(ent, out entInfo); if (entInfo == null) { return; } var bOriBBoxD = MyOrientedBoundingBoxD.CreateFromBoundingBox(grid.PositionComp.WorldAABB); if (entInfo.Relation != Ent.LargeEnemyGrid && GridInside(grid, bOriBBoxD)) { return; } BlockIntersect(grid, bOriBBoxD, entInfo); if (entInfo.MarkForClose) { EntIntersectInfo gridRemoved; WebEnts.TryRemove(grid, out gridRemoved); return; } if (!_isServer) { return; } var contactpoint = entInfo.ContactPoint; entInfo.ContactPoint = Vector3D.NegativeInfinity; entInfo.EmpDetonation = Vector3D.NegativeInfinity; entInfo.Damage = 0; entInfo.EmpSize = 0; if (contactpoint == Vector3D.NegativeInfinity) { return; } entInfo.Touched = true; }
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); } }
private void PlayerIntersect(MyEntity ent) { var character = ent as IMyCharacter; if (character == null) { return; } var npcname = character.ToString(); if (npcname.Equals(SpaceWolf)) { if (_isServer) { CharacterDmg.Enqueue(character); } return; } var player = MyAPIGateway.Multiplayer.Players.GetPlayerControllingEntity(ent); if (player == null || player.PromoteLevel == MyPromoteLevel.Owner || player.PromoteLevel == MyPromoteLevel.Admin) { return; } if (!_isServer) { if (character.EnabledDamping) { character.SwitchDamping(); } return; } if (character.EnabledDamping) { character.SwitchDamping(); } if (!character.EnabledThrusts) { return; } var playerInfo = WebEnts[ent]; var insideTime = (int)playerInfo.LastTick - (int)playerInfo.FirstTick; if (insideTime < 3000) { return; } EntIntersectInfo playerRemoved; WebEnts.TryRemove(ent, out playerRemoved); var hydrogenId = MyCharacterOxygenComponent.HydrogenId; var playerGasLevel = character.GetSuitGasFillLevel(hydrogenId); if (!(playerGasLevel > 0.01f)) { return; } CharacterDmg.Enqueue(character); }
private void ShieldIntersect(MyEntity ent) { var grid = ent as MyCubeGrid; if (grid == null) { return; } if (GridInside(grid, MyOrientedBoundingBoxD.CreateFromBoundingBox(grid.PositionComp.WorldAABB))) { return; } ShieldGridComponent shieldComponent; grid.Components.TryGet(out shieldComponent); if (shieldComponent?.DefenseShields == null) { return; } var ds = shieldComponent.DefenseShields; if (!ds.WasOnline) { EntIntersectInfo entInfo; WebEnts.TryRemove(ent, out entInfo); } var dsVerts = ds.ShieldComp.PhysicsOutside; var dsMatrixInv = ds.DetectMatrixOutsideInv; var myGrid = Shield.CubeGrid; var insidePoints = new List <Vector3D>(); if (_isServer) { CustomCollision.ShieldX2PointsInside(dsVerts, dsMatrixInv, ShieldComp.PhysicsOutside, DetectMatrixOutsideInv, insidePoints); } else { CustomCollision.ClientShieldX2PointsInside(dsVerts, dsMatrixInv, ShieldComp.PhysicsOutsideLow, DetectMatrixOutsideInv, insidePoints); } var bPhysics = ((IMyCubeGrid)grid).Physics; var sPhysics = myGrid.Physics; var bMass = grid.GetCurrentMass(); var sMass = ((MyCubeGrid)myGrid).GetCurrentMass(); if (bMass <= 0) { bMass = int.MaxValue; } if (sMass <= 0) { sMass = int.MaxValue; } var bVel = bPhysics.LinearVelocity; var bVelLen = bVel.Length(); var momentum = (bMass * bVel) + (sMass * sPhysics.LinearVelocity); var resultVelocity = momentum / (bMass + sMass); var collisionAvg = Vector3D.Zero; var numOfPointsInside = insidePoints.Count; for (int i = 0; i < numOfPointsInside; i++) { collisionAvg += insidePoints[i]; } collisionAvg /= numOfPointsInside; if (numOfPointsInside > 0 && !bPhysics.IsStatic) { var ejectorAccel = numOfPointsInside > 10 ? numOfPointsInside : 10; var impulseData = new MyImpulseData { MyGrid = grid, Direction = (resultVelocity - bVel) * bMass, Position = bPhysics.CenterOfMassWorld }; var forceData = new MyAddForceData { MyGrid = grid, Force = (bPhysics.CenterOfMassWorld - collisionAvg) * bMass * ejectorAccel, MaxSpeed = MathHelper.Clamp(bVelLen, 1f, 50f) }; ImpulseData.Enqueue(impulseData); ForceData.Enqueue(forceData); } if (!_isServer || numOfPointsInside <= 0) { return; } var shieldMaxChargeRate = ds._shieldMaxChargeRate; var damage = ((shieldMaxChargeRate * ConvToHp) * DsState.State.ModulateKinetic) * 0.01666666666f; if (_mpActive) { if (_isServer) { AddShieldHit(ds.Shield.EntityId, damage, Session.Instance.MPEnergy, null, false, collisionAvg); } } else { EnergyHit = true; WorldImpactPosition = collisionAvg; ds.EnergyHit = true; ds.WorldImpactPosition = collisionAvg; Absorb += damage; ImpactSize = damage; WebDamage = true; } }
private void ShieldIntersect(MyEntity ent) { var grid = ent as MyCubeGrid; if (grid == null) { return; } var bOriBBoxD = new MyOrientedBoundingBoxD(grid.PositionComp.LocalAABB, grid.PositionComp.WorldMatrixRef); if (EntInside(grid, ref bOriBBoxD)) { return; } var sObb = ShieldComp.DefenseShields.SOriBBoxD; if (!sObb.Intersects(ref SOriBBoxD)) { return; } ShieldGridComponent shieldComponent; grid.Components.TryGet(out shieldComponent); if (shieldComponent?.DefenseShields == null) { return; } var ds = shieldComponent.DefenseShields; if (!ds.NotFailed) { EntIntersectInfo entInfo; WebEnts.TryRemove(ent, out entInfo); Session.Instance.EntIntersectInfoPool.Return(entInfo); } var dsVerts = ds.ShieldComp.PhysicsOutside; var dsMatrixInv = ds.DetectMatrixOutsideInv; _insidePoints.Clear(); CustomCollision.ShieldX2PointsInside(dsVerts, dsMatrixInv, ShieldComp.PhysicsOutside, DetectMatrixOutsideInv, _insidePoints); var collisionAvg = Vector3D.Zero; var numOfPointsInside = _insidePoints.Count; for (int i = 0; i < numOfPointsInside; i++) { collisionAvg += _insidePoints[i]; } if (numOfPointsInside > 0) { collisionAvg /= numOfPointsInside; } if (collisionAvg == Vector3D.Zero) { GridIntersect(ent); return; } var iFortified = DsSet.Settings.FortifyShield && DsState.State.Enhancer; var bFortified = ds.DsSet.Settings.FortifyShield && ds.DsState.State.Enhancer; var iWinForceFight = iFortified && !bFortified; var iLoseForceFight = !iFortified && bFortified; if (!iLoseForceFight && (MyGrid.EntityId > grid.EntityId || iWinForceFight)) { ComputeCollisionPhysics(grid, MyGrid, collisionAvg); } else if (!_isServer) { return; } var damage = ((ds._shieldMaxChargeRate * ConvToHp) * DsState.State.ModulateKinetic) * 0.01666666666f; var shieldEvent = Session.Instance.ShieldEventPool.Get(); shieldEvent.Init(this, damage, collisionAvg, grid.EntityId); Session.Instance.ThreadEvents.Enqueue(shieldEvent); }
private void ShieldIntersect(MyEntity ent) { var grid = ent as MyCubeGrid; if (grid == null) { return; } if (EntInside(grid, MyOrientedBoundingBoxD.CreateFromBoundingBox(grid.PositionComp.WorldAABB))) { return; } ShieldGridComponent shieldComponent; grid.Components.TryGet(out shieldComponent); if (shieldComponent?.DefenseShields == null) { return; } var ds = shieldComponent.DefenseShields; if (!ds.NotFailed) { EntIntersectInfo entInfo; WebEnts.TryRemove(ent, out entInfo); Session.Instance.EntIntersectInfoPool.Return(entInfo); } var dsVerts = ds.ShieldComp.PhysicsOutside; var dsMatrixInv = ds.DetectMatrixOutsideInv; var insidePoints = new List <Vector3D>(); CustomCollision.ShieldX2PointsInside(dsVerts, dsMatrixInv, ShieldComp.PhysicsOutside, DetectMatrixOutsideInv, insidePoints); var collisionAvg = Vector3D.Zero; var numOfPointsInside = insidePoints.Count; for (int i = 0; i < numOfPointsInside; i++) { collisionAvg += insidePoints[i]; } if (numOfPointsInside > 0) { collisionAvg /= numOfPointsInside; } if (collisionAvg == Vector3D.Zero) { return; } if (MyGrid.EntityId > grid.EntityId) { ComputeCollisionPhysics(grid, MyGrid, collisionAvg); } else if (!_isServer) { return; } var damage = ((ds._shieldMaxChargeRate * ConvToHp) * DsState.State.ModulateKinetic) * 0.01666666666f; var shieldEvent = Session.Instance.ShieldEventPool.Get(); shieldEvent.Init(this, damage, collisionAvg, grid.EntityId); Session.Instance.ThreadEvents.Enqueue(shieldEvent); }
private void SyncThreadedEnts(bool clear = false, bool client = false) { try { if (clear) { Eject.Clear(); DestroyedBlocks.Clear(); MissileDmg.Clear(); MeteorDmg.Clear(); VoxelDmg.Clear(); CharacterDmg.Clear(); FewDmgBlocks.Clear(); CollidingBlocks.Clear(); ForceData.Clear(); ImpulseData.Clear(); return; } try { if (!Eject.IsEmpty) { MyCubeGrid myGrid; while (Eject.TryDequeue(out myGrid)) { if (myGrid == null || myGrid.MarkedForClose) { continue; } myGrid.Physics.LinearVelocity *= -0.25f; } } } catch (Exception ex) { Log.Line($"Exception in Eject: {ex}"); } try { if (!ForceData.IsEmpty) { MyAddForceData data; while (ForceData.TryDequeue(out data)) { var myGrid = data.MyGrid; if (myGrid == null || myGrid.MarkedForClose) { continue; } myGrid.Physics.AddForce(MyPhysicsForceType.APPLY_WORLD_FORCE, data.Force, null, Vector3D.Zero, data.MaxSpeed, data.Immediate); } } } catch (Exception ex) { Log.Line($"Exception in forceData: {ex}"); } try { if (!ImpulseData.IsEmpty) { MyImpulseData data; while (ImpulseData.TryDequeue(out data)) { var myGrid = data.MyGrid; if (myGrid == null || myGrid.MarkedForClose) { continue; } myGrid.Physics.ApplyImpulse(data.Direction, data.Position); } } } catch (Exception ex) { Log.Line($"Exception in impulseData: {ex}"); } if (client) { return; } try { if (!DestroyedBlocks.IsEmpty) { IMySlimBlock block; var nullCount = 0; while (DestroyedBlocks.TryDequeue(out block)) { var myGrid = block.CubeGrid as MyCubeGrid; if (myGrid == null) { continue; } EntIntersectInfo entInfo; WebEnts.TryGetValue(myGrid, out entInfo); if (entInfo == null) { nullCount++; myGrid.EnqueueDestroyedBlock(block.Position); continue; } EntIntersectInfo entRemoved; if (nullCount > 0) { WebEnts.TryRemove(myGrid, out entRemoved); } entInfo.CacheBlockList.Remove(block); myGrid.EnqueueDestroyedBlock(block.Position); } } } catch (Exception ex) { Log.Line($"Exception in destroyedBlocks: {ex}"); } try { if (!MissileDmg.IsEmpty) { MyEntity ent; while (MissileDmg.TryDequeue(out ent)) { if (ent == null || !ent.InScene || ent.MarkedForClose) { continue; } var computedDamage = ComputeAmmoDamage(ent); var damage = computedDamage * DsState.State.ModulateKinetic; if (computedDamage < 0) { damage = computedDamage; } var rayDir = Vector3D.Normalize(ent.Physics.LinearVelocity); var ray = new RayD(ent.PositionComp.WorldVolume.Center, rayDir); var intersect = CustomCollision.IntersectEllipsoid(DetectMatrixOutsideInv, DetectionMatrix, ray); var hitDist = intersect ?? 0; var hitPos = ray.Position + (ray.Direction * -hitDist); if (_mpActive) { AddShieldHit(ent.EntityId, damage, Session.Instance.MPExplosion, null, false, hitPos); ent.Close(); ent.InScene = false; } else { EnergyHit = true; WorldImpactPosition = hitPos; Absorb += damage; ImpactSize = damage; UtilsStatic.CreateFakeSmallExplosion(hitPos); ent.Close(); ent.InScene = false; } } } } catch (Exception ex) { Log.Line($"Exception in missileDmg: {ex}"); } try { if (!MeteorDmg.IsEmpty) { IMyMeteor meteor; while (MeteorDmg.TryDequeue(out meteor)) { if (meteor == null || meteor.MarkedForClose || meteor.Closed) { continue; } var damage = 5000 * DsState.State.ModulateEnergy; if (_mpActive) { AddShieldHit(meteor.EntityId, damage, Session.Instance.MPKinetic, null, false, meteor.PositionComp.WorldVolume.Center); meteor.DoDamage(10000f, Session.Instance.MpIgnoreDamage, true, null, MyCube.EntityId); } else { WorldImpactPosition = meteor.PositionComp.WorldVolume.Center; Absorb += damage; ImpactSize = damage; meteor.DoDamage(10000f, Session.Instance.MpIgnoreDamage, true, null, MyCube.EntityId); } } } } catch (Exception ex) { Log.Line($"Exception in missileDmg: {ex}"); } try { if (!VoxelDmg.IsEmpty) { MyVoxelBase voxel; while (VoxelDmg.TryDequeue(out voxel)) { if (voxel == null || voxel.RootVoxel.MarkedForClose || voxel.RootVoxel.Closed) { continue; } voxel.RootVoxel.RequestVoxelOperationElipsoid(Vector3.One * 1.0f, DetectMatrixOutside, 0, MyVoxelBase.OperationType.Cut); } } } catch (Exception ex) { Log.Line($"Exception in missileDmg: {ex}"); } try { if (!CharacterDmg.IsEmpty) { IMyCharacter character; while (CharacterDmg.TryDequeue(out character)) { var npcname = character.ToString(); if (npcname.Equals("Space_Wolf")) { character.Delete(); continue; } var hId = MyCharacterOxygenComponent.HydrogenId; var playerGasLevel = character.GetSuitGasFillLevel(hId); character.Components.Get <MyCharacterOxygenComponent>().UpdateStoredGasLevel(ref hId, (playerGasLevel * -0.0001f) + .002f); MyVisualScriptLogicProvider.CreateExplosion(character.GetPosition(), 0, 0); character.DoDamage(50f, Session.Instance.MpIgnoreDamage, true, null, MyCube.EntityId); var vel = character.Physics.LinearVelocity; if (vel == new Vector3D(0, 0, 0)) { vel = MyUtils.GetRandomVector3Normalized(); } var speedDir = Vector3D.Normalize(vel); var rnd = new Random(); var randomSpeed = rnd.Next(10, 20); var additionalSpeed = vel + (speedDir * randomSpeed); character.Physics.LinearVelocity = additionalSpeed; } } } catch (Exception ex) { Log.Line($"Exception in missileDmg: {ex}"); } try { if (!CollidingBlocks.IsEmpty) { IMySlimBlock block; var damageMulti = 350; if (ShieldMode == ShieldType.Station && DsState.State.Enhancer) { damageMulti = 10000; } while (CollidingBlocks.TryDequeue(out block)) { if (block == null) { continue; } var myGrid = block.CubeGrid as MyCubeGrid; if (block.IsDestroyed) { myGrid.EnqueueDestroyedBlock(block.Position); continue; } block.DoDamage(damageMulti, Session.Instance.MpIgnoreDamage, true, null, MyCube.EntityId); if (myGrid.BlocksCount == 0) { myGrid.SendGridCloseRequest(); } } } } catch (Exception ex) { Log.Line($"Exception in dmgBlocks: {ex}"); } try { if (!FewDmgBlocks.IsEmpty) { IMySlimBlock block; while (FewDmgBlocks.TryDequeue(out block)) { if (block == null) { continue; } var myGrid = block.CubeGrid as MyCubeGrid; if (block.IsDestroyed) { myGrid.EnqueueDestroyedBlock(block.Position); myGrid.Close(); continue; } block.DoDamage(block.MaxIntegrity * 0.9f, Session.Instance.MpIgnoreDamage, true, null, MyCube.EntityId); if (myGrid.BlocksCount == 0) { myGrid.SendGridCloseRequest(); } } } } catch (Exception ex) { Log.Line($"Exception in fewBlocks: {ex}"); } try { if (Session.Instance.EmpWork.EventRunning && Vector3D.DistanceSquared(DetectionCenter, Session.Instance.EmpWork.EpiCenter) <= Session.Instance.EmpWork.RangeCapSqr) { var empResistenceRatio = 1f; const long AttackerId = 0L; var energyResistenceRatio = DsState.State.ModulateKinetic; var epiCenter = Session.Instance.EmpWork.EpiCenter; var rangeCap = Session.Instance.EmpWork.RangeCap; var empDirYield = Session.Instance.EmpWork.DirYield; if (DsState.State.EmpProtection) { if (energyResistenceRatio < 0.4) { energyResistenceRatio = 0.4f; } empResistenceRatio = 0.1f; } //if (Session.Enforced.Debug >= 2) Log.Line($"[EmpBlastShield - Start] ShieldOwner:{MyGrid.DebugName} - Yield:{warHeadYield} - StackCount:{stackCount} - ProtectionRatio:{energyResistenceRatio * empResistenceRatio} - epiCenter:{epiCenter}"); var line = new LineD(epiCenter, SOriBBoxD.Center); var testDir = Vector3D.Normalize(line.From - line.To); var ray = new RayD(line.From, -testDir); var ellipsoid = CustomCollision.IntersectEllipsoid(DetectMatrixOutsideInv, DetectionMatrix, ray); if (!ellipsoid.HasValue) { //if (Session.Enforced.Debug >= 2) Log.Line($"[EmpBlastShield - Ellipsoid null hit] ShieldOwner:{MyGrid.DebugName} - Yield:{warHeadYield} - StackCount:{stackCount} - ProtectionRatio:{energyResistenceRatio * empResistenceRatio} - epiCenter:{epiCenter}"); return; } var impactPos = line.From + (testDir * -ellipsoid.Value); IHitInfo hitInfo; MyAPIGateway.Physics.CastRay(epiCenter, impactPos, out hitInfo, CollisionLayers.DefaultCollisionLayer); if (hitInfo != null) { //if (Session.Enforced.Debug >= 2) Log.Line($"[EmpBlastShield - occluded] ShieldOwner:{MyGrid.DebugName} - by {((MyEntity)hitInfo.HitEntity).DebugName}"); return; } var gridLocalMatrix = MyGrid.PositionComp.LocalMatrix; var worldDirection = impactPos - gridLocalMatrix.Translation; var localPosition = Vector3D.TransformNormal(worldDirection, MatrixD.Transpose(gridLocalMatrix)); var hitFaceSurfaceArea = UtilsStatic.GetIntersectingSurfaceArea(ShieldShapeMatrix, localPosition); var invSqrDist = UtilsStatic.InverseSqrDist(epiCenter, impactPos, rangeCap); var damageScaler = invSqrDist * hitFaceSurfaceArea; if (invSqrDist <= 0) { //if (Session.Enforced.Debug >= 2) Log.Line($"[EmpBlastShield - Range] ShieldOwner:{MyGrid.DebugName} - insqrDist was 0"); return; } var targetDamage = (float)(((empDirYield * damageScaler) * energyResistenceRatio) * empResistenceRatio); if (targetDamage >= DsState.State.Charge * ConvToHp) { _empOverLoad = true; } //if (Session.Enforced.Debug >= 2) Log.Line($"-----------------------] epiDist:{Vector3D.Distance(epiCenter, impactPos)} - iSqrDist:{invSqrDist} - RangeCap:{rangeCap} - SurfaceA:{hitFaceSurfaceArea}({_ellipsoidSurfaceArea * 0.5}) - dirYield:{empDirYield} - damageScaler:{damageScaler} - Damage:{targetDamage}(toOver:{(targetDamage / (DsState.State.Charge * ConvToHp))})"); if (_isServer && _mpActive) { AddEmpBlastHit(AttackerId, targetDamage, Session.Instance.MPEMP, impactPos); } EnergyHit = true; WorldImpactPosition = epiCenter; Absorb += targetDamage; } } catch (Exception ex) { Log.Line($"Exception in EmpBlast: {ex}"); } } catch (Exception ex) { Log.Line($"Exception in DamageGrids: {ex}"); } }