Skip to content

Instantly share code, notes, and snippets.

@gotmachine
Created March 22, 2021 14:42
Show Gist options
  • Save gotmachine/bb8f840eb36809a9f74b626eb8ccbfbb to your computer and use it in GitHub Desktop.
Save gotmachine/bb8f840eb36809a9f74b626eb8ccbfbb to your computer and use it in GitHub Desktop.
Fix for KSP 1.11+ not accounting for modules implementing IPartCostModifier when refunding parts on vessel recovery
using System;
using KSP.Localization;
using KSP.UI.Screens;
using KSP.UI.Screens.SpaceCenter.MissionSummaryDialog;
using KSP.UI.Util;
using UnityEngine;
namespace TestPlugin
{
[KSPAddon(KSPAddon.Startup.AllGameScenes, false)]
public class FixRecoveryCosts : MonoBehaviour
{
private MissionRecoveryDialog currentDialog;
private double lastFundsRecovered;
private ResourceWidget lastResourceWidget;
private void Start()
{
Version KSPVersion = new Version(Versioning.version_major, Versioning.version_minor, Versioning.Revision);
Version MinVersion = new Version(1, 11, 0);
Version MaxVersion = new Version(1, 11, 9);
if (KSPVersion >= MinVersion && KSPVersion <= MaxVersion)
{
GameEvents.onVesselRecoveryProcessing.Add(OnVesselRecoveryProcessing);
GameEvents.onGUIRecoveryDialogSpawn.Add(OnGUIRecoveryDialogSpawn);
GameEvents.onGUIRecoveryDialogDespawn.Add(OnGUIRecoveryDialogDespawn);
}
this.enabled = false;
}
private void OnDestroy()
{
GameEvents.onVesselRecoveryProcessing.Remove(OnVesselRecoveryProcessing);
GameEvents.onGUIRecoveryDialogSpawn.Remove(OnGUIRecoveryDialogSpawn);
GameEvents.onGUIRecoveryDialogDespawn.Remove(OnGUIRecoveryDialogDespawn);
}
private void OnGUIRecoveryDialogSpawn(MissionRecoveryDialog dialog)
{
this.enabled = true;
ResetFields();
currentDialog = dialog;
}
private void OnGUIRecoveryDialogDespawn(MissionRecoveryDialog dialog)
{
ResetFields();
this.enabled = false;
}
private void OnVesselRecoveryProcessing(ProtoVessel pv, MissionRecoveryDialog mrDialog, float recoveryScore)
{
lastFundsRecovered = 0.0;
int partCount = 0;
if (pv == null)
{
ResetFields();
return;
}
foreach (ProtoPartSnapshot protoPartSnapshot in pv.GetAllProtoPartsIncludingCargo())
{
if (protoPartSnapshot.moduleCosts != 0f)
{
partCount++;
lastFundsRecovered += protoPartSnapshot.moduleCosts;
}
}
lastFundsRecovered *= recoveryScore;
if (lastFundsRecovered != 0.0)
{
Debug.Log($"[VesselRecoveryFix] Extra recovered funds for {pv.vesselName} from partmodules : {lastFundsRecovered}");
Funding.Instance.AddFunds(lastFundsRecovered, TransactionReasons.VesselRecovery);
ConfigNode dummyResNode = new ConfigNode();
dummyResNode.AddValue("name", "dummyRecoveryResDef");
dummyResNode.AddValue("displayName", $"Part modules recovered from {partCount} part(s) :");
PartResourceDefinition dummyRecoveryResDef = new PartResourceDefinition();
dummyRecoveryResDef.Load(dummyResNode);
lastResourceWidget = ResourceWidget.Create(dummyRecoveryResDef, (float)lastFundsRecovered, 1f, mrDialog);
mrDialog.AddResourceWidget(lastResourceWidget);
}
}
private void Update()
{
if (currentDialog == null)
{
return;
}
if (currentDialog.fundsEarned > 0.0 && lastFundsRecovered > 0.0)
{
currentDialog.fundsEarned += lastFundsRecovered;
foreach (ImgText imgText in currentDialog.gameObject.GetComponentsInChildren<ImgText>())
{
if (imgText.gameObject.name == "TabFooterPanel")
{
imgText.text = Localizer.Format("#autoLOC_419438", currentDialog.fundsEarned.ToString("N0"));
}
}
if (lastResourceWidget != null)
{
lastResourceWidget.rscWidgetQtyContent.sprite = currentDialog.fundsIconGreen;
lastResourceWidget.rscWidgetQtyContent.text = $"+ {lastFundsRecovered.ToString("N0")} {Localizer.Format("#autoLOC_6002218")}";
lastResourceWidget.rscWidgetUnitValueContent.gameObject.SetActive(false);
lastResourceWidget.rscWidgetTotalValueContent.gameObject.SetActive(false);
}
ResetFields();
enabled = false;
}
}
private void ResetFields()
{
currentDialog = null;
lastResourceWidget = null;
lastFundsRecovered = 0.0;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment