Esempio n. 1
0
        private void SpawnConvoy(IMyShipController baseToSpawnAt)
        {
            var factionId       = baseToSpawnAt.OwnerId;
            var spawnerPosition = baseToSpawnAt.GetPosition();
            var gravity         = baseToSpawnAt.GetNaturalGravity();
            var unitType        = baseToSpawnAt.CustomName.Contains("GROUND") ? UnitType.Ground : UnitType.Air;
            var cargoSize       = heatSystem.GenerateCargoShipSize();

            //TODO: Should let base define the convoy spawn points
            //TODO: gravity is not normalized and is being used to scale the spawn point...  It should be normalized and then meters used to modify.
            // NOTE: The .Forward IS normalized, so the scalar is in meters.
            if (unitType == UnitType.Air)
            {
                var positionToSpawn = spawnerPosition + gravity * -5f + baseToSpawnAt.WorldMatrix.Forward * 30;
                var transportPrefab = PrefabGrid.GetAirTransport(cargoSize);
                DuckUtils.SpawnInGravity(positionToSpawn, gravity, factionId, transportPrefab.PrefabName,
                                         transportPrefab.InitialBeaconName,
                                         Vector3D.Normalize(baseToSpawnAt.WorldMatrix.Forward));
            }
            else
            {
                var positionToSpawn = spawnerPosition + gravity * -1f + baseToSpawnAt.WorldMatrix.Forward * 35;
                var transportPrefab = PrefabGrid.GetGroundTransport(cargoSize);
                DuckUtils.SpawnInGravity(positionToSpawn, gravity, factionId, transportPrefab.PrefabName,
                                         transportPrefab.InitialBeaconName,
                                         Vector3D.Normalize(baseToSpawnAt.WorldMatrix.Forward));
            }
        }
Esempio n. 2
0
            public WheelControl(IMyShipController rc, UpdateFrequency tickSpeed, List <IMyMotorSuspension> wheels)
            {
                if (rc == null)
                {
                    throw new Exception("Ship controller null.");
                }

                this.rc = rc;

                this.wheels = wheels.Select(x => new Wheel(x, GetForce(x))).ToList();

                double factor = 1;

                if (tickSpeed == UpdateFrequency.Update10)
                {
                    factor = 10;
                }
                else if (tickSpeed == UpdateFrequency.Update100)
                {
                    factor = 100;
                }
                double secondsPerTick = (1.0 / 60) * factor;

                anglePID   = new PID(P2 / factor, I2 / factor, D2 / factor, 0.2 / factor, secondsPerTick);
                forwardPID = new PID(P / factor, I / factor, D / factor, 0.2 / factor, secondsPerTick);
                Reset();
            }
Esempio n. 3
0
            public GyroRotation(Program P, IMyShipController cockpit)
            {
                this.P = P;

                P.GridTerminalSystem.GetBlocksOfType(gyros);
                this.cockpit = cockpit;
            }
Esempio n. 4
0
        public Program()
        {
            if (string.IsNullOrWhiteSpace(sensorGroup))
            {
                sensors = GetBlocks <IMySensorBlock>();
            }
            else
            {
                sensors = GetBlocks <IMySensorBlock>(sensorGroup, true);
            }

            // Prioritize the given cockpit name
            rc = GetBlock <IMyShipController>(cockpitName, true);
            if (rc == null) // Second priority cockpit
            {
                rc = GetBlock <IMyCockpit>();
            }
            if (rc == null) // Thrid priority remote control
            {
                rc = GetBlock <IMyRemoteControl>();
            }
            if (rc == null) // No cockpits found.
            {
                throw new Exception("No cockpit/remote control found. Set the cockpitName field in settings.");
            }

            if (activeRaycasting)
            {
                allCameras = new List <IMyCameraBlock>();
            }
            foreach (IMyCameraBlock c in GetBlocks <IMyCameraBlock>())
            {
                if (EqualsPrecision(Vector3D.Dot(rc.WorldMatrix.Forward, c.WorldMatrix.Forward), 1, 0.01))
                {
                    forwardCameras.Add(c);
                    c.EnableRaycast = true;
                }
                if (activeRaycasting)
                {
                    allCameras.Add(c);
                }
            }

            LoadStorage();

            if (tickSpeed == UpdateFrequency.Update10)
            {
                echoFrequency = 10;
            }
            else if (tickSpeed == UpdateFrequency.Update100)
            {
                echoFrequency = 1;
            }

            if (!isDisabled)
            {
                Runtime.UpdateFrequency = tickSpeed;
            }
            Echo("Ready");
        }
Esempio n. 5
0
        bool BlockCollect(IMyTerminalBlock block)
        {
            if (block is IMyMotorSuspension)
            {
                wheels.Add((IMyMotorSuspension)block);
            }

            if (block is IMyPistonBase && block.CustomName != null && block.CustomName.StartsWith(miningPrefix))
            {
                forwardPistons.Add((IMyPistonBase)block);
            }

            if (block is IMyPistonBase && block.CustomName != null && block.CustomName.StartsWith(miningReversePrefix))
            {
                backwardPistons.Add((IMyPistonBase)block);
            }

            if (block is IMyShipDrill && block.CustomName != null && block.CustomName.StartsWith(miningPrefix))
            {
                drills.Add((IMyShipDrill)block);
            }

            if (block is IMyShipController && ((IMyShipController)block).IsUnderControl && ((IMyShipController)block).CanControlShip)
            {
                shipController = (IMyShipController)block;
            }

            return(false);
        }
Esempio n. 6
0
        private static IMyShipController FindDefaultCockpit(IMyGridTerminalSystem gts, IMyTerminalBlock anyBlock)
        {
            List <IMyShipController> allBlocks = new List <IMyShipController>();

            gts.GetBlocksOfType <IMyShipController>(allBlocks, block => block.IsSameConstructAs(anyBlock) && block.CanControlShip);

            if (allBlocks.Count == 0)
            {
                return(null);
            }

            IMyShipController findedCtrl = allBlocks[0];

            foreach (IMyShipController ctrl in allBlocks)
            {
                if (ctrl.IsUnderControl)
                {
                    return(ctrl);
                }
                if (ctrl.IsMainCockpit)
                {
                    findedCtrl = ctrl;
                }
            }
            return(findedCtrl);
        }
Esempio n. 7
0
        //private void SettingsRequest(ulong steamid)
        //{
        //	NetSettings.SetValue(Settings.Static);

        //	Tools.Debug(MyAPIGateway.Utilities.SerializeToXML(Settings.Static));

        //}

        private void Changed(VRage.Game.ModAPI.Interfaces.IMyControllableEntity o, VRage.Game.ModAPI.Interfaces.IMyControllableEntity n)
        {
            foreach (WeaponBase w in GridWeapons)
            {
                w.State.Value &= ~WeaponState.ManualShoot;
            }

            GridWeapons.Clear();
            ControlledGridId = 0;

            ActiveTurret = n?.Entity as IMyLargeTurretBase;

            if (ActiveTurret == null)
            {
                ActiveShipController = n?.Entity as IMyShipController;
                SelectedDefinitionId = Tools.GetSelectedHotbarDefinition(ActiveShipController);
            }

            MyCubeGrid grid = (n?.Entity as MyCubeBlock)?.CubeGrid;

            if (grid != null)
            {
                ControlledGridId = grid.EntityId;
                foreach (MyCubeBlock block in grid.GetFatBlocks())
                {
                    WeaponControlLayer layer = block.GameLogic.GetAs <WeaponControlLayer>();

                    if (layer != null)
                    {
                        GridWeapons.Add(layer.Weapon);
                    }
                }
            }
        }
Esempio n. 8
0
        public Vector3D GetShipAngularVelocity(IMyShipController dataBlock)
        {
            var worldLocalVelocities     = dataBlock.GetShipVelocities().AngularVelocity;
            var worldToAnchorLocalMatrix = Matrix.Transpose(dataBlock.WorldMatrix.GetOrientation());

            return(Vector3D.Transform(worldLocalVelocities, worldToAnchorLocalMatrix));
        }
Esempio n. 9
0
        public Vector3D GetGravity(IMyShipController dataBlock)
        {
            var worldLocalGravity        = dataBlock.GetNaturalGravity();
            var worldToAnchorLocalMatrix = Matrix.Transpose(dataBlock.WorldMatrix.GetOrientation());

            return(Vector3D.Transform(worldLocalGravity, worldToAnchorLocalMatrix));
        }
Esempio n. 10
0
        public void Setup()
        {
            // Cockpit
            List <IMyTerminalBlock> cockpitListReferences = new List <IMyTerminalBlock>();

            GridTerminalSystem.SearchBlocksOfName(CockpitTag, cockpitListReferences);
            if (cockpitListReferences.Count == 0)
            {
                throw new Exception("No cockpit found! Check the naming tag.");
            }

            CockpitBlock   = (IMyShipController)cockpitListReferences[0];
            ReferenceBlock = cockpitListReferences[0];

            // Antenna
            List <IMyTerminalBlock> antennaListReferences = new List <IMyTerminalBlock>();

            GridTerminalSystem.SearchBlocksOfName(AntennaTag, antennaListReferences);

            if (antennaListReferences.Count == 0)
            {
                throw new Exception("No ILS Receiver Antenna! Check naming tag.");
            }

            Antenna = (IMyRadioAntenna)antennaListReferences[0];
            IGC.RegisterBroadcastListener(ILSAntennaChannel);
            IGC.RegisterBroadcastListener(VORAntennaChannel);
            IGC.RegisterBroadcastListener(NDBAntennaChannel);


            // Mark setup as completed.
            SetupComplete = true;
            Echo("Setup complete.");
        }
Esempio n. 11
0
            private float GetEdgeDistance(IMyShipController reference, Vector3D direction)
            {
                Vector3D edgeDirection = GetShipEdgeVector(reference, direction);
                Vector3D edgePos       = reference.GetPosition() + edgeDirection;

                return((float)Vector3D.Distance(reference.CenterOfMass, edgePos));
            }
Esempio n. 12
0
            public AdvanceControlShip(IMyCockpit cockpit)
            {
                m_shipControl = cockpit;
                m_cockpit     = cockpit;
                m_remote      = null;

                Matrix cockOrientation = new Matrix();

                m_shipControl.Orientation.GetMatrix(out cockOrientation);
                rotation_Bcockpit_2_Bship = cockOrientation;
                rotation_Bship_2_Bcockpit = MatrixD.Transpose(rotation_Bcockpit_2_Bship); //Transpose is quicker than invert, and equivalent in this case

                if (USE_DEBUG)
                {
                    lcd1 = m_cockpit.GetSurface(0);
                    setFont(lcd1);
                    if (m_cockpit.SurfaceCount > 1)
                    {
                        lcd2 = m_cockpit.GetSurface(1);
                        setFont(lcd2);
                    }
                    if (m_cockpit.SurfaceCount > 2)
                    {
                        lcd3 = m_cockpit.GetSurface(2);
                        setFont(lcd3);
                    }
                }
            }
            public ControlModule(GridTerminalSystemUtils gts, IMyShipController control)
            {
                this.control = control;

                gts.GetBlocksOfTypeOnGrid(thrusters);
                gts.GetBlocksOfTypeOnGrid(gyros);
            }
Esempio n. 14
0
        public void SpawnConvoyTransport(IMyShipController baseToSpawnAt)
        {
            var factionId       = baseToSpawnAt.OwnerId;
            var spawnerPosition = baseToSpawnAt.GetPosition();
            var gravity         = baseToSpawnAt.GetNaturalGravity();
            var unitType        = baseToSpawnAt.CustomName.Contains("GROUND") ? UnitType.Ground : UnitType.Air;
            var cargoSize       = heatSystem.GenerateCargoShipSize();

            if (unitType == UnitType.Air)
            {
                var positionToSpawn = spawnerPosition + gravity * -5f + baseToSpawnAt.WorldMatrix.Forward * 30;
                var transportPrefab = CalPrefabFactory.GetAirTransport(cargoSize);
                DuckUtils.SpawnInGravity(positionToSpawn, gravity, factionId, transportPrefab.PrefabName,
                                         transportPrefab.InitialBeaconName,
                                         Vector3D.Normalize(baseToSpawnAt.WorldMatrix.Forward));
            }
            else
            {
                var positionToSpawn = spawnerPosition + gravity * -1f + baseToSpawnAt.WorldMatrix.Forward * 35;
                var transportPrefab = CalPrefabFactory.GetGroundTransport(cargoSize);
                DuckUtils.SpawnInGravity(positionToSpawn, gravity, factionId, transportPrefab.PrefabName,
                                         transportPrefab.InitialBeaconName,
                                         Vector3D.Normalize(baseToSpawnAt.WorldMatrix.Forward));
            }
        }
            private void UpdateController()
            {
                Env.Log?.PushStack("UpdateControllerFromArgument");
                IMyShipController OldController = RefecenceController;

                RefecenceController = null;
                Env.Log?.IfDebug?.Debug("D1");
                string optionKey = "SetController";
                string findBy    = Env.GlobalArgs.hasOption(optionKey) && (Env.GlobalArgs.getOption(optionKey).Count > 0) ? Env.GlobalArgs.getOption(optionKey)[0] : "AUTO";

                switch (findBy)
                {
                case "AUTO":
                    UpdateControlerByAutodetect();
                    break;

                default:
                    UpdateControllerByTag(findBy);
                    break;
                }
                if (!OldController.Equals(RefecenceController))
                {
                    OnControllerChanged(OldController);
                }

                Env.Log?.PopStack();
            }
Esempio n. 16
0
 void GyroSetup()
 {
     foreach (var gyro in useGyros)
     {
         gyro.GyroOverride = false;
     }
     useGyros.Clear();
     if (gyroControl == null)
     {
         gyroControl = _program.wicoBlockMaster.GetMainController();
     }
     if (gyroControl == null)
     {
         // no good controller found
         //                    throw new Exception("GYROS: No controller found");
         return;
     }
     foreach (var tb in allLocalGyros)
     {
         if (useGyros.Count >= LIMIT_GYROS)
         {
             break; // we are done adding
         }
         // only use gyros that are on same grid as the controller
         if (tb.CubeGrid.EntityId == gyroControl.CubeGrid.EntityId)
         {
             // TODO: check limitations and naming options
             useGyros.Add(tb);
         }
     }
 }
 public ActiveSensor(IMyShipController Cont, IMyCameraBlock Cam, IMyMotorStator XRot, IMyMotorStator YRot)
 {
     this.Cont = Cont;
     this.Cam  = Cam;
     this.XRot = XRot;
     this.YRot = YRot;
 }
Esempio n. 18
0
 void LocalGridChangedHandler()
 {
     gyrosOff();
     gyroControl = null;
     useGyros.Clear();
     allLocalGyros.Clear();
 }
Esempio n. 19
0
 void LocalGridChangedHandler()
 {
     sensorsList.Clear();
     sensorInfos.Clear();
     shipController = null;
     localGrids.Clear();
 }
 public MissileManagementClient(ACPWrapper antennaWrapper, IMyShipController rc, long id, MissileType missileType)
 {
     this.antennaWrapper = antennaWrapper;
     this.rc             = rc;
     this.id             = id;
     this.missileType    = missileType;
 }
Esempio n. 21
0
        private void GetBlocks()
        {
            string        blockGroupName = configReader.Get <string>("blockGroupName");
            IMyBlockGroup blockGroup     = GridTerminalSystem.GetBlockGroupWithName(blockGroupName);

            List <IMyShipController> controllers = new List <IMyShipController>();

            blockGroup.GetBlocksOfType <IMyShipController>(controllers);
            if (controllers.Count == 0)
            {
                throw new Exception("Error: " + blockGroupName + " does not contain a cockpit or remote control block.");
            }
            cockpit = controllers[0];

            List <IMyTextPanel> textPanels = new List <IMyTextPanel>();

            blockGroup.GetBlocksOfType <IMyTextPanel>(textPanels);
            if (textPanels.Count > 0)
            {
                textPanel          = textPanels[0];
                textPanel.Font     = "Monospace";
                textPanel.FontSize = 1.0f;
                textPanel.ShowPublicTextOnScreen();
            }

            blockGroup.GetBlocksOfType <IMyGyro>(gyros);
            if (gyros.Count == 0)
            {
                throw new Exception("Error: " + blockGroupName + " does not contain any gyroscopes.");
            }
        }
Esempio n. 22
0
 public void LocalGridChangedHandler()
 {
     // forget what we thought we knew
     shipdimController  = null;
     MainShipController = null;
     shipControllers.Clear();
 }
        bool CollectParts(IMyTerminalBlock block)
        {
            if (Context.Reference.CubeGrid.EntityId != block.CubeGrid.EntityId)
            {
                return(false);
            }

            if (block is IMyShipController && ((IMyShipController)block).CanControlShip)
            {
                controller = (IMyShipController)block;
            }

            if (block is IMyThrust)
            {
                IMyThrust thruster = (IMyThrust)block;
                thrustersList.Add(thruster);
                thruster.ThrustOverride = 0;
                thrusterManager.AddThruster(thruster);
            }

            if (block is IMyGyro)
            {
                IMyGyro gyro = (IMyGyro)block;
                gyros.Add(gyro);
                gyro.Pitch        = 0;
                gyro.Yaw          = 0;
                gyro.Roll         = 0;
                gyro.GyroOverride = false;
            }

            return(false);
        }
        void SetDampenersOnline(bool dampOn)
        {
            if (shipControllers.Count <= 0)
            {
                return;
            }

            IMyShipController SHIP_CONTROLLER = null;

            foreach (IMyShipController controler in shipControllers)
            {
                if (controler.IsWorking)
                {
                    SHIP_CONTROLLER = controler; if (controler.IsMainCockpit)
                    {
                        break;
                    }
                }
            }

            if (SHIP_CONTROLLER != null)
            {
                if (dampOn)
                {
                    if (SHIP_CONTROLLER.GetShipSpeed() <= 0d)
                    {
                        SHIP_CONTROLLER.DampenersOverride = true;
                    }
                }
                else
                {
                    SHIP_CONTROLLER.DampenersOverride = false;
                }
            }
        }
 public Program()
 {
     // The constructor, called only once every session and
     // always before any other method is called. Use it to
     // initialize your script.
     //
     // The constructor is optional and can be removed if not
     // needed.
     //
     // It's recommended to set Runtime.UpdateFrequency
     // here, which will allow your script to run itself without a
     // timer block.
     Runtime.UpdateFrequency = UpdateFrequency.Update1;
     g         = GridTerminalSystem.GetBlockWithName("Gyro") as IMyGyro;
     sc        = GridTerminalSystem.GetBlockWithName("Cockpit") as IMyShipController;
     lcd       = GridTerminalSystem.GetBlockWithName("LCD") as IMyTextPanel;
     thrusters = new List <IMyThrust>();
     GridTerminalSystem.GetBlockGroupWithName("Thrusters").GetBlocksOfType <IMyThrust>(thrusters);
     hDamp        = false;
     manualAlt    = true;
     vDamp        = false;
     targAltitude = GetAltitude();
     mass         = sc.CalculateShipMass().PhysicalMass;
     curSpeed     = 0;
     lastHeading  = sc.WorldMatrix.Forward;
 }
        // Helpers

        void GetParts()
        {
            controller = null;

            thrustersList.Clear();
            for (int i = 0; i < thrusts.Length; i++)
            {
                thrusts[i] = 0;
            }

            thrusterManager.Clear();

            Context.Terminal.GetBlocksOfType <IMyTerminalBlock>(null, CollectParts);

            if (controller != null)
            {
                controller.IsMainCockpit     = true;
                controller.DampenersOverride = true;
                reference = controller;
            }
            foreach (var thruster in thrustersList)
            {
                var f = thruster.Orientation.Forward;
                thrusts[(int)f] += thruster.MaxEffectiveThrust;
            }
        }
            public CollisionAvoidance(IMyShipController rc, EntityTracking_Module trackingModule, int resX, int resY)
            {
                this.rc             = rc;
                this.trackingModule = trackingModule;

                localScanMap = BuildScanMap(resX, resY);
            }
            void ShipDimensions(IMyShipController orientationBlock)//BoundingBox bb, double BlockMetricConversion)
            {
                if (thisProgram.Me.CubeGrid.GridSizeEnum.ToString().ToLower().Contains("small"))
                {
                    gridsize = SMALL_BLOCK_LENGTH;
                }
                else
                {
                    gridsize = LARGE_BLOCK_LENGTH;
                }

                _obbf = new OrientedBoundingBoxFaces(orientationBlock);
                Vector3D[] points = new Vector3D[4];
                _obbf.GetFaceCorners(OrientedBoundingBoxFaces.LookupFront, points); // 5 = front
                                                                                    // front output order is BL, BR, TL, TR
                _width  = (points[0] - points[1]).Length();
                _height = (points[0] - points[2]).Length();
                _obbf.GetFaceCorners(0, points);
                // face 0=right output order is  BL, TL, BR, TR ???
                _length = (points[0] - points[2]).Length();

                _length_blocks = (float)(_length / gridsize);
                _width_blocks  = (float)(_width / gridsize);
                _height_blocks = (float)(_height / gridsize);

                /*
                 *              _length_blocks = bb.Size.GetDim(2) + 1;
                 *              _width_blocks = bb.Size.GetDim(0) + 1;
                 *              _height_blocks = bb.Size.GetDim(1) + 1;
                 *              _block2metric = BlockMetricConversion;
                 *              _length = Math.Round(_length_blocks * BlockMetricConversion, 2);
                 *              _width = Math.Round(_width_blocks * BlockMetricConversion, 2);
                 *              _height = Math.Round(_height_blocks * BlockMetricConversion, 2);
                 */
            }
Esempio n. 29
0
            /// <summary>Class that allow some high level control over the wheels. To be controlled, the wheels must be on the same grid than <paramref name="controller"/> and contain the keyword "Power"</summary>
            /// <param name="command">Command line where the commands will be registered</param>
            /// <param name="controller">Controller on the same grid than the wheels to get some physics information</param>
            /// <param name="gts">To retrieve the wheels</param>
            /// <param name="ini">Contains some serialized information for persistence</param>
            /// <param name="manager">To spawn the updater process</param>
            /// <param name="transformer">Transformer that transform world coordinates into the vehicules coordinate: Z must be parallel to the vehicle's forward direction an Y must be parallel to the vehicle's up direction</param>
            public WheelsController(CommandLine command, IMyShipController controller, IMyGridTerminalSystem gts, MyIni ini, ISaveManager manager, CoordinatesTransformer transformer)
            {
                this.transformer = transformer;
                this.controller  = controller;
                var wheels = new List <IMyMotorSuspension>();

                gts.GetBlocksOfType(wheels, w => w.CubeGrid == controller.CubeGrid && w.DisplayNameText.Contains("Power"));
                this.wheels = wheels.Select(w => new PowerWheel(w, this.WheelBase, transformer)).ToList();
                this.wheels.Sort((w1, w2) => Math.Sign(w1.Position.Z - w2.Position.Z)); // needed for calibration

                this.registerCommands(command);
                manager.Spawn(this.updateWheels, "wheels-controller", period: 10);
                manager.AddOnSave(this.save);

                if (ini.ContainsKey(SECTION, "cal-weight"))
                {
                    this.calibration = new Calibration()
                    {
                        Weight  = ini.Get(SECTION, "cal-weight").ToSingle(),
                        MinZ    = ini.Get(SECTION, "cal-min-z").ToDouble(),
                        MaxZ    = ini.Get(SECTION, "cal-max-z").ToDouble(),
                        MinMult = ini.Get(SECTION, "cal-min-mult").ToSingle(),
                        MaxMult = ini.Get(SECTION, "cal-max-mult").ToSingle()
                    };
                }

                this.targetRatio = ini.Get(SECTION, "target-ratio").ToSingle(0.35f);
                this.WheelBase.CenterOfTurnZOffset = ini.Get(SECTION, "turn-center-offset").ToDouble();
                this.WheelBase.TurnRadiusOverride  = ini.Get(SECTION, "turn-radius").ToDouble();
            }
Esempio n. 30
0
        bool GrabBlocks()
        {
            List <IMyShipController> shipControllers = new List <IMyShipController>();

            GridTerminalSystem.GetBlocksOfType(shipControllers, x => x.CustomName.Contains(shipControllerName));

            if (shipControllers.Count == 0)
            {
                Echo($"Error: No ship controller named '{shipControllerName}' were found!");
                return(false);
            }

            reference = shipControllers[0];

            GridTerminalSystem.GetBlocksOfType(mainThrusters, x => x.WorldMatrix.Forward == reference.WorldMatrix.Backward);
            if (mainThrusters.Count == 0)
            {
                Echo($"Error: No lift-off thrusters were found!");
                return(false);
            }

            GridTerminalSystem.GetBlocksOfType(gyros);
            if (gyros.Count == 0)
            {
                Echo($"Error: No gyros were found!");
                return(false);
            }

            return(true);
        }
Esempio n. 31
0
    private void Alignment(ShipControlCommons shipControl, IMyShipController controller)
    {
        Vector3D center;
        if (DropTarget == null || !controller.TryGetPlanetPosition(out center)) return;

        // Project the target position to our sphere
        var targetRayDirection = Vector3D.Normalize((Vector3D)DropTarget - center);
        var myRayLength = (shipControl.ReferencePoint - center).Length();
        var targetPosition = center + targetRayDirection * myRayLength;

        // Now get offset to target point on our sphere
        // (not all that accurate over large distances, but eh)
        var targetOffset = targetPosition - shipControl.ReferencePoint;

        // Project targetOffset along each reference vector,
        // set cruiser speed appropriately
        AlignmentThrust(shipControl, targetOffset, LongCruiser);
        AlignmentThrust(shipControl, targetOffset, LatCruiser);
    }