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); } }
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); } } }
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); } } }