Exemplo n.º 1
0
        //Finds Currently Detected Enemy Location
        #region Enemy Scan #RFC#

        /*=================================================
         * Function: RFC Function bar #RFC#
         * ---------------------------------------     */
        Vector3D EnemyScan(MISSILE This_Missile)
        {
            //Targeting Module
            //-----------------------------------------------

            //Retrieves Target Position
            var This_Missile_Director = This_Missile.TURRET as IMyLargeTurretBase;
            var ENEMY_POS             = new Vector3D();

            //LOS as first call
            if (TOWCamera != null)
            {
                Vector3D Scanpos = RC.WorldMatrix.Forward * TOW_Distance;
                if (TOWCamera.CanScan(Scanpos))
                {
                    TemporaryTarget = new MyDetectedEntityInfo();
                    var ThisEntity = TOWCamera.Raycast(Scanpos);
                    if (ThisEntity.Relationship == MyRelationsBetweenPlayerAndBlock.Enemies)
                    {
                        TemporaryTarget = ThisEntity;
                        ENEMY_POS       = (Vector3D)TemporaryTarget.HitPosition;
                    }
                }
            }


            //Turret Detection As Secondary
            else if (This_Missile_Director.GetTargetedEntity().IsEmpty() == false && !(OverrideToLongTargets && TemporaryTarget.IsEmpty()))
            {
                ENEMY_POS = This_Missile_Director.GetTargetedEntity().Position;     //Also based on position for critical hits
            }

            //Finally If nothing Detected on turrets default to LOS with some basic prediction
            else
            {
                if (!TemporaryTarget.IsEmpty())
                {
                    double   TimeSinceFired = (TemporaryTarget.TimeStamp - DateTime.Now.Millisecond) / 1000.00;
                    Vector3D Velocity       = (Vector3D)TemporaryTarget.Velocity;
                    ENEMY_POS = (Vector3D)TemporaryTarget.HitPosition + Velocity * TimeSinceFired;
                }

                //OtherWise Straigh Up TOW
                else
                {
                    ENEMY_POS = RC.GetPosition() + RC.WorldMatrix.Forward * ((This_Missile.GYRO.GetPosition() - Me.GetPosition()).Length() + 300);
                }
            }

            return(ENEMY_POS);
        }
Exemplo n.º 2
0
        //SubMethod State Machine For Launching Missiles
        #region MissileLaunchHandler
        public IEnumerable <bool> MissileLaunchHandler()
        {
            //Gathers Missile Information
            yield return(INIT_NEXT_MISSILE());

            //Disables Merge Block
            MISSILE ThisMissile = MISSILES[MISSILES.Count - 1];
            var     MERGE_A     = ThisMissile.MERGE;

            (MERGE_A as IMyShipMergeBlock).Enabled = false;
            yield return(true);

            yield return(true);            //Safety Tick

            //Launches Missile & Gathers Next Scanner
            PREP_FOR_LAUNCH(MISSILES.Count - 1);
        }
Exemplo n.º 3
0
        public void Update()
        {
            // スペースキーで一括回収
            if (Input.GetKeyDown(KeyCode.Space))
            {
                this.pool.Clear();
            }
            // アクティブなオブジェクト数の更新
            // 呼び出されたフレームで経過時間0 秒で処理されていたものを通常稼動扱いにする
            this.pool.FrameTop();
            float elapsedTime = Time.deltaTime;

            this.calcTime += elapsedTime;
            // とりあえず0.1 秒毎に発射
            float span = 0.1f;

            if (this.calcTime >= span)
            {
                // プールから取り出して点火
                Missile2D missile;
                Vector3   point = trans_.localPosition;
                if (this.pool.AwakeObject((int)this.nextType, point, out missile))
                {
                    missile.Ignition();
                }

                if (this.nextType == MISSILE.LEFT)
                {
                    this.nextType = MISSILE.UP;
                }
                else
                {
                    ++this.nextType;
                }
                this.calcTime -= span;
            }
            // アクティブなオブジェクトの更新
            this.pool.Proc(elapsedTime);
        }
Exemplo n.º 4
0
        //Preps For Launch & Launches
        #region RFC Prep-For Launch Subroutine #RFC#

        /*=================================================
         * Function: RFC Function bar #RFC#
         * ---------------------------------------     */
        void PREP_FOR_LAUNCH(int INT)
        {
            Echo(INT + "");
            MISSILE ThisMissile = MISSILES[INT];

            ThisMissile.MissileMass   = 0;
            ThisMissile.MissileThrust = 0;

            //Preps Battery For Launch
            var POWER_A = ThisMissile.POWER;

            if (ThisMissile.POWER != null && ThisMissile.POWER is IMyBatteryBlock)
            {
                POWER_A.ApplyAction("OnOff_On");
                POWER_A.SetValue("Recharge", false);
                POWER_A.SetValue("Discharge", true);
                ThisMissile.MissileMass += POWER_A.Mass;
            }


            //Removes Thrusters That Are Still on the same Grid As launcher
            List <IMyThrust> TemporaryThrust = new List <IMyThrust>();

            TemporaryThrust.AddRange(ThisMissile.THRUSTERS);
            for (int i = 0; i < TemporaryThrust.Count; i++)
            {
                var item = TemporaryThrust[i];
                if (item.CubeGrid != ThisMissile.GYRO.CubeGrid)
                {
                    ThisMissile.THRUSTERS.Remove(item); continue;
                }
            }

            //Retrieves Largest Thrust Direction
            Dictionary <Vector3D, double> ThrustDict = new Dictionary <Vector3D, double>();

            foreach (IMyThrust item in ThisMissile.THRUSTERS)
            {
                Vector3D Fwd    = item.WorldMatrix.Forward;
                double   Thrval = item.MaxEffectiveThrust;

                if (ThrustDict.ContainsKey(Fwd) == false)
                {
                    ThrustDict.Add(Fwd, Thrval);
                }
                else
                {
                    ThrustDict[Fwd] = ThrustDict[Fwd] + Thrval;
                }
            }
            List <KeyValuePair <Vector3D, double> > ThrustList = ThrustDict.ToList();

            ThrustList.Sort((x, y) => y.Value.CompareTo(x.Value));
            Vector3D ThrForward = ThrustList[0].Key;


            //Preps Thrusters For Launch (removes any not on grid)
            TemporaryThrust = new List <IMyThrust>();
            TemporaryThrust.AddRange(ThisMissile.THRUSTERS);
            for (int i = 0; i < TemporaryThrust.Count; i++)
            {
                var item = TemporaryThrust[i];

                //Retrieves Thrusters Only Going In The Forward
                if (item.WorldMatrix.Forward != ThrForward)
                {
                    item.ApplyAction("OnOff_On"); ThisMissile.THRUSTERS.Remove(item); continue;
                }

                //Runs Std Operations
                item.ApplyAction("OnOff_On");
                double ThisThrusterThrust = (item as IMyThrust).MaxThrust;
                (item as IMyThrust).ThrustOverride = (float)ThisThrusterThrust;
                ThisMissile.MissileThrust         += ThisThrusterThrust;
                ThisMissile.MissileMass           += item.Mass;
            }

            //Removes Any Warheads Not On The Grid
            List <IMyTerminalBlock> TemporaryWarheads = new List <IMyTerminalBlock>();

            TemporaryWarheads.AddRange(ThisMissile.WARHEADS);
            for (int i = 0; i < ThisMissile.WARHEADS.Count; i++)
            {
                var item = TemporaryWarheads[i];

                if (item.CubeGrid != ThisMissile.GYRO.CubeGrid)
                {
                    ThisMissile.WARHEADS.Remove(item); continue;
                }

                ThisMissile.MissileMass += item.Mass;
            }

            //-----------------------------------------------------

            //Adds Additional Mass & Sets Accel (ovverrides If Possible)
            ThisMissile.MissileMass += ThisMissile.GYRO.Mass;
            ThisMissile.MissileMass += ThisMissile.MERGE.Mass;
            double number;

            if (double.TryParse(ThisMissile.GYRO.CustomData, out number))
            {
                double.TryParse(ThisMissile.GYRO.CustomData, out ThisMissile.MissileMass);
            }
            ThisMissile.MissileAccel = ThisMissile.MissileThrust / ThisMissile.MissileMass;

            //Sets Grid Type
            ThisMissile.IsLargeGrid  = ThisMissile.GYRO.CubeGrid.GridSizeEnum == MyCubeSize.Large;
            ThisMissile.FuseDistance = ThisMissile.IsLargeGrid ? 16 : 7;
        }
Exemplo n.º 5
0
        //Finds First Missile Available
        #region RFC Initialise Missile Blocks #RFC#

        /*=================================================
         * Function: RFC Function bar #RFC#
         * ---------------------------------------     */
        bool INIT_NEXT_MISSILE()
        {
            //Finds Missile Blocks (performs 1 gts)
            List <IMyTerminalBlock> GYROS = new List <IMyTerminalBlock>();

            GridTerminalSystem.GetBlocksOfType <IMyGyro>(GYROS, b => b.CustomName == "#A#");
            List <IMyTerminalBlock> TURRETS = new List <IMyTerminalBlock>();

            GridTerminalSystem.GetBlocksOfType <IMyLargeTurretBase>(TURRETS, b => b.CustomName == "#A#");
            List <IMyThrust> THRUSTERS = new List <IMyThrust>();

            GridTerminalSystem.GetBlocksOfType <IMyThrust>(THRUSTERS, b => b.CustomName == "#A#");
            List <IMyTerminalBlock> MERGES = new List <IMyTerminalBlock>();

            GridTerminalSystem.GetBlocksOfType <IMyShipMergeBlock>(MERGES, b => b.CustomName == "#A#");
            List <IMyTerminalBlock> BATTERIES = new List <IMyTerminalBlock>();

            GridTerminalSystem.GetBlocksOfType <IMyTerminalBlock>(BATTERIES, b => b.CustomName == "#A#" && (b is IMyBatteryBlock || b is IMyReactor));
            List <IMyTerminalBlock> WARHEADS = new List <IMyTerminalBlock>();

            GridTerminalSystem.GetBlocksOfType <IMyWarhead>(WARHEADS, b => b.CustomName == "#A#");

            //Diagnostics For No Gyro
            Lstrundata = "No More Missile (Gyros) Detected";

            //Iterates Through List To Find Complete Missile Based On Gyro
            foreach (var Key_Gyro in GYROS)
            {
                MISSILE NEW_MISSILE = new MISSILE();
                NEW_MISSILE.GYRO = Key_Gyro;

                Vector3D GyroPos  = Key_Gyro.GetPosition();
                double   Distance = 40;

                //Sorts And Selects Turrets
                List <IMyTerminalBlock> TempTurrets = TURRETS.FindAll(b => (b.GetPosition() - GyroPos).LengthSquared() < Distance * Distance);
                TempTurrets.Sort((x, y) => (x.GetPosition() - Key_Gyro.GetPosition()).LengthSquared().CompareTo((y.GetPosition() - Key_Gyro.GetPosition()).LengthSquared()));

                //Sorts And Selects Batteries
                List <IMyTerminalBlock> TempPower = BATTERIES.FindAll(b => (b.GetPosition() - GyroPos).LengthSquared() < Distance * Distance);
                TempPower.Sort((x, y) => (x.GetPosition() - Key_Gyro.GetPosition()).LengthSquared().CompareTo((y.GetPosition() - Key_Gyro.GetPosition()).LengthSquared()));

                //Sorts And Selects Merges
                List <IMyTerminalBlock> TempMerges = MERGES.FindAll(b => (b.GetPosition() - GyroPos).LengthSquared() < Distance * Distance);
                TempMerges.Sort((x, y) => (x.GetPosition() - Key_Gyro.GetPosition()).LengthSquared().CompareTo((y.GetPosition() - Key_Gyro.GetPosition()).LengthSquared()));

                //Sorts And Selects Thrusters
                NEW_MISSILE.THRUSTERS = THRUSTERS.FindAll(b => (b.GetPosition() - GyroPos).LengthSquared() < Distance * Distance);

                //Sorts And Selects Warheads
                NEW_MISSILE.WARHEADS = WARHEADS.FindAll(b => (b.GetPosition() - GyroPos).LengthSquared() < Distance * Distance);

                //Checks All Key Blocks Are Present
                bool HasTurret   = TempTurrets.Count > 0;
                bool HasPower    = TempPower.Count > 0;
                bool HasMerge    = TempMerges.Count > 0;
                bool HasThruster = NEW_MISSILE.THRUSTERS.Count > 0;

                //Echos Some Useful Diagnostics
                Lstrundata = "Last Missile Failed To Fire\nReason:" +
                             "\nHas Gyro: True" +
                             "\nHas Turret: " + HasTurret +
                             "\nHas Power: " + HasPower +
                             "\nHasMerge: " + HasMerge +
                             "\nHasThruster: " + HasThruster;

                //Assigns and Exits Loop
                if (HasTurret && HasPower && HasMerge && HasThruster)
                {
                    NEW_MISSILE.TURRET = TempTurrets[0];
                    NEW_MISSILE.POWER  = TempPower[0];
                    NEW_MISSILE.MERGE  = TempMerges[0];
                    MISSILES.Add(NEW_MISSILE);
                    Lstrundata = "Launched Missile:" + MISSILES.Count;
                    return(true);
                }
            }
            return(false);
        }
Exemplo n.º 6
0
        //Standard Guidance Routine
        #region RdavNav Missile Guidance #RFC#

        /*=================================================
         * RdavNav
         * ---------------------------------------     */
        void STD_GUIDANCE(MISSILE This_Missile)
        {
            //Targeting Module
            //-----------------------------------------------

            //Retrieves Target Position
            var This_Missile_Director = This_Missile.TURRET as IMyLargeTurretBase;
            var ENEMY_POS             = new Vector3D();

            //Logical Determination Of Enemy Position
            if (This_Missile_Director.GetTargetedEntity().IsEmpty() == false)
            {
                ENEMY_POS = This_Missile_Director.GetTargetedEntity().Position;                 //Also based on position for critical hits
            }
            //else if (!(This_Missile.TARGET_PREV_POS == null)) //new Vector3D()
            //{ENEMY_POS = This_Missile.TARGET_PREV_POS;}
            else
            {
                ENEMY_POS = RC.GetPosition() + RC.WorldMatrix.Forward * ((This_Missile.GYRO.GetPosition() - Me.GetPosition()).Length() + 300);
            }

            //Sorts CurrentVelocities
            Vector3D MissilePosition     = This_Missile.GYRO.CubeGrid.WorldVolume.Center;
            Vector3D MissilePositionPrev = This_Missile.MIS_PREV_POS;
            Vector3D MissileVelocity     = (MissilePosition - MissilePositionPrev) / Global_Timestep;

            Vector3D TargetPosition     = ENEMY_POS;
            Vector3D TargetPositionPrev = This_Missile.TARGET_PREV_POS;
            Vector3D TargetVelocity     = (TargetPosition - This_Missile.TARGET_PREV_POS) / Global_Timestep;

            //Uses RdavNav Navigation APN Guidance System
            //-----------------------------------------------

            //Setup LOS rates and PN system
            Vector3D LOS_Old = Vector3D.Normalize(TargetPositionPrev - MissilePositionPrev);
            Vector3D LOS_New = Vector3D.Normalize(TargetPosition - MissilePosition);
            Vector3D Rel_Vel = Vector3D.Normalize(TargetVelocity - MissileVelocity);

            //And Assigners
            Vector3D am = new Vector3D(1, 0, 0); double LOS_Rate; Vector3D LOS_Delta;
            Vector3D MissileForwards = This_Missile.THRUSTERS[0].WorldMatrix.Backward;

            //Vector/Rotation Rates
            if (LOS_Old.Length() == 0)
            {
                LOS_Delta = new Vector3D(0, 0, 0); LOS_Rate = 0.0;
            }
            else
            {
                LOS_Delta = LOS_New - LOS_Old; LOS_Rate = LOS_Delta.Length() / Global_Timestep;
            }

            //-----------------------------------------------

            //Closing Velocity
            double Vclosing          = (TargetVelocity - MissileVelocity).Length();

            //If Under Gravity Use Gravitational Accel
            Vector3D GravityComp = -RC.GetNaturalGravity();

            //Calculate the final lateral acceleration
            Vector3D LateralDirection             = Vector3D.Normalize(Vector3D.Cross(Vector3D.Cross(Rel_Vel, LOS_New), Rel_Vel));
            Vector3D LateralAccelerationComponent = LateralDirection * PNGain * LOS_Rate * Vclosing + LOS_Delta * 9.8 * (0.5 * PNGain);             //Eases Onto Target Collision LOS_Delta * 9.8 * (0.5 * Gain)

            //If Impossible Solution (ie maxes turn rate) Use Drift Cancelling For Minimum T
            double OversteerReqt = (LateralAccelerationComponent).Length() / This_Missile.MissileAccel;

            if (OversteerReqt > 0.98)
            {
                LateralAccelerationComponent = This_Missile.MissileAccel * Vector3D.Normalize(LateralAccelerationComponent + (OversteerReqt * Vector3D.Normalize(-MissileVelocity)) * 40);
            }

            //Calculates And Applies Thrust In Correct Direction (Performs own inequality check)
            double ThrustPower = RdavUtils.Vector_Projection_Scalar(MissileForwards, Vector3D.Normalize(LateralAccelerationComponent));             //TESTTESTTEST

            ThrustPower = This_Missile.IsLargeGrid ? MathHelper.Clamp(ThrustPower, 0.9, 1) : ThrustPower;
            //MathHelper.Clamp(ThrustPower, 0.6, 1); //for improved thrust performance
            foreach (IMyThrust thruster in This_Missile.THRUSTERS)
            {
                if (thruster.ThrustOverride != (thruster.MaxThrust * ThrustPower))                 //12 increment inequality to help conserve on performance
                {
                    thruster.ThrustOverride = (float)(thruster.MaxThrust * ThrustPower);
                }
            }

            //Calculates Remaining Force Component And Adds Along LOS
            double RejectedAccel = Math.Sqrt(This_Missile.MissileAccel * This_Missile.MissileAccel - LateralAccelerationComponent.LengthSquared());             //Accel has to be determined whichever way you slice it

            if (double.IsNaN(RejectedAccel))
            {
                RejectedAccel = 0;
            }
            LateralAccelerationComponent = LateralAccelerationComponent + LOS_New * RejectedAccel;

            //-----------------------------------------------

            //Guides To Target Using Gyros
            am = Vector3D.Normalize(LateralAccelerationComponent + GravityComp);
            double Yaw; double Pitch;

            GyroTurn6(am, 18, 0.3, This_Missile.THRUSTERS[0], This_Missile.GYRO as IMyGyro, This_Missile.PREV_Yaw, This_Missile.PREV_Pitch, out Pitch, out Yaw);

            //Updates For Next Tick Round
            This_Missile.TARGET_PREV_POS = TargetPosition;
            This_Missile.MIS_PREV_POS    = MissilePosition;
            This_Missile.PREV_Yaw        = Yaw;
            This_Missile.PREV_Pitch      = Pitch;

            //Detonates warheads in close proximity
            if ((TargetPosition - MissilePosition).LengthSquared() < 20 * 20 && This_Missile.WARHEADS.Count > 0)             //Arms
            {
                foreach (var item in This_Missile.WARHEADS)
                {
                    (item as IMyWarhead).IsArmed = true;
                }
            }
            if ((TargetPosition - MissilePosition).LengthSquared() < This_Missile.FuseDistance * This_Missile.FuseDistance && This_Missile.WARHEADS.Count > 0)             //A mighty earth shattering kaboom
            {
                (This_Missile.WARHEADS[0] as IMyWarhead).Detonate();
            }
        }