private void GetFilteredItems(Vector3D epiCenter, double rangeCap, double dirYield) { _warHeadCubeHits.Clear(); _warHeadGridShapes.Clear(); var myCubeList = new List <MyEntity>(); foreach (var grid in _warHeadGridHits) { var invSqrDist = UtilsStatic.InverseSqrDist(epiCenter, grid.PositionComp.WorldAABB.Center, rangeCap); var damage = (uint)(dirYield * invSqrDist) * 5; var gridAabb = grid.PositionComp.WorldAABB; var sphere = CustomCollision.NewObbClosestTriCorners(grid, epiCenter); grid.Hierarchy.QueryAABB(ref gridAabb, myCubeList); _warHeadGridShapes.Add(grid, new WarHeadHit(sphere, damage)); } for (int i = 0; i < myCubeList.Count; i++) { var myEntity = myCubeList[i]; var myCube = myEntity as MyCubeBlock; if (myCube == null || myCube.MarkedForClose) { continue; } if ((myCube is IMyThrust || myCube is IMyUserControllableGun || myCube is IMyUpgradeModule) && myCube.IsFunctional && myCube.IsWorking) { _warHeadCubeHits.Add(myCube); } } if (Enforced.Debug >= 2) { Log.Line($"[ComputeEmpBlast] AllFat:{myCubeList.Count} - TrimmedFat:{_warHeadCubeHits.Count}"); } }
private static IMyTerminalBlock TAPI_GetClosestShield(Vector3D pos) { MyCubeBlock cloestSBlock = null; var closestDist = double.MaxValue; lock (Session.Instance.ActiveShields) { foreach (var s in Session.Instance.ActiveShields) { if (Vector3D.DistanceSquared(s.DetectionCenter, pos) > Session.Instance.SyncDistSqr) { continue; } var sDist = CustomCollision.EllipsoidDistanceToPos(s.DetectMatrixOutsideInv, s.DetectMatrixOutside, pos); if (sDist > 0 && sDist < closestDist) { cloestSBlock = s.MyCube; closestDist = sDist; } } } return(cloestSBlock as IMyTerminalBlock); }
private Vector3D ComputeHandlerImpact() { WebDamage = false; HandlerImpact.Active = false; if (HandlerImpact.HitBlock == null) { return(MyGrid.PositionComp.WorldAABB.Center); } Vector3D originHit; HandlerImpact.HitBlock.ComputeWorldCenter(out originHit); var line = new LineD(HandlerImpact.Attacker.PositionComp.WorldAABB.Center, originHit); var testDir = Vector3D.Normalize(line.From - line.To); var ray = new RayD(line.From, -testDir); var matrix = ShieldShapeMatrix * MyGrid.WorldMatrix; var intersectDist = CustomCollision.IntersectEllipsoid(MatrixD.Invert(matrix), matrix, ray); var ellipsoid = intersectDist ?? line.Length; var shieldHitPos = line.From + (testDir * -ellipsoid); return(shieldHitPos); }
private static float?TAPI_PointAttackShieldExt(IMyTerminalBlock block, Vector3D pos, long attackerId, float damage, bool energy, bool drawParticle, bool posMustBeInside = false) { var logic = block?.GameLogic?.GetAs <DefenseShields>()?.ShieldComp?.DefenseShields; if (logic == null) { return(null); } if (posMustBeInside) { lock (logic.MatrixLock) if (!CustomCollision.PointInShield(pos, logic.DetectMatrixOutsideInv)) { return(null); } } float hpRemaining; var pendingDamage = logic.Absorb > 0 ? logic.Absorb : 0; if (energy) { damage *= logic.DsState.State.ModulateKinetic; hpRemaining = (((logic.DsState.State.Charge * DefenseShields.ConvToHp) - pendingDamage) - damage); if (hpRemaining < 0) { hpRemaining /= logic.DsState.State.ModulateEnergy; } } else { damage *= logic.DsState.State.ModulateEnergy; hpRemaining = (((logic.DsState.State.Charge * DefenseShields.ConvToHp) - pendingDamage) - damage); if (hpRemaining < 0) { hpRemaining /= logic.DsState.State.ModulateEnergy; } } if (Session.Instance.MpActive) { var damageType = energy ? Session.Instance.MPEnergy : Session.Instance.MPKinetic; logic.AddShieldHit(attackerId, damage, damageType, null, true, pos); } else { logic.ImpactSize = damage; logic.WorldImpactPosition = pos; } if (!drawParticle) { logic.EnergyHit = DefenseShields.HitType.Other; } else if (energy) { logic.EnergyHit = DefenseShields.HitType.Energy; } else { logic.EnergyHit = DefenseShields.HitType.Kinetic; } logic.WebDamage = true; logic.Absorb += damage; return(hpRemaining); }
internal void EntIntersectSelector(KeyValuePair <MyEntity, EntIntersectInfo> pair) { var entInfo = pair.Value; var webent = pair.Key; if (entInfo == null || webent == null || webent.MarkedForClose) { return; } var relation = entInfo.Relation; var tick = Session.Instance.Tick; var tick25 = tick % 25 == 0; var entCenter = webent.PositionComp.WorldVolume.Center; if (entInfo.LastTick != tick) { return; } if (entInfo.BlockUpdateTick == tick && (relation == Ent.LargeNobodyGrid || relation == Ent.LargeEnemyGrid)) { (webent as IMyCubeGrid)?.GetBlocks(entInfo.CacheBlockList); } switch (relation) { case Ent.EnemyPlayer: { if (tick25 && CustomCollision.PointInShield(entCenter, DetectMatrixOutsideInv)) { if (Session.Enforced.Debug == 3) { Log.Line($"Ent EnemyPlayer: {webent.DebugName} - ShieldId [{Shield.EntityId}]"); } PlayerIntersect(webent); } return; } case Ent.SmallNobodyGrid: { if (Session.Enforced.Debug == 3) { Log.Line($"Ent SmallNobodyGrid: {webent.DebugName} - ShieldId [{Shield.EntityId}]"); } SmallGridIntersect(webent); return; } case Ent.LargeNobodyGrid: { if (Session.Enforced.Debug == 3) { Log.Line($"Ent LargeNobodyGrid: {webent.DebugName} - ShieldId [{Shield.EntityId}]"); } GridIntersect(webent); return; } case Ent.SmallEnemyGrid: { if (Session.Enforced.Debug == 3) { Log.Line($"Ent SmallEnemyGrid: {webent.DebugName} - ShieldId [{Shield.EntityId}]"); } SmallGridIntersect(webent); return; } case Ent.LargeEnemyGrid: { if (Session.Enforced.Debug == 3) { Log.Line($"Ent LargeEnemyGrid: {webent.DebugName} - ShieldId [{Shield.EntityId}]"); } GridIntersect(webent); return; } case Ent.Shielded: { if (Session.Enforced.Debug == 3) { Log.Line($"Ent Shielded: {webent.DebugName} - ShieldId [{Shield.EntityId}]"); } ShieldIntersect(webent); return; } case Ent.Other: { if (!_isServer) { return; } if (Session.Enforced.Debug == 3) { Log.Line($"Ent Other: {webent.DebugName} - ShieldId [{Shield.EntityId}]"); } if (webent.MarkedForClose || !webent.InScene || webent.Closed) { return; } var meteor = webent as IMyMeteor; if (meteor != null) { if (CustomCollision.PointInShield(entCenter, DetectMatrixOutsideInv)) { MeteorDmg.Enqueue(meteor); } } else { var predictedHit = CustomCollision.MissileIntersect(this, webent, DetectionMatrix, DetectMatrixOutsideInv); if (predictedHit != null) { MissileDmg.Enqueue(webent); } } return; } default: if (Session.Enforced.Debug == 3) { Log.Line($"Ent default: {webent.DebugName} - relation:{entInfo.Relation} - ShieldId [{Shield.EntityId}]"); } return; } }
public void CheckDamage(object target, ref MyDamageInformation info) { try { var damageType = info.Type; if (damageType == MpIgnoreDamage || damageType == MyDamageType.Drill || damageType == MyDamageType.Grind || ManagedAttackers.ContainsKey(info.AttackerId)) { return; } var block = target as IMySlimBlock; var character = target as IMyCharacter; if (block != null) { var myGrid = block.CubeGrid as MyCubeGrid; if (myGrid == null) { return; } MyProtectors protectors; GlobalProtect.TryGetValue(myGrid, out protectors); if (protectors == null) { return; } MyEntity hostileEnt; var attackerId = info.AttackerId; if (attackerId == _previousEntId) { hostileEnt = _previousEnt; } else { UpdatedHostileEnt(attackerId, out hostileEnt); } if (!IsServer && attackerId != 0 && hostileEnt == null) { ForceEntity(out hostileEnt); } MyEntity trueAttacker = null; var isVoxelBase = false; try { if (hostileEnt != null) { MyCubeGrid grid; if (damageType != MyDamageType.Environment) { grid = hostileEnt as MyCubeGrid; } else { grid = hostileEnt.Parent as MyCubeGrid; } if (grid == null) { var hostileCube = hostileEnt.Parent as MyCubeBlock; trueAttacker = (hostileCube ?? (hostileEnt as IMyGunBaseUser)?.Owner) ?? hostileEnt; if (trueAttacker is MyVoxelBase) { isVoxelBase = true; } } else { trueAttacker = grid; } protectors.LastAttackerWasInside = true; Vector3D originHit; block.ComputeWorldCenter(out originHit); var line = new LineD(trueAttacker.PositionComp.WorldAABB.Center, originHit); var lineLength = (float)line.Length; var testDir = Vector3D.Normalize(line.From - line.To); var ray = new RayD(line.From, -testDir); var hitDist = double.MaxValue; foreach (var shield in protectors.Shields.Keys) { shield.Asleep = false; shield.LastWokenTick = Tick; var shieldActive = shield.DsState.State.Online && !shield.DsState.State.Lowered; if (!shieldActive) { continue; } var intersectDist = CustomCollision.IntersectEllipsoid(ref shield.DetectMatrixOutsideInv, shield.DetectionMatrix, ref ray); var ellipsoid = intersectDist ?? 0; var notContained = isVoxelBase || intersectDist <= 0 && shield.GridIsMobile && !CustomCollision.PointInShield(trueAttacker.PositionComp.WorldAABB.Center, MatrixD.Invert(shield.ShieldShapeMatrix * shield.MyGrid.WorldMatrix)); if (notContained) { ellipsoid = lineLength; } var intersect = ellipsoid > 0 && lineLength + 1 >= ellipsoid; if (intersect && ellipsoid <= hitDist) { protectors.LastAttackerWasInside = false; hitDist = ellipsoid; protectors.BlockingShield = shield; protectors.BlockingTick = Tick; } } } if (Tick - protectors.BlockingTick > 10 && protectors.LastAttackerWasInside) { protectors.BlockingShield = null; } } catch (Exception ex) { Log.Line($"Exception in DamageFindShield: {ex}"); } try { var activeProtector = protectors.BlockingShield != null && protectors.BlockingShield.DsState.State.Online && !protectors.BlockingShield.DsState.State.Lowered; if (activeProtector) { var shield = protectors.BlockingShield; if (!IsServer && !shield.WarmedUp) { info.Amount = 0; return; } var isExplosionDmg = damageType == MyDamageType.Explosion; var isDeformationDmg = damageType == MyDamageType.Deformation; if (isVoxelBase) { shield.DeformEnabled = true; return; } if (damageType == Bypass) { shield.DeformEnabled = true; return; } if (!isDeformationDmg && !isExplosionDmg) { shield.DeformEnabled = false; protectors.IgnoreAttackerId = -1; } else if (shield.DeformEnabled && trueAttacker == null) { return; } else if (!shield.DeformEnabled && trueAttacker == null) { info.Amount = 0; return; } var bullet = damageType == MyDamageType.Bullet; if (bullet || isDeformationDmg) { info.Amount = info.Amount * shield.DsState.State.ModulateEnergy; } else { info.Amount = info.Amount * shield.DsState.State.ModulateKinetic; } var noHits = !DedicatedServer && shield.Absorb < 1; var hitSlotAvailable = noHits & (bullet && shield.KineticCoolDown == -1) || (!bullet && shield.EnergyCoolDown == -1); if (hitSlotAvailable) { lock (shield.HandlerImpact) { if (trueAttacker != null && block != null) { shield.HandlerImpact.Attacker = trueAttacker; shield.HandlerImpact.HitBlock = block; shield.ImpactSize = info.Amount; shield.HandlerImpact.Active = true; if (!bullet) { shield.EnergyHit = DefenseShields.HitType.Energy; } } } } if (isDeformationDmg && trueAttacker != null) { protectors.IgnoreAttackerId = attackerId; } if (!bullet) { shield.EnergyDamage += info.Amount; } else { shield.KineticDamage += info.Amount; } shield.Absorb += info.Amount; info.Amount = 0f; return; } } catch (Exception ex) { Log.Line($"Exception in DamageHandlerActive: {ex}"); } var iShield = protectors.IntegrityShield; if (iShield != null && iShield.DsState.State.Online && !iShield.DsState.State.Lowered) { var attackingVoxel = trueAttacker as MyVoxelBase; if (attackingVoxel != null || (trueAttacker is MyCubeGrid) && !(damageType == MPEnergy || damageType == MPKinetic || damageType == MPExplosion)) { iShield.DeformEnabled = true; } else if (trueAttacker != null) { iShield.DeformEnabled = false; } if (damageType == MyDamageType.Deformation && iShield.DeformEnabled) { if (attackingVoxel != null) { if (iShield.Absorb < 1 && iShield.WorldImpactPosition == Vector3D.NegativeInfinity && iShield.KineticCoolDown == -1) { attackingVoxel.RootVoxel.RequestVoxelOperationElipsoid(Vector3.One, iShield.DetectMatrixOutside, 0, MyVoxelBase.OperationType.Cut); } } var dmgAmount = info.Amount; if (IsServer) { iShield.AddShieldHit(attackerId, dmgAmount, damageType, block, false); iShield.Absorb += dmgAmount; iShield.KineticDamage += dmgAmount; } info.Amount = 0; return; } } if (info.AttackerId == protectors.IgnoreAttackerId && damageType == MyDamageType.Deformation) { if (Enforced.Debug >= 2) { Log.Line($"old Del/Mp Attacker, ignoring: {damageType} - {info.Amount} - attackerId:{attackerId}"); } info.Amount = 0; return; } protectors.IgnoreAttackerId = -1; if (Enforced.Debug >= 2) { Log.Line($"[Uncaught Damage] Type:{damageType} - Amount:{info.Amount} - nullTrue:{trueAttacker == null} - nullHostile:{hostileEnt == null} - nullShield:{protectors.BlockingShield == null} - iShell:{protectors.IntegrityShield != null} - protectorShields:{protectors.Shields.Count} - attackerId:{info.AttackerId}"); } } if (character != null && CharacterProtection(character, info.AttackerId, info.Type)) { info.Amount = 0; } } catch (Exception ex) { Log.Line($"Exception in SessionDamageHandler {_previousEnt == null}: {ex}"); } }
public Ent EntType(MyEntity ent) { if (ent is IMyFloatingObject) { if (CustomCollision.AllAabbInShield(ent.PositionComp.WorldAABB, DetectMatrixOutsideInv, _obbCorners)) { return(Ent.Ignore); } return(Ent.Floater); } var voxel = ent as MyVoxelBase; if (voxel != null && (Session.Enforced.DisableVoxelSupport == 1 || ShieldComp.Modulator == null || ShieldComp.Modulator.ModSet.Settings.ModulateVoxels || !GridIsMobile)) { return(Ent.Ignore); } if (EntityBypass.Contains(ent)) { return(Ent.Ignore); } var character = ent as IMyCharacter; if (character != null) { var dude = MyAPIGateway.Players.GetPlayerControllingEntity(ent)?.IdentityId; if (dude == null) { return(Ent.Ignore); } var playerrelationship = MyCube.GetUserRelationToOwner((long)dude); if (playerrelationship == MyRelationsBetweenPlayerAndBlock.Owner || playerrelationship == MyRelationsBetweenPlayerAndBlock.FactionShare) { var playerInShield = CustomCollision.PointInShield(ent.PositionComp.WorldAABB.Center, DetectMatrixOutsideInv); return(playerInShield ? Ent.Protected : Ent.Friendly); } if (character.IsDead) { return(Ent.Ignore); } if (CustomCollision.NewObbPointsInShield(ent, DetectMatrixOutsideInv, _obbPoints) == 9) { return(Ent.EnemyInside); } return(Ent.EnemyPlayer); } var grid = ent as MyCubeGrid; if (grid != null) { ModulateGrids = (ShieldComp.Modulator != null && ShieldComp.Modulator.ModSet.Settings.ModulateGrids) || Session.Enforced.DisableEntityBarrier == 1; ModulatorGridComponent modComp; grid.Components.TryGet(out modComp); if (!string.IsNullOrEmpty(modComp?.ModulationPassword) && modComp.ModulationPassword == Shield.CustomData) { var modShield = modComp.Modulator?.ShieldComp?.DefenseShields; if (modShield != null) { lock (modShield.SubLock) { foreach (var subGrid in modShield.ShieldComp.SubGrids) { if (ShieldEnt.PositionComp.WorldVolume.Intersects(grid.PositionComp.WorldVolume)) { if (CustomCollision.CornerOrCenterInShield(grid, DetectMatrixOutsideInv, _resetEntCorners) > 0) { return(Ent.Protected); } AuthenticatedCache.Add(subGrid); } else { AuthenticatedCache.Add(subGrid); } } } return(Ent.Authenticated); } foreach (var subGrid in modComp.SubGrids) { if (ShieldEnt.PositionComp.WorldVolume.Intersects(grid.PositionComp.WorldVolume)) { if (CustomCollision.CornerOrCenterInShield(grid, DetectMatrixOutsideInv, _resetEntCorners) > 0) { return(Ent.Protected); } AuthenticatedCache.Add(subGrid); } else { AuthenticatedCache.Add(subGrid); } } } var bigOwners = grid.BigOwners; var bigOwnersCnt = bigOwners.Count; if (CustomCollision.AllAabbInShield(ent.PositionComp.WorldAABB, DetectMatrixOutsideInv, _obbCorners)) { return(Ent.Protected); } if (!ModulateGrids && bigOwnersCnt == 0) { return(Ent.NobodyGrid); } var enemy = !ModulateGrids && GridEnemy(grid, bigOwners); if (!enemy) { lock (SubLock) if (ShieldComp.SubGrids.Contains(grid)) { return(Ent.Protected); } var pointsInShield = CustomCollision.NewObbPointsInShield(grid, DetectMatrixOutsideInv, _obbPoints); return(pointsInShield > 0 ? Ent.Protected : Ent.Friendly); } ShieldGridComponent shieldComponent; grid.Components.TryGet(out shieldComponent); if (shieldComponent?.DefenseShields?.ShieldComp != null && shieldComponent.DefenseShields.NotFailed) { var dsComp = shieldComponent.DefenseShields; var shieldEntity = MyCube.Parent; dsComp.EnemyShields.Add(shieldEntity); return(Ent.Shielded); } return(Ent.EnemyGrid); } if (ent is IMyMeteor || (ent.DefinitionId.HasValue && ent.DefinitionId.Value.TypeId == Session.Instance.MissileObj)) { return(Ent.Other); } if (voxel != null && GridIsMobile) { return(Ent.VoxelBase); } return(0); }
private void BlockIntersect(MyCubeGrid breaching, ref MyOrientedBoundingBoxD bOriBBoxD, ref EntIntersectInfo entInfo) { try { if (entInfo == null || breaching == null || breaching.MarkedForClose) { return; } //Quaternion quadMagic; //Quaternion.Divide(ref bOriBBoxD.Orientation, ref SOriBBoxD.Orientation, out quadMagic); //var sMatrix = DetectMatrixOutsideInv; if (bOriBBoxD.Intersects(ref SOriBBoxD)) //if (CustomCollision.IntersectEllipsoidObb(ref sMatrix, ref bOriBBoxD.Center, ref bOriBBoxD.HalfExtent, ref SOriBBoxD.HalfExtent, ref quadMagic)) { if (_tick - entInfo.RefreshTick == 0 || entInfo.CacheBlockList.IsEmpty) { entInfo.CacheBlockList.ClearImmediate(); RefreshBlockCache(breaching, entInfo); } var collisionAvg = Vector3D.Zero; const int blockDmgNum = 250; var rawDamage = 0f; var hits = 0; var cubeHitSet = Session.Instance.SetCubeAccelPool.Get(); var sMat = DetectMatrixOutside; for (int i = 0; i < entInfo.CacheBlockList.Count; i++) { var accel = entInfo.CacheBlockList[i]; if (_isServer && (accel.Block == null || accel.Block.CubeGrid != breaching)) { continue; } if (accel.Block == null || accel.Block.CubeGrid != breaching || accel.Block.IsDestroyed) { continue; } var block = accel.Block; var point = CustomCollision.BlockIntersect(block, accel.CubeExists, ref bOriBBoxD, ref sMat, ref DetectMatrixOutsideInv, ref _blockPoints); if (point == null) { continue; } collisionAvg += (Vector3D)point; hits++; if (!_isServer) { continue; } rawDamage += block.Integrity; if (Session.Enforced.DisableBlockDamage == 0) { cubeHitSet.Add(accel); } if (hits > blockDmgNum) { break; } } if (collisionAvg != Vector3D.Zero) { collisionAvg /= hits; ComputeCollisionPhysics(breaching, MyGrid, collisionAvg); entInfo.Touched = true; } else { return; } if (!_isServer) { return; } var damage = rawDamage * DsState.State.ModulateEnergy; var blockEvent = Session.Instance.ManyBlocksPool.Get(); blockEvent.Init(cubeHitSet, this, damage, collisionAvg, breaching.EntityId); Session.Instance.ThreadEvents.Enqueue(blockEvent); } } catch (Exception ex) { Log.Line($"Exception in BlockIntersect: {ex}"); } }
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 onCollisionEnter(CustomCollision col) { GameManager.GetInstance().AddPoints(points); Destroy(this.gameObject); }
internal void EntIntersectSelector(KeyValuePair <MyEntity, EntIntersectInfo> pair) { var entInfo = pair.Value; var webent = pair.Key; if (entInfo == null || webent == null || webent.MarkedForClose) { return; } var relation = entInfo.Relation; var tick = Session.Instance.Tick; var entCenter = webent.PositionComp.WorldVolume.Center; if (entInfo.LastTick != tick) { return; } if (entInfo.RefreshNow && (relation == Ent.NobodyGrid || relation == Ent.EnemyGrid)) { entInfo.CacheBlockList.Clear(); var grid = webent as MyCubeGrid; if (grid != null) { var checkSphere = WebSphere; checkSphere.Radius += 7.5; GetBlocksInsideSphereFast(grid, ref checkSphere, true, entInfo.CacheBlockList); } } entInfo.RefreshNow = false; switch (relation) { case Ent.EnemyPlayer: { PlayerIntersect(webent); return; } case Ent.EnemyInside: { if (!CustomCollision.PointInShield(entCenter, DetectMatrixOutsideInv)) { entInfo.RefreshNow = true; entInfo.EnemySafeInside = false; } return; } case Ent.NobodyGrid: { if (Session.Enforced.Debug == 3) { Log.Line($"Ent NobodyGrid: {webent.DebugName} - ShieldId [{Shield.EntityId}]"); } GridIntersect(webent); return; } case Ent.EnemyGrid: { if (Session.Enforced.Debug == 3) { Log.Line($"Ent LargeEnemyGrid: {webent.DebugName} - ShieldId [{Shield.EntityId}]"); } GridIntersect(webent); return; } case Ent.Shielded: { if (Session.Enforced.Debug == 3) { Log.Line($"Ent Shielded: {webent.DebugName} - ShieldId [{Shield.EntityId}]"); } ShieldIntersect(webent); return; } case Ent.Floater: { if (!_isServer || webent.MarkedForClose) { return; } if (CustomCollision.PointInShield(entCenter, DetectMatrixOutsideInv)) { Session.Instance.ThreadEvents.Enqueue(new FloaterThreadEvent(webent, this)); } return; } case Ent.Other: { if (!_isServer) { return; } if (Session.Enforced.Debug == 3) { Log.Line($"Ent Other: {webent.DebugName} - ShieldId [{Shield.EntityId}]"); } if (webent.MarkedForClose || !webent.InScene) { return; } var meteor = webent as IMyMeteor; if (meteor != null) { if (CustomCollision.PointInShield(entCenter, DetectMatrixOutsideInv)) { Session.Instance.ThreadEvents.Enqueue(new MeteorDmgThreadEvent(meteor, this)); } } else { var predictedHit = CustomCollision.FutureIntersect(this, webent, DetectionMatrix, DetectMatrixOutsideInv); if (predictedHit) { Session.Instance.ThreadEvents.Enqueue(new MissileThreadEvent(webent, this)); } } return; } default: return; } }
public void CheckDamage(object target, ref MyDamageInformation info) { try { var block = target as IMySlimBlock; if (block != null) { var damageType = info.Type; if (damageType == MpIgnoreDamage || damageType == MyDamageType.Drill || damageType == MyDamageType.Grind) { return; } var myEntity = block.CubeGrid as MyEntity; if (myEntity == null) { return; } MyProtectors protectors; GlobalProtect.TryGetValue(myEntity, out protectors); if (protectors == null) { return; } MyEntity hostileEnt; var attackerId = info.AttackerId; if (attackerId == _previousEntId) { hostileEnt = _previousEnt; } else { UpdatedHostileEnt(attackerId, out hostileEnt); } var shieldHitPos = Vector3D.NegativeInfinity; MyEntity trueAttacker = null; if (hostileEnt != null) { var blockingShield = false; var notBlockingShield = false; protectors.ProtectDamageReset(); MyCubeGrid myGrid; if (damageType != MyDamageType.Environment) { myGrid = hostileEnt as MyCubeGrid; } else { myGrid = hostileEnt.Parent as MyCubeGrid; } if (myGrid == null) { var hostileCube = hostileEnt.Parent as MyCubeBlock; trueAttacker = (hostileCube ?? (hostileEnt as IMyGunBaseUser)?.Owner) ?? hostileEnt; } else { trueAttacker = myGrid; } protectors.OriginBlock = block; protectors.OriginBlock.ComputeWorldCenter(out protectors.OriginHit); var line = new LineD(trueAttacker.PositionComp.WorldAABB.Center, protectors.OriginHit); var testDir = Vector3D.Normalize(line.From - line.To); var ray = new RayD(line.From, -testDir); var hitDist = double.MaxValue; foreach (var shield in protectors.Shields) { var shieldActive = shield.DsState.State.Online && !shield.DsState.State.Lowered; if (!shieldActive) { continue; } var intersectDist = CustomCollision.IntersectEllipsoid(shield.DetectMatrixOutsideInv, shield.DetectionMatrix, ray); var ellipsoid = intersectDist ?? 0; var intersect = ellipsoid > 0 && line.Length > ellipsoid; var noIntersect = ellipsoid <= 0 || line.Length < ellipsoid; if (intersect && ellipsoid <= hitDist) { hitDist = ellipsoid; shieldHitPos = line.From + (testDir * -ellipsoid); protectors.BlockingShield = shield; notBlockingShield = false; blockingShield = true; } else if (noIntersect && protectors.BlockingShield == null) { protectors.NotBlockingShield = shield; protectors.NotBlockingAttackerId = attackerId; protectors.NotBlockingMainDamageType = damageType; notBlockingShield = true; blockingShield = false; } } if (!blockingShield) { protectors.BlockingShield = null; } if (!notBlockingShield) { protectors.NotBlockingShield = null; } } var activeProtector = protectors.BlockingShield != null && protectors.BlockingShield.DsState.State.Online && !protectors.BlockingShield.DsState.State.Lowered && protectors.Shields.Contains(protectors.BlockingShield); if (activeProtector) { var shield = protectors.BlockingShield; if (!IsServer && !shield.WarmedUp) { info.Amount = 0; return; } var isExplosionDmg = damageType == MyDamageType.Explosion; var isDeformationDmg = damageType == MyDamageType.Deformation; if (trueAttacker is MyVoxelBase || (trueAttacker is MyCubeGrid && isDeformationDmg && shield.ModulateGrids)) { shield.DeformEnabled = true; return; } if (damageType == Bypass) { shield.DeformEnabled = true; return; } if (damageType == DSdamage || damageType == DSheal || damageType == DSbypass) { info.Amount = 0f; return; } if (!isDeformationDmg && !isExplosionDmg) { if (!IsServer) { protectors.NotBlockingShield = null; } shield.ExplosionEnabled = false; shield.DeformEnabled = false; protectors.IgnoreAttackerId = -1; } else if (!shield.DeformEnabled && trueAttacker == null) { info.Amount = 0; return; } var bullet = damageType == MyDamageType.Bullet; if (bullet || isDeformationDmg) { info.Amount = info.Amount * shield.DsState.State.ModulateEnergy; } else { info.Amount = info.Amount * shield.DsState.State.ModulateKinetic; } if (!DedicatedServer && shield.Absorb < 1 && shield.WorldImpactPosition == Vector3D.NegativeInfinity && shield.BulletCoolDown == -1) { shield.WorldImpactPosition = shieldHitPos; shield.ImpactSize = info.Amount; if (!bullet) { shield.EnergyHit = true; } } if (isDeformationDmg && trueAttacker != null) { protectors.IgnoreAttackerId = attackerId; } shield.Absorb += info.Amount; info.Amount = 0f; return; } var iShield = protectors.IntegrityShield; if (iShield != null && iShield.DsState.State.Online && !iShield.DsState.State.Lowered) { var attackingVoxel = trueAttacker as MyVoxelBase; if (attackingVoxel != null || trueAttacker is MyCubeGrid) { iShield.DeformEnabled = true; } else if (trueAttacker != null) { iShield.DeformEnabled = false; } if (damageType == MyDamageType.Deformation && iShield.DeformEnabled) { if (attackingVoxel != null) { if (iShield.Absorb < 1 && iShield.WorldImpactPosition == Vector3D.NegativeInfinity && iShield.BulletCoolDown == -1) { attackingVoxel.RootVoxel.RequestVoxelOperationElipsoid(Vector3.One, iShield.DetectMatrixOutside, 0, MyVoxelBase.OperationType.Cut); } } var dmgAmount = info.Amount * 10; if (IsServer) { iShield.AddShieldHit(attackerId, dmgAmount, damageType, block, false); iShield.Absorb += dmgAmount; } info.Amount = 0; return; } } if (info.AttackerId == protectors.IgnoreAttackerId && damageType == MyDamageType.Deformation) { if (Enforced.Debug >= 2) { Log.Line($"old Del/Mp Attacker, ignoring: {damageType} - {info.Amount} - attackerId:{attackerId}"); } info.Amount = 0; return; } protectors.IgnoreAttackerId = -1; if (Enforced.Debug >= 2) { Log.Line($"[Uncaught Damage] Type:{damageType} - Amount:{info.Amount} - nullHostileEnt:{trueAttacker == null} - nullShield:{protectors.BlockingShield == null} - iShell:{protectors.IntegrityShield != null} - protectorShields:{protectors.Shields.Count} - attackerId:{info.AttackerId}"); } } else if (target is IMyCharacter) { CharacterProtection(target, info); } } catch (Exception ex) { Log.Line($"Exception in SessionDamageHandler: {ex}"); } }
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}"); } }
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); } } } } }
internal void EntIntersectSelector(KeyValuePair <MyEntity, EntIntersectInfo> pair) { var entInfo = pair.Value; var webent = pair.Key; if (entInfo == null || webent == null || webent.MarkedForClose) { return; } var relation = entInfo.Relation; var tick = Session.Instance.Tick; var entCenter = webent.PositionComp.WorldVolume.Center; if (entInfo.LastTick != tick) { return; } entInfo.RefreshNow = false; switch (relation) { case Ent.EnemyPlayer: { PlayerIntersect(webent); return; } case Ent.EnemyInside: { if (!CustomCollision.PointInShield(entCenter, DetectMatrixOutsideInv)) { entInfo.RefreshNow = true; entInfo.EnemySafeInside = false; } return; } case Ent.NobodyGrid: { if (Session.Enforced.Debug == 3) { Log.Line($"Ent NobodyGrid: {webent.DebugName} - ShieldId [{Shield.EntityId}]"); } GridIntersect(webent); return; } case Ent.EnemyGrid: { if (Session.Enforced.Debug == 3) { Log.Line($"Ent LargeEnemyGrid: {webent.DebugName} - ShieldId [{Shield.EntityId}]"); } GridIntersect(webent); return; } case Ent.Shielded: { if (Session.Enforced.Debug == 3) { Log.Line($"Ent Shielded: {webent.DebugName} - ShieldId [{Shield.EntityId}]"); } ShieldIntersect(webent); return; } case Ent.Floater: { if (!_isServer || webent.MarkedForClose) { return; } if (CustomCollision.PointInShield(entCenter, DetectMatrixOutsideInv)) { var floater = Session.Instance.FloaterPool.Get(); floater.Init(webent, this); Session.Instance.ThreadEvents.Enqueue(floater); } return; } case Ent.Other: { if (!_isServer) { return; } if (Session.Enforced.Debug == 3) { Log.Line($"Ent Other: {webent.DebugName} - ShieldId [{Shield.EntityId}]"); } if (webent.MarkedForClose || !webent.InScene) { return; } var meteor = webent as IMyMeteor; if (meteor != null) { if (CustomCollision.PointInShield(entCenter, DetectMatrixOutsideInv)) { var meteorEvent = Session.Instance.MeteorPool.Get(); meteorEvent.Init(meteor, this); Session.Instance.ThreadEvents.Enqueue(meteorEvent); } } else { var predictedHit = CustomCollision.FutureIntersect(this, webent, DetectionMatrix, DetectMatrixOutsideInv); if (predictedHit) { var missileEvent = Session.Instance.MissilePool.Get(); missileEvent.Init(webent, this); Session.Instance.ThreadEvents.Enqueue(missileEvent); } } return; } default: return; } }
private void BlockIntersect(MyCubeGrid breaching, MyOrientedBoundingBoxD bOriBBoxD, ref EntIntersectInfo entInfo) { try { if (entInfo == null || breaching == null || breaching.MarkedForClose) { return; } if (bOriBBoxD.Intersects(ref SOriBBoxD)) { var collisionAvg = Vector3D.Zero; var damageBlocks = Session.Enforced.DisableBlockDamage == 0; var bQuaternion = Quaternion.CreateFromRotationMatrix(breaching.WorldMatrix); const int blockDmgNum = 250; var rawDamage = 0f; var blockSize = breaching.GridSize; var scaledBlockSize = blockSize * 3; var gc = breaching.WorldToGridInteger(DetectionCenter); var rc = ShieldSize.AbsMax() / blockSize; rc *= rc; rc = rc + 1; rc = Math.Ceiling(rc); var hits = 0; var blockPoints = new Vector3D[9]; var cloneCacheList = Session.Instance.ListCubeAccelPool.Get(); cloneCacheList.AddRange(entInfo.CacheBlockList); var cubeHitSet = Session.Instance.SetCubeAccelPool.Get(); for (int i = 0; i < cloneCacheList.Count; i++) { var accel = cloneCacheList[i]; var blockPos = accel.BlockPos; var num1 = gc.X - blockPos.X; var num2 = gc.Y - blockPos.Y; var num3 = gc.Z - blockPos.Z; var result = (num1 * num1) + (num2 * num2) + (num3 * num3); if (_isServer) { if (result > rc || accel.CubeExists && result > rc + scaledBlockSize) { continue; } if (accel.Block == null || accel.Block.CubeGrid != breaching) { continue; } } else { if (hits > blockDmgNum) { break; } if (result > rc || accel.CubeExists && result > rc + scaledBlockSize || accel.Block == null || accel.Block.CubeGrid != breaching || accel.Block.IsDestroyed) { continue; } } var block = accel.Block; var point = CustomCollision.BlockIntersect(block, accel.CubeExists, bQuaternion, DetectMatrixOutside, DetectMatrixOutsideInv, ref blockPoints); if (point == null) { continue; } collisionAvg += (Vector3D)point; hits++; if (!_isServer) { continue; } if (hits > blockDmgNum) { break; } rawDamage += block.Integrity; if (damageBlocks) { cubeHitSet.Add(accel); } } cloneCacheList.Clear(); Session.Instance.ListCubeAccelPool.Return(cloneCacheList); if (collisionAvg != Vector3D.Zero) { collisionAvg /= hits; ComputeCollisionPhysics(breaching, MyGrid, collisionAvg); entInfo.Touched = true; } else { return; } if (!_isServer) { return; } var damage = rawDamage * DsState.State.ModulateEnergy; var blockEvent = Session.Instance.ManyBlocksPool.Get(); blockEvent.Init(cubeHitSet, this, damage, collisionAvg, breaching.EntityId); Session.Instance.ThreadEvents.Enqueue(blockEvent); } } catch (Exception ex) { Log.Line($"Exception in BlockIntersect: {ex}"); } }
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); }
public virtual void OnCustomCollisionStay(CustomCollision collision) { }
public Ent EntType(MyEntity ent) { if (ent is IMyFloatingObject) { if (CustomCollision.AllAabbInShield(ent.PositionComp.WorldAABB, DetectMatrixOutsideInv, _obbCorners)) { return(Ent.Ignore); } return(Ent.Floater); } var voxel = ent as MyVoxelBase; if (voxel != null && (Session.Enforced.DisableVoxelSupport == 1 || ShieldComp.Modulator == null || ShieldComp.Modulator.ModSet.Settings.ModulateVoxels || !GridIsMobile)) { return(Ent.Ignore); } if (EntityBypass.Contains(ent)) { return(Ent.Ignore); } var character = ent as IMyCharacter; if (character != null) { var getComponentOwner = ent as IMyComponentOwner <MyIDModule>; long playerId; MyIDModule targetIdModule; if (getComponentOwner != null && getComponentOwner.GetComponent(out targetIdModule)) { playerId = targetIdModule.Owner; } else { var controllingId = character.ControllerInfo?.ControllingIdentityId; playerId = controllingId ?? 0; } if (playerId == 0 || character.IsDead || character.Integrity <= 0) { return(Ent.Ignore); } var playerrelationship = MyIDModule.GetRelationPlayerBlock(MyCube.IDModule.Owner, playerId, MyOwnershipShareModeEnum.Faction); var modulateAllies = (ShieldComp.Modulator != null && ShieldComp.Modulator.ModSet.Settings.AllowAllies); if (playerrelationship == MyRelationsBetweenPlayerAndBlock.Owner || playerrelationship == MyRelationsBetweenPlayerAndBlock.FactionShare || modulateAllies && playerrelationship == MyRelationsBetweenPlayerAndBlock.Friends) { var playerInShield = CustomCollision.PointInShield(ent.PositionComp.WorldAABB.Center, DetectMatrixOutsideInv); return(playerInShield ? Ent.Protected : Ent.Friendly); } if (CustomCollision.NewObbPointsInShield(ent, DetectMatrixOutsideInv, _obbPoints) == 9) { return(Ent.EnemyInside); } return(Ent.EnemyPlayer); } var grid = ent as MyCubeGrid; if (grid != null) { var modulateGrids = (ShieldComp.Modulator != null && ShieldComp.Modulator.ModSet.Settings.ModulateGrids) || Session.Enforced.DisableEntityBarrier == 1; ModulatorGridComponent modComp; grid.Components.TryGet(out modComp); if (!string.IsNullOrEmpty(modComp?.ModulationPassword) && modComp.ModulationPassword == Shield.CustomData) { var modShield = modComp.Modulator?.ShieldComp?.DefenseShields; if (modShield != null) { foreach (var subGrid in modShield.ShieldComp.SubGrids.Keys) { if (ShieldEnt.PositionComp.WorldVolume.Intersects(grid.PositionComp.WorldVolume)) { if (CustomCollision.CornerOrCenterInShield(grid, DetectMatrixOutsideInv, _resetEntCorners) > 0) { return(Ent.Protected); } AuthenticatedCache.Add(subGrid); } else { AuthenticatedCache.Add(subGrid); } } return(Ent.Authenticated); } foreach (var subGrid in modComp.SubGrids) { if (ShieldEnt.PositionComp.WorldVolume.Intersects(grid.PositionComp.WorldVolume)) { if (CustomCollision.CornerOrCenterInShield(grid, DetectMatrixOutsideInv, _resetEntCorners) > 0) { return(Ent.Protected); } AuthenticatedCache.Add((MyCubeGrid)subGrid); } else { AuthenticatedCache.Add((MyCubeGrid)subGrid); } } } List <long> bigOwners; int bigOwnersCnt; Session.ParentGrid parent; if (Session.Instance.GetParentGrid.TryGetValue(grid, out parent) && !CustomCollision.AllAabbInShield(parent.Parent.PositionComp.WorldAABB, DetectMatrixOutsideInv, _obbCorners)) { bigOwners = grid.BigOwners; bigOwnersCnt = bigOwners.Count; if (bigOwnersCnt == 0 || GridEnemy(grid, bigOwners)) { return(Ent.EnemyGrid); } } else { bigOwners = grid.BigOwners; bigOwnersCnt = bigOwners.Count; } if (CustomCollision.AllAabbInShield(ent.PositionComp.WorldAABB, DetectMatrixOutsideInv, _obbCorners)) { return(Ent.Protected); } if (!modulateGrids && bigOwnersCnt == 0) { return(Ent.NobodyGrid); } var enemy = !modulateGrids && GridEnemy(grid, bigOwners); if (!enemy) { if (ShieldComp.SubGrids.ContainsKey(grid)) { return(Ent.Protected); } var pointsInShield = CustomCollision.NewObbPointsInShield(grid, DetectMatrixOutsideInv, _obbPoints); return(pointsInShield > 0 ? Ent.Protected : Ent.Friendly); } ShieldGridComponent shieldComponent; grid.Components.TryGet(out shieldComponent); if (shieldComponent?.DefenseShields?.ShieldComp != null && shieldComponent.DefenseShields.NotFailed && shieldComponent.DefenseShields.DsState != null && !shieldComponent.DefenseShields.DsState.State.ReInforce) { var dsComp = shieldComponent.DefenseShields; var shieldEntity = MyCube.Parent; dsComp.EnemyShields.Add(shieldEntity); return(Ent.Shielded); } return(Ent.EnemyGrid); } if (ent is IMyMeteor || (ent.DefinitionId.HasValue && ent.DefinitionId.Value.TypeId == Session.Instance.MissileObj)) { return(Ent.Other); } if (voxel != null && GridIsMobile) { return(Ent.VoxelBase); } return(0); }
public virtual void OnCustomCollisionExit(CustomCollision collision) { }
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 virtual void OnCustomCollisionEnter(CustomCollision collision) { }
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); } } } } }
public void AbsorbEmp() { if (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 = HitType.Energy; WorldImpactPosition = epiCenter; Absorb += targetDamage; } }
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 static Vector3D?TAPI_LineAttackShield(IMyTerminalBlock block, LineD line, long attackerId, float damage, bool energy, bool drawParticle) { var logic = block?.GameLogic?.GetAs <DefenseShields>()?.ShieldComp?.DefenseShields; if (logic == null) { return(null); } var ray = new RayD(line.From, line.Direction); float?intersectDist; lock (logic.MatrixLock) intersectDist = CustomCollision.IntersectEllipsoid(logic.DetectMatrixOutsideInv, logic.DetectMatrixOutside, ray); if (!intersectDist.HasValue) { return(null); } var ellipsoid = intersectDist ?? 0; if (ellipsoid > line.Length) { return(null); } var hitPos = ray.Position + (ray.Direction * ellipsoid); if (energy) { damage *= logic.DsState.State.ModulateKinetic; } else { damage *= logic.DsState.State.ModulateEnergy; } if (Session.Instance.MpActive) { var damageType = energy ? Session.Instance.MPEnergy : Session.Instance.MPKinetic; logic.AddShieldHit(attackerId, damage, damageType, null, true, hitPos); } else { if (!drawParticle) { logic.EnergyHit = DefenseShields.HitType.Other; } else if (energy) { logic.EnergyHit = DefenseShields.HitType.Energy; } else { logic.EnergyHit = DefenseShields.HitType.Kinetic; } logic.ImpactSize = damage; logic.WorldImpactPosition = hitPos; } logic.WebDamage = true; logic.Absorb += damage; return(hitPos); }