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; }
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); }
public PowerDistributionPair(IResourceSuppliable key, PowerDistribution value) { Key = key; Value = value; }
public void PowerDrawPerSecond(IResourceSuppliable pm, double powerRequested, double powerConsumed) { PowerDrawPerSecond(pm, powerRequested, powerRequested, powerConsumed); }