Beispiel #1
0
        public override void Drive(FlightCtrlState s)
        {
            // Fix the Translatron behavuous with kill HS.
            // TODO : proper fix that register the attitude controler oustide of Drive
            if (!core.attitude.users.Contains(this) && (core.thrust.trans_kill_h && core.thrust.tmode != MechJebModuleThrustController.TMode.OFF))
            {
                core.attitude.users.Add(this);
            }
            if (core.attitude.users.Contains(this) && (!core.thrust.trans_kill_h || core.thrust.tmode == MechJebModuleThrustController.TMode.OFF))
            {
                core.attitude.users.Remove(this);
            }

            if (abort != AbortStage.OFF)
            {
                switch (abort)
                {
                case AbortStage.THRUSTOFF:
                    FlightInputHandler.SetNeutralControls();
                    s.mainThrottle = 0;
                    abort          = AbortStage.DECOUPLE;
                    break;

                case AbortStage.DECOUPLE:
                    recursiveDecouple();
                    abort      = AbortStage.BURNUP;
                    burnUpTime = Planetarium.GetUniversalTime();
                    break;

                case AbortStage.BURNUP:
                    if ((Planetarium.GetUniversalTime() - burnUpTime < 2) || (vesselState.speedVertical < 10))
                    {
                        core.thrust.tmode = MechJebModuleThrustController.TMode.DIRECT;
                        core.attitude.attitudeTo(Vector3d.up, AttitudeReference.SURFACE_NORTH, this);
                        double int_error = Math.Abs(Vector3d.Angle(vesselState.up, vesselState.forward));
                        core.thrust.trans_spd_act = (int_error < 90) ? 100 : 0;
                    }
                    else
                    {
                        abort = AbortStage.LAND;
                    }
                    break;

                case AbortStage.LAND:
                    core.thrust.users.Remove(this);
                    core.GetComputerModule <MechJebModuleLandingAutopilot>().LandUntargeted(this);
                    abort = AbortStage.LANDING;
                    break;

                case AbortStage.LANDING:
                    if (vessel.LandedOrSplashed)
                    {
                        abort = AbortStage.OFF;
                    }
                    break;
                }
            }
            base.Drive(s);
        }
Beispiel #2
0
 public override void OnUpdate()
 {
     if (tmode_changed)
     {
         if (trans_kill_h && (tmode == TMode.OFF))
         {
             core.attitude.attitudeDeactivate();
         }
         pid.Reset();
         tmode_changed = false;
         FlightInputHandler.SetNeutralControls();
     }
 }
        private void RenderAlignUI(GUIStyle sty, GUIStyle but)
        {
            if (!CheckVessel())
            {
                _flyByWire = false;
                Mode       = UIMode.SELECTED;
            }

            if (GUILayout.Button("Align Planes", but, GUILayout.ExpandWidth(true)))
            {
                Mode       = UIMode.SELECTED;
                _flyByWire = false;
            }

            GUILayout.Box("Time to AN : " + part.vessel.orbit.GetTimeToRelAN(FlightGlobals.Vessels[_selectedVesselIndex].orbit).ToString("F2"));
            GUILayout.Box("Time to DN : " + part.vessel.orbit.GetTimeToRelDN(FlightGlobals.Vessels[_selectedVesselIndex].orbit).ToString("F2"));
            GUILayout.Box("Relative Inclination :" + _relativeInclination.ToString("F2"));
            if (automation == true)
            {
                if (GUILayout.Button(_autoAlign ? "ALIGNING" : "Auto-Align", but, GUILayout.ExpandWidth(true)))
                {
                    _autoAlignBurnTriggered = false;
                    _autoAlign = !_autoAlign;
                }
            }
            if (_flyByWire == false)
            {
                if (GUILayout.Button("Orbit Normal", but, GUILayout.ExpandWidth(true)))
                {
                    _flyByWire = true;
                    PointAt    = Orient.Normal;
                }

                if (GUILayout.Button("Anti Normal", but, GUILayout.ExpandWidth(true)))
                {
                    _flyByWire = true;
                    PointAt    = Orient.AntiNormal;
                }
            }

            if (_flyByWire)
            {
                if (GUILayout.Button("Disable " + PointAt.ToString(), but, GUILayout.ExpandWidth(true)))
                {
                    FlightInputHandler.SetNeutralControls();
                    _flyByWire   = false;
                    _modeChanged = true;
                }
            }
        }
Beispiel #4
0
        /// <inheritdoc/>
        public Part CoupleParts(AttachNode sourceNode, AttachNode targetNode,
                                bool toDominantVessel = false)
        {
            if (toDominantVessel)
            {
                var dominantVessel =
                    Vessel.GetDominantVessel(sourceNode.owner.vessel, targetNode.owner.vessel);
                if (dominantVessel != targetNode.owner.vessel)
                {
                    var tmp = sourceNode;
                    sourceNode = targetNode;
                    targetNode = tmp;
                }
            }
            DebugEx.Fine("Couple {0} to {1}",
                         KASAPI.AttachNodesUtils.NodeId(sourceNode),
                         KASAPI.AttachNodesUtils.NodeId(targetNode));
            var srcPart   = sourceNode.owner;
            var srcVessel = srcPart.vessel;

            KASAPI.AttachNodesUtils.AddNode(srcPart, sourceNode);
            var tgtPart   = targetNode.owner;
            var tgtVessel = tgtPart.vessel;

            KASAPI.AttachNodesUtils.AddNode(tgtPart, targetNode);

            sourceNode.attachedPart   = tgtPart;
            sourceNode.attachedPartId = tgtPart.flightID;
            targetNode.attachedPart   = srcPart;
            targetNode.attachedPartId = srcPart.flightID;
            tgtPart.attachMode        = AttachModes.STACK;
            srcPart.Couple(tgtPart);
            // Depending on how active vessel has updated do either force active or make active. Note, that
            // active vessel can be EVA kerbal, in which case nothing needs to be adjusted.
            // FYI: This logic was taken from ModuleDockingNode.DockToVessel.
            if (srcVessel == FlightGlobals.ActiveVessel)
            {
                FlightGlobals.ForceSetActiveVessel(sourceNode.owner.vessel); // Use actual vessel.
                FlightInputHandler.SetNeutralControls();
            }
            else if (sourceNode.owner.vessel == FlightGlobals.ActiveVessel)
            {
                sourceNode.owner.vessel.MakeActive();
                FlightInputHandler.SetNeutralControls();
            }

            return(srcPart);
        }
        private static void AfterCouplingEvent()
        {
            if (_activeVesselIsWeakVessel)
            {
                if (_dominantVessel)
                {
                    FlightGlobals.ForceSetActiveVessel(_dominantVessel);
                    FlightInputHandler.SetNeutralControls();
                }
            }

            if (_activeVesselIsDominantVessel)
            {
                _dominantVessel.MakeActive();
                FlightInputHandler.SetNeutralControls();
            }
        }
        public override void OnUpdate()
        {
            if (core.GetComputerModule <MechJebModuleThrustWindow>().hidden&& core.GetComputerModule <MechJebModuleAscentGuidance>().hidden)
            {
                return;
            }

            if (tmode_changed)
            {
                if (trans_kill_h && (tmode == TMode.OFF))
                {
                    core.attitude.attitudeDeactivate();
                }
                pid.Reset();
                tmode_changed = false;
                FlightInputHandler.SetNeutralControls();
            }
        }
Beispiel #7
0
        public override void drive(FlightCtrlState s)
        {
            if (abort != AbortStage.OFF)
            {
                switch (abort)
                {
                case AbortStage.THRUSTOFF:
                    FlightInputHandler.SetNeutralControls();
                    s.mainThrottle = 0;
                    abort          = AbortStage.DECOUPLE;
                    break;

                case AbortStage.DECOUPLE:
                    recursiveDecouple();
                    abort      = AbortStage.BURNUP;
                    burnUpTime = Planetarium.GetUniversalTime();
                    break;

                case AbortStage.BURNUP:
                    if ((Planetarium.GetUniversalTime() - burnUpTime < 2) || (vesselState.speedVertical < 10))
                    {
                        core.tmode = MechJebCore.TMode.DIRECT;
                        core.attitudeTo(Vector3d.up, MechJebCore.AttitudeReference.SURFACE_NORTH, this);
                        double int_error = Math.Abs(Vector3d.Angle(vesselState.up, vesselState.forward));
                        core.trans_spd_act = (int_error < 90) ? 100 : 0;
                    }
                    else
                    {
                        abort = AbortStage.LAND;
                    }
                    break;

                case AbortStage.LAND:
                    core.controlRelease(this);
                    core.landActivate(this);
                    abort = AbortStage.OFF;
                    break;
                }
            }
            base.drive(s);
        }
        public override void OnUpdate()
        {
            if (core.GetComputerModule <MechJebModuleThrustWindow>().hidden&& core.GetComputerModule <MechJebModuleAscentGuidance>().hidden)
            {
                return;
            }

            if (tmode_changed)
            {
                if (trans_kill_h && (tmode == TMode.OFF))
                {
                    core.attitude.attitudeDeactivate();
                }
                pid.Reset();
                tmode_changed = false;
                FlightInputHandler.SetNeutralControls();
            }

            bool disableThrusters = (userCommandingRotation && !core.rcs.rcsForRotation);

            if (disableThrusters != lastDisableThrusters)
            {
                lastDisableThrusters = disableThrusters;
                var rcsModules = vessel.FindPartModulesImplementing <ModuleRCS>();
                foreach (var pm in rcsModules)
                {
                    if (disableThrusters)
                    {
                        pm.enablePitch = pm.enableRoll = pm.enableYaw = false;
                    }
                    else
                    {
                        // TODO : Check the protopart for the original values (slow) ? Or use a dict to save them (hard with save) ?
                        pm.enablePitch = pm.enableRoll = pm.enableYaw = true;
                    }
                }
            }
        }
        public override void OnUpdate()
        {
            if (core.GetComputerModule <MechJebModuleThrustWindow>().hidden&& core.GetComputerModule <MechJebModuleAscentGuidance>().hidden)
            {
                return;
            }

            if (tmode_changed)
            {
                if (trans_kill_h && (tmode == TMode.OFF))
                {
                    core.attitude.attitudeDeactivate();
                }
                pid.Reset();
                tmode_changed = false;
                FlightInputHandler.SetNeutralControls();
            }

            bool disableThrusters = (userCommandingRotation && !core.rcs.rcsForRotation);

            if (disableThrusters != lastDisableThrusters)
            {
                lastDisableThrusters = disableThrusters;
                var rcsModules = vessel.FindPartModulesImplementing <ModuleRCS>();
                foreach (var pm in rcsModules)
                {
                    if (disableThrusters)
                    {
                        pm.Disable();
                    }
                    else
                    {
                        pm.Enable();
                    }
                }
            }
        }
Beispiel #10
0
 protected override void on_vessel_launched(Vessel vsl)
 {
     base.on_vessel_launched(vsl);
     if (recipient_node != null)
     {
         var construction_node_pos =
             part.partTransform.TransformPoint(construction_node.position);
         var construction_part = recipient_node.owner;
         var docking_node      = kit.GetDockingNode(vsl, ConstructDockingNode);
         if (docking_node == null)
         {
             Utils.Message(
                 "No suitable attachment node found in \"{0}\" to dock it to the {1}",
                 vsl.GetDisplayName(),
                 construction_part.Title());
             return;
         }
         var docking_offset =
             docking_node.owner.partTransform.TransformPoint(docking_node.position)
             - construction_node_pos;
         FXMonger.Explode(part, construction_node_pos, 0);
         var docking_part = docking_node.owner;
         this.Log("Docking {} to {}", docking_part.GetID(), construction_part.GetID());
         // vessels' position and rotation
         construction_part.vessel.SetPosition(construction_part.vessel.transform.position,
                                              true);
         construction_part.vessel.SetRotation(construction_part.vessel.transform.rotation);
         docking_part.vessel.SetPosition(
             docking_part.vessel.transform.position - docking_offset,
             true);
         docking_part.vessel.SetRotation(docking_part.vessel.transform.rotation);
         construction_part.vessel.IgnoreGForces(10);
         docking_part.vessel.IgnoreGForces(10);
         if (construction_part == part.parent)
         {
             part.decouple();
         }
         else
         {
             construction_part.decouple();
         }
         recipient_node.attachedPart   = docking_part;
         recipient_node.attachedPartId = docking_part.flightID;
         docking_node.attachedPart     = construction_part;
         docking_node.attachedPartId   = construction_part.flightID;
         docking_part.Couple(construction_part);
         // manage docking ports, if any
         foreach (var port in construction_part.FindModulesImplementing <ModuleDockingNode>())
         {
             if (port.referenceNode == recipient_node)
             {
                 port.dockedPartUId = docking_part.persistentId;
                 port.fsm.StartFSM(port.st_preattached);
                 break;
             }
         }
         foreach (var port in docking_part.FindModulesImplementing <ModuleDockingNode>())
         {
             if (port.referenceNode == docking_node)
             {
                 port.dockedPartUId = construction_part.persistentId;
                 port.fsm.StartFSM(port.st_preattached);
                 break;
             }
         }
         // add fuel lookups
         construction_part.fuelLookupTargets.Add(docking_part);
         docking_part.fuelLookupTargets.Add(construction_part);
         GameEvents.onPartFuelLookupStateChange.Fire(
             new GameEvents.HostedFromToAction <bool, Part>(true,
                                                            docking_part,
                                                            construction_part));
         FlightGlobals.ForceSetActiveVessel(construction_part.vessel);
         FlightInputHandler.SetNeutralControls();
         GameEvents.onVesselWasModified.Fire(construction_part.vessel);
         recipient_node = null;
         this.Log("Docked {} to {}, new vessel {}",
                  docking_part,
                  construction_part,
                  construction_part.vessel.GetID());
     }
 }
        /*        void driveComeAlongside(FlightCtrlState controls) {
         *
         *              if (core.targetOrbit() == null)
         *              {
         *                  comeAlongside = false;
         *                  FlightInputHandler.SetNeutralControls();
         *                  core.controlRelease(this);
         *                  return;
         *              }
         *
         *              Vector3d targetPosition = core.targetPosition();// (core.targetType == MechJebCore.TargetType.VESSEL ? (Vector3d)core.targetVessel.transform.position : core.targetBody.position);
         *              Vector3d vectorToTarget = (targetPosition - vesselState.CoM).normalized;
         *              Vector3d relativeVelocity = vesselState.velocityVesselOrbit - core.targetOrbit().GetVel();
         *              Vector3d lateralVector = Vector3d.Exclude(vectorToTarget, relativeVelocity).normalized;
         *              double lateralSpeed = Vector3d.Dot(relativeVelocity, lateralVector);
         *              double closingSpeed = Vector3d.Dot(relativeVelocity, vectorToTarget);
         *              double closingDistance = Vector3d.Dot(targetPosition - vesselState.CoM, relativeVelocity.normalized);
         *              double lateralSpeedFraction = lateralSpeed / relativeVelocity.magnitude;
         *
         *              //print("lateralSpeedFraction = " + lateralSpeedFraction);
         *
         *              double maxClosingSpeed = Math.Sqrt(2 * Math.Max(closingDistance - 20, 0) * vesselState.maxThrustAccel);
         *              double desiredClosingSpeed = 0.5 * maxClosingSpeed;
         *
         *              //print(String.Format("closingSpeed / desiredClosingSpeed = {0:F1} / {1:F1}", closingSpeed, desiredClosingSpeed));
         *
         *              double lateralWeight = lateralSpeed;
         *              if (lateralSpeed < 1.0) lateralWeight *= lateralSpeed; //an attempt to suppress wiggles
         *              double closingWeight = ARUtils.Clamp(1.1*closingSpeed - desiredClosingSpeed, 0, maxClosingSpeed);
         *
         *              //print(String.Format("lateralWeight / closingWeight = {0:F1} / {1:F1}", lateralWeight, closingWeight));
         *
         *              Vector3d desiredAttitude = (-lateralWeight * lateralVector - closingWeight * relativeVelocity.normalized).normalized;
         *
         *              core.attitudeTo(desiredAttitude, MechJebCore.AttitudeReference.INERTIAL, this);
         *
         *              if (Vector3d.Dot(relativeVelocity, vectorToTarget) < 0 || relativeVelocity.magnitude < 0.1)
         *              {
         *                  comeAlongside = false;
         *                  FlightInputHandler.SetNeutralControls();
         *                  core.controlRelease(this);
         *              }
         *              else
         *              {
         *                  if (closingDistance < 25)
         *                  {
         *                      //print("last few meters: closingDistance = " + closingDistance);
         *                      core.attitudeTo(Vector3d.back, MechJebCore.AttitudeReference.TARGET, this);
         *                      if (core.attitudeAngleFromTarget() < 5)
         *                      {
         *                          controls.mainThrottle = Mathf.Clamp((float)(relativeVelocity.magnitude / vesselState.maxThrustAccel), 0.0F, 1.0F);
         *                      }
         *                  }
         *                  else if (core.attitudeAngleFromTarget() < 15 &&
         *                      (closingSpeed > desiredClosingSpeed || lateralSpeedFraction > 0.08))
         *                  {
         *                      float lateralThrottle = Mathf.Clamp((float)(20 * (lateralSpeedFraction - 0.08)), 0.0F, 1.0F);
         *                      float closingThrottle = Mathf.Clamp((float)(10 * (closingSpeed / desiredClosingSpeed - 1)), 0.0F, 1.0F);
         *                      controls.mainThrottle = Mathf.Max(lateralThrottle, closingThrottle);
         *                  }
         *                  else
         *                  {
         *                      controls.mainThrottle = 0.0F;
         *                  }
         *              }
         *      }*/


        void driveAutoAlign(FlightCtrlState controls)
        {
            if (!autoAlignBurnTriggered)
            {
                // Is it time to burn? Find soonest node.
                double timeToBurnAN = part.vessel.orbit.GetTimeToRelAN(core.targetOrbit());
                double timeToBurnDN = part.vessel.orbit.GetTimeToRelDN(core.targetOrbit());

                bool   ascendingSoonest = timeToBurnAN < timeToBurnDN;
                double timeToBurnNode   = ascendingSoonest ? timeToBurnAN : timeToBurnDN;

                autoAlignBurnDirection = ascendingSoonest ? Vector3.right : Vector3.left;

                double burnDV   = part.vessel.orbit.relativeInclination(core.targetOrbit()) * Math.PI / 180 * vesselState.speedOrbital;
                double burnTime = burnDV / vesselState.maxThrustAccel;
                double leadTime = Math.Max(burnTime / 2, 1.0); //min lead time of 1 second so we don't miss the burn if the burn time is short

                statusString = "Align Orbits: Burning in " + (int)(timeToBurnNode - leadTime) + " s";

                if (timeToBurnNode > leadTime + 30)
                {
                    core.warpTo(this, timeToBurnNode - burnTime / 2 - 30, warpLookaheadTimes);
                }
                else if (timeToBurnNode < leadTime)
                {
                    autoAlignBurnTriggered = true;
                    autoAlignDidBurn       = false;
                }
            }

            core.attitudeTo(autoAlignBurnDirection, MechJebCore.AttitudeReference.ORBIT, this);

            if (autoAlignBurnTriggered)
            {
                statusString = "Align Orbits: Burning to match planes";
                if (core.attitudeAngleFromTarget() < 5.0)
                {
                    double maxDegreesPerSecond = (180 / Math.PI) * vesselState.maxThrustAccel / vesselState.speedOrbital;
                    if (Math.Abs(part.vessel.orbit.relativeInclination(core.targetOrbit())) > maxDegreesPerSecond / 2)
                    {
                        controls.mainThrottle = 1.0f;
                    }
                    else
                    {
                        controls.mainThrottle = (float)Math.Max(part.vessel.orbit.relativeInclination(core.targetOrbit()) / maxDegreesPerSecond, 0.05F);
                    }
                    autoAlignDidBurn = true;
                }
                else
                {
                    controls.mainThrottle = 0.0f;
                }

                //stop burn if it's no longer pushing the orbit normals closer:
                Vector3d torqueNeeded     = ARUtils.swapYZ(part.vessel.orbit.GetOrbitNormal()).normalized - ARUtils.swapYZ(core.targetOrbit().GetOrbitNormal()).normalized;
                Vector3d torqueDir        = Vector3d.Cross(vesselState.CoM - part.vessel.mainBody.transform.position, vesselState.forward).normalized;
                double   torqueDotProduct = Vector3d.Dot(torqueDir, torqueNeeded);

                if (autoAlignDidBurn && (part.vessel.orbit.relativeInclination(core.targetOrbit()) < 0.005 || torqueDotProduct < 0))
                {
                    statusString           = "Align Orbits: Finished";
                    autoAlignBurnTriggered = false;
                    autoAlign = false;
                    FlightInputHandler.SetNeutralControls();
                    controls.mainThrottle = 0;
                    core.controlRelease(this);
                }
            }
        }
        protected override void WindowGUI(int windowID)
        {
            if (FlightGlobals.fetch.VesselTarget == null)
            {
                GUILayout.Label("Select a target via the map screen.");
                GUI.DragWindow();
                return;
            }

            if (core.targetOrbit().referenceBody != part.vessel.mainBody)
            {
                GUILayout.Label("Target (" + core.targetName() + ") is orbiting another body.");
                GUI.DragWindow();
                return;
            }

            //Now we can be sure that there is a target and it's in the same SOI as us.

            GUILayout.BeginVertical();

            GUILayout.Label("Distance: " + MuUtils.ToSI(core.distanceFromTarget(), 3) + "m", GUILayout.Width(300));

            GUILayout.Label("Relative Velocity: " + core.relativeVelocityToTarget().magnitude.ToString("F2") + " m/s");

            double closestApproachTime = ARUtils.timeOfClosestApproach(part.vessel.orbit, core.targetOrbit(), vesselState.time);

            GUILayout.Label("Closest approach in " + MuUtils.ToSI(closestApproachTime - vesselState.time, 3) + "s");

            double closestApproachDistance = (part.vessel.orbit.getAbsolutePositionAtUT(closestApproachTime) - core.targetOrbit().getAbsolutePositionAtUT(closestApproachTime)).magnitude;

            GUILayout.Label("Approach distance: " + MuUtils.ToSI(closestApproachDistance, 3) + "m");

            GUILayout.Label("Relative inclination: " + part.vessel.orbit.relativeInclination(core.targetOrbit()).ToString("F2") + "°");

            GUILayout.Label("Time to AN: " + MuUtils.ToSI(part.vessel.orbit.GetTimeToRelAN(core.targetOrbit()), 3) + "s");
            GUILayout.Label("Time to DN: " + MuUtils.ToSI(part.vessel.orbit.GetTimeToRelDN(core.targetOrbit()), 3) + "s");



            //                burnForCollisionCourse = GUILayout.Toggle(burnForCollisionCourse, "Burn to collide");

            /*                if (!comeAlongside && GUILayout.Button("Come alongside"))
             *              {
             *                  comeAlongside = true;
             *                  core.controlClaim(this);
             *              }
             *              else if (comeAlongside && GUILayout.Button("Stop coming alongside"))
             *              {
             *                  comeAlongside = false;
             *                  FlightInputHandler.SetNeutralControls();
             *                  core.controlRelease(this);
             *              }*/

            if (!autoAlign && GUILayout.Button("Align orbits"))
            {
                autoAlign = true;
                autoAlignBurnTriggered = false;
                core.controlClaim(this);
            }
            else if (autoAlign && GUILayout.Button("Stop aligning orbits"))
            {
                autoAlign = false;
                FlightInputHandler.SetNeutralControls();
                core.controlRelease(this);
            }

            if (statusString.Length > 0)
            {
                GUILayout.Label(statusString);
            }


            GUILayout.EndVertical();

            GUI.DragWindow();
        }
Beispiel #13
0
        public void AttachDocked(KASModuleAttachCore otherAttachModule)
        {
            // Save vessel Info
            this.vesselInfo             = new DockedVesselInfo();
            this.vesselInfo.name        = this.vessel.vesselName;
            this.vesselInfo.vesselType  = this.vessel.vesselType;
            this.vesselInfo.rootPartUId = this.vessel.rootPart.flightID;
            this.dockedAttachModule     = otherAttachModule;

            otherAttachModule.vesselInfo             = new DockedVesselInfo();
            otherAttachModule.vesselInfo.name        = otherAttachModule.vessel.vesselName;
            otherAttachModule.vesselInfo.vesselType  = otherAttachModule.vessel.vesselType;
            otherAttachModule.vesselInfo.rootPartUId = otherAttachModule.vessel.rootPart.flightID;
            otherAttachModule.dockedAttachModule     = this;

            // Set reference
            attachMode.Docked = true;

            // Stop if already docked
            if (otherAttachModule.part.parent == this.part || this.part.parent == otherAttachModule.part)
            {
                KAS_Shared.DebugWarning("DockTo(Core) Parts already docked, nothing more to do");
                return;
            }

            // Reset vessels position and rotation for returning all parts to their original position and rotation before coupling
            this.vessel.SetPosition(this.vessel.transform.position, true);
            this.vessel.SetRotation(this.vessel.transform.rotation);
            otherAttachModule.vessel.SetPosition(otherAttachModule.vessel.transform.position, true);
            otherAttachModule.vessel.SetRotation(otherAttachModule.vessel.transform.rotation);

            // Couple depending of mass

            Vessel dominantVessel = GetDominantVessel(this.vessel, otherAttachModule.vessel);

            KAS_Shared.DebugLog("DockTo(Core) Master vessel is " + dominantVessel.vesselName);

            if (dominantVessel == this.vessel)
            {
                KAS_Shared.DebugLog("DockTo(Core) Docking " + otherAttachModule.part.partInfo.title + " from " + otherAttachModule.vessel.vesselName + " with " + this.part.partInfo.title + " from " + this.vessel.vesselName);
                if (FlightGlobals.ActiveVessel == otherAttachModule.part.vessel)
                {
                    KAS_Shared.DebugLog("DockTo(Core) Switching focus to " + this.part.vessel.vesselName);
                    FlightGlobals.ForceSetActiveVessel(this.part.vessel);
                }
                otherAttachModule.part.Couple(this.part);
            }
            else
            {
                KAS_Shared.DebugLog("DockTo(Core) Docking " + this.part.partInfo.title + " from " + this.vessel.vesselName + " with " + otherAttachModule.part.partInfo.title + " from " + otherAttachModule.vessel.vesselName);
                if (FlightGlobals.ActiveVessel == this.part.vessel)
                {
                    KAS_Shared.DebugLog("DockTo(Core) Switching focus to " + otherAttachModule.part.vessel.vesselName);
                    FlightGlobals.ForceSetActiveVessel(otherAttachModule.part.vessel);
                }
                this.part.Couple(otherAttachModule.part);
            }

            this.vessel.ctrlState = new FlightCtrlState();
            FlightInputHandler.SetNeutralControls();
            GameEvents.onVesselWasModified.Fire(this.part.vessel);
        }
Beispiel #14
0
        public void DockToPart(Part other)
        {
            this.Log("Docking to vessel: {}", other.vessel.vesselName);
            var old_vessel = vessel;

            contacts.Clear();
            dockedPartUId = other.flightID;
            // save this vessel info
            this_vessel             = new DockedVesselInfo();
            this_vessel.name        = vessel.vesselName;
            this_vessel.vesselType  = vessel.vesselType;
            this_vessel.rootPartUId = vessel.rootPart.flightID;
            // save other vessel info
            docked_vessel             = new DockedVesselInfo();
            docked_vessel.name        = other.vessel.vesselName;
            docked_vessel.vesselType  = other.vessel.vesselType;
            docked_vessel.rootPartUId = other.vessel.rootPart.flightID;
            // reset vessels' position and rotation
            vessel.SetPosition(vessel.transform.position, true);
            vessel.SetRotation(vessel.transform.rotation);
            other.vessel.SetPosition(other.vessel.transform.position, true);
            other.vessel.SetRotation(other.vessel.transform.rotation);
            vessel.IgnoreGForces(10);
            other.vessel.IgnoreGForces(10);
            grapplePos = Vector3.zero;
            setup_grapple_node(other, part);
            PartJoint joint;

            if (Vessel.GetDominantVessel(vessel, other.vessel) == vessel)
            {
                other.Couple(part);
                joint = other.attachJoint;
            }
            else
            {
                part.Couple(other);
                joint = part.attachJoint;
            }
            joint.SetUnbreakable(true, true);
            // add fuel lookups
            part.fuelLookupTargets.Add(other);
            other.fuelLookupTargets.Add(part);
            GameEvents.onPartFuelLookupStateChange.Fire(new GameEvents.HostedFromToAction <bool, Part>(true, other, part));
            // switch vessel if needed
            if (old_vessel == FlightGlobals.ActiveVessel)
            {
                FlightGlobals.ForceSetActiveVessel(vessel);
                FlightInputHandler.SetNeutralControls();
            }
            else if (vessel == FlightGlobals.ActiveVessel)
            {
                vessel.MakeActive();
                FlightInputHandler.SetNeutralControls();
            }
            // untarget docked vessels
            if (FlightGlobals.fetch.VesselTarget != null)
            {
                if (FlightGlobals.fetch.VesselTarget.GetVessel() == other.vessel)
                {
                    FlightGlobals.fetch.SetVesselTarget(null, false);
                }
            }
            if (vessel.targetObject != null)
            {
                if (vessel.targetObject.GetVessel() == other.vessel)
                {
                    vessel.targetObject = null;
                }
            }
            if (other.vessel.targetObject != null)
            {
                if (other.vessel.targetObject.GetVessel() == part.vessel)
                {
                    other.vessel.targetObject = null;
                }
            }
            // update state and part menu
            state = State.Docked;
            update_part_menu();
            GameEvents.onVesselWasModified.Fire(vessel);
        }
        private void RenderRendezvousUI(GUIStyle sty, GUIStyle but)
        {
            if (!CheckVessel())
            {
                _flyByWire = false;
                Mode       = UIMode.SELECTED;
            }

            Vessel selectedVessel = FlightGlobals.Vessels[_selectedVesselIndex] as Vessel;

            if (GUILayout.Button(selectedVessel.vesselName, but, GUILayout.ExpandWidth(true)))
            {
                _flyByWire = false;
                Mode       = UIMode.SELECTED;
            }
            if (_targetDistance > 10000)
            {
                GUILayout.Box("Distance: " + (_targetDistance / 1000).ToString("F1") + "km", GUILayout.Width(300));
            }
            else
            {
                GUILayout.Box("Distance: " + _targetDistance.ToString("F1") + "m", GUILayout.Width(300));
            }
            GUILayout.Box("Rel Inc : " + _relativeInclination.ToString("F3"));
            GUILayout.Box("Rel VelM: " + _relativeVelocity.magnitude.ToString("F2"));

            // Take the relative velocity and project into ship local space.
            _localRelativeVelocity = part.vessel.transform.worldToLocalMatrix.MultiplyVector(_relativeVelocity);
            _localRelativePosition = part.vessel.transform.worldToLocalMatrix.MultiplyPoint(selectedVessel.transform.position);

            if (automation == true)
            {
                if (GUILayout.Button(_killRelativeVelocity == false ? "Kill Rel Vel" : "FIRING", but, GUILayout.ExpandWidth(true)))
                {
                    _killRelativeVelocity = !_killRelativeVelocity;
                }

                if (GUILayout.Button(_homeOnRelativePosition == false ? "Home on Y+ 5m" : "HOMING", but, GUILayout.ExpandWidth(true)))
                {
                    _homeOnRelativePosition = !_homeOnRelativePosition;
                }
            }
            GUILayout.Box("Rel Vel : " + _localRelativeVelocity.x.ToString("F2") + ", " + _localRelativeVelocity.y.ToString("F2") + ", " + _localRelativeVelocity.z.ToString("F2"));
            if (_targetDistance > 10000)
            {
                GUILayout.Box("Rel Pos : " + (_localRelativePosition.x / 1000).ToString("F2") + "km, " + (_localRelativePosition.y / 1000).ToString("F2") + "km, " + (_localRelativePosition.z / 1000).ToString("F2") + "km");
            }
            else
            {
                GUILayout.Box("Rel Pos : " + _localRelativePosition.x.ToString("F2") + ", " + _localRelativePosition.y.ToString("F2") + ", " + _localRelativePosition.z.ToString("F2"));
            }

            if (_flyByWire == false)
            {
                GUILayout.BeginHorizontal();

                if (GUILayout.Button(ControlModeCaptions[0], but, GUILayout.ExpandWidth(true)))
                {
                    _flyByWire       = true;
                    PointAt          = Orient.RelativeVelocity;
                    _modeChanged     = true;
                    _selectedFlyMode = 0;
                }


                if (GUILayout.Button(ControlModeCaptions[1], but, GUILayout.ExpandWidth(true)))
                {
                    _flyByWire       = true;
                    PointAt          = Orient.RelativeVelocityAway;
                    _modeChanged     = true;
                    _selectedFlyMode = 1;
                }


                if (GUILayout.Button(ControlModeCaptions[2], but, GUILayout.ExpandWidth(true)))
                {
                    _flyByWire       = true;
                    PointAt          = Orient.Target;
                    _modeChanged     = true;
                    _selectedFlyMode = 2;
                }

                GUILayout.EndHorizontal();

                GUILayout.BeginHorizontal();

                if (GUILayout.Button(ControlModeCaptions[3], but, GUILayout.ExpandWidth(true)))
                {
                    _flyByWire       = true;
                    PointAt          = Orient.TargetAway;
                    _modeChanged     = true;
                    _selectedFlyMode = 3;
                }

                if (GUILayout.Button(ControlModeCaptions[4], but, GUILayout.ExpandWidth(true)))
                {
                    _flyByWire       = true;
                    PointAt          = Orient.MatchTarget;
                    _modeChanged     = true;
                    _selectedFlyMode = 4;
                }

                if (GUILayout.Button(ControlModeCaptions[5], but, GUILayout.ExpandWidth(true)))
                {
                    _flyByWire       = true;
                    PointAt          = Orient.MatchTargetAway;
                    _modeChanged     = true;
                    _selectedFlyMode = 5;
                }

                GUILayout.EndHorizontal();
            }

            if (_flyByWire)
            {
                if (GUILayout.Button("Disable " + ControlModeCaptions[_selectedFlyMode], but, GUILayout.ExpandWidth(true)))
                {
                    FlightInputHandler.SetNeutralControls();
                    _flyByWire   = false;
                    _modeChanged = true;
                }
            }
        }