Exemple #1
0
        private static void ResUpdate(Vessel v, List <ResourceRatio> inputList, string ResourceName, float Efficiency, float systemHeatEfficiency, double abundance, double elapsed_s)
        {
            ResourceRecipe recipe = new ResourceRecipe(KERBALISM.ResourceBroker.GetOrCreate(
                                                           brokerName,
                                                           KERBALISM.ResourceBroker.BrokerCategory.Harvester,
                                                           brokerTitle));

            foreach (ResourceRatio ir in inputList)
            {
                recipe.AddInput(ir.ResourceName, ir.Ratio * elapsed_s);
            }
            recipe.AddOutput(ResourceName, Efficiency * systemHeatEfficiency * abundance * elapsed_s, dump: true);
            KERBALISM.ResourceCache.Get(v).AddRecipe(recipe);
        }
Exemple #2
0
        private static void ResUpdate(Vessel v, List <ResourceRatio> inputList, List <ResourceRatio> outputList, float systemHeatEfficiency, double elapsed_s)
        {
            ResourceRecipe recipe = new ResourceRecipe(KERBALISM.ResourceBroker.GetOrCreate(brokerName, KERBALISM.ResourceBroker.BrokerCategory.Converter, brokerTitle));

            foreach (ResourceRatio ir in inputList)
            {
                recipe.AddInput(ir.ResourceName, ir.Ratio * elapsed_s);
            }
            foreach (ResourceRatio or in outputList)
            {
                recipe.AddOutput(or.ResourceName, or.Ratio * systemHeatEfficiency * elapsed_s, or.DumpExcess);
            }
            KERBALISM.ResourceCache.Get(v).AddRecipe(recipe);
        }
    void Awake()
    {
        if (_instance != null && _instance != this)
        {
            throw new System.Exception("Multiple GameData instances are present. There should only be one instance of a Singleton.");
        }
        else
        {
            _instance = this;
        }

        // Load Resources
        nameToResource = new Dictionary <string, InGameResource>();
        baseResources  = new List <InGameResource>();
        using (StringReader reader = new StringReader(resourceFile.text))
        {
            string[] headers         = reader.ReadLine().Split(',');
            string[] expectedHeaders = { "Name", "Is Base" };
            CheckFileHeaders("resources", expectedHeaders, headers);

            while (reader.Peek() != -1)
            {
                string[]       fields   = reader.ReadLine().Split(',');
                InGameResource resource = new InGameResource(name: fields[0], isBaseResource: bool.Parse(fields[1]));

                nameToResource[resource.Name] = resource;
                if (resource.IsBaseResource)
                {
                    baseResources.Add(resource);
                }
            }
        }

        // Load Units
        mainBaseUnitInfo = null;
        nameToUnitInfo   = new Dictionary <string, UnitInfo>();
        using (StringReader reader = new StringReader(unitsFile.text))
        {
            string[] headers         = reader.ReadLine().Split(',');
            string[] expectedHeaders = { "Name", "MoveRange", "Health", "CloseDefense", "LongDefense", "CloseAttack", "LongAttack", "AttackRange", "Extra" };
            CheckFileHeaders("units", expectedHeaders, headers);

            while (reader.Peek() != -1)
            {
                string[] fields = reader.ReadLine().Split(',');

                Unit unitPrefab = Resources.Load <Unit>("UnitPrefabs/" + fields[0]);

                if (unitPrefab == null)
                {
                    throw new System.Exception("Failed to load unit in Resources/UnitPrefabs: " + fields[0]);
                }

                UnitInfo unitInfo = new UnitInfo(name: fields[0],
                                                 maxMoveRange: int.Parse(fields[1]),
                                                 health: int.Parse(fields[2]),
                                                 closeDefense: int.Parse(fields[3]),
                                                 longDefense: int.Parse(fields[4]),
                                                 closeAttack: int.Parse(fields[5]),
                                                 longAttack: int.Parse(fields[6]),
                                                 attackRange: int.Parse(fields[7]),
                                                 extra: fields[8],
                                                 unitPrefab: unitPrefab);

                nameToUnitInfo[fields[0]] = unitInfo;
                if (mainBaseUnitInfo != null)
                {
                    mainBaseUnitInfo = unitInfo;
                }
            }
        }

        // Load Recipes
        nameToRecipes = new Dictionary <string, Recipe>();
        using (StringReader reader = new StringReader(recipesFile.text))
        {
            string[] headers         = reader.ReadLine().Split(',');
            string[] expectedHeaders = { "Recipe Name", "Output", "Output Quantity", "Max Stack", "Input Item", "Input Quantity" };
            CheckFileHeaders("recipes", expectedHeaders, headers);


            Recipe recipe = null;
            while (reader.Peek() != -1)
            {
                string[] fields = reader.ReadLine().Split(',');

                // Starting a new recipe
                if (fields[0] != "")
                {
                    // recipe will be null in the first iteration
                    if (recipe != null)
                    {
                        RegisterRecipe(recipe);
                    }

                    // Check whether the recipe creates a resource or a unit
                    if (nameToResource.ContainsKey(fields[1]))
                    {
                        recipe = new ResourceRecipe(recipeName: fields[0],
                                                    outputName: fields[1],
                                                    outputQuantity: int.Parse(fields[2]),
                                                    maxStack: int.Parse(fields[3]));
                    }
                    else if (nameToUnitInfo.ContainsKey(fields[1]))
                    {
                        recipe = new UnitRecipe(
                            recipeName: fields[0],
                            outputName: fields[1]);
                    }
                    else
                    {
                        throw new System.Exception($"The provided output {fields[1]} does not exist as a Resource or as a Unit");
                    }
                    recipe.AddInput(nameToResource[fields[4]], int.Parse(fields[5]));
                }
            }

            RegisterRecipe(recipe);
        }
    }
Exemple #4
0
        // Simulate resources production/consumption for unloaded vessel
        public static string BackgroundUpdate(Vessel v, ProtoPartSnapshot part_snapshot, ProtoPartModuleSnapshot module_snapshot, PartModule proto_part_module, Part proto_part, Dictionary <string, double> availableResources, List <KeyValuePair <string, double> > resourceChangeRequest, double elapsed_s)
        {
            ProtoPartModuleSnapshot reactor = KSHUtils.FindPartModuleSnapshot(part_snapshot, engineModuleName);

            if (reactor != null)
            {
                if (Lib.Proto.GetBool(reactor, "Enabled") && Lib.Proto.GetBool(module_snapshot, "GeneratesElectricity"))
                {
                    float curThrottle       = Lib.Proto.GetFloat(reactor, "CurrentReactorThrottle") / 100f;
                    float minThrottle       = Lib.Proto.GetFloat(module_snapshot, "MinThrottle");
                    float maxThrottle       = Lib.Proto.GetFloat(module_snapshot, "MaxThrottle");
                    float maxECGeneration   = Lib.Proto.GetFloat(module_snapshot, "MaxECGeneration");
                    bool  needToStopReactor = false;
                    if (maxECGeneration > 0)
                    {
                        VesselResources resources = KERBALISM.ResourceCache.Get(v);
                        if (!(proto_part_module as SystemHeatFissionEngineKerbalismUpdater).resourcesListParsed)
                        {
                            (proto_part_module as SystemHeatFissionEngineKerbalismUpdater).ParseResourcesList(proto_part);
                        }

                        // Mininum reactor throttle
                        // Some input/output resources will always be consumed/produced as long as minThrottle > 0
                        if (minThrottle > 0)
                        {
                            ResourceRecipe recipe = new ResourceRecipe(KERBALISM.ResourceBroker.GetOrCreate(
                                                                           brokerName,
                                                                           KERBALISM.ResourceBroker.BrokerCategory.Converter,
                                                                           brokerTitle));
                            foreach (ResourceRatio ir in (proto_part_module as SystemHeatFissionEngineKerbalismUpdater).inputs)
                            {
                                recipe.AddInput(ir.ResourceName, ir.Ratio * minThrottle * elapsed_s);
                                if (resources.GetResource(v, ir.ResourceName).Amount < double.Epsilon)
                                {
                                    // Input resource amount is zero - stop reactor
                                    needToStopReactor = true;
                                }
                            }
                            foreach (ResourceRatio or in (proto_part_module as SystemHeatFissionEngineKerbalismUpdater).outputs)
                            {
                                recipe.AddOutput(or.ResourceName, or.Ratio * minThrottle * elapsed_s, dump: false);
                                if (1 - resources.GetResource(v, or.ResourceName).Level < double.Epsilon)
                                {
                                    // Output resource is at full capacity
                                    needToStopReactor = true;
                                    Message.Post(
                                        Severity.warning,
                                        Localizer.Format(
                                            "#LOC_KerbalismSystemHeat_ReactorOutputResourceFull",
                                            or.ResourceName,
                                            v.GetDisplayName(),
                                            part_snapshot.partName)
                                        );
                                }
                            }
                            recipe.AddOutput("ElectricCharge", minThrottle * maxECGeneration * elapsed_s, dump: true);
                            resources.AddRecipe(recipe);
                        }

                        if (!needToStopReactor)
                        {
                            if (!Lib.Proto.GetBool(reactor, "ManualControl"))
                            {
                                // Automatic reactor throttle mode
                                curThrottle = maxThrottle;
                            }
                            curThrottle -= minThrottle;
                            if (curThrottle > 0)
                            {
                                ResourceRecipe recipe = new ResourceRecipe(KERBALISM.ResourceBroker.GetOrCreate(
                                                                               brokerName,
                                                                               KERBALISM.ResourceBroker.BrokerCategory.Converter,
                                                                               brokerTitle));
                                foreach (ResourceRatio ir in (proto_part_module as SystemHeatFissionEngineKerbalismUpdater).inputs)
                                {
                                    recipe.AddInput(ir.ResourceName, ir.Ratio * curThrottle * elapsed_s);
                                    if (resources.GetResource(v, ir.ResourceName).Amount < double.Epsilon)
                                    {
                                        // Input resource amount is zero - stop reactor
                                        needToStopReactor = true;
                                    }
                                }
                                foreach (ResourceRatio or in (proto_part_module as SystemHeatFissionEngineKerbalismUpdater).outputs)
                                {
                                    recipe.AddOutput(or.ResourceName, or.Ratio * curThrottle * elapsed_s, dump: false);
                                    if (1 - resources.GetResource(v, or.ResourceName).Level < double.Epsilon)
                                    {
                                        // Output resource is at full capacity
                                        needToStopReactor = true;
                                        Message.Post(
                                            Severity.warning,
                                            Localizer.Format(
                                                "#LOC_KerbalismSystemHeat_ReactorOutputResourceFull",
                                                or.ResourceName,
                                                v.GetDisplayName(),
                                                part_snapshot.partName)
                                            );
                                    }
                                }
                                recipe.AddOutput("ElectricCharge", curThrottle * maxECGeneration * elapsed_s, dump: false);
                                resources.AddRecipe(recipe);
                            }
                        }
                    }

                    // Disable reactor
                    if (needToStopReactor)
                    {
                        Lib.Proto.Set(reactor, "Enabled", false);
                    }
                }
                else
                {
                    // Reactor disabled - radiation decay mechanics
                    if (Features.Radiation &&
                        Lib.Proto.GetBool(module_snapshot, "ReactorHasStarted") &&
                        Lib.Proto.GetDouble(module_snapshot, "ReactorStoppedTimestamp") > 0 &&
                        Lib.Proto.GetDouble(module_snapshot, "MinEmissionPercent") < 100)
                    {
                        ProtoPartModuleSnapshot emitter = KSHUtils.FindPartModuleSnapshot(part_snapshot, "Emitter");
                        if (emitter != null)
                        {
                            double EmitterMaxRadiation = Lib.Proto.GetDouble(module_snapshot, "EmitterMaxRadiation");
                            double MinEmissionPercent  = Lib.Proto.GetDouble(module_snapshot, "MinEmissionPercent");
                            double EmissionDecayRate   = Lib.Proto.GetDouble(module_snapshot, "EmissionDecayRate");
                            double MinRadiation        = EmitterMaxRadiation * MinEmissionPercent / 100;
                            if (EmissionDecayRate <= 0)
                            {
                                Lib.Proto.Set(emitter, "radiation", MinRadiation);
                                Lib.Proto.Set(module_snapshot, "ReactorStoppedTimestamp", 0d);
                            }
                            else
                            {
                                double secondsPassed = Planetarium.GetUniversalTime() - Lib.Proto.GetDouble(module_snapshot, "ReactorStoppedTimestamp");
                                if (secondsPassed > 0)
                                {
                                    double NewRadiation = EmitterMaxRadiation * (100 - secondsPassed / EmissionDecayRate) / 100;
                                    if (NewRadiation <= MinRadiation)
                                    {
                                        NewRadiation = MinRadiation;
                                        Lib.Proto.Set(module_snapshot, "ReactorStoppedTimestamp", 0d);
                                    }
                                    Lib.Proto.Set(emitter, "radiation", NewRadiation);
                                }
                            }
                        }
                    }
                }
                // Prevent resource consumption in ModuleSystemHeatFissionReactor.DoCatchup()
                // by setting LastUpdate to current time
                Lib.Proto.Set(reactor, "LastUpdateTime", Planetarium.GetUniversalTime());
                return(brokerTitle);
            }
            return("ERR: no engine");
        }