protected double getAmount(string resourceName, ResourceFlowMode flowMode) { double amount = 0; int count; if (flowMode != ResourceFlowMode.NO_FLOW) { if (!protoResources.ContainsKey(resourceName)) { return(0f); } List <ProtoPartResourceSnapshot> resourceShapshots = protoResources[resourceName]; count = resourceShapshots.Count; for (int index = 0; index < count; index++) { if (resourceShapshots[index].flowState) { amount += resourceShapshots[index].amount; } } } else //Check the part { count = protoPart.resources.Count; for (int index = 0; index < count; index++) { if (protoPart.resources[index].resourceName == resourceName && protoPart.resources[index].flowState) { return(protoPart.resources[index].amount); } } } return(amount); }
public void Sample(string resourceName, double demand, ResourceFlowMode FlowMode, double accepted) { if (demand == 0) { return; } if (demand > 0) { if (!sumConsumption.ContainsKey(resourceName)) { sumConsumption.Add(resourceName, demand); return; } sumConsumption[resourceName] += demand; } else { if (!sumGeneration.ContainsKey(resourceName)) { sumGeneration.Add(resourceName, demand); return; } sumGeneration[resourceName] += demand; } }
protected double requestAmount(string resourceName, double demand, ResourceFlowMode flowMode) { double supply = 0; int count; //Check vessel if (flowMode != ResourceFlowMode.NO_FLOW) { if (!protoResources.ContainsKey(resourceName)) { return(0f); } List <ProtoPartResourceSnapshot> resourceShapshots = protoResources[resourceName]; count = resourceShapshots.Count; double currentDemand = demand; for (int index = 0; index < count; index++) { if (resourceShapshots[index].amount > currentDemand) { resourceShapshots[index].amount -= currentDemand; supply += currentDemand; currentDemand = 0; } else //Current demand > what the part has. { supply += resourceShapshots[index].amount; currentDemand -= resourceShapshots[index].amount; resourceShapshots[index].amount = 0; } } } else //Check the part { count = protoPart.resources.Count; for (int index = 0; index < count; index++) { if (protoPart.resources[index].resourceName == resourceName) { supply = protoPart.resources[index].amount; if (supply >= demand) { protoPart.resources[index].amount = supply - demand; return(demand); } else { //Supply < demand protoPart.resources[index].amount = 0; return(supply); } } } } return(supply); }
public double ConsumeHeat(double amt, ResourceFlowMode mode) { double actual = part.RequestResource(Utils.HeatResourceName, amt * 0.2d, mode); actual += part.RequestResource(Utils.HeatResourceName, amt * 0.2d, mode); actual += part.RequestResource(Utils.HeatResourceName, amt * 0.2d, mode); actual += part.RequestResource(Utils.HeatResourceName, amt * 0.2d, mode); actual += part.RequestResource(Utils.HeatResourceName, amt * 0.2d, mode); return(actual); }
public static double fixedRequestResource(Part part, string resourcename, double resource_amount, ResourceFlowMode flow) { if (flow == ResourceFlowMode.NULL) flow = PartResourceLibrary.Instance.GetDefinition(resourcename).resourceFlowMode; if (flow != ResourceFlowMode.ALL_VESSEL) return part.RequestResource(resourcename, resource_amount); var partsWithResource = part.vessel.parts.Where(p => p.Resources.Contains(resourcename)); Dictionary<Part, ORSPropellantControl> partLookup; if (orsPropellantDictionary.ContainsKey(part.vessel)) partLookup = orsPropellantDictionary[part.vessel]; else { partLookup = part.vessel.FindPartModulesImplementing<ORSPropellantControl>().ToDictionary(p => p.part); orsPropellantDictionary.Add(part.vessel, partLookup); } var partResources = partsWithResource.Where(p => !partLookup.ContainsKey(p) || partLookup[p].isPropellant).Select(p => p.Resources[resourcename]); IList<PartResource> relevant_part_resources = new List<PartResource> ( resource_amount > 0 ? partResources.Where(p => p.flowState && p.amount > 0) : partResources.Where(p => p.flowState && p.maxAmount > p.amount) ); if (!relevant_part_resources.Any()) return 0; double total_resource_change = 0; double res_ratio = resource_amount > 0 ? Math.Min(resource_amount/relevant_part_resources.Sum(p => p.amount), 1) : Math.Min(-resource_amount/relevant_part_resources.Sum(p => p.maxAmount - p.amount), 1); if (res_ratio == 0 || double.IsNaN(res_ratio) || double.IsInfinity(res_ratio)) return 0; foreach (PartResource local_part_resource in relevant_part_resources) { if (resource_amount > 0) { var part_resource_change = local_part_resource.amount*res_ratio; local_part_resource.amount -= part_resource_change; total_resource_change += part_resource_change; } else { var part_resource_change = (local_part_resource.maxAmount - local_part_resource.amount)*res_ratio; local_part_resource.amount += part_resource_change; total_resource_change -= part_resource_change; } } return total_resource_change; }
public static double fixedRequestResource(Part part, string resourcename, double resource_amount) { if (resource_amount == 0) { return(0); } ResourceFlowMode flow = PartResourceLibrary.Instance.GetDefinition(resourcename).resourceFlowMode; return(fixedRequestResource(part, resourcename, resource_amount, flow)); }
public static double GetResourceAvailable(this Part part, ResourceFlowMode flowmode, PartResourceDefinition definition) { if (definition == null) { Debug.LogError("[KSPI]: PartResourceDefinition definition is NULL"); return(0); } part.GetConnectedResourceTotals(definition.id, flowmode, out var currentAmount, out _); return(currentAmount); }
public override double RequestResource(string resourceName, double demand, ResourceFlowMode flowMode) { // Pass transaction data to designated handler class double accepted = this.OnResourceRequested.Invoke(resourceName, demand, flowMode); // Send results of transaction to any classes that have asked to be told about it this.OnRequestResource.Invoke(resourceName, demand, flowMode, accepted); // Complete transaction by returning the amount of resource that was actually consumed return(accepted); }
public static double GetResourceAvailable(this Part part, string name, ResourceFlowMode flowMode) { var definition = PartResourceLibrary.Instance.GetDefinition(name); if (definition == null) { Debug.LogError("[KSPI]: PartResourceDefinition definition is NULL"); return(0); } part.GetConnectedResourceTotals(definition.id, flowMode, out var currentAmount, out _); return(currentAmount); }
public static List <PartResource> FindResources(Part part, Propellant p) { List <PartResource> list = new List <PartResource>(); ResourceFlowMode flow = p.GetFlowMode(); if (flow == ResourceFlowMode.STACK_PRIORITY_SEARCH || flow == ResourceFlowMode.STAGE_PRIORITY_FLOW_BALANCE || flow == ResourceFlowMode.STAGE_STACK_FLOW || flow == ResourceFlowMode.STAGE_STACK_FLOW_BALANCE) { HashSet <Part> visited = new HashSet <Part>(); CrossfeedRecurseParts(visited, part, null); foreach (Part n in visited) { n.Resources.GetAll(list, p.id); } } else { List <Part> parts; if (flow != ResourceFlowMode.NO_FLOW) { if (part.vessel != null) { parts = part.vessel.parts; } else if (EditorLogic.fetch != null && EditorLogic.fetch.ship != null) { parts = EditorLogic.fetch.ship.parts; } else { parts = new List <Part>(); parts.Add(part); } } else { parts = new List <Part>(); parts.Add(part); } for (int i = parts.Count - 1; i >= 0; --i) { Part foundPart = parts[i]; List <PartResource> resources = foundPart.Resources.GetAll(p.id); for (int j = resources.Count - 1; j >= 0; --j) { list.Add(resources[j]); } } } return(list); }
void AssignFuelDrainRateStackPriority(int type, ResourceFlowMode flowMode, float amount) { Disposable <HashSet <FuelNode> > sources = FindFuelSourcesStackPriority(type, flowMode != ResourceFlowMode.STACK_PRIORITY_SEARCH || PhysicsGlobals.Stack_PriUsesSurf); float amountPerSource = amount / sources.value.Count(); foreach (FuelNode source in sources.value) { if (!freeResources[type]) { source.resourceDrains[type] += amountPerSource; } } sources.Dispose(); }
public ConfigNode getPropellantNode(ResourceFlowMode flowMode) { ConfigNode node = new ConfigNode(); int len = resourceRatios.Length; for (int i = 0; i < len; i++) { ConfigNode propNode = new ConfigNode("PROPELLANT"); propNode.AddValue("name", resourceRatios[i].resourceName); propNode.AddValue("ratio", resourceRatios[i].resourceRatio); propNode.AddValue("resourceFlowMode", flowMode.ToString()); node.AddNode(propNode); } return(node); }
private static double fetchPartResource(Part part, int Id, ResourceFlowMode flowMode) { List <PartResource> Resources = new List <PartResource>(); part.GetConnectedResourceTotals(Id, out double amount, out double MaxAmount); if (Resources.Count <= 0) { return(amount); } foreach (PartResource Res in Resources) { amount += Res.amount; } return(amount); }
public static List <PartResource> FindResources(Part part, Propellant p) { List <PartResource> list = new List <PartResource>(); ResourceFlowMode flow = p.GetFlowMode(); if (flow == ResourceFlowMode.STACK_PRIORITY_SEARCH) { HashSet <Part> visited = new HashSet <Part>(); FindResources_StackPri(part, visited, list, p.id); } else { List <Part> parts; if (flow != ResourceFlowMode.NO_FLOW) { if (part.vessel != null) { parts = part.vessel.parts; } else if (EditorLogic.fetch != null && EditorLogic.fetch.ship != null) { parts = EditorLogic.fetch.ship.parts; } else { parts = new List <Part>(); parts.Add(part); } } else { parts = new List <Part>(); parts.Add(part); } for (int i = parts.Count - 1; i >= 0; --i) { Part foundPart = parts[i]; List <PartResource> resources = foundPart.Resources.GetAll(p.id); for (int j = resources.Count - 1; j >= 0; --j) { list.Add(resources[j]); } } } return(list); }
protected void supplyAmount(string resourceName, double supply, ResourceFlowMode flowMode, bool dumpExcess) { int count; double currentSupply = supply; if (flowMode != ResourceFlowMode.NO_FLOW) { if (!protoResources.ContainsKey(resourceName)) { return; } List <ProtoPartResourceSnapshot> resourceShapshots = protoResources[resourceName]; count = resourceShapshots.Count; //Distribute the resource throughout the resource snapshots. //TODO: find a way to evenly distribute the resource. for (int index = 0; index < count; index++) { //If the current part resource snapshot has enough room, then we can store all of the currentSupply and be done. if (resourceShapshots[index].amount + currentSupply < resourceShapshots[index].maxAmount) { resourceShapshots[index].amount += currentSupply; return; } //The current snapshot can't hold all of the currentSupply, but we can whittle down what we currently have. else { currentSupply -= resourceShapshots[index].maxAmount - resourceShapshots[index].amount; resourceShapshots[index].amount = resourceShapshots[index].maxAmount; } } //If we have any resource left over, then it means that our containers are full. //If we can't dump the excess, then we're done. if (currentSupply > 0.0001f && !dumpExcess) { isContainerFull = true; //Email player emailPlayer(resourceName, WBIBackroundEmailTypes.containerFull); //Done return; } } }
private double FetchResource(string resourceName, double demand, ResourceFlowMode flowMode) { double todo = demand; double done = 0; while (Math.Abs(todo) > 0) { done = part.RequestResource(resourceName, todo, flowMode); if (done == 0) { break; } todo = todo - done; } return(demand - todo); }
private double fetchPartResource(Part part, int Id, ResourceFlowMode flowMode) { double amount = 0; double MaxAmount = 0; List <PartResource> Resources = new List <PartResource>(); part.GetConnectedResourceTotals(Id, out amount, out MaxAmount); if (Resources.Count > 0) { foreach (PartResource Res in Resources) { amount += Res.amount; } } return(amount); }
public static List <PartResource> FindResources(Part part, Propellant p) { List <PartResource> list = new List <PartResource>(); ResourceFlowMode flow = p.GetFlowMode(); if (flow == ResourceFlowMode.STACK_PRIORITY_SEARCH || flow == ResourceFlowMode.STAGE_PRIORITY_FLOW_BALANCE || flow == ResourceFlowMode.STAGE_STACK_FLOW || flow == ResourceFlowMode.STAGE_STACK_FLOW_BALANCE) { foreach (Part n in part.crossfeedPartSet.GetParts()) { n.Resources.GetAll(list, p.id); } } else { List <Part> parts = null; if (flow != ResourceFlowMode.NO_FLOW) { if (part.vessel != null) { parts = part.vessel.parts; } else if (EditorLogic.fetch != null && EditorLogic.fetch.ship != null) { parts = EditorLogic.fetch.ship.parts; } } if (parts == null) { part.Resources.GetAll(list, p.id); } else { for (int i = parts.Count - 1; i >= 0; --i) { Part foundPart = parts[i]; foundPart.Resources.GetAll(list, p.id); } } } return(list); }
public double GenerateHeat(double amt, ResourceFlowMode mode) { //Utils.Log("Trying to add " + amt.ToString()); // returns actual amount generated double actual = part.RequestResource(Utils.HeatResourceName, -amt * 0.2d, mode); actual += part.RequestResource(Utils.HeatResourceName, -amt * 0.2d, mode); actual += part.RequestResource(Utils.HeatResourceName, -amt * 0.2d, mode); actual += part.RequestResource(Utils.HeatResourceName, -amt * 0.2d, mode); actual += part.RequestResource(Utils.HeatResourceName, -amt * 0.2d, mode); if (VesselHeatStored >= VesselMaxHeatStored) { return(amt - actual); } else { return(0d); } }
public static Services.ResourceFlowMode ToResourceFlowMode(this ResourceFlowMode mode) { switch (mode) { case ResourceFlowMode.ALL_VESSEL: return(Services.ResourceFlowMode.Vessel); case ResourceFlowMode.STAGE_PRIORITY_FLOW: return(Services.ResourceFlowMode.Stage); case ResourceFlowMode.STACK_PRIORITY_SEARCH: return(Services.ResourceFlowMode.Adjacent); case ResourceFlowMode.NO_FLOW: return(Services.ResourceFlowMode.None); default: throw new ArgumentOutOfRangeException(nameof(mode)); } }
public override void OnLoad(ConfigNode node) { base.OnLoad(node); if (node.HasNode("DRAINED_RESOURCE")) { ConfigNode[] nodes = node.GetNodes("DRAINED_RESOURCE"); double ratio = 0; bool dumpExcess = true; ResourceFlowMode flowMode = ResourceFlowMode.ALL_VESSEL; for (int index = 0; index < nodes.Length; index++) { ConfigNode configNode = nodes[index]; if (!configNode.HasValue("ResourceName") && !configNode.HasValue("Ratio")) { continue; } ratio = 0; dumpExcess = true; double.TryParse(configNode.GetValue("Ratio"), out ratio); bool.TryParse(configNode.GetValue("DumpExcess"), out dumpExcess); ResourceRatio resource = new ResourceRatio(node.GetValue("ResourceName"), ratio, dumpExcess); flowMode = ResourceFlowMode.ALL_VESSEL; if (configNode.HasValue("FlowMode")) { flowMode = (ResourceFlowMode)Enum.Parse(typeof(ResourceFlowMode), configNode.GetValue("FlowMode")); resource.FlowMode = flowMode; } else { resource.FlowMode = ResourceFlowMode.ALL_VESSEL; } drainedResources.Add(resource); } } }
public void Sample(string resourceName, double demand, ResourceFlowMode FlowMode, double accepted) { if (demand == 0) { return; } if (demand > 0) { if (!sumConsumption.ContainsKey (resourceName)) { sumConsumption.Add(resourceName, demand); return; } sumConsumption [resourceName] += demand; } else { if (!sumGeneration.ContainsKey (resourceName)) { sumGeneration.Add(resourceName, demand); return; } sumConsumption [resourceName] += demand; } }
private double CollectFuel(double demandMass, ResourceFlowMode fuelMode = ResourceFlowMode.STACK_PRIORITY_SEARCH) { fuelRequestAmount1 = 0; fuelRequestAmount2 = 0; fuelRequestAmount3 = 0; fuelRequestAmount4 = 0; if (CheatOptions.InfinitePropellant) { return(1); } if (demandMass == 0 || double.IsNaN(demandMass) || double.IsInfinity(demandMass)) { return(0); } var propellantWithMassNeededInLiter = demandMass / averageDensityInTonPerLiter; var overalAmountNeeded = propellantWithMassNeededInLiter / massPropellantRatio; var masslessResourceNeeded = overalAmountNeeded - propellantWithMassNeededInLiter; // first determine lowest availalable resource ratio double availableRatio = 1; if (propellantResourceDefinition1 != null && ratio1 > 0) { fuelRequestAmount1 = fuelWithMassPercentage1 > 0 ? fuelWithMassPercentage1 * propellantWithMassNeededInLiter : masslessFuelPercentage1 * masslessResourceNeeded; availableRatio = Math.Min(availableRatio, part.GetResourceAvailable(propellantResourceDefinition1, fuelMode) / fuelRequestAmount1); } if (propellantResourceDefinition2 != null && ratio2 > 0) { fuelRequestAmount2 = fuelWithMassPercentage2 > 0 ? fuelWithMassPercentage2 * propellantWithMassNeededInLiter : masslessFuelPercentage2 * masslessResourceNeeded; availableRatio = Math.Min(availableRatio, part.GetResourceAvailable(propellantResourceDefinition2, fuelMode) / fuelRequestAmount2); } if (propellantResourceDefinition3 != null && ratio3 > 0) { fuelRequestAmount3 = fuelWithMassPercentage3 > 0 ? fuelWithMassPercentage3 * propellantWithMassNeededInLiter : masslessFuelPercentage3 * masslessResourceNeeded; availableRatio = Math.Min(availableRatio, part.GetResourceAvailable(propellantResourceDefinition3, fuelMode) / fuelRequestAmount3); } if (propellantResourceDefinition4 != null && ratio4 > 0) { fuelRequestAmount4 = fuelWithMassPercentage4 > 0 ? fuelWithMassPercentage4 * propellantWithMassNeededInLiter : masslessFuelPercentage4 * masslessResourceNeeded; availableRatio = Math.Min(availableRatio, part.GetResourceAvailable(propellantResourceDefinition4, fuelMode) / fuelRequestAmount4); } // ignore insignificant amount if (availableRatio < 1e-6) { return(0); } consumedPropellant1 = 0; consumedPropellant2 = 0; consumedPropellant3 = 0; consumedPropellant4 = 0; double recievedRatio = 1; if (fuelRequestAmount1 > 0 && !double.IsNaN(fuelRequestAmount1) && !double.IsInfinity(fuelRequestAmount1)) { consumedPropellant1 = part.RequestResource(propellantResourceDefinition1.id, fuelRequestAmount1 * availableRatio, fuelMode); recievedRatio = Math.Min(recievedRatio, fuelRequestAmount1 > 0 ? consumedPropellant1 / fuelRequestAmount1 : 0); } if (fuelRequestAmount2 > 0 && !double.IsNaN(fuelRequestAmount2) && !double.IsInfinity(fuelRequestAmount2)) { consumedPropellant2 = part.RequestResource(propellantResourceDefinition2.id, fuelRequestAmount2 * availableRatio, fuelMode); recievedRatio = Math.Min(recievedRatio, fuelRequestAmount2 > 0 ? consumedPropellant2 / fuelRequestAmount2 : 0); } if (fuelRequestAmount3 > 0 && !double.IsNaN(fuelRequestAmount3) && !double.IsInfinity(fuelRequestAmount3)) { consumedPropellant3 = part.RequestResource(propellantResourceDefinition3.id, fuelRequestAmount3 * availableRatio, fuelMode); recievedRatio = Math.Min(recievedRatio, fuelRequestAmount3 > 0 ? consumedPropellant3 / fuelRequestAmount3 : 0); } if (fuelRequestAmount4 > 0 && !double.IsNaN(fuelRequestAmount4) && !double.IsInfinity(fuelRequestAmount4)) { consumedPropellant4 = part.RequestResource(propellantResourceDefinition4.id, fuelRequestAmount4 * availableRatio, fuelMode); recievedRatio = Math.Min(recievedRatio, fuelRequestAmount4 > 0 ? consumedPropellant4 / fuelRequestAmount4 : 0); } return(Math.Min(recievedRatio, 1)); }
public bool SetResourceDrains(LogMsg log, List <PartSim> allParts, List <PartSim> allFuelLines, HashSet <PartSim> drainingParts) { //DumpSourcePartSets(log, "before clear"); foreach (HashSet <PartSim> sourcePartSet in sourcePartSets.Values) { sourcePartSet.Clear(); } //DumpSourcePartSets(log, "after clear"); for (int index = 0; index < this.resourceConsumptions.Types.Count; index++) { int type = this.resourceConsumptions.Types[index]; HashSet <PartSim> sourcePartSet; if (!sourcePartSets.TryGetValue(type, out sourcePartSet)) { sourcePartSet = new HashSet <PartSim>(); sourcePartSets.Add(type, sourcePartSet); } switch ((ResourceFlowMode)this.resourceFlowModes[type]) { case ResourceFlowMode.NO_FLOW: if (partSim.resources[type] > SimManager.RESOURCE_MIN && partSim.resourceFlowStates[type] != 0) { sourcePartSet.Add(partSim); } break; case ResourceFlowMode.ALL_VESSEL: case ResourceFlowMode.ALL_VESSEL_BALANCE: for (int i = 0; i < allParts.Count; i++) { PartSim aPartSim = allParts[i]; if (aPartSim.resources[type] > SimManager.RESOURCE_MIN && aPartSim.resourceFlowStates[type] != 0) { sourcePartSet.Add(aPartSim); } } break; case ResourceFlowMode.STAGE_PRIORITY_FLOW: case ResourceFlowMode.STAGE_PRIORITY_FLOW_BALANCE: //All vessel ordered by stage if (log != null) { log.Append("Find ", ResourceContainer.GetResourceName(type), " sources for ", partSim.name) .AppendLine(":", partSim.partId); } foreach (HashSet <PartSim> stagePartSet in stagePartSets.Values) { stagePartSet.Clear(); } var maxStage = -1; for (int i = 0; i < allParts.Count; i++) { var aPartSim = allParts[i]; //if (log != null) log.Append(aPartSim.name, ":" + aPartSim.partId, " contains ", aPartSim.resources[type]) // .AppendLine((aPartSim.resourceFlowStates[type] == 0) ? " (disabled)" : ""); if (aPartSim.resources[type] > SimManager.RESOURCE_MIN && aPartSim.resourceFlowStates[type] != 0) { int stage = aPartSim.inverseStage; if (stage > maxStage) { maxStage = stage; } HashSet <PartSim> tempPartSet; if (!stagePartSets.TryGetValue(stage, out tempPartSet)) { tempPartSet = new HashSet <PartSim>(); stagePartSets.Add(stage, tempPartSet); } tempPartSet.Add(aPartSim); } } //Add resource containers in order by stage for (int j = maxStage; j >= -1; j--) { //if (log != null) log.AppendLine("Testing stage ", j); HashSet <PartSim> stagePartSet; if (stagePartSets.TryGetValue(j, out stagePartSet) && stagePartSet.Count > 0) { //if (log != null) log.AppendLine("Not empty"); // We have to copy the contents of the set here rather than copying the set reference or // bad things (tm) happen foreach (PartSim aPartSim in stagePartSet) { sourcePartSet.Add(aPartSim); } break; } } break; case ResourceFlowMode.STACK_PRIORITY_SEARCH: case ResourceFlowMode.STAGE_STACK_FLOW: case ResourceFlowMode.STAGE_STACK_FLOW_BALANCE: visited.Clear(); //Resource containers limited to current stage if (log != null) { log.Append("Find ", ResourceContainer.GetResourceName(type), " sources for ", partSim.name) .AppendLine(":", partSim.partId); } partSim.GetSourceSet(type, true, allParts, visited, sourcePartSet, false, log, ""); break; default: if (log != null) { log.Append("SetResourceDrains(", partSim.name, ":", partSim.partId) .AppendLine(") Unexpected flow type for ", ResourceContainer.GetResourceName(type), ")"); } break; } if (log != null && sourcePartSet.Count > 0) { log.AppendLine("Source parts for ", ResourceContainer.GetResourceName(type), ":"); foreach (PartSim partSim in sourcePartSet) { log.AppendLine(partSim.name, ":", partSim.partId); } } //DumpSourcePartSets(log, "after " + ResourceContainer.GetResourceName(type)); } // If we don't have sources for all the needed resources then return false without setting up any drains for (int i = 0; i < this.resourceConsumptions.Types.Count; i++) { int type = this.resourceConsumptions.Types[i]; HashSet <PartSim> sourcePartSet; if (!sourcePartSets.TryGetValue(type, out sourcePartSet) || sourcePartSet.Count == 0) { if (log != null) { log.AppendLine("No source of ", ResourceContainer.GetResourceName(type)); } isActive = false; return(false); } } // Now we set the drains on the members of the sets and update the draining parts set for (int i = 0; i < this.resourceConsumptions.Types.Count; i++) { int type = this.resourceConsumptions.Types[i]; HashSet <PartSim> sourcePartSet = sourcePartSets[type]; ResourceFlowMode mode = (ResourceFlowMode)resourceFlowModes[type]; double consumption = resourceConsumptions[type]; double amount = 0d; double total = 0d; if (mode == ResourceFlowMode.ALL_VESSEL_BALANCE || mode == ResourceFlowMode.STAGE_PRIORITY_FLOW_BALANCE || mode == ResourceFlowMode.STAGE_STACK_FLOW_BALANCE || mode == ResourceFlowMode.STACK_PRIORITY_SEARCH) { foreach (PartSim partSim in sourcePartSet) { total += partSim.resources[type]; } } else { amount = consumption / sourcePartSet.Count; } // Loop through the members of the set foreach (PartSim partSim in sourcePartSet) { if (total != 0d) { amount = consumption * partSim.resources[type] / total; } if (log != null) { log.Append("Adding drain of ", amount, " ", ResourceContainer.GetResourceName(type)) .AppendLine(" to ", partSim.name, ":", partSim.partId); } partSim.resourceDrains.Add(type, amount); drainingParts.Add(partSim); } } return(true); }
/// <summary> /// Is this flow mode one that can move between stages? /// </summary> /// <param name="flowMode"></param> /// <returns></returns> private static bool IsFreeFlow(ResourceFlowMode flowMode) { return(flowMode == ResourceFlowMode.ALL_VESSEL || flowMode == ResourceFlowMode.STAGE_PRIORITY_FLOW); }
public ResourceConsumer(int id, double rate, ResourceFlowMode flowMode) { ID = id; Rate = rate; FlowMode = flowMode; }
public static double fixedRequestResource(Part part, string resourcename, double resource_amount, ResourceFlowMode flow) { if (flow == ResourceFlowMode.NULL) { flow = PartResourceLibrary.Instance.GetDefinition(resourcename).resourceFlowMode; } if (flow == ResourceFlowMode.ALL_VESSEL) { // use our code var partsWithResource = part.vessel.parts.Where(p => p.Resources.Contains(resourcename)); Dictionary <Part, ORSPropellantControl> partLookup; if (orsPropellantDictionary.ContainsKey(part.vessel)) { partLookup = orsPropellantDictionary[part.vessel]; } else { partLookup = part.vessel.FindPartModulesImplementing <ORSPropellantControl>().ToDictionary(p => p.part); orsPropellantDictionary.Add(part.vessel, partLookup); } var partResources = partsWithResource.Where(p => !partLookup.ContainsKey(p) || ((ORSPropellantControl)partLookup[p]).isPropellant).Select(p => p.Resources[resourcename]); var prl = partResources.Where(p => p.flowState == true).ToList(); double max_available = 0; double spare_capacity = 0; foreach (PartResource partresource in prl) { max_available += partresource.amount; spare_capacity += partresource.maxAmount - partresource.amount; } double resource_left_to_draw = 0; double total_resource_change = 0; double res_ratio = 0; if (resource_amount > 0) { resource_left_to_draw = Math.Min(resource_amount, max_available); res_ratio = Math.Min(resource_amount / max_available, 1); } else { resource_left_to_draw = Math.Max(-spare_capacity, resource_amount); res_ratio = Math.Min(-resource_amount / spare_capacity, 1); } if (double.IsNaN(res_ratio) || double.IsInfinity(res_ratio) || res_ratio == 0) { return(0); } else { foreach (PartResource local_part_resource in prl) { if (resource_amount > 0) { local_part_resource.amount = local_part_resource.amount - local_part_resource.amount * res_ratio; total_resource_change += local_part_resource.amount * res_ratio; } else { local_part_resource.amount = local_part_resource.amount + (local_part_resource.maxAmount - local_part_resource.amount) * res_ratio; total_resource_change -= (local_part_resource.maxAmount - local_part_resource.amount) * res_ratio; } } } return(total_resource_change); } else { if (resource_amount > 0) { //return part.RequestResource(resourcename, Math.Min(resource_amount, max_available)); return(part.RequestResource(resourcename, resource_amount)); } else { //return part.RequestResource(resourcename, Math.Max(-spare_capacity, resource_amount)); return(part.RequestResource(resourcename, resource_amount)); } } }
void AssignFuelDrainRateStackPriority(int type, ResourceFlowMode flowMode, float amount) { Disposable<HashSet<FuelNode>> sources = FindFuelSourcesStackPriority(type, flowMode != ResourceFlowMode.STACK_PRIORITY_SEARCH || PhysicsGlobals.Stack_PriUsesSurf); float amountPerSource = amount / sources.value.Count(); foreach (FuelNode source in sources.value) if (!freeResources[type]) source.resourceDrains[type] += amountPerSource; sources.Dispose(); }
public static double fixedRequestResource(Part part, string resourcename, ResourceFlowMode resource_flow, double resource_amount) { List<PartResource> prl = new List<PartResource>(); List<Part> parts = new List<Part>(); part.GetConnectedResources(PartResourceLibrary.Instance.GetDefinition(resourcename).id, resource_flow, prl); ResourceFlowMode flow = resource_flow; prl = prl.Where(p => p.flowState == true).ToList(); double max_available = 0; double spare_capacity = 0; foreach (PartResource partresource in prl) { parts.Add(partresource.part); max_available += partresource.amount; spare_capacity += partresource.maxAmount - partresource.amount; } if (flow == ResourceFlowMode.ALL_VESSEL) { // use our code double resource_left_to_draw = 0; double total_resource_change = 0; double res_ratio = 0; if (resource_amount > 0) { resource_left_to_draw = Math.Min(resource_amount, max_available); res_ratio = Math.Min(resource_amount / max_available, 1); } else { resource_left_to_draw = Math.Max(-spare_capacity, resource_amount); res_ratio = Math.Min(-resource_amount / spare_capacity, 1); } if (double.IsNaN(res_ratio) || double.IsInfinity(res_ratio) || res_ratio == 0) { return 0; } else { foreach (PartResource local_part_resource in prl) { if (resource_amount > 0) { local_part_resource.amount = local_part_resource.amount - local_part_resource.amount * res_ratio; total_resource_change += local_part_resource.amount * res_ratio; } else { local_part_resource.amount = local_part_resource.amount + (local_part_resource.maxAmount - local_part_resource.amount) * res_ratio; total_resource_change -= (local_part_resource.maxAmount - local_part_resource.amount) * res_ratio; } } } return total_resource_change; } else { if (resource_amount > 0) { return part.RequestResource(resourcename, Math.Min(resource_amount, max_available)); } else { return part.RequestResource(resourcename, Math.Max(-spare_capacity, resource_amount)); } } }
public extern void GetConnectedResources(int resourceID, ResourceFlowMode flowMode, List <PartResource> Resources, out double amount, out double maxAmount);
public static double fixedRequestResource(Part part, string resourcename, double resource_amount, ResourceFlowMode flow) { if (flow == ResourceFlowMode.NULL) flow = PartResourceLibrary.Instance.GetDefinition(resourcename).resourceFlowMode; if (flow == ResourceFlowMode.ALL_VESSEL) { // use our code var partsWithResource = part.vessel.parts.Where(p => p.Resources.Contains(resourcename)); Dictionary<Part, ORSPropellantControl> partLookup; if (orsPropellantDictionary.ContainsKey(part.vessel)) partLookup = orsPropellantDictionary[part.vessel]; else { partLookup = part.vessel.FindPartModulesImplementing<ORSPropellantControl>().ToDictionary(p => p.part); orsPropellantDictionary.Add(part.vessel, partLookup); } var partResources = partsWithResource.Where(p => !partLookup.ContainsKey(p) || ((ORSPropellantControl)partLookup[p]).isPropellant).Select(p => p.Resources[resourcename]); var prl = partResources.Where(p => p.flowState == true).ToList(); double max_available = 0; double spare_capacity = 0; foreach (PartResource partresource in prl) { max_available += partresource.amount; spare_capacity += partresource.maxAmount - partresource.amount; } double resource_left_to_draw = 0; double total_resource_change = 0; double res_ratio = 0; if (resource_amount > 0) { resource_left_to_draw = Math.Min(resource_amount, max_available); res_ratio = Math.Min(resource_amount / max_available,1); } else { resource_left_to_draw = Math.Max(-spare_capacity, resource_amount); res_ratio = Math.Min(-resource_amount / spare_capacity,1); } if (double.IsNaN(res_ratio) || double.IsInfinity(res_ratio) || res_ratio == 0) { return 0; } else { foreach (PartResource local_part_resource in prl) { if (resource_amount > 0) { local_part_resource.amount = local_part_resource.amount - local_part_resource.amount * res_ratio; total_resource_change += local_part_resource.amount * res_ratio; } else { local_part_resource.amount = local_part_resource.amount + (local_part_resource.maxAmount - local_part_resource.amount) * res_ratio; total_resource_change -= (local_part_resource.maxAmount - local_part_resource.amount) * res_ratio; } } } return total_resource_change; } else { if (resource_amount > 0) //return part.RequestResource(resourcename, Math.Min(resource_amount, max_available)); return part.RequestResource(resourcename, resource_amount); else //return part.RequestResource(resourcename, Math.Max(-spare_capacity, resource_amount)); return part.RequestResource(resourcename,resource_amount); } }
public extern virtual double RequestResource(int resourceID, double demand, ResourceFlowMode flowMode);
public extern virtual double RequestResource(string resourceName, double demand, ResourceFlowMode flowMode);
public static double GetResourceSpareCapacity(this Part part, PartResourceDefinition definition, ResourceFlowMode flowmode) { part.GetConnectedResourceTotals(definition.id, flowmode, out var currentAmount, out var maxAmount); return(maxAmount - currentAmount); }
public static double fixedRequestResource(Part part, string resourcename, double resource_amount) { List <PartResource> prl = part.GetConnectedResources(resourcename).ToList(); List <Part> parts = new List <Part>(); ResourceFlowMode flow = PartResourceLibrary.Instance.GetDefinition(resourcename).resourceFlowMode; prl = prl.Where(p => p.flowState == true).ToList(); double max_available = 0; double spare_capacity = 0; foreach (PartResource partresource in prl) { parts.Add(partresource.part); max_available += partresource.amount; spare_capacity += partresource.maxAmount - partresource.amount; } if (flow == ResourceFlowMode.ALL_VESSEL) // use our code { double resource_left_to_draw = 0; double total_resource_change = 0; double res_ratio = 0; if (resource_amount > 0) { resource_left_to_draw = Math.Min(resource_amount, max_available); res_ratio = Math.Min(resource_amount / max_available, 1); } else { resource_left_to_draw = Math.Max(-spare_capacity, resource_amount); res_ratio = Math.Min(-resource_amount / spare_capacity, 1); } if (double.IsNaN(res_ratio) || double.IsInfinity(res_ratio) || res_ratio == 0) { return(0); } else { foreach (PartResource local_part_resource in prl) { if (resource_amount > 0) { local_part_resource.amount = local_part_resource.amount - local_part_resource.amount * res_ratio; total_resource_change += local_part_resource.amount * res_ratio; } else { local_part_resource.amount = local_part_resource.amount + (local_part_resource.maxAmount - local_part_resource.amount) * res_ratio; total_resource_change -= (local_part_resource.maxAmount - local_part_resource.amount) * res_ratio; } } } return(total_resource_change); } else { if (resource_amount > 0) { return(part.RequestResource(resourcename, Math.Min(resource_amount, max_available))); } else { return(part.RequestResource(resourcename, Math.Max(-spare_capacity, resource_amount))); } } }