public void update() { IsUpdatedAtLeastOnce = true; 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_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) { resource_bar_ratio = availableResourceAmount / maxResouceAmount; } else { resource_bar_ratio = 0; } 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; //Prioritise supplying stock ElectricCharge resource if (String.Equals(this.resource_name, ORSResourceManager.FNRESOURCE_MEGAJOULES) && 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 * TimeWarp.fixedDeltaTime, stock_electric_charge_needed); if (stock_electric_charge_needed > 0) { var deltaResourceDemand = stock_electric_charge_needed / 1000.0 / TimeWarp.fixedDeltaTime; current_resource_demand += deltaResourceDemand; charge_resource_demand += deltaResourceDemand; } if (power_supplied > 0) { double fixed_provided_electric_charge_in_MW = my_part.RequestResource(ORSResourceManager.STOCK_RESOURCE_ELECTRICCHARGE, -power_supplied) / 1000; var provided_electric_charge_per_second = fixed_provided_electric_charge_in_MW / TimeWarp.fixedDeltaTime; total_power_distributed += -provided_electric_charge_per_second; currentPowerSupply += provided_electric_charge_per_second; } } //sort by power draw //var power_draw_items = from pair in power_draws orderby pair.Value ascending select pair; List <KeyValuePair <ORSResourceSuppliable, double> > power_draw_items = power_draws.ToList(); power_draw_items.Sort ( delegate(KeyValuePair <ORSResourceSuppliable, double> firstPair, KeyValuePair <ORSResourceSuppliable, double> nextPair) { return(firstPair.Value.CompareTo(nextPair.Value)); } ); power_draw_list_archive = power_draw_items.ToList(); power_draw_list_archive.Reverse(); // check priority 1 parts like reactors foreach (KeyValuePair <ORSResourceSuppliable, double> power_kvp in power_draw_items) { ORSResourceSuppliable resourceSuppliable = power_kvp.Key; if (resourceSuppliable.getPowerPriority() == 1) { double power = power_kvp.Value; 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 like engines foreach (KeyValuePair <ORSResourceSuppliable, double> power_kvp in power_draw_items) { ORSResourceSuppliable resourceSuppliable = power_kvp.Key; if (resourceSuppliable.getPowerPriority() == 2) { double power = power_kvp.Value; 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 foreach (KeyValuePair <ORSResourceSuppliable, double> power_kvp in power_draw_items) { ORSResourceSuppliable resourceSuppliable = power_kvp.Key; if (resourceSuppliable.getPowerPriority() == 3) { double power = power_kvp.Value; 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 = -currentPowerSupply * TimeWarp.fixedDeltaTime + internl_power_extract_remainder; internl_power_extract = -currentPowerSupply * TimeWarp.fixedDeltaTime; pluginSpecificImpl(); if (internl_power_extract > 0) { internl_power_extract = Math.Min(internl_power_extract, availableResourceAmount); } else { internl_power_extract = Math.Max(internl_power_extract, -missingResourceAmount); } //ORSHelper.fixedRequestResource(my_part, this.resource_name, internl_power_extract); var actual_stored_power = my_part.RequestResource(this.resource_name, internl_power_extract); //calculate total input and output var total_power_consumed = power_consumed.Sum(m => m.Value); var total_power_max_supplied = power_max_supplies.Sum(m => m.Value); var total_power_min_supplied = power_min_supplies.Sum(m => m.Value); //generate wasteheat from used thermal power + thermal store if (!CheatOptions.IgnoreMaxTemperature && total_power_max_supplied > 0 && (resourceDefinition.id == thermalpowerResourceDefinition.id || resourceDefinition.id == chargedpowerResourceDefinition.id)) { // calculate Wasteheat var min_supplied_per_second = TimeWarp.fixedDeltaTime * total_power_min_supplied; var max_supplied_pers_second = TimeWarp.fixedDeltaTime * Math.Min(total_power_consumed, total_power_max_supplied) + Math.Max(-actual_stored_power, 0); var wasteheatProduction = Math.Max(min_supplied_per_second, max_supplied_pers_second); // generate Wasteheat my_part.RequestResource(ORSResourceManager.FNRESOURCE_WASTEHEAT, -wasteheatProduction); } //internl_power_extract_remainder = internl_power_extract - actual_stored_power; currentPowerSupply = 0; stable_supply = 0; power_max_supplies.Clear(); power_min_supplies.Clear(); power_draws.Clear(); power_consumed.Clear(); }
public void update() { stored_supply = powersupply; stored_stable_supply = stable_supply; stored_resource_demand = current_resource_demand; double stored_current_demand = current_resource_demand; double stored_current_hp_demand = high_priority_resource_demand; double stored_current_charge_demand = charge_resource_demand; stored_charge_demand = charge_resource_demand; current_resource_demand = 0; high_priority_resource_demand = 0; charge_resource_demand = 0; //Debug.Log ("Early:" + powersupply); //stored power List <PartResource> partresources = new List <PartResource>(); my_part.GetConnectedResources(PartResourceLibrary.Instance.GetDefinition(resource_name).id, PartResourceLibrary.Instance.GetDefinition(resource_name).resourceFlowMode, partresources); double currentmegajoules = 0; double maxmegajoules = 0; foreach (PartResource partresource in partresources) { currentmegajoules += partresource.amount; maxmegajoules += partresource.maxAmount; } if (maxmegajoules > 0) { resource_bar_ratio = currentmegajoules / maxmegajoules; } else { resource_bar_ratio = 0; } double missingmegajoules = maxmegajoules - currentmegajoules; powersupply += currentmegajoules; //Debug.Log ("Current:" + currentmegajoules); double demand_supply_ratio = 0; double high_priority_demand_supply_ratio = 0; if (high_priority_resource_demand > 0) { high_priority_demand_supply_ratio = Math.Min((powersupply - stored_current_charge_demand) / stored_current_hp_demand, 1.0); } else { high_priority_demand_supply_ratio = 1.0; } if (stored_current_demand > 0) { demand_supply_ratio = Math.Min((powersupply - stored_current_charge_demand - stored_current_hp_demand) / stored_current_demand, 1.0); } else { demand_supply_ratio = 1.0; } //Debug.Log ("Late:" + powersupply); //Prioritise supplying stock ElectricCharge resource if (String.Equals(this.resource_name, ORSResourceManager.FNRESOURCE_MEGAJOULES) && stored_stable_supply > 0) { List <PartResource> partresources2 = new List <PartResource>(); my_part.GetConnectedResources(PartResourceLibrary.Instance.GetDefinition("ElectricCharge").id, PartResourceLibrary.Instance.GetDefinition("ElectricCharge").resourceFlowMode, partresources2); double stock_electric_charge_needed = 0; foreach (PartResource partresource in partresources2) { stock_electric_charge_needed += partresource.maxAmount - partresource.amount; } double power_supplied = Math.Min(powersupply * 1000 * TimeWarp.fixedDeltaTime, stock_electric_charge_needed); if (stock_electric_charge_needed > 0) { current_resource_demand += stock_electric_charge_needed / 1000.0 / TimeWarp.fixedDeltaTime; charge_resource_demand += stock_electric_charge_needed / 1000.0 / TimeWarp.fixedDeltaTime; } if (power_supplied > 0) { powersupply += my_part.RequestResource("ElectricCharge", -power_supplied) / 1000 / TimeWarp.fixedDeltaTime; } } //sort by power draw //var power_draw_items = from pair in power_draws orderby pair.Value ascending select pair; List <KeyValuePair <ORSResourceSuppliable, double> > power_draw_items = power_draws.ToList(); power_draw_items.Sort(delegate(KeyValuePair <ORSResourceSuppliable, double> firstPair, KeyValuePair <ORSResourceSuppliable, double> nextPair) { return(firstPair.Value.CompareTo(nextPair.Value)); }); power_draw_list_archive = power_draw_items.ToList(); power_draw_list_archive.Reverse(); // check engines foreach (KeyValuePair <ORSResourceSuppliable, double> power_kvp in power_draw_items) { ORSResourceSuppliable ms = power_kvp.Key; if (ms.getPowerPriority() == 1) { double power = power_kvp.Value; 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(powersupply, power), 0.0); //Debug.Log (power + ", " + powersupply + "::: " + power_supplied); powersupply -= power_supplied; //notify of supply ms.receiveFNResource(power_supplied, this.resource_name); } } // check others foreach (KeyValuePair <ORSResourceSuppliable, double> power_kvp in power_draw_items) { ORSResourceSuppliable ms = power_kvp.Key; if (ms.getPowerPriority() == 2) { double power = power_kvp.Value; current_resource_demand += power; if (flow_type == FNRESOURCE_FLOWTYPE_EVEN) { power = power * demand_supply_ratio; } double power_supplied = Math.Max(Math.Min(powersupply, power), 0.0); powersupply -= power_supplied; //notify of supply ms.receiveFNResource(power_supplied, this.resource_name); } } // check radiators foreach (KeyValuePair <ORSResourceSuppliable, double> power_kvp in power_draw_items) { ORSResourceSuppliable ms = power_kvp.Key; if (ms.getPowerPriority() == 3) { double power = power_kvp.Value; current_resource_demand += power; if (flow_type == FNRESOURCE_FLOWTYPE_EVEN) { power = power * demand_supply_ratio; } double power_supplied = Math.Max(Math.Min(powersupply, power), 0.0); powersupply -= power_supplied; //notify of supply ms.receiveFNResource(power_supplied, this.resource_name); } } powersupply -= Math.Max(currentmegajoules, 0.0); internl_power_extract = -powersupply * TimeWarp.fixedDeltaTime; pluginSpecificImpl(); if (internl_power_extract > 0) { internl_power_extract = Math.Min(internl_power_extract, currentmegajoules); } else if (internl_power_extract < 0) { internl_power_extract = Math.Max(internl_power_extract, -missingmegajoules); } //my_part.RequestResource(this.resource_name, internl_power_extract); ORSHelper.fixedRequestResource(my_part, this.resource_name, internl_power_extract); powersupply = 0; stable_supply = 0; power_supplies.Clear(); power_draws.Clear(); }
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_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 = availableResourceAmount / maxResouceAmount; else resource_bar_ratio = 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; //Prioritise supplying stock ElectricCharge resource 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(ORSResourceManager.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<ORSResourceSuppliable, PowerConsumption>> 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 1 parts like reactors foreach (KeyValuePair<ORSResourceSuppliable, PowerConsumption> power_kvp in power_draw_items) { ORSResourceSuppliable 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 like reactors foreach (KeyValuePair<ORSResourceSuppliable, PowerConsumption> power_kvp in power_draw_items) { ORSResourceSuppliable 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<ORSResourceSuppliable, PowerConsumption> power_kvp in power_draw_items) { ORSResourceSuppliable 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<ORSResourceSuppliable, PowerConsumption> power_kvp in power_draw_items) { ORSResourceSuppliable 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<ORSResourceSuppliable, PowerConsumption> power_kvp in power_draw_items) { ORSResourceSuppliable 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; pluginSpecificImpl(); 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(this.resource_name, internl_power_extract_fixed); //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(ORSResourceManager.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(); }