예제 #1
0
        public static string GetGreatestCommonNodeType(ModuleAdaptiveDockingNode n1, ModuleAdaptiveDockingNode n2)
        {
            int count1 = 0;
            int count2 = 0;

            while (count1 < n1.validSizes.Count && count2 < n2.validSizes.Count)
            {
                int compareResult;

                compareResult = n1.validSizes[count1].CompareTo(n2.validSizes[count2]);

                if (compareResult == 0)
                {
                    return(n1.validSizes[count1]);
                }
                else if (compareResult > 0)
                {
                    count1++;
                }
                else
                {
                    count2++;
                }
            }

            return(string.Empty);
        }
예제 #2
0
        public void LateUpdate()
        {
            if (HighLogic.LoadedSceneIsEditor)
            {
                Logging.PostDebugMessage(this, "LateUpdate", string.Format("attachedPart: {0}", this.attachedPart));

                if (this.hasAttachedPart != this.hasAttachedState)
                {
                    this.hasAttachedState = this.hasAttachedPart;

                    if (this.attachedPart != null)
                    {
                        ModuleDockingNode attachedNode = this.attachedPart.getFirstModuleOfType <ModuleDockingNode>();

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

                        if (attachedNode != null)
                        {
                            ModuleAdaptiveDockingNode attachedADN = this.attachedPart
                                                                    .getFirstModuleOfType <ModuleAdaptiveDockingNode>();

                            if (attachedADN != null && attachedADN.currentSize != this.currentSize)
                            {
                                this.currentSize = GetGreatestCommonNodeType(this, attachedADN);

                                Logging.PostDebugMessage(this,
                                                         string.Format("Attached to AdaptiveDockingNode, setting currentSize = {0}",
                                                                       this.currentSize)
                                                         );
                            }
                            else if (attachedNode.nodeType != this.currentSize)
                            {
                                this.currentSize = attachedNode.nodeType;

                                Logging.PostDebugMessage(this,
                                                         string.Format("Attached to ModuleDockingNode, setting currentSize = {0}",
                                                                       this.currentSize)
                                                         );
                            }
                        }
                    }
                }
            }
        }
예제 #3
0
        public void FixedUpdate()
        {
            if (
                HighLogic.LoadedSceneIsFlight &&
                FlightGlobals.Vessels != null &&
                this.vessel != null &&
                this.dockingModule != null
                )
            {
                                #if DEBUG
                bool foundApproach = false;
                                #endif

                PooledDebugLogger verboseLog = PooledDebugLogger.New(this);

                                #if DEBUG
                try
                {
                                #endif

                verboseLog.AppendFormat(" ({0}_{1}) on {2}",
                                        this.part.partInfo.name, this.part.craftID, this.vessel.vesselName);
                verboseLog.AppendFormat("\nChecking within acquireRangeSqr: {0}", this.acquireRangeSqr);

                verboseLog.AppendFormat("this.dockingModule: {0}\n", this.dockingModule == null ?
                                        "null" : this.dockingModule.ToString());

                verboseLog.AppendFormat("this.dockingModule.state: {0}\n",
                                        this.dockingModule == null || this.dockingModule.state == null ?
                                        "null" :this.dockingModule.state.ToString());

                // If we're already docked or pre-attached...
                if (this.dockingModule.state == "Docked" || this.dockingModule.state == "PreAttached")
                {
                    // ...and if the timeout timer is running...
                    if (this.timeoutTimer.IsRunning)
                    {
                        // ...reset the timeout timer
                        this.timeoutTimer.Reset();
                    }

                    // ...skip this check
                    return;
                }

                // If the timeout timer is running, we found a match recently.  If we haven't found a match in more than
                // five seconds, it's not recent anymore, so reset our size to default.
                if (this.timeoutTimer.IsRunning && this.timeoutTimer.ElapsedMilliseconds > 5000)
                {
                    verboseLog.AppendFormat("\nNo target detected within 5 seconds, timing out.");

                    if (this.dockingModule.state != "Docked")
                    {
                        verboseLog.AppendFormat("\nReverting to default nodeType: {0}", this.defaultSize);
                        this.currentSize = this.defaultSize;
                    }

                    this.timeoutTimer.Reset();
                }

                bool foundTargetNode     = false;
                float closestNodeDistSqr = this.acquireRangeSqr * 4f;

                verboseLog.Append("Starting Vessels loop.");

                // Check all vessels for potential docking targets
                Vessel vessel;
                for (int vIdx = 0; vIdx < FlightGlobals.Vessels.Count; vIdx++)
                {
                    vessel = FlightGlobals.Vessels[vIdx];
                    if (vessel == null)
                    {
                        verboseLog.Append("Skipping null vessel.");
                        continue;
                    }

                    // Skip vessels that are just way too far away.
                    if (this.vessel.sqrDistanceTo(vessel) > this.vesselFilterDistanceSqr)
                    {
                        verboseLog.AppendFormat("\nSkipping distant vessel {0} (sqrDistance {1})",
                                                vessel.vesselName,
                                                (vessel.GetWorldPos3D() - this.dockingModule.nodeTransform.position).sqrMagnitude
                                                );
                        continue;
                    }

                    verboseLog.AppendFormat("\nChecking nearby vessel {0} (sqrDistance {1})",
                                            vessel.vesselName,
                                            (vessel.GetWorldPos3D() - this.dockingModule.nodeTransform.position).sqrMagnitude
                                            );

                    // Since this vessel is not too far away, check all docking nodes on the vessel.
                    IList <ModuleDockingNode> potentialNodes = vessel.getModulesOfType <ModuleDockingNode>();
                    ModuleDockingNode         potentialTargetNode;
                    for (int nIdx = 0; nIdx < potentialNodes.Count; nIdx++)
                    {
                        potentialTargetNode = potentialNodes[nIdx];

                        if (potentialTargetNode == null)
                        {
                            verboseLog.AppendFormat("\nSkipping potentialTargetNode at index {0} because it is null",
                                                    nIdx);
                            continue;
                        }

                        if (potentialTargetNode.part == null)
                        {
                            verboseLog.AppendFormat("\nSkipping potentialTargetNode at index {0} because its part is null",
                                                    nIdx);
                            continue;
                        }

                        if (potentialTargetNode.nodeTransform == null)
                        {
                            verboseLog.AppendFormat("\nSkipping potentialTargetNode at index {0} because its node transform is null",
                                                    nIdx);
                            continue;
                        }

                        verboseLog.AppendFormat("\nFound potentialTargetNode: {0}", potentialTargetNode);
                        verboseLog.AppendFormat("\n\tpotentialTargetNode.state: {0}", potentialTargetNode.state);
                        verboseLog.AppendFormat("\n\tpotentialTargetNode.nodeType: {0}", potentialTargetNode.nodeType);

                        // We can't skip the current vessel, because it's possible to dock parts on a single vessel to
                        // each other.  Still, we can't dock a port to itself, so skip this part.
                        if (potentialTargetNode.part == this.part)
                        {
                            verboseLog.AppendFormat("\nDiscarding potentialTargetNode: on this part.");
                            continue;
                        }

                        // If this docking node is already docked, we can't dock to it, so skip it.
                        if (
                            potentialTargetNode.state.Contains("Docked") ||
                            potentialTargetNode.state.Contains("PreAttached"))
                        {
                            verboseLog.Append("\nDiscarding potentialTargetNode: not ready.");
                            continue;
                        }

                        float thisNodeDistSqr =
                            (potentialTargetNode.nodeTransform.position - this.dockingModule.nodeTransform.position)
                            .sqrMagnitude;

                        verboseLog.AppendFormat(
                            "\n\tChecking potentialTargetNode sqrDistance against the lesser of acquireRangeSqr and " +
                            "closestNodeDistSqr ({0})",
                            Mathf.Min(this.acquireRangeSqr * 4f, closestNodeDistSqr)
                            );

                        // Only bother checking nodes closer than twice our acquire range.  We have to check before we
                        // get within acquire range to make sure Squad's code will catch us when we get there.
                        if (thisNodeDistSqr <= Mathf.Min(this.acquireRangeSqr * 4f, closestNodeDistSqr))
                        {
                                                        #if DEBUG
                            foundApproach = true;
                                                        #endif

                            verboseLog.AppendFormat(
                                "\n\tpotentialTargetNode is nearby ({0}), checking if adaptive.", thisNodeDistSqr);

                            ModuleAdaptiveDockingNode targetAdaptiveNode = null;

                            string targetSize;
                            targetSize = string.Empty;

                            // adapt to non-adaptive docking nodes
                            if (this.validSizes.Contains(potentialTargetNode.nodeType))
                            {
                                targetSize       = potentialTargetNode.nodeType;
                                this.currentSize = targetSize;
                            }
                            // Otherwise, look for another adaptive node.
                            else
                            {
                                // Check the part for an AdaptiveDockingNode
                                targetAdaptiveNode = potentialTargetNode.part
                                                     .getFirstModuleOfType <ModuleAdaptiveDockingNode>();
                            }

                            // If we've found an AdaptiveDockingNode...
                            if (targetAdaptiveNode != null)
                            {
                                verboseLog.AppendFormat("\n\tpotentialTargetNode is adaptive.");
                                verboseLog.AppendFormat("\n\tdefaultSize: {0}", targetAdaptiveNode.defaultSize);
                                verboseLog.AppendFormat("\n\tvalidSizes: {0}", targetAdaptiveNode.validSizes);

                                // ...and if we can become its largest (default) size...
                                // to their default size.
                                if (this.validSizes.Contains(targetAdaptiveNode.defaultSize))
                                {
                                    // ...target its default size.
                                    targetSize = targetAdaptiveNode.defaultSize;
                                }
                                // ...otherwise, look for a common size.
                                else
                                {
                                    string commonNodeType = GetGreatestCommonNodeType(this, targetAdaptiveNode);

                                    // ...if we didn't find a common size, stop processing this node
                                    if (commonNodeType == string.Empty)
                                    {
                                        verboseLog.AppendFormat("\n\tInvalid adaptive target: no common node types.");
                                        continue;
                                    }

                                    targetSize = commonNodeType;
                                    targetAdaptiveNode.currentSize = targetSize;

                                    verboseLog.AppendFormat(
                                        "\n\tTarget nodeType set to commonNodeType: {0}", targetSize);
                                }
                            }
                                                        #if DEBUG
                            else
                            {
                                verboseLog.AppendFormat("\n\tpotentialTargetNode is not adaptive.");
                                verboseLog.AppendFormat("\n\tnodeType: {0}", potentialTargetNode.nodeType);
                            }
                                                        #endif

                            // If we never found a target size, it's not a match, so stop processing.
                            if (targetSize == string.Empty)
                            {
                                continue;
                            }

                            // ...otherwise, log this node as the closest and adapt to the target size.
                            closestNodeDistSqr = thisNodeDistSqr;
                            this.currentSize   = targetSize;
                            foundTargetNode    = true;


                            verboseLog.AppendFormat("\n\tLocal nodeType set to commonNodeType: {0}", targetSize);
                            verboseLog.AppendFormat("\n\tFound suitable docking node.");
                            verboseLog.AppendFormat("\n\ttargetSize: {0}", targetSize);

                            verboseLog.AppendFormat("\n\tForward vector dot product: {0} (acquire minimum: {1})",
                                                    Vector3.Dot(potentialTargetNode.nodeTransform.forward,
                                                                this.dockingModule.nodeTransform.forward),
                                                    this.dockingModule.acquireMinFwdDot
                                                    );

                            verboseLog.AppendFormat("\n\tUp vector dot product: {0} (acquire minimum: {1})",
                                                    Vector3.Dot(potentialTargetNode.nodeTransform.up, this.dockingModule.nodeTransform.up),
                                                    this.dockingModule.acquireMinRollDot
                                                    );
                        }
                        else
                        {
                            verboseLog.AppendFormat(
                                "\nDiscarding potentialTargetNode: too far away (thisNodeDistSqr: {0})",
                                thisNodeDistSqr
                                );
                        }
                    }

                    verboseLog.Append('\n');
                }

                verboseLog.Append("\nFixedUpdate Finished.");

                if (foundTargetNode)
                {
                    if (this.timeoutTimer.IsRunning)
                    {
                        this.timeoutTimer.Reset();
                    }

                    this.timeoutTimer.Start();
                }

                                #if DEBUG
            }
            finally
            {
                // if (foundApproach)
                verboseLog.Print();
            }
                                #endif
            }
        }
        public static string GetGreatestCommonNodeType(ModuleAdaptiveDockingNode n1, ModuleAdaptiveDockingNode n2)
        {
            int count1 = 0;
            int count2 = 0;

            while (count1 < n1.validSizes.Count && count2 < n2.validSizes.Count)
            {
                int compareResult;

                compareResult = n1.validSizes[count1].CompareTo(n2.validSizes[count2]);

                if (compareResult == 0)
                {
                    return n1.validSizes[count1];
                }
                else if (compareResult > 0)
                {
                    count1++;
                }
                else
                {
                    count2++;
                }
            }

            return string.Empty;
        }