Decompiled source of Combat Stats Tracker v1.0.11
BepInEx/plugins/CombatStatsTracker.dll
Decompiled a week ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using DM; using HarmonyLib; using Landfall.TABS; using Landfall.TABS.GameMode; using Landfall.TABS.UnitPlacement; using Microsoft.CodeAnalysis; using TMPro; using UnityEngine; using UnityEngine.Events; using UnityEngine.SceneManagement; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyCompany("CombatStatsTracker")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("CombatStatsTracker")] [assembly: AssemblyTitle("CombatStatsTracker")] [assembly: AssemblyVersion("1.0.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace Fero.Tabs.CombatStatsTracker { [BepInPlugin("fero.tabs.combat_stats_tracker", "Combat Stats Tracker", "1.0.11")] public sealed class Plugin : BaseUnityPlugin { private enum Metric { DamageDealt, DamageTaken, Healing } private enum TeamFilter { All, Red, Blue } internal sealed class Entry { internal string Key; internal Team Team; internal UnitBlueprint Blueprint; internal string Name; internal readonly HashSet<int> Participants = new HashSet<int>(); internal bool HasInitialRoster; internal float Dealt; internal float Taken; internal float Healing; internal int Kills; internal int Deaths; } private sealed class RowView { internal GameObject Root; internal RectTransform Rect; internal Image Portrait; internal Image TeamStripe; internal RectTransform BarFill; internal Image BarFillImage; internal TextMeshProUGUI CountText; internal TextMeshProUGUI NameText; internal TextMeshProUGUI ValueText; internal int VisualIndex = -1; } internal struct DamageState { internal bool Track; internal bool Healing; internal Unit Target; internal Unit Source; internal float Before; internal float AcceptedDamage; internal DotAttribution Dot; internal float DotWeightTotal; } internal struct SourceState { internal Unit PreviousSource; internal int PreviousTarget; } internal struct DeathState { internal bool Track; internal Unit Target; internal Entry Victim; internal Entry Killer; } internal struct DotState { internal SourceState PreviousScope; internal DotAttribution PreviousDot; internal int PreviousDotTarget; internal DotAttribution ActiveDot; internal float RawDamageBefore; } internal struct EffectApplicationState { internal Unit PreviousSource; } internal sealed class DotAttribution { internal DamageOverTimeEffect Effect; internal readonly Dictionary<Entry, float> RemainingBySource = new Dictionary<Entry, float>(); } private sealed class ControlLabelKeeper : MonoBehaviour { private string _actionLabel; private string _bindingLabel; private TextMeshProUGUI _actionText; private TextMeshProUGUI _bindingText; internal void Configure(string actionLabel, string bindingLabel) { _actionLabel = actionLabel; _bindingLabel = bindingLabel; ApplyLabels(); } private void LateUpdate() { ApplyLabels(); } private void ApplyLabels() { if ((Object)(object)_actionText == (Object)null) { TextMeshProUGUI[] componentsInChildren = ((Component)this).GetComponentsInChildren<TextMeshProUGUI>(true); if (componentsInChildren.Length == 0) { return; } _actionText = componentsInChildren[0]; _bindingText = ((componentsInChildren.Length > 1) ? componentsInChildren[^1] : null); } if ((Object)(object)_actionText != (Object)null && ((TMP_Text)_actionText).text != _actionLabel) { ((TMP_Text)_actionText).text = _actionLabel; } if ((Object)(object)_bindingText != (Object)null && ((TMP_Text)_bindingText).text != _bindingLabel) { ((TMP_Text)_bindingText).text = _bindingLabel; } } } private sealed class CombatStatsKeyControl : MonoBehaviour { private bool _waitingForKey; private ControlLabelKeeper _labels; internal void Configure() { _labels = ((Component)this).GetComponent<ControlLabelKeeper>() ?? ((Component)this).gameObject.AddComponent<ControlLabelKeeper>(); RefreshLabels(); } internal void BeginRebind() { _waitingForKey = true; RefreshLabels(); } private void Update() { //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_004a: 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) if (!_waitingForKey) { return; } if (Input.GetKeyDown((KeyCode)27)) { _waitingForKey = false; RefreshLabels(); return; } if (Input.GetKeyDown((KeyCode)8) || Input.GetKeyDown((KeyCode)127)) { Commit((KeyCode)0); return; } KeyCode[] toggleKeyOptions = ToggleKeyOptions; foreach (KeyCode val in toggleKeyOptions) { if ((int)val != 0 && Input.GetKeyDown(val)) { Commit(val); break; } } } private void LateUpdate() { RefreshLabels(); } private void OnDisable() { _waitingForKey = false; } private void Commit(KeyCode key) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) SetToggleKey(key); _waitingForKey = false; RefreshLabels(); } private void RefreshLabels() { //IL_0037: 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_004b: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)_labels == (Object)null)) { KeyCode key = (KeyCode)(((??)Instance?._toggleKey?.Value) ?? 103); _labels.Configure("Sandbox Combat Stats", _waitingForKey ? "Press a key" : FormatToggleKey(key)); } } } public const string PluginGuid = "fero.tabs.combat_stats_tracker"; public const string PluginName = "Combat Stats Tracker"; public const string PluginVersion = "1.0.11"; private const string SettingKey = "Sandbox Combat Stats"; private const string ControlRowName = "Combat Stats Tracker Control"; private static readonly Dictionary<string, Entry> Entries = new Dictionary<string, Entry>(StringComparer.Ordinal); private static readonly Dictionary<int, Entry> EntryByUnit = new Dictionary<int, Entry>(); private static readonly Dictionary<int, Unit> Units = new Dictionary<int, Unit>(); private static readonly Dictionary<int, DotAttribution> DotAttributions = new Dictionary<int, DotAttribution>(); private static readonly HashSet<Unit> CountedDeaths = new HashSet<Unit>(); private static readonly FieldInfo CollisionOwner = AccessTools.Field(typeof(CollisionWeapon), "ownUnit"); private static readonly FieldInfo CollisionData = AccessTools.Field(typeof(CollisionWeapon), "connectedData"); private static readonly FieldInfo CollisionTeamHolder = AccessTools.Field(typeof(CollisionWeapon), "teamHolder"); private static readonly FieldInfo VampireTarget = AccessTools.Field(typeof(VapireBite), "targetData"); private static readonly FieldInfo DotDamageToDo = AccessTools.Field(typeof(DamageOverTimeEffect), "damageToDo"); private static readonly FieldInfo DotDamageDealtSinceLastStack = AccessTools.Field(typeof(DamageOverTimeEffect), "damageDealtSinceLastStack"); private static readonly Color Red = new Color(0.92f, 0.2f, 0.24f, 1f); private static readonly Color Blue = new Color(0.16f, 0.49f, 0.96f, 1f); private static readonly Color Gold = new Color(0.96f, 0.76f, 0.24f, 1f); private static readonly Dictionary<string, string> NameOverrides = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase) { ["banjo"] = "Bard", ["throwerboulder"] = "Stoner", ["musket"] = "Musketeer", ["throwerbomb"] = "Bomb Thrower", ["club"] = "Clubber", ["shieldroman"] = "Shield Bearer", ["orbcaster"] = "Celestial Aegis", ["fantasyassassin"] = "Shadow Walker", ["pitchfork"] = "Farmer", ["lassohorse"] = "Lasso", ["priest"] = "Healer", ["legwizard"] = "Wizard", ["legsuperpeasant"] = "Super Peasant", ["superpeasant"] = "Super Peasant", ["legdarkpeasant"] = "Dark Peasant", ["darkpeasant"] = "Dark Peasant", ["legbarrelroller"] = "Barrel Roller", ["barrelroller"] = "Barrel Roller", ["legpharaoh"] = "Pharaoh", ["pharaoh"] = "Pharaoh", ["legpike"] = "Pike", ["pike"] = "Pike", ["legbannerbearer"] = "Banner Bearer", ["bannerbearer"] = "Banner Bearer", ["scythe"] = "Harvester", ["goodcleric"] = "Righteous Paladin", ["vampirebiter"] = "Vampire", ["jouster"] = "Jouster Rider", ["jousteronhorse"] = "Jouster", ["legboxer"] = "Boxer", ["legflagbearer"] = "Flag Bearer", ["legacyboxer"] = "Boxer", ["legpeasant"] = "Peasant", ["legpoacher"] = "Poacher", ["legblowdarter"] = "Blowdarter", ["legchariot"] = "Chariot", ["legthor"] = "Thor", ["legtank"] = "Tank", ["eviltank"] = "Exiled Sentinel", ["fantasyeviltank"] = "Exiled Sentinel", ["legsuperboxer"] = "Super Boxer", ["elephant"] = "Sacred Elephant", ["thrownglaive"] = "Radiant Glaive", ["smitepriest"] = "Divine Arbiter", ["gauntlet"] = "Devout Gauntlet", ["timeninja"] = "Chronomancer", ["stormpriest"] = "Tempest Lich", ["evilcleric"] = "Void Cultist", ["darkking"] = "Void Monarch", ["mechanic"] = "Mad Mechanic", ["warglaive"] = "Death Bringer", ["throwerclam"] = "CLAMS", ["throwerpresent"] = "Present Elf", ["cavalryonhorse"] = "Cavalry", ["redjade"] = "Lady Red Jade" }; private static readonly KeyCode[] ToggleKeyOptions; private static Plugin Instance; private Harmony _harmony; private ConfigEntry<bool> _enabled; private ConfigEntry<KeyCode> _toggleKey; private ConfigEntry<bool> _windowVisible; private ConfigEntry<float> _windowPositionX; private ConfigEntry<float> _windowPositionY; private SettingsInstance _gameSetting; private static bool _battleActive; private static bool _supportedModeActive; private static bool _registeringRoster; private static bool _manualHidden; private static bool _freeLook; private static bool _menuOpen; private static bool _dirty; private static float _nextRefresh; private static Unit _scopedSource; private static int _scopedTarget; private static DotAttribution _activeDot; private static int _activeDotTarget; private static Unit _effectApplicationSource; private static int _environmentDepth; private static Metric _metric; private static TeamFilter _teamFilter; private static GameObject _canvas; private static GameObject _inputBlockerCanvas; private static RectTransform _inputBlocker; private static RectTransform _panel; private static RectTransform _dragHandle; private static RectTransform _viewport; private static RectTransform _content; private static TextMeshProUGUI _redSummary; private static TextMeshProUGUI _metricSummary; private static TextMeshProUGUI _blueSummary; private static TextMeshProUGUI _empty; private static TextMeshProUGUI _hideHint; private static RectTransform _dealtButton; private static RectTransform _takenButton; private static RectTransform _healingButton; private static RectTransform _allButton; private static RectTransform _redButton; private static RectTransform _blueButton; private static Sprite _shortcutCircleSprite; private static readonly Dictionary<string, RowView> RowViews; private static readonly List<Entry> VisibleEntries; private static readonly HashSet<string> VisibleKeys; private const int VisibleRowCapacity = 5; private const float RowSpacing = 54f; private static float _scrollPosition; private static float _scrollTarget; private static float _scrollVelocity; private static float _visibleMaximum; private static bool _scrollAnimationActive; private static bool _resetScroll; private static bool _draggingPanel; private static Vector2 _dragStartPointerLocal; private static Vector2 _dragStartPanelPosition; private static Vector2 _lastPanelParentSize; private static bool _panelUsesArenaLayout; private static bool _arenaIntegrationResolved; private static FieldInfo _arenaModeActiveField; private static PropertyInfo _arenaModeActiveProperty; private static MethodInfo _arenaDisplayNameMethod; private static readonly FieldInfo PlacementSceneDescriptionField; private static readonly FieldInfo PlacementWinConditionPresenterField; private static readonly FieldInfo PlacementMapButtonField; private static FieldInfo _sceneDescriptionTextField; private static FieldInfo _sceneDescriptionMapButtonField; private static FieldInfo _blueWinConditionsField; private static PlacementUI _suppressedHudPlacementUi; private static CanvasGroup _battleNameSuppression; private static CanvasGroup _mapButtonSuppression; private static CanvasGroup _objectiveSuppression; private static float _nextHudSuppressionDiscovery; private static readonly Vector3[] PanelScreenCorners; private static readonly Vector3[] HudScreenCorners; private static bool _primaryPressConsumed; private static bool _secondaryPressConsumed; private static int _blockPlacementThroughFrame; private void Awake() { //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Expected O, but got Unknown Instance = this; _enabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Interface", "Enabled", true, "Show the standalone combat statistics tracker."); _toggleKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("Interface", "ToggleKey", (KeyCode)103, "Show or hide the combat statistics tracker."); _windowVisible = ((BaseUnityPlugin)this).Config.Bind<bool>("Window", "Visible", true, "Remember whether Combat Stats was manually shown or hidden when the game closed."); _windowPositionX = ((BaseUnityPlugin)this).Config.Bind<float>("Window", "PositionX", -1f, "Saved normalized horizontal window position. -1 uses the default position."); _windowPositionY = ((BaseUnityPlugin)this).Config.Bind<float>("Window", "PositionY", -1f, "Saved normalized vertical window position. -1 uses the default position."); _manualHidden = !_windowVisible.Value; _harmony = new Harmony("fero.tabs.combat_stats_tracker"); PatchAllSafely(); SceneManager.activeSceneChanged += OnSceneChanged; ((MonoBehaviour)this).StartCoroutine(InjectSettingWhenReady()); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Combat Stats Tracker 1.0.11 loaded independently."); } private void PatchAllSafely() { int num = 0; int num2 = 0; Type[] types = typeof(Plugin).Assembly.GetTypes(); foreach (Type type in types) { if (type.GetCustomAttributes(typeof(HarmonyPatch), inherit: true).Any()) { try { _harmony.CreateClassProcessor(type).Patch(); num++; } catch (Exception ex) { num2++; ((BaseUnityPlugin)this).Logger.LogWarning((object)("Skipped Harmony patch " + type.FullName + ": " + ex.GetType().Name + ": " + ex.Message)); } } } ((BaseUnityPlugin)this).Logger.LogInfo((object)$"Combat Stats Harmony patch classes applied: {num}; skipped: {num2}."); } private void OnDestroy() { SceneManager.activeSceneChanged -= OnSceneChanged; Harmony harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } DestroyPanel(); } private void Update() { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) if (_supportedModeActive && _toggleKey != null && (int)_toggleKey.Value != 0 && Input.GetKeyDown(_toggleKey.Value)) { _manualHidden = !_manualHidden; _windowVisible.Value = !_manualHidden; ((BaseUnityPlugin)this).Config.Save(); _dirty = true; if (_manualHidden) { DestroyPanel(); } else { EnsurePanel(); } } if (!ShouldShow()) { if ((Object)(object)_canvas != (Object)null) { _canvas.SetActive(false); } if ((Object)(object)_inputBlockerCanvas != (Object)null) { _inputBlockerCanvas.SetActive(false); } return; } EnsurePanel(); if ((Object)(object)_canvas != (Object)null && !_canvas.activeSelf) { _canvas.SetActive(true); } if ((Object)(object)_inputBlockerCanvas != (Object)null && !_inputBlockerCanvas.activeSelf) { _inputBlockerCanvas.SetActive(true); } ApplyPanelPlacement(); HandlePanelDrag(); HandlePointerInput(); MaintainScrollAnimation(); if (_dirty && Time.unscaledTime >= _nextRefresh) { _nextRefresh = Time.unscaledTime + 0.25f; RefreshPanel(); } } private void LateUpdate() { if (ShouldShow() && (Object)(object)_canvas != (Object)null && _canvas.activeSelf) { MaintainOverlappedVanillaHudSuppression(); } else { RestoreOverlappedVanillaHud(); } } private static bool ShouldShow() { //IL_0063: 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) Plugin instance = Instance; if (instance == null || instance._enabled?.Value != true || _manualHidden || !_supportedModeActive) { return false; } if (_freeLook || _menuOpen || Time.timeScale <= 0.001f) { return false; } Scene activeScene = SceneManager.GetActiveScene(); return (((Scene)(ref activeScene)).name ?? string.Empty).IndexOf("menu", StringComparison.OrdinalIgnoreCase) < 0; } private void OnSceneChanged(Scene oldScene, Scene newScene) { bool supportedModeActive = IsArenaRoguelikeActive(); _battleActive = false; _supportedModeActive = supportedModeActive; _freeLook = false; _menuOpen = false; _primaryPressConsumed = false; _secondaryPressConsumed = false; _blockPlacementThroughFrame = -1; ClearEntries(); DestroyPanel(); } private static bool ActivateSupportedMode(BaseGameMode gameMode) { bool flag = IsArenaRoguelikeActive(); bool num = gameMode is SandboxGameMode || flag; if (num) { _supportedModeActive = true; } return num; } internal static void BeginBattle(BaseGameMode gameMode) { Plugin instance = Instance; if (instance == null || instance._enabled?.Value != true || !ActivateSupportedMode(gameMode) || _battleActive) { return; } ClearEntries(); _battleActive = true; _freeLook = false; _menuOpen = false; _registeringRoster = true; try { Unit[] array = Object.FindObjectsOfType<Unit>(); for (int i = 0; i < array.Length; i++) { Register(array[i]); } } finally { _registeringRoster = false; } _dirty = true; _nextRefresh = 0f; EnsurePanel(); } internal static void EnterPlacement(BaseGameMode gameMode) { if (ActivateSupportedMode(gameMode)) { _battleActive = false; _dirty = true; _nextRefresh = 0f; if (ShouldShow()) { EnsurePanel(); } } } internal static void EndBattle(BaseGameMode gameMode) { if (_supportedModeActive || ActivateSupportedMode(gameMode)) { _battleActive = false; _dirty = true; _nextRefresh = 0f; } } internal static void RegisterSpawned(Unit unit) { if (_battleActive) { Register(unit); } } private static Entry Register(Unit unit) { //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Expected I4, but got Unknown //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)unit?.data == (Object)null || (Object)(object)unit.unitBlueprint == (Object)null) { return null; } int num = (int)unit.Team; if (num != 0 && num != 1) { return null; } int instanceID = ((Object)unit).GetInstanceID(); if (EntryByUnit.TryGetValue(instanceID, out var value) && Units.TryGetValue(instanceID, out var value2) && value2 == unit) { return value; } EntryByUnit.Remove(instanceID); Units[instanceID] = unit; UnitBlueprint unitBlueprint = unit.unitBlueprint; string text = GetBlueprintKey(unitBlueprint); if (string.IsNullOrWhiteSpace(text)) { text = Normalize(unitBlueprint.Name); } string key = num.ToString(CultureInfo.InvariantCulture) + ":" + text; if (!Entries.TryGetValue(key, out var value3)) { value3 = new Entry { Key = key, Team = unit.Team, Blueprint = unitBlueprint, Name = DisplayName(unitBlueprint) }; Entries.Add(key, value3); } EntryByUnit[instanceID] = value3; bool num2 = _registeringRoster || (!value3.HasInitialRoster && value3.Participants.Count == 0); if (_registeringRoster) { value3.HasInitialRoster = true; } if (num2) { value3.Participants.Add(instanceID); } _dirty = true; return value3; } private static string DisplayName(UnitBlueprint blueprint) { if ((Object)(object)blueprint == (Object)null) { return "Unit"; } string text = null; string[] array = new string[2] { "m_name", "m_Name" }; foreach (string text2 in array) { try { text = AccessTools.Field(((object)blueprint).GetType(), text2)?.GetValue(blueprint) as string; } catch { } if (!string.IsNullOrWhiteSpace(text)) { break; } } if (string.IsNullOrWhiteSpace(text)) { text = blueprint.Name; } if (string.IsNullOrWhiteSpace(text)) { DatabaseEntity entity = blueprint.Entity; text = ((entity != null) ? entity.Name : null); } if (string.IsNullOrWhiteSpace(text)) { return "Unit"; } if (IsExiledSentinel(blueprint, text)) { return "Exiled Sentinel"; } if (TryGetCatapultDisplayName(blueprint, text, out var displayName)) { return displayName; } if (TryGetJousterDisplayName(blueprint, text, out var displayName2)) { return displayName2; } string key = NormalizeNameAlias(text); if (TryGetLegacyDisplayName(blueprint, text, out var displayName3)) { return displayName3; } if (NameOverrides.TryGetValue(key, out var value)) { return value; } try { ResolveArenaIntegration(); string text3 = _arenaDisplayNameMethod?.Invoke(null, new object[1] { blueprint }) as string; if (!string.IsNullOrWhiteSpace(text3)) { return CanonicalDisplayName(text3); } } catch { } return CanonicalDisplayName(text); } private static string NormalizeNameAlias(string name) { return Normalize(HumanizeDisplayName(name)); } private static string CanonicalDisplayName(string name) { string text = HumanizeDisplayName(name); if (!NameOverrides.TryGetValue(Normalize(text), out var value)) { return text; } return value; } private static string HumanizeDisplayName(string name) { string text = name?.Trim() ?? string.Empty; if (text.StartsWith("UNIT_", StringComparison.OrdinalIgnoreCase)) { string text2 = text.Substring("UNIT_".Length); if (NameOverrides.ContainsKey(Normalize(text2))) { return text2.Replace('_', ' '); } string[] array = text.Split(new char[1] { '_' }, StringSplitOptions.RemoveEmptyEntries); if (array.Length > 2) { text = string.Join(" ", from token in array.Skip(2) select (token.Length != 0) ? (char.ToUpperInvariant(token[0]) + token.Substring(1).ToLowerInvariant()) : token); } } return text; } private static bool TryGetLegacyDisplayName(UnitBlueprint blueprint, string primaryName, out string displayName) { displayName = null; if ((Object)(object)blueprint == (Object)null) { return false; } string[] obj = new string[7] { primaryName, blueprint.Name, ((Object)blueprint).name, null, null, null, null }; DatabaseEntity entity = blueprint.Entity; obj[3] = ((entity != null) ? entity.Name : null); obj[4] = (((Object)(object)blueprint.UnitBase != (Object)null) ? ((Object)blueprint.UnitBase).name : null); DatabaseEntity entity2 = blueprint.Entity; obj[5] = (((Object)(object)((entity2 != null) ? entity2.SpriteIcon : null) != (Object)null) ? ((Object)blueprint.Entity.SpriteIcon).name : null); obj[6] = blueprint.FilePath; string[] array = obj; for (int i = 0; i < array.Length; i++) { string text = Normalize(array[i]); if (text.Contains("superpeasant")) { displayName = "Super Peasant"; } else if (text.Contains("darkpeasant")) { displayName = "Dark Peasant"; } else if (text.Contains("barrelroller")) { displayName = "Barrel Roller"; } else if (text.Contains("pharaoh")) { displayName = "Pharaoh"; } else if (text.Contains("bannerbearer")) { displayName = "Banner Bearer"; } else if (text.Equals("pike", StringComparison.OrdinalIgnoreCase) || text.Contains("legpike") || text.Contains("legacypike")) { displayName = "Pike"; } if (displayName != null) { return true; } } return false; } private static bool TryGetJousterDisplayName(UnitBlueprint blueprint, string primaryName, out string displayName) { displayName = null; if ((Object)(object)blueprint == (Object)null) { return false; } List<string> obj = new List<string>(8) { primaryName, blueprint.Name, ((Object)blueprint).name }; DatabaseEntity entity = blueprint.Entity; obj.Add((entity != null) ? entity.Name : null); obj.Add(((Object)(object)blueprint.UnitBase != (Object)null) ? ((Object)blueprint.UnitBase).name : null); DatabaseEntity entity2 = blueprint.Entity; obj.Add(((Object)(object)((entity2 != null) ? entity2.SpriteIcon : null) != (Object)null) ? ((Object)blueprint.Entity.SpriteIcon).name : null); obj.Add(blueprint.FilePath); string[] source = (from candidate in obj.Where((string candidate) => !string.IsNullOrWhiteSpace(candidate)).Select(Normalize) where !string.IsNullOrWhiteSpace(candidate) select candidate).Distinct<string>(StringComparer.OrdinalIgnoreCase).ToArray(); if (!source.Any((string identity) => identity.Contains("jouster"))) { return false; } bool flag = source.Any((string identity) => identity.Contains("jousteronhorse") || identity.Contains("jousterhorse") || identity.Equals("horse", StringComparison.OrdinalIgnoreCase) || identity.EndsWith("horse", StringComparison.OrdinalIgnoreCase)); displayName = (flag ? "Jouster" : "Jouster Rider"); return true; } private static bool TryGetCatapultDisplayName(UnitBlueprint blueprint, string primaryName, out string displayName) { displayName = null; if ((Object)(object)blueprint == (Object)null) { return false; } string[] obj = new string[7] { primaryName, blueprint.Name, ((Object)blueprint).name, null, null, null, null }; DatabaseEntity entity = blueprint.Entity; obj[3] = ((entity != null) ? entity.Name : null); obj[4] = (((Object)(object)blueprint.UnitBase != (Object)null) ? ((Object)blueprint.UnitBase).name : null); DatabaseEntity entity2 = blueprint.Entity; obj[5] = (((Object)(object)((entity2 != null) ? entity2.SpriteIcon : null) != (Object)null) ? ((Object)blueprint.Entity.SpriteIcon).name : null); obj[6] = blueprint.FilePath; string[] source = (from candidate in obj.Where((string candidate) => !string.IsNullOrWhiteSpace(candidate)).Select(Normalize) where !string.IsNullOrWhiteSpace(candidate) select candidate).Distinct<string>(StringComparer.OrdinalIgnoreCase).ToArray(); if (!source.Any((string identity) => identity.Contains("catapult"))) { return false; } bool flag = source.Any((string identity) => identity.Contains("catapultrider")); bool flag2 = source.Any((string identity) => identity.Contains("spookycatapult") || identity.Contains("halloweencatapult") || identity.Contains("pumpkincatapult")) || IsSpookyCatapult(blueprint); displayName = ((!flag2) ? (flag ? "Catapult Rider" : "Catapult") : (flag ? "Pumpkin Catapult Rider" : "Pumpkin Catapult")); return true; } private static bool IsExiledSentinel(UnitBlueprint blueprint, string primaryName) { if ((Object)(object)blueprint == (Object)null) { return false; } string[] obj = new string[6] { primaryName, blueprint.Name, ((Object)blueprint).name, null, null, null }; DatabaseEntity entity = blueprint.Entity; obj[3] = ((entity != null) ? entity.Name : null); DatabaseEntity entity2 = blueprint.Entity; obj[4] = (((Object)(object)((entity2 != null) ? entity2.SpriteIcon : null) != (Object)null) ? ((Object)blueprint.Entity.SpriteIcon).name : null); obj[5] = blueprint.FilePath; string[] source = obj.Select(NormalizeNameAlias).ToArray(); if (source.Any((string identity) => identity.Contains("exiledsentinel"))) { return true; } if (source.Any((string identity) => identity == "eviltank" || identity == "fantasyeviltank")) { return true; } if (source.Any((string identity) => identity == "tank" || (identity.StartsWith("unit", StringComparison.Ordinal) && identity.EndsWith("tank", StringComparison.Ordinal)))) { return IsInFaction(blueprint, (string name) => name.Contains("evil")); } return false; } private static bool IsSpookyCatapult(UnitBlueprint blueprint) { return IsInFaction(blueprint, (string name) => name.Contains("spooky") || name.Contains("halloween")); } private static bool IsInFaction(UnitBlueprint blueprint, Func<string, bool> matchesFaction) { if ((Object)(object)blueprint == (Object)null) { return false; } try { string blueprintKey = GetBlueprintKey(blueprint); foreach (Faction allFaction in ContentDatabase.Instance().GetAllFactions()) { if ((Object)(object)allFaction == (Object)null) { continue; } DatabaseEntity entity = allFaction.Entity; string arg = Normalize(((entity != null) ? entity.Name : null) ?? ((Object)allFaction).name); if (!matchesFaction(arg)) { continue; } UnitBlueprint[] units = allFaction.Units; if (units == null) { continue; } UnitBlueprint[] array = units; foreach (UnitBlueprint val in array) { if (val == blueprint) { return true; } string blueprintKey2 = GetBlueprintKey(val); if (!string.IsNullOrWhiteSpace(blueprintKey) && string.Equals(blueprintKey2, blueprintKey, StringComparison.Ordinal)) { return true; } } } } catch { } return false; } private static string Normalize(string value) { return new string((value ?? string.Empty).Where(char.IsLetterOrDigit).Select(char.ToLowerInvariant).ToArray()); } private static string GetBlueprintKey(UnitBlueprint blueprint) { //IL_001b: Unknown result type (might be due to invalid IL or missing references) if (((blueprint != null) ? blueprint.Entity : null) == null) { return string.Empty; } try { object obj = blueprint.Entity.GUID; int? num = ReadIntMember(obj, "m_modID") ?? ReadIntMember(obj, "modID") ?? ReadIntMember(obj, "ModID"); int? num2 = ReadIntMember(obj, "m_ID") ?? ReadIntMember(obj, "ID") ?? ReadIntMember(obj, "Id"); if (num.HasValue && num2.HasValue) { return $"{num.Value}:{num2.Value}"; } return obj.ToString(); } catch { return string.Empty; } } private static int? ReadIntMember(object source, string name) { if (source == null) { return null; } try { FieldInfo fieldInfo = AccessTools.Field(source.GetType(), name); if (fieldInfo != null) { return Convert.ToInt32(fieldInfo.GetValue(source), CultureInfo.InvariantCulture); } PropertyInfo propertyInfo = AccessTools.Property(source.GetType(), name); if (propertyInfo != null) { return Convert.ToInt32(propertyInfo.GetValue(source, null), CultureInfo.InvariantCulture); } } catch { } return null; } internal static DamageState BeforeDamage(HealthHandler handler, float damage, Unit source) { Unit val = ((handler != null) ? ((Component)handler).GetComponentInParent<Unit>() : null); DamageState result = default(DamageState); if (!_battleActive || (Object)(object)val?.data == (Object)null || float.IsNaN(damage) || float.IsInfinity(damage) || float.IsNaN(val.data.health) || float.IsInfinity(val.data.health) || Mathf.Abs(damage) < 0.001f) { return result; } result.Track = true; result.Healing = damage < 0f; result.Target = val; result.Source = (result.Healing ? ResolveHealer(val, source) : ResolveSource(val, source)); if (!result.Healing && _environmentDepth == 0 && _activeDot != null && _activeDotTarget == ((Object)val).GetInstanceID()) { result.Dot = _activeDot; result.DotWeightTotal = GetDotWeightTotal(_activeDot); } result.Before = Mathf.Max(0f, val.data.health); result.AcceptedDamage = Mathf.Max(0f, damage); return result; } internal static void AfterDamage(DamageState state) { if (!state.Track || (Object)(object)state.Target?.data == (Object)null) { return; } float num = Mathf.Max(0f, state.Target.data.health); if (state.Healing) { float num2 = Mathf.Max(1f, state.Target.data.maxHealth); float num3 = Mathf.Clamp(state.Target.data.health, 0f, num2); float num4 = Mathf.Max(0f, num3 - state.Before); if (num4 <= 0.001f || float.IsNaN(num4) || float.IsInfinity(num4)) { return; } Entry entry = Register(state.Source ?? state.Target); if (entry != null) { entry.Healing += num4; } } else { float num5 = Mathf.Clamp(state.Before - num, 0f, state.Before); num5 = Mathf.Min(num5, state.AcceptedDamage); if (num5 <= 0.001f || float.IsNaN(num5) || float.IsInfinity(num5)) { return; } Entry entry2 = Register(state.Target); if (entry2 != null) { entry2.Taken += num5; } if (state.Dot != null && state.DotWeightTotal > 0.001f) { foreach (KeyValuePair<Entry, float> item in state.Dot.RemainingBySource) { if (item.Key != null && !(item.Value <= 0.001f)) { item.Key.Dealt += num5 * (item.Value / state.DotWeightTotal); } } } else { Entry entry3 = Register(state.Source); if (entry3 != null) { entry3.Dealt += num5; } } } _dirty = true; } internal static DeathState BeforeDeath(HealthHandler handler, Unit supplied) { //IL_0148: Unknown result type (might be due to invalid IL or missing references) //IL_014e: 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_00bd: Unknown result type (might be due to invalid IL or missing references) Unit val = ((handler != null) ? ((Component)handler).GetComponentInParent<Unit>() : null); if (!_battleActive || (Object)(object)val?.data == (Object)null || val.data.Dead) { return default(DeathState); } CountedDeaths.Remove(val); Entry entry = null; Unit val2 = ResolveSource(val, supplied); if ((Object)(object)supplied == (Object)null && _environmentDepth == 0 && _activeDot != null && _activeDotTarget == ((Object)val).GetInstanceID()) { float num = 0.001f; foreach (KeyValuePair<Entry, float> item in _activeDot.RemainingBySource) { Entry key = item.Key; if (key != null && key.Team != val.Team && !(item.Value <= 0.001f) && (item.Value > num || (item.Value == num && entry != null && StringComparer.Ordinal.Compare(key.Key, entry.Key) < 0))) { entry = key; num = item.Value; } } } else if ((Object)(object)val2?.data != (Object)null && (Object)(object)val2 != (Object)(object)val && val2.Team != val.Team) { entry = Register(val2); } return new DeathState { Track = true, Target = val, Victim = Register(val), Killer = entry }; } internal static void AfterDeath(DeathState state) { if (state.Track && !((Object)(object)state.Target?.data == (Object)null) && state.Target.data.Dead && CountedDeaths.Add(state.Target)) { if (state.Victim != null) { state.Victim.Deaths++; } if (state.Killer != null) { state.Killer.Kills++; } _dirty = true; } } private static Unit ResolveSource(Unit target, Unit supplied) { if ((Object)(object)supplied?.data != (Object)null) { if (!((Object)(object)supplied != (Object)(object)target)) { return null; } return supplied; } if (_environmentDepth > 0) { return null; } if ((Object)(object)_effectApplicationSource?.data != (Object)null && (Object)(object)_effectApplicationSource != (Object)(object)target) { return _effectApplicationSource; } if ((Object)(object)_scopedSource?.data != (Object)null && (Object)(object)_scopedSource != (Object)(object)target && (Object)(object)target != (Object)null && _scopedTarget == ((Object)target).GetInstanceID()) { return _scopedSource; } return null; } private static Unit ResolveHealer(Unit target, Unit supplied) { //IL_0068: 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_006d: 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_00c8: 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_0103: Unknown result type (might be due to invalid IL or missing references) //IL_011b: Unknown result type (might be due to invalid IL or missing references) //IL_011c: Unknown result type (might be due to invalid IL or missing references) //IL_0121: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)supplied?.data != (Object)null && (Object)(object)supplied != (Object)(object)target) { return supplied; } if ((Object)(object)target?.data == (Object)null) { return supplied; } Unit val = null; float num = float.PositiveInfinity; Vector3 val2 = (((Object)(object)target.data.mainRig != (Object)null) ? target.data.mainRig.position : ((Component)target).transform.position); foreach (Unit value in Units.Values) { if (!((Object)(object)value?.data == (Object)null) && !((Object)(object)value == (Object)(object)target) && !value.data.Dead && value.Team == target.Team && !((Object)(object)value.data.targetData != (Object)(object)target.data)) { Vector3 val3 = (((Object)(object)value.data.mainRig != (Object)null) ? value.data.mainRig.position : ((Component)value).transform.position) - val2; float sqrMagnitude = ((Vector3)(ref val3)).sqrMagnitude; if (!(sqrMagnitude >= num)) { val = value; num = sqrMagnitude; } } } return val ?? supplied ?? target; } internal static DotState BeginDot(DamageOverTimeEffect effect) { DotState result = new DotState { PreviousScope = SaveScope(), PreviousDot = _activeDot, PreviousDotTarget = _activeDotTarget }; _activeDot = null; _activeDotTarget = 0; if (!_battleActive || (Object)(object)effect == (Object)null) { return result; } Unit componentInParent = ((Component)effect).GetComponentInParent<Unit>(); Unit val = ResolveDotSource(effect); DotAttribution orCreateDotAttribution = GetOrCreateDotAttribution(effect); SynchronizeDotAttribution(orCreateDotAttribution, effect, val); SetScope(val, componentInParent); if ((Object)(object)componentInParent?.data != (Object)null && orCreateDotAttribution != null) { _activeDot = orCreateDotAttribution; _activeDotTarget = ((Object)componentInParent).GetInstanceID(); result.ActiveDot = orCreateDotAttribution; result.RawDamageBefore = ReadDotFloat(DotDamageDealtSinceLastStack, effect); } return result; } internal static void EndDot(DotState state) { if ((Object)(object)state.ActiveDot?.Effect != (Object)null) { float num = ReadDotFloat(DotDamageDealtSinceLastStack, state.ActiveDot.Effect) - state.RawDamageBefore; if (num > 0.0001f) { ConsumeDotWeights(state.ActiveDot, num); } SynchronizeDotAttribution(state.ActiveDot, state.ActiveDot.Effect, ResolveDotSource(state.ActiveDot.Effect)); } _activeDot = state.PreviousDot; _activeDotTarget = state.PreviousDotTarget; RestoreScope(state.PreviousScope); } internal static void RecordDotPing(DamageOverTimeEffect effect) { if (_battleActive && !((Object)(object)effect == (Object)null)) { DotAttribution orCreateDotAttribution = GetOrCreateDotAttribution(effect); Unit unit = _effectApplicationSource ?? ResolveDotSource(effect); SynchronizeDotAttribution(orCreateDotAttribution, effect, ResolveDotSource(effect)); Entry entry = Register(unit); float num = Mathf.Max(0f, effect.damagePerStack); if (entry != null && !(num <= 0.0001f)) { orCreateDotAttribution.RemainingBySource.TryGetValue(entry, out var value); orCreateDotAttribution.RemainingBySource[entry] = value + num; } } } internal static EffectApplicationState BeginEffectApplication(Component sourceComponent) { EffectApplicationState result = new EffectApplicationState { PreviousSource = _effectApplicationSource }; if (_battleActive) { _effectApplicationSource = ResolveSpawnerUnit(sourceComponent) ?? result.PreviousSource; } return result; } internal static EffectApplicationState BeginEffectApplication(Unit source) { EffectApplicationState result = new EffectApplicationState { PreviousSource = _effectApplicationSource }; if (_battleActive) { _effectApplicationSource = (((Object)(object)source?.data != (Object)null) ? source : result.PreviousSource); } return result; } internal static EffectApplicationState BeginCollisionEffectApplication(CollisionWeapon weapon) { FixCollisionOwner(weapon); object? obj = CollisionOwner?.GetValue(weapon); return BeginEffectApplication((Unit)(((obj is Unit) ? obj : null) ?? ResolveSpawnerUnit((Component)(object)weapon))); } internal static void EndEffectApplication(EffectApplicationState state) { _effectApplicationSource = state.PreviousSource; } private static Unit ResolveSpawnerUnit(Component component) { if ((Object)(object)component == (Object)null) { return null; } TeamHolder val = component.GetComponent<TeamHolder>() ?? component.GetComponentInParent<TeamHolder>(); Unit val2 = (((Object)(object)val?.spawner != (Object)null) ? (val.spawner.GetComponentInParent<Unit>() ?? val.spawner.GetComponentInChildren<Unit>()) : null); if ((Object)(object)val2 == (Object)null && (Object)(object)val?.spawnerWeapon != (Object)null) { val2 = val.spawnerWeapon.GetComponentInParent<Unit>(); } if (!((Object)(object)val2?.data != (Object)null)) { return null; } return val2; } private static Unit ResolveDotSource(DamageOverTimeEffect effect) { TeamHolder val = (((Object)(object)effect != (Object)null) ? ((Component)effect).GetComponent<TeamHolder>() : null); Unit val2 = (((Object)(object)val?.spawner != (Object)null) ? (val.spawner.GetComponentInParent<Unit>() ?? val.spawner.GetComponentInChildren<Unit>()) : null); if (!((Object)(object)val2?.data != (Object)null)) { return null; } return val2; } private static DotAttribution GetOrCreateDotAttribution(DamageOverTimeEffect effect) { if ((Object)(object)effect == (Object)null) { return null; } int instanceID = ((Object)effect).GetInstanceID(); if (DotAttributions.TryGetValue(instanceID, out var value) && value.Effect == effect) { return value; } DotAttribution dotAttribution = new DotAttribution { Effect = effect }; DotAttributions[instanceID] = dotAttribution; return dotAttribution; } private static float GetDotWeightTotal(DotAttribution dot) { if (dot == null) { return 0f; } float num = 0f; foreach (float value in dot.RemainingBySource.Values) { num += Mathf.Max(0f, value); } return num; } private static float ReadDotFloat(FieldInfo field, DamageOverTimeEffect effect) { if (field == null || (Object)(object)effect == (Object)null) { return 0f; } try { object value = field.GetValue(effect); return (value != null) ? Convert.ToSingle(value, CultureInfo.InvariantCulture) : 0f; } catch { return 0f; } } private static void SynchronizeDotAttribution(DotAttribution dot, DamageOverTimeEffect effect, Unit fallbackSource) { if (dot == null || (Object)(object)effect == (Object)null) { return; } float num = Mathf.Max(0f, ReadDotFloat(DotDamageToDo, effect) - ReadDotFloat(DotDamageDealtSinceLastStack, effect)); float dotWeightTotal = GetDotWeightTotal(dot); if (dotWeightTotal <= 0.0001f) { dot.RemainingBySource.Clear(); Entry entry = Register(fallbackSource); if (entry != null && num > 0.0001f) { dot.RemainingBySource[entry] = num; } return; } if (num <= 0.0001f) { dot.RemainingBySource.Clear(); return; } float num2 = num / dotWeightTotal; if (Mathf.Abs(num2 - 1f) <= 0.0001f) { return; } foreach (Entry item in dot.RemainingBySource.Keys.ToList()) { dot.RemainingBySource[item] = Mathf.Max(0f, dot.RemainingBySource[item] * num2); } } private static void ConsumeDotWeights(DotAttribution dot, float rawConsumed) { float dotWeightTotal = GetDotWeightTotal(dot); if (dotWeightTotal <= 0.0001f) { return; } float num = Mathf.Clamp01((dotWeightTotal - Mathf.Max(0f, rawConsumed)) / dotWeightTotal); foreach (Entry item in dot.RemainingBySource.Keys.ToList()) { float num2 = dot.RemainingBySource[item] * num; if (num2 <= 0.0001f) { dot.RemainingBySource.Remove(item); } else { dot.RemainingBySource[item] = num2; } } } internal static SourceState BeginVampire(VapireBite bite) { SourceState result = SaveScope(); if (!_battleActive || (Object)(object)bite == (Object)null) { return result; } Unit source = ((Component)bite).GetComponentInParent<Unit>() ?? ((Component)((Component)bite).transform.root).GetComponentInChildren<Unit>(); object? obj = VampireTarget?.GetValue(bite); DataHandler val = (DataHandler)((obj is DataHandler) ? obj : null); SetScope(source, val?.unit ?? ((val != null) ? ((Component)val).GetComponentInParent<Unit>() : null)); return result; } private static SourceState SaveScope() { return new SourceState { PreviousSource = _scopedSource, PreviousTarget = _scopedTarget }; } private static void SetScope(Unit source, Unit target) { _scopedSource = (((Object)(object)source?.data != (Object)null && (Object)(object)target?.data != (Object)null && (Object)(object)source != (Object)(object)target) ? source : null); _scopedTarget = (((Object)(object)_scopedSource != (Object)null) ? ((Object)target).GetInstanceID() : 0); } internal static void RestoreScope(SourceState state) { _scopedSource = state.PreviousSource; _scopedTarget = state.PreviousTarget; } internal static void BeginEnvironment() { _environmentDepth++; } internal static void EndEnvironment() { _environmentDepth = Mathf.Max(0, _environmentDepth - 1); } internal static void FixSwordOwner(SpookySwords caster, SpookySword sword) { //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) Unit val = ((caster != null) ? ((Component)caster).GetComponentInParent<Unit>() : null) ?? ((caster != null) ? ((Component)((Component)caster).transform.root).GetComponentInChildren<Unit>() : null); if (!((Object)(object)val?.data == (Object)null) && !((Object)(object)sword?.gameObject == (Object)null)) { TeamHolder obj = sword.gameObject.GetComponent<TeamHolder>() ?? sword.gameObject.AddComponent<TeamHolder>(); obj.team = val.Team; obj.spawner = ((Component)val).gameObject; if (_battleActive) { Register(val); } } } internal static void FixCollisionOwner(CollisionWeapon weapon) { if (!_battleActive || (Object)(object)weapon == (Object)null || CollisionOwner == null) { return; } Unit val = ((Component)weapon).GetComponentInParent<Unit>(); if ((Object)(object)val == (Object)null) { object? obj = CollisionData?.GetValue(weapon); DataHandler val2 = (DataHandler)((obj is DataHandler) ? obj : null); if (val2 != null) { val = val2.unit; } } object? obj2 = CollisionTeamHolder?.GetValue(weapon); TeamHolder val3 = (TeamHolder)(((obj2 is TeamHolder) ? obj2 : null) ?? ((Component)weapon).GetComponent<TeamHolder>() ?? ((Component)weapon).GetComponentInParent<TeamHolder>()); if ((Object)(object)val == (Object)null) { object obj3; if (val3 == null) { obj3 = null; } else { GameObject spawner = val3.spawner; obj3 = ((spawner != null) ? spawner.GetComponentInParent<Unit>() : null); } val = (Unit)obj3; } if (!((Object)(object)val?.data == (Object)null)) { if (CollisionOwner.GetValue(weapon) != val) { CollisionOwner.SetValue(weapon, val); } Register(val); } } internal static void Unregister(Unit unit) { if (!((Object)(object)unit == (Object)null)) { int instanceID = ((Object)unit).GetInstanceID(); Units.Remove(instanceID); EntryByUnit.Remove(instanceID); } } private static void ClearEntries() { Entries.Clear(); EntryByUnit.Clear(); Units.Clear(); DotAttributions.Clear(); CountedDeaths.Clear(); _scopedSource = null; _scopedTarget = 0; _activeDot = null; _activeDotTarget = 0; _effectApplicationSource = null; _environmentDepth = 0; _registeringRoster = false; VisibleEntries.Clear(); VisibleKeys.Clear(); foreach (RowView value in RowViews.Values) { if ((Object)(object)value?.Root != (Object)null) { Object.Destroy((Object)(object)value.Root); } } RowViews.Clear(); _scrollPosition = 0f; _scrollTarget = 0f; _scrollVelocity = 0f; _scrollAnimationActive = false; _resetScroll = true; _dirty = true; } private static void EnsurePanel() { //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Expected O, but got Unknown //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_00d2: 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_0110: Unknown result type (might be due to invalid IL or missing references) //IL_015f: Unknown result type (might be due to invalid IL or missing references) //IL_0169: Expected O, but got Unknown //IL_01cf: Unknown result type (might be due to invalid IL or missing references) //IL_01d4: Unknown result type (might be due to invalid IL or missing references) //IL_01ea: Unknown result type (might be due to invalid IL or missing references) //IL_01ff: Unknown result type (might be due to invalid IL or missing references) //IL_0223: 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_02c1: Unknown result type (might be due to invalid IL or missing references) //IL_02c6: Unknown result type (might be due to invalid IL or missing references) //IL_02d7: Unknown result type (might be due to invalid IL or missing references) //IL_02fc: Unknown result type (might be due to invalid IL or missing references) //IL_0323: Unknown result type (might be due to invalid IL or missing references) //IL_037d: Unknown result type (might be due to invalid IL or missing references) //IL_0382: Unknown result type (might be due to invalid IL or missing references) //IL_0393: Unknown result type (might be due to invalid IL or missing references) //IL_03b8: Unknown result type (might be due to invalid IL or missing references) //IL_03ff: Unknown result type (might be due to invalid IL or missing references) //IL_042d: Unknown result type (might be due to invalid IL or missing references) //IL_045b: Unknown result type (might be due to invalid IL or missing references) //IL_05b7: Unknown result type (might be due to invalid IL or missing references) //IL_05bc: Unknown result type (might be due to invalid IL or missing references) //IL_060d: Unknown result type (might be due to invalid IL or missing references) //IL_0612: Unknown result type (might be due to invalid IL or missing references) //IL_063c: Unknown result type (might be due to invalid IL or missing references) //IL_0655: Unknown result type (might be due to invalid IL or missing references) //IL_066e: Unknown result type (might be due to invalid IL or missing references) //IL_067d: Unknown result type (might be due to invalid IL or missing references) //IL_068c: Unknown result type (might be due to invalid IL or missing references) //IL_06c1: Unknown result type (might be due to invalid IL or missing references) //IL_06da: Unknown result type (might be due to invalid IL or missing references) //IL_06ee: Unknown result type (might be due to invalid IL or missing references) //IL_070c: Unknown result type (might be due to invalid IL or missing references) //IL_072a: Unknown result type (might be due to invalid IL or missing references) //IL_075f: Unknown result type (might be due to invalid IL or missing references) //IL_07c3: Unknown result type (might be due to invalid IL or missing references) //IL_07d2: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)_canvas != (Object)null) && ShouldShow()) { _canvas = new GameObject("Sandbox Combat Stats Canvas", new Type[3] { typeof(RectTransform), typeof(Canvas), typeof(CanvasScaler) }); Object.DontDestroyOnLoad((Object)(object)_canvas); Canvas component = _canvas.GetComponent<Canvas>(); component.renderMode = (RenderMode)0; component.sortingOrder = 30001; ConfigureScaler(_canvas.GetComponent<CanvasScaler>()); GameObject val = new GameObject("Panel", new Type[3] { typeof(RectTransform), typeof(CanvasRenderer), typeof(Image) }); val.transform.SetParent(_canvas.transform, false); _panel = val.GetComponent<RectTransform>(); _panel.sizeDelta = new Vector2(286f, 462f); Image component2 = val.GetComponent<Image>(); ((Graphic)component2).color = new Color(0.035f, 0.045f, 0.065f, 0.68f); ((Graphic)component2).raycastTarget = false; _inputBlockerCanvas = new GameObject("Sandbox Combat Stats Input Blocker Canvas", new Type[4] { typeof(RectTransform), typeof(Canvas), typeof(CanvasScaler), typeof(GraphicRaycaster) }); Object.DontDestroyOnLoad((Object)(object)_inputBlockerCanvas); Canvas component3 = _inputBlockerCanvas.GetComponent<Canvas>(); component3.renderMode = (RenderMode)0; component3.sortingOrder = 30002; ConfigureScaler(_inputBlockerCanvas.GetComponent<CanvasScaler>()); GameObject val2 = new GameObject("Combat Stats Input Blocker", new Type[3] { typeof(RectTransform), typeof(CanvasRenderer), typeof(Image) }); val2.transform.SetParent(_inputBlockerCanvas.transform, false); _inputBlocker = val2.GetComponent<RectTransform>(); _inputBlocker.sizeDelta = _panel.sizeDelta; Image component4 = val2.GetComponent<Image>(); ((Graphic)component4).color = new Color(0f, 0f, 0f, 0.001f); ((Graphic)component4).raycastTarget = true; ApplyPanelPlacement(force: true); GameObject val3 = new GameObject("Window Drag Handle", new Type[1] { typeof(RectTransform) }); val3.transform.SetParent((Transform)(object)_panel, false); _dragHandle = val3.GetComponent<RectTransform>(); Place(_dragHandle, 0f, 0f, 286f, 28f); GameObject val4 = new GameObject("Top Drag Accent", new Type[3] { typeof(RectTransform), typeof(CanvasRenderer), typeof(Image) }); val4.transform.SetParent((Transform)(object)_panel, false); Place(val4.GetComponent<RectTransform>(), 0f, 0f, 286f, 6f); Image component5 = val4.GetComponent<Image>(); ((Graphic)component5).color = Gold; ((Graphic)component5).raycastTarget = false; Place(((TMP_Text)CreateText((Transform)(object)_panel, "Title", "COMBAT STATS", 19, (FontStyles)1, (TextAlignmentOptions)514, Color.white)).rectTransform, 12f, 8f, 262f, 28f); GameObject val5 = new GameObject("Header Accent", new Type[3] { typeof(RectTransform), typeof(CanvasRenderer), typeof(Image) }); val5.transform.SetParent((Transform)(object)_panel, false); Place(val5.GetComponent<RectTransform>(), 12f, 38f, 262f, 2f); Image component6 = val5.GetComponent<Image>(); ((Graphic)component6).color = Gold; ((Graphic)component6).raycastTarget = false; float num = 102f; float x = num + 82f + 8f; _redSummary = CreateSummaryCell(_panel, "Red Team Total", "RED 0", 12f, 44f, 82f, 23f, Red); _metricSummary = CreateSummaryCell(_panel, "Metric Total Label", "DEALT", num, 44f, 82f, 23f, Color.white); _blueSummary = CreateSummaryCell(_panel, "Blue Team Total", "BLUE 0", x, 44f, 82f, 23f, Blue); _dealtButton = CreateButton(_panel, "Damage Dealt", "DMG DEALT", 12f, 71f, 82f, 30f); _takenButton = CreateButton(_panel, "Damage Taken", "DMG TAKEN", num, 71f, 82f, 30f); _healingButton = CreateButton(_panel, "Healing", "HEALING", x, 71f, 82f, 30f); CreateShortcutBadge(_dealtButton, "Damage Dealt Shortcut", "Q", right: false); CreateShortcutBadge(_healingButton, "Healing Shortcut", "E", right: true); _allButton = CreateButton(_panel, "All Teams", "ALL", 12f, 107f, 82f, 27f); _redButton = CreateButton(_panel, "Red Team", "RED", num, 107f, 82f, 27f); _blueButton = CreateButton(_panel, "Blue Team", "BLUE", x, 107f, 82f, 27f); GameObject val6 = new GameObject("Rows Viewport", new Type[2] { typeof(RectTransform), typeof(RectMask2D) }); val6.transform.SetParent((Transform)(object)_panel, false); _viewport = val6.GetComponent<RectTransform>(); Place(_viewport, 10f, 144f, 266f, 274f); GameObject val7 = new GameObject("Content", new Type[1] { typeof(RectTransform) }); val7.transform.SetParent((Transform)(object)_viewport, false); _content = val7.GetComponent<RectTransform>(); _content.anchorMin = new Vector2(0f, 1f); _content.anchorMax = new Vector2(1f, 1f); _content.pivot = new Vector2(0.5f, 1f); _content.anchoredPosition = Vector2.zero; _content.sizeDelta = Vector2.zero; _empty = CreateText((Transform)(object)_viewport, "Empty State", "START A BATTLE\nTO TRACK COMBAT", 15, (FontStyles)1, (TextAlignmentOptions)514, new Color(0.64f, 0.68f, 0.75f, 1f)); ((TMP_Text)_empty).rectTransform.anchorMin = Vector2.zero; ((TMP_Text)_empty).rectTransform.anchorMax = Vector2.one; ((TMP_Text)_empty).rectTransform.offsetMin = new Vector2(8f, 8f); ((TMP_Text)_empty).rectTransform.offsetMax = new Vector2(-8f, -8f); _hideHint = CreateText((Transform)(object)_panel, "Hide Hint", string.Empty, 13, (FontStyles)1, (TextAlignmentOptions)514, new Color(0.82f, 0.85f, 0.9f, 1f)); Place(((TMP_Text)_hideHint).rectTransform, 10f, 430f, 266f, 23f); ((TMP_Text)_hideHint).text = "Press (" + FormatToggleKey((KeyCode)(((??)Instance?._toggleKey?.Value) ?? 103)) + ") to hide"; RefreshButtonColors(); _dirty = true; _nextRefresh = 0f; _resetScroll = true; } } private static void ConfigureScaler(CanvasScaler scaler) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) scaler.uiScaleMode = (ScaleMode)1; scaler.referenceResolution = new Vector2(1920f, 1080f); scaler.screenMatchMode = (ScreenMatchMode)0; scaler.matchWidthOrHeight = 0.5f; } private static void DestroyPanel() { //IL_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_0100: Unknown result type (might be due to invalid IL or missing references) RestoreOverlappedVanillaHud(); if ((Object)(object)_canvas != (Object)null) { Object.Destroy((Object)(object)_canvas); } if ((Object)(object)_inputBlockerCanvas != (Object)null) { Object.Destroy((Object)(object)_inputBlockerCanvas); } _canvas = null; _inputBlockerCanvas = null; _inputBlocker = null; _panel = null; _dragHandle = null; _viewport = null; _content = null; _redSummary = null; _metricSummary = null; _blueSummary = null; _empty = null; _hideHint = null; _dealtButton = null; _takenButton = null; _healingButton = null; _allButton = null; _redButton = null; _blueButton = null; RowViews.Clear(); VisibleEntries.Clear(); VisibleKeys.Clear(); _scrollPosition = 0f; _scrollTarget = 0f; _scrollVelocity = 0f; _visibleMaximum = 1f; _scrollAnimationActive = false; _draggingPanel = false; _lastPanelParentSize = new Vector2(-1f, -1f); } private static void MaintainOverlappedVanillaHudSuppression() { try { if (Time.unscaledTime >= _nextHudSuppressionDiscovery) { _nextHudSuppressionDiscovery = Time.unscaledTime + 0.5f; if ((Object)(object)_suppressedHudPlacementUi == (Object)null) { _suppressedHudPlacementUi = Object.FindObjectOfType<PlacementUI>(); } } ResolveOverlappedVanillaHudTargets(_suppressedHudPlacementUi); EnforceSuppression(_battleNameSuppression); EnforceSuppression(_mapButtonSuppression); EnforceSuppression(_objectiveSuppression); } catch { } } private static void ResolveOverlappedVanillaHudTargets(PlacementUI placementUi) { if ((Object)(object)placementUi == (Object)null) { return; } object obj = PlacementSceneDescriptionField?.GetValue(placementUi); GameObject val = null; GameObject val2 = null; if (obj != null) { Type type = obj.GetType(); if ((object)_sceneDescriptionTextField == null) { _sceneDescriptionTextField = AccessTools.Field(type, "m_descriptionText"); } if ((object)_sceneDescriptionMapButtonField == null) { _sceneDescriptionMapButtonField = AccessTools.Field(type, "m_mapSelectionButton"); } object? obj2 = _sceneDescriptionTextField?.GetValue(obj); object? obj3 = ((obj2 is Component) ? obj2 : null); val = ((obj3 != null) ? ((Component)obj3).gameObject : null); object? obj4 = _sceneDescriptionMapButtonField?.GetValue(obj); object? obj5 = ((obj4 is Component) ? obj4 : null); val2 = ((obj5 != null) ? ((Component)obj5).gameObject : null); } if (val2 == null) { object? obj6 = PlacementMapButtonField?.GetValue(placementUi); object? obj7 = ((obj6 is Component) ? obj6 : null); val2 = ((obj7 != null) ? ((Component)obj7).gameObject : null); } object obj8 = PlacementWinConditionPresenterField?.GetValue(placementUi); GameObject val3 = null; if (obj8 != null) { if ((object)_blueWinConditionsField == null) { _blueWinConditionsField = AccessTools.Field(obj8.GetType(), "m_blueWinConditions"); } object? obj9 = _blueWinConditionsField?.GetValue(obj8); object? obj10 = ((obj9 is Transform) ? obj9 : null); val3 = ((obj10 != null) ? ((Component)obj10).gameObject : null); } BindSuppression(ref _battleNameSuppression, IsOverlappedByPanel(val) ? val : null); BindSuppression(ref _mapButtonSuppression, IsOverlappedByPanel(val2) ? val2 : null); BindSuppression(ref _objectiveSuppression, IsOverlappedByPanel(val3) ? val3 : null); } private static bool IsOverlappedByPanel(GameObject target) { //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_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_0059: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)_panel == (Object)null) && !((Object)(object)target == (Object)null)) { Transform transform = target.transform; RectTransform val = (RectTransform)(object)((transform is RectTransform) ? transform : null); if (val != null) { _panel.GetWorldCorners(PanelScreenCorners); val.GetWorldCorners(HudScreenCorners); Rect val2 = ScreenRectFromWorldCorners(PanelScreenCorners); Rect val3 = ScreenRectFromWorldCorners(HudScreenCorners); return ((Rect)(ref val2)).Overlaps(val3, true); } } return false; } private static Rect ScreenRectFromWorldCorners(Vector3[] corners) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_004c: 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_0068: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) Vector2 val = RectTransformUtility.WorldToScreenPoint((Camera)null, corners[0]); float num = val.x; float num2 = val.x; float num3 = val.y; float num4 = val.y; for (int i = 1; i < 4; i++) { Vector2 val2 = RectTransformUtility.WorldToScreenPoint((Camera)null, corners[i]); num = Mathf.Min(num, val2.x); num2 = Mathf.Max(num2, val2.x); num3 = Mathf.Min(num3, val2.y); num4 = Mathf.Max(num4, val2.y); } return Rect.MinMaxRect(num, num3, num2, num4); } private static void BindSuppression(ref CanvasGroup suppression, GameObject target) { if ((Object)(object)target == (Object)null) { ReleaseSuppression(ref suppression); } else if (!((Object)(object)suppression != (Object)null) || !((Object)(object)((Component)suppression).gameObject == (Object)(object)target)) { ReleaseSuppression(ref suppression); suppression = target.AddComponent<CanvasGroup>(); EnforceSuppression(suppression); } } private static void EnforceSuppression(CanvasGroup suppression) { if (!((Object)(object)suppression == (Object)null)) { if (suppression.alpha != 0f) { suppression.alpha = 0f; } if (suppression.interactable) { suppression.interactable = false; } if (suppression.blocksRaycasts) { suppression.blocksRaycasts = false; } } } private static void RestoreOverlappedVanillaHud() { ReleaseSuppression(ref _battleNameSuppression); ReleaseSuppression(ref _mapButtonSuppression); ReleaseSuppression(ref _objectiveSuppression); _suppressedHudPlacementUi = null; _nextHudSuppressionDiscovery = 0f; } private static void ReleaseSuppression(ref CanvasGroup suppression) { if ((Object)(object)suppression == (Object)null) { suppression = null; return; } suppression.alpha = 1f; suppression.interactable = true; suppression.blocksRaycasts = true; Object.Destroy((Object)(object)suppression); suppression = null; } private static void ApplyPanelPlacement(bool force = false) { //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_006f: 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_0095: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_009e: 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_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: 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_00d7: 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_00e7: 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_0052: 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_01bc: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_panel == (Object)null) { return; } Transform parent = ((Transform)_panel).parent; RectTransform val = (RectTransform)(object)((parent is RectTransform) ? parent : null); if ((Object)(object)val == (Object)null) { return; } if (force) { Canvas.ForceUpdateCanvases(); } Rect rect = val.rect; Vector2 size = ((Rect)(ref rect)).size; bool flag = IsArenaRoguelikeActive(); if (force || _panelUsesArenaLayout != flag || !(Vector2.SqrMagnitude(size - _lastPanelParentSize) <= 0.01f)) { _panelUsesArenaLayout = flag; _lastPanelParentSize = size; RectTransform panel = _panel; RectTransform panel2 = _panel; RectTransform panel3 = _panel; Vector2 val2 = default(Vector2); ((Vector2)(ref val2))..ctor(0f, 1f); panel3.pivot = val2; Vector2 anchorMin = (panel2.anchorMax = val2); panel.anchorMin = anchorMin; float x = size.x; rect = _panel.rect; float num = Mathf.Max(0f, x - ((Rect)(ref rect)).width); float y = size.y; rect = _panel.rect; float num2 = Mathf.Max(0f, y - ((Rect)(ref rect)).height); Vector2 panelPosition = default(Vector2); if (Instance?._windowPositionX != null && Instance?._windowPositionY != null && Instance._windowPositionX.Value >= 0f && Instance._windowPositionY.Value >= 0f) { ((Vector2)(ref panelPosition))..ctor(Mathf.Clamp01(Instance._windowPositionX.Value) * num, (0f - Mathf.Clamp01(Instance._windowPositionY.Value)) * num2); } else { float num3 = (flag ? 18f : 4f); float num4 = (flag ? (num2 * 0.5f) : 4f); ((Vector2)(ref panelPosition))..ctor(num - num3, 0f - num4); } SetPanelPosition(panelPosition); } } private static void HandlePanelDrag() { //IL_004e: 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_006d: 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_0076: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: 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_00c6: 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_0089: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_panel == (Object)null || (Object)(object)_dragHandle == (Object)null) { return; } Transform parent = ((Transform)_panel).parent; RectTransform val = (RectTransform)(object)((parent is RectTransform) ? parent : null); if ((Object)(object)val == (Object)null || !Cursor.visible) { if (_draggingPanel) { _draggingPanel = false; SavePanelPosition(); } return; } Vector2 val2 = Vector2.op_Implicit(Input.mousePosition); if (!_draggingPanel && Input.GetMouseButtonDown(0) && PointerOver(_dragHandle, val2) && RectTransformUtility.ScreenPointToLocalPointInRectangle(val, val2, (Camera)null, ref _dragStartPointerLocal)) { _dragStartPanelPosition = _panel.anchoredPosition; _draggingPanel = true; _primaryPressConsumed = true; } if (_draggingPanel) { Vector2 val3 = default(Vector2); if (Input.GetMouseButton(0) && RectTransformUtility.ScreenPointToLocalPointInRectangle(val, val2, (Camera)null, ref val3)) { SetPanelPosition(_dragStartPanelPosition + val3 - _dragStartPointerLocal); } if (Input.GetMouseButtonUp(0)) { _draggingPanel = false; SavePanelPosition(); } } } private static void SetPanelPosition(Vector2 position) { //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_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_0065: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_007e: 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_00a1: 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_00d6: 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_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_0112: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_panel == (Object)null) { return; } Transform parent = ((Transform)_panel).parent; RectTransform val = (RectTransform)(object)((parent is RectTransform) ? parent : null); if (val != null) { Rect rect = val.rect; float width = ((Rect)(ref rect)).width; rect = _panel.rect; float num = Mathf.Max(0f, width - ((Rect)(ref rect)).width); rect = val.rect; float height = ((Rect)(ref rect)).height; rect = _panel.rect; float num2 = Mathf.Max(0f, height - ((Rect)(ref rect)).height); _panel.anchoredPosition = new Vector2(Mathf.Clamp(position.x, 0f, num), Mathf.Clamp(position.y, 0f - num2, 0f)); if ((Object)(object)_inputBlocker != (Object)null) { _inputBlocker.anchorMin = _panel.anchorMin; _inputBlocker.anchorMax = _panel.anchorMax; _inputBlocker.pivot = _panel.pivot; _inputBlocker.anchoredPosition = _panel.anchoredPosition; _inputBlocker.sizeDelta = _panel.sizeDelta; } } } private static void SavePanelPosition() { //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_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_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_0084: 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) //IL_00b6: 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) if (!((Object)(object)_panel == (Object)null)) { Transform parent = ((Transform)_panel).parent; RectTransform val = (RectTransform)(object)((parent is RectTransform) ? parent : null); if (val != null && Instance?._windowPositionX != null && Instance._windowPositionY != null) { Rect rect = val.rect; float width = ((Rect)(ref rect)).width; rect = _panel.rect; float num = Mathf.Max(0f, width - ((Rect)(ref rect)).width); rect = val.rect; float height = ((Rect)(ref rect)).height; rect = _panel.rect; float num2 = Mathf.Max(0f, height - ((Rect)(ref rect)).height); Instance._windowPositionX.Value = ((num > 0.01f) ? Mathf.Clamp01(_panel.anchoredPosition.x / num) : 0f); Instance._windowPositionY.Value = ((num2 > 0.01f) ? Mathf.Clamp01((0f - _panel.anchoredPosition.y) / num2) : 0f); ((BaseUnityPlugin)Instance).Config.Save(); } } } private static void ResolveArenaIntegration() { if (!_arenaIntegrationResolved) { _arenaIntegrationResolved = true; Type type = AccessTools.TypeByName("Tabs.PersistentHealth.Mod.Plugin"); if (!(type == null)) { _arenaModeActiveField = AccessTools.Field(type, "ArenaModeActive"); _arenaModeActiveProperty = AccessTools.Property(type, "ArenaModeActive"); _arenaDisplayNameMethod = AccessTools.Method(type, "GetArenaArmyUnitDisplayName", new Type[1] { typeof(UnitBlueprint) }, (Type[])null); } } } private static bool IsArenaRoguelikeActive() { try { ResolveArenaIntegration(); if (_arenaModeActiveField?.GetValue(null) is bool result) { return result; } object obj = _arenaModeActiveProperty?.GetValue(null, null); bool flag = default(bool); int num; if (obj is bool) { flag = (bool)obj; num = 1; } else { num = 0; } return (byte)((uint)num & (flag ? 1u : 0u)) != 0; } catch { return false; } } private static void RequestUnitIcon(UnitBlueprint blueprint, Image target) { if (((blueprint != null) ? blueprint.Entity : null) == null || (Object)(object)target == (Object)null) { return; } Sprite spriteIcon = blueprint.Entity.SpriteIcon; if ((Object)(object)spriteIcon != (Object)null) { target.sprite = spriteIcon; } try { MethodInfo methodInfo = ((object)blueprint.Entity).GetType().GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).FirstOrDefault((MethodInfo candidate) => candidate.Name == "GetSpriteIconAsync" && candidate.GetParameters().Length == 1); if (methodInfo == null) { return; } Action<Sprite> action = delegate(Sprite sprite) { if ((Object)(object)target != (Object)null && (Object)(object)sprite != (Object)null) { target.sprite = sprite; } }; Type parameterType = methodInfo.GetParameters()[0].ParameterType; object obj = (parameterType.IsInstanceOfType(action) ? action : Delegate.CreateDelegate(parameterType, action.Target, action.Method)); methodInfo.Invoke(blueprint.Entity, new object[1] { obj }); } catch (Exception ex) { Plugin instance = Instance; if (instance != null) { ((BaseUnityPlugin)instance).Logger.LogWarning((object)("Could not load combat-stats icon for " + DisplayName(blueprint) + ": " + ex.Message)); } } } private static TextMeshProUGUI CreateText(Transform parent, string objectName, string value, int fontSize, FontStyles style, TextAlignmentOptions alignment, Color color) { //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_0055: 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_0065: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject(objectName, new Type[3] { typeof(RectTransform), typeof(CanvasRenderer), typeof(TextMeshProUGUI) }); val.transform.SetParent(parent, false); TextMeshProUGUI component = val.GetComponent<TextMeshProUGUI>(); ((TMP_Text)component).text = value; ((TMP_Text)component).fontSize = fontSize; ((TMP_Text)component).fontStyle = style; ((TMP_Text)component).alignment = alignment; ((Graphic)component).color = color; ((TMP_Text)component).enableWordWrapping = false; ((TMP_Text)component).overflowMode = (TextOverflowModes)1; ((Graphic)component).raycastTarget = false; return component; } private static RectTransform CreateButton(RectTransform parent, string objectName, string label, float x, float y, float width, float height) { //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_0040: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: 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_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject(objectName, new Type[3] { typeof(RectTransform), typeof(CanvasRenderer), typeof(Image) }); val.transform.SetParent((Transform)(object)parent, false); RectTransform component = val.GetComponent<RectTransform>(); Place(component, x, y, width, height); Image component2 = val.GetComponent<Image>(); ((Graphic)component2).color = new Color(0.1f, 0.12f, 0.17f, 0.78f); ((Graphic)component2).raycastTarget = false; int fontSize = ((width <= 86f && label.Length > 8) ? 10 : 12); TextMeshProUGUI obj = CreateText((Transform)(object)component, "Label", label, fontSize, (FontStyles)1, (TextAlignmentOptions)514, Color.white); ((TMP_Text)obj).rectTransform.anchorMin = Vector2.zero; ((TMP_Text)obj).rectTransform.anchorMax = Vector2.one; ((TMP_Text)obj).rectTransform.offsetMin = Vector2.zero; ((TMP_Text)obj).rectTransform.offsetMax = Vector2.zero; return component; } private static TextMeshProUGUI CreateSummaryCell(RectTransform parent, string objectName, string label, float x, float y, float width, float height, Color textColor) { //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_0040: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_008d: 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_00aa: 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_00ca: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject(objectName, new Type[3] { typeof(RectTransform), typeof(CanvasRenderer), typeof(Image) }); val.transform.SetParent((Transform)(object)parent, false); RectTransform component = val.GetComponent<RectTransform>(); Place(component, x, y, width, height); Image component2 = val.GetComponent<Image>(); ((Graphic)component2).color = new Color(0.025f, 0.03f, 0.045f, 0.92f); ((Graphic)component2).raycastTarget = false; TextMeshProUGUI obj = CreateText((Transform)(object)component, "Label", label, 13, (FontStyles)1, (TextAlignmentOptions)514, textColor); ((TMP_Text)obj).rectTransform.anchorMin = Vector2.zero; ((TMP_Text)obj).rectTransform.anchorMax = Vector2.one; ((TMP_Text)obj).rectTransform.offsetMin = Vector2.zero; ((TMP_Text)obj).rectTransform.offsetMax = Vector2.zero; return obj; } private static void CreateShortcutBadge(RectTransform parent, string objectName, string label, bool right) { //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Expected O, but got Unknown //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_007b: 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_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00df: 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_010d: Unknown result type (might be due to invalid IL or missing references) //IL_011d: Unknown result type (might be due to invalid IL or missing references) //IL_012d: Unknown result type (might be due to invalid IL or missing references) //IL_013c: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject(objectName, new Type[3] { typeof(RectTransform), typeof(CanvasRenderer), typeof(Image) }); val.transform.SetParent((Transform)(object)parent, false); RectTransform component = val.GetComponent<RectTransform>(); Vector2 val2 = default(Vector2); ((Vector2)(ref val2))..ctor(right ? 1f : 0f, 1f); component.anchorMax = val2; component.anchorMin = val2; component.pivot = new Vector2(0.5f, 0.5f); component.anchoredPosition = new Vector2(right ? (-1f) : 1f, 1f); component.sizeDelta = new Vector2(21f, 21f); Image component2 = val.GetComponent<Image>(); component2.sprite = GetShortcutCircleSprite(); ((Graphic)component2).color = new Color(0.055f, 0.065f, 0.085f, 0.98f); ((Graphic)component2).raycastTarget = false; TextMeshProUGUI obj = CreateText((Transform)(object)component, "Key", label, 12, (FontStyles)1, (TextAlignmentOptions)514, Color.white); ((TMP_Text)obj).rectTransform.anchorMin = Vector2.zero; ((TMP_Text)obj).rectTransform.anchorMax = Vector2.one; ((TMP_Text)obj).rectTransform.offsetMin = Vector2.zero; ((TMP_Text)obj).rectTransform.offsetMax = Vector2.zero; } private static Sprite GetShortcutCircleSprite() { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Expected O, but got Unknown //IL_00e8: 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_004e: 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_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) if ((Object)(object)_shortcutCircleSprite != (Object)null) { return _shortcutCircleSprite; } Texture2D val = new Texture2D(32, 32, (TextureFormat)4, false); Color32[] array = (Color32[])(object)new Color32[1024]; Vector2 val2 = default(Vector2); ((Vector2)(ref val2))..ctor(15.5f, 15.5f); for (int i = 0; i < 32; i++) { for (int j = 0; j < 32; j++) { float num = Mathf.Clamp01(14.75f - Vector2.Distance(new Vector2((float)j, (float)i), val2) + 1.25f); array[i * 32 + j] = new Color32(byte.MaxValue, byte.MaxValue, byte.MaxValue, (byte)Mathf.RoundToInt(num * 255f)); } } val.SetPixels32(array); val.Apply(false, true); ((Object)val).name = "Combat Stats Shortcut Circle"; ((Texture)val).wrapMode = (TextureWrapMode)1; ((Texture)val).filterMode = (FilterMode)1; _shortcutCircleSprite = Sprite.Create(val, new Rect(0f, 0f, 32f, 32f), new Vector2(0.5f, 0.5f), 100f); ((Object)_shortcutCircleSprite).name = "Combat Stats Shortcut Circle"; return _shortcutCircleSprite; } private static void Place(RectTransform rect, float x, float y, float width, float height) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0022: 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_003a: Unknown result type (might be due to invalid IL or missing references) Vector2 val = default(Vector2); ((Vector2)(ref val))..ctor(0f, 1f); rect.pivot = val; Vector2 anchorMin = (rect.anchorMax = val); rect.anchorMin = anchorMin; rect.anchoredPosition = new Vector2(x, 0f - y); rect.sizeDelta = new Vector2(width, height); } private static void HandlePointerInput() { //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_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) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_0127: 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_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) if ((Object)(object)_panel == (Object)null) { return; } if (Input.GetKeyDown((KeyCode)113)) { SelectMetric(-1); } else if (Input.GetKeyDown((KeyCode)101)) { SelectMetric(1); } bool flag = Cursor.visible && Input.GetMouseButtonDown(0); float y = Input.mouseScrollDelta.y; if (!flag && Mathf.Abs(y) <= 0.001f) { return; } bool flag2 = _battleActive && !Cursor.visible; Vector2 val = ((flag2 && !flag) ? Vector2.zero : Vector2.op_Implicit(Input.mousePosition)); if (flag) { if (PointerOver(_dealtButton, val)) { SelectMetric(Metric.DamageDealt); } else if (PointerOver(_takenButton, val)) { SelectMetric(Metric.DamageTaken); } else if (PointerOver(_healingButton, val)) { SelectMetric(Metric.Healing); } else if (PointerOver(_allButton, val)) { SelectTeam(TeamFilter.All); } else if (PointerOver(_redButton, val)) { SelectTeam(TeamFilter.Red); } else if (PointerOver(_blueButton, val)) { SelectTeam(TeamFilter.Blue); } } if (!(Mathf.Abs(y) <= 0.001f) && !((Object)(object)_viewport == (Object)null) && (flag2 || RectTransformUtility.RectangleContainsScreenPoint(_viewport, val, (Camera)null))) { int num = Mathf.Max(0, VisibleEntries.Count - 5); float num2 = Mathf.Clamp(_scrollTarget - y, 0f, (float)num); if (!(Mathf.Abs(num2 - _scrollTarget) <= 0.001f)) { _scrollTarget = num2; _scrollAnimationActive = true; } } } private static bool PointerOver(RectTransform rect, Vector2 pointer) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)rect != (Object)null) { return RectTransformUtility.RectangleContainsScreenPoint(rect, pointer, (Camera)null); } return false; } private static bool ShouldBlockPlacementInput() { //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) if (!ShouldShow() || !((Object)(object)_canvas != (Object)null) || !_canvas.activeInHierarchy || !((Object)(object)_panel != (Object)null) || !Cursor.visible) { if (!Input.GetMouseButton(0)) { _primaryPressConsumed = false; } if (!Input.GetMouseButton(1)) { _secondaryPressConsumed = false; } return Time.frameCount <= _blockPlacementThroughFrame; } bool mouseButtonDown = Input.GetMouseButtonDown(0); bool mouseButton = Input.GetMouseButton(0); bool mouseButtonUp = Input.GetMouseButtonUp(0); bool mouseButtonDown2 = Input.GetMouseButtonDown(1); bool mouseButton2 = Input.GetMouseButton(1); bool mouseButtonUp2 = Input.GetMouseButtonUp(1); bool flag = PointerOver(_panel, Vector2.op_Implicit(Input.mousePosition)); if (mouseButtonDown && flag) { _primaryPressConsumed = true; } if (mouseButtonDown2 && flag) { _secondaryPressConsumed = true; } bool result = _primaryPressConsumed || _secondaryPressConsumed || Time.frameCount <= _blockPlacementThroughFrame || (flag && (mouseButtonDown || mouseButton || mouseButtonUp || mouseButtonDown2 || mouseButton2 || mouseButtonUp2)); if (mouseButtonUp && (_primaryPressConsumed || flag)) { _blockPlacementThroughFrame = Mathf.Max(_blockPlacementThroughFrame, Time.frameCount + 1); _primaryPressConsumed = false; result = true; } else if (!mouseButton && !mouseButtonDown && !mouseButtonUp && _primaryPressConsumed) { _primaryPressConsumed = false; } if (mouseButtonUp2 && (_secondaryPressConsumed || flag)) { _blockPlacementThroughFrame = Mathf.Max(_blockPlacementThroughFrame, Time.frameCount + 1); _secondaryPressConsumed = false; result = true; } else if (!mouseButton2 && !mouseButtonDown2 && !mouseButtonUp2 && _secondaryPressConsumed) { _secondaryPressConsumed = false; } return result; } internal static bool AllowPlacementBrushUpdate() { return !ShouldBlockPlacementInput(); } private static void SelectMetric(int direction) { SelectMetric((Metric)((int)(_metric + Math.Sign(direction) + 3) % 3)); } private static void SelectMetric(Metric metric) { _metric = metric; _dirty = true; _nextRefresh = 0f; _resetScroll = true; RefreshButtonColors(); } private static void SelectTeam(TeamFilter filter) { _teamFilter = filter; _dirty = true; _nextRefresh = 0f; _resetScroll = true; RefreshButtonColors(); } private static void RefreshButtonColors() { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_003b: 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_0069: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) SetButtonColor(_dealtButton, _metric == Metric.DamageDealt, Gold); SetButtonColor(_takenButton, _metric == Metric.DamageTaken, Gold); SetButtonColor(_healingButton, _metric == Metric.Healing, Gold); SetButtonColor(_allButton, _teamFilter == TeamFilter.All, Gold); SetButtonColor(_redButton, _teamFilter == TeamFilter.Red, Red); SetButtonColor(_blueButton, _teamFilter == TeamFilter.Blue, Blue); } private static void SetButtonColor(RectTransform button, bool selected, Color accent) { //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0045: 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_0032: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)button == (Object)null)) { Image component = ((Component)button).GetComponent<Image>(); if ((Object)(object)component != (Object)null) { ((Graphic)component).color = (selected ? new Color(accent.r, accent.g, accent.b, 0.88f) : new Color(0.1f, 0.12f, 0.17f, 0.72f)); } TextMeshProUGUI componentInChildren = ((Component)button).GetComponentInChildren<TextMeshProUGUI>(true); if ((Object)(object)componentInChildren != (Object)null) { ((Graphic)componentInChildren).color = (Color)(selected ? Color.white : new Color(0.7f, 0.73f, 0.79f, 1f)); } } } private static float Value(Entry entry) { if (_metric != Metric.DamageDealt) { if (_metric != Metric.DamageTaken) { return entry.Healing; } return entry.Taken; } return entry.Dealt; } private static bool Visible(Entry entry) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Invalid comparison between Unknown and I4 if (_teamFilter != TeamFilter.All) { return _teamFilter == TeamFilter.Red == ((int)entry.Team == 0); } return true; } private static void RefreshPanel() { //IL_005e: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_panel == (Object)null || (Object)(object)_content == (Object)null) { return; } VisibleEntries.Clear(); float num = 1f; float num2 = 0f; float num3 = 0f; foreach (Entry value in Entries.Values) { float num4 = Value(value); if ((int)value.Team == 0) { num2 += num4; } else { num3 += num4; } if (Visible(value)) { VisibleEntries.Add(value); num = Mathf.Max(num, num4); } } VisibleEntries.Sort(delegate(Entry