using System; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using Unity.Netcode; using UnityEngine; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("BuildingLevelDisplay")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+cf5be1893d611266d3159afea93fca4a5a82124b")] [assembly: AssemblyProduct("BuildingLevelDisplay")] [assembly: AssemblyTitle("BuildingLevelDisplay")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [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 BuildingLevelDisplay { [BepInPlugin("com.kp.buildingleveldisplay", "Building Level Display", "1.1.3")] public class Plugin : BaseUnityPlugin { public static ManualLogSource? Log; private Harmony? _harmony; private void Awake() { //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Expected O, but got Unknown Log = ((BaseUnityPlugin)this).Logger; Log.LogInfo((object)"Building Level Display Mod is initializing..."); try { _harmony = new Harmony("com.kp.buildingleveldisplay"); _harmony.PatchAll(typeof(PlayerBuildingPatches)); Log.LogInfo((object)"Building Level Display patches applied successfully!"); } catch (Exception ex) { Log.LogError((object)("Failed to apply patches inside Building Level Display: " + ex)); } } private void OnDestroy() { Harmony? harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } } } public static class PlayerBuildingPatches { [HarmonyPatch(typeof(PlayerBuilding), "OnNetworkSpawn")] [HarmonyPostfix] public static void OnNetworkSpawn_Postfix(PlayerBuilding __instance) { EnsureComponentAttached(__instance); } [HarmonyPatch(typeof(BuildingSpot), "OnEnable")] [HarmonyPostfix] public static void BuildingSpot_OnEnable_Postfix(BuildingSpot __instance) { if ((Object)(object)__instance != (Object)null && (Object)(object)__instance.PlayerBuilding != (Object)null) { EnsureComponentAttached(__instance.PlayerBuilding); } } [HarmonyPatch(typeof(BuildingSpot), "Build", new Type[] { })] [HarmonyPostfix] public static void BuildingSpot_Build_Postfix(BuildingSpot __instance) { if ((Object)(object)__instance != (Object)null && (Object)(object)__instance.PlayerBuilding != (Object)null) { EnsureComponentAttached(__instance.PlayerBuilding); } } private static void EnsureComponentAttached(PlayerBuilding building) { //IL_003b: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)building == (Object)null) { return; } try { if ((Object)(object)((Component)building).gameObject.GetComponent() == (Object)null) { ((Component)building).gameObject.AddComponent(); ManualLogSource? log = Plugin.Log; if (log != null) { log.LogInfo((object)$"Attached BuildingLevelDisplayComponent to building of type {building.HouseType}"); } } } catch (Exception arg) { ManualLogSource? log2 = Plugin.Log; if (log2 != null) { log2.LogError((object)$"Error attaching component to building: {arg}"); } } } } public class BuildingLevelDisplayComponent : MonoBehaviour { private PlayerBuilding? _building; private LevelModule? _levelModule; private Camera? _cam; private Canvas? _canvas; private RectTransform? _canvasRT; private Text? _labelText; private Image? _bgImage; private Image? _borderImage; private bool _uiInitialized; private HouseType _lastHouseType; private int _lastLevel = -1; private float _cachedHeight = 3f; private static Material? _alwaysOnTopImageMaterial; private static Material? _alwaysOnTopTextMaterial; private static PlayerInteract? _staticLocalPlayer; private static float _staticLastPlayerCheckTime = -99f; private void Start() { _building = ((Component)this).GetComponent(); _cam = Camera.main; BuildUI(); } private void BuildUI() { //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Expected O, but got Unknown //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: 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_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: Expected O, but got Unknown //IL_0122: 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_0152: 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_017c: Unknown result type (might be due to invalid IL or missing references) //IL_0186: Unknown result type (might be due to invalid IL or missing references) //IL_0195: Unknown result type (might be due to invalid IL or missing references) //IL_019b: Expected O, but got Unknown //IL_01d3: 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_0203: Unknown result type (might be due to invalid IL or missing references) //IL_0218: Unknown result type (might be due to invalid IL or missing references) //IL_022d: Unknown result type (might be due to invalid IL or missing references) //IL_0237: 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: Expected O, but got Unknown //IL_02c1: Unknown result type (might be due to invalid IL or missing references) //IL_030f: Unknown result type (might be due to invalid IL or missing references) //IL_0323: Unknown result type (might be due to invalid IL or missing references) //IL_033f: Unknown result type (might be due to invalid IL or missing references) //IL_0354: Unknown result type (might be due to invalid IL or missing references) //IL_0369: Unknown result type (might be due to invalid IL or missing references) //IL_037e: 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) if (_uiInitialized) { return; } try { Transform val = ((Component)this).transform.Find("BuildingLevelCanvas"); if ((Object)(object)val != (Object)null) { Object.DestroyImmediate((Object)(object)((Component)val).gameObject); } GameObject val2 = new GameObject("BuildingLevelCanvas"); val2.transform.SetParent(((Component)this).transform, false); _canvas = val2.AddComponent(); _canvas.renderMode = (RenderMode)2; _canvas.overrideSorting = true; _canvas.sortingOrder = 30000; _canvasRT = val2.GetComponent(); _canvasRT.sizeDelta = new Vector2(100f, 40f); ((Transform)_canvasRT).localScale = Vector3.one * 0.018f; ((Transform)_canvasRT).localPosition = new Vector3(0f, 3.5f, 0f); GameObject val3 = new GameObject("Border"); val3.transform.SetParent(val2.transform, false); _borderImage = val3.AddComponent(); ((Graphic)_borderImage).color = new Color(0.35f, 0.35f, 0.4f, 0.85f); RectTransform component = val3.GetComponent(); component.anchorMin = new Vector2(0.5f, 0.5f); component.anchorMax = new Vector2(0.5f, 0.5f); component.pivot = new Vector2(0.5f, 0.5f); component.sizeDelta = new Vector2(94f, 34f); component.anchoredPosition = Vector2.zero; GameObject val4 = new GameObject("Background"); val4.transform.SetParent(val2.transform, false); _bgImage = val4.AddComponent(); ((Graphic)_bgImage).color = new Color(0.06f, 0.06f, 0.08f, 0.92f); RectTransform component2 = val4.GetComponent(); component2.anchorMin = new Vector2(0.5f, 0.5f); component2.anchorMax = new Vector2(0.5f, 0.5f); component2.pivot = new Vector2(0.5f, 0.5f); component2.sizeDelta = new Vector2(90f, 30f); component2.anchoredPosition = Vector2.zero; GameObject val5 = new GameObject("LevelText"); val5.transform.SetParent(val2.transform, false); _labelText = val5.AddComponent(); Font font = Font.CreateDynamicFontFromOSFont("Arial", 28) ?? Resources.GetBuiltinResource("LegacyRuntime.ttf"); _labelText.font = font; _labelText.fontSize = 22; _labelText.fontStyle = (FontStyle)1; _labelText.alignment = (TextAnchor)4; ((Graphic)_labelText).color = Color.white; _labelText.horizontalOverflow = (HorizontalWrapMode)1; _labelText.verticalOverflow = (VerticalWrapMode)1; _labelText.text = "Lvl 1"; Outline obj = val5.AddComponent(); ((Shadow)obj).effectColor = new Color(0f, 0f, 0f, 0.95f); ((Shadow)obj).effectDistance = new Vector2(1.5f, -1.5f); RectTransform component3 = val5.GetComponent(); component3.anchorMin = new Vector2(0.5f, 0.5f); component3.anchorMax = new Vector2(0.5f, 0.5f); component3.pivot = new Vector2(0.5f, 0.5f); component3.sizeDelta = new Vector2(90f, 30f); component3.anchoredPosition = Vector2.zero; ApplyOverlayMaterials(); _uiInitialized = true; UpdateLevelText(); } catch (Exception arg) { ManualLogSource? log = Plugin.Log; if (log != null) { log.LogError((object)$"Failed to build UI for building: {arg}"); } } } private void ApplyOverlayMaterials() { //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Expected O, but got Unknown //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Expected O, but got Unknown try { if ((Object)(object)_alwaysOnTopImageMaterial == (Object)null) { Shader val = Shader.Find("UI/Default") ?? Shader.Find("Sprites/Default"); if ((Object)(object)val != (Object)null) { _alwaysOnTopImageMaterial = new Material(val); _alwaysOnTopImageMaterial.SetInt("_ZTest", 8); _alwaysOnTopImageMaterial.SetInt("unity_GUIZTestMode", 8); _alwaysOnTopImageMaterial.renderQueue = 5000; } } if ((Object)(object)_alwaysOnTopTextMaterial == (Object)null) { Shader val2 = Shader.Find("UI/Default Font") ?? Shader.Find("UI/Default"); if ((Object)(object)val2 != (Object)null) { _alwaysOnTopTextMaterial = new Material(val2); _alwaysOnTopTextMaterial.SetInt("_ZTest", 8); _alwaysOnTopTextMaterial.SetInt("unity_GUIZTestMode", 8); _alwaysOnTopTextMaterial.renderQueue = 5000; } } if ((Object)(object)_borderImage != (Object)null && (Object)(object)_alwaysOnTopImageMaterial != (Object)null) { ((Graphic)_borderImage).material = _alwaysOnTopImageMaterial; } if ((Object)(object)_bgImage != (Object)null && (Object)(object)_alwaysOnTopImageMaterial != (Object)null) { ((Graphic)_bgImage).material = _alwaysOnTopImageMaterial; } if ((Object)(object)_labelText != (Object)null && (Object)(object)_alwaysOnTopTextMaterial != (Object)null) { ((Graphic)_labelText).material = _alwaysOnTopTextMaterial; } } catch (Exception ex) { ManualLogSource? log = Plugin.Log; if (log != null) { log.LogWarning((object)("Error applying overlay materials: " + ex.Message)); } } } private void Update() { //IL_0041: 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_0079: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_014c: 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_0169: 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_0218: Unknown result type (might be due to invalid IL or missing references) //IL_01b3: Unknown result type (might be due to invalid IL or missing references) //IL_01b9: Unknown result type (might be due to invalid IL or missing references) //IL_01be: Unknown result type (might be due to invalid IL or missing references) //IL_01c3: Unknown result type (might be due to invalid IL or missing references) //IL_01cb: 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) //IL_01d2: Unknown result type (might be due to invalid IL or missing references) //IL_01da: Unknown result type (might be due to invalid IL or missing references) //IL_01eb: Unknown result type (might be due to invalid IL or missing references) //IL_01f0: Unknown result type (might be due to invalid IL or missing references) //IL_0267: Unknown result type (might be due to invalid IL or missing references) //IL_0277: 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_0281: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_building == (Object)null) { _building = ((Component)this).GetComponent(); if ((Object)(object)_building == (Object)null) { return; } } bool flag = false; PlayerInteract localPlayer = GetLocalPlayer(); if ((Object)(object)localPlayer != (Object)null) { flag = Vector3.Distance(((Component)localPlayer).transform.position, ((Component)this).transform.position) < 32f; } else if ((Object)(object)_cam != (Object)null) { flag = Vector3.Distance(((Component)_cam).transform.position, ((Component)this).transform.position) < 45f; } if (!flag) { if ((Object)(object)_canvas != (Object)null && ((Component)_canvas).gameObject.activeSelf) { ((Component)_canvas).gameObject.SetActive(false); } return; } if (!_uiInitialized) { BuildUI(); } if ((Object)(object)_canvas != (Object)null && !((Component)_canvas).gameObject.activeSelf) { ((Component)_canvas).gameObject.SetActive(true); } if ((Object)(object)_levelModule == (Object)null) { _levelModule = _building.LevelModule; } int num = ((!((Object)(object)_levelModule != (Object)null)) ? 1 : _levelModule.Level); if (_building.HouseType != _lastHouseType || num != _lastLevel) { _lastHouseType = _building.HouseType; _lastLevel = num; _cachedHeight = CalculateBuildingHeight(); UpdateLevelText(); } if ((Object)(object)_canvasRT != (Object)null) { PlayerInteractable interactable = GetInteractable(); if ((Object)(object)interactable != (Object)null) { Vector3 val = ((Component)interactable).transform.position + interactable.CostPanelOffset; Vector3 val2 = ((Component)this).transform.InverseTransformPoint(val); ((Transform)_canvasRT).localPosition = val2 + new Vector3(0f, 1.3f, 0f); } else { ((Transform)_canvasRT).localPosition = new Vector3(0f, _cachedHeight + 0.3f, 0f); } if ((Object)(object)_cam == (Object)null || !((Component)_cam).gameObject.activeInHierarchy) { _cam = Camera.main; } if ((Object)(object)_cam != (Object)null) { ((Transform)_canvasRT).rotation = Quaternion.LookRotation(((Transform)_canvasRT).position - ((Component)_cam).transform.position); } } } private void UpdateLevelText() { //IL_018f: Unknown result type (might be due to invalid IL or missing references) //IL_01c1: Unknown result type (might be due to invalid IL or missing references) //IL_011a: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_014f: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_labelText == (Object)null) { return; } int num = 1; int num2 = 0; bool flag = false; if ((Object)(object)_levelModule != (Object)null) { num = _levelModule.Level; num2 = _levelModule.MaxLevel; flag = _levelModule.IsMaxLevel || (num2 > 0 && num >= num2); } if (num2 > 0) { if (flag) { _labelText.text = $"Lvl {num}/{num2}"; ((Graphic)_labelText).color = new Color(1f, 0.82f, 0f, 0.95f); if ((Object)(object)_borderImage != (Object)null) { ((Graphic)_borderImage).color = new Color(1f, 0.82f, 0f, 0.85f); } } else { _labelText.text = $"Lvl {num}/{num2}"; ((Graphic)_labelText).color = new Color(0.85f, 0.9f, 1f, 0.95f); if ((Object)(object)_borderImage != (Object)null) { ((Graphic)_borderImage).color = new Color(0.35f, 0.35f, 0.4f, 0.85f); } } } else { _labelText.text = $"Lvl {num}"; ((Graphic)_labelText).color = new Color(0.85f, 0.9f, 1f, 0.95f); if ((Object)(object)_borderImage != (Object)null) { ((Graphic)_borderImage).color = new Color(0.35f, 0.35f, 0.4f, 0.85f); } } } private float CalculateBuildingHeight() { //IL_0021: 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_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: Unknown result type (might be due to invalid IL or missing references) try { Renderer[] componentsInChildren = ((Component)this).GetComponentsInChildren(true); if (componentsInChildren != null && componentsInChildren.Length != 0) { float num = 0f; float y = ((Component)this).transform.position.y; bool flag = false; Renderer[] array = componentsInChildren; foreach (Renderer val in array) { if (!((Object)(object)val != (Object)null) || !val.enabled || !((Component)val).gameObject.activeInHierarchy) { continue; } string text = ((Object)((Component)val).gameObject).name.ToLower(); if (!text.Contains("shadow") && !text.Contains("decal") && !text.Contains("ui") && !text.Contains("outline") && !text.Contains("range") && !text.Contains("selection") && !text.Contains("arrow")) { Bounds bounds = val.bounds; float num2 = ((Bounds)(ref bounds)).max.y - y; if (num2 > num) { num = num2; flag = true; } } } if (flag && num > 0.5f) { return num; } } } catch (Exception ex) { ManualLogSource? log = Plugin.Log; if (log != null) { log.LogWarning((object)("Error calculating building height: " + ex.Message)); } } return 3f; } private PlayerInteractable? GetInteractable() { if ((Object)(object)_building == (Object)null) { return null; } PlayerInteractable componentInChildren = ((Component)_building).GetComponentInChildren(true); if ((Object)(object)componentInChildren != (Object)null) { return componentInChildren; } if ((Object)(object)_building.BuildingSpot != (Object)null) { return _building.BuildingSpot.Interactable; } return null; } private PlayerInteract? GetLocalPlayer() { if ((Object)(object)_staticLocalPlayer != (Object)null && (Object)(object)((Component)_staticLocalPlayer).gameObject != (Object)null && ((Component)_staticLocalPlayer).gameObject.activeInHierarchy) { return _staticLocalPlayer; } if (Time.time - _staticLastPlayerCheckTime > 2f) { _staticLastPlayerCheckTime = Time.time; _staticLocalPlayer = null; PlayerInteract[] array = Object.FindObjectsOfType(); if (array != null && array.Length != 0) { PlayerInteract[] array2 = array; foreach (PlayerInteract val in array2) { if ((Object)(object)val != (Object)null && (Object)(object)((Component)val).gameObject != (Object)null && ((Component)val).gameObject.activeInHierarchy && ((NetworkBehaviour)val).IsOwner) { _staticLocalPlayer = val; break; } } if ((Object)(object)_staticLocalPlayer == (Object)null && (Object)(object)array[0] != (Object)null && ((Component)array[0]).gameObject.activeInHierarchy) { _staticLocalPlayer = array[0]; } } } return _staticLocalPlayer; } private void OnDestroy() { if ((Object)(object)_canvas != (Object)null && (Object)(object)((Component)_canvas).gameObject != (Object)null) { Object.Destroy((Object)(object)((Component)_canvas).gameObject); } } } }