protected virtual bool payUpgradeCost() { if (HighLogic.LoadedSceneIsFlight == false) { return(true); } if (!WBIMainSettings.PayToReconfigure) { return(true); } if (upgradeCost == 0f) { return(true); } if (string.IsNullOrEmpty(upgradeResource)) { return(true); } PartResourceDefinition definition = ResourceHelper.DefinitionForResource(upgradeResource); double resourcePaid = FlightGlobals.ActiveVessel.rootPart.RequestResource(definition.id, upgradeCost, ResourceFlowMode.ALL_VESSEL);; //Could we afford it? if (Math.Abs(resourcePaid) / Math.Abs(upgradeCost) < 0.999f) { //Put back what we took this.part.RequestResource(definition.id, -resourcePaid, ResourceFlowMode.ALL_VESSEL); return(false); } return(true); }
protected virtual void prepareOutputs() { Log("prepareOutputs called"); PartResourceDefinition inputDef = null; //Get the input mass from the list of inputs. Ignore ElectricCharge. foreach (ResourceRatio input in inputList) { if (input.ResourceName != "ElectricCharge") { inputDef = ResourceHelper.DefinitionForResource(input.ResourceName); inputMass += (float)input.Ratio * inputDef.density; inputSources += input.ResourceName + ";"; } } if (!string.IsNullOrEmpty(byproduct)) { byproductDef = ResourceHelper.DefinitionForResource(byproduct); byproductMass = inputMass * (byproductMinPercent / 100.0f); yieldMass = inputMass - byproductMass; } else { yieldMass = inputMass; } Log("inputMass: " + inputMass); Log("byproductMass: " + byproductMass); Log("yieldMass: " + yieldMass); outputList.Clear(); prepareOutputsByLocale(); }
public override void OnStart(StartState state) { base.OnStart(state); if (HighLogic.LoadedSceneIsFlight == false) { return; } //Get the density of the input resource PartResourceDefinition inputDef = ResourceHelper.DefinitionForResource(inputResource); if (inputDef != null) { inputResourceDensity = inputDef.density; } //Get the units of the input resource foreach (ResourceRatio ratio in inputList) { if (ratio.ResourceName == inputResource) { inputResourceUnits = ratio.Ratio; break; } } debugLog("inputResourceDensity: " + inputResourceDensity); debugLog("inputResourceUnits: " + inputResourceUnits); //Get the asteroid if any asteroid = this.part.vessel.FindPartModuleImplementing <ModuleAsteroid>(); updateNearestLode(); updateLastLocation(); }
protected override bool payPartsCost(int templateIndex) { if (HighLogic.LoadedSceneIsFlight == false) { return(true); } if (!WBIMainSettings.PayToReconfigure) { return(true); } if (reconfigureCost == 0f) { return(true); } if (!templateManager[templateIndex].HasValue(kRequiredResourceField)) { return(true); } float remodelCost = calculateRemodelCost(templateIndex); string resourceName = templateManager[templateIndex].GetValue(kRequiredResourceField); PartResourceDefinition definition = ResourceHelper.DefinitionForResource(resourceName); double partsPaid = this.part.RequestResource(definition.id, remodelCost, ResourceFlowMode.ALL_VESSEL); //Could we afford it? if (Math.Abs(partsPaid) / Math.Abs(reconfigureCost) < 0.999f) { //Put back what we took this.part.RequestResource(definition.id, -partsPaid, ResourceFlowMode.ALL_VESSEL); return(false); } return(true); }
public virtual void SetupLiftGas() { PartResourceDefinition definition = ResourceHelper.DefinitionForResource(liftGasResource); float tonnesPerLiter = definition.density / definition.volume; liftGasDensityKgCubicMeters = liftGasDensity * 1000000; }
protected float calculateRepairCost() { if (this.part.vessel == null) { return(-1.0f); } float repairUnits = repairAmount; double totalResources = ResourceHelper.GetTotalResourceAmount(repairResource, this.part.vessel); //Anybody can repair the scope, but the right skill can reduce the cost by as much as 60% ProtoCrewMember astronaut = FlightGlobals.ActiveVessel.GetVesselCrew()[0]; if (astronaut.HasEffect(repairSkill)) { repairUnits = repairUnits * (0.9f - (astronaut.experienceTrait.CrewMemberExperienceLevel() * 0.1f)); } //Now make sure the kerbal has enough resources to conduct repairs. //Get the resource definition PartResourceDefinition definition = ResourceHelper.DefinitionForResource(repairResource); if (definition == null) { return(-1.0f); } //make sure the ship has enough of the resource if (totalResources < repairUnits) { return(-1.0f); } return(repairUnits); }
public void DrawView() { int buttonIndex; PartResourceDefinition definition; GUILayout.BeginVertical(); if (distributionMap == null) { GUILayout.Label("WARNING! distributionMap is null!"); GUILayout.EndVertical(); return; } if (scrollStyle == null) { scrollStyle = new GUIStyle(GUI.skin.textArea); } GUILayout.BeginScrollView(scrollPanePos, scrollStyle, scrollOptions); //Do we participate? isParticipating = GUILayout.Toggle(isParticipating, "Participate in resource distribution"); //Do we share? isSharingWithVessel = GUILayout.Toggle(isSharingWithVessel, "Share resources with vessel"); //Participation level of individual resources scrollPos = GUILayout.BeginScrollView(scrollPos); string[] resourceKeys = distributionMap.Keys.ToArray <string>(); string key; for (int index = 0; index < resourceKeys.Length; index++) { key = resourceKeys[index]; definition = ResourceHelper.DefinitionForResource(key); if (distributionMap[key] != EDistributionModes.DistributionModeRequired) { GUILayout.BeginHorizontal(); buttonIndex = (int)distributionMap[key]; buttonIndex = GUILayout.SelectionGrid(buttonIndex, distributeOptions, distributeOptions.Length, gridOptions); distributionMap[key] = (EDistributionModes)buttonIndex; if (!string.IsNullOrEmpty(definition.displayName)) { GUILayout.Label("<color=white>" + definition.displayName + "</color>"); } else { GUILayout.Label("<color=white>" + key + "</color>"); } GUILayout.EndHorizontal(); } } GUILayout.EndScrollView(); GUILayout.EndScrollView(); GUILayout.EndVertical(); }
protected override bool canAffordReconfigure(string templateName, bool deflatedModulesAutoPass = true) { if (HighLogic.LoadedSceneIsFlight == false) { return(true); } if (!WBIMainSettings.PayToReconfigure) { return(true); } if (isInflatable && !isDeployed && deflatedModulesAutoPass) { return(true); } //Build the input list buildInputList(templateName); int totalKeys = inputList.Keys.Count; if (totalKeys == 0) { reconfigureCost = 0f; Log("canAffordReconfigure: no resources so we can afford it."); return(true); } //Go through the input list and see if we can affort the resources double currentAmount, maxAmount; string resourceName; string[] keys = inputList.Keys.ToArray(); PartResourceDefinition resourceDefiniton; for (int index = 0; index < totalKeys; index++) { resourceName = keys[index]; resourceDefiniton = ResourceHelper.DefinitionForResource(resourceName); this.part.vessel.resourcePartSet.GetConnectedResourceTotals(resourceDefiniton.id, out currentAmount, out maxAmount, true); if (currentAmount < inputList[resourceName]) { if (showInsufficientResourcesMsg) { string notEnoughPartsMsg = string.Format(kInsufficientParts, inputList[resourceName], resourceName); ScreenMessages.PostScreenMessage(notEnoughPartsMsg, 5.0f, ScreenMessageStyle.UPPER_CENTER); } return(false); } } Log("We can afford the reconfigure."); return(true); }
protected virtual void harvestCrops(float harvestAmount) { PartResourceDefinition definition; definition = ResourceHelper.DefinitionForResource(cropResource); if (definition == null) { Log("No definition for " + cropResource); return; } this.part.RequestResource(definition.id, -harvestAmount, ResourceFlowMode.ALL_VESSEL); }
public void ScrapPartEVA() { //Make sure that there are no kerbals on the part. if (this.part.protoModuleCrew.Count > 0) { ScreenMessages.PostScreenMessage(kPartIsOccupied, kMessageDuration, ScreenMessageStyle.UPPER_CENTER); } //Check for confirmation if (PathfinderSettings.ConfirmScrap && !scrapConfirmed) { scrapConfirmed = true; ScreenMessages.PostScreenMessage(kConfirmScrap, kMessageDuration, ScreenMessageStyle.UPPER_CENTER); return; } scrapConfirmed = false; if (FlightGlobals.ActiveVessel.isEVA) { Vessel vessel = FlightGlobals.ActiveVessel; ProtoCrewMember astronaut = vessel.GetVesselCrew()[0]; //Check for skill & experience. if (astronaut.HasEffect(scrapSkill) == false) { ScreenMessages.PostScreenMessage(string.Format(kInsufficientSkill, Utils.GetTraitsWithEffect(scrapSkill)), kMessageDuration, ScreenMessageStyle.UPPER_CENTER); return; } if (Utils.IsExperienceEnabled()) { //Check for experience level if (astronaut.experienceLevel < minimumPartRecycleSkill) { ScreenMessages.PostScreenMessage(string.Format(kInsufficientExperiencePart, minimumPartRecycleSkill), kMessageDuration, ScreenMessageStyle.UPPER_CENTER); return; } } //Ok, we're good to go, get the resource definition for the recycleResource. PartResourceDefinition def = ResourceHelper.DefinitionForResource(recycleResource); if (def == null) { Debug.Log("[WBIPartScrapper] - Definition not found for " + recycleResource); return; } //Recycle the part and its resources recyclePart(this.part, def, astronaut); } }
protected void reconfigureDrill() { //If required, make sure we have the proper skill if (WBIMainSettings.RequiresSkillCheck) { if (FlightGlobals.ActiveVessel.isEVA && Utils.IsExperienceEnabled()) { Vessel vessel = FlightGlobals.ActiveVessel; ProtoCrewMember astronaut = vessel.GetVesselCrew()[0]; if (astronaut.HasEffect(requiredSkill)) { ScreenMessages.PostScreenMessage(string.Format(kInsufficientSkill, requiredSkill), 5.0f, ScreenMessageStyle.UPPER_CENTER); return; } } } //If needed, pay the cost to reconfigure if (WBIMainSettings.PayToReconfigure) { //Make sure we can afford it PartResourceDefinition definition = ResourceHelper.DefinitionForResource(requiredResource); //Pay for the reconfiguration cost. double partsPaid = this.part.RequestResource(definition.id, reconfigureCost, ResourceFlowMode.ALL_VESSEL); //Could we afford it? if (Math.Abs(partsPaid) / Math.Abs(reconfigureCost) < 0.999f) { ScreenMessages.PostScreenMessage(string.Format(insufficientResourcesMsg, reconfigureCost, requiredResource), 6.0f, ScreenMessageStyle.UPPER_CENTER); //Put back what we took this.part.RequestResource(definition.id, -partsPaid, ResourceFlowMode.ALL_VESSEL); return; } } //Now reconfigure the drill. ModuleResourceHarvester drill; string resourceName; for (int drillIndex = 0; drillIndex < groundDrills.Count; drillIndex++) { drill = groundDrills[drillIndex]; resourceName = resourceList[groundDrillResourceIndexes[drillIndex]]; setupDrillGUI(drill, resourceName); } ScreenMessages.PostScreenMessage(kDrillReconfigured, 5.0f, ScreenMessageStyle.UPPER_CENTER); }
protected override bool payPartsCost(int templateIndex, bool deflatedModulesAutoPass = true) { if (HighLogic.LoadedSceneIsFlight == false) { return(true); } if (!WBIMainSettings.PayToReconfigure) { return(true); } if (inputList.Keys.Count == 0) { Log("No resources to pay"); return(true); } if (isInflatable && !isDeployed && deflatedModulesAutoPass) { return(true); } //Double check that we have enough resources string[] keys = inputList.Keys.ToArray(); string resourceName; double currentAmount, maxAmount; PartResourceDefinition resourceDefiniton; for (int index = 0; index < keys.Length; index++) { resourceName = keys[index]; resourceDefiniton = ResourceHelper.DefinitionForResource(resourceName); this.part.vessel.resourcePartSet.GetConnectedResourceTotals(resourceDefiniton.id, out currentAmount, out maxAmount, true); if (currentAmount < inputList[resourceName]) { Log("Not enough " + resourceName); return(false); } } //Now pay the cost. for (int index = 0; index < keys.Length; index++) { resourceName = keys[index]; this.part.RequestResource(resourceName, inputList[resourceName]); Log("Paid " + inputList[resourceName] + " units of " + resourceName); } return(true); }
protected void setupRecycleResource() { if (usePrimaryResource) { recycleResource = primaryRecycleResource; } else { recycleResource = secondaryRecyceResource; } def = ResourceHelper.DefinitionForResource(recycleResource); recycleMode = def.displayName; }
protected bool payPartsCost() { double amount = resourceCost * (1.0 - reconfigureCostModifier); PartResourceDefinition definition = ResourceHelper.DefinitionForResource(resourceRequired); double partsPaid = this.part.RequestResource(definition.id, amount, ResourceFlowMode.ALL_VESSEL); //Could we afford it? if (Math.Abs(partsPaid) / Math.Abs(amount) < 0.999f) { //Put back what we took this.part.RequestResource(definition.id, -partsPaid, ResourceFlowMode.ALL_VESSEL); return(false); } return(true); }
protected void rebuildAbundanceSummary() { Log("rebuildAbundanceSummary called"); PartResourceDefinition resourceDef = null; float abundance = 0f; if (this.part.vessel.situation == Vessel.Situations.LANDED || this.part.vessel.situation == Vessel.Situations.SPLASHED || this.part.vessel.situation == Vessel.Situations.PRELAUNCH) { currentBiome = Utils.GetCurrentBiome(this.part.vessel).name; } if (!ResourceMap.Instance.IsPlanetScanned(this.part.vessel.mainBody.flightGlobalsIndex) && !ResourceMap.Instance.IsBiomeUnlocked(this.part.vessel.mainBody.flightGlobalsIndex, currentBiome)) { Log("Planet not scanned or biome still locked. Exiting"); return; } abundanceSummary.Clear(); abundanceCache = ResourceCache.Instance.AbundanceCache. Where(a => a.HarvestType == HarvestTypes.Planetary && a.BodyId == this.part.vessel.mainBody.flightGlobalsIndex && a.BiomeName == currentBiome); foreach (ResourceCache.AbundanceSummary summary in abundanceCache) { Log("Getting abundance for " + summary.ResourceName); resourceDef = ResourceHelper.DefinitionForResource(summary.ResourceName); if (resourceDef == null) { continue; } abundance = ResourceMap.Instance.GetAbundance(new AbundanceRequest() { Altitude = this.vessel.altitude, BodyId = FlightGlobals.currentMainBody.flightGlobalsIndex, CheckForLock = true, Latitude = this.vessel.latitude, Longitude = this.vessel.longitude, ResourceType = HarvestTypes.Planetary, ResourceName = summary.ResourceName }); abundanceSummary.Add(resourceDef.displayName, abundance); Log("Added abundance for " + summary.ResourceName + ": " + abundance); } Log("Found abundances for " + abundanceSummary.Keys.Count + " resources"); }
protected bool canAffordReconfigure() { if (HighLogic.LoadedSceneIsFlight == false) { return(true); } if (!payForReconfigure) { return(true); } bool canAffordCost = false; string notEnoughPartsMsg; PartResourceDefinition definition = ResourceHelper.DefinitionForResource(resourceRequired); Vessel.ActiveResource resource = this.part.vessel.GetActiveResource(definition); calculateRemodelCostModifier(); double amount = resourceCost * (1.0 - reconfigureCostModifier); //An inflatable part that hasn't been inflated yet is an automatic pass. if (switcher.isInflatable && !switcher.isDeployed) { return(true); } //now check to make sure the vessel has enough parts. if (resource == null) { canAffordCost = false; } else if (resource.amount < amount) { canAffordCost = false; } if (!canAffordCost) { notEnoughPartsMsg = string.Format(kInsufficientParts, amount, resourceRequired); ScreenMessages.PostScreenMessage(notEnoughPartsMsg, 5.0f, ScreenMessageStyle.UPPER_CENTER); return(false); } return(true); }
public bool UpdateLode() { if (HighLogic.LoadedSceneIsFlight == false) { return(false); } //If we aren't landed then we're done. if (this.part.vessel.situation != Vessel.Situations.PRELAUNCH && this.part.vessel.situation != Vessel.Situations.LANDED) { //Inform player lodeStatus = Localizer.Format(statusNoNearbyName); return(false); } //Find the nearest node findNearestLode(); if (nearestLode == null) { //Inform player lodeStatus = Localizer.Format(statusNoNearbyName); return(false); } //Check units remaining if (nearestLode.amountRemaining == 0) { //Inform player debugLog("Converter stopped. Lode is depleted."); ScreenMessages.PostScreenMessage(string.Format(depletedMessage, nearestLode.resourceName), kMessageDisplayTime, ScreenMessageStyle.UPPER_CENTER); return(false); } //Ok, we've got a valid lode, we're in harvest range, there are units remaining, it's dark, and we're wearing sunglasses. //Hit it! //Find the resource definition for the output resource outputDef = ResourceHelper.DefinitionForResource(nearestLode.resourceName); if (outputDef == null) { debugLog("No definition for " + nearestLode.resourceName); StopResourceConverter(); return(false); } return(true); }
public virtual bool canAffordResource(string resourceName, double resourceCost, bool deflatedModulesAutoPass = true) { PartResourceDefinition resourceDefiniton; double currentAmount, maxAmount; if (isInflatable && !isDeployed && deflatedModulesAutoPass) { return(true); } resourceDefiniton = ResourceHelper.DefinitionForResource(resourceName); this.part.vessel.resourcePartSet.GetConnectedResourceTotals(resourceDefiniton.id, out currentAmount, out maxAmount, true); if (currentAmount >= resourceCost) { return(true); } else { return(false); } }
protected float calculateRepairCost() { float repairUnits = repairAmount; if (FlightGlobals.ActiveVessel.isEVA == false) { return(-1.0f); //Should not get to here as the event is set up for EVA only. } //Anybody can repair the scope, but the right skill can reduce the cost by as much as 60% Experience.ExperienceTrait experience = FlightGlobals.ActiveVessel.GetVesselCrew()[0].experienceTrait; if (experience.TypeName == repairSkill) { repairUnits = repairUnits * (0.9f - (experience.CrewMemberExperienceLevel() * 0.1f)); } //Now make sure the kerbal has enough resources to conduct repairs. //Get the resource definition PartResourceDefinition definition = ResourceHelper.DefinitionForResource(repairResource); if (definition == null) { return(-1.0f); } //make sure the ship has enough of the resource Vessel.ActiveResource activeResource = FlightGlobals.ActiveVessel.GetActiveResource(definition); if (activeResource == null) { return(-1.0f); } if (activeResource.amount < repairUnits) { return(-1.0f); } return(repairUnits); }
public string GetMissingRequiredResource() { PartResourceDefinition definition; Dictionary <string, PartResource> resourceMap = new Dictionary <string, PartResource>(); foreach (PartResource res in this.part.Resources) { resourceMap.Add(res.resourceName, res); } //If we have required resources, make sure we have them. if (reqList.Count > 0) { foreach (ResourceRatio resRatio in reqList) { //Do we have a definition? definition = ResourceHelper.DefinitionForResource(resRatio.ResourceName); if (definition == null) { return(resRatio.ResourceName); } //Do we have the resource aboard? if (resourceMap.ContainsKey(resRatio.ResourceName) == false) { return(resRatio.ResourceName); } //Do we have enough? if (resourceMap[resRatio.ResourceName].amount < resRatio.Ratio) { return(resRatio.ResourceName); } } } return(null); }
protected override bool payPartsCost() { if (HighLogic.LoadedSceneIsFlight == false) { return(true); } if (!payForReconfigure) { return(true); } PartResourceDefinition definition = ResourceHelper.DefinitionForResource("RocketParts"); double partsPaid = this.part.RequestResource(definition.id, reconfigureCost, ResourceFlowMode.ALL_VESSEL); //Could we afford it? if (Math.Abs(partsPaid) / Math.Abs(reconfigureCost) < 0.999f) { //Put back what we took this.part.RequestResource(definition.id, -partsPaid, ResourceFlowMode.ALL_VESSEL); return(false); } return(true); }
public void SetupIntake() { ModuleResourceIntake intake = this.part.FindModuleImplementing <ModuleResourceIntake>(); if (intake == null) { return; } PartResourceDefinitionList definitions = PartResourceLibrary.Instance.resourceDefinitions; PartResourceDefinition resourceDef = null; PartResource resource = null; string resourceName = ""; bool checkForOxygen = false; if (multiModeEngine.runningPrimary) { resourceName = primaryEngineIntake; resourceDef = ResourceHelper.DefinitionForResource(resourceName); resource = this.part.Resources[resourceDef.name]; checkForOxygen = primaryCheckForOxygen; } else { resourceName = secondaryEngineIntake; resourceDef = ResourceHelper.DefinitionForResource(resourceName); resource = this.part.Resources[resourceDef.name]; checkForOxygen = secondaryCheckForOxygen; } //Change the resource to intake intake.resourceName = resourceName; intake.resourceDef = resourceDef; intake.resourceId = resourceDef.id; intake.res = resource; intake.checkForOxygen = checkForOxygen; }
protected virtual void updatePartMass() { if (CurrentTemplate.HasValue("mass")) { partMass = float.Parse(CurrentTemplate.GetValue("mass")); } else { PartResourceDefinition definition; buildInputList(CurrentTemplateName); string[] keys = inputList.Keys.ToArray(); string resourceName; partMass = 0; for (int index = 0; index < keys.Length; index++) { resourceName = keys[index]; definition = ResourceHelper.DefinitionForResource(resourceName); partMass += definition.density * (float)inputList[resourceName]; } } }
protected override bool canAffordReconfigure(string templateName) { if (HighLogic.LoadedSceneIsFlight == false) { return(true); } if (!payForReconfigure) { return(true); } string value; bool canAffordCost = false; requriredResource = templatesModel[templateName].GetValue("rocketParts"); if (string.IsNullOrEmpty(requriredResource) == false) { float reconfigureAmount = float.Parse(requriredResource); PartResourceDefinition definition = ResourceHelper.DefinitionForResource("RocketParts"); Vessel.ActiveResource resource = this.part.vessel.GetActiveResource(definition); //An inflatable part that hasn't been inflated yet is an automatic pass. if (isInflatable && !isDeployed) { return(true); } //Get the current template's rocket part cost. value = CurrentTemplate.GetValue("rocketParts"); if (string.IsNullOrEmpty(value) == false) { float recycleAmount = float.Parse(value); //calculate the amount of parts that we can recycle. recycleAmount *= calculateRecycleAmount(); //Now recalculate rocketPartCost, accounting for the parts we can recycle. //A negative value means we'll get parts back, a positive number means we pay additional parts. //Ex: current configuration takes 1200 parts. new configuration takes 900. //We recycle 90% of the current configuration (1080 parts). //The reconfigure cost is: 900 - 1080 = -180 parts //If we reverse the numbers so new configuration takes 1200: 1200 - (900 * .9) = 390 reconfigureCost = reconfigureAmount - recycleAmount; } //now check to make sure the vessel has enough parts. if (resource == null) { canAffordCost = false; } else if (resource.amount < reconfigureCost) { canAffordCost = false; } else { canAffordCost = true; } } if (!canAffordCost) { string notEnoughPartsMsg = string.Format(kInsufficientParts, reconfigureCost, "RocketParts"); ScreenMessages.PostScreenMessage(notEnoughPartsMsg, 5.0f, ScreenMessageStyle.UPPER_CENTER); return(false); } return(true); }
protected override ConversionRecipe PrepareRecipe(double deltatime) { PartResourceDefinition outputDef = null; double flowRate = 1.0f; string flowRateString = string.Empty; //If the converter isn't running then we're done. if (IsActivated == false) { return(base.PrepareRecipe(deltatime)); } //If our situation isn't valid then we're done. if (!situationIsValid()) { return(base.PrepareRecipe(deltatime)); } //Ok, we've got a valid lode, we're in harvest range, and there are units remaining. //Find the resource definition for the output resource outputDef = ResourceHelper.DefinitionForResource(nearestLode.resourceName); if (outputDef == null) { debugLog("No definition for " + nearestLode.resourceName); ScreenMessages.PostScreenMessage("Can't find a definition for " + nearestLode.resourceName, kMessageDisplayTime, ScreenMessageStyle.UPPER_CENTER); StopResourceConverter(); return(base.PrepareRecipe(deltatime)); } //Get the input resource flow rate. if (asteroid == null) //Use planetary drill { //Good going SQUAD, how about making _resFlow public??? if (string.IsNullOrEmpty(harvester.ResourceStatus) == false) { flowRateString = harvester.ResourceStatus.Substring(0, harvester.ResourceStatus.IndexOf("/ sec")); double.TryParse(flowRateString, out flowRate); } } //Output units per second is the ratio of the input to output density, multiplied by the drill's flow rate. outputUnits = (inputResourceDensity / outputDef.density) * flowRate; //The output list is in terms of units per second. We need units per time tick for the hack to work. outputUnits *= deltatime; //Keep track of how many units we've dug up. //If the amount remaining < outputUnits then adjust accordingly. if (nearestLode.amountRemaining > outputUnits) { nearestLode.amountRemaining -= outputUnits; } else { outputUnits = nearestLode.amountRemaining; nearestLode.amountRemaining = 0f; } //Update GUI lodeUnitsRemaining = nearestLode.amountRemaining; // debugLog("nearestLode.amountRemaining: " + nearestLode.amountRemaining); // debugLog("status: " + status); // debugLog("statusPercent: " + statusPercent); // debugLog("outputUnits: " + outputUnits); /* * HACK! Technically, I can add the output source to the output list and the converter will do its thing- unless the output is pretty small. * Thanks to the crappy documentation by SQUAD, I can't figure out why the small numbers of the output ratio don't seen to actually output the desired resource. * So, what we'll do is simply let the converter consume the Ore per time tick, and manually add the desired resource throughout the vessel. * ResourceRatio outputSource = new ResourceRatio { ResourceName = nearestLode.resourceName, Ratio = outputUnits, FlowMode = ResourceFlowMode.ALL_VESSEL_BALANCE, DumpExcess = false }; * outputList.Clear(); * outputList.Add(outputSource); * outputUnits = 0f; */ //The converter is set up to just consume Ore. Manually create the output resource, with the units already accounting for conservation of mass. this.part.RequestResource(nearestLode.resourceName, -outputUnits, ResourceFlowMode.ALL_VESSEL_BALANCE); return(base.PrepareRecipe(deltatime)); }
protected void rebuildResourceRatios() { PartResourceDefinition resourceDef = null; float abundance = 0f; float harvestEfficiency; ResourceRatio ratio; if (!ResourceMap.Instance.IsPlanetScanned(this.part.vessel.mainBody.flightGlobalsIndex) && !ResourceMap.Instance.IsBiomeUnlocked(this.part.vessel.mainBody.flightGlobalsIndex, currentBiome)) { return; } abundanceCache = Utils.GetAbundances(this.part.vessel, currentHarvestType); debugLog("Rebuilding resource ratios... "); debugLog("abundanceCache count: " + abundanceCache.ToArray().Length); resourceRatios.Clear(); this.recipe.Outputs.Clear(); foreach (ResourceCache.AbundanceSummary summary in abundanceCache) { //Get the resource definition debugLog("Getting abundance for " + summary.ResourceName); resourceDef = ResourceHelper.DefinitionForResource(summary.ResourceName); if (resourceDef == null) { debugLog("No definition found!"); continue; } //Get the abundance abundance = ResourceMap.Instance.GetAbundance(new AbundanceRequest() { Altitude = this.vessel.altitude, BodyId = FlightGlobals.currentMainBody.flightGlobalsIndex, CheckForLock = true, Latitude = this.vessel.latitude, Longitude = this.vessel.longitude, ResourceType = currentHarvestType, ResourceName = summary.ResourceName }); if (abundance < HarvestThreshold || abundance < 0.001f) { debugLog("Abundance is below HarvestThreshold or minimum abundance (0.001)"); continue; } //Now determine the harvest efficiency harvestEfficiency = abundance * Efficiency; //Setup the resource ratio ratio = new ResourceRatio(); ratio.ResourceName = summary.ResourceName; ratio.Ratio = harvestEfficiency; ratio.DumpExcess = true; ratio.FlowMode = ResourceFlowMode.NULL; resourceRatios.Add(ratio); debugLog("Added resource ratio for " + summary.ResourceName + " abundance: " + abundance); } debugLog("Found abundances for " + resourceRatios.Count + " resources"); }
protected override void prepareOutputsByLocale() { ResourceRatio outputSource; PartResourceDefinition outputDef = null; float totalAbundance = 0f; float abundance = 0f; float outputMass = 0f; float outputUnits = 0f; //Get the asteroid to process findSourceAsteroid(); if (this.asteroid == null) { return; } //Get the resources List <ModuleAsteroidResource> asteroidResources = this.asteroid.part.FindModulesImplementing <ModuleAsteroidResource>(); foreach (ModuleAsteroidResource summary in asteroidResources) { outputDef = ResourceHelper.DefinitionForResource(summary.resourceName); abundance = summary.abundance; outputMass = abundance * yieldMass; outputUnits = outputMass / outputDef.density; //If the resource is an input resource then add its output mass to the byproductMass. if (inputSources.Contains(summary.resourceName)) { byproductMass += outputMass; } //If the resource is on our ignore list, then add the output mass to the byproductMass. else if (!string.IsNullOrEmpty(ignoreResources) && ignoreResources.Contains(summary.resourceName)) { byproductMass += outputMass; } //Legit! else if (summary.abundance > 0.001f) { totalAbundance += abundance; // Debug.Log("FRED " + summary.ResourceName + " abundance: " + abundance + " Ratio: " + outputUnits); outputSource = new ResourceRatio { ResourceName = summary.resourceName, Ratio = outputUnits, FlowMode = ResourceFlowMode.ALL_VESSEL_BALANCE, DumpExcess = true }; outputList.Add(outputSource); } } //Leftovers byproductMass += (1.0f - totalAbundance) * yieldMass; outputUnits = byproductMass / byproductDef.density; outputSource = new ResourceRatio { ResourceName = byproduct, Ratio = outputUnits, FlowMode = ResourceFlowMode.ALL_VESSEL_BALANCE, DumpExcess = true }; outputList.Add(outputSource); Log("totalAbundance: " + totalAbundance); Log("Byproduct Units: " + outputUnits); }
public void ScrapVessel() { //Make sure the vessel isn't occupied. if (this.part.vessel.GetCrewCount() > 0) { ScreenMessages.PostScreenMessage(kVesselIsOccupied, kMessageDuration, ScreenMessageStyle.UPPER_CENTER); return; } //Check for confirmation if (PathfinderSettings.ConfirmScrap && !scrapConfirmed) { scrapConfirmed = true; ScreenMessages.PostScreenMessage(kConfirmScrap, kMessageDuration, ScreenMessageStyle.UPPER_CENTER); return; } scrapConfirmed = false; if (FlightGlobals.ActiveVessel.isEVA) { Vessel vessel = FlightGlobals.ActiveVessel; ProtoCrewMember astronaut = vessel.GetVesselCrew()[0]; //Check for skill & experience. if (astronaut.HasEffect(scrapSkill) == false) { ScreenMessages.PostScreenMessage(string.Format(kInsufficientSkill, Utils.GetTraitsWithEffect(scrapSkill)), kMessageDuration, ScreenMessageStyle.UPPER_CENTER); return; } if (Utils.IsExperienceEnabled()) { //Check for experience level if (astronaut.experienceLevel < minimumVesselRecycleSkill) { ScreenMessages.PostScreenMessage(string.Format(kInsufficientExperienceVessel, minimumVesselRecycleSkill), kMessageDuration, ScreenMessageStyle.UPPER_CENTER); return; } } //Ok, we're good to go, get the resource definition for the recycleResource. PartResourceDefinition def = ResourceHelper.DefinitionForResource(recycleResource); if (def == null) { Debug.Log("[WBIPartScrapper] - Definition not found for " + recycleResource); return; } //Recycle all parts in the vessel. List <Part> doomedParts = new List <Part>(); foreach (Part doomed in this.part.vessel.parts) { if (doomed != this.part) { doomedParts.Add(doomed); } } foreach (Part doomed in doomedParts) { recyclePart(doomed, def, astronaut); } //Final recycle recyclePart(this.part, def, astronaut); } }
protected virtual void prepareOutputsByLocale(HarvestTypes harvestType) { Log("prepareOutputsByLocale called for harvestType: " + harvestType.ToString()); ResourceRatio outputSource; PartResourceDefinition outputDef = null; float totalAbundance = 0f; float abundance = 0f; float outputMass = 0f; float outputUnits = 0f; IEnumerable <ResourceCache.AbundanceSummary> abundanceCache; if (harvestType == HarvestTypes.Planetary) { if (!ResourceMap.Instance.IsPlanetScanned(this.part.vessel.mainBody.flightGlobalsIndex) && !ResourceMap.Instance.IsBiomeUnlocked(this.part.vessel.mainBody.flightGlobalsIndex, currentBiome)) { return; } abundanceCache = Utils.GetAbundances(this.part.vessel, harvestType); } else { abundanceCache = Utils.GetAbundances(this.part.vessel, harvestType); } foreach (ResourceCache.AbundanceSummary summary in abundanceCache) { Log("checking " + summary.ResourceName); outputDef = ResourceHelper.DefinitionForResource(summary.ResourceName); if (outputDef == null) { continue; } abundance = ResourceMap.Instance.GetAbundance(new AbundanceRequest() { Altitude = this.vessel.altitude, BodyId = FlightGlobals.currentMainBody.flightGlobalsIndex, CheckForLock = true, Latitude = this.vessel.latitude, Longitude = this.vessel.longitude, ResourceType = harvestType, ResourceName = summary.ResourceName }); outputMass = abundance * yieldMass; if (outputDef.density > 0) { outputUnits = outputMass / outputDef.density; } else { outputUnits = outputMass; } Log("abundance: " + abundance); Log("outputUnits: " + outputUnits); //If the resource is an input resource then add its output mass to the byproductMass. if (inputSources.Contains(summary.ResourceName)) { Log(summary.ResourceName + " added to byproductMass"); byproductMass += outputMass; } //If the resource is on our ignore list, then add the output mass to the byproductMass. else if (!string.IsNullOrEmpty(ignoreResources) && ignoreResources.Contains(summary.ResourceName)) { Log(summary.ResourceName + " ignored and added to byproductMass"); byproductMass += outputMass; } //Legit! else if (abundance > 0.0001f) { totalAbundance += abundance; Log(summary.ResourceName + " abundance: " + abundance + " Ratio: " + outputUnits); outputSource = new ResourceRatio { ResourceName = summary.ResourceName, Ratio = outputUnits, FlowMode = ResourceFlowMode.ALL_VESSEL_BALANCE, DumpExcess = true }; outputList.Add(outputSource); } } //Leftovers if (!string.IsNullOrEmpty(byproduct)) { byproductMass += (1.0f - totalAbundance) * yieldMass; outputUnits = byproductMass / byproductDef.density; outputSource = new ResourceRatio { ResourceName = byproduct, Ratio = outputUnits, FlowMode = ResourceFlowMode.ALL_VESSEL_BALANCE, DumpExcess = true }; outputList.Add(outputSource); Log("added " + byproduct + " to output list"); } Log("totalAbundance: " + totalAbundance); Log("Byproduct Units: " + outputUnits); Log("output resources added: " + outputList.Count); }
public void ScrapPart(Part doomedPart) { //Make sure that there are no kerbals on the part. if (doomedPart.protoModuleCrew.Count > 0) { ScreenMessages.PostScreenMessage(kPartIsOccupied, kMessageDuration, ScreenMessageStyle.UPPER_CENTER); return; } //Check for confirmation if (PathfinderSettings.ConfirmScrap && !scrapConfirmed) { scrapConfirmed = true; ScreenMessages.PostScreenMessage(kConfirmScrap, kMessageDuration, ScreenMessageStyle.UPPER_CENTER); return; } scrapConfirmed = false; //Check for skill & experience. List <ProtoCrewMember> crewMembers = this.part.vessel.GetVesselCrew(); bool hasSufficientSkill = false; bool hasSufficientExperience = false; ProtoCrewMember highestRankingAstronaut = null; foreach (ProtoCrewMember astronaut in crewMembers) { //Check skill if (astronaut.HasEffect(scrapSkill)) { hasSufficientSkill = true; } //Check for experience level if (Utils.IsExperienceEnabled()) { if (astronaut.experienceLevel >= minimumPartRecycleSkill) { hasSufficientExperience = true; if (highestRankingAstronaut == null) { highestRankingAstronaut = astronaut; } if (astronaut.experienceLevel > highestRankingAstronaut.experienceLevel) { highestRankingAstronaut = astronaut; } } } } if (!hasSufficientSkill) { ScreenMessages.PostScreenMessage(string.Format(kInsufficientSkill, Utils.GetTraitsWithEffect(scrapSkill)), kMessageDuration, ScreenMessageStyle.UPPER_CENTER); return; } if (!hasSufficientExperience) { ScreenMessages.PostScreenMessage(string.Format(kInsufficientExperiencePart, minimumPartRecycleSkill), kMessageDuration, ScreenMessageStyle.UPPER_CENTER); return; } //Ok, we're good to go, get the resource definition for the recycleResource. PartResourceDefinition def = ResourceHelper.DefinitionForResource(recycleResource); if (def == null) { Debug.Log("[WBIPartScrapper] - Definition not found for " + recycleResource); return; } //Recycle the part and its resources recyclePart(doomedPart, def, highestRankingAstronaut); }