using System; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using HarmonyLib; using Microsoft.CodeAnalysis; using UnityEngine; using UnityEngine.Rendering; [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.6.2", FrameworkDisplayName = ".NET Framework 4.6.2")] [assembly: AssemblyCompany("BigBattles")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+6a33726e3a84ddf770b4ea8cef0c84c5d22a5665")] [assembly: AssemblyProduct("BigBattles")] [assembly: AssemblyTitle("BigBattles")] [assembly: AssemblyVersion("1.0.0.0")] [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 BigBattles { public enum ArmySide { A, B } public enum NpcCategory { Human, Creature } public class NpcTypeDefinition { public string DisplayName; public string PrefabName; public NpcCategory Category; public bool SupportsEquipment; public float DefaultHealth; public float Scale; public float SpacingMultiplier; public float OverrideAttackRange; public float AttackCooldown; public bool ArcherMode; public NpcTypeDefinition(string displayName, string prefabName, NpcCategory category, bool supportsEquipment, float defaultHealth, float scale = 1f, float spacingMultiplier = 1f, float overrideAttackRange = 0f, float attackCooldown = 0f, bool archerMode = false) { DisplayName = displayName; PrefabName = prefabName; Category = category; SupportsEquipment = supportsEquipment; DefaultHealth = defaultHealth; Scale = scale; SpacingMultiplier = spacingMultiplier; OverrideAttackRange = overrideAttackRange; AttackCooldown = attackCooldown; ArcherMode = archerMode; } } public class ArmyConfig { public ArmySide Side; public int SelectedNpcType; public int[] EquipmentSlots; public int SpawnCount; public bool DefaultsApplied; private static readonly string[] SafeHelmets = new string[11] { "HelmetBronze", "HelmetIron", "HelmetDrake", "HelmetPadded", "HelmetCarapace", "HelmetFlametal", "HelmetMage", "HelmetFenring", "HelmetYule", "HelmetTrollLeather", "HelmetLeather" }; private static readonly string[] SafeChests = new string[12] { "ArmorBronzeChest", "ArmorIronChest", "ArmorWolfChest", "ArmorPaddedCuirass", "ArmorCarapaceChest", "ArmorFlametalChest", "ArmorMageChest", "ArmorTrollLeatherChest", "ArmorLeatherChest", "ArmorRagsChest", "ArmorRootChest", "ArmorFenringChest" }; private static readonly string[] SafeLegs = new string[12] { "ArmorBronzeLegs", "ArmorIronLegs", "ArmorWolfLegs", "ArmorPaddedGreaves", "ArmorCarapaceLegs", "ArmorFlametalLegs", "ArmorMageLegs", "ArmorTrollLeatherLegs", "ArmorLeatherLegs", "ArmorRagsLegs", "ArmorRootLegs", "ArmorFenringLegs" }; private static readonly string[] SafeBows = new string[5] { "Bow", "BowFineWood", "BowHuntsman", "BowDraugrFang", "BowSpineSnap" }; private static readonly string[] SafeMeleeWeapons = new string[25] { "SwordBronze", "SwordIron", "SwordSilver", "SwordBlackmetal", "SwordMistwalker", "SwordNiedhogg", "MaceBronze", "MaceIron", "MaceSilver", "MaceNeedle", "MaceStagbreaker", "AxeBronze", "AxeIron", "AxeBlackMetal", "AxeJotunBane", "KnifeFlint", "KnifeCopper", "KnifeChitin", "KnifeSilver", "KnifeBlackMetal", "KnifeSkollAndHati", "Club", "SledgeStagbreaker", "FistFenrirClaw", "Splitnir" }; public ArmyConfig(ArmySide side) { Side = side; SelectedNpcType = 0; EquipmentSlots = new int[6]; SpawnCount = 80; DefaultsApplied = false; } public void ApplyDefaults(NpcTypeDefinition npcType = null) { if (DefaultsApplied || !EquipmentData.IsReady) { return; } DefaultsApplied = true; if (npcType != null && npcType.ArcherMode) { if (Side == ArmySide.A) { EquipmentSlots[0] = EquipmentData.FindIndexByName(0, "Flametal"); EquipmentSlots[1] = EquipmentData.FindIndexByName(1, "Flametal"); EquipmentSlots[2] = EquipmentData.FindIndexByName(2, "Flametal"); EquipmentSlots[3] = EquipmentData.FindIndexByName(3, "#0 Red"); EquipmentSlots[4] = EquipmentData.FindIndexByName(4, "Draugr Fang"); EquipmentSlots[5] = 0; } else { EquipmentSlots[0] = EquipmentData.FindIndexByName(0, "Drake"); EquipmentSlots[1] = EquipmentData.FindIndexByName(1, "Wolf Hide Chest"); EquipmentSlots[2] = EquipmentData.FindIndexByName(2, "Wolf Hide Trou"); EquipmentSlots[3] = EquipmentData.FindIndexByName(3, "#2 Blue"); EquipmentSlots[4] = EquipmentData.FindIndexByName(4, "Spine Snap"); EquipmentSlots[5] = 0; } } else if (Side == ArmySide.A) { EquipmentSlots[0] = EquipmentData.FindIndexByName(0, "Flametal"); EquipmentSlots[1] = EquipmentData.FindIndexByName(1, "Flametal"); EquipmentSlots[2] = EquipmentData.FindIndexByName(2, "Flametal"); EquipmentSlots[3] = EquipmentData.FindIndexByName(3, "#0 Red"); EquipmentSlots[4] = EquipmentData.FindIndexByName(4, "Splitnir"); EquipmentSlots[5] = EquipmentData.FindIndexByName(5, "Flametal"); } else { EquipmentSlots[0] = EquipmentData.FindIndexByName(0, "Drake"); EquipmentSlots[1] = EquipmentData.FindIndexByName(1, "Wolf Hide Chest"); EquipmentSlots[2] = EquipmentData.FindIndexByName(2, "Wolf Hide Trou"); EquipmentSlots[3] = EquipmentData.FindIndexByName(3, "#2 Blue"); EquipmentSlots[4] = EquipmentData.FindIndexByName(4, "Nidh"); EquipmentSlots[5] = EquipmentData.FindIndexByName(5, "Carapace"); } } public void RandomizeEquipment(bool archerMode = false) { if (!EquipmentData.IsReady) { return; } for (int i = 0; i < 6; i++) { List listForSlot = EquipmentData.GetListForSlot(i); if (listForSlot.Count <= 1) { continue; } switch (i) { case 0: EquipmentSlots[i] = PickFromSafeList(listForSlot, SafeHelmets); continue; case 1: EquipmentSlots[i] = PickFromSafeList(listForSlot, SafeChests); continue; case 2: EquipmentSlots[i] = PickFromSafeList(listForSlot, SafeLegs); continue; case 3: if (Side == ArmySide.A) { EquipmentSlots[i] = EquipmentData.FindIndexByName(3, "#0 Red"); } else { EquipmentSlots[i] = EquipmentData.FindIndexByName(3, "#1 White"); } continue; } if (i == 4 && archerMode) { EquipmentSlots[i] = PickFromSafeList(listForSlot, SafeBows); continue; } switch (i) { case 4: if (Random.value < 0.15f) { int num2 = PickFromSafeList(listForSlot, SafeBows); EquipmentSlots[i] = ((num2 > 0) ? num2 : PickRandomMeleeWeapon(listForSlot)); } else { EquipmentSlots[i] = PickRandomMeleeWeapon(listForSlot); } break; case 5: { if (archerMode) { EquipmentSlots[i] = 0; break; } string value = ""; List listForSlot2 = EquipmentData.GetListForSlot(4); int num = EquipmentSlots[4]; if (num > 0 && num < listForSlot2.Count) { value = listForSlot2[num].PrefabName; } if (Array.IndexOf(SafeBows, value) >= 0) { EquipmentSlots[i] = 0; } else { EquipmentSlots[i] = Random.Range(1, listForSlot.Count); } break; } } } } private static int PickFromSafeList(List list, string[] safeNames) { HashSet hashSet = new HashSet(safeNames); List list2 = new List(); for (int i = 1; i < list.Count; i++) { if (hashSet.Contains(list[i].PrefabName)) { list2.Add(i); } } if (list2.Count > 0) { return list2[Random.Range(0, list2.Count)]; } return Random.Range(1, list.Count); } private static int PickRandomMeleeWeapon(List weapons) { //IL_0100: 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_0107: Unknown result type (might be due to invalid IL or missing references) //IL_010a: Invalid comparison between Unknown and I4 List list = new List(); HashSet hashSet = new HashSet(SafeMeleeWeapons); for (int i = 1; i < weapons.Count; i++) { if (hashSet.Contains(weapons[i].PrefabName)) { list.Add(i); } } if (list.Count > 0) { return list[Random.Range(0, list.Count)]; } for (int j = 1; j < weapons.Count; j++) { string prefabName = weapons[j].PrefabName; if (string.IsNullOrEmpty(prefabName)) { continue; } ObjectDB instance = ObjectDB.instance; GameObject val = ((instance != null) ? instance.GetItemPrefab(prefabName) : null); if ((Object)(object)val == (Object)null) { continue; } ItemDrop component = val.GetComponent(); if (component?.m_itemData?.m_shared == null) { continue; } ItemType itemType = component.m_itemData.m_shared.m_itemType; if ((int)itemType == 3) { float num = component.m_itemData.m_shared.m_damages.m_damage + component.m_itemData.m_shared.m_damages.m_blunt + component.m_itemData.m_shared.m_damages.m_slash + component.m_itemData.m_shared.m_damages.m_pierce; if (num > 5f) { list.Add(j); } } } if (list.Count > 0) { return list[Random.Range(0, list.Count)]; } return Random.Range(1, weapons.Count); } } public static class NpcTypes { public static readonly List All = new List { new NpcTypeDefinition("Viking Warrior", null, NpcCategory.Human, supportsEquipment: true, 200f, 0.95f), new NpcTypeDefinition("Viking Archer", null, NpcCategory.Human, supportsEquipment: true, 200f, 0.95f, 1.4f, 80f, 3f, archerMode: true), new NpcTypeDefinition("Dverger", "Dverger", NpcCategory.Creature, supportsEquipment: false, 200f, 1f, 1.3f, 80f, 3f), new NpcTypeDefinition("Dverger Mage", "DvergerMage", NpcCategory.Creature, supportsEquipment: false, 200f, 1f, 1.3f, 80f, 3f), new NpcTypeDefinition("Goblin Brute", "GoblinBrute", NpcCategory.Creature, supportsEquipment: false, 800f, 1f, 1.8f, 0f, 3.5f), new NpcTypeDefinition("Goblin", "Goblin", NpcCategory.Creature, supportsEquipment: false, 175f, 1f, 0.8f, 0f, 0.5f), new NpcTypeDefinition("Troll", "Troll", NpcCategory.Creature, supportsEquipment: false, 600f, 1f, 2.5f, 0f, 3.5f), new NpcTypeDefinition("Neck", "Neck", NpcCategory.Creature, supportsEquipment: false, 50f, 1f, 0.7f, 0f, 0.5f) }; } public class BattleController : MonoBehaviour { public enum BattleState { Idle, Active, Paused } private bool victoryAnnounced; private bool damageTextWasEnabled = true; public static BattleController Instance { get; private set; } public BattleState CurrentState { get; private set; } = BattleState.Idle; public static bool DangerMode { get; set; } public int ArmyAAlive { get; private set; } public int ArmyBAlive { get; private set; } public float BattleDuration { get; private set; } private void Awake() { Instance = this; } private void Update() { if ((Object)(object)WarriorManager.Instance == (Object)null) { return; } ArmyAAlive = WarriorManager.Instance.GetAliveCount(ArmySide.A); ArmyBAlive = WarriorManager.Instance.GetAliveCount(ArmySide.B); SuppressDamageText(); if (CurrentState != BattleState.Active) { return; } BattleDuration += Time.deltaTime; if (!victoryAnnounced && BattleDuration > 2f) { if (ArmyAAlive == 0 && ArmyBAlive > 0) { ShowMsg($"Army B wins! ({ArmyBAlive} survivors)"); victoryAnnounced = true; FreezeAll(); CurrentState = BattleState.Idle; } else if (ArmyBAlive == 0 && ArmyAAlive > 0) { ShowMsg($"Army A wins! ({ArmyAAlive} survivors)"); victoryAnnounced = true; FreezeAll(); CurrentState = BattleState.Idle; } else if (ArmyAAlive == 0 && ArmyBAlive == 0) { ShowMsg("Draw! Both armies wiped out!"); victoryAnnounced = true; CurrentState = BattleState.Idle; } else if (BattleDuration > 300f) { ShowMsg($"Stalemate! Army A: {ArmyAAlive} vs Army B: {ArmyBAlive}"); victoryAnnounced = true; FreezeAll(); CurrentState = BattleState.Idle; } } } public void StartBattle() { //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_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_0062: 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_0071: 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) WarriorManager instance = WarriorManager.Instance; if (!((Object)(object)instance == (Object)null)) { if (instance.GetAliveCount(ArmySide.A) == 0 || instance.GetAliveCount(ArmySide.B) == 0) { ShowMsg("Need warriors on both sides to start a battle!"); return; } WarriorAI.ResetTargetTracking(); Vector3 armyCenter = instance.GetArmyCenter(ArmySide.A); Vector3 armyCenter2 = instance.GetArmyCenter(ArmySide.B); ChargeArmySpread(instance.ArmyA, armyCenter, armyCenter2); ChargeArmySpread(instance.ArmyB, armyCenter2, armyCenter); CurrentState = BattleState.Active; BattleDuration = 0f; victoryAnnounced = false; ShowMsg("BATTLE COMMENCED!"); BigBattlesPlugin.Log($"Battle started: Army A ({ArmyAAlive}) vs Army B ({ArmyBAlive})"); } } public void PauseBattle() { if (CurrentState == BattleState.Active) { FreezeAll(); CurrentState = BattleState.Paused; ShowMsg("Battle paused."); } } public void ResumeBattle() { if (CurrentState != BattleState.Paused) { return; } WarriorManager instance = WarriorManager.Instance; if ((Object)(object)instance == (Object)null) { return; } foreach (WarriorAI item in instance.ArmyA) { if (!((Object)(object)item == (Object)null)) { Character component = ((Component)item).GetComponent(); if ((Object)(object)component != (Object)null && !component.IsDead()) { item.Resume(); } } } foreach (WarriorAI item2 in instance.ArmyB) { if (!((Object)(object)item2 == (Object)null)) { Character component2 = ((Component)item2).GetComponent(); if ((Object)(object)component2 != (Object)null && !component2.IsDead()) { item2.Resume(); } } } CurrentState = BattleState.Active; ShowMsg("Battle resumed!"); } public void ResetBattle() { WarriorManager instance = WarriorManager.Instance; if ((Object)(object)instance == (Object)null) { return; } DangerMode = false; WarriorAI.ResetTargetTracking(); instance.DespawnAll(); Ragdoll[] array = Object.FindObjectsOfType(); foreach (Ragdoll val in array) { if ((Object)(object)val != (Object)null && val.m_ttl > 9999f) { Object.Destroy((Object)(object)((Component)val).gameObject); } } WarriorManager.ClearDeathPositions(); ProjectileOnHit_FriendlyPassthrough.CleanupAllStuckArrows(); CurrentState = BattleState.Idle; BattleDuration = 0f; victoryAnnounced = false; ShowMsg("Battle reset. All warriors removed."); } public void ActivateDangerMode() { //IL_0070: 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_00c8: 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) WarriorManager instance = WarriorManager.Instance; if ((Object)(object)instance == (Object)null) { return; } Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null) { return; } int num = instance.GetAliveCount(ArmySide.A) + instance.GetAliveCount(ArmySide.B); if (num == 0) { ShowMsg("No warriors to fight!"); return; } DangerMode = true; WarriorAI.ResetTargetTracking(); Vector3 position = ((Component)localPlayer).transform.position; foreach (WarriorAI item in instance.ArmyA) { if (!((Object)(object)item == (Object)null)) { Character myCharacter = item.MyCharacter; if ((Object)(object)myCharacter != (Object)null && !myCharacter.IsDead()) { item.StartCharge(position); } } } foreach (WarriorAI item2 in instance.ArmyB) { if (!((Object)(object)item2 == (Object)null)) { Character myCharacter2 = item2.MyCharacter; if ((Object)(object)myCharacter2 != (Object)null && !myCharacter2.IsDead()) { item2.StartCharge(position); } } } CurrentState = BattleState.Active; BattleDuration = 0f; victoryAnnounced = false; ShowMsg("DANGER! All warriors target YOU!"); BigBattlesPlugin.Log($"Danger mode activated: {num} warriors targeting player."); } public void DeactivateDangerMode() { DangerMode = false; FreezeAll(); CurrentState = BattleState.Idle; ShowMsg("Danger mode off. Warriors frozen."); BigBattlesPlugin.Log("Danger mode deactivated."); } private void ChargeArmySpread(List army, Vector3 ownCenter, Vector3 enemyCenter) { //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0050: 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_0056: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005d: 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_006d: Unknown result type (might be due to invalid IL or missing references) foreach (WarriorAI item in army) { if (!((Object)(object)item == (Object)null)) { Character myCharacter = item.MyCharacter; if (!((Object)(object)myCharacter == (Object)null) && !myCharacter.IsDead()) { Vector3 val = ((Component)item).transform.position - ownCenter; Vector3 enemyCenter2 = enemyCenter + val; enemyCenter2.y = enemyCenter.y; item.StartCharge(enemyCenter2); } } } } private void FreezeAll() { WarriorManager instance = WarriorManager.Instance; if ((Object)(object)instance == (Object)null) { return; } foreach (WarriorAI item in instance.ArmyA) { item?.Freeze(); } foreach (WarriorAI item2 in instance.ArmyB) { item2?.Freeze(); } } public string GetDurationString() { int num = (int)(BattleDuration / 60f); int num2 = (int)(BattleDuration % 60f); return $"{num:00}:{num2:00}"; } private void SuppressDamageText() { DamageText instance = DamageText.instance; if (!((Object)(object)instance == (Object)null)) { WarriorManager instance2 = WarriorManager.Instance; bool flag = (Object)(object)instance2 != (Object)null && (instance2.ArmyA.Count > 0 || instance2.ArmyB.Count > 0); if (flag && ((Behaviour)instance).enabled) { damageTextWasEnabled = true; ((Behaviour)instance).enabled = false; } else if (!flag && !((Behaviour)instance).enabled && damageTextWasEnabled) { ((Behaviour)instance).enabled = true; } } } private void ShowMsg(string text) { Player localPlayer = Player.m_localPlayer; if (localPlayer != null) { ((Character)localPlayer).Message((MessageType)2, text, 0, (Sprite)null); } } } public class BattleMenu : MonoBehaviour { private ArmyConfig configA; private ArmyConfig configB; private int browsingSlot = -1; private ArmySide browsingForSide; private Vector2 browseScroll; private Rect windowRect; private bool stylesReady; private GUIStyle headerStyle; private GUIStyle titleStyle; private GUIStyle sectionStyle; private GUIStyle labelStyle; private GUIStyle buttonStyle; private GUIStyle activeButtonStyle; private GUIStyle closeHintStyle; private GUIStyle slotButtonStyle; private GUIStyle browseItemStyle; private GUIStyle browseItemActiveStyle; private GUIStyle typeSelectorStyle; private GUIStyle dangerButtonStyle; private Texture2D bgTex; private Texture2D btnTex; private Texture2D btnActiveTex; private Texture2D btnHoverTex; private Texture2D glowTex; private Texture2D ropeBorderH; private Texture2D ropeBorderV; private Texture2D cornerTex; private Texture2D slotBtnTex; private Texture2D slotBtnHoverTex; private bool wasCursorVisible; private CursorLockMode wasCursorLock; private float glowPulse; private float menuCloseCooldown; private const float WIN_WIDTH = 380f; private const float WIN_HEIGHT_NORMAL = 860f; private const float WIN_HEIGHT_BROWSE = 520f; private const float GLOW_SIZE = 18f; private const float ROPE_WIDTH = 6f; private const float CORNER_SIZE = 16f; private const int SLOT_COUNT = 6; private static readonly int WindowID = "BigBattles_BattleMenu".GetHashCode(); private float currentWinHeight; private string[] npcTypeNames; private static readonly HashSet BowPrefabs = new HashSet { "Bow", "BowFineWood", "BowHuntsman", "BowDraugrFang", "BowSpineSnap" }; public static BattleMenu Instance { get; private set; } public bool IsMenuOpen { get; private set; } public bool MenuCloseCooldownActive => menuCloseCooldown > 0f; private void Awake() { //IL_005c: 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) Instance = this; configA = new ArmyConfig(ArmySide.A); configB = new ArmyConfig(ArmySide.B); currentWinHeight = 860f; windowRect = new Rect(((float)Screen.width - 380f) / 2f, ((float)Screen.height - currentWinHeight) / 2f, 380f, currentWinHeight); npcTypeNames = new string[NpcTypes.All.Count]; for (int i = 0; i < NpcTypes.All.Count; i++) { npcTypeNames[i] = NpcTypes.All[i].DisplayName; } } private void Update() { //IL_0037: Unknown result type (might be due to invalid IL or missing references) if (menuCloseCooldown > 0f) { menuCloseCooldown -= Time.deltaTime; } if (IsTyping()) { return; } if (Input.GetKeyDown(BigBattlesPlugin.MenuKey.Value)) { SetMenuOpen(!IsMenuOpen); } if (IsMenuOpen && Input.GetKeyDown((KeyCode)27)) { if (browsingSlot >= 0) { browsingSlot = -1; } else { SetMenuOpen(open: false); } } if (IsMenuOpen) { glowPulse = Mathf.PingPong(Time.time * 0.6f, 1f); } } private void LateUpdate() { if (IsMenuOpen) { Cursor.visible = true; Cursor.lockState = (CursorLockMode)0; } } private void SetMenuOpen(bool open) { //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_0088: 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_00be: Unknown result type (might be due to invalid IL or missing references) if (open == IsMenuOpen) { return; } IsMenuOpen = open; if (open) { browsingSlot = -1; wasCursorVisible = Cursor.visible; wasCursorLock = Cursor.lockState; Cursor.visible = true; Cursor.lockState = (CursorLockMode)0; currentWinHeight = 860f; windowRect = new Rect(((float)Screen.width - 380f) / 2f, ((float)Screen.height - currentWinHeight) / 2f, 380f, currentWinHeight); } else { if (Time.timeScale < 0.01f) { Time.timeScale = 1f; } Cursor.visible = wasCursorVisible; Cursor.lockState = wasCursorLock; menuCloseCooldown = 0.5f; } } public void ForceClose() { SetMenuOpen(open: false); } public void ResetConfigs() { configA = new ArmyConfig(ArmySide.A); configB = new ArmyConfig(ArmySide.B); } private static bool IsTyping() { try { if (Console.IsVisible()) { return true; } if ((Object)(object)Chat.instance != (Object)null && Chat.instance.HasFocus()) { return true; } } catch { } return false; } private void OnGUI() { //IL_005b: 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_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: 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_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_0113: Expected O, but got Unknown //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) if (IsMenuOpen) { InitStyles(); Cursor.visible = true; Cursor.lockState = (CursorLockMode)0; Event current = Event.current; if ((current.isMouse || current.isKey || current.isScrollWheel) && (!current.isMouse || !((Rect)(ref windowRect)).Contains(current.mousePosition))) { current.Use(); } float num = ((browsingSlot >= 0) ? 520f : 860f); if (Mathf.Abs(currentWinHeight - num) > 1f) { currentWinHeight = num; ((Rect)(ref windowRect)).height = currentWinHeight; } DrawGoldenGlow(windowRect); DrawRopeBorder(windowRect); DrawCornerKnots(windowRect); windowRect = GUI.Window(WindowID, windowRect, new WindowFunction(DrawPanel), "", headerStyle); } } private void DrawGoldenGlow(Rect rect) { //IL_0027: 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_007c: Unknown result type (might be due to invalid IL or missing references) float num = Mathf.Lerp(0.25f, 0.45f, glowPulse); GUI.color = new Color(1f, 1f, 1f, num); float num2 = 18f; Rect val = default(Rect); ((Rect)(ref val))..ctor(((Rect)(ref rect)).x - num2, ((Rect)(ref rect)).y - num2, ((Rect)(ref rect)).width + num2 * 2f, ((Rect)(ref rect)).height + num2 * 2f); GUI.DrawTexture(val, (Texture)(object)glowTex); GUI.color = Color.white; } private void DrawRopeBorder(Rect rect) { //IL_0025: 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_008b: 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) float num = 6f; GUI.DrawTexture(new Rect(((Rect)(ref rect)).x, ((Rect)(ref rect)).y - num * 0.5f, ((Rect)(ref rect)).width, num), (Texture)(object)ropeBorderH); GUI.DrawTexture(new Rect(((Rect)(ref rect)).x, ((Rect)(ref rect)).y + ((Rect)(ref rect)).height - num * 0.5f, ((Rect)(ref rect)).width, num), (Texture)(object)ropeBorderH); GUI.DrawTexture(new Rect(((Rect)(ref rect)).x - num * 0.5f, ((Rect)(ref rect)).y, num, ((Rect)(ref rect)).height), (Texture)(object)ropeBorderV); GUI.DrawTexture(new Rect(((Rect)(ref rect)).x + ((Rect)(ref rect)).width - num * 0.5f, ((Rect)(ref rect)).y, num, ((Rect)(ref rect)).height), (Texture)(object)ropeBorderV); } private void DrawCornerKnots(Rect rect) { //IL_0023: 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_007d: 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) float num = 16f; float num2 = num * 0.5f; GUI.DrawTexture(new Rect(((Rect)(ref rect)).x - num2, ((Rect)(ref rect)).y - num2, num, num), (Texture)(object)cornerTex); GUI.DrawTexture(new Rect(((Rect)(ref rect)).x + ((Rect)(ref rect)).width - num2, ((Rect)(ref rect)).y - num2, num, num), (Texture)(object)cornerTex); GUI.DrawTexture(new Rect(((Rect)(ref rect)).x - num2, ((Rect)(ref rect)).y + ((Rect)(ref rect)).height - num2, num, num), (Texture)(object)cornerTex); GUI.DrawTexture(new Rect(((Rect)(ref rect)).x + ((Rect)(ref rect)).width - num2, ((Rect)(ref rect)).y + ((Rect)(ref rect)).height - num2, num, num), (Texture)(object)cornerTex); } private void DrawPanel(int windowID) { if (browsingSlot >= 0) { DrawBrowseMode(windowID); } else { DrawNormalMode(windowID); } } private void DrawNormalMode(int windowID) { //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_020d: Unknown result type (might be due to invalid IL or missing references) //IL_0212: 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_0227: 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_02de: 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_02fa: Unknown result type (might be due to invalid IL or missing references) //IL_034d: Unknown result type (might be due to invalid IL or missing references) //IL_0360: 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_037e: Unknown result type (might be due to invalid IL or missing references) //IL_03f8: Unknown result type (might be due to invalid IL or missing references) //IL_04ac: Unknown result type (might be due to invalid IL or missing references) GUILayout.Space(4f); GUILayout.Label("Big Battles", titleStyle, Array.Empty()); GUILayout.Space(2f); DrawArmySection(configA, "ARMY A (Red)", new Color(1f, 0.4f, 0.4f)); GUILayout.Space(4f); DrawArmySection(configB, "ARMY B (Green)", new Color(0.4f, 1f, 0.4f)); GUILayout.Space(4f); GUILayout.Label("— BATTLE CONTROLS —", sectionStyle, Array.Empty()); GUILayout.Space(2f); BattleController instance = BattleController.Instance; BattleController.BattleState battleState = instance?.CurrentState ?? BattleController.BattleState.Idle; GUILayout.BeginHorizontal(Array.Empty()); switch (battleState) { case BattleController.BattleState.Idle: if (GUILayout.Button("START BATTLE", buttonStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(28f) })) { instance?.StartBattle(); } break; case BattleController.BattleState.Active: if (GUILayout.Button("PAUSE", buttonStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(28f) })) { instance?.PauseBattle(); } break; case BattleController.BattleState.Paused: if (GUILayout.Button("RESUME", buttonStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(28f) })) { instance?.ResumeBattle(); } break; } if (GUILayout.Button("RESET ALL", buttonStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(28f) })) { instance?.ResetBattle(); } GUILayout.EndHorizontal(); GUILayout.Space(2f); bool dangerMode = BattleController.DangerMode; int num = (WarriorManager.Instance?.GetAliveCount(ArmySide.A) ?? 0) + (WarriorManager.Instance?.GetAliveCount(ArmySide.B) ?? 0); Color backgroundColor = GUI.backgroundColor; GUI.backgroundColor = (dangerMode ? new Color(1f, 0.1f, 0.1f) : new Color(0.7f, 0.12f, 0.12f)); GUI.enabled = num > 0; if (GUILayout.Button(dangerMode ? "⚠ DANGER ON ⚠" : "⚠ DANGER ⚠", dangerButtonStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(32f) })) { if (dangerMode) { instance?.DeactivateDangerMode(); } else { instance?.ActivateDangerMode(); } } GUI.enabled = true; GUI.backgroundColor = backgroundColor; GUILayout.Space(2f); GUILayout.BeginHorizontal(Array.Empty()); bool flag = Time.timeScale < 0.01f; Color backgroundColor2 = GUI.backgroundColor; if (flag) { GUI.backgroundColor = new Color(0.4f, 0.8f, 1f); } if (GUILayout.Button(flag ? "UNFREEZE" : "FREEZE", buttonStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(24f) })) { Time.timeScale = (flag ? 1f : 0f); } GUI.backgroundColor = backgroundColor2; bool value = BigBattlesPlugin.EqualDamage.Value; Color backgroundColor3 = GUI.backgroundColor; if (value) { GUI.backgroundColor = new Color(0.4f, 1f, 0.5f); } if (GUILayout.Button(value ? "EQUAL: ON" : "EQUAL: OFF", buttonStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(24f) })) { BigBattlesPlugin.EqualDamage.Value = !BigBattlesPlugin.EqualDamage.Value; if (BigBattlesPlugin.EqualDamage.Value) { WarriorManager.Instance?.EqualizeHealth(); } } GUI.backgroundColor = backgroundColor3; GUILayout.EndHorizontal(); GUILayout.Space(2f); int num2 = instance?.ArmyAAlive ?? 0; int num3 = instance?.ArmyBAlive ?? 0; string text = instance?.GetDurationString() ?? "00:00"; string text2 = battleState.ToString().ToUpper(); GUILayout.Label($"{text2} | {text} | A:{num2} B:{num3}", labelStyle, Array.Empty()); GUILayout.Space(4f); GUILayout.Label($"Press {BigBattlesPlugin.MenuKey.Value} or ESC to close", closeHintStyle, Array.Empty()); } private void DrawArmySection(ArmyConfig config, string title, Color accent) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0007: 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) Color contentColor = GUI.contentColor; GUI.contentColor = accent; GUILayout.Label("— " + title + " —", sectionStyle, Array.Empty()); GUI.contentColor = contentColor; GUILayout.Space(4f); WarriorManager instance = WarriorManager.Instance; int num = instance?.GetArmyCount(config.Side) ?? 0; int value = BigBattlesPlugin.MaxPerSide.Value; GUILayout.Label($"Spawned: {num}/{value}", labelStyle, Array.Empty()); GUILayout.Space(2f); NpcTypeDefinition npcTypeDefinition = NpcTypes.All[config.SelectedNpcType]; GUILayout.BeginHorizontal(Array.Empty()); if (GUILayout.Button("◀", buttonStyle, (GUILayoutOption[])(object)new GUILayoutOption[2] { GUILayout.Width(40f), GUILayout.Height(30f) })) { int selectedNpcType = config.SelectedNpcType; config.SelectedNpcType--; if (config.SelectedNpcType < 0) { config.SelectedNpcType = NpcTypes.All.Count - 1; } npcTypeDefinition = NpcTypes.All[config.SelectedNpcType]; if (selectedNpcType != config.SelectedNpcType) { config.DefaultsApplied = false; } } GUILayout.FlexibleSpace(); GUILayout.Label(npcTypeDefinition.DisplayName, typeSelectorStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(30f) }); GUILayout.FlexibleSpace(); if (GUILayout.Button("▶", buttonStyle, (GUILayoutOption[])(object)new GUILayoutOption[2] { GUILayout.Width(40f), GUILayout.Height(30f) })) { int selectedNpcType2 = config.SelectedNpcType; config.SelectedNpcType++; if (config.SelectedNpcType >= NpcTypes.All.Count) { config.SelectedNpcType = 0; } npcTypeDefinition = NpcTypes.All[config.SelectedNpcType]; if (selectedNpcType2 != config.SelectedNpcType) { config.DefaultsApplied = false; } } GUILayout.EndHorizontal(); GUILayout.Space(2f); if (npcTypeDefinition.SupportsEquipment && EquipmentData.IsReady) { config.ApplyDefaults(npcTypeDefinition); bool archerMode = npcTypeDefinition.ArcherMode; if (archerMode) { config.EquipmentSlots[5] = 0; EnsureBowEquipped(config); } bool flag = IsWeaponTwoHanded(config); if (flag) { config.EquipmentSlots[5] = 0; } for (int i = 0; i < 6; i++) { if (i == 5 && (flag || archerMode)) { DrawSlotRowDisabled(config, i, archerMode ? "(Archer)" : "(Two-Handed)"); } else if (i == 4 && archerMode) { DrawSlotRowBowsOnly(config, i); } else { DrawSlotRow(config, i); } } GUILayout.Space(2f); } GUILayout.BeginHorizontal(Array.Empty()); GUILayout.Label($"Count: {config.SpawnCount}", labelStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(80f) }); config.SpawnCount = Mathf.RoundToInt(GUILayout.HorizontalSlider((float)config.SpawnCount, 1f, (float)value, Array.Empty())); GUILayout.EndHorizontal(); GUILayout.Space(2f); GUILayout.BeginHorizontal(Array.Empty()); if (GUILayout.Button("Place Formation", buttonStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(22f) })) { PlacementSystem.Instance?.EnterPlacementMode(config.Side, individual: false, config, NpcTypes.All[config.SelectedNpcType]); } if (GUILayout.Button("Place Individual", buttonStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(22f) })) { PlacementSystem.Instance?.EnterPlacementMode(config.Side, individual: true, config, NpcTypes.All[config.SelectedNpcType]); } GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(Array.Empty()); if (npcTypeDefinition.SupportsEquipment && EquipmentData.IsReady && GUILayout.Button("Place Random", buttonStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(22f) })) { PlacementSystem.Instance?.EnterPlacementMode(config.Side, individual: false, config, NpcTypes.All[config.SelectedNpcType], randomizePerWarrior: true); } if (num > 0 && GUILayout.Button($"Remove {config.Side}", buttonStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(22f) })) { instance?.DespawnArmy(config.Side); } GUILayout.EndHorizontal(); } private void DrawSlotRow(ArmyConfig config, int slot) { //IL_00ae: 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) List listForSlot = EquipmentData.GetListForSlot(slot); int num = config.EquipmentSlots[slot]; string text = ((num >= 0 && num < listForSlot.Count) ? listForSlot[num].DisplayName : "— None —"); GUILayout.BeginHorizontal(Array.Empty()); GUILayout.Label(EquipmentData.GetSlotName(slot) + ":", labelStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(55f) }); if (GUILayout.Button(text, slotButtonStyle ?? buttonStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(22f) })) { browsingSlot = slot; browsingForSide = config.Side; browseScroll = Vector2.zero; } GUILayout.EndHorizontal(); } private void DrawSlotRowDisabled(ArmyConfig config, int slot, string reason) { GUILayout.BeginHorizontal(Array.Empty()); GUILayout.Label(EquipmentData.GetSlotName(slot) + ":", labelStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(55f) }); GUI.enabled = false; GUILayout.Button(reason, slotButtonStyle ?? buttonStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(22f) }); GUI.enabled = true; GUILayout.EndHorizontal(); } private static bool IsWeaponTwoHanded(ArmyConfig config) { //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Invalid comparison between Unknown and I4 //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Invalid comparison between Unknown and I4 //IL_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: Invalid comparison between Unknown and I4 if (!EquipmentData.IsReady) { return false; } List listForSlot = EquipmentData.GetListForSlot(4); int num = config.EquipmentSlots[4]; if (num <= 0 || num >= listForSlot.Count) { return false; } string prefabName = listForSlot[num].PrefabName; if (string.IsNullOrEmpty(prefabName)) { return false; } ObjectDB instance = ObjectDB.instance; GameObject val = ((instance != null) ? instance.GetItemPrefab(prefabName) : null); if ((Object)(object)val == (Object)null) { return false; } ItemDrop component = val.GetComponent(); if (component?.m_itemData?.m_shared == null) { return false; } ItemType itemType = component.m_itemData.m_shared.m_itemType; return (int)itemType == 14 || (int)itemType == 22 || (int)itemType == 4; } private static void EnsureBowEquipped(ArmyConfig config) { List listForSlot = EquipmentData.GetListForSlot(4); int num = config.EquipmentSlots[4]; if (num > 0 && num < listForSlot.Count && BowPrefabs.Contains(listForSlot[num].PrefabName)) { return; } for (int i = 1; i < listForSlot.Count; i++) { if (BowPrefabs.Contains(listForSlot[i].PrefabName)) { config.EquipmentSlots[4] = i; break; } } } private void DrawSlotRowBowsOnly(ArmyConfig config, int slot) { List listForSlot = EquipmentData.GetListForSlot(slot); int num = config.EquipmentSlots[slot]; string text = ((num >= 0 && num < listForSlot.Count) ? listForSlot[num].DisplayName : "— None —"); GUILayout.BeginHorizontal(Array.Empty()); GUILayout.Label("Bow:", labelStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(55f) }); if (GUILayout.Button("<", buttonStyle, (GUILayoutOption[])(object)new GUILayoutOption[2] { GUILayout.Width(24f), GUILayout.Height(22f) })) { config.EquipmentSlots[slot] = FindAdjacentBow(listForSlot, num, -1); } GUILayout.Label(text, labelStyle, Array.Empty()); if (GUILayout.Button(">", buttonStyle, (GUILayoutOption[])(object)new GUILayoutOption[2] { GUILayout.Width(24f), GUILayout.Height(22f) })) { config.EquipmentSlots[slot] = FindAdjacentBow(listForSlot, num, 1); } GUILayout.EndHorizontal(); } private static int FindAdjacentBow(List list, int current, int direction) { List list2 = new List(); for (int i = 1; i < list.Count; i++) { if (BowPrefabs.Contains(list[i].PrefabName)) { list2.Add(i); } } if (list2.Count == 0) { return current; } int num = list2.IndexOf(current); if (num < 0) { return list2[0]; } num += direction; if (num < 0) { num = list2.Count - 1; } if (num >= list2.Count) { num = 0; } return list2[num]; } private void DrawBrowseMode(int windowID) { //IL_00ae: 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_00c7: Unknown result type (might be due to invalid IL or missing references) ArmyConfig armyConfig = ((browsingForSide == ArmySide.A) ? configA : configB); List listForSlot = EquipmentData.GetListForSlot(browsingSlot); string slotName = EquipmentData.GetSlotName(browsingSlot); GUILayout.Space(8f); GUILayout.Label($"Select {slotName} for Army {browsingForSide}", titleStyle, Array.Empty()); GUILayout.Space(6f); if (GUILayout.Button("← Back", buttonStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(24f) })) { browsingSlot = -1; return; } GUILayout.Space(4f); browseScroll = GUILayout.BeginScrollView(browseScroll, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandHeight(true) }); for (int i = 0; i < listForSlot.Count; i++) { GUIStyle val = ((armyConfig.EquipmentSlots[browsingSlot] == i) ? (browseItemActiveStyle ?? activeButtonStyle) : (browseItemStyle ?? buttonStyle)); if (GUILayout.Button(listForSlot[i].DisplayName, val, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(22f) })) { armyConfig.EquipmentSlots[browsingSlot] = i; browsingSlot = -1; } } GUILayout.EndScrollView(); } private void OnDestroy() { if ((Object)(object)bgTex != (Object)null) { Object.Destroy((Object)(object)bgTex); } if ((Object)(object)btnTex != (Object)null) { Object.Destroy((Object)(object)btnTex); } if ((Object)(object)btnActiveTex != (Object)null) { Object.Destroy((Object)(object)btnActiveTex); } if ((Object)(object)btnHoverTex != (Object)null) { Object.Destroy((Object)(object)btnHoverTex); } if ((Object)(object)glowTex != (Object)null) { Object.Destroy((Object)(object)glowTex); } if ((Object)(object)ropeBorderH != (Object)null) { Object.Destroy((Object)(object)ropeBorderH); } if ((Object)(object)ropeBorderV != (Object)null) { Object.Destroy((Object)(object)ropeBorderV); } if ((Object)(object)cornerTex != (Object)null) { Object.Destroy((Object)(object)cornerTex); } if ((Object)(object)slotBtnTex != (Object)null) { Object.Destroy((Object)(object)slotBtnTex); } if ((Object)(object)slotBtnHoverTex != (Object)null) { Object.Destroy((Object)(object)slotBtnHoverTex); } } private void InitStyles() { //IL_002e: 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_007a: 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_00c6: 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_0112: 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_015e: Unknown result type (might be due to invalid IL or missing references) //IL_0184: Unknown result type (might be due to invalid IL or missing references) //IL_019e: 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_01b5: Unknown result type (might be due to invalid IL or missing references) //IL_01bb: Unknown result type (might be due to invalid IL or missing references) //IL_01c6: Unknown result type (might be due to invalid IL or missing references) //IL_01dd: Expected O, but got Unknown //IL_01e8: Unknown result type (might be due to invalid IL or missing references) //IL_01ed: Unknown result type (might be due to invalid IL or missing references) //IL_01f6: Unknown result type (might be due to invalid IL or missing references) //IL_01fe: 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_021b: Unknown result type (might be due to invalid IL or missing references) //IL_022b: Expected O, but got Unknown //IL_0236: Unknown result type (might be due to invalid IL or missing references) //IL_023b: Unknown result type (might be due to invalid IL or missing references) //IL_0244: Unknown result type (might be due to invalid IL or missing references) //IL_024c: Unknown result type (might be due to invalid IL or missing references) //IL_0254: Unknown result type (might be due to invalid IL or missing references) //IL_0269: Unknown result type (might be due to invalid IL or missing references) //IL_0279: Expected O, but got Unknown //IL_0284: 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_02a7: Unknown result type (might be due to invalid IL or missing references) //IL_02b7: Expected O, but got Unknown //IL_02c2: Unknown result type (might be due to invalid IL or missing references) //IL_02c7: 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_02d8: 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_02ff: 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_031c: Unknown result type (might be due to invalid IL or missing references) //IL_0322: Unknown result type (might be due to invalid IL or missing references) //IL_032d: Unknown result type (might be due to invalid IL or missing references) //IL_033f: Unknown result type (might be due to invalid IL or missing references) //IL_0345: Unknown result type (might be due to invalid IL or missing references) //IL_0355: Expected O, but got Unknown //IL_035c: Unknown result type (might be due to invalid IL or missing references) //IL_0361: Unknown result type (might be due to invalid IL or missing references) //IL_0373: Unknown result type (might be due to invalid IL or missing references) //IL_0388: Unknown result type (might be due to invalid IL or missing references) //IL_0398: Expected O, but got Unknown //IL_03a3: Unknown result type (might be due to invalid IL or missing references) //IL_03a8: Unknown result type (might be due to invalid IL or missing references) //IL_03b1: Unknown result type (might be due to invalid IL or missing references) //IL_03b9: Unknown result type (might be due to invalid IL or missing references) //IL_03c1: Unknown result type (might be due to invalid IL or missing references) //IL_03d6: Unknown result type (might be due to invalid IL or missing references) //IL_03e6: Expected O, but got Unknown //IL_03fc: Unknown result type (might be due to invalid IL or missing references) //IL_041d: Unknown result type (might be due to invalid IL or missing references) //IL_043e: Unknown result type (might be due to invalid IL or missing references) //IL_0454: Unknown result type (might be due to invalid IL or missing references) //IL_0459: Unknown result type (might be due to invalid IL or missing references) //IL_0462: Unknown result type (might be due to invalid IL or missing references) //IL_046a: Unknown result type (might be due to invalid IL or missing references) //IL_0472: Unknown result type (might be due to invalid IL or missing references) //IL_047f: Unknown result type (might be due to invalid IL or missing references) //IL_0494: Unknown result type (might be due to invalid IL or missing references) //IL_049f: Unknown result type (might be due to invalid IL or missing references) //IL_04ac: Unknown result type (might be due to invalid IL or missing references) //IL_04c1: Unknown result type (might be due to invalid IL or missing references) //IL_04cc: Unknown result type (might be due to invalid IL or missing references) //IL_04d9: Unknown result type (might be due to invalid IL or missing references) //IL_04df: Unknown result type (might be due to invalid IL or missing references) //IL_04ef: Expected O, but got Unknown //IL_04fa: Unknown result type (might be due to invalid IL or missing references) //IL_04ff: Unknown result type (might be due to invalid IL or missing references) //IL_0508: 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_0525: Unknown result type (might be due to invalid IL or missing references) //IL_0535: Expected O, but got Unknown //IL_053c: Unknown result type (might be due to invalid IL or missing references) //IL_0541: Unknown result type (might be due to invalid IL or missing references) //IL_054a: Unknown result type (might be due to invalid IL or missing references) //IL_055c: Unknown result type (might be due to invalid IL or missing references) //IL_0571: 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_058e: Unknown result type (might be due to invalid IL or missing references) //IL_0594: Unknown result type (might be due to invalid IL or missing references) //IL_05a4: Expected O, but got Unknown //IL_05ab: Unknown result type (might be due to invalid IL or missing references) //IL_05b0: Unknown result type (might be due to invalid IL or missing references) //IL_05b9: Unknown result type (might be due to invalid IL or missing references) //IL_05c6: Expected O, but got Unknown //IL_05cd: Unknown result type (might be due to invalid IL or missing references) //IL_05d2: Unknown result type (might be due to invalid IL or missing references) //IL_05e4: Unknown result type (might be due to invalid IL or missing references) //IL_05f9: Unknown result type (might be due to invalid IL or missing references) //IL_0609: Expected O, but got Unknown if (!stylesReady) { stylesReady = true; bgTex = MakeTex(2, 2, new Color(0.08f, 0.06f, 0.04f, 0.95f)); btnTex = MakeTex(2, 2, new Color(0.18f, 0.14f, 0.1f, 0.9f)); btnActiveTex = MakeTex(2, 2, new Color(0.35f, 0.25f, 0.12f, 0.95f)); btnHoverTex = MakeTex(2, 2, new Color(0.25f, 0.18f, 0.1f, 0.9f)); glowTex = MakeTex(2, 2, new Color(0.85f, 0.65f, 0.2f, 0.5f)); ropeBorderH = MakeTex(2, 2, new Color(0.45f, 0.1f, 0.05f, 0.8f)); ropeBorderV = MakeTex(2, 2, new Color(0.45f, 0.1f, 0.05f, 0.8f)); cornerTex = MakeTex(2, 2, new Color(0.7f, 0.5f, 0.15f, 0.9f)); slotBtnTex = MakeTex(2, 2, new Color(0.14f, 0.12f, 0.08f, 0.85f)); slotBtnHoverTex = MakeTex(2, 2, new Color(0.22f, 0.18f, 0.1f, 0.9f)); GUIStyle val = new GUIStyle(GUI.skin.window); val.normal.background = bgTex; val.normal.textColor = Color.white; val.onNormal.background = bgTex; headerStyle = val; GUIStyle val2 = new GUIStyle(GUI.skin.label) { fontSize = 18, fontStyle = (FontStyle)1, alignment = (TextAnchor)4 }; val2.normal.textColor = new Color(0.9f, 0.75f, 0.3f); titleStyle = val2; GUIStyle val3 = new GUIStyle(GUI.skin.label) { fontSize = 13, fontStyle = (FontStyle)1, alignment = (TextAnchor)4 }; val3.normal.textColor = new Color(0.85f, 0.65f, 0.2f); sectionStyle = val3; GUIStyle val4 = new GUIStyle(GUI.skin.label) { fontSize = 12 }; val4.normal.textColor = new Color(0.85f, 0.8f, 0.7f); labelStyle = val4; GUIStyle val5 = new GUIStyle(GUI.skin.button) { fontSize = 12, fontStyle = (FontStyle)1 }; val5.normal.background = btnTex; val5.normal.textColor = new Color(0.9f, 0.85f, 0.7f); val5.hover.background = btnHoverTex; val5.hover.textColor = Color.white; val5.active.background = btnActiveTex; val5.active.textColor = Color.white; buttonStyle = val5; GUIStyle val6 = new GUIStyle(buttonStyle); val6.normal.background = btnActiveTex; val6.normal.textColor = new Color(1f, 0.9f, 0.5f); activeButtonStyle = val6; GUIStyle val7 = new GUIStyle(GUI.skin.label) { fontSize = 16, fontStyle = (FontStyle)1, alignment = (TextAnchor)4 }; val7.normal.textColor = new Color(1f, 0.9f, 0.5f); typeSelectorStyle = val7; Texture2D background = MakeTex(2, 2, new Color(0.6f, 0.05f, 0.05f, 0.95f)); Texture2D background2 = MakeTex(2, 2, new Color(0.8f, 0.1f, 0.1f, 0.95f)); Texture2D background3 = MakeTex(2, 2, new Color(1f, 0.15f, 0.15f, 0.95f)); GUIStyle val8 = new GUIStyle(GUI.skin.button) { fontSize = 16, fontStyle = (FontStyle)1, alignment = (TextAnchor)4 }; val8.normal.background = background; val8.normal.textColor = new Color(1f, 0.3f, 0.3f); val8.hover.background = background2; val8.hover.textColor = new Color(1f, 0.5f, 0.5f); val8.active.background = background3; val8.active.textColor = Color.white; dangerButtonStyle = val8; GUIStyle val9 = new GUIStyle(GUI.skin.label) { fontSize = 10, alignment = (TextAnchor)4 }; val9.normal.textColor = new Color(0.5f, 0.45f, 0.35f); closeHintStyle = val9; GUIStyle val10 = new GUIStyle(buttonStyle) { fontSize = 11 }; val10.normal.background = slotBtnTex; val10.normal.textColor = new Color(0.85f, 0.8f, 0.7f); val10.hover.background = slotBtnHoverTex; val10.hover.textColor = Color.white; slotButtonStyle = val10; browseItemStyle = new GUIStyle(buttonStyle) { fontSize = 11, alignment = (TextAnchor)3 }; GUIStyle val11 = new GUIStyle(browseItemStyle); val11.normal.background = btnActiveTex; val11.normal.textColor = new Color(1f, 0.9f, 0.5f); browseItemActiveStyle = val11; } } private static Texture2D MakeTex(int w, int h, 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[w * h]; for (int i = 0; i < array.Length; i++) { array[i] = col; } Texture2D val = new Texture2D(w, h); val.SetPixels(array); val.Apply(); return val; } } public static class EquipmentData { public struct ItemEntry { public string PrefabName; public string DisplayName; public int Variant; } private static List helmets; private static List chests; private static List legs; private static List capes; private static List weapons; private static List shields; private static bool initialized; private static readonly List Empty = new List { new ItemEntry { PrefabName = "", DisplayName = "— None —", Variant = 0 } }; private static readonly HashSet BlacklistedPrefabs = new HashSet { "PickaxeAntler", "PickaxeIron", "PickaxeBronze", "PickaxeStone", "PickaxeBlackMetal", "Hammer", "Hoe", "Cultivator", "FishingRod", "AxeStone", "AxeFlint", "AxeBronze", "AxeIron", "AxeBlackMetal", "AxeJotunBane", "Tankard", "TankardAnniversary", "TankardOdin", "TankardDvergr", "HelmetDverger", "SwordCheat", "AxeTest", "Torch", "TorchMist" }; private static readonly string[] BlacklistedNameFragments = new string[10] { "Chicken", "Turnip", "Carrot", "Mushroom", "Sausage", "Bread", "Fish", "Serpent stew", "Blood pudding", "Lox pie" }; private static readonly Dictionary CapeVariants = new Dictionary { { "CapeLinen", new string[10] { "#0 Red", "#1 White", "#2 Blue", "#3 Yellow", "#4 Green", "#5 Black", "#6 Purple", "#7 White Alt", "#8 Teal", "#9 Brown" } }, { "CapeLox", new string[3] { "#0 Default", "#1 Dark", "#2 White" } } }; public static List Helmets { get { EnsureInit(); return helmets ?? Empty; } } public static List Chests { get { EnsureInit(); return chests ?? Empty; } } public static List Legs { get { EnsureInit(); return legs ?? Empty; } } public static List Capes { get { EnsureInit(); return capes ?? Empty; } } public static List Weapons { get { EnsureInit(); return weapons ?? Empty; } } public static List Shields { get { EnsureInit(); return shields ?? Empty; } } public static bool IsReady { get { if (!initialized) { EnsureInit(); } return initialized; } } public static List GetListForSlot(int slot) { return slot switch { 0 => Helmets, 1 => Chests, 2 => Legs, 3 => Capes, 4 => Weapons, 5 => Shields, _ => Empty, }; } public static string GetSlotName(int slot) { return slot switch { 0 => "Head", 1 => "Chest", 2 => "Legs", 3 => "Cape", 4 => "Weapon", 5 => "Offhand", _ => "???", }; } private static void EnsureInit() { if (!initialized && !((Object)(object)ObjectDB.instance == (Object)null) && ObjectDB.instance.m_items != null && ObjectDB.instance.m_items.Count != 0) { BigBattlesPlugin.Log("EquipmentData: Scanning ObjectDB for equipment items..."); helmets = ScanItems((ItemType)6); chests = ScanItems((ItemType)7); legs = ScanItems((ItemType)11); capes = ScanCapes(); ItemType[] array = new ItemType[4]; RuntimeHelpers.InitializeArray(array, (RuntimeFieldHandle)/*OpCode not supported: LdMemberToken*/); weapons = ScanItems((ItemType[])(object)array); shields = ScanItems((ItemType)5); ItemEntry itemEntry = default(ItemEntry); itemEntry.PrefabName = ""; itemEntry.DisplayName = "— None —"; itemEntry.Variant = 0; ItemEntry item = itemEntry; helmets.Insert(0, item); chests.Insert(0, item); legs.Insert(0, item); capes.Insert(0, item); weapons.Insert(0, item); shields.Insert(0, item); initialized = true; BigBattlesPlugin.Log($"EquipmentData ready: {helmets.Count} helmets, {chests.Count} chests, " + $"{legs.Count} legs, {capes.Count} capes, {weapons.Count} weapons, " + $"{shields.Count} shields"); } } private static List ScanItems(params ItemType[] types) { //IL_0096: Unknown result type (might be due to invalid IL or missing references) HashSet hashSet = new HashSet(types); HashSet hashSet2 = new HashSet(); List list = new List(); foreach (GameObject item in ObjectDB.instance.m_items) { if ((Object)(object)item == (Object)null) { continue; } ItemDrop component = item.GetComponent(); if ((Object)(object)component == (Object)null || component.m_itemData == null || component.m_itemData.m_shared == null || !hashSet.Contains(component.m_itemData.m_shared.m_itemType) || !hashSet2.Add(((Object)item).name) || BlacklistedPrefabs.Contains(((Object)item).name)) { continue; } string localizedName = GetLocalizedName(item, component); if (localizedName.StartsWith("$")) { continue; } bool flag = false; for (int i = 0; i < BlacklistedNameFragments.Length; i++) { if (localizedName.IndexOf(BlacklistedNameFragments[i], StringComparison.OrdinalIgnoreCase) >= 0) { flag = true; break; } } if (!flag) { list.Add(new ItemEntry { PrefabName = ((Object)item).name, DisplayName = localizedName, Variant = 0 }); } } list.Sort((ItemEntry a, ItemEntry b) => string.Compare(a.DisplayName, b.DisplayName, StringComparison.OrdinalIgnoreCase)); return list; } private static List ScanCapes() { //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Invalid comparison between Unknown and I4 HashSet hashSet = new HashSet(); List list = new List(); foreach (GameObject item in ObjectDB.instance.m_items) { if ((Object)(object)item == (Object)null) { continue; } ItemDrop component = item.GetComponent(); if ((Object)(object)component == (Object)null || component.m_itemData == null || component.m_itemData.m_shared == null || (int)component.m_itemData.m_shared.m_itemType != 17 || !hashSet.Add(((Object)item).name) || BlacklistedPrefabs.Contains(((Object)item).name)) { continue; } string localizedName = GetLocalizedName(item, component); if (localizedName.StartsWith("$")) { continue; } if (CapeVariants.TryGetValue(((Object)item).name, out var value)) { for (int i = 0; i < value.Length; i++) { list.Add(new ItemEntry { PrefabName = ((Object)item).name, DisplayName = localizedName + " (" + value[i] + ")", Variant = i }); } } else { list.Add(new ItemEntry { PrefabName = ((Object)item).name, DisplayName = localizedName, Variant = 0 }); } } list.Sort((ItemEntry a, ItemEntry b) => string.Compare(a.DisplayName, b.DisplayName, StringComparison.OrdinalIgnoreCase)); return list; } private static string GetLocalizedName(GameObject go, ItemDrop itemDrop) { string name = itemDrop.m_itemData.m_shared.m_name; string text = name; try { if (Localization.instance != null) { text = Localization.instance.Localize(name); } } catch { } if (string.IsNullOrEmpty(text)) { text = ((Object)go).name; } if (text.StartsWith("$")) { text = ((Object)go).name; } return text; } public static int FindIndexByName(int slot, string nameContains) { List listForSlot = GetListForSlot(slot); for (int i = 0; i < listForSlot.Count; i++) { if (listForSlot[i].DisplayName.IndexOf(nameContains, StringComparison.OrdinalIgnoreCase) >= 0) { return i; } } return 0; } public static void Reset() { initialized = false; helmets = null; chests = null; legs = null; capes = null; weapons = null; shields = null; } } public static class FormationCalculator { public static List GetPositions(Vector3 center, Vector3 facing, int count, int columns = 8, int rows = 5, float spacing = 2f, float spacingMultiplier = 1f) { //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_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_0090: 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_0094: 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_00a1: Unknown result type (might be due to invalid IL or missing references) //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_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) List list = new List(count); float num = spacing * spacingMultiplier; facing.y = 0f; if (((Vector3)(ref facing)).sqrMagnitude < 0.01f) { facing = Vector3.forward; } ((Vector3)(ref facing)).Normalize(); Vector3 val = Vector3.Cross(Vector3.up, facing); Vector3 normalized = ((Vector3)(ref val)).normalized; int num2 = columns * rows; if (count > num2) { count = num2; } for (int i = 0; i < count; i++) { int num3 = i / columns; int num4 = i % columns; float num5 = ((float)num4 - (float)(columns - 1) * 0.5f) * num; float num6 = (float)(-num3) * num; Vector3 pos = center + normalized * num5 + facing * num6; pos = SnapToGround(pos); list.Add(pos); } return list; } public static Vector3 SnapToGround(Vector3 pos) { //IL_002b: 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_0016: 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) float y = default(float); if ((Object)(object)ZoneSystem.instance != (Object)null && ZoneSystem.instance.GetGroundHeight(pos, ref y)) { pos.y = y; } return pos; } } [HarmonyPatch(typeof(Projectile), "IsValidTarget")] public static class ProjectileIsValidTarget_Patch { private static readonly FieldInfo s_ownerField = AccessTools.Field(typeof(Projectile), "m_owner"); private static bool Prefix(Projectile __instance, ref bool __result, IDestructible destr) { object? obj = s_ownerField?.GetValue(__instance); Character val = (Character)((obj is Character) ? obj : null); if ((Object)(object)val == (Object)null) { return true; } WarriorAI cached = WarriorAI.GetCached(val); if ((Object)(object)cached == (Object)null) { return true; } Character val2 = (Character)(object)((destr is Character) ? destr : null); if ((Object)(object)val2 == (Object)null) { MonoBehaviour val3 = (MonoBehaviour)(object)((destr is MonoBehaviour) ? destr : null); if ((Object)(object)val3 != (Object)null) { val2 = ((Component)val3).GetComponentInParent(); } } if ((Object)(object)val2 == (Object)null) { return true; } if (!((Object)(object)WarriorAI.GetCached(val2) != (Object)null) && !(val2 is Player)) { return true; } if ((Object)(object)val2 == (Object)(object)val || val2.IsDead()) { __result = false; return false; } __result = BaseAI.IsEnemy(val, val2); return false; } } [HarmonyPatch(typeof(Humanoid), "GetAttackDrawPercentage")] public static class WarriorBowFullDraw_Patch { private static bool Prefix(Humanoid __instance, ref float __result) { //IL_0044: 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_0058: Invalid comparison between Unknown and I4 if ((Object)(object)__instance == (Object)null || (Object)(object)WarriorAI.GetCached((Character)(object)__instance) == (Object)null) { return true; } ItemData currentWeapon = __instance.GetCurrentWeapon(); if (currentWeapon == null || (int)(currentWeapon.m_shared?.m_itemType).GetValueOrDefault() != 4) { return true; } WarriorAI cached = WarriorAI.GetCached((Character)(object)__instance); __result = (((Object)(object)cached != (Object)null) ? cached.NextDrawPercent : 1f); return false; } } [HarmonyPatch(typeof(Projectile), "Setup")] public static class ProjectileSetup_TagWarriorArrows { private static readonly FieldInfo s_gravityField = AccessTools.Field(typeof(Projectile), "m_gravity"); private static readonly FieldInfo s_velField = AccessTools.Field(typeof(Projectile), "m_vel"); private static void Postfix(Projectile __instance, Character owner) { //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: 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_00c2: 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_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: 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_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: 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_0134: 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_0118: 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_0162: Unknown result type (might be due to invalid IL or missing references) //IL_0164: Unknown result type (might be due to invalid IL or missing references) //IL_0168: 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_0174: Unknown result type (might be due to invalid IL or missing references) //IL_0176: Unknown result type (might be due to invalid IL or missing references) //IL_0178: Unknown result type (might be due to invalid IL or missing references) //IL_017d: 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_018d: Unknown result type (might be due to invalid IL or missing references) //IL_01a2: Unknown result type (might be due to invalid IL or missing references) //IL_0222: Unknown result type (might be due to invalid IL or missing references) //IL_0227: Unknown result type (might be due to invalid IL or missing references) //IL_023b: Unknown result type (might be due to invalid IL or missing references) //IL_0247: Unknown result type (might be due to invalid IL or missing references) //IL_0251: Unknown result type (might be due to invalid IL or missing references) //IL_0256: 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_025f: Unknown result type (might be due to invalid IL or missing references) //IL_0267: Unknown result type (might be due to invalid IL or missing references) //IL_026a: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)owner == (Object)null) { return; } WarriorAI cached = WarriorAI.GetCached(owner); if ((Object)(object)cached == (Object)null) { return; } ((Component)__instance).gameObject.AddComponent(); if (s_gravityField != null) { s_gravityField.SetValue(__instance, 5f); } Character targetCreature = ((BaseAI)cached).GetTargetCreature(); if ((Object)(object)targetCreature == (Object)null || s_velField == null) { return; } Vector3 val = (Vector3)s_velField.GetValue(__instance); float magnitude = ((Vector3)(ref val)).magnitude; if (magnitude < 5f) { return; } Vector3 centerPoint = targetCreature.GetCenterPoint(); Vector3 position = ((Component)__instance).transform.position; Vector3 val2 = centerPoint - position; Vector3 val3 = default(Vector3); ((Vector3)(ref val3))..ctor(val2.x, 0f, val2.z); float magnitude2 = ((Vector3)(ref val3)).magnitude; float y = val2.y; if (magnitude2 < 3f) { s_velField.SetValue(__instance, ((Vector3)(ref val2)).normalized * magnitude); return; } Vector3 velocity = targetCreature.GetVelocity(); if (((Vector3)(ref velocity)).sqrMagnitude > 0.5f && magnitude2 > 10f) { float num = magnitude2 / magnitude; Vector3 val4 = centerPoint + velocity * num; val2 = val4 - position; ((Vector3)(ref val3))..ctor(val2.x, 0f, val2.z); magnitude2 = ((Vector3)(ref val3)).magnitude; y = val2.y; } float num2 = magnitude * magnitude; float num3 = num2 * num2; float num4 = 5f; float num5 = num3 - num4 * (num4 * magnitude2 * magnitude2 + 2f * y * num2); float num6; if (num5 < 0f) { num6 = 0.43633232f; } else { num6 = Mathf.Atan2(num2 - Mathf.Sqrt(num5), num4 * magnitude2); num6 = Mathf.Clamp(num6, -0.1f, 0.43633232f); } Vector3 normalized = ((Vector3)(ref val3)).normalized; float num7 = Mathf.Cos(num6); float num8 = Mathf.Sin(num6); Vector3 val5 = new Vector3(normalized.x * num7, num8, normalized.z * num7); Vector3 normalized2 = ((Vector3)(ref val5)).normalized; s_velField.SetValue(__instance, normalized2 * magnitude); } } public class WarriorArrowTag : MonoBehaviour { } public class StuckArrowBehaviour : MonoBehaviour { private float _orphanTimer; private bool _isOrphaned; private void LateUpdate() { //IL_0079: 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) if ((Object)(object)((Component)this).transform.parent == (Object)null && !_isOrphaned) { _isOrphaned = true; _orphanTimer = 0f; } if (!_isOrphaned) { return; } _orphanTimer += Time.deltaTime; Ragdoll[] array = Object.FindObjectsOfType(); foreach (Ragdoll val in array) { if ((Object)(object)val != (Object)null && Vector3.Distance(((Component)this).transform.position, ((Component)val).transform.position) < 5f) { ((Component)this).transform.SetParent(((Component)val).transform, true); _isOrphaned = false; return; } } if (_orphanTimer > 1f) { Object.Destroy((Object)(object)((Component)this).gameObject); } } } [HarmonyPatch(typeof(Projectile), "OnHit")] public static class ProjectileOnHit_FriendlyPassthrough { private static readonly FieldInfo s_ownerField = AccessTools.Field(typeof(Projectile), "m_owner"); public static readonly List AllStuckArrows = new List(); private const int MAX_ARROWS_PER_CHARACTER = 10; private static bool Prefix(Projectile __instance, Collider collider, Vector3 hitPoint) { //IL_0123: Unknown result type (might be due to invalid IL or missing references) object? obj = s_ownerField?.GetValue(__instance); Character val = (Character)((obj is Character) ? obj : null); if ((Object)(object)val == (Object)null) { return true; } WarriorAI cached = WarriorAI.GetCached(val); if ((Object)(object)cached == (Object)null) { return true; } Character val2 = ((collider != null) ? ((Component)collider).GetComponentInParent() : null); if ((Object)(object)val2 != (Object)null) { if ((Object)(object)val2 == (Object)(object)val) { Collider component = ((Component)__instance).GetComponent(); if ((Object)(object)component != (Object)null && (Object)(object)collider != (Object)null) { Physics.IgnoreCollision(component, collider, true); } return false; } WarriorAI cached2 = WarriorAI.GetCached(val2); if ((Object)(object)cached2 != (Object)null && cached2.Side == cached.Side) { Collider component2 = ((Component)__instance).GetComponent(); if ((Object)(object)component2 != (Object)null && (Object)(object)collider != (Object)null) { Physics.IgnoreCollision(component2, collider, true); } return false; } if ((Object)(object)cached2 != (Object)null || val2 is Player) { EmbedArrowInTarget(__instance, val2, hitPoint); } } return true; } private static void EmbedArrowInTarget(Projectile projectile, Character target, Vector3 hitPoint) { //IL_008c: 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_00e6: Unknown result type (might be due to invalid IL or missing references) try { Transform val = null; FieldInfo fieldInfo = AccessTools.Field(typeof(Projectile), "m_visual"); if (fieldInfo != null) { object? value = fieldInfo.GetValue(projectile); GameObject val2 = (GameObject)((value is GameObject) ? value : null); if ((Object)(object)val2 != (Object)null) { val = val2.transform; } } if ((Object)(object)val == (Object)null) { MeshRenderer componentInChildren = ((Component)projectile).GetComponentInChildren(); if ((Object)(object)componentInChildren != (Object)null) { val = ((Component)componentInChildren).transform; } } if ((Object)(object)val == (Object)null) { return; } Transform val3 = FindNearestBone(target, hitPoint); if ((Object)(object)val3 == (Object)null) { val3 = ((Component)target).transform; } GameObject val4 = Object.Instantiate(((Component)val).gameObject); ((Object)val4).name = "BB_StuckArrow"; val4.transform.SetParent(val3, true); val4.transform.position = hitPoint; val4.transform.rotation = ((Component)projectile).transform.rotation; Rigidbody component = val4.GetComponent(); if ((Object)(object)component != (Object)null) { Object.Destroy((Object)(object)component); } Collider[] componentsInChildren = val4.GetComponentsInChildren(); foreach (Collider val5 in componentsInChildren) { Object.Destroy((Object)(object)val5); } val4.AddComponent(); AllStuckArrows.Add(val4); int num = 0; for (int num2 = AllStuckArrows.Count - 1; num2 >= 0; num2--) { if ((Object)(object)AllStuckArrows[num2] == (Object)null) { AllStuckArrows.RemoveAt(num2); } else if (AllStuckArrows[num2].transform.IsChildOf(((Component)target).transform)) { num++; if (num > 10) { Object.Destroy((Object)(object)AllStuckArrows[num2]); AllStuckArrows.RemoveAt(num2); } } } } catch (Exception ex) { BigBattlesPlugin.LogErr("EmbedArrowInTarget error: " + ex.Message); } } private static Transform FindNearestBone(Character character, Vector3 worldPoint) { //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) SkinnedMeshRenderer componentInChildren = ((Component)character).GetComponentInChildren(); if ((Object)(object)componentInChildren == (Object)null || componentInChildren.bones == null || componentInChildren.bones.Length == 0) { return ((Component)character).transform; } Transform val = null; float num = float.MaxValue; Transform[] bones = componentInChildren.bones; foreach (Transform val2 in bones) { if (!((Object)(object)val2 == (Object)null)) { float num2 = Vector3.SqrMagnitude(val2.position - worldPoint); if (num2 < num) { num = num2; val = val2; } } } return val ?? ((Component)character).transform; } public static void CleanupAllStuckArrows() { for (int num = AllStuckArrows.Count - 1; num >= 0; num--) { if ((Object)(object)AllStuckArrows[num] != (Object)null) { Object.Destroy((Object)(object)AllStuckArrows[num]); } } AllStuckArrows.Clear(); } } [HarmonyPatch(typeof(BaseAI), "DoProjectileHitNoise")] public static class DoProjectileHitNoise_NullGuard { private static bool Prefix(Character attacker) { return (Object)(object)attacker != (Object)null; } } [HarmonyPatch(typeof(Humanoid), "OnRagdollCreated")] public static class OnRagdollCreated_TransferArrows { private static void Postfix(Humanoid __instance, Ragdoll ragdoll) { //IL_00db: 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_01c5: Unknown result type (might be due to invalid IL or missing references) //IL_01cc: Unknown result type (might be due to invalid IL or missing references) //IL_01e0: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)__instance == (Object)null || (Object)(object)ragdoll == (Object)null || (Object)(object)WarriorAI.GetCached((Character)(object)__instance) == (Object)null) { return; } try { SkinnedMeshRenderer componentInChildren = ((Component)__instance).GetComponentInChildren(); SkinnedMeshRenderer componentInChildren2 = ((Component)ragdoll).GetComponentInChildren(); if (((componentInChildren != null) ? componentInChildren.bones : null) == null || ((componentInChildren2 != null) ? componentInChildren2.bones : null) == null) { return; } Dictionary dictionary = new Dictionary(); Transform[] bones = componentInChildren2.bones; foreach (Transform val in bones) { if ((Object)(object)val != (Object)null && !dictionary.ContainsKey(((Object)val).name)) { dictionary[((Object)val).name] = val; } } float num = 1f; float x = ((Component)__instance).transform.lossyScale.x; float x2 = ((Component)ragdoll).transform.lossyScale.x; if (x > 0.01f && x2 > 0.01f) { num = x2 / x; } int num2 = 0; Transform[] bones2 = componentInChildren.bones; foreach (Transform val2 in bones2) { if ((Object)(object)val2 == (Object)null) { continue; } for (int num3 = val2.childCount - 1; num3 >= 0; num3--) { Transform child = val2.GetChild(num3); if (!((Object)(object)child == (Object)null) && ((Object)child).name.StartsWith("BB_StuckArrow") && dictionary.TryGetValue(((Object)val2).name, out var value)) { GameObject val3 = Object.Instantiate(((Component)child).gameObject, value); val3.transform.localPosition = child.localPosition * num; val3.transform.localRotation = child.localRotation; ((Object)val3).name = "BB_StuckArrow_Ragdoll"; StuckArrowBehaviour component = val3.GetComponent(); if ((Object)(object)component != (Object)null) { Object.Destroy((Object)(object)component); } ProjectileOnHit_FriendlyPassthrough.AllStuckArrows.Add(val3); num2++; } } } for (int num4 = ((Component)__instance).transform.childCount - 1; num4 >= 0; num4--) { Transform child2 = ((Component)__instance).transform.GetChild(num4); if (!((Object)(object)child2 == (Object)null) && ((Object)child2).name.StartsWith("BB_StuckArrow")) { child2.SetParent(((Component)ragdoll).transform, true); StuckArrowBehaviour component2 = ((Component)child2).GetComponent(); if ((Object)(object)component2 != (Object)null) { Object.Destroy((Object)(object)component2); } num2++; } } if (num2 > 0) { BigBattlesPlugin.Log($"Transferred {num2} stuck arrows to ragdoll."); } } catch (Exception ex) { BigBattlesPlugin.LogErr("Arrow ragdoll transfer error: " + ex.Message); } } } public static class Patches { [HarmonyPatch(typeof(BaseAI), "IsEnemy", new Type[] { typeof(Character), typeof(Character) })] public static class IsEnemy_Patch { private static void Postfix(Character a, Character b, ref bool __result) { WarriorAI cached = WarriorAI.GetCached(a); WarriorAI cached2 = WarriorAI.GetCached(b); if (!((Object)(object)cached == (Object)null) || !((Object)(object)cached2 == (Object)null)) { if ((Object)(object)cached != (Object)null && (Object)(object)cached2 != (Object)null && cached.Side == cached2.Side) { __result = false; } else if ((Object)(object)cached != (Object)null && (Object)(object)cached2 != (Object)null && cached.Side != cached2.Side) { __result = !BattleController.DangerMode; } else if (((Object)(object)cached != (Object)null && b is Player) || (a is Player && (Object)(object)cached2 != (Object)null)) { __result = true; } else if (((Object)(object)cached != (Object)null && (Object)(object)cached2 == (Object)null && !(b is Player)) || ((Object)(object)cached2 != (Object)null && (Object)(object)cached == (Object)null && !(a is Player))) { __result = false; } } } } [HarmonyPatch(typeof(Character), "Damage")] public static class Damage_Patch { private static bool Prefix(Character __instance, HitData hit) { //IL_0268: Unknown result type (might be due to invalid IL or missing references) //IL_026d: 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_028d: Unknown result type (might be due to invalid IL or missing references) WarriorAI cached = WarriorAI.GetCached(__instance); if ((Object)(object)cached == (Object)null) { return true; } Character attacker = hit.GetAttacker(); if ((Object)(object)attacker != (Object)null) { WarriorAI cached2 = WarriorAI.GetCached(attacker); if ((Object)(object)cached2 != (Object)null && cached2.Side == cached.Side) { return false; } } if ((Object)(object)attacker == (Object)null) { return false; } if ((Object)(object)WarriorAI.GetCached(attacker) == (Object)null && !(attacker is Player)) { return false; } float value = BigBattlesPlugin.BlockChance.Value; if (value > 0f && hit.m_damage.m_damage < 999f && Random.value < value) { try { Humanoid component = ((Component)__instance).GetComponent(); if ((Object)(object)component != (Object)null) { MethodInfo methodInfo = AccessTools.Method(typeof(Humanoid), "BlockAttack", (Type[])null, (Type[])null); if (methodInfo != null) { methodInfo.Invoke(component, new object[2] { hit, attacker }); } } } catch { } return false; } if (BigBattlesPlugin.EqualDamage.Value) { float value2 = BigBattlesPlugin.NormalizedDamagePerHit.Value; float health = __instance.GetHealth(); float num = health - value2; if (num <= 0f) { hit.m_damage.m_damage = health + 1f; hit.m_damage.m_blunt = 0f; hit.m_damage.m_slash = 0f; hit.m_damage.m_pierce = 0f; hit.m_damage.m_chop = 0f; hit.m_damage.m_pickaxe = 0f; hit.m_damage.m_fire = 0f; hit.m_damage.m_frost = 0f; hit.m_damage.m_lightning = 0f; hit.m_damage.m_poison = 0f; hit.m_damage.m_spirit = 0f; return true; } __instance.SetHealth(num); try { Humanoid component2 = ((Component)__instance).GetComponent(); if (((Character)(component2?)).m_hitEffects != null && hit.m_point != Vector3.zero) { ((Character)component2).m_hitEffects.Create(hit.m_point, Quaternion.identity, ((Component)__instance).transform, 1f, -1); } } catch { } return false; } return true; } } [HarmonyPatch(typeof(Character), "GetSkillFactor")] public static class WarriorSkillProficiency_Patch { private static bool Prefix(Character __instance, ref float __result) { if ((Object)(object)WarriorAI.GetCached(__instance) != (Object)null) { __result = 1f; return false; } return true; } } [HarmonyPatch(typeof(Character), "RaiseSkill")] public static class WarriorNoSkillRaise_Patch { private static bool Prefix(Character __instance) { if ((Object)(object)WarriorAI.GetCached(__instance) != (Object)null) { return false; } return true; } } [HarmonyPatch(typeof(Character), "HaveEitr")] public static class WarriorInfiniteEitr_Patch { private static bool Prefix(Character __instance, ref bool __result) { if ((Object)(object)WarriorAI.GetCached(__instance) != (Object)null) { __result = true; return false; } return true; } } [HarmonyPatch(typeof(Character), "UseEitr")] public static class WarriorNoEitrCost_Patch { private static bool Prefix(Character __instance) { if ((Object)(object)WarriorAI.GetCached(__instance) != (Object)null) { return false; } return true; } } [HarmonyPatch(typeof(Character), "UseStamina")] public static class WarriorNoStaminaCost_Patch { private static bool Prefix(Character __instance) { if ((Object)(object)WarriorAI.GetCached(__instance) != (Object)null) { return false; } return true; } } [HarmonyPatch(typeof(Character), "HaveStamina")] public static class WarriorInfiniteStamina_Patch { private static bool Prefix(Character __instance, ref bool __result) { if ((Object)(object)WarriorAI.GetCached(__instance) != (Object)null) { __result = true; return false; } return true; } } [HarmonyPatch(typeof(CharacterDrop), "OnDeath")] public static class NoLootDrop_Patch { private static bool Prefix(CharacterDrop __instance) { Character component = ((Component)__instance).GetComponent(); if ((Object)(object)component != (Object)null && (Object)(object)WarriorAI.GetCached(component) != (Object)null) { return false; } return true; } } [HarmonyPatch(typeof(Character), "OnDeath")] public static class WarriorDeathPosition_Patch { private static void Prefix(Character __instance) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)WarriorAI.GetCached(__instance) != (Object)null) { WarriorManager.RecordDeathPosition(((Component)__instance).transform.position); } } } [HarmonyPatch(typeof(Ragdoll), "Awake")] public static class RagdollPersist_Patch { private static void Postfix(Ragdoll __instance) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_002e: 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 (!BigBattlesPlugin.PersistentBodies.Value) { return; } Vector3 position = ((Component)__instance).transform.position; List deathPositions = WarriorManager.GetDeathPositions(); bool flag = false; for (int i = 0; i < deathPositions.Count; i++) { if (Vector3.Distance(position, deathPositions[i]) < 5f) { ((MonoBehaviour)__instance).CancelInvoke("DestroyNow"); __instance.m_ttl = 99999f; flag = true; break; } } } } [HarmonyPatch(typeof(TimedDestruction), "Awake")] public static class BloodSlowFade_Patch { private static void Postfix(TimedDestruction __instance) { //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_0092: 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_009f: 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_0171: Unknown result type (might be due to invalid IL or missing references) //IL_0176: Unknown result type (might be due to invalid IL or missing references) //IL_010c: 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) if (!BigBattlesPlugin.PersistentBodies.Value || (Object)(object)WarriorManager.Instance == (Object)null || (WarriorManager.Instance.ArmyA.Count == 0 && WarriorManager.Instance.ArmyB.Count == 0)) { return; } Vector3 position = ((Component)__instance).transform.position; bool flag = false; foreach (WarriorAI item in WarriorManager.Instance.ArmyA) { if ((Object)(object)item != (Object)null && Vector3.SqrMagnitude(position - ((Component)item).transform.position) < 225f) { flag = true; break; } } if (!flag) { foreach (WarriorAI item2 in WarriorManager.Instance.ArmyB) { if ((Object)(object)item2 != (Object)null && Vector3.SqrMagnitude(position - ((Component)item2).transform.position) < 225f) { flag = true; break; } } } if (!flag) { List deathPositions = WarriorManager.GetDeathPositions(); for (int i = 0; i < deathPositions.Count; i++) { if (Vector3.SqrMagnitude(position - deathPositions[i]) < 225f) { flag = true; break; } } } if (flag) { __instance.m_timeout = 300f; } } } [HarmonyPatch(typeof(GameCamera), "UpdateCamera")] public static class GameCameraUpdate_Patch { private static bool Prefix() { if ((Object)(object)BattleMenu.Instance != (Object)null && BattleMenu.Instance.IsMenuOpen) { return false; } return true; } } [HarmonyPatch(typeof(Player), "TakeInput")] public static class PlayerTakeInput_Patch { private static bool Prefix(ref bool __result) { if ((Object)(object)BattleMenu.Instance != (Object)null && BattleMenu.Instance.IsMenuOpen) { __result = false; return false; } if ((Object)(object)PlacementSystem.Instance != (Object)null && PlacementSystem.Instance.IsActive) { __result = false; return false; } return true; } } [HarmonyPatch(typeof(Humanoid), "StartAttack")] public static class BlockAttackWhenMenuOpen_Patch { private static bool Prefix(Humanoid __instance) { if (__instance is Player) { if ((Object)(object)BattleMenu.Instance != (Object)null && BattleMenu.Instance.IsMenuOpen) { return false; } if ((Object)(object)BattleMenu.Instance != (Object)null && BattleMenu.Instance.MenuCloseCooldownActive) { return false; } if ((Object)(object)PlacementSystem.Instance != (Object)null && PlacementSystem.Instance.IsActive) { return false; } } return true; } } [HarmonyPatch(typeof(Game), "OnDestroy")] public static class GameCleanup_Patch { private static void Prefix() { WarriorManager.Instance?.DespawnAll(); WarriorManager.Instance?.ResetPrefabState(); BattleMenu.Instance?.ResetConfigs(); BattleController.DangerMode = false; WarriorAI.ClearAllCaches(); ProjectileOnHit_FriendlyPassthrough.CleanupAllStuckArrows(); Ragdoll[] array = Object.FindObjectsOfType(); foreach (Ragdoll val in array) { if ((Object)(object)val != (Object)null && val.m_ttl > 9999f) { Object.Destroy((Object)(object)((Component)val).gameObject); } } WarriorManager.ClearDeathPositions(); BigBattlesPlugin.Log("World unloading — all warriors and ragdolls cleaned up."); } } } public class PlacementSystem : MonoBehaviour { private ArmyConfig currentConfig; private NpcTypeDefinition currentNpcType; private bool randomPerWarrior; private GameObject groundIndicator; private MeshRenderer indicatorRenderer; private Material indicatorMatA; private Material indicatorMatB; private List previewMarkers = new List(); private static Mesh s_cachedCylinderMesh; private Vector3 lastHitPoint; private bool hasValidHit; private bool wasCursorVisible; private CursorLockMode wasCursorLock; private int groundMask; public static PlacementSystem Instance { get; private set; } public bool IsActive { get; private set; } public ArmySide PlacingSide { get; private set; } public bool IndividualMode { get; private set; } private void Awake() { Instance = this; groundMask = LayerMask.GetMask(new string[5] { "Default", "static_solid", "Default_small", "terrain", "piece" }); } public void EnterPlacementMode(ArmySide side, bool individual, ArmyConfig config, NpcTypeDefinition npcType, bool randomizePerWarrior = false) { //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) PlacingSide = side; IndividualMode = individual; currentConfig = config; currentNpcType = npcType; randomPerWarrior = randomizePerWarrior; IsActive = true; if ((Object)(object)BattleMenu.Instance != (Object)null) { BattleMenu.Instance.ForceClose(); } CreateIndicator(); wasCursorVisible = Cursor.visible; wasCursorLock = Cursor.lockState; Cursor.visible = true; Cursor.lockState = (CursorLockMode)0; ShowMsg($"Click to place Army {side}. Right-click or Escape to cancel."); } public void ExitPlacementMode() { //IL_001d: Unknown result type (might be due to invalid IL or missing references) IsActive = false; DestroyVisuals(); Cursor.visible = wasCursorVisible; Cursor.lockState = wasCursorLock; } private void Update() { //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_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_0117: Unknown result type (might be due to invalid IL or missing references) if (!IsActive) { return; } if (Input.GetMouseButtonDown(1) || Input.GetKeyDown((KeyCode)27)) { ExitPlacementMode(); return; } hasValidHit = RaycastGround(out lastHitPoint); if (hasValidHit && (Object)(object)groundIndicator != (Object)null) { groundIndicator.SetActive(true); groundIndicator.transform.position = lastHitPoint + Vector3.up * 0.05f; ((Renderer)indicatorRenderer).material = ((PlacingSide == ArmySide.A) ? indicatorMatA : indicatorMatB); } else if ((Object)(object)groundIndicator != (Object)null) { groundIndicator.SetActive(false); } if (!IndividualMode && hasValidHit) { UpdateFormationPreview(); } if (Input.GetMouseButtonDown(0) && hasValidHit) { OnPlacementClick(lastHitPoint); } } private void LateUpdate() { if (IsActive) { Cursor.visible = true; Cursor.lockState = (CursorLockMode)0; } } private bool RaycastGround(out Vector3 hitPoint) { //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_003c: 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_0046: 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_0064: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) hitPoint = Vector3.zero; Camera val = (((Object)(object)GameCamera.instance != (Object)null) ? ((Component)GameCamera.instance).GetComponent() : Camera.main); if ((Object)(object)val == (Object)null) { return false; } Ray val2 = val.ScreenPointToRay(Input.mousePosition); RaycastHit val3 = default(RaycastHit); if (Physics.Raycast(val2, ref val3, 200f, groundMask)) { hitPoint = ((RaycastHit)(ref val3)).point; return true; } return false; } private void OnPlacementClick(Vector3 groundPos) { //IL_0091: 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_0097: 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_0041: 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_0048: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: 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_0068: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_0154: Unknown result type (might be due to invalid IL or missing references) if (currentNpcType == null || currentConfig == null) { return; } Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null) { return; } if (IndividualMode) { Vector3 spawnFacing = GetSpawnFacing(groundPos); Quaternion rotation = Quaternion.LookRotation(spawnFacing); WarriorManager.Instance?.SpawnWarrior(PlacingSide, currentNpcType, groundPos, rotation); if (currentNpcType.SupportsEquipment) { ApplyEquipmentToLastWarrior(); } return; } Vector3 spawnFacing2 = GetSpawnFacing(groundPos); int spawnCount = currentConfig.SpawnCount; WarriorManager.Instance?.SpawnFormation(PlacingSide, currentNpcType, groundPos, spawnFacing2, spawnCount); if (currentNpcType.SupportsEquipment) { if (randomPerWarrior) { ApplyRandomEquipmentPerWarrior(); } else { ApplyEquipmentToArmy(); } } WarriorManager instance = WarriorManager.Instance; if ((Object)(object)instance != (Object)null) { if (instance.GetArmyCount(ArmySide.A) > 0 && instance.GetArmyCount(ArmySide.B) > 0) { instance.FaceArmiesAtEachOther(); } else if ((Object)(object)localPlayer != (Object)null) { instance.FaceArmyToward(PlacingSide, ((Component)localPlayer).transform.position); } } ExitPlacementMode(); } private void ApplyEquipmentToArmy() { if (currentConfig != null && EquipmentData.IsReady) { EquipmentData.ItemEntry[] items = BuildEquipmentArray(currentConfig); WarriorManager.Instance?.ApplyEquipment(PlacingSide, items); } } private void ApplyRandomEquipmentPerWarrior() { if (!EquipmentData.IsReady) { return; } List list = WarriorManager.Instance?.GetArmy(PlacingSide); if (list == null) { return; } ArmyConfig armyConfig = new ArmyConfig(PlacingSide); foreach (WarriorAI item in list) { if (!((Object)(object)item == (Object)null)) { armyConfig.RandomizeEquipment(currentNpcType?.ArcherMode ?? false); EquipmentData.ItemEntry[] items = BuildEquipmentArray(armyConfig); WarriorManager.Instance?.ApplyEquipmentToSingle(item, items); } } BigBattlesPlugin.Log($"Applied random loadouts to {list.Count} warriors in Army {PlacingSide}."); } private void ApplyEquipmentToLastWarrior() { if (currentConfig == null || !EquipmentData.IsReady) { return; } List list = WarriorManager.Instance?.GetArmy(PlacingSide); if (list != null && list.Count != 0) { WarriorAI warriorAI = list[list.Count - 1]; if (!((Object)(object)warriorAI == (Object)null)) { EquipmentData.ItemEntry[] items = BuildEquipmentArray(currentConfig); WarriorManager.Instance?.ApplyEquipmentToSingle(warriorAI, items); } } } public static EquipmentData.ItemEntry[] BuildEquipmentArray(ArmyConfig config) { EquipmentData.ItemEntry[] array = new EquipmentData.ItemEntry[6]; for (int i = 0; i < 6; i++) { List listForSlot = EquipmentData.GetListForSlot(i); int num = config.EquipmentSlots[i]; if (num >= 0 && num < listForSlot.Count) { array[i] = listForSlot[num]; continue; } array[i] = new EquipmentData.ItemEntry { PrefabName = "", DisplayName = "", Variant = 0 }; } return array; } private void UpdateFormationPreview() { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0076: 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_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: 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_010b: Unknown result type (might be due to invalid IL or missing references) //IL_0110: Unknown result type (might be due to invalid IL or missing references) //IL_011a: Unknown result type (might be due to invalid IL or missing references) //IL_011f: Unknown result type (might be due to invalid IL or missing references) //IL_0167: Unknown result type (might be due to invalid IL or missing references) Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null) { return; } Vector3 spawnFacing = GetSpawnFacing(lastHitPoint); int count = currentConfig?.SpawnCount ?? 40; int value = BigBattlesPlugin.FormationColumns.Value; int value2 = BigBattlesPlugin.FormationRows.Value; float value3 = BigBattlesPlugin.FormationSpacing.Value; float spacingMultiplier = currentNpcType?.SpacingMultiplier ?? 1f; List positions = FormationCalculator.GetPositions(lastHitPoint, spawnFacing, count, value, value2, value3, spacingMultiplier); while (previewMarkers.Count < positions.Count) { AddPreviewMarker(); } Color color = ((PlacingSide == ArmySide.A) ? new Color(1f, 0.3f, 0.3f, 0.3f) : new Color(0.3f, 1f, 0.3f, 0.3f)); for (int i = 0; i < positions.Count; i++) { previewMarkers[i].transform.position = positions[i] + Vector3.up * 0.1f; previewMarkers[i].SetActive(true); MeshRenderer component = previewMarkers[i].GetComponent(); if ((Object)(object)component != (Object)null) { ((Renderer)component).material.color = color; } } for (int j = positions.Count; j < previewMarkers.Count; j++) { previewMarkers[j].SetActive(false); } } private static Mesh GetCachedCylinderMesh() { if ((Object)(object)s_cachedCylinderMesh == (Object)null) { GameObject val = GameObject.CreatePrimitive((PrimitiveType)2); s_cachedCylinderMesh = val.GetComponent().sharedMesh; Object.Destroy((Object)(object)val); } return s_cachedCylinderMesh; } private void AddPreviewMarker() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Expected O, but got Unknown //IL_0032: 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_0059: Expected O, but got Unknown //IL_0074: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("BB_PreviewMarker"); val.AddComponent().sharedMesh = GetCachedCylinderMesh(); val.transform.localScale = new Vector3(0.5f, 0.05f, 0.5f); MeshRenderer val2 = val.AddComponent(); ((Renderer)val2).material = new Material(Shader.Find("Sprites/Default")); ((Renderer)val2).material.color = new Color(1f, 0.3f, 0.3f, 0.3f); ((Renderer)val2).shadowCastingMode = (ShadowCastingMode)0; ((Renderer)val2).receiveShadows = false; previewMarkers.Add(val); } private void CreateIndicator() { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Expected O, but got Unknown //IL_0056: 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_0089: Expected O, but got Unknown //IL_00a3: 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_00ba: Expected O, but got Unknown //IL_00d4: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)groundIndicator != (Object)null)) { groundIndicator = new GameObject("BB_GroundIndicator"); groundIndicator.AddComponent().sharedMesh = GetCachedCylinderMesh(); groundIndicator.transform.localScale = new Vector3(3f, 0.02f, 3f); indicatorRenderer = groundIndicator.AddComponent(); Shader val = Shader.Find("Sprites/Default"); indicatorMatA = new Material(val); indicatorMatA.color = new Color(1f, 0.3f, 0.3f, 0.4f); indicatorMatB = new Material(val); indicatorMatB.color = new Color(0.3f, 1f, 0.3f, 0.4f); ((Renderer)indicatorRenderer).material = ((PlacingSide == ArmySide.A) ? indicatorMatA : indicatorMatB); ((Renderer)indicatorRenderer).shadowCastingMode = (ShadowCastingMode)0; ((Renderer)indicatorRenderer).receiveShadows = false; } } private void DestroyVisuals() { if ((Object)(object)groundIndicator != (Object)null) { Object.Destroy((Object)(object)groundIndicator); groundIndicator = null; } if ((Object)(object)indicatorMatA != (Object)null) { Object.Destroy((Object)(object)indicatorMatA); indicatorMatA = null; } if ((Object)(object)indicatorMatB != (Object)null) { Object.Destroy((Object)(object)indicatorMatB); indicatorMatB = null; } foreach (GameObject previewMarker in previewMarkers) { if ((Object)(object)previewMarker != (Object)null) { MeshRenderer component = previewMarker.GetComponent(); if ((Object)(object)component != (Object)null && (Object)(object)((Renderer)component).material != (Object)null) { Object.Destroy((Object)(object)((Renderer)component).material); } Object.Destroy((Object)(object)previewMarker); } } previewMarkers.Clear(); } private void OnDestroy() { DestroyVisuals(); } private Vector3 GetSpawnFacing(Vector3 groundPos) { //IL_001e: 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_002f: 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_0017: 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_0070: 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_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) //IL_005d: 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_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null) { return Vector3.forward; } Vector3 val = groundPos - ((Component)localPlayer).transform.position; val.y = 0f; if (((Vector3)(ref val)).sqrMagnitude > 1f) { return -((Vector3)(ref val)).normalized; } Vector3 val2 = -((Component)localPlayer).transform.forward; val2.y = 0f; if (((Vector3)(ref val2)).sqrMagnitude > 0.01f) { return ((Vector3)(ref val2)).normalized; } return Vector3.forward; } private void ShowMsg(string text) { Player localPlayer = Player.m_localPlayer; if (localPlayer != null) { ((Character)localPlayer).Message((MessageType)2, text, 0, (Sprite)null); } } } [BepInPlugin("com.mitch.bigbattles", "Big Battles", "1.1.0")] public class BigBattlesPlugin : BaseUnityPlugin { public const string PluginGUID = "com.mitch.bigbattles"; public const string PluginName = "Big Battles"; public const string PluginVersion = "1.1.0"; public static ConfigEntry MenuKey; public static ConfigEntry MaxPerSide; public static ConfigEntry FormationColumns; public static ConfigEntry FormationRows; public static ConfigEntry FormationSpacing; public static ConfigEntry HumanHealth; public static ConfigEntry HumanWalkSpeed; public static ConfigEntry HumanRunSpeed; public static ConfigEntry HumanScale; public static ConfigEntry EqualDamage; public static ConfigEntry NormalizedDamagePerHit; public static ConfigEntry BlockChance; public static ConfigEntry PersistentBodies; private Harmony harmony; public static BigBattlesPlugin Instance { get; private set; } private void Awake() { //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Expected O, but got Unknown //IL_015b: Unknown result type (might be due to invalid IL or missing references) //IL_0165: Expected O, but got Unknown //IL_01b8: Unknown result type (might be due to invalid IL or missing references) //IL_01c2: Expected O, but got Unknown //IL_01f5: Unknown result type (might be due to invalid IL or missing references) //IL_01ff: Expected O, but got Unknown //IL_022a: Unknown result type (might be due to invalid IL or missing references) //IL_0234: Expected O, but got Unknown Instance = this; MenuKey = ((BaseUnityPlugin)this).Config.Bind("Controls", "MenuKey", (KeyCode)107, "Key to open/close the BigBattles battle panel."); MaxPerSide = ((BaseUnityPlugin)this).Config.Bind("Army", "MaxPerSide", 80, new ConfigDescription("Maximum NPCs per army side.", (AcceptableValueBase)(object)new AcceptableValueRange(1, 80), Array.Empty())); FormationColumns = ((BaseUnityPlugin)this).Config.Bind("Army", "FormationColumns", 8, "Number of columns in the spawn grid."); FormationRows = ((BaseUnityPlugin)this).Config.Bind("Army", "FormationRows", 10, "Number of rows in the spawn grid."); FormationSpacing = ((BaseUnityPlugin)this).Config.Bind("Army", "FormationSpacing", 2f, "Meters between NPCs in formation."); HumanHealth = ((BaseUnityPlugin)this).Config.Bind("Warriors", "HumanHealth", 1000f, "Health for human warriors."); HumanWalkSpeed = ((BaseUnityPlugin)this).Config.Bind("Warriors", "HumanWalkSpeed", 2.5f, "Walking speed for human warriors."); HumanRunSpeed = ((BaseUnityPlugin)this).Config.Bind("Warriors", "HumanRunSpeed", 7f, "Running speed for human warriors."); HumanScale = ((BaseUnityPlugin)this).Config.Bind("Warriors", "HumanScale", 0.95f, new ConfigDescription("Scale of human warriors (0.95 compensates for armor bulk).", (AcceptableValueBase)(object)new AcceptableValueRange(0.7f, 1.2f), Array.Empty())); EqualDamage = ((BaseUnityPlugin)this).Config.Bind("Balance", "EqualDamage", true, "When enabled, all warriors deal the same damage per hit regardless of weapon."); NormalizedDamagePerHit = ((BaseUnityPlugin)this).Config.Bind("Balance", "NormalizedDamagePerHit", 100f, new ConfigDescription("Base DPS when EqualDamage is on. Actual per-hit damage scales with weapon speed so fast weapons do less per hit but same DPS.", (AcceptableValueBase)(object)new AcceptableValueRange(10f, 500f), Array.Empty())); BlockChance = ((BaseUnityPlugin)this).Config.Bind("Balance", "BlockChance", 0.2f, new ConfigDescription("Chance (0-1) that a warrior blocks an incoming attack with their shield. 0.20 = 20%.", (AcceptableValueBase)(object)new AcceptableValueRange(0f, 0.8f), Array.Empty())); PersistentBodies = ((BaseUnityPlugin)this).Config.Bind("Balance", "PersistentBodies", true, "When enabled, dead warrior bodies (ragdolls) stay on the battlefield until manually cleared."); harmony = new Harmony("com.mitch.bigbattles"); try { harmony.PatchAll(); ((BaseUnityPlugin)this).Logger.LogInfo((object)"All Harmony patches applied."); } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogError((object)("Harmony PatchAll failed: " + ex.Message)); ((BaseUnityPlugin)this).Logger.LogError((object)"Attempting individual patches..."); ApplyPatchesSafe(); } ((BaseUnityPlugin)this).Logger.LogInfo((object)"Big Battles v1.1.0 loaded!"); } private void Start() { ((Component)this).gameObject.AddComponent(); ((Component)this).gameObject.AddComponent(); ((Component)this).gameObject.AddComponent(); ((Component)this).gameObject.AddComponent(); } private void ApplyPatchesSafe() { Type[] nestedTypes = typeof(Patches).GetNestedTypes(BindingFlags.Static | BindingFlags.Public); Type[] array = nestedTypes; foreach (Type type in array) { try { harmony.CreateClassProcessor(type).Patch(); ((BaseUnityPlugin)this).Logger.LogInfo((object)(" Patched: " + type.Name)); } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogWarning((object)(" SKIPPED: " + type.Name + " — " + ex.Message)); } } } private void OnDestroy() { Harmony obj = harmony; if (obj != null) { obj.UnpatchSelf(); } } public static void Log(string msg) { BigBattlesPlugin instance = Instance; if (instance != null) { ((BaseUnityPlugin)instance).Logger.LogInfo((object)msg); } } public static void LogWarn(string msg) { BigBattlesPlugin instance = Instance; if (instance != null) { ((BaseUnityPlugin)instance).Logger.LogWarning((object)msg); } } public static void LogErr(string msg) { BigBattlesPlugin instance = Instance; if (instance != null) { ((BaseUnityPlugin)instance).Logger.LogError((object)msg); } } } public class WarriorAI : BaseAI { public enum WarriorState { Idle, Charging, Fighting } private static readonly Dictionary s_characterToWarrior = new Dictionary(); private Humanoid humanoid; private Rigidbody body; private Character attackTarget; private Vector3 chargeTarget; private float scanTimer; private float attackCooldown; private float visEquipTimer; private float pathStuckTimer; private Vector3 lastMovePos; private bool initialized; private Vector3 idleLookAtPos; private bool hasIdleLookAt; private float overrideAttackRange; private float overrideAttackCooldown; private bool _isCreature; private int _inAttackFrames; private float _nextDrawPercent = 1f; private static readonly Dictionary s_targetCounts = new Dictionary(); private const float SPREAD_PENALTY = 12f; private const int MAX_PER_TARGET = 3; private const float PROXIMITY_PENALTY = 8f; private WarriorState stateBeforePause; private Character targetBeforePause; private int frameCounter; private const float AI_FULL_UPDATE_RANGE = 100f; private static MethodInfo s_showHandItemsMethod; private static bool s_reflectionCached; private float cachedWeaponRange = -1f; private bool weaponSelectionDone; public WarriorState CurrentState { get; set; } = WarriorState.Idle; public ArmySide Side { get; private set; } public Character MyCharacter { get; private set; } public float NextDrawPercent => _nextDrawPercent; public static WarriorAI GetCached(Character c) { if ((Object)(object)c == (Object)null) { return null; } s_characterToWarrior.TryGetValue(c, out var value); return value; } private static void CacheReflection() { if (!s_reflectionCached) { s_reflectionCached = true; s_showHandItemsMethod = typeof(Humanoid).GetMethod("ShowHandItems", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); } } protected override void Awake() { ((BaseAI)this).Awake(); humanoid = ((Component)this).GetComponent(); body = ((Component)this).GetComponent(); MyCharacter = ((Component)this).GetComponent(); CacheReflection(); if ((Object)(object)MyCharacter != (Object)null) { s_characterToWarrior[MyCharacter] = this; } } protected virtual void OnDestroy() { UnregisterTarget(); if ((Object)(object)MyCharacter != (Object)null) { s_characterToWarrior.Remove(MyCharacter); } } private void SetTarget(Character newTarget) { if (!((Object)(object)newTarget == (Object)(object)attackTarget)) { UnregisterTarget(); attackTarget = newTarget; RegisterTarget(); } } private void RegisterTarget() { if (!((Object)(object)attackTarget == (Object)null)) { if (s_targetCounts.ContainsKey(attackTarget)) { s_targetCounts[attackTarget]++; } else { s_targetCounts[attackTarget] = 1; } } } private void UnregisterTarget() { if (!((Object)(object)attackTarget == (Object)null) && s_targetCounts.ContainsKey(attackTarget)) { s_targetCounts[attackTarget]--; if (s_targetCounts[attackTarget] <= 0) { s_targetCounts.Remove(attackTarget); } } } private static int GetTargetCount(Character c) { if ((Object)(object)c == (Object)null) { return 0; } s_targetCounts.TryGetValue(c, out var value); return value; } public static void ResetTargetTracking() { s_targetCounts.Clear(); } public static void ClearAllCaches() { s_characterToWarrior.Clear(); s_targetCounts.Clear(); } public void Initialize(ArmySide side, Faction faction, float attackRange = 0f, float attackCooldown = 0f, bool isCreature = false) { //IL_008b: 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) Side = side; overrideAttackRange = attackRange; overrideAttackCooldown = attackCooldown; _isCreature = isCreature; if ((Object)(object)humanoid == (Object)null) { humanoid = ((Component)this).GetComponent(); } if ((Object)(object)body == (Object)null) { body = ((Component)this).GetComponent(); } if ((Object)(object)MyCharacter == (Object)null) { MyCharacter = ((Component)this).GetComponent(); } if ((Object)(object)humanoid != (Object)null) { ((Character)humanoid).m_faction = faction; } if ((Object)(object)body != (Object)null) { body.constraints = (RigidbodyConstraints)112; } CurrentState = WarriorState.Idle; initialized = true; scanTimer = Random.Range(0f, 1.5f); if (attackRange > 5f) { attackCooldown = Random.Range(0.1f, 3f); } ResetClothSimulation(); } public override Character GetTargetCreature() { return attackTarget; } public override bool UpdateAI(float dt) { //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) if (!initialized) { return false; } try { if (!((BaseAI)this).UpdateAI(dt)) { return false; } if ((Object)(object)base.m_character == (Object)null || base.m_character.IsDead()) { return true; } frameCounter++; Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer != (Object)null && frameCounter % 5 != 0) { float num = Vector3.Distance(((Component)this).transform.position, ((Component)localPlayer).transform.position); if (num > 100f) { return true; } } visEquipTimer -= dt; if (visEquipTimer <= 0f) { visEquipTimer = 2f; SyncVisEquipment(); } switch (CurrentState) { case WarriorState.Idle: UpdateIdle(); break; case WarriorState.Charging: UpdateCharging(dt); break; case WarriorState.Fighting: UpdateFighting(dt); break; } } catch (Exception ex) { BigBattlesPlugin.LogErr("WarriorAI.UpdateAI error: " + ex.Message); } return true; } private void UpdateIdle() { //IL_000e: 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_004c: 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_0061: 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) ((BaseAI)this).StopMoving(); base.m_character.SetMoveDir(Vector3.zero); base.m_character.SetRun(false); base.m_character.SetWalk(false); if (hasIdleLookAt) { ((BaseAI)this).LookAt(idleLookAtPos); Vector3 val = idleLookAtPos - ((Component)this).transform.position; val.y = 0f; if (((Vector3)(ref val)).sqrMagnitude > 0.1f) { base.m_character.SetLookDir(((Vector3)(ref val)).normalized, 0f); } } } public void SetIdleFacing(Vector3 lookAtPosition) { //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) idleLookAtPos = lookAtPosition; hasIdleLookAt = true; } private void UpdateCharging(float dt) { //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: 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_0148: 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_0116: 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_0056: Unknown result type (might be due to invalid IL or missing references) //IL_0161: 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_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) base.m_character.SetWalk(false); base.m_character.SetRun(true); if (BattleController.DangerMode) { Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer != (Object)null && !((Character)localPlayer).IsDead()) { chargeTarget = ((Component)localPlayer).transform.position; } } scanTimer -= dt; if (scanTimer <= 0f) { scanTimer = 0.5f; float weaponRange = GetWeaponRange(); float range = Mathf.Max(weaponRange + 10f, 25f); Character val = FindBestTarget(range); if ((Object)(object)val != (Object)null) { float num = Vector3.Distance(((Component)this).transform.position, ((Component)val).transform.position); if (num <= weaponRange) { SetTarget(val); CurrentState = WarriorState.Fighting; return; } chargeTarget = ((Component)val).transform.position; } } float weaponRange2 = GetWeaponRange(); float num2 = ((weaponRange2 > 5f) ? (weaponRange2 * 0.85f) : 3f); float num3 = Vector3.Distance(((Component)this).transform.position, chargeTarget); if (num3 > num2) { ((BaseAI)this).MoveTo(dt, chargeTarget, num2 * 0.8f, true); CheckPathStuck(dt, chargeTarget); return; } Character val2 = FindBestTarget(50f); if ((Object)(object)val2 != (Object)null) { SetTarget(val2); CurrentState = WarriorState.Fighting; return; } val2 = FindBestTarget(200f); if ((Object)(object)val2 != (Object)null) { chargeTarget = ((Component)val2).transform.position; return; } ((BaseAI)this).StopMoving(); CurrentState = WarriorState.Idle; } private void UpdateFighting(float dt) { //IL_009e: 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) //IL_020a: Unknown result type (might be due to invalid IL or missing references) //IL_020f: Unknown result type (might be due to invalid IL or missing references) //IL_0213: Unknown result type (might be due to invalid IL or missing references) //IL_0107: 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_011c: Unknown result type (might be due to invalid IL or missing references) //IL_012c: Unknown result type (might be due to invalid IL or missing references) //IL_0131: Unknown result type (might be due to invalid IL or missing references) //IL_0135: 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_0154: Unknown result type (might be due to invalid IL or missing references) //IL_0164: Unknown result type (might be due to invalid IL or missing references) //IL_0169: Unknown result type (might be due to invalid IL or missing references) //IL_016e: Unknown result type (might be due to invalid IL or missing references) //IL_022f: 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_01a8: Unknown result type (might be due to invalid IL or missing references) //IL_01ac: Unknown result type (might be due to invalid IL or missing references) //IL_01b1: 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_01c4: Unknown result type (might be due to invalid IL or missing references) //IL_01c9: Unknown result type (might be due to invalid IL or missing references) //IL_01d3: 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_025c: 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_0276: 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) //IL_0367: 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_0388: Unknown result type (might be due to invalid IL or missing references) //IL_038d: Unknown result type (might be due to invalid IL or missing references) //IL_0392: Unknown result type (might be due to invalid IL or missing references) //IL_0396: Unknown result type (might be due to invalid IL or missing references) //IL_039b: Unknown result type (might be due to invalid IL or missing references) //IL_03a3: Unknown result type (might be due to invalid IL or missing references) //IL_0304: Unknown result type (might be due to invalid IL or missing references) //IL_0309: Unknown result type (might be due to invalid IL or missing references) //IL_030b: Unknown result type (might be due to invalid IL or missing references) //IL_0313: Unknown result type (might be due to invalid IL or missing references) //IL_0318: Unknown result type (might be due to invalid IL or missing references) //IL_031d: 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_050c: Unknown result type (might be due to invalid IL or missing references) //IL_0518: Unknown result type (might be due to invalid IL or missing references) if (attackCooldown > 0f) { attackCooldown -= dt; } if ((Object)(object)attackTarget == (Object)null || attackTarget.IsDead()) { SetTarget(null); float range = Mathf.Max(GetWeaponRange(), 30f); Character val = FindBestTarget(range); if ((Object)(object)val != (Object)null) { SetTarget(val); return; } ((BaseAI)this).StopMoving(); CurrentState = WarriorState.Idle; return; } float num = Vector3.Distance(((Component)this).transform.position, ((Component)attackTarget).transform.position); float weaponRange = GetWeaponRange(); bool flag = weaponRange > 5f; if (num > weaponRange) { base.m_character.SetWalk(false); base.m_character.SetRun(true); if (flag) { Vector3 val2 = ((Component)attackTarget).transform.position - ((Component)this).transform.position; val2.y = 0f; Vector3 normalized = ((Vector3)(ref val2)).normalized; Vector3 val3 = default(Vector3); ((Vector3)(ref val3))..ctor(0f - normalized.z, 0f, normalized.x); float num2 = Vector3.Dot(((Component)this).transform.position - ((Component)attackTarget).transform.position, val3); float num3 = ((Vector3)(ref val2)).magnitude - weaponRange * 0.8f; if (num3 > 0f) { Vector3 val4 = ((Component)attackTarget).transform.position + val3 * num2 - normalized * (weaponRange * 0.8f); val4.y = ((Component)this).transform.position.y; ((BaseAI)this).MoveTo(dt, val4, 3f, true); } else { ((BaseAI)this).StopMoving(); } } else { Vector3 approachPosition = GetApproachPosition(attackTarget, weaponRange); ((BaseAI)this).MoveTo(dt, approachPosition, 1.5f, true); } CheckPathStuck(dt, ((Component)attackTarget).transform.position); } else { if (flag && num < 15f) { Vector3 val5 = ((Component)this).transform.position - ((Component)attackTarget).transform.position; val5.y = 0f; if (((Vector3)(ref val5)).sqrMagnitude > 0.01f) { base.m_character.SetMoveDir(((Vector3)(ref val5)).normalized); base.m_character.SetWalk(true); base.m_character.SetRun(false); } } else { ((BaseAI)this).StopMoving(); } if (flag && !_isCreature) { _nextDrawPercent = Random.Range(0.5f, 1f); Vector3 centerPoint = attackTarget.GetCenterPoint(); Vector3 val6 = centerPoint - ((Component)this).transform.position; val6.y = 0f; if (((Vector3)(ref val6)).sqrMagnitude > 0.01f) { base.m_character.SetLookDir(((Vector3)(ref val6)).normalized, 0f); } } else { ((BaseAI)this).LookAt(((Component)attackTarget).transform.position); Vector3 val7 = ((Component)attackTarget).transform.position - ((Component)this).transform.position; Vector3 normalized2 = ((Vector3)(ref val7)).normalized; base.m_character.SetLookDir(normalized2, 0f); } if ((Object)(object)humanoid != (Object)null && attackCooldown <= 0f) { if (((Character)humanoid).InAttack()) { _inAttackFrames++; return; } _inAttackFrames = 0; EnsureBestWeaponEquipped(num); bool flag2 = false; if (_isCreature) { flag2 = TryCreatureAttack(num); } if (!flag2) { flag2 = ((Character)humanoid).StartAttack(attackTarget, false); } if (flag2) { if (overrideAttackCooldown > 0f) { attackCooldown = overrideAttackCooldown; } else if (flag) { attackCooldown = 3f; } else { attackCooldown = 0.5f; } } } } if (flag) { return; } scanTimer -= dt; if (!(scanTimer <= 0f)) { return; } scanTimer = 0.8f; Character val8 = FindBestTarget(15f); if ((Object)(object)val8 != (Object)null && (Object)(object)val8 != (Object)(object)attackTarget) { float num4 = Vector3.Distance(((Component)this).transform.position, ((Component)val8).transform.position); float num5 = num + (float)GetTargetCount(attackTarget) * 12f; float num6 = num4 + (float)GetTargetCount(val8) * 12f; if (num6 < num5 * 0.85f) { SetTarget(val8); } } } public void StartCharge(Vector3 enemyCenter) { //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) chargeTarget = enemyCenter; CurrentState = WarriorState.Charging; hasIdleLookAt = false; DrawWeapons(); ResetClothSimulation(); } public void Freeze() { stateBeforePause = CurrentState; targetBeforePause = attackTarget; CurrentState = WarriorState.Idle; ((BaseAI)this).StopMoving(); } public void Resume() { if (stateBeforePause == WarriorState.Fighting && (Object)(object)targetBeforePause != (Object)null && !targetBeforePause.IsDead()) { SetTarget(targetBeforePause); CurrentState = WarriorState.Fighting; return; } if (stateBeforePause == WarriorState.Charging) { CurrentState = WarriorState.Charging; return; } Character val = FindBestTarget(30f); if ((Object)(object)val != (Object)null) { SetTarget(val); CurrentState = WarriorState.Fighting; } else { CurrentState = WarriorState.Idle; } } private Character FindBestTarget(float range) { //IL_0053: 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_0108: 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_015d: Unknown result type (might be due to invalid IL or missing references) //IL_0162: 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_01c6: Unknown result type (might be due to invalid IL or missing references) //IL_01c8: Unknown result type (might be due to invalid IL or missing references) WarriorManager instance = WarriorManager.Instance; if ((Object)(object)instance == (Object)null) { return null; } if (BattleController.DangerMode) { Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer != (Object)null && !((Character)localPlayer).IsDead()) { float num = Vector3.Distance(((Component)this).transform.position, ((Component)localPlayer).transform.position); if (num <= range) { return (Character)(object)localPlayer; } } return null; } List army = instance.GetArmy((Side == ArmySide.A) ? ArmySide.B : ArmySide.A); List army2 = instance.GetArmy(Side); Character val = null; float num2 = float.MaxValue; for (int i = 0; i < army.Count; i++) { WarriorAI warriorAI = army[i]; if ((Object)(object)warriorAI == (Object)null) { continue; } Character myCharacter = warriorAI.MyCharacter; if ((Object)(object)myCharacter == (Object)null || myCharacter.IsDead()) { continue; } float num3 = Vector3.Distance(((Component)this).transform.position, ((Component)myCharacter).transform.position); if (num3 > range) { continue; } int targetCount = GetTargetCount(myCharacter); if (targetCount >= 3 && (Object)(object)val != (Object)null) { continue; } int num4 = 0; Vector3 position = ((Component)myCharacter).transform.position; for (int j = 0; j < army2.Count; j++) { WarriorAI warriorAI2 = army2[j]; if (!((Object)(object)warriorAI2 == (Object)null) && !((Object)(object)warriorAI2 == (Object)(object)this) && !((Object)(object)warriorAI2.MyCharacter == (Object)null) && !warriorAI2.MyCharacter.IsDead() && Vector3.SqrMagnitude(((Component)warriorAI2).transform.position - position) < 9f) { num4++; } } float num5 = num3 + (float)targetCount * 12f + (float)num4 * 8f; if (num5 < num2) { num2 = num5; val = myCharacter; } } return val; } private Vector3 GetApproachPosition(Character target, float attackRange) { //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_0085: 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_007b: 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_0081: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)target == (Object)null) { return ((Component)this).transform.position; } int instanceID = ((Object)this).GetInstanceID(); float num = (float)(instanceID % 16) * 22.5f * ((float)Math.PI / 180f); float num2 = ((!(attackRange > 5f)) ? 2.5f : (attackRange * 0.75f)); Vector3 val = default(Vector3); ((Vector3)(ref val))..ctor(Mathf.Cos(num) * num2, 0f, Mathf.Sin(num) * num2); return ((Component)target).transform.position + val; } private float GetWeaponRange() { if (cachedWeaponRange > 0f) { return cachedWeaponRange; } if (overrideAttackRange > 0f) { cachedWeaponRange = overrideAttackRange; return cachedWeaponRange; } if ((Object)(object)humanoid == (Object)null) { cachedWeaponRange = 2.5f; return cachedWeaponRange; } ItemData currentWeapon = humanoid.GetCurrentWeapon(); float num = CheckItemRange(currentWeapon); if (num > 0f) { cachedWeaponRange = num; return cachedWeaponRange; } Inventory inventory = humanoid.GetInventory(); if (inventory != null) { float num2 = 0f; foreach (ItemData allItem in inventory.GetAllItems()) { float num3 = CheckItemRange(allItem); if (num3 > num2) { num2 = num3; } } if (num2 > 0f) { cachedWeaponRange = num2; return cachedWeaponRange; } } if (humanoid.m_defaultItems != null) { float num4 = 0f; GameObject[] defaultItems = humanoid.m_defaultItems; foreach (GameObject val in defaultItems) { if ((Object)(object)val == (Object)null) { continue; } ItemDrop component = val.GetComponent(); if (component?.m_itemData != null) { float num5 = CheckItemRange(component.m_itemData); if (num5 > num4) { num4 = num5; } } } if (num4 > 0f) { cachedWeaponRange = num4; return cachedWeaponRange; } } if (currentWeapon == null) { return 2.5f; } cachedWeaponRange = 2.5f; return cachedWeaponRange; } private static float CheckItemRange(ItemData item) { //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Invalid comparison between Unknown and I4 //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Invalid comparison between Unknown and I4 //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Invalid comparison between Unknown and I4 if (item == null || item.m_shared == null) { return 0f; } if ((int)item.m_shared.m_itemType == 4) { return 50f; } Attack attack = item.m_shared.m_attack; if (attack != null && (int)attack.m_attackType == 2) { float aiAttackRange = item.m_shared.m_aiAttackRange; return (aiAttackRange > 3f) ? (aiAttackRange * 2f) : 50f; } Attack secondaryAttack = item.m_shared.m_secondaryAttack; if (secondaryAttack != null && (int)secondaryAttack.m_attackType == 2) { return 50f; } if (item.m_shared.m_aiAttackRangeMin > 10f) { return item.m_shared.m_aiAttackRangeMin * 2f; } return 0f; } private bool TryCreatureAttack(float distToTarget) { if ((Object)(object)humanoid == (Object)null) { return false; } Inventory inventory = humanoid.GetInventory(); if (inventory == null) { return false; } List allItems = inventory.GetAllItems(); ItemData val = null; float num = float.MaxValue; foreach (ItemData item in allItems) { if (item?.m_shared?.m_attack != null && !string.IsNullOrEmpty(item.m_shared.m_attack.m_attackAnimation)) { float num2 = item.m_shared.m_aiAttackRange; if (num2 <= 0f) { num2 = 2.5f; } float aiAttackRangeMin = item.m_shared.m_aiAttackRangeMin; float num3 = ((distToTarget >= aiAttackRangeMin && distToTarget <= num2) ? (num2 - distToTarget - 100f) : ((!(distToTarget < aiAttackRangeMin)) ? (distToTarget - num2) : (aiAttackRangeMin - distToTarget + 50f))); if (num3 < num) { num = num3; val = item; } } } if (val == null) { return false; } if (humanoid.GetCurrentWeapon() != val) { humanoid.EquipItem(val, true); cachedWeaponRange = -1f; } return ((Character)humanoid).StartAttack(attackTarget, false); } private void ApplyDirectDamage(Character target) { //IL_01b2: Unknown result type (might be due to invalid IL or missing references) //IL_01b9: Expected O, but got Unknown //IL_01d2: Unknown result type (might be due to invalid IL or missing references) //IL_01d7: Unknown result type (might be due to invalid IL or missing references) //IL_01dc: 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_01ee: Unknown result type (might be due to invalid IL or missing references) //IL_01f9: Unknown result type (might be due to invalid IL or missing references) //IL_01fe: 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_0207: Unknown result type (might be due to invalid IL or missing references) //IL_020c: 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_0099: Expected O, but got Unknown //IL_00b2: 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_00bc: 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_00ce: 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_00de: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: 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_0262: Unknown result type (might be due to invalid IL or missing references) //IL_0267: Unknown result type (might be due to invalid IL or missing references) //IL_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_0142: 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_014c: Unknown result type (might be due to invalid IL or missing references) //IL_0151: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)target == (Object)null || target.IsDead()) { return; } float value = BigBattlesPlugin.BlockChance.Value; if (value > 0f && Random.value < value) { return; } float health = target.GetHealth(); Vector3 val2; if (BigBattlesPlugin.EqualDamage.Value) { float value2 = BigBattlesPlugin.NormalizedDamagePerHit.Value; float num = health - value2; if (num <= 0f) { target.SetHealth(1f); HitData val = new HitData(); val.m_damage.m_damage = 999f; val.m_point = ((Component)target).transform.position + Vector3.up; val2 = ((Component)target).transform.position - ((Component)this).transform.position; val.m_dir = ((Vector3)(ref val2)).normalized; val.SetAttacker(base.m_character); target.Damage(val); return; } target.SetHealth(num); try { Humanoid component = ((Component)target).GetComponent(); if (((Character)(component?)).m_hitEffects != null) { ((Character)component).m_hitEffects.Create(((Component)target).transform.position + Vector3.up, Quaternion.identity, ((Component)target).transform, 1f, -1); } return; } catch { return; } } float maxHealth = target.GetMaxHealth(); float num2 = maxHealth * 0.1f; float num3 = health - num2; if (num3 <= 0f) { target.SetHealth(1f); HitData val3 = new HitData(); val3.m_damage.m_damage = 999f; val3.m_point = ((Component)target).transform.position + Vector3.up; val2 = ((Component)target).transform.position - ((Component)this).transform.position; val3.m_dir = ((Vector3)(ref val2)).normalized; val3.SetAttacker(base.m_character); target.Damage(val3); return; } target.SetHealth(num3); try { Humanoid component2 = ((Component)target).GetComponent(); if (((Character)(component2?)).m_hitEffects != null) { ((Character)component2).m_hitEffects.Create(((Component)target).transform.position + Vector3.up, Quaternion.identity, ((Component)target).transform, 1f, -1); } } catch { } } private void EnsureBestWeaponEquipped(float distToTarget) { //IL_00c3: 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) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: 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_00e1: 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_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: 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_0109: 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_0199: Invalid comparison between Unknown and I4 //IL_01a4: Unknown result type (might be due to invalid IL or missing references) //IL_01aa: Invalid comparison between Unknown and I4 if ((Object)(object)humanoid == (Object)null || weaponSelectionDone) { return; } Inventory inventory = humanoid.GetInventory(); if (inventory == null) { return; } List allItems = inventory.GetAllItems(); if (allItems.Count <= 1) { weaponSelectionDone = true; return; } bool flag = overrideAttackRange > 5f; ItemData val = null; float num = -999f; foreach (ItemData item in allItems) { if (item?.m_shared != null) { float num2 = 0f; DamageTypes damages = item.m_shared.m_damages; float num3 = damages.m_damage + damages.m_blunt + damages.m_slash + damages.m_pierce + damages.m_fire + damages.m_frost + damages.m_lightning + damages.m_poison + damages.m_spirit; num2 += num3; if (item.m_shared.m_aiAttackRange > 0f) { num2 += 50f; } if (item.m_shared.m_attack?.m_attackAnimation == null || string.IsNullOrEmpty(item.m_shared.m_attack.m_attackAnimation)) { num2 -= 500f; } Attack attack = item.m_shared.m_attack; bool flag2 = (attack != null && (int)attack.m_attackType == 2) || (int)item.m_shared.m_itemType == 4 || item.m_shared.m_aiAttackRange > 10f; if (flag && flag2) { num2 += 1000f; } if (flag && !flag2) { num2 -= 500f; } if (!flag && flag2) { num2 -= 100f; } if (num2 > num) { num = num2; val = item; } } } if (val != null) { humanoid.EquipItem(val, true); cachedWeaponRange = -1f; } weaponSelectionDone = true; } private Vector3 CalculateBallisticAim(Vector3 toTarget, float dist, float arrowSpeed) { //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_002f: 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_0117: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: 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_00f1: 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_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) Vector3 val = toTarget; float y = toTarget.y; val.y = 0f; float magnitude = ((Vector3)(ref val)).magnitude; if (magnitude < 10f) { return ((Vector3)(ref toTarget)).normalized; } float num = arrowSpeed * arrowSpeed / 4.9f; float num2 = 4.9f * magnitude / (arrowSpeed * arrowSpeed); float num3; if (num2 >= 1f) { num3 = 0.34906584f; } else { num3 = Mathf.Asin(num2) * 0.5f; if (num3 > 0.34906584f) { num3 = 0.34906584f; } } if (Mathf.Abs(y) > 1f) { float num4 = Mathf.Atan2(y, magnitude); num3 += num4 * 0.5f; num3 = Mathf.Clamp(num3, -0.1f, 0.34906584f); } Vector3 normalized = ((Vector3)(ref val)).normalized; float num5 = Mathf.Cos(num3); float num6 = Mathf.Sin(num3); Vector3 val2 = default(Vector3); ((Vector3)(ref val2))..ctor(normalized.x * num5, num6, normalized.z * num5); return ((Vector3)(ref val2)).normalized; } private void CheckPathStuck(float dt, Vector3 target) { //IL_0007: 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_00d4: 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_0048: 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_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_0089: Unknown result type (might be due to invalid IL or missing references) float num = Vector3.Distance(((Component)this).transform.position, lastMovePos); if (num < 0.1f) { pathStuckTimer += dt; if (pathStuckTimer > 3f) { Vector3 moveDir = target - ((Component)this).transform.position; moveDir.y = 0f; if (((Vector3)(ref moveDir)).sqrMagnitude > 0.01f) { ((Vector3)(ref moveDir)).Normalize(); base.m_character.SetMoveDir(moveDir); base.m_character.SetRun(true); } if (pathStuckTimer > 6f) { pathStuckTimer = 3f; } } } else { pathStuckTimer = 0f; } lastMovePos = ((Component)this).transform.position; } private void SyncVisEquipment() { if ((Object)(object)humanoid == (Object)null) { return; } VisEquipment component = ((Component)humanoid).GetComponent(); if (!((Object)(object)component == (Object)null)) { try { typeof(VisEquipment).GetMethod("UpdateVisuals", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.Invoke(component, null); } catch { } if (CurrentState == WarriorState.Charging || CurrentState == WarriorState.Fighting) { DrawWeapons(); } WarriorManager.StripWeaponVFX(((Component)this).gameObject); } } private void ResetClothSimulation() { try { Behaviour[] componentsInChildren = ((Component)this).GetComponentsInChildren(true); foreach (Behaviour val in componentsInChildren) { if ((Object)(object)val != (Object)null && ((object)val).GetType().Name == "Cloth") { val.enabled = false; val.enabled = true; } } } catch { } } public void DrawWeapons() { if ((Object)(object)humanoid == (Object)null) { return; } try { if (s_showHandItemsMethod != null) { s_showHandItemsMethod.Invoke(humanoid, null); } } catch { } } } public class WarriorManager : MonoBehaviour { private GameObject prefabContainer; private GameObject humanWarriorPrefab; private bool humanPrefabReady; private Dictionary creaturePrefabCache = new Dictionary(); private float purgeTimer; private const float PURGE_INTERVAL = 1f; private static readonly List s_ewDeathPositions = new List(); private const float EQUALIZED_HEALTH = 1000f; public static WarriorManager Instance { get; private set; } public List ArmyA { get; private set; } = new List(); public List ArmyB { get; private set; } = new List(); public static void RecordDeathPosition(Vector3 pos) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) s_ewDeathPositions.Add(pos); } public static List GetDeathPositions() { return s_ewDeathPositions; } public static void ClearDeathPositions() { s_ewDeathPositions.Clear(); } private void Awake() { Instance = this; CleanupStaleRagdolls(); } public static void CleanupStaleRagdolls() { int num = 0; Ragdoll[] array = Object.FindObjectsOfType(); foreach (Ragdoll val in array) { if ((Object)(object)val != (Object)null && val.m_ttl > 9999f) { Object.Destroy((Object)(object)((Component)val).gameObject); num++; } } ClearDeathPositions(); if (num > 0) { BigBattlesPlugin.Log($"Cleaned up {num} stale warrior ragdolls from previous session."); } } private void Update() { purgeTimer -= Time.deltaTime; if (purgeTimer <= 0f) { purgeTimer = 1f; PurgeDeadFromList(ArmyA); PurgeDeadFromList(ArmyB); } } private static void PurgeDeadFromList(List army) { for (int num = army.Count - 1; num >= 0; num--) { WarriorAI warriorAI = army[num]; if ((Object)(object)warriorAI == (Object)null || (Object)(object)((Component)warriorAI).gameObject == (Object)null) { int index = army.Count - 1; army[num] = army[index]; army.RemoveAt(index); } } } private void EnsureContainer() { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Expected O, but got Unknown if ((Object)(object)prefabContainer == (Object)null) { prefabContainer = new GameObject("BB_PrefabContainer"); Object.DontDestroyOnLoad((Object)(object)prefabContainer); prefabContainer.SetActive(false); } } private bool EnsureHumanPrefab() { if (humanPrefabReady && (Object)(object)humanWarriorPrefab != (Object)null) { return true; } if ((Object)(object)ZNetScene.instance == (Object)null) { return false; } GameObject prefab = ZNetScene.instance.GetPrefab("Player"); if ((Object)(object)prefab == (Object)null) { return false; } EnsureContainer(); humanWarriorPrefab = Object.Instantiate(prefab, prefabContainer.transform, false); ((Object)humanWarriorPrefab).name = "BB_HumanWarrior_Prefab"; Humanoid component = prefab.GetComponent(); ItemDrop unarmedWeapon = component?.m_unarmedWeapon; EffectList consumeItemEffects = component?.m_consumeItemEffects; EffectList equipEffects = component?.m_equipEffects; EffectList deathEffects = ((Character)(component?)).m_deathEffects; EffectList hitEffects = ((Character)(component?)).m_hitEffects; SafeDestroy(humanWarriorPrefab); SafeDestroy(humanWarriorPrefab); SafeDestroy(humanWarriorPrefab); SafeDestroy(humanWarriorPrefab); SafeDestroy(humanWarriorPrefab); SafeDestroy(humanWarriorPrefab); SafeDestroy(humanWarriorPrefab); Humanoid val = humanWarriorPrefab.AddComponent(); val.m_unarmedWeapon = unarmedWeapon; val.m_consumeItemEffects = consumeItemEffects; val.m_equipEffects = equipEffects; ((Character)val).m_deathEffects = deathEffects; ((Character)val).m_hitEffects = hitEffects; CharacterAnimEvent componentInChildren = humanWarriorPrefab.GetComponentInChildren(); if ((Object)(object)componentInChildren != (Object)null) { AccessTools.Field(typeof(CharacterAnimEvent), "m_character")?.SetValue(componentInChildren, val); } SetupHumanoid(val); SetupSharedComponents(humanWarriorPrefab); Rigidbody component2 = humanWarriorPrefab.GetComponent(); if ((Object)(object)component2 != (Object)null) { component2.mass = 50f; } WarriorAI ai = humanWarriorPrefab.AddComponent(); SetupBaseAIFields(ai); RegisterPrefab(humanWarriorPrefab, ZNetScene.instance); humanPrefabReady = true; BigBattlesPlugin.Log("Human warrior prefab created."); return true; } private void SetupHumanoid(Humanoid h) { //IL_0019: 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) ((Character)h).m_name = "Warrior"; ((Character)h).m_group = "BB_Warrior"; ((Character)h).m_faction = (Faction)8; ((Character)h).m_boss = false; ((Character)h).m_health = BigBattlesPlugin.HumanHealth.Value; ((Character)h).m_walkSpeed = BigBattlesPlugin.HumanWalkSpeed.Value; ((Character)h).m_runSpeed = BigBattlesPlugin.HumanRunSpeed.Value; ((Character)h).m_speed = 5f; ((Character)h).m_crouchSpeed = 2f; ((Character)h).m_turnSpeed = 300f; ((Character)h).m_runTurnSpeed = 300f; ((Character)h).m_acceleration = 1f; ((Character)h).m_jumpForce = 8f; ((Character)h).m_jumpForceForward = 2f; ((Character)h).m_jumpForceTiredFactor = 0.6f; ((Character)h).m_canSwim = true; ((Character)h).m_swimDepth = 2f; ((Character)h).m_swimSpeed = 2f; ((Character)h).m_swimTurnSpeed = 100f; ((Character)h).m_swimAcceleration = 0.05f; ((Character)h).m_tolerateWater = true; ((Character)h).m_groundTilt = (GroundTiltType)0; ((Character)h).m_groundTiltSpeed = 50f; ((Character)h).m_eye = Utils.FindChild(((Component)h).gameObject.transform, "EyePos", (IterativeSearchType)0); ((Character)h).m_staggerWhenBlocked = true; ((Character)h).m_staggerDamageFactor = 0f; } private void SetupSharedComponents(GameObject go) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) ZNetView component = go.GetComponent(); if ((Object)(object)component != (Object)null) { component.m_persistent = false; component.m_distant = false; component.m_type = (ObjectType)0; component.m_syncInitialScale = false; } ZSyncTransform component2 = go.GetComponent(); if ((Object)(object)component2 != (Object)null) { component2.m_syncPosition = true; component2.m_syncRotation = true; component2.m_syncScale = false; component2.m_syncBodyVelocity = false; component2.m_characterParentSync = false; } ZSyncAnimation component3 = go.GetComponent(); if ((Object)(object)component3 != (Object)null) { component3.m_smoothCharacterSpeeds = true; } } private void SetupBaseAIFields(WarriorAI ai) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) ((BaseAI)ai).m_viewRange = 15f; ((BaseAI)ai).m_viewAngle = 90f; ((BaseAI)ai).m_hearRange = 15f; ((BaseAI)ai).m_pathAgentType = (AgentType)1; ((BaseAI)ai).m_smoothMovement = true; ((BaseAI)ai).m_serpentMovement = false; ((BaseAI)ai).m_moveMinAngle = 90f; ((BaseAI)ai).m_randomCircleInterval = 0f; ((BaseAI)ai).m_randomMoveInterval = 0f; ((BaseAI)ai).m_randomMoveRange = 0f; ((BaseAI)ai).m_avoidFire = false; ((BaseAI)ai).m_afraidOfFire = false; ((BaseAI)ai).m_avoidWater = false; ((BaseAI)ai).m_aggravatable = false; } private GameObject EnsureCreaturePrefab(string prefabName) { //IL_01ff: Unknown result type (might be due to invalid IL or missing references) string text = "BB_" + prefabName + "_Warrior"; if (creaturePrefabCache.TryGetValue(text, out var value) && (Object)(object)value != (Object)null) { return value; } if ((Object)(object)ZNetScene.instance == (Object)null) { return null; } GameObject prefab = ZNetScene.instance.GetPrefab(prefabName); if ((Object)(object)prefab == (Object)null) { BigBattlesPlugin.LogErr("Creature prefab '" + prefabName + "' not found in ZNetScene! Check spelling. Available prefabs can be listed with 'listprefabs' console command."); return null; } EnsureContainer(); GameObject val = Object.Instantiate(prefab, prefabContainer.transform, false); ((Object)val).name = text; SafeDestroy(val); SafeDestroy(val); int num = 10; BaseAI component; while (num-- > 0 && (Object)(object)(component = val.GetComponent()) != (Object)null && !(component is WarriorAI)) { Object.DestroyImmediate((Object)(object)component); } SafeDestroy(val); SafeDestroy(val); MonoBehaviour[] components = val.GetComponents(); for (int num2 = components.Length - 1; num2 >= 0; num2--) { MonoBehaviour val2 = components[num2]; if ((Object)(object)val2 == (Object)null) { continue; } string name = ((object)val2).GetType().Name; switch (name) { default: if (!(name == "NpcText")) { continue; } break; case "Npc": case "Trader": case "RandomAnimation": case "RandomIdle": case "Growup": case "Procreation": case "Talker": break; } Object.DestroyImmediate((Object)(object)val2); } Humanoid component2 = val.GetComponent(); if ((Object)(object)component2 != (Object)null) { ((Character)component2).m_faction = (Faction)8; CharacterAnimEvent componentInChildren = val.GetComponentInChildren(); if ((Object)(object)componentInChildren != (Object)null) { AccessTools.Field(typeof(CharacterAnimEvent), "m_character")?.SetValue(componentInChildren, component2); } } SetupSharedComponents(val); Rigidbody component3 = val.GetComponent(); if ((Object)(object)component3 != (Object)null) { component3.constraints = (RigidbodyConstraints)112; component3.isKinematic = false; } WarriorAI ai = val.AddComponent(); SetupBaseAIFields(ai); RegisterPrefab(val, ZNetScene.instance); creaturePrefabCache[text] = val; BigBattlesPlugin.Log("Creature warrior prefab created: " + text); return val; } public WarriorAI SpawnWarrior(ArmySide side, NpcTypeDefinition npcType, Vector3 position, Quaternion rotation) { //IL_00d9: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_014b: Unknown result type (might be due to invalid IL or missing references) //IL_0152: Unknown result type (might be due to invalid IL or missing references) //IL_01cb: Unknown result type (might be due to invalid IL or missing references) //IL_01d0: Unknown result type (might be due to invalid IL or missing references) List army = GetArmy(side); if (army.Count >= BigBattlesPlugin.MaxPerSide.Value) { ShowMsg($"Army {side} is full ({BigBattlesPlugin.MaxPerSide.Value} max)."); return null; } GameObject val; if (npcType.Category == NpcCategory.Human) { if (!EnsureHumanPrefab()) { return null; } val = humanWarriorPrefab; } else { val = EnsureCreaturePrefab(npcType.PrefabName); if ((Object)(object)val == (Object)null) { return null; } } bool activeSelf = val.activeSelf; val.SetActive(false); GameObject val2 = Object.Instantiate(val); val.SetActive(activeSelf); val2.transform.SetParent((Transform)null); val2.transform.position = position; val2.transform.rotation = rotation; if (npcType.Category == NpcCategory.Human) { int num = LayerMask.NameToLayer("character"); if (num >= 0) { SetLayerRecursive(val2, num); } } float num2 = npcType.Scale; if (npcType.Category == NpcCategory.Human) { num2 = BigBattlesPlugin.HumanScale.Value; } val2.transform.localScale = Vector3.one * num2; val2.SetActive(true); int num3 = army.Count + 1; ((Object)val2).name = $"BB_{side}_{npcType.DisplayName}_{num3}"; WarriorAI component = val2.GetComponent(); if ((Object)(object)component == (Object)null) { BigBattlesPlugin.LogErr("WarriorAI missing on spawned NPC!"); Object.Destroy((Object)(object)val2); return null; } Faction faction = (Faction)((side == ArmySide.A) ? 8 : 7); component.Initialize(side, faction, npcType.OverrideAttackRange, npcType.AttackCooldown, npcType.Category == NpcCategory.Creature); Humanoid component2 = val2.GetComponent(); if ((Object)(object)component2 != (Object)null) { float num4 = npcType.DefaultHealth; if (npcType.Category == NpcCategory.Human) { num4 = BigBattlesPlugin.HumanHealth.Value; } ((Character)component2).m_health = num4; ((Character)component2).SetMaxHealth(num4); ((Character)component2).SetHealth(num4); ((Character)component2).m_name = $"{npcType.DisplayName} ({side})"; if (npcType.Category == NpcCategory.Creature) { component2.GiveDefaultItems(); Inventory inventory = component2.GetInventory(); if (inventory != null) { List allItems = inventory.GetAllItems(); foreach (ItemData item in allItems) { component2.EquipItem(item, true); } } } if (npcType.Category == NpcCategory.Human) { VisEquipment component3 = val2.GetComponent(); if ((Object)(object)component3 != (Object)null) { AccessTools.Field(typeof(Humanoid), "m_visEquipment")?.SetValue(component2, component3); } } } Rigidbody component4 = val2.GetComponent(); if ((Object)(object)component4 != (Object)null) { component4.constraints = (RigidbodyConstraints)112; } army.Add(component); return component; } public void SpawnFormation(ArmySide side, NpcTypeDefinition npcType, Vector3 centerPos, Vector3 facing, int count) { //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_0036: 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_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0057: 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) int value = BigBattlesPlugin.FormationColumns.Value; int value2 = BigBattlesPlugin.FormationRows.Value; float value3 = BigBattlesPlugin.FormationSpacing.Value; List positions = FormationCalculator.GetPositions(centerPos, facing, count, value, value2, value3, npcType.SpacingMultiplier); Quaternion rotation = Quaternion.LookRotation(facing); foreach (Vector3 item in positions) { WarriorAI warriorAI = SpawnWarrior(side, npcType, item, rotation); if ((Object)(object)warriorAI == (Object)null) { break; } } ShowMsg($"Spawned {Mathf.Min(count, positions.Count)} {npcType.DisplayName}(s) for Army {side}."); } public void EqualizeHealth() { int num = 0; List[] array = new List[2] { ArmyA, ArmyB }; foreach (List list in array) { foreach (WarriorAI item in list) { if (!((Object)(object)item == (Object)null)) { Humanoid component = ((Component)item).GetComponent(); if (!((Object)(object)component == (Object)null) && !((Character)component).IsDead()) { ((Character)component).m_health = 1000f; ((Character)component).SetMaxHealth(1000f); ((Character)component).SetHealth(1000f); num++; } } } } BigBattlesPlugin.Log($"Equalized health to {1000f} for {num} warriors."); ShowMsg($"All warriors set to {1000f} HP."); } public void ApplyEquipment(ArmySide side, EquipmentData.ItemEntry[] items) { List army = GetArmy(side); foreach (WarriorAI item in army) { if ((Object)(object)item == (Object)null || (Object)(object)((Component)item).gameObject == (Object)null) { continue; } Humanoid component = ((Component)item).GetComponent(); if (!((Object)(object)component == (Object)null)) { component.UnequipAllItems(); Inventory inventory = component.GetInventory(); if (inventory != null) { inventory.RemoveAll(); } for (int i = 0; i < items.Length; i++) { TryAddAndEquip(component, inventory, items[i].PrefabName, items[i].Variant); } } } foreach (WarriorAI item2 in army) { if ((Object)(object)item2 != (Object)null) { StripWeaponVFX(((Component)item2).gameObject); } } BigBattlesPlugin.Log($"Applied equipment to Army {side} ({army.Count} warriors)."); } public static void StripWeaponVFX(GameObject warrior) { if (!((Object)(object)warrior == (Object)null)) { ParticleSystem[] componentsInChildren = warrior.GetComponentsInChildren(true); foreach (ParticleSystem val in componentsInChildren) { val.Stop(true, (ParticleSystemStopBehavior)0); ((Component)val).gameObject.SetActive(false); } TrailRenderer[] componentsInChildren2 = warrior.GetComponentsInChildren(true); foreach (TrailRenderer val2 in componentsInChildren2) { ((Renderer)val2).enabled = false; } Light[] componentsInChildren3 = warrior.GetComponentsInChildren(true); foreach (Light val3 in componentsInChildren3) { ((Behaviour)val3).enabled = false; } } } public void ApplyEquipmentToSingle(WarriorAI warrior, EquipmentData.ItemEntry[] items) { if ((Object)(object)warrior == (Object)null || (Object)(object)((Component)warrior).gameObject == (Object)null) { return; } Humanoid component = ((Component)warrior).GetComponent(); if (!((Object)(object)component == (Object)null)) { component.UnequipAllItems(); Inventory inventory = component.GetInventory(); if (inventory != null) { inventory.RemoveAll(); } for (int i = 0; i < items.Length; i++) { TryAddAndEquip(component, inventory, items[i].PrefabName, items[i].Variant); } } } private static void TryAddAndEquip(Humanoid humanoid, Inventory inv, string prefabName, int variant = 0) { //IL_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Invalid comparison between Unknown and I4 //IL_00f9: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Expected O, but got Unknown //IL_030c: Unknown result type (might be due to invalid IL or missing references) //IL_0312: Invalid comparison between Unknown and I4 //IL_0170: Unknown result type (might be due to invalid IL or missing references) //IL_017a: Expected O, but got Unknown //IL_01e5: Unknown result type (might be due to invalid IL or missing references) //IL_01ef: Expected O, but got Unknown //IL_0338: Unknown result type (might be due to invalid IL or missing references) //IL_033f: Invalid comparison between Unknown and I4 if (string.IsNullOrEmpty(prefabName) || (Object)(object)humanoid == (Object)null || inv == null) { return; } ObjectDB instance = ObjectDB.instance; GameObject val = ((instance != null) ? instance.GetItemPrefab(prefabName) : null); if ((Object)(object)val == (Object)null) { return; } ItemDrop component = val.GetComponent(); if ((Object)(object)component == (Object)null || component.m_itemData == null) { return; } ItemData val2 = component.m_itemData.Clone(); val2.m_stack = 1; val2.m_quality = 4; val2.m_variant = variant; val2.m_crafterID = 0L; val2.m_crafterName = ""; val2.m_equipped = false; val2.m_dropPrefab = val; if (val2.m_shared != null && (int)val2.m_shared.m_itemType == 4) { Attack attack = val2.m_shared.m_attack; if (attack != null) { val2.m_shared = new SharedData(); FieldInfo[] fields = typeof(SharedData).GetFields(BindingFlags.Instance | BindingFlags.Public); SharedData shared = component.m_itemData.m_shared; FieldInfo[] array = fields; foreach (FieldInfo fieldInfo in array) { fieldInfo.SetValue(val2.m_shared, fieldInfo.GetValue(shared)); } if (shared.m_attack != null) { val2.m_shared.m_attack = new Attack(); FieldInfo[] fields2 = typeof(Attack).GetFields(BindingFlags.Instance | BindingFlags.Public); FieldInfo[] array2 = fields2; foreach (FieldInfo fieldInfo2 in array2) { fieldInfo2.SetValue(val2.m_shared.m_attack, fieldInfo2.GetValue(shared.m_attack)); } } if (shared.m_secondaryAttack != null) { val2.m_shared.m_secondaryAttack = new Attack(); FieldInfo[] fields3 = typeof(Attack).GetFields(BindingFlags.Instance | BindingFlags.Public); FieldInfo[] array3 = fields3; foreach (FieldInfo fieldInfo3 in array3) { fieldInfo3.SetValue(val2.m_shared.m_secondaryAttack, fieldInfo3.GetValue(shared.m_secondaryAttack)); } } Attack attack2 = val2.m_shared.m_attack; if (attack2 != null) { float num = 45f; if (attack2.m_projectileVel < num) { attack2.m_projectileVel = num; } attack2.m_projectileVelMin = attack2.m_projectileVel * 0.5f; attack2.m_drawDurationMin = 0f; attack2.m_projectileAccuracy = 0f; attack2.m_projectileAccuracyMin = 0f; BigBattlesPlugin.Log($"[BowFix] {prefabName}: vel={attack2.m_projectileVel}, velMin={attack2.m_projectileVelMin}, accuracy=0"); } } } if (!inv.AddItem(val2)) { return; } humanoid.EquipItem(val2, true); if (val2.m_shared != null && (int)val2.m_shared.m_itemType == 4) { TryAddAmmo(humanoid, inv); } if (variant == 0 || val2.m_shared == null || (int)val2.m_shared.m_itemType != 17) { return; } VisEquipment component2 = ((Component)humanoid).GetComponent(); if ((Object)(object)component2 != (Object)null) { MethodInfo methodInfo = AccessTools.Method(typeof(VisEquipment), "SetShoulderItemVariant", (Type[])null, (Type[])null); if (methodInfo != null) { methodInfo.Invoke(component2, new object[1] { variant }); } else { AccessTools.Field(typeof(VisEquipment), "m_shoulderItemVariant")?.SetValue(component2, variant); } } } private static void TryAddAmmo(Humanoid humanoid, Inventory inv) { string[] array = new string[7] { "ArrowCharred", "ArrowNeedle", "ArrowObsidian", "ArrowIron", "ArrowBronze", "ArrowFlint", "ArrowWood" }; string[] array2 = array; foreach (string text in array2) { ObjectDB instance = ObjectDB.instance; GameObject val = ((instance != null) ? instance.GetItemPrefab(text) : null); if ((Object)(object)val == (Object)null) { continue; } ItemDrop component = val.GetComponent(); if (!((Object)(object)component == (Object)null)) { ItemData val2 = component.m_itemData.Clone(); val2.m_stack = 999; val2.m_quality = 1; val2.m_dropPrefab = val; if (inv.AddItem(val2)) { humanoid.EquipItem(val2, true); break; } } } } public void DespawnArmy(ArmySide side) { List army = GetArmy(side); foreach (WarriorAI item in army) { if ((Object)(object)item != (Object)null && (Object)(object)((Component)item).gameObject != (Object)null) { Object.Destroy((Object)(object)((Component)item).gameObject); } } army.Clear(); } public void DespawnAll() { DespawnArmy(ArmySide.A); DespawnArmy(ArmySide.B); CleanupRagdolls(); } public void CleanupRagdolls() { //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_0040: 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) Ragdoll[] array = Object.FindObjectsOfType(); int num = 0; Ragdoll[] array2 = array; foreach (Ragdoll val in array2) { if ((Object)(object)val == (Object)null) { continue; } bool flag = false; Vector3 position = ((Component)val).transform.position; for (int j = 0; j < s_ewDeathPositions.Count; j++) { if (Vector3.Distance(position, s_ewDeathPositions[j]) < 10f) { flag = true; break; } } if (flag) { Object.Destroy((Object)(object)((Component)val).gameObject); num++; } } s_ewDeathPositions.Clear(); if (num > 0) { BigBattlesPlugin.Log($"Cleaned up {num} ragdolls."); } } public void ResetPrefabState() { humanPrefabReady = false; humanWarriorPrefab = null; creaturePrefabCache.Clear(); if ((Object)(object)prefabContainer != (Object)null) { Object.Destroy((Object)(object)prefabContainer); prefabContainer = null; } EquipmentData.Reset(); BigBattlesPlugin.Log("Prefab state reset for next world load."); } public void FaceArmiesAtEachOther() { //IL_002a: 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_0032: 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_0073: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) if (ArmyA.Count == 0 || ArmyB.Count == 0) { return; } Vector3 armyCenter = GetArmyCenter(ArmySide.A); Vector3 armyCenter2 = GetArmyCenter(ArmySide.B); foreach (WarriorAI item in ArmyA) { if ((Object)(object)item != (Object)null && (Object)(object)((Component)item).gameObject != (Object)null) { item.SetIdleFacing(armyCenter2); } } foreach (WarriorAI item2 in ArmyB) { if ((Object)(object)item2 != (Object)null && (Object)(object)((Component)item2).gameObject != (Object)null) { item2.SetIdleFacing(armyCenter); } } BigBattlesPlugin.Log("Both armies now face each other."); } public void FaceArmyToward(ArmySide side, Vector3 targetPos) { //IL_0039: Unknown result type (might be due to invalid IL or missing references) List army = GetArmy(side); foreach (WarriorAI item in army) { if ((Object)(object)item != (Object)null && (Object)(object)((Component)item).gameObject != (Object)null) { item.SetIdleFacing(targetPos); } } } public List GetArmy(ArmySide side) { return (side == ArmySide.A) ? ArmyA : ArmyB; } public int GetArmyCount(ArmySide side) { return GetArmy(side).Count; } public int GetAliveCount(ArmySide side) { int num = 0; List army = GetArmy(side); foreach (WarriorAI item in army) { if ((Object)(object)item != (Object)null && (Object)(object)((Component)item).gameObject != (Object)null) { Character myCharacter = item.MyCharacter; if ((Object)(object)myCharacter != (Object)null && !myCharacter.IsDead()) { num++; } } } return num; } public Vector3 GetArmyCenter(ArmySide side) { //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_0016: 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_00d2: 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_00c9: 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_00ce: 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_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_0099: Unknown result type (might be due to invalid IL or missing references) List army = GetArmy(side); if (army.Count == 0) { return Vector3.zero; } Vector3 val = Vector3.zero; int num = 0; foreach (WarriorAI item in army) { if ((Object)(object)item != (Object)null && (Object)(object)((Component)item).gameObject != (Object)null) { Character myCharacter = item.MyCharacter; if ((Object)(object)myCharacter != (Object)null && !myCharacter.IsDead()) { val += ((Component)item).transform.position; num++; } } } return (num > 0) ? (val / (float)num) : Vector3.zero; } private void RegisterPrefab(GameObject go, ZNetScene zNetScene) { int stableHashCode = StringExtensionMethods.GetStableHashCode(((Object)go).name); zNetScene.m_prefabs.Add(go); FieldInfo fieldInfo = AccessTools.Field(typeof(ZNetScene), "m_namedPrefabs"); if (fieldInfo != null && fieldInfo.GetValue(zNetScene) is Dictionary dictionary) { dictionary[stableHashCode] = go; } } private void SafeDestroy(GameObject obj) where T : Component { T component = obj.GetComponent(); if ((Object)(object)component != (Object)null) { Object.DestroyImmediate((Object)(object)component); } } private static void SetLayerRecursive(GameObject obj, int layer) { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Expected O, but got Unknown obj.layer = layer; foreach (Transform item in obj.transform) { Transform val = item; SetLayerRecursive(((Component)val).gameObject, layer); } } private void ShowMsg(string text) { Player localPlayer = Player.m_localPlayer; if (localPlayer != null) { ((Character)localPlayer).Message((MessageType)2, text, 0, (Sprite)null); } } } }