Esempio n. 1
0
        internal PartAnimation(PartAnimation copyFromAnimation)
        {
            EventTrigger        = copyFromAnimation.EventTrigger;
            RotationSet         = copyFromAnimation.RotationSet;
            RotCenterSet        = copyFromAnimation.RotCenterSet;
            CurrentEmissivePart = copyFromAnimation.CurrentEmissivePart;
            AnimationId         = copyFromAnimation.AnimationId;
            ResetEmissives      = copyFromAnimation.ResetEmissives;
            EmissiveIds         = copyFromAnimation.EmissiveIds;

            //Unique Animation ID
            _uid = Guid.NewGuid();

            TypeSet          = copyFromAnimation.TypeSet;
            Muzzle           = copyFromAnimation.Muzzle;
            MoveToSetIndexer = copyFromAnimation.MoveToSetIndexer;
            NumberOfMoves    = copyFromAnimation.NumberOfMoves;
            System           = copyFromAnimation.System;
            SubpartId        = copyFromAnimation.SubpartId;
            MotionDelay      = copyFromAnimation.MotionDelay;
            DoesLoop         = copyFromAnimation.DoesLoop;
            DoesReverse      = copyFromAnimation.DoesReverse;
            TriggerOnce      = copyFromAnimation.TriggerOnce;
            _currentMove     = 0;
            MovesPivotPos    = copyFromAnimation.MovesPivotPos;
            FinalPos         = copyFromAnimation.FinalPos;
            HomePos          = copyFromAnimation.HomePos;
            HasMovement      = copyFromAnimation.HasMovement;
            EmissiveParts    = copyFromAnimation.EmissiveParts;
            EventIdLookup    = copyFromAnimation.EventIdLookup;
        }
 internal void Close()
 {
     // Reset only vars that are not always set
     Hit = new Hit();
     if (AmmoSound)
     {
         TravelEmitter.StopSound(true);
         AmmoSound = false;
     }
     HitVelocity        = Vector3D.Zero;
     TracerBack         = Vector3D.Zero;
     TracerFront        = Vector3D.Zero;
     ClosestPointOnLine = Vector3D.Zero;
     Color             = Vector4.Zero;
     OnScreen          = Screen.None;
     Tracer            = TracerState.Off;
     Trail             = TrailState.Off;
     LifeTime          = 0;
     TracerSteps       = 0;
     TracerStep        = 0;
     DistanceToLine    = 0;
     TracerWidth       = 0;
     TrailWidth        = 0;
     TrailScaler       = 0;
     MaxTrajectory     = 0;
     ShotFade          = 0;
     ParentId          = ulong.MaxValue;
     Dirty             = false;
     AmmoSound         = false;
     HitSoundActive    = false;
     StartSoundActived = false;
     IsShrapnel        = false;
     HasTravelSound    = false;
     HitParticle       = ParticleState.None;
     Triggered         = false;
     Cloaked           = false;
     Active            = false;
     TrailActivated    = false;
     ShrinkInited      = false;
     Hitting           = false;
     Back            = false;
     LastStep        = false;
     DetonateFakeExp = false;
     TracerShrinks.Clear();
     GlowSteps.Clear();
     Offsets.Clear();
     //
     FiringWeapon  = null;
     PrimeEntity   = null;
     TriggerEntity = null;
     Ai            = null;
     AmmoDef       = null;
     System        = null;
 }
Esempio n. 3
0
        private static bool AcquireBlock(WeaponSystem system, GridAi ai, Target target, TargetInfo info, Vector3D weaponPos, WeaponRandomGenerator wRng, RandomType type, ref BoundingSphereD waterSphere, Weapon w = null, bool checkPower = true)
        {
            if (system.TargetSubSystems)
            {
                var subSystems     = system.Values.Targeting.SubSystems;
                var targetLinVel   = info.Target.Physics?.LinearVelocity ?? Vector3D.Zero;
                var targetAccel    = (int)system.Values.HardPoint.AimLeadingPrediction > 1 ? info.Target.Physics?.LinearAcceleration ?? Vector3D.Zero : Vector3.Zero;
                var focusSubSystem = w != null && w.Comp.Data.Repo.Base.Set.Overrides.FocusSubSystem;

                foreach (var blockType in subSystems)
                {
                    var bt = focusSubSystem ? w.Comp.Data.Repo.Base.Set.Overrides.SubSystem : blockType;

                    ConcurrentDictionary <BlockTypes, ConcurrentCachingList <MyCubeBlock> > blockTypeMap;
                    system.Session.GridToBlockTypeMap.TryGetValue((MyCubeGrid)info.Target, out blockTypeMap);
                    if (bt != Any && blockTypeMap != null && blockTypeMap[bt].Count > 0)
                    {
                        var subSystemList = blockTypeMap[bt];
                        if (system.ClosestFirst)
                        {
                            if (target.Top5.Count > 0 && (bt != target.LastBlockType || target.Top5[0].CubeGrid != subSystemList[0].CubeGrid))
                            {
                                target.Top5.Clear();
                            }

                            target.LastBlockType = bt;
                            if (GetClosestHitableBlockOfType(subSystemList, ai, target, weaponPos, targetLinVel, targetAccel, ref waterSphere, w, checkPower))
                            {
                                return(true);
                            }
                        }
                        else if (FindRandomBlock(system, ai, target, weaponPos, info, subSystemList, w, wRng, type, ref waterSphere, checkPower))
                        {
                            return(true);
                        }
                    }

                    if (focusSubSystem)
                    {
                        break;
                    }
                }

                if (system.OnlySubSystems || focusSubSystem && w.Comp.Data.Repo.Base.Set.Overrides.SubSystem != Any)
                {
                    return(false);
                }
            }
            FatMap fatMap;

            return(system.Session.GridToFatMap.TryGetValue((MyCubeGrid)info.Target, out fatMap) && fatMap.MyCubeBocks != null && FindRandomBlock(system, ai, target, weaponPos, info, fatMap.MyCubeBocks, w, wRng, type, ref waterSphere, checkPower));
        }
Esempio n. 4
0
        private void GetPeakDps(WeaponAmmoTypes ammoDef, WeaponSystem system, WeaponDefinition wDef, out float peakDps, out float shotsPerSec, out float baseDps, out float areaDps, out float detDps)
        {
            var s           = system;
            var a           = ammoDef.AmmoDef;
            var hasShrapnel = ShrapnelId > -1;
            var l           = wDef.HardPoint.Loading;

            if (s.ReloadTime > 0 || MagazineSize > 0)
            {
                var burstPerMag = l.ShotsInBurst > 0 ? (int)Math.Floor((double)(MagazineSize / l.ShotsInBurst)) : 0;
                burstPerMag = burstPerMag >= 1 ? burstPerMag - 1 : burstPerMag;
                var drainPerMin = ((MagazineSize / (float)s.RateOfFire) / s.BarrelsPerShot) * 3600.0f;
                drainPerMin = MagazineSize >= 1 ? drainPerMin : 1;

                var timeSpentOnBurst = l.DelayAfterBurst > 0 ? burstPerMag * l.DelayAfterBurst : 0;
                var timePerMag       = drainPerMin + s.ReloadTime + timeSpentOnBurst;

                shotsPerSec = ((3600f / timePerMag) * MagazineSize) / 60 * l.TrajectilesPerBarrel;
                baseDps     = BaseDamage * shotsPerSec;
                areaDps     = !AmmoAreaEffect ? 0 : (float)((a.AreaEffect.AreaEffectDamage * (a.AreaEffect.AreaEffectRadius * 0.5f)) * shotsPerSec);
                detDps      = a.AreaEffect.Detonation.DetonateOnEnd ? (a.AreaEffect.Detonation.DetonationDamage * (a.AreaEffect.Detonation.DetonationRadius * 0.5f)) * shotsPerSec : 0;
                if (hasShrapnel)
                {
                    var sAmmo     = wDef.Ammos[ShrapnelId];
                    var fragments = a.Shrapnel.Fragments;
                    baseDps += sAmmo.BaseDamage * fragments;
                    areaDps += sAmmo.AreaEffect.AreaEffect == AreaEffectType.Disabled ? 0 : (float)((sAmmo.AreaEffect.AreaEffectDamage * (sAmmo.AreaEffect.AreaEffectRadius * 0.5f)) * fragments);
                    detDps  += sAmmo.AreaEffect.Detonation.DetonateOnEnd ? (sAmmo.AreaEffect.Detonation.DetonationDamage * (sAmmo.AreaEffect.Detonation.DetonationRadius * 0.5f)) * fragments : 0;
                }
                peakDps = (baseDps + areaDps + detDps);
            }
            else
            {
                var timeSpentOnBurst = l.DelayAfterBurst > 0 ? ((3600 / s.RateOfFire) * (l.ShotsInBurst / s.BarrelsPerShot)) + l.DelayAfterBurst : 0;

                shotsPerSec = timeSpentOnBurst > 0 ? (((3600 / timeSpentOnBurst) * l.ShotsInBurst) / 60 * l.TrajectilesPerBarrel) * s.BarrelsPerShot : (((60) / (3600 / s.RateOfFire)) * l.TrajectilesPerBarrel) * s.BarrelsPerShot;
                baseDps     = BaseDamage * shotsPerSec;
                areaDps     = !AmmoAreaEffect ? 0 : (float)((a.AreaEffect.AreaEffectDamage * (a.AreaEffect.AreaEffectRadius * 0.5f)) * shotsPerSec);
                detDps      = a.AreaEffect.Detonation.DetonateOnEnd ? (a.AreaEffect.Detonation.DetonationDamage * (a.AreaEffect.Detonation.DetonationRadius * 0.5f)) * shotsPerSec : 0;
                if (hasShrapnel)
                {
                    var sAmmo     = wDef.Ammos[ShrapnelId];
                    var fragments = a.Shrapnel.Fragments;
                    baseDps += sAmmo.BaseDamage * fragments;
                    areaDps += sAmmo.AreaEffect.AreaEffect == AreaEffectType.Disabled ? 0 : (float)((sAmmo.AreaEffect.AreaEffectDamage * (sAmmo.AreaEffect.AreaEffectRadius * 0.5f)) * fragments);
                    detDps  += sAmmo.AreaEffect.Detonation.DetonateOnEnd ? (sAmmo.AreaEffect.Detonation.DetonationDamage * (sAmmo.AreaEffect.Detonation.DetonationRadius * 0.5f)) * fragments : 0;
                }
                peakDps = (baseDps + areaDps + detDps);
            }
        }
        internal void Init(ProInfo info, double firstStepSize, double maxSpeed)
        {
            System     = info.System;
            AmmoDef    = info.AmmoDef;
            Ai         = info.Ai;
            IsShrapnel = info.IsShrapnel;
            if (ParentId != ulong.MaxValue)
            {
                Log.Line($"invalid avshot, parentId:{ParentId}");
            }
            ParentId        = info.Id;
            Model           = (info.AmmoDef.Const.PrimeModel || info.AmmoDef.Const.TriggerModel) ? Model = ModelState.Exists : Model = ModelState.None;
            PrimeEntity     = info.PrimeEntity;
            TriggerEntity   = info.TriggerEntity;
            Origin          = info.Origin;
            Offset          = AmmoDef.Const.OffsetEffect;
            MaxTracerLength = info.TracerLength;
            MuzzleId        = info.MuzzleId;
            WeaponId        = info.WeaponId;
            MaxSpeed        = maxSpeed;
            MaxStepSize     = MaxSpeed * MyEngineConstants.PHYSICS_STEP_SIZE_IN_SECONDS;
            ShootVelStep    = info.ShooterVel * MyEngineConstants.PHYSICS_STEP_SIZE_IN_SECONDS;
            info.Ai.WeaponBase.TryGetValue(info.Target.FiringCube, out FiringWeapon);
            MaxTrajectory = info.MaxTrajectory;
            ShotFade      = info.ShotFade;
            ShrinkInited  = false;
            HitEmitter.CanPlayLoopSounds = false;
            if (AmmoDef.Const.DrawLine)
            {
                Tracer = !AmmoDef.Const.IsBeamWeapon && firstStepSize < MaxTracerLength && !MyUtils.IsZero(firstStepSize - MaxTracerLength, 1E-01F) ? TracerState.Grow : TracerState.Full;
            }
            else
            {
                Tracer = TracerState.Off;
            }

            if (AmmoDef.Const.Trail)
            {
                MaxGlowLength  = MathHelperD.Clamp(AmmoDef.AmmoGraphics.Lines.Trail.DecayTime * MaxStepSize, 0.1f, MaxTrajectory);
                Trail          = AmmoDef.AmmoGraphics.Lines.Trail.Back ? TrailState.Back : Trail = TrailState.Front;
                GlowShrinkSize = !AmmoDef.AmmoGraphics.Lines.Trail.UseColorFade ? AmmoDef.Const.TrailWidth / AmmoDef.AmmoGraphics.Lines.Trail.DecayTime : 1f / AmmoDef.AmmoGraphics.Lines.Trail.DecayTime;
                Back           = Trail == TrailState.Back;
            }
            else
            {
                Trail = TrailState.Off;
            }
            TotalLength = MathHelperD.Clamp(MaxTracerLength + MaxGlowLength, 0.1f, MaxTrajectory);
        }
Esempio n. 6
0
 internal void InitVirtual(WeaponSystem system, GridAi ai, AmmoDef ammodef, MyEntity primeEntity, MyEntity triggerEntity, Target target, int weaponId, int muzzleId, Vector3D origin, Vector3D virDirection)
 {
     System            = system;
     Ai                = ai;
     AmmoDef           = ammodef;
     PrimeEntity       = primeEntity;
     TriggerEntity     = triggerEntity;
     Target.Entity     = target.Entity;
     Target.Projectile = target.Projectile;
     Target.FiringCube = target.FiringCube;
     WeaponId          = weaponId;
     MuzzleId          = muzzleId;
     Direction         = virDirection;
     Origin            = origin;
 }
Esempio n. 7
0
        internal void Clean(uint expireTick)
        {
            Target.Reset(expireTick, Target.States.ProjectileClosed);
            HitList.Clear();

            if (PrimeEntity != null)
            {
                AmmoDef.Const.PrimeEntityPool.Return(PrimeEntity);
                PrimeEntity = null;
            }

            if (TriggerEntity != null)
            {
                Ai.Session.TriggerEntityPool.Return(TriggerEntity);
                TriggerEntity = null;
            }
            AvShot                 = null;
            System                 = null;
            Ai                     = null;
            AmmoDef                = null;
            WeaponCache            = null;
            LastHitShield          = false;
            IsShrapnel             = false;
            TriggeredPulse         = false;
            EwarActive             = false;
            ModelOnly              = false;
            LockOnFireState        = false;
            IsFiringPlayer         = false;
            ClientSent             = false;
            TriggerGrowthSteps     = 0;
            WeaponId               = 0;
            MuzzleId               = 0;
            Age                    = 0;
            ProjectileDisplacement = 0;
            MaxTrajectory          = 0;
            ShotFade               = 0;
            TracerLength           = 0;
            EnableGuidance         = true;
            Direction              = Vector3D.Zero;
            VisualDir              = Vector3D.Zero;
            Origin                 = Vector3D.Zero;
            ShooterVel             = Vector3D.Zero;
            TriggerMatrix          = MatrixD.Identity;
        }
Esempio n. 8
0
 internal void InitVirtual(Weapon weapon, AmmoDef ammodef, MyEntity primeEntity, MyEntity triggerEntity, Weapon.Muzzle muzzle, double maxTrajectory, float shotFade)
 {
     IsVirtual         = true;
     System            = weapon.System;
     Ai                = weapon.Comp.Ai;
     MyPlanet          = weapon.Comp.Ai.MyPlanet;
     MyShield          = weapon.Comp.Ai.MyShield;
     InPlanetGravity   = weapon.Comp.Ai.InPlanetGravity;
     AmmoDef           = ammodef;
     PrimeEntity       = primeEntity;
     TriggerEntity     = triggerEntity;
     Target.Entity     = weapon.Target.Entity;
     Target.Projectile = weapon.Target.Projectile;
     Target.FiringCube = weapon.Target.FiringCube;
     WeaponId          = weapon.WeaponId;
     MuzzleId          = muzzle.MuzzleId;
     UniqueMuzzleId    = muzzle.UniqueId;
     Direction         = muzzle.DeviatedDir;
     Origin            = muzzle.Position;
     MaxTrajectory     = maxTrajectory;
     ShotFade          = shotFade;
 }
Esempio n. 9
0
        private void Energy(WeaponAmmoTypes ammoPair, WeaponSystem system, WeaponDefinition wDef, out bool energyAmmo, out bool mustCharge, out bool reloadable, out int energyMagSize, out bool burstMode, out bool shotReload)
        {
            energyAmmo = ammoPair.AmmoDefinitionId.SubtypeId.String == "Energy" || ammoPair.AmmoDefinitionId.SubtypeId.String == string.Empty;
            mustCharge = (energyAmmo || IsHybrid) && system.ReloadTime > 0;

            reloadable = !energyAmmo || mustCharge;

            burstMode = wDef.HardPoint.Loading.ShotsInBurst > 0 && (energyAmmo || MagazineDef.Capacity >= wDef.HardPoint.Loading.ShotsInBurst);

            shotReload = !burstMode && wDef.HardPoint.Loading.ShotsInBurst > 0 && wDef.HardPoint.Loading.DelayAfterBurst > 0;

            if (mustCharge)
            {
                var ewar           = (int)ammoPair.AmmoDef.AreaEffect.AreaEffect > 3;
                var shotEnergyCost = ewar ? ammoPair.AmmoDef.EnergyCost * AreaEffectDamage : ammoPair.AmmoDef.EnergyCost * BaseDamage;
                var requiredPower  = (((shotEnergyCost * ((system.RateOfFire / MyEngineConstants.UPDATE_STEPS_PER_SECOND) * MyEngineConstants.PHYSICS_STEP_SIZE_IN_SECONDS)) * wDef.HardPoint.Loading.BarrelsPerShot) * wDef.HardPoint.Loading.TrajectilesPerBarrel);

                energyMagSize = (int)Math.Ceiling(requiredPower * (system.ReloadTime / MyEngineConstants.UPDATE_STEPS_PER_SECOND));
                return;
            }

            energyMagSize = int.MaxValue;
        }
        internal static Vector3D?ProcessVoxel(LineD trajectile, MyVoxelBase voxel, WeaponSystem system, List <Vector3I> testPoints)
        {
            var planet       = voxel as MyPlanet;
            var voxelMap     = voxel as MyVoxelMap;
            var ray          = new RayD(trajectile.From, trajectile.Direction);
            var voxelAABB    = voxel.PositionComp.WorldAABB;
            var rayVoxelDist = ray.Intersects(voxelAABB);

            if (rayVoxelDist.HasValue)
            {
                var voxelMaxLen = voxel.PositionComp.WorldVolume.Radius * 2;
                var start       = trajectile.From + (ray.Direction * rayVoxelDist.Value);
                var lenRemain   = trajectile.Length - rayVoxelDist.Value;
                var end         = voxelMaxLen > lenRemain ? start + (ray.Direction * lenRemain) : start + (ray.Direction * voxelMaxLen);
                var testLine    = new LineD(trajectile.From + (ray.Direction * rayVoxelDist.Value), end);
                var rotMatrix   = Quaternion.CreateFromRotationMatrix(voxel.WorldMatrix);
                var obb         = new MyOrientedBoundingBoxD(voxel.PositionComp.WorldAABB.Center, voxel.PositionComp.LocalAABB.HalfExtents, rotMatrix);
                if (obb.Intersects(ref testLine) != null)
                {
                    Log.Line("obb");
                    if (planet != null)
                    {
                        var startPos = trajectile.From - planet.PositionLeftBottomCorner;
                        var startInt = Vector3I.Round(startPos);
                        var endPos   = trajectile.To - planet.PositionLeftBottomCorner;
                        var endInt   = Vector3I.Round(endPos);

                        BresenhamLineDraw(startInt, endInt, testPoints);

                        for (int i = 0; i < testPoints.Count; ++i)
                        {
                            var voxelCoord = testPoints[i];
                            var voxelHit   = new VoxelHit();
                            planet.Storage.ExecuteOperationFast(ref voxelHit, MyStorageDataTypeFlags.Content, ref voxelCoord, ref voxelCoord, notifyRangeChanged: false);
                            if (voxelHit.HasHit)
                            {
                                return((Vector3D)voxelCoord + planet.PositionLeftBottomCorner);
                            }
                        }
                    }
                    else if (voxelMap != null)
                    {
                        var startPos = trajectile.From - voxelMap.PositionLeftBottomCorner;
                        var startInt = Vector3I.Round(startPos);
                        var endPos   = trajectile.To - voxelMap.PositionLeftBottomCorner;
                        var endInt   = Vector3I.Round(endPos);

                        BresenhamLineDraw(startInt, endInt, testPoints);

                        for (int i = 0; i < testPoints.Count; ++i)
                        {
                            var voxelCoord = testPoints[i];
                            var voxelHit   = new VoxelHit();
                            voxelMap.Storage.ExecuteOperationFast(ref voxelHit, MyStorageDataTypeFlags.Content, ref voxelCoord, ref voxelCoord, notifyRangeChanged: false);
                            if (voxelHit.HasHit)
                            {
                                return((Vector3D)voxelCoord + voxelMap.PositionLeftBottomCorner);
                            }
                        }
                    }
                }
            }

            return(null);
        }
Esempio n. 11
0
        private static bool FindRandomBlock(WeaponSystem system, GridAi ai, Target target, Vector3D weaponPos, TargetInfo info, ConcurrentCachingList <MyCubeBlock> subSystemList, Weapon w, WeaponRandomGenerator wRng, RandomType type, ref BoundingSphereD waterSphere, bool checkPower = true)
        {
            var totalBlocks = subSystemList.Count;

            var topEnt = info.Target.GetTopMostParent();

            var entSphere   = topEnt.PositionComp.WorldVolume;
            var distToEnt   = MyUtils.GetSmallestDistanceToSphere(ref weaponPos, ref entSphere);
            var turretCheck = w != null;
            var topBlocks   = system.Values.Targeting.TopBlocks;
            var lastBlocks  = topBlocks > 10 && distToEnt < 1000 ? topBlocks : 10;
            var isPriroity  = false;

            if (lastBlocks < 250)
            {
                TargetInfo priorityInfo;
                MyEntity   fTarget;
                if (ai.Construct.Data.Repo.FocusData.Target[0] > 0 && MyEntities.TryGetEntityById(ai.Construct.Data.Repo.FocusData.Target[0], out fTarget) && ai.Targets.TryGetValue(fTarget, out priorityInfo) && priorityInfo.Target?.GetTopMostParent() == topEnt)
                {
                    isPriroity = true;
                    lastBlocks = totalBlocks < 250 ? totalBlocks : 250;
                }
                else if (ai.Construct.Data.Repo.FocusData.Target[1] > 0 && MyEntities.TryGetEntityById(ai.Construct.Data.Repo.FocusData.Target[1], out fTarget) && ai.Targets.TryGetValue(fTarget, out priorityInfo) && priorityInfo.Target?.GetTopMostParent() == topEnt)
                {
                    isPriroity = true;
                    lastBlocks = totalBlocks < 250 ? totalBlocks : 250;
                }
            }

            if (totalBlocks < lastBlocks)
            {
                lastBlocks = totalBlocks;
            }
            var      deck          = GetDeck(ref target.BlockDeck, ref target.BlockPrevDeckLen, 0, totalBlocks, topBlocks, wRng, type);
            var      physics       = system.Session.Physics;
            var      iGrid         = topEnt as IMyCubeGrid;
            var      gridPhysics   = iGrid?.Physics;
            Vector3D targetLinVel  = gridPhysics?.LinearVelocity ?? Vector3D.Zero;
            Vector3D targetAccel   = (int)system.Values.HardPoint.AimLeadingPrediction > 1 ? info.Target.Physics?.LinearAcceleration ?? Vector3D.Zero : Vector3.Zero;
            var      foundBlock    = false;
            var      blocksChecked = 0;
            var      blocksSighted = 0;

            for (int i = 0; i < totalBlocks; i++)
            {
                if (turretCheck && (blocksChecked > lastBlocks || isPriroity && (blocksSighted > 100 || blocksChecked > 50 && system.Session.RandomRayCasts > 500 || blocksChecked > 25 && system.Session.RandomRayCasts > 1000)))
                {
                    break;
                }

                var card  = deck[i];
                var block = subSystemList[card];

                if (!(block is IMyTerminalBlock) || block.MarkedForClose || checkPower && !block.IsWorking)
                {
                    continue;
                }

                system.Session.BlockChecks++;

                var    blockPos = block.CubeGrid.GridIntegerToWorld(block.Position);
                double rayDist;
                if (turretCheck)
                {
                    double distSqr;
                    Vector3D.DistanceSquared(ref blockPos, ref weaponPos, out distSqr);
                    if (distSqr > w.MaxTargetDistanceSqr || distSqr < w.MinTargetDistanceSqr)
                    {
                        continue;
                    }

                    blocksChecked++;
                    ai.Session.CanShoot++;
                    Vector3D predictedPos;
                    if (!Weapon.CanShootTarget(w, ref blockPos, targetLinVel, targetAccel, out predictedPos))
                    {
                        continue;
                    }

                    if (system.Session.WaterApiLoaded && waterSphere.Radius > 2 && waterSphere.Contains(predictedPos) != ContainmentType.Disjoint)
                    {
                        continue;
                    }

                    blocksSighted++;

                    system.Session.RandomRayCasts++;
                    IHitInfo hitInfo;
                    physics.CastRay(weaponPos, blockPos, out hitInfo, 15);

                    if (hitInfo?.HitEntity == null || hitInfo.HitEntity is MyVoxelBase)
                    {
                        continue;
                    }

                    var hitGrid = hitInfo.HitEntity as MyCubeGrid;
                    if (hitGrid != null)
                    {
                        if (hitGrid.MarkedForClose || hitGrid != block.CubeGrid && hitGrid.IsSameConstructAs(ai.MyGrid))
                        {
                            continue;
                        }
                        bool enemy;

                        var bigOwners = hitGrid.BigOwners;
                        if (bigOwners.Count == 0)
                        {
                            enemy = true;
                        }
                        else
                        {
                            var relationship = target.FiringCube.GetUserRelationToOwner(hitGrid.BigOwners[0]);
                            enemy = relationship != MyRelationsBetweenPlayerAndBlock.Owner &&
                                    relationship != MyRelationsBetweenPlayerAndBlock.FactionShare;
                        }

                        if (!enemy)
                        {
                            continue;
                        }
                    }

                    Vector3D.Distance(ref weaponPos, ref blockPos, out rayDist);
                    var shortDist = rayDist * (1 - hitInfo.Fraction);
                    var origDist  = rayDist * hitInfo.Fraction;
                    var topEntId  = block.GetTopMostParent().EntityId;
                    target.Set(block, hitInfo.Position, shortDist, origDist, topEntId);
                    foundBlock = true;
                    break;
                }

                Vector3D.Distance(ref weaponPos, ref blockPos, out rayDist);
                target.Set(block, block.PositionComp.WorldAABB.Center, rayDist, rayDist, block.GetTopMostParent().EntityId);
                foundBlock = true;
                break;
            }
            return(foundBlock);
        }
Esempio n. 12
0
        internal static bool GetClosestHitableBlockOfType(ConcurrentCachingList <MyCubeBlock> cubes, GridAi ai, Target target, Vector3D currentPos, Vector3D targetLinVel, Vector3D targetAccel, WeaponSystem system, Weapon w = null, bool checkPower = true)
        {
            var minValue  = double.MaxValue;
            var minValue0 = double.MaxValue;
            var minValue1 = double.MaxValue;
            var minValue2 = double.MaxValue;
            var minValue3 = double.MaxValue;

            MyCubeBlock newEntity   = null;
            MyCubeBlock newEntity0  = null;
            MyCubeBlock newEntity1  = null;
            MyCubeBlock newEntity2  = null;
            MyCubeBlock newEntity3  = null;
            var         bestCubePos = Vector3D.Zero;
            var         top5Count   = target.Top5.Count;
            var         testPos     = currentPos;
            var         top5        = target.Top5;
            IHitInfo    hitInfo     = null;
            var         notSelfHit  = false;

            for (int i = 0; i < cubes.Count + top5Count; i++)
            {
                ai.Session.BlockChecks++;
                var index = i < top5Count ? i : i - top5Count;
                var cube  = i < top5Count ? top5[index] : cubes[index];

                var grid = cube.CubeGrid;
                if (grid?.Physics == null || !grid.Physics.Enabled || grid.PositionComp == null)
                {
                    continue;
                }

                if (cube.MarkedForClose || checkPower && !cube.IsWorking || !(cube is IMyTerminalBlock) || cube == newEntity || cube == newEntity0 || cube == newEntity1 || cube == newEntity2 || cube == newEntity3)
                {
                    continue;
                }
                var cubePos = grid.GridIntegerToWorld(cube.Position);
                var range   = cubePos - testPos;
                var test    = (range.X * range.X) + (range.Y * range.Y) + (range.Z * range.Z);
                if (test < minValue3)
                {
                    IHitInfo hit      = null;
                    var      best     = test < minValue;
                    var      bestTest = false;
                    if (best)
                    {
                        if (w != null && !(!w.IsTurret && w.ActiveAmmoDef.AmmoDef.Trajectory.Smarts.OverideTarget))
                        {
                            ai.Session.CanShoot++;
                            var castRay = false;

                            Vector3D predictedPos;
                            Vector3D?hitPos;
                            if (Weapon.CanShootTarget(w, cubePos, targetLinVel, targetAccel, out predictedPos))
                            {
                                castRay = !w.HitOther || !GridIntersection.BresenhamGridIntersection(ai.MyGrid, ref testPos, ref cubePos, out hitPos, w.Comp.MyCube, w.Comp.Ai);
                            }

                            if (castRay)
                            {
                                ai.Session.ClosestRayCasts++;
                                bestTest = MyAPIGateway.Physics.CastRay(testPos, cubePos, out hit, 15, true) && hit?.HitEntity == cube.CubeGrid;

                                if (hit == null && (!w.System.Values.HardPoint.Other.MuzzleCheck || !w.MuzzleHitSelf()) || (hit.HitEntity != ai.MyGrid))
                                {
                                    notSelfHit = true;
                                }
                            }
                        }
                        else
                        {
                            bestTest = true;
                        }
                    }
                    if (best && bestTest)
                    {
                        minValue3  = minValue2;
                        newEntity3 = newEntity2;
                        minValue2  = minValue1;
                        newEntity2 = newEntity1;
                        minValue1  = minValue0;
                        newEntity1 = newEntity0;
                        minValue0  = minValue;
                        newEntity0 = newEntity;
                        minValue   = test;

                        newEntity   = cube;
                        bestCubePos = cubePos;
                        hitInfo     = hit;
                    }
                    else if (test < minValue0)
                    {
                        minValue3  = minValue2;
                        newEntity3 = newEntity2;
                        minValue2  = minValue1;
                        newEntity2 = newEntity1;
                        minValue1  = minValue0;
                        newEntity1 = newEntity0;
                        minValue0  = test;

                        newEntity0 = cube;
                    }
                    else if (test < minValue1)
                    {
                        minValue3  = minValue2;
                        newEntity3 = newEntity2;
                        minValue2  = minValue1;
                        newEntity2 = newEntity1;
                        minValue1  = test;

                        newEntity1 = cube;
                    }
                    else if (test < minValue2)
                    {
                        minValue3  = minValue2;
                        newEntity3 = newEntity2;
                        minValue2  = test;

                        newEntity2 = cube;
                    }
                    else
                    {
                        minValue3  = test;
                        newEntity3 = cube;
                    }
                }
            }
            top5.Clear();
            if (newEntity != null && hitInfo != null)
            {
                double rayDist;
                Vector3D.Distance(ref testPos, ref bestCubePos, out rayDist);
                var shortDist = rayDist * (1 - hitInfo.Fraction);
                var origDist  = rayDist * hitInfo.Fraction;
                var topEntId  = newEntity.GetTopMostParent().EntityId;
                target.Set(newEntity, hitInfo.Position, shortDist, origDist, topEntId);
                top5.Add(newEntity);
            }
            else if (newEntity != null)
            {
                double rayDist;
                Vector3D.Distance(ref testPos, ref bestCubePos, out rayDist);
                var shortDist = rayDist;
                var origDist  = rayDist;
                var topEntId  = newEntity.GetTopMostParent().EntityId;
                target.Set(newEntity, bestCubePos, shortDist, origDist, topEntId);
                top5.Add(newEntity);
            }
            else
            {
                target.Reset(ai.Session.Tick, Target.States.NoTargetsSeen, w == null);
            }

            if (newEntity0 != null)
            {
                top5.Add(newEntity0);
            }
            if (newEntity1 != null)
            {
                top5.Add(newEntity1);
            }
            if (newEntity2 != null)
            {
                top5.Add(newEntity2);
            }
            if (newEntity3 != null)
            {
                top5.Add(newEntity3);
            }

            if (!notSelfHit && w != null)
            {
                w.HitOther = true;
            }

            return(hitInfo != null);
        }
Esempio n. 13
0
        private static bool FindRandomBlock(WeaponSystem system, GridAi ai, Target target, Vector3D weaponPos, TargetInfo info, ConcurrentCachingList <MyCubeBlock> subSystemList, Weapon w, int seed, bool checkPower = true)
        {
            var totalBlocks = subSystemList.Count;

            var topEnt = info.Target.GetTopMostParent();

            var entSphere   = topEnt.PositionComp.WorldVolume;
            var distToEnt   = MyUtils.GetSmallestDistanceToSphere(ref weaponPos, ref entSphere);
            var turretCheck = w != null;
            var topBlocks   = system.Values.Targeting.TopBlocks;
            var lastBlocks  = topBlocks > 10 && distToEnt < 1000 ? topBlocks : 10;
            var isPriroity  = false;

            if (lastBlocks < 250)
            {
                TargetInfo priorityInfo;
                if (ai.Focus.Target[0] != null && ai.Targets.TryGetValue(ai.Focus.Target[0], out priorityInfo) && priorityInfo.Target?.GetTopMostParent() == topEnt)
                {
                    isPriroity = true;
                    lastBlocks = totalBlocks < 250 ? totalBlocks : 250;
                }
                else if (ai.Focus.Target[1] != null && ai.Targets.TryGetValue(ai.Focus.Target[1], out priorityInfo) && priorityInfo.Target?.GetTopMostParent() == topEnt)
                {
                    isPriroity = true;
                    lastBlocks = totalBlocks < 250 ? totalBlocks : 250;
                }
            }

            if (totalBlocks < lastBlocks)
            {
                lastBlocks = totalBlocks;
            }
            var      deck           = GetDeck(ref target.BlockDeck, ref target.BlockPrevDeckLen, 0, totalBlocks, topBlocks, seed);
            var      physics        = ai.Session.Physics;
            var      iGrid          = topEnt as IMyCubeGrid;
            var      gridPhysics    = iGrid?.Physics;
            Vector3D targetLinVel   = gridPhysics?.LinearVelocity ?? Vector3D.Zero;
            Vector3D targetAccel    = (int)system.Values.HardPoint.AimLeadingPrediction > 1 ? info.Target.Physics?.LinearAcceleration ?? Vector3D.Zero : Vector3.Zero;
            var      notSelfHit     = false;
            var      foundBlock     = false;
            var      blocksChecked  = 0;
            var      blocksSighted  = 0;
            var      weaponRangeSqr = turretCheck ? w.MaxTargetDistanceSqr : 0;

            for (int i = 0; i < totalBlocks; i++)
            {
                if (turretCheck && (blocksChecked > lastBlocks || isPriroity && (blocksSighted > 100 || blocksChecked > 50 && ai.Session.RandomRayCasts > 500 || blocksChecked > 25 && ai.Session.RandomRayCasts > 1000)))
                {
                    break;
                }

                var card  = deck[i];
                var block = subSystemList[card];

                if (!(block is IMyTerminalBlock) || block.MarkedForClose || checkPower && !block.IsWorking)
                {
                    continue;
                }

                ai.Session.BlockChecks++;

                var    blockPos = block.CubeGrid.GridIntegerToWorld(block.Position);
                double rayDist;
                if (turretCheck)
                {
                    double distSqr;
                    Vector3D.DistanceSquared(ref blockPos, ref weaponPos, out distSqr);
                    if (distSqr > weaponRangeSqr)
                    {
                        continue;
                    }

                    blocksChecked++;
                    ai.Session.CanShoot++;
                    Vector3D predictedPos;
                    if (!Weapon.CanShootTarget(w, blockPos, targetLinVel, targetAccel, out predictedPos))
                    {
                        continue;
                    }

                    blocksSighted++;
                    Vector3D?hitPos;
                    if (!w.HitOther && GridIntersection.BresenhamGridIntersection(ai.MyGrid, ref weaponPos, ref blockPos, out hitPos, w.Comp.MyCube, w.Comp.Ai))
                    {
                        continue;
                    }

                    ai.Session.RandomRayCasts++;
                    IHitInfo hitInfo;
                    physics.CastRay(weaponPos, blockPos, out hitInfo, 15, true);

                    if (hitInfo == null || hitInfo.HitEntity != ai.MyGrid && (!w.System.Values.HardPoint.Other.MuzzleCheck || !w.MuzzleHitSelf()))
                    {
                        notSelfHit = true;
                    }

                    if (hitInfo?.HitEntity == null || hitInfo.HitEntity is MyVoxelBase ||
                        hitInfo.HitEntity == ai.MyGrid)
                    {
                        continue;
                    }

                    var hitGrid = hitInfo.HitEntity as MyCubeGrid;
                    if (hitGrid != null)
                    {
                        if (hitGrid.MarkedForClose)
                        {
                            continue;
                        }
                        bool enemy;

                        var bigOwners = hitGrid.BigOwners;
                        if (bigOwners.Count == 0)
                        {
                            enemy = true;
                        }
                        else
                        {
                            var relationship = target.FiringCube.GetUserRelationToOwner(hitGrid.BigOwners[0]);
                            enemy = relationship != MyRelationsBetweenPlayerAndBlock.Owner &&
                                    relationship != MyRelationsBetweenPlayerAndBlock.FactionShare;
                        }

                        if (!enemy)
                        {
                            continue;
                        }
                    }

                    Vector3D.Distance(ref weaponPos, ref blockPos, out rayDist);
                    var shortDist = rayDist * (1 - hitInfo.Fraction);
                    var origDist  = rayDist * hitInfo.Fraction;
                    var topEntId  = block.GetTopMostParent().EntityId;
                    target.Set(block, hitInfo.Position, shortDist, origDist, topEntId);
                    foundBlock = true;
                    break;
                }

                Vector3D.Distance(ref weaponPos, ref blockPos, out rayDist);
                target.Set(block, block.PositionComp.WorldAABB.Center, rayDist, rayDist, block.GetTopMostParent().EntityId);
                foundBlock = true;
                break;
            }
            if (turretCheck && !notSelfHit)
            {
                w.HitOther = true;
            }
            return(foundBlock);
        }
Esempio n. 14
0
        public AmmoConstants(WeaponAmmoTypes ammo, WeaponDefinition wDef, Session session, WeaponSystem system)
        {
            MyInventory.GetItemVolumeAndMass(ammo.AmmoDefinitionId, out MagMass, out MagVolume);

            MagazineDef    = MyDefinitionManager.Static.GetAmmoMagazineDefinition(ammo.AmmoDefinitionId);
            TracerMaterial = MyStringId.GetOrCompute(ammo.AmmoDef.AmmoGraphics.Lines.TracerMaterial);
            TrailMaterial  = MyStringId.GetOrCompute(ammo.AmmoDef.AmmoGraphics.Lines.Trail.Material);

            if (ammo.AmmoDefinitionId.SubtypeId.String != "Energy" || ammo.AmmoDefinitionId.SubtypeId.String == string.Empty)
            {
                AmmoItem = new MyPhysicalInventoryItem()
                {
                    Amount = 1, Content = MyObjectBuilderSerializer.CreateNewObject <MyObjectBuilder_AmmoMagazine>(ammo.AmmoDefinitionId.SubtypeName)
                }
            }
            ;

            for (int i = 0; i < wDef.Ammos.Length; i++)
            {
                var ammoType = wDef.Ammos[i];
                if (ammoType.AmmoRound.Equals(ammo.AmmoDef.Shrapnel.AmmoRound))
                {
                    ShrapnelId = i;
                }
            }

            IsMine             = ammo.AmmoDef.Trajectory.Guidance == DetectFixed || ammo.AmmoDef.Trajectory.Guidance == DetectSmart || ammo.AmmoDef.Trajectory.Guidance == DetectTravelTo;
            IsField            = ammo.AmmoDef.Trajectory.FieldTime > 0;
            IsHybrid           = ammo.AmmoDef.HybridRound;
            IsTurretSelectable = !ammo.IsShrapnel || ammo.AmmoDef.HardPointUsable;


            AmmoParticle        = ammo.AmmoDef.AmmoGraphics.Particles.Ammo.Name != string.Empty;
            AmmoParticleShrinks = ammo.AmmoDef.AmmoGraphics.Particles.Ammo.ShrinkByDistance;
            HitParticleShrinks  = ammo.AmmoDef.AmmoGraphics.Particles.Hit.ShrinkByDistance;

            HitParticle = ammo.AmmoDef.AmmoGraphics.Particles.Hit.Name != string.Empty;

            DrawLine          = ammo.AmmoDef.AmmoGraphics.Lines.Tracer.Enable;
            LineColorVariance = ammo.AmmoDef.AmmoGraphics.Lines.ColorVariance.Start > 0 && ammo.AmmoDef.AmmoGraphics.Lines.ColorVariance.End > 0;
            LineWidthVariance = ammo.AmmoDef.AmmoGraphics.Lines.WidthVariance.Start > 0 || ammo.AmmoDef.AmmoGraphics.Lines.WidthVariance.End > 0;
            SpeedVariance     = ammo.AmmoDef.Trajectory.SpeedVariance.Start > 0 || ammo.AmmoDef.Trajectory.SpeedVariance.End > 0;
            RangeVariance     = ammo.AmmoDef.Trajectory.RangeVariance.Start > 0 || ammo.AmmoDef.Trajectory.RangeVariance.End > 0;
            TrailWidth        = ammo.AmmoDef.AmmoGraphics.Lines.Trail.CustomWidth > 0 ? ammo.AmmoDef.AmmoGraphics.Lines.Trail.CustomWidth : ammo.AmmoDef.AmmoGraphics.Lines.Tracer.Width;
            TargetOffSet      = ammo.AmmoDef.Trajectory.Smarts.Inaccuracy > 0;

            TargetLossTime   = ammo.AmmoDef.Trajectory.TargetLossTime > 0 ? ammo.AmmoDef.Trajectory.TargetLossTime : int.MaxValue;
            CanZombie        = TargetLossTime > 0 && TargetLossTime != int.MaxValue && !IsMine;
            MaxLifeTime      = ammo.AmmoDef.Trajectory.MaxLifeTime > 0 ? ammo.AmmoDef.Trajectory.MaxLifeTime : int.MaxValue;
            MaxChaseTime     = ammo.AmmoDef.Trajectory.Smarts.MaxChaseTime > 0 ? ammo.AmmoDef.Trajectory.Smarts.MaxChaseTime : int.MaxValue;
            MaxObjectsHit    = ammo.AmmoDef.ObjectsHit.MaxObjectsHit > 0 ? ammo.AmmoDef.ObjectsHit.MaxObjectsHit : int.MaxValue;
            BaseDamage       = ammo.AmmoDef.BaseDamage;
            MaxTargets       = ammo.AmmoDef.Trajectory.Smarts.MaxTargets;
            TargetLossDegree = ammo.AmmoDef.Trajectory.TargetLossDegree > 0 ? (float)Math.Cos(MathHelper.ToRadians(ammo.AmmoDef.Trajectory.TargetLossDegree)) : 0;

            ShieldModifier  = ammo.AmmoDef.DamageScales.Shields.Modifier > 0 ? ammo.AmmoDef.DamageScales.Shields.Modifier : 1;
            ShieldBypassMod = ammo.AmmoDef.DamageScales.Shields.BypassModifier > 0 && ammo.AmmoDef.DamageScales.Shields.BypassModifier < 1 ? ammo.AmmoDef.DamageScales.Shields.BypassModifier : 1;
            AmmoSkipAccel   = ammo.AmmoDef.Trajectory.AccelPerSec <= 0;
            FeelsGravity    = ammo.AmmoDef.Trajectory.GravityMultiplier > 0;

            MaxTrajectory    = ammo.AmmoDef.Trajectory.MaxTrajectory;
            MaxTrajectorySqr = MaxTrajectory * MaxTrajectory;
            HasBackKickForce = ammo.AmmoDef.BackKickForce > 0;

            MaxLateralThrust = MathHelperD.Clamp(ammo.AmmoDef.Trajectory.Smarts.MaxLateralThrust, 0.000001, 1);

            Fields(ammo.AmmoDef, out PulseInterval, out PulseChance, out Pulse);
            AreaEffects(ammo.AmmoDef, out AreaEffect, out AreaEffectDamage, out AreaEffectSize, out DetonationDamage, out AmmoAreaEffect, out AreaRadiusSmall, out AreaRadiusLarge, out DetonateRadiusSmall, out DetonateRadiusLarge, out Ewar, out EwarEffect, out EwarTriggerRange);

            DamageScales(ammo.AmmoDef, out DamageScaling, out FallOffScaling, out ArmorScaling, out CustomDamageScales, out CustomBlockDefinitionBasesToScales, out SelfDamage, out VoxelDamage);
            Beams(ammo.AmmoDef, out IsBeamWeapon, out VirtualBeams, out RotateRealBeam, out ConvergeBeams, out OneHitParticle, out OffsetEffect);
            CollisionShape(ammo.AmmoDef, out CollisionIsLine, out CollisionSize, out TracerLength);
            SmartsDelayDistSqr = (CollisionSize * ammo.AmmoDef.Trajectory.Smarts.TrackingDelay) * (CollisionSize * ammo.AmmoDef.Trajectory.Smarts.TrackingDelay);
            PrimeEntityPool    = Models(ammo.AmmoDef, wDef, out PrimeModel, out TriggerModel, out ModelPath);
            Energy(ammo, system, wDef, out EnergyAmmo, out MustCharge, out Reloadable, out EnergyMagSize, out BurstMode, out HasShotReloadDelay);
            Sound(ammo.AmmoDef, session, out HitSound, out AmmoTravelSound, out HitSoundDistSqr, out AmmoTravelSoundDistSqr, out AmmoSoundMaxDistSqr);
            MagazineSize = EnergyAmmo ? EnergyMagSize : MagazineDef.Capacity;
            GetPeakDps(ammo, system, wDef, out PeakDps, out ShotsPerSec, out BaseDps, out AreaDps, out DetDps);

            DesiredProjectileSpeed = (float)(!IsBeamWeapon ? ammo.AmmoDef.Trajectory.DesiredSpeed : MaxTrajectory * MyEngineConstants.UPDATE_STEPS_PER_SECOND);
            Trail = ammo.AmmoDef.AmmoGraphics.Lines.Trail.Enable;
        }
Esempio n. 15
0
        internal void Clean()
        {
            if (Monitors?.Count > 0)
            {
                for (int i = 0; i < Monitors.Count; i++)
                {
                    Monitors[i].Invoke(Target.FiringCube.EntityId, WeaponId, Id, Target.TargetId, Hit.LastHit, false);
                }

                System.Session.MonitoredProjectiles.Remove(Id);
            }
            Monitors = null;

            Target.Reset(System.Session.Tick, Target.States.ProjectileClosed);
            HitList.Clear();
            if (IsShrapnel)
            {
                if (VoxelCache != null && System.Session != null)
                {
                    System.Session.NewVoxelCache = VoxelCache;
                }
                else
                {
                    Log.Line($"IsShrapnel voxelcache return failure");
                }
            }

            if (PrimeEntity != null)
            {
                AmmoDef.Const.PrimeEntityPool.Return(PrimeEntity);
                PrimeEntity = null;
            }

            if (TriggerEntity != null)
            {
                System.Session.TriggerEntityPool.Return(TriggerEntity);
                TriggerEntity = null;
            }

            AvShot                 = null;
            System                 = null;
            Ai                     = null;
            MyPlanet               = null;
            MyShield               = null;
            AmmoDef                = null;
            WeaponCache            = null;
            VoxelCache             = null;
            IsShrapnel             = false;
            EwarAreaPulse          = false;
            EwarActive             = false;
            ModelOnly              = false;
            LockOnFireState        = false;
            IsFiringPlayer         = false;
            ClientSent             = false;
            InPlanetGravity        = false;
            TriggerGrowthSteps     = 0;
            WeaponId               = 0;
            MuzzleId               = 0;
            Age                    = 0;
            ProjectileDisplacement = 0;
            MaxTrajectory          = 0;
            ShotFade               = 0;
            TracerLength           = 0;
            FireCounter            = 0;
            AiVersion              = 0;
            UniqueMuzzleId         = 0;
            EnableGuidance         = true;
            Hit                    = new Hit();
            Direction              = Vector3D.Zero;
            VisualDir              = Vector3D.Zero;
            Origin                 = Vector3D.Zero;
            ShooterVel             = Vector3D.Zero;
            TriggerMatrix          = MatrixD.Identity;
        }
Esempio n. 16
0
        internal PartAnimation(EventTriggers eventTrigger, string animationId, Matrix[] rotationSet, Matrix[] rotCeterSet, AnimationType[] typeSet, string[] emissiveIds, int[] currentEmissivePart, int[][] moveToSetIndexer, string subpartId, MyEntity part, MyEntity mainEnt, string muzzle, uint motionDelay, WeaponSystem system, bool loop = false, bool reverse = false, bool triggerOnce = false, bool resetEmissives = false)
        {
            EventTrigger        = eventTrigger;
            RotationSet         = rotationSet;
            RotCenterSet        = rotCeterSet;
            CurrentEmissivePart = currentEmissivePart;
            AnimationId         = animationId;
            ResetEmissives      = resetEmissives;
            EmissiveIds         = emissiveIds;

            //Unique Animation ID
            _uid = Guid.NewGuid();

            TypeSet          = typeSet;
            Muzzle           = muzzle;
            MoveToSetIndexer = moveToSetIndexer;
            NumberOfMoves    = MoveToSetIndexer.Length;
            Part             = part;
            System           = system;
            SubpartId        = subpartId;
            MotionDelay      = motionDelay;
            MainEnt          = mainEnt;
            DoesLoop         = loop;
            DoesReverse      = reverse;
            TriggerOnce      = triggerOnce;
            _currentMove     = 0;

            if (part != null)
            {
                FinalPos = HomePos = part.PositionComp.LocalMatrixRef;
                var emissivePartCheck = new HashSet <string>();
                var emissiveParts     = new List <string>();
                for (int i = 0; i < NumberOfMoves; i++)
                {
                    Matrix        rotation;
                    Matrix        rotAroundCenter;
                    Vector3D      translation;
                    AnimationType animationType;
                    EmissiveState currentEmissive;
                    GetCurrentMove(out translation, out rotation, out rotAroundCenter, out animationType, out currentEmissive);

                    if (animationType == AnimationType.Movement)
                    {
                        HasMovement           = true;
                        FinalPos.Translation += translation;
                    }

                    if (rotation != Matrix.Zero)
                    {
                        HasMovement = true;
                        FinalPos   *= rotation;
                    }

                    if (rotAroundCenter != Matrix.Zero)
                    {
                        HasMovement = true;
                        FinalPos   *= rotAroundCenter;
                    }

                    if (currentEmissive.EmissiveParts != null)
                    {
                        for (int j = 0; j < currentEmissive.EmissiveParts.Length; j++)
                        {
                            var currEmissive = currentEmissive.EmissiveParts[j];

                            if (emissivePartCheck.Contains(currEmissive))
                            {
                                continue;
                            }

                            emissivePartCheck.Add(currEmissive);
                            emissiveParts.Add(currEmissive);
                        }
                    }

                    Next();
                }
                EmissiveParts = emissiveParts.ToArray();
                Reset();

                foreach (var evnt in Enum.GetNames(typeof(EventTriggers)))
                {
                    EventTriggers trigger;
                    Enum.TryParse(evnt, out trigger);
                    EventIdLookup.Add(trigger, evnt + SubpartId);
                }

                CheckAffectPivot(part, out MovesPivotPos);
            }
        }