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);
        }
Ejemplo n.º 2
0
        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;
            }
        }
Ejemplo n.º 3
0
        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);
        }
Ejemplo n.º 4
0
        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);
        }
Ejemplo n.º 5
0
        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;
        }
Ejemplo n.º 6
0
        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));
        }
Ejemplo n.º 7
0
        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);
        }
Ejemplo n.º 8
0
        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);
        }
Ejemplo n.º 9
0
        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);
        }
Ejemplo n.º 10
0
        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);
        }
Ejemplo n.º 11
0
        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();
        }
Ejemplo n.º 12
0
        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);
        }
Ejemplo n.º 13
0
        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);
        }
Ejemplo n.º 14
0
        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;
                }
            }
        }
Ejemplo n.º 16
0
        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);
        }
Ejemplo n.º 17
0
        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);
        }
Ejemplo n.º 18
0
        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);
        }
Ejemplo n.º 19
0
        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);
            }
        }
Ejemplo n.º 20
0
        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));
            }
        }
Ejemplo n.º 21
0
        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;
     }
 }
Ejemplo n.º 23
0
        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));
        }
Ejemplo n.º 24
0
        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);
 }
Ejemplo n.º 26
0
 public ResourceConsumer(int id, double rate, ResourceFlowMode flowMode)
 {
     ID       = id;
     Rate     = rate;
     FlowMode = flowMode;
 }
Ejemplo n.º 27
0
        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));
                }
            }
        }
Ejemplo n.º 28
0
 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();
 }
Ejemplo n.º 29
0
        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));
                }
            }
        }
Ejemplo n.º 30
0
 public extern void GetConnectedResources(int resourceID, ResourceFlowMode flowMode, List <PartResource> Resources, out double amount, out double maxAmount);
Ejemplo n.º 31
0
        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);
            }
        }
Ejemplo n.º 32
0
 public extern virtual double RequestResource(int resourceID, double demand, ResourceFlowMode flowMode);
Ejemplo n.º 33
0
 public extern virtual double RequestResource(string resourceName, double demand, ResourceFlowMode flowMode);
Ejemplo n.º 34
0
 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);
 }
Ejemplo n.º 35
0
        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)));
                }
            }
        }