public bool SituationIsValid() { debugLog("SituationIsValid: checking..."); GoldStrikeLode lode = null; //Do we have enough crew? if (minimumCrew > 0) { if (this.part.protoModuleCrew.Count < minimumCrew) { ScreenMessages.PostScreenMessage(this.part.partInfo.title + "Must be staffed with at least " + minimumCrew + " crewmembers.", kMessageDisplayTime, ScreenMessageStyle.UPPER_CENTER); status = Localizer.Format(statusInsufficientCrewName); return(false); } } //Can we prospect the location? switch (WBIGoldStrikeScenario.Instance.GetProspectSituation(this.part.vessel, out lode, out prospectResources)) { case ProspectSituations.NoResourcesToProspect: status = Localizer.Format(statusNoResources); ScreenMessages.PostScreenMessage("No resource lodes detected here. Try traveling further.", kMessageDisplayTime, ScreenMessageStyle.UPPER_CENTER); return(false); case ProspectSituations.InvalidVesselSituation: debugLog("Vessel situation not valid"); ScreenMessages.PostScreenMessage("Vessel must be landed, splashed, or in orbit/docked with an asteroid attached", kMessageDisplayTime, ScreenMessageStyle.UPPER_CENTER); status = Localizer.Format(statusNAName); return(false); case ProspectSituations.LodeAlreadyExists: if (lode != null) { debugLog("Situation not valid, existing lode found: " + lode.ToString()); string message = string.Format("You already found a vein of {0:s} at this location. It has {1:f2} units remaining.", lode.resourceName, lode.amountRemaining); ScreenMessages.PostScreenMessage(message, kMessageDisplayTime, ScreenMessageStyle.UPPER_CENTER); status = Localizer.Format(statusAlreadyProspectedName); } return(false); case ProspectSituations.AsteroidProspected: debugLog("Asteroid has already been prospected"); ScreenMessages.PostScreenMessage("Asteroid has already been prospected.", kMessageDisplayTime, ScreenMessageStyle.UPPER_CENTER); status = Localizer.Format(statusAlreadyProspectedName); if (!WBIGoldStrikeScenario.debugProspectAlwaysSuccessful) { return(false); } else { debugLog("Debug: Prospect is guaranteed"); return(true); } //A-OK default: status = Localizer.Format(statusReadyName); return(true); } }
protected void findNearestLode() { //Do we have an asteroid? asteroid = this.part.vessel.FindPartModuleImplementing <ModuleAsteroid>(); if (asteroid == null) { nearestLode = null; lodeStatus = Localizer.Format(statusNoNearbyName); lodeResourceName = "N/A"; debugLog("No lode found nearby because there's no captured asteroid."); return; } //Find the nearest lode (if any) debugLog("Looking for a prospect lode for asteroid " + asteroid.AsteroidName); nearestLode = WBIPathfinderScenario.Instance.FindNearestLode(asteroid); if (nearestLode != null) { lodeStatus = Localizer.Format(statusOKName); lodeResourceName = nearestLode.resourceName; lodeAbundance = nearestLode.abundance * 100.0f; debugLog("nearestLode: " + nearestLode.ToString()); } else { lodeStatus = Localizer.Format(statusNoNearbyName); lodeResourceName = "N/A"; debugLog("No lode found nearby."); } }
protected void findNearestLode() { int planetID; string biomeName; double longitude = 0f; double latitude = 0f; if (this.part.vessel.situation == Vessel.Situations.LANDED || this.part.vessel.situation == Vessel.Situations.PRELAUNCH) { longitude = this.part.vessel.longitude; latitude = this.part.vessel.latitude; //Find the nearest lode (if any) GoldStrikeUtils.GetBiomeAndPlanet(out biomeName, out planetID, this.part.vessel); nearestLode = WBIPathfinderScenario.Instance.FindNearestLode(planetID, biomeName, longitude, latitude, maxHarvestRange); if (nearestLode != null) { lodeStatus = Localizer.Format(statusOKName); lodeResourceName = nearestLode.resourceName; debugLog("nearestLode: " + nearestLode.ToString()); } else { lodeStatus = Localizer.Format(statusNoNearbyName); lodeResourceName = "N/A"; debugLog("No lode found nearby."); } } }
public GoldStrikeLode AddLode(int planetID, string biome, double longitude, double lattitude, double altitude, string resourceName, double amountRemaining) { GoldStrikeLode lode = new GoldStrikeLode(); Dictionary <string, GoldStrikeLode> lodeMap = null; string planetBiomeKey = planetID.ToString() + biome; string lodeKey = longitude.ToString() + lattitude.ToString() + resourceName; //Setup the new lode lode.resourceName = resourceName; lode.longitude = longitude; lode.lattitude = lattitude; lode.biome = biome; lode.amountRemaining = amountRemaining; lode.planetID = planetID; //Get the lode map if (goldStrikeLodes.ContainsKey(planetBiomeKey) == false) { lodeMap = new Dictionary <string, GoldStrikeLode>(); goldStrikeLodes.Add(planetBiomeKey, lodeMap); } lodeMap = goldStrikeLodes[planetBiomeKey]; //Add the new lode lodeMap.Add(lodeKey, lode); goldStrikeLodes[planetBiomeKey] = lodeMap; debugLog("Added new lode: " + lode.ToString()); //Save the game GamePersistence.SaveGame("quicksave", HighLogic.SaveFolder, SaveMode.BACKUP); return(lode); }
public bool IsLodeWaypoint(string navigationID) { Dictionary <string, GoldStrikeLode>[] lodeMaps = null; Dictionary <string, GoldStrikeLode> lodeMap = null; GoldStrikeLode[] lodes = null; GoldStrikeLode lode = null; lodeMaps = goldStrikeLodes.Values.ToArray(); for (int index = 0; index < lodeMaps.Length; index++) { lodeMap = lodeMaps[index]; lodes = lodeMap.Values.ToArray(); for (int lodeIndex = 0; lodeIndex < lodes.Length; lodeIndex++) { lode = lodes[lodeIndex]; if (string.IsNullOrEmpty(lode.navigationID)) { continue; } if (lode.navigationID == navigationID) { return(true); } } } return(false); }
public GoldStrikeLode FindNearestLode(int planetID, string biome, double longitude, double latitude, double altitude, double searchDistance = kMaxProspectSearchDistance) { string planetBiomeKey = planetID.ToString() + biome; Dictionary <string, GoldStrikeLode> lodeMap = null; //Get the lode map. If there is none then we're done. if (goldStrikeLodes.ContainsKey(planetBiomeKey) == false) { debugLog("no lodeMap found for key: " + planetBiomeKey); return(null); } lodeMap = goldStrikeLodes[planetBiomeKey]; //Now iterate through the dictionary to find the nearest lode. //We have a minimum cutoff distance GoldStrikeLode[] lodes = lodeMap.Values.ToArray <GoldStrikeLode>(); GoldStrikeLode lode, closestProspect = null; double distance, prevDistance; debugLog("lodes length: " + lodes.Length); prevDistance = double.MaxValue; for (int index = 0; index < lodes.Length; index++) { lode = lodes[index]; debugLog("checking lode: " + lode.ToString()); distance = Utils.HaversineDistance(longitude, latitude, lode.longitude, lode.lattitude, FlightGlobals.Bodies[lode.planetID]); debugLog("distance between current location and lode location: " + distance); if ((distance <= searchDistance) && (distance < prevDistance)) { debugLog("new closest lode: " + lode); closestProspect = lode; prevDistance = distance; } } if (closestProspect != null) { debugLog("closest lode found"); return(closestProspect); } else { debugLog("closest lode not found"); return(null); } }
public override void OnLoad(ConfigNode node) { ConfigNode[] goldStrikeNodes = GameDatabase.Instance.GetConfigNodes(kGoldStrikeDataNode); ConfigNode[] goldStrikeLodeNodes = node.GetNodes(kGoldStrikeLodeNode); ConfigNode[] asteroidsSearched = node.GetNodes(kAsteroidsSearched); debugLog("OnLoad: there are " + goldStrikeNodes.Length + " GOLDSTRIKE items to load."); foreach (ConfigNode goldStrikeDataNode in goldStrikeNodes) { GoldStrikeData strikeData = new GoldStrikeData(); strikeData.Load(goldStrikeDataNode); if (string.IsNullOrEmpty(strikeData.resourceName) == false) { goldStrikeResources.Add(strikeData.resourceName, strikeData); } } debugLog("OnLoad: there are " + goldStrikeLodeNodes.Length + " GoldStrikeLode items to load."); foreach (ConfigNode goldStrikeLodeNode in goldStrikeLodeNodes) { GoldStrikeLode lode = new GoldStrikeLode(); Dictionary <string, GoldStrikeLode> lodeMap = null; string planetBiomeKey, lodeKey; lode.Load(goldStrikeLodeNode); planetBiomeKey = lode.planetID.ToString() + lode.biome; if (goldStrikeLodes.ContainsKey(planetBiomeKey) == false) { lodeMap = new Dictionary <string, GoldStrikeLode>(); goldStrikeLodes.Add(planetBiomeKey, lodeMap); } lodeMap = goldStrikeLodes[planetBiomeKey]; //Add the new lode lodeKey = lode.longitude.ToString() + lode.lattitude.ToString() + lode.resourceName; lodeMap.Add(lodeKey, lode); } debugLog("OnLoad: there are " + asteroidsSearched.Length + " asteroids that have been prospected."); foreach (ConfigNode asteroidNode in asteroidsSearched) { prospectedAsteroids.Add(asteroidNode.GetValue(kName)); } }
protected string setWaypoint(string resourceName, GoldStrikeLode lode) { if (this.part.vessel.situation == Vessel.Situations.LANDED || this.part.vessel.situation == Vessel.Situations.PRELAUNCH) { debugLog("Trying to set waypoint"); string location = string.Format("Lon: {0:f2} Lat: {1:f2} Alt: {2:f2}", this.part.vessel.longitude, this.part.vessel.latitude, this.part.vessel.altitude); Waypoint waypoint = new Waypoint(); waypoint.name = resourceName + " Lode"; waypoint.isExplored = true; waypoint.isNavigatable = true; waypoint.isOnSurface = true; waypoint.celestialName = this.part.vessel.mainBody.name; waypoint.longitude = this.part.vessel.longitude; waypoint.latitude = this.part.vessel.latitude; waypoint.altitude = this.part.vessel.altitude; waypoint.seed = UnityEngine.Random.Range(0, int.MaxValue); waypoint.navigationId = Guid.NewGuid(); //Add the waypoint to the custom waypoint scenario ScenarioCustomWaypoints.AddWaypoint(waypoint); //Our icon is not correct, do a quick remove, reset the icon, and add WaypointManager.RemoveWaypoint(waypoint); waypoint.id = WBIGoldStrikeScenario.kLodeIcon; waypoint.nodeCaption1 = location; WaypointManager.AddWaypoint(waypoint); //Record the waypoint info lode.navigationID = waypoint.navigationId.ToString(); //Save the game GamePersistence.SaveGame("quicksave", HighLogic.SaveFolder, SaveMode.BACKUP); //Done return(waypoint.navigationId.ToString()); } return(string.Empty); }
public void SetupLodeIcons() { try { Dictionary <string, Dictionary <string, GoldStrikeLode> > goldStrikeLodes = WBIPathfinderScenario.Instance.goldStrikeLodes; Dictionary <string, GoldStrikeLode>[] lodeMaps = null; Dictionary <string, GoldStrikeLode> lodeMap = null; GoldStrikeLode[] lodes = null; GoldStrikeLode lode = null; Waypoint waypoint = null; string location = string.Empty; lodeMaps = goldStrikeLodes.Values.ToArray(); for (int index = 0; index < lodeMaps.Length; index++) { lodeMap = lodeMaps[index]; lodes = lodeMap.Values.ToArray(); for (int lodeIndex = 0; lodeIndex < lodes.Length; lodeIndex++) { lode = lodes[lodeIndex]; if (string.IsNullOrEmpty(lode.navigationID)) { continue; } waypoint = WaypointManager.FindWaypoint(new Guid(lode.navigationID)); location = string.Format("Lon: {0:f2} Lat: {1:f2}", waypoint.longitude, waypoint.latitude); if (waypoint != null) { WaypointManager.RemoveWaypoint(waypoint); waypoint.id = WBIPathfinderScenario.kLodeIcon; waypoint.nodeCaption1 = location; WaypointManager.AddWaypoint(waypoint); } } } } catch { } }
protected void updateNearestLode() { int planetID; string biomeName; double longitude = 0f; double latitude = 0f; if (this.part.vessel.situation == Vessel.Situations.LANDED || this.part.vessel.situation == Vessel.Situations.PRELAUNCH) { longitude = this.part.vessel.longitude; latitude = this.part.vessel.latitude; } //Find the nearest lode (if any) GoldStrikeUtils.GetBiomeAndPlanet(out biomeName, out planetID, this.part.vessel, asteroid); nearestLode = WBIPathfinderScenario.Instance.FindNearestLode(planetID, biomeName, longitude, latitude); if (nearestLode != null) { debugLog("nearestLode: " + nearestLode.ToString()); } }
public GoldStrikeLode AddLode(ModuleAsteroid asteroid, string resourceName, float abundance) { int planetID; string biomeName; GoldStrikeUtils.GetBiomeAndPlanet(out biomeName, out planetID, null, asteroid); GoldStrikeLode lode = new GoldStrikeLode(); Dictionary <string, GoldStrikeLode> lodeMap = null; string planetBiomeKey = planetID.ToString() + biomeName; //Setup the new lode lode.resourceName = resourceName; lode.longitude = 0; lode.lattitude = 0; lode.biome = biomeName; lode.abundance = abundance; lode.planetID = planetID; //Get the lode map if (goldStrikeLodes.ContainsKey(planetBiomeKey) == false) { lodeMap = new Dictionary <string, GoldStrikeLode>(); goldStrikeLodes.Add(planetBiomeKey, lodeMap); debugLog("Added new goldStrikeLode with planetBiomeKey: " + planetBiomeKey); } lodeMap = goldStrikeLodes[planetBiomeKey]; //Add the new lode lodeMap.Add(asteroid.AsteroidName, lode); goldStrikeLodes[planetBiomeKey] = lodeMap; debugLog("Added new lode: " + lode.ToString()); //Save the game GamePersistence.SaveGame("quicksave", HighLogic.SaveFolder, SaveMode.BACKUP); return(lode); }
protected void loadGoldStrokeLodes(ConfigNode[] goldStrikeLodeNodes) { debugLog("OnLoad: there are " + goldStrikeLodeNodes.Length + " GoldStrikeLode items to load."); foreach (ConfigNode goldStrikeLodeNode in goldStrikeLodeNodes) { GoldStrikeLode lode = new GoldStrikeLode(); Dictionary <string, GoldStrikeLode> lodeMap = null; string planetBiomeKey, lodeKey; lode.Load(goldStrikeLodeNode); planetBiomeKey = lode.planetID.ToString() + lode.biome; if (goldStrikeLodes.ContainsKey(planetBiomeKey) == false) { lodeMap = new Dictionary <string, GoldStrikeLode>(); goldStrikeLodes.Add(planetBiomeKey, lodeMap); } lodeMap = goldStrikeLodes[planetBiomeKey]; //Add the new lode lodeKey = lode.longitude.ToString() + lode.lattitude.ToString() + lode.resourceName; lodeMap.Add(lodeKey, lode); } }
public ProspectSituations GetProspectSituation(Vessel vessel, out GoldStrikeLode lode, out List <GoldStrikeData> prospectResources) { ModuleAsteroid asteroid = null; CBAttributeMapSO.MapAttribute biome = null; string biomeName = string.Empty; int planetID = int.MaxValue; bool vesselSituationIsValid = false; double longitude = 0f; double latitude = 0f; double altitude = 0f; //Initialize the list of resources to prospect. prospectResources = null; //If we're landed then we're ok to check prospect situation. if (VesselSituationValid(vessel)) { biome = Utils.GetCurrentBiome(vessel); biomeName = biome.name; planetID = vessel.mainBody.flightGlobalsIndex; longitude = vessel.longitude; latitude = vessel.latitude; altitude = vessel.altitude; vesselSituationIsValid = true; debugLog("Vessel is landed or prelaunch"); } //If we have an asteroid, then we're ok to check prospect situation. asteroid = vessel.FindPartModuleImplementing <ModuleAsteroid>(); if (asteroid != null) { biomeName = asteroid.AsteroidName; vesselSituationIsValid = true; debugLog("Vessel has an asteroid"); } //Is there a lode in the area? if (asteroid != null) { lode = FindNearestLode(asteroid); } else { lode = FindNearestLode(planetID, biomeName, vessel.longitude, vessel.latitude, vessel.altitude); } if (lode != null) { return(ProspectSituations.LodeAlreadyExists); } //If the flight situation is bad then we're done. if (vesselSituationIsValid == false) { return(ProspectSituations.InvalidVesselSituation); } //Is the prospect site an asteroid, and has it been prospected? if (asteroid != null) { if (prospectedAsteroids.Contains(asteroid.AsteroidName)) { return(ProspectSituations.AsteroidProspected); } else //Record the fact that we prospected the asteroid. { prospectedAsteroids.Add(asteroid.AsteroidName); } } //Do we have resources that can be prospected? else { double travelDistance = GetDistanceFromLastLocation(vessel); List <GoldStrikeData> resources = new List <GoldStrikeData>(); GoldStrikeData strikeData; int count = goldStrikeResources.Keys.Count; string[] keys = goldStrikeResources.Keys.ToArray(); string resourceName; for (int index = 0; index < count; index++) { resourceName = keys[index]; strikeData = goldStrikeResources[resourceName]; if (strikeData.MatchesProspectCriteria(vessel.situation, vessel.mainBody.name, biomeName, altitude, travelDistance)) { resources.Add(strikeData); } } //If we have no resources that meet the criteria then we're done. if (resources.Count == 0) { return(ProspectSituations.NoResourcesToProspect); } //Record the possible prospect resources. else { prospectResources = resources; } } return(ProspectSituations.Valid); }
public override void OnLoad(ConfigNode node) { base.OnLoad(node); ConfigNode[] efficiencyNodes = node.GetNodes(kEfficiencyData); ConfigNode[] toolTipsShown = node.GetNodes(kToolTip); ConfigNode[] goldStrikeNodes = GameDatabase.Instance.GetConfigNodes(kGoldStrikeDataNode); ConfigNode[] goldStrikeLodeNodes = node.GetNodes(kGoldStrikeLodeNode); ConfigNode[] strikeChances = node.GetNodes(kGoldStrikeChance); string value = node.GetValue(kReputationIndex); GoldStrikeChance chance = null; if (string.IsNullOrEmpty(value) == false) { reputationIndex = int.Parse(value); } debugLog("OnLoad: there are " + goldStrikeNodes.Length + " GOLDSTRIKE items to load."); foreach (ConfigNode goldStrikeDataNode in goldStrikeNodes) { GoldStrikeData strikeData = new GoldStrikeData(); strikeData.Load(goldStrikeDataNode); if (string.IsNullOrEmpty(strikeData.resourceName) == false) { goldStrikeResources.Add(strikeData.resourceName, strikeData); } } debugLog("OnLoad: there are " + goldStrikeLodeNodes.Length + " GoldStrikeLode items to load."); foreach (ConfigNode goldStrikeLodeNode in goldStrikeLodeNodes) { GoldStrikeLode lode = new GoldStrikeLode(); Dictionary <string, GoldStrikeLode> lodeMap = null; string planetBiomeKey, lodeKey; lode.Load(goldStrikeLodeNode); planetBiomeKey = lode.planetID.ToString() + lode.biome; if (goldStrikeLodes.ContainsKey(planetBiomeKey) == false) { lodeMap = new Dictionary <string, GoldStrikeLode>(); goldStrikeLodes.Add(planetBiomeKey, lodeMap); } lodeMap = goldStrikeLodes[planetBiomeKey]; //Add the new lode lodeKey = lode.longitude.ToString() + lode.lattitude.ToString() + lode.resourceName; lodeMap.Add(lodeKey, lode); } debugLog("OnLoad: there are " + strikeChances.Length + " GoldStrikeChance items to load."); foreach (ConfigNode chanceNode in strikeChances) { chance = new GoldStrikeChance(); chance.Load(chanceNode); string planetBiomeKey = chance.planetID.ToString() + chance.biome; goldStrikeChances.Add(planetBiomeKey, chance); } foreach (ConfigNode efficiencyNode in efficiencyNodes) { EfficiencyData efficiencyData = new EfficiencyData(); efficiencyData.Load(efficiencyNode); efficiencyDataMap.Add(efficiencyData.Key, efficiencyData); } foreach (ConfigNode toolTipNode in toolTipsShown) { if (toolTipNode.HasValue(kName) == false) { continue; } value = toolTipNode.GetValue(kName); if (toolTips.ContainsKey(value)) { toolTips[value] = toolTipNode; } else { toolTips.Add(value, toolTipNode); } } }
public void CheckGoldStrike() { string[] strikeResourceKeys = null; int resourceIndex; GoldStrikeData strikeData = null; WBIPathfinderScenario scenario = WBIPathfinderScenario.Instance; string resourceName = string.Empty; double resourceAmount = 0f; float analysisRoll = 0f; float successTargetNumber = prospectChance; int chancesRemaining = 0; string navigationID = string.Empty; GoldStrikeLode lode = null; string biomeName = string.Empty; int planetID = -1; //Do we have gold strike resources? if (scenario.goldStrikeResources.Count() == 0) { ScreenMessages.PostScreenMessage("There are no Gold Strike resources to prospect!", kMessageDisplayTime, ScreenMessageStyle.UPPER_CENTER); debugLog("No resources to prospect"); return; } //Do we have a valid situation? if (SituationIsValid() == false) { return; } //Ok, we can prospect at this location. GoldStrikeUtils.GetBiomeAndPlanet(out biomeName, out planetID, this.part.vessel, asteroid); setLastLocation(); chancesRemaining = updateChancesRemaining(); //Time to see if we find anything. //Tally up the % chance we have to make a successful prospect. //prospectChance: base chance to find a prospect. Some parts are better than others. //prospectSkillBonus: multiplied by the EVA prospector's skill level. Default is 1.0. //labBonus: For each Pathfinder geology lab in the vicinity, give one point per crew member staffing the lab that has the prospectSkill. //For each non-Pathfinder geology lab in the vicinity, give half a point per crew member staffing the lab that has the prospectSkill. //Chance = prospectChance + prospectSkillBonus + labBonus. //Ex: A 3-star scientist on EVA makes a prospect check. skillBonus = 3; prospectSkillBonus = 1.0. Total skill bonus = 3.0. //Inside the Bison are two scientists staffing a geology lab (non-pathfinder). labBonus = 2 * 0.5 = 1 //Gold Digger has a base 10% chance of finding a prospect. //successTargetNumber = 10 + 3 + 1 = 14. successTargetNumber = prospectChance + GetProspectBonus(); debugLog("Base chance to succeed: " + prospectChance); debugLog("successTargetNumber: " + successTargetNumber); //Roll the chance and check it. analysisRoll = UnityEngine.Random.Range(1, 6); analysisRoll += UnityEngine.Random.Range(1, 6); analysisRoll += UnityEngine.Random.Range(1, 6); analysisRoll *= 5.5556f; debugLog("analysisRoll: " + analysisRoll); //If we didn't succeed then we're done. if (analysisRoll > successTargetNumber) { debugLog("Prospect failed; didn't roll low enough."); ScreenMessages.PostScreenMessage("Nothing of value here, try another location. " + chancesRemaining + " chances remain in the " + biomeName, kMessageDisplayTime, ScreenMessageStyle.UPPER_CENTER); return; } //Success! Get the resource name and strike data. strikeResourceKeys = scenario.goldStrikeResources.Keys.ToArray(); resourceIndex = UnityEngine.Random.Range(0, strikeResourceKeys.Length - 1); resourceName = strikeResourceKeys[resourceIndex]; strikeData = scenario.goldStrikeResources[resourceName]; debugLog("strikeResourceKeys count: " + strikeResourceKeys.Length); debugLog("resourceIndex: " + resourceIndex); debugLog("strikeData: " + strikeData.ToString()); //Now, generate the resource amount to add to the map resourceAmount = UnityEngine.Random.Range(strikeData.minAmount, strikeData.maxAmount); debugLog("resourceAmount: " + resourceAmount); //If we hit the motherlode then factor that in. //The motherloade is 5% of the target number. if (analysisRoll <= (successTargetNumber * kMotherlodeFactor)) { resourceAmount *= strikeData.motherlodeMultiplier; debugLog("resourceAmount after motherlode: " + resourceAmount); ScreenMessages.PostScreenMessage(string.Format("Congratulations! You found a {0:s} motherlode with {1:f2} units available to mine!", resourceName, resourceAmount), kMessageDisplayTime, ScreenMessageStyle.UPPER_CENTER); } else { ScreenMessages.PostScreenMessage(string.Format("Congratulations! You found a {0:s} lode with {1:f2} units available to mine!", resourceName, resourceAmount), kMessageDisplayTime, ScreenMessageStyle.UPPER_CENTER); } ScreenMessages.PostScreenMessage(chancesRemaining + " chances remain to find another lode in the " + biomeName, kMessageDisplayTime, ScreenMessageStyle.UPPER_LEFT); //Play the jingle playJingle(); //Now set up the lode debugLog("Adding new lode entry to " + FlightGlobals.currentMainBody.name + " with flight global index " + FlightGlobals.currentMainBody.flightGlobalsIndex); debugLog("Biome: " + biomeName); debugLog("Lon/Lat: " + this.part.vessel.longitude + "/" + this.part.vessel.latitude); lode = scenario.AddLode(planetID, biomeName, this.part.vessel.longitude, this.part.vessel.latitude, resourceName, resourceAmount); //Set waypoint if (lode != null) { setWaypoint(resourceName, lode); } }
public void CheckGoldStrike() { string[] strikeResourceKeys = null; int resourceIndex; GoldStrikeData strikeData = null; WBIGoldStrikeScenario scenario = WBIGoldStrikeScenario.Instance; string resourceName = string.Empty; double resourceAmount = 0f; float analysisRoll = 0f; float successTargetNumber = prospectChance; string navigationID = string.Empty; GoldStrikeLode lode = null; string biomeName = string.Empty; int planetID = -1; //Do we have a valid situation? if (SituationIsValid() == false) { return; } //Update our location. asteroid = this.part.vessel.FindPartModuleImplementing <ModuleAsteroid>(); GoldStrikeUtils.GetBiomeAndPlanet(out biomeName, out planetID, this.part.vessel, asteroid); vesselModule.UpdateLastProspectLocation(); //Time to see if we find anything. //prospectChance: base chance to find a prospect. Some parts are better than others. //prospectBonus: Various situations contribute to the success of the attempt. successTargetNumber = 100 - (prospectChance + GetProspectBonus()); debugLog("successTargetNumber: " + successTargetNumber); //Roll the chance and check it. analysisRoll = UnityEngine.Random.Range(1, 100); debugLog("analysisRoll: " + analysisRoll); //If we didn't succeed then we're done. if (analysisRoll < successTargetNumber && !WBIGoldStrikeScenario.debugProspectAlwaysSuccessful) { debugLog("Prospect failed; didn't roll high enough."); ScreenMessages.PostScreenMessage("Nothing of value here, try another location. ", kMessageDisplayTime, ScreenMessageStyle.UPPER_CENTER); return; } //Success! Get the resource name and strike data. //If we're near an anomaly then we need a roll table. if (anomalyBonus > 0) { SortedDictionary <int, GoldStrikeData> sortedResources = new SortedDictionary <int, GoldStrikeData>(); int resourceCount = prospectResources.Count; //Add any resources that have an anomaly chance into the sorted resources for (int index = 0; index < resourceCount; index++) { strikeData = prospectResources[index]; if (strikeData.anomalyChance > 0) { sortedResources.Add(strikeData.anomalyChance, strikeData); } } //Roll a 1-100 int pressenceRoll = UnityEngine.Random.Range(1, 100); //See if we have any strike data strikeData = null; foreach (KeyValuePair <int, GoldStrikeData> pair in sortedResources) { if (pressenceRoll < pair.Key) { strikeData = pair.Value; break; } } //If we don't have any strike data then pick a random resource if (strikeData == null) { resourceIndex = UnityEngine.Random.Range(0, resourceCount - 1); strikeData = prospectResources[resourceIndex]; resourceName = strikeData.resourceName; } } else { resourceIndex = UnityEngine.Random.Range(0, prospectResources.Count - 1); strikeData = prospectResources[resourceIndex]; resourceName = strikeData.resourceName; debugLog("prospectResources count: " + prospectResources.Count); debugLog("resourceIndex: " + resourceIndex); } debugLog("strikeData: " + strikeData.ToString()); //Play the jingle playJingle(); //Setup a planetary surface lode if (asteroid == null) { debugLog("Setting up surface lode"); //Now, generate the resource amount to add to the map resourceAmount = UnityEngine.Random.Range(strikeData.minAmount, strikeData.maxAmount); debugLog("resourceAmount: " + resourceAmount); //If we hit the motherlode then factor that in. //The motherloade is 5% of the target number. if (analysisRoll <= (successTargetNumber * kMotherlodeFactor)) { resourceAmount *= strikeData.motherlodeMultiplier; debugLog("resourceAmount after motherlode: " + resourceAmount); ScreenMessages.PostScreenMessage(string.Format("Congratulations! You found a {0:s} motherlode with {1:f2} units available to mine!", resourceName, resourceAmount), kMessageDisplayTime, ScreenMessageStyle.UPPER_CENTER); } else { ScreenMessages.PostScreenMessage(string.Format("Congratulations! You found a {0:s} lode with {1:f2} units available to mine!", resourceName, resourceAmount), kMessageDisplayTime, ScreenMessageStyle.UPPER_CENTER); } if (!string.IsNullOrEmpty(anomalyName)) { ScreenMessages.PostScreenMessage("Special cache found at " + anomalyName, kMessageDisplayTime, ScreenMessageStyle.UPPER_CENTER); } debugLog("Adding new lode entry to " + FlightGlobals.currentMainBody.name + " with flight global index " + FlightGlobals.currentMainBody.flightGlobalsIndex); debugLog("Biome: " + biomeName); debugLog("Lon/Lat: " + this.part.vessel.longitude + "/" + this.part.vessel.latitude); lode = scenario.AddLode(planetID, biomeName, this.part.vessel.longitude, this.part.vessel.latitude, this.part.vessel.altitude, resourceName, resourceAmount); } //Setup an asteroid lode else { debugLog("Setting up asteroid lode"); float abundance = 0.01f; //Get the resource module for the lode. ModuleAsteroidResource lodeResource = null; ModuleAsteroidResource[] resourceModules = asteroid.part.FindModulesImplementing <ModuleAsteroidResource>().ToArray(); for (int index = 0; index < resourceModules.Length; index++) { if (resourceModules[index].resourceName == resourceName) { debugLog("ModuleAsteroidResource found for " + resourceName); lodeResource = resourceModules[index]; break; } } if (lodeResource == null) { debugLog("ModuleAsteroidResource NOT found for " + resourceName); return; } //Adjust abundance for motherlode if (analysisRoll <= (successTargetNumber * kMotherlodeFactor)) { abundance *= strikeData.motherlodeMultiplier; } debugLog("abundance increase: " + abundance); //Display appropriate message ScreenMessages.PostScreenMessage(string.Format("Congratulations! A careful scan of {0:s} has revealed an increased abundance of {1:s}", asteroid.AsteroidName, resourceName), kMessageDisplayTime, ScreenMessageStyle.UPPER_CENTER); //Update resource module debugLog("Old abundance: " + lodeResource.abundance); lodeResource.abundance += abundance; lodeResource.displayAbundance += abundance; debugLog("New abundance: " + lodeResource.abundance); debugLog("Adding new lode entry for asteroid: " + asteroid.AsteroidName); lode = scenario.AddLode(asteroid, resourceName, lodeResource.displayAbundance); } //Update any drills in the area. scenario.UpdateDrillLodes(asteroid); //Set waypoint if (lode != null && asteroid == null) { setWaypoint(resourceName, lode); } }
public ProspectSituations GetProspectSituation(int planetID, string biome, double longitude, double lattitude, double altitude, out GoldStrikeLode lode) { GoldStrikeChance chance = GetGoldStrikeChance(planetID, biome); double travelDistance = chance.GetDistanceFromLastLocation(longitude, lattitude, altitude); //Set the lode object lode = FindNearestLode(planetID, biome, longitude, lattitude); //Are we out of chances? if (chance.chancesRemaining <= 0) { return(ProspectSituations.OutOfChances); } //Is there a lode in the area? if (lode != null) { return(ProspectSituations.LodeAlreadyExists); } //Have we traveled far enough? if (travelDistance < GoldStrikeSettings.DistanceBetweenProspects) { debugLog("Calculated distance between current location and last prospect location: " + travelDistance); return(ProspectSituations.NotEnoughDistance); } return(ProspectSituations.Valid); }
public ProspectSituations GetProspectSituation(Vessel vessel, out GoldStrikeLode lode) { ModuleAsteroid asteroid = null; CBAttributeMapSO.MapAttribute biome = null; string biomeName = string.Empty; int planetID = int.MaxValue; bool vesselSituationIsValid = false; double longitude = 0f; double latitude = 0f; double altitude = 0f; //If we're landed then we're ok to check prospect situation. if (vessel.situation == Vessel.Situations.LANDED || vessel.situation == Vessel.Situations.PRELAUNCH) { biome = Utils.GetCurrentBiome(vessel); biomeName = biome.name; planetID = vessel.mainBody.flightGlobalsIndex; longitude = vessel.longitude; latitude = vessel.latitude; altitude = vessel.altitude; vesselSituationIsValid = true; debugLog("Vessel is landed or prelaunch"); } //If we have an asteroid, then we're ok to check prospect situation. asteroid = vessel.FindPartModuleImplementing <ModuleAsteroid>(); if (asteroid != null) { biomeName = asteroid.AsteroidName; vesselSituationIsValid = true; debugLog("Vessel has an asteroid"); } //Is there a lode in the area? if (asteroid != null) { lode = FindNearestLode(asteroid); } else { lode = FindNearestLode(planetID, biomeName, vessel.longitude, vessel.latitude); } if (lode != null) { return(ProspectSituations.LodeAlreadyExists); } //If the flight situation is bad then we're done. if (vesselSituationIsValid == false) { return(ProspectSituations.InvalidVesselSituation); } //Is the prospect site an asteroid, and has it been prospected? if (asteroid != null) { if (prospectedAsteroids.Contains(asteroid.AsteroidName)) { return(ProspectSituations.AsteroidProspected); } else //Record the fact that we prospected the asteroid. { prospectedAsteroids.Add(asteroid.AsteroidName); } } //Have we traveled far enough? else { double travelDistance = GetDistanceFromLastLocation(vessel); if (travelDistance < GoldStrikeSettings.DistanceBetweenProspects) { debugLog("Calculated distance between current location and last prospect location: " + travelDistance); return(ProspectSituations.NotEnoughDistance); } } return(ProspectSituations.Valid); }
public bool SituationIsValid() { debugLog("SituationIsValid: checking..."); CBAttributeMapSO.MapAttribute biome = null; string biomeName = string.Empty; int planetID = int.MaxValue; bool vesselSituationIsValid = false; double longitude = 0f; double latitude = 0f; double altitude = 0f; GoldStrikeLode lode = null; //If we're landed then we're ok to check prospect situation. if (this.part.vessel.situation == Vessel.Situations.LANDED || this.part.vessel.situation == Vessel.Situations.PRELAUNCH) { biome = Utils.GetCurrentBiome(this.part.vessel); biomeName = biome.name; planetID = this.part.vessel.mainBody.flightGlobalsIndex; longitude = this.part.vessel.longitude; latitude = this.part.vessel.latitude; altitude = this.part.vessel.altitude; vesselSituationIsValid = true; debugLog("Vessel is landed or prelaunch"); } //If we're docked or orbiting, and we have an asteroid, then we're ok to check prospect situation. if ((this.part.vessel.situation == Vessel.Situations.ORBITING || this.part.vessel.situation == Vessel.Situations.DOCKED) && asteroid != null) { biomeName = asteroid.AsteroidName; vesselSituationIsValid = true; debugLog("Vessel has an asteroid"); } //If the flight situation is bad then we're done. if (vesselSituationIsValid == false) { debugLog("Vessel situation not valid"); ScreenMessages.PostScreenMessage("Vessel must be landed or in orbit/docked with an asteroid attached", kMessageDisplayTime, ScreenMessageStyle.UPPER_CENTER); return(false); } //If we don't have sufficient ore abundance then we're done. if (!HasSufficientAbundance()) { return(false); } //Can we prospect the location? switch (WBIPathfinderScenario.Instance.GetProspectSituation(planetID, biomeName, longitude, latitude, altitude, out lode)) { case ProspectSituations.LodeAlreadyExists: if (lode != null) { debugLog("Situation not valid, existing lode found: " + lode.ToString()); string message = string.Format("You already found a vein of {0:s} at this location. It has {1:f2} units remaining.", lode.resourceName, lode.amountRemaining); ScreenMessages.PostScreenMessage(message, kMessageDisplayTime, ScreenMessageStyle.UPPER_CENTER); } return(false); case ProspectSituations.NotEnoughDistance: debugLog("Vessel has not traveled enough distance between prospects"); ScreenMessages.PostScreenMessage("Vessel must travel further before prospecting again.", kMessageDisplayTime, ScreenMessageStyle.UPPER_CENTER); return(false); case ProspectSituations.OutOfChances: debugLog("Out of prospecting chances for this area or asteroid"); ScreenMessages.PostScreenMessage("Out of prospecting chances in this area.", kMessageDisplayTime, ScreenMessageStyle.UPPER_CENTER); //Enable option to reset chances. Events["ResetProspects"].guiActive = true; Events["ResetProspects"].guiActiveUnfocused = true; return(false); //A-OK default: return(true); } }