Пример #1
0
        private float GetActiveConverters()
        {
            //We don't just count converters - we count total efficiency of those
            //converters.  This way high efficiency modules get a higher weight.
            var totEff = 0f;

            //Find any vessels that have an MKS Module tied to this same eTag.
            var vList =
                LogisticsTools.GetNearbyVessels(EFF_RANGE, true, vessel, true)
                .Where(v => v.FindPartModulesImplementing <MKSModule>().Any(m => m.eTag == eTag));

            foreach (var vsl in vList)
            {
                var pList = vsl.FindPartModulesImplementing <BaseConverter>();
                foreach (var p in pList)
                {
                    var m = p.part.FindModuleImplementing <MKSModule>();
                    if (m != null && m.eTag == eTag)
                    {
                        if (p.IsActivated) // p has a GetEfficiencyMultiplier ()
                        {
                            totEff += m.eMultiplier;
                        }
                    }
                }
            }
            return(totEff);
        }
        public List <Vessel> GetResourceStockpiles()
        {
            List <Vessel> depots = LogisticsTools.GetNearbyVessels(LogisticsSetup.Instance.Config.ScavangeRange, false, vessel, true)
                                   .Where(dv => dv.FindPartModulesImplementing <USI_ModuleResourceWarehouse>().Any()).ToList();
            var nearbyVesselList = LogisticsTools.GetNearbyVessels(LogisticsTools.PHYSICS_RANGE, false, vessel, true);

            foreach (var v in nearbyVesselList)
            {
                var range = LogisticsTools.GetRange(vessel, v);
                var parts =
                    v.Parts.Where(
                        p => p.FindModuleImplementing <ModuleResourceDistributor>() != null && LogisticsTools.HasCrew(p, "Pilot"));
                foreach (var p in parts)
                {
                    var m = p.FindModuleImplementing <ModuleResourceDistributor>();
                    if (range <= m.ResourceDistributionRange)
                    {
                        //Now find ones adjacent to our depot.
                        List <Vessel> stockpiles = LogisticsTools.GetNearbyVessels(m.ResourceDistributionRange, false, vessel,
                                                                                   true).Where(sv => sv.FindPartModulesImplementing <USI_ModuleResourceWarehouse>().Any()).ToList();
                        foreach (var s in stockpiles)
                        {
                            if (!depots.Contains(s))
                            {
                                depots.Add(s);
                            }
                        }
                    }
                }
            }
            return(depots);
        }
Пример #3
0
        private float GetCurrentConsumption(string tag)
        {
            // We don't just count consumers - we count total efficiency consumption.
            // This way high efficiency modules get a higher weight.
            var totalEfficiencyConsumption = 0f;

            // Find any nearby vessels that have consumers for this efficiency bonus tag.
            var mksVessels = LogisticsTools.GetNearbyVessels(EFFICIENCY_RANGE, true, vessel, true)
                             .Where(v => v
                                    .FindConverterAddonsImplementing <USI_EfficiencyConsumerAddonForConverters>()
                                    .Any(a => a.Tag == tag));

            foreach (var mksVessel in mksVessels)
            {
                var mksModule = mksVessel.FindPartModuleImplementing <MKSModule>();
                if (mksModule == null)
                {
                    Debug.LogError(string.Format("[MKS] {0}: Part is misconfigured. Parts with an EfficiencyConsumerAddon must also have an MKSModule.", GetType().Name));
                    continue;
                }

                var consumers = mksVessel.FindConverterAddonsImplementing <USI_EfficiencyConsumerAddonForConverters>();
                foreach (var consumer in consumers)
                {
                    if (consumer.IsActive && consumer.Tag == tag)
                    {
                        totalEfficiencyConsumption += mksModule.EfficiencyMultiplier;
                    }
                }
            }

            return(totalEfficiencyConsumption);
        }
Пример #4
0
        private void PushResources(string resourceName, double amount)
        {
            var vessels = LogisticsTools.GetNearbyVessels(2000, true, vessel, false);

            foreach (var v in vessels)
            {
                //Put recycled stuff into recycleable places
                foreach (var p in v.parts.Where(vp => vp != part && vp.Modules.Contains("USI_ModuleRecycleBin")))
                {
                    if (p.Resources.Contains(resourceName))
                    {
                        var partRes  = p.Resources[resourceName];
                        var partNeed = partRes.maxAmount - partRes.amount;
                        if (partNeed > 0 && amount > 0)
                        {
                            if (partNeed > amount)
                            {
                                partNeed = amount;
                            }
                            partRes.amount += partNeed;
                            amount         -= partNeed;
                        }
                    }
                }
            }
            if (amount > 1f)
            {
                ScreenMessages.PostScreenMessage(String.Format("{0:0} units of {1} were lost due to lack of recycle space", amount, ResourceName), 5f, ScreenMessageStyle.UPPER_CENTER);
            }
        }
Пример #5
0
        private void TransferSetup()
        {
            if (!HighLogic.LoadedSceneIsFlight)
            {
                return;
            }

            activeId = FlightGlobals.ActiveVessel.id;
            var PotentialVessels = LogisticsTools.GetNearbyVessels(150, true, FlightGlobals.ActiveVessel, true);

            NearVessels = new List <Vessel>();
            foreach (var v in PotentialVessels)
            {
                if (HasResources(v))
                {
                    NearVessels.Add(v);
                }
            }

            if (NearVessels.Count == 0)
            {
                return;
            }

            _crewPresent = NearVessels.Any(v => v.GetCrewCount() > 0);
            _fromVessel  = new TransferVessel();
            _fromVessel.Setup(NearVessels[0], 0);
            var lastIdx = NearVessels.Count - 1;

            _toVessel = new TransferVessel();
            _toVessel.Setup(NearVessels[lastIdx], lastIdx);
            _resList = RebuildResourceList();
        }
Пример #6
0
        private float GetActiveConverters()
        {
            //We don't just count converters - we count total efficiency of those
            //converters.  This way high efficiency modules get a higher weight.
            var totEff = 0f;

            //Find any vessels that have an MKS Module tied to this same eTag.
            var vList =
                LogisticsTools.GetNearbyVessels(EFF_RANGE, true, vessel, true)
                .Where(v => v.FindPartModulesImplementing <MKSModule>().Any(m => m.eTag == eTag));

            var validMods = new List <String>
            {
                "ModuleResourceConverter",
                "ModuleResourceHarvester",
                "ModuleBulkHarvester"
            };

            foreach (var vsl in vList)
            {
                var pList = vsl.FindPartModulesImplementing <BaseConverter>().Where(m => validMods.Contains(m.name));
                foreach (var p in pList)
                {
                    var m = p.part.FindModuleImplementing <MKSModule>();
                    if (m != null)
                    {
                        if (p.IsActivated)
                        {
                            totEff += (p.Efficiency * m.eMultiplier);
                        }
                    }
                }
            }
            return(totEff);
        }
Пример #7
0
        private double FetchResources(double amount, PartResourceDefinition resource, double fillPercent)
        {
            double demand  = amount;
            double fetched = 0d;

            try
            {
                var rangeFactor = LOG_RANGE;
                if (resource.name == "ElectricCharge")
                {
                    rangeFactor = POWER_RANGE;
                }

                var nearVessels = LogisticsTools.GetNearbyVessels(rangeFactor, false, vessel, true);
                foreach (var v in nearVessels)
                {
                    if (demand <= ResourceUtilities.FLOAT_TOLERANCE)
                    {
                        break;
                    }
                    //Is this a valid target?
                    if (!HasResourcesToSpare(v, resource, fillPercent))
                    {
                        continue;
                    }
                    //Can we find what we're looking for?
                    var partList = v.Parts.Where(
                        p => p.Resources.Contains(resource.name));
                    foreach (var p in partList)
                    {
                        //Special case - EC can only come from a PDU
                        if (resource.name == "ElectricCharge" && !p.Modules.Contains("ModulePowerDistributor"))
                        {
                            continue;
                        }
                        var pr = p.Resources[resource.name];
                        if (pr.amount >= demand)
                        {
                            pr.amount -= demand;
                            fetched   += demand;
                            demand     = 0;
                            break;
                        }
                        else
                        {
                            demand   -= pr.amount;
                            fetched  += pr.amount;
                            pr.amount = 0;
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                print(String.Format("[MKS] - ERROR in FetchResources - {0}", ex.StackTrace));
            }
            return(fetched);
        }
Пример #8
0
        public List <Vessel> GetPowerDistributors(Vessel thisVessel)
        {
            bool hasRelay = false;
            var  pList    = new List <Vessel>();
            var  vList    = LogisticsTools.GetNearbyVessels(20000, true, thisVessel, true);

            foreach (var v in vList)
            {
                var gParts = v.parts.Where(p => p.FindModuleImplementing <ModulePowerDistributor>() != null && HasCrew(p, "Engineer"));
                if (gParts != null)
                {
                    foreach (var p in gParts)
                    {
                        var mod      = p.FindModuleImplementing <ModulePowerDistributor>();
                        var posCur   = vessel.GetWorldPos3D();
                        var posNext  = v.GetWorldPos3D();
                        var distance = Vector3d.Distance(posCur, posNext);
                        if (distance < mod.PowerDistributionRange)
                        {
                            pList.Add(v);
                        }
                    }
                }

                if (!hasRelay)
                {
                    var dParts = v.parts.Where(p => p.FindModuleImplementing <ModulePowerCoupler>() != null);
                    if (dParts != null)
                    {
                        foreach (var p in dParts)
                        {
                            var mod      = p.FindModuleImplementing <ModulePowerCoupler>();
                            var posCur   = vessel.GetWorldPos3D();
                            var posNext  = v.GetWorldPos3D();
                            var distance = Vector3d.Distance(posCur, posNext);
                            if (distance < mod.PowerCouplingRange)
                            {
                                hasRelay = true;
                            }
                        }
                    }
                }
            }

            if (hasRelay)
            {
                return(pList);
            }

            else
            {
                return(new List <Vessel>());
            }
        }
Пример #9
0
        public bool LogisticsAvailable()
        {
            var vList = LogisticsTools.GetNearbyVessels(DEPOT_RANGE, true, vessel, true);

            foreach (var v in vList.Where(v => v.GetTotalMass() <= 3f))
            {
                if (v.Parts.Any(p => p.FindModuleImplementing <ModuleResourceDistributor>() != null && HasCrew(p, "Pilot")))
                {
                    return(true);
                }
            }
            return(false);
        }
Пример #10
0
        public bool PowerAvailable()
        {
            var vList = LogisticsTools.GetNearbyVessels(POWER_RANGE, true, vessel, true);

            foreach (var v in vList)
            {
                if (v.Parts.Any(p => p.FindModuleImplementing <ModulePowerDistributor>() != null && HasCrew(p, "Engineer")))
                {
                    return(true);
                }
            }
            return(false);
        }
        private void LevelResources(string resource)
        {
            var nearbyShips = LogisticsTools.GetNearbyVessels(LogisticsRange, true, vessel, true);
            var depots      = new List <Vessel>();

            foreach (var d in nearbyShips)
            {
                if (d.FindPartModulesImplementing <ModuleDistributedWarehouse>().Any() &&
                    d.Parts.Any(p => p.Resources.Contains(resource)))
                {
                    depots.Add(d);
                }
            }
            //Get relevant parts
            var resParts = new List <Part>();

            foreach (var d in depots)
            {
                var pList = d.parts.Where(p => p.Resources.Contains(resource) && p.Modules.Contains("ModuleDistributedWarehouse"));
                foreach (var p in pList)
                {
                    var wh = p.FindModuleImplementing <USI_ModuleResourceWarehouse>();
                    if (wh != null && wh.transferEnabled)
                    {
                        resParts.Add(p);
                    }
                }
            }
            var amountSum = 0d;
            var maxSum    = 0d;

            //Figure out our average fill percent
            foreach (var p in resParts)
            {
                var res = p.Resources[resource];
                amountSum += res.amount;
                maxSum    += res.maxAmount;
            }
            if (maxSum > 0 && amountSum > 0)
            {
                double fillPercent = amountSum / maxSum;
                //Level everything
                foreach (var p in resParts)
                {
                    var res = p.Resources[resource];
                    res.amount = res.maxAmount * fillPercent;
                }
            }
        }
Пример #12
0
        private float GetActiveBoosters(string tag)
        {
            var totalEfficiencyBoost = 0f;
            var boosters             = LogisticsTools.GetNearbyVessels(EFFICIENCY_RANGE, true, vessel, true)
                                       .SelectMany(v => v
                                                   .FindConverterAddonsImplementing <USI_EfficiencyBoosterAddon>()
                                                   .Where(a => a.Tag == tag));

            foreach (var booster in boosters)
            {
                if (booster.IsActive)
                {
                    totalEfficiencyBoost += (float)(booster.EfficiencyMultiplier * booster.Multiplier);
                }
            }

            return(totalEfficiencyBoost);
        }
        public List <Vessel> GetPowerDistributors()
        {
            var distributors  = new List <Vessel>();
            var nearbyVessels = LogisticsTools.GetNearbyVessels(LogisticsTools.PHYSICS_RANGE, false,
                                                                vessel, true);

            foreach (var v in nearbyVessels)
            {
                var range = LogisticsTools.GetRange(vessel, v);

                if (v.parts
                    .Select(p => p.FindModuleImplementing <ModulePowerDistributor>())
                    .Any(m => m != null && range <= m.ActiveDistributionRange))
                {
                    distributors.Add(v);
                }
            }
            return(distributors);
        }
Пример #14
0
        private float GetActiveEParts()
        {
            var totEff = 0f;
            var vList  =
                LogisticsTools.GetNearbyVessels(EFF_RANGE, true, vessel, true)
                .Where(v => v.FindPartModulesImplementing <ModuleEfficiencyPart>().Any(m => m.eTag == eTag));

            foreach (var vsl in vList)
            {
                var pList = vsl.FindPartModulesImplementing <ModuleEfficiencyPart>();
                foreach (var p in pList)
                {
                    if (p.IsActivated && p.eTag == eTag)
                    {
                        totEff += (float)(p.EfficiencyMultiplier * p.eMultiplier);
                    }
                }
            }
            return(totEff);
        }
Пример #15
0
        private float GetCrewHappiness()
        {
            //Crew Happiness is a function of the ratio of living space to Kerbals.
            //These are COLONY-WIDE.
            var   kShips = LogisticsTools.GetNearbyVessels(COLONY_RANGE, true, vessel, true);
            float ls     = GetKolonyLivingSpace(kShips);

            //We can add in a limited number for crew capacity - 10%
            ls += GetKolonyCrewCap(kShips) * .1f;

            var totKerbs = GetKolonyInhabitants(kShips);
            var hap      = 0f;

            if (totKerbs > 0)
            {
                hap = ls / totKerbs;
            }

            //Range is 50% - 150% for crowding and extra space.
            //This is calculated before loneliness.
            if (hap < .5f)
            {
                hap = .5f;
            }
            if (hap > 1.5f)
            {
                hap = 1.5f;
            }

            //Kerbals hate being alone.  Any fewer than five Kerbals incurs a pretty significant penalty.
            if (totKerbs < 5)
            {
                //20% - 80%
                hap *= (totKerbs * .2f);
            }
            return(hap);
        }
Пример #16
0
        private void RefreshResourceList()
        {
            if (vesselId != FlightGlobals.ActiveVessel.id.ToString())
            {
                vesselId = FlightGlobals.ActiveVessel.id.ToString();
                _resourceList.Clear();
            }

            var vList = LogisticsTools.GetNearbyVessels(LOCAL_LOGISTICS_RANGE, false, FlightGlobals.ActiveVessel, true);

            vList.Add(FlightGlobals.ActiveVessel);

            var _workList = new List <ResourceSummary>();

            var vCount = vList.Count;

            for (int i = 0; i < vCount; ++i)
            {
                var thisVessel = vList[i];
                var pCount     = thisVessel.Parts.Count;
                for (int p = 0; p < pCount; ++p)
                {
                    var thisPart = thisVessel.Parts[p];
                    var rCount   = thisPart.Resources.Count;
                    for (int r = 0; r < rCount; ++r)
                    {
                        var res = thisPart.Resources[r];
                        if (!res.isVisible)
                        {
                            continue;
                        }

                        var found = false;
                        wlCount = _workList.Count();
                        for (int c = 0; c < wlCount; ++c)
                        {
                            var thisRes = _workList[c];
                            if (thisRes.ResourceName == res.resourceName)
                            {
                                found = true;
                                thisRes.CurrentAmount = +res.amount;
                                thisRes.CurrentMax    = +res.maxAmount;
                                break;
                            }
                        }
                        if (!found)
                        {
                            _workList.Add(new ResourceSummary
                            {
                                CurrentMax    = res.maxAmount,
                                CurrentAmount = res.amount,
                                ResourceName  = res.resourceName
                            });
                        }
                    }
                }
            }

            //At this point we have a populated working list.  We now update the master list.

            rlCount = _resourceList.Count;
            wlCount = _workList.Count;

            for (int w = 0; w < wlCount; w++)
            {
                var found = false;
                var wRes  = _workList[w];
                for (int r = 0; r < _resourceList.Count; r++)
                {
                    var res = _resourceList[r];
                    if (wRes.ResourceName == res.ResourceName)
                    {
                        res.LastAmount    = res.CurrentAmount;
                        res.LastTime      = res.CurrentTime;
                        res.LastMax       = res.CurrentMax;
                        res.CurrentAmount = wRes.CurrentAmount;
                        res.CurrentMax    = wRes.CurrentMax;
                        res.CurrentTime   = Planetarium.GetUniversalTime();
                        found             = true;
                        break;
                    }
                }
                if (!found)
                {
                    _resourceList.Add(new ResourceSummary
                    {
                        LastTime      = Planetarium.GetUniversalTime() - UpdateFrequency,
                        LastAmount    = wRes.CurrentAmount,
                        LastMax       = wRes.CurrentMax,
                        CurrentAmount = wRes.CurrentAmount,
                        CurrentMax    = wRes.CurrentMax,
                        CurrentTime   = Planetarium.GetUniversalTime(),
                        ResourceName  = wRes.ResourceName
                    });
                }
            }

            //Cull missing resources
            for (int r = rlCount; r-- > 0;)
            {
                var res   = _resourceList[r];
                var found = false;
                for (int w = 0; r < _workList.Count; w++)
                {
                    var wRes = _workList[w];
                    if (wRes.ResourceName == res.ResourceName)
                    {
                        found = true;
                        break;
                    }
                }
                if (!found)
                {
                    _resourceList.Remove(res);
                }
            }
        }
Пример #17
0
        private void TransferResources(PartResourceDefinition resource, double amount, TransferType transferType)
        {
            try
            {
                var transferAmount = amount;
                var nearVessels    = LogisticsTools.GetNearbyVessels(LogisticsRange, false, vessel);
                foreach (var v in nearVessels)
                {
                    if (transferAmount == 0)
                    {
                        break;
                    }
                    //Can we find what we're looking for?
                    var partList = v.Parts.Where(
                        p => p.Resources.Contains(resource.name) &&
                        p != part &&
                        p.Modules.Contains("ProxyLogistics"));
                    foreach (var p in partList)
                    {
                        var pr = p.Resources[resource.name];
                        if (transferType == TransferType.TakeResources)
                        {
                            // RemotePartAmount:       200    -> 150
                            // LocalPartAmount:         10    -> 60
                            // TransferAmount:          50    -> 0
                            //
                            if (pr.amount >= transferAmount)
                            {
                                pr.amount -= transferAmount;
                                part.Resources[resource.name].amount += transferAmount;
                                transferAmount = 0;
                                break;
                            }
                            else
                            {
                                // RemotePartAmount:        10    -> 0
                                // LocalPartAmount:         10    -> 20
                                // TransferAmount:          50    -> 40
                                //
                                transferAmount -= pr.amount;
                                part.Resources[resource.name].amount += pr.amount;
                                pr.amount = 0;
                            }
                        }
                        else
                        {
                            var plMods = p.Modules.OfType <ProxyLogistics>().Where(m => m.IsLogisticsDistributor);

                            if (plMods.Any())
                            {
                                var storageSpace = pr.maxAmount - pr.amount;
                                if (storageSpace >= transferAmount)
                                {
                                    // SS: 100
                                    // RemotePartAmount:        400/500 -> 450/500
                                    // LocalPartAmount:         100     -> 50
                                    // TransferAmount:          50      -> 0
                                    pr.amount += transferAmount;
                                    part.Resources[resource.name].amount -= transferAmount;
                                    transferAmount = 0;
                                    break;
                                }
                                else
                                {
                                    // SS:10
                                    // RemotePartAmount:        490/500 -> 500/500
                                    // LocalPartAmount:         100     -> 90
                                    // TransferAmount:          50      -> 40
                                    transferAmount -= storageSpace;
                                    part.Resources[resource.name].amount -= storageSpace;
                                    pr.amount = pr.maxAmount;
                                }
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                print(String.Format("[MKS] - ERROR in TransferResources - {0}", ex.StackTrace));
            }
        }
Пример #18
0
        public List <Vessel> GetPowerDistributors(Vessel thisVessel)
        {
            bool hasRelay = false;
            var  pList    = new List <Vessel>();
            var  vList    = LogisticsTools.GetNearbyVessels(20000, true, thisVessel, true);

            print("Checking " + vList.Count + " vessels...");

            foreach (var v in vList)
            {
                var gParts = v.parts.Where(p => p.FindModuleImplementing <ModulePowerDistributor>() != null && HasCrew(p, "Engineer"));
                if (gParts != null)
                {
                    print("Found " + gParts.Count() + " parts that are distributors!");
                    foreach (var p in gParts)
                    {
                        var mod      = p.FindModuleImplementing <ModulePowerDistributor>();
                        var posCur   = vessel.GetWorldPos3D();
                        var posNext  = v.GetWorldPos3D();
                        var distance = Vector3d.Distance(posCur, posNext);
                        if (distance < mod.PowerDistributionRange)
                        {
                            print("Adding PDU in range");
                            pList.Add(v);
                        }
                        else
                        {
                            print("PDU was not in range...");
                        }
                    }
                }

                if (!hasRelay)
                {
                    var dParts = v.parts.Where(p => p.FindModuleImplementing <ModulePowerCoupler>() != null);
                    if (dParts != null)
                    {
                        print("Found " + gParts.Count() + " parts that are couplers!");
                        foreach (var p in dParts)
                        {
                            var mod      = p.FindModuleImplementing <ModulePowerCoupler>();
                            var posCur   = vessel.GetWorldPos3D();
                            var posNext  = v.GetWorldPos3D();
                            var distance = Vector3d.Distance(posCur, posNext);
                            if (distance < mod.PowerCouplingRange)
                            {
                                print("Relay was in range!!!!");
                                hasRelay = true;
                            }
                            else
                            {
                                print("Relay was not in range");
                            }
                        }
                    }
                }
            }

            if (hasRelay)
            {
                return(pList);
            }

            else
            {
                return(new List <Vessel>());
            }
        }
Пример #19
0
        private void DrawLogistics()
        {
            var vessels = LogisticsTools.GetNearbyVessels(2000, true, _model, true);
            List <LogisticsResource>   resources = new List <LogisticsResource>();
            Dictionary <string, float> dr        = new Dictionary <string, float>();

            int kerbals = 0;

            foreach (Vessel v in vessels)
            {
                // Storage
                foreach (var r in v.GetStorage())
                {
                    getResourceFromList(resources, r.resourceName).maxAmount += r.amount;
                }

                // Amount
                foreach (var r in v.GetResourceAmounts())
                {
                    getResourceFromList(resources, r.resourceName).amount += r.amount;
                }

                // Production of converters
                foreach (var r in v.GetProduction())
                {
                    getResourceFromList(resources, r.resourceName).change += r.amount;
                }

                // Consumption of Converters
                foreach (var r in v.GetProduction(false))
                {
                    getResourceFromList(resources, r.resourceName).change -= r.amount;
                }

                // Drills
                foreach (Part drill in v.Parts.Where(p => p.Modules.Contains("ModuleResourceHarvester")))
                {
                    foreach (ModuleResourceHarvester m in drill.FindModulesImplementing <ModuleResourceHarvester>().Where(mod => mod.IsActivated))
                    {
                        bool hasResource = false;
                        foreach (var p in v.Parts)
                        {
                            var res = p.Resources.Get(m.ResourceName);
                            if (res == null)
                            {
                                continue;
                            }
                            if (res.amount <= res.maxAmount)
                            {
                                hasResource = true;
                            }
                        }
                        if (hasResource)
                        // test if storage for this resource on this vessel is not full
                        {
                            AbundanceRequest ar = new AbundanceRequest
                            {
                                Altitude     = v.altitude,
                                BodyId       = FlightGlobals.currentMainBody.flightGlobalsIndex,
                                CheckForLock = false,
                                Latitude     = v.latitude,
                                Longitude    = v.longitude,
                                ResourceType = HarvestTypes.Planetary,
                                ResourceName = m.ResourceName
                            };
                            getResourceFromList(resources, m.ResourceName).change   += (double)ResourceMap.Instance.GetAbundance(ar);
                            getResourceFromList(resources, "ElectricCharge").change -= 6;
                        }
                    }
                }

                // Life Support
                kerbals += v.GetCrewCount();
            }
            if (_usils)
            {
                getResourceFromList(resources, "Supplies").change       -= kerbals * 0.00005;
                getResourceFromList(resources, "Mulch").change          += kerbals * 0.00005;
                getResourceFromList(resources, "ElectricCharge").change -= kerbals * 0.01;
            }
            if (_tacls)
            {
                // TAC-LS consumption rates are a bit complex to calculate, so here is an approximated calculation where
                // - Kerbals on EVA are not handled
                // - BaseElectricityConsumptionRate is not taken into account
                getResourceFromList(resources, "Oxygen").change         -= kerbals * 0.001713537562385;
                getResourceFromList(resources, "Food").change           -= kerbals * 0.000016927083333;
                getResourceFromList(resources, "Water").change          -= kerbals * 0.000011188078704;
                getResourceFromList(resources, "CarbonDioxide").change  += kerbals * 0.00148012889876;
                getResourceFromList(resources, "Waste").change          += kerbals * 0.000001539351852;
                getResourceFromList(resources, "WasteWater").change     += kerbals * 0.000014247685185;
                getResourceFromList(resources, "ElectricCharge").change -= kerbals * 0.014166666666667;
                // Values are based on TAC-LS Version 0.11.1.20
            }
            // Consumption rates for Snacks are not calculated

            resources.Sort(new LogisticsResourceComparer());
            foreach (LogisticsResource r in resources)
            {
                GUILayout.Label(r.resourceName + ": " + numberToOut(r.amount, -1, false) + "/" + Math.Round(r.maxAmount, 5) + " (" + numberToOut(r.change, r.change > 0 ? r.maxAmount - r.amount : r.amount) + ")");
            }
        }
Пример #20
0
        private static List <Vessel> FetchNewParticipatingVessels()
        {
            var nearbyVessels = LogisticsTools.GetNearbyVessels(LOCAL_LOGISTICS_RANGE, true, FlightGlobals.ActiveVessel, true);

            return(nearbyVessels.Where(HasResources).ToList());
        }
Пример #21
0
        private float GetEfficiency()
        {
            try
            {
                //Efficiency is based on various factors.  These come in three
                //categories:
                //  * Part
                //  * Vessel
                //  * Colony
                //  - Vessel Workspaces         [numWorkspaces]
                //  - 25% Vessel Crew Capacity  [numWorkSpaces]
                //  - Vessel MKS Module count   [numModules]
                //  - Part Crew                 [modKerbalFactor]   (0.05 - 3.75 per Kerbal)
                //  - Vessel crew               [numWeightedKerbals]
                //  - Colony efficiency parts   [added to eff]
                //          Bonus equal to 100 * number of units - 1
                //  - Colony Living Space/Kerbal Happiness

                float numWorkspaces = GetKolonyWorkspaces(vessel);
                //Plus 25% of Crew Cap as low efficiency workspaces
                numWorkspaces += vessel.GetCrewCapacity() * .25f;
                //Number of active modules
                var numModules = GetActiveKolonyModules(vessel);
                //Kerbals in the module
                float modKerbalFactor = part.protoModuleCrew.Sum(k => GetKerbalFactor(k));
                modKerbalFactor *= GetCrewHappiness();
                //Kerbals in the ship
                float numWeightedKerbals = vessel.GetVesselCrew().Sum(k => GetKerbalFactor(k));
                numWeightedKerbals *= GetCrewHappiness();
                //Worst case, 25% (if crewed).  Uncrewed vessels will be at 0%
                //You need crew for these things, no robo ships.
                float eff = .0f;
                if (vessel.GetCrewCount() > 0)
                {
                    float WorkSpaceKerbalRatio = numWorkspaces / vessel.GetCrewCount();
                    if (WorkSpaceKerbalRatio > 3)
                    {
                        WorkSpaceKerbalRatio = 3;
                    }
                    //A module gets 100% bonus from Kerbals inside of it,
                    //in addition to a 10% bonus for Kerbals in the entire station.
                    float WorkUnits = WorkSpaceKerbalRatio * modKerbalFactor;
                    WorkUnits += WorkSpaceKerbalRatio * numWeightedKerbals * CrewBonus;
                    eff        = WorkUnits / numModules;
                    if (eff > MaxEfficiency)
                    {
                        eff = MaxEfficiency;
                    }
                    if (eff < .25)
                    {
                        eff = .25f;
                    }
                }

                //Add in efficiencyParts
                if (efficiencyPart != "")
                {
                    var validEffParts = new List <EffPart>();
                    var effPartBits   = efficiencyPart.Split(',')
                                        .Select(effPartName => effPartName.Trim().Replace('_', '.')).ToArray();

                    for (int i = 0; i < effPartBits.Count(); i += 2)
                    {
                        validEffParts.Add(new EffPart
                        {
                            Name       = effPartBits[i],
                            Multiplier = float.Parse(effPartBits[i + 1])
                        });
                    }

                    var effParts = 0f;
                    foreach (var vep in validEffParts)
                    {
                        var vList       = LogisticsTools.GetNearbyVessels(EFF_RANGE, true, vessel, true);
                        var effPartList = new List <Part>();
                        foreach (var v in vList)
                        {
                            var nameWhenRootPart = vep.Name + " (" + v.GetName() + ")";
                            var pList            = v.Parts.Where(p => p.name == vep.Name || p.name == nameWhenRootPart);
                            effPartList.AddRange(pList);
                        }

                        foreach (var ep in effPartList)
                        {
                            var mod = ep.FindModuleImplementing <USIAnimation>();
                            if (mod == null)
                            {
                                effParts += vep.Multiplier;
                            }
                            else
                            {
                                if (mod.isDeployed)
                                {
                                    effParts += vep.Multiplier;
                                }
                            }
                        }
                    }
                    eff += effParts;
                    if (eff < 0.25)
                    {
                        eff = 0.25f;  //We can go as low as 25% as these are almost mandatory.
                    }
                }

                if (!calculateEfficiency)
                {
                    eff        = 1f;
                    efficiency = String.Format("100% [Fixed]");
                }

                efficiency = String.Format("{0}%", Math.Round((eff * 100), 1));

                //DEBUG DATA
                //DEBUG

                return(eff);
            }
            catch (Exception ex)
            {
                print(String.Format("[MKS] - ERROR in GetEfficiency - {0}", ex.Message));
                return(1f);
            }
        }
Пример #22
0
        private void DrawLogistics()
        {
            var vessels = LogisticsTools.GetNearbyVessels(2000, true, _model, true);
            List <LogisticsResource>   resources = new List <LogisticsResource>();
            Dictionary <string, float> dr        = new Dictionary <string, float>();

            int kerbals = 0;

            foreach (Vessel v in vessels)
            {
                // Storage
                foreach (var r in v.GetStorage())
                {
                    getResourceFromList(resources, r.resourceName).maxAmount += r.amount;
                }

                // Amount
                foreach (var r in v.GetResourceAmounts())
                {
                    getResourceFromList(resources, r.resourceName).amount += r.amount;
                }

                // Production of converters
                foreach (var r in v.GetProduction())
                {
                    getResourceFromList(resources, r.resourceName).change += r.amount;
                }

                // Consumption of Converters
                foreach (var r in v.GetProduction(false))
                {
                    getResourceFromList(resources, r.resourceName).change -= r.amount;
                }

                // Drills
                foreach (Part drill in v.Parts.Where(p => p.Modules.Contains("ModuleResourceHarvester")))
                {
                    foreach (ModuleResourceHarvester m in drill.FindModulesImplementing <ModuleResourceHarvester>().Where(mod => mod.IsActivated))
                    {
                        if (v.Parts.Exists(p => p.Resources.list.Exists(r => r.resourceName == m.ResourceName && r.amount < r.maxAmount)))
                        // test if storage for this resource on this vessel is not full
                        {
                            AbundanceRequest ar = new AbundanceRequest
                            {
                                Altitude     = v.altitude,
                                BodyId       = FlightGlobals.currentMainBody.flightGlobalsIndex,
                                CheckForLock = false,
                                Latitude     = v.latitude,
                                Longitude    = v.longitude,
                                ResourceType = HarvestTypes.Planetary,
                                ResourceName = m.ResourceName
                            };
                            getResourceFromList(resources, m.ResourceName).change   += (double)ResourceMap.Instance.GetAbundance(ar);
                            getResourceFromList(resources, "ElectricCharge").change -= 6;
                        }
                    }
                }

                // Life Support
                kerbals += v.GetCrewCount();
            }
            if (_usils)
            {
                getResourceFromList(resources, "Supplies").change       -= kerbals * 0.00005;
                getResourceFromList(resources, "Mulch").change          += kerbals * 0.00005;
                getResourceFromList(resources, "ElectricCharge").change -= kerbals * 0.01;
            }
            resources.Sort(new LogisticsResourceComparer());
            foreach (LogisticsResource r in resources)
            {
                GUILayout.Label(r.resourceName + ": " + numberToOut(r.amount, -1, false) + "/" + Math.Round(r.maxAmount, 5) + " (" + numberToOut(r.change, r.change > 0 ? r.maxAmount - r.amount : r.amount) + ")");
            }
        }