public override bool MeetRequirements() { CelestialBodySubtree progress = null; foreach (var node in ProgressTracking.Instance.celestialBodyNodes) { if (node.Body == Planetarium.fetch.Home) { progress = node; } } if (progress == null) { StnSciScenario.LogError("ProgressNode for Kerbin not found, terminating"); return(false); } if (progress.orbit.IsComplete && (IsPartUnlocked("dockingPort1") || IsPartUnlocked("dockingPort2") || IsPartUnlocked("dockingPort3") || IsPartUnlocked("dockingPortLarge") || IsPartUnlocked("dockingPortLateral")) && (IsPartUnlocked("StnSciLab") || IsPartUnlocked("StnSciCyclo"))) { return(true); } return(false); }
private void OnVesselSituationChange(GameEvents.HostedFromToAction <Vessel, Vessel.Situations> arg) { StnSciScenario.Log("OnVesselSituationChanged"); if (!((arg.from == Vessel.Situations.LANDED || arg.from == Vessel.Situations.PRELAUNCH) && (arg.to == Vessel.Situations.FLYING || arg.to == Vessel.Situations.SUB_ORBITAL))) { return; } if (arg.host.mainBody.name != "Kerbin") { return; } AvailablePart experimentType = StnSciParameter.getExperimentType(this); if (experimentType == null) { return; } foreach (Part part in arg.host.Parts) { if (part.name == experimentType.name) { StationExperiment e = part.FindModuleImplementing <StationExperiment>(); if (e != null && e.launched == 0) { e.launched = (float)Planetarium.GetUniversalTime(); } } } }
private int CompletedCount(String exp = null, CelestialBody body = null) { int ret = 0; if (ContractSystem.Instance == null) { StnSciScenario.Log("ContractSystem Instance is null"); return(0); } if (ContractSystem.Instance.ContractsFinished == null) { StnSciScenario.Log("ContractSystem ContratsFinished is null"); return(0); } foreach (Contract con in ContractSystem.Instance.ContractsFinished) { StnSciContract sscon = con as StnSciContract; if (sscon != null && sscon.ContractState == Contract.State.Completed && sscon.experimentType != null && sscon.targetBody != null && (exp == null || sscon.experimentType != null) && (body == null || sscon.targetBody != null) && ((exp == null || exp == sscon.experimentType.name) && (body == null || body.name == sscon.targetBody.name))) { ret += 1; } } return(ret); }
private void OnRecovered(ProtoVessel pv, bool dummy) { CelestialBody targetBody = StnSciParameter.getTargetBody(this); AvailablePart experimentType = StnSciParameter.getExperimentType(this); if (targetBody == null || experimentType == null) { return; } foreach (ProtoPartSnapshot part in pv.protoPartSnapshots) { if (part.partName == experimentType.name) { foreach (ProtoPartModuleSnapshot module in part.modules) { if (module.moduleName == "StationExperiment") { ConfigNode cn = module.moduleValues; if (!cn.HasValue("launched") || !cn.HasValue("completed")) { continue; } float launched, completed; try { launched = float.Parse(cn.GetValue("launched")); completed = float.Parse(cn.GetValue("completed")); } catch (Exception e) { StnSciScenario.LogError(e.ToString()); continue; } if (launched >= this.Root.DateAccepted && completed >= launched) { foreach (ConfigNode datum in cn.GetNodes("ScienceData")) { if (!datum.HasValue("subjectID")) { continue; } string subjectID = datum.GetValue("subjectID"); if (subjectID.ToLower().Contains("@" + targetBody.name.ToLower() + "inspace")) { StnSciParameter parent = this.Parent as StnSciParameter; SetComplete(); if (parent != null) { parent.Complete(); } return; } } } } } } } }
private bool SetTarget(string planet) { targetBody = FlightGlobals.Bodies.FirstOrDefault(body => body.bodyName.ToLower() == planet.ToLower()); if (targetBody == null) { StnSciScenario.LogError("Couldn't find planet: " + planet); return(false); } return(true); }
private bool SetExperiment(string exp) { experimentType = PartLoader.getPartInfoByName(exp); if (experimentType == null) { StnSciScenario.LogError("Couldn't find experiment part: " + exp); return(false); } return(true); }
// Thanks to John D. Cook (johndcook.com) for this public domain random variate code // Get normal (Gaussian) random sample with specified mean and standard deviation static double GetNormal(double mean = 0.0, double standardDeviation = 1.0) { if (standardDeviation <= 0.0) { StnSciScenario.LogWarning("Invalid standard deviation: " + standardDeviation); return(0); } // Use Box-Muller algorithm double u1 = GetUniform(); double u2 = GetUniform(); double r = Math.Sqrt(-2.0 * Math.Log(u1)); double theta = 2.0 * Math.PI * u2; return(mean + standardDeviation * r * Math.Sin(theta)); }
protected override void OnUpdate() { base.OnUpdate(); if (lastUpdate > UnityEngine.Time.realtimeSinceStartup + .1) { return; } CelestialBody targetBody = StnSciParameter.getTargetBody(this); AvailablePart experimentType = StnSciParameter.getExperimentType(this); if (targetBody == null || experimentType == null) { if (targetBody == null || experimentType == null) { StnSciScenario.Log("targetBody or experimentType is null"); return; } } lastUpdate = UnityEngine.Time.realtimeSinceStartup; Vessel vessel = FlightGlobals.ActiveVessel; if (vessel != null) { foreach (Part part in vessel.Parts) { if (part.name == experimentType.name) { StationExperiment e = part.FindModuleImplementing <StationExperiment>(); if (e != null) { if (e.completed >= this.Root.DateAccepted && e.completed > e.launched) { ScienceData[] data = e.GetData(); foreach (ScienceData datum in data) { if (datum.subjectID.ToLower().Contains("@" + targetBody.name.ToLower() + "inspace")) { SetComplete(); return; } } } } } } } SetIncomplete(); }
private void OnVesselCreate(Vessel vessel) { StnSciScenario.Log("OnVesselCreate"); AvailablePart experimentType = StnSciParameter.getExperimentType(this); if (experimentType == null) { return; } foreach (Part part in vessel.Parts) { if (part.name == experimentType.name) { StationExperiment e = part.FindModuleImplementing <StationExperiment>(); if (e != null) { e.launched = (float)Planetarium.GetUniversalTime(); } } } }
static double GetGamma(double shape, double scale) { // Implementation based on "A Simple Method for Generating Gamma Variables" // by George Marsaglia and Wai Wan Tsang. ACM Transactions on Mathematical Software // Vol 26, No 3, September 2000, pages 363-372. double d, c, x, xsquared, v, u; if (shape >= 1.0) { d = shape - 1.0 / 3.0; c = 1.0 / Math.Sqrt(9.0 * d); for (;;) { do { x = GetNormal(); v = 1.0 + c * x; }while (v <= 0.0); v = v * v * v; u = GetUniform(); xsquared = x * x; if (u < 1.0 - .0331 * xsquared * xsquared || Math.Log(u) < 0.5 * xsquared + d * (1.0 - v + Math.Log(v))) { return(scale * d * v); } } } else if (shape <= 0.0) { StnSciScenario.LogWarning("Invalid Gamma shape: " + shape); return(0); } else { double g = GetGamma(shape + 1.0, 1.0); double w = GetUniform(); return(scale * g * Math.Pow(w, 1.0 / shape)); } }
private void OnRecovery(Vessel vessel) { StnSciScenario.Log("Recovering " + vessel.vesselName); CelestialBody targetBody = StnSciParameter.getTargetBody(this); AvailablePart experimentType = StnSciParameter.getExperimentType(this); if (targetBody == null || experimentType == null) { StnSciScenario.Log("targetBody or experimentType is null"); return; } foreach (Part part in vessel.Parts) { if (part.name == experimentType.name) { StationExperiment e = part.FindModuleImplementing <StationExperiment>(); if (e != null) { if (e.launched >= this.Root.DateAccepted && e.completed >= e.launched) { ScienceData[] data = e.GetData(); foreach (ScienceData datum in data) { if (datum.subjectID.ToLower().Contains("@" + targetBody.name.ToLower() + "inspace")) { StnSciParameter parent = this.Parent as StnSciParameter; SetComplete(); if (parent != null) { parent.Complete(); } return; } } } } } } SetIncomplete(); }
protected override bool Generate() { StnSciScenario.Log("Considering a StatSci contract"); if (ActiveCount() >= StnSciScenario.Instance.settings.maxContracts) { /*StnSciScenario.Log("StationScience contracts cap hit (" + * StnSciScenario.Instance.settings.maxContracts + ").");*/ return(false); } double xp = StnSciScenario.Instance.xp + Reputation.Instance.reputation * StnSciScenario.Instance.settings.reputationFactor; if (this.Prestige == ContractPrestige.Trivial) { xp *= StnSciScenario.Instance.settings.trivialMultiplier; } if (this.Prestige == ContractPrestige.Significant) { xp *= StnSciScenario.Instance.settings.significantMultiplier; } if (this.Prestige == ContractPrestige.Exceptional) { xp *= StnSciScenario.Instance.settings.exceptionalMultiplier; } if (xp <= 0.5) { xp = 0.5; } StnSciScenario.Log("checking unlocked experiements"); List <string> experiments = GetUnlockedExperiments(); StnSciScenario.Log("experiements = " + experiments + " checking unlocked bodies"); List <CelestialBody> bodies = GetBodies_Reached(true, false); StnSciScenario.Log("bodies = " + bodies); List <ContractCandidate> candidates = new List <ContractCandidate>(); double totalWeight = 0.0; //Get most difficult combination of planet and experiment that doesn't exceed random difficulty target foreach (var exp in experiments) { StnSciScenario.Log("Experiment: " + exp); double expValue; try { expValue = StnSciScenario.Instance.settings.experimentChallenge[exp]; } catch (KeyNotFoundException) { continue; } foreach (var body in bodies) { StnSciScenario.Log("Body: " + body.name); int acount = ActiveCount(exp, body); if (acount > 0) { StnSciScenario.Log("Contract already active!"); continue; } double plaValue; try { plaValue = StnSciScenario.Instance.settings.planetChallenge[body.name]; } catch (KeyNotFoundException) { continue; } ContractCandidate candidate = new ContractCandidate(); candidate.body = body; candidate.experiment = exp; candidate.value = expValue * plaValue; /* log-gaussian function; * when val equals xp, weight is 1 * when val is half of xp, weight is .5 */ candidate.weight = Math.Exp(-Math.Pow(Math.Log(candidate.value / xp, 2), 2) / (2 * Math.Pow(2 / 2.355, 2))); candidates.Add(candidate); totalWeight += candidate.weight; } } StnSciScenario.Log("Candidate List: " + candidates.Count); double rand = GetUniform() * totalWeight; ContractCandidate chosen = null; foreach (var cand in candidates) { if (rand <= cand.weight) { chosen = cand; break; } rand -= cand.weight; } if (chosen == null) { StnSciScenario.LogError("Couldn't find appropriate planet/experiment!"); return(false); } if (!SetExperiment(chosen.experiment)) { return(false); } targetBody = chosen.body; this.value = chosen.value; this.AddParameter(new Parameters.StnSciParameter(experimentType, targetBody), null); int ccount = CompletedCount(experimentType.name, targetBody); bool first_time = (ccount == 0); float v = (float)this.value; base.SetExpiry(); float sciReward = StnSciScenario.Instance.settings.contractScience.calcReward(v, first_time); StnSciScenario.Log("SciReward: " + sciReward); base.SetScience(sciReward, targetBody); base.SetDeadlineYears(StnSciScenario.Instance.settings.contractDeadline.calcReward(v, first_time), targetBody); base.SetReputation(StnSciScenario.Instance.settings.contractReputation.calcReward(v, first_time), StnSciScenario.Instance.settings.contractReputation.calcFailure(v, first_time), targetBody); base.SetFunds(StnSciScenario.Instance.settings.contractFunds.calcAdvance(v, first_time), StnSciScenario.Instance.settings.contractFunds.calcReward(v, first_time), StnSciScenario.Instance.settings.contractFunds.calcFailure(v, first_time), targetBody); return(true); }