Exemple #1
0
        public void powerDrawFixed(IResourceSuppliable pm, double power_draw, double power_cosumtion)
        {
            var timeWarpFixedDeltaTime     = TimeWarpFixedDeltaTime;
            var power_draw_per_second      = power_draw / timeWarpFixedDeltaTime;
            var power_cosumtion_per_second = power_cosumtion / timeWarpFixedDeltaTime;

            PowerDistribution powerDistribution;

            if (!power_consumption.TryGetValue(pm, out powerDistribution))
            {
                powerDistribution = new PowerDistribution();
                power_consumption.Add(pm, powerDistribution);
            }
            powerDistribution.Power_draw    += power_draw_per_second;
            powerDistribution.Power_consume += power_cosumtion_per_second;
        }
        public void powerDrawPerSecond(IResourceSuppliable pm, double power_current_requested, double power_maximum_requested, double power_consumed)
        {
            if (power_current_requested.IsInfinityOrNaN() || power_maximum_requested.IsInfinityOrNaN() || power_consumed.IsInfinityOrNaN())
            {
                return;
            }

            CurrentConsumption += power_consumed;

            if (!consumptionRequests.TryGetValue(pm, out PowerDistribution powerDistribution))
            {
                consumptionRequests.Add(pm, powerDistribution = new PowerDistribution());
            }

            powerDistribution.PowerCurrentRequest += power_current_requested;
            powerDistribution.PowerMaximumRequest += power_maximum_requested;
            powerDistribution.PowerConsumed       += power_consumed;
        }
Exemple #3
0
        public void update(long counter)
        {
            var timeWarpFixedDeltaTime = TimeWarpFixedDeltaTime;

            IsUpdatedAtLeastOnce = true;
            Counter = counter;

            stored_supply                = currentPowerSupply;
            stored_stable_supply         = stable_supply;
            stored_resource_demand       = current_resource_demand;
            stored_current_demand        = current_resource_demand;
            stored_current_hp_demand     = high_priority_resource_demand;
            stored_current_charge_demand = charge_resource_demand;
            stored_total_power_supplied  = total_power_distributed;

            current_resource_demand       = 0;
            high_priority_resource_demand = 0;
            charge_resource_demand        = 0;
            total_power_distributed       = 0;

            double availableResourceAmount;
            double maxResouceAmount;

            my_part.GetConnectedResourceTotals(resourceDefinition.id, out availableResourceAmount, out maxResouceAmount);

            if (maxResouceAmount > 0 && !double.IsNaN(maxResouceAmount) && !double.IsNaN(availableResourceAmount))
            {
                resource_bar_ratio_end = availableResourceAmount / maxResouceAmount;
            }
            else
            {
                resource_bar_ratio_end = 0.0001;
            }

            double missingResourceAmount = maxResouceAmount - availableResourceAmount;

            currentPowerSupply += availableResourceAmount;

            double high_priority_demand_supply_ratio = high_priority_resource_demand > 0
                ? Math.Min((currentPowerSupply - stored_current_charge_demand) / stored_current_hp_demand, 1.0)
                : 1.0;

            double demand_supply_ratio = stored_current_demand > 0
                ? Math.Min((currentPowerSupply - stored_current_charge_demand - stored_current_hp_demand) / stored_current_demand, 1.0)
                : 1.0;

            //First supply minimal Amount of Stock ElectricCharge resource to keep probe core and life support functioning
            if (resourceDefinition.id == megajouleResourceDefinition.id && stored_stable_supply > 0)
            {
                double amount;
                double maxAmount;

                my_part.GetConnectedResourceTotals(electricResourceDefinition.id, out amount, out maxAmount);
                double stock_electric_charge_needed = Math.Min(10, maxAmount - amount);
                if (stock_electric_charge_needed > 0)
                {
                    var deltaResourceDemand = stock_electric_charge_needed / 1000 / timeWarpFixedDeltaTime;
                    current_resource_demand += deltaResourceDemand;
                    charge_resource_demand  += deltaResourceDemand;
                }

                double power_supplied = Math.Min(currentPowerSupply * 1000 * timeWarpFixedDeltaTime, stock_electric_charge_needed);
                if (power_supplied > 0)
                {
                    double fixed_provided_electric_charge_in_MW = my_part.RequestResource(ResourceManager.STOCK_RESOURCE_ELECTRICCHARGE, -power_supplied) / 1000;
                    var    provided_electric_charge_per_second  = fixed_provided_electric_charge_in_MW / timeWarpFixedDeltaTime;
                    total_power_distributed += -provided_electric_charge_per_second;
                    currentPowerSupply      += provided_electric_charge_per_second;
                }
            }

            power_supply_list_archive = power_produced.OrderByDescending(m => m.Value.maximumSupply).ToList();

            // store current supply and update average
            power_supply_list_archive.ForEach(m =>
            {
                Queue <double> queue;

                if (!power_produced_history.TryGetValue(m.Key, out queue))
                {
                    queue = new Queue <double>(10);
                    power_produced_history.Add(m.Key, queue);
                }

                if (queue.Count > 10)
                {
                    queue.Dequeue();
                }
                queue.Enqueue(m.Value.currentSupply);

                m.Value.averageSupply = queue.Average();
            });

            List <KeyValuePair <IResourceSuppliable, PowerDistribution> > power_draw_items = power_consumption.OrderBy(m => m.Value.Power_draw).ToList();

            power_draw_list_archive = power_draw_items.ToList();
            power_draw_list_archive.Reverse();

            // check priority 0 parts like fusion reactors that need to be fed before any other parts can consume large amounts of power
            foreach (KeyValuePair <IResourceSuppliable, PowerDistribution> power_kvp in power_draw_items)
            {
                IResourceSuppliable resourceSuppliable = power_kvp.Key;

                if (resourceSuppliable.getPowerPriority() == 0)
                {
                    double power = power_kvp.Value.Power_draw;
                    current_resource_demand       += power;
                    high_priority_resource_demand += power;

                    if (flow_type == FNRESOURCE_FLOWTYPE_EVEN)
                    {
                        power = power * high_priority_demand_supply_ratio;
                    }

                    double power_supplied = Math.Max(Math.Min(currentPowerSupply, power), 0.0);

                    currentPowerSupply      -= power_supplied;
                    total_power_distributed += power_supplied;

                    //notify of supply
                    resourceSuppliable.receiveFNResource(power_supplied, this.resource_name);
                }
            }

            //Prioritise supplying stock ElectricCharge for High power
            if (resourceDefinition.id == megajouleResourceDefinition.id && stored_stable_supply > 0)
            {
                double amount;
                double maxAmount;

                my_part.GetConnectedResourceTotals(electricResourceDefinition.id, out amount, out maxAmount);
                double stock_electric_charge_needed = maxAmount - amount;

                double power_supplied = Math.Min(currentPowerSupply * 1000 * timeWarpFixedDeltaTime, stock_electric_charge_needed);
                if (stock_electric_charge_needed > 0)
                {
                    var deltaResourceDemand = stock_electric_charge_needed / 1000 / timeWarpFixedDeltaTime;
                    current_resource_demand += deltaResourceDemand;
                    charge_resource_demand  += deltaResourceDemand;
                }

                if (power_supplied > 0)
                {
                    double fixed_provided_electric_charge_in_MW = my_part.RequestResource(ResourceManager.STOCK_RESOURCE_ELECTRICCHARGE, -power_supplied) / 1000;
                    var    provided_electric_charge_per_second  = fixed_provided_electric_charge_in_MW / timeWarpFixedDeltaTime;
                    total_power_distributed += -provided_electric_charge_per_second;
                    currentPowerSupply      += provided_electric_charge_per_second;
                }
            }

            // check priority 1 parts
            foreach (KeyValuePair <IResourceSuppliable, PowerDistribution> power_kvp in power_draw_items)
            {
                IResourceSuppliable resourceSuppliable = power_kvp.Key;

                if (resourceSuppliable.getPowerPriority() == 1)
                {
                    double power = power_kvp.Value.Power_draw;
                    current_resource_demand       += power;
                    high_priority_resource_demand += power;

                    if (flow_type == FNRESOURCE_FLOWTYPE_EVEN)
                    {
                        power = power * high_priority_demand_supply_ratio;
                    }

                    double power_supplied = Math.Max(Math.Min(currentPowerSupply, power), 0.0);

                    currentPowerSupply      -= power_supplied;
                    total_power_distributed += power_supplied;

                    //notify of supply
                    resourceSuppliable.receiveFNResource(power_supplied, this.resource_name);
                }
            }

            // check priority 2 parts
            foreach (KeyValuePair <IResourceSuppliable, PowerDistribution> power_kvp in power_draw_items)
            {
                IResourceSuppliable resourceSuppliable = power_kvp.Key;

                if (resourceSuppliable.getPowerPriority() == 2)
                {
                    double power = power_kvp.Value.Power_draw;
                    current_resource_demand += power;

                    if (flow_type == FNRESOURCE_FLOWTYPE_EVEN)
                    {
                        power = power * demand_supply_ratio;
                    }

                    double power_supplied = Math.Max(Math.Min(currentPowerSupply, power), 0.0);

                    currentPowerSupply      -= power_supplied;
                    total_power_distributed += power_supplied;

                    //notify of supply
                    resourceSuppliable.receiveFNResource(power_supplied, this.resource_name);
                }
            }

            // check priority 3 parts like engines and nuclear reactors
            foreach (KeyValuePair <IResourceSuppliable, PowerDistribution> power_kvp in power_draw_items)
            {
                IResourceSuppliable resourceSuppliable = power_kvp.Key;

                if (resourceSuppliable.getPowerPriority() == 3)
                {
                    double power = power_kvp.Value.Power_draw;
                    current_resource_demand += power;

                    if (flow_type == FNRESOURCE_FLOWTYPE_EVEN)
                    {
                        power = power * demand_supply_ratio;
                    }

                    double power_supplied = Math.Max(Math.Min(currentPowerSupply, power), 0.0);

                    currentPowerSupply      -= power_supplied;
                    total_power_distributed += power_supplied;

                    //notify of supply
                    resourceSuppliable.receiveFNResource(power_supplied, this.resource_name);
                }
            }

            // check priority 4 parts like antimatter reactors, engines and transmitters
            foreach (KeyValuePair <IResourceSuppliable, PowerDistribution> power_kvp in power_draw_items)
            {
                IResourceSuppliable resourceSuppliable = power_kvp.Key;

                if (resourceSuppliable.getPowerPriority() == 4)
                {
                    double power = power_kvp.Value.Power_draw;
                    current_resource_demand += power;

                    if (flow_type == FNRESOURCE_FLOWTYPE_EVEN)
                    {
                        power = power * demand_supply_ratio;
                    }

                    double power_supplied = Math.Max(Math.Min(currentPowerSupply, power), 0.0);

                    currentPowerSupply      -= power_supplied;
                    total_power_distributed += power_supplied;

                    //notify of supply
                    resourceSuppliable.receiveFNResource(power_supplied, this.resource_name);
                }
            }

            // check priority 5 parts and higher
            foreach (KeyValuePair <IResourceSuppliable, PowerDistribution> power_kvp in power_draw_items)
            {
                IResourceSuppliable resourceSuppliable = power_kvp.Key;

                if (resourceSuppliable.getPowerPriority() >= 5)
                {
                    double power = power_kvp.Value.Power_draw;
                    current_resource_demand += power;

                    if (flow_type == FNRESOURCE_FLOWTYPE_EVEN)
                    {
                        power = power * demand_supply_ratio;
                    }

                    double power_supplied = Math.Max(Math.Min(currentPowerSupply, power), 0.0);

                    currentPowerSupply      -= power_supplied;
                    total_power_distributed += power_supplied;

                    //notify of supply
                    resourceSuppliable.receiveFNResource(power_supplied, this.resource_name);
                }
            }

            // substract avaialble resource amount to get delta resource change
            currentPowerSupply         -= Math.Max(availableResourceAmount, 0.0);
            internl_power_extract_fixed = -currentPowerSupply * timeWarpFixedDeltaTime;

            if (resourceDefinition.id == wasteheatResourceDefinition.id)
            {
                // passive dissip of waste heat - a little bit of this
                double vessel_mass    = my_vessel.totalMass;
                double passive_dissip = 2947.295521 * GameConstants.stefan_const * vessel_mass * 2;
                internl_power_extract_fixed += passive_dissip * TimeWarp.fixedDeltaTime;

                if (my_vessel.altitude <= PluginHelper.getMaxAtmosphericAltitude(my_vessel.mainBody))
                {
                    // passive convection - a lot of this
                    double pressure          = FlightGlobals.getStaticPressure(my_vessel.transform.position) * 0.01;
                    double conv_power_dissip = pressure * 40 * vessel_mass * GameConstants.rad_const_h / 1e6 * TimeWarp.fixedDeltaTime;
                    internl_power_extract_fixed += conv_power_dissip;
                }
            }

            if (internl_power_extract_fixed > 0)
            {
                internl_power_extract_fixed = Math.Min(internl_power_extract_fixed, availableResourceAmount);
            }
            else
            {
                internl_power_extract_fixed = Math.Max(internl_power_extract_fixed, -missingResourceAmount);
            }

            my_part.RequestResource(resourceDefinition.id, internl_power_extract_fixed);

            my_part.GetConnectedResourceTotals(resourceDefinition.id, out availableResourceAmount, out maxResouceAmount);

            if (maxResouceAmount > 0 && !double.IsNaN(maxResouceAmount) && !double.IsNaN(availableResourceAmount))
            {
                resource_bar_ratio_begin = availableResourceAmount / maxResouceAmount;
            }
            else
            {
                resource_bar_ratio_begin = resourceDefinition.id == wasteheatResourceDefinition.id ? 0.999 : 0;
            }

            //calculate total input and output
            //var total_current_supplied = power_produced.Sum(m => m.Value.currentSupply);
            //var total_current_provided = power_produced.Sum(m => m.Value.currentProvided);
            //var total_power_consumed = power_consumption.Sum(m => m.Value.Power_consume);
            //var total_power_min_supplied = power_produced.Sum(m => m.Value.minimumSupply);

            ////generate wasteheat from used thermal power + thermal store
            //if (!CheatOptions.IgnoreMaxTemperature && total_current_produced > 0 &&
            //    (resourceDefinition.id == thermalpowerResourceDefinition.id || resourceDefinition.id == chargedpowerResourceDefinition.id))
            //{
            //    var min_supplied_fixed = TimeWarp.fixedDeltaTime * total_power_min_supplied;
            //    var used_or_stored_power_fixed = TimeWarp.fixedDeltaTime * Math.Min(total_power_consumed, total_current_produced) + Math.Max(-actual_stored_power, 0);
            //    var wasteheat_produced_fixed = Math.Max(min_supplied_fixed, used_or_stored_power_fixed);

            //    var effective_wasteheat_ratio = Math.Max(wasteheat_produced_fixed / (total_current_produced * TimeWarp.fixedDeltaTime), 1);

            //    ORSResourceManager manager = ORSResourceOvermanager.getResourceOvermanagerForResource(ResourceManager.FNRESOURCE_WASTEHEAT).getManagerForVessel(my_vessel);

            //    foreach (var supplier_key_value in power_produced)
            //    {
            //        if (supplier_key_value.Value.currentSupply > 0)
            //        {
            //            manager.powerSupplyPerSecondWithMax(supplier_key_value.Key, supplier_key_value.Value.currentSupply * effective_wasteheat_ratio, supplier_key_value.Value.maximumSupply * effective_wasteheat_ratio);
            //        }
            //    }
            //}

            currentPowerSupply = 0;
            stable_supply      = 0;

            power_produced.Clear();
            power_consumption.Clear();
        }
 public void powerDrawPerSecond(IResourceSuppliable pm, double power_requested, double power_consumed)
 {
     powerDrawPerSecond(pm, power_requested, power_requested, power_consumed);
 }
Exemple #5
0
 public PowerDistributionPair(IResourceSuppliable key, PowerDistribution value)
 {
     Key   = key;
     Value = value;
 }
Exemple #6
0
 public void PowerDrawPerSecond(IResourceSuppliable pm, double powerRequested, double powerConsumed)
 {
     PowerDrawPerSecond(pm, powerRequested, powerRequested, powerConsumed);
 }