Esempio n. 1
0
        /// <summary>
        /// Gets the state of a docking port. Does not consider the state of an attached docking port.
        /// </summary>
        static DockingPortState IndividualState(ModuleDockingNode node)
        {
            var state = node.state;

            if (state == "Ready")
            {
                return(DockingPortState.Ready);
            }
            if (state.StartsWith("Docked", StringComparison.CurrentCulture) || state == "PreAttached")
            {
                return(DockingPortState.Docked);
            }
            if (state.Contains("Acquire"))
            {
                return(DockingPortState.Docking);
            }
            if (state == "Disengage")
            {
                return(DockingPortState.Undocking);
            }
            if (state == "Disabled")
            {
                var shieldModule = node.part.Module <ModuleAnimateGeneric> ();
                if (shieldModule == null)
                {
                    throw new InvalidOperationException("Docking port state is '" + node.state + "', but it does not have a shield!");
                }
                return(shieldModule.status.StartsWith("Moving", StringComparison.CurrentCulture) ? DockingPortState.Moving : DockingPortState.Shielded);
            }
            throw new ArgumentException("Unknown docking port state '" + node.state + "'");
        }
        public override void OnStart(StartState state)
        {
            base.OnStart(state);

            if (fixedUpdateHelper == null && HighLogic.LoadedSceneIsFlight)
            {
                fixedUpdateHelper = this.part.gameObject.AddComponent <FixedUpdateHelper>();
                fixedUpdateHelper.onFixedUpdateDelegate = OnUpdateFixed;
                fixedUpdateHelper.enabled = true;
            }

            ModuleDockingNode dockingNode = this.part.FindModuleImplementing <ModuleDockingNode>();

            if (!dockingNode)
            {
                return;
            }

            if (dockingNode.isEnabled)
            {
                Events["ToggleDockingPort"].guiName = "Disable Docking Port";
            }

            else
            {
                Events["ToggleDockingPort"].guiName = "Enable Docking Port";
            }
        }
Esempio n. 3
0
 // This method allows us to check if a specified ModuleDockingNode is one that this hatch is attached to
 internal bool IsRelatedDockingNode(ModuleDockingNode dockNode)
 {
     if (dockNode.nodeTransformName == docNodeTransformName)
     {
         if (string.IsNullOrEmpty(docNodeAttachmentNodeName))
         {
             docNodeAttachmentNodeName = dockNode.referenceNode.id;
         }
         modDockNode = dockNode;
         return(true);
     }
     if (dockNode.referenceNode.id == docNodeAttachmentNodeName)
     {
         if (string.IsNullOrEmpty(docNodeTransformName))
         {
             docNodeTransformName = dockNode.nodeTransformName;
         }
         modDockNode = dockNode;
         return(true);
     }
     // If we are here, we have an orphaned hatch.  we may be able to recover if the part only has one docking module...
     // TODO, check for dups in the same part...
     if (this.part.FindModulesImplementing <ModuleDockingNode>().Count == 1)
     {
         // we are good.  lets fix the hatch and continue
         modDockNode               = this.part.FindModulesImplementing <ModuleDockingNode>().First();
         docNodeTransformName      = modDockNode.nodeTransformName;
         docNodeAttachmentNodeName = modDockNode.referenceAttachNode;
         return(true);
     }
     return(false);
 }
Esempio n. 4
0
        /// <summary>
        /// Convert the textual docking node state into an enum, so we don't
        /// need to do string compares.
        /// </summary>
        /// <param name="whichNode"></param>
        /// <returns></returns>
        internal static DockingNodeState GetNodeState(ModuleDockingNode whichNode)
        {
            if (whichNode == null)
            {
                return(DockingNodeState.UNKNOWN);
            }

            switch (whichNode.state)
            {
            case "PreAttached":
                return(DockingNodeState.PREATTACHED);

            case "Docked (docker)":
                return(DockingNodeState.DOCKED);

            case "Docked (dockee)":
                return(DockingNodeState.DOCKED);

            case "Ready":
                return(DockingNodeState.READY);

            default:
                return(DockingNodeState.UNKNOWN);
            }
        }
Esempio n. 5
0
 private bool CheckModuleDockingNode()
 {
     if (null == modDockNode)
     {
         // We do not know which ModuleDockingNode we are attached to yet. Try to find one.
         IEnumerator <ModuleDockingNode> eNodes = part.Modules.OfType <ModuleDockingNode>().GetEnumerator();
         while (eNodes.MoveNext())
         {
             if (eNodes.Current == null)
             {
                 continue;
             }
             if (IsRelatedDockingNode(eNodes.Current))
             {
                 modDockNode = eNodes.Current;
                 return(true);
             }
         }
         eNodes.Dispose();
     }
     else
     {
         return(true);
     }
     return(false);
 }
        // Adapted from KIS by IgorZ
        // See https://github.com/ihsoft/KIS/blob/master/Source/KIS_Shared.cs#L1005-L1039
        // This method is in the public domain.
        /// <summary>Couples docking port with a part at its reference attach node.</summary>
        /// <remarks>Both parts must be already connected and the attach nodes correctly set.</remarks>
        /// <param name="dockingNode">Port to couple.</param>
        /// <returns><c>true</c> if coupling was successful.</returns>
        public static bool CoupleDockingPortWithPart(ModuleDockingNode dockingNode)
        {
            Part tgtPart = dockingNode.referenceNode.attachedPart;

            if (tgtPart == null)
            {
                log.error("Node's part " + dockingNode.part.name + " is not attached to anything thru the reference node");
                return(false);
            }
            if (dockingNode.state != dockingNode.st_ready.name)
            {
                log.debug("Hard reset docking node " + dockingNode.part.name + " from state " + dockingNode.state + " to " + dockingNode.st_ready.name);
                dockingNode.dockedPartUId          = 0;
                dockingNode.dockingNodeModuleIndex = 0;
                // Target part lived in real world for some time, so its state may be anything.
                // Do a hard reset.
                dockingNode.fsm.StartFSM(dockingNode.st_ready.name);
            }
            var initState = dockingNode.lateFSMStart(PartModule.StartState.None);

            // Make sure part init catched the new state.
            while (initState.MoveNext())
            {
                // Do nothing. Just wait.
            }
            if (dockingNode.fsm.currentStateName != dockingNode.st_preattached.name)
            {
                log.warning("Node on " + dockingNode.part.name + " is unexpected state " + dockingNode.fsm.currentStateName);
                return(false);
            }
            log.debug("Successfully set docking node " + dockingNode.part + " to state " + dockingNode.fsm.currentStateName + " with part " + tgtPart.name);
            return(true);
        }
Esempio n. 7
0
        public void SendToPartUndockNotifyees(Part p)
        {
            // Notify any hooks attached to the part on the "from" side of the event:
            UniqueSetValue <UserDelegate> notifyees = GetPartUndockNotifyees(p);

            foreach (UserDelegate del in notifyees)
            {
                if (UserDelgateIsAcceptable(del))
                {
                    Shared.Cpu.AddTrigger(del);
                }
            }

            // Notify any hooks attached to the part on the "to" side of the event:
            ModuleDockingNode dockModule = (ModuleDockingNode)p.Modules["ModuleDockingNode"];

            notifyees = GetPartUndockNotifyees(dockModule.otherNode.part);
            foreach (UserDelegate del in notifyees)
            {
                if (UserDelgateIsAcceptable(del))
                {
                    Shared.Cpu.AddTrigger(del);
                }
            }

            // The event has no data available on which other part it had been attached to, apparently.
        }
        private bool CheckForNodeDockedToPart(ModuleDockingNode thisNode, Part otherPart)
        {
            bool retVal = false;

            Log.dbg("thisNode.dockedPartUId={0} otherPart.flightID={1} thisNode.state: {2}", thisNode.dockedPartUId, otherPart.flightID, thisNode.state);

            // if (otherPart == thisNode.part.vessel[thisNode.dockedPartUId])
            if (thisNode.dockedPartUId == otherPart.flightID)
            {
                Log.dbg("IDs match");
                if (thisNode.state == "Docked (dockee)")
                {
                    Log.dbg(" this module is docked (dockee) to the other part");
                    retVal = true;
                }
                else if (thisNode.state == "Docked (docker)")
                {
                    Log.dbg("this module is docked (docker) to the other part");
                    retVal = true;
                }
                else if (thisNode.state == "Acquire")
                {
                    Log.warn("this module is in the Acquire state, which might mean it is in the process of docking.");
                    retVal = true;
                }
            }
            return(retVal);
        }
 public override void OnStart(StartState state)
 {
     base.OnStart(state);
     SpawnManager.Init(part);
     SpawnManager.SetupSensor();
     if (!string.IsNullOrEmpty(ConstructionNode))
     {
         construction_node = part.FindAttachNode(ConstructionNode);
         foreach (var port in part.FindModulesImplementing <ModuleDockingNode>())
         {
             if (port.nodeTransformName == ConstructionNode ||
                 port.referenceAttachNode == ConstructionNode)
             {
                 construction_port = port;
                 break;
             }
         }
     }
     if (construction_node == null)
     {
         this.Log("ERROR: unable to find construction AttachNode with id: {}",
                  ConstructionNode);
         this.EnableModule(false);
         return;
     }
     if (kit && ConstructDockingNode >= 0)
     {
         construct_docking_node = kit.DockingNodes[ConstructDockingNode];
     }
 }
Esempio n. 10
0
        public static bool IsDocked(Vessel vessel, Part part)
        {
            ModuleDockingNode dockingPort = part.Modules.OfType <ModuleDockingNode>().FirstOrDefault();

            //this port is docked
            if (dockingPort.state.Length >= 6 && dockingPort.state.Substring(0, 6) == "Docked" && null != dockingPort.vesselInfo.name)
            {
                return(true);
            }

            //no joined port filled
            if (dockingPort.dockedPartUId == 0)
            {
                return(false);
            }

            //find joined port
            foreach (Part p in vessel.parts)
            {
                if (p.flightID == dockingPort.dockedPartUId)
                {
                    ModuleDockingNode pDockingPort = p.Modules.OfType <ModuleDockingNode>().FirstOrDefault();
                    if (pDockingPort != null && pDockingPort.state.Length >= 6 && pDockingPort.state.Substring(0, 6) == "Docked")
                    {
                        return(true);
                    }
                }
            }
            return(false);
        }
Esempio n. 11
0
        // Vessel Menu
        private void TargetVessel(int index, TextMenu.Item ti)
        {
            if (selectedVessel == vesselsList[index].vessel)
            {
                // Already selected.  Are there ports?
                if (UpdatePortsList() > 0)
                {
                    currentMenu = MenuList.Ports;

                    activeMenu = new TextMenu();
                    activeMenu.rightColumnWidth = 7;

                    activeMenu.labelColor     = nameColorTag;
                    activeMenu.selectedColor  = selectedColorTag;
                    activeMenu.disabledColor  = unavailableColorTag;
                    activeMenu.rightTextColor = distanceColorTag;

                    UpdateLists();

                    if (selectedPort != null)
                    {
                        int idx = portsList.FindIndex(x => x == selectedPort);
                        activeMenu.currentSelection = idx;
                    }
                }
            }
            else
            {
                vesselsList[index].SetTarget();
                selectedCelestial = null;
                selectedPort      = null;

                activeMenu.SetSelected(index, true);
            }
        }
 public void OnDestroy()
 {
     //free referenced modules
     extendAnimation = null;
     dockingNode     = null;
     anim            = null;
 }
Esempio n. 13
0
        public override void OnUpdate()
        {
            if (!pageActiveState || !JUtil.VesselIsInIVA(vessel))
            {
                return;
            }

            currentTarget     = FlightGlobals.fetch.VesselTarget;
            selectedCelestial = currentTarget as CelestialBody;
            selectedVessel    = currentTarget as Vessel;
            selectedPort      = currentTarget as ModuleDockingNode;
            selectedClaw      = currentTarget as ModuleGrappleNode;
            if (selectedPort != null)
            {
                selectedVessel = selectedPort.vessel;
            }
            if (selectedClaw != null)
            {
                selectedVessel = selectedClaw.vessel;
            }
            if (vessel.parts.Count != partCount)
            {
                FindReferencePoints();
                //UpdateUndockablesList();
            }
            if (!UpdateCheck())
            {
                return;
            }
            UpdateLists();
        }
Esempio n. 14
0
        /// <summary>
        /// Flag the lists as invalid due to craft changes / destruction.
        /// </summary>
        internal void InvalidateModuleLists()
        {
            listsInvalid = true;

            availableAblators.Clear();
            availableAirIntakes.Clear();
            availableAlternators.Clear();
            availableAlternatorOutput.Clear();
            availableDeployableWheels.Clear();
            availableEngines.Clear();
            availableFuelCells.Clear();
            availableFuelCellOutput.Clear();
            availableGenerators.Clear();
            availableGeneratorOutput.Clear();
            availableGimbals.Clear();
            availableMultiModeEngines.Clear();
            availableParachutes.Clear();
            availableRadars.Clear();
            availableRealChutes.Clear();
            availableSolarPanels.Clear();
            availableThrustReverser.Clear();
            availableWheelBrakes.Clear();
            availableWheelDamage.Clear();

            mainDockingNode = null;
        }
Esempio n. 15
0
        private void onSnapChanged(BaseField field, System.Object obj)
        {
            ModuleDockingNode mdn = part.GetComponent <ModuleDockingNode>();

            mdn.snapOffset   = snapAngle;
            mdn.snapRotation = enableSnap;
            MonoBehaviour.print("Set docking node module to snap angle: " + snapAngle + " enabled: " + enableSnap);
        }
        public void Start()
        {
            dockingNode    = part.FindModuleImplementing <ModuleDockingNode>();
            hasDockingNode = dockingNode != null;

            Fields["dockFSMState"].guiActive  = Fields["dockFSMState"].guiActiveUnfocused = hasDockingNode;
            Fields["dockOtherNode"].guiActive = Fields["dockOtherNode"].guiActiveUnfocused = hasDockingNode;
        }
Esempio n. 17
0
        // Celestial Menu
        private void TargetCelestial(int index, TextMenu.Item ti)
        {
            celestialsList[index].SetTarget();
            selectedVessel = null;
            selectedPort   = null;

            activeMenu.SetSelected(index, true);
        }
Esempio n. 18
0
        // Space Object Menu
        private void TargetSpaceObject(int index, TextMenu.Item ti)
        {
            spaceObjectsList[index].SetTarget();
            selectedCelestial = null;
            selectedPort      = null;

            activeMenu.SetSelected(index, true);
        }
        public void Start()
        {
            updateGUI();
            ModuleDockingNode mdn = part.GetComponent <ModuleDockingNode>();

            mdn.snapOffset   = snapAngle;
            mdn.snapRotation = enableSnap;
        }
 private void departureStage1()
 {
     if (RmmUtil.IsDocked(_vessel, _part))
     {
         ModuleDockingNode DockNode = _part.Modules.OfType <ModuleDockingNode>().FirstOrDefault();
         DockNode.Undock();
     }
     _departureStage = 2;
     _nextLogicTime  = Planetarium.GetUniversalTime() + 2;
 }
        private Part getDockPart()
        {
            ModuleDockingNode mdn = part.GetComponent <ModuleDockingNode>();

            if (mdn != null && mdn.otherNode != null)
            {
                return(mdn.otherNode.part);
            }
            return(null);
        }
Esempio n. 22
0
 public override void Load(ConfigNode node)
 {
     base.Load(node);
     part_node    = part.FindAttachNode(NodeID);
     docking_node = part.Modules.GetModule <ModuleDockingNode>();
     if (docking_node != null && docking_node.referenceAttachNode != NodeID)
     {
         docking_node = null;
     }
 }
Esempio n. 23
0
        bool can_restore()
        {
            //if hangar is not ready, return
            if (hangar_state == HangarState.Inactive)
            {
                ScreenMessager.showMessage("Activate the hangar first", 3);
                return(false);
            }
            if (hangar_gates.State != AnimatorState.Opened)
            {
                ScreenMessager.showMessage("Open hangar gates first", 3);
                return(false);
            }
            //if something is docked to the hangar docking port (if its present)
            ModuleDockingNode dport = part.Modules.OfType <ModuleDockingNode>().SingleOrDefault();

            if (dport != null && dport.vesselInfo != null)
            {
                ScreenMessager.showMessage("Cannot launch a vessel while another is docked", 3);
                return(false);
            }
            //if in orbit or on the ground and not moving
            switch (FlightGlobals.ClearToSave())
            {
            case ClearToSaveStatus.NOT_IN_ATMOSPHERE:
            {
                ScreenMessager.showMessage("Cannot launch a vessel while flying in atmosphere", 3);
                return(false);
            }

            case ClearToSaveStatus.NOT_UNDER_ACCELERATION:
            {
                ScreenMessager.showMessage("Cannot launch a vessel hangar is under accelleration", 3);
                return(false);
            }

            case ClearToSaveStatus.NOT_WHILE_ABOUT_TO_CRASH:
            {
                ScreenMessager.showMessage("Cannot launch a vessel while about to crush", 3);
                return(false);
            }

            case ClearToSaveStatus.NOT_WHILE_MOVING_OVER_SURFACE:
            {
                ScreenMessager.showMessage("Cannot launch a vessel while moving over the surface", 3);
                return(false);
            }
            }
            if (vessel.angularVelocity.magnitude > 0.003)
            {
                ScreenMessager.showMessage("Cannot launch a vessel while rotating", 3);
                return(false);
            }
            return(true);
        }
Esempio n. 24
0
 private ModuleDockingHatch GetHatchForDockingNode(ModuleDockingNode dockNode)
 {
     foreach (ModuleDockingHatch dockHatch in dockNode.part.Modules.OfType <ModuleDockingHatch>())
     {
         if (dockHatch.modDockNode == dockNode)
         {
             return(dockHatch);
         }
     }
     return(null);
 }
Esempio n. 25
0
        private void setDockingPortTarget(ModuleDockingNode portNode)
        {
            var vessel = portNode.GetVessel();

            //can't set target if the vessel is not loaded or is the active vessel
            if (!vessel.loaded || vessel.isActiveVessel)
            {
                return;
            }

            FlightGlobals.fetch.SetVesselTarget(portNode);
        }
        protected static void RestoreMainCamera()
        {
            DebugOutput("RestoreMainCamera");

            if (sCam != null)
            {
                sCam.transform.parent        = sOrigParent;
                sCam.transform.localPosition = sOrigPosition;
                sCam.transform.localRotation = sOrigRotation;
                sCam.SetFoV(sOrigFov);
                sCam.ActivateUpdate();

                if (FlightGlobals.ActiveVessel != null && HighLogic.LoadedScene == GameScenes.FLIGHT)
                {
                    //sCam.SetTarget(FlightGlobals.ActiveVessel.transform, FlightCamera.TargetMode.Transform);
                    sCam.SetTarget(FlightGlobals.ActiveVessel.transform, FlightCamera.TargetMode.Vessel);
                }

                sOrigParent = null;
            }
            if (sCurrentCamera != null)
            {
                sCurrentCamera.mt.SetCameraMode(CameraFilter.eCameraMode.Normal);
                sCurrentCamera.camActive = false;
            }
            sCurrentCamera            = null;
            Camera.main.nearClipPlane = sOrigClip;

            /////////////////////////////////////

            if (sOrigVesselTransformPart != null)
            {
                if (GameSettings.MODIFIER_KEY.GetKey(false))
                {
#if false
                    ModuleDockingNode mdn = sOrigVesselTransformPart.FindModuleImplementing <ModuleDockingNode>();
                    if (mdn != null)
                    {
                        sOrigVesselTransformPart.SetReferenceTransform(mdn.controlTransform);
                    }
                    else
#endif
                    {
                        // sOrigVesselTransformPart.SetReferenceTransform(sOrigVesselTransformPart.GetReferenceTransform());
                    }

                    FlightGlobals.ActiveVessel.SetReferenceTransform(sOrigVesselTransformPart, true);
                    ScreenMessages.PostScreenMessage(locControlPointRestored + " " + sOrigVesselTransformPart.partInfo.title);
                    sOrigVesselTransformPart = null;
                }
            }
            /////////////////////////////////////
        }
Esempio n. 27
0
        internal DockingPort(Part part)
        {
            Part = part;
            var internalPart = part.InternalPart;

            port   = internalPart.Module <ModuleDockingNode> ();
            shield = internalPart.Module <ModuleAnimateGeneric> ();
            if (port == null)
            {
                throw new ArgumentException("Part is not a docking port");
            }
        }
Esempio n. 28
0
        public void Start()
        {
            ModuleDockingNode[] dockModules = part.GetComponents <ModuleDockingNode>();
            if (dockingModuleIndex >= dockModules.Length)
            {
                MonoBehaviour.print("ERROR: Could not locate docking port by index: " + dockingModuleIndex + " only found: " + dockModules.Length + " docking modules on part.  Please check your part configuration for errors.");
                return;
            }
            ModuleDockingNode dockModule = dockModules[dockingModuleIndex];

            updateDockingModuleFieldNames(dockModule, portName);
        }
Esempio n. 29
0
 ReferenceFrame(
     Type type, global::CelestialBody body = null, global::Vessel vessel = null,
     ManeuverNode node = null, Part part = null, ModuleDockingNode dockingPort = null)
 {
     this.type     = type;
     this.body     = body;
     this.vesselId = vessel != null ? vessel.id : Guid.Empty;
     this.node     = node;
     //TODO: is it safe to use a part id of 0 to mean no part?
     this.partId      = part != null ? part.flightID : 0;
     this.dockingPort = dockingPort;
 }
Esempio n. 30
0
        private bool PointToReferenceCamera()
        {
            isReferenceCamera = true;
            referencePart     = ourVessel.GetReferenceTransformPart();
            ModuleDockingNode thatPort = null;
            ModuleGrappleNode thatClaw = null;

            if (referencePart != null)
            {
                foreach (PartModule thatModule in referencePart.Modules)
                {
                    thatPort = thatModule as ModuleDockingNode;
                    thatClaw = thatModule as ModuleGrappleNode;
                    if (thatPort != null || thatClaw != null)
                    {
                        break;
                    }
                }
            }

            if (thatPort != null)
            {
                if (!LocateCamera(referencePart, "dockingNode"))
                {
                    cameraPart                 = thatPort.part;
                    cameraTransform            = ourVessel.ReferenceTransform.gameObject;
                    isReferenceTransformCamera = true;
                }
                isReferenceClawCamera = false;
                return(CreateCameraObjects());
            }
            else if (thatClaw != null)
            {
                // Mihara: Dirty hack to get around the fact that claws have their reference transform inside the structure.
                if (LocateCamera(referencePart, "ArticulatedCap"))
                {
                    isReferenceClawCamera = true;
                    clawModule            = thatClaw;
                }
                else
                {
                    JUtil.LogMessage(this, "Claw was not a stock part. Falling back to reference transform position...");
                    cameraPart      = thatClaw.part;
                    cameraTransform = ourVessel.ReferenceTransform.gameObject;
                }

                return(CreateCameraObjects());
            }
            else
            {
                return(false);
            }
        }
Esempio n. 31
0
        public override void OnStart(StartState st)
        {
            base.OnStart(st);

            dockingNode = this.part.FindModuleImplementing<ModuleDockingNode>();

            //Hide the native events
            if (dockingNode != null)
            {
                dockingNode.Events["SetAsTarget"].guiActiveUnfocused = false;
                dockingNode.Events["UnsetTarget"].guiActiveUnfocused = false;
                //dockingNode.Events["MakeReferenceTransform"].guiActive = false;
            }
        }
 private void updateDockingModules(bool start)
 {
     //TODO only remove and replace modules if the new setup differs from the old
     if (topDockPartModule != null)
     {
         part.RemoveModule(topDockPartModule);
         topDockPartModule = null;
     }
     if (bottomDockPartModule != null)
     {
         part.RemoveModule(bottomDockPartModule);
         bottomDockPartModule = null;
     }
     updateTopDockModule(start);
     updateBottomDockModule(start);
 }
 //TODO load docking module config from sub-config nodes in the module node
 private void updateTopDockModule(bool start)
 {
     bool topNodeActive = topDockModule.model != null;
     if (topNodeActive && topDockPartModule == null)
     {
         ConfigNode topModuleNode = new ConfigNode("MODULE");
         topModuleNode.AddValue("name", "ModuleDockingNode");
         topModuleNode.AddValue("referenceAttachNode", topDockNode);
         topModuleNode.AddValue("useReferenceAttachNode", true);
         topModuleNode.AddValue("nodeTransformName", topDockName);
         topModuleNode.AddValue("controlTransformName", topDockName + "Control");
         topModuleNode.AddValue("nodeType", "size0, size1");
         topModuleNode.AddValue("captureRange", "0.1");
         topDockPartModule = (ModuleDockingNode)part.AddModule(topModuleNode);
         if (start) { topDockPartModule.OnStart(StartState.Editor); }
         topDockPartModule.referenceNode = part.FindAttachNode(topDockNode);
     }
     else if (!topNodeActive && topDockPartModule != null)
     {
         part.RemoveModule(topDockPartModule);
     }
     if (topNodeActive)
     {
         SSTUMultiDockingPort.updateDockingModuleFieldNames(topDockPartModule, "Top Port");
     }
 }
Esempio n. 34
0
        //Draw the right click context menu window contents
        private void drawContext(int windowID)
        {
            int _top = 0;
            if (GUI.Button(new Rect(0, _top, contextPos.width, 20), "Target Vessel", contextStyle))
            {
                if (contextActive != null) FlightGlobals.fetch.SetVesselTarget(contextActive.vessel);
                contextActive = null;
            }
            _top += Mathf.RoundToInt(contextStyle.fixedHeight);
            if (GUI.Button(new Rect(0, _top, contextPos.width, 20), "Control Vessel", contextStyle))
            {
                saveConfig();
                //GamePersistence.SaveGame("persistent", HighLogic.SaveFolder, SaveMode.OVERWRITE);
                if (contextActive != null) FlightGlobals.SetActiveVessel(contextActive.vessel);
                contextActive = null;
            }
            _top += Mathf.RoundToInt(contextStyle.fixedHeight);
            const string renameStr = "Rename Vessel";
            String renameHint = string.Empty;
            if (contextActive != null && !contextActive.vessel.loaded)
            {
                //renameStr = "Queue Vessel Rename";
                renameHint = "Too far to rename";
                GUI.enabled = false;
            }
            if (GUI.Button(new Rect(0, _top, contextPos.width, 20), new GUIContent(renameStr, renameHint), contextStyle))
            {
                if (contextActive != null) contextActive.vessel.RenameVessel();
                contextActive = null;
            }
            GUI.enabled = true;

            _top += Mathf.RoundToInt(contextStyle.fixedHeight);
            if (contextActive == null) return;
            lastActiveDockingNode = activeDockingNode;
            activeDockingNode = null;
            foreach (ModuleDockingNode m in contextActive.availableDocks)
            {
                if (Vector3.Distance(FlightGlobals.ActiveVessel.GetTransform().position, m.GetTransform().position) >= 196.0f)
                    GUI.enabled = false;
                GUIStyle temp = contextStyle;
                if (FlightGlobals.fetch.VesselTarget != null && FlightGlobals.fetch.VesselTarget.Equals(m))
                    temp = contextStyle2;

                if (new Rect(0, _top, contextPos.width, 20).Contains(Event.current.mousePosition))
                {
                    m.part.SetHighlightColor(Color.red);
                    m.part.SetHighlight(true);
                }
                else
                {
                    m.part.SetHighlightDefault();
                    m.part.SetHighlight(false);
                }

                if (GUI.Button(new Rect(0, _top, contextPos.width, 20), "Target " + m.part.partInfo.title, temp))
                {
                    FlightGlobals.fetch.SetVesselTarget(m);
                    m.part.SetHighlightDefault();
                    m.part.SetHighlight(false);
                    contextActive = null;
                }
                GUI.enabled = true;
                _top += Mathf.RoundToInt(contextStyle.fixedHeight);
            }
        }
        private void init(bool start)
        {
            if (initialized) { return; }
            initialized = true;

            topNodeNames = SSTUUtils.parseCSV(topManagedNodes);
            bottomNodeNames = SSTUUtils.parseCSV(bottomManagedNodes);
            ConfigNode node = SSTUConfigNodeUtils.parseConfigNode(configNodeData);

            coreModules = SingleModelData.parseModels(node.GetNodes("CORE"));

            List<ConfigNode> tops = new List<ConfigNode>();
            List<ConfigNode> bottoms = new List<ConfigNode>();
            ConfigNode[] mNodes = node.GetNodes("CAP");
            ConfigNode mNode;
            int len = mNodes.Length;
            for (int i = 0; i < len; i++)
            {
                mNode = mNodes[i];
                if (mNode.GetBoolValue("useForTop", true)) { tops.Add(mNode); }
                if (mNode.GetBoolValue("useForBottom", true)) { bottoms.Add(mNode); }
            }
            topModules = SingleModelData.parseModels(tops.ToArray());
            bottomModules = SingleModelData.parseModels(bottoms.ToArray());
            tops.Clear();
            bottoms.Clear();

            mNodes = node.GetNodes("DOCK");
            len = mNodes.Length;
            for (int i = 0; i < len; i++)
            {
                mNode = mNodes[i];
                if (mNode.GetBoolValue("useForTop", true)) { tops.Add(mNode); }
                if (mNode.GetBoolValue("useForBottom", true)) { bottoms.Add(mNode); }
            }
            topDockModules = SingleModelData.parseModels(tops.ToArray());
            bottomDockModules = SingleModelData.parseModels(bottoms.ToArray());
            tops.Clear();
            bottoms.Clear();

            mNodes = node.GetNodes("SOLAR");
            len = mNodes.Length;
            solarModules = new SolarData[len];
            for (int i = 0; i < len; i++)
            {
                mNode = mNodes[i];
                solarModules[i] = new SolarData(mNode);
            }

            topDockModule = SingleModelData.findModel(topDockModules, currentTopDock);
            topModule = SingleModelData.findModel(topModules, currentTop);
            coreModule = SingleModelData.findModel(coreModules, currentCore);
            bottomModule = SingleModelData.findModel(bottomModules, currentBottom);
            bottomDockModule = SingleModelData.findModel(bottomDockModules, currentBottomDock);
            solarModule = Array.Find(solarModules, m => m.name == currentSolar);//TODO cleanup
            if (!topModule.isValidTextureSet(currentTopTexture)) { currentTopTexture = topModule.getDefaultTextureSet(); }
            if (!coreModule.isValidTextureSet(currentCoreTexture)) { currentCoreTexture = coreModule.getDefaultTextureSet(); }
            if (!bottomModule.isValidTextureSet(currentBottomTexture)) { currentBottomTexture = bottomModule.getDefaultTextureSet(); }
            restoreModels();
            updateModulePositions();
            updateMass();
            updateCost();
            updateAttachNodes(false);
            if (HighLogic.LoadedSceneIsEditor || HighLogic.LoadedSceneIsFlight)
            {
                ModuleDockingNode[] mdns = part.GetComponents<ModuleDockingNode>();
                if (mdns.Length > 0)
                {
                    if (topDockModule.model != null)
                    {
                        topDockPartModule = mdns[0];
                    }
                    if (bottomDockModule.model != null)
                    {
                        bottomDockPartModule = mdns.Length > 1 ? mdns[1] : mdns[0];
                    }
                }
                updateDockingModules(start);
            }
            //resources are updated in Start(), to ensure that the dependent modules have loaded
        }
Esempio n. 36
0
        public override void OnUpdate()
        {
            if (!pageActiveState || !JUtil.VesselIsInIVA(vessel))
            {
                return;
            }

            currentTarget = FlightGlobals.fetch.VesselTarget;
            selectedCelestial = currentTarget as CelestialBody;
            selectedVessel = currentTarget as Vessel;
            selectedPort = currentTarget as ModuleDockingNode;
            selectedClaw = currentTarget as ModuleGrappleNode;
            if (selectedPort != null)
            {
                selectedVessel = selectedPort.vessel;
            }
            if (selectedClaw != null)
            {
                selectedVessel = selectedClaw.vessel;
            }
            if (vessel.parts.Count != partCount)
            {
                FindReferencePoints();
                //UpdateUndockablesList();
            }
            if (!UpdateCheck())
                return;
            UpdateLists();
        }
 public override void OnStart(PartModule.StartState state)
 {
     base.OnStart(state);
     this.module = base.part.FindModuleImplementing<ModuleDockingNode>();
 }
 private ModuleDockingHatch GetHatchForDockingNode(ModuleDockingNode dockNode)
 {
     IEnumerator<ModuleDockingHatch> epHatches = dockNode.part.Modules.OfType<ModuleDockingHatch>().GetEnumerator();
       while (epHatches.MoveNext())
       {
     if (epHatches.Current == null) continue;
     if (epHatches.Current.modDockNode == dockNode)
     {
       return epHatches.Current;
     }
       }
       return null;
 }
Esempio n. 39
0
 private ModuleDockingHatch GetHatchForDockingNode(ModuleDockingNode dockNode)
 {
     foreach (ModuleDockingHatch dockHatch in dockNode.part.Modules.OfType<ModuleDockingHatch>())
     {
         if (dockHatch.modDockNode == dockNode)
         {
             return dockHatch;
         }
     }
     return null;
 }
Esempio n. 40
0
        // Vessel Menu
        private void TargetVessel(int index, TextMenu.Item ti)
        {
            if (selectedVessel == vesselsList[index].vessel)
            {
                // Already selected.  Are there ports?
                UpdatePortsList();
                if (portsList.Count > 0)
                {
                    currentMenu = MenuList.Ports;

                    activeMenu = new TextMenu();
                    activeMenu.rightColumnWidth = 8;

                    activeMenu.labelColor = nameColorTag;
                    activeMenu.selectedColor = selectedColorTag;
                    activeMenu.disabledColor = unavailableColorTag;
                    activeMenu.rightTextColor = distanceColorTag;

                    UpdateLists();

                    if (selectedPort != null)
                    {
                        int idx = portsList.FindIndex(x => x == selectedPort);
                        activeMenu.currentSelection = idx;
                    }
                }
            }
            else
            {
                vesselsList[index].SetTarget();
                selectedCelestial = null;
                selectedPort = null;

                activeMenu.SetSelected(index, true);
            }
        }
        private void FetchCommonData()
        {
            localGeeASL = vessel.orbit.referenceBody.GeeASL * gee;
            coM = vessel.findWorldCenterOfMass();
            localGeeDirect = FlightGlobals.getGeeForceAtPosition(coM).magnitude;
            up = (coM - vessel.mainBody.position).normalized;
            forward = vessel.GetTransform().up;
            right = vessel.GetTransform().right;
            north = Vector3d.Exclude(up, (vessel.mainBody.position + vessel.mainBody.transform.up * (float)vessel.mainBody.Radius) - coM).normalized;
            rotationSurface = Quaternion.LookRotation(north, up);
            rotationVesselSurface = Quaternion.Inverse(Quaternion.Euler(90, 0, 0) * Quaternion.Inverse(vessel.GetTransform().rotation) * rotationSurface);

            velocityVesselOrbit = vessel.orbit.GetVel();
            velocityVesselSurface = velocityVesselOrbit - vessel.mainBody.getRFrmVel(coM);

            speedVertical = Vector3d.Dot(velocityVesselSurface, up);
            speedVerticalRounded = Math.Ceiling(speedVertical * 20) / 20;
            target = FlightGlobals.fetch.VesselTarget;
            node = vessel.patchedConicSolver.maneuverNodes.Count > 0 ? vessel.patchedConicSolver.maneuverNodes[0] : null;
            time = Planetarium.GetUniversalTime();
            FetchAltitudes();
            terrainHeight = altitudeASL - altitudeTrue;
            if (time >= lastTimePerSecond + 1) {
                terrainDelta = terrainHeight - lastTerrainHeight;
                lastTerrainHeight = terrainHeight;
                lastTimePerSecond = time;
            }

            horzVelocity = (velocityVesselSurface - (speedVertical * up)).magnitude;
            horzVelocityForward = Vector3d.Dot(velocityVesselSurface, forward);
            horzVelocityRight = Vector3d.Dot(velocityVesselSurface, right);

            atmPressure = FlightGlobals.getStaticPressure(altitudeASL, vessel.mainBody);
            dynamicPressure = 0.5 * velocityVesselSurface.sqrMagnitude * vessel.atmDensity;

            if (target != null) {
                targetSeparation = vessel.GetTransform().position - target.GetTransform().position;
                targetOrientation = target.GetTransform().rotation;

                targetVessel = target as Vessel;
                targetBody = target as CelestialBody;
                targetDockingNode = target as ModuleDockingNode;

                targetDistance = Vector3.Distance(target.GetTransform().position, vessel.GetTransform().position);

                // This is kind of messy.
                targetOrbitSensibility = false;
                // All celestial bodies except the sun have orbits that make sense.
                targetOrbitSensibility |= targetBody != null && targetBody != Planetarium.fetch.Sun;

                if (targetVessel != null)
                    targetOrbitSensibility = JUtil.OrbitMakesSense(targetVessel);
                if (targetDockingNode != null)
                    targetOrbitSensibility = JUtil.OrbitMakesSense(target.GetVessel());

                if (targetOrbitSensibility)
                    targetOrbit = target.GetOrbit();

                // TODO: Actually, there's a lot of nonsensical cases here that need more reasonable handling.
                // Like what if we're targeting a vessel landed on a moon of another planet?...
                if (targetOrbit != null) {
                    velocityRelativeTarget = vessel.orbit.GetVel() - target.GetOrbit().GetVel();
                } else {
                    velocityRelativeTarget = vessel.orbit.GetVel();
                }

                // If our target is somehow our own celestial body, approach speed is equal to vertical speed.
                if (targetBody == vessel.mainBody)
                    approachSpeed = speedVertical;
                // In all other cases, that should work. I think.
                approachSpeed = Vector3d.Dot(velocityRelativeTarget, (target.GetTransform().position - vessel.GetTransform().position).normalized);
            } else {
                velocityRelativeTarget = targetSeparation = Vector3d.zero;
                targetOrbit = null;
                targetDistance = 0;
                approachSpeed = 0;
                targetBody = null;
                targetVessel = null;
                targetDockingNode = null;
                targetOrientation = vessel.GetTransform().rotation;
                targetOrbitSensibility = false;
            }
            orbitSensibility = JUtil.OrbitMakesSense(vessel);
            if (vessel.situation == Vessel.Situations.SUB_ORBITAL || vessel.situation == Vessel.Situations.FLYING) {
                // Mental note: the local g taken from vessel.mainBody.GeeASL will suffice.
                //  t = (v+sqrt(v²+2gd))/g or something.

                // What is the vertical component of current acceleration?
                double accelUp = Vector3d.Dot(vessel.acceleration, up);

                double altitude = altitudeTrue;
                if (vessel.mainBody.ocean && altitudeASL > 0.0) {
                    // AltitudeTrue shows distance above the floor of the ocean,
                    // so use ASL if it's closer in this case, and we're not
                    // already below SL.
                    altitude = Math.Min(altitudeASL, altitudeTrue);
                }

                if (accelUp < 0.0 || speedVertical >= 0.0 || Planetarium.TimeScale > 1.0) {
                    // If accelUp is negative, we can't use it in the general
                    // equation for finding time to impact, since it could
                    // make the term inside the sqrt go negative.
                    // If we're going up, we can use this as well, since
                    // the precision is not critical.
                    // If we are warping, accelUp is always zero, so if we
                    // do not use this case, we would fall to the simple
                    // formula, which is wrong.
                    secondsToImpact = (speedVertical + Math.Sqrt(speedVertical * speedVertical + 2 * localGeeASL * altitude)) / localGeeASL;
                } else if (accelUp > 0.005) {
                    // This general case takes into account vessel acceleration,
                    // so estimates on craft that include parachutes or do
                    // powered descents are more accurate.
                    secondsToImpact = (speedVertical + Math.Sqrt(speedVertical * speedVertical + 2 * accelUp * altitude)) / accelUp;
                } else {
                    // If accelUp is small, we get floating point precision
                    // errors that tend to make secondsToImpact get really big.
                    secondsToImpact = altitude / -speedVertical;
                }

                // MOARdV: I think this gets the computation right.  High thrust will
                // result in NaN, which is already handled.
                /*
                double accelerationAtMaxThrust = localG - (totalMaximumThrust / totalShipWetMass);
                double timeToImpactAtMaxThrust = (speedVertical + Math.Sqrt(speedVertical * speedVertical + 2 * accelerationAtMaxThrust * altitude)) / accelerationAtMaxThrust;
                bestPossibleSpeedAtImpact = speedVertical - accelerationAtMaxThrust * timeToImpactAtMaxThrust;
                if (double.IsNaN(bestPossibleSpeedAtImpact))
                    bestPossibleSpeedAtImpact = 0;
                */
                bestPossibleSpeedAtImpact = SpeedAtImpact(totalMaximumThrust, totalShipWetMass, localGeeASL, speedVertical, altitude);
                expectedSpeedAtImpact = SpeedAtImpact(totalCurrentThrust, totalShipWetMass, localGeeASL, speedVertical, altitude);

            } else {
                secondsToImpact = Double.NaN;
                bestPossibleSpeedAtImpact = 0;
                expectedSpeedAtImpact = 0;
            }
        }
Esempio n. 42
0
        // Space Object Menu
        private void TargetSpaceObject(int index, TextMenu.Item ti)
        {
            spaceObjectsList[index].SetTarget();
            selectedCelestial = null;
            selectedPort = null;

            activeMenu.SetSelected(index, true);
        }
Esempio n. 43
0
        // Celestial Menu
        private void TargetCelestial(int index, TextMenu.Item ti)
        {
            celestialsList[index].SetTarget();
            selectedVessel = null;
            selectedPort = null;

            activeMenu.SetSelected(index, true);
        }
Esempio n. 44
0
        private static string GetPortName(ModuleDockingNode port)
        {
            if (dpaiFound)
            {
                PartModule dockingNode = null;
                for (int i = 0; i < port.part.Modules.Count; i++)
                {
                    var module = port.part.Modules[i];
                    if (module.GetType() == dpaiModuleDockingNodeNamed)
                    {
                        dockingNode = module;
                        break;
                    }
                }

                if (dockingNode != null)
                {
                    return (string)dpaiPortName.GetValue(dockingNode);
                }
            }

            return port.part.partInfo.title;
        }
Esempio n. 45
0
 public void Start()
 {
     MonoBehaviour.print("DockPortFix, Start() " + GetHashCode());
     if (!HighLogic.LoadedSceneIsFlight) { return; }
     dockNode = part.GetComponents<ModuleDockingNode>()[portIndex];
     dockNodeUndockEvent = dockNode.Events[nameof(dockNode.Undock)];
     dockNodeUndockSameEvent = dockNode.Events[nameof(dockNode.UndockSameVessel)];
     dockNodeDecoupleEvent = dockNode.Events[nameof(dockNode.Decouple)];
     forceUndockEvent = Events[nameof(forceUndock)];
     forceUndockEvent.guiName = "Force " + dockNodeUndockEvent.guiName;
     updateState();
 }
 // This method allows us to check if a specified ModuleDockingNode is one that this hatch is attached to
 internal bool IsRelatedDockingNode(ModuleDockingNode dockNode)
 {
   if (dockNode.nodeTransformName == this.docNodeTransformName)
   {
     this.modDockNode = dockNode;
     return true;
   }
   if (dockNode.referenceAttachNode == this.docNodeAttachmentNodeName)
   {
     this.modDockNode = dockNode;
     return true;
   }
   return false;
 }
Esempio n. 47
0
        private bool CheckForNodeDockedToPart(ModuleDockingNode thisNode, Part otherPart)
        {
            bool retVal = false;

            // TODO remove debugging
            //Debug.Log("thisNode.dockedPartUId=" + thisNode.dockedPartUId + " otherPart.flightID=" + otherPart.flightID + " thisNode.state:" + thisNode.state);

            // if (otherPart == thisNode.part.vessel[thisNode.dockedPartUId])
            if (thisNode.dockedPartUId == otherPart.flightID)
            {
                //Debug.Log("IDs match");
                if(thisNode.state == "Docked (dockee)")
                {
                    //Debug.Log("this module is docked (dockee) to the other part");
                    retVal = true;
                }
                else if (thisNode.state == "Docked (docker)")
                {
                    //Debug.Log("this module is docked (docker) to the other part");
                    retVal = true;
                }
                else if (thisNode.state == "Acquire")
                {
                    Debug.LogWarning("this module is in the Acquire state, which might mean it is in the process of docking.");
                    retVal = true;
                }
            }
            return retVal;
        }
        /// <summary>
        /// Convert the textual docking node state into an enum, so we don't
        /// need to do string compares.
        /// </summary>
        /// <param name="whichNode"></param>
        /// <returns></returns>
        internal static DockingNodeState GetNodeState(ModuleDockingNode whichNode)
        {
            if (whichNode == null)
            {
                return DockingNodeState.UNKNOWN;
            }

            switch (whichNode.state)
            {
                case "PreAttached":
                    return DockingNodeState.PREATTACHED;
                case "Docked (docker)":
                    return DockingNodeState.DOCKED;
                case "Docked (dockee)":
                    return DockingNodeState.DOCKED;
                case "Ready":
                    return DockingNodeState.READY;
                default:
                    return DockingNodeState.UNKNOWN;
            }
        }
        /// <summary>
        /// Flag the lists as invalid due to craft changes / destruction.
        /// </summary>
        internal void InvalidateModuleLists()
        {
            listsInvalid = true;

            availableAblators.Clear();
            availableAirIntakes.Clear();
            availableAlternators.Clear();
            availableAlternatorOutput.Clear();
            availableDeployableWheels.Clear();
            availableEngines.Clear();
            availableFuelCells.Clear();
            availableFuelCellOutput.Clear();
            availableGenerators.Clear();
            availableGeneratorOutput.Clear();
            availableGimbals.Clear();
            availableMultiModeEngines.Clear();
            availableParachutes.Clear();
            availableRadars.Clear();
            availableRealChutes.Clear();
            availableSolarPanels.Clear();
            availableThrustReverser.Clear();
            availableWheelBrakes.Clear();
            availableWheelDamage.Clear();

            mainDockingNode = null;
        }
Esempio n. 50
0
 public DockingPortValue(ModuleDockingNode module)
     : base(module.part)
 {
     this.module = module;
 }
Esempio n. 51
0
 public DockingPortValue(ModuleDockingNode module, SharedObjects sharedObj)
     : base(module.part, sharedObj)
 {
     this.module = module;
     DockingInitializeSuffixes();
 }
Esempio n. 52
0
 public DockingPortValue(global::Part part, ModuleDockingNode module)
     : base(part)
 {
     this.module = module;
 }
 private bool CheckModuleDockingNode()
 {
   if (null == this.modDockNode)
   {
     // We do not know which ModuleDockingNode we are attached to yet. Try to find one.
     foreach (ModuleDockingNode dockNode in this.part.Modules.OfType<ModuleDockingNode>())
     {
       if (IsRelatedDockingNode(dockNode))
       {
         this.modDockNode = dockNode;
         return true;
       }
     }
   }
   else
   {
     return true;
   }
   return false;
 }
        public override void OnStart(StartState state)
        {
            base.OnStart(state);

            /*switch (state)
            {
                case StartState.Editor:
                case StartState.None:
                    Logging.PostDebugMessage(this, "Refusing to start when not in flight.");
                    return;
                default:
                    break;
            }*/

            if (this.ValidSizes != string.Empty)
            {
                this.validSizes = new List<string>();

                string[] splitSizes = this.ValidSizes.Split(',');

                for (int idx = 0; idx < splitSizes.Length; idx++)
                {
                    this.validSizes.Add(splitSizes[idx].Trim());
                }

                this.validSizes.Sort();
                this.validSizes.Reverse();

                this.defaultSize = this.validSizes[0];
            }

            if (this.validSizes == null || this.validSizes.Count == 0)
            {
                Logging.PostDebugMessage(this,
                    "Refusing to start because our module was configured poorly." +
                    "\n\tvalidSizes: {0}",
                    this.validSizes
                );
                return;
            }

            Logging.PostDebugMessage(this, "Loaded!" +
                "\n\tdefaultSize: {0}",
                this.defaultSize
            );

            this.timeoutTimer = new System.Diagnostics.Stopwatch();

            this.dockingModule = this.part.getFirstModuleOfType<ModuleDockingNode>();

            if (this.dockingModule == null)
            {
                Logging.PostDebugMessage(this, "Failed startup because a docking module could not be found.");
                return;
            }

            this.dockingModule.Fields["nodeType"].isPersistant = true;

            // If we're not in the editor, not docked, and not preattached, set the current size to the default size.
            if (
                !HighLogic.LoadedSceneIsEditor &&
                this.dockingModule.state != "Docked" &&
                this.dockingModule.state != "PreAttached"
            )
            {
                this.currentSize = this.defaultSize;
            }

            #if DEBUG
            this.dockingModule.Fields["nodeType"].guiActive = true;
            this.dockingModule.Fields["nodeType"].guiName = "Node Size";
            #endif

            if (this.dockingModule.referenceAttachNode != string.Empty)
            {
                Logging.PostDebugMessage(this,
                    string.Format("referenceAttachNode string: {0}", this.dockingModule.referenceAttachNode));

                AttachNode node;
                for (int nIdx = 0; nIdx < this.part.attachNodes.Count; nIdx++)
                {
                    node = this.part.attachNodes[nIdx];

                    if (node.id == this.dockingModule.referenceAttachNode)
                    {
                        this.referenceAttachNode = node;
                        break;
                    }
                }

                Logging.PostDebugMessage(this,
                    string.Format("referenceAttachNode: {0}", this.referenceAttachNode));
            }

            this.acquireRangeSqr = this.dockingModule.acquireRange * this.dockingModule.acquireRange;

            var config = KSP.IO.PluginConfiguration.CreateForType<ModuleAdaptiveDockingNode>();
            config.load();

            this.vesselFilterDistanceSqr = config.GetValue("vesselFilterDistance", 1000d);
            config.SetValue("vesselFilterDistance", this.vesselFilterDistanceSqr);

            this.vesselFilterDistanceSqr *= this.vesselFilterDistanceSqr;

            config.save();

            this.hasAttachedState = !this.hasAttachedPart;

            Logging.PostDebugMessage(this, "Started!",
                string.Format("dockingModule: {0}", this.dockingModule)
            );
        }
    // Method that can be used to set up the ModuleDockingNode that this ModuleDockingHatch refers to.
    public void AttachModuleDockingNode(ModuleDockingNode _modDocNode)
    {
      this.modDockNode = _modDocNode;

      this.docNodeTransformName = _modDocNode.nodeTransformName;
      this.docNodeAttachmentNodeName = _modDocNode.referenceAttachNode;
    }
 private bool CheckModuleDockingNode()
 {
     if (null == modDockNode)
       {
     // We do not know which ModuleDockingNode we are attached to yet. Try to find one.
     IEnumerator<ModuleDockingNode> eNodes = part.Modules.OfType<ModuleDockingNode>().GetEnumerator();
     while (eNodes.MoveNext())
     {
       if (eNodes.Current == null) continue;
       if (IsRelatedDockingNode(eNodes.Current))
       {
     modDockNode = eNodes.Current;
     return true;
       }
     }
       }
       else
       {
     return true;
       }
       return false;
 }
		/*
		 * Methods
		 * */
		// Runs when each new part is started.
		public override void OnStart(StartState st)
		{
			this.dockingNodeModule = (ModuleDockingNode)base.part.Modules["ModuleDockingNode"];

			PartModule needle;

			for (int idx = 0; idx < base.part.Modules.Count; idx++)
			{
				needle = base.part.Modules[idx];

				if (needle is ModuleAnimateGeneric)
				{
					if (((ModuleAnimateGeneric)needle).animationName == this.deployAnimationControllerName)
					{
						this.deployAnimation = (ModuleAnimateGeneric)needle;
						break;
					}
				}
			}

			// If we've loaded a deployAnimationControllerName from the cfg...

			// Start the underlying ModuleDockingNode.
			base.OnStart(st);

			ModuleDockingNode prefabModule = PartLoader.getPartInfoByName(this.part.partInfo.name)
				.partPrefab.getFirstModuleOfType<ModuleDockingNode>();

			TweakableTools.InitializeTweakable<ModuleTweakableDockingNode>(
				this.Fields["acquireRange"].uiControlCurrent(),
				ref this.acquireRange,
				ref this.dockingNodeModule.acquireRange,
				prefabModule.acquireRange
			);

			TweakableTools.InitializeTweakable<ModuleTweakableDockingNode>(
				this.Fields["acquireForce"].uiControlCurrent(),
				ref this.acquireForce,
				ref this.dockingNodeModule.acquireForce,
				prefabModule.acquireForce
			);

			TweakableTools.InitializeTweakable<ModuleTweakableDockingNode>(
				this.Fields["acquireTorque"].uiControlCurrent(),
				ref this.acquireTorque,
				ref this.dockingNodeModule.acquireTorque,
				prefabModule.acquireForce
			);

			TweakableTools.InitializeTweakable<ModuleTweakableDockingNode>(
				this.Fields["undockEjectionForce"].uiControlCurrent(),
				ref this.undockEjectionForce,
				ref this.dockingNodeModule.undockEjectionForce,
				prefabModule.undockEjectionForce
			);

			TweakableTools.InitializeTweakable<ModuleTweakableDockingNode>(
				this.Fields["minDistanceToReEngage"].uiControlCurrent(),
				ref this.minDistanceToReEngage,
				ref this.dockingNodeModule.minDistanceToReEngage,
				prefabModule.minDistanceToReEngage
			);

			this.Fields["maxRollAngle"].uiControlFlight.controlEnabled = false;

			this.maxRollAngle = Mathf.Acos(this.minRollDotProduct) * 180f / Mathf.PI;
			this.dockingNodeModule.acquireMinRollDot = this.minRollDotProduct * this.minRollDotProduct;
			this.dockingNodeModule.captureMinRollDot = this.minRollDotProduct;

			this.lastMaxRollAngle = this.maxRollAngle;

			// If we have a tweakable AttachNode, use it.
			if (this.TDNnodeName != string.Empty)
			{
				this.attachNode = base.part.findAttachNode(this.TDNnodeName);
			}

			base.part.attachRules.allowStack = this.IsOpen | this.AlwaysAllowStack;

			this.dockingNodeModule.Events["EnableXFeed"].guiActive = false;
			this.dockingNodeModule.Events["DisableXFeed"].guiActive = false;

			this.dockingNodeModule.Events["EnableXFeed"].guiActiveEditor = false;
			this.dockingNodeModule.Events["DisableXFeed"].guiActiveEditor = false;

			this.dockingNodeModule.Events["EnableXFeed"].active = false;
			this.dockingNodeModule.Events["DisableXFeed"].active = false;

			/* @subclass
			ModuleStagingToggle stagingToggleModule;

			if (this.part.tryGetFirstModuleOfType<ModuleStagingToggle>(out stagingToggleModule))
			{
				stagingToggleModule.OnToggle += new ModuleStagingToggle.ToggleEventHandler(this.OnStagingToggle);
			}
			*/

			// Yay debugging!
			this.LogDebug(
				"{0}: Started with assembly version {4}." +
				"\n\tdeployAnimationModule={1}, attachNode={2}, TDNnodeName={3}, attachedPart={5}, fuelCrossFeed={6}",
				this.GetType().Name,
				this.deployAnimation,
				this.attachNode,
				this.TDNnodeName,
				this.GetType().Assembly.GetName().Version,
				this.attachedPart
			);
		}
        /// <summary>
        /// Refresh docking node data, including selecting the "reference"
        /// docking node (for docking node control).
        /// </summary>
        private void FetchDockingNodeData()
        {
            mainDockingNode = null;
            mainDockingNodeState = DockingNodeState.UNKNOWN;

            Part referencePart = vessel.GetReferenceTransformPart();
            if (referencePart != null)
            {
                ModuleDockingNode node = referencePart.FindModuleImplementing<ModuleDockingNode>();
                if (node != null)
                {
                    // The current reference part is a docking node, so we
                    // choose it.
                    mainDockingNode = node;
                }
            }

            if (mainDockingNode == null)
            {
                uint launchId;
                Part currentPart = JUtil.DeduceCurrentPart(vessel);
                if (currentPart == null)
                {
                    launchId = 0u;
                }
                else
                {
                    launchId = currentPart.launchID;
                }

                for (int i = 0; i < vessel.parts.Count; ++i)
                {
                    if (vessel.parts[i].launchID == launchId)
                    {
                        ModuleDockingNode node = vessel.parts[i].FindModuleImplementing<ModuleDockingNode>();
                        if (node != null)
                        {
                            // We found a docking node that has the same launch
                            // ID as the current IVA part, so we consider it our
                            // main docking node.
                            mainDockingNode = node;
                            break;
                        }
                    }
                }
            }

            mainDockingNodeState = GetNodeState(mainDockingNode);
        }