using System; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using FluxTeam.Antacid; using HarmonyLib; using MelonLoader; using MelonLoader.Preferences; using Microsoft.CodeAnalysis; using Mimic.Actors; using ReluProtocol; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("Antacid")] [assembly: AssemblyDescription("Disables Acid Rain and Sprinkler damage, or removes them altogether.")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("FluxTeam")] [assembly: AssemblyProduct("FluxTeam.Antacid")] [assembly: AssemblyCopyright("Copyright © FluxTeam 2026")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("3d2017be-9172-4c52-bfeb-543db974fc68")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: MelonInfo(typeof(AntacidMod), "Antacid", "1.0.0", "FluxTeam", null)] [assembly: MelonGame("ReLUGames", "MIMESIS")] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace FluxTeam.Antacid { public sealed class AntacidMod : MelonMod { public override void OnInitializeMelon() { AntacidConfig.Initialize(); ((MelonBase)this).LoggerInstance.Msg("Antacid v1.0.0 initialized — " + AntacidConfig.Summary()); } } internal static class AntacidConfig { public const int SprinklerFieldSkillMasterID = 70007; public static MelonPreferences_Entry SprinklersEvent; public static MelonPreferences_Entry SprinklersToxic; public static MelonPreferences_Entry AcidRainEvent; public static MelonPreferences_Entry AcidRainToxic; public static bool SuppressSprinklerEffect { get { if (True(SprinklersToxic)) { return !True(SprinklersEvent); } return true; } } public static bool HideSprinklerVisual => !True(SprinklersEvent); public static bool NeutralizeRainConta { get { if (True(AcidRainToxic)) { return !True(AcidRainEvent); } return true; } } public static bool ForceSunnyVisual => !True(AcidRainEvent); public static void Initialize() { MelonPreferences.CreateCategory("Antacid", "FluxTeam Antacid"); SprinklersEvent = MelonPreferences.CreateEntry("Antacid", "SprinklersEvent", true, "Sprinklers trigger (true) / never trigger (false).", (string)null, false, false, (ValueValidator)null); SprinklersToxic = MelonPreferences.CreateEntry("Antacid", "SprinklersToxic", false, "Sprinklers deal Contamination (true) / harmless (false).", (string)null, false, false, (ValueValidator)null); AcidRainEvent = MelonPreferences.CreateEntry("Antacid", "AcidRainEvent", true, "Acid rain occurs (true) / always sunny (false).", (string)null, false, false, (ValueValidator)null); AcidRainToxic = MelonPreferences.CreateEntry("Antacid", "AcidRainToxic", false, "Acid rain adds Contamination (true) / no Conta (false).", (string)null, false, false, (ValueValidator)null); } public static string Summary() { return "Sprinklers[Event=" + V(SprinklersEvent) + " Toxic=" + V(SprinklersToxic) + "] AcidRain[Event=" + V(AcidRainEvent) + " Toxic=" + V(AcidRainToxic) + "]"; } private static bool True(MelonPreferences_Entry e) { return e?.Value ?? false; } private static string V(MelonPreferences_Entry e) { return (e?.Value ?? false).ToString(); } } internal static class AntacidLog { private static readonly HashSet _seen = new HashSet(); private static readonly object _gate = new object(); public static void WarnOnce(string key, string message) { lock (_gate) { if (!_seen.Add(key)) { return; } } MelonLogger.Warning("[Antacid] " + message); } } } namespace FluxTeam.Antacid.Patches { [HarmonyPatch(typeof(DungeonWeather), "GetCurrentContaRate")] internal static class DungeonWeather_GetCurrentContaRate_Patch { [HarmonyPostfix] private static void Postfix(ref float __result) { try { if (AntacidConfig.NeutralizeRainConta) { __result = 1f; } } catch (Exception ex) { AntacidLog.WarnOnce("GetCurrentContaRate", "DungeonWeather.GetCurrentContaRate patch failed (game update?): " + ex.Message); } } } [HarmonyPatch(typeof(SkyAndWeatherSystem), "SetWeatherPreset")] internal static class SkyAndWeatherSystem_SetWeatherPreset_Patch { [HarmonyPrefix] private static void Prefix(ref eWeatherPreset newWeatherPreset) { try { if (AntacidConfig.ForceSunnyVisual) { newWeatherPreset = (eWeatherPreset)0; } } catch (Exception ex) { AntacidLog.WarnOnce("SetWeatherPreset", "SkyAndWeatherSystem.SetWeatherPreset patch failed (game update?): " + ex.Message); } } } [HarmonyPatch(typeof(SkyAndWeatherSystem), "TurnOn", new Type[] { typeof(eWeatherPreset) })] internal static class SkyAndWeatherSystem_TurnOn_Preset_Patch { [HarmonyPrefix] private static void Prefix(ref eWeatherPreset weatherPreset) { try { if (AntacidConfig.ForceSunnyVisual) { weatherPreset = (eWeatherPreset)0; } } catch (Exception ex) { AntacidLog.WarnOnce("TurnOn.Preset", "SkyAndWeatherSystem.TurnOn(preset) patch failed (game update?): " + ex.Message); } } } [HarmonyPatch(typeof(SkyAndWeatherSystem), "TurnOn", new Type[] { typeof(eWeather), typeof(eCloudDensity), typeof(float) })] internal static class SkyAndWeatherSystem_TurnOn_Weather_Patch { [HarmonyPrefix] private static void Prefix(ref eWeather newWeather, ref eCloudDensity newCloud, ref float newRainIntensity) { try { if (AntacidConfig.ForceSunnyVisual) { newWeather = (eWeather)0; newCloud = (eCloudDensity)0; newRainIntensity = 0f; } } catch (Exception ex) { AntacidLog.WarnOnce("TurnOn.Weather", "SkyAndWeatherSystem.TurnOn(weather) patch failed (game update?): " + ex.Message); } } } [HarmonyPatch(typeof(FieldSkillObject), "ProcessMutableValue")] internal static class FieldSkillObject_ProcessMutableValue_Patch { [HarmonyPrefix] private static bool Prefix(FieldSkillObject __instance, ref List __result) { try { if (AntacidConfig.SuppressSprinklerEffect && __instance.GetFieldSkillMasterID() == 70007) { __result = new List(); return false; } } catch (Exception ex) { AntacidLog.WarnOnce("ProcessMutableValue", "FieldSkillObject.ProcessMutableValue patch failed (game update?): " + ex.Message); } return true; } } [HarmonyPatch(typeof(FieldSkillActor), "Spawn")] internal static class FieldSkillActor_Spawn_Patch { private static readonly Action SetActorID = (Action)(AccessTools.PropertySetter(typeof(FieldSkillActor), "ActorID")?.CreateDelegate(typeof(Action))); [HarmonyPrefix] private static bool Prefix(FieldSkillActor __instance, FieldSkillObjectInfo fieldSkillObjectInfo, ref float __result) { try { if (AntacidConfig.HideSprinklerVisual && fieldSkillObjectInfo != null && fieldSkillObjectInfo.fieldSkillMasterID == 70007) { if (SetActorID != null) { SetActorID(__instance, ((ActorBaseInfo)fieldSkillObjectInfo).actorID); } else { AntacidLog.WarnOnce("Spawn.ActorID", "FieldSkillActor.ActorID setter not resolved via reflection (game update?); suppressed sprinkler actor registers under id 0."); } __result = 0f; return false; } } catch (Exception ex) { AntacidLog.WarnOnce("Spawn", "FieldSkillActor.Spawn patch failed (game update?): " + ex.Message); } return true; } } }