Example #1
0
        private void EatSnacks()
        {
            try
            {
                double snackDeficit;
                int    crewCount = 0;

                //Post the before snack time event
                onBeforeSnackTime.Fire();

                //Consume snacks for loaded vessels
                //Debug.Log("Loaded vessles count: " + FlightGlobals.VesselsLoaded.Count);
                foreach (Vessel vessel in FlightGlobals.Vessels)
                {
                    snackDeficit = 0;

                    //Skip the vessel if it has unowned crew
                    if (SnackConsumer.hasUnownedCrew(vessel))
                    {
                        Debug.Log("Skipping " + vessel.vesselName + " due to unowned crew");
                        continue;
                    }

                    //Consume snacks and get the deficit if any.
                    if (vessel.loaded)
                    {
                        crewCount = vessel.GetCrewCount();
                    }
                    else
                    {
                        crewCount = vessel.protoVessel.GetVesselCrew().Count;
                    }

                    if (crewCount > 0)
                    {
                        //Consume snacks and get the deficit (if any)
                        snackDeficit = consumer.ConsumeAndGetDeficit(vessel);

                        //Apply penalties if we have a deficit
                        if (snackDeficit > 0)
                        {
                            applyPenalties(snackDeficit, vessel);
                        }

                        //Make sure to remove all penalties, the kerbals are all fed.
                        else
                        {
                            removePenalties(vessel);
                        }
                    }
                }

                //Post the snack time event
                onSnackTime.Fire();
            }
            catch (Exception ex)
            {
                Debug.Log("Snacks - EatSnacks: " + ex.Message + ex.StackTrace);
            }
        }
Example #2
0
 void Awake()
 {
     try
     {
         GameEvents.onCrewOnEva.Add(OnCrewOnEva);
         GameEvents.onCrewBoardVessel.Add(OnCrewBoardVessel);
         GameEvents.onGameStateLoad.Add(onLoad);
         GameEvents.onVesselRename.Add(OnRename);
         GameEvents.onVesselChange.Add(OnVesselChange);
         GameEvents.onVesselWasModified.Add(OnVesselWasModified);
         SnackConfiguration snackConfig = SnackConfiguration.Instance();
         snackResourceId     = snackConfig.SnackResourceId;
         soilResourceId      = snackConfig.SoilResourceId;
         snackFrequency      = 6 * 60 * 60 * 2 / snackConfig.MealsPerDay;
         snacksPerMeal       = snackConfig.SnacksPerMeal;
         lossPerDayPerKerbal = snackConfig.LossPerDay;
         kerbalDeath         = snackConfig.KerbalDeath;
         consumer            = new SnackConsumer(snackConfig.SnacksPerMeal, snackConfig.LossPerDay);
     }
     catch (Exception ex)
     {
         Debug.Log("Snacks - Awake error: " + ex.Message + ex.StackTrace);
     }
 }
Example #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);
                }
            }
        }
Example #4
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);
                }
            }
        }
Example #5
0
 void Awake()
 {
     try
     {
         GameEvents.onCrewOnEva.Add(OnCrewOnEva);
         GameEvents.onCrewBoardVessel.Add(OnCrewBoardVessel);
         GameEvents.onGameStateLoad.Add(onLoad);
         GameEvents.onVesselRename.Add(OnRename);
         GameEvents.onVesselChange.Add(OnVesselChange);
         GameEvents.onVesselWasModified.Add(OnVesselWasModified);
         SnackConfiguration snackConfig = SnackConfiguration.Instance();
         snackResourceId = snackConfig.SnackResourceId;
         soilResourceId = snackConfig.SoilResourceId;
         snackFrequency = 6 * 60 * 60 * 2 / snackConfig.MealsPerDay;
         snacksPerMeal = snackConfig.SnacksPerMeal;
         lossPerDayPerKerbal = snackConfig.LossPerDay;
         kerbalDeath = snackConfig.KerbalDeath;
         consumer = new SnackConsumer(snackConfig.SnacksPerMeal, snackConfig.LossPerDay);
     }
     catch (Exception ex)
     {
         Debug.Log("Snacks - Awake error: " + ex.Message + ex.StackTrace);
     }
 }