private void OnVesselRecoveryProcessing(ProtoVessel data0, MissionRecoveryDialog data1, float data2) { ScienceAIVesselModule mod = data0.vesselRef.GetComponent <ScienceAIVesselModule>(); if (mod.active) { foreach (ProtoPartSnapshot part in data0.protoPartSnapshots) { if (part.persistentId == mod.partID) { foreach (ProtoPartModuleSnapshot partmodule in part.modules) { if (partmodule.moduleName == "ModuleScienceContainer") { ConfigNode node = partmodule.moduleValues; node.RemoveNodes("ScienceData"); foreach (ScienceAIData result in mod.results) { node.AddNode("ScienceData", result.GetConfigNode()); } break; } } } } } }
public void vesselRecoveryProcessingEvent(ProtoVessel pvessel, MissionRecoveryDialog dialog, float recoveryFactor) { BeanCounter.LogFormatted_DebugOnly("---------- vesselRecoveryProcessingEvent ------------"); BeanCounter.LogFormatted_DebugOnly("recoveryFactor: {0:f3}", recoveryFactor); BeanCounter.LogFormatted_DebugOnly("Vessel root missionID: {0}", BCUtils.GetVesselMissionID(pvessel)); // Get a list of every missionID from the recovered parts List <uint> recovered_mission_ids = (from ppart in pvessel.protoPartSnapshots select ppart.missionID).ToList(); // Get a list of every unique part ID so we can match them up List <uint> recovered_part_ids = (from ppart in pvessel.protoPartSnapshots select ppart.flightID).ToList(); // Now lets get all of the launches that contain recovered parts List <BCLaunchData> recovered_launches = (from launch in OATBeanCounterData.data.launches where recovered_mission_ids.Contains(launch.missionID) select launch).ToList(); // And finally we get the full list of every recovered part so we can flag them all as recovered var recoveredparts = from launch in recovered_launches from part in launch.parts where recovered_part_ids.Contains(part.uid) select part; foreach (BCVesselPartData partdata in recoveredparts) { BeanCounter.LogFormatted_DebugOnly("Flagging part as recovered: {0} - {1}", partdata.partName, partdata.uid); partdata.status = BCVesselPartStatus.Recovered; } BCRecoveryData recovery = new BCRecoveryData(true); OATBeanCounterData.data.recoveries.Add(recovery); recovery.partIDs = recovered_part_ids; recovery.recoveryFactor = recoveryFactor; // Try to match this to the transaction BCTransactionData transaction = (from trans in OATBeanCounterData.data.transactions where trans.time == HighLogic.fetch.currentGame.UniversalTime && trans.reason == TransactionReasons.VesselRecovery select trans).SingleOrDefault(); if (transaction != null) { BeanCounter.LogFormatted_DebugOnly("Found matching transaction for this recovery: {0}", transaction.id); recovery.transactionID = transaction.id; transaction.dataID = recovery.id; } BeanCounter.LogFormatted_DebugOnly("--------- /vesselRecoveryProcessingEvent ------------"); }
public void vesselRecoveryProcessingEvent(ProtoVessel pvessel, MissionRecoveryDialog dialog, float recoveryFactor) { BeanCounter.LogFormatted_DebugOnly("---------- vesselRecoveryProcessingEvent ------------"); BeanCounter.LogFormatted_DebugOnly("recoveryFactor: {0:f3}", recoveryFactor); BeanCounter.LogFormatted_DebugOnly("Vessel root missionID: {0}", BCUtils.GetVesselMissionID(pvessel)); // Get a list of every missionID from the recovered parts List<uint> recovered_mission_ids = (from ppart in pvessel.protoPartSnapshots select ppart.missionID).ToList(); // Get a list of every unique part ID so we can match them up List<uint> recovered_part_ids = (from ppart in pvessel.protoPartSnapshots select ppart.flightID).ToList(); // Now lets get all of the launches that contain recovered parts List<BCLaunchData> recovered_launches = (from launch in OATBeanCounterData.data.launches where recovered_mission_ids.Contains(launch.missionID) select launch).ToList(); // And finally we get the full list of every recovered part so we can flag them all as recovered var recoveredparts = from launch in recovered_launches from part in launch.parts where recovered_part_ids.Contains(part.uid) select part; foreach(BCVesselPartData partdata in recoveredparts) { BeanCounter.LogFormatted_DebugOnly("Flagging part as recovered: {0} - {1}", partdata.partName, partdata.uid); partdata.status = BCVesselPartStatus.Recovered; } BCRecoveryData recovery = new BCRecoveryData(true); OATBeanCounterData.data.recoveries.Add(recovery); recovery.partIDs = recovered_part_ids; recovery.recoveryFactor = recoveryFactor; // Try to match this to the transaction BCTransactionData transaction = (from trans in OATBeanCounterData.data.transactions where trans.time == HighLogic.fetch.currentGame.UniversalTime && trans.reason == TransactionReasons.VesselRecovery select trans).SingleOrDefault(); if (transaction != null) { BeanCounter.LogFormatted_DebugOnly("Found matching transaction for this recovery: {0}", transaction.id); recovery.transactionID = transaction.id; transaction.dataID = recovery.id; } BeanCounter.LogFormatted_DebugOnly("--------- /vesselRecoveryProcessingEvent ------------"); }
void onVesselRecoveryProcessing(ProtoVessel vessel, MissionRecoveryDialog d, float f) { double UT = Planetarium.GetUniversalTime(); var crew = vessel.GetVesselCrew(); foreach (var kerbal in crew) { ExperienceTracker.instance.FinishAllTasks(kerbal, UT); } }
internal void OnRecoveryProcessing(ProtoVessel data0, MissionRecoveryDialog data1, float data2) { foreach (var launch in launches) { if (data0.vesselID.ToString() == launch.shipID) { launch.SetSciencePoints(data1.scienceEarned); } } FlightGUI.SaveData(); }
private void OnVesselRecoveryProcessing(ProtoVessel pv, MissionRecoveryDialog dlg, float idunno) { List <MessageSystem.Message> messages = new List <MessageSystem.Message>(); foreach (var group in pv.protoPartSnapshots.SelectMany(p => p.resources).GroupBy(r => r.resourceName)) { if (ColonizationResearchScenario.Instance.TryParseTieredResourceName(group.Key, out TieredResource tieredResource, out TechTier tier)) { float amount = (float)group.Sum(r => r.amount); float repGain = tieredResource.GetReputationGain(tier, amount); if (repGain > 0) { dlg.reputationEarned += repGain; MessageSystem.Instance.AddMessage(new MessageSystem.Message( "Shinies!", $"You get {repGain:N} reputation for selling {amount:N} {tier.DisplayName()} {tieredResource.DisplayName}.", MessageSystemButton.MessageButtonColor.GREEN, MessageSystemButton.ButtonIcons.ACHIEVE)); } } } }
// recoveryFraction - percentage of funds added after recovery, based on distance from KSC public void onVesselRecoveryProcessing(ProtoVessel v, MissionRecoveryDialog dialog, float recoveryFraction) { KerbalGUIManager.print("[rusty] onVesselRecoveryProcessing: x = " + recoveryFraction); KerbalGUIManager.print("[rusty] onVesselRecoveryProcessing: AddFunds = " + -dialog.fundsEarned); // deduct recovered funds Funding.Instance.AddFunds(-dialog.fundsEarned, TransactionReasons.VesselRecovery); // calculate distance // longest possible ground distance on Kerbin [km] //const double HALF_CIRCLE = 2 * Mathf.PI * 600 / 2; // distance from KSC [m] double distance = SpaceCenter.Instance.GreatCircleDistance(SpaceCenter.Instance.cb.GetRelSurfaceNVector(v.latitude, v.longitude)); // KSC is supposedly 25 m^2 in size, so no more than 5 km can be considered free if (distance <= 5000.0) { distance = 0.0f; } KerbalGUIManager.print("[rusty] onVesselRecoveryProcessing: distance = " + distance + " m"); // calculate recovery price // price of 1 metric tone per 1km const double recoveryRate = 100.0; double recoveryPrice = (double)vesselMass * (distance / 1000.0) * recoveryRate; // reset funds dialog.fundsEarned = 0.0; // show recovery GUI GUIRecovery wndRecovery = new GUIRecovery(); wndRecovery.vesselMass = vesselMass; wndRecovery.vesselTitle = v.vesselName; wndRecovery.recoveryPrice = recoveryPrice; wndRecovery.recoveryDistance = Math.Ceiling(distance / 1000.0); wndRecovery.show(); }
public void onGUIRecoveryDialogSpawn(MissionRecoveryDialog dialog) { KerbalGUIManager.print("[rusty] onGUIRecoveryDialogSpawn"); }
void OnGUIRecoveryDialogSpawn(MissionRecoveryDialog dialog) { m_UIHidden = true; }
private void VesselRecoveryProcessing(ProtoVessel v, MissionRecoveryDialog mrDialog, float data) { Debug.Log("[VR] - Vessel recovery processing"); List <string> retirementChanges = new List <string>(); List <string> inactivity = new List <string>(); double UT = Planetarium.GetUniversalTime(); // normally we would use v.missionTime, but that doesn't seem to update // when you're not actually controlling the vessel double elapsedTime = UT - v.launchTime; // When flight duration was too short, mission training should not be set as expired. // This can happen when an on-the-pad failure occurs and the vessel is recovered. // We could perhaps override this if they're not actually in flight // (if the user didn't recover right from the pad I think this is a fair assumption) if (elapsedTime < settings.minFlightDurationSecondsForTrainingExpire) { Debug.Log("[VR] - mission time too short for crew to be inactive (elapsed time was " + elapsedTime + ", settings set for " + settings.minFlightDurationSecondsForTrainingExpire + ")"); return; } foreach (ProtoCrewMember pcm in v.GetVesselCrew()) { Debug.Log("[VR] - Found ProtoCrewMember: " + pcm.displayName); bool hasSpace = false; bool hasOrbit = false; bool hasEVA = false; bool hasEVAOther = false; bool hasOther = false; bool hasOrbitOther = false; bool hasLandOther = false; int curFlight = pcm.careerLog.Last().flight; foreach (FlightLog.Entry e in pcm.careerLog.Entries) { if (e.type == "TRAINING_mission") { SetExpiration(pcm.name, e, Planetarium.GetUniversalTime()); } if (e.flight != curFlight) { continue; } bool isOther = false; if (!string.IsNullOrEmpty(e.target) && e.target != Planetarium.fetch.Home.name) { isOther = hasOther = true; } if (!string.IsNullOrEmpty(e.type)) { switch (e.type) { case "Suborbit": hasSpace = true; break; case "Orbit": if (isOther) { hasOrbitOther = true; } else { hasOrbit = true; } break; case "ExitVessel": if (isOther) { hasEVAOther = true; } else { hasEVA = true; } break; case "Land": if (isOther) { hasLandOther = true; } break; default: break; } } } double multiplier = 1d; double constant = 0.5d; if (hasSpace) { multiplier += settings.recSpace.x; constant += settings.recSpace.y; } if (hasOrbit) { multiplier += settings.recOrbit.x; constant += settings.recOrbit.y; } if (hasOther) { multiplier += settings.recOtherBody.x; constant += settings.recOtherBody.y; } if (hasOrbit && hasEVA) // EVA should only count while in orbit, not when walking on Earth { multiplier += settings.recEVA.x; constant += settings.recEVA.y; } if (hasEVAOther) { multiplier += settings.recEVAOther.x; constant += settings.recEVAOther.y; } if (hasOrbitOther) { multiplier += settings.recOrbitOther.x; constant += settings.recOrbitOther.y; } if (hasLandOther) { multiplier += settings.recLandOther.x; constant += settings.recLandOther.y; } double retTime; if (kerbalRetireTimes.TryGetValue(pcm.name, out retTime)) { double offset = constant * 86400d * settings.retireOffsetBaseMult / (1 + Math.Pow(Math.Max(curFlight + settings.retireOffsetFlightNumOffset, 0d), settings.retireOffsetFlightNumPow) * UtilMath.Lerp(settings.retireOffsetStupidMin, settings.retireOffsetStupidMax, pcm.stupidity)); if (offset > 0d) { retTime += offset; kerbalRetireTimes[pcm.name] = retTime; retirementChanges.Add("\n" + pcm.name + ", no earlier than " + KSPUtil.PrintDate(retTime, false)); } } multiplier /= (ScenarioUpgradeableFacilities.GetFacilityLevel(SpaceCenterFacility.AstronautComplex) + 1d); double inactiveTime = elapsedTime * multiplier + constant * 86400d; pcm.SetInactive(inactiveTime, false); inactivity.Add("\n" + pcm.name + ", until " + KSPUtil.PrintDate(inactiveTime + UT, true, false)); } if (inactivity.Count > 0) { Debug.Log("[VR] - showing on leave message"); string msgStr = "The following crew members will be on leave:"; foreach (string s in inactivity) { msgStr += s; } if (retirementEnabled && retirementChanges.Count > 0) { msgStr += "\n\nThe following retirement changes have occurred:"; foreach (string s in retirementChanges) { msgStr += s; } } PopupDialog.SpawnPopupDialog(new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), "CrewUpdateNotification", "Crew Updates", msgStr, "OK", true, HighLogic.UISkin); } }
void OnGUIRecoveryDialogDespawn(MissionRecoveryDialog dialog) { m_UIHidden = false; }
private void recoverySpawn(MissionRecoveryDialog d) { overlay = true; }
private void VesselRecoveryProcessing(ProtoVessel v, MissionRecoveryDialog mrDialog, float data) { Debug.Log("[RP-0] - Vessel recovery processing"); var retirementChanges = new List <string>(); var inactivity = new List <string>(); double UT = KSPUtils.GetUT(); // normally we would use v.missionTime, but that doesn't seem to update // when you're not actually controlling the vessel double elapsedTime = UT - v.launchTime; Debug.Log($"[RP-0] mission elapsedTime: {KSPUtil.PrintDateDeltaCompact(elapsedTime, true, true)}"); // When flight duration was too short, mission training should not be set as expired. // This can happen when an on-the-pad failure occurs and the vessel is recovered. // We could perhaps override this if they're not actually in flight // (if the user didn't recover right from the pad I think this is a fair assumption) if (elapsedTime < Settings.minFlightDurationSecondsForTrainingExpire) { Debug.Log($"[RP-0] - mission time too short for crew to be inactive (elapsed time was {elapsedTime}, settings set for {Settings.minFlightDurationSecondsForTrainingExpire})"); return; } var validStatuses = new List <string> { FlightLog.EntryType.Flight.ToString(), Situation_FlightHigh, FlightLog.EntryType.Suborbit.ToString(), FlightLog.EntryType.Orbit.ToString(), FlightLog.EntryType.ExitVessel.ToString(), FlightLog.EntryType.Land.ToString(), FlightLog.EntryType.Flyby.ToString() }; foreach (ProtoCrewMember pcm in v.GetVesselCrew()) { Debug.Log("[RP-0] - Found ProtoCrewMember: " + pcm.displayName); var allFlightsDict = new Dictionary <string, int>(); int curFlight = pcm.careerLog.Last().flight; double inactivityMult = 0; double retirementMult = 0; foreach (FlightLog.Entry e in pcm.careerLog.Entries) { if (e.type == "Nationality") { continue; } if (e.type == TrainingType_Mission) { SetExpiration(pcm.name, e, KSPUtils.GetUT()); } if (validStatuses.Contains(e.type)) { int situationCount; var key = $"{e.target}-{e.type}"; if (allFlightsDict.ContainsKey(key)) { situationCount = allFlightsDict[key]; allFlightsDict[key] = ++situationCount; } else { situationCount = 1; allFlightsDict.Add(key, situationCount); } if (e.flight != curFlight) { continue; } if (TryGetBestSituationMatch(e.target, e.type, "Retire", out double situationMult)) { double countMult = 1 + Math.Pow(situationCount - 1, Settings.retireOffsetFlightNumPow); retirementMult += situationMult / countMult; } if (TryGetBestSituationMatch(e.target, e.type, "Inactive", out double inactivMult)) { inactivityMult += inactivMult; } } } Debug.Log("[RP-0] retirementMult: " + retirementMult); Debug.Log("[RP-0] inactivityMult: " + inactivityMult); double acMult = ScenarioUpgradeableFacilities.GetFacilityLevel(SpaceCenterFacility.AstronautComplex) + 1; Debug.Log("[RP-0] AC multiplier: " + acMult); if (KerbalRetireTimes.TryGetValue(pcm.name, out double retTime)) { double stupidityPenalty = UtilMath.Lerp(Settings.retireOffsetStupidMin, Settings.retireOffsetStupidMax, pcm.stupidity); Debug.Log($"[RP-0] stupidityPenalty for {pcm.stupidity}: {stupidityPenalty}"); double retireOffset = retirementMult * 86400 * Settings.retireOffsetBaseMult / stupidityPenalty; if (retireOffset > 0) { KerbalRetireIncreases.TryGetValue(pcm.name, out double retIncreaseTotal); retIncreaseTotal += retireOffset; if (retIncreaseTotal > Settings.retireIncreaseCap) { // Cap the total retirement increase at a specific number of years retireOffset -= retIncreaseTotal - Settings.retireIncreaseCap; retIncreaseTotal = Settings.retireIncreaseCap; } KerbalRetireIncreases[pcm.name] = retIncreaseTotal; string sRetireOffset = KSPUtil.PrintDateDelta(retireOffset, false, false); Debug.Log("[RP-0] retire date increased by: " + sRetireOffset); retTime += retireOffset; KerbalRetireTimes[pcm.name] = retTime; retirementChanges.Add($"\n{pcm.name}, +{sRetireOffset}, no earlier than {KSPUtil.PrintDate(retTime, false)}"); } } inactivityMult = Math.Max(1, inactivityMult); double elapsedTimeDays = elapsedTime / 86400; double inactiveTimeDays = Math.Pow(Math.Max(Settings.inactivityMinFlightDurationDays, elapsedTimeDays), Settings.inactivityFlightDurationExponent) * Math.Min(Settings.inactivityMaxSituationMult, inactivityMult) / acMult; double inactiveTime = inactiveTimeDays * 86400; Debug.Log("[RP-0] inactive for: " + KSPUtil.PrintDateDeltaCompact(inactiveTime, true, false)); pcm.SetInactive(inactiveTime, false); inactivity.Add($"\n{pcm.name}, until {KSPUtil.PrintDate(inactiveTime + UT, true, false)}"); } if (inactivity.Count > 0) { StringBuilder sb = new StringBuilder(); sb.Append("The following crew members will be on leave:"); foreach (string s in inactivity) { sb.Append(s); } if (RetirementEnabled && retirementChanges.Count > 0) { sb.Append("\n\nThe following retirement changes have occurred:"); foreach (string s in retirementChanges) { sb.Append(s); } } PopupDialog.SpawnPopupDialog(new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), "CrewUpdateNotification", "Crew Updates", sb.ToString(), "OK", true, HighLogic.UISkin); } }
private void recoveryDeSpawn(MissionRecoveryDialog d) { overlay = false; }
void VesselRecoveryProcessing(ProtoVessel v, MissionRecoveryDialog dialog, float score) { // note: // this function accumulate science stored in drives on recovery, // and visualize the data in the recovery dialog window // do nothing if science system is disabled, or in sandbox mode if (!Features.Science || HighLogic.CurrentGame.Mode == Game.Modes.SANDBOX) return; // get the drive data from DB uint root_id = v.protoPartSnapshots[v.rootIndex].flightID; if (!DB.vessels.ContainsKey(root_id)) return; Drive drive = DB.vessels[root_id].drive; // for each file in the drive foreach (var p in drive.files) { // shortcuts string filename = p.Key; File file = p.Value; // de-buffer partially transmitted data file.size += file.buff; file.buff = 0.0; // get subject ScienceSubject subject = ResearchAndDevelopment.GetSubjectByID(filename); // credit science double credits = Science.Credit(filename, file.size, false, v); // create science widged ScienceSubjectWidget widged = ScienceSubjectWidget.Create ( subject, // subject (float)file.size, // data gathered (float)credits, // science points dialog // recovery dialog ); // add widget to dialog dialog.AddDataWidget(widged); // add science credits to total dialog.scienceEarned += (float)credits; } // for each sample in the drive // for each file in the drive foreach (var p in drive.samples) { // shortcuts string filename = p.Key; Sample sample = p.Value; // get subject ScienceSubject subject = ResearchAndDevelopment.GetSubjectByID(filename); // credit science double credits = Science.Credit(filename, sample.size, false, v); // create science widged ScienceSubjectWidget widged = ScienceSubjectWidget.Create ( subject, // subject (float)sample.size, // data gathered (float)credits, // science points dialog // recovery dialog ); // add widget to dialog dialog.AddDataWidget(widged); // add science credits to total dialog.scienceEarned += (float)credits; } }
void OnVesselRecoveryProcessing(ProtoVessel vessel, MissionRecoveryDialog recoveryDialog, float blah) { print("Vessel Name(ISRecoverable:float): " + vessel.vesselName + "(" + vessel.vesselRef.IsRecoverable + ":" + blah + ")"); print("Recovery Dialog: " + string.Join(" |\r\n ", recoveryDialog.GetType().GetMembers(System.Reflection.BindingFlags.NonPublic).Select(m=> m.MemberType+": "+ m.ReflectedType + " "+ m.Name).ToArray())); // https://code.google.com/p/ssaad/source/browse/ // public void handleRecoveryProcessing(ProtoVessel pv, MissionRecoveryDialog d, float f) { // foreach (JMPScienceSubject s in scienceData.Keys) { // float sci = ResearchAndDevelopment.GetScienceValue(scienceData[s], s.subject); // ResearchAndDevelopment.Instance.SubmitScienceData(scienceData[s], s.subject); // // d.AddDataWidget(new MissionRecoveryDialog.ScienceSubjectWidget(s.subject, scienceData[s], sci)); // } // // scienceData.Clear(); // capacityUsed = 0; // part.RequestResource("DataStorage", -capacity); // // GameEvents.onVesselRecoveryProcessing.Remove(handleRecoveryProcessing); // } // Figured it out, I have to call ResearchAndDevelopment.GetSubjectByID() during recovery processing to get the ScienceSubject to do stuff to. // ProtoVessel => ProtoPartSnapshot => ProtoPartModuleSnapshot => ConfigNode = ProtoPartModuleSnapshot.moduleValues => ConfigNode.GetValue("nameOfYourField") // public void onVesselRecovered(ProtoVessel vessel) // { // List<ProtoPartSnapshot> partList = vessel.protoPartSnapshots; // foreach (ProtoPartSnapshot a in partList) // { // List<ProtoPartModuleSnapshot> modules = a.modules; // foreach (ProtoPartModuleSnapshot module in modules) // { // if (module.moduleName == "DeepFreezer") // { // ConfigNode node = module.moduleValues; // string FrozenCrew = node.GetValue("FrozenCrew"); // ThawFrozenCrew(FrozenCrew); // } // } // } //} //public void ThawFrozenCrew(String FrozenCrew) //{ // List<String> StoredCrew = FrozenCrew.Split(',').ToList(); // foreach (string frozenkerbal in StoredCrew) // { // foreach (ProtoCrewMember kerbal in HighLogic.CurrentGame.CrewRoster.Crew) //There's probably a more efficient way to find Protocrewmember from the CrewRoster // { // if (kerbal.name == frozenkerbal) // { // kerbal.rosterStatus = ProtoCrewMember.RosterStatus.Available; // ScreenMessages.PostScreenMessage(kerbal.name + " was found in and thawed out.", 5.0f, ScreenMessageStyle.UPPER_CENTER); // } // } // } //} // void RecoveryProcessingCallback(ProtoVessel pv, MissionRecoveryDialog dlg, float recovery) //{ // float repEarned = dlg.reputationEarned; // float sciEarned = dlg.scienceEarned; // double fundsEarned = dlg.fundsEarned; // Debug.Log("[Recovery Timer] Rep: " + repEarned); // Debug.Log("[Recovery Timer] Sci: " + sciEarned); // Debug.Log("[Recovery Timer] Funds: " + fundsEarned); // double currentUniversalTime = Planetarium.GetUniversalTime(); // Debug.Log("[Recovery Timer] Time of recovery: " + currentUniversalTime); //} }
// recoveryFraction - percentage of funds added after recovery, based on distance from KSC public void onVesselRecoveryProcessing(ProtoVessel v, MissionRecoveryDialog dialog, float recoveryFraction) { KerbalGUIManager.print("[rusty] onVesselRecoveryProcessing"); if (saveVesselLater != null) { //KSP_rusty.Inventory.Add(saveVesselLater); saveVesselLater = null; //return; } Vessel recoveredVessel = null; try { recoveredVessel = Utils.getVesselByGuid(v.vesselID); } catch (Exception e) { KerbalGUIManager.print("[rusty] Exception on trying to find vessel" + e.Message); } if (recoveredVessel == null) { KerbalGUIManager.print("[rusty] onVesselRecoveryProcessing: vessel not found.."); // try by guid from game return; } // deduct recovered funds try { if (HighLogic.CurrentGame.Mode == Game.Modes.CAREER) { Funding.Instance.AddFunds(-dialog.fundsEarned, TransactionReasons.VesselRecovery); } } catch (Exception e) { KerbalGUIManager.print("[rusty] Exception on deducting funds " + e.Message); } // calculate distance // longest possible ground distance on Kerbin [km] //const double HALF_CIRCLE = 2 * Mathf.PI * 600 / 2; // distance from KSC [m] double distance = 0.0; try { distance = SpaceCenter.Instance.GreatCircleDistance(SpaceCenter.Instance.cb.GetRelSurfaceNVector(v.latitude, v.longitude)); } catch (Exception e) { KerbalGUIManager.print("[rusty] Exception on calculating distance" + e.Message); } // KSC is supposedly 25 m^2 in size, so no more than 5 km can be considered free if (distance <= 5000.0) { distance = 0.0f; } KerbalGUIManager.print("[rusty] distance calculated: " + distance); // calculate recovery price // price of 1 metric tone per 1km const double recoveryRate = 100.0; double recoveryPrice = 1000.0 + (double)recoveredVessel.GetTotalMass() * (distance / 1000.0) * recoveryRate; KerbalGUIManager.print("[rusty] recoveryPrice calculated: " + recoveryPrice); // reset funds dialog.fundsEarned = 0.0; // show recovery GUI KSP_rusty.wndRecovery.vesselMass = recoveredVessel.GetTotalMass(); KSP_rusty.wndRecovery.vesselTitle = recoveredVessel.vesselName; KSP_rusty.wndRecovery.recoveryPrice = recoveryPrice; KSP_rusty.wndRecovery.recoveryDistance = Math.Ceiling(distance / 1000.0); KSP_rusty.wndRecovery.show(); KerbalGUIManager.print("[rusty] wndRecovery shown"); /// RECOVER VESSEL KerbalGUIManager.print("[rusty] Trying to recover. Guid: " + v.vesselID.ToString().Replace("-", "")); ConfigNode recoveredVesselConfigNode = Utils.getVesselConfigByGuidFromGame(v.vesselID); if (recoveredVesselConfigNode == null) { KerbalGUIManager.print("[rusty] recoveredVesselConfigNode is empty"); } // adjust data /// ADJUST VESSEL NODE // get values string name = recoveredVesselConfigNode.GetValue("name"); if (name == null) name = ""; // set values recoveredVesselConfigNode.SetValue("type", "VAB"); recoveredVesselConfigNode.SetValue("ship", name, true); recoveredVesselConfigNode.SetValue("description", "", true); // remove values recoveredVesselConfigNode.RemoveNode("ORBIT"); recoveredVesselConfigNode.RemoveNode("ACTIONGROUPS"); recoveredVesselConfigNode.RemoveNode("DISCOVERY"); recoveredVesselConfigNode.RemoveNode("FLIGHTPLAN"); recoveredVesselConfigNode.RemoveNode("CTRLSTATE"); recoveredVesselConfigNode.RemoveValues(new string[] {"pid", "name", "sit", "landed", "landedAt", "splashed", "met", "lct", "lat", "lon", "alt", "hgt", "nrm", "rot", "CoM", "stg", "prst", "ref", "ctrl", "cPch", "cHdg", "cMod", "root"}); // cycle proto part snapshots // gather needed information and internal values KerbalGUIManager.print("[rusty] We have " + v.protoPartSnapshots.Count + " part snapshots"); ConfigNode[] configParts = recoveredVesselConfigNode.GetNodes("PART"); KerbalGUIManager.print("[rusty] And we have " + (configParts.GetUpperBound(0)+1) + " parts"); int pid = 0; Vector3 rootPos = Vector3.zero; recoveredVesselConfigNode.Save("D:/rusty_from_flight_state.cfg"); foreach (ProtoPartSnapshot snapshot in v.protoPartSnapshots) { KerbalGUIManager.print("[rusty] SNAP " + snapshot.partName + "_" + snapshot.craftID); if (configParts[pid] == null) { KerbalGUIManager.print("[rusty] Mathing not found. id: " + pid); ++pid; continue; } KerbalGUIManager.print("[rusty] PART " + configParts[pid].GetValue("name") + "_" + configParts[pid].GetValue("cid")); configParts[pid].SetValue("pos", configParts[pid].GetValue("position")); // get values string name_Part = configParts[pid].GetValue("name"); string name_partName = "Part"; if (name_Part == "strutConnector" || name_Part == "fuelLine") { name_partName = "CompoundPart"; } string cid = configParts[pid].GetValue("cid"); if (cid != null) name_Part = name_Part + "_" + cid; // remove some values //configParts[pid].RemoveValues(new string[] { "launchID", "parent", "position", "rotation", "mirror", "symMethod", "cid", "uid", "mid", "name" }); // get staging (probably) values int istg = int.Parse(configParts[pid].GetValue("istg")); int dstg = int.Parse(configParts[pid].GetValue("dstg")); int sqor = int.Parse(configParts[pid].GetValue("sqor")); int sepI = int.Parse(configParts[pid].GetValue("sepI")); int sidx = int.Parse(configParts[pid].GetValue("sidx")); int attm = int.Parse(configParts[pid].GetValue("attm")); // something else int sym = 0; try { sym = int.Parse(configParts[pid].GetValue("sym")); } catch (Exception e) { sym = 0; } // attachments string[] attcfg = configParts[pid].GetValues("attN"); string[] srfAttcfg = configParts[pid].GetValues("srfN"); // remove some more values /*configParts[pid].RemoveValues(new string[] { "istg", "dstg", "sqor", "sepI", "sidx", "attm", "srfN", "attN", "mass", "temp", "expt", "state" , "connected" , "attached" , "flag" , "rTrf", "modCost", "crew" }); */ // poof! configParts[pid].ClearValues(); // move the part, so that when it appears, appears not on the ground of VAB/SPH snapshot.position += new Vector3d(1.0, 14.0, 0.0); // root position to offset all other parts if (pid == 0) { rootPos = snapshot.position; } // set values configParts[pid].SetValue("part", name_Part, true); configParts[pid].SetValue("partName", name_partName, true); // how to get attPos? // Should be ok for now to give it's value to attPos0 and keep attPos a zero Vector3d attPos = Vector3d.zero; Vector3d attPos0 = snapshot.position - rootPos; // - attPos // basic part position in assembly configParts[pid].SetValue("pos", Utils.Vector3dToString(snapshot.position), true); // moved offset by offset gizmo configParts[pid].SetValue("attPos", "0,0,0", true); // this.attPos0 = this.pos - root.pos; configParts[pid].SetValue("attPos0", Utils.Vector3dToString(attPos0), true); configParts[pid].SetValue("rot", Utils.QuaternionToString(snapshot.rotation), true); configParts[pid].SetValue("attRot", Utils.QuaternionToString(snapshot.rotation), true); // not sure configParts[pid].SetValue("attRot0", "0,0,0,1", true); // not sure configParts[pid].SetValue("mir", Utils.Vector3ToString(snapshot.mirror), true); configParts[pid].SetValue("symMethod", ""+snapshot.symMethod, true); // add some previuosly removed values configParts[pid].SetValue("istg", istg.ToString(), true); configParts[pid].SetValue("dstg", dstg.ToString(), true); configParts[pid].SetValue("sqor", sqor.ToString(), true); configParts[pid].SetValue("sepI", sepI.ToString(), true); configParts[pid].SetValue("sidx", sidx.ToString(), true); configParts[pid].SetValue("attm", attm.ToString(), true); configParts[pid].SetValue("modCost", "0", true); configParts[pid].SetValue("modMass", "0", true); configParts[pid].SetValue("modSize", "(0.0, 0.0, 0.0)", true); // add attachments KerbalGUIManager.print("[rusty] adding attN attachments"); foreach (string attN in attcfg) { // find if attachment is not negative (unused) string tmp = attN.Replace(" ", ""); string[] attN_spl = tmp.Split(','); int attachId = int.Parse(attN_spl[1]); if (attachId == -1) continue; // get the attachment position: bottom, top, etc.. tmp = attN_spl[0]; // we will use this tmp var to add value to confignode // generate the unique part identifier if (attachId > configParts.GetUpperBound(0)) return; string partId = ""; // if the target parts wasn't yet iterated, use original values if (attachId > pid) { partId = configParts[attachId].GetValue("name") + "_"; partId += configParts[attachId].GetValue("cid"); // of the target target was already iterated, use the new value } else { partId = configParts[attachId].GetValue("part"); } // add to this configNode configParts[pid].AddValue("attN", tmp + "," + partId); } // add sym KerbalGUIManager.print("[rusty] Got sym: " + sym); if (sym > 0 && sym <= configParts.GetUpperBound(0)) { string partId = ""; // if the target parts wasn't yet iterated, use original values if (sym > pid) { partId = configParts[sym].GetValue("name") + "_"; partId += configParts[sym].GetValue("cid"); // of the target target was already iterated, use the new value } else { partId = configParts[sym].GetValue("part"); } // add to this configNode KerbalGUIManager.print("[rusty] Adding sym: " + sym); configParts[pid].AddValue("sym", partId); } // add surface attachments KerbalGUIManager.print("[rusty] adding srfN attachments"); foreach (string srfN in srfAttcfg) { // find if attachment is not negative (unused) string tmp = srfN.Replace(" ", ""); string[] srfN_spl = tmp.Split(','); int attachId = int.Parse(srfN_spl[1]); if (attachId == -1) continue; // get the attachment position: bottom, top, etc.. tmp = srfN_spl[0]; // we will use this tmp var to add value to confignode // generate the unique part identifier if (attachId > configParts.GetUpperBound(0)) return; string partId = ""; // if the target parts wasn't yet iterated, use original values if (attachId > pid) { partId = configParts[attachId].GetValue("name") + "_"; partId += configParts[attachId].GetValue("cid"); // of the target target was already iterated, use the new value } else { partId = configParts[attachId].GetValue("part"); } // add to this configNode configParts[pid].AddValue("srfN", tmp + "," + partId); } // tell your daddy 'hello' if (configParts[snapshot.parentIdx] != null && pid != snapshot.parentIdx) { KerbalGUIManager.print("[rusty] adding link"); configParts[snapshot.parentIdx].AddValue("link", snapshot.partName + "_" + snapshot.craftID); } // add sym links. nope.. "sym" is just "sym" in config. /* if (snapshot.symLinks != null) { KerbalGUIManager.print("[rusty] adding symlinks"); foreach (ProtoPartSnapshot child in snapshot.symLinks) { configParts[pid].AddValue("sym", child.partName + "_" + child.craftID); } } * */ ++pid; } recoveredVesselConfigNode.Save("D:/rusty_after_flight_state.cfg"); KSP_rusty.Inventory.Add(recoveredVesselConfigNode); KerbalGUIManager.print("[rusty] recovered ship added to inventory"); recoveredVessel = null; return; /* if (recoveredVesselConfigNode == null) { KerbalGUIManager.print("[rusty] recoveredVesselConfigNode is empty"); } else { // ADJUST PART NODES ConfigNode[] partNodes = recoveredVesselConfigNode.GetNodes("PART"); if (partNodes != null) { KerbalGUIManager.print("[rusty] adjusting parts"); foreach (ConfigNode partNode in partNodes) { // get values string name_Part = partNode.GetValue("name"); string cid = partNode.GetValue("cid"); if (cid != null) name_Part = name_Part + "_" + cid; string mir = partNode.GetValue("mirror"); string position = partNode.GetValue("position"); // set values partNode.SetValue("part", name_Part, true); partNode.SetValue("partName", "Part", true); partNode.SetValue("mir", mir, true); partNode.SetValue("pos", position, true); partNode.SetValue("attPos0", position, true); // remove values recoveredVesselConfigNode.RemoveValues(new string[] {"name", "cid", "uid", "mid"}); } } KSP_rusty.Inventory.Add(recoveredVesselConfigNode); KerbalGUIManager.print("[rusty] recovered ship added to inventory"); } recoveredVessel = null;*/ }
void VesselRecoveryProcessing(ProtoVessel v, MissionRecoveryDialog dialog, float score) { // note: // this function accumulate science stored in drives on recovery, // and visualize the data in the recovery dialog window // do nothing if science system is disabled, or in sandbox mode if (!Features.Science || HighLogic.CurrentGame.Mode == Game.Modes.SANDBOX) { return; } var vesselID = Lib.VesselID(v); // get the drive data from DB if (!DB.vessels.ContainsKey(vesselID)) { return; } foreach (Drive drive in Drive.GetDrives(v)) { // for each file in the drive foreach (KeyValuePair <string, File> p in drive.files) { // shortcuts string filename = p.Key; File file = p.Value; // de-buffer partially transmitted data file.size += file.buff; file.buff = 0.0; // get subject ScienceSubject subject = ResearchAndDevelopment.GetSubjectByID(filename); // credit science float credits = Science.Credit(filename, file.size, false, v); // create science widged ScienceSubjectWidget widged = ScienceSubjectWidget.Create ( subject, // subject (float)file.size, // data gathered credits, // science points dialog // recovery dialog ); // add widget to dialog dialog.AddDataWidget(widged); // add science credits to total dialog.scienceEarned += (float)credits; } // for each sample in the drive // for each file in the drive foreach (KeyValuePair <string, Sample> p in drive.samples) { // shortcuts string filename = p.Key; Sample sample = p.Value; // get subject ScienceSubject subject = ResearchAndDevelopment.GetSubjectByID(filename); // credit science float credits = Science.Credit(filename, sample.size, false, v); // create science widged ScienceSubjectWidget widged = ScienceSubjectWidget.Create ( subject, // subject (float)sample.size, // data gathered credits, // science points dialog // recovery dialog ); // add widget to dialog dialog.AddDataWidget(widged); // add science credits to total dialog.scienceEarned += (float)credits; } } }
void onVesselRecoveryProcessing(ProtoVessel vessel, MissionRecoveryDialog d, float f) { Debug.Log (String.Format ("[KS Exp] {0}: {1} {2} {3}", "onVesselRecoveryProcessing", vessel, d, f)); }
void OnProcessRecovery(ProtoVessel vessel, MissionRecoveryDialog dialog, float fFloat) { dRecoveryValue = dialog.fundsEarned; PersistenceUtils.savePersistenceBackup(); }
void OnProcessRecovery(ProtoVessel vessel, MissionRecoveryDialog dialog, float fFloat) { if (!disableRemoteRecovery) { if (MiscUtils.CareerStrategyEnabled(HighLogic.CurrentGame)) { if (DebugMode) Debug.Log("KK: OnProcessRecovery"); if (vessel == null) return; if (dialog == null) return; if (DebugMode) Debug.Log("KK: OnProcessRecovery"); dRecoveryValue = dialog.fundsEarned; PersistenceUtils.savePersistenceBackup(); } } }