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 BloodMoon v0.5.1
BloodMoon.dll
Decompiled 4 days agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using UnityEngine; using UnityEngine.Networking; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyVersion("0.0.0.0")] namespace BloodMoon; [BepInPlugin("com.burks.bloodmoon", "Blood Moon", "0.5.1")] public class BloodMoonPlugin : BaseUnityPlugin { public const string GUID = "com.burks.bloodmoon"; public const string NAME = "Blood Moon"; public const string VERSION = "0.5.1"; public static ManualLogSource Log; public static ConfigEntry<int> IntervalDays; public static ConfigEntry<int> MaxNearby; public static ConfigEntry<int> GroupMin; public static ConfigEntry<int> GroupMax; public static ConfigEntry<bool> SpawnMonsters; public static ConfigEntry<bool> BlockSleep; public static ConfigEntry<bool> RedSky; public static ConfigEntry<bool> HuntPlayers; public static ConfigEntry<bool> MusicOn; public static ConfigEntry<bool> MusicInDungeons; public static ConfigEntry<bool> ShelterSafe; public static ConfigEntry<float> MusicVolume; public static ConfigEntry<float> Intensity; public static ConfigEntry<float> Chance; public static ConfigEntry<float> SpawnInterval; public static ConfigEntry<float> OneStarChance; public static ConfigEntry<float> TwoStarChance; public static ConfigEntry<float> RedStrength; public static ConfigEntry<float> ToughBias; public static ConfigEntry<string> Exclude; private bool _headless; private float _nextState; private float _nextSpawn; private int _phase = -1; private void Awake() { //IL_02b1: Unknown result type (might be due to invalid IL or missing references) //IL_02b7: Invalid comparison between Unknown and I4 //IL_02dc: Unknown result type (might be due to invalid IL or missing references) Log = ((BaseUnityPlugin)this).Logger; IntervalDays = ((BaseUnityPlugin)this).Config.Bind<int>("Schedule", "IntervalDays", 7, "A blood moon rises on the night of every day that divides by this number (7 = days 7, 14, 21 ...)."); Chance = ((BaseUnityPlugin)this).Config.Bind<float>("Schedule", "Chance", 0.5f, "Chance (0-1) that a blood moon actually rises on a scheduled day. 1 = always. Every player must use the same value, or they will disagree about which nights are blood moons."); SpawnMonsters = ((BaseUnityPlugin)this).Config.Bind<bool>("Danger", "SpawnMonsters", true, "Extra monsters from the biome you are in keep appearing around you all night."); SpawnInterval = ((BaseUnityPlugin)this).Config.Bind<float>("Danger", "SpawnIntervalSeconds", 25f, "Seconds between waves around each player."); MaxNearby = ((BaseUnityPlugin)this).Config.Bind<int>("Danger", "MaxNearbyMonsters", 10, "No new wave while this many monsters are already within 60 m of you."); GroupMin = ((BaseUnityPlugin)this).Config.Bind<int>("Danger", "GroupSizeMin", 1, "Smallest wave."); GroupMax = ((BaseUnityPlugin)this).Config.Bind<int>("Danger", "GroupSizeMax", 3, "Largest wave."); OneStarChance = ((BaseUnityPlugin)this).Config.Bind<float>("Danger", "OneStarChance", 0.3f, "Chance (0-1) that a blood moon monster is one-star."); TwoStarChance = ((BaseUnityPlugin)this).Config.Bind<float>("Danger", "TwoStarChance", 0.1f, "Chance (0-1) that a blood moon monster is two-star."); ToughBias = ((BaseUnityPlugin)this).Config.Bind<float>("Danger", "TougherMonsterBias", 0.6f, "0 = every monster of the biome is equally likely, 1 = strongly favour the biome's toughest monsters."); Exclude = ((BaseUnityPlugin)this).Config.Bind<string>("Danger", "ExcludeCreatures", "", "Comma-separated creature prefab names that never appear in a wave. The log names every wave, so copy names from there."); HuntPlayers = ((BaseUnityPlugin)this).Config.Bind<bool>("Danger", "MonstersHuntYou", true, "Blood moon monsters know where you are and come for you, like raid monsters."); BlockSleep = ((BaseUnityPlugin)this).Config.Bind<bool>("Danger", "BlockSleep", true, "Nobody with the mod can sleep through a blood moon."); Intensity = ((BaseUnityPlugin)this).Config.Bind<float>("Danger", "Intensity", 1.6f, "Overall danger multiplier on top of the settings above: waves come this much faster, this many more monsters may be around you at once, and starred monsters are this much more likely. 1 = the 0.3.0 behaviour."); ShelterSafe = ((BaseUnityPlugin)this).Config.Bind<bool>("Danger", "ShelterIsSafe", true, "While you are under a roof (the game's Shelter status), no waves come for you and blood moon monsters stop hunting you."); RedSky = ((BaseUnityPlugin)this).Config.Bind<bool>("Look", "RedSky", true, "Tint the night red."); RedStrength = ((BaseUnityPlugin)this).Config.Bind<float>("Look", "RedSkyStrength", 0.65f, "How strong the red tint is (0-1)."); MusicOn = ((BaseUnityPlugin)this).Config.Bind<bool>("Music", "Music", true, "Play the blood moon track once when the blood moon rises, then keep the music silent for the rest of the night. The track is the audio file (.ogg, .wav or .mp3) next to BloodMoon.dll; a file named bloodmoon.* wins if there are several."); MusicInDungeons = ((BaseUnityPlugin)this).Config.Bind<bool>("Music", "MusicInDungeons", true, "Keep the track playing inside dungeons and other interiors."); MusicVolume = ((BaseUnityPlugin)this).Config.Bind<float>("Music", "MusicVolume", 1f, "Track volume (0-1), on top of the game's own music volume slider."); _headless = (int)SystemInfo.graphicsDeviceType == 4; if (_headless) { ((BaseUnityPlugin)this).Logger.LogInfo((object)"Headless server detected; Blood Moon runs on the players' games, nothing to do here."); return; } new Harmony("com.burks.bloodmoon").PatchAll(Assembly.GetExecutingAssembly()); if (MusicOn.Value) { ((MonoBehaviour)this).StartCoroutine(Music.Load(Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location))); } ((BaseUnityPlugin)this).Logger.LogInfo((object)"Blood Moon 0.5.1 loaded."); } private void Update() { if (_headless) { return; } float unscaledTime = Time.unscaledTime; if (unscaledTime >= _nextState) { _nextState = unscaledTime + 1f; try { UpdateState(); } catch (Exception ex) { Log.LogWarning((object)("State check failed: " + ex.Message)); _nextState = unscaledTime + 30f; } } if (unscaledTime >= _nextSpawn) { _nextSpawn = unscaledTime + Mathf.Clamp(SpawnInterval.Value / Spawner.Intensity, 3f, 600f); try { Spawner.Wave(); } catch (Exception ex2) { Log.LogWarning((object)("Wave failed: " + ex2)); _nextSpawn = unscaledTime + 60f; } } Sky.Fade(Time.unscaledDeltaTime); Music.Tick(Time.unscaledDeltaTime); } private void UpdateState() { if ((Object)(object)Player.m_localPlayer == (Object)null || (Object)(object)EnvMan.instance == (Object)null) { _phase = -1; return; } Commands.Register(); Spawner.UpdateShelter(); int num = (Moon.Active ? 2 : (Moon.Tonight ? 1 : 0)); if (num == _phase) { return; } int phase = _phase; _phase = num; switch (num) { case 1: Say("A blood moon will rise tonight."); break; case 2: Say(BlockSleep.Value ? "The blood moon rises. There will be no sleep tonight." : "The blood moon rises."); break; default: if (phase == 2) { Say("The blood moon fades."); } break; } Log.LogInfo((object)("Day " + EnvMan.instance.GetDay() + ": " + num switch { 1 => "blood moon tonight", 2 => "blood moon is up", _ => "no blood moon", })); } private static void Say(string text) { if ((Object)(object)MessageHud.instance != (Object)null) { MessageHud.instance.ShowMessage((MessageType)2, text, 0, (Sprite)null, false, true); } } } public static class Moon { public static bool Forced; private static int _latchedNight = int.MinValue; public static bool Active { get { if (Forced) { return true; } EnvMan instance = EnvMan.instance; if ((Object)(object)instance == (Object)null) { return false; } int day = instance.GetDay(); float dayFraction = instance.GetDayFraction(); int num = ((dayFraction >= 0.5f) ? day : (day - 1)); if ((dayFraction >= 0.75f && IsBloodDay(day)) || (dayFraction <= 0.25f && IsBloodDay(day - 1))) { _latchedNight = num; return true; } if (_latchedNight == num) { if (!(dayFraction > 0.6f)) { return dayFraction < 0.3f; } return true; } return false; } } public static bool Tonight { get { EnvMan instance = EnvMan.instance; if ((Object)(object)instance == (Object)null || Forced) { return false; } float dayFraction = instance.GetDayFraction(); if (dayFraction > 0.25f && dayFraction < 0.75f) { return IsBloodDay(instance.GetDay()); } return false; } } public static void ClearLatch() { _latchedNight = int.MinValue; } private static bool IsBloodDay(int day) { int num = Mathf.Max(1, BloodMoonPlugin.IntervalDays.Value); if (day <= 0 || day % num != 0) { return false; } float num2 = Mathf.Clamp01(BloodMoonPlugin.Chance.Value); if (num2 >= 1f) { return true; } ulong num3 = (ulong)(day * -7046029254386353131L); try { if ((Object)(object)ZNet.instance != (Object)null) { num3 ^= (ulong)ZNet.instance.GetWorldUID(); } } catch (Exception) { } num3 ^= num3 >> 33; num3 *= 18397679294719823053uL; num3 ^= num3 >> 33; num3 *= 14181476777654086739uL; num3 ^= num3 >> 33; return num3 % 10000 < (ulong)Mathf.RoundToInt(num2 * 10000f); } } public static class Spawner { private static readonly List<SpawnData> _pool = new List<SpawnData>(); private static readonly List<float> _weight = new List<float>(); private static readonly HashSet<string> _exclude = new HashSet<string>(StringComparer.OrdinalIgnoreCase); private static string _excludeRaw; private static readonly List<MonsterAI> _mine = new List<MonsterAI>(); private static bool _safe; public static float Intensity => Mathf.Clamp(BloodMoonPlugin.Intensity.Value, 0.25f, 5f); private static int Bits(int v) { uint num = (uint)v; int num2 = 0; while (num != 0) { num2 += (int)(num & 1); num >>= 1; } return num2; } public static bool Sheltered() { Player localPlayer = Player.m_localPlayer; if (BloodMoonPlugin.ShelterSafe.Value && (Object)(object)localPlayer != (Object)null) { return localPlayer.InShelter(); } return false; } public static void UpdateShelter() { bool flag = Sheltered(); _mine.RemoveAll((MonsterAI a) => (Object)(object)a == (Object)null); if (flag == _safe) { return; } _safe = flag; bool huntPlayer = !flag && BloodMoonPlugin.HuntPlayers.Value && Moon.Active; foreach (MonsterAI item in _mine) { try { ((BaseAI)item).SetHuntPlayer(huntPlayer); } catch (Exception) { } } } public unsafe static void Wave() { //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: 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_01f8: Unknown result type (might be due to invalid IL or missing references) //IL_020c: Unknown result type (might be due to invalid IL or missing references) //IL_0213: Unknown result type (might be due to invalid IL or missing references) //IL_0218: Unknown result type (might be due to invalid IL or missing references) //IL_021d: Unknown result type (might be due to invalid IL or missing references) //IL_0224: Unknown result type (might be due to invalid IL or missing references) //IL_0235: Unknown result type (might be due to invalid IL or missing references) //IL_0259: Unknown result type (might be due to invalid IL or missing references) //IL_0278: Unknown result type (might be due to invalid IL or missing references) //IL_0290: Unknown result type (might be due to invalid IL or missing references) //IL_0292: Unknown result type (might be due to invalid IL or missing references) //IL_0297: Unknown result type (might be due to invalid IL or missing references) //IL_02a0: Unknown result type (might be due to invalid IL or missing references) //IL_02a7: Unknown result type (might be due to invalid IL or missing references) //IL_02ae: Unknown result type (might be due to invalid IL or missing references) //IL_02b3: Unknown result type (might be due to invalid IL or missing references) //IL_0381: Unknown result type (might be due to invalid IL or missing references) //IL_0386: Unknown result type (might be due to invalid IL or missing references) //IL_0388: Unknown result type (might be due to invalid IL or missing references) //IL_06e6: Unknown result type (might be due to invalid IL or missing references) //IL_070b: Unknown result type (might be due to invalid IL or missing references) //IL_0710: Unknown result type (might be due to invalid IL or missing references) //IL_0715: Unknown result type (might be due to invalid IL or missing references) //IL_071c: Unknown result type (might be due to invalid IL or missing references) //IL_0757: Unknown result type (might be due to invalid IL or missing references) //IL_0772: Unknown result type (might be due to invalid IL or missing references) //IL_0419: Unknown result type (might be due to invalid IL or missing references) //IL_0423: Expected I4, but got Unknown //IL_0514: Unknown result type (might be due to invalid IL or missing references) //IL_051a: Invalid comparison between Unknown and I4 if (Sheltered() || !BloodMoonPlugin.SpawnMonsters.Value || !Moon.Active) { return; } Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null || ((Character)localPlayer).IsDead() || ((Character)localPlayer).IsTeleporting() || ((Character)localPlayer).InInterior() || (Object)(object)ZoneSystem.instance == (Object)null || (Object)(object)ZNetScene.instance == (Object)null) { return; } Vector3 position = ((Component)localPlayer).transform.position; int num = 0; foreach (Character allCharacter in Character.GetAllCharacters()) { if (!((Object)(object)allCharacter == (Object)null) && !allCharacter.IsPlayer() && !allCharacter.IsDead() && !allCharacter.IsTamed()) { Vector3 val = ((Component)allCharacter).transform.position - position; if (!(((Vector3)(ref val)).sqrMagnitude > 3600f) && (Object)(object)((Component)allCharacter).GetComponent<MonsterAI>() != (Object)null) { num++; } } } if (num >= Mathf.RoundToInt((float)BloodMoonPlugin.MaxNearby.Value * Intensity)) { return; } if (_excludeRaw != BloodMoonPlugin.Exclude.Value) { _excludeRaw = BloodMoonPlugin.Exclude.Value; _exclude.Clear(); string[] array = (_excludeRaw ?? "").Split(','); foreach (string text in array) { if (text.Trim().Length > 0) { _exclude.Add(text.Trim()); } } } SpawnSystem val2 = Object.FindFirstObjectByType<SpawnSystem>(); if ((Object)(object)val2 == (Object)null || val2.m_spawnLists == null) { return; } float waterLevel = ZoneSystem.instance.m_waterLevel; float num4 = default(float); float num16 = default(float); for (int j = 0; j < 30; j++) { float num2 = Random.Range(0f, (float)Math.PI * 2f); float num3 = ((j < 10) ? Random.Range(22f, 40f) : Random.Range(40f, 90f)); Vector3 val3 = position + new Vector3(Mathf.Cos(num2), 0f, Mathf.Sin(num2)) * num3; if (!ZNetScene.instance.IsAreaReady(val3) || !ZoneSystem.instance.GetSolidHeight(val3, ref num4, 1000) || num4 < waterLevel + 0.3f || Mathf.Abs(num4 - position.y) > 30f) { continue; } val3.y = num4; if ((Object)(object)EffectArea.IsPointInsideArea(val3, (Type)4, 3f) != (Object)null) { continue; } Biome val4 = Heightmap.FindBiome(val3); float num5 = num4 - waterLevel; Vector2 val5 = new Vector2(val3.x, val3.z); float magnitude = ((Vector2)(ref val5)).magnitude; float num6 = Mathf.Clamp01(BloodMoonPlugin.ToughBias.Value); _pool.Clear(); _weight.Clear(); float num7 = 0f; foreach (SpawnSystemList spawnList in val2.m_spawnLists) { if ((Object)(object)spawnList == (Object)null || spawnList.m_spawners == null) { continue; } foreach (SpawnData d in spawnList.m_spawners) { if (d != null && d.m_enabled && !((Object)(object)d.m_prefab == (Object)null) && (d.m_biome & val4) != 0 && d.m_spawnAtNight && !(num5 < d.m_minAltitude) && !(num5 > d.m_maxAltitude) && (!d.m_inLava || d.m_outsideLava) && (string.IsNullOrEmpty(d.m_requiredGlobalKey) || ZoneSystem.instance.GetGlobalKey(d.m_requiredGlobalKey)) && Bits((int)d.m_biome) <= 2 && string.IsNullOrEmpty(d.m_requiredPersistentEvent) && (d.m_requiredEnvironments == null || d.m_requiredEnvironments.Count <= 0) && (!(d.m_minDistanceFromCenter > 0f) || !(magnitude < d.m_minDistanceFromCenter)) && (!(d.m_maxDistanceFromCenter > 0f) || !(magnitude > d.m_maxDistanceFromCenter)) && !((Object)(object)d.m_prefab.GetComponent<MonsterAI>() == (Object)null) && !_exclude.Contains(((Object)d.m_prefab).name)) { Character component = d.m_prefab.GetComponent<Character>(); if (!((Object)(object)component == (Object)null) && !component.IsBoss() && (int)component.m_faction != 1 && !_pool.Exists((SpawnData x) => (Object)(object)x.m_prefab == (Object)(object)d.m_prefab)) { float num8 = Mathf.Pow(Mathf.Max(1f, component.m_health), num6); _pool.Add(d); _weight.Add(num8); num7 += num8; } } } } if (_pool.Count == 0) { continue; } float num9 = Random.value * num7; int index = _pool.Count - 1; for (int num10 = 0; num10 < _pool.Count; num10++) { num9 -= _weight[num10]; if (num9 <= 0f) { index = num10; break; } } SpawnData val6 = _pool[index]; int num11 = Mathf.Max(1, BloodMoonPlugin.GroupMin.Value); int num12 = Mathf.Max(num11, BloodMoonPlugin.GroupMax.Value); int num13 = Random.Range(num11, num12 + 1); Character component2 = val6.m_prefab.GetComponent<Character>(); if ((Object)(object)component2 != (Object)null && component2.m_health >= 400f) { num13 = 1; } GameObject val7 = null; if (((Object)val6.m_prefab).name == "Greydwarf" && !_exclude.Contains("Greydwarf_Elite")) { val7 = ZNetScene.instance.GetPrefab("Greydwarf_Elite"); if ((Object)(object)val7 != (Object)null && (Object)(object)val7.GetComponent<MonsterAI>() == (Object)null) { val7 = null; } } int num14 = 0; for (int num15 = 0; num15 < num13 + (((Object)(object)val7 != (Object)null) ? 1 : 0); num15++) { GameObject val8 = ((num15 < num13) ? val6.m_prefab : val7); Vector3 val9 = val3 + new Vector3(Random.Range(-3f, 3f), 0f, Random.Range(-3f, 3f)); if (!ZoneSystem.instance.GetSolidHeight(val9, ref num16, 1000) || num16 < waterLevel + 0.3f) { continue; } val9.y = num16 + 0.5f + val6.m_groundOffset; GameObject obj = Object.Instantiate<GameObject>(val8, val9, Quaternion.Euler(0f, Random.Range(0f, 360f), 0f)); Character component3 = obj.GetComponent<Character>(); if ((Object)(object)component3 != (Object)null) { float value = Random.value; float num17 = Mathf.Clamp01(BloodMoonPlugin.TwoStarChance.Value * Intensity); float num18 = Mathf.Clamp01(BloodMoonPlugin.OneStarChance.Value * Intensity); if (value < num17) { component3.SetLevel(3); } else if (value < num17 + num18) { component3.SetLevel(2); } } MonsterAI component4 = obj.GetComponent<MonsterAI>(); if ((Object)(object)component4 != (Object)null) { component4.SetDespawnInDay(true); if (BloodMoonPlugin.HuntPlayers.Value) { ((BaseAI)component4).SetHuntPlayer(true); } _mine.Add(component4); } num14++; } if (num14 > 0) { BloodMoonPlugin.Log.LogInfo((object)("Wave: " + num14 + " x " + ((Object)val6.m_prefab).name + (((Object)(object)val7 != (Object)null) ? " (one of them a brute)" : "") + " in " + ((object)(*(Biome*)(&val4))/*cast due to .constrained prefix*/).ToString() + ".")); } break; } } } [HarmonyPatch(typeof(EnvMan), "SetEnv")] public static class Sky { private static float _k; private static readonly int SunFog = Shader.PropertyToID("_SunFogColor"); private static readonly int Sun = Shader.PropertyToID("_SunColor"); private static readonly int Ambient = Shader.PropertyToID("_AmbientColor"); public static void Fade(float dt) { bool flag = false; try { flag = BloodMoonPlugin.RedSky.Value && (Object)(object)Player.m_localPlayer != (Object)null && Moon.Active && !((Character)Player.m_localPlayer).InInterior(); } catch { flag = false; } _k = Mathf.MoveTowards(_k, flag ? 1f : 0f, dt / 6f); } private static Color Tint(Color c, float amount) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0050: 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) float num = Mathf.Max(c.r, Mathf.Max(c.g, c.b)); Color val = default(Color); ((Color)(ref val))..ctor(Mathf.Min(1.5f, num * 1.5f + 0.1f), num * 0.12f, num * 0.1f, c.a); return Color.Lerp(c, val, amount); } [HarmonyPostfix] public static void Postfix(EnvMan __instance) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: 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_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) if (_k <= 0.001f) { return; } try { float amount = _k * Mathf.Clamp01(BloodMoonPlugin.RedStrength.Value); RenderSettings.ambientLight = Tint(RenderSettings.ambientLight, amount); RenderSettings.fogColor = Tint(RenderSettings.fogColor, amount); if ((Object)(object)__instance.m_dirLight != (Object)null) { __instance.m_dirLight.color = Tint(__instance.m_dirLight.color, amount); } Shader.SetGlobalColor(SunFog, Tint(Shader.GetGlobalColor(SunFog), amount)); Shader.SetGlobalColor(Sun, Tint(Shader.GetGlobalColor(Sun), amount)); Shader.SetGlobalColor(Ambient, Tint(Shader.GetGlobalColor(Ambient), amount)); } catch { } } } [HarmonyPatch(typeof(EnvMan), "CanSleep")] public static class SleepPatch { [HarmonyPostfix] public static void Postfix(ref bool __result) { try { if (__result && BloodMoonPlugin.BlockSleep.Value && Moon.Active) { __result = false; } } catch { } } } public static class Commands { private static bool _done; public static void Register() { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Expected O, but got Unknown //IL_002e: Unknown result type (might be due to invalid IL or missing references) if (_done) { return; } _done = true; try { new ConsoleCommand("bloodmoon", "start | stop | status - test the blood moon on your own game", new ConsoleEvent(Run), false, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false); } catch (Exception ex) { BloodMoonPlugin.Log.LogWarning((object)("Could not add the 'bloodmoon' console command: " + ex.Message)); } } private static void Run(ConsoleEventArgs args) { string text = ((args.Args.Length > 1) ? args.Args[1].ToLowerInvariant() : "status"); if (text == "start") { Moon.Forced = true; args.Context.AddString("Blood moon forced on (your game only). 'bloodmoon stop' ends it."); return; } if (text == "stop") { Moon.Forced = false; Moon.ClearLatch(); args.Context.AddString("Forced blood moon ended."); return; } int num = Mathf.Max(1, BloodMoonPlugin.IntervalDays.Value); int num2 = (((Object)(object)EnvMan.instance != (Object)null) ? EnvMan.instance.GetDay() : 0); int num3 = (num2 / num + 1) * num; if (num2 > 0 && num2 % num == 0 && !Moon.Active && EnvMan.instance.GetDayFraction() < 0.75f) { num3 = num2; } args.Context.AddString("Day " + num2 + ". Blood moon " + (Moon.Active ? "is up now" : ("next on the night of day " + num3)) + " (every " + num + " days)."); } } [HarmonyPatch(typeof(MusicMan), "UpdateCurrentMusic")] public static class Music { public const string Name = "bloodmoon"; private static AudioClip _clip; private static readonly MethodInfo StopM = AccessTools.Method(typeof(MusicMan), "StopMusic", (Type[])null, (Type[])null); private static readonly MethodInfo CurrentM = AccessTools.Method(typeof(MusicMan), "GetCurrentMusic", (Type[])null, (Type[])null); private static AudioSource _src; private static bool _played; private static bool _warned; private static float _vol; public static IEnumerator Load(string dir) { string file = null; try { string[] files = Directory.GetFiles(dir); foreach (string text in files) { string text2 = Path.GetExtension(text).ToLowerInvariant(); if ((!(text2 != ".ogg") || !(text2 != ".wav") || !(text2 != ".mp3")) && (file == null || Path.GetFileNameWithoutExtension(text).ToLowerInvariant() == "bloodmoon")) { file = text; } } } catch (Exception ex) { BloodMoonPlugin.Log.LogWarning((object)("Could not look for a music file: " + ex.Message)); } if (file == null) { BloodMoonPlugin.Log.LogInfo((object)"No music file (.ogg, .wav, .mp3) next to BloodMoon.dll; blood moons will be silent."); yield break; } string text3 = Path.GetExtension(file).ToLowerInvariant(); AudioType val = (AudioType)((text3 == ".ogg") ? 14 : ((text3 == ".wav") ? 20 : 13)); UnityWebRequest req = UnityWebRequestMultimedia.GetAudioClip(new Uri(file).AbsoluteUri, val); try { yield return req.SendWebRequest(); AudioClip val2 = null; try { if (string.IsNullOrEmpty(req.error)) { val2 = DownloadHandlerAudioClip.GetContent(req); } } catch (Exception ex2) { BloodMoonPlugin.Log.LogWarning((object)("Music file could not be decoded: " + ex2.Message)); } if ((Object)(object)val2 == (Object)null || val2.length <= 0f) { BloodMoonPlugin.Log.LogWarning((object)("Could not load music file " + Path.GetFileName(file) + ": " + req.error)); yield break; } ((Object)val2).name = "bloodmoon"; _clip = val2; BloodMoonPlugin.Log.LogInfo((object)("Music loaded: " + Path.GetFileName(file) + " (" + Mathf.RoundToInt(val2.length) + " s).")); } finally { ((IDisposable)req)?.Dispose(); } } private static bool Wanted() { Player localPlayer = Player.m_localPlayer; if ((Object)(object)_clip == (Object)null || !BloodMoonPlugin.MusicOn.Value || (Object)(object)localPlayer == (Object)null || !Moon.Active) { return false; } if (!BloodMoonPlugin.MusicInDungeons.Value) { return !((Character)localPlayer).InInterior(); } return true; } public static void Tick(float dt) { //IL_005d: 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) //IL_0068: Expected O, but got Unknown try { if ((Object)(object)_clip == (Object)null) { return; } if (!((Object)(object)Player.m_localPlayer != (Object)null) || !Moon.Active) { _played = false; } bool flag = Wanted(); if (flag && !_played) { _played = true; if ((Object)(object)_src == (Object)null) { GameObject val = new GameObject("BloodMoonMusic"); Object.DontDestroyOnLoad((Object)val); _src = val.AddComponent<AudioSource>(); _src.spatialBlend = 0f; _src.loop = false; _src.playOnAwake = false; _src.bypassReverbZones = true; _src.priority = 0; } _src.clip = _clip; _vol = 0f; _src.volume = 0f; _src.Play(); BloodMoonPlugin.Log.LogInfo((object)"Blood moon track playing."); } if (!((Object)(object)_src == (Object)null) && _src.isPlaying) { _vol = Mathf.MoveTowards(_vol, flag ? 1f : 0f, dt / 2f); _src.volume = _vol * Mathf.Clamp01(BloodMoonPlugin.MusicVolume.Value) * Mathf.Clamp01(MusicMan.m_masterMusicVolume); if (!flag && _vol <= 0f) { _src.Stop(); } } } catch (Exception ex) { if (!_warned) { _warned = true; BloodMoonPlugin.Log.LogWarning((object)("Music failed: " + ex)); } } } [HarmonyPrefix] public static bool Prefix(MusicMan __instance) { try { if (!Wanted()) { return true; } if (!string.IsNullOrEmpty(CurrentM.Invoke(__instance, null) as string)) { StopM.Invoke(__instance, null); } return false; } catch (Exception) { return true; } } }