Пример #1
0
 public void UpdateFairingNodes()
 {
     ROLLog.log($"UpdateFairingNodes()");
     foreach (ROLNodeFairingData data in fairingParts)
     {
         ROLLog.log($"fairingName: {fairingName}");
         // Update the Nose Interstage Node
         if (fairingName == "Top Fairing")
         {
             Vector3 pos = new Vector3(0, data.topY, 0);
             ROLLog.log($"data.topY: {data.topY}");
             ROLSelectableNodes.updateNodePosition(part, noseFairingNode, pos);
             if (part.FindAttachNode(noseFairingNode) is AttachNode noseInterstage)
             {
                 ROLAttachNodeUtils.updateAttachNodePosition(part, noseInterstage, pos, Vector3.up, true, 2);
             }
         }
         // Update the Mount Interstage Node
         if (fairingName == "Bottom Fairing")
         {
             Vector3 pos = new Vector3(0, data.bottomY, 0);
             ROLSelectableNodes.updateNodePosition(part, data.mountNode, pos);
             if (part.FindAttachNode(mountFairingNode) is AttachNode mountInterstage)
             {
                 ROLAttachNodeUtils.updateAttachNodePosition(part, mountInterstage, pos, Vector3.down, true, 2);
             }
         }
     }
 }
Пример #2
0
 private void FindAnimations()
 {
     Animation[] componentsInChildren = part.transform.ROLFindRecursive("model").GetComponentsInChildren <Animation>();
     foreach (Animation a in componentsInChildren)
     {
         if (a.GetClip(this.animationName) != null)
         {
             ROLLog.debug($"[AnimDebug] Animation: {a}");
             this.anim = a;
             ROLLog.debug($"a.GetClip(this.animationName) this.anim: {this.anim}");
         }
     }
     if (componentsInChildren.Length > 0 && this.anim == null)
     {
         this.anim = componentsInChildren[0];
         ROLLog.debug($"componentsInChildren.Length > 0 - this.anim: {this.anim}");
     }
     if (this.anim == null)
     {
         this.useAnimation = false;
     }
     else
     {
         this.useAnimation = true;
     }
 }
Пример #3
0
        public void UpdateImpulseValues()
        {
            ROLLog.log("UpdateImpulseValues() called");
            float nf = (float)Math.Min(100f * Math.Pow(modularPart.currentDiameter, diamExponent), maxImpulse);

            nf = (float)Math.Round(nf, 0);
            currentEjectionForce = decouple.ejectionForce = nf;
        }
Пример #4
0
        private void UpdateAttachNodes(bool userInput)
        {
            coreModule.updateAttachNodeBody(coreNodeNames, userInput);
            AttachNode surfaceNode = part.srfAttachNode;

            ROLLog.debug($"part.srfAttachNode: {part.srfAttachNode}");
            coreModule.updateSurfaceAttachNode(surfaceNode, panelLength, panelWidth, userInput);
        }
Пример #5
0
        private void UpdateMassAndCost()
        {
            lengthWidth = coreModule.definition.lengthWidth;
            if (!lengthWidth)
            {
                ROLLog.debug($"UpdateMassAndCost() lengthWidth false");
                area = coreModule.definition.panelArea * panelScale * panelScale;
                ROLLog.debug($"coreModule.definition.panelArea: {coreModule.definition.panelArea}");
                ROLLog.debug($"panelScale: {panelScale}");
                ROLLog.debug($"area: {area}");
            }
            else
            {
                ROLLog.debug($"UpdateMassAndCost() lengthWidth true");
                float lengthScale = panelLength / coreModule.definition.panelLength;
                float widthScale  = panelWidth / coreModule.definition.panelWidth;
                area = coreModule.definition.panelArea * lengthScale * widthScale;
                ROLLog.debug($"coreModule.definition.panelArea: {coreModule.definition.panelArea}");
                ROLLog.debug($"lengthScale: {lengthScale}");
                ROLLog.debug($"widthScale: {widthScale}");
                ROLLog.debug($"area: {area}");
            }

            kgPerM2   = stl.kgPerM2;
            costPerM2 = stl.costPerM2;
            mass      = area * kgPerM2;
            cost      = area * costPerM2;
            switch (solarPanelType)
            {
            case "hinged":
                mass *= stl.massMultHinged;
                cost *= stl.costMultHinged;
                break;

            case "folded":
                mass *= stl.massMultFolded;
                cost *= stl.costMultFolded;
                break;

            case "tracking":
                mass *= stl.massMultTrack;
                cost *= stl.costMultTrack;
                break;

            default:
                break;
            }
            if (addMass > 0)
            {
                mass += addMass;
            }
            if (addCost > 0)
            {
                cost += addCost;
            }
            modifiedMass = mass = Math.Max(mass, 0.0001f);
            modifiedCost = cost = Math.Max(cost, 0.1f);
        }
Пример #6
0
        /// <summary>
        /// Updates all dimensions for the PAW and tooling.
        /// </summary>
        public void UpdateDimensions()
        {
            float mountMaxDiam = currentMount.Contains("Mount") ? mountModule.moduleUpperDiameter : Math.Max(mountModule.moduleLowerDiameter, mountModule.moduleUpperDiameter);
            float noseMaxDiam  = Math.Max(noseModule.moduleLowerDiameter, noseModule.moduleUpperDiameter);

            totalTankLength = GetTotalHeight();
            largestDiameter = Math.Max(currentDiameter, Math.Max(noseMaxDiam, mountMaxDiam));
            ROLLog.debug($"UpdateDimensions() currentMount: {currentMount}  Largest Diameter: {largestDiameter}.  Total Tank length: {totalTankLength}");
        }
Пример #7
0
 private bool FindDecoupler()
 {
     ROLLog.debug("Finding Decoupler...");
     if (decouple == null)
     {
         decouple = part.Modules["ModuleDecouple"] as ModuleDecouple;
     }
     return(decouple != null);
 }
Пример #8
0
        public ModelLayoutData getLayout(string name)
        {
            ModelLayoutData mld = layouts.ROLFind(m => m.name == name);

            if (mld == null)
            {
                ROLLog.error("ERROR: Could not locate layout for name: " + name);
            }
            return(mld);
        }
Пример #9
0
        public readonly float gimbalFlightRange;     //how far the gimbal may be actuated while in flight from the adjusted reference angle

        public ModelEngineTransformData(ConfigNode node)
        {
            thrustTransformName = node.ROLGetStringValue("thrustTransform");
            if (string.IsNullOrEmpty(thrustTransformName))
            {
                ROLLog.error("ERROR: THrust transform name was null for model def engine transform data");
            }
            gimbalTransformName   = node.ROLGetStringValue("gimbalTransform");
            gimbalAdjustmentRange = node.ROLGetFloatValue("gimbalAdjustRange", 0);
            gimbalFlightRange     = node.ROLGetFloatValue("gimbalFlightRange", 0);
        }
Пример #10
0
 public override void OnLoad(ConfigNode node)
 {
     base.OnLoad(node);
     if (string.IsNullOrEmpty(configNodeData))
     {
         ROLLog.debug($"{modName}: OnLoad loading configNodeData");
         configNodeData = node.ToString();
         ROLLog.debug($"{modName}: OnLoad() configNodeData: {configNodeData}");
     }
     ROLLog.debug($"{modName}: OnLoad calling Initialize()");
     Initialize();
 }
Пример #11
0
        public void SetCurrentDiameter(float f)
        {
            float oldDiameter = module.currentDiameter;

            module.currentDiameter = f;
            BaseField fld = module.Fields[nameof(module.currentDiameter)];

            fld.uiControlEditor.onFieldChanged.Invoke(fld, oldDiameter);

            MonoUtilities.RefreshContextWindows(module.part);
            ROLLog.log("ModuleROTank - Diameter set to: " + f);
        }
Пример #12
0
        private void SetupUICallbacks()
        {
            ROLLog.debug("Setting up UICallbacks...");
            if (FindModularPart() is ModuleROTank p)
            {
                ROLLog.debug("p: " + p);
                ROLLog.debug("p.Fields[nameof(p.currentDiameter): " + p.Fields[nameof(p.currentDiameter)]);
                ROLLog.debug("p.Fields: " + p.Fields);

                UI_FloatEdit mp = p.Fields[nameof(p.currentDiameter)].uiControlEditor as UI_FloatEdit;
                mp.onFieldChanged += new Callback <BaseField, object>(OnDiameterChange);
            }
        }
Пример #13
0
 public ModelDefinitionLayoutOptions(ROLModelDefinition def)
 {
     definition = def;
     if (definition == null)
     {
         ROLLog.error("Model definition was null when creating model layout options!");
     }
     layouts = ROLModelLayout.findLayouts(new string[] { "default" });
     if (this.layouts == null || this.layouts.Length < 1)
     {
         throw new InvalidOperationException("ERROR: No valid layout data specified.");
     }
 }
Пример #14
0
 public static void Init(ConfigNode config)
 {
     ROLLog.debug($"{modTag}: Init() Started");
     allTL.Clear();
     foreach (ConfigNode node in config.GetNodes("ROS_TECH"))
     {
         SolarTechLimit obj = ConfigNode.CreateObjectFromConfig <SolarTechLimit>(node);
         ROLLog.debug($"{modTag}: Adding ROSTL {obj}");
         allTL.Add(obj.level, obj);
         maxTL = Math.Max(maxTL, obj.level);
     }
     isInitialized = true;
 }
Пример #15
0
 public ModelDefinitionLayoutOptions(ROLModelDefinition def, ModelLayoutData[] layouts)
 {
     this.definition = def;
     if (definition == null)
     {
         ROLLog.error("Model definition was null when creating model layout options!");
     }
     this.layouts = layouts;
     if (this.layouts == null || this.layouts.Length < 1)
     {
         throw new InvalidOperationException("ERROR: No valid layout data specified.");
     }
 }
Пример #16
0
        /// <summary>
        /// Create a group of model definition layout sets.  Loads the model definitions + their supported layout configurations.
        /// </summary>
        /// <param name="nodes"></param>
        /// <returns></returns>
        public static ModelDefinitionLayoutOptions[] getModelDefinitions(ConfigNode[] nodes)
        {
            int len = nodes.Length;

            List <ModelDefinitionLayoutOptions> options = new List <ModelDefinitionLayoutOptions>();
            List <ModelLayoutData> layoutDataList       = new List <ModelLayoutData>();
            ROLModelDefinition     def;

            string[] groupedNames;
            string[] groupedLayouts;
            int      len2;

            for (int i = 0; i < len; i++)
            {
                //because configNode.ToString() reverses the order of values, and model def layouts are always loaded from string-cached config nodes
                //we need to reverse the order of the model and layout names during parsing
                groupedNames   = nodes[i].ROLGetStringValues("model");
                groupedLayouts = nodes[i].ROLGetStringValues("layout", new string[] { "default" });
                len2           = groupedNames.Length;
                for (int k = 0; k < len2; k++)
                {
                    def = ROLModelData.getModelDefinition(groupedNames[k]);
                    layoutDataList.AddRange(ROLModelLayout.findLayouts(groupedLayouts));
                    if (nodes[i].HasValue("position") || nodes[i].HasValue("rotation") || nodes[i].HasValue("scale"))
                    {
                        Vector3           pos    = nodes[i].ROLGetVector3("position", Vector3.zero);
                        Vector3           scale  = nodes[i].ROLGetVector3("scale", Vector3.one);
                        Vector3           rot    = nodes[i].ROLGetVector3("rotation", Vector3.zero);
                        ModelPositionData mpd    = new ModelPositionData(pos, scale, rot);
                        ModelLayoutData   custom = new ModelLayoutData("default", new ModelPositionData[] { mpd });
                        if (layoutDataList.Exists(m => m.name == "default"))
                        {
                            ModelLayoutData del = layoutDataList.Find(m => m.name == "default");
                            layoutDataList.Remove(del);
                        }
                        layoutDataList.Add(custom);
                    }
                    if (def == null)
                    {
                        ROLLog.error("Model definition was null for name: " + groupedNames[k] + ". Skipping definition during loading of part");
                    }
                    else
                    {
                        options.Add(new ModelDefinitionLayoutOptions(def, layoutDataList.ToArray()));
                    }
                    layoutDataList.Clear();
                }
            }
            return(options.ToArray());
        }
Пример #17
0
        public static ModelLayoutData findLayout(string name)
        {
            if (!loaded)
            {
                load();
            }
            ModelLayoutData mld;

            if (!layouts.TryGetValue(name, out mld))
            {
                ROLLog.error("Could not find layout by name: " + name);
            }
            return(mld);
        }
Пример #18
0
        public static void load()
        {
            ROLLog.log("Loading Model Layouts");
            layouts.Clear();
            ConfigNode[] layoutNodes = GameDatabase.Instance.GetConfigNodes("ROL_MODEL_LAYOUT");
            int          len         = layoutNodes.Length;

            for (int i = 0; i < len; i++)
            {
                ModelLayoutData mld = new ModelLayoutData(layoutNodes[i]);
                layouts.Add(mld.name, mld);
            }
            loaded = true;
            ROLLog.log("Finished loading Model Layouts");
        }
Пример #19
0
        public override void OnStart(StartState state)
        {
            base.OnStart(state);

            if (!FindDecoupler())
            {
                ROLLog.error("Unable to find any Decoupler modules");
                isEnabled = enabled = false;
                return;
            }

            if (HighLogic.LoadedSceneIsFlight)
            {
                decouple.isOmniDecoupler = isOmniDecoupler;
            }
        }
Пример #20
0
        /// <summary>
        /// Return the total height of this part in its current configuration.  This will be the distance from the bottom attach node to the top attach node, and may not include any 'extra' structure. TOOLING
        /// </summary>
        /// <returns></returns>
        private float getTotalHeight()
        {
            float totalHeight = noseModule.moduleHeight;

            totalHeight += mountModule.moduleHeight;
            if (currentCore.Contains("Booster"))
            {
                ROLLog.debug("currentCore: " + currentCore);
                totalHeight += coreModule.moduleActualHeight;
            }
            else
            {
                totalHeight += coreModule.moduleHeight;
            }
            return(totalHeight);
        }
Пример #21
0
        public void toggleNode()
        {
            AttachNode node = part.FindAttachNode(nodeName);

            ROLLog.debug("toggleNode() node: " + node);
            if (node == null)
            {
                currentlyEnabled = true;
                ROLAttachNodeUtils.createAttachNode(part, nodeName, nodeDefaultPosition, nodeDefaultOrientation, 2);
            }
            else if (node.attachedPart == null)
            {
                currentlyEnabled = false;
                ROLAttachNodeUtils.destroyAttachNode(part, node);
            }
        }
Пример #22
0
        public static Vector3 ROLGetVector3(this ConfigNode node, String name, Vector3 defaultValue)
        {
            String value = node.GetValue(name);

            if (value == null)
            {
                return(defaultValue);
            }
            String[] vals = value.Split(',');
            if (vals.Length < 3)
            {
                ROLLog.error("ERROR parsing values for Vector3 from input: " + value + ". found less than 3 values, cannot create Vector3");
                return(defaultValue);
            }
            return(new Vector3((float)ROLUtils.safeParseDouble(vals[0]), (float)ROLUtils.safeParseDouble(vals[1]), (float)ROLUtils.safeParseDouble(vals[2])));
        }
Пример #23
0
 private void WindowPre(int uid)
 {
     try
     {
         InputLockManager.RemoveControlLock("ROLWindowLock");
         /* Block clicks through window onto ship or other editor UI */
         if (this.backupPosition.Contains(new Vector2(Input.mousePosition.x, Screen.height - Input.mousePosition.y)))
         {
             InputLockManager.SetControlLock(ControlTypes.EDITOR_LOCK, "ROLWindowLock");
         }
         Window(uid);
     }
     catch (Exception e)
     {
         ROLLog.exc(e);
     }
 }
Пример #24
0
 public override void OnStart(StartState state)
 {
     ROLLog.debug($"OnStart(state)");
     base.OnStart(state);
     ROLLog.debug($"this.anim: {this.anim}");
     ROLLog.debug("Anim loop");
     foreach (Animation a in this.GetComponentsInChildren <Animation>())
     {
         ROLLog.debug($"[AnimDebug] Animation: {a}");
     }
     ROLLog.debug("Anim loop done");
     SetMaxTechLevel();
     ROLLog.debug($"{modName} OnStart calling Initialize()");
     Initialize();
     ROLLog.debug($"{modName} OnStart calling InitializeUI()");
     InitializeUI();
 }
Пример #25
0
        /// <summary>
        /// Update the scale and position values for all currently configured models.  Does no validation, only updates positions.<para/>
        /// After calling this method, all models will be scaled and positioned according to their internal position/scale values and the orientations/offsets defined in the models.
        /// </summary>
        public void updateModulePositions()
        {
            ROLLog.debug($"UpdateModulePositions()");
            //scales for modules depend on the module above/below them
            //first set the scale for the core module -- this depends directly on the UI specified 'diameter' value.
            if (lengthWidth)
            {
                debug($"UpdateModulePositions(): setScaleForHeightAndDiameter");
                coreModule.setScaleForHeightAndDiameter(currentLength, currentDiameter);
            }
            else
            {
                debug($"UpdateModulePositions(): setScaleForDiameter");
                coreModule.setScaleForDiameter(currentDiameter, currentVScale);
            }
            ROLLog.debug($"UpdateModulePositions(): currentDiameter: {currentDiameter}, currentVScale: {currentVScale}");

            //next, set nose scale values
            noseModule.setDiameterFromBelow(coreModule.moduleUpperDiameter, currentVScale);

            //finally, set mount scale values
            mountModule.setDiameterFromAbove(coreModule.moduleLowerDiameter, currentVScale);

            //total height of the part is determined by the sum of the heights of the modules at their current scale
            float totalHeight = noseModule.moduleHeight;

            totalHeight += coreModule.moduleHeight;
            totalHeight += mountModule.moduleHeight;

            //position of each module is set such that the vertical center of the models is at part origin/COM
            float pos = totalHeight * 0.5f;        //abs top of model

            pos -= noseModule.moduleHeight;        //bottom of nose model
            noseModule.setPosition(pos);
            pos -= coreModule.moduleHeight * 0.5f; //center of 'core' model
            coreModule.setPosition(pos);
            pos -= coreModule.moduleHeight * 0.5f; //bottom of 'core' model
            mountModule.setPosition(pos);

            //update actual model positions and scales
            noseModule.updateModelMeshes();
            coreModule.updateModelMeshes();
            mountModule.updateModelMeshes();
        }
Пример #26
0
        /// <summary>
        /// Create a group of model definition layout options by model definition name, with default (single position) layouts.
        /// </summary>
        /// <param name="names"></param>
        /// <returns></returns>
        public static ModelDefinitionLayoutOptions[] getModelDefinitionLayouts(string[] names)
        {
            List <ModelDefinitionLayoutOptions> defs = new List <ModelDefinitionLayoutOptions>();
            int len = names.Length;

            for (int i = 0; i < len; i++)
            {
                ROLModelDefinition def = getModelDefinition(names[i]);
                if (def != null)
                {
                    defs.Add(new ModelDefinitionLayoutOptions(def));
                }
                else
                {
                    ROLLog.error("Could not locate model defintion for name: " + names[i]);
                }
            }
            return(defs.ToArray());
        }
Пример #27
0
        public static T ROLFind <T>(this T[] array, Func <T, bool> predicate)
        {
            int len = array.Length;

            for (int i = 0; i < len; i++)
            {
                if (array[i] == null)
                {
                    ROLLog.error("ERROR: Null value in array in Find method, at index: " + i);
                }
                if (predicate(array[i]))
                {
                    return(array[i]);
                }
            }
            //return default in order to properly handle value types (structs)
            //should return either null for reference types or default value for structs
            return(default(T));
        }
Пример #28
0
        public override void OnStartFinished(StartState state)
        {
            base.OnStartFinished(state);

            ROLLog.debug("OnStartFinished()...");
            if (!FindModularPart())
            {
                ROLLog.error("Unable to find any Modular Part modules");
                isEnabled = enabled = false;
                return;
            }

            SetupUICallbacks();

            if (HighLogic.LoadedSceneIsEditor)
            {
                UpdateImpulseValues();
            }
        }
Пример #29
0
        public void SetCurrentDiameter(float f)
        {
            module.currentDiameter = f;

            module.updateModulePositions();
            module.updateDimensions();
            module.updateAttachNodes(true);
            module.updateAvailableVariants();
            if (module.scaleMass)
            {
                module.updateMass();
            }
            if (module.scaleCost)
            {
                module.updateCost();
            }

            UpdatePartActionWindow();
            ROLLog.log("ModuleROTank - Diameter set to: " + f);
        }
Пример #30
0
        /// <summary>
        /// Updates all dimensions for the PAW and tooling.
        /// </summary>
        public void updateDimensions()
        {
            float noseMaxDiam, mountMaxDiam = 0.0f;

            noseMaxDiam = Math.Max(noseModule.moduleLowerDiameter, noseModule.moduleUpperDiameter);
            ROLLog.debug("currentMount: " + currentMount);
            if (currentMount.Contains("Mount"))
            {
                ROLLog.debug("currentMount: " + currentMount);
                mountMaxDiam = mountModule.moduleUpperDiameter;
            }
            else
            {
                mountMaxDiam = Math.Max(mountModule.moduleLowerDiameter, mountModule.moduleUpperDiameter);
            }

            totalTankLength = getTotalHeight();
            ROLLog.debug("The Total Tank Length is: " + totalTankLength);
            largestDiameter = Math.Max(currentDiameter, Math.Max(noseMaxDiam, mountMaxDiam));
        }