Пример #1
0
        public ModelGUISelection(ModelData data, float size)
        {
            modelName = data.name;
            description = data.modelDefinition.title + " - " + data.modelDefinition.description;
            float m = data.mass;
            float c = data.cost;
            float v = data.volume;

            float scale = size / data.modelDefinition.diameter == 0 ? 1 : data.modelDefinition.diameter;

            float pow = Mathf.Pow(scale, 3);
            m *= pow;
            c *= pow;
            v *= pow;

            string suffix;
            suffix = m < 1 ? "kg" : m < 1000 ? "t" : "kt";
            m = m < 1 ? m * 1000 : m < 1000 ? m : m * 0.001f;
            mass = m.ToString("N1")+suffix;

            suffix = c < 1000 ? "" : "k";
            c = c > 1000 ? c * 0.001f : c;
            cost = c.ToString("N1")+suffix;

            suffix = v < 1 ? "l" : v < 1000 ? "kl" : "Ml";
            v = v < 1 ? v * 1000 : v < 1000 ? v : v * 0.001f;
            volume = v.ToString("N1")+suffix;

            if (String.IsNullOrEmpty(data.modelDefinition.icon) || (texture = GameDatabase.Instance.GetTexture(data.modelDefinition.icon, false))==null)
            {
                //TODO do textures need to be destroyed when no longer in use?  Can call unity asset-cleanup on GUI close?
                texture = GameDatabase.Instance.GetTexture("Squad/PartList/SimpleIcons/RDicon_propulsionSystems", false);
            }
        }
Пример #2
0
 public static ModelGUISelection[] createFromModelData(ModelData[] data, float diameter)
 {
     int len = data.Length;
     ModelGUISelection[] selections = new ModelGUISelection[len];
     for (int i = 0; i < len; i++)
     {
         selections[i] = new ModelGUISelection(data[i], diameter);
     }
     return selections;
 }
Пример #3
0
        private void initialize()
        {
            if (initialized)
            {
                return;
            }
            initialized = true;
            ConfigNode node = SSTUConfigNodeUtils.parseConfigNode(configNodeData);
            Transform  root = part.transform.FindRecursive("model").FindOrCreate(rootTransformName);

            models = new ModelModule <PositionedModelData, SSTUModelSwitch2>(part, this, root, ModelOrientation.TOP, nameof(modelPersistentData), nameof(currentModel), nameof(currentTexture));
            models.getSymmetryModule = m => m.models;
            models.setupModelList(ModelData.parseModels <PositionedModelData>(node.GetNodes("MODEL"), m => new PositionedModelData(m)));
            models.setupModel();
            models.model.updateScale(currentScale);
            models.updateModel();
            updateMassAndCost();
            updateAttachNodes(false);
        }
Пример #4
0
        public ModelGUISelection(ModelData data, float size)
        {
            modelName   = data.name;
            description = data.modelDefinition.title + " - " + data.modelDefinition.description;
            float m = data.mass;
            float c = data.cost;
            float v = data.volume;

            float scale = size / data.modelDefinition.diameter == 0 ? 1 : data.modelDefinition.diameter;

            float pow = Mathf.Pow(scale, 3);

            m *= pow;
            c *= pow;
            v *= pow;

            string suffix;

            suffix = m < 1 ? "kg" : m < 1000 ? "t" : "kt";
            m      = m < 1 ? m * 1000 : m < 1000 ? m : m * 0.001f;
            mass   = m.ToString("N1") + suffix;

            suffix = c < 1000 ? "" : "k";
            c      = c > 1000 ? c * 0.001f : c;
            cost   = c.ToString("N1") + suffix;

            suffix = v < 1 ? "l" : v < 1000 ? "kl" : "Ml";
            v      = v < 1 ? v * 1000 : v < 1000 ? v : v * 0.001f;
            volume = v.ToString("N1") + suffix;


            if (String.IsNullOrEmpty(data.modelDefinition.icon) || (texture = GameDatabase.Instance.GetTexture(data.modelDefinition.icon, false)) == null)
            {
                //TODO do textures need to be destroyed when no longer in use?  Can call unity asset-cleanup on GUI close?
                texture = GameDatabase.Instance.GetTexture("Squad/PartList/SimpleIcons/RDicon_propulsionSystems", false);
            }
        }
Пример #5
0
 /// <summary>
 /// Finds the model for the given part, if it currently exists; else it clones it
 /// </summary>
 /// <param name="model"></param>
 /// <returns></returns>
 private void setupModel(ModelData model, Transform parent, ModelOrientation orientation)
 {
     model.setupModel(part, parent, orientation);
 }
Пример #6
0
 /// <summary>
 /// Removes the current model of the passed in upper-stage part; used when switching mounts or intertank parts
 /// </summary>
 /// <param name="usPart"></param>
 private void removeCurrentModel(ModelData usPart)
 {
     usPart.destroyCurrentModel();
 }
Пример #7
0
        /// <summary>
        /// Restores ModelData instances from config node data, and populates the 'currentModule' instances with the currently enabled modules.
        /// </summary>
        private void loadConfigData()
        {
            ConfigNode node = SSTUConfigNodeUtils.parseConfigNode(configNodeData);

            ConfigNode[] tankSetsNodes = node.GetNodes("TANKSET");
            ConfigNode[] tankNodes     = node.GetNodes("TANK");
            ConfigNode[] mountNodes    = node.GetNodes("CAP");
            ConfigNode[] limitNodes    = node.GetNodes("TECHLIMIT");

            tankSets = TankSet.parseSets(tankSetsNodes);
            //if no sets exist, initialize a default set to add all models to
            if (tankSets.Length == 0)
            {
                tankSets = new TankSet[1];
                ConfigNode defaultSetNode = new ConfigNode("TANKSET");
                defaultSetNode.AddValue("name", "default");
                tankSets[0] = new TankSet(defaultSetNode);
            }
            mainTankModules = ModelData.parseModels <TankModelData>(tankNodes, m => new TankModelData(m));

            int     len = mainTankModules.Length;
            TankSet set;

            for (int i = 0; i < len; i++)
            {
                set = Array.Find(tankSets, m => m.name == mainTankModules[i].setName);
                //if set is not found by name, add it to the first set which is guaranteed to exist due to the default-set-adding code above.
                if (set == null)
                {
                    set = tankSets[0];
                }
                set.addModel(mainTankModules[i]);
            }

            len = mountNodes.Length;
            ConfigNode             mountNode;
            List <SingleModelData> noses  = new List <SingleModelData>();
            List <SingleModelData> mounts = new List <SingleModelData>();

            for (int i = 0; i < len; i++)
            {
                mountNode = mountNodes[i];
                if (mountNode.GetBoolValue("useForNose", true))
                {
                    mountNode.SetValue("nose", "true");
                    noses.Add(new SingleModelData(mountNode));
                }
                if (mountNode.GetBoolValue("useForMount", true))
                {
                    mountNode.SetValue("nose", "false");
                    mounts.Add(new SingleModelData(mountNode));
                }
            }
            mountModules = mounts.ToArray();
            noseModules  = noses.ToArray();

            topNodeNames    = SSTUUtils.parseCSV(topManagedNodeNames);
            bottomNodeNames = SSTUUtils.parseCSV(bottomManagedNodeNames);

            currentMainTankModule = Array.Find(mainTankModules, m => m.name == currentTankType);
            if (currentMainTankModule == null)
            {
                MonoBehaviour.print("ERROR: Could not locate tank type for: " + currentTankType + ". reverting to first available tank type.");
                currentMainTankModule = mainTankModules[0];
                currentTankType       = currentMainTankModule.name;
            }

            currentTankSetModule = Array.Find(tankSets, m => m.name == currentMainTankModule.setName);
            currentTankSet       = currentTankSetModule.name;
            lastSelectedVariant  = currentMainTankModule.variantName;

            currentNoseModule = Array.Find(noseModules, m => m.name == currentNoseType);
            if (currentNoseModule == null)
            {
                MonoBehaviour.print("ERROR: Could not locate nose type for: " + currentNoseType + ". reverting to first available nose type.");
                currentNoseModule = noseModules[0];
                currentNoseType   = currentNoseModule.name;
            }

            currentMountModule = Array.Find(mountModules, m => m.name == currentMountType);
            if (currentMountModule == null)
            {
                MonoBehaviour.print("ERROR: Could not locate mount type for: " + currentMountType + ". reverting to first available mount type.");
                currentMountModule = mountModules[0];
                currentMountType   = currentMountModule.name;
            }
            if (!currentMainTankModule.isValidTextureSet(currentTankTexture))
            {
                currentTankTexture = currentMainTankModule.getDefaultTextureSet();
            }
            if (!currentNoseModule.isValidTextureSet(currentNoseTexture))
            {
                currentNoseTexture = currentNoseModule.getDefaultTextureSet();
            }
            if (!currentMountModule.isValidTextureSet(currentMountTexture))
            {
                currentMountTexture = currentMountModule.getDefaultTextureSet();
            }
        }
Пример #8
0
 public void selectMountEvent()
 {
     ModuleSelectionGUI.openGUI(ModelData.getValidSelections(part, mountModules, bottomNodeNames), currentTankDiameter, setMountModuleFromEditor);
 }
Пример #9
0
 public void selectNoseEvent()
 {
     ModuleSelectionGUI.openGUI(ModelData.getValidSelections(part, noseModules, topNodeNames), currentTankDiameter, setNoseModuleFromEditor);
 }
Пример #10
0
        private void initialize(bool start)
        {
            if (initialized)
            {
                return;
            }
            initialized = true;

            topNodeNames    = SSTUUtils.parseCSV(topManagedNodes);
            bottomNodeNames = SSTUUtils.parseCSV(bottomManagedNodes);

            ConfigNode node = SSTUConfigNodeUtils.parseConfigNode(configNodeData);

            coreModule = new ModelModule <ServiceModuleCoreModel, SSTUModularServiceModule>(part, this, getRootTransform("MSC-CORE", true), ModelOrientation.TOP, nameof(coreModulePersistentData), nameof(currentCore), nameof(currentCoreTexture));
            coreModule.getSymmetryModule = m => m.coreModule;
            coreModule.setupModelList(ModelData.parseModels(node.GetNodes("CORE"), m => new ServiceModuleCoreModel(m)));

            topModule = new ModelModule <SingleModelData, SSTUModularServiceModule>(part, this, getRootTransform("MSC-TOP", true), ModelOrientation.TOP, nameof(topModulePersistentData), nameof(currentTop), nameof(currentTopTexture));
            topModule.getSymmetryModule  = m => m.topModule;
            topModule.getValidSelections = m => topModule.models.FindAll(s => s.canSwitchTo(part, topNodeNames));

            bottomModule = new ModelModule <SingleModelData, SSTUModularServiceModule>(part, this, getRootTransform("MSC-BOTTOM", true), ModelOrientation.BOTTOM, nameof(bottomModulePersistentData), nameof(currentBottom), nameof(currentBottomTexture));
            bottomModule.getSymmetryModule  = m => m.bottomModule;
            bottomModule.getValidSelections = m => bottomModule.models.FindAll(s => s.canSwitchTo(part, bottomNodeNames));

            solarModule = new ModelModule <SolarData, SSTUModularServiceModule>(part, this, getRootTransform("MSC-Solar", true), ModelOrientation.CENTRAL, null, nameof(currentSolar), null);
            solarModule.getSymmetryModule = m => m.solarModule;
            solarModule.setupModelList(ModelData.parseModels(node.GetNodes("SOLAR"), m => new SolarData(m)));
            solarModule.getValidSelections = delegate(IEnumerable <SolarData> all)
            {
                //System.Linq.Enumerable.Where(all, s => s.isAvailable(upgradesApplied));
                float scale = coreModule.model.currentDiameterScale;
                //find all solar panels that are unlocked via upgrades/tech-tree
                List <SolarData> unlocked = solarModule.models.FindAll(s => s.isAvailable(upgradesApplied));
                //filter those to find only the ones available for the current
                List <SolarData> availableByScale = unlocked.FindAll(s => coreModule.model.isValidSolarOption(s.name, scale));
                return(availableByScale);
            };
            solarModule.preModelSetup = delegate(SolarData d)
            {
                d.positions = coreModule.model.getPanelConfiguration(d.name).getScaledPositions(coreModule.model.currentDiameterScale);
            };

            rcsModule = new ModelModule <ServiceModuleRCSModelData, SSTUModularServiceModule>(part, this, getRootTransform("MSC-Rcs", true), ModelOrientation.CENTRAL, null, nameof(currentRCS), null);
            rcsModule.getSymmetryModule = m => m.rcsModule;
            rcsModule.setupModelList(ModelData.parseModels(node.GetNodes("RCS"), m => new ServiceModuleRCSModelData(m)));
            rcsModule.getValidSelections = m => rcsModule.models.FindAll(s => s.isAvailable(upgradesApplied));

            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);
                }
            }
            topModule.setupModelList(SingleModelData.parseModels(tops.ToArray()));
            bottomModule.setupModelList(SingleModelData.parseModels(bottoms.ToArray()));

            tops.Clear();
            bottoms.Clear();
            topModule.setupModel();
            coreModule.setupModel();
            coreModule.model.updateScaleForDiameter(currentDiameter);
            bottomModule.setupModel();
            solarModule.setupModel();
            rcsModule.setupModel();
            rcsModule.model.renameThrustTransforms(rcsThrustTransformName);

            updateModulePositions();
            updateMassAndCost();
            updateAttachNodes(false);
            SSTUStockInterop.updatePartHighlighting(part);
        }
Пример #11
0
        /// <summary>
        /// Restores ModelData instances from config node data, and populates the 'currentModule' instances with the currently enabled modules.
        /// </summary>
        private void loadConfigData()
        {
            ConfigNode node = SSTUConfigNodeUtils.parseConfigNode(configNodeData);

            ConfigNode[] tankSetsNodes = node.GetNodes("TANKSET");
            ConfigNode[] tankNodes     = node.GetNodes("TANK");
            ConfigNode[] mountNodes    = node.GetNodes("CAP");

            variantData = TankVariant.parseVariants(node.GetNodes("VARIANT"));

            tankSets = TankSet.parseSets(tankSetsNodes);
            //if no sets exist, initialize a default set to add all models to
            if (tankSets.Length == 0)
            {
                tankSets = new TankSet[1];
                ConfigNode defaultSetNode = new ConfigNode("TANKSET");
                defaultSetNode.AddValue("name", "default");
                tankSets[0] = new TankSet(defaultSetNode);
            }
            TankModelData[] mainTankModules = ModelData.parseModels <TankModelData>(tankNodes, m => new TankModelData(m));

            int     len = mainTankModules.Length;
            TankSet set;

            for (int i = 0; i < len; i++)
            {
                set = Array.Find(tankSets, m => m.name == mainTankModules[i].setName);
                //if set is not found by name, add it to the first set which is guaranteed to exist due to the default-set-adding code above.
                if (set == null)
                {
                    set = tankSets[0];
                }
                set.addModel(mainTankModules[i]);
            }

            topNodeNames    = SSTUUtils.parseCSV(topManagedNodeNames);
            bottomNodeNames = SSTUUtils.parseCSV(bottomManagedNodeNames);

            tankModule = new ModelModule <TankModelData, SSTUModularFuelTank>(part, this, getRootTransform(rootTransformName, true), ModelOrientation.CENTRAL, nameof(bodyModuleData), nameof(currentTankType), nameof(currentTankTexture));
            tankModule.getSymmetryModule = m => m.tankModule;
            tankModule.getDisplayNames   = m => SSTUUtils.getNames(m, s => s.variantName);
            tankModule.setupModelList(mainTankModules);

            currentTankSetModule = Array.Find(tankSets, m => m.name == tankModule.model.setName);
            currentTankSet       = currentTankSetModule.name;
            lastSelectedVariant  = tankModule.model.variantName;

            tankModule.getValidSelections = delegate(IEnumerable <TankModelData> data) { return(System.Linq.Enumerable.Where(data, s => s.setName == currentTankSet)); };
            tankModule.updateSelections();
            tankModule.setupModel();

            len = mountNodes.Length;
            ConfigNode             mountNode;
            List <SingleModelData> noses  = new List <SingleModelData>();
            List <SingleModelData> mounts = new List <SingleModelData>();

            for (int i = 0; i < len; i++)
            {
                mountNode = mountNodes[i];
                if (mountNode.GetBoolValue("useForNose", true))
                {
                    mountNode.SetValue("nose", "true");
                    noses.Add(new SingleModelData(mountNode));
                }
                if (mountNode.GetBoolValue("useForMount", true))
                {
                    mountNode.SetValue("nose", "false");
                    mounts.Add(new SingleModelData(mountNode));
                }
            }

            noseModule = new ModelModule <SingleModelData, SSTUModularFuelTank>(part, this, getRootTransform(rootNoseTransformName, true), ModelOrientation.TOP, nameof(noseModuleData), nameof(currentNoseType), nameof(currentNoseTexture));
            noseModule.getSymmetryModule  = m => m.noseModule;
            noseModule.getValidSelections = delegate(IEnumerable <SingleModelData> data)
            {
                return(System.Linq.Enumerable.Where(data, m => m.canSwitchTo(part, topNodeNames) && TankVariant.isValidNose(m.name, tankModule.model.variantName, variantData)));
            };
            noseModule.setupModelList(noses);
            noseModule.setupModel();

            mountModule = new ModelModule <SingleModelData, SSTUModularFuelTank>(part, this, getRootTransform(rootMountTransformName, true), ModelOrientation.BOTTOM, nameof(mountModuleData), nameof(currentMountType), nameof(currentMountTexture));
            mountModule.getSymmetryModule  = m => m.mountModule;
            mountModule.getValidSelections = delegate(IEnumerable <SingleModelData> data)
            {
                return(System.Linq.Enumerable.Where(data, m => m.canSwitchTo(part, bottomNodeNames) && TankVariant.isValidMount(m.name, tankModule.model.variantName, variantData)));
            };
            mountModule.setupModelList(mounts);
            mountModule.setupModel();
        }
Пример #12
0
 /// <summary>
 /// Finds the model for the given part, if it currently exists; else it clones it
 /// </summary>
 /// <param name="model"></param>
 /// <returns></returns>
 private void setupModel(ModelData model, Transform parent)
 {
     model.setupModel(part, parent);
 }
Пример #13
0
        /// <summary>
        /// Should be called by the PartModule to open the GUI.
        /// </summary>
        /// <param name="models"></param>
        public static void openGUI(ModelData[] models, float diameter, Action<String, bool> modelSelectedCB)
        {
            if (guiOpen)
            {
                throw new NotSupportedException("Cannot open a GUI when it is already open!");
            }

            EditorLogic editor = EditorLogic.fetch;
            if (editor != null) { editor.Lock(true, true, true, "SSTUModelSelectLock"); }

            adapters = ModelGUISelection.createFromModelData(models, diameter);
            modelSelectedCallback = modelSelectedCB;
            guiOpen = true;
            shouldClose = false;

            UIPartActionController.Instance.Deactivate();
        }