Beispiel #1
0
            public bool CanTarget(Vector3D target)
            {
                Vector3D
                    up   = BSDCon.WorldMatrix.Forward,
                    down = BSDCon.WorldMatrix.Backward;

                target = Vector3D.Normalize(Vector3D.Subtract(target, Vector3D.Add(BSDCon.GetPosition(), Vector3D.Multiply(down, 2))));

                if (InterCosine(up, target) >= Math.Cos(maxAngle * (Math.PI / 180.0)))
                {
                    return(true);
                }
                return(false);
            }
Beispiel #2
0
            public string DoYourJob()
            {
                string output = "";

                if (Evaluate(out output))
                {
                    DisownTheTurret();
                    return(output);
                }

                if (CTRL.IsUnderControl)
                {
                    if (this.currState != State.MANUAL)
                    {
                        ChangeState(State.MANUAL);
                    }
                    if (RLDCon.Enabled == true)
                    {
                        RLDCon.Enabled = false;
                    }

                    XROT.UpperLimitDeg = float.MaxValue;
                    XROT.LowerLimitDeg = float.MinValue;

                    XROT.TargetVelocityRPM  = 0;
                    YROT.TargetVelocityRPM  = 0;
                    YROTA.TargetVelocityRPM = 0;

                    float X = CTRL == null ? 0f : CTRL.RotationIndicator.Y;
                    float Y = CTRL == null ? 0f : CTRL.RotationIndicator.X;
                    float Z = CTRL == null ? 0f : CTRL.MoveIndicator.Z;

                    if (Z < 0)
                    {
                        Fire(true);
                    }
                    else
                    {
                        Fire(false);
                    }


                    Move(X / 20, Y / 20);
                    return(output + "Manual Control");
                }
                else
                {
                    if (currState.Equals(State.IDLE))
                    {
                        Move(0, 0);
                        return(output + "Idle");
                    }
                    else
                    if (currState.Equals(State.RELOAD))
                    {
                        Move(0, 0);
                        return(output + "Reloading...");
                    }
                    else
                    if (currState.Equals(State.MANUAL))
                    {
                        ChangeState(State.STOW);
                        return(output + "...");
                    }
                    Vector3D
                        target = currState.Equals(State.TRACK) ? targetCoords : Vector3D.Add(BSDCon.GetPosition(), Vector3D.Multiply(BSDCon.WorldMatrix.Forward, 100)),
                        me     = this.CTRL.GetPosition(),

                        sub  = CutVector(Vector3D.Normalize(Vector3D.Subtract(target, me))),
                        curr = Vector3D.Subtract(CutVector(DirintToVec(1)), sub);


                    List <NavPrompt>
                    prompts    = new List <NavPrompt>(),
                        sorted = new List <NavPrompt>();

                    for (int i = 3; i < 7; i++)
                    {
                        prompts.Add(new NavPrompt(i, Vector3D.Subtract(CutVector(DirintToVec(i)), sub)));
                    }
                    sorted = prompts.OrderBy(o => o.vLength).ToList();

                    Vector2I culprit = new Vector2I(sorted[0].dirInt, sorted[1].dirInt);

                    if (currState.Equals(State.STOW))
                    {
                        if (this.RLDCon.Enabled == false)
                        {
                            this.RLDCon.Enabled = true;
                        }
                        if ((this.RLDCon.Status == MyShipConnectorStatus.Connectable && curr.Length() < 0.02f) || this.RLDCon.Status == MyShipConnectorStatus.Connected)
                        {
                            this.RLDCon.Connect();
                            if (!hasTarget)
                            {
                                ChangeState(State.IDLE);
                            }
                            else
                            {
                                ChangeState(State.RELOAD);
                            }
                        }
                        else
                        {
                            DoubleCTM(sorted[0].dirInt, sorted[0].vLength, sorted[1].dirInt, sorted[1].vLength);
                        }
                        return(output + "Stowing");
                    }
                    else
                    if (currState.Equals(State.TRACK))
                    {
                        if (this.RLDCon.Enabled == true)
                        {
                            this.RLDCon.Enabled = false;
                        }
                        if (!this.hasTarget)
                        {
                            ChangeState(State.STOW);
                            return("Lost Target");
                        }

                        DoubleCTM(sorted[0].dirInt, sorted[0].vLength, sorted[1].dirInt, sorted[1].vLength);

                        double
                            distance   = Vector3D.Distance(target, me),
                            currlength = curr.Length();

                        if (currlength < 0.2f && distance <= 800d)
                        {
                            Fire(true);
                            return(output + ("Firing"));
                        }
                        else
                        {
                            Fire(false);
                            return(output + ("Tracking..."));
                        }
                        /**/
                    }
                    return("???");
                }
            }
        }

        public class Entry {
            public Vector3D
                position,
                velocity;

            private static Vector3D NOTHING = new Vector3D(44, 44, 44);
            private const double maxSpeed   = 400d;

            public Entry(Vector3D position, Vector3D velocity)
            {
                this.position = position;
                this.velocity = velocity;
            }

            public Entry(double px, double py, double pz, double vx, double vy, double vz) : this(new Vector3D(px, py, pz), new Vector3D(vx, vy, vz))
            {
            }

            public Vector3D EstimatePosition()
            {
                return(ApplyTarSpd(position, velocity));
            }

            double InterCosine(Vector3D first, Vector3D second)
            {
                double
                    scalarProduct    = first.X * second.X + first.Y * second.Y + first.Z * second.Z,
                    productOfLengths = first.Length() * second.Length();

                return(scalarProduct / productOfLengths);
            }

            Vector3D GetProjectedPos(Vector3D enPos, Vector3D enSpeed, Vector3D myPos)
            {
                /// do not enter if enSpeed is a "0" vector, or if our speed is 0
                Vector3D
                    A = enPos,
                    B = myPos;

                double
                    t = enSpeed.Length() / maxSpeed, //t -> b = a*t
                    projPath,                        //b
                    dist = Vector3D.Distance(A, B),  //c
                    cos  = InterCosine(enSpeed, Vector3D.Subtract(myPos, enPos)),

                    delta = 4 * dist * dist * ((1 / (t * t)) + (cos * cos) - 1);

                if (delta < 0)
                {
                    return(NOTHING);
                }
                else
                if (delta == 0)
                {
                    if (t == 0)
                    {
                        return(NOTHING);
                    }
                    projPath = -1 * (2 * dist * cos) / (2 * (((t * t) - 1) / (t * t)));
                }
                else
                {
                    if (t == 0)
                    {
                        return(NOTHING);
                    }
                    else
                    if (t == 1)
                    {
                        projPath = (dist) / (2 * cos);
                    }
                    else
                    {
                        projPath = ((2 * dist * cos - Math.Sqrt(delta)) / (2 * (((t * t) - 1) / (t * t))));
                        if (projPath < 0)
                        {
                            projPath = ((2 * dist * cos + Math.Sqrt(delta)) / (2 * (((t * t) - 1) / (t * t))));
                        }
                    }
                }
                enSpeed = Vector3D.Normalize(enSpeed);
                enSpeed = Vector3D.Multiply(enSpeed, projPath);

                return(Vector3D.Add(enPos, enSpeed));
            }

            Vector3D ApplyTarSpd(Vector3D position, Vector3D speed)
            {
                double
                    mySpeed = turret.CTRL.GetShipVelocities().LinearVelocity.Length(),
                    enSpeed = speed.Length(),
                    multiplier;

                /**/
                position = Vector3D.Add(position, Vector3D.Multiply(speed, Math.Sqrt(enSpeed) / 60));
                /**/

                if (enSpeed > 0)
                {
                    Vector3D output = GetProjectedPos(position, speed, turret.CTRL.GetPosition());
                    if (!output.Equals(NOTHING))
                    {
                        return(output);
                    }
                }

                multiplier = (mySpeed != 0 && enSpeed != 0) ? (enSpeed / mySpeed) : 0;

                Vector3D
                    addition = Vector3D.Multiply(speed, multiplier);

                return(Vector3D.Add(position, addition));
            }
        }


        public void Save()
        {
            Storage = hasTurret.ToString() + ";" + turIndx.ToString();
        }

        bool SetAEGISController()
        {
            /// this should be okay if there are no ships with Radar Control Script docked to the main ship
            AEGIS_Controller = GridTerminalSystem.GetBlockWithName(GetFullScriptName(AEGIS_CONTROLLER_SCRIPT_NAME)) as IMyProgrammableBlock;

            /// if the programmable block we picked is not from this ship, we commence the search to find it anyway
            if (AEGIS_Controller != null && !IsOnThisGrid(AEGIS_Controller))
            {
                List <IMyProgrammableBlock> temp = new List <IMyProgrammableBlock>();
                AEGIS_Controller = null;
                GridTerminalSystem.GetBlocksOfType(temp);
                foreach (IMyProgrammableBlock prog in temp)
                {
                    if (IsOnThisGrid(prog) && prog.CustomName.Equals(GetFullScriptName(AEGIS_CONTROLLER_SCRIPT_NAME)))
                    {
                        AEGIS_Controller = prog; return(true);
                    }
                }
            }
            /// and if we fail... welp, we can just inform the rest of the script that we can't do nothing
            return(AEGIS_Controller != null);
        }

        public Program()
        {
            Runtime.UpdateFrequency = UpdateFrequency.Update1;
            MyInstance = this;
            SetAEGISController();
            String[] data = Storage.Split(';');
            try { hasTurret = bool.Parse(data[0]); }    catch (Exception e) { e.ToString(); hasTurret = false; }
            try { turIndx = int.Parse(data[1]); }       catch (Exception e) { e.ToString(); turIndx = 0; }
            SetTurIndx(turIndx);
        }

        string GetFullScriptName(string ScriptName)
        {
            return("[" + ScriptName + "] Script");
        }

        void SayMyName(string ScriptName, float textSize = 2f)
        {
            Me.CustomName = GetFullScriptName(ScriptName);
            ScriptName    = "\n\n" + ScriptName;
            IMyTextSurface surface = Me.GetSurface(0);

            surface.Alignment   = TextAlignment.CENTER;
            surface.ContentType = ContentType.TEXT_AND_IMAGE;
            surface.FontSize    = textSize;
            surface.WriteText(ScriptName);
        }

        void SetTurIndx(int index)
        {
            if (index < 1)
            {
                turret    = new Turret();
                hasTurret = false;
                turIndx   = 0;
                Runtime.UpdateFrequency = UpdateFrequency.None;
                MY_PREFIX = "UNS-AEG";
            }
            else
            {
                turIndx = index;
                if (GetTheTurret())
                {
                    hasTurret = true;
                    Runtime.UpdateFrequency = UpdateFrequency.Update1;
                    MY_PREFIX = TURRET_BASE + index;
                }
                else
                {
                    turret    = new Turret();
                    hasTurret = false;
                    turIndx   = 0;
                    Runtime.UpdateFrequency = UpdateFrequency.None;
                    MY_PREFIX = "UNS-AEG";
                }
            }
            SayMyName(MY_PREFIX);
        }

        bool IsOnThisGrid(IMyCubeBlock one)
        {
            return(AreOnSameGrid(one, Me));
        }

        bool AreOnSameGrid(IMyCubeBlock one, IMyCubeBlock two)
        {
            return(one.CubeGrid.Equals(two.CubeGrid));
        }

        static void DisownTheTurret()
        {
            turret.Lockdown();
            MyInstance.hasTurret = false;
            MyInstance.turIndx   = 0;
            turret = null;
            MyInstance.MY_PREFIX = "UNS-AEG";
            MyInstance.Runtime.UpdateFrequency = UpdateFrequency.None;
            MyInstance.SayMyName(MyInstance.MY_PREFIX);
        }

        void MakeInvisible(IMyTerminalBlock block)
        {
            block.ShowInToolbarConfig = false;
            block.ShowInTerminal      = false;
            block.ShowInInventory     = false;
            block.ShowOnHUD           = false;
        }

        bool GetTheTurret()
        {
            List <IMyRemoteControl>   remCons = new List <IMyRemoteControl>();
            List <IMyMotorStator>     rots = new List <IMyMotorStator>();
            List <IMySmallGatlingGun> gatGuns = new List <IMySmallGatlingGun>(), ctrlGuns;
            List <IMyShipConnector>   conns   = new List <IMyShipConnector>();
            List <IMyConveyorSorter>  sorters = new List <IMyConveyorSorter>();
            List <IMyCameraBlock>     cameras = new List <IMyCameraBlock>();

            GridTerminalSystem.GetBlocksOfType(remCons);
            GridTerminalSystem.GetBlocksOfType(rots);
            GridTerminalSystem.GetBlocksOfType(gatGuns);
            GridTerminalSystem.GetBlocksOfType(conns);
            GridTerminalSystem.GetBlocksOfType(sorters);
            GridTerminalSystem.GetBlocksOfType(cameras);

            string status = "";
            int    turNo;

            turret = null;

            foreach (IMyRemoteControl ctrl in remCons)
            {
                if (ctrl.CustomData.StartsWith(TURRET_BASE))
                {
                    try{
                        turNo = int.Parse(ctrl.CustomData.Substring(TURRET_BASE.Length));
                        if (turNo != turIndx)
                        {
                            continue;
                        }
                        ctrl.CustomName = "[" + TURRET_BASE + turNo + "] Controller";
                        turret          = new Turret(ctrl);
                        ctrlGuns        = new List <IMySmallGatlingGun>();

                        foreach (IMySmallGatlingGun gun in gatGuns)
                        {
                            if (AreOnSameGrid(gun, ctrl))
                            {
                                ctrlGuns.Add(gun); gun.CustomName = "[" + TURRET_BASE + turNo + "] Gun"; MakeInvisible(gun);
                            }
                        }
                        foreach (IMyShipConnector con in conns)
                        {
                            if (AreOnSameGrid(con, ctrl))
                            {
                                turret.SetRLCon(con); con.CustomName = "[" + TURRET_BASE + turNo + "] Reload Con"; conns.Remove(con); MakeInvisible(con); break;
                            }
                        }
                        foreach (IMyConveyorSorter sor in sorters)
                        {
                            if (AreOnSameGrid(sor, ctrl))
                            {
                                sor.CustomName = "[" + TURRET_BASE + turNo + "] Sorter"; MakeInvisible(sor);
                            }
                        }
                        foreach (IMyCameraBlock cam in cameras)
                        {
                            if (AreOnSameGrid(cam, ctrl))
                            {
                                turret.SetCamera(cam); cam.CustomName = "[" + TURRET_BASE + turNo + "] Camera"; MakeInvisible(cam); break;
                            }
                        }

                        if (!turret.HasRLDCon())
                        {
                            status += "\n102:The turret does not have a reload connector: " + turNo;
                        }

                        if (ctrlGuns.Count > 0)
                        {
                            turret.AddWeapon(ctrlGuns);
                        }
                        else
                        {
                            status += "\n105:There is a turret without weaponry on it: " + turNo;
                        }
                    }
                    catch (Exception e) {
                        e.ToString();
                        status += "\n109:There was a parsing error: \"" + ctrl.CustomData.Substring(TURRET_BASE.Length) + "\"";
                        status += "\n" + e.StackTrace;
                    }
                }
            }

            if (turret == null)
            {
                status       += "\n115:The turret was not found.";
                Me.CustomData = status; return(false);
            }
            else
            {
                foreach (IMyMotorStator rot in rots)
                {
                    if (rot.CustomData.Length <= 0)
                    {
                        continue;
                    }
                    string[] data = rot.CustomData.ToUpper().Split(';');
                    if (data.Length < 2)
                    {
                        try {
                            turNo = int.Parse(rot.CustomData.Substring(TURRET_BASE.Length));
                            if (turNo != turIndx)
                            {
                                continue;
                            }
                        }
                        catch (Exception e) {
                            e.ToString();
                            status += "\n127:There was a parsing error: \"" + rot.CustomData.Substring(TURRET_BASE.Length) + "\"";
                            continue;
                        }
                        status += "\n130:There is no rotor definition for a rotor: " + turNo;
                    }
                    else
                    {
                        try {
                            turNo = int.Parse(data[0].Substring(TURRET_BASE.Length));
                        }
                        catch (Exception e) {
                            e.ToString();
                            status += "\n138:There was a parsing error: \"" + data[0].Substring(TURRET_BASE.Length) + "\"";
                            continue;
                        }
                        if (turNo != turIndx)
                        {
                            continue;
                        }

                        if (data[1].ToUpper().Equals("XROT"))
                        {
                            if (!turret.HasXROT())
                            {
                                turret.SetXROT(rot);
                                rot.CustomName = "[" + TURRET_BASE + turNo + "] XROT";
                            }
                            else
                            {
                                status += "\n148:There is a double-XROT situation going on: " + turNo;
                            }
                        }
                        else
                        if (data[1].ToUpper().Equals("YROT"))
                        {
                            if (!turret.HasYROT())
                            {
                                turret.SetYROT(rot);
                                rot.CustomName = "[" + TURRET_BASE + turNo + "] YROT";
                                if (!turret.HasBSCon())
                                {
                                    foreach (IMyShipConnector con in conns)
                                    {
                                        if (AreOnSameGrid(rot, con))
                                        {
                                            turret.SetBSCon(con); con.CustomName = "[" + TURRET_BASE + turNo + "] Base Con"; break;
                                        }
                                    }
                                }
                            }
                            else
                            {
                                status += "\n157:There is a double-YROT situation going on: " + turNo;
                            }
                        }
                        else
                        if (data[1].ToUpper().Equals("YROTA"))
                        {
                            if (!turret.HasYROTA())
                            {
                                turret.SetYROTA(rot);
                                rot.CustomName = "[" + TURRET_BASE + turNo + "] YROTA";
                                if (!turret.HasBSCon())
                                {
                                    foreach (IMyShipConnector con in conns)
                                    {
                                        if (AreOnSameGrid(rot, con))
                                        {
                                            turret.SetBSCon(con); con.CustomName = "[" + TURRET_BASE + turNo + "] Base Con"; break;
                                        }
                                    }
                                }
                            }
                            else
                            {
                                status += "\n166:There is a double-YROTA situation going on: " + turNo;
                            }
                        }
                        else
                        {
                            status += "\n167:There is an incomprehensible definition for a rotor: " + data[1];
                        }
                    }
                }
            }
            //Echo(status);
            if (status.Length > 0)
            {
                Me.CustomData = status;
            }
            return(true);
        }

        public void Output(object input)
        {
            string message = input is string?(string)input : input.ToString();

            message = turIndx + ";" + message + "\n";

            if (AEGIS_Controller != null || SetAEGISController())
            {
                AEGIS_Controller.CustomData += message;
            }
            else
            {
                Echo("UnU");
            }
        }

        int TimeNo = 0;
        public void Main(string argument, UpdateType updateSource)
        {
            /**/
            if ((updateSource & (UpdateType.Script | UpdateType.Terminal | UpdateType.Trigger)) > 0)
            {
                string[] args = argument.ToLower().Split(' ');
                if (args.Length > 0)
                {
                    int    turId;
                    double px, py, pz /**/, sx, sy, sz /**/;
                    switch (args[0])
                    {
                    case "tar":
                        if (turret == null || !hasTurret)
                        {
                            return;
                        }
                        if (args.Length > 3)
                        {
                            if (Double.TryParse(args[1], out px) && Double.TryParse(args[2], out py) && Double.TryParse(args[3], out pz))
                            {
                                Vector3D vec = new Vector3D(px, py, pz);
                                turret.TrySetTarget(vec);
                                turret.RLDCon.CustomData = turret.CanTarget(vec).ToString();
                            }
                            else
                            {
                                turret.ChangeState(Turret.State.STOW);
                            }
                        }
                        else
                        {
                            turret.ChangeState(Turret.State.STOW);
                        }
                        break;

                    case "assign":
                    case "set":
                        if (args.Length > 1)
                        {
                            if (int.TryParse(args[1], out turId))
                            {
                                Echo("Attempting to set Turret " + turId);
                                SetTurIndx(turId);
                            }
                            else
                            {
                                Echo("Failed to parse index.");
                            }
                        }
                        break;


                    case "reg":     // "you have been provided a fresh data package"
                        /**/
                        if (turret == null || !hasTurret)
                        {
                            return;
                        }

                        string[]
                        registry = Me.CustomData.Split('\n'),
                        row;

                        Vector3D target;
                        for (int i = 0; i < registry.Length; i++)
                        {
                            row = registry[i].Split(';');
                            int ind = 0;
                            if (row.Length > 5 &&
                                double.TryParse(row[ind++], out px) &&
                                double.TryParse(row[ind++], out py) &&
                                double.TryParse(row[ind++], out pz) &&

                                double.TryParse(row[ind++], out sx) &&
                                double.TryParse(row[ind++], out sy) &&
                                double.TryParse(row[ind++], out sz))
                            {
                                /// dividing by 10, because the fire control provides data multiplied by 10 to aleviate the influence of the number limits on the accuracy of the data
                                /// (that is, it ommits the dots in the data provided and multiplies by 10)
                                target = new Entry(new Vector3D(px / 10, py / 10, pz / 10), new Vector3D(sx / 10, sy / 10, sz / 10)).EstimatePosition();
                                if (turret.TrySetTarget(target))
                                {
                                    return;
                                }
                            }
                        }
                        turret.ClearTarget();
                        /**/
                        break;

                    default:
                        Echo("Command unknown");
                        break;
                    }
                }
            }
            else
            {
                if (hasTurret && turret != null && TimeNo++ >= 600)
                {
                    TimeNo = 0;
                    turret.PerformSelfDiagnostic();
                }

                if (hasTurret && turret != null)
                {
                    string output = turret.DoYourJob();
                    Output(output);
                }
            }
            /**/
        }
    }
}
            /// 24 (longest string in 'Status') 6 + 18
            ///

            public string DoYourJob()
            {
                string output;

                if (Evaluate(out output))
                {
                    return(output);
                }
                if (CTRL.IsUnderControl)
                {
                    if (this.currState != State.MANUAL)
                    {
                        ChangeState(State.MANUAL);
                    }
                    if (RLDCon.Enabled == true)
                    {
                        RLDCon.Enabled = false;
                    }

                    XROT.UpperLimitDeg = float.MaxValue;
                    XROT.LowerLimitDeg = float.MinValue;

                    XROT.TargetVelocityRPM  = 0;
                    YROT.TargetVelocityRPM  = 0;
                    YROTA.TargetVelocityRPM = 0;

                    float X = CTRL == null ? 0f : CTRL.RotationIndicator.Y;
                    float Y = CTRL == null ? 0f : CTRL.RotationIndicator.X;
                    float Z = CTRL == null ? 0f : CTRL.MoveIndicator.Z;

                    if (Z < 0)
                    {
                        Fire(true);
                    }
                    else
                    {
                        Fire(false);
                    }


                    Move(X / 25, Y / 25);
                    return(output + "Manual Control");
                }
                else
                {
                    if (currState.Equals(State.IDLE))
                    {
                        Move(0, 0);
                        return(output + "Idle");
                    }
                    else
                    if (currState.Equals(State.RELOAD))
                    {
                        Move(0, 0);
                        return(output + "Reloading...");
                    }
                    else
                    if (currState.Equals(State.MANUAL))
                    {
                        ChangeState(State.STOW);
                        return(output + "...");
                    }
                    Vector3D
                        target = currState.Equals(State.TRACK)? targetCoords : Vector3D.Add(BSDCon.GetPosition(), Vector3D.Multiply(BSDCon.WorldMatrix.Forward, 100)),
                        me     = this.CTRL.GetPosition(),

                        sub  = CutVector(Vector3D.Normalize(Vector3D.Subtract(target, me))),
                        curr = Vector3D.Subtract(CutVector(DirintToVec(1)), sub);


                    List <NavPrompt>
                    prompts    = new List <NavPrompt>(),
                        sorted = new List <NavPrompt>();
                    /**/
                    for (int i = 3; i < 7; i++)
                    {
                        prompts.Add(new NavPrompt(i, Vector3D.Subtract(CutVector(DirintToVec(i)), sub)));
                    }
                    sorted = prompts.OrderBy(o => o.vLength).ToList();

                    Vector2I culprit = new Vector2I(sorted[0].dirInt, sorted[1].dirInt);
                    /**/
                    //// Old Culprit System Below

                    /**
                     * int culprit;
                     *
                     * for (int i = 1; i < 7; i++)
                     *  prompts.Add(new NavPrompt(i, Vector3D.Subtract(CutVector(DirintToVec(i)), sub)));
                     * sorted = prompts.OrderBy(o => o.vLength).ToList();
                     *
                     * for (culprit = 0; culprit < 3; culprit++) {
                     *  if (sorted[culprit].dirInt != 1 && sorted[culprit].dirInt != 2) {
                     *      if(culprit==1 && (sorted[culprit].dirInt==5 || sorted[culprit].dirInt == 6)) {
                     *          if (!AreQuiteSame(prompts[2].vLength, prompts[3].vLength)) {culprit=2;}
                     *      }
                     *      break;
                     *  }
                     * }
                     * culprit = sorted[culprit].dirInt;
                     * /**/

                    if (currState.Equals(State.STOW))
                    {
                        if (this.RLDCon.Enabled == false)
                        {
                            this.RLDCon.Enabled = true;
                        }
                        if ((this.RLDCon.Status == MyShipConnectorStatus.Connectable && curr.Length() < 0.02f) || this.RLDCon.Status == MyShipConnectorStatus.Connected)
                        {
                            this.RLDCon.Connect();
                            if (!hasTarget)
                            {
                                ChangeState(State.IDLE);
                            }
                            else
                            {
                                ChangeState(State.RELOAD);
                            }
                        }
                        else
                        {
                            //Move(CulpritToMove(culprit,(float)curr.Length()));
                            DoubleCTM(sorted[0].dirInt, sorted[0].vLength, sorted[1].dirInt, sorted[1].vLength);
                        }
                        return(output + "Stowing");
                    }
                    else
                    if (currState.Equals(State.TRACK))
                    {
                        if (this.RLDCon.Enabled == true)
                        {
                            this.RLDCon.Enabled = false;
                        }
                        if (!this.hasTarget)
                        {
                            ChangeState(State.STOW);
                            return("Lost Target");
                        }
                        //Move(CulpritToMove(culprit, (float)(curr.Length())));
                        DoubleCTM(sorted[0].dirInt, sorted[0].vLength, sorted[1].dirInt, sorted[1].vLength);
                        /**/
                        if (curr.Length() < 0.1f && Vector3D.Subtract(target, me).Length() <= 800)
                        {
                            Fire(true);
                            return(output + ("Firing"));
                        }
                        else
                        {
                            Fire(false);
                            return(output + ("Tracking..."));
                        }
                        /**/
                    }
                    return("???");
                }
            }