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