示例#1
0
        private void AddShipSupply(ShipSupply supply, int planet)
        {
            if (!vessels.ContainsKey(planet))
            {
                vessels.Add(planet, new List <ShipSupply>());
            }

            List <ShipSupply> ships;
            bool suc = vessels.TryGetValue(planet, out ships);

            ships.Add(supply);
        }
示例#2
0
        public void drawEditorWindow()
        {
            ShipSupply supply = SnackSnapshot.Instance().TakeEditorSnapshot();

            scrollPos = GUILayout.BeginScrollView(scrollPos, GUILayout.Height(300), GUILayout.Width(300));

            if (!GameSettings.KERBIN_TIME)
            {
                GUILayout.Label("<color=lightblue>Time format: 24hr/day, 365 day/year</color>");
            }

            if (SnacksProperties.EnableRandomSnacking || SnacksProperties.RecyclersEnabled)
            {
                GUILayout.Label("<color=yellow>The following are estimates</color>");
            }

            GUILayout.Label("<color=white>Snacks: " + supply.SnackAmount + "/" + supply.SnackMaxAmount + "</color>");
            //GUILayout.Label("<color=white>Days (Cur Crew): " + supply.DayEstimate + "</color>");
            //GUILayout.Label("<color=white>Days (Max Crew): " + supply.MaxDayEstimate + "</color>");

            if (supply.DayEstimate > 0)
            {
                GUILayout.Label("<color=white>Current Crew: " + supply.CrewCount + "</color>");
                GUILayout.Label("<color=white>Duration: " + timeFormat(supply.DayEstimate) + "</color>");
            }
            else
            {
                GUILayout.Label("<color=white>Current Crew: " + supply.CrewCount + "</color>");
                GUILayout.Label("<color=white>Duration: Indefinite</color>");
            }

            if (supply.MaxDayEstimate > 0)
            {
                GUILayout.Label("<color=white>Max Crew: " + supply.MaxCrewCount + "</color>");
                GUILayout.Label("<color=white>Duration: " + timeFormat(supply.MaxDayEstimate) + "</color>");
            }
            else
            {
                GUILayout.Label("<color=white>Max Crew: " + supply.MaxCrewCount + "</color>");
                GUILayout.Label("<color=white>Duration: Indefinite</color>");
            }


            GUILayout.EndScrollView();
        }
示例#3
0
        protected void TakeSnapshotLoaded(Dictionary <int, List <ShipSupply> > vessels)
        {
            vessels = new Dictionary <int, List <ShipSupply> >();
            double snacksPerKerbal = SnacksProperties.MealsPerDay * SnacksProperties.SnacksPerMeal;
            Vessel v;

            Vessel[] loadedVessels;
            double   snackAmount      = 0;
            double   snackMax         = 0;
            double   snackConsumption = 0;
            double   snackProduction  = 0;
            double   recycleCapacity  = 0;
            int      crewCount;

            loadedVessels = FlightGlobals.VesselsLoaded.ToArray();
            for (int index = 0; index < loadedVessels.Length; index++)
            {
                v = loadedVessels[index];

                //Skip vessels with unowned crew
                if (SnackConsumer.hasUnownedCrew(v))
                {
                    continue;
                }

                crewCount = v.GetVesselCrew().Count;
                //Debug.Log("processing v:" + v.vesselName);
                if (crewCount > 0)
                {
                    v.resourcePartSet.GetConnectedResourceTotals(SnacksProperties.SnackResourceID, out snackAmount, out snackMax, true);

                    //Calculate snack consumption
                    snackConsumption = crewCount * snacksPerKerbal;
                    snackProduction  = 0;
                    if (SnacksProperties.RecyclersEnabled)
                    {
                        SoilRecycler[] recyclers = v.FindPartModulesImplementing <SoilRecycler>().ToArray();
                        for (int recyclerIndex = 0; recyclerIndex < recyclers.Length; recyclerIndex++)
                        {
                            if (recyclers[recyclerIndex].IsActivated)
                            {
                                snackProduction += recyclers[recyclerIndex].GetDailySnacksOutput();
                                recycleCapacity += recyclers[recyclerIndex].RecyclerCapacity;
                            }
                        }

                        //Account for the recyclers
                        if (crewCount >= recycleCapacity)
                        {
                            snackConsumption -= snackProduction;
                        }
                        else
                        {
                            snackConsumption -= snackProduction * (crewCount / recycleCapacity);
                        }
                    }

                    ShipSupply supply = new ShipSupply();
                    supply.VesselName     = v.vesselName;
                    supply.BodyName       = v.mainBody.name;
                    supply.SnackAmount    = Convert.ToInt32(snackAmount);
                    supply.SnackMaxAmount = Convert.ToInt32(snackMax);
                    supply.CrewCount      = crewCount;
                    supply.DayEstimate    = Convert.ToInt32(snackAmount / snackConsumption);
                    supply.Percent        = snackMax == 0 ? 0 : Convert.ToInt32(snackAmount / snackMax * 100);
                    AddShipSupply(supply, v.protoVessel.orbitSnapShot.ReferenceBodyIndex);
                    outOfSnacks.Add(v.id, snackAmount != 0.0 ? false : true);
                }
            }
        }
示例#4
0
        public ShipSupply TakeEditorSnapshot()
        {
            ShipSupply shipSupply          = new ShipSupply();
            double     snackProduction     = 0;
            double     snackConsumption    = 0;
            double     snackConsumptionMax = 0;
            double     currentSnacks       = 0;
            double     maxSnacks           = 0;
            double     recycleCapacity     = 0;
            double     snacksPerKerbal     = SnacksProperties.MealsPerDay * SnacksProperties.SnacksPerMeal;
            int        maxCrew             = 0;

            Part[] parts = EditorLogic.fetch.ship.parts.ToArray();
            Part   part;

            SoilRecycler[]     recyclers;
            VesselCrewManifest manifest = CrewAssignmentDialog.Instance.GetManifest();

            //No parts? Then we're done
            if (parts.Length == 0)
            {
                return(shipSupply);
            }
            if (manifest == null)
            {
                return(shipSupply);
            }
            if (manifest.CrewCount == 0)
            {
                return(shipSupply);
            }
            int crewCount = manifest.CrewCount;

            for (int index = 0; index < parts.Length; index++)
            {
                part = parts[index];

                //Update max crew
                maxCrew += part.CrewCapacity;

                //Make sure the crewed part has snacks
                if (!part.Resources.Contains(SnacksProperties.SnacksResourceName) && part.CrewCapacity >= 1)
                {
                    ConfigNode node   = new ConfigNode("RESOURCE");
                    double     amount = 0;
                    node.AddValue("name", SnacksProperties.SnacksResourceName);
                    if (part.FindModuleImplementing <ModuleCommand>() != null)
                    {
                        amount = SnacksProperties.SnacksPerCommand * part.CrewCapacity;
                    }
                    else
                    {
                        amount = SnacksProperties.SnacksPerCrewModule * part.CrewCapacity;
                    }
                    node.AddValue("amount", amount.ToString());
                    node.AddValue("maxAmount", amount.ToString());
                    part.AddResource(node);
                }

                //Update snack resource values
                if (part.Resources.Contains(SnacksProperties.SnacksResourceName))
                {
                    if (part.Resources[SnacksProperties.SnacksResourceName].flowState)
                    {
                        currentSnacks += part.Resources[SnacksProperties.SnacksResourceName].amount;
                        maxSnacks     += part.Resources[SnacksProperties.SnacksResourceName].maxAmount;
                    }
                }

                //Compute snack production
                if (SnacksProperties.RecyclersEnabled)
                {
                    recyclers = part.FindModulesImplementing <SoilRecycler>().ToArray();
                    for (int recyclerIndex = 0; recyclerIndex < recyclers.Length; recyclerIndex++)
                    {
                        snackProduction += recyclers[recyclerIndex].GetDailySnacksOutput();
                        recycleCapacity += recyclers[recyclerIndex].RecyclerCapacity;
                    }
                }
            }

            //Calculate consumption estimates. Account for crew being less than max recycling capacity
            snackConsumption = snacksPerKerbal * crewCount;
            if (crewCount >= recycleCapacity)
            {
                snackConsumption -= snackProduction;
            }

            else
            {
                snackConsumption -= snackProduction * (crewCount / recycleCapacity);
            }

            snackConsumptionMax = snacksPerKerbal * maxCrew;
            if (maxCrew >= recycleCapacity)
            {
                snackConsumptionMax -= snackProduction;
            }
            else
            {
                snackConsumptionMax -= snackProduction * (maxCrew / recycleCapacity);
            }

            if (snackConsumption == 0 || snackConsumptionMax == 0)
            {
                return(shipSupply);
            }

            //Setup the supply snapshot
            shipSupply.SnackAmount    = Convert.ToInt32(currentSnacks);
            shipSupply.SnackMaxAmount = Convert.ToInt32(maxSnacks);
            shipSupply.CrewCount      = crewCount;
            shipSupply.DayEstimate    = Convert.ToInt32(currentSnacks / snackConsumption);
            shipSupply.MaxCrewCount   = maxCrew;
            shipSupply.MaxDayEstimate = Convert.ToInt32(maxSnacks / snackConsumptionMax);

            return(shipSupply);
        }
示例#5
0
        protected void takeSnapshotProto(Dictionary <int, List <ShipSupply> > vessels)
        {
            double      snacksPerKerbal = SnacksProperties.MealsPerDay * SnacksProperties.SnacksPerMeal;
            ProtoVessel pv;

            ProtoVessel[] protoVessels;
            double        snackAmount      = 0;
            double        snackMax         = 0;
            double        snackConsumption = 0;
            double        snackProduction  = 0;
            double        recycleCapacity  = 0;
            int           crewCount;
            int           partCrewCount;
            bool          foundSnackResource = false;

            protoVessels = HighLogic.CurrentGame.flightState.protoVessels.ToArray();
            for (int index = 0; index < protoVessels.Length; index++)
            {
                pv = protoVessels[index];

                //Skip vessels with unowned crew
                if (SnackConsumer.hasUnownedCrew(pv.vesselRef))
                {
                    continue;
                }

                //Debug.Log("processing pv:" + pv.vesselName);
                if (!pv.vesselRef.loaded)
                {
                    crewCount = pv.GetVesselCrew().Count;
                    if (crewCount < 1)
                    {
                        continue;
                    }
                    snackAmount      = 0;
                    snackMax         = 0;
                    snackConsumption = crewCount * snacksPerKerbal;
                    foreach (ProtoPartSnapshot pps in pv.protoPartSnapshots)
                    {
                        foundSnackResource = false;
                        partCrewCount      = pps.partInfo.partPrefab.CrewCapacity;

                        //Tally the snack and max snack amounts
                        foreach (ProtoPartResourceSnapshot resource in pps.resources)
                        {
                            if (resource.resourceName == SnacksProperties.SnacksResourceName)
                            {
                                if (resource.flowState)
                                {
//                                    Debug.Log("Found snacks in " + pps.partName);
                                    snackAmount += resource.amount;
                                    snackMax    += resource.maxAmount;
                                }
                                foundSnackResource = true;
                            }
                        }

                        //Add Snacks if we don't find any
                        if (!foundSnackResource && partCrewCount > 0)
                        {
//                            Debug.Log("Part should have Snacks but doesn't. Trying to add Snacks to " + pps.partName);
                            int snacksPer = SnacksProperties.SnacksPerCrewModule;

                            //See if we have a command module. If so, that will affect how many snacks we have in the part.
                            ProtoPartModuleSnapshot[] modules = pps.modules.ToArray();
                            for (int moduleIndex = 0; moduleIndex < modules.Length; moduleIndex++)
                            {
                                if (modules[moduleIndex].moduleName == "ModuleCommand")
                                {
                                    snacksPer = SnacksProperties.SnacksPerCommand;
                                    break;
                                }
                            }

                            ConfigNode snackNode   = new ConfigNode("RESOURCE");
                            int        totalSnacks = pps.partInfo.partPrefab.CrewCapacity * snacksPer;
                            snackNode.AddValue("name", SnacksProperties.SnacksResourceName);
                            snackNode.AddValue("amount", totalSnacks);
                            snackNode.AddValue("maxAmount", totalSnacks);
                            pps.resources.Add(new ProtoPartResourceSnapshot(snackNode));
                            snackAmount += totalSnacks;
                            snackMax    += totalSnacks;
                        }

                        //Check for recyclers
                        if (SnacksProperties.RecyclersEnabled)
                        {
                            bool         isActivated          = false;
                            ConfigNode[] snapModules          = pps.partInfo.partConfig.GetNodes("MODULE");
                            ConfigNode   snapModule           = null;
                            ProtoPartModuleSnapshot[] modules = pps.modules.ToArray();

                            //See if the part has a recycler
                            for (int moduleIndex = 0; moduleIndex < snapModules.Length; moduleIndex++)
                            {
                                if (snapModules[moduleIndex].GetValue("name") == "SoilRecycler")
                                {
                                    snapModule = snapModules[moduleIndex];
                                    break;
                                }
                            }

                            //Check for activation
                            for (int snapModIndex = 0; snapModIndex < modules.Length; snapModIndex++)
                            {
                                if (modules[snapModIndex].moduleName == "SoilRecycler")
                                {
                                    //Activation status
                                    string activated = modules[snapModIndex].moduleValues.GetValue("IsActivated").ToLower();
                                    if (activated == "true")
                                    {
                                        isActivated = true;
                                        break;
                                    }
                                }
                            }

                            //If it has a recycler then calculate the snack production if the recycler is active
                            if (snapModule != null && isActivated)
                            {
                                //Capacity
                                if (snapModule.HasValue("RecyclerCapacity"))
                                {
                                    recycleCapacity += int.Parse(snapModule.GetValue("RecyclerCapacity"));
                                }

                                ConfigNode[] outputs = snapModule.GetNodes("OUTPUT_RESOURCE");
                                for (int outputIndex = 0; outputIndex < outputs.Length; outputIndex++)
                                {
                                    if (outputs[outputIndex].GetValue("ResourceName") == SnacksProperties.SnacksResourceName)
                                    {
                                        snackProduction += double.Parse(outputs[outputIndex].GetValue("Ratio")) * SnacksProperties.RecyclerEfficiency * 21600;
                                    }
                                }
                            }
                        }
                    }

                    if (SnacksProperties.RecyclersEnabled)
                    {
                        //Account for recyclers
                        if (crewCount >= recycleCapacity)
                        {
                            snackConsumption -= snackProduction;
                        }
                        else
                        {
                            snackConsumption -= snackProduction * (crewCount / recycleCapacity);
                        }
                    }

                    //Debug.Log(pv.vesselName + "1");
                    ShipSupply supply = new ShipSupply();
                    supply.VesselName     = pv.vesselName;
                    supply.BodyName       = pv.vesselRef.mainBody.name;
                    supply.SnackAmount    = Convert.ToInt32(snackAmount);
                    supply.SnackMaxAmount = Convert.ToInt32(snackMax);
                    supply.CrewCount      = crewCount;
                    //Debug.Log(pv.vesselName + supply.CrewCount);
                    supply.DayEstimate = Convert.ToInt32(snackAmount / snackConsumption);
                    //Debug.Log(pv.vesselName + supply.DayEstimate);
                    //Debug.Log("sa:" + snackAmount + " sm:" + snackMax);
                    supply.Percent = snackMax == 0 ? 0 : Convert.ToInt32(snackAmount / snackMax * 100);
                    //Debug.Log(pv.vesselName + supply.Percent);
                    AddShipSupply(supply, pv.orbitSnapShot.ReferenceBodyIndex);
                    outOfSnacks.Add(pv.vesselID, snackAmount != 0.0 ? false : true);
                }
            }
        }
示例#6
0
        public Dictionary <int, List <ShipSupply> > Vessels()
        {
            try
            {
                if (vessels == null)
                {
                    Debug.Log("rebuilding snapshot");
                    int snackResourceId = SnackConfiguration.Instance().SnackResourceId;
                    vessels     = new Dictionary <int, List <ShipSupply> >();
                    outOfSnacks = new Dictionary <Guid, bool>();

                    List <Guid> activeVessels = new List <Guid>();

                    foreach (Vessel v in FlightGlobals.Vessels)
                    {
                        //Debug.Log("processing v:" + v.vesselName);
                        if (v.GetVesselCrew().Count > 0 && v.loaded)
                        {
                            activeVessels.Add(v.id);
                            List <PartResource> resources = new List <PartResource>();
                            v.rootPart.GetConnectedResources(snackResourceId, ResourceFlowMode.ALL_VESSEL, resources);
                            double snackAmount = 0;
                            double snackMax    = 0;
                            foreach (PartResource r in resources)
                            {
                                snackAmount += r.amount;
                                snackMax    += r.maxAmount;
                            }

                            ShipSupply supply = new ShipSupply();
                            supply.VesselName     = v.vesselName;
                            supply.BodyName       = v.mainBody.name;
                            supply.SnackAmount    = Convert.ToInt32(snackAmount);
                            supply.SnackMaxAmount = Convert.ToInt32(snackMax);
                            supply.CrewCount      = v.GetVesselCrew().Count;
                            supply.DayEstimate    = Convert.ToInt32(snackAmount / supply.CrewCount / (SnackConfiguration.Instance().MealsPerDay *SnackConfiguration.Instance().SnacksPerMeal));
                            supply.Percent        = snackMax == 0 ? 0 : Convert.ToInt32(snackAmount / snackMax * 100);
                            AddShipSupply(supply, v.protoVessel.orbitSnapShot.ReferenceBodyIndex);
                            outOfSnacks.Add(v.id, snackAmount != 0.0 ? false : true);
                        }
                    }

                    foreach (var pv in HighLogic.CurrentGame.flightState.protoVessels)
                    {
                        //Debug.Log("processing pv:" + pv.vesselName);
                        if (!pv.vesselRef.loaded && !activeVessels.Contains(pv.vesselID))
                        {
                            if (pv.GetVesselCrew().Count < 1)
                            {
                                continue;
                            }
                            double snackAmount = 0;
                            double snackMax    = 0;
                            foreach (ProtoPartSnapshot pps in pv.protoPartSnapshots)
                            {
                                var res = from r in pps.resources
                                          where r.resourceName == "Snacks"
                                          select r;
                                if (res.Count() > 0)
                                {
                                    ConfigNode node = res.First().resourceValues;
                                    snackAmount += Double.Parse(node.GetValue("amount"));
                                    snackMax    += Double.Parse(node.GetValue("maxAmount"));
                                }
                            }
                            //Debug.Log(pv.vesselName + "1");
                            ShipSupply supply = new ShipSupply();
                            supply.VesselName     = pv.vesselName;
                            supply.BodyName       = pv.vesselRef.mainBody.name;
                            supply.SnackAmount    = Convert.ToInt32(snackAmount);
                            supply.SnackMaxAmount = Convert.ToInt32(snackMax);
                            supply.CrewCount      = pv.GetVesselCrew().Count;
                            //Debug.Log(pv.vesselName + supply.CrewCount);
                            supply.DayEstimate = Convert.ToInt32(snackAmount / supply.CrewCount / (SnackConfiguration.Instance().MealsPerDay *SnackConfiguration.Instance().SnacksPerMeal));
                            //Debug.Log(pv.vesselName + supply.DayEstimate);
                            //Debug.Log("sa:" + snackAmount + " sm:" + snackMax);
                            supply.Percent = snackMax == 0 ? 0 : Convert.ToInt32(snackAmount / snackMax * 100);
                            //Debug.Log(pv.vesselName + supply.Percent);
                            AddShipSupply(supply, pv.orbitSnapShot.ReferenceBodyIndex);
                            outOfSnacks.Add(pv.vesselID, snackAmount != 0.0 ? false : true);
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                Debug.Log("building snapshot failed: " + ex.Message + ex.StackTrace);
            }
            return(vessels);
        }