Exemple #1
0
        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);
        }
Exemple #2
0
 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);
         }
     }
 }
Exemple #3
0
        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}");
            }
        }
Exemple #4
0
        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}"); }
        }