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;
            }
        }
Beispiel #2
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;
            }
        }
Beispiel #3
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}"); }
        }
Beispiel #4
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);
        }
Beispiel #5
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);
        }
Beispiel #6
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;
            }
        }
        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;
            }
        }
Beispiel #8
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);
        }