Decompiled source of ToynbeeTiles v0.1.1

ToynbeeTiles.dll

Decompiled 3 days ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using HarmonyLib;
using Jotunn.Managers;
using Microsoft.CodeAnalysis;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyCompany("ToynbeeTiles")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("ToynbeeTiles")]
[assembly: AssemblyTitle("ToynbeeTiles")]
[assembly: AssemblyVersion("1.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 ToynbeeTiles
{
	public class ToynbeeTileComponent : MonoBehaviour, Hoverable, Interactable
	{
		[SerializeField]
		private string _flavorText = "TOYNBEE IDEA\nIN MOVIE 2001\nRESURRECT DEAD\nON PLANET JUPITER";

		public string GetHoverName()
		{
			return "Weathered Tile";
		}

		public string GetHoverText()
		{
			return Localization.instance.Localize("Weathered Tile\n[<color=yellow><b>$KEY_Use</b></color>] Read");
		}

		public float GetHoverOffset()
		{
			return 0f;
		}

		public bool Interact(Humanoid user, bool hold, bool alt)
		{
			if (hold)
			{
				return false;
			}
			MessageHud.instance.ShowMessage((MessageType)2, _flavorText, 0, (Sprite)null, false, true);
			return true;
		}

		public bool UseItem(Humanoid user, ItemData item)
		{
			return false;
		}
	}
	[BepInPlugin("TOYNBEE.valheim.toynbeetiles", "ToynbeeTiles", "0.1.1")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class ToynbeeTilePlugin : BaseUnityPlugin
	{
		public const string PluginGUID = "TOYNBEE.valheim.toynbeetiles";

		public const string PluginName = "ToynbeeTiles";

		public const string PluginVersion = "0.1.1";

		public static GameObject TileTilePrefab;

		public static ToynbeeTilePlugin Instance;

		private Harmony _harmony;

		private void Awake()
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Expected O, but got Unknown
			Instance = this;
			PrefabManager.OnVanillaPrefabsAvailable += CreateTilePrefabSafe;
			_harmony = new Harmony("TOYNBEE.valheim.toynbeetiles");
			_harmony.PatchAll();
		}

		public void EnsureTilePrefab()
		{
			if ((Object)(object)TileTilePrefab != (Object)null)
			{
				return;
			}
			try
			{
				PrefabManager.Instance.RemovePrefab("ToynbeeTile");
				CreateTilePrefab();
			}
			catch (Exception arg)
			{
				Debug.LogError((object)$"[ToynbeeTiles] Failed to (re)create tile prefab: {arg}");
			}
		}

		private void CreateTilePrefabSafe()
		{
			PrefabManager.OnVanillaPrefabsAvailable -= CreateTilePrefabSafe;
			((MonoBehaviour)this).StartCoroutine(CreateTilePrefabWhenReady());
		}

		private IEnumerator CreateTilePrefabWhenReady()
		{
			while (ZDOMan.instance == null)
			{
				yield return null;
			}
			EnsureTilePrefab();
		}

		private void CreateTilePrefab()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: 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_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Expected O, but got Unknown
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("ToynbeeTile");
			GameObject val2 = GameObject.CreatePrimitive((PrimitiveType)4);
			val2.transform.SetParent(val.transform);
			val2.transform.localScale = new Vector3(0.3f, 1f, 0.2f);
			val2.transform.localPosition = new Vector3(0f, 0.15f, 0f);
			Object.Destroy((Object)(object)val2.GetComponent<Collider>());
			MeshRenderer component = val2.GetComponent<MeshRenderer>();
			Shader val3 = FindTileShader();
			if ((Object)(object)val3 == (Object)null)
			{
				Debug.LogWarning((object)"[ToynbeeTiles] No known shader found for the tile material; leaving the default material in place (tile will be visible but untextured).");
			}
			else
			{
				((Renderer)component).material = new Material(val3)
				{
					mainTexture = (Texture)(object)LoadEmbeddedTexture("ToynbeeTiles.Assets.tile_texture.png")
				};
			}
			BoxCollider val4 = val.AddComponent<BoxCollider>();
			val4.size = new Vector3(3f, 0.3f, 2f);
			val4.center = new Vector3(0f, 0.15f, 0f);
			val.AddComponent<ToynbeeTileComponent>();
			ZNetView val5 = val.AddComponent<ZNetView>();
			val5.m_persistent = true;
			PrefabManager.Instance.AddPrefab(val);
			TileTilePrefab = val;
		}

		private static Shader FindTileShader()
		{
			string[] array = new string[2] { "Standard", "Legacy Shaders/Diffuse" };
			Shader[] array2 = Resources.FindObjectsOfTypeAll<Shader>();
			string[] array3 = array;
			foreach (string text in array3)
			{
				Shader[] array4 = array2;
				foreach (Shader val in array4)
				{
					if (((Object)val).name == text)
					{
						return val;
					}
				}
			}
			string[] array5 = array;
			foreach (string text2 in array5)
			{
				Shader val2 = Shader.Find(text2);
				if ((Object)(object)val2 != (Object)null)
				{
					return val2;
				}
			}
			return null;
		}

		private static Texture2D LoadEmbeddedTexture(string resourceName)
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Expected O, but got Unknown
			Assembly executingAssembly = Assembly.GetExecutingAssembly();
			using Stream stream = executingAssembly.GetManifestResourceStream(resourceName);
			using MemoryStream memoryStream = new MemoryStream();
			stream.CopyTo(memoryStream);
			Texture2D val = new Texture2D(2, 2);
			ImageConversion.LoadImage(val, memoryStream.ToArray());
			return val;
		}

		private void OnDestroy()
		{
			Harmony harmony = _harmony;
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
		}
	}
}
namespace ToynbeeTiles.Patches
{
	[HarmonyPatch(typeof(ZNetScene), "CreateObject")]
	public static class CleanupCorruptedZdoPatch
	{
		[HarmonyPostfix]
		public static void Postfix(ZDO zdo, ref GameObject __result)
		{
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)__result == (Object)null) && zdo != null && ((Object)__result).name.StartsWith("ToynbeeTile") && !((Object)(object)__result.GetComponent<ZNetView>() != (Object)null))
			{
				Debug.LogWarning((object)$"[ToynbeeTiles] Cleaning up corrupted ZDO at {zdo.GetPosition()} (created without a ZNetView — left over from an earlier buggy build).");
				Object.Destroy((Object)(object)__result);
				ZDOMan.instance.DestroyZDO(zdo);
				__result = null;
			}
		}
	}
	[HarmonyPatch(typeof(ZNetScene), "Awake")]
	public static class EnsurePrefabBeforeRegistrationPatch
	{
		[HarmonyPrefix]
		public static void Prefix()
		{
			if (ZDOMan.instance != null && !((Object)(object)ToynbeeTilePlugin.Instance == (Object)null))
			{
				ToynbeeTilePlugin.Instance.EnsureTilePrefab();
			}
		}
	}
	[HarmonyPatch(typeof(ZoneSystem), "SpawnLocation")]
	public static class LocationSpawnPatch
	{
		private static readonly string[] TargetSubstrings = new string[8] { "Eikthyrnir", "GDKing", "Bonemass", "Dragonqueen", "GoblinKing", "Vendor_BlackForest", "BogWitch_Camp", "Hildir_camp" };

		private static readonly HashSet<string> LoggedPrefabNames = new HashSet<string>();

		private const int HeightSearchMargin = 1000;

		[HarmonyPostfix]
		public static void Postfix(ZoneLocation location, Vector3 pos, GameObject __result)
		{
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_0100: Unknown result type (might be due to invalid IL or missing references)
			//IL_0114: Unknown result type (might be due to invalid IL or missing references)
			//IL_0119: Unknown result type (might be due to invalid IL or missing references)
			//IL_0126: Unknown result type (might be due to invalid IL or missing references)
			//IL_0127: Unknown result type (might be due to invalid IL or missing references)
			//IL_0128: Unknown result type (might be due to invalid IL or missing references)
			//IL_012d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0133: Unknown result type (might be due to invalid IL or missing references)
			//IL_015a: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_019b: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)__result == (Object)null)
			{
				return;
			}
			if (LoggedPrefabNames.Add(location.m_prefabName))
			{
				Debug.Log((object)("[ToynbeeTiles] location prefab spawned: " + location.m_prefabName));
			}
			if (!TargetSubstrings.Any((string t) => location.m_prefabName.Contains(t)))
			{
				return;
			}
			string text = $"toynbee_near_{location.m_prefabName}_{pos.x:F0}_{pos.z:F0}";
			if (ZoneSystem.instance.GetGlobalKey(text))
			{
				return;
			}
			ToynbeeTilePlugin.Instance.EnsureTilePrefab();
			if ((Object)(object)ToynbeeTilePlugin.TileTilePrefab == (Object)null)
			{
				Debug.LogWarning((object)("[ToynbeeTiles] Tile prefab not ready yet; skipping guaranteed spawn near " + location.m_prefabName + " (will retry next time this zone loads)."));
				return;
			}
			Vector3 val = Random.insideUnitSphere * Random.Range(8f, 20f);
			val.y = 0f;
			Vector3 val2 = pos + val;
			float num = default(float);
			if (!ZoneSystem.instance.GetSolidHeight(val2, ref num, 1000))
			{
				Debug.LogWarning((object)$"[ToynbeeTiles] GetSolidHeight failed near {location.m_prefabName} at {val2}; skipping (will retry next time this zone loads).");
				return;
			}
			if (num < 30f)
			{
				Debug.LogWarning((object)$"[ToynbeeTiles] Placement near {location.m_prefabName} at {val2} would be underwater (height={num:F1}, sea level={30f:F1}); skipping (will retry next time this zone loads).");
				return;
			}
			val2.y = num;
			GameObject val3 = Object.Instantiate<GameObject>(ToynbeeTilePlugin.TileTilePrefab, val2, Quaternion.identity);
			Debug.Log((object)$"[ToynbeeTiles] Spawned guaranteed tile near {location.m_prefabName} at {val2}");
			ZNetView component = val3.GetComponent<ZNetView>();
			if (((component != null) ? component.GetZDO() : null) == null)
			{
				Debug.LogWarning((object)("[ToynbeeTiles] New tile near " + location.m_prefabName + " has no ZDO — it won't survive a relog. This should never happen with the current code; if it does, something regressed."));
			}
			ZoneSystem.instance.SetGlobalKey(text);
		}
	}
	[HarmonyPatch(typeof(ZoneSystem), "SpawnZone")]
	public static class ZoneSpawnPatch
	{
		private const float SpawnChance = 0.08f;

		private const int HeightSearchMargin = 1000;

		[HarmonyPostfix]
		public static void Postfix(ZoneSystem __instance, Vector2s zoneID, SpawnMode mode)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: 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_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: 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_010f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: 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_0133: 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_01cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_01df: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0176: 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_018e: Unknown result type (might be due to invalid IL or missing references)
			string text = $"toynbee_zone_{zoneID.x}_{zoneID.y}";
			if (__instance.GetGlobalKey(text))
			{
				return;
			}
			int seed = WorldGenerator.instance.GetSeed() ^ (zoneID.x * 4096 + zoneID.y);
			Random random = new Random(seed);
			if (random.NextDouble() > 0.07999999821186066)
			{
				__instance.SetGlobalKey(text);
				return;
			}
			Vector3 zonePos = ZoneSystem.GetZonePos(zoneID);
			Vector3 val = zonePos + new Vector3((float)(random.NextDouble() - 0.5) * 60f, 0f, (float)(random.NextDouble() - 0.5) * 60f);
			ToynbeeTilePlugin.Instance.EnsureTilePrefab();
			if ((Object)(object)ToynbeeTilePlugin.TileTilePrefab == (Object)null)
			{
				Debug.LogWarning((object)$"[ToynbeeTiles] Tile prefab not ready yet; skipping zone spawn at {zoneID.x},{zoneID.y} (will retry next time this zone loads).");
				return;
			}
			float num = default(float);
			if (!__instance.GetSolidHeight(val, ref num, 1000))
			{
				Debug.LogWarning((object)$"[ToynbeeTiles] GetSolidHeight failed at {val} in zone {zoneID.x},{zoneID.y}; skipping (will retry next time this zone loads).");
				return;
			}
			if (num < 30f)
			{
				Debug.LogWarning((object)$"[ToynbeeTiles] Placement at {val} in zone {zoneID.x},{zoneID.y} would be underwater (height={num:F1}, sea level={30f:F1}); skipping (will retry next time this zone loads).");
				return;
			}
			val.y = num;
			GameObject val2 = Object.Instantiate<GameObject>(ToynbeeTilePlugin.TileTilePrefab, val, Quaternion.identity);
			Debug.Log((object)$"[ToynbeeTiles] Spawned random zone tile at {val} (zone {zoneID.x},{zoneID.y})");
			ZNetView component = val2.GetComponent<ZNetView>();
			if (((component != null) ? component.GetZDO() : null) == null)
			{
				Debug.LogWarning((object)"[ToynbeeTiles] New tile has no ZDO — it won't survive a relog. This should never happen with the current code; if it does, something regressed.");
			}
			__instance.SetGlobalKey(text);
		}
	}
}