diff --git a/NewHorizons/Components/Volumes/NHRepairReceiver.cs b/NewHorizons/Components/Volumes/NHRepairReceiver.cs new file mode 100644 index 00000000..130d8486 --- /dev/null +++ b/NewHorizons/Components/Volumes/NHRepairReceiver.cs @@ -0,0 +1,103 @@ +using NewHorizons.Handlers; +using OWML.Utils; +using System.Collections.Generic; +using System.Linq; +using UnityEngine; +using UnityEngine.Events; + +namespace NewHorizons.Components.Volumes +{ + // RepairReceiver isn't set up for proper subclassing but a subclass is necessary for the first-person manipulator to detect it. + public class NHRepairReceiver : RepairReceiver + { + public static Type RepairReceiverType = EnumUtils.Create("NewHorizons"); + + public class RepairEvent : UnityEvent { } + + public RepairEvent OnRepaired = new(); + public RepairEvent OnDamaged = new(); + + public string displayName; + public float repairTime; + public string damagedCondition; + public string repairedCondition; + public string revealFact; + + float _repairFraction = 0f; + UITextType _uiTextType = UITextType.None; + + public float repairFraction + { + get => _repairFraction; + set + { + var prevValue = _repairFraction; + _repairFraction = Mathf.Clamp01(value); + if (prevValue < 1f && _repairFraction >= 1f) + { + Repair(); + } + else if (prevValue >= 1f && _repairFraction < 1f) + { + Damage(); + } + } + } + + public new virtual bool IsRepairable() => IsDamaged(); + public new virtual bool IsDamaged() => _repairFraction < 1f; + public new virtual float GetRepairFraction() => _repairFraction; + + protected new void Awake() + { + base.Awake(); + _type = RepairReceiverType; + if (IsDamaged()) Damage(); + else Repair(); + } + + public new virtual void RepairTick() + { + if (!IsRepairable()) return; + repairFraction += Time.deltaTime / repairTime; + } + + public new virtual UITextType GetRepairableName() + { + if (_uiTextType != UITextType.None) return _uiTextType; + var value = TranslationHandler.GetTranslation(displayName, TranslationHandler.TextType.UI); + _uiTextType = (UITextType)TranslationHandler.AddUI(value, false); + return _uiTextType; + } + + void Damage() + { + if (!string.IsNullOrEmpty(damagedCondition)) + { + DialogueConditionManager.SharedInstance.SetConditionState(damagedCondition, true); + } + if (!string.IsNullOrEmpty(repairedCondition)) + { + DialogueConditionManager.SharedInstance.SetConditionState(repairedCondition, false); + } + OnDamaged.Invoke(this); + } + + void Repair() + { + if (!string.IsNullOrEmpty(damagedCondition)) + { + DialogueConditionManager.SharedInstance.SetConditionState(damagedCondition, false); + } + if (!string.IsNullOrEmpty(repairedCondition)) + { + DialogueConditionManager.SharedInstance.SetConditionState(repairedCondition, true); + } + if (!string.IsNullOrEmpty(revealFact)) + { + Locator.GetShipLogManager().RevealFact(revealFact); + } + OnRepaired.Invoke(this); + } + } +} diff --git a/NewHorizons/Patches/VolumePatches/RepairReceiverPatches.cs b/NewHorizons/Patches/VolumePatches/RepairReceiverPatches.cs new file mode 100644 index 00000000..a21e6b79 --- /dev/null +++ b/NewHorizons/Patches/VolumePatches/RepairReceiverPatches.cs @@ -0,0 +1,62 @@ +using HarmonyLib; +using NewHorizons.Components.Volumes; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace NewHorizons.Patches.VolumePatches +{ + + [HarmonyPatch(typeof(RepairReceiver))] + public static class RepairReceiverPatches + { + // We can't actually override these methods so we patch the base class methods to invoke the subclass methods dynamically + + [HarmonyPostfix, HarmonyPatch(nameof(RepairReceiver.IsRepairable))] + public static void IsRepairable(RepairReceiver __instance, ref bool __result) + { + if (__instance is NHRepairReceiver r) + { + __result = r.IsRepairable(); + } + } + + [HarmonyPostfix, HarmonyPatch(nameof(RepairReceiver.RepairTick))] + public static void RepairTick(RepairReceiver __instance) + { + if (__instance is NHRepairReceiver r) + { + r.RepairTick(); + } + } + + [HarmonyPostfix, HarmonyPatch(nameof(RepairReceiver.IsDamaged))] + public static void IsDamaged(RepairReceiver __instance, ref bool __result) + { + if (__instance is NHRepairReceiver r) + { + __result = r.IsDamaged(); + } + } + + [HarmonyPostfix, HarmonyPatch(nameof(RepairReceiver.GetRepairableName))] + public static void GetRepairableName(RepairReceiver __instance, ref UITextType __result) + { + if (__instance is NHRepairReceiver r) + { + __result = r.GetRepairableName(); + } + } + + [HarmonyPostfix, HarmonyPatch(nameof(RepairReceiver.GetRepairFraction))] + public static void GetRepairFraction(RepairReceiver __instance, ref float __result) + { + if (__instance is NHRepairReceiver r) + { + __result = r.GetRepairFraction(); + } + } + } +}