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<BuildingLevelDisplayComponent>() == (Object)null)
{
((Component)building).gameObject.AddComponent<BuildingLevelDisplayComponent>();
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<PlayerBuilding>();
_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>();
_canvas.renderMode = (RenderMode)2;
_canvas.overrideSorting = true;
_canvas.sortingOrder = 30000;
_canvasRT = val2.GetComponent<RectTransform>();
_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<Image>();
((Graphic)_borderImage).color = new Color(0.35f, 0.35f, 0.4f, 0.85f);
RectTransform component = val3.GetComponent<RectTransform>();
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<Image>();
((Graphic)_bgImage).color = new Color(0.06f, 0.06f, 0.08f, 0.92f);
RectTransform component2 = val4.GetComponent<RectTransform>();
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<Text>();
Font font = Font.CreateDynamicFontFromOSFont("Arial", 28) ?? Resources.GetBuiltinResource<Font>("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<Outline>();
((Shadow)obj).effectColor = new Color(0f, 0f, 0f, 0.95f);
((Shadow)obj).effectDistance = new Vector2(1.5f, -1.5f);
RectTransform component3 = val5.GetComponent<RectTransform>();
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<PlayerBuilding>();
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<Renderer>(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<PlayerInteractable>(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<PlayerInteract>();
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);
}
}
}
}