private Vector3D ComputeHandlerImpact() { WebDamage = false; HandlerImpact.Active = false; if (HandlerImpact.HitBlock == null) { return(DetectionCenter); } 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 = DetectionMatrix; var invMatrix = MatrixD.Invert(matrix); var intersectDist = CustomCollision.IntersectEllipsoid(ref invMatrix, matrix, ref ray); var ellipsoid = intersectDist ?? line.Length; var shieldHitPos = line.From + (testDir * -ellipsoid); return(shieldHitPos); }
private static Vector3D?TAPI_LineIntersectShield(IMyTerminalBlock block, LineD line) { 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); } return(ray.Position + (ray.Direction * ellipsoid)); }
// ModApi only methods below private static Vector3D?TAPI_RayAttackShield(IMyTerminalBlock block, RayD ray, long attackerId, float damage, bool energy, bool drawParticle) { var logic = block?.GameLogic?.GetAs <DefenseShields>()?.ShieldComp?.DefenseShields; if (logic == null) { return(null); } float?intersectDist; lock (logic.MatrixLock) intersectDist = CustomCollision.IntersectEllipsoid(logic.DetectMatrixOutsideInv, logic.DetectMatrixOutside, ray); if (!intersectDist.HasValue) { return(null); } var ellipsoid = intersectDist ?? 0; 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); }
private static MyTuple <float?, IMyTerminalBlock> TAPI_ClosestShieldInLine(LineD line, bool onlyIfOnline) { var segment = SegmentPool.Get(); MyGamePruningStructure.GetTopmostEntitiesOverlappingRay(ref line, segment, MyEntityQueryType.Dynamic); var ray = new RayD(line.From, line.Direction); var closest = float.MaxValue; IMyTerminalBlock closestShield = null; for (int i = 0; i < segment.Count; i++) { var ent = segment[i].Element; if (ent == null || ent.Physics != null && !ent.Physics.IsPhantom) { continue; } ShieldGridComponent c; if (Session.Instance.IdToBus.TryGetValue(ent.EntityId, out c) && c.DefenseShields != null) { if (onlyIfOnline && (!c.DefenseShields.DsState.State.Online || c.DefenseShields.DsState.State.Lowered)) { continue; } var s = c.DefenseShields; var intersectDist = CustomCollision.IntersectEllipsoid(s.DetectMatrixOutsideInv, s.DetectMatrixOutside, ray); if (!intersectDist.HasValue) { continue; } var ellipsoid = intersectDist ?? 0; if (ellipsoid > line.Length || ellipsoid > closest || CustomCollision.PointInShield(ray.Position, s.DetectMatrixOutsideInv)) { continue; } closest = ellipsoid; closestShield = s.Shield; } } segment.Clear(); SegmentPool.Return(segment); var response = new MyTuple <float?, IMyTerminalBlock>(); if (closestShield == null) { response.Item1 = null; response.Item2 = null; return(response); } response.Item1 = closest; response.Item2 = closestShield; return(response); }
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 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; } }
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}"); } }