private bool CharacterProtection(IMyCharacter character, long attackerId, MyStringHash damageType) { if (damageType == MpIgnoreDamage || damageType == MyDamageType.LowPressure) { return(false); } var myEntity = character as MyEntity; if (myEntity == null) { return(false); } MyProtectors protectors; GlobalProtect.TryGetValue(myEntity, out protectors); if (protectors == null) { return(false); } foreach (var shield in protectors.Shields.Keys) { var shieldActive = shield.DsState.State.Online && !shield.DsState.State.Lowered; if (!shieldActive) { continue; } MyEntity hostileEnt; if (attackerId == _previousEntId) { hostileEnt = _previousEnt; } else { UpdatedHostileEnt(attackerId, out hostileEnt); } var playerInside = shield.ProtectedEntCache.ContainsKey(myEntity); if (!playerInside || hostileEnt != null && shield.ProtectedEntCache.ContainsKey(hostileEnt)) { continue; } return(true); } return(false); }
private void OnEntityRemove(MyEntity myEntity) { if (Environment.CurrentManagedThreadId == 1) { MyProtectors protector; if (GlobalProtect.TryGetValue(myEntity, out protector)) { foreach (var s in protector.Shields.Keys) { ProtectCache cache; if (s.ProtectedEntCache.TryRemove(myEntity, out cache)) { ProtectCachePool.Return(cache); } } EntRefreshQueue.Enqueue(myEntity); } } }
private void LoadBalancer() { var shieldsWaking = 0; var entsUpdated = 0; var entsremoved = 0; var entsLostShield = 0; if (++RefreshCycle >= EntSlotScaler) { RefreshCycle = 0; } MyEntity ent; while (_entRefreshQueue.TryDequeue(out ent)) { MyProtectors myProtector; if (!GlobalProtect.TryGetValue(ent, out myProtector)) { continue; } var entShields = myProtector.Shields; var refreshCount = 0; DefenseShields iShield = null; var removeIShield = false; foreach (var s in entShields) { if (s.WasPaused) { continue; } lock (s.SubLock) { if (s.DsState.State.ReInforce && s.ShieldComp.SubGrids.Contains(ent)) { iShield = s; refreshCount++; } else if (!ent.InScene || !s.ResetEnts(ent, Tick)) { myProtector.Shields.Remove(s); entsLostShield++; } else { refreshCount++; } } if (iShield == null && myProtector.IntegrityShield == s) { removeIShield = true; myProtector.IntegrityShield = null; } var detectedStates = s.PlayerByShield || s.MoverByShield || Tick <= s.LastWokenTick + 580 || iShield != null || removeIShield; if (ScalerChanged || detectedStates) { s.Asleep = false; shieldsWaking++; } } if (iShield != null) { myProtector.Shields.Remove(iShield); myProtector.IntegrityShield = iShield; } myProtector.Shields.ApplyChanges(); if (refreshCount == 0) { GlobalProtect.Remove(ent); ProtSets.Return(myProtector); entsremoved++; } else { entsUpdated++; } } if (Tick1800 && Enforced.Debug >= 3) { for (int i = 0; i < SlotCnt.Length; i++) { SlotCnt[i] = 0; } foreach (var pair in GlobalProtect) { SlotCnt[pair.Value.RefreshSlot]++; } Log.Line($"[NewRefresh] SlotScaler:{EntSlotScaler} - EntsUpdated:{entsUpdated} - ShieldsWaking:{shieldsWaking} - EntsRemoved: {entsremoved} - EntsLostShield:{entsLostShield} - EntInRefreshSlots:({SlotCnt[0]} - {SlotCnt[1]} - {SlotCnt[2]} - {SlotCnt[3]} - {SlotCnt[4]} - {SlotCnt[5]} - {SlotCnt[6]} - {SlotCnt[7]} - {SlotCnt[8]}) \n" + $" ProtectedEnts:{GlobalProtect.Count} - FunctionalShields:{FunctionalShields.Count} - AllControllerBlocks:{Controllers.Count}"); } }
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}"); } }
private void CharacterProtection(object target, MyDamageInformation info) { if (info.Type == MpIgnoreDamage || info.Type == MyDamageType.LowPressure) { return; } var myEntity = target as MyEntity; if (myEntity == null) { return; } MyProtectors protectors; GlobalProtect.TryGetValue(myEntity, out protectors); if (protectors == null) { return; } foreach (var shield in protectors.Shields) { var shieldActive = shield.DsState.State.Online && !shield.DsState.State.Lowered; if (!shieldActive) { continue; } MyEntity hostileEnt; var attackerId = info.AttackerId; if (attackerId == _previousEntId) { hostileEnt = _previousEnt; } else { UpdatedHostileEnt(attackerId, out hostileEnt); } var nullAttacker = hostileEnt == null; var playerProtected = false; ProtectCache protectedEnt; if (nullAttacker) { shield.ProtectedEntCache.TryGetValue(myEntity, out protectedEnt); if (protectedEnt != null && protectedEnt.Relation == DefenseShields.Ent.Protected) { playerProtected = true; } } else { shield.ProtectedEntCache.TryGetValue(hostileEnt, out protectedEnt); if (protectedEnt != null && protectedEnt.Relation != DefenseShields.Ent.Protected) { playerProtected = true; } } if (!playerProtected) { continue; } info.Amount = 0f; myEntity.Physics.SetSpeeds(Vector3.Zero, Vector3.Zero); } }
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}"); } }