private bool FieldShapeBlocked()
        {
            ModulatorGridComponent modComp;

            MyGrid.Components.TryGet(out modComp);
            if (ShieldComp.Modulator == null || ShieldComp.Modulator.ModSet.Settings.ModulateVoxels || Session.Enforced.DisableVoxelSupport == 1)
            {
                return(false);
            }

            var pruneSphere = new BoundingSphereD(DetectionCenter, BoundingRange);
            var pruneList   = new List <MyVoxelBase>();

            MyGamePruningStructure.GetAllVoxelMapsInSphere(ref pruneSphere, pruneList);

            if (pruneList.Count == 0)
            {
                return(false);
            }
            MobileUpdate();
            Icosphere.ReturnPhysicsVerts(DetectMatrixOutside, ShieldComp.PhysicsOutsideLow);
            foreach (var voxel in pruneList)
            {
                if (voxel.RootVoxel == null || voxel != voxel.RootVoxel)
                {
                    continue;
                }
                if (!CustomCollision.VoxelContact(ShieldComp.PhysicsOutsideLow, voxel))
                {
                    continue;
                }

                Shield.Enabled             = false;
                DsState.State.FieldBlocked = true;
                DsState.State.Message      = true;
                if (Session.Enforced.Debug == 3)
                {
                    Log.Line($"Field blocked: - ShieldId [{Shield.EntityId}]");
                }
                return(true);
            }
            DsState.State.FieldBlocked = false;
            return(false);
        }
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 Draw(int onCount, bool sphereOnCamera)
        {
            _onCount = onCount;

            var renderId    = MyGrid.Render.GetRenderObjectID();
            var percent     = DsState.State.ShieldPercent;
            var reInforce   = DsState.State.ReInforce;
            var hitAnim     = !reInforce && DsSet.Settings.HitWaveAnimation;
            var refreshAnim = !reInforce && DsSet.Settings.RefreshAnimation;

            Vector3D impactPos;

            lock (HandlerImpact) impactPos = HandlerImpact.Active ? ComputeHandlerImpact() : WorldImpactPosition;
            var intersected = WorldImpactPosition != Vector3D.NegativeInfinity && impactPos != Vector3D.Zero;

            WorldImpactPosition = impactPos;
            var activeVisible = DetermineVisualState(reInforce);

            WorldImpactPosition = Vector3D.NegativeInfinity;

            var kineticHit = EnergyHit == HitType.Kinetic;

            _localImpactPosition = Vector3D.NegativeInfinity;

            if (impactPos != Vector3D.NegativeInfinity && (kineticHit && KineticCoolDown < 0 || EnergyHit == HitType.Energy && EnergyCoolDown < 0))
            {
                if (_isServer && WebDamage && GridIsMobile)
                {
                    Vector3 pointVel;
                    var     gridCenter = MyGrid.PositionComp.WorldAABB.Center;
                    MyGrid.Physics.GetVelocityAtPointLocal(ref gridCenter, out pointVel);
                    impactPos += (Vector3D)pointVel * Session.TwoStep;
                }

                if (kineticHit)
                {
                    KineticCoolDown = 0;
                }
                else if (EnergyHit == HitType.Energy)
                {
                    EnergyCoolDown = 0;
                }

                if (EnergyHit != HitType.Other)
                {
                    HitParticleStart(impactPos, intersected);
                }

                var cubeBlockLocalMatrix   = MyGrid.PositionComp.LocalMatrix;
                var referenceWorldPosition = cubeBlockLocalMatrix.Translation;
                var worldDirection         = impactPos - referenceWorldPosition;
                var localPosition          = Vector3D.TransformNormal(worldDirection, MatrixD.Transpose(cubeBlockLocalMatrix));
                _localImpactPosition = localPosition;
            }

            EnergyHit = HitType.Kinetic;

            if (DsState.State.Online)
            {
                var prevlod = _prevLod;
                var lod     = CalculateLod(_onCount);
                if (_shapeChanged || _updateRender || lod != prevlod)
                {
                    _updateRender = false;
                    _shapeChanged = false;

                    Icosphere.CalculateTransform(ShieldShapeMatrix, lod);
                    if (!GridIsMobile)
                    {
                        Icosphere.ReturnPhysicsVerts(DetectionMatrix, ShieldComp.PhysicsOutside);
                    }
                }
                Icosphere.ComputeEffects(ShieldShapeMatrix, _localImpactPosition, _shellPassive, _shellActive, prevlod, percent, activeVisible, refreshAnim);
            }
            else if (_shapeChanged)
            {
                _updateRender = true;
            }

            if (hitAnim && sphereOnCamera && DsState.State.Online)
            {
                Icosphere.Draw(renderId);
            }
        }
Beispiel #4
0
        public void Draw(int onCount, bool sphereOnCamera)
        {
            _onCount = onCount;

            var renderId    = MyGrid.Render.GetRenderObjectID();
            var percent     = DsState.State.ShieldPercent;
            var reInforce   = DsState.State.ReInforce;
            var hitAnim     = !reInforce && DsSet.Settings.HitWaveAnimation;
            var refreshAnim = !reInforce && DsSet.Settings.RefreshAnimation;

            var activeVisible = DetermineVisualState(reInforce);

            var impactPos = WorldImpactPosition;
            var webEffect = WebDamage && BulletCoolDown > -1 && WebCoolDown < 0;

            _localImpactPosition = Vector3D.NegativeInfinity;
            if (impactPos != Vector3D.NegativeInfinity && (BulletCoolDown < 0 || webEffect))
            {
                if (webEffect)
                {
                    WebCoolDown = 0;
                    HitParticleStart();
                }
                else
                {
                    if (WebDamage)
                    {
                        WebCoolDown = 0;
                    }
                    BulletCoolDown = 0;
                    HitParticleStart();
                    var cubeBlockLocalMatrix   = MyGrid.PositionComp.LocalMatrix;
                    var referenceWorldPosition = cubeBlockLocalMatrix.Translation;
                    var worldDirection         = impactPos - referenceWorldPosition;
                    var localPosition          = Vector3D.TransformNormal(worldDirection, MatrixD.Transpose(cubeBlockLocalMatrix));
                    _localImpactPosition = localPosition;
                }
            }

            WorldImpactPosition = Vector3D.NegativeInfinity;
            WebDamage           = false;

            if (IsWorking)
            {
                var prevlod = _prevLod;
                var lod     = CalculateLod(_onCount);
                if (_shapeChanged || _updateRender || lod != prevlod)
                {
                    Icosphere.CalculateTransform(ShieldShapeMatrix, lod);
                    if (!GridIsMobile)
                    {
                        Icosphere.ReturnPhysicsVerts(DetectionMatrix, ShieldComp.PhysicsOutside);
                    }
                }
                Icosphere.ComputeEffects(ShieldShapeMatrix, _localImpactPosition, _shellPassive, _shellActive, prevlod, percent, activeVisible, refreshAnim);
            }
            if (hitAnim && sphereOnCamera && IsWorking)
            {
                Icosphere.Draw(renderId);
            }

            _updateRender = false;
            _shapeChanged = false;
        }
Beispiel #5
0
        public void Draw(int onCount, bool sphereOnCamera)
        {
            _onCount = onCount;

            var renderId  = MyGrid.Render.GetRenderObjectID();
            var percent   = DsState.State.ShieldPercent;
            var reInforce = DsState.State.ReInforce;
            //var hitAnim = !reInforce && DsSet.Settings.HitWaveAnimation;

            Vector3D impactPos;

            lock (HandlerImpact) impactPos = HandlerImpact.Active ? ComputeHandlerImpact() : WorldImpactPosition;
            var intersected = WorldImpactPosition != Vector3D.NegativeInfinity && impactPos != Vector3D.Zero;

            WorldImpactPosition = impactPos;
            var activeVisible = DetermineVisualState(reInforce);

            WorldImpactPosition = Vector3D.NegativeInfinity;

            var vanillaHit = EnergyHit != HitType.Other;
            var kineticHit = EnergyHit == HitType.Kinetic;

            _localImpactPosition = Vector3D.NegativeInfinity;

            if (impactPos != Vector3D.NegativeInfinity && (kineticHit && KineticCoolDown < 0 || EnergyHit == HitType.Energy && EnergyCoolDown < 0 || EnergyHit == HitType.Other))
            {
                if (_isServer && WebDamage && GridIsMobile)
                {
                    Vector3 pointVel;
                    var     gridCenter = DetectionCenter;
                    MyGrid.Physics.GetVelocityAtPointLocal(ref gridCenter, out pointVel);
                    impactPos += (Vector3D)pointVel * Session.TwoStep;
                }

                if (kineticHit)
                {
                    KineticCoolDown = 0;
                }
                else if (EnergyHit == HitType.Energy)
                {
                    EnergyCoolDown = 0;
                }

                if (EnergyHit != HitType.Other)
                {
                    HitParticleStart(impactPos, intersected);
                }

                var cubeBlockLocalMatrix   = MyGrid.PositionComp.LocalMatrixRef;
                var referenceWorldPosition = cubeBlockLocalMatrix.Translation;
                var worldDirection         = impactPos - referenceWorldPosition;
                var localPosition          = Vector3D.TransformNormal(worldDirection, MatrixD.Transpose(cubeBlockLocalMatrix));
                _localImpactPosition = localPosition;
            }

            EnergyHit = HitType.Kinetic;

            if (DsState.State.Online)
            {
                var prevlod = _prevLod;
                var lod     = CalculateLod(_onCount);
                if (_shapeChanged || _updateRender || lod != prevlod)
                {
                    _updateRender = false;
                    _shapeChanged = false;

                    Icosphere.CalculateTransform(ShieldShapeMatrix, lod);
                    if (!GridIsMobile)
                    {
                        Icosphere.ReturnPhysicsVerts(DetectionMatrix, ShieldComp.PhysicsOutside);
                    }
                }
                Icosphere.ComputeEffects(this, _localImpactPosition, prevlod, percent, activeVisible);
            }
            else if (_shapeChanged)
            {
                _updateRender = true;
            }

            var startPulse = Session.Instance.Tick20 && _toggle;
            var updated    = Session.Instance.Tick300 || startPulse;
            var wasPulsing = _sidePulsing;

            if (updated && ShellActive != null && RedirectVisualUpdate())
            {
                UpdateShieldRedirectVisuals();
            }

            if (ShellActive != null && _sidePulsing)
            {
                SidePulseRender();
            }

            if (wasPulsing && !_sidePulsing)
            {
                ClearSidePulse();
            }


            if (sphereOnCamera && DsState.State.Online && Session.Instance.Settings.ClientConfig.ShowHitRings || vanillaHit)
            {
                Icosphere.Draw(renderId, this);
            }
        }