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 ContagiousRepair v1.0.0
ContagiousRepair.dll
Decompiled 3 days agousing System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using HarmonyLib; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("RepairTrickle")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("RepairTrickle")] [assembly: AssemblyCopyright("Copyright © 2026")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("527dfcf7-c0b5-4c36-8981-97f3afffa72d")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyVersion("1.0.0.0")] namespace ContagiousRepair; [BepInPlugin("robit.contagiousrepair", "Contagious Repair", "1.0.0")] public class ContagiousRepairPlugin : BaseUnityPlugin { public const string PluginGuid = "robit.contagiousrepair"; public const string PluginName = "Contagious Repair"; public const string PluginVersion = "1.0.0"; internal static ContagiousRepairPlugin Instance; internal static ConfigEntry<bool> ModEnabled; internal static ConfigEntry<float> PropagationDelay; internal static ConfigEntry<float> TouchPadding; internal static ConfigEntry<int> MaxPieces; internal static ConfigEntry<bool> UseStamina; internal static ConfigEntry<float> StaminaPerRepair; private Harmony _harmony; private void Awake() { //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Expected O, but got Unknown Instance = this; ModEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, "Enable or disable Repair Trickle."); PropagationDelay = ((BaseUnityPlugin)this).Config.Bind<float>("General", "PropagationDelay", 0.1f, "Delay in seconds between repair waves."); TouchPadding = ((BaseUnityPlugin)this).Config.Bind<float>("General", "TouchPadding", 0.08f, "Small amount added around colliders when detecting touching pieces."); MaxPieces = ((BaseUnityPlugin)this).Config.Bind<int>("General", "MaxPiecesPerCascade", 250, "Maximum number of pieces that can be checked in one repair cascade."); UseStamina = ((BaseUnityPlugin)this).Config.Bind<bool>("Stamina", "UseStamina", true, "If enabled, each contagious repair consumes stamina."); StaminaPerRepair = ((BaseUnityPlugin)this).Config.Bind<float>("Stamina", "StaminaPerRepair", 1f, "Stamina consumed for each contagious repair."); _harmony = new Harmony("robit.contagiousrepair"); _harmony.PatchAll(); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Contagious Repair 1.0.0 loaded."); } private void OnDestroy() { Harmony harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } } internal void BeginCascade(Piece startingPiece) { if (ModEnabled.Value && !((Object)(object)startingPiece == (Object)null)) { ((BaseUnityPlugin)this).Logger.LogInfo((object)("Contagion started from: " + ((Object)startingPiece).name)); ((MonoBehaviour)this).StartCoroutine(ContagiousRepair(startingPiece)); } } private IEnumerator ContagiousRepair(Piece startingPiece) { Queue<Piece> currentWave = new Queue<Piece>(); Queue<Piece> nextWave = new Queue<Piece>(); HashSet<int> visited = new HashSet<int>(); currentWave.Enqueue(startingPiece); visited.Add(((Object)startingPiece).GetInstanceID()); int checkedPieces = 1; while (currentWave.Count > 0) { yield return (object)new WaitForSeconds(PropagationDelay.Value); nextWave.Clear(); while (currentWave.Count > 0) { Piece val = currentWave.Dequeue(); if ((Object)(object)val == (Object)null) { continue; } foreach (Piece item in FindTouchingPieces(val)) { if ((Object)(object)item == (Object)null) { continue; } int instanceID = ((Object)item).GetInstanceID(); if (visited.Contains(instanceID)) { continue; } visited.Add(instanceID); checkedPieces++; if (checkedPieces > MaxPieces.Value) { ((BaseUnityPlugin)this).Logger.LogDebug((object)$"Repair cascade reached limit of {MaxPieces.Value} pieces."); yield break; } WearNTear component = ((Component)item).GetComponent<WearNTear>(); if ((Object)(object)component != (Object)null && component.GetHealthPercentage() < 0.9999f) { if (UseStamina.Value) { Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null) { yield break; } float value = StaminaPerRepair.Value; if (localPlayer.GetStamina() < value) { ((BaseUnityPlugin)this).Logger.LogDebug((object)"Contagious repair stopped: not enough stamina."); yield break; } ((Character)localPlayer).UseStamina(value); } if (component.Repair() && item.m_placeEffect != null) { item.m_placeEffect.Create(((Component)item).transform.position, ((Component)item).transform.rotation, (Transform)null, 1f, -1, default(ZDOID)); } } nextWave.Enqueue(item); nextWave.Enqueue(item); } } Queue<Piece> queue = currentWave; currentWave = nextWave; nextWave = queue; } } private IEnumerable<Piece> FindTouchingPieces(Piece sourcePiece) { //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) HashSet<Piece> hashSet = new HashSet<Piece>(); Collider[] componentsInChildren = ((Component)sourcePiece).GetComponentsInChildren<Collider>(); foreach (Collider val in componentsInChildren) { if ((Object)(object)val == (Object)null || !val.enabled) { continue; } Bounds bounds = val.bounds; Vector3 val2 = ((Bounds)(ref bounds)).extents + Vector3.one * TouchPadding.Value; Collider[] array = Physics.OverlapBox(((Bounds)(ref bounds)).center, val2, Quaternion.identity, -1, (QueryTriggerInteraction)1); foreach (Collider val3 in array) { if (!((Object)(object)val3 == (Object)null)) { Piece componentInParent = ((Component)val3).GetComponentInParent<Piece>(); if (!((Object)(object)componentInParent == (Object)null) && !((Object)(object)componentInParent == (Object)(object)sourcePiece)) { hashSet.Add(componentInParent); } } } } return hashSet; } } [HarmonyPatch(typeof(Player), "Repair")] internal static class PlayerRepairPatch { private struct RepairState { public Piece Piece; public float HealthBefore; } private static void Prefix(Player __instance, out RepairState __state) { __state = new RepairState { Piece = null, HealthBefore = 0f }; if ((Object)(object)ContagiousRepairPlugin.Instance == (Object)null || !ContagiousRepairPlugin.ModEnabled.Value) { return; } Piece hoveringPiece = __instance.GetHoveringPiece(); if ((Object)(object)hoveringPiece == (Object)null) { return; } WearNTear component = ((Component)hoveringPiece).GetComponent<WearNTear>(); if (!((Object)(object)component == (Object)null)) { float healthPercentage = component.GetHealthPercentage(); if (!(healthPercentage >= 0.9999f)) { __state = new RepairState { Piece = hoveringPiece, HealthBefore = healthPercentage }; } } } private static void Postfix(RepairState __state) { if (!((Object)(object)__state.Piece == (Object)null) && !((Object)(object)ContagiousRepairPlugin.Instance == (Object)null)) { WearNTear component = ((Component)__state.Piece).GetComponent<WearNTear>(); if (!((Object)(object)component == (Object)null) && !(component.GetHealthPercentage() <= __state.HealthBefore + 0.0001f)) { ContagiousRepairPlugin.Instance.BeginCascade(__state.Piece); } } } }