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 Fimbulvetr v1.1.0
Fimbulvetr.dll
Decompiled 11 hours agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using HarmonyLib; using Microsoft.CodeAnalysis; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.6.2", FrameworkDisplayName = "")] [assembly: AssemblyVersion("0.0.0.0")] [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 Fimbulvetr { [BepInPlugin("com.chase.fimbulvetr", "Fimbulvetr", "1.1.0")] public class Plugin : BaseUnityPlugin { private class Fragment { public Vector3 center; public Vector3 halfSize; public Quaternion rotation; public float radius; } private class SheetState { public Fragment[] fragments; public float fullHealth; public double lastTick; public float lastStamp; public float progress; public float awayCarry; } private struct Heat { public Vector3 pos; public bool pyre; } [HarmonyPatch(typeof(MineRock5), "Awake")] private static class RegisterSheet { private static void Postfix(MineRock5 __instance) { if (!s_replaying && (Object)(object)Instance != (Object)null && Instance.IsIceSheet(__instance)) { s_sheets.Add(__instance); } } } [HarmonyPatch(typeof(Destructible), "Awake")] private static class RegisterWholeSheet { private static void Postfix(Destructible __instance) { MineRock5 val = (((Object)(object)__instance.m_spawnWhenDestroyed != (Object)null) ? __instance.m_spawnWhenDestroyed.GetComponent<MineRock5>() : null); if (!s_replaying && (Object)(object)val != (Object)null && (Object)(object)Instance != (Object)null && Instance.IsIceSheet(val)) { s_wholeSheets.RemoveWhere((Destructible d) => (Object)(object)d == (Object)null); s_wholeSheets.Add(__instance); } } } [HarmonyPatch(typeof(Fireplace), "Awake")] private static class RegisterFire { private static void Postfix(Fireplace __instance) { s_fires.RemoveWhere((Fireplace f) => (Object)(object)f == (Object)null); s_fires.Add(__instance); } } [HarmonyPatch(typeof(Piece), "Awake")] private static class RegisterPyre { private static void Postfix(Piece __instance) { if (__instance.m_name != "$piece_faderember") { return; } s_pyres.Add(__instance); if (!s_loggedPyre && (Object)(object)Instance != (Object)null) { s_loggedPyre = true; List<string> list = new List<string>(); Component[] components = ((Component)__instance).GetComponents<Component>(); foreach (Component val in components) { list.Add(((object)val).GetType().Name); } ((BaseUnityPlugin)Instance).Logger.LogInfo((object)("Eternal Pyre found: " + ((Object)((Component)__instance).gameObject).name + " (" + string.Join(", ", list) + ")")); } } } [HarmonyPatch(typeof(MineRock5), "DamageArea")] private static class KeepBrokenSheet { private static void Prefix(MineRock5 __instance) { s_breaking = (((Object)(object)Instance != (Object)null && Instance.m_enabled.Value && Instance.m_iceRefreeze.Value && s_sheets.Contains(__instance)) ? __instance : null); } private static void Postfix(MineRock5 __instance) { if ((Object)(object)s_breaking == (Object)(object)__instance) { f_mrAllDestroyed.SetValue(__instance, false); } s_breaking = null; } } [HarmonyPatch(typeof(ZNetView), "Destroy")] private static class SkipSheetDestroy { private static bool Prefix(ZNetView __instance) { if (!((Object)(object)s_breaking == (Object)null)) { return (Object)(object)((Component)__instance).gameObject != (Object)(object)((Component)s_breaking).gameObject; } return true; } } private class ZoneState { public bool[] deepNorth; public byte[] shelter; public float shelterCheckedAt; public double lastTick; public float lastSave; public bool dirty; public float pending; } [HarmonyPatch(typeof(TerrainComp), "Save")] private static class StampSaveTime { private static void Postfix(TerrainComp __instance) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Expected O, but got Unknown //IL_003d: Unknown result type (might be due to invalid IL or missing references) try { ZNetView val = (ZNetView)f_nview.GetValue(__instance); if ((Object)(object)val != (Object)null && val.IsValid() && val.IsOwner() && (Object)(object)ZNet.instance != (Object)null && TouchesDeepNorth(((Component)__instance).transform.position)) { ZDO zDO = val.GetZDO(); zDO.Set(s_lastSnowTime, (long)ZNet.instance.GetTimeSeconds()); f_lastDataRevision.SetValue(__instance, zDO.DataRevision); } } catch { } } } [HarmonyPatch(typeof(ZNet), "Shutdown")] private static class SaveOnShutdown { private static void Prefix() { try { Instance?.SaveAll(); } catch { } } } [HarmonyPatch(typeof(Terminal), "InitTerminal")] private static class Commands { [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static ConsoleEvent <>9__0_0; internal void <Postfix>b__0_0(ConsoleEventArgs args) { if ((Object)(object)Instance == (Object)null) { return; } if (args.Length > 1) { string text = args[1].ToLowerInvariant(); if (text == "disable" || text == "enable") { Instance.m_enabled.Value = text == "enable"; Instance.m_zones.Clear(); Instance.m_sheetStates.Clear(); Instance.m_zonesChecked.Clear(); Instance.m_resumeTime = (((Object)(object)ZNet.instance != (Object)null) ? ZNet.instance.GetTimeSeconds() : 0.0); } else { Instance.m_force = ((text == "off") ? "" : text); } } args.Context.AddString(Instance.Status()); } } private static void Postfix() { //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Expected O, but got Unknown object obj = <>c.<>9__0_0; if (obj == null) { ConsoleEvent val = delegate(ConsoleEventArgs args) { if (!((Object)(object)Instance == (Object)null)) { if (args.Length > 1) { string text = args[1].ToLowerInvariant(); if (text == "disable" || text == "enable") { Instance.m_enabled.Value = text == "enable"; Instance.m_zones.Clear(); Instance.m_sheetStates.Clear(); Instance.m_zonesChecked.Clear(); Instance.m_resumeTime = (((Object)(object)ZNet.instance != (Object)null) ? ZNet.instance.GetTimeSeconds() : 0.0); } else { Instance.m_force = ((text == "off") ? "" : text); } } args.Context.AddString(Instance.Status()); } }; <>c.<>9__0_0 = val; obj = (object)val; } new ConsoleCommand("fimbul", "[calm|snow|storm|off|enable|disable] Deep North snow regrowth and ice refreezing: show status and cost, force a weather rate, or switch it off", (ConsoleEvent)obj, false, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false); } } private struct Original { public string prefab; public string frac; public Vector3 pos; public Quaternion rot; public Vector3 scale; } [HarmonyPatch(typeof(ZoneSystem), "IsBlocked")] private static class ReplayBlockCheck { private static readonly RaycastHit[] s_hits = (RaycastHit[])(object)new RaycastHit[32]; private static bool Prefix(Vector3 p, ref bool __result) { //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) if (!s_replaying) { return true; } if (s_blockMaskNoPieces == 0) { s_blockMaskNoPieces = LayerMask.GetMask(new string[3] { "Default", "static_solid", "Default_small" }); } p.y += 2000f; int num = Physics.RaycastNonAlloc(p, Vector3.down, s_hits, 10000f, s_blockMaskNoPieces); __result = false; for (int i = 0; i < num; i++) { ZNetView componentInParent = ((Component)((RaycastHit)(ref s_hits[i])).collider).GetComponentInParent<ZNetView>(); if (!((Object)(object)componentInParent != (Object)null) || componentInParent.GetZDO() == null || !s_iceNames.Contains(ZdoPrefabName(componentInParent))) { __result = true; break; } } return false; } } private const string PyrePieceName = "$piece_faderember"; private static readonly int s_iceLastTime = StringExtensionMethods.GetStableHashCode("fimbul_iceLast"); private static readonly Type t_hitArea = AccessTools.Inner(typeof(MineRock5), "HitArea"); private static readonly FieldInfo f_hitAreas = AccessTools.Field(typeof(MineRock5), "m_hitAreas"); private static readonly FieldInfo f_haHealth = AccessTools.Field(t_hitArea, "m_health"); private static readonly FieldInfo f_haMesh = AccessTools.Field(t_hitArea, "m_meshFilter"); private static readonly FieldInfo f_mrNview = AccessTools.Field(typeof(MineRock5), "m_nview"); private static readonly FieldInfo f_mrAllDestroyed = AccessTools.Field(typeof(MineRock5), "m_allDestroyed"); private static readonly FieldInfo f_mrLastRevision = AccessTools.Field(typeof(MineRock5), "m_lastDataRevision"); private static readonly MethodInfo m_loadHealth = AccessTools.Method(typeof(MineRock5), "LoadHealth", (Type[])null, (Type[])null); private static readonly MethodInfo m_saveHealth = AccessTools.Method(typeof(MineRock5), "SaveHealth", (Type[])null, (Type[])null); private static readonly HashSet<MineRock5> s_sheets = new HashSet<MineRock5>(); private static readonly HashSet<Piece> s_pyres = new HashSet<Piece>(); private static readonly HashSet<Fireplace> s_fires = new HashSet<Fireplace>(); private static readonly HashSet<Destructible> s_wholeSheets = new HashSet<Destructible>(); private static bool s_loggedPyre; private static MineRock5 s_breaking; private ConfigEntry<bool> m_iceRefreeze; private ConfigEntry<string> m_icePrefabs; private ConfigEntry<float> m_iceMinutes; private ConfigEntry<float> m_icePlayerDistance; private ConfigEntry<bool> m_iceHeat; private ConfigEntry<float> m_iceHeatMargin; private ConfigEntry<bool> m_icePyre; private ConfigEntry<float> m_icePyreRadius; private readonly Dictionary<MineRock5, SheetState> m_sheetStates = new Dictionary<MineRock5, SheetState>(); private readonly List<MineRock5> m_sheetScratch = new List<MineRock5>(); private readonly List<int> m_eligible = new List<int>(); private readonly Collider[] m_overlap = (Collider[])(object)new Collider[8]; private int m_blockMask; private int m_refrozen; private int m_thawed; private readonly Dictionary<string, bool> m_iceKinds = new Dictionary<string, bool>(); private float m_newSheetCheck; private readonly List<MineRock5> m_gone2 = new List<MineRock5>(); private readonly List<Heat> m_heat = new List<Heat>(); private readonly List<ZDO> m_heatZdos = new List<ZDO>(); private readonly Dictionary<int, int> m_heatKinds = new Dictionary<int, int>(); private static readonly MethodInfo m_handleDestroyed = AccessTools.Method(typeof(ZDOMan), "HandleDestroyedZDO", (Type[])null, (Type[])null); public const string Guid = "com.chase.fimbulvetr"; public const string Version = "1.1.0"; private const float MetresAtFullMask = 2f; private static readonly int s_lastSnowTime = StringExtensionMethods.GetStableHashCode("fimbul_lastSnow"); private static readonly FieldInfo f_instances = AccessTools.Field(typeof(TerrainComp), "s_instances"); private static readonly FieldInfo f_paintMask = AccessTools.Field(typeof(TerrainComp), "m_paintMask"); private static readonly FieldInfo f_modifiedPaint = AccessTools.Field(typeof(TerrainComp), "m_modifiedPaint"); private static readonly FieldInfo f_hmap = AccessTools.Field(typeof(TerrainComp), "m_hmap"); private static readonly FieldInfo f_nview = AccessTools.Field(typeof(TerrainComp), "m_nview"); private static readonly FieldInfo f_initialized = AccessTools.Field(typeof(TerrainComp), "m_initialized"); private static readonly FieldInfo f_lastDataRevision = AccessTools.Field(typeof(TerrainComp), "m_lastDataRevision"); private static readonly FieldInfo f_buildData = AccessTools.Field(typeof(Heightmap), "m_buildData"); private static readonly MethodInfo m_save = AccessTools.Method(typeof(TerrainComp), "Save", (Type[])null, (Type[])null); internal static Plugin Instance; private ConfigEntry<bool> m_enabled; private ConfigEntry<float> m_calmRate; private ConfigEntry<float> m_snowfallRate; private ConfigEntry<float> m_stormRate; private ConfigEntry<bool> m_catchUp; private ConfigEntry<bool> m_protectRoofs; private ConfigEntry<bool> m_protectShields; private ConfigEntry<bool> m_fireMelts; private ConfigEntry<float> m_range; private ConfigEntry<float> m_tickInterval; private ConfigEntry<float> m_saveInterval; private ConfigEntry<float> m_minStep; private ConfigEntry<int> m_maxRedrawsPerTick; private readonly Dictionary<TerrainComp, ZoneState> m_zones = new Dictionary<TerrainComp, ZoneState>(); private readonly List<TerrainComp> m_scratch = new List<TerrainComp>(); private readonly List<TerrainComp> m_gone = new List<TerrainComp>(); private readonly HashSet<TerrainComp> m_toSync = new HashSet<TerrainComp>(); private float m_timer; private readonly Stopwatch m_watch = new Stopwatch(); private double m_tickMs; private int m_ticks; private int m_redraws; private float m_statsSince; private int m_shelterMask; private int m_pieceMask; private float m_minSnowBuildup = -1f; private float m_maxSnowBuildup = -1f; private double m_resumeTime; internal string m_force = ""; private static readonly MethodInfo m_placeVegetation = AccessTools.Method(typeof(ZoneSystem), "PlaceVegetation", (Type[])null, (Type[])null); private static readonly MethodInfo m_updateMesh = AccessTools.Method(typeof(MineRock5), "UpdateMesh", (Type[])null, (Type[])null); private static readonly Type t_clearArea = AccessTools.Inner(typeof(ZoneSystem), "ClearArea"); private static readonly FieldInfo f_spawnSystems = AccessTools.Field(typeof(SpawnSystem), "m_instances"); private static readonly FieldInfo f_spawnNview = AccessTools.Field(typeof(SpawnSystem), "m_nview"); private static bool s_replaying; private static int s_blockMaskNoPieces; private ConfigEntry<bool> m_iceRestore; private List<ZoneVegetation> m_iceVegetation; private readonly Dictionary<string, string> m_iceFrac = new Dictionary<string, string>(); private static readonly HashSet<string> s_iceNames = new HashSet<string>(); private readonly HashSet<Vector2s> m_zonesChecked = new HashSet<Vector2s>(); private readonly Dictionary<Vector2s, float> m_zoneSeen = new Dictionary<Vector2s, float>(); private readonly List<GameObject> m_ghosts = new List<GameObject>(); private int m_restored; private int m_removedDuplicates; private static readonly int s_restoredFlag = StringExtensionMethods.GetStableHashCode("fimbul_restored"); private readonly List<ZDO> m_zoneZdos = new List<ZDO>(); private readonly List<ZDO> m_iceZdos = new List<ZDO>(); private void BindIce() { m_iceRefreeze = ((BaseUnityPlugin)this).Config.Bind<bool>("Ice", "RefreezeIce", true, "Broken Deep North Ice Sheets slowly freeze back over, faster in snowstorms. A sheet broken completely is kept so it can refreeze."); m_icePrefabs = ((BaseUnityPlugin)this).Config.Bind<string>("Ice", "IcePrefabs", "IceShore", "Comma-separated prefab name prefixes of the ice sheets that refreeze. Any mineable rock that drops Ice also counts."); m_iceMinutes = ((BaseUnityPlugin)this).Config.Bind<float>("Ice", "MinutesPerPiece", 6f, "Real minutes for one broken piece of a sheet to refreeze in light snowfall. Scales with the snow rates: about 5x slower with no snow falling, 5x faster in the heaviest blizzard (default rates)."); m_icePlayerDistance = ((BaseUnityPlugin)this).Config.Bind<float>("Ice", "PlayerDistance", 30f, "Ice never refreezes within this many metres of a player, so nobody gets frozen in or sees it pop back."); m_iceHeat = ((BaseUnityPlugin)this).Config.Bind<bool>("Ice", "HeatKeepsWaterOpen", true, "Ice doesn't refreeze where the heat of a campfire, hearth, brazier or other heat source reaches it."); m_iceHeatMargin = ((BaseUnityPlugin)this).Config.Bind<float>("Ice", "FireReach", 8f, "Ice doesn't refreeze within this many metres of a lit fire: torches, campfires, braziers, hearths and the like."); m_icePyre = ((BaseUnityPlugin)this).Config.Bind<bool>("Ice", "EternalPyreThaws", true, "A lit Eternal Pyre thaws all ice within PyreRadius, a piece at a time, and keeps it from refreezing. Thawed ice drops nothing."); m_icePyreRadius = ((BaseUnityPlugin)this).Config.Bind<float>("Ice", "PyreRadius", 40f, "Metres around a lit Eternal Pyre that are kept ice-free."); BindRestore(); } internal static string PrefabNameOf(MineRock5 rock) { ZNetView component = ((Component)rock).GetComponent<ZNetView>(); ZDO val = ((component != null) ? component.GetZDO() : null); if (val != null && (Object)(object)ZNetScene.instance != (Object)null) { GameObject prefab = ZNetScene.instance.GetPrefab(val.GetPrefab()); if ((Object)(object)prefab != (Object)null) { return ((Object)prefab).name; } } return Utils.GetPrefabName(((Component)rock).gameObject); } private bool IsIceSheet(MineRock5 rock) { //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_004e: 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) string text = PrefabNameOf(rock); if (m_iceKinds.TryGetValue(text, out var value)) { return value; } bool flag = IsIcePrefab(text); if (!flag && rock.m_dropItems != null) { foreach (DropData drop in rock.m_dropItems.m_drops) { ItemDrop val = (((Object)(object)drop.m_item != (Object)null) ? drop.m_item.GetComponent<ItemDrop>() : null); if ((Object)(object)val != (Object)null && val.m_itemData?.m_shared?.m_name == "$item_ice") { flag = true; break; } } } m_iceKinds[text] = flag; ((BaseUnityPlugin)this).Logger.LogInfo((object)("Mineable rock kind " + text + " (" + rock.m_name + "): " + (flag ? "ice sheet, will refreeze" : "not ice"))); return flag; } private float IceRate(float snowRate) { float num = Mathf.Max(0.01f, m_snowfallRate.Value); return snowRate / num / (Mathf.Max(0.1f, m_iceMinutes.Value) * 60f); } private bool HasNewSheet() { //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Expected O, but got Unknown //IL_0079: 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_0098: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Unknown result type (might be due to invalid IL or missing references) if (!m_iceRefreeze.Value || Time.time - m_newSheetCheck < 0.5f) { return false; } m_newSheetCheck = Time.time; foreach (MineRock5 s_sheet in s_sheets) { if ((Object)(object)s_sheet != (Object)null && !m_sheetStates.ContainsKey(s_sheet)) { ZNetView val = (ZNetView)f_mrNview.GetValue(s_sheet); Vector3 position = ((Component)s_sheet).transform.position; if ((Object)(object)val != (Object)null && val.IsValid() && val.IsOwner() && Vector3.Distance(position, ((Component)Player.m_localPlayer).transform.position) <= m_range.Value + 30f && WorldGenerator.IsDeepnorth(position.x, position.z) && ZNetScene.instance.IsAreaReady(position)) { return true; } } } return false; } private void IceTick(double now) { //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Expected O, but got Unknown //IL_0139: Unknown result type (might be due to invalid IL or missing references) //IL_013e: Unknown result type (might be due to invalid IL or missing references) //IL_0140: Unknown result type (might be due to invalid IL or missing references) //IL_0142: Unknown result type (might be due to invalid IL or missing references) //IL_014e: Unknown result type (might be due to invalid IL or missing references) //IL_0155: Unknown result type (might be due to invalid IL or missing references) //IL_0166: Unknown result type (might be due to invalid IL or missing references) //IL_01c8: Unknown result type (might be due to invalid IL or missing references) //IL_020f: Unknown result type (might be due to invalid IL or missing references) //IL_0219: Expected O, but got Unknown //IL_0445: Unknown result type (might be due to invalid IL or missing references) //IL_0447: Unknown result type (might be due to invalid IL or missing references) if (!m_iceRefreeze.Value) { return; } CollectHeat(); CrackWholeSheetsNearPyres(); if (m_blockMask == 0) { m_blockMask = LayerMask.GetMask(new string[5] { "vehicle", "character", "character_net", "character_ghost", "item" }); } string label; float num = IceRate(CurrentRate(out label)); float num2 = IceRate(m_calmRate.Value); Vector3 position = ((Component)Player.m_localPlayer).transform.position; float num3 = m_range.Value + 30f; m_sheetScratch.Clear(); m_sheetScratch.AddRange(s_sheets); foreach (MineRock5 item in m_sheetScratch) { if ((Object)(object)item == (Object)null) { s_sheets.Remove(item); continue; } ZNetView val = (ZNetView)f_mrNview.GetValue(item); if ((Object)(object)val == (Object)null || !val.IsValid() || !val.IsOwner()) { m_sheetStates.Remove(item); continue; } Vector3 position2 = ((Component)item).transform.position; if (Vector3.Distance(position2, position) > num3 || !WorldGenerator.IsDeepnorth(position2.x, position2.z) || !SurroundingsLoaded(position2)) { continue; } ZDO zDO = val.GetZDO(); m_loadHealth.Invoke(item, null); IList list = (IList)f_hitAreas.GetValue(item); if (list == null || list.Count == 0) { continue; } if (!m_sheetStates.TryGetValue(item, out var value)) { if (!ZNetScene.instance.IsAreaReady(position2)) { continue; } value = new SheetState(); value.fragments = new Fragment[list.Count]; for (int i = 0; i < list.Count; i++) { value.fragments[i] = MeasureFragment((MeshFilter)f_haMesh.GetValue(list[i])); } value.fullHealth = item.m_health + (float)Game.m_worldLevel * item.m_health * Game.instance.m_worldLevelMineHPMultiplier; long num4 = zDO.GetLong(s_iceLastTime, 0L); value.lastTick = ((m_catchUp.Value && num4 > 0) ? Math.Max(num4, m_resumeTime) : now); value.lastStamp = Time.time; m_sheetStates[item] = value; } double num5 = now - value.lastTick; value.lastTick = now; bool flag = false; if (m_icePyre.Value) { for (int j = 0; j < list.Count; j++) { if ((float)f_haHealth.GetValue(list[j]) > 0f && NearLitPyre(value.fragments[j])) { SetFragment(item, val, list[j], j, 0f); m_thawed++; flag = true; } } } bool anyIntact = false; int num6 = 0; for (int k = 0; k < list.Count; k++) { if ((float)f_haHealth.GetValue(list[k]) > 0f) { anyIntact = true; } else { num6++; } } if (num5 > 0.0 && num6 > 0) { double num7 = Math.Min(num5, m_tickInterval.Value * 2f); double num8 = num5 - num7; if (num8 > 0.0) { float num9 = (float)(num8 * (double)num2) + value.awayCarry; int num10 = Freeze(item, val, value, list, Mathf.FloorToInt(num9), ignorePlayers: true, ref anyIntact); value.awayCarry = Mathf.Min(num9 - (float)Mathf.FloorToInt(num9), 1f); if (num10 > 0) { flag = true; num6 -= num10; ((BaseUnityPlugin)this).Logger.LogInfo((object)$"Ice caught up {num10} pieces for {num8 / 60.0:0} min away, {Vector3.Distance(position2, position):0} m from you"); } } value.progress = Mathf.Min(value.progress + (float)(num7 * (double)num), (float)num6); int num11 = Mathf.FloorToInt(value.progress); if (num11 > 0) { int num12 = Freeze(item, val, value, list, num11, ignorePlayers: false, ref anyIntact); value.progress -= num12; flag = flag || num12 > 0; } } bool flag2 = false; for (int l = 0; l < list.Count; l++) { if (flag2) { break; } flag2 = (float)f_haHealth.GetValue(list[l]) <= 0f; } if (flag2 && (flag || Time.time - value.lastStamp >= 60f)) { zDO.Set(s_iceLastTime, (long)now); value.lastStamp = Time.time; flag = true; } if (flag) { m_saveHealth.Invoke(item, null); } } m_gone2.Clear(); foreach (KeyValuePair<MineRock5, SheetState> sheetState in m_sheetStates) { if ((Object)(object)sheetState.Key == (Object)null) { m_gone2.Add(sheetState.Key); } } foreach (MineRock5 item2 in m_gone2) { m_sheetStates.Remove(item2); } } private static void SetFragment(MineRock5 rock, ZNetView nview, object area, int index, float health) { f_haHealth.SetValue(area, health); nview.InvokeRPC(ZNetView.Everybody, "RPC_SetAreaHealth", new object[2] { index, health }); } private static Fragment MeasureFragment(MeshFilter filter) { //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_006c: 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_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_00fd: Unknown result type (might be due to invalid IL or missing references) //IL_0102: 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_003f: 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_004a: 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) Fragment fragment = new Fragment(); if ((Object)(object)filter == (Object)null || (Object)(object)filter.sharedMesh == (Object)null) { fragment.center = (((Object)(object)filter != (Object)null) ? ((Component)filter).transform.position : Vector3.zero); fragment.halfSize = Vector3.one; fragment.rotation = Quaternion.identity; fragment.radius = 2f; return fragment; } Bounds bounds = filter.sharedMesh.bounds; Transform transform = ((Component)filter).transform; fragment.center = transform.TransformPoint(((Bounds)(ref bounds)).center); fragment.halfSize = Vector3.Scale(((Bounds)(ref bounds)).extents, transform.lossyScale); fragment.halfSize = new Vector3(Mathf.Abs(fragment.halfSize.x), Mathf.Abs(fragment.halfSize.y), Mathf.Abs(fragment.halfSize.z)); fragment.rotation = transform.rotation; Vector2 val = new Vector2(fragment.halfSize.x, fragment.halfSize.z); fragment.radius = ((Vector2)(ref val)).magnitude; return fragment; } private int Freeze(MineRock5 rock, ZNetView nview, SheetState state, IList areas, int count, bool ignorePlayers, ref bool anyIntact) { if (count <= 0) { return 0; } m_eligible.Clear(); for (int i = 0; i < areas.Count; i++) { if ((float)f_haHealth.GetValue(areas[i]) <= 0f && CanRefreeze(state.fragments[i], ignorePlayers)) { m_eligible.Add(i); } } int num = 0; while (num < count && m_eligible.Count > 0) { int index = (anyIntact ? ClosestToIntact(state, areas, m_eligible) : 0); int index2 = m_eligible[index]; m_eligible.RemoveAt(index); SetFragment(rock, nview, areas[index2], index2, state.fullHealth); anyIntact = true; num++; m_refrozen++; } return num; } private bool CanRefreeze(Fragment f, bool ignorePlayers = false) { //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) if (!ignorePlayers && Player.IsPlayerInRange(f.center, m_icePlayerDistance.Value + f.radius)) { return false; } if (m_icePyre.Value && NearLitPyre(f)) { return false; } if (m_iceHeat.Value && (NearLitFire(f) || (Object)(object)EffectArea.IsPointInsideArea(f.center, (Type)1, f.radius + 2f) != (Object)null)) { return false; } Vector3 val = f.halfSize + new Vector3(0.5f, 1.5f, 0.5f); return Physics.OverlapBoxNonAlloc(f.center, val, m_overlap, f.rotation, m_blockMask) == 0; } private void CollectHeat() { //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004a: 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_0177: Unknown result type (might be due to invalid IL or missing references) //IL_017c: Unknown result type (might be due to invalid IL or missing references) m_heat.Clear(); if ((s_sheets.Count == 0 && s_wholeSheets.Count == 0) || ZDOMan.instance == null) { return; } m_heatZdos.Clear(); ZDOMan.instance.FindSectorObjects(ZoneSystem.GetZone(((Component)Player.m_localPlayer).transform.position), new SimulationDistance(3, 0, true), m_heatZdos, (List<ZDO>)null); foreach (ZDO heatZdo in m_heatZdos) { int prefab = heatZdo.GetPrefab(); if (!m_heatKinds.TryGetValue(prefab, out var value)) { value = 0; GameObject prefab2 = ZNetScene.instance.GetPrefab(prefab); if ((Object)(object)prefab2 != (Object)null) { Fireplace component = prefab2.GetComponent<Fireplace>(); Piece component2 = prefab2.GetComponent<Piece>(); if ((Object)(object)component2 != (Object)null && component2.m_name == "$piece_faderember") { value = 2 | (((Object)(object)component == (Object)null || component.m_infiniteFuel) ? 4 : 0); } else if ((Object)(object)component != (Object)null) { value = 1 | (component.m_infiniteFuel ? 4 : 0); } } m_heatKinds[prefab] = value; } if (value != 0) { bool pyre = (value & 2) != 0; bool flag = (value & 4) != 0; if (heatZdo.GetInt(ZDOVars.s_state, 1) == 1 && (flag || heatZdo.GetFloat(ZDOVars.s_fuel, 0f) > 0f)) { m_heat.Add(new Heat { pos = heatZdo.GetPosition(), pyre = pyre }); } } } } private static bool SurroundingsLoaded(Vector3 pos) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: 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_0014: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) Vector2s zone = ZoneSystem.GetZone(pos); for (int i = -1; i <= 1; i++) { for (int j = -1; j <= 1; j++) { if (!ZoneSystem.instance.IsZoneLoaded(new Vector2s(zone.x + i, zone.y + j))) { return false; } } } return true; } private bool NearLitFire(Fragment f) { //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0033: 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_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) float num = m_iceHeatMargin.Value + f.radius; foreach (Heat item in m_heat) { Vector3 val = item.pos - f.center; if (val.x * val.x + val.z * val.z <= num * num) { return true; } } return false; } private bool NearLitPyre(Fragment f) { //IL_0032: 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_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0049: 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_0056: Unknown result type (might be due to invalid IL or missing references) float num = m_icePyreRadius.Value + f.radius; foreach (Heat item in m_heat) { if (item.pyre) { Vector3 val = item.pos - f.center; if (val.x * val.x + val.z * val.z <= num * num) { return true; } } } return false; } private static int ClosestToIntact(SheetState state, IList areas, List<int> eligible) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0051: 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) int result = 0; float num = float.MaxValue; for (int i = 0; i < eligible.Count; i++) { Vector3 center = state.fragments[eligible[i]].center; for (int j = 0; j < areas.Count; j++) { if (!((float)f_haHealth.GetValue(areas[j]) <= 0f)) { Vector3 val = state.fragments[j].center - center; float sqrMagnitude = ((Vector3)(ref val)).sqrMagnitude; if (sqrMagnitude < num) { num = sqrMagnitude; result = i; } } } } return result; } internal string IceStatus() { int num = 0; int num2 = 0; foreach (KeyValuePair<MineRock5, SheetState> sheetState in m_sheetStates) { if ((Object)(object)sheetState.Key == (Object)null) { continue; } num++; IList list = (IList)f_hitAreas.GetValue(sheetState.Key); int num3 = 0; while (list != null && num3 < list.Count) { if ((float)f_haHealth.GetValue(list[num3]) <= 0f) { num2++; } num3++; } } int num4 = 0; int num5 = 0; foreach (Heat item in m_heat) { if (item.pyre) { num4++; } else { num5++; } } string result = (m_iceRefreeze.Value ? $"Ice: {num} sheets tracked, {num2} pieces open, {m_refrozen} refrozen and {m_thawed} thawed by a pyre, {m_restored} missing sheets restored, {m_removedDuplicates} duplicates removed (since last check), {num4} lit Eternal Pyres and {num5} lit fires nearby" : "Ice: refreezing off"); m_refrozen = 0; m_restored = 0; m_removedDuplicates = 0; m_thawed = 0; return result; } private void CrackWholeSheetsNearPyres() { //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Unknown result type (might be due to invalid IL or missing references) if (!m_icePyre.Value) { return; } foreach (Destructible s_wholeSheet in s_wholeSheets) { if ((Object)(object)s_wholeSheet == (Object)null) { continue; } ZNetView component = ((Component)s_wholeSheet).GetComponent<ZNetView>(); if ((Object)(object)component == (Object)null || !component.IsValid() || !component.IsOwner()) { continue; } Fragment f = new Fragment { center = ((Component)s_wholeSheet).transform.position, radius = SheetRadius(s_wholeSheet) }; if (NearLitPyre(f)) { Vector3 position = ((Component)s_wholeSheet).transform.position; GameObject val = Object.Instantiate<GameObject>(s_wholeSheet.m_spawnWhenDestroyed, position, ((Component)s_wholeSheet).transform.rotation); ZNetView component2 = val.GetComponent<ZNetView>(); if (component2 != null) { component2.SetLocalScale(((Component)s_wholeSheet).transform.localScale); } ZDO zDO = component.GetZDO(); ZNetScene.instance.Destroy(((Component)s_wholeSheet).gameObject); ForgetZdo(zDO); OpenUnderHeat(val.GetComponent<MineRock5>()); ((BaseUnityPlugin)this).Logger.LogInfo((object)$"Eternal Pyre cracked a whole ice sheet at {position:F0}"); } } } internal static void ForgetZdo(ZDO zdo) { //IL_0025: Unknown result type (might be due to invalid IL or missing references) if (zdo != null && zdo.IsValid() && ZDOMan.instance != null) { m_handleDestroyed.Invoke(ZDOMan.instance, new object[1] { zdo.m_uid }); } } private void OpenUnderHeat(MineRock5 rock) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Expected O, but got Unknown ZNetView val = ((!((Object)(object)rock != (Object)null)) ? ((ZNetView)null) : ((ZNetView)f_mrNview.GetValue(rock))); IList list = (((Object)(object)rock != (Object)null) ? ((IList)f_hitAreas.GetValue(rock)) : null); if ((Object)(object)val == (Object)null || !val.IsValid() || list == null) { return; } bool flag = false; foreach (object item in list) { Fragment f = MeasureFragment((MeshFilter)f_haMesh.GetValue(item)); if (NearLitPyre(f) || (m_iceHeat.Value && NearLitFire(f))) { f_haHealth.SetValue(item, 0f); m_thawed++; flag = true; } } if (flag) { val.GetZDO().Set(s_iceLastTime, (long)ZNet.instance.GetTimeSeconds()); m_saveHealth.Invoke(rock, null); m_updateMesh.Invoke(rock, null); } } private static float SheetRadius(Destructible whole) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0031: 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_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0047: 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_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) float num = 0f; Collider[] componentsInChildren = ((Component)whole).GetComponentsInChildren<Collider>(); for (int i = 0; i < componentsInChildren.Length; i++) { Bounds bounds = componentsInChildren[i].bounds; Vector3 val = ((Bounds)(ref bounds)).center - ((Component)whole).transform.position; float num2 = num; Vector2 val2 = new Vector2(val.x, val.z); float magnitude = ((Vector2)(ref val2)).magnitude; val2 = new Vector2(((Bounds)(ref bounds)).extents.x, ((Bounds)(ref bounds)).extents.z); num = Mathf.Max(num2, magnitude + ((Vector2)(ref val2)).magnitude * 0.7f); } if (!(num > 0f)) { return 10f; } return num; } private void Awake() { //IL_01da: Unknown result type (might be due to invalid IL or missing references) Instance = this; m_enabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, "Let Deep North ground snow build back up."); m_calmRate = ((BaseUnityPlugin)this).Config.Bind<float>("Rates", "CalmRate", 1f, "Centimetres of snow per real minute when no snow is falling (drift)."); m_snowfallRate = ((BaseUnityPlugin)this).Config.Bind<float>("Rates", "SnowfallRate", 5f, "Centimetres per real minute in the lightest snowfall."); m_stormRate = ((BaseUnityPlugin)this).Config.Bind<float>("Rates", "StormRate", 25f, "Centimetres per real minute in the heaviest blizzard. Weather in between is interpolated."); m_catchUp = ((BaseUnityPlugin)this).Config.Bind<bool>("Rates", "CatchUpWhileAway", true, "When you come back to an area (or after sleeping), add the snow that fell meanwhile at the calm rate."); m_protectRoofs = ((BaseUnityPlugin)this).Config.Bind<bool>("Shelter", "KeepRoofedGroundClear", true, "No snow builds up on ground with a building piece above it (floors, roofs)."); m_protectShields = ((BaseUnityPlugin)this).Config.Bind<bool>("Shelter", "KeepShieldedGroundClear", true, "No snow builds up inside a Shield Generator's dome."); m_fireMelts = ((BaseUnityPlugin)this).Config.Bind<bool>("Shelter", "KeepHeatedGroundClear", true, "No snow builds up inside the heat area of fires and other heat sources."); m_range = ((BaseUnityPlugin)this).Config.Bind<float>("Performance", "Range", 150f, "Only zones within this many metres of you are updated."); m_tickInterval = ((BaseUnityPlugin)this).Config.Bind<float>("Performance", "TickSeconds", 2f, "How often the snow grows locally."); m_saveInterval = ((BaseUnityPlugin)this).Config.Bind<float>("Performance", "SaveSeconds", 20f, "How often grown snow is saved to the world and sent to other players."); m_minStep = ((BaseUnityPlugin)this).Config.Bind<float>("Performance", "MinStepCm", 2f, "Snow is applied (and the terrain redrawn) only once this many centimetres have built up in an area."); m_maxRedrawsPerTick = ((BaseUnityPlugin)this).Config.Bind<int>("Performance", "MaxRedrawsPerTick", 2, "At most this many terrain areas are redrawn per tick; the rest wait for the next one."); BindIce(); new Harmony("com.chase.fimbulvetr").PatchAll(typeof(Plugin).Assembly); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Fimbulvetr 1.1.0 loaded"); } private void Update() { if (!m_enabled.Value || (Object)(object)Player.m_localPlayer == (Object)null || (Object)(object)ZNet.instance == (Object)null || (Object)(object)EnvMan.instance == (Object)null || WorldGenerator.instance == null) { return; } m_timer += Time.deltaTime; if (m_timer < m_tickInterval.Value && !HasNewSheet()) { return; } m_timer = 0f; try { m_watch.Restart(); Tick(); IceTick(ZNet.instance.GetTimeSeconds()); RestoreTick(); m_watch.Stop(); m_tickMs += m_watch.Elapsed.TotalMilliseconds; m_ticks++; } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogError((object)ex); } } private void Tick() { //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_0152: Unknown result type (might be due to invalid IL or missing references) //IL_0157: Unknown result type (might be due to invalid IL or missing references) //IL_0159: Unknown result type (might be due to invalid IL or missing references) //IL_0160: Unknown result type (might be due to invalid IL or missing references) //IL_0167: Unknown result type (might be due to invalid IL or missing references) //IL_016e: Unknown result type (might be due to invalid IL or missing references) //IL_0175: Unknown result type (might be due to invalid IL or missing references) //IL_017a: Unknown result type (might be due to invalid IL or missing references) //IL_018a: Unknown result type (might be due to invalid IL or missing references) //IL_01a2: Unknown result type (might be due to invalid IL or missing references) //IL_01a9: Expected O, but got Unknown //IL_01ce: Unknown result type (might be due to invalid IL or missing references) if (m_shelterMask == 0) { m_shelterMask = LayerMask.GetMask(new string[2] { "piece", "static_solid" }); m_pieceMask = LayerMask.GetMask(new string[1] { "piece" }); } InitWeatherScale(); double timeSeconds = ZNet.instance.GetTimeSeconds(); string label; float num = CurrentRate(out label) / 100f / 2f / 60f; float num2 = m_calmRate.Value / 100f / 2f / 60f; Vector3 position = ((Component)Player.m_localPlayer).transform.position; float num3 = m_range.Value + 45f; float num4 = m_minStep.Value / 100f / 2f; int num5 = 0; m_scratch.Clear(); m_scratch.AddRange((List<TerrainComp>)f_instances.GetValue(null)); foreach (TerrainComp item in m_scratch) { if ((Object)(object)item == (Object)null || !(bool)f_initialized.GetValue(item)) { continue; } if (!item.IsOwner()) { m_zones.Remove(item); continue; } Vector3 position2 = ((Component)item).transform.position; Vector2 val = new Vector2(position2.x - position.x, position2.z - position.z); if (((Vector2)(ref val)).magnitude > num3 || !TouchesDeepNorth(position2)) { continue; } Heightmap val2 = (Heightmap)f_hmap.GetValue(item); if ((Object)(object)val2 == (Object)null || val2.IsDistantLod) { continue; } ZDO zDO = ((ZNetView)f_nview.GetValue(item)).GetZDO(); if (!m_zones.TryGetValue(item, out var value)) { value = new ZoneState(); long num6 = zDO.GetLong(s_lastSnowTime, 0L); value.lastTick = ((m_catchUp.Value && num6 > 0) ? Math.Max(num6, m_resumeTime) : timeSeconds); value.lastSave = Time.time; m_zones[item] = value; m_toSync.Add(item); } double num7 = timeSeconds - value.lastTick; value.lastTick = timeSeconds; if (num7 <= 0.0) { continue; } double num8 = Math.Min(num7, m_tickInterval.Value * 2f); value.pending += (float)(num8 * (double)num + (num7 - num8) * (double)num2); if (value.pending >= num4 && num5 < m_maxRedrawsPerTick.Value) { float pending = value.pending; value.pending = 0f; if (Grow(item, val2, value, pending)) { m_toSync.Add(item); val2.Poke(1, true); value.dirty = true; num5++; m_redraws++; } } if (value.dirty && Time.time - value.lastSave >= m_saveInterval.Value) { SaveZone(item); value.dirty = false; value.lastSave = Time.time; } } foreach (TerrainComp item2 in m_toSync) { if ((Object)(object)item2 != (Object)null) { SyncEdges(item2); } } m_toSync.Clear(); m_gone.Clear(); foreach (KeyValuePair<TerrainComp, ZoneState> zone in m_zones) { if ((Object)(object)zone.Key == (Object)null) { m_gone.Add(zone.Key); } } foreach (TerrainComp item3 in m_gone) { m_zones.Remove(item3); } } private void SyncEdges(TerrainComp a) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Expected O, but got Unknown //IL_00d9: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_0111: Unknown result type (might be due to invalid IL or missing references) //IL_0132: Unknown result type (might be due to invalid IL or missing references) //IL_0167: Unknown result type (might be due to invalid IL or missing references) //IL_016e: Expected O, but got Unknown //IL_0145: Unknown result type (might be due to invalid IL or missing references) //IL_026a: Unknown result type (might be due to invalid IL or missing references) //IL_026f: Unknown result type (might be due to invalid IL or missing references) //IL_027c: 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_032e: Unknown result type (might be due to invalid IL or missing references) //IL_0324: Unknown result type (might be due to invalid IL or missing references) //IL_0333: Unknown result type (might be due to invalid IL or missing references) //IL_034b: Unknown result type (might be due to invalid IL or missing references) //IL_0340: Unknown result type (might be due to invalid IL or missing references) //IL_0350: Unknown result type (might be due to invalid IL or missing references) //IL_0352: Unknown result type (might be due to invalid IL or missing references) //IL_0359: Unknown result type (might be due to invalid IL or missing references) //IL_036d: Unknown result type (might be due to invalid IL or missing references) //IL_0374: 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_038f: Unknown result type (might be due to invalid IL or missing references) //IL_03cc: Unknown result type (might be due to invalid IL or missing references) //IL_03ce: Unknown result type (might be due to invalid IL or missing references) //IL_03eb: Unknown result type (might be due to invalid IL or missing references) //IL_03f2: Unknown result type (might be due to invalid IL or missing references) //IL_03d6: Unknown result type (might be due to invalid IL or missing references) //IL_03dd: Unknown result type (might be due to invalid IL or missing references) //IL_041e: Unknown result type (might be due to invalid IL or missing references) //IL_0425: Unknown result type (might be due to invalid IL or missing references) //IL_0409: Unknown result type (might be due to invalid IL or missing references) //IL_0410: Unknown result type (might be due to invalid IL or missing references) //IL_0451: Unknown result type (might be due to invalid IL or missing references) //IL_0458: Unknown result type (might be due to invalid IL or missing references) //IL_043c: Unknown result type (might be due to invalid IL or missing references) //IL_0443: Unknown result type (might be due to invalid IL or missing references) //IL_046c: Unknown result type (might be due to invalid IL or missing references) //IL_046e: Unknown result type (might be due to invalid IL or missing references) //IL_0483: Unknown result type (might be due to invalid IL or missing references) //IL_0485: Unknown result type (might be due to invalid IL or missing references) if (!m_zones.TryGetValue(a, out var value)) { return; } Heightmap val = (Heightmap)f_hmap.GetValue(a); Color[] array = (Color[])f_paintMask.GetValue(a); bool[] array2 = (bool[])f_modifiedPaint.GetValue(a); object? value2 = f_buildData.GetValue(val); Color[] array3 = ((HMBuildData)(((value2 is HMBuildData) ? value2 : null)?)).m_baseMask; if ((Object)(object)val == (Object)null || array == null || array2 == null || array3 == null) { return; } int width = val.m_width; int num = width + 1; bool flag = false; foreach (TerrainComp item in m_scratch) { if ((Object)(object)item == (Object)null || (Object)(object)item == (Object)(object)a || !(bool)f_initialized.GetValue(item)) { continue; } Vector3 val2 = ((Component)item).transform.position - ((Component)a).transform.position; if (Mathf.Abs(val2.x) > (float)width * val.m_scale + 1f || Mathf.Abs(val2.z) > (float)width * val.m_scale + 1f || (Mathf.Abs(val2.x) < 1f && Mathf.Abs(val2.z) < 1f)) { continue; } Heightmap val3 = (Heightmap)f_hmap.GetValue(item); Color[] array4 = (Color[])f_paintMask.GetValue(item); bool[] array5 = (bool[])f_modifiedPaint.GetValue(item); Color[] array6 = ((!((Object)(object)val3 != (Object)null)) ? null : ((HMBuildData)(/*isinst with value type is only supported in some contexts*/?)).m_baseMask); if ((Object)(object)val3 == (Object)null || array4 == null || array5 == null || array6 == null || val3.m_width != width) { continue; } ZoneState value3; bool flag2 = item.IsOwner() && m_zones.TryGetValue(item, out value3); bool flag3 = false; for (int i = 0; i < 4 * width; i++) { int num2; int num3; if (i < width) { num2 = i; num3 = 0; } else if (i < 2 * width) { num2 = width; num3 = i - width; } else if (i < 3 * width) { num2 = width - (i - 2 * width); num3 = width; } else { num2 = 0; num3 = width - (i - 3 * width); } Vector3 val4 = val.VertexMaskToWorld(num2, num3); int num4 = Mathf.RoundToInt((val4.x - ((Component)val3).transform.position.x) / val3.m_scale + (float)(width / 2) + 0.5f); int num5 = Mathf.RoundToInt((val4.z - ((Component)val3).transform.position.z) / val3.m_scale + (float)(width / 2) + 0.5f); if (num4 < 0 || num5 < 0 || num4 > width || num5 > width) { continue; } int num6 = num3 * num + num2; int num7 = num5 * num + num4; if (!array2[num6] && !array5[num7]) { continue; } Color val5 = (array2[num6] ? array[num6] : array3[num6]); Color val6 = (array5[num7] ? array4[num7] : array6[num7]); if (!(Mathf.Abs(val5.g - val6.g) < 0.002f) || !(Mathf.Abs(val5.r - val6.r) < 0.002f) || !(Mathf.Abs(val5.b - val6.b) < 0.002f)) { bool flag4 = value.shelter != null && value.shelter.Length == array.Length && value.shelter[num6] == 2; Color val7 = val5; val7.g = (flag4 ? Mathf.Min(val5.g, val6.g) : Mathf.Max(val5.g, val6.g)); val7.r = (flag4 ? Mathf.Max(val5.r, val6.r) : Mathf.Min(val5.r, val6.r)); val7.b = (flag4 ? Mathf.Max(val5.b, val6.b) : Mathf.Min(val5.b, val6.b)); array[num6] = val7; array2[num6] = true; flag = true; if (flag2) { array4[num7] = val7; array5[num7] = true; flag3 = true; } } } if (flag3) { val3.Poke(1, true); m_zones[item].dirty = true; } } if (flag) { val.Poke(1, true); value.dirty = true; } } private static bool TouchesDeepNorth(Vector3 c) { //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_0013: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0032: 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_0051: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) if (!WorldGenerator.IsDeepnorth(c.x, c.z) && !WorldGenerator.IsDeepnorth(c.x - 32f, c.z - 32f) && !WorldGenerator.IsDeepnorth(c.x + 32f, c.z - 32f) && !WorldGenerator.IsDeepnorth(c.x - 32f, c.z + 32f)) { return WorldGenerator.IsDeepnorth(c.x + 32f, c.z + 32f); } return true; } private bool Grow(TerrainComp comp, Heightmap hmap, ZoneState zone, float add) { //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: 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_012c: Unknown result type (might be due to invalid IL or missing references) //IL_0131: Unknown result type (might be due to invalid IL or missing references) //IL_0136: Unknown result type (might be due to invalid IL or missing references) //IL_013b: Unknown result type (might be due to invalid IL or missing references) //IL_013d: Unknown result type (might be due to invalid IL or missing references) //IL_0144: Unknown result type (might be due to invalid IL or missing references) //IL_0155: Unknown result type (might be due to invalid IL or missing references) //IL_0163: Unknown result type (might be due to invalid IL or missing references) //IL_016a: Unknown result type (might be due to invalid IL or missing references) //IL_0179: Unknown result type (might be due to invalid IL or missing references) //IL_0180: Unknown result type (might be due to invalid IL or missing references) //IL_019f: Unknown result type (might be due to invalid IL or missing references) //IL_01ee: Unknown result type (might be due to invalid IL or missing references) //IL_0236: Unknown result type (might be due to invalid IL or missing references) //IL_024c: Unknown result type (might be due to invalid IL or missing references) //IL_0253: Unknown result type (might be due to invalid IL or missing references) //IL_0269: Unknown result type (might be due to invalid IL or missing references) //IL_0270: Unknown result type (might be due to invalid IL or missing references) //IL_0286: Unknown result type (might be due to invalid IL or missing references) //IL_028d: Unknown result type (might be due to invalid IL or missing references) //IL_02a4: Unknown result type (might be due to invalid IL or missing references) //IL_02a6: Unknown result type (might be due to invalid IL or missing references) //IL_0206: 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_021f: Unknown result type (might be due to invalid IL or missing references) if (add <= 0f) { return false; } Color[] array = (Color[])f_paintMask.GetValue(comp); bool[] array2 = (bool[])f_modifiedPaint.GetValue(comp); object? value = f_buildData.GetValue(hmap); Color[] array3 = ((HMBuildData)(((value is HMBuildData) ? value : null)?)).m_baseMask; if (array == null || array2 == null || array3 == null || array3.Length != array.Length) { return false; } int num = hmap.m_width + 1; if (zone.deepNorth == null || zone.deepNorth.Length != array.Length) { zone.deepNorth = new bool[array.Length]; zone.shelter = new byte[array.Length]; for (int i = 0; i < array.Length; i++) { Vector3 val = hmap.VertexMaskToWorld(i % num, i / num); zone.deepNorth[i] = WorldGenerator.IsDeepnorth(val.x, val.z); } } if (Time.time - zone.shelterCheckedAt > 60f) { Array.Clear(zone.shelter, 0, zone.shelter.Length); zone.shelterCheckedAt = Time.time; } bool result = false; for (int j = 0; j < array.Length; j++) { if (!array2[j] || !zone.deepNorth[j]) { continue; } Color val2 = array3[j]; Color val3 = array[j]; bool flag = val3.g < val2.g - 0.0001f; bool flag2 = val2.g > 0.05f && (val3.r > val2.r + 0.0001f || val3.b > val2.b + 0.0001f); if (!flag && !flag2 && val3.g <= 0.0001f) { continue; } if (zone.shelter[j] == 0) { zone.shelter[j] = Shelter(hmap, j % num, j / num); } if (zone.shelter[j] == 3) { continue; } if (zone.shelter[j] == 2) { if (val3.g > 0.0001f) { val3.g = Mathf.Max(0f, val3.g - add); array[j] = val3; result = true; } } else if (flag || flag2) { float num2 = add / Mathf.Max(val2.g, 0.15f); val3.g = Mathf.Min(val2.g, val3.g + add); val3.r = Mathf.Max(val2.r, val3.r - num2); val3.b = Mathf.Max(val2.b, val3.b - num2); array[j] = val3; result = true; } } return result; } private byte Shelter(Heightmap hmap, int x, int y) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0029: 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_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_0092: 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_0058: 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_0067: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) Vector3 val = hmap.VertexMaskToWorld(x, y); float y2 = default(float); if (hmap.GetWorldHeight(val, ref y2)) { val.y = y2; } if (m_protectRoofs.Value) { if (Physics.Raycast(val - Vector3.up * 1f, Vector3.up, 61f, m_pieceMask)) { return 2; } if (Physics.Raycast(val + Vector3.up * 0.05f, Vector3.up, 60f, m_shelterMask)) { return 3; } } if (m_protectShields.Value && ShieldGenerator.IsInsideShield(val)) { return 3; } if (m_fireMelts.Value && (Object)(object)EffectArea.IsPointInsideArea(val, (Type)1, 0f) != (Object)null) { return 3; } return 1; } private static void SaveZone(TerrainComp comp) { m_save.Invoke(comp, new object[1] { true }); } private void InitWeatherScale() { if (m_maxSnowBuildup >= 0f) { return; } float num = float.MaxValue; float num2 = 0f; foreach (EnvSetup environment in EnvMan.instance.m_environments) { if (environment.m_snowBuildup > 0f) { num = Mathf.Min(num, environment.m_snowBuildup); num2 = Mathf.Max(num2, environment.m_snowBuildup); ((BaseUnityPlugin)this).Logger.LogInfo((object)$"Snowing weather: {environment.m_name} buildup {environment.m_snowBuildup}"); } } m_maxSnowBuildup = num2; m_minSnowBuildup = ((num2 > 0f) ? num : 0f); } internal float CurrentRate(out string label) { switch (m_force) { case "calm": label = "forced calm"; return m_calmRate.Value; case "snow": label = "forced snowfall"; return m_snowfallRate.Value; case "storm": label = "forced storm"; return m_stormRate.Value; default: { EnvSetup currentEnvironment = EnvMan.instance.GetCurrentEnvironment(); float num = currentEnvironment?.m_snowBuildup ?? 0f; label = currentEnvironment?.m_name ?? "?"; if (num <= 0f || m_maxSnowBuildup <= 0f) { return m_calmRate.Value; } float num2 = ((m_maxSnowBuildup > m_minSnowBuildup) ? Mathf.InverseLerp(m_minSnowBuildup, m_maxSnowBuildup, num) : 1f); return Mathf.Lerp(m_snowfallRate.Value, m_stormRate.Value, num2); } } } internal string Status() { InitWeatherScale(); string label; float num = CurrentRate(out label); int num2 = 0; int num3 = 0; foreach (KeyValuePair<TerrainComp, ZoneState> zone in m_zones) { if ((Object)(object)zone.Key != (Object)null && zone.Key.IsOwner()) { num2++; if (zone.Value.dirty) { num3++; } } } float num4 = Mathf.Max(1f / 60f, (Time.time - m_statsSince) / 60f); string text = ((m_ticks > 0) ? $"{m_tickMs / (double)m_ticks:0.00} ms per tick, {(float)m_redraws / num4:0.#} terrain redraws per minute" : "no ticks yet"); m_tickMs = 0.0; m_ticks = 0; m_redraws = 0; m_statsSince = Time.time; return string.Format("Fimbulvetr {0}: weather '{1}', {2:0.#} cm/min, {3} Deep North zones tracked, {4} with unsaved growth; {5} (since last check)\n{6}", m_enabled.Value ? "ON" : "OFF", label, num, num2, num3, text, IceStatus()); } internal void SaveAll() { foreach (KeyValuePair<TerrainComp, ZoneState> zone in m_zones) { if ((Object)(object)zone.Key != (Object)null && zone.Key.IsOwner() && zone.Value.dirty) { SaveZone(zone.Key); zone.Value.dirty = false; zone.Value.lastSave = Time.time; } } } private void BindRestore() { m_iceRestore = ((BaseUnityPlugin)this).Config.Bind<bool>("Ice", "RestoreMissingSheets", true, "Put back Ice Sheets the game deleted after they were broken completely (including before this mod was installed), empty, so they refreeze to the world's original ice."); } private void RestoreTick() { //IL_02ce: Unknown result type (might be due to invalid IL or missing references) //IL_02d3: Unknown result type (might be due to invalid IL or missing references) //IL_0312: Unknown result type (might be due to invalid IL or missing references) //IL_0319: Expected O, but got Unknown //IL_0345: Unknown result type (might be due to invalid IL or missing references) //IL_034a: Unknown result type (might be due to invalid IL or missing references) //IL_034f: Unknown result type (might be due to invalid IL or missing references) //IL_0357: Unknown result type (might be due to invalid IL or missing references) //IL_0363: Unknown result type (might be due to invalid IL or missing references) //IL_0365: Unknown result type (might be due to invalid IL or missing references) //IL_036a: Unknown result type (might be due to invalid IL or missing references) //IL_036c: Unknown result type (might be due to invalid IL or missing references) //IL_0373: Unknown result type (might be due to invalid IL or missing references) //IL_037a: 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_0388: Unknown result type (might be due to invalid IL or missing references) //IL_038d: Unknown result type (might be due to invalid IL or missing references) //IL_03a3: Unknown result type (might be due to invalid IL or missing references) //IL_03b4: Unknown result type (might be due to invalid IL or missing references) //IL_03d7: Unknown result type (might be due to invalid IL or missing references) //IL_03df: Unknown result type (might be due to invalid IL or missing references) //IL_0246: Unknown result type (might be due to invalid IL or missing references) //IL_024d: Invalid comparison between Unknown and I4 //IL_03fe: Unknown result type (might be due to invalid IL or missing references) //IL_0400: Unknown result type (might be due to invalid IL or missing references) if (!m_iceRefreeze.Value || !m_iceRestore.Value || (Object)(object)ZoneSystem.instance == (Object)null || (Object)(object)ZNetScene.instance == (Object)null) { return; } if (m_iceVegetation == null) { m_iceVegetation = new List<ZoneVegetation>(); foreach (ZoneVegetation item in ZoneSystem.instance.m_vegetation) { if (item.m_enable && !((Object)(object)item.m_prefab == (Object)null)) { MineRock5 val = item.m_prefab.GetComponent<MineRock5>(); if ((Object)(object)val == (Object)null) { GameObject val2 = item.m_prefab.GetComponent<Destructible>()?.m_spawnWhenDestroyed; val = (((Object)(object)val2 != (Object)null) ? val2.GetComponent<MineRock5>() : null); } if ((Object)(object)val != (Object)null && IsIceSheet(val)) { m_iceVegetation.Add(item); m_iceFrac[((Object)item.m_prefab).name] = ((Object)((Component)val).gameObject).name; s_iceNames.Add(((Object)item.m_prefab).name); s_iceNames.Add(((Object)((Component)val).gameObject).name); ((BaseUnityPlugin)this).Logger.LogInfo((object)("Ice sheet world generation entry: " + item.m_name + " (" + ((Object)item.m_prefab).name + ", breaks into " + ((Object)((Component)val).gameObject).name + ")")); } } } if (m_iceVegetation.Count == 0) { List<string> list = new List<string>(); foreach (ZoneVegetation item2 in ZoneSystem.instance.m_vegetation) { if ((Object)(object)item2.m_prefab != (Object)null && ((Object)(object)item2.m_prefab.GetComponent<MineRock5>() != (Object)null || ((Object)item2.m_prefab).name.IndexOf("ice", StringComparison.OrdinalIgnoreCase) >= 0)) { list.Add(((Object)item2.m_prefab).name + (item2.m_enable ? "" : " (off)") + (((int)item2.m_biome == 64) ? " [DN]" : "")); } } ((BaseUnityPlugin)this).Logger.LogWarning((object)string.Format("No ice sheet world generation entries found among {0}; missing sheets can't be restored. Mineable/ice entries: {1}", ZoneSystem.instance.m_vegetation.Count, string.Join(", ", list))); } } if (m_iceVegetation.Count == 0) { return; } Vector3 position = ((Component)Player.m_localPlayer).transform.position; foreach (SpawnSystem item3 in (List<SpawnSystem>)f_spawnSystems.GetValue(null)) { if ((Object)(object)item3 == (Object)null) { continue; } ZNetView val3 = (ZNetView)f_spawnNview.GetValue(item3); if ((Object)(object)val3 == (Object)null || !val3.IsValid() || !val3.IsOwner()) { continue; } Vector2s zone = ZoneSystem.GetZone(((Component)item3).transform.position); if (m_zonesChecked.Contains(zone)) { continue; } Vector3 zonePos = ZoneSystem.GetZonePos(zone); Vector2 val4 = new Vector2(zonePos.x - position.x, zonePos.z - position.z); if (((Vector2)(ref val4)).magnitude > 96f) { continue; } if (!m_zoneSeen.TryGetValue(zone, out var value)) { m_zoneSeen[zone] = Time.time; } else if (!(Time.time - value < 10f)) { m_zonesChecked.Add(zone); Heightmap val5 = Heightmap.FindHeightmap(zonePos); if (!((Object)(object)val5 == (Object)null) && val5.HaveBiome((Biome)64)) { RestoreZone(zone, zonePos, val5); break; } } } } private void RestoreZone(Vector2s zone, Vector3 center, Heightmap hmap) { //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0054: 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_0064: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_011b: Unknown result type (might be due to invalid IL or missing references) //IL_0124: Unknown result type (might be due to invalid IL or missing references) //IL_0283: 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_01cf: Unknown result type (might be due to invalid IL or missing references) //IL_01d4: Unknown result type (might be due to invalid IL or missing references) //IL_01e2: Unknown result type (might be due to invalid IL or missing references) //IL_01e7: Unknown result type (might be due to invalid IL or missing references) //IL_01f5: Unknown result type (might be due to invalid IL or missing references) //IL_01fa: Unknown result type (might be due to invalid IL or missing references) //IL_02dd: Unknown result type (might be due to invalid IL or missing references) //IL_02e4: Unknown result type (might be due to invalid IL or missing references) //IL_0327: Unknown result type (might be due to invalid IL or missing references) //IL_03f9: Unknown result type (might be due to invalid IL or missing references) List<Original> list = new List<Original>(); ZoneSystem instance = ZoneSystem.instance; List<ZoneVegetation> vegetation = instance.m_vegetation; IList list2 = (IList)Activator.CreateInstance(typeof(List<>).MakeGenericType(t_clearArea)); if (instance.m_locationInstances.TryGetValue(zone, out var value) && value.m_location != null && value.m_location.m_clearArea) { Vector3 position = value.m_position; if (value.m_location.m_snapToWater) { position.y = 30f; } list2.Add(Activator.CreateInstance(t_clearArea, position, value.m_location.m_exteriorRadius)); } List<ZoneVegetation> list3 = new List<ZoneVegetation>(1); List<GameObject> list4 = new List<GameObject>(); foreach (ZoneVegetation item in m_iceVegetation) { list3.Clear(); list3.Add(item); m_ghosts.Clear(); try { s_replaying = true; instance.m_vegetation = list3; m_placeVegetation.Invoke(instance, new object[7] { zone, center, ((Component)hmap).transform, hmap, list2, (object)(SpawnMode)2, m_ghosts }); } finally { instance.m_vegetation = vegetation; s_replaying = false; } foreach (GameObject ghost in m_ghosts) { if (!((Object)(object)ghost == (Object)null)) { list.Add(new Original { prefab = ((Object)item.m_prefab).name, frac = m_iceFrac[((Object)item.m_prefab).name], pos = ghost.transform.position, rot = ghost.transform.rotation, scale = ghost.transform.localScale }); list4.Add(ghost); } } } foreach (GameObject item2 in list4) { Object.Destroy((Object)(object)item2); } m_ghosts.Clear(); CollectIceZdos(zone); RemoveDuplicates(); CollectIceZdos(zone); foreach (Original item3 in list) { if (SheetExistsNear(item3)) { continue; } GameObject prefab = ZNetScene.instance.GetPrefab(item3.frac); if ((Object)(object)prefab == (Object)null) { continue; } GameObject obj = Object.Instantiate<GameObject>(prefab, item3.pos, item3.rot); ZNetView component = obj.GetComponent<ZNetView>(); MineRock5 component2 = obj.GetComponent<MineRock5>(); if (!((Object)(object)component == (Object)null) && component.IsValid() && !((Object)(object)component2 == (Object)null)) { component.SetLocalScale(item3.scale); IList list5 = (IList)f_hitAreas.GetValue(component2); int num = 0; while (list5 != null && num < list5.Count) { f_haHealth.SetValue(list5[num], 0f); num++; } component.GetZDO().Set(s_iceLastTime, (long)ZNet.instance.GetTimeSeconds()); component.GetZDO().Set(s_restoredFlag, true); m_iceZdos.Add(component.GetZDO()); m_saveHealth.Invoke(component2, null); m_updateMesh.Invoke(component2, null); m_restored++; ((BaseUnityPlugin)this).Logger.LogInfo((object)$"Restored missing ice sheet {item3.prefab} at {item3.pos:F0} (empty; it will refreeze)"); } } } private void CollectIceZdos(Vector2s zone) { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) m_zoneZdos.Clear(); m_iceZdos.Clear(); ZDOMan.instance.FindSectorObjects(zone, new SimulationDistance(1, 0, true), m_zoneZdos, (List<ZDO>)null); foreach (ZDO zoneZdo in m_zoneZdos) { GameObject prefab = ZNetScene.instance.GetPrefab(zoneZdo.GetPrefab()); if ((Object)(object)prefab != (Object)null && s_iceNames.Contains(((Object)prefab).name)) { m_iceZdos.Add(zoneZdo); } } } private bool SheetExistsNear(Original o) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0033: 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) foreach (ZDO iceZdo in m_iceZdos) { Vector3 val = iceZdo.GetPosition() - o.pos; if (val.x * val.x + val.z * val.z < 4f) { return true; } } return false; } private void RemoveDuplicates() { //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: 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_00b4: 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_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_0177: Unknown result type (might be due to invalid IL or missing references) //IL_017c: Unknown result type (might be due to invalid IL or missing references) //IL_01cd: Unknown result type (might be due to invalid IL or missing references) HashSet<ZDO> hashSet = new HashSet<ZDO>(); foreach (ZDO iceZdo in m_iceZdos) { GameObject prefab = ZNetScene.instance.GetPrefab(iceZdo.GetPrefab()); if ((Object)(object)prefab == (Object)null || (Object)(object)prefab.GetComponent<MineRock5>() == (Object)null || !iceZdo.IsOwner()) { continue; } bool flag = iceZdo.GetBool(s_restoredFlag, false); foreach (ZDO iceZdo2 in m_iceZdos) { if (iceZdo2 == iceZdo || hashSet.Contains(iceZdo2) || !iceZdo2.IsValid()) { continue; } Vector3 val = iceZdo2.GetPosition() - iceZdo.GetPosition(); if (val.x * val.x + val.z * val.z >= (flag ? 4f : 0.25f)) { continue; } GameObject prefab2 = ZNetScene.instance.GetPrefab(iceZdo2.GetPrefab()); bool num = (Object)(object)prefab2 != (Object)null && (Object)(object)prefab2.GetComponent<MineRock5>() == (Object)null; bool flag2 = iceZdo2.GetBool(s_restoredFlag, false); if (num || (flag && !flag2) || (flag == flag2 && string.CompareOrdinal(((object)Unsafe.As<ZDOID, ZDOID>(ref iceZdo.m_uid)/*cast due to .constrained prefix*/).ToString(), ((object)Unsafe.As<ZDOID, ZDOID>(ref iceZdo2.m_uid)/*cast due to .constrained prefix*/).ToString()) > 0)) { ZNetView val2 = ZNetScene.instance.FindInstance(iceZdo); Vector3 position = iceZdo.GetPosition(); if ((Object)(object)val2 != (Object)null) { ZNetScene.instance.Destroy(((Component)val2).gameObject); } else { ZDOMan.instance.DestroyZDO(iceZdo); } hashSet.Add(iceZdo); ForgetZdo(iceZdo); m_removedDuplicates++; ((BaseUnityPlugin)this).Logger.LogInfo((object)$"Removed a duplicate ice sheet at {position:F0}"); break; } } } } private static string ZdoPrefabName(ZNetView nview) { ZDO zDO = nview.GetZDO(); GameObject val = ((zDO != null && (Object)(object)ZNetScene.instance != (Object)null) ? ZNetScene.instance.GetPrefab(zDO.GetPrefab()) : null); if (!((Object)(object)val != (Object)null)) { return ""; } return ((Object)val).name; } private bool IsIcePrefab(string name) { string[] array = m_icePrefabs.Value.Split(','); for (int i = 0; i < array.Length; i++) { string text = array[i].Trim(); if (text.Length > 0 && name.StartsWith(text, StringComparison.OrdinalIgnoreCase)) { return true; } } return false; } } }