Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of RechargeableDefibro Fix v1.0.2
RechargeableDefibroFix.dll
Decompiled a day agousing System; using System.Collections.Generic; using System.Reflection; using System.Runtime.CompilerServices; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Photon.Pun; using UnityEngine; [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: CompilationRelaxations(8)] [assembly: AssemblyVersion("0.0.0.0")] namespace RechargeableDefibroFix; [BepInPlugin("rechargeabledefibro.fix.runtime", "RechargeableDefibro Fix", "1.0.1")] [BepInDependency(/*Could not decode attribute arguments.*/)] public sealed class Plugin : BaseUnityPlugin { internal static ManualLogSource Log; internal static ConfigEntry<bool> DebugLogging; internal static ConfigEntry<bool> ReplaceBatteryUpdate; internal static ConfigEntry<bool> SuppressBatteryErrors; internal static ConfigEntry<bool> KeepDefibroAfterUse; internal static ConfigEntry<bool> AllowRecharge; internal static ConfigEntry<bool> DisableAutoDrain; internal static ConfigEntry<bool> SuppressBatteryUi; internal static ConfigEntry<bool> ShowHeldBatteryUi; internal static ConfigEntry<bool> UseBatteryVisuals; internal static ConfigEntry<int> BatteryBars; internal static ConfigEntry<int> BatteryLifeOnSpawn; internal static ConfigEntry<int> BatteryLifeAfterUse; internal static ConfigEntry<float> ChargeMultiplier; private void Awake() { //IL_014f: Unknown result type (might be due to invalid IL or missing references) //IL_0159: Expected O, but got Unknown //IL_0183: Unknown result type (might be due to invalid IL or missing references) //IL_018d: Expected O, but got Unknown //IL_01b6: Unknown result type (might be due to invalid IL or missing references) //IL_01c0: Expected O, but got Unknown //IL_01f4: Unknown result type (might be due to invalid IL or missing references) //IL_01fe: Expected O, but got Unknown //IL_0208: Unknown result type (might be due to invalid IL or missing references) Log = ((BaseUnityPlugin)this).Logger; DebugLogging = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "DebugLogging", false, "Enable extra logs for RechargeableDefibro Fix."); ReplaceBatteryUpdate = ((BaseUnityPlugin)this).Config.Bind<bool>("Fixes", "ReplaceDefibroBatteryUpdate", true, "Use a safe battery update loop for Defibro instead of the vanilla ItemBattery.Update."); SuppressBatteryErrors = ((BaseUnityPlugin)this).Config.Bind<bool>("Fixes", "SuppressDefibroBatteryErrors", true, "Suppress Defibro ItemBattery exceptions after repairing the battery state."); KeepDefibroAfterUse = ((BaseUnityPlugin)this).Config.Bind<bool>("Defibro", "KeepDefibroAfterUse", true, "Keep Defibro as a rechargeable item after revive instead of letting it behave like a destroyed one."); AllowRecharge = ((BaseUnityPlugin)this).Config.Bind<bool>("Defibro", "AllowRecharge", true, "Allow charging stations to recharge Defibro."); DisableAutoDrain = ((BaseUnityPlugin)this).Config.Bind<bool>("Defibro", "DisableAutoDrain", true, "Prevent passive battery drain on Defibro."); SuppressBatteryUi = ((BaseUnityPlugin)this).Config.Bind<bool>("Defibro", "SuppressBatteryUi", false, "Legacy option for hiding Defibro battery UI when the safe update loop is disabled."); ShowHeldBatteryUi = ((BaseUnityPlugin)this).Config.Bind<bool>("Defibro", "ShowHeldBatteryUi", true, "Show the vanilla held-item battery UI for Defibro while using the safe update loop."); UseBatteryVisuals = ((BaseUnityPlugin)this).Config.Bind<bool>("Defibro", "UseBatteryVisuals", false, "Use vanilla battery bar visuals when the Defibro prefab has a BatteryVisualLogic component."); BatteryBars = ((BaseUnityPlugin)this).Config.Bind<int>("Defibro", "BatteryBars", 1, new ConfigDescription("Number of battery bars Defibro uses.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 10), new object[0])); BatteryLifeOnSpawn = ((BaseUnityPlugin)this).Config.Bind<int>("Defibro", "BatteryLifeOnSpawn", 100, new ConfigDescription("Battery life when Defibro is created.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), new object[0])); BatteryLifeAfterUse = ((BaseUnityPlugin)this).Config.Bind<int>("Defibro", "BatteryLifeAfterUse", 0, new ConfigDescription("Battery life after a revive is fired.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), new object[0])); ChargeMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("Defibro", "ChargeMultiplier", 1f, new ConfigDescription("Multiplier for charging speed applied only to Defibro.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 10f), new object[0])); new Harmony("rechargeabledefibro.fix.runtime").PatchAll(); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Patched RechargeableDefibro battery handling."); } } internal static class ModLog { private static bool loggedMissingState; private static bool loggedSuppressedUpdate; private static bool loggedReactivated; public static void Debug(string message) { if (Plugin.DebugLogging != null && Plugin.DebugLogging.Value && Plugin.Log != null) { Plugin.Log.LogInfo((object)("[Debug] " + message)); } } public static void Warning(string message) { if (Plugin.Log != null) { Plugin.Log.LogWarning((object)message); } } public static void MissingState() { if (!loggedMissingState) { Warning("RechargeableDefibro state component was not found."); loggedMissingState = true; } } public static void SuppressedUpdate(Exception ex) { if (loggedSuppressedUpdate) { Debug("Suppressed another Defibro ItemBattery exception: " + ex.GetType().Name); return; } Warning("Suppressed a Defibro ItemBattery exception after repairing the battery state: " + ex.GetType().Name); loggedSuppressedUpdate = true; } public static void Reactivated() { if (loggedReactivated) { Debug("Defibro reactivated after recharge."); return; } Debug("Defibro reactivated after recharge."); loggedReactivated = true; } } internal static class DefibroBattery { private static readonly Type StateType = AccessTools.TypeByName("RechargeableDefibro.DefibroState"); private static readonly FieldInfo StateIsDepleted = ((StateType == null) ? null : AccessTools.Field(StateType, "isDepleted")); private static readonly FieldInfo StateReviveFired = ((StateType == null) ? null : AccessTools.Field(StateType, "reviveFired")); private static readonly MethodInfo HardResetVisuals = AccessTools.Method(typeof(ItemReviveItem), "HardResetVisuals", (Type[])null, (Type[])null); private static readonly MethodInfo BatteryUpdateBarsMethod = AccessTools.Method(typeof(ItemBattery), "BatteryUpdateBars", (Type[])null, (Type[])null); private static readonly MethodInfo BatteryFullPercentChangeMethod = AccessTools.Method(typeof(ItemBattery), "BatteryFullPercentChange", (Type[])null, (Type[])null); private static readonly MethodInfo BatteryFullPercentChangeLogicMethod = AccessTools.Method(typeof(ItemBattery), "BatteryFullPercentChangeLogic", (Type[])null, (Type[])null); private static readonly FieldInfo SuppressBatteryUiField = AccessTools.Field(typeof(ItemBattery), "suppressBatteryUI"); private static readonly FieldInfo DrainRateField = AccessTools.Field(typeof(ItemBattery), "drainRate"); private static readonly FieldInfo DrainTimerField = AccessTools.Field(typeof(ItemBattery), "drainTimer"); private static readonly FieldInfo ChargerListField = AccessTools.Field(typeof(ItemBattery), "chargerList"); private static readonly FieldInfo ItemAttributesField = AccessTools.Field(typeof(ItemBattery), "itemAttributes"); private static readonly FieldInfo PhotonViewField = AccessTools.Field(typeof(ItemBattery), "photonView"); private static readonly FieldInfo ItemEquippableField = AccessTools.Field(typeof(ItemBattery), "itemEquippable"); private static readonly FieldInfo PhysGrabObjectField = AccessTools.Field(typeof(ItemBattery), "physGrabObject"); private static readonly FieldInfo MainCameraField = AccessTools.Field(typeof(ItemBattery), "mainCamera"); private static readonly FieldInfo BatteryVisualLogicField = AccessTools.Field(typeof(ItemBattery), "batteryVisualLogic"); private static readonly FieldInfo ChargeTimerField = AccessTools.Field(typeof(ItemBattery), "chargeTimer"); private static readonly FieldInfo ChargeRateField = AccessTools.Field(typeof(ItemBattery), "chargeRate"); private static readonly FieldInfo IsChargingField = AccessTools.Field(typeof(ItemBattery), "isCharging"); private static readonly FieldInfo BatteryLifePrevField = AccessTools.Field(typeof(ItemBattery), "batteryLifePrev"); private static readonly FieldInfo BatteryLifeIntField = AccessTools.Field(typeof(ItemBattery), "batteryLifeInt"); private static readonly FieldInfo BatteryColorField = AccessTools.Field(typeof(ItemBattery), "batteryColor"); private static readonly FieldInfo BatteryColorMediumField = AccessTools.Field(typeof(ItemBattery), "batteryColorMedium"); private static readonly FieldInfo CurrentBarsField = AccessTools.Field(typeof(ItemBattery), "currentBars"); private static readonly FieldInfo BatteryLifeCountBarsField = AccessTools.Field(typeof(ItemBattery), "batteryLifeCountBars"); private static readonly FieldInfo BatteryLifeCountBarsPrevField = AccessTools.Field(typeof(ItemBattery), "batteryLifeCountBarsPrev"); private static readonly FieldInfo MapToolActiveField = AccessTools.Field(typeof(MapToolController), "Active"); private static readonly FieldInfo GrabbedPhysGrabObjectField = AccessTools.Field(typeof(PhysGrabber), "grabbedPhysGrabObject"); private static readonly FieldInfo BatteryVisualCurrentBarsField = AccessTools.Field(typeof(BatteryVisualLogic), "currentBars"); private static readonly FieldInfo InventorySpotBatteryVisualLogicField = AccessTools.Field(typeof(InventorySpot), "batteryVisualLogic"); private static readonly FieldInfo ItemAttributesColorPresetField = AccessTools.Field(typeof(ItemAttributes), "colorPreset"); private static readonly Type ColorPresetsType = AccessTools.TypeByName("ColorPresets"); private static readonly MethodInfo ColorPresetGetColorLightMethod = ((ColorPresetsType == null) ? null : AccessTools.Method(ColorPresetsType, "GetColorLight", (Type[])null, (Type[])null)); private static readonly MethodInfo ColorPresetGetColorMainMethod = ((ColorPresetsType == null) ? null : AccessTools.Method(ColorPresetsType, "GetColorMain", (Type[])null, (Type[])null)); private static readonly Color DefaultBatteryColor = new Color(1f, 1f, 0f, 1f); private static readonly Color DefaultBatteryMediumColor = new Color(1f, 0.75f, 0f, 1f); public static bool IsDefibroBattery(ItemBattery battery) { if ((Object)(object)battery != (Object)null) { return (Object)(object)((Component)battery).GetComponent<ItemReviveItem>() != (Object)null; } return false; } public static void Repair(ItemBattery battery, bool initial) { if (IsDefibroBattery(battery)) { int batteryBars = Mathf.Max(1, Plugin.BatteryBars.Value); battery.batteryBars = batteryBars; battery.isUnchargable = !Plugin.AllowRecharge.Value; BatteryVisualLogic batteryVisualLogic = GetBatteryVisualLogic(battery); battery.hasBatteryVisuals = Plugin.UseBatteryVisuals.Value && (Object)(object)batteryVisualLogic != (Object)null; SetField(SuppressBatteryUiField, battery, !ShouldShowHeldBatteryUi() || Plugin.SuppressBatteryUi.Value); if (Plugin.DisableAutoDrain.Value) { battery.autoDrain = false; battery.batteryDrainRate = 0f; SetField(DrainRateField, battery, 0f); SetField(DrainTimerField, battery, 0f); } if (GetChargerList(battery) == null) { SetField(ChargerListField, battery, new List<GameObject>()); } if ((Object)(object)GetField<ItemAttributes>(ItemAttributesField, battery) == (Object)null) { SetField(ItemAttributesField, battery, ((Component)battery).GetComponent<ItemAttributes>()); } if ((Object)(object)GetField<PhotonView>(PhotonViewField, battery) == (Object)null) { SetField(PhotonViewField, battery, ((Component)battery).GetComponent<PhotonView>()); } if ((Object)(object)GetField<ItemEquippable>(ItemEquippableField, battery) == (Object)null) { SetField(ItemEquippableField, battery, GetItemEquippable(battery)); } if ((Object)(object)GetPhysGrabObject(battery) == (Object)null) { SetField(PhysGrabObjectField, battery, ((Component)battery).GetComponentInChildren<PhysGrabObject>(true)); } if ((Object)(object)GetField<Camera>(MainCameraField, battery) == (Object)null) { SetField(MainCameraField, battery, Camera.main); } if ((Object)(object)batteryVisualLogic == (Object)null) { SetField(BatteryVisualLogicField, battery, ((Component)battery).GetComponentInChildren<BatteryVisualLogic>(true)); } if ((Object)(object)GetBatteryVisualLogic(battery) == (Object)null) { battery.hasBatteryVisuals = false; } if (initial && battery.batteryLife <= 1f) { battery.batteryLife = Plugin.BatteryLifeOnSpawn.Value; } battery.batteryLife = Mathf.Clamp(battery.batteryLife, 0f, 100f); ApplyVanillaBatteryColors(battery); ApplyCounts(battery, notifyChange: false); } } public static void Update(ItemBattery battery) { Repair(battery, initial: false); if (Plugin.AllowRecharge.Value && SemiFunc.IsMasterClientOrSingleplayer()) { float field = GetField(ChargeTimerField, battery, 0f); float field2 = GetField(ChargeRateField, battery, 0f); bool field3 = GetField(IsChargingField, battery, fallback: false); if (field > 0f && battery.batteryLife < 100f) { SetField(IsChargingField, battery, true); battery.batteryLife = Mathf.Clamp(battery.batteryLife + field2 * Plugin.ChargeMultiplier.Value * Time.deltaTime, 0f, 100f); SetField(ChargeTimerField, battery, Mathf.Max(0f, field - Time.deltaTime)); } else if (field2 != 0f || field3) { SetField(ChargeRateField, battery, 0f); SetField(ChargeTimerField, battery, 0f); SetField(IsChargingField, battery, false); GetChargerList(battery)?.Clear(); } } ApplyCounts(battery, notifyChange: true); ReactivateIfReady(battery); ShowHeldBatteryUi(battery); if (battery.hasBatteryVisuals && (Object)(object)GetBatteryVisualLogic(battery) != (Object)null && BatteryUpdateBarsMethod != null) { BatteryUpdateBarsMethod.Invoke(battery, new object[1] { GetBatteryLifeInt(battery) }); } } public static void SetAfterUse(ItemBattery battery) { if (IsDefibroBattery(battery) && Plugin.KeepDefibroAfterUse.Value) { Repair(battery, initial: false); battery.batteryLife = Mathf.Clamp(Plugin.BatteryLifeAfterUse.Value, 0, 100); SetField(BatteryLifePrevField, battery, -1f); battery.batteryActive = true; SetField(IsChargingField, battery, false); SetField(ChargeRateField, battery, 0f); SetField(ChargeTimerField, battery, 0f); ApplyCounts(battery, notifyChange: true); PhysGrabObject physGrabObject = GetPhysGrabObject(battery); if ((Object)(object)physGrabObject != (Object)null) { physGrabObject.dead = false; } } } public static bool SetBatteryLife(ItemBattery battery, int life) { if (!IsDefibroBattery(battery)) { return true; } Repair(battery, initial: false); battery.batteryLife = Mathf.Clamp(life, 0, 100); SetField(BatteryLifePrevField, battery, -1f); ApplyCounts(battery, notifyChange: true); ReactivateIfReady(battery); return false; } public static bool CanRunBatteryVisualMethod(ItemBattery battery) { if (IsDefibroBattery(battery)) { if (battery.hasBatteryVisuals && (Object)(object)GetBatteryVisualLogic(battery) != (Object)null) { return !Plugin.SuppressBatteryUi.Value; } return false; } return true; } public static bool CanCharge(ItemBattery battery) { if (!IsDefibroBattery(battery)) { return true; } Repair(battery, initial: false); return Plugin.AllowRecharge.Value; } private static void ApplyCounts(ItemBattery battery, bool notifyChange) { int num = Mathf.Max(1, battery.batteryBars); int num2 = Mathf.Clamp(Mathf.RoundToInt(battery.batteryLife / (100f / (float)num)), 0, num); int field = GetField(BatteryLifeCountBarsPrevField, battery, GetBatteryLifeInt(battery)); SetField(BatteryLifeCountBarsField, battery, num2); SetField(BatteryLifeIntField, battery, num2); SetField(CurrentBarsField, battery, num2); if (notifyChange && num2 != field) { NotifyBatteryChanged(battery, num2, field < num2); SetField(BatteryLifeCountBarsPrevField, battery, num2); } else { SetField(BatteryLifeCountBarsPrevField, battery, num2); } } private static void ReactivateIfReady(ItemBattery battery) { if (IsDepleted(battery) && !(battery.batteryLife < 99f)) { SetDepleted(battery, value: false); SetReviveFired(battery, value: false); PhysGrabObject physGrabObject = GetPhysGrabObject(battery); if ((Object)(object)physGrabObject != (Object)null) { physGrabObject.dead = false; } ItemReviveItem component = ((Component)battery).GetComponent<ItemReviveItem>(); if ((Object)(object)component != (Object)null && HardResetVisuals != null) { HardResetVisuals.Invoke(component, null); } ModLog.Reactivated(); } } public static int GetBatteryLifeIntForUi(ItemBattery battery) { return Mathf.Clamp(GetBatteryLifeInt(battery), 0, Mathf.Max(1, ((Object)(object)battery == (Object)null) ? 1 : battery.batteryBars)); } public static void BindInventorySpotVisual(InventorySpot spot) { if (!((Object)(object)spot == (Object)null) && spot.IsOccupied()) { ItemBattery val = FindDefibroBattery((Component)(object)spot.CurrentItem); if (!((Object)(object)val == (Object)null)) { Repair(val, initial: false); BatteryVisualLogic visualLogic = (BatteryVisualLogic)((InventorySpotBatteryVisualLogicField == null) ? null : /*isinst with value type is only supported in some contexts*/); ApplyBatteryVisual(visualLogic, val, rebuild: true); } } } public static ItemBattery FindDefibroBattery(Component component) { if ((Object)(object)component == (Object)null) { return null; } ItemBattery component2 = component.GetComponent<ItemBattery>(); if (IsDefibroBattery(component2)) { return component2; } ItemReviveItem val = component.GetComponent<ItemReviveItem>(); if ((Object)(object)val == (Object)null) { val = component.GetComponentInParent<ItemReviveItem>(true); } if ((Object)(object)val == (Object)null) { val = component.GetComponentInChildren<ItemReviveItem>(true); } if ((Object)(object)val != (Object)null) { ItemBattery component3 = ((Component)val).GetComponent<ItemBattery>(); if (IsDefibroBattery(component3)) { return component3; } } ItemBattery componentInParent = component.GetComponentInParent<ItemBattery>(true); if (IsDefibroBattery(componentInParent)) { return componentInParent; } ItemBattery componentInChildren = component.GetComponentInChildren<ItemBattery>(true); if (!IsDefibroBattery(componentInChildren)) { return null; } return componentInChildren; } private static void ApplyVanillaBatteryColors(ItemBattery battery) { //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) ItemAttributes val = GetField<ItemAttributes>(ItemAttributesField, battery); if ((Object)(object)val == (Object)null) { val = ((Component)battery).GetComponent<ItemAttributes>(); if ((Object)(object)val != (Object)null) { SetField(ItemAttributesField, battery, val); } } Color val2 = DefaultBatteryColor; Color val3 = DefaultBatteryMediumColor; object obj = ((ItemAttributesColorPresetField == null || (Object)(object)val == (Object)null) ? null : ItemAttributesColorPresetField.GetValue(val)); if (obj != null && ColorPresetGetColorLightMethod != null && ColorPresetGetColorMainMethod != null) { try { Color val4 = (Color)ColorPresetGetColorLightMethod.Invoke(obj, null); Color val5 = (Color)ColorPresetGetColorMainMethod.Invoke(obj, null); if (IsVisibleColor(val4)) { val2 = val4; } if (IsVisibleColor(val5)) { val3 = val5; } } catch (Exception ex) { ModLog.Debug("Could not fetch Defibro battery colors from ColorPreset: " + ex.GetType().Name); } } SetField(BatteryColorField, battery, val2); SetField(BatteryColorMediumField, battery, val3); } private static bool IsVisibleColor(Color color) { if (color.a > 0.01f) { return color.r + color.g + color.b > 0.05f; } return false; } private static void ApplyBatteryVisual(BatteryVisualLogic visualLogic, ItemBattery battery, bool rebuild) { if ((Object)(object)visualLogic == (Object)null || (Object)(object)battery == (Object)null) { return; } try { if (!((Component)visualLogic).gameObject.activeSelf) { ((Component)visualLogic).gameObject.SetActive(true); } if ((Object)(object)visualLogic.itemBattery != (Object)(object)battery) { visualLogic.itemBattery = battery; rebuild = true; } if (visualLogic.batteryBars != battery.batteryBars) { rebuild = true; } if (rebuild) { visualLogic.BatteryBarsSet(); } visualLogic.BatteryBarsUpdate(GetBatteryLifeIntForUi(battery), true); } catch (Exception ex) { ModLog.Debug("Could not apply Defibro battery visual: " + ex.GetType().Name); } } private static int GetBatteryLifeInt(ItemBattery battery) { return GetField(BatteryLifeIntField, battery, 0); } private static bool ShouldShowHeldBatteryUi() { if (Plugin.ShowHeldBatteryUi != null) { return Plugin.ShowHeldBatteryUi.Value; } return false; } private static void ShowHeldBatteryUi(ItemBattery battery) { if (!ShouldShowHeldBatteryUi()) { return; } try { if (SemiFunc.RunIsShop() || SemiFunc.RunIsArena() || ((Object)(object)MapToolController.instance != (Object)null && GetObjectField(MapToolActiveField, MapToolController.instance, fallback: false))) { return; } PhysGrabObject physGrabObject = GetPhysGrabObject(battery); PhysGrabObject val = (((Object)(object)PhysGrabber.instance == (Object)null) ? null : GetObjectField<PhysGrabObject>(GrabbedPhysGrabObjectField, PhysGrabber.instance)); if ((Object)(object)physGrabObject == (Object)null || (Object)(object)PhysGrabber.instance == (Object)null || !PhysGrabber.instance.grabbed || (Object)(object)val != (Object)(object)physGrabObject) { return; } BatteryUI instance = BatteryUI.instance; if (!((Object)(object)instance == (Object)null) && !((Object)(object)instance.batteryVisualLogic == (Object)null)) { BatteryVisualLogic batteryVisualLogic = instance.batteryVisualLogic; bool flag = (Object)(object)batteryVisualLogic.itemBattery != (Object)(object)battery; if (flag) { batteryVisualLogic.itemBattery = battery; } int objectField = GetObjectField(BatteryVisualCurrentBarsField, batteryVisualLogic, -1); if (flag || batteryVisualLogic.batteryBars != battery.batteryBars || objectField != GetBatteryLifeIntForUi(battery)) { ApplyBatteryVisual(batteryVisualLogic, battery, rebuild: true); } else { ApplyBatteryVisual(batteryVisualLogic, battery, rebuild: false); } ((SemiUI)instance).Show(); } } catch (Exception ex) { ModLog.Debug("Could not show Defibro battery UI: " + ex.GetType().Name); } } private static void NotifyBatteryChanged(ItemBattery battery, int level, bool charging) { if (BatteryFullPercentChangeMethod == null) { SetField(BatteryLifeIntField, battery, level); SetField(CurrentBarsField, battery, level); return; } try { if ((Object)(object)GetField<PhotonView>(PhotonViewField, battery) == (Object)null && BatteryFullPercentChangeLogicMethod != null) { BatteryFullPercentChangeLogicMethod.Invoke(battery, new object[2] { level, charging }); } else { BatteryFullPercentChangeMethod.Invoke(battery, new object[2] { level, charging }); } } catch (Exception ex) { ModLog.Debug("Could not run Defibro battery change callback: " + ex.GetType().Name); SetField(BatteryLifeIntField, battery, level); SetField(CurrentBarsField, battery, level); } } private static List<GameObject> GetChargerList(ItemBattery battery) { return GetField<List<GameObject>>(ChargerListField, battery); } private static BatteryVisualLogic GetBatteryVisualLogic(ItemBattery battery) { BatteryVisualLogic field = GetField<BatteryVisualLogic>(BatteryVisualLogicField, battery); if (!((Object)(object)field != (Object)null)) { return ((Component)battery).GetComponentInChildren<BatteryVisualLogic>(true); } return field; } private static PhysGrabObject GetPhysGrabObject(ItemBattery battery) { PhysGrabObject field = GetField<PhysGrabObject>(PhysGrabObjectField, battery); if ((Object)(object)field != (Object)null) { return field; } field = ((Component)battery).GetComponent<PhysGrabObject>(); if ((Object)(object)field != (Object)null) { return field; } field = ((Component)battery).GetComponentInChildren<PhysGrabObject>(true); if (!((Object)(object)field != (Object)null)) { return ((Component)battery).GetComponentInParent<PhysGrabObject>(true); } return field; } private static ItemEquippable GetItemEquippable(ItemBattery battery) { ItemEquippable component = ((Component)battery).GetComponent<ItemEquippable>(); if ((Object)(object)component != (Object)null) { return component; } component = ((Component)battery).GetComponentInChildren<ItemEquippable>(true); if (!((Object)(object)component != (Object)null)) { return ((Component)battery).GetComponentInParent<ItemEquippable>(true); } return component; } private static T GetField<T>(FieldInfo field, ItemBattery battery, T fallback = default(T)) { if (field == null || (Object)(object)battery == (Object)null) { return fallback; } object value = field.GetValue(battery); if (value == null) { return fallback; } if (!(value is T)) { return fallback; } return (T)value; } private static T GetObjectField<T>(FieldInfo field, object instance, T fallback = default(T)) { if (field == null || instance == null) { return fallback; } object value = field.GetValue(instance); if (value == null) { return fallback; } if (!(value is T)) { return fallback; } return (T)value; } private static void SetField(FieldInfo field, ItemBattery battery, object value) { if (field != null && (Object)(object)battery != (Object)null) { field.SetValue(battery, value); } } private static bool IsDepleted(ItemBattery battery) { Component state = GetState(battery); if ((Object)(object)state != (Object)null && StateIsDepleted != null) { return (bool)StateIsDepleted.GetValue(state); } return false; } private static void SetDepleted(ItemBattery battery, bool value) { Component state = GetState(battery); if ((Object)(object)state != (Object)null && StateIsDepleted != null) { StateIsDepleted.SetValue(state, value); } } private static void SetReviveFired(ItemBattery battery, bool value) { Component state = GetState(battery); if ((Object)(object)state != (Object)null && StateReviveFired != null) { StateReviveFired.SetValue(state, value); } } private static Component GetState(ItemBattery battery) { if (StateType == null || (Object)(object)battery == (Object)null) { ModLog.MissingState(); return null; } Component component = ((Component)battery).GetComponent(StateType); if ((Object)(object)component != (Object)null) { return component; } return ((Component)battery).gameObject.AddComponent(StateType); } } [HarmonyPatch(typeof(ItemReviveItem), "Start")] internal static class ItemReviveItemStartPatch { private static void Postfix(ItemReviveItem __instance) { ItemBattery battery = (((Object)(object)__instance == (Object)null) ? null : ((Component)__instance).GetComponent<ItemBattery>()); DefibroBattery.Repair(battery, initial: true); } } [HarmonyPatch(typeof(ItemReviveItem), "ReviveAndDestroy")] internal static class ItemReviveItemReviveAndDestroyPatch { private static void Postfix(ItemReviveItem __instance) { ItemBattery afterUse = (((Object)(object)__instance == (Object)null) ? null : ((Component)__instance).GetComponent<ItemBattery>()); DefibroBattery.SetAfterUse(afterUse); } } [HarmonyPatch(typeof(ItemBattery), "Update")] internal static class ItemBatteryUpdatePatch { private static bool Prefix(ItemBattery __instance) { if (!DefibroBattery.IsDefibroBattery(__instance) || !Plugin.ReplaceBatteryUpdate.Value) { return true; } DefibroBattery.Update(__instance); return false; } private static Exception Finalizer(Exception __exception, ItemBattery __instance) { if (__exception == null || !DefibroBattery.IsDefibroBattery(__instance) || !Plugin.SuppressBatteryErrors.Value) { return __exception; } DefibroBattery.Repair(__instance, initial: false); ModLog.SuppressedUpdate(__exception); return null; } } [HarmonyPatch(typeof(InventorySpot), "StateOccupied")] internal static class InventorySpotStateOccupiedPatch { private static void Postfix(InventorySpot __instance) { DefibroBattery.BindInventorySpotVisual(__instance); } } [HarmonyPatch(typeof(Inventory), "GetBatteryStateFromInventorySpot")] internal static class InventoryGetBatteryStateFromInventorySpotPatch { private static void Postfix(Inventory __instance, int index, ref int __result) { if ((Object)(object)__instance == (Object)null) { return; } InventorySpot spotByIndex = __instance.GetSpotByIndex(index); if (!((Object)(object)spotByIndex == (Object)null) && spotByIndex.IsOccupied()) { ItemEquippable currentItem = spotByIndex.CurrentItem; ItemBattery val = DefibroBattery.FindDefibroBattery((Component)(object)currentItem); if (!((Object)(object)val == (Object)null)) { DefibroBattery.Repair(val, initial: false); __result = DefibroBattery.GetBatteryLifeIntForUi(val); } } } } [HarmonyPatch(typeof(ItemBattery), "SetBatteryLife")] internal static class ItemBatterySetBatteryLifePatch { private static bool Prefix(ItemBattery __instance, int _batteryLife) { return DefibroBattery.SetBatteryLife(__instance, _batteryLife); } } [HarmonyPatch(typeof(ItemBattery), "ChargeBattery")] internal static class ItemBatteryChargeBatteryPatch { private static bool Prefix(ItemBattery __instance) { return DefibroBattery.CanCharge(__instance); } private static void Postfix(ItemBattery __instance) { if (DefibroBattery.IsDefibroBattery(__instance)) { DefibroBattery.Repair(__instance, initial: false); } } } [HarmonyPatch(typeof(ItemBattery), "BatteryLookAt")] internal static class ItemBatteryLookAtPatch { private static bool Prefix(ItemBattery __instance) { return DefibroBattery.CanRunBatteryVisualMethod(__instance); } } [HarmonyPatch(typeof(ItemBattery), "BatteryChargingVisuals")] internal static class ItemBatteryChargingVisualsPatch { private static bool Prefix(ItemBattery __instance) { return DefibroBattery.CanRunBatteryVisualMethod(__instance); } } [HarmonyPatch(typeof(ItemBattery), "BatteryUpdateBars")] internal static class ItemBatteryUpdateBarsPatch { private static bool Prefix(ItemBattery __instance) { return DefibroBattery.CanRunBatteryVisualMethod(__instance); } }