using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using FortecaClanWarfare.Core; using FortecaClanWarfare.Data; using FortecaClanWarfare.Network; using FortecaClanWarfare.Patches; using FortecaClanWarfare.UI; using FortecaClanWarfare.Utils; using HarmonyLib; using Microsoft.CodeAnalysis; using UnityEngine; using UnityEngine.UI; [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.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyCompany("forteca")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyDescription("Clan-based territory warfare mod for Valheim")] [assembly: AssemblyFileVersion("0.1.0.0")] [assembly: AssemblyInformationalVersion("0.1.0")] [assembly: AssemblyProduct("FortecaClanWarfare")] [assembly: AssemblyTitle("FortecaClanWarfare")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("0.1.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.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 FortecaClanWarfare { [BepInPlugin("com.forteca.clanwarfare", "Forteca Clan Warfare", "0.1.0")] [BepInProcess("valheim.exe")] [BepInProcess("valheim_server.exe")] public class Plugin : BaseUnityPlugin { public const string PluginGUID = "com.forteca.clanwarfare"; public const string PluginName = "Forteca Clan Warfare"; public const string PluginVersion = "0.1.0"; private Harmony _harmony; private GameObject _managerObj; public static Plugin Instance { get; private set; } public static ManualLogSource Log { get; private set; } private void Awake() { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Expected O, but got Unknown //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Expected O, but got Unknown //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Invalid comparison between Unknown and I4 Instance = this; Log = ((BaseUnityPlugin)this).Logger; ClanConfig.Initialize(((BaseUnityPlugin)this).Config); _harmony = new Harmony("com.forteca.clanwarfare"); _harmony.PatchAll(typeof(Plugin).Assembly); _managerObj = new GameObject("FortecaClanWarfare"); Object.DontDestroyOnLoad((Object)(object)_managerObj); _managerObj.AddComponent(); _managerObj.AddComponent(); if ((int)SystemInfo.graphicsDeviceType != 4) { _managerObj.AddComponent(); _managerObj.AddComponent(); _managerObj.AddComponent(); _managerObj.AddComponent(); _managerObj.AddComponent(); _managerObj.AddComponent(); } Log.LogMessage((object)""); Log.LogMessage((object)" ============================================"); Log.LogMessage((object)" FORTECA CLAN WARFARE"); Log.LogMessage((object)" Developed by Freyja"); Log.LogMessage((object)" https://tinyurl.com/DiscordFreyja"); Log.LogMessage((object)" ============================================"); Log.LogMessage((object)""); } private void OnDestroy() { Harmony harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } if ((Object)(object)_managerObj != (Object)null) { Object.Destroy((Object)(object)_managerObj); } } } } namespace FortecaClanWarfare.Utils { public static class BiomeUtils { private static Dictionary _merchantCache = new Dictionary(); private static float _merchantCacheTime = 0f; private const float MerchantCacheLifetime = 60f; public static Biome GetBiomeAt(Vector3 position) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0017: 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_000e: 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) if (WorldGenerator.instance == null) { return (Biome)1; } return WorldGenerator.instance.GetBiome(position); } public static Dictionary SampleBiomeComposition(Vector2i gridPos, int sampleCount = 100) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0087: 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_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: 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_01ea: 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_01f3: Unknown result type (might be due to invalid IL or missing references) //IL_01ff: Expected I4, but got Unknown //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: 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) //IL_0103: Unknown result type (might be due to invalid IL or missing references) //IL_0108: Unknown result type (might be due to invalid IL or missing references) //IL_010a: Unknown result type (might be due to invalid IL or missing references) //IL_010e: Expected I4, but got Unknown Dictionary dictionary = new Dictionary(); Vector3 regionCenter = VoronoiGrid.Instance.GetRegionCenter(gridPos); float num = VoronoiGrid.Instance.GetApproximateRegionRadius(gridPos); if (num < 200f) { num = 200f; } if (num > 2000f) { num = 2000f; } int num2 = (int)Mathf.Sqrt((float)sampleCount); if (num2 < 5) { num2 = 5; } float num3 = num * 2f; float num4 = num3 * 2f / (float)num2; int num5 = 0; Vector3 val = default(Vector3); for (int i = 0; i < num2; i++) { for (int j = 0; j < num2; j++) { float num6 = regionCenter.x - num3 + ((float)i + 0.5f) * num4; float num7 = regionCenter.z - num3 + ((float)j + 0.5f) * num4; ((Vector3)(ref val))..ctor(num6, 0f, num7); Vector2i region = VoronoiGrid.Instance.GetRegion(val); if (region.x == gridPos.x && region.y == gridPos.y) { Biome biomeAt = GetBiomeAt(val); int key = (int)biomeAt; if (!dictionary.ContainsKey(key)) { dictionary[key] = 0f; } dictionary[key]++; num5++; } } } if (num5 > 0) { foreach (int item in new List(dictionary.Keys)) { dictionary[item] = dictionary[item] / (float)num5 * 100f; } } if (num5 == 0) { Biome biomeAt2 = GetBiomeAt(regionCenter); dictionary[(int)biomeAt2] = 100f; } return dictionary; } public static bool CellHasMerchant(Vector2i gridPos) { //IL_004b: 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_008b: Unknown result type (might be due to invalid IL or missing references) //IL_008d: 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_016b: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: 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_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_0112: 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_011b: Unknown result type (might be due to invalid IL or missing references) //IL_0122: Unknown result type (might be due to invalid IL or missing references) //IL_012a: 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) if ((Object)(object)ZoneSystem.instance == (Object)null) { return false; } if (Time.time - _merchantCacheTime > 60f) { _merchantCache.Clear(); _merchantCacheTime = Time.time; } if (_merchantCache.TryGetValue(gridPos, out var value)) { return value; } bool flag = false; Vector3 worldPos = default(Vector3); foreach (KeyValuePair locationInstance in ZoneSystem.instance.m_locationInstances) { LocationInstance value2 = locationInstance.Value; if (value2.m_location == null) { continue; } string text = value2.m_location.m_prefabName?.ToLower() ?? ""; if (text.Contains("haldor") || text.Contains("hildir")) { ((Vector3)(ref worldPos))..ctor(value2.m_position.x, 0f, value2.m_position.z); Vector2i region = VoronoiGrid.Instance.GetRegion(worldPos); if (region.x == gridPos.x && region.y == gridPos.y) { flag = true; break; } } } _merchantCache[gridPos] = flag; return flag; } public static Biome GetDominantBiome(Dictionary composition) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) if (composition == null || composition.Count == 0) { return (Biome)1; } int num = 1; float num2 = 0f; foreach (KeyValuePair item in composition) { if (item.Value > num2) { num2 = item.Value; num = item.Key; } } return (Biome)num; } public static bool HasPointOfInterest(Vector2i gridPos) { //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_003f: 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_007b: 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_008c: 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_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: 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) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)ZoneSystem.instance == (Object)null) { return false; } Vector3 worldPos = default(Vector3); foreach (KeyValuePair locationInstance in ZoneSystem.instance.m_locationInstances) { LocationInstance value = locationInstance.Value; if (value.m_location == null) { continue; } string prefabName = value.m_location.m_prefabName ?? ""; if (IsPOILocation(prefabName)) { ((Vector3)(ref worldPos))..ctor(value.m_position.x, 0f, value.m_position.z); Vector2i region = VoronoiGrid.Instance.GetRegion(worldPos); if (region.x == gridPos.x && region.y == gridPos.y) { return true; } } } return false; } private static bool IsPOILocation(string prefabName) { if (string.IsNullOrEmpty(prefabName)) { return false; } string text = prefabName.ToLower(); if (text.Contains("altar") || text.Contains("boss")) { return true; } if (text.Contains("haldor") || text.Contains("hildir")) { return true; } if (text.Contains("infectedmine") || text.Contains("sunkencrypt") || text.Contains("mountaincave") || text.Contains("goblinking")) { return true; } return false; } public static Color GetBiomeColor(Biome biome) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Invalid comparison between Unknown and I4 //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Invalid comparison between Unknown and I4 //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Expected I4, but got Unknown //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Invalid comparison between Unknown and I4 //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Invalid comparison between Unknown and I4 //IL_007f: 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_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_0148: Unknown result type (might be due to invalid IL or missing references) //IL_014d: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: 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_0145: Unknown result type (might be due to invalid IL or missing references) //IL_0112: Unknown result type (might be due to invalid IL or missing references) //IL_0117: 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) //IL_0026: Invalid comparison between Unknown and I4 //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Invalid comparison between Unknown and I4 //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Invalid comparison between Unknown and I4 //IL_0154: 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_0099: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: 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_0129: Unknown result type (might be due to invalid IL or missing references) //IL_012e: Unknown result type (might be due to invalid IL or missing references) //IL_0158: 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_002d: Invalid comparison between Unknown and I4 //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) if (1 == 0) { } Color result; if ((int)biome <= 16) { switch (biome - 1) { case 0: goto IL_0070; case 1: goto IL_00a4; case 3: goto IL_00be; case 2: goto IL_0148; } if ((int)biome != 8) { if ((int)biome != 16) { goto IL_0148; } result = new Color(0.9f, 0.85f, 0.4f); } else { result = new Color(0.2f, 0.4f, 0.2f); } } else if ((int)biome <= 64) { if ((int)biome != 32) { if ((int)biome != 64) { goto IL_0148; } result = new Color(0.7f, 0.9f, 1f); } else { result = new Color(0.8f, 0.3f, 0.2f); } } else if ((int)biome != 256) { if ((int)biome != 512) { goto IL_0148; } result = new Color(0.5f, 0.3f, 0.6f); } else { result = new Color(0.2f, 0.4f, 0.8f); } goto IL_0150; IL_0148: result = Color.gray; goto IL_0150; IL_00be: result = new Color(0.8f, 0.8f, 0.9f); goto IL_0150; IL_0070: result = new Color(0.4f, 0.8f, 0.3f); goto IL_0150; IL_00a4: result = new Color(0.4f, 0.35f, 0.2f); goto IL_0150; IL_0150: if (1 == 0) { } return result; } public static string GetBiomeName(Biome biome) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Invalid comparison between Unknown and I4 //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Invalid comparison between Unknown and I4 //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Expected I4, but got Unknown //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Invalid comparison between Unknown and I4 //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Invalid comparison between Unknown and I4 //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Invalid comparison between Unknown and I4 //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Invalid comparison between Unknown and I4 //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Invalid comparison between Unknown and I4 //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Invalid comparison between Unknown and I4 //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Invalid comparison between Unknown and I4 //IL_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: Invalid comparison between Unknown and I4 //IL_0107: Unknown result type (might be due to invalid IL or missing references) //IL_010a: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Invalid comparison between Unknown and I4 //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Invalid comparison between Unknown and I4 //IL_011c: Unknown result type (might be due to invalid IL or missing references) //IL_011e: Unknown result type (might be due to invalid IL or missing references) //IL_0120: Invalid comparison between Unknown and I4 //IL_0130: 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_0134: Invalid comparison between Unknown and I4 //IL_0144: Unknown result type (might be due to invalid IL or missing references) //IL_0146: Unknown result type (might be due to invalid IL or missing references) //IL_0148: Invalid comparison between Unknown and I4 //IL_0158: 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_015c: Invalid comparison between Unknown and I4 //IL_016c: Unknown result type (might be due to invalid IL or missing references) //IL_0172: Unknown result type (might be due to invalid IL or missing references) //IL_0174: Invalid comparison between Unknown and I4 if ((int)biome <= 16) { switch (biome - 1) { default: if ((int)biome != 8) { if ((int)biome != 16) { break; } return "Plains"; } return "Black Forest"; case 0: return "Meadows"; case 1: return "Swamp"; case 3: return "Mountain"; case 2: break; } } else if ((int)biome <= 64) { if ((int)biome == 32) { return "Ashlands"; } if ((int)biome == 64) { return "Deep North"; } } else { if ((int)biome == 256) { return "Ocean"; } if ((int)biome == 512) { return "Mistlands"; } } if ((biome & 0x20) > 0) { return "Ashlands"; } if ((biome & 0x40) > 0) { return "Deep North"; } if ((biome & 0x200) > 0) { return "Mistlands"; } if ((biome & 0x10) > 0) { return "Plains"; } if ((biome & 4) > 0) { return "Mountain"; } if ((biome & 2) > 0) { return "Swamp"; } if ((biome & 8) > 0) { return "Black Forest"; } if ((biome & 1) > 0) { return "Meadows"; } if ((biome & 0x100) > 0) { return "Ocean"; } return "Wilds"; } public static float GetBiomeTollMultiplier(Biome biome) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Invalid comparison between Unknown and I4 //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Invalid comparison between Unknown and I4 //IL_0011: 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_0029: Expected I4, but got Unknown //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Invalid comparison between Unknown and I4 //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Invalid comparison between Unknown and I4 //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Invalid comparison between Unknown and I4 //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Invalid comparison between Unknown and I4 //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Invalid comparison between Unknown and I4 //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Invalid comparison between Unknown and I4 Biome val = ResolveBiome(biome); if (1 == 0) { } float result; if ((int)val <= 16) { switch (val - 1) { case 0: goto IL_005f; case 1: goto IL_006f; case 3: goto IL_0077; case 2: goto IL_00a7; } if ((int)val != 8) { if ((int)val != 16) { goto IL_00a7; } result = 3f; } else { result = 1.5f; } } else if ((int)val <= 64) { if ((int)val != 32) { if ((int)val != 64) { goto IL_00a7; } result = 3f; } else { result = 5f; } } else if ((int)val != 256) { if ((int)val != 512) { goto IL_00a7; } result = 4f; } else { result = 0.5f; } goto IL_00af; IL_00a7: result = 1f; goto IL_00af; IL_0077: result = 2.5f; goto IL_00af; IL_005f: result = 1f; goto IL_00af; IL_006f: result = 2f; goto IL_00af; IL_00af: if (1 == 0) { } return result; } public static Biome ResolveBiome(Biome biome) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Invalid comparison between Unknown and I4 //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Invalid comparison between Unknown and I4 //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Invalid comparison between Unknown and I4 //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Invalid comparison between Unknown and I4 //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Invalid comparison between Unknown and I4 //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Invalid comparison between Unknown and I4 //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Invalid comparison between Unknown and I4 //IL_0050: 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_0105: 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: Invalid comparison between Unknown and I4 //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Invalid comparison between Unknown and I4 //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Invalid comparison between Unknown and I4 //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Invalid comparison between Unknown and I4 //IL_0057: 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_005c: Invalid comparison between Unknown and I4 //IL_006a: 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) //IL_006f: Invalid comparison between Unknown and I4 //IL_0064: 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_0085: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Invalid comparison between Unknown and I4 //IL_0079: 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_009a: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Invalid comparison between Unknown and I4 //IL_0094: 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) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Invalid comparison between Unknown and I4 //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: 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_00bd: Invalid comparison between Unknown and I4 //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Invalid comparison between Unknown and I4 //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: Invalid comparison between Unknown and I4 //IL_00d6: 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_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Invalid comparison between Unknown and I4 //IL_00e6: 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_00fe: Unknown result type (might be due to invalid IL or missing references) if ((int)biome <= 16) { if ((int)biome <= 4) { if (biome - 1 <= 1 || (int)biome == 4) { goto IL_0050; } } else if ((int)biome == 8 || (int)biome == 16) { goto IL_0050; } } else if ((int)biome <= 64) { if ((int)biome == 32 || (int)biome == 64) { goto IL_0050; } } else if ((int)biome == 256 || (int)biome == 512) { goto IL_0050; } if ((biome & 0x20) > 0) { return (Biome)32; } if ((biome & 0x40) > 0) { return (Biome)64; } if ((biome & 0x200) > 0) { return (Biome)512; } if ((biome & 0x10) > 0) { return (Biome)16; } if ((biome & 4) > 0) { return (Biome)4; } if ((biome & 2) > 0) { return (Biome)2; } if ((biome & 8) > 0) { return (Biome)8; } if ((biome & 1) > 0) { return (Biome)1; } if ((biome & 0x100) > 0) { return (Biome)256; } return (Biome)1; IL_0050: return biome; } } public static class TerritoryNaming { private static readonly string[] NorthPrefixes = new string[5] { "Norðri", "Northern", "Frost", "Winter's", "Boreal" }; private static readonly string[] SouthPrefixes = new string[5] { "Suðri", "Southern", "Sun's", "Warm", "Golden" }; private static readonly string[] EastPrefixes = new string[5] { "Austri", "Eastern", "Dawn", "Rising", "Morning" }; private static readonly string[] WestPrefixes = new string[5] { "Vestri", "Western", "Twilight", "Setting", "Dusk" }; private static readonly string[] CenterPrefixes = new string[5] { "Miðgarð", "Central", "Heart of", "Ancient", "Old" }; private static readonly Dictionary BiomeNames = new Dictionary { { (Biome)1, new string[8] { "Meadow", "Grassland", "Green Vale", "Peaceful Fields", "Idavoll", "Folkvangr", "Verdant Lea", "Shepherd's Rest" } }, { (Biome)8, new string[8] { "Dark Woods", "Eerie Forest", "Shadow Grove", "Myrkviðr", "Ironwood", "Troll's Domain", "Whispering Pines", "Draugr's Reach" } }, { (Biome)2, new string[8] { "Murky Fen", "Poison Marsh", "Dead Man's Bog", "Hel's Mire", "Rotting Wetlands", "Drowned Vale", "Festering Swamp", "Corpse Marsh" } }, { (Biome)4, new string[8] { "Frost Peak", "Stone Heights", "Jötunheimr", "Eagle's Nest", "Ice Crown", "Thunder Summit", "Goat's Path", "Windswept Ridge" } }, { (Biome)16, new string[8] { "Golden Plains", "Fuling Lands", "Scorched Fields", "Barren Reach", "Vigriðr", "Blood Prairie", "Deathstalker's Domain", "Sun-bleached Expanse" } }, { (Biome)512, new string[8] { "Shrouded Vale", "Spider's Web", "Mist Hollow", "Gjöll", "Veiled Ruins", "Ancient's Rest", "Forgotten Realm", "Skuld's Domain" } }, { (Biome)32, new string[8] { "Scorched Waste", "Múspellheim", "Ember Fields", "Burning Reach", "Cinder Vale", "Charred Domain", "Flame's Edge", "Surt's Realm" } }, { (Biome)64, new string[8] { "Frozen Waste", "Niflheim", "Eternal Ice", "Frost Giant's Land", "Glacial Expanse", "Winter's End", "Permafrost Domain", "Hrimfaxi's Path" } }, { (Biome)256, new string[8] { "Ægir's Domain", "Depths", "Serpent's Sea", "Njord's Waters", "Kraken's Reach", "Wayward Waves", "Storm Channel", "Ran's Grasp" } } }; private static readonly string[] MixedSuffixes = new string[6] { "Borderlands", "Frontier", "Crossroads", "Threshold", "Edge", "Marches" }; private static readonly string[] MerchantModifiers = new string[4] { "Market", "Trade Post", "Merchant's Haven", "Trader's Rest" }; private static readonly string[] BossModifiers = new string[4] { "Altar", "Sacred Ground", "Ritual Site", "Offering Place" }; public static string GenerateTerritoryName(Vector2i gridPos, Dictionary biomeComposition, bool hasMerchant = false, bool hasBossAltar = false) { //IL_003d: 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_0059: 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_0060: 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_0070: 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_0026: 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_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_009d: 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_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) if (biomeComposition == null || biomeComposition.Count == 0) { return $"Unknown Land ({gridPos.x}, {gridPos.y})"; } int seed = gridPos.x * 10000 + gridPos.y; Random random = new Random(seed); Biome dominantBiome = GetDominantBiome(biomeComposition); float biomePercent = GetBiomePercent(biomeComposition, dominantBiome); string directionalPrefix = GetDirectionalPrefix(gridPos, random); string text = GetBiomeName(dominantBiome, random); if (biomePercent < 70f && biomeComposition.Count > 1) { Biome secondaryBiome = GetSecondaryBiome(biomeComposition, dominantBiome); if (secondaryBiome != dominantBiome) { string text2 = MixedSuffixes[random.Next(MixedSuffixes.Length)]; text = GetShortBiomeName(dominantBiome) + "-" + GetShortBiomeName(secondaryBiome) + " " + text2; } } if (hasMerchant) { string text3 = MerchantModifiers[random.Next(MerchantModifiers.Length)]; return directionalPrefix + " " + text3; } if (hasBossAltar) { string text4 = BossModifiers[random.Next(BossModifiers.Length)]; return text + " " + text4; } return directionalPrefix + " " + text; } public static string GetSimpleName(Vector2i gridPos, Dictionary biomeComposition) { //IL_001d: 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_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_003f: Unknown result type (might be due to invalid IL or missing references) if (biomeComposition == null || biomeComposition.Count == 0) { return "Unknown"; } int seed = gridPos.x * 10000 + gridPos.y; Random rng = new Random(seed); Biome dominantBiome = GetDominantBiome(biomeComposition); return GetBiomeName(dominantBiome, rng); } private static string GetDirectionalPrefix(Vector2i gridPos, Random rng) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_000d: 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) Vector3 regionCenter = VoronoiGrid.Instance.GetRegionCenter(gridPos); float x = regionCenter.x; float z = regionCenter.z; float num = Mathf.Sqrt(x * x + z * z); if (num < 2000f) { return CenterPrefixes[rng.Next(CenterPrefixes.Length)]; } float num2 = Mathf.Atan2(z, x) * 57.29578f; if (num2 >= 45f && num2 < 135f) { return NorthPrefixes[rng.Next(NorthPrefixes.Length)]; } if (num2 >= -45f && num2 < 45f) { return EastPrefixes[rng.Next(EastPrefixes.Length)]; } if (num2 >= -135f && num2 < -45f) { return SouthPrefixes[rng.Next(SouthPrefixes.Length)]; } return WestPrefixes[rng.Next(WestPrefixes.Length)]; } private static string GetBiomeName(Biome biome, Random rng) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0022: 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_0028: 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_0032: Unknown result type (might be due to invalid IL or missing references) if (BiomeNames.TryGetValue(biome, out var value)) { return value[rng.Next(value.Length)]; } Biome val = ResolveBiomeFlag(biome); if (val != biome && BiomeNames.TryGetValue(val, out var value2)) { return value2[rng.Next(value2.Length)]; } return "Wilderness"; } private static Biome ResolveBiomeFlag(Biome biome) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Invalid comparison between Unknown and I4 //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Invalid comparison between Unknown and I4 //IL_000e: 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_002d: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Invalid comparison between Unknown and I4 //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: 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_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Invalid comparison between Unknown and I4 //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Invalid comparison between Unknown and I4 //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Invalid comparison between Unknown and I4 //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Invalid comparison between Unknown and I4 //IL_006c: 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_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Invalid comparison between Unknown and I4 //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_008f: 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_0097: Invalid comparison between Unknown and I4 //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) if ((biome & 0x20) > 0) { return (Biome)32; } if ((biome & 0x40) > 0) { return (Biome)64; } if ((biome & 0x200) > 0) { return (Biome)512; } if ((biome & 0x10) > 0) { return (Biome)16; } if ((biome & 4) > 0) { return (Biome)4; } if ((biome & 2) > 0) { return (Biome)2; } if ((biome & 8) > 0) { return (Biome)8; } if ((biome & 1) > 0) { return (Biome)1; } if ((biome & 0x100) > 0) { return (Biome)256; } return biome; } private static string GetShortBiomeName(Biome biome) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Invalid comparison between Unknown and I4 //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Invalid comparison between Unknown and I4 //IL_002d: 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_0035: Invalid comparison between Unknown and I4 //IL_0046: 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_004b: Invalid comparison between Unknown and I4 //IL_005b: 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_005f: Invalid comparison between Unknown and I4 //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Invalid comparison between Unknown and I4 //IL_0083: 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_0087: Invalid comparison between Unknown and I4 //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Invalid comparison between Unknown and I4 //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Invalid comparison between Unknown and I4 if ((biome & 0x20) > 0) { return "Ash"; } if ((biome & 0x40) > 0) { return "Frost"; } if ((biome & 0x200) > 0) { return "Mist"; } if ((biome & 0x10) > 0) { return "Plains"; } if ((biome & 4) > 0) { return "Mountain"; } if ((biome & 2) > 0) { return "Swamp"; } if ((biome & 8) > 0) { return "Forest"; } if ((biome & 1) > 0) { return "Meadow"; } if ((biome & 0x100) > 0) { return "Sea"; } return "Wilds"; } private static Biome GetDominantBiome(Dictionary composition) { //IL_005a: 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) int num = 1; float num2 = 0f; foreach (KeyValuePair item in composition) { if (item.Value > num2) { num2 = item.Value; num = item.Key; } } return (Biome)num; } private static Biome GetSecondaryBiome(Dictionary composition, Biome exclude) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Expected I4, but got Unknown //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Invalid comparison between I4 and Unknown //IL_0067: 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) int num = (int)exclude; float num2 = 0f; foreach (KeyValuePair item in composition) { if (item.Key != (int)exclude && item.Value > num2) { num2 = item.Value; num = item.Key; } } return (Biome)num; } private static float GetBiomePercent(Dictionary composition, Biome biome) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Expected I4, but got Unknown float value; return composition.TryGetValue((int)biome, out value) ? value : 0f; } public static string GetBiomeCompositionDescription(Dictionary composition) { if (composition == null || composition.Count == 0) { return "Unknown terrain"; } List list = new List(); List> list2 = new List>(composition); list2.Sort((KeyValuePair a, KeyValuePair b) => b.Value.CompareTo(a.Value)); foreach (KeyValuePair item in list2) { if (item.Value >= 5f) { string biomeName = BiomeUtils.GetBiomeName((Biome)item.Key); list.Add($"{biomeName} {item.Value:F0}%"); } } return string.Join(", ", list); } } public class VoronoiGrid { private static VoronoiGrid _instance; private static readonly object _lock = new object(); private List _seeds; private Dictionary _quantizedToIndex; private Dictionary> _spatialGrid; private const float SpatialCellSize = 2000f; private Dictionary _regionCache; private const float CacheQuantize = 8f; private float MapRadius = 10500f; private float _spawnProtectionRadius; public static VoronoiGrid Instance { get { if (_instance == null) { lock (_lock) { if (_instance == null) { _instance = new VoronoiGrid(); } } } return _instance; } } public bool IsInitialized { get; private set; } public int SpawnZoneSeedIndex => 0; public int RegionCount { get { EnsureInitialized(); return _seeds.Count; } } public static void Reset() { lock (_lock) { _instance = null; } } private VoronoiGrid() { _seeds = new List(); _quantizedToIndex = new Dictionary(); _spatialGrid = new Dictionary>(); _regionCache = new Dictionary(); IsInitialized = false; } public void Initialize(string worldName) { if (!IsInitialized) { _spawnProtectionRadius = ClanConfig.SpawnProtectionRadius?.Value ?? 2500; MapRadius = 10500f; int num = 180; int num2 = worldName?.GetHashCode() ?? 0; Plugin.Log.LogWarning((object)$"VoronoiGrid: MapRadius={MapRadius}, TerritoryCount={num}, SpawnProtection={_spawnProtectionRadius}, WorldSeed={num2}"); GenerateSeeds(num2, num); BuildSpatialGrid(); BuildQuantizedIndex(); IsInitialized = true; Plugin.Log.LogWarning((object)$"VoronoiGrid initialized with {_seeds.Count} regions for world '{worldName}' (radius={MapRadius})"); } } public void EnsureInitialized() { if (!IsInitialized) { string text = null; if ((Object)(object)ZNet.instance != (Object)null) { text = ZNet.instance.GetWorldName(); } if (string.IsNullOrEmpty(text)) { text = "default_world"; } Initialize(text); } } private void GenerateSeeds(int worldSeed, int targetCount) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0130: Unknown result type (might be due to invalid IL or missing references) //IL_0147: Unknown result type (might be due to invalid IL or missing references) //IL_01a6: Unknown result type (might be due to invalid IL or missing references) //IL_0278: Unknown result type (might be due to invalid IL or missing references) //IL_028f: Unknown result type (might be due to invalid IL or missing references) //IL_02ed: Unknown result type (might be due to invalid IL or missing references) _seeds.Clear(); Random random = new Random(worldSeed); _seeds.Add(new Vector2(0f, 0f)); float num = MapRadius * 2f / Mathf.Sqrt((float)targetCount) * 0.6f; int num2 = targetCount * 80; int num3 = 0; while (_seeds.Count < targetCount && num3 < num2) { num3++; float num4 = (float)(random.NextDouble() * 2.0 * Math.PI); float num5 = (float)Math.Sqrt(random.NextDouble()) * (MapRadius - 200f); float num6 = num5 * Mathf.Cos(num4); float num7 = num5 * Mathf.Sin(num4); if (num6 * num6 + num7 * num7 < _spawnProtectionRadius * _spawnProtectionRadius) { continue; } float num8 = Mathf.Sqrt(num6 * num6 + num7 * num7); float num9 = num8 / MapRadius; float num10 = 0.3f + num9 * 1.5f; float num11 = 0.7f + (float)random.NextDouble() * 0.6f; float num12 = num10 * num11; float num13 = num * num12; bool flag = false; for (int i = 0; i < _seeds.Count; i++) { float num14 = _seeds[i].x - num6; float num15 = _seeds[i].y - num7; if (num14 * num14 + num15 * num15 < num13 * num13) { flag = true; break; } } if (!flag) { _seeds.Add(new Vector2(num6, num7)); } } float num16 = num * 0.4f; float[] array = new float[3] { MapRadius * 0.7f, MapRadius * 0.82f, MapRadius * 0.93f }; int num17 = 45; for (int j = 0; j < array.Length; j++) { float num18 = array[j]; float num19 = (float)j * 0.5f; for (int k = 0; k < num17; k++) { float num20 = ((float)k + num19) / (float)num17 * (float)Math.PI * 2f; float num21 = num18 * Mathf.Cos(num20); float num22 = num18 * Mathf.Sin(num20); bool flag2 = false; for (int l = 0; l < _seeds.Count; l++) { float num23 = _seeds[l].x - num21; float num24 = _seeds[l].y - num22; if (num23 * num23 + num24 * num24 < num16 * num16) { flag2 = true; break; } } if (!flag2) { _seeds.Add(new Vector2(num21, num22)); } } } for (int m = 0; m < 3; m++) { LloydRelaxation(); } Plugin.Log.LogInfo((object)$"Generated {_seeds.Count} Voronoi seeds (target: {targetCount}, attempts: {num3})"); } private void LloydRelaxation() { //IL_01ae: Unknown result type (might be due to invalid IL or missing references) int num = 80; float num2 = MapRadius * 2f / (float)num; float[] array = new float[_seeds.Count]; float[] array2 = new float[_seeds.Count]; int[] array3 = new int[_seeds.Count]; for (int i = 0; i < num; i++) { for (int j = 0; j < num; j++) { float num3 = 0f - MapRadius + ((float)i + 0.5f) * num2; float num4 = 0f - MapRadius + ((float)j + 0.5f) * num2; if (!(num3 * num3 + num4 * num4 > MapRadius * MapRadius)) { int num5 = FindNearestSeedBruteForce(num3, num4); if (num5 >= 0) { array[num5] += num3; array2[num5] += num4; array3[num5]++; } } } } for (int k = 0; k < _seeds.Count; k++) { if (k != SpawnZoneSeedIndex && array3[k] > 0) { float num6 = array[k] / (float)array3[k]; float num7 = array2[k] / (float)array3[k]; if (num6 * num6 + num7 * num7 >= _spawnProtectionRadius * _spawnProtectionRadius && num6 * num6 + num7 * num7 < MapRadius * MapRadius) { _seeds[k] = new Vector2(num6, num7); } } } } private float SmoothNoise(float x, float z, int seed) { int num = Mathf.FloorToInt(x); int num2 = Mathf.FloorToInt(z); float num3 = x - (float)num; float num4 = z - (float)num2; num3 = num3 * num3 * (3f - 2f * num3); num4 = num4 * num4 * (3f - 2f * num4); float num5 = HashFloat(num, num2, seed); float num6 = HashFloat(num + 1, num2, seed); float num7 = HashFloat(num, num2 + 1, seed); float num8 = HashFloat(num + 1, num2 + 1, seed); float num9 = num5 + (num6 - num5) * num3; float num10 = num7 + (num8 - num7) * num3; return num9 + (num10 - num9) * num4; } private float HashFloat(int x, int z, int seed) { int num = x * 374761393 + z * 668265263 + seed * 1274126177; num = (num ^ (num >> 13)) * 1103515245; num ^= num >> 16; return (float)(num & 0x7FFFFFFF) / 2.1474836E+09f; } private float PerturbedDistanceSq(float x, float z, int seedIndex) { //IL_0008: 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) float num = _seeds[seedIndex].x - x; float num2 = _seeds[seedIndex].y - z; float num3 = Mathf.Sqrt(num * num + num2 * num2); float num4 = (float)seedIndex * 73.7f; float num5 = (float)seedIndex * 91.3f; float num6 = 0f; num6 += (Mathf.PerlinNoise((x + num4) * 0.006f, (z + num5) * 0.006f) - 0.5f) * 2f; num6 += (Mathf.PerlinNoise((x + num4) * 0.015f, (z + num5) * 0.015f) - 0.5f) * 1f; num6 += (Mathf.PerlinNoise((x + num4) * 0.03f, (z + num5) * 0.03f) - 0.5f) * 0.5f; num6 += (Mathf.PerlinNoise((x + num4) * 0.06f, (z + num5) * 0.06f) - 0.5f) * 0.25f; float num7 = num3 + num6 * 80f; return num7 * num7; } private int FindNearestSeedBruteForce(float x, float z) { int result = -1; float num = float.MaxValue; for (int i = 0; i < _seeds.Count; i++) { float num2 = PerturbedDistanceSq(x, z, i); if (num2 < num) { num = num2; result = i; } } return result; } private void BuildSpatialGrid() { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) _spatialGrid.Clear(); for (int i = 0; i < _seeds.Count; i++) { long key = SpatialKey(_seeds[i].x, _seeds[i].y); if (!_spatialGrid.TryGetValue(key, out var value)) { value = new List(); _spatialGrid[key] = value; } value.Add(i); } } private long SpatialKey(float x, float z) { int num = Mathf.FloorToInt(x / 2000f); int num2 = Mathf.FloorToInt(z / 2000f); return ((long)num << 32) | (uint)num2; } private void BuildQuantizedIndex() { //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_001a: 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) _quantizedToIndex.Clear(); for (int i = 0; i < _seeds.Count; i++) { Vector2i val = QuantizeSeed(i); long key = ((long)val.x << 32) | (uint)val.y; _quantizedToIndex[key] = i; } } private Vector2i QuantizeSeed(int index) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_000e: 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_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_003c: Unknown result type (might be due to invalid IL or missing references) Vector2 val = _seeds[index]; int num = Mathf.RoundToInt(val.x / 10f); int num2 = Mathf.RoundToInt(val.y / 10f); return new Vector2i(num, num2); } public Vector2i GetRegion(Vector3 worldPos) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0035: 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_0049: 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_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_0081: 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_0086: Unknown result type (might be due to invalid IL or missing references) EnsureInitialized(); long key = CacheKey(worldPos.x, worldPos.z); if (_regionCache.TryGetValue(key, out var value)) { return value; } int index = FindNearestSeed(worldPos.x, worldPos.z); Vector2i val = QuantizeSeed(index); if (_regionCache.Count > 500000) { _regionCache.Clear(); } _regionCache[key] = val; return val; } public Vector3 GetRegionCenter(Vector2i regionId) { //IL_0009: 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_0062: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0074: 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_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0037: 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_0048: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) EnsureInitialized(); int num = RegionIdToIndex(regionId); if (num >= 0 && num < _seeds.Count) { Vector2 val = _seeds[num]; return new Vector3(val.x, 0f, val.y); } return new Vector3((float)regionId.x * 10f, 0f, (float)regionId.y * 10f); } public bool IsSpawnZone(Vector2i regionId) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) int num = RegionIdToIndex(regionId); return num == SpawnZoneSeedIndex; } public string GetRegionKey(Vector2i regionId) { //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) return $"{regionId.x}_{regionId.y}"; } public bool IsOnBorder(Vector3 worldPos, float threshold = 80f) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_009e: 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) EnsureInitialized(); float x = worldPos.x; float z = worldPos.z; int num = -1; int num2 = -1; float num3 = float.MaxValue; float num4 = float.MaxValue; int num5 = Mathf.FloorToInt(x / 2000f); int num6 = Mathf.FloorToInt(z / 2000f); for (int i = -1; i <= 1; i++) { for (int j = -1; j <= 1; j++) { long key = ((long)(num5 + i) << 32) | (uint)(num6 + j); if (!_spatialGrid.TryGetValue(key, out var value)) { continue; } for (int k = 0; k < value.Count; k++) { int num7 = value[k]; float num8 = _seeds[num7].x - x; float num9 = _seeds[num7].y - z; float num10 = num8 * num8 + num9 * num9; if (num10 < num3) { num4 = num3; num2 = num; num3 = num10; num = num7; } else if (num10 < num4) { num4 = num10; num2 = num7; } } } } if (num < 0 || num2 < 0) { return false; } float num11 = Mathf.Sqrt(num3); float num12 = Mathf.Sqrt(num4); return num12 - num11 < threshold; } public float GetApproximateRegionRadius(Vector2i regionId) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0030: 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_005c: 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) //IL_0077: Unknown result type (might be due to invalid IL or missing references) EnsureInitialized(); int num = RegionIdToIndex(regionId); if (num < 0) { return 500f; } Vector2 val = _seeds[num]; float num2 = float.MaxValue; for (int i = 0; i < _seeds.Count; i++) { if (i != num) { float num3 = _seeds[i].x - val.x; float num4 = _seeds[i].y - val.y; float num5 = num3 * num3 + num4 * num4; if (num5 < num2) { num2 = num5; } } } return Mathf.Sqrt(num2) * 0.5f; } public IReadOnlyList GetAllSeeds() { EnsureInitialized(); return _seeds; } public int RegionIdToIndex(Vector2i regionId) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) long key = ((long)regionId.x << 32) | (uint)regionId.y; if (_quantizedToIndex.TryGetValue(key, out var value)) { return value; } return -1; } public Vector2i IndexToRegionId(int index) { //IL_0029: 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_001f: 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) //IL_0031: Unknown result type (might be due to invalid IL or missing references) if (index < 0 || index >= _seeds.Count) { return new Vector2i(0, 0); } return QuantizeSeed(index); } private int FindNearestSeed(float x, float z) { int num = -1; float num2 = float.MaxValue; int num3 = Mathf.FloorToInt(x / 2000f); int num4 = Mathf.FloorToInt(z / 2000f); for (int i = -2; i <= 2; i++) { for (int j = -2; j <= 2; j++) { long key = ((long)(num3 + i) << 32) | (uint)(num4 + j); if (!_spatialGrid.TryGetValue(key, out var value)) { continue; } for (int k = 0; k < value.Count; k++) { int num5 = value[k]; float num6 = PerturbedDistanceSq(x, z, num5); if (num6 < num2) { num2 = num6; num = num5; } } } } if (num < 0) { num = FindNearestSeedBruteForce(x, z); } return num; } private long CacheKey(float x, float z) { int num = Mathf.FloorToInt(x / 8f); int num2 = Mathf.FloorToInt(z / 8f); return ((long)num << 32) | (uint)num2; } } } namespace FortecaClanWarfare.UI { public class ClanNameTagRenderer : MonoBehaviour { private GUIStyle _tagStyle; private GUIStyle _shadowStyle; private bool _styleInit; private const float MaxRenderDistance = 80f; private const float HeadOffsetY = 2.05f; public static ClanNameTagRenderer Instance { get; private set; } private void Awake() { Instance = this; } private void InitStyle() { //IL_001f: 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) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0035: 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_0045: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Expected O, but got Unknown //IL_0059: 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_0078: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Expected O, but got Unknown if (!_styleInit) { _styleInit = true; _tagStyle = new GUIStyle(GUI.skin.label) { fontSize = 13, fontStyle = (FontStyle)1, alignment = (TextAnchor)4, richText = true, wordWrap = false }; GUIStyle val = new GUIStyle(_tagStyle); val.normal.textColor = new Color(0f, 0f, 0f, 0.85f); _shadowStyle = val; } } private void OnGUI() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Invalid comparison between Unknown and I4 //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_016d: Unknown result type (might be due to invalid IL or missing references) //IL_0172: 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_0181: 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_0189: Unknown result type (might be due to invalid IL or missing references) //IL_018b: Unknown result type (might be due to invalid IL or missing references) //IL_0190: Unknown result type (might be due to invalid IL or missing references) //IL_0192: Unknown result type (might be due to invalid IL or missing references) //IL_01b4: Unknown result type (might be due to invalid IL or missing references) //IL_01e0: Unknown result type (might be due to invalid IL or missing references) //IL_01ea: Expected O, but got Unknown //IL_01e5: Unknown result type (might be due to invalid IL or missing references) //IL_01ea: Unknown result type (might be due to invalid IL or missing references) //IL_01ec: Unknown result type (might be due to invalid IL or missing references) //IL_01f3: Unknown result type (might be due to invalid IL or missing references) //IL_0205: Unknown result type (might be due to invalid IL or missing references) //IL_025f: Unknown result type (might be due to invalid IL or missing references) //IL_027a: 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) //IL_0288: Unknown result type (might be due to invalid IL or missing references) //IL_02ab: Unknown result type (might be due to invalid IL or missing references) //IL_02b2: Unknown result type (might be due to invalid IL or missing references) //IL_02b9: Unknown result type (might be due to invalid IL or missing references) //IL_02dc: Unknown result type (might be due to invalid IL or missing references) //IL_02e3: Unknown result type (might be due to invalid IL or missing references) //IL_02ea: Unknown result type (might be due to invalid IL or missing references) //IL_030d: Unknown result type (might be due to invalid IL or missing references) //IL_0314: Unknown result type (might be due to invalid IL or missing references) //IL_031b: Unknown result type (might be due to invalid IL or missing references) //IL_033b: Unknown result type (might be due to invalid IL or missing references) //IL_0347: Unknown result type (might be due to invalid IL or missing references) //IL_0353: Unknown result type (might be due to invalid IL or missing references) //IL_035f: Unknown result type (might be due to invalid IL or missing references) //IL_036e: Unknown result type (might be due to invalid IL or missing references) //IL_0375: Unknown result type (might be due to invalid IL or missing references) //IL_037c: Unknown result type (might be due to invalid IL or missing references) if ((int)Event.current.type != 7 || (Object)(object)Player.m_localPlayer == (Object)null) { return; } Camera main = Camera.main; if ((Object)(object)main == (Object)null) { return; } WarfareData warfareData = WarfareManager.Instance?.Data; if (warfareData == null) { return; } InitStyle(); List allPlayers = Player.GetAllPlayers(); if (allPlayers == null) { return; } Vector3 position = ((Component)Player.m_localPlayer).transform.position; for (int i = 0; i < allPlayers.Count; i++) { Player val = allPlayers[i]; if ((Object)(object)val == (Object)null || (Object)(object)val == (Object)(object)Player.m_localPlayer || ((Character)val).IsDead()) { continue; } float num = Vector3.Distance(((Component)val).transform.position, position); if (num > 80f) { continue; } long playerID = val.GetPlayerID(); if (playerID == 0) { continue; } PlayerClanInfo player = warfareData.GetPlayer(playerID); if (player == null || player.ClanId == 0) { continue; } Clan clan = ClanConfig.GetClan(player.ClanId); if (clan != null) { Vector3 val2 = ((Component)val).transform.position + Vector3.up * 2.05f; Vector3 val3 = main.WorldToScreenPoint(val2); if (!(val3.z <= 0f)) { float num2 = (float)Screen.height - val3.y; string text = clan.Symbol + " " + clan.Name; Vector2 val4 = _tagStyle.CalcSize(new GUIContent(text)); float num3 = val3.x - val4.x / 2f; float num4 = num2 - val4.y - 4f; float num5 = Mathf.Clamp01(1f - num / 80f); num5 = Mathf.Lerp(0.35f, 1f, num5); _shadowStyle.normal.textColor = new Color(0f, 0f, 0f, num5 * 0.85f); GUI.Label(new Rect(num3 + 1f, num4 + 1f, val4.x, val4.y), text, _shadowStyle); GUI.Label(new Rect(num3 - 1f, num4 + 1f, val4.x, val4.y), text, _shadowStyle); GUI.Label(new Rect(num3 + 1f, num4 - 1f, val4.x, val4.y), text, _shadowStyle); GUI.Label(new Rect(num3 - 1f, num4 - 1f, val4.x, val4.y), text, _shadowStyle); _tagStyle.normal.textColor = new Color(clan.Color.r, clan.Color.g, clan.Color.b, num5); GUI.Label(new Rect(num3, num4, val4.x, val4.y), text, _tagStyle); } } } } } public class ClanSelectionUI : MonoBehaviour { private enum Mode { Browse, Create, Role } private Mode _mode = Mode.Browse; private string _createName = ""; private string _createTag = ""; private int _colorIndex; private int _iconIndex; private Vector2 _browseScroll; private Vector2 _roleScroll; private bool _stylesInit; private GUIStyle _titleStyle; private GUIStyle _subtitleStyle; private GUIStyle _bodyStyle; private GUIStyle _cardStyle; private GUIStyle _cardHoverStyle; private GUIStyle _btnStyle; private GUIStyle _fieldStyle; private GUIStyle _roleNameStyle; private Texture2D _backdropTex; private Texture2D _panelTex; private Texture2D _cardTex; private Texture2D _cardHoverTex; private Texture2D _pixelTex; private Texture2D _fieldTex; private static readonly (ClanRole role, string title, string norse, string lore, string perks)[] RoleEntries = new(ClanRole, string, string, string, string)[5] { (ClanRole.Explorer, "EXPLORER", "Útsýn — \"Far-Seer\"", "Raven-followers who roam past the last hearth-fire to claim untamed land for their jarl.", "Only role that can claim unclaimed territory. +stats in the wild."), (ClanRole.Invader, "INVADER", "Berserkr — \"Bear-Shirt\"", "Mead-drunk frenzy-warriors who break enemy halls and crack their vaults.", "2x loot from enemy land. Cracks enemy vaults."), (ClanRole.Gatherer, "GATHERER", "Vegfarandi — \"Wayfarer\"", "Silent road-walkers who reap from rival fields and return heavy of pack.", "2x resources from enemy land. +500 carry weight."), (ClanRole.Guardian, "GUARDIAN", "Hirðmaðr — \"Hearth-Guard\"", "Oath-sworn shield-wall whose roots drink deep of clan soil.", "+stats & -50% build cost at home. Holds the line."), (ClanRole.Parasite, "PARASITE", "Draugr — \"The Restless\"", "Undead leeches who raise rot totems to wither a rival's land.", "Raises rot totems on enemy land. -50% enemy crafting cost.") }; public static ClanSelectionUI Instance { get; private set; } public static bool IsOpen { get; private set; } private static float UIScale => (float)Screen.height / 1080f; public static bool ShouldBlockInput() { return IsOpen; } private void Awake() { Instance = this; } private void Update() { if ((Object)(object)Player.m_localPlayer == (Object)null || (Object)(object)Game.instance == (Object)null || (Object)(object)ZNet.instance == (Object)null) { IsOpen = false; _mode = Mode.Browse; return; } WarfareData warfareData = WarfareManager.Instance?.Data; if (warfareData == null) { IsOpen = false; return; } PlayerClanInfo player = warfareData.GetPlayer(Player.m_localPlayer.GetPlayerID()); if (player == null || player.ClanId == 0) { IsOpen = true; if (_mode == Mode.Role) { _mode = Mode.Browse; } } else if (player.Role == ClanRole.None) { IsOpen = true; _mode = Mode.Role; } else { IsOpen = false; } if (IsOpen) { Cursor.lockState = (CursorLockMode)0; Cursor.visible = true; } } private Texture2D MakeTex(Color c) { //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_0012: Expected O, but got Unknown //IL_0015: Unknown result type (might be due to invalid IL or missing references) Texture2D val = new Texture2D(1, 1) { hideFlags = (HideFlags)61 }; val.SetPixel(0, 0, c); val.Apply(); return val; } private Texture2D MakeGradientTex(int w, int h, Color top, Color bottom) { //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_0011: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Expected O, but got Unknown //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0021: 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_0034: Unknown result type (might be due to invalid IL or missing references) Texture2D val = new Texture2D(w, h) { hideFlags = (HideFlags)61, wrapMode = (TextureWrapMode)1 }; for (int i = 0; i < h; i++) { Color val2 = Color.Lerp(bottom, top, (float)i / (float)h); for (int j = 0; j < w; j++) { val.SetPixel(j, i, val2); } } val.Apply(); return val; } private void InitStyles() { //IL_0019: 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_0067: 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_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Unknown result type (might be due to invalid IL or missing references) //IL_0129: Unknown result type (might be due to invalid IL or missing references) //IL_0185: 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_0193: 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) //IL_01a3: Unknown result type (might be due to invalid IL or missing references) //IL_01b0: Expected O, but got Unknown //IL_01bb: 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_01db: Unknown result type (might be due to invalid IL or missing references) //IL_01e3: 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_01f8: Expected O, but got Unknown //IL_0203: Unknown result type (might be due to invalid IL or missing references) //IL_0215: Unknown result type (might be due to invalid IL or missing references) //IL_021a: Unknown result type (might be due to invalid IL or missing references) //IL_0223: Unknown result type (might be due to invalid IL or missing references) //IL_022b: Unknown result type (might be due to invalid IL or missing references) //IL_0238: Expected O, but got Unknown //IL_0243: Unknown result type (might be due to invalid IL or missing references) //IL_0255: Unknown result type (might be due to invalid IL or missing references) //IL_025a: Unknown result type (might be due to invalid IL or missing references) //IL_026c: Unknown result type (might be due to invalid IL or missing references) //IL_0271: Unknown result type (might be due to invalid IL or missing references) //IL_027b: Expected O, but got Unknown //IL_027c: Unknown result type (might be due to invalid IL or missing references) //IL_0285: Unknown result type (might be due to invalid IL or missing references) //IL_028f: Expected O, but got Unknown //IL_0290: Unknown result type (might be due to invalid IL or missing references) //IL_0295: Unknown result type (might be due to invalid IL or missing references) //IL_029f: Expected O, but got Unknown //IL_02a5: Expected O, but got Unknown //IL_02ac: Unknown result type (might be due to invalid IL or missing references) //IL_02b1: Unknown result type (might be due to invalid IL or missing references) //IL_02c8: Expected O, but got Unknown //IL_02d3: Unknown result type (might be due to invalid IL or missing references) //IL_02d8: Unknown result type (might be due to invalid IL or missing references) //IL_02e1: Unknown result type (might be due to invalid IL or missing references) //IL_02e9: Unknown result type (might be due to invalid IL or missing references) //IL_02f0: Unknown result type (might be due to invalid IL or missing references) //IL_02fa: Expected O, but got Unknown //IL_0300: Expected O, but got Unknown //IL_0350: Unknown result type (might be due to invalid IL or missing references) //IL_0362: Unknown result type (might be due to invalid IL or missing references) //IL_0378: Unknown result type (might be due to invalid IL or missing references) //IL_037d: Unknown result type (might be due to invalid IL or missing references) //IL_0386: Unknown result type (might be due to invalid IL or missing references) //IL_038b: Unknown result type (might be due to invalid IL or missing references) //IL_0395: Expected O, but got Unknown //IL_039b: Expected O, but got Unknown //IL_03bd: Unknown result type (might be due to invalid IL or missing references) //IL_03d3: Unknown result type (might be due to invalid IL or missing references) //IL_03d8: Unknown result type (might be due to invalid IL or missing references) //IL_03e1: Unknown result type (might be due to invalid IL or missing references) //IL_03e9: Unknown result type (might be due to invalid IL or missing references) //IL_03f6: Expected O, but got Unknown //IL_0401: Unknown result type (might be due to invalid IL or missing references) if (!_stylesInit) { _stylesInit = true; _pixelTex = MakeTex(Color.white); _backdropTex = MakeTex(new Color(0f, 0f, 0f, 0.8f)); _panelTex = MakeGradientTex(48, 48, new Color(0.09f, 0.07f, 0.045f, 0.98f), new Color(0.05f, 0.04f, 0.025f, 0.99f)); _cardTex = MakeGradientTex(32, 32, new Color(0.16f, 0.12f, 0.07f, 0.96f), new Color(0.1f, 0.08f, 0.04f, 0.97f)); _cardHoverTex = MakeGradientTex(32, 32, new Color(0.26f, 0.19f, 0.09f, 0.97f), new Color(0.16f, 0.12f, 0.05f, 0.98f)); _fieldTex = MakeTex(new Color(0.03f, 0.025f, 0.018f, 1f)); Color textColor = default(Color); ((Color)(ref textColor))..ctor(0.96f, 0.83f, 0.38f); Color textColor2 = default(Color); ((Color)(ref textColor2))..ctor(0.86f, 0.8f, 0.66f); Color textColor3 = default(Color); ((Color)(ref textColor3))..ctor(0.74f, 0.68f, 0.55f); _titleStyle = new GUIStyle(GUI.skin.label) { fontSize = 26, fontStyle = (FontStyle)1, alignment = (TextAnchor)4, richText = true }; _titleStyle.normal.textColor = textColor; _subtitleStyle = new GUIStyle(GUI.skin.label) { fontSize = 13, fontStyle = (FontStyle)2, alignment = (TextAnchor)4, richText = true }; _subtitleStyle.normal.textColor = textColor3; _bodyStyle = new GUIStyle(GUI.skin.label) { fontSize = 13, richText = true, wordWrap = true }; _bodyStyle.normal.textColor = textColor2; GUIStyle val = new GUIStyle(GUI.skin.box); val.normal.background = _cardTex; val.border = new RectOffset(6, 6, 6, 6); val.padding = new RectOffset(12, 12, 10, 10); val.margin = new RectOffset(4, 4, 4, 4); _cardStyle = val; GUIStyle val2 = new GUIStyle(_cardStyle); val2.normal.background = _cardHoverTex; _cardHoverStyle = val2; _btnStyle = new GUIStyle(GUI.skin.button) { fontSize = 14, fontStyle = (FontStyle)1, padding = new RectOffset(14, 14, 8, 8) }; _btnStyle.normal.background = _cardTex; _btnStyle.hover.background = _cardHoverTex; _btnStyle.active.background = _cardHoverTex; _btnStyle.normal.textColor = textColor; _btnStyle.hover.textColor = Color.white; _fieldStyle = new GUIStyle(GUI.skin.textField) { fontSize = 16, padding = new RectOffset(8, 8, 6, 6) }; _fieldStyle.normal.background = _fieldTex; _fieldStyle.normal.textColor = Color.white; _roleNameStyle = new GUIStyle(GUI.skin.label) { fontSize = 16, fontStyle = (FontStyle)1, richText = true }; _roleNameStyle.normal.textColor = textColor; } } private void OnGUI() { //IL_0021: 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_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_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_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0071: 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) if (IsOpen) { InitStyles(); float uIScale = UIScale; Matrix4x4 matrix = GUI.matrix; GUI.matrix = Matrix4x4.TRS(Vector3.zero, Quaternion.identity, new Vector3(uIScale, uIScale, 1f)); float num = (float)Screen.width / uIScale; float num2 = (float)Screen.height / uIScale; GUI.color = Color.white; GUI.DrawTexture(new Rect(0f, 0f, num, num2), (Texture)(object)_backdropTex); switch (_mode) { case Mode.Browse: DrawBrowse(num, num2); break; case Mode.Create: DrawCreate(num, num2); break; case Mode.Role: DrawRole(num, num2); break; } GUI.matrix = matrix; } } private void DrawPanel(Rect r) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0022: 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_0078: 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_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Unknown result type (might be due to invalid IL or missing references) GUI.DrawTexture(r, (Texture)(object)_panelTex); GUI.color = new Color(0.65f, 0.5f, 0.2f, 0.85f); GUI.DrawTexture(new Rect(((Rect)(ref r)).x, ((Rect)(ref r)).y, ((Rect)(ref r)).width, 2f), (Texture)(object)_pixelTex); GUI.DrawTexture(new Rect(((Rect)(ref r)).x, ((Rect)(ref r)).yMax - 2f, ((Rect)(ref r)).width, 2f), (Texture)(object)_pixelTex); GUI.DrawTexture(new Rect(((Rect)(ref r)).x, ((Rect)(ref r)).y, 2f, ((Rect)(ref r)).height), (Texture)(object)_pixelTex); GUI.DrawTexture(new Rect(((Rect)(ref r)).xMax - 2f, ((Rect)(ref r)).y, 2f, ((Rect)(ref r)).height), (Texture)(object)_pixelTex); GUI.color = Color.white; } private void DrawBrowse(float refW, float refH) { //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_005c: 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_0154: 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_015c: Unknown result type (might be due to invalid IL or missing references) //IL_015e: 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_018e: Unknown result type (might be due to invalid IL or missing references) //IL_01e0: Unknown result type (might be due to invalid IL or missing references) //IL_01ec: Unknown result type (might be due to invalid IL or missing references) //IL_045f: Unknown result type (might be due to invalid IL or missing references) //IL_0208: 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_023e: Unknown result type (might be due to invalid IL or missing references) //IL_024f: Unknown result type (might be due to invalid IL or missing references) //IL_0254: Unknown result type (might be due to invalid IL or missing references) //IL_025f: Expected O, but got Unknown //IL_0268: Unknown result type (might be due to invalid IL or missing references) //IL_0297: Unknown result type (might be due to invalid IL or missing references) //IL_02b6: Unknown result type (might be due to invalid IL or missing references) //IL_02bb: Unknown result type (might be due to invalid IL or missing references) //IL_02c6: Expected O, but got Unknown //IL_02cf: Unknown result type (might be due to invalid IL or missing references) //IL_0306: 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_03da: Unknown result type (might be due to invalid IL or missing references) float num = 720f; float num2 = Mathf.Min(refH - 60f, 640f); Rect r = default(Rect); ((Rect)(ref r))..ctor((refW - num) / 2f, (refH - num2) / 2f, num, num2); DrawPanel(r); GUI.Label(new Rect(((Rect)(ref r)).x, ((Rect)(ref r)).y + 18f, ((Rect)(ref r)).width, 36f), "CHOOSE YOUR CLAN", _titleStyle); GUI.Label(new Rect(((Rect)(ref r)).x, ((Rect)(ref r)).y + 56f, ((Rect)(ref r)).width, 20f), "Join a clan that already stands, or found your own.", _subtitleStyle); WarfareData warfareData = WarfareManager.Instance?.Data; List list = ((warfareData != null) ? new List(warfareData.Clans.Values) : new List()); Rect val = default(Rect); ((Rect)(ref val))..ctor(((Rect)(ref r)).x + 24f, ((Rect)(ref r)).y + 90f, ((Rect)(ref r)).width - 48f, ((Rect)(ref r)).height - 170f); float num3 = 64f; Rect val2 = default(Rect); ((Rect)(ref val2))..ctor(0f, 0f, ((Rect)(ref val)).width - 20f, Mathf.Max(((Rect)(ref val)).height, (float)list.Count * (num3 + 6f))); _browseScroll = GUI.BeginScrollView(val, _browseScroll, val2); if (list.Count == 0) { GUI.Label(new Rect(0f, 10f, ((Rect)(ref val2)).width, 30f), "No clans exist yet — be the first to found one!", _subtitleStyle); } Rect val3 = default(Rect); Rect val6 = default(Rect); for (int i = 0; i < list.Count; i++) { Clan clan = list[i]; ((Rect)(ref val3))..ctor(0f, (float)i * (num3 + 6f), ((Rect)(ref val2)).width, num3); bool flag = ((Rect)(ref val3)).Contains(Event.current.mousePosition); GUI.DrawTexture(val3, (Texture)(object)(flag ? _cardHoverTex : _cardTex)); GUI.color = clan.Color; GUI.DrawTexture(new Rect(((Rect)(ref val3)).x, ((Rect)(ref val3)).y, 5f, ((Rect)(ref val3)).height), (Texture)(object)_pixelTex); GUI.color = Color.white; GUIStyle val4 = new GUIStyle(_titleStyle) { fontSize = 30 }; val4.normal.textColor = clan.Color; GUI.Label(new Rect(((Rect)(ref val3)).x + 14f, ((Rect)(ref val3)).y + 14f, 44f, 40f), ClanConfig.GetIcon(clan.IconIndex), val4); GUIStyle val5 = new GUIStyle(_roleNameStyle) { fontSize = 17 }; val5.normal.textColor = clan.Color; GUI.Label(new Rect(((Rect)(ref val3)).x + 66f, ((Rect)(ref val3)).y + 8f, ((Rect)(ref val3)).width - 200f, 24f), clan.Name + " [" + clan.Tag + "]", val5); int clanMemberCount = warfareData.GetClanMemberCount(clan.ClanId); int clanTerritoryCount = warfareData.GetClanTerritoryCount(clan.ClanId); GUI.Label(new Rect(((Rect)(ref val3)).x + 66f, ((Rect)(ref val3)).y + 32f, ((Rect)(ref val3)).width - 200f, 22f), $"{clanMemberCount} members {clanTerritoryCount} territories {clan.Treasury} coins", _bodyStyle); ((Rect)(ref val6))..ctor(((Rect)(ref val3)).xMax - 110f, ((Rect)(ref val3)).y + 16f, 96f, 32f); if (GUI.Button(val6, "Join", _btnStyle)) { WarfareRPC.Instance?.RequestJoinClan(clan.ClanId); } } GUI.EndScrollView(); if (GUI.Button(new Rect(((Rect)(ref r)).x + ((Rect)(ref r)).width / 2f - 140f, ((Rect)(ref r)).yMax - 64f, 280f, 40f), "⚒ Found a New Clan", _btnStyle)) { _mode = Mode.Create; _createName = ""; _createTag = ""; } } private void DrawCreate(float refW, float refH) { //IL_0029: 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_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: 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_0127: 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_01c2: 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_01db: Unknown result type (might be due to invalid IL or missing references) //IL_02ef: Unknown result type (might be due to invalid IL or missing references) //IL_028a: 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_0231: Unknown result type (might be due to invalid IL or missing references) //IL_0268: Unknown result type (might be due to invalid IL or missing references) //IL_0279: Unknown result type (might be due to invalid IL or missing references) //IL_0298: Unknown result type (might be due to invalid IL or missing references) //IL_0342: Unknown result type (might be due to invalid IL or missing references) //IL_0424: Unknown result type (might be due to invalid IL or missing references) //IL_0429: Unknown result type (might be due to invalid IL or missing references) //IL_0431: Unknown result type (might be due to invalid IL or missing references) //IL_043c: Expected O, but got Unknown //IL_0449: Unknown result type (might be due to invalid IL or missing references) //IL_0362: Unknown result type (might be due to invalid IL or missing references) //IL_0367: Unknown result type (might be due to invalid IL or missing references) //IL_036f: Unknown result type (might be due to invalid IL or missing references) //IL_037a: Expected O, but got Unknown //IL_03a1: Unknown result type (might be due to invalid IL or missing references) //IL_0394: Unknown result type (might be due to invalid IL or missing references) //IL_03ac: Unknown result type (might be due to invalid IL or missing references) //IL_03c3: Unknown result type (might be due to invalid IL or missing references) //IL_0496: Unknown result type (might be due to invalid IL or missing references) //IL_0510: Unknown result type (might be due to invalid IL or missing references) //IL_03d1: Unknown result type (might be due to invalid IL or missing references) //IL_0564: Unknown result type (might be due to invalid IL or missing references) float num = 660f; float num2 = 560f; Rect r = default(Rect); ((Rect)(ref r))..ctor((refW - num) / 2f, (refH - num2) / 2f, num, num2); DrawPanel(r); GUI.Label(new Rect(((Rect)(ref r)).x, ((Rect)(ref r)).y + 18f, ((Rect)(ref r)).width, 36f), "FOUND A CLAN", _titleStyle); float num3 = ((Rect)(ref r)).x + 40f; float num4 = ((Rect)(ref r)).width - 80f; float num5 = ((Rect)(ref r)).y + 70f; GUI.Label(new Rect(num3, num5, num4, 20f), "Clan name (3-24 characters)", _bodyStyle); _createName = GUI.TextField(new Rect(num3, num5 + 22f, num4, 32f), _createName ?? "", 24, _fieldStyle); num5 += 66f; GUI.Label(new Rect(num3, num5, num4, 20f), "Clan tag (1-6 characters)", _bodyStyle); _createTag = GUI.TextField(new Rect(num3, num5 + 22f, 160f, 32f), _createTag ?? "", 6, _fieldStyle); num5 += 66f; GUI.Label(new Rect(num3, num5, num4, 20f), "Banner colour", _bodyStyle); num5 += 24f; int num6 = 12; float num7 = (num4 - (float)((num6 - 1) * 6)) / (float)num6; Rect val = default(Rect); for (int i = 0; i < ClanConfig.ClanColors.Length; i++) { ((Rect)(ref val))..ctor(num3 + (float)i * (num7 + 6f), num5, num7, 28f); GUI.color = ClanConfig.ClanColors[i]; GUI.DrawTexture(val, (Texture)(object)_pixelTex); GUI.color = Color.white; if (i == _colorIndex) { GUI.color = Color.white; GUI.DrawTexture(new Rect(((Rect)(ref val)).x - 2f, ((Rect)(ref val)).y - 2f, ((Rect)(ref val)).width + 4f, 2f), (Texture)(object)_pixelTex); GUI.DrawTexture(new Rect(((Rect)(ref val)).x - 2f, ((Rect)(ref val)).yMax, ((Rect)(ref val)).width + 4f, 2f), (Texture)(object)_pixelTex); GUI.color = Color.white; } if ((int)Event.current.type == 0 && ((Rect)(ref val)).Contains(Event.current.mousePosition)) { _colorIndex = i; Event.current.Use(); } } num5 += 48f; GUI.Label(new Rect(num3, num5, num4, 20f), "Clan emblem", _bodyStyle); num5 += 24f; Rect val2 = default(Rect); for (int j = 0; j < ClanConfig.ClanIcons.Length; j++) { ((Rect)(ref val2))..ctor(num3 + (float)j * (num7 + 6f), num5, num7, 34f); bool flag = j == _iconIndex; GUI.DrawTexture(val2, (Texture)(object)(flag ? _cardHoverTex : _cardTex)); GUIStyle val3 = new GUIStyle(_roleNameStyle) { alignment = (TextAnchor)4, fontSize = 20 }; val3.normal.textColor = (Color)(flag ? ClanConfig.GetColor(_colorIndex) : new Color(0.8f, 0.75f, 0.6f)); GUI.Label(val2, ClanConfig.ClanIcons[j], val3); if ((int)Event.current.type == 0 && ((Rect)(ref val2)).Contains(Event.current.mousePosition)) { _iconIndex = j; Event.current.Use(); } } num5 += 56f; GUIStyle val4 = new GUIStyle(_roleNameStyle) { alignment = (TextAnchor)4, fontSize = 22 }; val4.normal.textColor = ClanConfig.GetColor(_colorIndex); string text = (string.IsNullOrEmpty(_createName) ? "Your Clan" : _createName); string text2 = (string.IsNullOrEmpty(_createTag) ? "TAG" : _createTag); GUI.Label(new Rect(num3, num5, num4, 30f), ClanConfig.GetIcon(_iconIndex) + " " + text + " [" + text2 + "]", val4); if (GUI.Button(new Rect(((Rect)(ref r)).x + ((Rect)(ref r)).width / 2f - 200f, ((Rect)(ref r)).yMax - 56f, 190f, 38f), "Back", _btnStyle)) { _mode = Mode.Browse; } if (GUI.Button(new Rect(((Rect)(ref r)).x + ((Rect)(ref r)).width / 2f + 10f, ((Rect)(ref r)).yMax - 56f, 190f, 38f), "Found Clan", _btnStyle)) { WarfareRPC.Instance?.RequestCreateClan(_createName, _createTag, _colorIndex, _iconIndex); } } private void DrawRole(float refW, float refH) { //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_01d1: 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_01d9: Unknown result type (might be due to invalid IL or missing references) //IL_01db: Unknown result type (might be due to invalid IL or missing references) //IL_01e0: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: 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_00d7: Expected O, but got Unknown //IL_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_010b: Unknown result type (might be due to invalid IL or missing references) //IL_0224: Unknown result type (might be due to invalid IL or missing references) //IL_0230: Unknown result type (might be due to invalid IL or missing references) //IL_02c6: 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_02e9: Unknown result type (might be due to invalid IL or missing references) //IL_02f1: Unknown result type (might be due to invalid IL or missing references) //IL_02fc: Expected O, but got Unknown //IL_0328: Unknown result type (might be due to invalid IL or missing references) //IL_0351: Unknown result type (might be due to invalid IL or missing references) //IL_0356: Unknown result type (might be due to invalid IL or missing references) //IL_0360: Expected O, but got Unknown //IL_038c: Unknown result type (might be due to invalid IL or missing references) //IL_03a6: Unknown result type (might be due to invalid IL or missing references) //IL_03ab: Unknown result type (might be due to invalid IL or missing references) //IL_03b6: Expected O, but got Unknown //IL_03cc: Unknown result type (might be due to invalid IL or missing references) //IL_0406: Unknown result type (might be due to invalid IL or missing references) //IL_0429: Unknown result type (might be due to invalid IL or missing references) //IL_0258: Unknown result type (might be due to invalid IL or missing references) //IL_027d: Unknown result type (might be due to invalid IL or missing references) //IL_028e: Unknown result type (might be due to invalid IL or missing references) //IL_0437: Unknown result type (might be due to invalid IL or missing references) float num = 760f; float num2 = Mathf.Min(refH - 80f, 720f); Rect r = default(Rect); ((Rect)(ref r))..ctor((refW - num) / 2f, (refH - num2) / 2f, num, num2); DrawPanel(r); GUI.Label(new Rect(((Rect)(ref r)).x, ((Rect)(ref r)).y + 18f, ((Rect)(ref r)).width, 36f), "CHOOSE YOUR ROLE", _titleStyle); WarfareData warfareData = WarfareManager.Instance?.Data; PlayerClanInfo playerClanInfo = warfareData?.GetPlayer(Player.m_localPlayer.GetPlayerID()); Clan clan = ((playerClanInfo != null) ? warfareData.GetClan(playerClanInfo.ClanId) : null); if (clan != null) { GUIStyle val = new GUIStyle(_subtitleStyle) { fontSize = 14 }; val.normal.textColor = clan.Color; GUI.Label(new Rect(((Rect)(ref r)).x, ((Rect)(ref r)).y + 54f, ((Rect)(ref r)).width, 22f), ClanConfig.GetIcon(clan.IconIndex) + " " + clan.Name + " [" + clan.Tag + "]", val); } Rect val2 = default(Rect); ((Rect)(ref val2))..ctor(((Rect)(ref r)).x + 28f, ((Rect)(ref r)).y + 86f, ((Rect)(ref r)).width - 56f, ((Rect)(ref r)).height - 110f); float num3 = 110f; Rect val3 = default(Rect); ((Rect)(ref val3))..ctor(0f, 0f, ((Rect)(ref val2)).width - 20f, (float)RoleEntries.Length * (num3 + 8f)); _roleScroll = GUI.BeginScrollView(val2, _roleScroll, val3); Rect val4 = default(Rect); for (int i = 0; i < RoleEntries.Length; i++) { (ClanRole, string, string, string, string) tuple = RoleEntries[i]; ((Rect)(ref val4))..ctor(0f, (float)i * (num3 + 8f), ((Rect)(ref val3)).width, num3); bool flag = ((Rect)(ref val4)).Contains(Event.current.mousePosition); GUI.DrawTexture(val4, (Texture)(object)(flag ? _cardHoverTex : _cardTex)); if (clan != null) { GUI.color = clan.Color; GUI.DrawTexture(new Rect(((Rect)(ref val4)).x, ((Rect)(ref val4)).y, 5f, ((Rect)(ref val4)).height), (Texture)(object)_pixelTex); GUI.color = Color.white; } GUI.Label(new Rect(((Rect)(ref val4)).x + 18f, ((Rect)(ref val4)).y + 10f, ((Rect)(ref val4)).width - 36f, 24f), tuple.Item2, _roleNameStyle); GUIStyle val5 = new GUIStyle(_subtitleStyle) { alignment = (TextAnchor)3, fontSize = 12 }; GUI.Label(new Rect(((Rect)(ref val4)).x + 18f, ((Rect)(ref val4)).y + 34f, ((Rect)(ref val4)).width - 36f, 18f), "" + tuple.Item3 + "", val5); GUIStyle val6 = new GUIStyle(_bodyStyle) { fontStyle = (FontStyle)2 }; GUI.Label(new Rect(((Rect)(ref val4)).x + 18f, ((Rect)(ref val4)).y + 52f, ((Rect)(ref val4)).width - 36f, 36f), tuple.Item4, val6); GUIStyle val7 = new GUIStyle(_bodyStyle) { fontSize = 11 }; val7.normal.textColor = new Color(0.85f, 0.72f, 0.35f); GUI.Label(new Rect(((Rect)(ref val4)).x + 18f, ((Rect)(ref val4)).y + num3 - 24f, ((Rect)(ref val4)).width - 36f, 20f), "⚔ " + tuple.Item5, val7); if ((int)Event.current.type == 0 && ((Rect)(ref val4)).Contains(Event.current.mousePosition)) { WarfareRPC.Instance?.RequestSetRole(tuple.Item1); Event.current.Use(); } } GUI.EndScrollView(); } } public class MapGridOverlay : MonoBehaviour { private Vector2i? _selectedCell = null; private bool _showClaimPanel = false; private Texture2D _pixelTex; private GUIStyle _panelStyle; private GUIStyle _headerStyle; private GUIStyle _labelStyle; private GUIStyle _buttonStyle; private GUIStyle _closeButtonStyle; private GUIStyle _tooltipTitleStyle; private GUIStyle _tooltipDetailStyle; private bool _stylesInit = false; private Vector2 _mouseDownPos; private bool _isDragging; private int _closeCooldown = 0; private Vector2i? _cachedHighlightRegion = null; private Texture2D _highlightTex = null; private Rect _highlightWorldBounds; private float _lastZoom = -1f; private Vector2i? _stableHoveredCell = null; private int _hoverStableFrames = 0; private int _frameSkip = 0; private Vector2i? _lastLookupResult = null; private Dictionary> _claimedBorderCache = new Dictionary>(); private Dictionary> _claimedScreenCache = new Dictionary>(); private float _claimedPanX = float.MinValue; private float _claimedPanY = float.MinValue; private float _claimedZoom = float.MinValue; private int _claimedTerritoryCount = -1; private float _nextClaimedRebuild = 0f; private GUIStyle _territoryLabelStyle; private List _cachedScreenPoints = new List(); private float _lastMapPanX = float.MinValue; private float _lastMapPanY = float.MinValue; private float _lastMapZoom2 = float.MinValue; private List _cachedBorderWorldPoints = new List(); public static MapGridOverlay Instance { get; private set; } private float WorldRadius => 10500f; private void Awake() { if ((Object)(object)Instance != (Object)null && (Object)(object)Instance != (Object)(object)this) { Object.Destroy((Object)(object)this); return; } Instance = this; Plugin.Log.LogInfo((object)"Map overlay initialized (Voronoi mode)"); } private void Update() { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Invalid comparison between Unknown and I4 //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)Minimap.instance == (Object)null || (int)Minimap.instance.m_mode != 2) { _showClaimPanel = false; _selectedCell = null; _isDragging = false; return; } if (_closeCooldown > 0) { _closeCooldown--; } if (Input.GetMouseButtonDown(0)) { _mouseDownPos = Vector2.op_Implicit(Input.mousePosition); _isDragging = false; } if (Input.GetMouseButton(0) && Vector2.Distance(_mouseDownPos, Vector2.op_Implicit(Input.mousePosition)) > 10f) { _isDragging = true; } if (!_isDragging && Input.GetMouseButtonUp(0) && _closeCooldown == 0) { Vector2i? cellUnderMouse = GetCellUnderMouse(); if (cellUnderMouse.HasValue) { _selectedCell = cellUnderMouse; _showClaimPanel = true; } } } private void ClosePanel() { _showClaimPanel = false; _selectedCell = null; _closeCooldown = 10; } private Vector2 WorldToMapPoint(Vector3 worldPos) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0045: 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) float num = Minimap.instance.m_textureSize; float pixelSize = Minimap.instance.m_pixelSize; float num2 = (worldPos.x / pixelSize + num / 2f) / num; float num3 = (worldPos.z / pixelSize + num / 2f) / num; return new Vector2(num2, num3); } private Vector3 MapPointToWorld(Vector2 mapPoint) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //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_004e: Unknown result type (might be due to invalid IL or missing references) float num = Minimap.instance.m_textureSize; float pixelSize = Minimap.instance.m_pixelSize; float num2 = (mapPoint.x * num - num / 2f) * pixelSize; float num3 = (mapPoint.y * num - num / 2f) * pixelSize; return new Vector3(num2, 0f, num3); } private Vector2? WorldToScreenGUI(float worldX, float worldZ) { //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0059: 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_006d: 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_013a: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)Minimap.instance == (Object)null) { return null; } RawImage mapImageLarge = Minimap.instance.m_mapImageLarge; if ((Object)(object)mapImageLarge == (Object)null) { return null; } RectTransform component = ((Component)mapImageLarge).GetComponent(); Rect uvRect = mapImageLarge.uvRect; Vector2 val = WorldToMapPoint(new Vector3(worldX, 0f, worldZ)); float num = (val.x - ((Rect)(ref uvRect)).x) / ((Rect)(ref uvRect)).width; float num2 = (val.y - ((Rect)(ref uvRect)).y) / ((Rect)(ref uvRect)).height; if (num < -0.1f || num > 1.1f || num2 < -0.1f || num2 > 1.1f) { return null; } Vector3[] array = (Vector3[])(object)new Vector3[4]; component.GetWorldCorners(array); float num3 = Mathf.Lerp(array[0].x, array[2].x, num); float num4 = Mathf.Lerp(array[0].y, array[2].y, num2); return new Vector2(num3, (float)Screen.height - num4); } private Vector3? ScreenGUIToWorld(Vector2 guiPos) { //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0059: 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_0067: Unknown result type (might be due to invalid IL or missing references) //IL_0165: 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) if ((Object)(object)Minimap.instance == (Object)null) { return null; } RawImage mapImageLarge = Minimap.instance.m_mapImageLarge; if ((Object)(object)mapImageLarge == (Object)null) { return null; } RectTransform component = ((Component)mapImageLarge).GetComponent(); Rect uvRect = mapImageLarge.uvRect; float x = guiPos.x; float num = (float)Screen.height - guiPos.y; Vector3[] array = (Vector3[])(object)new Vector3[4]; component.GetWorldCorners(array); if (x < array[0].x || x > array[2].x || num < array[0].y || num > array[2].y) { return null; } float num2 = (x - array[0].x) / (array[2].x - array[0].x); float num3 = (num - array[0].y) / (array[2].y - array[0].y); float num4 = ((Rect)(ref uvRect)).x + num2 * ((Rect)(ref uvRect)).width; float num5 = ((Rect)(ref uvRect)).y + num3 * ((Rect)(ref uvRect)).height; return MapPointToWorld(new Vector2(num4, num5)); } private Vector2i WorldToGridCell(Vector3 worldPos) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) return VoronoiGrid.Instance.GetRegion(worldPos); } private Vector2i? GetCellUnderMouse() { //IL_0003: 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_0024: 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_0055: 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_006e: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: 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) Vector2 guiPos = default(Vector2); ((Vector2)(ref guiPos))..ctor(Input.mousePosition.x, (float)Screen.height - Input.mousePosition.y); Vector3? val = ScreenGUIToWorld(guiPos); if (!val.HasValue) { return null; } float num = Mathf.Sqrt(val.Value.x * val.Value.x + val.Value.z * val.Value.z); if (num > WorldRadius) { return null; } return WorldToGridCell(val.Value); } private void OnGUI() { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Invalid comparison between Unknown and I4 //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_020b: Unknown result type (might be due to invalid IL or missing references) //IL_0125: Unknown result type (might be due to invalid IL or missing references) //IL_011c: Unknown result type (might be due to invalid IL or missing references) //IL_012a: 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_01b4: Unknown result type (might be due to invalid IL or missing references) //IL_01b6: Unknown result type (might be due to invalid IL or missing references) //IL_01bf: 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_0177: Unknown result type (might be due to invalid IL or missing references) //IL_0185: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)Minimap.instance == (Object)null || (int)Minimap.instance.m_mode != 2) { return; } InitStyles(); _frameSkip++; if (_frameSkip >= 3) { _frameSkip = 0; _lastLookupResult = GetCellUnderMouse(); } Vector2i? lastLookupResult = _lastLookupResult; if (lastLookupResult.HasValue) { if (!_stableHoveredCell.HasValue || _stableHoveredCell.Value.x != lastLookupResult.Value.x || _stableHoveredCell.Value.y != lastLookupResult.Value.y) { _hoverStableFrames++; if (_hoverStableFrames > 3) { _stableHoveredCell = lastLookupResult; _hoverStableFrames = 0; } } else { _hoverStableFrames = 0; } Vector2i val = (Vector2i)(((??)_stableHoveredCell) ?? lastLookupResult.Value); ClanTerritory clanTerritory = WarfareManager.Instance?.Data?.GetTerritory(val); Color color = default(Color); if (clanTerritory != null && clanTerritory.OwnerClanId != 0) { color = ClanConfig.GetClan(clanTerritory.OwnerClanId)?.Color ?? Color.grey; color.a = 0.85f; } else { ((Color)(ref color))..ctor(0.5f, 0.5f, 0.5f, 0.6f); } DrawRegionBorder(val, color); DrawCellTooltip(val); } else { _stableHoveredCell = null; _hoverStableFrames = 0; } DrawAllClaimedBorders(); if (!_showClaimPanel || !_selectedCell.HasValue) { return; } try { DrawClaimPanel(_selectedCell.Value); } catch { _stylesInit = false; } } private void DrawAllClaimedBorders() { //IL_0186: Unknown result type (might be due to invalid IL or missing references) //IL_018b: Unknown result type (might be due to invalid IL or missing references) //IL_030a: Unknown result type (might be due to invalid IL or missing references) //IL_0314: Expected O, but got Unknown //IL_0354: Unknown result type (might be due to invalid IL or missing references) //IL_0123: Unknown result type (might be due to invalid IL or missing references) //IL_03b6: Unknown result type (might be due to invalid IL or missing references) //IL_03ad: Unknown result type (might be due to invalid IL or missing references) //IL_0255: Unknown result type (might be due to invalid IL or missing references) //IL_025a: Unknown result type (might be due to invalid IL or missing references) //IL_025e: Unknown result type (might be due to invalid IL or missing references) //IL_0265: Unknown result type (might be due to invalid IL or missing references) //IL_03bb: Unknown result type (might be due to invalid IL or missing references) //IL_0295: Unknown result type (might be due to invalid IL or missing references) //IL_028c: Unknown result type (might be due to invalid IL or missing references) //IL_049c: Unknown result type (might be due to invalid IL or missing references) //IL_049e: Unknown result type (might be due to invalid IL or missing references) //IL_04a3: Unknown result type (might be due to invalid IL or missing references) //IL_04a6: Unknown result type (might be due to invalid IL or missing references) //IL_04ad: 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) //IL_040b: 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_0420: 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_0427: Unknown result type (might be due to invalid IL or missing references) //IL_0476: Unknown result type (might be due to invalid IL or missing references) //IL_0435: Unknown result type (might be due to invalid IL or missing references) //IL_044f: 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_054f: Unknown result type (might be due to invalid IL or missing references) //IL_0546: Unknown result type (might be due to invalid IL or missing references) //IL_0562: Unknown result type (might be due to invalid IL or missing references) //IL_056c: Expected O, but got Unknown //IL_0567: Unknown result type (might be due to invalid IL or missing references) //IL_056c: Unknown result type (might be due to invalid IL or missing references) //IL_0572: Unknown result type (might be due to invalid IL or missing references) //IL_057c: Unknown result type (might be due to invalid IL or missing references) //IL_058c: Unknown result type (might be due to invalid IL or missing references) //IL_0596: Unknown result type (might be due to invalid IL or missing references) //IL_05a4: Unknown result type (might be due to invalid IL or missing references) //IL_05ab: Unknown result type (might be due to invalid IL or missing references) //IL_05b7: Unknown result type (might be due to invalid IL or missing references) WarfareData warfareData = WarfareManager.Instance?.Data; if (warfareData?.Territories == null || warfareData.Territories.Count == 0) { return; } int num = 0; foreach (KeyValuePair territory in warfareData.Territories) { if (territory.Value.OwnerClanId != 0) { num++; } } if (num != _claimedTerritoryCount || Time.time > _nextClaimedRebuild) { _claimedBorderCache.Clear(); _claimedScreenCache.Clear(); Vector2i regionId = default(Vector2i); foreach (KeyValuePair territory2 in warfareData.Territories) { ClanTerritory value = territory2.Value; if (value.OwnerClanId != 0) { string key = territory2.Key; ((Vector2i)(ref regionId))..ctor(value.GridX, value.GridY); List list = new List(); BuildBorderWorldPointsFor(regionId, list); _claimedBorderCache[key] = list; } } _claimedTerritoryCount = num; _nextClaimedRebuild = Time.time + 10f; _claimedPanX = float.MinValue; } Rect uvRect = Minimap.instance.m_mapImageLarge.uvRect; if (Mathf.Abs(((Rect)(ref uvRect)).x - _claimedPanX) > 0.0001f || Mathf.Abs(((Rect)(ref uvRect)).y - _claimedPanY) > 0.0001f || Mathf.Abs(((Rect)(ref uvRect)).width - _claimedZoom) > 0.0001f) { _claimedPanX = ((Rect)(ref uvRect)).x; _claimedPanY = ((Rect)(ref uvRect)).y; _claimedZoom = ((Rect)(ref uvRect)).width; _claimedScreenCache.Clear(); foreach (KeyValuePair> item in _claimedBorderCache) { List list2 = new List(); foreach (Vector2 item2 in item.Value) { list2.Add((Vector2)(((??)WorldToScreenGUI(item2.x, item2.y)) ?? new Vector2(-9999f, -9999f))); } _claimedScreenCache[item.Key] = list2; } } if (_territoryLabelStyle == null) { _territoryLabelStyle = new GUIStyle(GUI.skin.label); _territoryLabelStyle.fontSize = 11; _territoryLabelStyle.fontStyle = (FontStyle)1; _territoryLabelStyle.alignment = (TextAnchor)4; _territoryLabelStyle.richText = true; _territoryLabelStyle.normal.textColor = Color.white; } Vector2i regionId2 = default(Vector2i); Rect val5 = default(Rect); foreach (KeyValuePair territory3 in warfareData.Territories) { ClanTerritory value2 = territory3.Value; if (value2.OwnerClanId == 0) { continue; } Clan clan = ClanConfig.GetClan(value2.OwnerClanId); Color color = clan?.Color ?? Color.grey; color.a = 0.5f; if (_claimedScreenCache.TryGetValue(territory3.Key, out var value3) && value3.Count >= 3) { GUI.color = color; for (int i = 0; i < value3.Count; i++) { Vector2 val = value3[i]; Vector2 val2 = value3[(i + 1) % value3.Count]; if (!(val.x < -9000f) && !(val2.x < -9000f)) { DrawLineSimple(val, val2, 2f); } } GUI.color = Color.white; } ((Vector2i)(ref regionId2))..ctor(value2.GridX, value2.GridY); Vector3 regionCenter = VoronoiGrid.Instance.GetRegionCenter(regionId2); Vector2? val3 = WorldToScreenGUI(regionCenter.x, regionCenter.z); if (val3.HasValue) { string text = clan?.Symbol + " " + value2.DisplayName; if (value2.IsCapital) { text = "★ " + text; } if (value2.RotCount > 0) { text += $" [{value2.RotCount}/4 rot]"; } _territoryLabelStyle.normal.textColor = clan?.Color ?? Color.white; Vector2 val4 = _territoryLabelStyle.CalcSize(new GUIContent(text)); ((Rect)(ref val5))..ctor(val3.Value.x - val4.x / 2f, val3.Value.y - val4.y / 2f, val4.x, val4.y); GUI.Label(val5, text, _territoryLabelStyle); } } } private void BuildBorderWorldPointsFor(Vector2i regionId, List result) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0012: 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_0083: 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_00a4: 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) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_018d: 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) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: 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_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_010d: 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_011e: Unknown result type (might be due to invalid IL or missing references) //IL_0123: Unknown result type (might be due to invalid IL or missing references) //IL_0125: 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_0134: 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) Vector3 regionCenter = VoronoiGrid.Instance.GetRegionCenter(regionId); float num = VoronoiGrid.Instance.GetApproximateRegionRadius(regionId) * 4f; if (num < 2000f) { num = 2000f; } int num2 = 60; float num3 = (float)Math.PI * 2f / (float)num2; for (int i = 0; i < num2; i++) { float num4 = (float)i * num3; float num5 = Mathf.Cos(num4); float num6 = Mathf.Sin(num4); float num7 = 50f; float num8 = num; for (float num9 = num7; num9 < num; num9 += num7) { float num10 = regionCenter.x + num5 * num9; float num11 = regionCenter.z + num6 * num9; Vector2i region = VoronoiGrid.Instance.GetRegion(new Vector3(num10, 0f, num11)); if (region.x == regionId.x && region.y == regionId.y) { continue; } float num12 = num9 - num7; float num13 = num9; for (int j = 0; j < 4; j++) { float num14 = (num12 + num13) * 0.5f; Vector2i region2 = VoronoiGrid.Instance.GetRegion(new Vector3(regionCenter.x + num5 * num14, 0f, regionCenter.z + num6 * num14)); if (region2.x == regionId.x && region2.y == regionId.y) { num12 = num14; } else { num13 = num14; } } num8 = (num12 + num13) * 0.5f; break; } float num15 = regionCenter.x + num5 * num8; float num16 = regionCenter.z + num6 * num8; float num17 = Mathf.Sqrt(num15 * num15 + num16 * num16); if (num17 > WorldRadius) { num15 *= WorldRadius / num17; num16 *= WorldRadius / num17; } result.Add(new Vector2(num15, num16)); } } private void InitStyles() { //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Expected O, but got Unknown //IL_0070: 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_009c: Expected O, but got Unknown //IL_00be: 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_00e6: Expected O, but got Unknown //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Expected O, but got Unknown //IL_0131: Unknown result type (might be due to invalid IL or missing references) //IL_0154: Unknown result type (might be due to invalid IL or missing references) //IL_015e: Expected O, but got Unknown //IL_0177: Unknown result type (might be due to invalid IL or missing references) //IL_01a7: Unknown result type (might be due to invalid IL or missing references) //IL_01b1: Expected O, but got Unknown //IL_01ca: Unknown result type (might be due to invalid IL or missing references) //IL_01e1: Unknown result type (might be due to invalid IL or missing references) //IL_01eb: Expected O, but got Unknown //IL_01f7: Unknown result type (might be due to invalid IL or missing references) //IL_0201: Expected O, but got Unknown //IL_0227: Unknown result type (might be due to invalid IL or missing references) //IL_023d: Unknown result type (might be due to invalid IL or missing references) //IL_0247: Expected O, but got Unknown //IL_027c: Unknown result type (might be due to invalid IL or missing references) //IL_0292: Unknown result type (might be due to invalid IL or missing references) //IL_029c: Expected O, but got Unknown //IL_02b5: Unknown result type (might be due to invalid IL or missing references) if (_stylesInit) { if (!((Object)(object)_pixelTex == (Object)null)) { GUIStyle panelStyle = _panelStyle; object obj; if (panelStyle == null) { obj = null; } else { GUIStyleState normal = panelStyle.normal; obj = ((normal != null) ? normal.background : null); } if (!((Object)obj == (Object)null)) { goto IL_004c; } } _stylesInit = false; } goto IL_004c; IL_004c: if (!_stylesInit) { _pixelTex = new Texture2D(1, 1); _pixelTex.SetPixel(0, 0, Color.white); _pixelTex.Apply(); _panelStyle = new GUIStyle(GUI.skin.box); _panelStyle.normal.background = MakeTex(2, 2, new Color(0.1f, 0.1f, 0.1f, 0.95f)); _panelStyle.padding = new RectOffset(15, 15, 10, 10); _headerStyle = new GUIStyle(GUI.skin.label); _headerStyle.fontSize = 18; _headerStyle.fontStyle = (FontStyle)1; _headerStyle.normal.textColor = new Color(1f, 0.85f, 0.4f); _headerStyle.alignment = (TextAnchor)4; _labelStyle = new GUIStyle(GUI.skin.label); _labelStyle.fontSize = 14; _labelStyle.normal.textColor = Color.white; _labelStyle.richText = true; _labelStyle.wordWrap = true; _buttonStyle = new GUIStyle(GUI.skin.button); _buttonStyle.fontSize = 14; _buttonStyle.normal.textColor = Color.white; _buttonStyle.padding = new RectOffset(10, 10, 6, 6); _closeButtonStyle = new GUIStyle(GUI.skin.button); _closeButtonStyle.fontSize = 16; _closeButtonStyle.fontStyle = (FontStyle)1; _closeButtonStyle.normal.textColor = Color.white; _tooltipTitleStyle = new GUIStyle(GUI.skin.label); _tooltipTitleStyle.fontSize = 14; _tooltipTitleStyle.fontStyle = (FontStyle)1; _tooltipTitleStyle.normal.textColor = new Color(1f, 0.85f, 0.4f); _tooltipDetailStyle = new GUIStyle(GUI.skin.label); _tooltipDetailStyle.fontSize = 12; _tooltipDetailStyle.normal.textColor = Color.white; _tooltipDetailStyle.richText = true; _stylesInit = true; } } private Texture2D MakeTex(int width, int height, Color col) { //IL_0010: 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_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Expected O, but got Unknown Color[] array = (Color[])(object)new Color[width * height]; for (int i = 0; i < array.Length; i++) { array[i] = col; } Texture2D val = new Texture2D(width, height); val.SetPixels(array); val.Apply(); return val; } private void DrawRegionMarker(Vector2i regionId, Color color, float size) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_000e: 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_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_005d: 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) Vector3 regionCenter = VoronoiGrid.Instance.GetRegionCenter(regionId); Vector2? val = WorldToScreenGUI(regionCenter.x, regionCenter.z); if (val.HasValue) { GUI.color = color; float num = size / 2f; GUI.DrawTexture(new Rect(val.Value.x - num, val.Value.y - num, size, size), (Texture)(object)_pixelTex); GUI.color = Color.white; } } private void DrawPlayerCellMarker() { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0021: 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_0024: 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_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)Player.m_localPlayer == (Object)null)) { Vector3 position = ((Component)Player.m_localPlayer).transform.position; Vector2i regionId = WorldToGridCell(position); DrawRegionMarker(regionId, new Color(0.3f, 0.8f, 0.3f, 0.4f), 10f); } } private void DrawRegionBorder(Vector2i regionId, Color color) { //IL_0014: 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_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0036: 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_0056: 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_00a0: 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_01c2: 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_013d: 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_0145: 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_01e4: Unknown result type (might be due to invalid IL or missing references) //IL_01e9: Unknown result type (might be due to invalid IL or missing references) //IL_0201: 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_0208: Unknown result type (might be due to invalid IL or missing references) //IL_0260: Unknown result type (might be due to invalid IL or missing references) //IL_0261: Unknown result type (might be due to invalid IL or missing references) //IL_0266: Unknown result type (might be due to invalid IL or missing references) //IL_0268: Unknown result type (might be due to invalid IL or missing references) //IL_026e: 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_0177: Unknown result type (might be due to invalid IL or missing references) //IL_0216: Unknown result type (might be due to invalid IL or missing references) //IL_02d0: Unknown result type (might be due to invalid IL or missing references) //IL_0289: Unknown result type (might be due to invalid IL or missing references) //IL_0292: Unknown result type (might be due to invalid IL or missing references) //IL_02a4: Unknown result type (might be due to invalid IL or missing references) //IL_02be: Unknown result type (might be due to invalid IL or missing references) //IL_0230: Unknown result type (might be due to invalid IL or missing references) //IL_0232: Unknown result type (might be due to invalid IL or missing references) if (!_cachedHighlightRegion.HasValue || _cachedHighlightRegion.Value.x != regionId.x || _cachedHighlightRegion.Value.y != regionId.y) { BuildBorderWorldPoints(regionId); _cachedHighlightRegion = regionId; _lastMapPanX = float.MinValue; } if (_cachedBorderWorldPoints == null || _cachedBorderWorldPoints.Count < 3) { return; } Rect uvRect = Minimap.instance.m_mapImageLarge.uvRect; if (Mathf.Abs(((Rect)(ref uvRect)).x - _lastMapPanX) > 0.0001f || Mathf.Abs(((Rect)(ref uvRect)).y - _lastMapPanY) > 0.0001f || Mathf.Abs(((Rect)(ref uvRect)).width - _lastMapZoom2) > 0.0001f) { _lastMapPanX = ((Rect)(ref uvRect)).x; _lastMapPanY = ((Rect)(ref uvRect)).y; _lastMapZoom2 = ((Rect)(ref uvRect)).width; _cachedScreenPoints.Clear(); for (int i = 0; i < _cachedBorderWorldPoints.Count; i++) { Vector2 val = _cachedBorderWorldPoints[i]; Vector2? val2 = WorldToScreenGUI(val.x, val.y); _cachedScreenPoints.Add((Vector2)(((??)val2) ?? new Vector2(-9999f, -9999f))); } } if (_cachedScreenPoints.Count < 3) { return; } Color color2 = color; color2.a = 0.85f; GUI.color = color2; for (int j = 0; j < _cachedScreenPoints.Count; j++) { Vector2 val3 = _cachedScreenPoints[j]; Vector2 val4 = _cachedScreenPoints[(j + 1) % _cachedScreenPoints.Count]; if (!(val3.x < -9000f) && !(val4.x < -9000f)) { DrawLineSimple(val3, val4, 3f); } } Vector3 regionCenter = VoronoiGrid.Instance.GetRegionCenter(regionId); Vector2? val5 = WorldToScreenGUI(regionCenter.x, regionCenter.z); if (val5.HasValue) { GUI.color = color; GUI.DrawTexture(new Rect(val5.Value.x - 4f, val5.Value.y - 4f, 8f, 8f), (Texture)(object)_pixelTex); } GUI.color = Color.white; } private void DrawLineSimple(Vector2 a, Vector2 b, float thickness) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //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_0021: 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_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_0040: 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_004d: 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_006e: Unknown result type (might be due to invalid IL or missing references) Vector2 val = b - a; float magnitude = ((Vector2)(ref val)).magnitude; if (!(magnitude < 0.5f)) { float num = Mathf.Atan2(val.y, val.x) * 57.29578f; Matrix4x4 matrix = GUI.matrix; GUIUtility.RotateAroundPivot(num, a); GUI.DrawTexture(new Rect(a.x, a.y - thickness * 0.5f, magnitude, thickness), (Texture)(object)_pixelTex); GUI.matrix = matrix; } } private void BuildBorderWorldPoints(Vector2i regionId) { //IL_0012: 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_0018: 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_0081: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_0199: Unknown result type (might be due to invalid IL or missing references) //IL_01a7: 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_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_01ff: Unknown result type (might be due to invalid IL or missing references) //IL_0108: 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_0125: Unknown result type (might be due to invalid IL or missing references) //IL_012a: Unknown result type (might be due to invalid IL or missing references) //IL_012f: 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_0138: 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_0147: Unknown result type (might be due to invalid IL or missing references) _cachedBorderWorldPoints.Clear(); Vector3 regionCenter = VoronoiGrid.Instance.GetRegionCenter(regionId); float num = VoronoiGrid.Instance.GetApproximateRegionRadius(regionId) * 4f; if (num < 2000f) { num = 2000f; } int num2 = 90; float num3 = (float)Math.PI * 2f / (float)num2; for (int i = 0; i < num2; i++) { float num4 = (float)i * num3; float num5 = Mathf.Cos(num4); float num6 = Mathf.Sin(num4); float num7 = 30f; float num8 = num; for (float num9 = num7; num9 < num; num9 += num7) { float num10 = regionCenter.x + num5 * num9; float num11 = regionCenter.z + num6 * num9; Vector2i region = VoronoiGrid.Instance.GetRegion(new Vector3(num10, 0f, num11)); if (region.x == regionId.x && region.y == regionId.y) { continue; } float num12 = num9 - num7; float num13 = num9; for (int j = 0; j < 5; j++) { float num14 = (num12 + num13) * 0.5f; Vector2i region2 = VoronoiGrid.Instance.GetRegion(new Vector3(regionCenter.x + num5 * num14, 0f, regionCenter.z + num6 * num14)); if (region2.x == regionId.x && region2.y == regionId.y) { num12 = num14; } else { num13 = num14; } } num8 = (num12 + num13) * 0.5f; break; } float num15 = regionCenter.x + num5 * num8; float num16 = regionCenter.z + num6 * num8; float num17 = Mathf.Sqrt(num15 * num15 + num16 * num16); if (num17 > WorldRadius) { num15 *= WorldRadius / num17; num16 *= WorldRadius / num17; } _cachedBorderWorldPoints.Add(new Vector2(num15, num16)); } } private void DrawCellTooltip(Vector2i cell) { //IL_0003: 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_0025: 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_004b: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0077: 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) //IL_007e: 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_008d: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_0257: Unknown result type (might be due to invalid IL or missing references) //IL_026b: Unknown result type (might be due to invalid IL or missing references) //IL_02da: Unknown result type (might be due to invalid IL or missing references) //IL_02fb: Unknown result type (might be due to invalid IL or missing references) //IL_031f: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_0353: Unknown result type (might be due to invalid IL or missing references) Vector2 value = default(Vector2); ((Vector2)(ref value))..ctor(Input.mousePosition.x, (float)Screen.height - Input.mousePosition.y); Vector2? val = value; bool flag = IsCellExplored(cell); ClanTerritory clanTerritory = WarfareManager.Instance?.Data?.GetTerritory(cell); bool flag2 = false; if ((Object)(object)Player.m_localPlayer != (Object)null) { Vector2i val2 = WorldToGridCell(((Component)Player.m_localPlayer).transform.position); flag2 = val2.x == cell.x && val2.y == cell.y; } string text; string text2; if (VoronoiGrid.Instance.IsSpawnZone(cell)) { text = "Spawn Zone"; text2 = "Neutral ground\nNo claims allowed"; } else if (clanTerritory != null && clanTerritory.OwnerClanId != 0) { Clan clan = ClanConfig.GetClan(clanTerritory.OwnerClanId); string text3 = ((clan != null) ? ColorUtility.ToHtmlStringRGB(clan.Color) : "888888"); string displayName = clanTerritory.DisplayName; text = "" + clan?.Symbol + " " + displayName + ""; WarfareManager instance = WarfareManager.Instance; object obj; if (instance == null) { obj = null; } else { WarfareData data = instance.Data; if (data == null) { obj = null; } else { Player localPlayer = Player.m_localPlayer; obj = data.GetPlayer((localPlayer != null) ? localPlayer.GetPlayerID() : 0); } } PlayerClanInfo playerClanInfo = (PlayerClanInfo)obj; text2 = ((playerClanInfo != null && playerClanInfo.ClanId == clanTerritory.OwnerClanId) ? ("HOME — " + clan?.Name + "\nClaimed by " + clanTerritory.ClaimedByPlayerName + "") : ("ENEMY — " + clan?.Name + "\nClaimed by " + clanTerritory.ClaimedByPlayerName + "")); } else { text = "Unclaimed Territory"; text2 = "Click to view / claim"; } string text4 = (flag2 ? "You are here" : ""); float num = 260f; float num2 = 95f; float num3 = val.Value.x + 20f; float num4 = val.Value.y - num2 / 2f; num3 = Mathf.Clamp(num3, 10f, (float)Screen.width - num - 10f); num4 = Mathf.Clamp(num4, 10f, (float)Screen.height - num2 - 10f); GUI.Box(new Rect(num3 - 5f, num4 - 5f, num + 10f, num2 + 10f), "", _panelStyle); GUI.Label(new Rect(num3, num4, num, 22f), text, _tooltipTitleStyle); GUI.Label(new Rect(num3, num4 + 22f, num, 40f), text2, _tooltipDetailStyle); if (!string.IsNullOrEmpty(text4)) { GUI.Label(new Rect(num3, num4 + 58f, num, 22f), text4, _tooltipDetailStyle); } } private bool IsCellExplored(Vector2i cell) { return true; } private void DrawOwnedTerritoryInfo(ClanTerritory territory, Vector2i cell) { //IL_0007: 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_003b: Unknown result type (might be due to invalid IL or missing references) //IL_02d2: 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_03ab: Unknown result type (might be due to invalid IL or missing references) Clan clan = ClanConfig.GetClan(territory.OwnerClanId); string text = clan?.Name ?? "Unknown"; string text2 = ((clan != null) ? ColorUtility.ToHtmlStringRGB(clan.Color) : "888888"); string text3 = (territory.IsCapital ? "★ Capital" : "Colony"); GUILayout.Label("" + clan?.Symbol + " " + text + " — " + text3, _headerStyle, Array.Empty()); GUILayout.Space(4f); GUILayout.Label($"Size {territory.SizeLevel} {Economy.ValueTierName(territory.BiomeValueTier)}-value " + $"Income {Economy.TerritoryIncome(territory)}/tick", _labelStyle, Array.Empty()); GUILayout.Label($"State: {territory.State} HP: {Mathf.RoundToInt(territory.HP)}/{Mathf.RoundToInt(territory.MaxHP)}", _labelStyle, Array.Empty()); if (territory.RotCount > 0) { GUILayout.Label($"Rot: {territory.RotCount}/4 — {territory.RotCount * 25}% income lost", _labelStyle, Array.Empty()); } WarfareData warfareData = WarfareManager.Instance?.Data; object obj; if (warfareData == null) { obj = null; } else { Player localPlayer = Player.m_localPlayer; obj = warfareData.GetPlayer((localPlayer != null) ? localPlayer.GetPlayerID() : 0); } PlayerClanInfo playerClanInfo = (PlayerClanInfo)obj; bool flag = playerClanInfo != null && playerClanInfo.ClanId == territory.OwnerClanId; GUILayout.Label(flag ? "Your clan's territory" : "Enemy territory", _labelStyle, Array.Empty()); CaptureSession captureSession = warfareData?.ActiveCaptures?.Find((CaptureSession c) => c.TerritoryGridX == cell.x && c.TerritoryGridY == cell.y); if (captureSession != null) { GUILayout.Label($"Being captured by {ClanConfig.GetClan(captureSession.AttackerClanId)?.Name} — {captureSession.Progress01 * 100f:F0}%", _labelStyle, Array.Empty()); } GUILayout.Space(6f); if (territory.IsRotted && playerClanInfo != null && playerClanInfo.ClanId != 0) { if (GUILayout.Button("Seize this rotted territory", _buttonStyle, Array.Empty())) { WarfareRPC.Instance?.RequestClaimTerritory(cell); ClosePanel(); } } else if (flag && playerClanInfo.Rank >= ClanRank.Officer) { int num = ClanConfig.MaxTerritorySizeLevel?.Value ?? 5; if (territory.SizeLevel < num && GUILayout.Button($"Upgrade Size ({Economy.TerritoryUpgradeCost(territory.SizeLevel)} coins)", _buttonStyle, Array.Empty())) { WarfareRPC.Instance?.RequestUpgradeTerritory(cell); ClosePanel(); } if (!territory.IsCapital && GUILayout.Button("Set as Capital", _buttonStyle, Array.Empty())) { WarfareRPC.Instance?.RequestSetCapital(cell); ClosePanel(); } } else if (!flag) { GUILayout.Label("Declare war from the F3 panel, then capture this land by standing in it.", _labelStyle, Array.Empty()); } } private void DrawClaimPanel(Vector2i cell) { //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_013f: 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) float num = 380f; float num2 = 350f; float num3 = ((float)Screen.width - num) / 2f; float num4 = ((float)Screen.height - num2) / 2f; Rect val = default(Rect); ((Rect)(ref val))..ctor(num3, num4, num, num2); GUI.Box(val, "", _panelStyle); GUILayout.BeginArea(new Rect(num3 + 15f, num4 + 10f, num - 30f, num2 - 20f)); ClanTerritory clanTerritory = WarfareManager.Instance?.Data?.GetTerritory(cell); GUILayout.BeginHorizontal(Array.Empty()); GUILayout.FlexibleSpace(); string text = ((clanTerritory != null && clanTerritory.OwnerClanId != 0) ? clanTerritory.DisplayName : "Territory"); GUILayout.Label(text, _headerStyle, Array.Empty()); GUILayout.FlexibleSpace(); if (GUILayout.Button("X", _closeButtonStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(30f) })) { ClosePanel(); } GUILayout.EndHorizontal(); GUILayout.Space(15f); if (clanTerritory != null && clanTerritory.OwnerClanId != 0) { DrawOwnedTerritoryInfo(clanTerritory, cell); } else { DrawUnclaimedTerritoryInfo(cell); } GUILayout.EndArea(); } private void DrawUnclaimedTerritoryInfo(Vector2i cell) { //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_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Unknown result type (might be due to invalid IL or missing references) //IL_013a: Unknown result type (might be due to invalid IL or missing references) GUILayout.Label("Unclaimed Territory", _headerStyle, Array.Empty()); GUILayout.Space(10f); WarfareManager instance = WarfareManager.Instance; object obj; if (instance == null) { obj = null; } else { WarfareData data = instance.Data; if (data == null) { obj = null; } else { Player localPlayer = Player.m_localPlayer; obj = data.GetPlayer((localPlayer != null) ? localPlayer.GetPlayerID() : 0); } } PlayerClanInfo playerClanInfo = (PlayerClanInfo)obj; if (playerClanInfo == null || playerClanInfo.ClanId == 0) { GUILayout.Label("Join a clan first to claim territories.", _labelStyle, Array.Empty()); return; } if (playerClanInfo.Role != ClanRole.Explorer) { GUILayout.Label("Only Explorers can claim territory.", _labelStyle, Array.Empty()); return; } Vector2i val = WorldToGridCell(((Component)Player.m_localPlayer).transform.position); if (val.x != cell.x || val.y != cell.y) { GUILayout.Label("You must be standing in this territory to claim it.", _labelStyle, Array.Empty()); return; } GUILayout.Space(10f); if (GUILayout.Button("Claim for your Clan", _buttonStyle, Array.Empty())) { WarfareRPC.Instance?.RequestClaimTerritory(cell); ClosePanel(); } } private void TryClaimTerritory(Vector2i cell) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) WarfareRPC.Instance?.RequestClaimTerritory(cell); ClosePanel(); } } public class WarfareHUD : MonoBehaviour { private bool _isVisible; private Rect _windowRect; private int _windowId; private int _tab; private bool _stylesInit; private Vector2 _scrollA; private Vector2 _scrollB; private string _renameTarget; private string _renameInput = ""; private string _bountyInput = "100"; private int _bountyTargetClan; private GUIStyle _windowStyle; private GUIStyle _labelStyle; private GUIStyle _labelGoldStyle; private GUIStyle _buttonStyle; private GUIStyle _smallButtonStyle; private GUIStyle _tabStyle; private GUIStyle _tabActiveStyle; private GUIStyle _boxStyle; private Texture2D _panelBg; private Texture2D _btnTex; private Texture2D _btnActiveTex; private Texture2D _boxTex; private Texture2D _pixelTex; private static readonly string[] Tabs = new string[7] { "Overview", "Members", "Territory", "Economy", "War", "Vault", "Role" }; public static WarfareHUD Instance { get; private set; } private static float UIScale => (float)Screen.height / 1080f; private void Awake() { //IL_0053: 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) Instance = this; _windowId = ((Object)this).GetInstanceID(); float num = (float)Screen.width / UIScale; float num2 = (float)Screen.height / UIScale; _windowRect = new Rect((num - 780f) / 2f, (num2 - 540f) / 2f, 780f, 540f); } public void Toggle() { _isVisible = !_isVisible; } private void Update() { if (Input.GetKeyDown((KeyCode)284)) { _isVisible = !_isVisible; } } private void InitStyles() { //IL_0031: 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_0073: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: 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_0104: Unknown result type (might be due to invalid IL or missing references) //IL_011e: Unknown result type (might be due to invalid IL or missing references) //IL_0128: Expected O, but got Unknown //IL_0164: Unknown result type (might be due to invalid IL or missing references) //IL_016e: Expected O, but got Unknown //IL_017d: Unknown result type (might be due to invalid IL or missing references) //IL_0187: Expected O, but got Unknown //IL_0193: Unknown result type (might be due to invalid IL or missing references) //IL_0198: Unknown result type (might be due to invalid IL or missing references) //IL_01a1: Unknown result type (might be due to invalid IL or missing references) //IL_01a9: Unknown result type (might be due to invalid IL or missing references) //IL_01b6: Expected O, but got Unknown //IL_01d0: 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_01f0: Unknown result type (might be due to invalid IL or missing references) //IL_01fd: Expected O, but got Unknown //IL_0217: 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: Expected O, but got Unknown //IL_0296: Unknown result type (might be due to invalid IL or missing references) //IL_02bb: Unknown result type (might be due to invalid IL or missing references) //IL_02eb: Unknown result type (might be due to invalid IL or missing references) //IL_02f5: Expected O, but got Unknown //IL_0300: Unknown result type (might be due to invalid IL or missing references) //IL_030a: Expected O, but got Unknown //IL_0312: Unknown result type (might be due to invalid IL or missing references) //IL_031c: Expected O, but got Unknown //IL_034d: 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_036d: Expected O, but got Unknown //IL_03cc: Unknown result type (might be due to invalid IL or missing references) //IL_03f1: Unknown result type (might be due to invalid IL or missing references) //IL_0423: Unknown result type (might be due to invalid IL or missing references) //IL_042d: Expected O, but got Unknown //IL_0438: Unknown result type (might be due to invalid IL or missing references) //IL_0442: Expected O, but got Unknown //IL_044a: Unknown result type (might be due to invalid IL or missing references) //IL_044f: 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_045d: Unknown result type (might be due to invalid IL or missing references) //IL_0467: Expected O, but got Unknown //IL_046d: Expected O, but got Unknown //IL_0478: Unknown result type (might be due to invalid IL or missing references) //IL_0482: Expected O, but got Unknown //IL_04a3: Unknown result type (might be due to invalid IL or missing references) //IL_04ad: Expected O, but got Unknown //IL_04b8: Unknown result type (might be due to invalid IL or missing references) //IL_04c2: Expected O, but got Unknown if (!_stylesInit) { _stylesInit = true; _panelBg = MakeGradientTex(32, 32, new Color(0.08f, 0.06f, 0.04f, 0.95f), new Color(0.05f, 0.04f, 0.03f, 0.97f)); _btnTex = MakeGradientTex(16, 16, new Color(0.18f, 0.14f, 0.08f, 0.9f), new Color(0.12f, 0.09f, 0.05f, 0.92f)); _btnActiveTex = MakeGradientTex(16, 16, new Color(0.32f, 0.23f, 0.1f, 0.95f), new Color(0.2f, 0.15f, 0.06f, 0.97f)); _boxTex = MakeTex(new Color(0.1f, 0.08f, 0.05f, 0.7f)); _pixelTex = MakeTex(Color.white); _windowStyle = new GUIStyle(GUI.skin.window); _windowStyle.normal.background = _panelBg; _windowStyle.onNormal.background = _panelBg; _windowStyle.border = new RectOffset(12, 12, 45, 12); _windowStyle.padding = new RectOffset(18, 18, 50, 16); _labelStyle = new GUIStyle(GUI.skin.label) { fontSize = 13, richText = true, wordWrap = true }; _labelStyle.normal.textColor = new Color(0.82f, 0.78f, 0.68f); _labelGoldStyle = new GUIStyle(_labelStyle) { fontSize = 14, fontStyle = (FontStyle)1 }; _labelGoldStyle.normal.textColor = new Color(0.92f, 0.8f, 0.36f); _tabStyle = new GUIStyle(GUI.skin.button); _tabStyle.normal.background = _btnTex; _tabStyle.hover.background = _btnActiveTex; _tabStyle.active.background = _btnActiveTex; _tabStyle.normal.textColor = new Color(0.75f, 0.68f, 0.52f); _tabStyle.hover.textColor = new Color(0.97f, 0.87f, 0.6f); _tabStyle.fontSize = 12; _tabStyle.fontStyle = (FontStyle)1; _tabStyle.padding = new RectOffset(6, 6, 7, 7); _tabStyle.margin = new RectOffset(2, 2, 0, 0); _tabActiveStyle = new GUIStyle(_tabStyle); _tabActiveStyle.normal.background = _btnActiveTex; _tabActiveStyle.normal.textColor = new Color(1f, 0.9f, 0.46f); _buttonStyle = new GUIStyle(GUI.skin.button); _buttonStyle.normal.background = _btnTex; _buttonStyle.hover.background = _btnActiveTex; _buttonStyle.active.background = _btnActiveTex; _buttonStyle.normal.textColor = new Color(0.92f, 0.84f, 0.62f); _buttonStyle.hover.textColor = new Color(1f, 0.96f, 0.82f); _buttonStyle.fontSize = 13; _buttonStyle.fontStyle = (FontStyle)1; _buttonStyle.padding = new RectOffset(10, 10, 6, 6); _buttonStyle.margin = new RectOffset(0, 0, 3, 3); _smallButtonStyle = new GUIStyle(_buttonStyle) { fontSize = 11, padding = new RectOffset(7, 7, 4, 4) }; _boxStyle = new GUIStyle(GUI.skin.box); _boxStyle.normal.background = _boxTex; _boxStyle.padding = new RectOffset(8, 8, 6, 6); _boxStyle.margin = new RectOffset(0, 0, 3, 3); } } private Texture2D MakeTex(Color c) { //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_0012: Expected O, but got Unknown //IL_0015: Unknown result type (might be due to invalid IL or missing references) Texture2D val = new Texture2D(1, 1) { hideFlags = (HideFlags)61 }; val.SetPixel(0, 0, c); val.Apply(); return val; } private Texture2D MakeGradientTex(int w, int h, Color top, Color bottom) { //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_0011: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Expected O, but got Unknown //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0021: 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_0034: Unknown result type (might be due to invalid IL or missing references) Texture2D val = new Texture2D(w, h) { hideFlags = (HideFlags)61, wrapMode = (TextureWrapMode)1 }; for (int i = 0; i < h; i++) { Color val2 = Color.Lerp(bottom, top, (float)i / (float)h); for (int j = 0; j < w; j++) { val.SetPixel(j, i, val2); } } val.Apply(); return val; } private void OnGUI() { //IL_001f: 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) //IL_0025: 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_0036: 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_0085: Unknown result type (might be due to invalid IL or missing references) //IL_005f: 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_0080: Expected O, but got Unknown //IL_007b: 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) if (!((Object)(object)Player.m_localPlayer == (Object)null)) { InitStyles(); float uIScale = UIScale; Matrix4x4 matrix = GUI.matrix; GUI.matrix = Matrix4x4.TRS(Vector3.zero, Quaternion.identity, new Vector3(uIScale, uIScale, 1f)); DrawStatusBar(); if (_isVisible) { _windowRect = GUI.Window(_windowId, _windowRect, new WindowFunction(DrawWindow), "", _windowStyle); } GUI.matrix = matrix; } } private void DrawStatusBar() { //IL_0109: Unknown result type (might be due to invalid IL or missing references) //IL_010e: Unknown result type (might be due to invalid IL or missing references) //IL_0113: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_0187: Unknown result type (might be due to invalid IL or missing references) //IL_016c: Unknown result type (might be due to invalid IL or missing references) //IL_018c: Unknown result type (might be due to invalid IL or missing references) //IL_0196: 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) WarfareData warfareData = WarfareManager.Instance?.Data; if (warfareData != null) { long pid = Player.m_localPlayer.GetPlayerID(); float num = (float)Screen.width / UIScale; float num2 = 380f; float num3 = 26f; float num4 = (num - num2) / 2f; float num5 = 84f; VaultCrackSession vaultCrackSession = warfareData.ActiveCracks.Find((VaultCrackSession c) => c.PlayerId == pid); if (vaultCrackSession != null) { Bar(new Rect(num4, num5, num2, num3), vaultCrackSession.Progress01, new Color(0.8f, 0.55f, 0.15f, 0.9f), $"Cracking Vault — {vaultCrackSession.Progress01 * 100f:F0}% ({vaultCrackSession.MinutesElapsed:F0}/{vaultCrackSession.DurationMinutes} min)"); num5 += num3 + 4f; } Vector2i grid = GridExtensions.WorldToGrid(((Component)Player.m_localPlayer).transform.position); CaptureSession captureSession = warfareData.ActiveCaptures.Find((CaptureSession c) => c.TerritoryGridX == grid.x && c.TerritoryGridY == grid.y); if (captureSession != null) { Clan clan = warfareData.GetClan(captureSession.AttackerClanId); Color fill = (captureSession.Siege ? new Color(0.85f, 0.2f, 0.2f, 0.9f) : new Color(0.75f, 0.4f, 0.15f, 0.9f)); Bar(new Rect(num4, num5, num2, num3), captureSession.Progress01, fill, string.Format("{0}{1} capturing — {2:F0}%", captureSession.Siege ? "SIEGE — " : "", clan?.Name, captureSession.Progress01 * 100f)); } } } private void Bar(Rect r, float t, Color fill, string label) { //IL_0015: 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_002d: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: 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) //IL_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_010c: 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_0119: Unknown result type (might be due to invalid IL or missing references) //IL_0121: Unknown result type (might be due to invalid IL or missing references) //IL_012b: Expected O, but got Unknown //IL_0131: Unknown result type (might be due to invalid IL or missing references) //IL_013c: Unknown result type (might be due to invalid IL or missing references) GUI.color = new Color(0f, 0f, 0f, 0.82f); GUI.DrawTexture(r, (Texture)(object)_pixelTex); GUI.color = fill; GUI.DrawTexture(new Rect(((Rect)(ref r)).x + 2f, ((Rect)(ref r)).y + 2f, (((Rect)(ref r)).width - 4f) * Mathf.Clamp01(t), ((Rect)(ref r)).height - 4f), (Texture)(object)_pixelTex); GUI.color = new Color(0.65f, 0.5f, 0.2f, 0.9f); GUI.DrawTexture(new Rect(((Rect)(ref r)).x, ((Rect)(ref r)).y, ((Rect)(ref r)).width, 1f), (Texture)(object)_pixelTex); GUI.DrawTexture(new Rect(((Rect)(ref r)).x, ((Rect)(ref r)).yMax - 1f, ((Rect)(ref r)).width, 1f), (Texture)(object)_pixelTex); GUI.color = Color.white; GUIStyle val = new GUIStyle(_labelStyle) { alignment = (TextAnchor)4, fontStyle = (FontStyle)1, fontSize = 12 }; val.normal.textColor = Color.white; GUI.Label(r, label, val); } private void DrawWindow(int id) { //IL_0060: 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_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: 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_010a: Unknown result type (might be due to invalid IL or missing references) //IL_0114: Expected O, but got Unknown //IL_012e: Unknown result type (might be due to invalid IL or missing references) //IL_015f: 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_0203: Unknown result type (might be due to invalid IL or missing references) //IL_040a: Unknown result type (might be due to invalid IL or missing references) WarfareData warfareData = WarfareManager.Instance?.Data; if (warfareData == null) { GUILayout.Label("Waiting for server data...", _labelStyle, Array.Empty()); return; } long playerID = Player.m_localPlayer.GetPlayerID(); PlayerClanInfo player = warfareData.GetPlayer(playerID); GUI.color = new Color(0.06f, 0.04f, 0.03f, 0.95f); GUI.DrawTexture(new Rect(5f, 5f, ((Rect)(ref _windowRect)).width - 10f, 38f), (Texture)(object)_pixelTex); GUI.color = new Color(0.65f, 0.5f, 0.2f, 0.7f); GUI.DrawTexture(new Rect(5f, 42f, ((Rect)(ref _windowRect)).width - 10f, 1f), (Texture)(object)_pixelTex); GUI.color = Color.white; GUIStyle val = new GUIStyle(_labelGoldStyle) { alignment = (TextAnchor)4, fontSize = 17 }; GUI.Label(new Rect(0f, 8f, ((Rect)(ref _windowRect)).width, 32f), "FORTECA CLAN WARFARE", val); if (GUI.Button(new Rect(((Rect)(ref _windowRect)).width - 38f, 10f, 28f, 26f), "X", _tabStyle)) { _isVisible = false; } if (player == null || player.ClanId == 0) { GUILayout.Space(6f); GUILayout.Label("You have no clan. The clan menu opens automatically — found or join a clan to begin.", _labelStyle, Array.Empty()); GUI.DragWindow(new Rect(0f, 0f, ((Rect)(ref _windowRect)).width - 40f, 45f)); return; } Clan clan = warfareData.GetClan(player.ClanId); string text = ((clan != null) ? WarfareManager.ColorHex(clan.Color) : "ffffff"); GUILayout.Label("" + ClanConfig.GetIcon(clan?.IconIndex ?? 0) + " " + clan?.Name + " [" + clan?.Tag + "] " + $"Rank: {player.Rank} Role: {player.Role} " + $"Treasury: {clan?.Treasury ?? 0} coins", _labelStyle, Array.Empty()); GUILayout.Space(2f); GUILayout.BeginHorizontal(Array.Empty()); for (int i = 0; i < Tabs.Length; i++) { if (GUILayout.Button(Tabs[i], (_tab == i) ? _tabActiveStyle : _tabStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(26f) })) { _tab = i; } } GUILayout.EndHorizontal(); GUILayout.Space(6f); switch (_tab) { case 0: DrawOverview(warfareData, player, clan); break; case 1: DrawMembers(warfareData, player, clan); break; case 2: DrawTerritory(warfareData, player, clan); break; case 3: DrawEconomy(warfareData, player, clan); break; case 4: DrawWar(warfareData, player, clan); break; case 5: DrawVault(warfareData, player, clan); break; case 6: DrawRole(warfareData, player); break; } GUI.DragWindow(new Rect(0f, 0f, ((Rect)(ref _windowRect)).width - 40f, 45f)); } private void DrawOverview(WarfareData data, PlayerClanInfo info, Clan clan) { //IL_0120: Unknown result type (might be due to invalid IL or missing references) //IL_0125: Unknown result type (might be due to invalid IL or missing references) //IL_012a: 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_0292: Unknown result type (might be due to invalid IL or missing references) //IL_017e: Unknown result type (might be due to invalid IL or missing references) int clanTerritoryCount = data.GetClanTerritoryCount(info.ClanId); int num = ((clan != null) ? Economy.TerritoryCap(clan) : 0); int clanMemberCount = data.GetClanMemberCount(info.ClanId); GUILayout.BeginVertical(_boxStyle, Array.Empty()); GUILayout.Label($"Members: {clanMemberCount} Territories: {clanTerritoryCount}/{num} " + "Economy: " + EconomyBandColored(clanTerritoryCount), _labelStyle, Array.Empty()); long v = ((clan != null) ? Economy.NetClanTick(data, info.ClanId) : 0); GUILayout.Label("Net income: " + ColoredCoins(v) + " / tick " + $"Vault tier: {clan?.VaultTier} " + $"Active wars: {data.GetActiveWarsInvolving(info.ClanId).Count}", _labelStyle, Array.Empty()); GUILayout.EndVertical(); Vector2i grid = GridExtensions.WorldToGrid(((Component)Player.m_localPlayer).transform.position); ClanTerritory territory = data.GetTerritory(grid); GUILayout.BeginVertical(_boxStyle, Array.Empty()); if (territory != null && territory.OwnerClanId != 0) { Clan clan2 = data.GetClan(territory.OwnerClanId); string text = ((clan2 != null) ? WarfareManager.ColorHex(clan2.Color) : "888888"); bool flag = territory.OwnerClanId == info.ClanId; GUILayout.Label("Current zone: " + territory.DisplayName + " " + string.Format("({0}) — {1}, {2}-value, ", flag ? "HOME" : "ENEMY", territory.Type, Economy.ValueTierName(territory.BiomeValueTier)) + $"size {territory.SizeLevel}", _labelStyle, Array.Empty()); if (territory.RotCount > 0) { GUILayout.Label($"Rot: {territory.RotCount}/4 — {territory.RotCount * 25}% income lost", _labelStyle, Array.Empty()); } } else { GUILayout.Label("Current zone: Unclaimed wilderness", _labelStyle, Array.Empty()); } DrawZoneActions(data, info, territory, grid); GUILayout.EndVertical(); } private void DrawZoneActions(WarfareData data, PlayerClanInfo info, ClanTerritory t, Vector2i grid) { //IL_0092: 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) bool flag = t == null || t.OwnerClanId == 0; bool flag2 = t?.IsRotted ?? false; bool flag3 = t != null && t.OwnerClanId != 0 && t.OwnerClanId != info.ClanId; if (((flag && info.Role == ClanRole.Explorer) || flag2) && GUILayout.Button(flag2 ? "Seize this rotted territory" : "Claim this territory", _buttonStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(28f) })) { WarfareRPC.Instance?.RequestClaimTerritory(grid); } if (flag3 && !flag2 && info.Role == ClanRole.Invader) { if (info.CanCrackVault(ClanConfig.VaultCrackCooldownHours?.Value ?? 6)) { if (GUILayout.Button($"Start Vault Crack ({ClanConfig.VaultCrackDurationMinutes?.Value ?? 30} min)", _buttonStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(28f) })) { WarfareRPC.Instance?.RequestStartVaultCrack(grid); } } else { GUILayout.Label("Vault crack on cooldown.", _labelStyle, Array.Empty()); } } if (flag3 && !flag2 && info.Role == ClanRole.Parasite && GUILayout.Button("Raise Rot Totem here", _buttonStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(28f) })) { WarfareRPC.Instance?.RequestPlaceRotTotem(); } } private void DrawMembers(WarfareData data, PlayerClanInfo info, Clan clan) { //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_0046: 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_013c: Unknown result type (might be due to invalid IL or missing references) //IL_0141: Unknown result type (might be due to invalid IL or missing references) HashSet online = new HashSet(); if ((Object)(object)ZNet.instance != (Object)null) { foreach (PlayerInfo player in ZNet.instance.GetPlayerList()) { online.Add(player.m_name); } } List clanMembers = data.GetClanMembers(info.ClanId); clanMembers.Sort(delegate(PlayerClanInfo a, PlayerClanInfo b) { bool flag4 = online.Contains(a.PlayerName); bool flag5 = online.Contains(b.PlayerName); if (flag4 != flag5) { return flag5.CompareTo(flag4); } return (a.Rank != b.Rank) ? b.Rank.CompareTo(a.Rank) : string.Compare(a.PlayerName, b.PlayerName, StringComparison.OrdinalIgnoreCase); }); long num = ((clan != null) ? (clan.NextElectionTimestamp - WarfareManager.Now()) : 0); GUILayout.Label($"Roster — {clanMembers.Count} members Next election: " + ((num > 0) ? $"{num / 86400}d {num % 86400 / 3600}h" : "soon"), _labelGoldStyle, Array.Empty()); GUILayout.Space(2f); bool flag = info.Rank >= ClanRank.Officer; bool flag2 = info.Rank == ClanRank.Jarl; _scrollA = GUILayout.BeginScrollView(_scrollA, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandHeight(true) }); foreach (PlayerClanInfo item in clanMembers) { string text = (online.Contains(item.PlayerName) ? "●" : "●"); bool flag3 = clan != null && clan.JarlId == item.PlayerId; GUILayout.BeginHorizontal(_boxStyle, Array.Empty()); GUILayout.Label(text + " " + item.PlayerName + "", _labelStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(170f) }); GUILayout.Label((flag3 ? "Jarl" : item.Rank.ToString()) ?? "", _labelStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(70f) }); GUILayout.Label($"{item.Role}", _labelStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(80f) }); if (item.Bounty > 0) { GUILayout.Label($"{item.Bounty}c bounty", _labelStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(110f) }); } GUILayout.FlexibleSpace(); if (GUILayout.Button("Vote", _smallButtonStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(54f) })) { WarfareRPC.Instance?.RequestCastVote(item.PlayerId); } if (flag2 && item.PlayerId != info.PlayerId) { if (item.Rank == ClanRank.Member && GUILayout.Button("Promote", _smallButtonStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(74f) })) { WarfareRPC.Instance?.RequestSetRank(item.PlayerId, ClanRank.Officer); } else if (item.Rank == ClanRank.Officer && GUILayout.Button("Demote", _smallButtonStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(74f) })) { WarfareRPC.Instance?.RequestSetRank(item.PlayerId, ClanRank.Member); } } if (flag && item.PlayerId != info.PlayerId && item.Rank < info.Rank && GUILayout.Button("Kick", _smallButtonStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(54f) })) { WarfareRPC.Instance?.RequestKickMember(item.PlayerId); } GUILayout.EndHorizontal(); } GUILayout.EndScrollView(); GUILayout.BeginHorizontal(Array.Empty()); if (GUILayout.Button("Leave Clan", _buttonStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(140f) })) { WarfareRPC.Instance?.RequestLeaveClan(); } if (flag2 && GUILayout.Button("Disband Clan", _buttonStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(150f) })) { WarfareRPC.Instance?.RequestDisbandClan(); } GUILayout.EndHorizontal(); } private void DrawTerritory(WarfareData data, PlayerClanInfo info, Clan clan) { //IL_0046: 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_005f: Unknown result type (might be due to invalid IL or missing references) //IL_021a: Unknown result type (might be due to invalid IL or missing references) //IL_033c: Unknown result type (might be due to invalid IL or missing references) //IL_0389: Unknown result type (might be due to invalid IL or missing references) List clanTerritories = data.GetClanTerritories(info.ClanId); if (clanTerritories.Count == 0) { GUILayout.Label("Your clan holds no territory. Explorers claim land from the map.", _labelStyle, Array.Empty()); return; } bool flag = info.Rank >= ClanRank.Officer; _scrollB = GUILayout.BeginScrollView(_scrollB, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandHeight(true) }); foreach (ClanTerritory item in clanTerritories) { string text = WarfareData.GridToKey(item.GridX, item.GridY); GUILayout.BeginVertical(_boxStyle, Array.Empty()); string text2 = (item.IsCapital ? "★ Capital" : "Colony"); GUILayout.Label($"{item.DisplayName} ({item.GridX},{item.GridY}) — {text2}, size {item.SizeLevel}, " + Economy.ValueTierName(item.BiomeValueTier) + "-value", _labelStyle, Array.Empty()); GUILayout.Label($"State: {item.State} HP: {Mathf.RoundToInt(item.HP)}/{Mathf.RoundToInt(item.MaxHP)} " + $"Rot: {item.RotCount}/4 Income: {Economy.TerritoryIncome(item)}/tick", _labelStyle, Array.Empty()); if (_renameTarget == text) { GUILayout.BeginHorizontal(Array.Empty()); _renameInput = GUILayout.TextField(_renameInput, 32, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(220f) }); if (GUILayout.Button("Save", _smallButtonStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(60f) })) { WarfareRPC.Instance?.RequestRenameTerritory(item.GridPosition, _renameInput); _renameTarget = null; } if (GUILayout.Button("Cancel", _smallButtonStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(70f) })) { _renameTarget = null; } GUILayout.EndHorizontal(); } else { GUILayout.BeginHorizontal(Array.Empty()); if (GUILayout.Button("Rename", _smallButtonStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(80f) })) { _renameTarget = text; _renameInput = item.CustomName ?? ""; } if (flag) { int num = ClanConfig.MaxTerritorySizeLevel?.Value ?? 5; if (item.SizeLevel < num && GUILayout.Button($"Upgrade ({Economy.TerritoryUpgradeCost(item.SizeLevel)}c)", _smallButtonStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(150f) })) { WarfareRPC.Instance?.RequestUpgradeTerritory(item.GridPosition); } if (!item.IsCapital && GUILayout.Button("Make Capital", _smallButtonStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(120f) })) { WarfareRPC.Instance?.RequestSetCapital(item.GridPosition); } } GUILayout.EndHorizontal(); } GUILayout.EndVertical(); } GUILayout.EndScrollView(); } private void DrawEconomy(WarfareData data, PlayerClanInfo info, Clan clan) { if (clan == null) { return; } int clanTerritoryCount = data.GetClanTerritoryCount(info.ClanId); float num = Economy.GlobalUpkeepMultiplier(clanTerritoryCount); long num2 = 0L; long num3 = 0L; foreach (ClanTerritory clanTerritory in data.GetClanTerritories(info.ClanId)) { num2 += Economy.TerritoryIncome(clanTerritory); num3 += Economy.TerritoryUpkeep(clanTerritory, num); } GUILayout.BeginVertical(_boxStyle, Array.Empty()); GUILayout.Label($"Treasury: {clan.Treasury} coins", _labelGoldStyle, Array.Empty()); GUILayout.Label($"Gross income: +{num2}/tick " + $"Upkeep: -{num3}/tick " + "Net: " + ColoredCoins(num2 - num3) + "/tick", _labelStyle, Array.Empty()); GUILayout.Label($"Global upkeep multiplier: x{num:F2} ({clanTerritoryCount} territories — {EconomyBandColored(clanTerritoryCount)})", _labelStyle, Array.Empty()); GUILayout.Label($"Economy tick: every {ClanConfig.UpkeepTickMinutes?.Value ?? 30} minutes.", _labelStyle, Array.Empty()); GUILayout.EndVertical(); bool flag = info.Rank >= ClanRank.Officer; GUILayout.BeginVertical(_boxStyle, Array.Empty()); int num4 = Economy.VaultCapacity(clan, clanTerritoryCount); GUILayout.Label($"Vault: tier {clan.VaultTier}, capacity {num4} stacks " + $"({data.GetVaultStackCount(info.ClanId)} used)", _labelStyle, Array.Empty()); int num5 = ClanConfig.MaxVaultTier?.Value ?? 5; if (flag && clan.VaultTier < num5) { if (GUILayout.Button($"Upgrade Vault to tier {clan.VaultTier + 1} ({Economy.VaultUpgradeCost(clan.VaultTier)}c)", _buttonStyle, Array.Empty())) { WarfareRPC.Instance?.RequestUpgradeVault(); } } else if (clan.VaultTier >= num5) { GUILayout.Label("Vault at maximum tier.", _labelStyle, Array.Empty()); } GUILayout.EndVertical(); GUILayout.BeginVertical(_boxStyle, Array.Empty()); GUILayout.Label($"Territory cap: {Economy.TerritoryCap(clan)} " + $"(base {ClanConfig.BaseTerritoryCap?.Value ?? 10} + {clan.ExtraTerritorySlots} expansion(s))", _labelStyle, Array.Empty()); if (flag && Economy.TerritoryCap(clan) < (ClanConfig.MaxTerritoryCap?.Value ?? 100) && GUILayout.Button($"Buy Expansion (+{ClanConfig.TerritoryExpansionBlock?.Value ?? 10} slots, " + $"{Economy.TerritoryExpansionCost(clan.ExtraTerritorySlots)}c)", _buttonStyle, Array.Empty())) { WarfareRPC.Instance?.RequestBuyExpansion(); } GUILayout.EndVertical(); } private void DrawWar(WarfareData data, PlayerClanInfo info, Clan clan) { //IL_0184: Unknown result type (might be due to invalid IL or missing references) //IL_019c: Unknown result type (might be due to invalid IL or missing references) //IL_01a1: Unknown result type (might be due to invalid IL or missing references) //IL_020d: Unknown result type (might be due to invalid IL or missing references) GUILayout.Label("Active Wars", _labelGoldStyle, Array.Empty()); List activeWarsInvolving = data.GetActiveWarsInvolving(info.ClanId); if (activeWarsInvolving.Count == 0) { GUILayout.Label("Your clan is at peace.", _labelStyle, Array.Empty()); } foreach (War item in activeWarsInvolving) { Clan clan2 = data.GetClan(item.AttackerClanId); Clan clan3 = data.GetClan(item.DefenderClanId); GUILayout.BeginHorizontal(_boxStyle, Array.Empty()); GUILayout.Label($"{item.Type}: {clan2?.Name} vs {clan3?.Name} — " + $"{item.MinutesRemaining:F0} min left", _labelStyle, Array.Empty()); GUILayout.EndHorizontal(); } GUILayout.Space(6f); if (info.Rank < ClanRank.Officer) { GUILayout.Label("Only Officers and the Jarl may declare war or set bounties.", _labelStyle, Array.Empty()); return; } GUILayout.Label($"Declare War (costs {ClanConfig.WarDeclareCost?.Value ?? 200}c)", _labelGoldStyle, Array.Empty()); _scrollA = GUILayout.BeginScrollView(_scrollA, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(150f) }); foreach (Clan value in data.Clans.Values) { if (value.ClanId == info.ClanId) { continue; } bool flag = data.GetActiveWarBetween(info.ClanId, value.ClanId) != null; GUILayout.BeginHorizontal(_boxStyle, Array.Empty()); string text = WarfareManager.ColorHex(value.Color); GUILayout.Label("" + value.Name + " [" + value.Tag + "]", _labelStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(200f) }); if (flag) { GUILayout.Label("at war", _labelStyle, Array.Empty()); } else { if (GUILayout.Button("Raid", _smallButtonStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(60f) })) { WarfareRPC.Instance?.RequestDeclareWar(value.ClanId, WarType.Raid); } if (GUILayout.Button("War", _smallButtonStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(60f) })) { WarfareRPC.Instance?.RequestDeclareWar(value.ClanId, WarType.War); } if (GUILayout.Button("Rage War", _smallButtonStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(86f) })) { WarfareRPC.Instance?.RequestDeclareWar(value.ClanId, WarType.RageWar); } } GUILayout.FlexibleSpace(); if (GUILayout.Button("Bounty", _smallButtonStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(70f) })) { _bountyTargetClan = value.ClanId; } GUILayout.EndHorizontal(); } GUILayout.EndScrollView(); if (_bountyTargetClan != 0) { Clan clan4 = data.GetClan(_bountyTargetClan); GUILayout.BeginHorizontal(_boxStyle, Array.Empty()); GUILayout.Label("Bounty on " + clan4?.Name + ":", _labelStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(160f) }); _bountyInput = GUILayout.TextField(_bountyInput, 9, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(80f) }); if (GUILayout.Button("Place", _smallButtonStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(70f) })) { long result; long amount = (long.TryParse(_bountyInput, out result) ? result : 0); WarfareRPC.Instance?.RequestPlaceBounty(0L, _bountyTargetClan, amount); _bountyTargetClan = 0; } if (GUILayout.Button("Cancel", _smallButtonStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(70f) })) { _bountyTargetClan = 0; } GUILayout.EndHorizontal(); } } private void DrawVault(WarfareData data, PlayerClanInfo info, Clan clan) { //IL_008b: 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_00a4: Unknown result type (might be due to invalid IL or missing references) bool flag = WarfareManager.Instance.IsVaultOpen(); GUILayout.Label(flag ? "VAULT OPEN — withdraw now!" : "Vault closed. Opens on the scheduled day/hour.", _labelGoldStyle, Array.Empty()); List vault = data.GetVault(info.ClanId); int num = ((clan != null) ? Economy.VaultCapacity(clan, data.GetClanTerritoryCount(info.ClanId)) : 0); GUILayout.Label($"{vault.Count}/{num} stacks stored.", _labelStyle, Array.Empty()); GUILayout.Space(4f); _scrollA = GUILayout.BeginScrollView(_scrollA, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandHeight(true) }); if (vault.Count == 0) { GUILayout.Label("The vault is empty. Invaders and Gatherers fill it by farming enemy land.", _labelStyle, Array.Empty()); } foreach (ClanVaultItem item in vault) { GUILayout.Label($" {item.DisplayName}: x{item.Amount}", _labelStyle, Array.Empty()); } GUILayout.EndScrollView(); if (flag && vault.Count > 0 && GUILayout.Button("Withdraw All Items", _buttonStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(30f) })) { WarfareRPC.Instance?.RequestWithdrawVault(info.ClanId); } } private void DrawRole(WarfareData data, PlayerClanInfo info) { GUILayout.Label($"Current role: {info.Role}", _labelGoldStyle, Array.Empty()); bool flag = info.CanChangeRole(ClanConfig.RoleChangeCooldownHours?.Value ?? 24); GUILayout.Label(flag ? "You may change your role now." : "Role change on cooldown.", _labelStyle, Array.Empty()); GUILayout.Space(6f); RoleOption(ClanRole.Explorer, "Explorer", "Claims unclaimed land. +stats in the wild.", flag); RoleOption(ClanRole.Invader, "Invader", "2x loot from enemy land. Cracks enemy vaults.", flag); RoleOption(ClanRole.Gatherer, "Gatherer", "2x resources from enemy land. +carry weight.", flag); RoleOption(ClanRole.Guardian, "Guardian", "+stats & cheap building at home. Holds the line.", flag); RoleOption(ClanRole.Parasite, "Parasite", "Raises rot totems on enemy land. Cheap enemy crafting.", flag); } private void RoleOption(ClanRole role, string name, string desc, bool can) { GUILayout.BeginHorizontal(_boxStyle, Array.Empty()); GUI.enabled = can; if (GUILayout.Button(name, _buttonStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(120f) })) { WarfareRPC.Instance?.RequestSetRole(role); } GUI.enabled = true; GUILayout.Label(desc, _labelStyle, Array.Empty()); GUILayout.EndHorizontal(); } private string EconomyBandColored(int territoryCount) { string text = Economy.EconomyBand(territoryCount); string text2 = ((text == "Profit") ? "88ff88" : ((text == "Balanced") ? "ffd24a" : "ff6666")); return "" + text + ""; } private string ColoredCoins(long v) { return (v >= 0) ? $"+{v}" : $"{v}"; } } } namespace FortecaClanWarfare.Patches { [HarmonyPatch] public static class CombatPatch { private static readonly Dictionary> _lastAttacker = new Dictionary>(); private static bool IsServer => (Object)(object)ZNet.instance != (Object)null && ZNet.instance.IsServer(); private static long Now() { return DateTimeOffset.UtcNow.ToUnixTimeSeconds(); } [HarmonyPatch(typeof(Character), "Damage")] [HarmonyPostfix] public static void RecordAttacker(Character __instance, HitData hit) { //IL_0022: 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_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0073: 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) if (!IsServer || (Object)(object)__instance == (Object)null || hit == null || hit.m_attacker == ZDOID.None) { return; } ZNetScene instance = ZNetScene.instance; GameObject val = ((instance != null) ? instance.FindInstance(hit.m_attacker) : null); if (!((Object)(object)val == (Object)null) && !((Object)(object)val.GetComponent() == (Object)null)) { _lastAttacker[__instance.GetZDOID()] = new KeyValuePair(hit.m_attacker, Now()); if (_lastAttacker.Count > 256) { PruneAttackers(); } } } [HarmonyPatch(typeof(Character), "OnDeath")] [HarmonyPostfix] public static void OnCharacterDeath(Character __instance) { //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_0065: 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_0177: Unknown result type (might be due to invalid IL or missing references) if (!IsServer || (Object)(object)__instance == (Object)null) { return; } WarfareManager instance = WarfareManager.Instance; WarfareData warfareData = instance?.Data; if (warfareData == null || !_lastAttacker.TryGetValue(__instance.GetZDOID(), out var value)) { return; } _lastAttacker.Remove(__instance.GetZDOID()); if (Now() - value.Value > 30) { return; } ZNetScene instance2 = ZNetScene.instance; GameObject val = ((instance2 != null) ? instance2.FindInstance(value.Key) : null); Player val2 = ((val != null) ? val.GetComponent() : null); if ((Object)(object)val2 == (Object)null) { return; } long playerID = val2.GetPlayerID(); int num = warfareData.GetPlayer(playerID)?.ClanId ?? 0; int num2 = 0; if (__instance.IsPlayer()) { num2 = ClanConfig.CombatPointsKill?.Value ?? 500; } else if (__instance.IsBoss()) { num2 = ClanConfig.CombatPointsBoss?.Value ?? 5000; } else if (__instance.GetLevel() > 1) { num2 = ClanConfig.CombatPointsElite?.Value ?? 1000; } if (num2 > 0 && num != 0) { instance.RegisterCombatKill(((Component)__instance).transform.position, num, num2); } if (!__instance.IsPlayer()) { return; } Player val3 = (Player)(object)((__instance is Player) ? __instance : null); if (!((Object)(object)val3 == (Object)null) && !((Object)(object)val3 == (Object)(object)val2)) { long playerID2 = val3.GetPlayerID(); PlayerClanInfo player = warfareData.GetPlayer(playerID2); int num3 = player?.ClanId ?? 0; if (num == 0 || num3 == 0 || !instance.AreAtWar(num, num3)) { instance.RegisterIllegalKill(playerID); } if (player != null && player.Bounty > 0) { instance.CollectBounty(playerID, playerID2); } } } private static void PruneAttackers() { //IL_0043: 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_007a: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) long num = Now() - 60; List list = new List(); foreach (KeyValuePair> item in _lastAttacker) { if (item.Value.Value < num) { list.Add(item.Key); } } foreach (ZDOID item2 in list) { _lastAttacker.Remove(item2); } } } [HarmonyPatch] public static class GuardianBuildPatch { [HarmonyPatch(typeof(Player), "ConsumeResources")] [HarmonyPrefix] public static void ConsumeResources_Prefix(Player __instance, Requirement[] requirements) { //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0073: 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_007a: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)__instance != (Object)(object)Player.m_localPlayer) { return; } WarfareData warfareData = WarfareManager.Instance?.Data; if (warfareData == null) { return; } PlayerClanInfo player = warfareData.GetPlayer(__instance.GetPlayerID()); if (player == null || player.Role != ClanRole.Guardian || player.ClanId == 0) { return; } Vector2i grid = GridExtensions.WorldToGrid(((Component)__instance).transform.position); ClanTerritory territory = warfareData.GetTerritory(grid); if (territory == null || territory.OwnerClanId != player.ClanId) { return; } float num = (ClanConfig.GuardianBuildCostReduction?.Value ?? 50f) / 100f; foreach (Requirement val in requirements) { if (val != null && val.m_amount > 1) { val.m_amount = Math.Max(1, (int)((float)val.m_amount * (1f - num))); } } } } [HarmonyPatch] public static class GuardianPvPPatch { [HarmonyPatch(typeof(Player), "Update")] [HarmonyPostfix] public static void Player_Update(Player __instance) { //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)__instance != (Object)(object)Player.m_localPlayer) { return; } WarfareData warfareData = WarfareManager.Instance?.Data; if (warfareData == null) { return; } PlayerClanInfo player = warfareData.GetPlayer(__instance.GetPlayerID()); if (player != null && player.ClanId != 0) { Vector2i grid = GridExtensions.WorldToGrid(((Component)__instance).transform.position); ClanTerritory territory = warfareData.GetTerritory(grid); bool flag = false; if (player.Role == ClanRole.Guardian && territory != null && territory.OwnerClanId == player.ClanId) { flag = true; } ConfigEntry fullPvPDuringWar = ClanConfig.FullPvPDuringWar; if (fullPvPDuringWar != null && fullPvPDuringWar.Value && territory != null && territory.OwnerClanId != 0 && warfareData.GetActiveWarsInvolving(territory.OwnerClanId).Count > 0) { flag = true; } if (flag && !((Character)__instance).IsPVPEnabled()) { __instance.SetPVP(true); } } } [HarmonyPatch(typeof(Character), "Damage")] [HarmonyPrefix] public static bool PreventFriendlyFire(Character __instance, HitData hit) { //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)__instance == (Object)null || !__instance.IsPlayer()) { return true; } if (hit == null || hit.m_attacker == ZDOID.None) { return true; } ZNetScene instance = ZNetScene.instance; GameObject val = ((instance != null) ? instance.FindInstance(hit.m_attacker) : null); Player val2 = ((val != null) ? val.GetComponent() : null); if ((Object)(object)val2 == (Object)null) { return true; } Player val3 = (Player)(object)((__instance is Player) ? __instance : null); if ((Object)(object)val3 == (Object)null || (Object)(object)val3 == (Object)(object)val2) { return true; } WarfareData warfareData = WarfareManager.Instance?.Data; if (warfareData == null) { return true; } PlayerClanInfo player = warfareData.GetPlayer(val2.GetPlayerID()); PlayerClanInfo player2 = warfareData.GetPlayer(val3.GetPlayerID()); if (player == null || player2 == null) { return true; } if (player.ClanId != 0 && player.ClanId == player2.ClanId) { return false; } return true; } } [HarmonyPatch] public static class InputBlockingPatches { [HarmonyPatch(typeof(Player), "TakeInput")] [HarmonyPrefix] public static bool Player_TakeInput_Prefix(ref bool __result) { if (ClanSelectionUI.ShouldBlockInput()) { __result = false; return false; } return true; } [HarmonyPatch(typeof(PlayerController), "TakeInput")] [HarmonyPrefix] public static bool PlayerController_TakeInput_Prefix(ref bool __result) { if (ClanSelectionUI.ShouldBlockInput()) { __result = false; return false; } return true; } } [HarmonyPatch] public static class ScrollBlockingPatches { [HarmonyPatch(typeof(ZInput), "GetMouseScrollWheel")] [HarmonyPrefix] public static bool ZInput_GetMouseScrollWheel_Prefix(ref float __result) { if (ClanSelectionUI.ShouldBlockInput()) { __result = 0f; return false; } return true; } } [HarmonyPatch] public static class CursorPatches { [HarmonyPatch(typeof(GameCamera), "UpdateMouseCapture")] [HarmonyPrefix] public static bool GameCamera_UpdateMouseCapture_Prefix() { if (ClanSelectionUI.ShouldBlockInput()) { Cursor.lockState = (CursorLockMode)0; Cursor.visible = true; return false; } return true; } } [HarmonyPatch] public static class ParasitePatches { [HarmonyPatch(typeof(CharacterDrop), "GenerateDropList")] [HarmonyPostfix] public static void ReduceLootFromPump(CharacterDrop __instance, ref List> __result) { //IL_0044: 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_004e: 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) if (__result == null || __result.Count == 0) { return; } WarfareData warfareData = WarfareManager.Instance?.Data; if (warfareData == null) { return; } Vector2i grid = GridExtensions.WorldToGrid(((Component)__instance).transform.position); int lootReductionPercent = warfareData.GetLootReductionPercent(grid); if (lootReductionPercent <= 0) { return; } float num = 1f - (float)lootReductionPercent / 100f; if (num <= 0f) { __result.Clear(); return; } for (int i = 0; i < __result.Count; i++) { KeyValuePair keyValuePair = __result[i]; int value = Math.Max(1, (int)((float)keyValuePair.Value * num)); __result[i] = new KeyValuePair(keyValuePair.Key, value); } } private static bool IsParasiteInEnemyTerritory(Player player) { //IL_0058: 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_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) WarfareData warfareData = WarfareManager.Instance?.Data; if (warfareData == null) { return false; } PlayerClanInfo player2 = warfareData.GetPlayer(player.GetPlayerID()); if (player2 == null || player2.Role != ClanRole.Parasite || player2.ClanId == 0) { return false; } Vector2i grid = GridExtensions.WorldToGrid(((Component)player).transform.position); ClanTerritory territory = warfareData.GetTerritory(grid); return territory != null && territory.OwnerClanId != 0 && territory.OwnerClanId != player2.ClanId; } } [HarmonyPatch] public static class RolePatches { [HarmonyPatch(typeof(SEMan), "ModifyAttack")] [HarmonyPostfix] public static void ModifyAttack(SEMan __instance, SkillType skill, ref HitData hitData) { float statMultiplier = GetStatMultiplier(__instance); if (statMultiplier != 1f) { ((DamageTypes)(ref hitData.m_damage)).Modify(statMultiplier); } } [HarmonyPatch(typeof(Character), "RPC_Damage")] [HarmonyPrefix] public static void ModifyDefense(Character __instance, HitData hit) { if (__instance.IsPlayer()) { float statMultiplier = GetStatMultiplier(__instance.GetSEMan()); if (statMultiplier != 1f && statMultiplier < 1f) { ((DamageTypes)(ref hit.m_damage)).Modify(1f / statMultiplier); } else if (statMultiplier > 1f) { ((DamageTypes)(ref hit.m_damage)).Modify(1f / statMultiplier); } } } private static float GetStatMultiplier(SEMan seMan) { //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: 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_00ae: Unknown result type (might be due to invalid IL or missing references) if (seMan == null) { return 1f; } Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null || (Object)(object)localPlayer != (Object)(object)Player.m_localPlayer) { return 1f; } WarfareData warfareData = WarfareManager.Instance?.Data; if (warfareData == null) { return 1f; } PlayerClanInfo player = warfareData.GetPlayer(localPlayer.GetPlayerID()); if (player == null || player.ClanId == 0) { return 1f; } Vector2i grid = GridExtensions.WorldToGrid(((Component)localPlayer).transform.position); ClanTerritory territory = warfareData.GetTerritory(grid); float num = 1f + (ClanConfig.RoleBuffPercent?.Value ?? 20f) / 100f; float num2 = 1f - (ClanConfig.RoleDebuffPercent?.Value ?? 20f) / 100f; bool flag = territory != null && territory.OwnerClanId == player.ClanId; bool flag2 = territory != null && territory.OwnerClanId != 0 && territory.OwnerClanId != player.ClanId; bool flag3 = territory == null || territory.OwnerClanId == 0; return player.Role switch { ClanRole.Explorer => flag3 ? num : ((flag || flag2) ? num2 : 1f), ClanRole.Guardian => flag ? num : num2, ClanRole.Invader => flag2 ? num : 1f, _ => 1f, }; } [HarmonyPatch(typeof(Player), "GetMaxCarryWeight")] [HarmonyPostfix] public static void GathererCarryWeight(Player __instance, ref float __result) { if ((Object)(object)__instance != (Object)(object)Player.m_localPlayer) { return; } WarfareData warfareData = WarfareManager.Instance?.Data; if (warfareData != null) { PlayerClanInfo player = warfareData.GetPlayer(__instance.GetPlayerID()); if (player != null && player.Role == ClanRole.Gatherer) { __result += ClanConfig.GathererCarryWeightBonus?.Value ?? 500; } } } [HarmonyPatch(typeof(CharacterDrop), "GenerateDropList")] [HarmonyPostfix] public static void DoubleLoot(CharacterDrop __instance, ref List> __result) { //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) if (__result == null || __result.Count == 0) { return; } Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null) { return; } WarfareData warfareData = WarfareManager.Instance?.Data; if (warfareData == null) { return; } PlayerClanInfo player = warfareData.GetPlayer(localPlayer.GetPlayerID()); if (player == null || player.ClanId == 0 || (player.Role != ClanRole.Invader && player.Role != ClanRole.Gatherer)) { return; } Vector2i grid = GridExtensions.WorldToGrid(((Component)__instance).transform.position); ClanTerritory territory = warfareData.GetTerritory(grid); if (territory == null || territory.OwnerClanId == 0 || territory.OwnerClanId == player.ClanId) { return; } foreach (KeyValuePair item in __result) { if (!((Object)(object)item.Key == (Object)null)) { ItemDrop component = item.Key.GetComponent(); if (component?.m_itemData?.m_shared != null) { string name = ((Object)item.Key).name; string name2 = component.m_itemData.m_shared.m_name; int value = item.Value; WarfareRPC.Instance?.SendItemToClanVault(player.ClanId, name, name2, value); } } } } [HarmonyPatch(typeof(Player), "OnSpawned")] [HarmonyPostfix] public static void OnPlayerSpawned(Player __instance) { if ((Object)(object)__instance != (Object)(object)Player.m_localPlayer) { return; } WarfareRPC.Instance?.RequestDataFromServer(); WarfareData warfareData = WarfareManager.Instance?.Data; if (warfareData != null) { PlayerClanInfo player = warfareData.GetPlayer(__instance.GetPlayerID()); if (player == null || player.ClanId == 0) { Plugin.Log.LogInfo((object)"Player needs clan selection."); } } } [HarmonyPatch(typeof(ZNet), "Awake")] [HarmonyPostfix] public static void ZNet_Awake(ZNet __instance) { if (__instance.IsServer()) { WarfareManager.Instance?.InitServer(); } } [HarmonyPatch(typeof(ZNet), "Shutdown")] [HarmonyPrefix] public static void ZNet_Shutdown() { ZNet instance = ZNet.instance; if (instance != null && instance.IsServer()) { WarfareManager.Instance?.SaveData(); } } [HarmonyPatch(typeof(Game), "SavePlayerProfile")] [HarmonyPrefix] public static void Game_Save() { ZNet instance = ZNet.instance; if (instance != null && instance.IsServer()) { WarfareManager.Instance?.SaveData(); } } } [HarmonyPatch] public static class TabMenuPatch { private static GameObject _clanButton; private static bool _created; private static bool _showButton; private static bool _guiInit; private static GUIStyle _btnStyle; [HarmonyPatch(typeof(InventoryGui), "Show")] [HarmonyPostfix] public static void InventoryGui_Show(InventoryGui __instance) { //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Expected O, but got Unknown if (_created && (Object)(object)_clanButton != (Object)null) { _clanButton.SetActive(true); return; } try { Transform val = null; foreach (Transform item in ((Component)__instance.m_player).transform.parent) { Transform val2 = item; if (((Object)val2).name.Contains("Trophie") || ((Object)val2).name.Contains("Trophy")) { val = val2; break; } } _created = true; } catch { _created = true; } } [HarmonyPatch(typeof(InventoryGui), "Hide")] [HarmonyPostfix] public static void InventoryGui_Hide() { if ((Object)(object)_clanButton != (Object)null) { _clanButton.SetActive(false); } } [HarmonyPatch(typeof(InventoryGui), "Update")] [HarmonyPostfix] public static void InventoryGui_Update(InventoryGui __instance) { _showButton = true; } public static void DrawButton() { //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_004d: 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_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Expected O, but got Unknown //IL_007a: Expected O, but got Unknown //IL_0093: Unknown result type (might be due to invalid IL or missing references) if (!_showButton) { return; } if (!InventoryGui.IsVisible()) { _showButton = false; return; } if (!_guiInit) { _guiInit = true; _btnStyle = new GUIStyle(GUI.skin.button) { fontSize = 14, fontStyle = (FontStyle)1, padding = new RectOffset(10, 10, 6, 6) }; _btnStyle.normal.textColor = new Color(1f, 0.85f, 0.4f); } float num = (float)Screen.height / 1080f; float num2 = 160f * num; float num3 = 32f * num; float num4 = (float)(Screen.width / 2) - num2 / 2f; float num5 = 8f * num; if (GUI.Button(new Rect(num4, num5, num2, num3), "Clan Warfare [F3]", _btnStyle) && (Object)(object)WarfareHUD.Instance != (Object)null) { WarfareHUD.Instance.Toggle(); } } } public class TabMenuButtonRenderer : MonoBehaviour { private void OnGUI() { TabMenuPatch.DrawButton(); } } [HarmonyPatch] public static class VaultCrackMonitor { [HarmonyPatch(typeof(Character), "OnDeath")] [HarmonyPostfix] public static void OnDeath(Character __instance) { if (!__instance.IsPlayer()) { return; } ZNet instance = ZNet.instance; if (instance == null || !instance.IsServer()) { return; } Player val = (Player)(object)((__instance is Player) ? __instance : null); if ((Object)(object)val == (Object)null) { return; } long playerId = val.GetPlayerID(); WarfareData warfareData = WarfareManager.Instance?.Data; if (warfareData != null) { VaultCrackSession vaultCrackSession = warfareData.ActiveCracks.Find((VaultCrackSession c) => c.PlayerId == playerId); if (vaultCrackSession != null) { warfareData.ActiveCracks.Remove(vaultCrackSession); string message = "" + vaultCrackSession.PlayerName + " died while cracking a vault! Attempt failed."; WarfareRPC.Instance?.BroadcastGlobalMessage(message); Plugin.Log.LogInfo((object)("Vault crack cancelled (death): " + vaultCrackSession.PlayerName)); } } } public static void CheckActiveCracks() { //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: 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_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_010d: Unknown result type (might be due to invalid IL or missing references) WarfareData warfareData = WarfareManager.Instance?.Data; if (warfareData == null || warfareData.ActiveCracks.Count == 0) { return; } for (int num = warfareData.ActiveCracks.Count - 1; num >= 0; num--) { VaultCrackSession vaultCrackSession = warfareData.ActiveCracks[num]; Player val = null; foreach (Player allPlayer in Player.GetAllPlayers()) { if (allPlayer.GetPlayerID() == vaultCrackSession.PlayerId) { val = allPlayer; break; } } if ((Object)(object)val == (Object)null) { warfareData.ActiveCracks.RemoveAt(num); WarfareRPC.Instance?.BroadcastGlobalMessage("" + vaultCrackSession.PlayerName + " disconnected during vault crack! Attempt failed."); } else { Vector2i val2 = GridExtensions.WorldToGrid(((Component)val).transform.position); if (val2.x != vaultCrackSession.TerritoryGridX || val2.y != vaultCrackSession.TerritoryGridY) { warfareData.ActiveCracks.RemoveAt(num); WarfareRPC.Instance?.BroadcastGlobalMessage("" + vaultCrackSession.PlayerName + " left the territory! Vault crack failed."); } else if (vaultCrackSession.IsComplete) { Plugin.Log.LogInfo((object)$"Vault crack in progress: {vaultCrackSession.PlayerName} ({vaultCrackSession.MinutesElapsed:F1}min)"); } } } } } } namespace FortecaClanWarfare.Network { public class WarfareRPC : MonoBehaviour { private const string RPC_SyncData = "FCW_SyncData"; private const string RPC_RequestData = "FCW_RequestData"; private const string RPC_CreateClan = "FCW_CreateClan"; private const string RPC_JoinClan = "FCW_JoinClan"; private const string RPC_LeaveClan = "FCW_LeaveClan"; private const string RPC_DisbandClan = "FCW_DisbandClan"; private const string RPC_KickMember = "FCW_KickMember"; private const string RPC_SetRank = "FCW_SetRank"; private const string RPC_SetRole = "FCW_SetRole"; private const string RPC_CastVote = "FCW_CastVote"; private const string RPC_ClaimTerritory = "FCW_ClaimTerritory"; private const string RPC_ClaimResult = "FCW_ClaimResult"; private const string RPC_RenameTerritory = "FCW_RenameTerritory"; private const string RPC_UpgradeTerritory = "FCW_UpgradeTerritory"; private const string RPC_SetCapital = "FCW_SetCapital"; private const string RPC_BuyExpansion = "FCW_BuyExpansion"; private const string RPC_UpgradeVault = "FCW_UpgradeVault"; private const string RPC_WithdrawVault = "FCW_WithdrawVault"; private const string RPC_AddToVault = "FCW_AddToVault"; private const string RPC_StartVaultCrack = "FCW_StartVaultCrack"; private const string RPC_CancelVaultCrack = "FCW_CancelVaultCrack"; private const string RPC_DeclareWar = "FCW_DeclareWar"; private const string RPC_PlaceRotTotem = "FCW_PlaceRotTotem"; private const string RPC_PlaceBounty = "FCW_PlaceBounty"; private const string RPC_Notification = "FCW_Notification"; private const string RPC_GlobalMessage = "FCW_GlobalMessage"; private bool _registered; public static WarfareRPC Instance { get; private set; } private static bool IsServer => (Object)(object)ZNet.instance != (Object)null && ZNet.instance.IsServer(); private static long LocalId { get { Player localPlayer = Player.m_localPlayer; return (localPlayer != null) ? localPlayer.GetPlayerID() : 0; } } private static string LocalName { get { Player localPlayer = Player.m_localPlayer; return ((localPlayer != null) ? localPlayer.GetPlayerName() : null) ?? ""; } } public event Action OnNotificationReceived; private void Awake() { if ((Object)(object)Instance != (Object)null && (Object)(object)Instance != (Object)(object)this) { Object.Destroy((Object)(object)this); } else { Instance = this; } } private void Update() { if (!_registered) { TryRegister(); } } private void TryRegister() { if (!_registered && ZRoutedRpc.instance != null) { _registered = true; ZRoutedRpc.instance.Register("FCW_SyncData", (Action)RPC_OnSyncData); ZRoutedRpc.instance.Register("FCW_RequestData", (Action)RPC_OnRequestData); ZRoutedRpc.instance.Register("FCW_CreateClan", (Action)RPC_OnCreateClan); ZRoutedRpc.instance.Register("FCW_JoinClan", (Action)RPC_OnJoinClan); ZRoutedRpc.instance.Register("FCW_LeaveClan", (Action)RPC_OnLeaveClan); ZRoutedRpc.instance.Register("FCW_DisbandClan", (Action)RPC_OnDisbandClan); ZRoutedRpc.instance.Register("FCW_KickMember", (Action)RPC_OnKickMember); ZRoutedRpc.instance.Register("FCW_SetRank", (Action)RPC_OnSetRank); ZRoutedRpc.instance.Register("FCW_SetRole", (Action)RPC_OnSetRole); ZRoutedRpc.instance.Register("FCW_CastVote", (Action)RPC_OnCastVote); ZRoutedRpc.instance.Register("FCW_ClaimTerritory", (Action)RPC_OnClaimTerritory); ZRoutedRpc.instance.Register("FCW_ClaimResult", (Action)RPC_OnClaimResult); ZRoutedRpc.instance.Register("FCW_RenameTerritory", (Action)RPC_OnRenameTerritory); ZRoutedRpc.instance.Register("FCW_UpgradeTerritory", (Action)RPC_OnUpgradeTerritory); ZRoutedRpc.instance.Register("FCW_SetCapital", (Action)RPC_OnSetCapital); ZRoutedRpc.instance.Register("FCW_BuyExpansion", (Action)RPC_OnBuyExpansion); ZRoutedRpc.instance.Register("FCW_UpgradeVault", (Action)RPC_OnUpgradeVault); ZRoutedRpc.instance.Register("FCW_WithdrawVault", (Action)RPC_OnWithdrawVault); ZRoutedRpc.instance.Register("FCW_AddToVault", (Action)RPC_OnAddToVault); ZRoutedRpc.instance.Register("FCW_StartVaultCrack", (Action)RPC_OnStartVaultCrack); ZRoutedRpc.instance.Register("FCW_CancelVaultCrack", (Action)RPC_OnCancelVaultCrack); ZRoutedRpc.instance.Register("FCW_DeclareWar", (Action)RPC_OnDeclareWar); ZRoutedRpc.instance.Register("FCW_PlaceRotTotem", (Action)RPC_OnPlaceRotTotem); ZRoutedRpc.instance.Register("FCW_PlaceBounty", (Action)RPC_OnPlaceBounty); ZRoutedRpc.instance.Register("FCW_Notification", (Action)RPC_OnNotification); ZRoutedRpc.instance.Register("FCW_GlobalMessage", (Action)RPC_OnGlobalMessage); Plugin.Log.LogInfo((object)"Warfare RPCs registered."); } } private long GetServerPeerID() { if ((Object)(object)ZNet.instance == (Object)null) { return 0L; } if (ZNet.instance.IsServer()) { return ZNet.GetUID(); } return ZNet.instance.GetServerPeer()?.m_uid ?? 0; } private void ToServer(string rpc, ZPackage pkg) { ZRoutedRpc instance = ZRoutedRpc.instance; if (instance != null) { instance.InvokeRoutedRPC(GetServerPeerID(), rpc, new object[1] { pkg }); } } public void RequestDataFromServer() { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown ZPackage val = new ZPackage(); val.Write(LocalId); ToServer("FCW_RequestData", val); } private void RPC_OnRequestData(long sender, ZPackage pkg) { if (IsServer) { SyncDataToClient(sender); } } public void SyncAllDataToClients() { //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Expected O, but got Unknown if (!IsServer) { return; } byte[] array = WarfareManager.Instance?.Data?.Serialize(); if (array != null) { ZRoutedRpc instance = ZRoutedRpc.instance; if (instance != null) { instance.InvokeRoutedRPC(ZRoutedRpc.Everybody, "FCW_SyncData", new object[1] { (object)new ZPackage(array) }); } } } private void SyncDataToClient(long peerUID) { //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Expected O, but got Unknown byte[] array = WarfareManager.Instance?.Data?.Serialize(); if (array != null) { ZRoutedRpc instance = ZRoutedRpc.instance; if (instance != null) { instance.InvokeRoutedRPC(peerUID, "FCW_SyncData", new object[1] { (object)new ZPackage(array) }); } } } private void RPC_OnSyncData(long sender, ZPackage pkg) { if (!IsServer) { WarfareManager.Instance?.ApplyServerData(WarfareData.Deserialize(pkg.GetArray())); } } public void RequestCreateClan(string name, string tag, int colorIndex, int iconIndex) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Expected O, but got Unknown if (!((Object)(object)Player.m_localPlayer == (Object)null)) { ZPackage val = new ZPackage(); val.Write(LocalId); val.Write(LocalName); val.Write(name ?? ""); val.Write(tag ?? ""); val.Write(colorIndex); val.Write(iconIndex); ToServer("FCW_CreateClan", val); } } private void RPC_OnCreateClan(long sender, ZPackage pkg) { if (IsServer) { long playerId = pkg.ReadLong(); string playerName = pkg.ReadString(); string name = pkg.ReadString(); string tag = pkg.ReadString(); int colorIndex = pkg.ReadInt(); int iconIndex = pkg.ReadInt(); string message = WarfareManager.Instance?.CreateClan(playerId, playerName, name, tag, colorIndex, iconIndex) ?? "Failed"; SendNotification(sender, message); SyncAllDataToClients(); } } public void RequestJoinClan(int clanId) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Expected O, but got Unknown if (!((Object)(object)Player.m_localPlayer == (Object)null)) { ZPackage val = new ZPackage(); val.Write(LocalId); val.Write(LocalName); val.Write(clanId); ToServer("FCW_JoinClan", val); } } private void RPC_OnJoinClan(long sender, ZPackage pkg) { if (IsServer) { long playerId = pkg.ReadLong(); string playerName = pkg.ReadString(); int clanId = pkg.ReadInt(); string message = WarfareManager.Instance?.JoinClan(playerId, playerName, clanId) ?? "Failed"; SendNotification(sender, message); SyncAllDataToClients(); } } public void RequestLeaveClan() { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown ZPackage val = new ZPackage(); val.Write(LocalId); ToServer("FCW_LeaveClan", val); } private void RPC_OnLeaveClan(long sender, ZPackage pkg) { if (IsServer) { string message = WarfareManager.Instance?.LeaveClan(pkg.ReadLong()) ?? "Failed"; SendNotification(sender, message); SyncAllDataToClients(); } } public void RequestDisbandClan() { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown ZPackage val = new ZPackage(); val.Write(LocalId); ToServer("FCW_DisbandClan", val); } private void RPC_OnDisbandClan(long sender, ZPackage pkg) { if (IsServer) { string message = WarfareManager.Instance?.DisbandClan(pkg.ReadLong()) ?? "Failed"; SendNotification(sender, message); SyncAllDataToClients(); } } public void RequestKickMember(long targetId) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown ZPackage val = new ZPackage(); val.Write(LocalId); val.Write(targetId); ToServer("FCW_KickMember", val); } private void RPC_OnKickMember(long sender, ZPackage pkg) { if (IsServer) { string message = WarfareManager.Instance?.KickMember(pkg.ReadLong(), pkg.ReadLong()) ?? "Failed"; SendNotification(sender, message); SyncAllDataToClients(); } } public void RequestSetRank(long targetId, ClanRank rank) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown ZPackage val = new ZPackage(); val.Write(LocalId); val.Write(targetId); val.Write((int)rank); ToServer("FCW_SetRank", val); } private void RPC_OnSetRank(long sender, ZPackage pkg) { if (IsServer) { string message = WarfareManager.Instance?.SetRank(pkg.ReadLong(), pkg.ReadLong(), (ClanRank)pkg.ReadInt()) ?? "Failed"; SendNotification(sender, message); SyncAllDataToClients(); } } public void RequestSetRole(ClanRole role) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown ZPackage val = new ZPackage(); val.Write(LocalId); val.Write((int)role); ToServer("FCW_SetRole", val); } private void RPC_OnSetRole(long sender, ZPackage pkg) { if (IsServer) { string message = WarfareManager.Instance?.SetPlayerRole(pkg.ReadLong(), (ClanRole)pkg.ReadInt()) ?? "Failed"; SendNotification(sender, message); SyncAllDataToClients(); } } public void RequestCastVote(long candidateId) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown ZPackage val = new ZPackage(); val.Write(LocalId); val.Write(candidateId); ToServer("FCW_CastVote", val); } private void RPC_OnCastVote(long sender, ZPackage pkg) { if (IsServer) { string message = WarfareManager.Instance?.CastElectionVote(pkg.ReadLong(), pkg.ReadLong()) ?? "Failed"; SendNotification(sender, message); SyncAllDataToClients(); } } public void RequestClaimTerritory(Vector2i grid) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Expected O, but got Unknown //IL_0031: 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) if (!((Object)(object)Player.m_localPlayer == (Object)null)) { ZPackage val = new ZPackage(); val.Write(LocalId); val.Write(LocalName); val.Write(grid.x); val.Write(grid.y); ToServer("FCW_ClaimTerritory", val); } } private void RPC_OnClaimTerritory(long sender, ZPackage pkg) { //IL_0040: 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_0053: Expected O, but got Unknown if (IsServer) { long playerId = pkg.ReadLong(); string playerName = pkg.ReadString(); int num = pkg.ReadInt(); int num2 = pkg.ReadInt(); WarfareManager.ClaimResult claimResult = WarfareManager.Instance?.TryClaimTerritory(playerId, playerName, new Vector2i(num, num2)); ZPackage val = new ZPackage(); val.Write(claimResult?.Success ?? false); val.Write(claimResult?.Message ?? "Unknown error"); ZRoutedRpc instance = ZRoutedRpc.instance; if (instance != null) { instance.InvokeRoutedRPC(sender, "FCW_ClaimResult", new object[1] { val }); } if (claimResult != null && claimResult.Success) { SyncAllDataToClients(); } } } private void RPC_OnClaimResult(long sender, ZPackage pkg) { bool flag = pkg.ReadBool(); string text = pkg.ReadString(); MessageHud instance = MessageHud.instance; if (instance != null) { instance.ShowMessage((MessageType)2, flag ? ("" + text + "") : ("" + text + ""), 0, (Sprite)null, false); } } public void RequestRenameTerritory(Vector2i grid, string newName) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) ZPackage val = new ZPackage(); val.Write(LocalId); val.Write(grid.x); val.Write(grid.y); val.Write(newName ?? ""); ToServer("FCW_RenameTerritory", val); } private void RPC_OnRenameTerritory(long sender, ZPackage pkg) { //IL_003c: Unknown result type (might be due to invalid IL or missing references) if (IsServer) { long playerId = pkg.ReadLong(); int num = pkg.ReadInt(); int num2 = pkg.ReadInt(); string newName = pkg.ReadString(); string message = WarfareManager.Instance?.TryRenameTerritory(playerId, new Vector2i(num, num2), newName) ?? "Failed"; SendNotification(sender, message); SyncAllDataToClients(); } } public void RequestUpgradeTerritory(Vector2i grid) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) ZPackage val = new ZPackage(); val.Write(LocalId); val.Write(grid.x); val.Write(grid.y); ToServer("FCW_UpgradeTerritory", val); } private void RPC_OnUpgradeTerritory(long sender, ZPackage pkg) { //IL_002d: Unknown result type (might be due to invalid IL or missing references) if (IsServer) { string message = WarfareManager.Instance?.UpgradeTerritory(pkg.ReadLong(), new Vector2i(pkg.ReadInt(), pkg.ReadInt())) ?? "Failed"; SendNotification(sender, message); SyncAllDataToClients(); } } public void RequestSetCapital(Vector2i grid) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) ZPackage val = new ZPackage(); val.Write(LocalId); val.Write(grid.x); val.Write(grid.y); ToServer("FCW_SetCapital", val); } private void RPC_OnSetCapital(long sender, ZPackage pkg) { //IL_002d: Unknown result type (might be due to invalid IL or missing references) if (IsServer) { string message = WarfareManager.Instance?.SetCapital(pkg.ReadLong(), new Vector2i(pkg.ReadInt(), pkg.ReadInt())) ?? "Failed"; SendNotification(sender, message); SyncAllDataToClients(); } } public void RequestBuyExpansion() { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown ZPackage val = new ZPackage(); val.Write(LocalId); ToServer("FCW_BuyExpansion", val); } private void RPC_OnBuyExpansion(long sender, ZPackage pkg) { if (IsServer) { string message = WarfareManager.Instance?.BuyTerritoryExpansion(pkg.ReadLong()) ?? "Failed"; SendNotification(sender, message); SyncAllDataToClients(); } } public void RequestUpgradeVault() { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown ZPackage val = new ZPackage(); val.Write(LocalId); ToServer("FCW_UpgradeVault", val); } private void RPC_OnUpgradeVault(long sender, ZPackage pkg) { if (IsServer) { string message = WarfareManager.Instance?.UpgradeVault(pkg.ReadLong()) ?? "Failed"; SendNotification(sender, message); SyncAllDataToClients(); } } public void RequestWithdrawVault(int clanId) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown ZPackage val = new ZPackage(); val.Write(LocalId); val.Write(clanId); ToServer("FCW_WithdrawVault", val); } private void RPC_OnWithdrawVault(long sender, ZPackage pkg) { //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Expected O, but got Unknown if (!IsServer) { return; } long playerId = pkg.ReadLong(); int num = pkg.ReadInt(); WarfareManager instance = WarfareManager.Instance; if ((Object)(object)instance == (Object)null) { return; } if (!instance.IsVaultOpen()) { SendNotification(sender, "The vault is closed."); return; } WarfareData data = instance.Data; PlayerClanInfo player = data.GetPlayer(playerId); if (player == null || player.ClanId != num) { SendNotification(sender, "That is not your clan's vault."); return; } List vault = data.GetVault(num); foreach (ClanVaultItem item in vault) { ZPackage val = new ZPackage(); val.Write(false); val.Write(item.PrefabName); val.Write(item.Amount); ZRoutedRpc instance2 = ZRoutedRpc.instance; if (instance2 != null) { instance2.InvokeRoutedRPC(sender, "FCW_AddToVault", new object[1] { val }); } } vault.Clear(); instance.MarkDirty(); SyncAllDataToClients(); SendNotification(sender, "Vault contents withdrawn."); } private void RPC_OnAddToVault(long sender, ZPackage pkg) { bool flag = pkg.ReadBool(); if (flag && IsServer) { int clanId = pkg.ReadInt(); string prefab = pkg.ReadString(); string displayName = pkg.ReadString(); int amount = pkg.ReadInt(); WarfareManager instance = WarfareManager.Instance; WarfareData warfareData = instance?.Data; if (warfareData != null) { Clan clan = warfareData.GetClan(clanId); int num = Economy.VaultCapacity(clan, warfareData.GetClanTerritoryCount(clanId)); if (warfareData.GetVaultStackCount(clanId) < num || warfareData.GetVault(clanId).Find((ClanVaultItem v) => v.PrefabName == prefab) != null) { warfareData.AddToVault(clanId, prefab, displayName, amount); instance.MarkDirty(); } } } else { if (flag || IsServer) { return; } string text = pkg.ReadString(); int num2 = pkg.ReadInt(); Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null) { return; } ObjectDB instance2 = ObjectDB.instance; GameObject val = ((instance2 != null) ? instance2.GetItemPrefab(text) : null); if ((Object)(object)val != (Object)null) { Inventory inventory = ((Humanoid)localPlayer).GetInventory(); if (inventory != null) { inventory.AddItem(val, num2); } } } } public void SendItemToClanVault(int clanId, string prefab, string display, int amount) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown ZPackage val = new ZPackage(); val.Write(true); val.Write(clanId); val.Write(prefab ?? ""); val.Write(display ?? ""); val.Write(amount); ToServer("FCW_AddToVault", val); } public void RequestStartVaultCrack(Vector2i grid) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Expected O, but got Unknown //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0040: 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) Player localPlayer = Player.m_localPlayer; if (!((Object)(object)localPlayer == (Object)null)) { ZPackage val = new ZPackage(); val.Write(LocalId); val.Write(LocalName); val.Write(grid.x); val.Write(grid.y); val.Write(((Component)localPlayer).transform.position); ToServer("FCW_StartVaultCrack", val); } } private void RPC_OnStartVaultCrack(long sender, ZPackage pkg) { //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_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) if (IsServer) { long playerId = pkg.ReadLong(); string playerName = pkg.ReadString(); int num = pkg.ReadInt(); int num2 = pkg.ReadInt(); Vector3 pos = pkg.ReadVector3(); string message = WarfareManager.Instance?.StartVaultCrack(playerId, playerName, new Vector2i(num, num2), pos) ?? "Failed"; SendNotification(sender, message); } } public void RequestCancelVaultCrack() { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown ZPackage val = new ZPackage(); val.Write(LocalId); ToServer("FCW_CancelVaultCrack", val); } private void RPC_OnCancelVaultCrack(long sender, ZPackage pkg) { if (IsServer) { long playerId = pkg.ReadLong(); WarfareManager.Instance?.Data?.ActiveCracks.RemoveAll((VaultCrackSession c) => c.PlayerId == playerId); SendNotification(sender, "Vault crack cancelled."); } } public void RequestDeclareWar(int targetClanId, WarType type) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown ZPackage val = new ZPackage(); val.Write(LocalId); val.Write(targetClanId); val.Write((int)type); ToServer("FCW_DeclareWar", val); } private void RPC_OnDeclareWar(long sender, ZPackage pkg) { if (IsServer) { string message = WarfareManager.Instance?.DeclareWar(pkg.ReadLong(), pkg.ReadInt(), (WarType)pkg.ReadInt()) ?? "Failed"; SendNotification(sender, message); SyncAllDataToClients(); } } public void RequestPlaceRotTotem() { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Expected O, but got Unknown //IL_0039: Unknown result type (might be due to invalid IL or missing references) Player localPlayer = Player.m_localPlayer; if (!((Object)(object)localPlayer == (Object)null)) { ZPackage val = new ZPackage(); val.Write(LocalId); val.Write(LocalName); val.Write(((Component)localPlayer).transform.position); ToServer("FCW_PlaceRotTotem", val); } } private void RPC_OnPlaceRotTotem(long sender, ZPackage pkg) { //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_0034: Unknown result type (might be due to invalid IL or missing references) if (IsServer) { long playerId = pkg.ReadLong(); string playerName = pkg.ReadString(); Vector3 worldPos = pkg.ReadVector3(); string message = WarfareManager.Instance?.PlaceRotTotem(playerId, playerName, worldPos) ?? "Failed"; SendNotification(sender, message); SyncAllDataToClients(); } } public void RequestPlaceBounty(long targetPlayerId, int targetClanId, long amount) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown ZPackage val = new ZPackage(); val.Write(LocalId); val.Write(targetPlayerId); val.Write(targetClanId); val.Write(amount); ToServer("FCW_PlaceBounty", val); } private void RPC_OnPlaceBounty(long sender, ZPackage pkg) { if (IsServer) { string message = WarfareManager.Instance?.PlaceBounty(pkg.ReadLong(), pkg.ReadLong(), pkg.ReadInt(), pkg.ReadLong()) ?? "Failed"; SendNotification(sender, message); SyncAllDataToClients(); } } public void SendNotification(long peerUID, string message) { ZRoutedRpc instance = ZRoutedRpc.instance; if (instance != null) { instance.InvokeRoutedRPC(peerUID, "FCW_Notification", new object[1] { message }); } } public void BroadcastGlobalMessage(string message) { ZRoutedRpc instance = ZRoutedRpc.instance; if (instance != null) { instance.InvokeRoutedRPC(ZRoutedRpc.Everybody, "FCW_GlobalMessage", new object[1] { message }); } } private void RPC_OnNotification(long sender, string message) { this.OnNotificationReceived?.Invoke(message); MessageHud instance = MessageHud.instance; if (instance != null) { instance.ShowMessage((MessageType)2, message, 0, (Sprite)null, false); } } private void RPC_OnGlobalMessage(long sender, string message) { MessageHud instance = MessageHud.instance; if (instance != null) { instance.ShowMessage((MessageType)2, message, 0, (Sprite)null, false); } } } } namespace FortecaClanWarfare.Data { public enum ClanRole { None, Explorer, Invader, Gatherer, Guardian, Parasite } public enum ClanRank { Member, Officer, Jarl } public enum TerritoryType { Colony, Capital } public enum TerritoryState { Normal, Contested, Attacked, Rooted, Captured } public enum WarType { None, Raid, War, RageWar } public enum TotemState { Placed, Active, Decay, Destroyed } [Serializable] public class Clan { public int ClanId; public string Name; public string Tag; public int IconIndex; public float ColorR = 0.7f; public float ColorG = 0.5f; public float ColorB = 0.2f; public long FounderId; public long JarlId; public long Treasury; public int VaultTier = 1; public int ExtraTerritorySlots; public long CreatedTimestamp; public long NextElectionTimestamp; public long Bounty; public Dictionary ElectionVotes = new Dictionary(); public Color Color => new Color(ColorR, ColorG, ColorB, 1f); public string Symbol => Tag; public void SetColor(Color c) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) ColorR = c.r; ColorG = c.g; ColorB = c.b; } } [Serializable] public class PlayerClanInfo { public long PlayerId; public string PlayerName; public int ClanId; public ClanRole Role; public ClanRank Rank = ClanRank.Member; public long LastRoleChangeTimestamp; public long LastVaultCrackTimestamp; public long JoinedClanTimestamp; public long LastClanLeaveTimestamp; public long LastSeenTimestamp; public long Bounty; public bool CanChangeRole(double cooldownHours = 24.0) { if (LastRoleChangeTimestamp == 0) { return true; } double num = (double)(Now() - LastRoleChangeTimestamp) / 3600.0; return num >= cooldownHours; } public bool CanCrackVault(double cooldownHours = 6.0) { if (LastVaultCrackTimestamp == 0) { return true; } double num = (double)(Now() - LastVaultCrackTimestamp) / 3600.0; return num >= cooldownHours; } public bool CanJoinClan(double cooldownHours) { if (LastClanLeaveTimestamp == 0) { return true; } double num = (double)(Now() - LastClanLeaveTimestamp) / 3600.0; return num >= cooldownHours; } private static long Now() { return DateTimeOffset.UtcNow.ToUnixTimeSeconds(); } } [Serializable] public class ClanTerritory { public int GridX; public int GridY; public int OwnerClanId; public long ClaimedByPlayerId; public string ClaimedByPlayerName; public long ClaimTimestamp; public string CustomName; public long LastRenameTimestamp; public TerritoryType Type = TerritoryType.Colony; public TerritoryState State = TerritoryState.Normal; public int SizeLevel = 1; public int BiomeValueTier = 1; public int RotCount; public long LastRotTickTimestamp; public long LastIncomeTimestamp; public float HP; public float MaxHP; [NonSerialized] public float CaptureProgress; [NonSerialized] public int CaptureAttackerClanId; public Vector2i GridPosition => new Vector2i(GridX, GridY); public string DisplayName => (!string.IsNullOrEmpty(CustomName)) ? CustomName : $"({GridX}, {GridY})"; public bool IsRotted => RotCount >= 4; public bool IsCapital => Type == TerritoryType.Capital; public bool CanRename(double cooldownHours = 24.0) { if (LastRenameTimestamp == 0) { return true; } double num = (double)(DateTimeOffset.UtcNow.ToUnixTimeSeconds() - LastRenameTimestamp) / 3600.0; return num >= cooldownHours; } } [Serializable] public class ClanVaultItem { public string PrefabName; public string DisplayName; public int Amount; } [Serializable] public class RotTotem { public int TerritoryGridX; public int TerritoryGridY; public long PlacedByPlayerId; public string PlacedByPlayerName; public int PlacerClanId; public long PlacedTimestamp; public Vector3 WorldPosition; public TotemState State = TotemState.Placed; public int Level = 1; public long LastDecayTimestamp; public int DaysActive => (int)((DateTimeOffset.UtcNow.ToUnixTimeSeconds() - PlacedTimestamp) / 86400); public int LootReductionPercent => Math.Min(DaysActive * 10, 100); public Vector2i GridPosition => new Vector2i(TerritoryGridX, TerritoryGridY); } [Serializable] public class War { public int WarId; public int AttackerClanId; public int DefenderClanId; public WarType Type = WarType.War; public long StartTimestamp; public long EndTimestamp; public bool IsActive => DateTimeOffset.UtcNow.ToUnixTimeSeconds() < EndTimestamp; public double MinutesRemaining => Math.Max(0.0, (double)(EndTimestamp - DateTimeOffset.UtcNow.ToUnixTimeSeconds()) / 60.0); public bool Involves(int clanId) { return AttackerClanId == clanId || DefenderClanId == clanId; } public bool IsBetween(int a, int b) { return (AttackerClanId == a && DefenderClanId == b) || (AttackerClanId == b && DefenderClanId == a); } } [Serializable] public class VaultCrackSession { public long PlayerId; public string PlayerName; public int PlayerClanId; public int TargetClanId; public int TerritoryGridX; public int TerritoryGridY; public long StartTimestamp; public Vector3 StartPosition; public int DurationMinutes = 30; public double MinutesElapsed => (double)(DateTimeOffset.UtcNow.ToUnixTimeSeconds() - StartTimestamp) / 60.0; public bool IsComplete => MinutesElapsed >= (double)DurationMinutes; public float Progress01 => Mathf.Clamp01((float)(MinutesElapsed / (double)Math.Max(1, DurationMinutes))); } [Serializable] public class CaptureSession { public int TerritoryGridX; public int TerritoryGridY; public int AttackerClanId; public int DefenderClanId; public float Progress; public float Threshold = 100f; public int CombatPoints; public long StartTimestamp; public long LastAttackerSeenTime; public long LastDefenderMajorityTime; public bool Siege; public Vector2i GridPosition => new Vector2i(TerritoryGridX, TerritoryGridY); public float Progress01 => (Threshold <= 0f) ? 0f : Mathf.Clamp01(Progress / Threshold); } [Serializable] public class WarfareData { public const int DataVersion = 3; public int SeasonNumber = 1; public long SeasonStartTimestamp; public int NextClanId = 1; public int NextWarId = 1; public List ActiveCracks = new List(); public List ActiveCaptures = new List(); public int Version { get; set; } = 3; public Dictionary Clans { get; set; } = new Dictionary(); public Dictionary Players { get; set; } = new Dictionary(); public Dictionary Territories { get; set; } = new Dictionary(); public Dictionary> ClanVaults { get; set; } = new Dictionary>(); public List RotTotems { get; set; } = new List(); public List Wars { get; set; } = new List(); public static string GridToKey(Vector2i grid) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) return $"{grid.x},{grid.y}"; } public static string GridToKey(int x, int y) { return $"{x},{y}"; } public PlayerClanInfo GetPlayer(long playerId) { PlayerClanInfo value; return Players.TryGetValue(playerId, out value) ? value : null; } public PlayerClanInfo GetOrCreatePlayer(long playerId, string playerName) { if (!Players.TryGetValue(playerId, out var value)) { value = new PlayerClanInfo { PlayerId = playerId, PlayerName = playerName, ClanId = 0, Role = ClanRole.None }; Players[playerId] = value; } if (!string.IsNullOrEmpty(playerName)) { value.PlayerName = playerName; } return value; } public Clan GetClan(int clanId) { Clan value; return Clans.TryGetValue(clanId, out value) ? value : null; } public List GetClanMembers(int clanId) { List list = new List(); foreach (PlayerClanInfo value in Players.Values) { if (value.ClanId == clanId) { list.Add(value); } } return list; } public int GetClanMemberCount(int clanId) { int num = 0; foreach (PlayerClanInfo value in Players.Values) { if (value.ClanId == clanId) { num++; } } return num; } public ClanTerritory GetTerritory(Vector2i grid) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) ClanTerritory value; return Territories.TryGetValue(GridToKey(grid), out value) ? value : null; } public ClanTerritory GetTerritory(int x, int y) { ClanTerritory value; return Territories.TryGetValue(GridToKey(x, y), out value) ? value : null; } public int GetClanTerritoryCount(int clanId) { int num = 0; foreach (ClanTerritory value in Territories.Values) { if (value.OwnerClanId == clanId) { num++; } } return num; } public List GetClanTerritories(int clanId) { List list = new List(); foreach (ClanTerritory value in Territories.Values) { if (value.OwnerClanId == clanId) { list.Add(value); } } return list; } public bool ClanHasCapital(int clanId) { foreach (ClanTerritory value in Territories.Values) { if (value.OwnerClanId == clanId && value.Type == TerritoryType.Capital) { return true; } } return false; } public void AddToVault(int clanId, string prefabName, string displayName, int amount) { if (!ClanVaults.ContainsKey(clanId)) { ClanVaults[clanId] = new List(); } List list = ClanVaults[clanId]; ClanVaultItem clanVaultItem = list.Find((ClanVaultItem v) => v.PrefabName == prefabName); if (clanVaultItem != null) { clanVaultItem.Amount += amount; return; } list.Add(new ClanVaultItem { PrefabName = prefabName, DisplayName = displayName, Amount = amount }); } public List GetVault(int clanId) { List value; return ClanVaults.TryGetValue(clanId, out value) ? value : new List(); } public int GetVaultStackCount(int clanId) { List value; return ClanVaults.TryGetValue(clanId, out value) ? value.Count : 0; } public int GetLootReductionPercent(Vector2i grid) { //IL_0030: 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) int num = 0; foreach (RotTotem rotTotem in RotTotems) { if (rotTotem.State != TotemState.Destroyed && rotTotem.TerritoryGridX == grid.x && rotTotem.TerritoryGridY == grid.y) { num += rotTotem.LootReductionPercent; } } return Math.Min(num, 100); } public War GetActiveWarBetween(int clanA, int clanB) { foreach (War war in Wars) { if (war.IsActive && war.IsBetween(clanA, clanB)) { return war; } } return null; } public List GetActiveWarsInvolving(int clanId) { List list = new List(); foreach (War war in Wars) { if (war.IsActive && war.Involves(clanId)) { list.Add(war); } } return list; } public byte[] Serialize() { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown //IL_05ab: Unknown result type (might be due to invalid IL or missing references) //IL_0736: Unknown result type (might be due to invalid IL or missing references) ZPackage val = new ZPackage(); val.Write(3); val.Write(SeasonNumber); val.Write(SeasonStartTimestamp); val.Write(NextClanId); val.Write(NextWarId); val.Write(Clans.Count); foreach (KeyValuePair clan in Clans) { Clan value = clan.Value; val.Write(value.ClanId); val.Write(value.Name ?? ""); val.Write(value.Tag ?? ""); val.Write(value.IconIndex); val.Write(value.ColorR); val.Write(value.ColorG); val.Write(value.ColorB); val.Write(value.FounderId); val.Write(value.JarlId); val.Write(value.Treasury); val.Write(value.VaultTier); val.Write(value.ExtraTerritorySlots); val.Write(value.CreatedTimestamp); val.Write(value.NextElectionTimestamp); val.Write(value.Bounty); Dictionary dictionary = value.ElectionVotes ?? new Dictionary(); val.Write(dictionary.Count); foreach (KeyValuePair item in dictionary) { val.Write(item.Key); val.Write(item.Value); } } val.Write(Players.Count); foreach (KeyValuePair player in Players) { PlayerClanInfo value2 = player.Value; val.Write(value2.PlayerId); val.Write(value2.PlayerName ?? ""); val.Write(value2.ClanId); val.Write((int)value2.Role); val.Write((int)value2.Rank); val.Write(value2.LastRoleChangeTimestamp); val.Write(value2.LastVaultCrackTimestamp); val.Write(value2.JoinedClanTimestamp); val.Write(value2.LastClanLeaveTimestamp); val.Write(value2.LastSeenTimestamp); val.Write(value2.Bounty); } val.Write(Territories.Count); foreach (KeyValuePair territory in Territories) { ClanTerritory value3 = territory.Value; val.Write(territory.Key); val.Write(value3.GridX); val.Write(value3.GridY); val.Write(value3.OwnerClanId); val.Write(value3.ClaimedByPlayerId); val.Write(value3.ClaimedByPlayerName ?? ""); val.Write(value3.ClaimTimestamp); val.Write(value3.CustomName ?? ""); val.Write(value3.LastRenameTimestamp); val.Write((int)value3.Type); val.Write((int)value3.State); val.Write(value3.SizeLevel); val.Write(value3.BiomeValueTier); val.Write(value3.RotCount); val.Write(value3.LastRotTickTimestamp); val.Write(value3.LastIncomeTimestamp); val.Write(value3.HP); val.Write(value3.MaxHP); } val.Write(ClanVaults.Count); foreach (KeyValuePair> clanVault in ClanVaults) { val.Write(clanVault.Key); List list = clanVault.Value ?? new List(); val.Write(list.Count); foreach (ClanVaultItem item2 in list) { val.Write(item2.PrefabName ?? ""); val.Write(item2.DisplayName ?? ""); val.Write(item2.Amount); } } val.Write(RotTotems.Count); foreach (RotTotem rotTotem in RotTotems) { val.Write(rotTotem.TerritoryGridX); val.Write(rotTotem.TerritoryGridY); val.Write(rotTotem.PlacedByPlayerId); val.Write(rotTotem.PlacedByPlayerName ?? ""); val.Write(rotTotem.PlacerClanId); val.Write(rotTotem.PlacedTimestamp); val.Write(rotTotem.WorldPosition); val.Write((int)rotTotem.State); val.Write(rotTotem.Level); val.Write(rotTotem.LastDecayTimestamp); } val.Write(Wars.Count); foreach (War war in Wars) { val.Write(war.WarId); val.Write(war.AttackerClanId); val.Write(war.DefenderClanId); val.Write((int)war.Type); val.Write(war.StartTimestamp); val.Write(war.EndTimestamp); } val.Write(ActiveCracks.Count); foreach (VaultCrackSession activeCrack in ActiveCracks) { val.Write(activeCrack.PlayerId); val.Write(activeCrack.PlayerName ?? ""); val.Write(activeCrack.PlayerClanId); val.Write(activeCrack.TargetClanId); val.Write(activeCrack.TerritoryGridX); val.Write(activeCrack.TerritoryGridY); val.Write(activeCrack.StartTimestamp); val.Write(activeCrack.StartPosition); val.Write(activeCrack.DurationMinutes); } val.Write(ActiveCaptures.Count); foreach (CaptureSession activeCapture in ActiveCaptures) { val.Write(activeCapture.TerritoryGridX); val.Write(activeCapture.TerritoryGridY); val.Write(activeCapture.AttackerClanId); val.Write(activeCapture.DefenderClanId); val.Write(activeCapture.Progress); val.Write(activeCapture.Threshold); val.Write(activeCapture.CombatPoints); val.Write(activeCapture.StartTimestamp); val.Write(activeCapture.LastAttackerSeenTime); val.Write(activeCapture.LastDefenderMajorityTime); val.Write(activeCapture.Siege); } return val.GetArray(); } public static WarfareData Deserialize(byte[] data) { //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Expected O, but got Unknown //IL_04d6: Unknown result type (might be due to invalid IL or missing references) //IL_04db: Unknown result type (might be due to invalid IL or missing references) //IL_060c: Unknown result type (might be due to invalid IL or missing references) //IL_0611: Unknown result type (might be due to invalid IL or missing references) WarfareData warfareData = new WarfareData(); if (data == null || data.Length == 0) { return warfareData; } try { ZPackage val = new ZPackage(data); int num = val.ReadInt(); if (num < 3) { Debug.LogWarning((object)($"[ClanWarfare] Save format v{num} predates the warfare redesign. " + "Starting a fresh season (Cycle of Odin).")); warfareData.SeasonStartTimestamp = DateTimeOffset.UtcNow.ToUnixTimeSeconds(); return warfareData; } warfareData.Version = num; warfareData.SeasonNumber = val.ReadInt(); warfareData.SeasonStartTimestamp = val.ReadLong(); warfareData.NextClanId = val.ReadInt(); warfareData.NextWarId = val.ReadInt(); int num2 = val.ReadInt(); for (int i = 0; i < num2; i++) { Clan clan = new Clan { ClanId = val.ReadInt(), Name = val.ReadString(), Tag = val.ReadString(), IconIndex = val.ReadInt(), ColorR = val.ReadSingle(), ColorG = val.ReadSingle(), ColorB = val.ReadSingle(), FounderId = val.ReadLong(), JarlId = val.ReadLong(), Treasury = val.ReadLong(), VaultTier = val.ReadInt(), ExtraTerritorySlots = val.ReadInt(), CreatedTimestamp = val.ReadLong(), NextElectionTimestamp = val.ReadLong(), Bounty = val.ReadLong() }; int num3 = val.ReadInt(); for (int j = 0; j < num3; j++) { long key = val.ReadLong(); long value = val.ReadLong(); clan.ElectionVotes[key] = value; } warfareData.Clans[clan.ClanId] = clan; } int num4 = val.ReadInt(); for (int k = 0; k < num4; k++) { PlayerClanInfo playerClanInfo = new PlayerClanInfo { PlayerId = val.ReadLong(), PlayerName = val.ReadString(), ClanId = val.ReadInt(), Role = (ClanRole)val.ReadInt(), Rank = (ClanRank)val.ReadInt(), LastRoleChangeTimestamp = val.ReadLong(), LastVaultCrackTimestamp = val.ReadLong(), JoinedClanTimestamp = val.ReadLong(), LastClanLeaveTimestamp = val.ReadLong(), LastSeenTimestamp = val.ReadLong(), Bounty = val.ReadLong() }; warfareData.Players[playerClanInfo.PlayerId] = playerClanInfo; } int num5 = val.ReadInt(); for (int l = 0; l < num5; l++) { string key2 = val.ReadString(); ClanTerritory clanTerritory = new ClanTerritory { GridX = val.ReadInt(), GridY = val.ReadInt(), OwnerClanId = val.ReadInt(), ClaimedByPlayerId = val.ReadLong(), ClaimedByPlayerName = val.ReadString(), ClaimTimestamp = val.ReadLong(), CustomName = val.ReadString(), LastRenameTimestamp = val.ReadLong(), Type = (TerritoryType)val.ReadInt(), State = (TerritoryState)val.ReadInt(), SizeLevel = val.ReadInt(), BiomeValueTier = val.ReadInt(), RotCount = val.ReadInt(), LastRotTickTimestamp = val.ReadLong(), LastIncomeTimestamp = val.ReadLong(), HP = val.ReadSingle(), MaxHP = val.ReadSingle() }; if (string.IsNullOrEmpty(clanTerritory.CustomName)) { clanTerritory.CustomName = null; } warfareData.Territories[key2] = clanTerritory; } int num6 = val.ReadInt(); for (int m = 0; m < num6; m++) { int key3 = val.ReadInt(); int num7 = val.ReadInt(); List list = new List(); for (int n = 0; n < num7; n++) { list.Add(new ClanVaultItem { PrefabName = val.ReadString(), DisplayName = val.ReadString(), Amount = val.ReadInt() }); } warfareData.ClanVaults[key3] = list; } int num8 = val.ReadInt(); for (int num9 = 0; num9 < num8; num9++) { warfareData.RotTotems.Add(new RotTotem { TerritoryGridX = val.ReadInt(), TerritoryGridY = val.ReadInt(), PlacedByPlayerId = val.ReadLong(), PlacedByPlayerName = val.ReadString(), PlacerClanId = val.ReadInt(), PlacedTimestamp = val.ReadLong(), WorldPosition = val.ReadVector3(), State = (TotemState)val.ReadInt(), Level = val.ReadInt(), LastDecayTimestamp = val.ReadLong() }); } int num10 = val.ReadInt(); for (int num11 = 0; num11 < num10; num11++) { warfareData.Wars.Add(new War { WarId = val.ReadInt(), AttackerClanId = val.ReadInt(), DefenderClanId = val.ReadInt(), Type = (WarType)val.ReadInt(), StartTimestamp = val.ReadLong(), EndTimestamp = val.ReadLong() }); } int num12 = val.ReadInt(); for (int num13 = 0; num13 < num12; num13++) { warfareData.ActiveCracks.Add(new VaultCrackSession { PlayerId = val.ReadLong(), PlayerName = val.ReadString(), PlayerClanId = val.ReadInt(), TargetClanId = val.ReadInt(), TerritoryGridX = val.ReadInt(), TerritoryGridY = val.ReadInt(), StartTimestamp = val.ReadLong(), StartPosition = val.ReadVector3(), DurationMinutes = val.ReadInt() }); } int num14 = val.ReadInt(); for (int num15 = 0; num15 < num14; num15++) { warfareData.ActiveCaptures.Add(new CaptureSession { TerritoryGridX = val.ReadInt(), TerritoryGridY = val.ReadInt(), AttackerClanId = val.ReadInt(), DefenderClanId = val.ReadInt(), Progress = val.ReadSingle(), Threshold = val.ReadSingle(), CombatPoints = val.ReadInt(), StartTimestamp = val.ReadLong(), LastAttackerSeenTime = val.ReadLong(), LastDefenderMajorityTime = val.ReadLong(), Siege = val.ReadBool() }); } return warfareData; } catch (Exception ex) { Debug.LogError((object)("[ClanWarfare] Deserialize failed: " + ex.Message + "\n" + ex.StackTrace)); return new WarfareData(); } } } } namespace FortecaClanWarfare.Core { public static class ClanConfig { public static ConfigEntry GridCellSize; public static ConfigEntry SpawnProtectionRadius; public static ConfigEntry ClanFreeMemberLimit; public static ConfigEntry ClanMemberCostBase; public static ConfigEntry ClanMaxMembers; public static ConfigEntry ClanCreationCost; public static ConfigEntry ClanLeaveCooldownHours; public static ConfigEntry MaxClans; public static ConfigEntry ElectionIntervalDays; public static ConfigEntry BaseTerritoryCap; public static ConfigEntry MaxTerritoryCap; public static ConfigEntry TerritoryExpansionBlock; public static ConfigEntry TerritoryExpansionCost; public static ConfigEntry TerritoryUpgradeCostBase; public static ConfigEntry MaxTerritorySizeLevel; public static ConfigEntry ProfitThreshold; public static ConfigEntry BalancedThreshold; public static ConfigEntry IncomeBiomeLow; public static ConfigEntry IncomeBiomeMid; public static ConfigEntry IncomeBiomeHigh; public static ConfigEntry UpkeepPerSizeLevel; public static ConfigEntry GlobalUpkeepBase; public static ConfigEntry GlobalUpkeepPerTerritory; public static ConfigEntry GlobalUpkeepFreeTerritories; public static ConfigEntry UpkeepTickMinutes; public static ConfigEntry StartingTreasury; public static ConfigEntry VaultCapacityBase; public static ConfigEntry VaultUpgradeCostBase; public static ConfigEntry MaxVaultTier; public static ConfigEntry VaultOpenDayOfWeek; public static ConfigEntry VaultOpenHourUTC; public static ConfigEntry VaultOpenDurationMinutes; public static ConfigEntry VaultAlwaysOpen; public static ConfigEntry RoleBuffPercent; public static ConfigEntry RoleDebuffPercent; public static ConfigEntry GuardianBuildCostReduction; public static ConfigEntry ParasiteCraftCostReduction; public static ConfigEntry GathererCarryWeightBonus; public static ConfigEntry RoleChangeCooldownHours; public static ConfigEntry VaultCrackDurationMinutes; public static ConfigEntry VaultCrackCooldownHours; public static ConfigEntry VaultCrackMinStacks; public static ConfigEntry VaultCrackMaxStacks; public static ConfigEntry WarDurationMinutes; public static ConfigEntry RaidPlayersRequired; public static ConfigEntry WarPlayersRequired; public static ConfigEntry RageWarPlayersRequired; public static ConfigEntry WarDeclareCost; public static ConfigEntry CaptureThresholdPerSize; public static ConfigEntry ClaimSpeedBase; public static ConfigEntry CombatPointsKill; public static ConfigEntry CombatPointsElite; public static ConfigEntry CombatPointsBoss; public static ConfigEntry InterruptNoAttackerSeconds; public static ConfigEntry InterruptDefenderMajoritySeconds; public static ConfigEntry SiegeAttackerCount; public static ConfigEntry SiegeDefenseReduction; public static ConfigEntry SiegeClaimSpeedBonus; public static ConfigEntry TerritoryHPBase; public static ConfigEntry CapitalHPModifier; public static ConfigEntry ColonyHPModifier; public static ConfigEntry RotDecayHours; public static ConfigEntry RotTotemCostBase; public static ConfigEntry MaxRotTotemsPerTerritory; public static ConfigEntry AutoBountyIllegalKill; public static ConfigEntry BountyRevealThreshold; public static ConfigEntry BountySystemEnabled; public static ConfigEntry FullPvPDuringWar; public static ConfigEntry ProtectHotbarOnDeath; public static ConfigEntry AntiAltEnabled; public static ConfigEntry OfflineRaidProtection; public static ConfigEntry OfflineRaidEffectReduction; public static ConfigEntry SeasonLengthDays; public static readonly Color[] ClanColors = (Color[])(object)new Color[12] { new Color(0.78f, 0.2f, 0.2f, 1f), new Color(0.25f, 0.4f, 0.85f, 1f), new Color(0.22f, 0.68f, 0.3f, 1f), new Color(0.62f, 0.38f, 0.88f, 1f), new Color(0.92f, 0.55f, 0.12f, 1f), new Color(0.55f, 0.55f, 0.58f, 1f), new Color(0.2f, 0.66f, 0.78f, 1f), new Color(0.86f, 0.72f, 0.22f, 1f), new Color(0.88f, 0.36f, 0.62f, 1f), new Color(0.4f, 0.78f, 0.8f, 1f), new Color(0.55f, 0.74f, 0.2f, 1f), new Color(0.8f, 0.3f, 0.16f, 1f) }; public static readonly string[] ClanIcons = new string[12] { "⚔", "☠", "⚓", "⚑", "⚜", "♦", "★", "⚡", "♠", "☸", "✪", "◈" }; public static void Initialize(ConfigFile config) { GridCellSize = config.Bind("Grid", "CellSize", 500, "Fallback grid cell size in meters (Voronoi territories are used in-game)."); SpawnProtectionRadius = config.Bind("Grid", "SpawnProtectionRadius", 2500, "No-claim radius around world spawn."); ClanFreeMemberLimit = config.Bind("Clan", "FreeMemberLimit", 3, "How many members a clan can hold for free."); ClanMemberCostBase = config.Bind("Clan", "MemberCostBase", 100, "Coin cost for the first paid member slot. Doubles for each additional slot (100, 200, 400, ...)."); ClanMaxMembers = config.Bind("Clan", "MaxMembers", 20, "Hard cap on clan members."); ClanCreationCost = config.Bind("Clan", "CreationCost", 0, "Coin cost to found a clan (paid from founder's vision — usually 0)."); ClanLeaveCooldownHours = config.Bind("Clan", "LeaveCooldownHours", 24, "Hours before a player who left a clan may join another."); MaxClans = config.Bind("Clan", "MaxClans", 8, "Maximum number of clans that can exist at once. 0 = unlimited."); ElectionIntervalDays = config.Bind("Clan", "ElectionIntervalDays", 14, "Real days between Jarl elections."); BaseTerritoryCap = config.Bind("Territory", "BaseCap", 10, "Territory cap for a fresh clan."); MaxTerritoryCap = config.Bind("Territory", "MaxCap", 100, "Absolute maximum territories a clan can ever hold."); TerritoryExpansionBlock = config.Bind("Territory", "ExpansionBlock", 10, "Extra territory slots granted per expansion purchase."); TerritoryExpansionCost = config.Bind("Territory", "ExpansionCost", 1000, "Coin cost to buy one expansion block of territory slots."); TerritoryUpgradeCostBase = config.Bind("Territory", "UpgradeCostBase", 500, "Base coin cost to upgrade a territory's size level (scales with level)."); MaxTerritorySizeLevel = config.Bind("Territory", "MaxSizeLevel", 5, "Maximum size/upgrade level per territory."); ProfitThreshold = config.Bind("Territory", "ProfitThreshold", 20, "At or below this many territories a clan runs at a profit."); BalancedThreshold = config.Bind("Territory", "BalancedThreshold", 40, "Above this many territories a clan runs at a loss."); IncomeBiomeLow = config.Bind("Economy", "IncomeBiomeLow", 5, "Coins per upkeep tick per size level for low-value biomes (Meadows, Black Forest, Ocean)."); IncomeBiomeMid = config.Bind("Economy", "IncomeBiomeMid", 10, "Coins per upkeep tick per size level for mid-value biomes (Swamp, Mountain, Ashlands, Deep North)."); IncomeBiomeHigh = config.Bind("Economy", "IncomeBiomeHigh", 20, "Coins per upkeep tick per size level for high-value biomes (Plains, Mistlands)."); UpkeepPerSizeLevel = config.Bind("Economy", "UpkeepPerSizeLevel", 4f, "Base coin upkeep per size level, before the global multiplier."); GlobalUpkeepBase = config.Bind("Economy", "GlobalUpkeepBase", 1f, "Base global upkeep multiplier."); GlobalUpkeepPerTerritory = config.Bind("Economy", "GlobalUpkeepPerTerritory", 0.1f, "Added to the global upkeep multiplier per territory beyond the free count."); GlobalUpkeepFreeTerritories = config.Bind("Economy", "GlobalUpkeepFreeTerritories", 5, "Territories that do not add to the global upkeep multiplier."); UpkeepTickMinutes = config.Bind("Economy", "UpkeepTickMinutes", 30, "Real minutes between economy ticks (income + upkeep)."); StartingTreasury = config.Bind("Economy", "StartingTreasury", 0, "Coins a clan starts with on creation."); VaultCapacityBase = config.Bind("Vault", "CapacityBase", 100, "Vault capacity = Base x Tier x Territories (stacks)."); VaultUpgradeCostBase = config.Bind("Vault", "UpgradeCostBase", 1000, "Base coin cost to upgrade vault tier (scales with tier)."); MaxVaultTier = config.Bind("Vault", "MaxTier", 5, "Maximum vault tier."); VaultOpenDayOfWeek = config.Bind("Vault", "OpenDayOfWeek", 0, "Day of week the vault opens (0=Sunday, 6=Saturday)."); VaultOpenHourUTC = config.Bind("Vault", "OpenHourUTC", 16, "Hour (UTC) when the vault opens."); VaultOpenDurationMinutes = config.Bind("Vault", "OpenDurationMinutes", 30, "How long the vault stays open."); VaultAlwaysOpen = config.Bind("Vault", "AlwaysOpen", false, "If true the vault is always open (ignores the schedule)."); RoleBuffPercent = config.Bind("Roles", "BuffPercent", 20f, "Stat buff percentage in a role's preferred territory."); RoleDebuffPercent = config.Bind("Roles", "DebuffPercent", 20f, "Stat debuff percentage outside a role's preferred territory."); GuardianBuildCostReduction = config.Bind("Roles", "GuardianBuildCostReduction", 50f, "Build cost reduction (%) for Guardians in clan territory."); ParasiteCraftCostReduction = config.Bind("Roles", "ParasiteCraftCostReduction", 50f, "Craft cost reduction (%) for Parasites in enemy territory."); GathererCarryWeightBonus = config.Bind("Roles", "GathererCarryWeightBonus", 500, "Extra carry weight for Gatherers."); RoleChangeCooldownHours = config.Bind("Roles", "ChangeCooldownHours", 24, "Hours between role changes."); VaultCrackDurationMinutes = config.Bind("VaultCrack", "DurationMinutes", 30, "Minutes an Invader must hold an enemy territory to crack the vault."); VaultCrackCooldownHours = config.Bind("VaultCrack", "CooldownHours", 6, "Hours between vault crack attempts per player."); VaultCrackMinStacks = config.Bind("VaultCrack", "MinStacks", 1, "Minimum item stacks stolen on a successful crack."); VaultCrackMaxStacks = config.Bind("VaultCrack", "MaxStacks", 5, "Maximum item stacks stolen on a successful crack."); WarDurationMinutes = config.Bind("War", "DurationMinutes", 120, "How long a declared war stays active."); RaidPlayersRequired = config.Bind("War", "RaidPlayersRequired", 1, "Attackers required to sustain a Raid."); WarPlayersRequired = config.Bind("War", "WarPlayersRequired", 3, "Attackers required to sustain a War."); RageWarPlayersRequired = config.Bind("War", "RageWarPlayersRequired", 5, "Attackers required to sustain a Rage War."); WarDeclareCost = config.Bind("War", "DeclareCost", 200, "Coin cost to declare a war."); CaptureThresholdPerSize = config.Bind("Capture", "ThresholdPerSize", 100, "Capture threshold = ThresholdPerSize x territory size level."); ClaimSpeedBase = config.Bind("Capture", "ClaimSpeedBase", 1f, "Base capture progress per attacker per claim tick (1s)."); CombatPointsKill = config.Bind("Capture", "CombatPointsKill", 500, "Capture progress from a player kill inside the contested territory."); CombatPointsElite = config.Bind("Capture", "CombatPointsElite", 1000, "Capture progress from an elite kill."); CombatPointsBoss = config.Bind("Capture", "CombatPointsBoss", 5000, "Capture progress from a boss kill."); InterruptNoAttackerSeconds = config.Bind("Capture", "InterruptNoAttackerSeconds", 60, "Seconds with no attackers present before capture progress resets."); InterruptDefenderMajoritySeconds = config.Bind("Capture", "InterruptDefenderMajoritySeconds", 30, "Seconds of defender majority before capture progress reverses."); SiegeAttackerCount = config.Bind("Capture", "SiegeAttackerCount", 5, "Attackers present to trigger Siege state."); SiegeDefenseReduction = config.Bind("Capture", "SiegeDefenseReduction", 30f, "Defense reduction (%) while a territory is under Siege."); SiegeClaimSpeedBonus = config.Bind("Capture", "SiegeClaimSpeedBonus", 50f, "Capture speed bonus (%) while a territory is under Siege."); TerritoryHPBase = config.Bind("Defense", "TerritoryHPBase", 1000f, "Territory HP = Base x SizeLevel x type modifier."); CapitalHPModifier = config.Bind("Defense", "CapitalHPModifier", 2f, "HP modifier for Capital territories."); ColonyHPModifier = config.Bind("Defense", "ColonyHPModifier", 1f, "HP modifier for Colony territories."); RotDecayHours = config.Bind("Rot", "DecayHours", 6, "Real hours per rot decay tick (each active totem adds 1 rot)."); RotTotemCostBase = config.Bind("Rot", "TotemCostBase", 100, "Totem cost = Base x totem level x territory value tier."); MaxRotTotemsPerTerritory = config.Bind("Rot", "MaxTotemsPerTerritory", 4, "Maximum rot totems on a single territory."); BountySystemEnabled = config.Bind("Bounty", "Enabled", true, "Enable the bounty system."); AutoBountyIllegalKill = config.Bind("Bounty", "AutoBountyIllegalKill", 250, "Bounty added for a kill made outside a war (an 'illegal' kill)."); BountyRevealThreshold = config.Bind("Bounty", "RevealThreshold", 1000, "Bounty above which a target's territory is revealed on the map."); FullPvPDuringWar = config.Bind("PvP", "FullPvPDuringWar", true, "Force PvP on for players inside a territory involved in an active war."); ProtectHotbarOnDeath = config.Bind("PvP", "ProtectHotbarOnDeath", false, "If true the hotbar is kept on death (purely informational — drop behaviour is vanilla)."); AntiAltEnabled = config.Bind("Security", "AntiAltEnabled", true, "Enable basic anti-alt protections (clan-hop cooldown)."); OfflineRaidProtection = config.Bind("Security", "OfflineRaidProtection", true, "Reduce capture/crack effectiveness against clans with no members online."); OfflineRaidEffectReduction = config.Bind("Security", "OfflineRaidEffectReduction", 50f, "Effectiveness reduction (%) for offline raids."); SeasonLengthDays = config.Bind("Season", "LengthDays", 60, "Real days per season before the Cycle of Odin resets territories/vaults/rot. 0 = never auto-reset."); } public static string GetIcon(int index) { if (ClanIcons.Length == 0) { return "*"; } return ClanIcons[(index % ClanIcons.Length + ClanIcons.Length) % ClanIcons.Length]; } public static Color GetColor(int index) { //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_000e: 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_003c: Unknown result type (might be due to invalid IL or missing references) if (ClanColors.Length == 0) { return Color.white; } return ClanColors[(index % ClanColors.Length + ClanColors.Length) % ClanColors.Length]; } public static Clan GetClan(int clanId) { return WarfareManager.Instance?.Data?.GetClan(clanId); } } public static class ClanExporter { private static string ExportPath => Path.Combine(GetExportDir(), "clan_export.json"); private static string GetExportDir() { string text = Path.Combine(Paths.ConfigPath, "FortecaClanWarfare"); if (!Directory.Exists(text)) { Directory.CreateDirectory(text); } return text; } public static string ExportClansToJson() { WarfareData warfareData = WarfareManager.Instance?.Data; if (warfareData == null) { return "No warfare data loaded."; } StringBuilder stringBuilder = new StringBuilder(); stringBuilder.AppendLine("{"); stringBuilder.AppendLine($" \"season\": {warfareData.SeasonNumber},"); stringBuilder.AppendLine(" \"clans\": ["); int num = 0; foreach (Clan value in warfareData.Clans.Values) { if (num > 0) { stringBuilder.AppendLine(","); } stringBuilder.Append(" { \"name\": " + JsonString(value.Name) + ", \"tag\": " + JsonString(value.Tag) + ", " + $"\"icon\": {value.IconIndex}, \"colorR\": {To255(value.ColorR)}, \"colorG\": {To255(value.ColorG)}, " + $"\"colorB\": {To255(value.ColorB)}, \"treasury\": {value.Treasury}, \"vaultTier\": {value.VaultTier} }}"); num++; } stringBuilder.AppendLine(); stringBuilder.AppendLine(" ],"); stringBuilder.AppendLine(" \"players\": ["); int num2 = 0; foreach (PlayerClanInfo value2 in warfareData.Players.Values) { if (value2.ClanId == 0) { continue; } Clan clan = warfareData.GetClan(value2.ClanId); if (clan != null) { if (num2 > 0) { stringBuilder.AppendLine(","); } stringBuilder.Append($" {{ \"playerId\": {value2.PlayerId}, \"playerName\": {JsonString(value2.PlayerName)}, " + $"\"clanName\": {JsonString(clan.Name)}, \"role\": {(int)value2.Role}, \"rank\": {(int)value2.Rank} }}"); num2++; } } stringBuilder.AppendLine(); stringBuilder.AppendLine(" ],"); stringBuilder.AppendLine(" \"vaults\": {"); int num3 = 0; foreach (KeyValuePair> clanVault in warfareData.ClanVaults) { if (clanVault.Value == null || clanVault.Value.Count == 0) { continue; } Clan clan2 = warfareData.GetClan(clanVault.Key); if (clan2 != null) { if (num3 > 0) { stringBuilder.AppendLine(","); } stringBuilder.AppendLine(" " + JsonString(clan2.Name) + ": ["); for (int i = 0; i < clanVault.Value.Count; i++) { ClanVaultItem clanVaultItem = clanVault.Value[i]; stringBuilder.Append(" { \"prefab\": " + JsonString(clanVaultItem.PrefabName) + ", \"name\": " + JsonString(clanVaultItem.DisplayName) + ", " + $"\"amount\": {clanVaultItem.Amount} }}"); stringBuilder.AppendLine((i < clanVault.Value.Count - 1) ? "," : ""); } stringBuilder.Append(" ]"); num3++; } } stringBuilder.AppendLine(); stringBuilder.AppendLine(" }"); stringBuilder.AppendLine("}"); File.WriteAllText(ExportPath, stringBuilder.ToString()); return $"Exported {num} clans, {num2} players and {num3} vaults to {ExportPath}"; } public static string ImportClansFromJson() { WarfareData warfareData = WarfareManager.Instance?.Data; if (warfareData == null) { return "No warfare data loaded."; } if (!File.Exists(ExportPath)) { return "File not found: " + ExportPath; } try { string json = File.ReadAllText(ExportPath); int num = 0; int num2 = 0; int num3 = 0; Dictionary dictionary = new Dictionary(StringComparer.OrdinalIgnoreCase); foreach (Clan value3 in warfareData.Clans.Values) { if (!string.IsNullOrEmpty(value3.Name)) { dictionary[value3.Name] = value3.ClanId; } } foreach (string item in ExtractArray(json, "clans")) { string text = ExtractString(item, "name"); if (!string.IsNullOrEmpty(text) && !dictionary.ContainsKey(text)) { int num4 = warfareData.NextClanId++; Clan value = new Clan { ClanId = num4, Name = text, Tag = ExtractString(item, "tag"), IconIndex = ExtractInt(item, "icon"), ColorR = (float)ExtractInt(item, "colorR") / 255f, ColorG = (float)ExtractInt(item, "colorG") / 255f, ColorB = (float)ExtractInt(item, "colorB") / 255f, Treasury = ExtractLong(item, "treasury"), VaultTier = Math.Max(1, ExtractInt(item, "vaultTier")), CreatedTimestamp = WarfareManager.Now(), NextElectionTimestamp = WarfareManager.Now() + 1209600 }; warfareData.Clans[num4] = value; dictionary[text] = num4; num++; } } foreach (string item2 in ExtractArray(json, "players")) { long num5 = ExtractLong(item2, "playerId"); string text2 = ExtractString(item2, "clanName"); if (num5 != 0L && !string.IsNullOrEmpty(text2) && dictionary.TryGetValue(text2, out var value2) && !warfareData.Players.ContainsKey(num5)) { warfareData.Players[num5] = new PlayerClanInfo { PlayerId = num5, PlayerName = ExtractString(item2, "playerName"), ClanId = value2, Role = (ClanRole)ExtractInt(item2, "role"), Rank = (ClanRank)ExtractInt(item2, "rank"), JoinedClanTimestamp = WarfareManager.Now() }; num2++; } } foreach (Clan value4 in warfareData.Clans.Values) { if (warfareData.GetPlayer(value4.JarlId) != null) { continue; } foreach (PlayerClanInfo value5 in warfareData.Players.Values) { if (value5.ClanId == value4.ClanId) { value4.JarlId = value5.PlayerId; value5.Rank = ClanRank.Jarl; break; } } } string text3 = ExtractObject(json, "vaults"); if (!string.IsNullOrEmpty(text3)) { foreach (KeyValuePair item3 in dictionary) { List list = ExtractArray(text3, item3.Key); if (list.Count == 0) { continue; } foreach (string item4 in list) { string text4 = ExtractString(item4, "prefab"); int num6 = ExtractInt(item4, "amount"); if (!string.IsNullOrEmpty(text4) && num6 > 0) { warfareData.AddToVault(item3.Value, text4, ExtractString(item4, "name"), num6); num3++; } } } } WarfareManager.Instance?.MarkDirty(); WarfareRPC.Instance?.SyncAllDataToClients(); return $"Imported {num} clans, {num2} players, {num3} vault items."; } catch (Exception ex) { return "Import failed: " + ex.Message; } } private static int To255(float f) { return Mathf.Clamp(Mathf.RoundToInt(f * 255f), 0, 255); } private static string JsonString(string s) { if (s == null) { return "\"\""; } return "\"" + s.Replace("\\", "\\\\").Replace("\"", "\\\"") + "\""; } private static List ExtractArray(string json, string key) { List list = new List(); int num = json.IndexOf("\"" + key + "\""); if (num < 0) { return list; } int num2 = json.IndexOf('[', num); if (num2 < 0) { return list; } int num3 = 0; int num4 = -1; for (int i = num2; i < json.Length; i++) { char c = json[i]; if (c == '[') { num3++; if (num3 == 1) { continue; } } if (c == ']') { num3--; if (num3 == 0) { break; } } if (c == '{' && num3 == 1) { num4 = i; } if (c == '}' && num3 == 1 && num4 >= 0) { list.Add(json.Substring(num4, i - num4 + 1)); num4 = -1; } } return list; } private static string ExtractObject(string json, string key) { int num = json.IndexOf("\"" + key + "\""); if (num < 0) { return null; } int num2 = json.IndexOf('{', num + key.Length + 2); if (num2 < 0) { return null; } int num3 = 0; for (int i = num2; i < json.Length; i++) { if (json[i] == '{') { num3++; } if (json[i] == '}') { num3--; if (num3 == 0) { return json.Substring(num2, i - num2 + 1); } } } return null; } private static string ExtractString(string json, string key) { string text = "\"" + key + "\":"; int num = json.IndexOf(text); if (num < 0) { text = "\"" + key + "\" :"; num = json.IndexOf(text); } if (num < 0) { return ""; } int num2 = json.IndexOf('"', num + text.Length); if (num2 < 0) { return ""; } int num3 = json.IndexOf('"', num2 + 1); if (num3 < 0) { return ""; } return json.Substring(num2 + 1, num3 - num2 - 1); } private static int ExtractInt(string json, string key) { return (int)ExtractLong(json, key); } private static long ExtractLong(string json, string key) { string text = "\"" + key + "\":"; int num = json.IndexOf(text); if (num < 0) { text = "\"" + key + "\" :"; num = json.IndexOf(text); } if (num < 0) { return 0L; } int i; for (i = num + text.Length; i < json.Length && (json[i] == ' ' || json[i] == '\t'); i++) { } int j; for (j = i; j < json.Length && (char.IsDigit(json[j]) || json[j] == '-'); j++) { } long result; return long.TryParse(json.Substring(i, j - i), out result) ? result : 0; } } [HarmonyPatch] public static class ClanExporterCommands { [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static ConsoleEvent <>9__0_0; public static ConsoleEvent <>9__0_1; public static ConsoleEvent <>9__0_2; public static ConsoleEvent <>9__0_3; internal void b__0_0(ConsoleEventArgs args) { args.Context.AddString(ClanExporter.ExportClansToJson()); } internal void b__0_1(ConsoleEventArgs args) { args.Context.AddString(ClanExporter.ImportClansFromJson()); } internal void b__0_2(ConsoleEventArgs args) { ZNet instance = ZNet.instance; if (instance != null && instance.IsServer()) { WarfareManager.Instance?.RunCycleOfOdin(); args.Context.AddString("Cycle of Odin triggered."); } else { args.Context.AddString("Server only."); } } internal void b__0_3(ConsoleEventArgs args) { ZNet instance = ZNet.instance; if (instance == null || !instance.IsServer()) { args.Context.AddString("Server only."); return; } if (args.Length < 3 || !int.TryParse(args[1], out var result) || !long.TryParse(args[2], out var result2)) { args.Context.AddString("Usage: clan_givecoins "); return; } Clan clan = WarfareManager.Instance?.Data?.GetClan(result); if (clan == null) { args.Context.AddString("Clan not found."); return; } clan.Treasury += result2; WarfareManager.Instance.MarkDirty(); WarfareRPC.Instance?.SyncAllDataToClients(); args.Context.AddString($"{clan.Name} treasury is now {clan.Treasury}."); } } [HarmonyPatch(typeof(Terminal), "InitTerminal")] [HarmonyPostfix] public static void RegisterCommands() { //IL_0033: 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_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Expected O, but got Unknown //IL_006b: 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_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Expected O, but got Unknown //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Expected O, but got Unknown //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: 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_00d2: Expected O, but got Unknown object obj = <>c.<>9__0_0; if (obj == null) { ConsoleEvent val = delegate(ConsoleEventArgs args) { args.Context.AddString(ClanExporter.ExportClansToJson()); }; <>c.<>9__0_0 = val; obj = (object)val; } new ConsoleCommand("clan_export", "Export clans, rosters and vaults to JSON for cross-server sharing (admin)", (ConsoleEvent)obj, true, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false); object obj2 = <>c.<>9__0_1; if (obj2 == null) { ConsoleEvent val2 = delegate(ConsoleEventArgs args) { args.Context.AddString(ClanExporter.ImportClansFromJson()); }; <>c.<>9__0_1 = val2; obj2 = (object)val2; } new ConsoleCommand("clan_import", "Import clans, rosters and vaults from clan_export.json (admin)", (ConsoleEvent)obj2, true, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false); object obj3 = <>c.<>9__0_2; if (obj3 == null) { ConsoleEvent val3 = delegate(ConsoleEventArgs args) { ZNet instance2 = ZNet.instance; if (instance2 != null && instance2.IsServer()) { WarfareManager.Instance?.RunCycleOfOdin(); args.Context.AddString("Cycle of Odin triggered."); } else { args.Context.AddString("Server only."); } }; <>c.<>9__0_2 = val3; obj3 = (object)val3; } new ConsoleCommand("clan_season_reset", "Force the Cycle of Odin — wipe territories/vaults/rot, keep clans (admin)", (ConsoleEvent)obj3, true, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false); object obj4 = <>c.<>9__0_3; if (obj4 == null) { ConsoleEvent val4 = delegate(ConsoleEventArgs args) { ZNet instance = ZNet.instance; int result; long result2; if (instance == null || !instance.IsServer()) { args.Context.AddString("Server only."); } else if (args.Length < 3 || !int.TryParse(args[1], out result) || !long.TryParse(args[2], out result2)) { args.Context.AddString("Usage: clan_givecoins "); } else { Clan clan = WarfareManager.Instance?.Data?.GetClan(result); if (clan == null) { args.Context.AddString("Clan not found."); } else { clan.Treasury += result2; WarfareManager.Instance.MarkDirty(); WarfareRPC.Instance?.SyncAllDataToClients(); args.Context.AddString($"{clan.Name} treasury is now {clan.Treasury}."); } } }; <>c.<>9__0_3 = val4; obj4 = (object)val4; } new ConsoleCommand("clan_givecoins", "clan_givecoins — add coins to a clan treasury (admin)", (ConsoleEvent)obj4, true, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false); } } public static class Economy { public static int BiomeValueTier(Biome biome) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: 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_0009: 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_000d: Invalid comparison between Unknown and I4 //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Invalid comparison between Unknown and I4 //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Invalid comparison between Unknown and I4 //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Invalid comparison between Unknown and I4 //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Invalid comparison between Unknown and I4 //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Invalid comparison between Unknown and I4 //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Invalid comparison between Unknown and I4 Biome val = BiomeUtils.ResolveBiome(biome); Biome val2 = val; if ((int)val2 <= 16) { if ((int)val2 == 2 || (int)val2 == 4) { goto IL_003e; } if ((int)val2 == 16) { goto IL_003a; } } else { if ((int)val2 == 32 || (int)val2 == 64) { goto IL_003e; } if ((int)val2 == 512) { goto IL_003a; } } return 1; IL_003a: return 3; IL_003e: return 2; } public static string ValueTierName(int tier) { return tier switch { 3 => "High", 2 => "Mid", _ => "Low", }; } public static int IncomeBiomeRate(int valueTier) { return valueTier switch { 3 => ClanConfig.IncomeBiomeHigh?.Value ?? 20, 2 => ClanConfig.IncomeBiomeMid?.Value ?? 10, _ => ClanConfig.IncomeBiomeLow?.Value ?? 5, }; } public static long TerritoryIncome(ClanTerritory t) { if (t == null) { return 0L; } float num = IncomeBiomeRate(t.BiomeValueTier) * Mathf.Max(1, t.SizeLevel); num *= RotIncomeMultiplier(t.RotCount); return (long)Mathf.Round(num); } public static float RotIncomeMultiplier(int rotCount) { return Mathf.Clamp01(1f - (float)Mathf.Clamp(rotCount, 0, 4) * 0.25f); } public static float GlobalUpkeepMultiplier(int territoryCount) { float num = ClanConfig.GlobalUpkeepBase?.Value ?? 1f; float num2 = ClanConfig.GlobalUpkeepPerTerritory?.Value ?? 0.1f; int num3 = ClanConfig.GlobalUpkeepFreeTerritories?.Value ?? 5; int num4 = Mathf.Max(0, territoryCount - num3); return num + (float)num4 * num2; } public static long TerritoryUpkeep(ClanTerritory t, float globalMultiplier) { if (t == null) { return 0L; } float num = ClanConfig.UpkeepPerSizeLevel?.Value ?? 4f; return (long)Mathf.Round((float)Mathf.Max(1, t.SizeLevel) * num * globalMultiplier); } public static long NetClanTick(WarfareData data, int clanId) { if (data == null) { return 0L; } List clanTerritories = data.GetClanTerritories(clanId); float globalMultiplier = GlobalUpkeepMultiplier(clanTerritories.Count); long num = 0L; foreach (ClanTerritory item in clanTerritories) { num += TerritoryIncome(item) - TerritoryUpkeep(item, globalMultiplier); } return num; } public static string EconomyBand(int territoryCount) { int num = ClanConfig.ProfitThreshold?.Value ?? 20; int num2 = ClanConfig.BalancedThreshold?.Value ?? 40; if (territoryCount <= num) { return "Profit"; } if (territoryCount <= num2) { return "Balanced"; } return "Loss"; } public static long ClanMemberSlotCost(int newMemberCount) { int num = ClanConfig.ClanFreeMemberLimit?.Value ?? 3; if (newMemberCount <= num) { return 0L; } long num2 = ClanConfig.ClanMemberCostBase?.Value ?? 100; int num3 = newMemberCount - num - 1; return num2 * (long)Mathf.Pow(2f, (float)Mathf.Max(0, num3)); } public static long TerritoryUpgradeCost(int currentSizeLevel) { long num = ClanConfig.TerritoryUpgradeCostBase?.Value ?? 500; return num * Mathf.Max(1, currentSizeLevel); } public static long VaultUpgradeCost(int currentTier) { long num = ClanConfig.VaultUpgradeCostBase?.Value ?? 1000; return num * Mathf.Max(1, currentTier); } public static long TerritoryExpansionCost(int expansionsBought) { long num = ClanConfig.TerritoryExpansionCost?.Value ?? 1000; return num * (expansionsBought + 1); } public static long RotTotemCost(int totemLevel, int biomeValueTier) { long num = ClanConfig.RotTotemCostBase?.Value ?? 100; return num * Mathf.Max(1, totemLevel) * Mathf.Max(1, biomeValueTier); } public static int TerritoryCap(Clan clan) { int num = ClanConfig.BaseTerritoryCap?.Value ?? 10; int num2 = ClanConfig.TerritoryExpansionBlock?.Value ?? 10; int num3 = ClanConfig.MaxTerritoryCap?.Value ?? 100; int num4 = num + (clan?.ExtraTerritorySlots ?? 0) * num2; return Mathf.Clamp(num4, num, num3); } public static int VaultCapacity(Clan clan, int territoryCount) { int num = ClanConfig.VaultCapacityBase?.Value ?? 100; int num2 = Mathf.Max(1, clan?.VaultTier ?? 1); return num * num2 * Mathf.Max(1, territoryCount); } public static float TerritoryMaxHP(ClanTerritory t) { if (t == null) { return 0f; } float num = ClanConfig.TerritoryHPBase?.Value ?? 1000f; float num2 = ((t.Type != TerritoryType.Capital) ? (ClanConfig.ColonyHPModifier?.Value ?? 1f) : (ClanConfig.CapitalHPModifier?.Value ?? 2f)); return num * (float)Mathf.Max(1, t.SizeLevel) * num2; } public static float CaptureThreshold(ClanTerritory t) { int num = ClanConfig.CaptureThresholdPerSize?.Value ?? 100; return num * Mathf.Max(1, t?.SizeLevel ?? 1); } public static float ClaimSpeed(int attackers, float roleFactor, ClanTerritory t, bool siege) { float num = ClanConfig.ClaimSpeedBase?.Value ?? 1f; float num2 = 1f / (float)Mathf.Max(1, t?.SizeLevel ?? 1); float num3 = (siege ? (1f + (ClanConfig.SiegeClaimSpeedBonus?.Value ?? 50f) / 100f) : 1f); return num * (float)Mathf.Max(1, attackers) * Mathf.Max(0.1f, roleFactor) * num2 * num3; } public static int PlayersRequired(WarType type) { return type switch { WarType.RageWar => ClanConfig.RageWarPlayersRequired?.Value ?? 5, WarType.War => ClanConfig.WarPlayersRequired?.Value ?? 3, _ => ClanConfig.RaidPlayersRequired?.Value ?? 1, }; } } public class GridManager : MonoBehaviour { private Vector2i? _currentGrid; private int _lastAnnouncedClanId = -1; private float _checkTimer; public static GridManager Instance { get; private set; } private void Awake() { if ((Object)(object)Instance != (Object)null && (Object)(object)Instance != (Object)(object)this) { Object.Destroy((Object)(object)this); } else { Instance = this; } } private void Update() { if (!((Object)(object)Player.m_localPlayer == (Object)null)) { _checkTimer += Time.deltaTime; if (!(_checkTimer < 0.5f)) { _checkTimer = 0f; CheckTerritoryChange(); } } } private void CheckTerritoryChange() { //IL_001f: 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) //IL_0029: 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_0047: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0076: 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_0136: Unknown result type (might be due to invalid IL or missing references) Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null) { return; } Vector2i val = GridExtensions.WorldToGrid(((Component)localPlayer).transform.position); if (_currentGrid.HasValue && _currentGrid.Value.x == val.x && _currentGrid.Value.y == val.y) { return; } _currentGrid = val; WarfareData warfareData = WarfareManager.Instance?.Data; if (warfareData == null) { return; } int num = warfareData.GetTerritory(val)?.OwnerClanId ?? 0; if (num == _lastAnnouncedClanId) { return; } _lastAnnouncedClanId = num; int num2 = warfareData.GetPlayer(localPlayer.GetPlayerID())?.ClanId ?? 0; if (num == 0) { MessageHud instance = MessageHud.instance; if (instance != null) { instance.ShowMessage((MessageType)2, "Unclaimed Territory", 0, (Sprite)null, false); } return; } Clan clan = ClanConfig.GetClan(num); string text = ((clan != null) ? ColorUtility.ToHtmlStringRGB(clan.Color) : "ffffff"); bool flag = num == num2; string text2 = (flag ? "HOME TERRITORY" : "ENEMY TERRITORY"); MessageHud instance2 = MessageHud.instance; if (instance2 != null) { instance2.ShowMessage((MessageType)2, "" + clan?.Symbol + " " + clan?.Name + "\n" + text2 + "", 0, (Sprite)null, false); } } public Vector2i? GetCurrentGrid() { return _currentGrid; } public ClanTerritory GetCurrentTerritory() { //IL_0035: Unknown result type (might be due to invalid IL or missing references) if (!_currentGrid.HasValue) { return null; } return WarfareManager.Instance?.Data?.GetTerritory(_currentGrid.Value); } } public class WarfareManager : MonoBehaviour { public class ClaimResult { public bool Success; public string Message; public ClaimResult(bool s, string m) { Success = s; Message = m; } } private bool _isServer; private bool _dirty; private float _saveTimer; private float _captureTimer; private float _miscTimer; private float _slowTimer; public static WarfareManager Instance { get; private set; } public WarfareData Data { get; private set; } = new WarfareData(); public bool IsServer => _isServer; private void Awake() { if ((Object)(object)Instance != (Object)null && (Object)(object)Instance != (Object)(object)this) { Object.Destroy((Object)(object)this); } else { Instance = this; } } private void Update() { if (!_isServer) { return; } float deltaTime = Time.deltaTime; if (_dirty) { _saveTimer += deltaTime; if (_saveTimer >= 60f) { _saveTimer = 0f; SaveData(); _dirty = false; } } _captureTimer += deltaTime; if (_captureTimer >= 1f) { _captureTimer = 0f; try { CaptureTick(); } catch (Exception ex) { Plugin.Log.LogError((object)("CaptureTick: " + ex.Message)); } } _miscTimer += deltaTime; if (_miscTimer >= 5f) { _miscTimer = 0f; try { ProcessVaultCracks(); VaultCrackMonitor.CheckActiveCracks(); WarExpiryTick(); } catch (Exception ex2) { Plugin.Log.LogError((object)("MiscTick: " + ex2.Message)); } } _slowTimer += deltaTime; if (!(_slowTimer >= 60f)) { return; } _slowTimer = 0f; try { EconomyTick(); RotTick(); ElectionTick(); SeasonTick(); } catch (Exception ex3) { Plugin.Log.LogError((object)("SlowTick: " + ex3.Message)); } } public void InitServer() { _isServer = true; LoadData(); if (Data.SeasonStartTimestamp == 0) { Data.SeasonStartTimestamp = Now(); MarkDirty(); } } public void MarkDirty() { _dirty = true; } public static long Now() { return DateTimeOffset.UtcNow.ToUnixTimeSeconds(); } public void LoadData() { if (!_isServer) { return; } try { byte[] worldCustomData = GetWorldCustomData(); if (worldCustomData != null && worldCustomData.Length != 0) { Data = WarfareData.Deserialize(worldCustomData); } Plugin.Log.LogInfo((object)($"Loaded warfare data: season {Data.SeasonNumber}, " + $"{Data.Clans.Count} clans, {Data.Players.Count} players, " + $"{Data.Territories.Count} territories, {Data.Wars.Count} wars.")); } catch (Exception ex) { Plugin.Log.LogError((object)("LoadData failed: " + ex.Message)); } } public void SaveData() { if (!_isServer) { return; } try { SetWorldCustomData(Data.Serialize()); } catch (Exception ex) { Plugin.Log.LogError((object)("SaveData failed: " + ex.Message)); } } private string GetSavePath() { string text = Path.Combine(Paths.ConfigPath, "FortecaClanWarfare"); if (!Directory.Exists(text)) { Directory.CreateDirectory(text); } return Path.Combine(text, "warfare_data.bin"); } private byte[] GetWorldCustomData() { string savePath = GetSavePath(); return File.Exists(savePath) ? File.ReadAllBytes(savePath) : null; } private void SetWorldCustomData(byte[] data) { File.WriteAllBytes(GetSavePath(), data); } public void ApplyServerData(WarfareData data) { Data = data; } public string CreateClan(long playerId, string playerName, string name, string tag, int colorIndex, int iconIndex) { //IL_0246: Unknown result type (might be due to invalid IL or missing references) //IL_02a1: Unknown result type (might be due to invalid IL or missing references) PlayerClanInfo orCreatePlayer = Data.GetOrCreatePlayer(playerId, playerName); if (orCreatePlayer.ClanId != 0) { return "You are already in a clan."; } ConfigEntry antiAltEnabled = ClanConfig.AntiAltEnabled; if (antiAltEnabled != null && antiAltEnabled.Value && !orCreatePlayer.CanJoinClan(ClanConfig.ClanLeaveCooldownHours?.Value ?? 24)) { return "You left a clan too recently. Try again later."; } name = (name ?? "").Trim(); tag = (tag ?? "").Trim(); if (name.Length < 3 || name.Length > 24) { return "Clan name must be 3-24 characters."; } if (tag.Length < 1 || tag.Length > 6) { return "Clan tag must be 1-6 characters."; } foreach (Clan value in Data.Clans.Values) { if (string.Equals(value.Name, name, StringComparison.OrdinalIgnoreCase)) { return "A clan with that name already exists."; } if (string.Equals(value.Tag, tag, StringComparison.OrdinalIgnoreCase)) { return "A clan with that tag already exists."; } } int num = ClanConfig.MaxClans?.Value ?? 8; if (num > 0 && Data.Clans.Count >= num) { return $"The world is full — {num} clans already exist."; } int num2 = Data.NextClanId++; Clan clan = new Clan { ClanId = num2, Name = name, Tag = tag, IconIndex = iconIndex, FounderId = playerId, JarlId = playerId, Treasury = (ClanConfig.StartingTreasury?.Value ?? 0), CreatedTimestamp = Now(), NextElectionTimestamp = Now() + (long)(ClanConfig.ElectionIntervalDays?.Value ?? 14) * 86400L }; clan.SetColor(ClanConfig.GetColor(colorIndex)); Data.Clans[num2] = clan; orCreatePlayer.ClanId = num2; orCreatePlayer.Rank = ClanRank.Jarl; orCreatePlayer.JoinedClanTimestamp = Now(); MarkDirty(); WarfareRPC.Instance?.BroadcastGlobalMessage("" + ClanConfig.GetIcon(iconIndex) + " Clan " + name + " [" + tag + "] has been founded by " + playerName + "!"); return "Clan " + name + " founded! You are its first Jarl."; } public string DisbandClan(long playerId) { PlayerClanInfo player = Data.GetPlayer(playerId); if (player == null || player.ClanId == 0) { return "You are not in a clan."; } Clan clan = Data.GetClan(player.ClanId); if (clan == null) { return "Clan not found."; } if (clan.JarlId != playerId) { return "Only the Jarl may disband the clan."; } int clanId = clan.ClanId; DoDisbandClan(clanId); MarkDirty(); WarfareRPC.Instance?.BroadcastGlobalMessage("Clan " + clan.Name + " has been disbanded."); return "Clan disbanded."; } private void DoDisbandClan(int clanId) { foreach (PlayerClanInfo value in Data.Players.Values) { if (value.ClanId == clanId) { value.ClanId = 0; value.Rank = ClanRank.Member; value.LastClanLeaveTimestamp = Now(); } } List list = new List(); foreach (KeyValuePair territory in Data.Territories) { if (territory.Value.OwnerClanId == clanId) { list.Add(territory.Key); } } foreach (string item in list) { Data.Territories.Remove(item); } Data.ClanVaults.Remove(clanId); Data.Clans.Remove(clanId); Data.Wars.RemoveAll((War w) => w.Involves(clanId)); Data.RotTotems.RemoveAll((RotTotem t) => t.PlacerClanId == clanId); Data.ActiveCaptures.RemoveAll((CaptureSession c) => c.AttackerClanId == clanId || c.DefenderClanId == clanId); Data.ActiveCracks.RemoveAll((VaultCrackSession c) => c.PlayerClanId == clanId || c.TargetClanId == clanId); } public string JoinClan(long playerId, string playerName, int clanId) { //IL_0179: Unknown result type (might be due to invalid IL or missing references) PlayerClanInfo orCreatePlayer = Data.GetOrCreatePlayer(playerId, playerName); if (orCreatePlayer.ClanId != 0) { return "You are already in a clan."; } Clan clan = Data.GetClan(clanId); if (clan == null) { return "That clan no longer exists."; } ConfigEntry antiAltEnabled = ClanConfig.AntiAltEnabled; if (antiAltEnabled != null && antiAltEnabled.Value && !orCreatePlayer.CanJoinClan(ClanConfig.ClanLeaveCooldownHours?.Value ?? 24)) { return "You left a clan too recently. Try again later."; } int clanMemberCount = Data.GetClanMemberCount(clanId); int num = ClanConfig.ClanMaxMembers?.Value ?? 20; if (clanMemberCount >= num) { return $"{clan.Name} is full ({clanMemberCount}/{num})."; } long num2 = Economy.ClanMemberSlotCost(clanMemberCount + 1); if (num2 > 0) { if (clan.Treasury < num2) { return $"{clan.Name} cannot afford the member slot ({num2} coins needed)."; } clan.Treasury -= num2; } orCreatePlayer.ClanId = clanId; orCreatePlayer.Rank = ClanRank.Member; orCreatePlayer.Role = ClanRole.None; orCreatePlayer.JoinedClanTimestamp = Now(); MarkDirty(); WarfareRPC.Instance?.BroadcastGlobalMessage("" + playerName + " joined " + clan.Name + "!"); return "Joined " + clan.Name + "."; } public string LeaveClan(long playerId) { //IL_00c5: Unknown result type (might be due to invalid IL or missing references) PlayerClanInfo player = Data.GetPlayer(playerId); if (player == null || player.ClanId == 0) { return "You are not in a clan."; } Clan clan = Data.GetClan(player.ClanId); int clanId = player.ClanId; player.ClanId = 0; player.Rank = ClanRank.Member; player.Role = ClanRole.None; player.LastClanLeaveTimestamp = Now(); if (clan != null && clan.JarlId == playerId) { PlayerClanInfo playerClanInfo = PickSuccessor(clanId); if (playerClanInfo != null) { clan.JarlId = playerClanInfo.PlayerId; playerClanInfo.Rank = ClanRank.Jarl; WarfareRPC.Instance?.BroadcastGlobalMessage("" + playerClanInfo.PlayerName + " is the new Jarl of " + clan.Name + "."); } else { DoDisbandClan(clanId); } } MarkDirty(); return "You have left the clan."; } public string KickMember(long actorId, long targetId) { PlayerClanInfo player = Data.GetPlayer(actorId); PlayerClanInfo player2 = Data.GetPlayer(targetId); if (player == null || player.ClanId == 0) { return "You are not in a clan."; } if (player2 == null || player2.ClanId != player.ClanId) { return "That player is not in your clan."; } if (player.Rank < ClanRank.Officer) { return "Only Officers and the Jarl may kick members."; } if (targetId == actorId) { return "You cannot kick yourself — use Leave Clan."; } if (player2.Rank >= player.Rank) { return "You cannot kick someone of equal or higher rank."; } player2.ClanId = 0; player2.Rank = ClanRank.Member; player2.Role = ClanRole.None; player2.LastClanLeaveTimestamp = Now(); MarkDirty(); return "" + player2.PlayerName + " was removed from the clan."; } public string SetRank(long actorId, long targetId, ClanRank rank) { PlayerClanInfo player = Data.GetPlayer(actorId); PlayerClanInfo player2 = Data.GetPlayer(targetId); if (player == null || player.ClanId == 0) { return "You are not in a clan."; } Clan clan = Data.GetClan(player.ClanId); if (clan == null || clan.JarlId != actorId) { return "Only the Jarl may change ranks."; } if (player2 == null || player2.ClanId != player.ClanId) { return "That player is not in your clan."; } if (rank == ClanRank.Jarl) { clan.JarlId = targetId; player2.Rank = ClanRank.Jarl; player.Rank = ClanRank.Officer; MarkDirty(); return "" + player2.PlayerName + " is now the Jarl."; } player2.Rank = rank; MarkDirty(); return $"{player2.PlayerName} is now {rank}."; } private PlayerClanInfo PickSuccessor(int clanId) { PlayerClanInfo playerClanInfo = null; foreach (PlayerClanInfo value in Data.Players.Values) { if (value.ClanId == clanId && (playerClanInfo == null || value.Rank > playerClanInfo.Rank || (value.Rank == playerClanInfo.Rank && value.JoinedClanTimestamp < playerClanInfo.JoinedClanTimestamp))) { playerClanInfo = value; } } return playerClanInfo; } public string SetPlayerRole(long playerId, ClanRole role) { PlayerClanInfo player = Data.GetPlayer(playerId); if (player == null || player.ClanId == 0) { return "Join a clan first."; } if (player.Role != 0 && !player.CanChangeRole(ClanConfig.RoleChangeCooldownHours?.Value ?? 24)) { return "Role change is on cooldown."; } player.Role = role; player.LastRoleChangeTimestamp = Now(); MarkDirty(); return $"Role set to {role}."; } public string CastElectionVote(long voterId, long candidateId) { PlayerClanInfo player = Data.GetPlayer(voterId); if (player == null || player.ClanId == 0) { return "You are not in a clan."; } Clan clan = Data.GetClan(player.ClanId); if (clan == null) { return "Clan not found."; } PlayerClanInfo player2 = Data.GetPlayer(candidateId); if (player2 == null || player2.ClanId != player.ClanId) { return "That candidate is not in your clan."; } clan.ElectionVotes[voterId] = candidateId; MarkDirty(); return "Vote cast for " + player2.PlayerName + "."; } private void ElectionTick() { long num = Now(); foreach (Clan value in Data.Clans.Values) { if (value.NextElectionTimestamp == 0) { value.NextElectionTimestamp = num + (long)(ClanConfig.ElectionIntervalDays?.Value ?? 14) * 86400L; } else if (num >= value.NextElectionTimestamp) { ResolveElection(value); value.NextElectionTimestamp = num + (long)(ClanConfig.ElectionIntervalDays?.Value ?? 14) * 86400L; MarkDirty(); } } } private void ResolveElection(Clan clan) { //IL_01f8: Unknown result type (might be due to invalid IL or missing references) //IL_0181: Unknown result type (might be due to invalid IL or missing references) Dictionary dictionary = new Dictionary(); foreach (KeyValuePair electionVote in clan.ElectionVotes) { PlayerClanInfo player = Data.GetPlayer(electionVote.Value); if (player != null && player.ClanId == clan.ClanId) { dictionary[electionVote.Value] = ((!dictionary.TryGetValue(electionVote.Value, out var value)) ? 1 : (value + 1)); } } long num = clan.JarlId; int num2 = -1; foreach (KeyValuePair item in dictionary) { if (item.Value > num2) { num2 = item.Value; num = item.Key; } } clan.ElectionVotes.Clear(); if (num != clan.JarlId && Data.GetPlayer(num) != null) { PlayerClanInfo player2 = Data.GetPlayer(clan.JarlId); if (player2 != null) { player2.Rank = ClanRank.Officer; } clan.JarlId = num; PlayerClanInfo player3 = Data.GetPlayer(num); player3.Rank = ClanRank.Jarl; WarfareRPC.Instance?.BroadcastGlobalMessage("" + clan.Name + " has elected " + player3.PlayerName + " as Jarl!"); } else { PlayerClanInfo player4 = Data.GetPlayer(clan.JarlId); WarfareRPC.Instance?.BroadcastGlobalMessage("" + clan.Name + "'s election kept " + (player4?.PlayerName ?? "the Jarl") + " in power."); } } public bool IsVaultOpen() { ConfigEntry vaultAlwaysOpen = ClanConfig.VaultAlwaysOpen; if (vaultAlwaysOpen != null && vaultAlwaysOpen.Value) { return true; } DateTime utcNow = DateTime.UtcNow; int num = ClanConfig.VaultOpenDayOfWeek?.Value ?? 0; int num2 = ClanConfig.VaultOpenHourUTC?.Value ?? 16; int num3 = ClanConfig.VaultOpenDurationMinutes?.Value ?? 30; if (utcNow.DayOfWeek != (DayOfWeek)num) { return false; } if (utcNow.Hour != num2) { return false; } if (utcNow.Minute >= num3) { return false; } return true; } public string UpgradeVault(long playerId) { PlayerClanInfo player = Data.GetPlayer(playerId); if (player == null || player.ClanId == 0) { return "You are not in a clan."; } if (player.Rank < ClanRank.Officer) { return "Only Officers and the Jarl may upgrade the vault."; } Clan clan = Data.GetClan(player.ClanId); if (clan == null) { return "Clan not found."; } int num = ClanConfig.MaxVaultTier?.Value ?? 5; if (clan.VaultTier >= num) { return "Vault is already at maximum tier."; } long num2 = Economy.VaultUpgradeCost(clan.VaultTier); if (clan.Treasury < num2) { return $"Treasury needs {num2} coins (has {clan.Treasury})."; } clan.Treasury -= num2; clan.VaultTier++; MarkDirty(); return $"Vault upgraded to tier {clan.VaultTier}."; } private void ProcessVaultCracks() { for (int num = Data.ActiveCracks.Count - 1; num >= 0; num--) { VaultCrackSession vaultCrackSession = Data.ActiveCracks[num]; if (vaultCrackSession.IsComplete) { int num2 = Random.Range(ClanConfig.VaultCrackMinStacks?.Value ?? 1, (ClanConfig.VaultCrackMaxStacks?.Value ?? 5) + 1); if (ShouldReduceForOffline(vaultCrackSession.TargetClanId)) { num2 = Mathf.Max(1, Mathf.RoundToInt((float)num2 * (1f - (ClanConfig.OfflineRaidEffectReduction?.Value ?? 50f) / 100f))); } List vault = Data.GetVault(vaultCrackSession.TargetClanId); int num3 = 0; for (int i = 0; i < num2; i++) { if (vault.Count <= 0) { break; } int index = Random.Range(0, vault.Count); ClanVaultItem clanVaultItem = vault[index]; Data.AddToVault(vaultCrackSession.PlayerClanId, clanVaultItem.PrefabName, clanVaultItem.DisplayName, clanVaultItem.Amount); vault.RemoveAt(index); num3++; } Clan clan = Data.GetClan(vaultCrackSession.TargetClanId); Clan clan2 = Data.GetClan(vaultCrackSession.PlayerClanId); WarfareRPC.Instance?.BroadcastGlobalMessage(string.Format("{0} cracked {1} vault — {2} stacks taken by {3}!", vaultCrackSession.PlayerName, clan?.Name ?? "a", num3, clan2?.Name ?? "the raiders")); Data.ActiveCracks.RemoveAt(num); MarkDirty(); } } } public bool ShouldReduceForOffline(int clanId) { //IL_004b: 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_0053: Unknown result type (might be due to invalid IL or missing references) ConfigEntry offlineRaidProtection = ClanConfig.OfflineRaidProtection; if (offlineRaidProtection == null || !offlineRaidProtection.Value) { return false; } HashSet hashSet = new HashSet(); if ((Object)(object)ZNet.instance != (Object)null) { foreach (PlayerInfo player in ZNet.instance.GetPlayerList()) { hashSet.Add(player.m_name); } } foreach (PlayerClanInfo value in Data.Players.Values) { if (value.ClanId == clanId && hashSet.Contains(value.PlayerName)) { return false; } } return true; } public static string ColorHex(Color c) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) return ColorUtility.ToHtmlStringRGB(c); } private void EconomyTick() { long num = Now(); int num2 = Mathf.Max(60, (ClanConfig.UpkeepTickMinutes?.Value ?? 30) * 60); Dictionary dictionary = new Dictionary(); foreach (ClanTerritory value3 in Data.Territories.Values) { if (value3.OwnerClanId != 0) { dictionary[value3.OwnerClanId] = ((!dictionary.TryGetValue(value3.OwnerClanId, out var value)) ? 1 : (value + 1)); } } bool flag = false; foreach (ClanTerritory value4 in Data.Territories.Values) { if (value4.OwnerClanId == 0) { continue; } if (value4.LastIncomeTimestamp == 0) { value4.LastIncomeTimestamp = num; flag = true; } else { if (num - value4.LastIncomeTimestamp < num2) { continue; } int num3 = (int)((num - value4.LastIncomeTimestamp) / num2); num3 = Mathf.Clamp(num3, 1, 48); Clan clan = Data.GetClan(value4.OwnerClanId); if (clan != null) { int value2; int territoryCount = ((!dictionary.TryGetValue(value4.OwnerClanId, out value2)) ? 1 : value2); float globalMultiplier = Economy.GlobalUpkeepMultiplier(territoryCount); long num4 = (Economy.TerritoryIncome(value4) - Economy.TerritoryUpkeep(value4, globalMultiplier)) * num3; clan.Treasury += num4; if (clan.Treasury < 0) { clan.Treasury = 0L; } value4.LastIncomeTimestamp = num; flag = true; } } } if (flag) { MarkDirty(); } } private void RotTick() { //IL_008d: Unknown result type (might be due to invalid IL or missing references) long num = Now(); int num2 = Mathf.Max(60, (ClanConfig.RotDecayHours?.Value ?? 6) * 3600); bool flag = false; for (int num3 = Data.RotTotems.Count - 1; num3 >= 0; num3--) { RotTotem rotTotem = Data.RotTotems[num3]; if (rotTotem.State == TotemState.Destroyed) { Data.RotTotems.RemoveAt(num3); } else { ClanTerritory territory = Data.GetTerritory(rotTotem.GridPosition); if (territory == null || territory.OwnerClanId == 0) { Data.RotTotems.RemoveAt(num3); flag = true; } else if (rotTotem.LastDecayTimestamp == 0) { rotTotem.LastDecayTimestamp = num; flag = true; } else if (num - rotTotem.LastDecayTimestamp >= num2) { int num4 = Mathf.Clamp((int)((num - rotTotem.LastDecayTimestamp) / num2), 1, 8); rotTotem.LastDecayTimestamp = num; rotTotem.State = TotemState.Active; int rotCount = territory.RotCount; territory.RotCount = Mathf.Clamp(territory.RotCount + num4, 0, 4); flag = true; if (rotCount < 4 && territory.RotCount >= 4) { territory.State = TerritoryState.Rooted; Data.ActiveCaptures.RemoveAll((CaptureSession c) => c.TerritoryGridX == territory.GridX && c.TerritoryGridY == territory.GridY); Clan clan = Data.GetClan(territory.OwnerClanId); WarfareRPC.Instance?.BroadcastGlobalMessage("" + territory.DisplayName + " (" + clan?.Name + ") has fully rotted — any clan may now seize it!"); } else if (territory.RotCount > 0 && territory.State == TerritoryState.Normal) { territory.State = TerritoryState.Contested; } } } } if (flag) { MarkDirty(); } } private void SeasonTick() { int num = ClanConfig.SeasonLengthDays?.Value ?? 60; if (num <= 0) { return; } if (Data.SeasonStartTimestamp == 0) { Data.SeasonStartTimestamp = Now(); return; } long num2 = Now() - Data.SeasonStartTimestamp; if (num2 >= (long)num * 86400L) { RunCycleOfOdin(); } } public void RunCycleOfOdin() { Data.SeasonNumber++; Data.SeasonStartTimestamp = Now(); Data.Territories.Clear(); Data.ClanVaults.Clear(); Data.RotTotems.Clear(); Data.Wars.Clear(); Data.ActiveCaptures.Clear(); Data.ActiveCracks.Clear(); int num = ClanConfig.StartingTreasury?.Value ?? 0; foreach (Clan value in Data.Clans.Values) { value.Treasury = num; value.VaultTier = 1; value.ExtraTerritorySlots = 0; value.ElectionVotes.Clear(); value.NextElectionTimestamp = Now() + (long)(ClanConfig.ElectionIntervalDays?.Value ?? 14) * 86400L; } MarkDirty(); SaveData(); WarfareRPC.Instance?.BroadcastGlobalMessage($"══ THE CYCLE OF ODIN ══\nSeason {Data.SeasonNumber} begins. The map is reborn — claim it anew!"); WarfareRPC.Instance?.SyncAllDataToClients(); Plugin.Log.LogWarning((object)$"Cycle of Odin: season {Data.SeasonNumber} started."); } public ClaimResult TryClaimTerritory(long playerId, string playerName, Vector2i grid) { //IL_0007: 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_007d: 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_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: 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_02af: Unknown result type (might be due to invalid IL or missing references) PlayerClanInfo player = Data.GetPlayer(playerId); if (player == null || player.ClanId == 0) { return new ClaimResult(s: false, "You must join a clan first!"); } Clan clan = Data.GetClan(player.ClanId); if (clan == null) { return new ClaimResult(s: false, "Your clan no longer exists."); } if (VoronoiGrid.Instance != null && VoronoiGrid.Instance.IsSpawnZone(grid)) { return new ClaimResult(s: false, "The spawn zone is neutral ground — no claims allowed."); } float num = Vector3.Distance(grid.ToWorldCenter(), Vector3.zero); if (num < (float)(ClanConfig.SpawnProtectionRadius?.Value ?? 2500)) { return new ClaimResult(s: false, "Too close to world spawn!"); } ClanTerritory territory = Data.GetTerritory(grid); bool flag = territory?.IsRotted ?? false; if (territory != null && territory.OwnerClanId != 0 && !flag) { if (territory.OwnerClanId == player.ClanId) { return new ClaimResult(s: false, "Your clan already owns this territory."); } return new ClaimResult(s: false, "Enemy land — declare war and capture it instead."); } if (!flag && player.Role != ClanRole.Explorer) { return new ClaimResult(s: false, "Only Explorers can claim unclaimed territory!"); } int clanTerritoryCount = Data.GetClanTerritoryCount(player.ClanId); int num2 = Economy.TerritoryCap(clan); if (clanTerritoryCount >= num2) { return new ClaimResult(s: false, $"Territory cap reached ({clanTerritoryCount}/{num2}). Buy an expansion."); } ClanTerritory clanTerritory = territory ?? new ClanTerritory { GridX = grid.x, GridY = grid.y }; clanTerritory.OwnerClanId = player.ClanId; clanTerritory.ClaimedByPlayerId = playerId; clanTerritory.ClaimedByPlayerName = playerName; clanTerritory.ClaimTimestamp = Now(); clanTerritory.RotCount = 0; clanTerritory.State = TerritoryState.Normal; clanTerritory.LastIncomeTimestamp = Now(); clanTerritory.LastRotTickTimestamp = Now(); clanTerritory.Type = ((!Data.ClanHasCapital(player.ClanId)) ? TerritoryType.Capital : TerritoryType.Colony); if (clanTerritory.SizeLevel < 1) { clanTerritory.SizeLevel = 1; } ValueTerritory(clanTerritory); InitTerritoryStats(clanTerritory); Data.Territories[WarfareData.GridToKey(grid)] = clanTerritory; Data.RotTotems.RemoveAll((RotTotem t) => t.TerritoryGridX == grid.x && t.TerritoryGridY == grid.y); Data.ActiveCaptures.RemoveAll((CaptureSession c) => c.TerritoryGridX == grid.x && c.TerritoryGridY == grid.y); MarkDirty(); string text = (clanTerritory.IsCapital ? "Capital" : "Colony"); return new ClaimResult(s: true, "Claimed " + clanTerritory.DisplayName + " as a " + text + " for " + clan.Name + "!"); } public void ValueTerritory(ClanTerritory t) { //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_0009: 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_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0035: 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_0046: Unknown result type (might be due to invalid IL or missing references) try { Vector2i gridPosition = t.GridPosition; Dictionary dictionary = BiomeUtils.SampleBiomeComposition(gridPosition, 64); Biome dominantBiome = BiomeUtils.GetDominantBiome(dictionary); t.BiomeValueTier = Economy.BiomeValueTier(dominantBiome); if (string.IsNullOrEmpty(t.CustomName)) { bool hasMerchant = BiomeUtils.CellHasMerchant(gridPosition); bool hasBossAltar = BiomeUtils.HasPointOfInterest(gridPosition); t.CustomName = TerritoryNaming.GenerateTerritoryName(gridPosition, dictionary, hasMerchant, hasBossAltar); } } catch (Exception ex) { Plugin.Log.LogWarning((object)$"ValueTerritory failed for ({t.GridX},{t.GridY}): {ex.Message}"); if (t.BiomeValueTier < 1) { t.BiomeValueTier = 1; } } } public void InitTerritoryStats(ClanTerritory t) { t.MaxHP = Economy.TerritoryMaxHP(t); if (t.HP <= 0f || t.HP > t.MaxHP) { t.HP = t.MaxHP; } } public string TryRenameTerritory(long playerId, Vector2i grid, string newName) { //IL_0032: Unknown result type (might be due to invalid IL or missing references) PlayerClanInfo player = Data.GetPlayer(playerId); if (player == null || player.ClanId == 0) { return "You must join a clan first!"; } ClanTerritory territory = Data.GetTerritory(grid); if (territory == null || territory.OwnerClanId == 0) { return "This territory is not claimed!"; } if (territory.OwnerClanId != player.ClanId) { return "You can only rename your own clan's territories!"; } if (!territory.CanRename()) { return "Territory rename on cooldown (24 hours)."; } newName = newName?.Trim(); if (string.IsNullOrEmpty(newName) || newName.Length > 32) { return "Name must be 1-32 characters!"; } territory.CustomName = newName; territory.LastRenameTimestamp = Now(); MarkDirty(); return "Territory renamed to \"" + newName + "\"!"; } public string UpgradeTerritory(long playerId, Vector2i grid) { //IL_0050: Unknown result type (might be due to invalid IL or missing references) PlayerClanInfo player = Data.GetPlayer(playerId); if (player == null || player.ClanId == 0) { return "You are not in a clan."; } if (player.Rank < ClanRank.Officer) { return "Only Officers and the Jarl may upgrade territory."; } ClanTerritory territory = Data.GetTerritory(grid); if (territory == null || territory.OwnerClanId != player.ClanId) { return "That is not your clan's territory."; } int num = ClanConfig.MaxTerritorySizeLevel?.Value ?? 5; if (territory.SizeLevel >= num) { return "Territory is already at maximum size."; } Clan clan = Data.GetClan(player.ClanId); long num2 = Economy.TerritoryUpgradeCost(territory.SizeLevel); if (clan.Treasury < num2) { return $"Treasury needs {num2} coins (has {clan.Treasury})."; } clan.Treasury -= num2; territory.SizeLevel++; float num3 = ((territory.MaxHP > 0f) ? (territory.HP / territory.MaxHP) : 1f); territory.MaxHP = Economy.TerritoryMaxHP(territory); territory.HP = territory.MaxHP * num3; MarkDirty(); return $"{territory.DisplayName} upgraded to size {territory.SizeLevel}."; } public string SetCapital(long playerId, Vector2i grid) { //IL_004c: Unknown result type (might be due to invalid IL or missing references) PlayerClanInfo player = Data.GetPlayer(playerId); if (player == null || player.ClanId == 0) { return "You are not in a clan."; } if (player.Rank < ClanRank.Officer) { return "Only Officers and the Jarl may move the Capital."; } ClanTerritory territory = Data.GetTerritory(grid); if (territory == null || territory.OwnerClanId != player.ClanId) { return "That is not your clan's territory."; } if (territory.IsCapital) { return "That is already your Capital."; } foreach (ClanTerritory clanTerritory in Data.GetClanTerritories(player.ClanId)) { if (clanTerritory.Type == TerritoryType.Capital) { clanTerritory.Type = TerritoryType.Colony; clanTerritory.MaxHP = Economy.TerritoryMaxHP(clanTerritory); clanTerritory.HP = Mathf.Min(clanTerritory.HP, clanTerritory.MaxHP); } } territory.Type = TerritoryType.Capital; territory.MaxHP = Economy.TerritoryMaxHP(territory); territory.HP = territory.MaxHP; MarkDirty(); return "" + territory.DisplayName + " is now your Capital."; } public string BuyTerritoryExpansion(long playerId) { PlayerClanInfo player = Data.GetPlayer(playerId); if (player == null || player.ClanId == 0) { return "You are not in a clan."; } if (player.Rank < ClanRank.Officer) { return "Only Officers and the Jarl may buy expansions."; } Clan clan = Data.GetClan(player.ClanId); if (clan == null) { return "Clan not found."; } int num = Economy.TerritoryCap(clan); if (num >= (ClanConfig.MaxTerritoryCap?.Value ?? 100)) { return "Territory cap is already at the maximum."; } long num2 = Economy.TerritoryExpansionCost(clan.ExtraTerritorySlots); if (clan.Treasury < num2) { return $"Treasury needs {num2} coins (has {clan.Treasury})."; } clan.Treasury -= num2; clan.ExtraTerritorySlots++; MarkDirty(); return $"Territory cap raised to {Economy.TerritoryCap(clan)}."; } private void CaptureTick() { //IL_0123: 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_0135: 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_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Unknown result type (might be due to invalid IL or missing references) Dictionary> dictionary = new Dictionary>(); Dictionary dictionary2 = new Dictionary(); List allPlayers = Player.GetAllPlayers(); if (allPlayers != null) { foreach (Player item in allPlayers) { if ((Object)(object)item == (Object)null || ((Character)item).IsDead()) { continue; } PlayerClanInfo player = Data.GetPlayer(item.GetPlayerID()); if (player != null && player.ClanId != 0) { Vector2i val = GridExtensions.WorldToGrid(((Component)item).transform.position); string key = WarfareData.GridToKey(val); if (!dictionary.TryGetValue(key, out var value)) { value = (dictionary[key] = new List()); dictionary2[key] = val; } value.Add(player); } } } foreach (KeyValuePair> item2 in dictionary) { Vector2i grid = dictionary2[item2.Key]; ClanTerritory territory = Data.GetTerritory(grid); if (territory == null || territory.OwnerClanId == 0 || territory.IsCapital || territory.IsRotted) { continue; } int ownerClanId = territory.OwnerClanId; Dictionary dictionary3 = new Dictionary(); int num = 0; foreach (PlayerClanInfo item3 in item2.Value) { if (item3.ClanId == ownerClanId) { num++; } else if (Data.GetActiveWarBetween(item3.ClanId, ownerClanId) != null) { dictionary3[item3.ClanId] = ((!dictionary3.TryGetValue(item3.ClanId, out var value2)) ? 1 : (value2 + 1)); } } int num2 = 0; int num3 = 0; foreach (KeyValuePair item4 in dictionary3) { if (item4.Value > num3) { num3 = item4.Value; num2 = item4.Key; } } CaptureSession captureSession = Data.ActiveCaptures.Find((CaptureSession c) => c.TerritoryGridX == grid.x && c.TerritoryGridY == grid.y); if (num2 == 0) { continue; } if (captureSession == null) { captureSession = new CaptureSession { TerritoryGridX = grid.x, TerritoryGridY = grid.y, AttackerClanId = num2, DefenderClanId = ownerClanId, Threshold = Economy.CaptureThreshold(territory), StartTimestamp = Now() }; Data.ActiveCaptures.Add(captureSession); territory.State = TerritoryState.Contested; Clan clan = Data.GetClan(num2); WarfareRPC.Instance?.BroadcastGlobalMessage("" + clan?.Name + " is capturing " + territory.DisplayName + "!"); } captureSession.AttackerClanId = num2; captureSession.DefenderClanId = ownerClanId; captureSession.LastAttackerSeenTime = Now(); bool flag = (captureSession.Siege = num3 >= (ClanConfig.SiegeAttackerCount?.Value ?? 5)); territory.State = ((!flag) ? TerritoryState.Contested : TerritoryState.Attacked); if (num > num3) { if (captureSession.LastDefenderMajorityTime == 0) { captureSession.LastDefenderMajorityTime = Now(); } if (Now() - captureSession.LastDefenderMajorityTime >= (ClanConfig.InterruptDefenderMajoritySeconds?.Value ?? 30)) { captureSession.Progress = Mathf.Max(0f, captureSession.Progress - Economy.ClaimSpeed(num, 1f, territory, siege: false)); } } else { captureSession.LastDefenderMajorityTime = 0L; float num4 = Economy.ClaimSpeed(num3, 1f, territory, flag); if (ShouldReduceForOffline(ownerClanId)) { num4 *= 1f - (ClanConfig.OfflineRaidEffectReduction?.Value ?? 50f) / 100f; } captureSession.Progress += num4; } if (captureSession.CombatPoints > 0) { captureSession.Progress += captureSession.CombatPoints; captureSession.CombatPoints = 0; } if (captureSession.Progress >= captureSession.Threshold) { CompleteCapture(territory, captureSession); } } CaptureExpiryScan(); } private void CaptureExpiryScan() { //IL_005b: Unknown result type (might be due to invalid IL or missing references) int num = ClanConfig.InterruptNoAttackerSeconds?.Value ?? 60; for (int num2 = Data.ActiveCaptures.Count - 1; num2 >= 0; num2--) { CaptureSession captureSession = Data.ActiveCaptures[num2]; if (Now() - captureSession.LastAttackerSeenTime >= num) { ClanTerritory territory = Data.GetTerritory(captureSession.GridPosition); if (territory != null && !territory.IsRotted) { territory.State = TerritoryState.Normal; } Data.ActiveCaptures.RemoveAt(num2); } } } private void CompleteCapture(ClanTerritory territory, CaptureSession session) { Clan clan = Data.GetClan(territory.OwnerClanId); Clan clan2 = Data.GetClan(session.AttackerClanId); territory.OwnerClanId = session.AttackerClanId; territory.Type = TerritoryType.Colony; territory.State = TerritoryState.Normal; territory.ClaimTimestamp = Now(); territory.ClaimedByPlayerName = clan2?.Name ?? "raiders"; territory.RotCount = 0; territory.HP = territory.MaxHP; territory.LastIncomeTimestamp = Now(); Data.ActiveCaptures.Remove(session); Data.RotTotems.RemoveAll((RotTotem t) => t.TerritoryGridX == territory.GridX && t.TerritoryGridY == territory.GridY); MarkDirty(); WarfareRPC.Instance?.BroadcastGlobalMessage("" + clan2?.Name + " captured " + territory.DisplayName + " from " + clan?.Name + "!"); } public void RegisterCombatKill(Vector3 deathPosition, int attackerClanId, int points) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) Vector2i grid = GridExtensions.WorldToGrid(deathPosition); CaptureSession captureSession = Data.ActiveCaptures.Find((CaptureSession c) => c.TerritoryGridX == grid.x && c.TerritoryGridY == grid.y); if (captureSession != null && captureSession.AttackerClanId == attackerClanId) { captureSession.CombatPoints += points; } } public string DeclareWar(long playerId, int targetClanId, WarType type) { PlayerClanInfo player = Data.GetPlayer(playerId); if (player == null || player.ClanId == 0) { return "You are not in a clan."; } if (player.Rank < ClanRank.Officer) { return "Only Officers and the Jarl may declare war."; } if (type == WarType.None) { type = WarType.War; } Clan clan = Data.GetClan(player.ClanId); Clan clan2 = Data.GetClan(targetClanId); if (clan2 == null) { return "That clan no longer exists."; } if (targetClanId == player.ClanId) { return "You cannot declare war on yourself."; } if (Data.GetActiveWarBetween(player.ClanId, targetClanId) != null) { return "You are already at war with " + clan2.Name + "."; } long num = ClanConfig.WarDeclareCost?.Value ?? 200; if (clan.Treasury < num) { return $"Treasury needs {num} coins to declare war (has {clan.Treasury})."; } clan.Treasury -= num; long num2 = Now(); War item = new War { WarId = Data.NextWarId++, AttackerClanId = player.ClanId, DefenderClanId = targetClanId, Type = type, StartTimestamp = num2, EndTimestamp = num2 + (long)(ClanConfig.WarDurationMinutes?.Value ?? 120) * 60L }; Data.Wars.Add(item); MarkDirty(); WarfareRPC.Instance?.BroadcastGlobalMessage($"⚔ {clan.Name} has declared {type} on {clan2.Name}! ⚔"); return $"{type} declared on {clan2.Name}."; } private void WarExpiryTick() { bool flag = false; for (int num = Data.Wars.Count - 1; num >= 0; num--) { War war = Data.Wars[num]; if (!war.IsActive) { Clan clan = Data.GetClan(war.AttackerClanId); Clan clan2 = Data.GetClan(war.DefenderClanId); Data.ActiveCaptures.RemoveAll((CaptureSession c) => c.TerritoryGridX != int.MinValue && ((c.AttackerClanId == war.AttackerClanId && c.DefenderClanId == war.DefenderClanId) || (c.AttackerClanId == war.DefenderClanId && c.DefenderClanId == war.AttackerClanId))); Data.Wars.RemoveAt(num); flag = true; WarfareRPC.Instance?.BroadcastGlobalMessage(string.Format("The {0} between {1} and {2} has ended.", war.Type, clan?.Name ?? "?", clan2?.Name ?? "?")); } } if (flag) { MarkDirty(); } } public bool AreAtWar(int clanA, int clanB) { return clanA != 0 && clanB != 0 && Data.GetActiveWarBetween(clanA, clanB) != null; } public string PlaceRotTotem(long playerId, string playerName, Vector3 worldPos) { //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0055: 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_0066: 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_01f5: Unknown result type (might be due to invalid IL or missing references) PlayerClanInfo player = Data.GetPlayer(playerId); if (player == null || player.ClanId == 0) { return "You are not in a clan."; } if (player.Role != ClanRole.Parasite) { return "Only Parasites can raise rot totems."; } Vector2i grid = GridExtensions.WorldToGrid(worldPos); ClanTerritory territory = Data.GetTerritory(grid); if (territory == null || territory.OwnerClanId == 0) { return "Rot totems can only be raised on enemy territory."; } if (territory.OwnerClanId == player.ClanId) { return "You cannot rot your own clan's land."; } if (territory.IsRotted) { return "That territory is already fully rotted."; } int count = Data.RotTotems.FindAll((RotTotem t) => t.TerritoryGridX == grid.x && t.TerritoryGridY == grid.y && t.State != TotemState.Destroyed).Count; int num = ClanConfig.MaxRotTotemsPerTerritory?.Value ?? 4; if (count >= num) { return $"That territory already holds {count}/{num} rot totems."; } Clan clan = Data.GetClan(player.ClanId); long num2 = Economy.RotTotemCost(1, territory.BiomeValueTier); if (clan.Treasury < num2) { return $"Treasury needs {num2} coins to raise a totem (has {clan.Treasury})."; } clan.Treasury -= num2; Data.RotTotems.Add(new RotTotem { TerritoryGridX = grid.x, TerritoryGridY = grid.y, PlacedByPlayerId = playerId, PlacedByPlayerName = playerName, PlacerClanId = player.ClanId, PlacedTimestamp = Now(), LastDecayTimestamp = Now(), WorldPosition = worldPos, State = TotemState.Placed, Level = 1 }); MarkDirty(); Clan clan2 = Data.GetClan(territory.OwnerClanId); WarfareRPC.Instance?.BroadcastGlobalMessage("A rot totem festers in " + clan2?.Name + "'s land at " + territory.DisplayName + "!"); return "Rot totem raised. The land will wither."; } public string PlaceBounty(long actorId, long targetPlayerId, int targetClanId, long amount) { ConfigEntry bountySystemEnabled = ClanConfig.BountySystemEnabled; if (bountySystemEnabled == null || !bountySystemEnabled.Value) { return "The bounty system is disabled."; } PlayerClanInfo player = Data.GetPlayer(actorId); if (player == null || player.ClanId == 0) { return "You are not in a clan."; } if (player.Rank < ClanRank.Officer) { return "Only Officers and the Jarl may place bounties."; } if (amount <= 0) { return "Bounty must be positive."; } Clan clan = Data.GetClan(player.ClanId); if (clan.Treasury < amount) { return $"Treasury needs {amount} coins (has {clan.Treasury})."; } if (targetPlayerId != 0) { PlayerClanInfo player2 = Data.GetPlayer(targetPlayerId); if (player2 == null) { return "Unknown target player."; } clan.Treasury -= amount; player2.Bounty += amount; MarkDirty(); WarfareRPC.Instance?.BroadcastGlobalMessage($"A {player2.Bounty}-coin bounty hangs over {player2.PlayerName}!"); return "Bounty placed on " + player2.PlayerName + "."; } if (targetClanId != 0) { Clan clan2 = Data.GetClan(targetClanId); if (clan2 == null) { return "Unknown target clan."; } clan.Treasury -= amount; clan2.Bounty += amount; MarkDirty(); WarfareRPC.Instance?.BroadcastGlobalMessage($"A {clan2.Bounty}-coin bounty hangs over clan {clan2.Name}!"); return "Bounty placed on " + clan2.Name + "."; } return "No bounty target given."; } public void RegisterIllegalKill(long killerId) { ConfigEntry bountySystemEnabled = ClanConfig.BountySystemEnabled; if (bountySystemEnabled != null && bountySystemEnabled.Value) { PlayerClanInfo player = Data.GetPlayer(killerId); if (player != null) { player.Bounty += ClanConfig.AutoBountyIllegalKill?.Value ?? 250; MarkDirty(); } } } public void CollectBounty(long killerId, long victimId) { ConfigEntry bountySystemEnabled = ClanConfig.BountySystemEnabled; if (bountySystemEnabled == null || !bountySystemEnabled.Value) { return; } PlayerClanInfo player = Data.GetPlayer(killerId); PlayerClanInfo player2 = Data.GetPlayer(victimId); if (player == null || player2 == null || player2.Bounty <= 0) { return; } if (player.ClanId != 0) { Clan clan = Data.GetClan(player.ClanId); if (clan != null) { clan.Treasury += player2.Bounty; } } WarfareRPC.Instance?.BroadcastGlobalMessage($"{player.PlayerName} claimed the {player2.Bounty}-coin bounty on {player2.PlayerName}!"); player2.Bounty = 0L; MarkDirty(); } public string StartVaultCrack(long playerId, string playerName, Vector2i grid, Vector3 pos) { //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_0139: Unknown result type (might be due to invalid IL or missing references) //IL_0145: Unknown result type (might be due to invalid IL or missing references) //IL_015c: Unknown result type (might be due to invalid IL or missing references) //IL_015e: Unknown result type (might be due to invalid IL or missing references) PlayerClanInfo player = Data.GetPlayer(playerId); if (player == null || player.ClanId == 0) { return "You are not in a clan."; } if (player.Role != ClanRole.Invader) { return "Only Invaders can crack vaults!"; } if (!player.CanCrackVault(ClanConfig.VaultCrackCooldownHours?.Value ?? 6)) { return "Vault crack is on cooldown."; } ClanTerritory territory = Data.GetTerritory(grid); if (territory == null || territory.OwnerClanId == 0 || territory.OwnerClanId == player.ClanId) { return "You must be in enemy territory."; } if (Data.ActiveCracks.Exists((VaultCrackSession c) => c.PlayerId == playerId)) { return "You are already cracking a vault."; } int num = ClanConfig.VaultCrackDurationMinutes?.Value ?? 30; VaultCrackSession item = new VaultCrackSession { PlayerId = playerId, PlayerName = playerName, PlayerClanId = player.ClanId, TargetClanId = territory.OwnerClanId, TerritoryGridX = grid.x, TerritoryGridY = grid.y, StartTimestamp = Now(), StartPosition = pos, DurationMinutes = num }; Data.ActiveCracks.Add(item); player.LastVaultCrackTimestamp = Now(); MarkDirty(); Clan clan = Data.GetClan(territory.OwnerClanId); WarfareRPC.Instance?.BroadcastGlobalMessage("" + playerName + " is cracking the vault in " + clan?.Name + "'s " + territory.DisplayName + "!"); return $"Vault crack started — hold the ground for {num} minutes!"; } } public static class GridExtensions { public static Vector3 ToWorldCenter(this Vector2i grid) { //IL_0012: 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_0018: 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_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0048: 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_005f: Unknown result type (might be due to invalid IL or missing references) if (VoronoiGrid.Instance != null) { return VoronoiGrid.Instance.GetRegionCenter(grid); } int num = ClanConfig.GridCellSize?.Value ?? 500; return new Vector3((float)(grid.x * num) + (float)num / 2f, 0f, (float)(grid.y * num) + (float)num / 2f); } public static Vector2i WorldToGrid(Vector3 worldPos) { //IL_0012: 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_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0055: 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_003f: Unknown result type (might be due to invalid IL or missing references) //IL_004d: 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) if (VoronoiGrid.Instance != null) { return VoronoiGrid.Instance.GetRegion(worldPos); } int num = ClanConfig.GridCellSize?.Value ?? 500; return new Vector2i(Mathf.FloorToInt(worldPos.x / (float)num), Mathf.FloorToInt(worldPos.z / (float)num)); } } }