Пример #1
0
        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}");
            }
        }
Пример #2
0
        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);
        }
Пример #3
0
        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);
        }
Пример #4
0
        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);
        }
Пример #5
0
        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;
            }
        }
Пример #6
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}"); }
        }
Пример #7
0
        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);
        }
Пример #8
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}"); }
        }
Пример #9
0
        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);
        }
Пример #10
0
 private void onCollisionEnter(CustomCollision col)
 {
     GameManager.GetInstance().AddPoints(points);
     Destroy(this.gameObject);
 }
Пример #11
0
        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;
            }
        }
Пример #12
0
        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}"); }
        }
Пример #13
0
        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}"); }
        }
Пример #14
0
        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);
                        }
                    }
                }
            }
        }
Пример #15
0
        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;
            }
        }
Пример #16
0
        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}"); }
        }
Пример #17
0
        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);
        }
Пример #18
0
 public virtual void OnCustomCollisionStay(CustomCollision collision)
 {
 }
Пример #19
0
        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);
        }
Пример #20
0
 public virtual void OnCustomCollisionExit(CustomCollision collision)
 {
 }
Пример #21
0
        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;
            }
        }
Пример #22
0
 public virtual void OnCustomCollisionEnter(CustomCollision collision)
 {
 }
Пример #23
0
        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);
                        }
                    }
                }
            }
        }
Пример #24
0
        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;
            }
        }
Пример #25
0
        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;
            }
        }
Пример #26
0
        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);
        }