protected override void OnOffered() { System.Random random = new System.Random(contract.MissionSeed); int i = 0; foreach (WaypointData wpData in waypoints) { // Do type-specific waypoint handling if (wpData.type == "RANDOM_WAYPOINT") { // Generate the position WaypointManager.ChooseRandomPosition(out wpData.waypoint.latitude, out wpData.waypoint.longitude, wpData.waypoint.celestialName, wpData.waterAllowed, wpData.forceEquatorial, random); } else if (wpData.type == "RANDOM_WAYPOINT_NEAR") { Waypoint nearWaypoint = waypoints[wpData.nearIndex].waypoint; WaypointManager.ChooseRandomPositionNear(out wpData.waypoint.latitude, out wpData.waypoint.longitude, nearWaypoint.latitude, nearWaypoint.longitude, wpData.waypoint.celestialName, wpData.nearDistance, wpData.waterAllowed, random); } // Set altitude if (wpData.randomAltitude) { CelestialBody body = FlightGlobals.Bodies.Where <CelestialBody>(b => b.name == wpData.waypoint.celestialName).First(); if (body.atmosphere) { wpData.waypoint.altitude = random.NextDouble() * (body.maxAtmosphereAltitude); } else { wpData.waypoint.altitude = 0.0; } } // Set name if (string.IsNullOrEmpty(wpData.waypoint.name)) { CelestialBody body = FlightGlobals.Bodies.Where <CelestialBody>(b => b.name == wpData.waypoint.celestialName).First(); wpData.waypoint.name = StringUtilities.GenerateSiteName(contract.MissionSeed + i++, body, !wpData.waterAllowed); } AddWayPoint(wpData.waypoint); } }
protected override bool Generate() { if (AreWingsUnlocked() == false) { return(false); } int offeredContracts = 0; int activeContracts = 0; foreach (AerialContract contract in ContractSystem.Instance.GetCurrentContracts <AerialContract>()) { if (contract.ContractState == Contract.State.Offered) { offeredContracts++; } else if (contract.ContractState == Contract.State.Active) { activeContracts++; } } if (offeredContracts >= FPConfig.Aerial.MaximumAvailable || activeContracts >= FPConfig.Aerial.MaximumActive) { return(false); } double range = 10000.0; System.Random generator = new System.Random(this.MissionSeed); int additionalWaypoints = 0; List <CelestialBody> allBodies = GetBodies_Reached(true, false); List <CelestialBody> atmosphereBodies = new List <CelestialBody>(); foreach (CelestialBody body in allBodies) { if (body.atmosphere) { atmosphereBodies.Add(body); } } if (atmosphereBodies.Count == 0) { return(false); } targetBody = atmosphereBodies[generator.Next(0, atmosphereBodies.Count)]; //TODO: Find some common ground to calculate these values automatically without specific names. switch (targetBody.GetName()) { case "Jool": additionalWaypoints = 0; minAltitude = 15000.0; maxAltitude = 30000.0; break; case "Duna": additionalWaypoints = 1; minAltitude = 8000.0; maxAltitude = 16000.0; break; case "Laythe": additionalWaypoints = 1; minAltitude = 15000.0; maxAltitude = 30000.0; break; case "Eve": additionalWaypoints = 1; minAltitude = 20000.0; maxAltitude = 40000.0; break; case "Kerbin": additionalWaypoints = 2; minAltitude = 12500.0; maxAltitude = 25000.0; break; default: additionalWaypoints = 0; minAltitude = 0.0; maxAltitude = 10000.0; break; } int waypointCount = 0; float fundsMultiplier = 1; float scienceMultiplier = 1; float reputationMultiplier = 1; float wpFundsMultiplier = 1; float wpScienceMultiplier = 1; float wpReputationMultiplier = 1; double altitudeHalfQuarterRange = Math.Abs(maxAltitude - minAltitude) * 0.125; double upperMidAltitude = ((maxAltitude + minAltitude) / 2.0) + altitudeHalfQuarterRange; double lowerMidAltitude = ((maxAltitude + minAltitude) / 2.0) - altitudeHalfQuarterRange; minAltitude = Math.Round((minAltitude + (generator.NextDouble() * (lowerMidAltitude - minAltitude))) / 100.0) * 100.0; maxAltitude = Math.Round((upperMidAltitude + (generator.NextDouble() * (maxAltitude - upperMidAltitude))) / 100.0) * 100.0; switch (this.prestige) { case ContractPrestige.Trivial: waypointCount = FPConfig.Aerial.TrivialWaypoints; waypointCount += additionalWaypoints; range = FPConfig.Aerial.TrivialRange; if (Util.IsGasGiant(targetBody)) { if (generator.Next(0, 100) < FPConfig.Aerial.ExceptionalLowAltitudeChance / 2) { minAltitude *= FPConfig.Aerial.ExceptionalLowAltitudeMultiplier; maxAltitude *= FPConfig.Aerial.ExceptionalLowAltitudeMultiplier; isLowAltitude = true; } } else { if (generator.Next(0, 100) < FPConfig.Aerial.TrivialLowAltitudeChance) { minAltitude *= FPConfig.Aerial.TrivialLowAltitudeMultiplier; maxAltitude *= FPConfig.Aerial.TrivialLowAltitudeMultiplier; isLowAltitude = true; } } if (generator.Next(0, 100) < FPConfig.Aerial.TrivialHomeNearbyChance && targetBody == Planetarium.fetch.Home) { WaypointManager.ChooseRandomPositionNear(out centerLatitude, out centerLongitude, SpaceCenter.Instance.Latitude, SpaceCenter.Instance.Longitude, targetBody.GetName(), FPConfig.Aerial.TrivialHomeNearbyRange, true); } else { WaypointManager.ChooseRandomPosition(out centerLatitude, out centerLongitude, targetBody.GetName(), true, false); } break; case ContractPrestige.Significant: waypointCount = FPConfig.Aerial.SignificantWaypoints; waypointCount += additionalWaypoints; range = FPConfig.Aerial.SignificantRange; fundsMultiplier = FPConfig.Aerial.Funds.SignificantMultiplier; scienceMultiplier = FPConfig.Aerial.Science.SignificantMultiplier; reputationMultiplier = FPConfig.Aerial.Reputation.SignificantMultiplier; wpFundsMultiplier = FPConfig.Aerial.Funds.WaypointSignificantMultiplier; wpScienceMultiplier = FPConfig.Aerial.Science.WaypointSignificantMultiplier; wpReputationMultiplier = FPConfig.Aerial.Reputation.WaypointSignificantMultiplier; if (Util.IsGasGiant(targetBody)) { if (generator.Next(0, 100) < FPConfig.Aerial.SignificantLowAltitudeChance / 2) { minAltitude *= FPConfig.Aerial.SignificantLowAltitudeMultiplier; maxAltitude *= FPConfig.Aerial.SignificantLowAltitudeMultiplier; isLowAltitude = true; } } else { if (generator.Next(0, 100) < FPConfig.Aerial.SignificantLowAltitudeChance) { minAltitude *= FPConfig.Aerial.SignificantLowAltitudeMultiplier; maxAltitude *= FPConfig.Aerial.SignificantLowAltitudeMultiplier; isLowAltitude = true; } } if (generator.Next(0, 100) < FPConfig.Aerial.SignificantHomeNearbyChance && targetBody == Planetarium.fetch.Home) { WaypointManager.ChooseRandomPositionNear(out centerLatitude, out centerLongitude, SpaceCenter.Instance.Latitude, SpaceCenter.Instance.Longitude, targetBody.GetName(), FPConfig.Aerial.SignificantHomeNearbyRange, true); } else { WaypointManager.ChooseRandomPosition(out centerLatitude, out centerLongitude, targetBody.GetName(), true, false); } break; case ContractPrestige.Exceptional: waypointCount = FPConfig.Aerial.ExceptionalWaypoints; waypointCount += additionalWaypoints; range = FPConfig.Aerial.ExceptionalRange; fundsMultiplier = FPConfig.Aerial.Funds.ExceptionalMultiplier; scienceMultiplier = FPConfig.Aerial.Science.ExceptionalMultiplier; reputationMultiplier = FPConfig.Aerial.Reputation.ExceptionalMultiplier; wpFundsMultiplier = FPConfig.Aerial.Funds.WaypointExceptionalMultiplier; wpScienceMultiplier = FPConfig.Aerial.Science.WaypointExceptionalMultiplier; wpReputationMultiplier = FPConfig.Aerial.Reputation.WaypointExceptionalMultiplier; if (Util.IsGasGiant(targetBody)) { if (generator.Next(0, 100) < FPConfig.Aerial.TrivialLowAltitudeChance / 2) { minAltitude *= FPConfig.Aerial.TrivialLowAltitudeMultiplier; maxAltitude *= FPConfig.Aerial.TrivialLowAltitudeMultiplier; isLowAltitude = true; } } else { if (generator.Next(0, 100) < FPConfig.Aerial.ExceptionalLowAltitudeChance) { minAltitude *= FPConfig.Aerial.ExceptionalLowAltitudeMultiplier; maxAltitude *= FPConfig.Aerial.ExceptionalLowAltitudeMultiplier; isLowAltitude = true; } } if (generator.Next(0, 100) < FPConfig.Aerial.ExceptionalHomeNearbyChance && targetBody == Planetarium.fetch.Home) { WaypointManager.ChooseRandomPositionNear(out centerLatitude, out centerLongitude, SpaceCenter.Instance.Latitude, SpaceCenter.Instance.Longitude, targetBody.GetName(), FPConfig.Aerial.ExceptionalHomeNearbyRange, true); } else { WaypointManager.ChooseRandomPosition(out centerLatitude, out centerLongitude, targetBody.GetName(), true, false); } break; } for (int x = 0; x < waypointCount; x++) { ContractParameter newParameter; newParameter = this.AddParameter(new FlightWaypointParameter(x, targetBody, minAltitude, maxAltitude, centerLatitude, centerLongitude, range), null); newParameter.SetFunds(Mathf.Round(FPConfig.Aerial.Funds.WaypointBaseReward * wpFundsMultiplier), targetBody); newParameter.SetReputation(Mathf.Round(FPConfig.Aerial.Reputation.WaypointBaseReward * wpReputationMultiplier), targetBody); newParameter.SetScience(Mathf.Round(FPConfig.Aerial.Science.WaypointBaseReward * wpScienceMultiplier), targetBody); } base.AddKeywords(new string[] { "surveyflight" }); base.SetExpiry(FPConfig.Aerial.Expire.MinimumExpireDays, FPConfig.Aerial.Expire.MaximumExpireDays); base.SetDeadlineDays(FPConfig.Aerial.Expire.DeadlineDays, targetBody); base.SetFunds(Mathf.Round(FPConfig.Aerial.Funds.BaseAdvance * fundsMultiplier), Mathf.Round(FPConfig.Aerial.Funds.BaseReward * fundsMultiplier), Mathf.Round(FPConfig.Aerial.Funds.BaseFailure * fundsMultiplier), targetBody); base.SetScience(Mathf.Round(FPConfig.Aerial.Science.BaseReward * scienceMultiplier), targetBody); base.SetReputation(Mathf.Round(FPConfig.Aerial.Reputation.BaseReward * reputationMultiplier), Mathf.Round(FPConfig.Aerial.Reputation.BaseFailure * reputationMultiplier), targetBody); return(true); }
public void Initialize() { if (!initialized) { LoggingUtil.LogVerbose(this, "Initializing waypoint generator."); foreach (WaypointData wpData in waypoints) { CelestialBody body = FlightGlobals.Bodies.Where <CelestialBody>(b => b.name == wpData.waypoint.celestialName).FirstOrDefault(); if (body == null) { continue; } // Do type-specific waypoint handling if (wpData.type == "RANDOM_WAYPOINT") { LoggingUtil.LogVerbose(this, " Generating a random waypoint..."); while (true) { // Generate the position WaypointManager.ChooseRandomPosition(out wpData.waypoint.latitude, out wpData.waypoint.longitude, wpData.waypoint.celestialName, wpData.waterAllowed, wpData.forceEquatorial, random); // Force a water waypoint if (wpData.underwater) { Vector3d radialVector = QuaternionD.AngleAxis(wpData.waypoint.longitude, Vector3d.down) * QuaternionD.AngleAxis(wpData.waypoint.latitude, Vector3d.forward) * Vector3d.right; if (body.pqsController.GetSurfaceHeight(radialVector) - body.pqsController.radius >= 0.0) { continue; } } break; } } else if (wpData.type == "RANDOM_WAYPOINT_NEAR") { Waypoint nearWaypoint = waypoints[wpData.nearIndex].waypoint; LoggingUtil.LogVerbose(this, " Generating a random waypoint near waypoint " + nearWaypoint.name + "..."); // TODO - this is really bad, we need to implement this method ourselves... do { WaypointManager.ChooseRandomPositionNear(out wpData.waypoint.latitude, out wpData.waypoint.longitude, nearWaypoint.latitude, nearWaypoint.longitude, wpData.waypoint.celestialName, wpData.maxDistance, wpData.waterAllowed, random); // Force a water waypoint if (wpData.underwater) { Vector3d radialVector = QuaternionD.AngleAxis(wpData.waypoint.longitude, Vector3d.down) * QuaternionD.AngleAxis(wpData.waypoint.latitude, Vector3d.forward) * Vector3d.right; if (body.pqsController.GetSurfaceHeight(radialVector) - body.pqsController.radius >= 0.0) { continue; } } } while (WaypointUtil.GetDistance(wpData.waypoint.latitude, wpData.waypoint.longitude, nearWaypoint.latitude, nearWaypoint.longitude, body.Radius) < wpData.minDistance); } else if (wpData.type == "PQS_CITY") { GeneratePQSCityCoordinates(wpData, body); } // Set altitude SetAltitude(wpData, body); LoggingUtil.LogVerbose(this, " Generated waypoint " + wpData.waypoint.name + " at " + wpData.waypoint.latitude + ", " + wpData.waypoint.longitude + "."); } initialized = true; LoggingUtil.LogVerbose(this, "Waypoint generator initialized."); } }
protected override void OnOffered() { System.Random random = new System.Random(contract.MissionSeed); int index = 0; foreach (WaypointData wpData in waypoints) { // Do type-specific waypoint handling if (wpData.type == "RANDOM_WAYPOINT") { // Generate the position WaypointManager.ChooseRandomPosition(out wpData.waypoint.latitude, out wpData.waypoint.longitude, wpData.waypoint.celestialName, wpData.waterAllowed, wpData.forceEquatorial, random); } else if (wpData.type == "RANDOM_WAYPOINT_NEAR") { CelestialBody body = FlightGlobals.Bodies.Where(b => b.name == wpData.waypoint.celestialName).First(); Waypoint nearWaypoint = waypoints[wpData.nearIndex].waypoint; // TODO - this is really bad, we need to implement this method ourselves... do { WaypointManager.ChooseRandomPositionNear(out wpData.waypoint.latitude, out wpData.waypoint.longitude, nearWaypoint.latitude, nearWaypoint.longitude, wpData.waypoint.celestialName, wpData.maxDistance, wpData.waterAllowed, random); } while (WaypointUtil.GetDistance(wpData.waypoint.latitude, wpData.waypoint.longitude, nearWaypoint.latitude, nearWaypoint.longitude, body.Radius) < wpData.minDistance); } else if (wpData.type == "PQS_CITY") { CelestialBody body = FlightGlobals.Bodies.Where(b => b.name == wpData.waypoint.celestialName).First(); Vector3d position = wpData.pqsCity.transform.position; // Translate by the PQS offset (inverse transform of coordinate system) Vector3d v = wpData.pqsOffset; Vector3d i = wpData.pqsCity.transform.right; Vector3d j = wpData.pqsCity.transform.forward; Vector3d k = wpData.pqsCity.transform.up; Vector3d offsetPos = new Vector3d( (j.y * k.z - j.z * k.y) * v.x + (i.z * k.y - i.y * k.z) * v.y + (i.y * j.z - i.z * j.y) * v.z, (j.z * k.x - j.x * k.z) * v.x + (i.x * k.z - i.z * k.x) * v.y + (i.z * j.x - i.x * j.z) * v.z, (j.x * k.y - j.y * k.x) * v.x + (i.y * k.x - i.x * k.y) * v.y + (i.x * j.y - i.y * j.x) * v.z ); offsetPos *= (i.x * j.y * k.z) + (i.y * j.z * k.x) + (i.z * j.x * k.y) - (i.z * j.y * k.x) - (i.y * j.x * k.z) - (i.x * j.z * k.y); wpData.waypoint.latitude = body.GetLatitude(position + offsetPos); wpData.waypoint.longitude = body.GetLongitude(position + offsetPos); } // Set altitude if (wpData.randomAltitude) { CelestialBody body = FlightGlobals.Bodies.Where <CelestialBody>(b => b.name == wpData.waypoint.celestialName).First(); if (body.atmosphere) { wpData.waypoint.altitude = random.NextDouble() * (body.atmosphereDepth); } else { wpData.waypoint.altitude = 0.0; } } // Set name if (string.IsNullOrEmpty(wpData.waypoint.name)) { CelestialBody body = FlightGlobals.Bodies.Where <CelestialBody>(b => b.name == wpData.waypoint.celestialName).First(); wpData.waypoint.name = StringUtilities.GenerateSiteName(contract.MissionSeed + index++, body, !wpData.waterAllowed); } if (!wpData.hidden && (string.IsNullOrEmpty(wpData.parameter) || contract.AllParameters. Where(p => p.ID == wpData.parameter && p.State == ParameterState.Complete).Any())) { AddWayPoint(wpData.waypoint); } } }
protected override bool Generate() { if (AreWheelsUnlocked() == false) { return(false); } //Allow four contracts in pocket but only two on the board at a time. int offeredContracts = 0; int activeContracts = 0; foreach (RoverContract contract in ContractSystem.Instance.GetCurrentContracts <RoverContract>()) { if (contract.ContractState == Contract.State.Offered) { offeredContracts++; } else if (contract.ContractState == Contract.State.Active) { activeContracts++; } } if (offeredContracts >= FPConfig.Rover.MaximumAvailable || activeContracts >= FPConfig.Rover.MaximumActive) { return(false); } System.Random generator = new System.Random(this.MissionSeed); double range = 10000.0; List <CelestialBody> bodies = GetBodies_Reached(true, false); if (bodies.Count == 0) { return(false); } targetBody = bodies[generator.Next(0, bodies.Count)]; if (Util.IsGasGiant(targetBody)) { targetBody = Util.RandomNeighbor(MissionSeed, targetBody, false); if (Util.IsGasGiant(targetBody) || targetBody == null) { return(false); } } int waypointCount = 0; float fundsMultiplier = 1; float scienceMultiplier = 1; float reputationMultiplier = 1; float wpFundsMultiplier = 1; float wpScienceMultiplier = 1; float wpReputationMultiplier = 1; switch (this.prestige) { case ContractPrestige.Trivial: waypointCount = FPConfig.Rover.TrivialWaypoints; range = FPConfig.Rover.TrivialRange; range /= 2; range = range + range * targetBody.GeeASL; if (generator.Next(0, 100) < FPConfig.Rover.TrivialHomeNearbyChance && targetBody == Planetarium.fetch.Home) { WaypointManager.ChooseRandomPositionNear(out centerLatitude, out centerLongitude, SpaceCenter.Instance.Latitude, SpaceCenter.Instance.Longitude, targetBody.GetName(), FPConfig.Rover.TrivialHomeNearbyRange, false); } else { WaypointManager.ChooseRandomPosition(out centerLatitude, out centerLongitude, targetBody.GetName(), false, false); } break; case ContractPrestige.Significant: waypointCount = FPConfig.Rover.SignificantWaypoints; range = FPConfig.Rover.SignificantRange; fundsMultiplier = FPConfig.Rover.Funds.SignificantMultiplier; scienceMultiplier = FPConfig.Rover.Science.SignificantMultiplier; reputationMultiplier = FPConfig.Rover.Reputation.SignificantMultiplier; wpFundsMultiplier = FPConfig.Rover.Funds.WaypointSignificantMultiplier; wpScienceMultiplier = FPConfig.Rover.Science.WaypointSignificantMultiplier; wpReputationMultiplier = FPConfig.Rover.Reputation.WaypointSignificantMultiplier; range /= 2; range = range + range * targetBody.GeeASL; if (generator.Next(0, 100) < FPConfig.Rover.SignificantHomeNearbyChance && targetBody == Planetarium.fetch.Home) { WaypointManager.ChooseRandomPositionNear(out centerLatitude, out centerLongitude, SpaceCenter.Instance.Latitude, SpaceCenter.Instance.Longitude, targetBody.GetName(), FPConfig.Rover.SignificantHomeNearbyRange, false); } else { WaypointManager.ChooseRandomPosition(out centerLatitude, out centerLongitude, targetBody.GetName(), false, false); } break; case ContractPrestige.Exceptional: waypointCount = FPConfig.Rover.ExceptionalWaypoints; range = FPConfig.Rover.ExceptionalRange; fundsMultiplier = FPConfig.Rover.Funds.ExceptionalMultiplier; scienceMultiplier = FPConfig.Rover.Science.ExceptionalMultiplier; reputationMultiplier = FPConfig.Rover.Reputation.ExceptionalMultiplier; wpFundsMultiplier = FPConfig.Rover.Funds.WaypointExceptionalMultiplier; wpScienceMultiplier = FPConfig.Rover.Science.WaypointExceptionalMultiplier; wpReputationMultiplier = FPConfig.Rover.Reputation.WaypointExceptionalMultiplier; range /= 2; range = range + range * targetBody.GeeASL; if (generator.Next(0, 100) < FPConfig.Rover.ExceptionalHomeNearbyChance && targetBody == Planetarium.fetch.Home) { WaypointManager.ChooseRandomPositionNear(out centerLatitude, out centerLongitude, SpaceCenter.Instance.Latitude, SpaceCenter.Instance.Longitude, targetBody.GetName(), FPConfig.Rover.ExceptionalHomeNearbyRange, false); } else { WaypointManager.ChooseRandomPosition(out centerLatitude, out centerLongitude, targetBody.GetName(), false, false); } break; } int secret = generator.Next(0, waypointCount); for (int x = 0; x < waypointCount; x++) { ContractParameter newParameter; if (x == secret) { newParameter = this.AddParameter(new RoverWaypointParameter(x, targetBody, centerLatitude, centerLongitude, range, true), null); } else { newParameter = this.AddParameter(new RoverWaypointParameter(x, targetBody, centerLatitude, centerLongitude, range, false), null); } newParameter.SetFunds(Mathf.Round(FPConfig.Rover.Funds.WaypointBaseReward * wpFundsMultiplier), targetBody); newParameter.SetScience(Mathf.Round(FPConfig.Rover.Science.WaypointBaseReward * wpScienceMultiplier), targetBody); newParameter.SetReputation(Mathf.Round(FPConfig.Rover.Reputation.WaypointBaseReward * wpReputationMultiplier), targetBody); } base.AddKeywords(new string[] { "roversearch" }); base.SetExpiry(FPConfig.Rover.Expire.MinimumExpireDays, FPConfig.Rover.Expire.MaximumExpireDays); base.SetDeadlineDays(FPConfig.Rover.Expire.DeadlineDays, targetBody); base.SetFunds(Mathf.Round(FPConfig.Rover.Funds.BaseAdvance * fundsMultiplier), Mathf.Round(FPConfig.Rover.Funds.BaseReward * fundsMultiplier), Mathf.Round(FPConfig.Rover.Funds.BaseFailure * fundsMultiplier), targetBody); base.SetScience(Mathf.Round(FPConfig.Rover.Science.BaseReward * scienceMultiplier), targetBody); base.SetReputation(Mathf.Round(FPConfig.Rover.Reputation.BaseReward * reputationMultiplier), Mathf.Round(FPConfig.Rover.Reputation.BaseFailure * reputationMultiplier), targetBody); return(true); }