Beispiel #1
0
        public override void OnLoad(ConfigNode node)
        {
            // setups data from structured config node is only available at part compilation
            // for this reason, we parse it and then re-serialize it as a string
            if (HighLogic.LoadedScene == GameScenes.LOADING)
            {
                // parse all setups from config node and generate details
                setups = new List <ConfigureSetup>();
                foreach (var setup_node in node.GetNodes("SETUP"))
                {
                    setups.Add(new ConfigureSetup(setup_node, this));
                }

                // serialize the setups to string data
                var archive = new WriteArchive();
                archive.Save(setups.Count);
                foreach (var setup in setups)
                {
                    setup.Save(archive);
                }
                data = archive.Serialize();

                // serialize empty configuration to string data
                archive = new WriteArchive();
                archive.Save(0);
                cfg = archive.Serialize();

                // serialize empty previous configuration to string data
                archive = new WriteArchive();
                archive.Save(0);
                prev_cfg = archive.Serialize();
            }
        }
Beispiel #2
0
        public void DoConfigure()
        {
            // shortcut to resource library
            var reslib = PartResourceLibrary.Instance.resourceDefinitions;

            // reset extra cost and mass
            extra_cost = 0.0;
            extra_mass = 0.0;

            // find modules unlocked by tech
            unlocked = new List <ConfigureSetup>();
            foreach (ConfigureSetup setup in setups)
            {
                // if unlocked
                if (setup.tech.Length == 0 || Lib.HasTech(setup.tech))
                {
                    // unlock
                    unlocked.Add(setup);
                }
            }

            // make sure configuration include all available slots
            // this also create default configuration
            // - we do it only in the editor
            // - we avoid corner case when cfg was never set up (because craft was never in VAB)
            if (Lib.IsEditor() || selected.Count == 0)
            {
                while (selected.Count < Math.Min(slots, (uint)unlocked.Count))
                {
                    selected.Add(unlocked.Find(k => selected.IndexOf(k.name) == -1).name);
                }
            }

            // for each setup
            foreach (ConfigureSetup setup in setups)
            {
                // detect if the setup is selected in multiple slots
                int count = (selected.FindAll(x => x == setup.name)).Count;

                // detect if the setup is selected
                bool active = count > 0;
                active &= enabled;

                // detect if the setup was previously selected in multiple slots
                int prev_count = (prev_selected.FindAll(x => x == setup.name)).Count;

                // detect if the setup was previously selected
                bool prev_active = prev_count > 0;

                // for each module specification in the setup
                foreach (ConfigureModule cm in setup.modules)
                {
                    // try to find the module
                    PartModule m = Find_module(cm);

                    // if the module exist
                    if (m != null)
                    {
                        // call configure/deconfigure functions on module if available
                        if (m is IConfigurable configurable_module)
                        {
                            configurable_module.Configure(active);
                        }

                        // enable/disable the module
                        m.isEnabled = active;
                        m.enabled   = active;
                    }
                }

                // for each resource specification in the setup
                foreach (ConfigureResource cr in setup.resources)
                {
                    // ignore non-existing resources
                    if (!reslib.Contains(cr.name))
                    {
                        continue;
                    }

                    // get resource unit cost
                    double unit_cost = reslib[cr.name].unitCost;

                    // parse resource amount and capacity
                    double amount   = Lib.Parse.ToDouble(cr.amount);
                    double capacity = Lib.Parse.ToDouble(cr.maxAmount);

                    // add/remove resource
                    if ((prev_active != (active && capacity > 0.0)) || (reconfigure_cs && initialized) || (count != prev_count))
                    {
                        // if previously selected
                        if (prev_active)
                        {
                            // remove the resources
                            prev_count = prev_count == 0 ? 1 : prev_count;
                            Lib.RemoveResource(part, cr.name, amount * prev_count, capacity * prev_count);
                        }

                        // if selected
                        if (active && capacity > 0.0)
                        {
                            // add the resources
                            // - in flight, do not add amount
                            Lib.AddResource(part, cr.name, Lib.IsFlight() ? 0.0 : amount * count, capacity * count);
                        }
                    }

                    // add resource cost
                    if (active)
                    {
                        extra_cost += amount * unit_cost * count;
                    }
                }

                // add setup extra cost and mass
                if (active)
                {
                    extra_cost += setup.cost * count;
                    extra_mass += setup.mass * count;
                }
            }

            // remember previously selected setups
            prev_selected.Clear();
            foreach (string s in selected)
            {
                prev_selected.Add(s);
            }

            // save configuration
            WriteArchive archive = new WriteArchive();

            archive.Save(selected.Count);
            foreach (string s in selected)
            {
                archive.Save(s);
            }
            cfg = archive.Serialize();

            // save previous configuration
            archive = new WriteArchive();
            archive.Save(prev_selected.Count);
            foreach (string s in prev_selected)
            {
                archive.Save(s);
            }
            prev_cfg = archive.Serialize();

            // in the editor
            if (Lib.IsEditor())
            {
                // for each part in the symmetry group (avoid infinite recursion)
                if (!avoid_inf_recursion && symmetric)
                {
                    avoid_inf_recursion = true;
                    foreach (Part p in part.symmetryCounterparts)
                    {
                        // get the Configure module
                        Configure c = p.FindModulesImplementing <Configure>().Find(k => k.title == title);

                        // both modules will share configuration
                        c.selected = selected;

                        // re-configure the other module
                        c.DoConfigure();
                    }
                    avoid_inf_recursion = false;
                }
            }

            // refresh this part ui
            MonoUtilities.RefreshContextWindows(part);

            // refresh VAB ui
            if (Lib.IsEditor())
            {
                GameEvents.onEditorShipModified.Fire(EditorLogic.fetch.ship);
            }

            // this was configured at least once
            initialized = true;
        }