using System; using System.Collections; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using EntityStates; using EntityStates.Drifter; using EntityStates.FalseSon; using EntityStates.LunarTeleporter; using EntityStates.Seeker; using HG; using HurricaneDifficulty.Config; using HurricaneDifficulty.Pantheon; using IL; using IL.EntityStates; using IL.EntityStates.Bell.BellWeapon; using IL.EntityStates.FalseSon; using IL.EntityStates.FlyingVermin.Weapon; using IL.EntityStates.SolusHeart.Death; using IL.RoR2; using IL.RoR2.Artifacts; using Microsoft.CodeAnalysis; using Mono.Cecil; using Mono.Cecil.Cil; using Mono.Collections.Generic; using MonoMod.Cil; using On.EntityStates.Drifter; using On.EntityStates.Seeker; using On.RoR2; using On.RoR2.Artifacts; using On.RoR2.UI; using On.RoR2.UI.MainMenu; using PvPMode; using PvPMode.Combat; using PvPMode.Compatibility; using PvPMode.Config; using PvPMode.Debugging; using PvPMode.Equipment; using PvPMode.Loadouts; using PvPMode.Match; using PvPMode.Minions; using PvPMode.Respawn; using PvPMode.Routes; using PvPMode.Spawn; using PvPMode.Teams; using PvPMode.UI; using R2API; using R2API.Utils; using RoR2; using RoR2.Achievements; using RoR2.AddressableAssets; using RoR2.CharacterAI; using RoR2.ExpansionManagement; using RoR2.HudOverlay; using RoR2.Items; using RoR2.Navigation; using RoR2.Networking; using RoR2.Projectile; using RoR2.Skills; using RoR2.Stats; using RoR2.UI; using RoR2.UI.LogBook; using RoR2.UI.MainMenu; using TMPro; using UnityEngine; using UnityEngine.AddressableAssets; using UnityEngine.EventSystems; using UnityEngine.Events; using UnityEngine.Networking; using UnityEngine.SceneManagement; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("ResonatorsOfTheSoul")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("0.25.33.0")] [assembly: AssemblyInformationalVersion("0.25.33")] [assembly: AssemblyProduct("ResonatorsOfTheSoul")] [assembly: AssemblyTitle("ResonatorsOfTheSoul")] [assembly: AssemblyVersion("0.25.33.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace PvPMode { public static class Plugin { internal const string GameModePrefabName = "WaterBucketPvPModeRun"; internal const string GameModeNameToken = "WATERBUCKET_PVP_MODE_NAME"; internal const string GameModeDescriptionToken = "WATERBUCKET_PVP_MODE_DESCRIPTION"; private static bool initialized; internal static BaseUnityPlugin Instance { get; private set; } internal static ManualLogSource Log { get; private set; } internal static GameEndingDef? PvPMatchEnding { get; private set; } public static bool IsPvPModeActive { get { if (ResonatorModules.PvPActive && Object.op_Implicit((Object)(object)Run.instance)) { return Object.op_Implicit((Object)(object)((Component)Run.instance).GetComponent()); } return false; } } internal static void Initialize(BaseUnityPlugin owner, ManualLogSource logger) { if (!initialized) { initialized = true; Instance = owner; Log = logger; PvPConfig.Bind(owner.Config); RegisterLanguage(); PvPTeamRegistry.RegisterTeams(PvPConfig.MaxPvPTeams.Value); RegisterGameMode(); RegisterMatchEnding(); PvPTeamManager.Install(); PvPMatchManager.Install(); VanillaPlayerTeamCompatibility.Install(); PvPSurvivorMechanics.Install(); PvPMinionTeamController.Install(); PvPDamageController.Install(); PvPSpawnManager.Install(); PvPRespawnManager.Install(); PvPStageRouteManager.Install(); PvPStartingLoadoutManager.Install(); PvPRadarScannerNames.Install(); PvPScoreboardPrivacy.Install(); PvPLobbySettingsUI.Install(); PvPCommands.Install(); Log.LogInfo((object)"Resonators of the Soul PvP module initialized."); } } internal static void Shutdown() { if (initialized) { initialized = false; PvPCommands.Uninstall(); PvPLobbySettingsUI.Uninstall(); PvPScoreboardPrivacy.Uninstall(); PvPRadarScannerNames.Uninstall(); PvPStartingLoadoutManager.Uninstall(); PvPStageRouteManager.Uninstall(); PvPRespawnManager.Uninstall(); PvPSpawnManager.Uninstall(); PvPDamageController.Uninstall(); PvPMinionTeamController.Uninstall(); PvPSurvivorMechanics.Uninstall(); VanillaPlayerTeamCompatibility.Uninstall(); PvPMatchManager.Uninstall(); PvPTeamManager.Uninstall(); PvPMatchEnding = null; } } private static void RegisterLanguage() { LanguageAPI.Add("WATERBUCKET_PVP_MODE_NAME", "PvP Mode"); LanguageAPI.Add("WATERBUCKET_PVP_MODE_NAME", "PvP 对战", "zh-CN"); LanguageAPI.Add("WATERBUCKET_PVP_MODE_DESCRIPTION", "Rival player teams with scaled PvP damage, separated spawns, minion allegiance, and respawning."); LanguageAPI.Add("WATERBUCKET_PVP_MODE_DESCRIPTION", "玩家分属敌对队伍,具有独立 PvP 伤害倍率、分散出生、召唤物阵营继承和死亡重生。", "zh-CN"); AddLanguage("WATERBUCKET_PVP_SETTINGS_BUTTON", "PvP Settings", "PvP 设置"); AddLanguage("WATERBUCKET_PVP_SETTINGS_TITLE", "PvP Lobby Settings", "PvP 房间设置"); AddLanguage("WATERBUCKET_PVP_SETTINGS_HINT", "Host settings are saved immediately and apply when the run starts.", "仅房主可修改;设置会立即保存,并在开局时生效。"); AddLanguage("WATERBUCKET_PVP_SETTINGS_TAB_RULES", "RULES", "规则"); AddLanguage("WATERBUCKET_PVP_SETTINGS_TAB_MODE", "MODE", "模式"); AddLanguage("WATERBUCKET_PVP_SETTINGS_TAB_TEAMS", "TEAMS", "分队"); AddLanguage("WATERBUCKET_PVP_SETTINGS_TAB_LOADOUT", "LOADOUT", "装备"); AddLanguage("WATERBUCKET_PVP_SETTINGS_MODE_HINT", "Choose the match ending rule, team structure, and respawn behavior.", "设置比赛结束条件、队伍结构和复活规则。"); AddLanguage("WATERBUCKET_PVP_SETTINGS_HOST_ONLY", "Only the host can edit match rules.", "仅房主可修改对战规则。"); AddLanguage("WATERBUCKET_PVP_SETTINGS_SECTION_MATCH", "MATCH", "对战"); AddLanguage("WATERBUCKET_PVP_SETTINGS_SECTION_MATCH_RULE", "MATCH RULE", "胜负规则"); AddLanguage("WATERBUCKET_PVP_SETTINGS_SECTION_TEAMS", "TEAMS", "队伍"); AddLanguage("WATERBUCKET_PVP_SETTINGS_SECTION_SPAWN", "SPAWNING", "出生"); AddLanguage("WATERBUCKET_PVP_SETTINGS_SECTION_RESPAWN", "RESPAWNING", "复活"); AddLanguage("WATERBUCKET_PVP_SETTINGS_SECTION_ROUTE", "STAGE ROUTE", "关卡路线"); AddLanguage("WATERBUCKET_PVP_SETTINGS_TEAM_HINT", "Choose your own team. Automatic players still follow the host's assignment rule.", "选择你要加入的队伍;选择自动的玩家仍按房主设定的规则分配。"); AddLanguage("WATERBUCKET_PVP_SETTINGS_TEAM_AUTO", "Automatic", "自动分配"); AddLanguage("WATERBUCKET_PVP_SETTINGS_TEAM_CURRENT", "Current choice", "当前选择"); AddLanguage("WATERBUCKET_PVP_SETTINGS_TEAM_ROSTER", "LOBBY PLAYERS", "房间玩家"); AddLanguage("WATERBUCKET_PVP_SETTINGS_TEAM_PENDING", "Automatic / pending", "自动 / 待分配"); AddLanguage("WATERBUCKET_PVP_LOADOUT_HINT", "The host sets per-player allowances. Every player chooses only their own starting items.", "房主设置每人额度;每名玩家只能选择自己的初始物品。"); AddLanguage("WATERBUCKET_PVP_LOADOUT_CATEGORY", "Item category", "物品类别"); AddLanguage("WATERBUCKET_PVP_LOADOUT_ALLOWANCE", "Per-player allowance", "每人额度"); AddLanguage("WATERBUCKET_PVP_LOADOUT_SELECTED", "Selected: {0} / {1}", "已选择:{0} / {1}"); AddLanguage("WATERBUCKET_PVP_LOADOUT_CLICK_HINT", "Left click to add; right click to remove. Lunar equipment uses blue allowance.", "左键增加,右键减少;月球主动装备占用蓝色额度。"); AddLanguage("WATERBUCKET_PVP_LOADOUT_CLEAR", "Clear this category", "清空当前类别"); AddLanguage("WATERBUCKET_PVP_LOADOUT_WHITE", "White", "白色"); AddLanguage("WATERBUCKET_PVP_LOADOUT_GREEN", "Green", "绿色"); AddLanguage("WATERBUCKET_PVP_LOADOUT_YELLOW", "Yellow", "黄色"); AddLanguage("WATERBUCKET_PVP_LOADOUT_ORANGE", "Orange equipment", "橙色主动装备"); AddLanguage("WATERBUCKET_PVP_LOADOUT_RED", "Red", "红色"); AddLanguage("WATERBUCKET_PVP_LOADOUT_BLUE", "Blue / Lunar", "蓝色/月球"); AddLanguage("WATERBUCKET_PVP_LOADOUT_VOID_WHITE", "Void white", "白紫"); AddLanguage("WATERBUCKET_PVP_LOADOUT_VOID_GREEN", "Void green", "绿紫"); AddLanguage("WATERBUCKET_PVP_LOADOUT_VOID_RED", "Void red", "红紫"); AddLanguage("WATERBUCKET_PVP_LOADOUT_PRESETS", "LOCAL PRESETS", "本地配装预设"); AddLanguage("WATERBUCKET_PVP_LOADOUT_PRESET_HINT", "Left click a slot to load it; right click to overwrite-save the current full loadout.", "左键一键加载;右键用当前完整配装覆盖保存。"); AddLanguage("WATERBUCKET_PVP_LOADOUT_PRESET_SLOT_SAVED", "◆ Preset {0}", "◆ 预设 {0}"); AddLanguage("WATERBUCKET_PVP_LOADOUT_PRESET_SLOT_EMPTY", "Preset {0}", "预设 {0}"); AddLanguage("WATERBUCKET_PVP_LOADOUT_PRESET_SAVED", "Saved preset {0} ({1} selections).", "已保存预设 {0}({1} 件)。"); AddLanguage("WATERBUCKET_PVP_LOADOUT_PRESET_LOADED", "Loaded preset {0}: {1} selected, {2} skipped.", "已加载预设 {0}:选择 {1} 件,跳过 {2} 件。"); AddLanguage("WATERBUCKET_PVP_LOADOUT_PRESET_EMPTY", "This preset slot is empty.", "这个预设栏位为空。"); AddLanguage("WATERBUCKET_PVP_LOADOUT_PRESET_INVALID", "This preset could not be read.", "这个预设无法读取。"); AddLanguage("WATERBUCKET_PVP_SETTINGS_MATCH_MODE", "Match mode", "比赛模式"); AddLanguage("WATERBUCKET_PVP_SETTINGS_MATCH_LIMITED", "Limited lives", "有限生命"); AddLanguage("WATERBUCKET_PVP_SETTINGS_MATCH_UNLIMITED", "Unlimited", "无限制"); AddLanguage("WATERBUCKET_PVP_SETTINGS_MATCH_TIMED", "Timed team kills", "限时队伍击杀"); AddLanguage("WATERBUCKET_PVP_SETTINGS_LIVES", "Lives per player", "每人生命数"); AddLanguage("WATERBUCKET_PVP_SETTINGS_TIME_LIMIT", "Time limit", "时间限制"); AddLanguage("WATERBUCKET_PVP_SETTINGS_CLOSE", "Close", "关闭"); AddLanguage("WATERBUCKET_PVP_SETTINGS_ENABLED", "Enabled", "开启"); AddLanguage("WATERBUCKET_PVP_SETTINGS_DISABLED", "Disabled", "关闭"); AddLanguage("WATERBUCKET_PVP_SETTINGS_TEAM_MODE", "Teams", "组队"); AddLanguage("WATERBUCKET_PVP_SETTINGS_MODE", "Team assignment", "队伍模式"); AddLanguage("WATERBUCKET_PVP_SETTINGS_TEAM_COUNT", "Team count", "队伍数量"); AddLanguage("WATERBUCKET_PVP_SETTINGS_FRIENDLY_FIRE", "Friendly fire", "队友伤害"); AddLanguage("WATERBUCKET_PVP_SETTINGS_PLAYER_PLAYER", "Player → player damage", "玩家 → 玩家伤害"); AddLanguage("WATERBUCKET_PVP_SETTINGS_MINION_PLAYER", "Minion → player damage", "召唤物 → 玩家伤害"); AddLanguage("WATERBUCKET_PVP_SETTINGS_PLAYER_MINION", "Player → minion damage", "玩家 → 召唤物伤害"); AddLanguage("WATERBUCKET_PVP_SETTINGS_MINION_MINION", "Minion → minion damage", "召唤物 → 召唤物伤害"); AddLanguage("WATERBUCKET_PVP_SETTINGS_CONTROL_DURATION", "Player hard-control duration", "玩家硬控时间倍率"); AddLanguage("WATERBUCKET_PVP_SETTINGS_FALLBACK_DISTANCE", "Fallback spawn distance", "备用出生距离"); AddLanguage("WATERBUCKET_PVP_SETTINGS_TEAM_RADIUS", "Ally spawn radius", "队友出生半径"); AddLanguage("WATERBUCKET_PVP_SETTINGS_SPAWN_PROTECTION", "Initial spawn protection", "初始出生保护"); AddLanguage("WATERBUCKET_PVP_SETTINGS_RESPAWN", "Automatic respawn", "自动复活"); AddLanguage("WATERBUCKET_PVP_SETTINGS_RESPAWN_DELAY", "Respawn delay", "复活等待时间"); AddLanguage("WATERBUCKET_PVP_SETTINGS_RESPAWN_PROTECTION", "Respawn protection", "复活保护"); AddLanguage("WATERBUCKET_PVP_SETTINGS_STAGE_FIVE_ROUTE", "Sky Meadow default route", "第五层默认路线"); AddLanguage("WATERBUCKET_PVP_SETTINGS_ROUTE_LOOP", "Loop", "循环"); AddLanguage("WATERBUCKET_PVP_SETTINGS_ROUTE_MOON", "Moon", "月球"); AddLanguage("WATERBUCKET_PVP_MATCH_ENDING", "PvP match complete", "PvP 对战结束"); AddLanguage("WATERBUCKET_PVP_MATCH_START_LIVES", "Limited-lives match started: {0} lives per player.", "有限生命比赛开始:每名玩家 {0} 条生命。"); AddLanguage("WATERBUCKET_PVP_MATCH_START_UNLIMITED", "Unlimited PvP match started. There is no automatic ending condition.", "无限制比赛开始:不会自动结束。"); AddLanguage("WATERBUCKET_PVP_MATCH_START_TIMED", "Timed team-kill match started: {0} minutes.", "限时队伍击杀比赛开始:限时 {0} 分钟。"); AddLanguage("WATERBUCKET_PVP_MATCH_LIVES_MESSAGE", "{0} has {1} lives remaining.", "{0} 剩余 {1} 条生命。"); AddLanguage("WATERBUCKET_PVP_MATCH_SEEKER_LIFE", "Seeker revived eliminated player {0} and restored 1 life.", "求道者复活了已淘汰玩家 {0},并为其恢复 1 条生命。"); AddLanguage("WATERBUCKET_PVP_MATCH_SCORE_MESSAGE", "{0} now has {1} kills.", "{0} 当前击杀数:{1}。"); AddLanguage("WATERBUCKET_PVP_MATCH_OVERTIME", "The score is tied. Overtime continues until there is a sole leading team.", "最高击杀数相同,进入加时;出现唯一领先队伍时结束。"); AddLanguage("WATERBUCKET_PVP_MATCH_WINNER", "{0} wins the PvP match!", "{0} 赢得了 PvP 比赛!"); AddLanguage("WATERBUCKET_PVP_MATCH_NO_VIABLE_TEAMS", "No team has any lives remaining.", "所有队伍的生命均已耗尽。"); AddLanguage("WATERBUCKET_PVP_RESPAWN_COUNTDOWN", "Respawning in {0}s • {1} lives remaining", "将在 {0} 秒后复活\u3000•\u3000剩余 {1} 条生命"); AddLanguage("WATERBUCKET_PVP_RESPAWN_NOW", "Respawning… • {0} lives remaining", "正在复活…\u3000•\u3000剩余 {0} 条生命"); for (int i = 0; i < PvPConfig.MaxPvPTeams.Value; i++) { string teamNameToken = PvPTeamRegistry.GetTeamNameToken(i); LanguageAPI.Add(teamNameToken, $"PvP Team {i + 1}"); LanguageAPI.Add(teamNameToken, $"PvP 队伍 {i + 1}", "zh-CN"); } } private static void AddLanguage(string token, string english, string simplifiedChinese) { LanguageAPI.Add(token, english); LanguageAPI.Add(token, simplifiedChinese, "zh-CN"); } private static void RegisterGameMode() { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) GameObject obj = Addressables.LoadAssetAsync((object)"RoR2/Base/ClassicRun/ClassicRun.prefab").WaitForCompletion(); if (!Object.op_Implicit((Object)(object)obj)) { throw new InvalidOperationException("Could not load the current ClassicRun prefab."); } GameObject obj2 = PrefabAPI.InstantiateClone(obj, "WaterBucketPvPModeRun", true); Run component = obj2.GetComponent(); component.nameToken = "WATERBUCKET_PVP_MODE_NAME"; component.userPickable = true; obj2.AddComponent(); if (!ContentAddition.AddGameMode(obj2, "WATERBUCKET_PVP_MODE_DESCRIPTION")) { throw new InvalidOperationException("R2API rejected the PvP game-mode prefab."); } } private static void RegisterMatchEnding() { //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_0077: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) try { GameEndingDef val = ScriptableObject.CreateInstance(); ((Object)val).name = "WaterBucketPvPMatchEnding"; val.cachedName = "WaterBucketPvPMatchEnding"; val.endingTextToken = "WATERBUCKET_PVP_MATCH_ENDING"; val.isWin = true; val.showCredits = false; val.lunarCoinReward = 0u; val.defaultKillerOverride = null; val.backgroundColor = new Color(0.035f, 0.055f, 0.09f, 1f); val.foregroundColor = new Color(0.55f, 0.85f, 1f, 1f); if (ContentAddition.AddGameEndingDef(val)) { PvPMatchEnding = val; return; } Object.Destroy((Object)(object)val); Log.LogWarning((object)"R2API rejected the custom PvP ending. A vanilla ending will be used instead."); } catch (Exception arg) { PvPMatchEnding = null; Log.LogWarning((object)$"Could not register the custom PvP ending; PvP mode remains available. {arg}"); } } internal static GameEndingDef? GetMatchEnding() { //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) GameEndingDef pvPMatchEnding = PvPMatchEnding; GameEndingDef val = GameEndings.PrismaticTrialEnding; if (!Object.op_Implicit((Object)(object)val)) { val = GameEndings.StandardLoss; } if (pvPMatchEnding != null && Object.op_Implicit((Object)(object)pvPMatchEnding) && val != null && Object.op_Implicit((Object)(object)val)) { pvPMatchEnding.gameOverControllerState = val.gameOverControllerState; pvPMatchEnding.icon = val.icon; pvPMatchEnding.material = val.material; return pvPMatchEnding; } return val; } internal static GameEndingDef? GetLossEnding() { GameEndingDef standardLoss = GameEndings.StandardLoss; if (standardLoss == null || !Object.op_Implicit((Object)(object)standardLoss)) { return GetMatchEnding(); } return standardLoss; } } public sealed class PvPModeRunMarker : MonoBehaviour { } } namespace PvPMode.UI { internal static class PvPLobbySettingsUI { [CompilerGenerated] private static class <>O { public static hook_Awake <0>__CharacterSelectControllerAwake; } private static bool installed; internal static void Install() { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Expected O, but got Unknown if (!installed) { installed = true; object obj = <>O.<0>__CharacterSelectControllerAwake; if (obj == null) { hook_Awake val = CharacterSelectControllerAwake; <>O.<0>__CharacterSelectControllerAwake = val; obj = (object)val; } CharacterSelectController.Awake += (hook_Awake)obj; } } internal static void Uninstall() { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Expected O, but got Unknown if (installed) { installed = false; object obj = <>O.<0>__CharacterSelectControllerAwake; if (obj == null) { hook_Awake val = CharacterSelectControllerAwake; <>O.<0>__CharacterSelectControllerAwake = val; obj = (object)val; } CharacterSelectController.Awake -= (hook_Awake)obj; } } private static void CharacterSelectControllerAwake(orig_Awake orig, CharacterSelectController self) { orig.Invoke(self); if (!Object.op_Implicit((Object)(object)((Component)self).GetComponent())) { ((Component)self).gameObject.AddComponent(); } } } internal sealed class PvPLobbySettingsPanel : MonoBehaviour { private const int ModulesPage = 0; private const int ModePage = 1; private const int RulesPage = 2; private const int TeamsPage = 3; private const int LoadoutPage = 4; private const string SettingsTitle = "Resonators of the Soul 设置"; private const string CloseToken = "WATERBUCKET_PVP_SETTINGS_CLOSE"; private readonly List valueRefreshers = new List(); private readonly List<(MPButton Button, int TeamId)> teamButtons = new List<(MPButton, int)>(); private readonly List<(MPButton Button, StartingLoadoutOption Option, TMP_Text Label)> loadoutButtons = new List<(MPButton, StartingLoadoutOption, TMP_Text)>(); private readonly List<(MPButton Button, TMP_Text Label, int SlotIndex)> loadoutPresetButtons = new List<(MPButton, TMP_Text, int)>(); private CharacterSelectController controller; private MPButton buttonTemplate; private MPButton? settingsStyleTemplate; private Image? settingsPanelStyleTemplate; private GameObject openButtonObject; private GameObject overlayObject; private GameObject modulesPageObject; private GameObject modePageObject; private GameObject rulesPageObject; private GameObject teamsPageObject; private GameObject loadoutPageObject; private RectTransform overlayRect; private RectTransform panelRect; private MPButton modulesTabButton; private MPButton modeTabButton; private MPButton rulesTabButton; private MPButton teamsTabButton; private MPButton loadoutTabButton; private MPButton loadoutBudgetDecreaseButton; private MPButton loadoutBudgetIncreaseButton; private MPButton? firstRulesButton; private HGTextMeshProUGUI pageHintText; private HGTextMeshProUGUI currentChoiceText; private HGTextMeshProUGUI rosterText; private HGTextMeshProUGUI loadoutCategoryText; private HGTextMeshProUGUI loadoutBudgetText; private HGTextMeshProUGUI loadoutSelectedText; private HGTextMeshProUGUI loadoutPresetStatusText; private RectTransform loadoutGrid; private int currentPage; private bool wasVisible; private bool wasPvPConfigurationAvailable; private int localLobbySelection = -1; private float nextTeamRefreshTime; private float nextLoadoutRefreshTime; private StartingLoadoutCategory loadoutCategory; private void Start() { controller = ((Component)this).GetComponent(); if (!Object.op_Implicit((Object)(object)controller) || !Object.op_Implicit((Object)(object)controller.readyButton)) { ((Behaviour)this).enabled = false; return; } buttonTemplate = controller.readyButton; try { LoadNativeSettingsStyle(); CreateOpenButton(); CreatePanel(); ResonatorModules.StateChanged -= OnModuleStateChanged; ResonatorModules.StateChanged += OnModuleStateChanged; ResonatorModules.RequestSync(); RefreshVisibility(force: true); RefreshPvPTabAvailability(force: true); Plugin.Log.LogDebug((object)"Resonators of the Soul lobby settings UI initialized."); } catch (Exception arg) { Plugin.Log.LogError((object)$"Failed to initialize the PvP lobby settings UI: {arg}"); if (Object.op_Implicit((Object)(object)openButtonObject)) { Object.Destroy((Object)(object)openButtonObject); } if (Object.op_Implicit((Object)(object)overlayObject)) { Object.Destroy((Object)(object)overlayObject); } ((Behaviour)this).enabled = false; } } private void OnDestroy() { ResonatorModules.StateChanged -= OnModuleStateChanged; if (Object.op_Implicit((Object)(object)openButtonObject)) { Object.Destroy((Object)(object)openButtonObject); } if (Object.op_Implicit((Object)(object)overlayObject)) { Object.Destroy((Object)(object)overlayObject); } } private void Update() { RefreshVisibility(force: false); RefreshPvPTabAvailability(force: false); if (Object.op_Implicit((Object)(object)overlayObject) && overlayObject.activeSelf) { if (Input.GetKeyDown((KeyCode)27)) { ClosePanel(); } else if (currentPage == 3 && Time.unscaledTime >= nextTeamRefreshTime) { nextTeamRefreshTime = Time.unscaledTime + 0.25f; RefreshTeamPage(); } else if (currentPage == 4 && Time.unscaledTime >= nextLoadoutRefreshTime) { nextLoadoutRefreshTime = Time.unscaledTime + 0.15f; RefreshLoadoutPage(); } } } private static bool IsPvPModeSelected() { //IL_0011: Unknown result type (might be due to invalid IL or missing references) PreGameController instance = PreGameController.instance; if (!Object.op_Implicit((Object)(object)instance)) { return false; } Run gameModePrefabComponent = GameModeCatalog.GetGameModePrefabComponent(instance.gameModeIndex); if (Object.op_Implicit((Object)(object)gameModePrefabComponent)) { return ((Object)((Component)gameModePrefabComponent).gameObject).name == "WaterBucketPvPModeRun"; } return false; } private static bool IsPvPConfigurationAvailable() { if (ResonatorModules.GetLobbyEnabled(ResonatorModules.ModuleKind.PvP)) { return IsPvPModeSelected(); } return false; } private void RefreshVisibility(bool force) { bool flag = Object.op_Implicit((Object)(object)controller) && ((Component)controller).gameObject.activeInHierarchy; if (force || flag != wasVisible) { wasVisible = flag; if (Object.op_Implicit((Object)(object)openButtonObject)) { openButtonObject.SetActive(flag); } if (!flag && Object.op_Implicit((Object)(object)overlayObject)) { overlayObject.SetActive(false); } } } private void OnModuleStateChanged() { RefreshValues(); RefreshPvPTabAvailability(force: true); } private void CreateOpenButton() { //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Expected O, but got Unknown //IL_0058: 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_0064: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_0070: 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_007c: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: Expected O, but got Unknown openButtonObject = Object.Instantiate(((Component)buttonTemplate).gameObject, ((Component)buttonTemplate).transform.parent, false); ((Object)openButtonObject).name = "ResonatorsOfTheSoulSettingsButton"; RectTransform val = (RectTransform)openButtonObject.transform; RectTransform val2 = (RectTransform)((Component)buttonTemplate).transform; val.anchorMin = val2.anchorMin; val.anchorMax = val2.anchorMax; val.pivot = val2.pivot; val.sizeDelta = val2.sizeDelta; Vector2 anchoredPosition = val2.anchoredPosition; Rect rect = val2.rect; val.anchoredPosition = anchoredPosition + new Vector2(0f, ((Rect)(ref rect)).height + 10f); MPButton component = openButtonObject.GetComponent(); ResetButton(component, "Resonators of the Soul 设置", tokenized: false); ApplyNativeSettingsStyle(component); ((UnityEvent)((Button)component).onClick).AddListener(new UnityAction(OpenPanel)); } private void CreatePanel() { //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Expected O, but got Unknown //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Expected O, but got Unknown //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_0121: Unknown result type (might be due to invalid IL or missing references) //IL_0127: Expected O, but got Unknown //IL_0156: Unknown result type (might be due to invalid IL or missing references) //IL_0160: Expected O, but got Unknown //IL_0170: Unknown result type (might be due to invalid IL or missing references) //IL_018a: Unknown result type (might be due to invalid IL or missing references) //IL_019a: Unknown result type (might be due to invalid IL or missing references) //IL_01aa: Unknown result type (might be due to invalid IL or missing references) //IL_01d0: Unknown result type (might be due to invalid IL or missing references) //IL_01fc: Unknown result type (might be due to invalid IL or missing references) //IL_0210: Unknown result type (might be due to invalid IL or missing references) //IL_024b: Unknown result type (might be due to invalid IL or missing references) //IL_0252: Expected O, but got Unknown //IL_0279: Unknown result type (might be due to invalid IL or missing references) //IL_027e: Unknown result type (might be due to invalid IL or missing references) //IL_0284: Expected O, but got Unknown //IL_0284: Unknown result type (might be due to invalid IL or missing references) //IL_028f: Unknown result type (might be due to invalid IL or missing references) //IL_02a3: Unknown result type (might be due to invalid IL or missing references) //IL_02b9: Unknown result type (might be due to invalid IL or missing references) //IL_02c3: Expected O, but got Unknown //IL_036d: 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_0409: Expected O, but got Unknown Canvas componentInParent = ((Component)controller).GetComponentInParent(); Canvas val = (Object.op_Implicit((Object)(object)componentInParent) ? componentInParent.rootCanvas : null); if (!Object.op_Implicit((Object)(object)val)) { throw new InvalidOperationException("Character select UI has no root Canvas."); } overlayObject = new GameObject("ResonatorsOfTheSoulSettingsOverlay", new Type[2] { typeof(RectTransform), typeof(Image) }); overlayObject.layer = ((Component)val).gameObject.layer; overlayObject.transform.SetParent(((Component)val).transform, false); overlayObject.transform.SetAsLastSibling(); overlayRect = (RectTransform)overlayObject.transform; Stretch(overlayRect); Image component = overlayObject.GetComponent(); ((Graphic)component).color = new Color(0.006f, 0.011f, 0.019f, 0.86f); ((Graphic)component).raycastTarget = true; GameObject val2 = new GameObject("Panel", new Type[3] { typeof(RectTransform), typeof(Image), typeof(Outline) }); val2.layer = overlayObject.layer; val2.transform.SetParent(overlayObject.transform, false); panelRect = (RectTransform)val2.transform; panelRect.anchorMin = new Vector2(0.16f, 0.045f); panelRect.anchorMax = new Vector2(0.84f, 0.955f); panelRect.offsetMin = Vector2.zero; panelRect.offsetMax = Vector2.zero; Image component2 = val2.GetComponent(); ((Graphic)component2).color = new Color(0.025f, 0.043f, 0.061f, 0.985f); ApplyNativePanelStyle(component2); Outline component3 = val2.GetComponent(); ((Shadow)component3).effectColor = new Color(0.46f, 0.67f, 0.74f, 0.55f); ((Shadow)component3).effectDistance = new Vector2(1f, -1f); CreateAccentStrip(val2.transform); GameObject val3 = new GameObject("Content", new Type[2] { typeof(RectTransform), typeof(VerticalLayoutGroup) }); val3.layer = val2.layer; val3.transform.SetParent(val2.transform, false); RectTransform val4 = (RectTransform)val3.transform; Stretch(val4); val4.offsetMin = new Vector2(34f, 24f); val4.offsetMax = new Vector2(-34f, -22f); VerticalLayoutGroup component4 = val3.GetComponent(); ((LayoutGroup)component4).padding = new RectOffset(4, 4, 2, 2); ((HorizontalOrVerticalLayoutGroup)component4).spacing = 6f; ((LayoutGroup)component4).childAlignment = (TextAnchor)1; ((HorizontalOrVerticalLayoutGroup)component4).childControlHeight = true; ((HorizontalOrVerticalLayoutGroup)component4).childControlWidth = true; ((HorizontalOrVerticalLayoutGroup)component4).childForceExpandHeight = false; ((HorizontalOrVerticalLayoutGroup)component4).childForceExpandWidth = true; ((TMP_Text)CreateText(val3.transform, "Resonators of the Soul 设置", 31f, (FontStyles)1, (TextAlignmentOptions)514, 44f, tokenized: false)).characterSpacing = 1.5f; CreateTabRow(val3.transform); pageHintText = CreateText(val3.transform, string.Empty, 16f, (FontStyles)0, (TextAlignmentOptions)514, 30f, tokenized: false); ((Graphic)pageHintText).color = new Color(0.73f, 0.81f, 0.84f, 1f); modulesPageObject = CreateModulesPage(val3.transform); modePageObject = CreateModePage(val3.transform); rulesPageObject = CreateRulesPage(val3.transform); teamsPageObject = CreateTeamsPage(val3.transform); loadoutPageObject = CreateLoadoutPage(val3.transform); ((UnityEvent)((Button)CloneButton(val3.transform, "WATERBUCKET_PVP_SETTINGS_CLOSE", tokenized: true, -1f, 45f)).onClick).AddListener(new UnityAction(ClosePanel)); overlayObject.SetActive(false); Plugin.Log.LogDebug((object)("Resonators of the Soul settings overlay attached to root Canvas '" + ((Object)val).name + "'.")); } private void CreateAccentStrip(Transform parent) { //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_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_005e: 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_0073: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("Accent", new Type[2] { typeof(RectTransform), typeof(Image) }) { layer = ((Component)parent).gameObject.layer }; val.transform.SetParent(parent, false); RectTransform val2 = (RectTransform)val.transform; val2.anchorMin = new Vector2(0f, 0f); val2.anchorMax = new Vector2(0f, 1f); val2.pivot = new Vector2(0f, 0.5f); val2.sizeDelta = new Vector2(4f, 0f); val2.anchoredPosition = Vector2.zero; ((Graphic)val.GetComponent()).color = new Color(0.35f, 0.75f, 0.91f, 0.9f); } private void CreateTabRow(Transform parent) { //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Expected O, but got Unknown //IL_0155: Unknown result type (might be due to invalid IL or missing references) //IL_015f: Expected O, but got Unknown //IL_0171: Unknown result type (might be due to invalid IL or missing references) //IL_017b: Expected O, but got Unknown //IL_018d: Unknown result type (might be due to invalid IL or missing references) //IL_0197: Expected O, but got Unknown //IL_01a9: Unknown result type (might be due to invalid IL or missing references) //IL_01b3: Expected O, but got Unknown //IL_01c5: Unknown result type (might be due to invalid IL or missing references) //IL_01cf: Expected O, but got Unknown GameObject val = new GameObject("Tabs", new Type[3] { typeof(RectTransform), typeof(HorizontalLayoutGroup), typeof(LayoutElement) }); val.layer = ((Component)parent).gameObject.layer; val.transform.SetParent(parent, false); val.GetComponent().preferredHeight = 48f; HorizontalLayoutGroup component = val.GetComponent(); ((HorizontalOrVerticalLayoutGroup)component).spacing = 5f; ((LayoutGroup)component).childAlignment = (TextAnchor)4; ((HorizontalOrVerticalLayoutGroup)component).childControlHeight = true; ((HorizontalOrVerticalLayoutGroup)component).childControlWidth = true; ((HorizontalOrVerticalLayoutGroup)component).childForceExpandHeight = true; ((HorizontalOrVerticalLayoutGroup)component).childForceExpandWidth = true; modulesTabButton = CloneButton(val.transform, "模块", tokenized: false, -1f, 46f); modeTabButton = CloneButton(val.transform, "WATERBUCKET_PVP_SETTINGS_TAB_MODE", tokenized: true, -1f, 46f); rulesTabButton = CloneButton(val.transform, "WATERBUCKET_PVP_SETTINGS_TAB_RULES", tokenized: true, -1f, 46f); teamsTabButton = CloneButton(val.transform, "WATERBUCKET_PVP_SETTINGS_TAB_TEAMS", tokenized: true, -1f, 46f); loadoutTabButton = CloneButton(val.transform, "WATERBUCKET_PVP_SETTINGS_TAB_LOADOUT", tokenized: true, -1f, 46f); ((UnityEvent)((Button)modulesTabButton).onClick).AddListener((UnityAction)delegate { ShowPage(0); }); ((UnityEvent)((Button)modeTabButton).onClick).AddListener((UnityAction)delegate { ShowPage(1); }); ((UnityEvent)((Button)rulesTabButton).onClick).AddListener((UnityAction)delegate { ShowPage(2); }); ((UnityEvent)((Button)teamsTabButton).onClick).AddListener((UnityAction)delegate { ShowPage(3); }); ((UnityEvent)((Button)loadoutTabButton).onClick).AddListener((UnityAction)delegate { ShowPage(4); }); } private GameObject CreateModulesPage(Transform parent) { //IL_0084: Unknown result type (might be due to invalid IL or missing references) GameObject obj = CreatePage(parent, "ModulesPage", 628f); Transform transform = obj.transform; CreateSectionHeader(transform, "功能模块", tokenized: false); AddModuleToggleRow(transform, "强化难度", ResonatorModules.ModuleKind.Difficulties); AddModuleToggleRow(transform, "神器", ResonatorModules.ModuleKind.Artifacts); AddModuleToggleRow(transform, "PvP", ResonatorModules.ModuleKind.PvP); HGTextMeshProUGUI obj2 = CreateText(transform, "模块由房主统一控制,并同步给房间内所有玩家。关闭模块不会移除其联网目录内容,避免多人配置不一致。", 17f, (FontStyles)0, (TextAlignmentOptions)257, 96f, tokenized: false); ((TMP_Text)obj2).enableWordWrapping = true; ((Graphic)obj2).color = new Color(0.73f, 0.81f, 0.84f, 1f); return obj; } private GameObject CreateModePage(Transform parent) { GameObject obj = CreatePage(parent, "ModePage", 628f); Transform transform = obj.transform; CreateSectionHeader(transform, "WATERBUCKET_PVP_SETTINGS_SECTION_MATCH_RULE"); AddChoiceRow(transform, "WATERBUCKET_PVP_SETTINGS_MATCH_MODE", GetMatchModeText, delegate { CycleMatchMode(-1); }, delegate { CycleMatchMode(1); }); AddIntegerRow(transform, "WATERBUCKET_PVP_SETTINGS_LIVES", PvPConfig.LivesPerPlayer, 1, 1, () => 99); AddIntegerRow(transform, "WATERBUCKET_PVP_SETTINGS_TIME_LIMIT", PvPConfig.TimeLimitMinutes, 1, 1, () => 120); CreateSectionHeader(transform, "WATERBUCKET_PVP_SETTINGS_SECTION_TEAMS"); AddToggleRow(transform, "WATERBUCKET_PVP_SETTINGS_MODE", () => (!PvPConfig.IsFfa) ? Language.GetString("WATERBUCKET_PVP_SETTINGS_TEAM_MODE") : "FFA", delegate { PvPConfig.AssignmentMode.Value = (PvPConfig.IsFfa ? "Team" : "FFA"); }); AddIntegerRow(transform, "WATERBUCKET_PVP_SETTINGS_TEAM_COUNT", PvPConfig.TeamCount, 1, 2, () => Math.Max(2, PvPTeamRegistry.Count)); AddToggleRow(transform, "WATERBUCKET_PVP_SETTINGS_FRIENDLY_FIRE", () => BoolText(PvPConfig.FriendlyFire.Value), delegate { PvPConfig.FriendlyFire.Value = !PvPConfig.FriendlyFire.Value; }); CreateSectionHeader(transform, "WATERBUCKET_PVP_SETTINGS_SECTION_RESPAWN"); AddDynamicFloatRow(transform, "WATERBUCKET_PVP_SETTINGS_RESPAWN_DELAY", () => PvPConfig.CurrentRespawnDelaySeconds, delegate(float value) { if (PvPConfig.CurrentMatchMode == PvPConfig.MatchModeKind.LimitedLives) { PvPConfig.LimitedLivesRespawnDelaySeconds.Value = value; } else { PvPConfig.RespawnDelaySeconds.Value = value; } }, 5f, 0.5f, () => (PvPConfig.CurrentMatchMode != PvPConfig.MatchModeKind.LimitedLives) ? 60f : 180f, SecondsText); AddFloatRow(transform, "WATERBUCKET_PVP_SETTINGS_RESPAWN_PROTECTION", PvPConfig.RespawnInvulnerabilitySeconds, 0.5f, 0f, 15f, SecondsText); CreateSectionHeader(transform, "WATERBUCKET_PVP_SETTINGS_SECTION_ROUTE"); AddToggleRow(transform, "WATERBUCKET_PVP_SETTINGS_STAGE_FIVE_ROUTE", () => Language.GetString(PvPConfig.StageFiveDefaultsToLoop ? "WATERBUCKET_PVP_SETTINGS_ROUTE_LOOP" : "WATERBUCKET_PVP_SETTINGS_ROUTE_MOON"), delegate { PvPConfig.StageFiveRoute.Value = (PvPConfig.StageFiveDefaultsToLoop ? "Moon" : "Loop"); }); return obj; } private GameObject CreateRulesPage(Transform parent) { GameObject obj = CreatePage(parent, "RulesPage", 628f); Transform transform = obj.transform; CreateSectionHeader(transform, "WATERBUCKET_PVP_SETTINGS_SECTION_MATCH"); AddFloatRow(transform, "WATERBUCKET_PVP_SETTINGS_PLAYER_PLAYER", PvPConfig.PlayerToPlayerDamage, 0.05f, 0f, 5f, (float value) => $"×{value:0.00}"); AddFloatRow(transform, "WATERBUCKET_PVP_SETTINGS_MINION_PLAYER", PvPConfig.MinionToPlayerDamage, 0.05f, 0f, 5f, (float value) => $"×{value:0.00}"); AddFloatRow(transform, "WATERBUCKET_PVP_SETTINGS_PLAYER_MINION", PvPConfig.PlayerToMinionDamage, 0.05f, 0f, 5f, (float value) => $"×{value:0.00}"); AddFloatRow(transform, "WATERBUCKET_PVP_SETTINGS_MINION_MINION", PvPConfig.MinionToMinionDamage, 0.05f, 0f, 5f, (float value) => $"×{value:0.00}"); AddFloatRow(transform, "WATERBUCKET_PVP_SETTINGS_CONTROL_DURATION", PvPConfig.PlayerControlDurationMultiplier, 0.1f, 0f, 5f, (float value) => $"×{value:0.00}"); CreateSectionHeader(transform, "WATERBUCKET_PVP_SETTINGS_SECTION_SPAWN"); AddFloatRow(transform, "WATERBUCKET_PVP_SETTINGS_FALLBACK_DISTANCE", PvPConfig.MinimumSpawnDistance, 5f, 10f, 200f, (float value) => $"{value:0} m"); AddFloatRow(transform, "WATERBUCKET_PVP_SETTINGS_TEAM_RADIUS", PvPConfig.TeamSpawnRadius, 2.5f, 0f, 50f, (float value) => $"{value:0.#} m"); AddFloatRow(transform, "WATERBUCKET_PVP_SETTINGS_SPAWN_PROTECTION", PvPConfig.SpawnInvulnerabilitySeconds, 0.5f, 0f, 15f, SecondsText); return obj; } private GameObject CreateTeamsPage(Transform parent) { //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Expected O, but got Unknown //IL_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_01a5: Unknown result type (might be due to invalid IL or missing references) GameObject val = CreatePage(parent, "TeamsPage", 628f); Transform transform = val.transform; currentChoiceText = CreateText(transform, string.Empty, 20f, (FontStyles)1, (TextAlignmentOptions)514, 42f, tokenized: false); ((Graphic)currentChoiceText).color = new Color(0.88f, 0.95f, 1f, 1f); GameObject val2 = new GameObject("TeamGrid", new Type[3] { typeof(RectTransform), typeof(GridLayoutGroup), typeof(LayoutElement) }); val2.layer = val.layer; val2.transform.SetParent(transform, false); LayoutElement component = val2.GetComponent(); component.preferredHeight = 188f; component.minHeight = 188f; GridLayoutGroup component2 = val2.GetComponent(); component2.cellSize = new Vector2(206f, 54f); component2.spacing = new Vector2(10f, 9f); component2.constraint = (Constraint)1; component2.constraintCount = 3; ((LayoutGroup)component2).childAlignment = (TextAnchor)1; CreateTeamButton(val2.transform, -1); for (int i = 0; i < PvPTeamRegistry.Count; i++) { CreateTeamButton(val2.transform, i); } CreateSectionHeader(transform, "WATERBUCKET_PVP_SETTINGS_TEAM_ROSTER"); rosterText = CreateText(transform, string.Empty, 18f, (FontStyles)0, (TextAlignmentOptions)257, 250f, tokenized: false); ((Component)rosterText).GetComponent().flexibleHeight = 1f; ((TMP_Text)rosterText).enableWordWrapping = true; ((Graphic)rosterText).color = new Color(0.8f, 0.87f, 0.9f, 1f); return val; } private GameObject CreateLoadoutPage(Transform parent) { //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Expected O, but got Unknown //IL_0160: Unknown result type (might be due to invalid IL or missing references) //IL_01c9: Unknown result type (might be due to invalid IL or missing references) //IL_01d3: Expected O, but got Unknown //IL_01df: Unknown result type (might be due to invalid IL or missing references) //IL_01e9: Expected O, but got Unknown //IL_025b: Unknown result type (might be due to invalid IL or missing references) //IL_0265: Expected O, but got Unknown //IL_0277: Unknown result type (might be due to invalid IL or missing references) //IL_0281: Expected O, but got Unknown //IL_02d5: Unknown result type (might be due to invalid IL or missing references) //IL_032b: Unknown result type (might be due to invalid IL or missing references) //IL_0332: Expected O, but got Unknown //IL_0384: Unknown result type (might be due to invalid IL or missing references) //IL_03cd: Unknown result type (might be due to invalid IL or missing references) //IL_03d4: Expected O, but got Unknown //IL_03fd: Unknown result type (might be due to invalid IL or missing references) //IL_0407: Expected O, but got Unknown //IL_0417: Unknown result type (might be due to invalid IL or missing references) //IL_0431: Unknown result type (might be due to invalid IL or missing references) //IL_044b: Unknown result type (might be due to invalid IL or missing references) //IL_0465: Unknown result type (might be due to invalid IL or missing references) //IL_047f: Unknown result type (might be due to invalid IL or missing references) //IL_049b: Unknown result type (might be due to invalid IL or missing references) //IL_04b0: Unknown result type (might be due to invalid IL or missing references) //IL_04bf: Unknown result type (might be due to invalid IL or missing references) //IL_04c9: Expected O, but got Unknown //IL_04f9: Unknown result type (might be due to invalid IL or missing references) //IL_0503: Expected O, but got Unknown //IL_0551: Unknown result type (might be due to invalid IL or missing references) //IL_055b: Expected O, but got Unknown //IL_009c: 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_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Expected O, but got Unknown GameObject val = CreatePage(parent, "LoadoutPage", 628f); Transform transform = val.transform; CreateSectionHeader(transform, "WATERBUCKET_PVP_LOADOUT_PRESETS"); Transform parent2 = CreateRow(transform); for (int i = 0; i < 5; i++) { int capturedSlot = i; MPButton val2 = CloneButton(parent2, string.Empty, tokenized: false, 112f, 44f); ((UnityEvent)((Button)val2).onClick).AddListener((UnityAction)delegate { LoadLoadoutPreset(capturedSlot); }); EventTrigger obj = ((Component)val2).gameObject.GetComponent() ?? ((Component)val2).gameObject.AddComponent(); Entry val3 = new Entry { eventID = (EventTriggerType)4 }; ((UnityEvent)(object)val3.callback).AddListener((UnityAction)delegate(BaseEventData data) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Invalid comparison between Unknown and I4 PointerEventData val9 = (PointerEventData)(object)((data is PointerEventData) ? data : null); if (val9 != null && (int)val9.button == 1) { SaveLoadoutPreset(capturedSlot); } }); obj.triggers.Add(val3); TMP_Text componentInChildren = ((Component)val2).GetComponentInChildren(true); if (Object.op_Implicit((Object)(object)componentInChildren)) { componentInChildren.fontSize = 14f; componentInChildren.alignment = (TextAlignmentOptions)514; } loadoutPresetButtons.Add((val2, componentInChildren, capturedSlot)); } loadoutPresetStatusText = CreateText(transform, "WATERBUCKET_PVP_LOADOUT_PRESET_HINT", 14f, (FontStyles)0, (TextAlignmentOptions)514, 25f, tokenized: true); ((Graphic)loadoutPresetStatusText).color = new Color(0.72f, 0.8f, 0.84f, 1f); Transform val4 = CreateRow(transform); CreateRowLabel(val4, "WATERBUCKET_PVP_LOADOUT_CATEGORY"); loadoutCategoryText = CreateValueText(val4); MPButton val5 = CloneButton(val4, "‹", tokenized: false, 58f, 38f); MPButton obj2 = CloneButton(val4, "›", tokenized: false, 58f, 38f); ((UnityEvent)((Button)val5).onClick).AddListener((UnityAction)delegate { CycleLoadoutCategory(-1); }); ((UnityEvent)((Button)obj2).onClick).AddListener((UnityAction)delegate { CycleLoadoutCategory(1); }); Transform val6 = CreateRow(transform); CreateRowLabel(val6, "WATERBUCKET_PVP_LOADOUT_ALLOWANCE"); loadoutBudgetText = CreateValueText(val6); loadoutBudgetDecreaseButton = CloneButton(val6, "−", tokenized: false, 58f, 38f); loadoutBudgetIncreaseButton = CloneButton(val6, "+", tokenized: false, 58f, 38f); ((UnityEvent)((Button)loadoutBudgetDecreaseButton).onClick).AddListener((UnityAction)delegate { ChangeLoadoutBudget(-1); }); ((UnityEvent)((Button)loadoutBudgetIncreaseButton).onClick).AddListener((UnityAction)delegate { ChangeLoadoutBudget(1); }); loadoutSelectedText = CreateText(transform, string.Empty, 19f, (FontStyles)1, (TextAlignmentOptions)514, 34f, tokenized: false); ((Graphic)CreateText(transform, "WATERBUCKET_PVP_LOADOUT_CLICK_HINT", 15f, (FontStyles)0, (TextAlignmentOptions)514, 27f, tokenized: true)).color = new Color(0.72f, 0.8f, 0.84f, 1f); GameObject val7 = new GameObject("LoadoutScroll", new Type[5] { typeof(RectTransform), typeof(Image), typeof(Mask), typeof(ScrollRect), typeof(LayoutElement) }); val7.layer = val.layer; val7.transform.SetParent(transform, false); LayoutElement component = val7.GetComponent(); component.minHeight = 300f; component.flexibleHeight = 1f; ((Graphic)val7.GetComponent()).color = new Color(0.018f, 0.032f, 0.045f, 0.94f); val7.GetComponent().showMaskGraphic = true; GameObject val8 = new GameObject("LoadoutGrid", new Type[3] { typeof(RectTransform), typeof(GridLayoutGroup), typeof(ContentSizeFitter) }); val8.layer = val.layer; val8.transform.SetParent(val7.transform, false); loadoutGrid = (RectTransform)val8.transform; loadoutGrid.anchorMin = new Vector2(0f, 1f); loadoutGrid.anchorMax = new Vector2(1f, 1f); loadoutGrid.pivot = new Vector2(0.5f, 1f); loadoutGrid.offsetMin = new Vector2(8f, 0f); loadoutGrid.offsetMax = new Vector2(-8f, 0f); GridLayoutGroup component2 = val8.GetComponent(); component2.cellSize = new Vector2(166f, 72f); component2.spacing = new Vector2(8f, 8f); ((LayoutGroup)component2).padding = new RectOffset(8, 8, 8, 8); component2.constraint = (Constraint)1; component2.constraintCount = 4; ((LayoutGroup)component2).childAlignment = (TextAnchor)1; val8.GetComponent().verticalFit = (FitMode)2; ScrollRect component3 = val7.GetComponent(); component3.viewport = (RectTransform)val7.transform; component3.content = loadoutGrid; component3.horizontal = false; component3.vertical = true; component3.movementType = (MovementType)2; component3.scrollSensitivity = 28f; ((UnityEvent)((Button)CloneButton(transform, "WATERBUCKET_PVP_LOADOUT_CLEAR", tokenized: true, -1f, 40f)).onClick).AddListener((UnityAction)delegate { PvPStartingLoadoutManager.ClearCategory(loadoutCategory); RefreshLoadoutPage(); }); RebuildLoadoutGrid(); return val; } private void SaveLoadoutPreset(int slotIndex) { int num = PvPLoadoutPresetStore.SaveSlot(slotIndex); ((TMP_Text)loadoutPresetStatusText).text = string.Format(Language.GetString("WATERBUCKET_PVP_LOADOUT_PRESET_SAVED"), slotIndex + 1, num); RefreshLoadoutPresetButtons(); } private void LoadLoadoutPreset(int slotIndex) { LoadoutPresetLoadResult loadoutPresetLoadResult = PvPLoadoutPresetStore.LoadSlot(slotIndex); if (!loadoutPresetLoadResult.Success) { ((TMP_Text)loadoutPresetStatusText).text = Language.GetString(PvPLoadoutPresetStore.IsSlotSaved(slotIndex) ? "WATERBUCKET_PVP_LOADOUT_PRESET_INVALID" : "WATERBUCKET_PVP_LOADOUT_PRESET_EMPTY"); return; } int num = PvPStartingLoadoutManager.RequestSelectionReplacement(loadoutPresetLoadResult.Selections); int num2 = Math.Max(0, loadoutPresetLoadResult.SavedCount - num); ((TMP_Text)loadoutPresetStatusText).text = string.Format(Language.GetString("WATERBUCKET_PVP_LOADOUT_PRESET_LOADED"), slotIndex + 1, num, num2); RefreshLoadoutPage(); } private void RefreshLoadoutPresetButtons() { //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) foreach (var (val, val2, num) in loadoutPresetButtons) { if (Object.op_Implicit((Object)(object)val2)) { bool flag = PvPLoadoutPresetStore.IsSlotSaved(num); val2.text = string.Format(Language.GetString(flag ? "WATERBUCKET_PVP_LOADOUT_PRESET_SLOT_SAVED" : "WATERBUCKET_PVP_LOADOUT_PRESET_SLOT_EMPTY"), num + 1); ((Graphic)val2).color = (flag ? new Color(1f, 0.76f, 0.3f, 1f) : new Color(0.78f, 0.86f, 0.9f, 1f)); ((Selectable)val).interactable = true; } } } private void CycleLoadoutCategory(int direction) { int num = 9; int num2 = ((int)loadoutCategory + direction) % num; if (num2 < 0) { num2 += num; } loadoutCategory = (StartingLoadoutCategory)num2; RebuildLoadoutGrid(); PvPStartingLoadoutManager.RequestSync(); RefreshLoadoutPage(); } private void ChangeLoadoutBudget(int delta) { if (NetworkServer.active) { ConfigEntry budgetEntry = PvPStartingLoadoutManager.GetBudgetEntry(loadoutCategory); budgetEntry.Value = Math.Clamp(budgetEntry.Value + delta, 0, PvPStartingLoadoutManager.GetMaximumBudget(loadoutCategory)); PvPStartingLoadoutManager.NotifyHostBudgetsChanged(); RefreshLoadoutPage(); } } private void RebuildLoadoutGrid() { //IL_0022: 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_00bc: Expected O, but got Unknown //IL_013f: Unknown result type (might be due to invalid IL or missing references) //IL_0144: Unknown result type (might be due to invalid IL or missing references) //IL_0156: Unknown result type (might be due to invalid IL or missing references) //IL_0169: Unknown result type (might be due to invalid IL or missing references) //IL_016f: Unknown result type (might be due to invalid IL or missing references) //IL_0174: Unknown result type (might be due to invalid IL or missing references) //IL_017f: Unknown result type (might be due to invalid IL or missing references) //IL_0189: Unknown result type (might be due to invalid IL or missing references) //IL_0194: Unknown result type (might be due to invalid IL or missing references) //IL_019e: Unknown result type (might be due to invalid IL or missing references) //IL_01a9: Unknown result type (might be due to invalid IL or missing references) //IL_01b3: Unknown result type (might be due to invalid IL or missing references) //IL_01be: Unknown result type (might be due to invalid IL or missing references) //IL_01d2: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_010b: Unknown result type (might be due to invalid IL or missing references) //IL_0110: Unknown result type (might be due to invalid IL or missing references) //IL_0243: Unknown result type (might be due to invalid IL or missing references) //IL_0248: Unknown result type (might be due to invalid IL or missing references) //IL_024a: Unknown result type (might be due to invalid IL or missing references) //IL_0251: Expected O, but got Unknown if (!Object.op_Implicit((Object)(object)loadoutGrid)) { return; } foreach (Transform item in (Transform)loadoutGrid) { Object.Destroy((Object)(object)((Component)item).gameObject); } loadoutButtons.Clear(); foreach (StartingLoadoutOption option in PvPStartingLoadoutManager.GetAvailableDefinitions(loadoutCategory)) { MPButton val = CloneButton((Transform)(object)loadoutGrid, string.Empty, tokenized: false, 166f, 72f); ((UnityEvent)((Button)val).onClick).AddListener((UnityAction)delegate { PvPStartingLoadoutManager.RequestSelectionChange(loadoutCategory, option.DefinitionIndex, option.IsEquipment, 1); RefreshLoadoutPage(); }); TMP_Text componentInChildren = ((Component)val).GetComponentInChildren(true); if (Object.op_Implicit((Object)(object)componentInChildren)) { componentInChildren.fontSize = 13f; componentInChildren.alignment = (TextAlignmentOptions)514; componentInChildren.enableWordWrapping = true; RectTransform val2 = (RectTransform)componentInChildren.transform; val2.offsetMin += new Vector2(44f, 0f); } GameObject val3 = new GameObject("Icon", new Type[2] { typeof(RectTransform), typeof(Image) }) { layer = ((Component)val).gameObject.layer }; val3.transform.SetParent(((Component)val).transform, false); RectTransform val4 = (RectTransform)val3.transform; val4.anchorMin = new Vector2(0f, 0.5f); val4.anchorMax = new Vector2(0f, 0.5f); val4.pivot = new Vector2(0f, 0.5f); val4.anchoredPosition = new Vector2(6f, 0f); val4.sizeDelta = new Vector2(40f, 40f); Image component = val3.GetComponent(); component.sprite = PvPStartingLoadoutManager.GetDefinitionIcon(loadoutCategory, option.DefinitionIndex, option.IsEquipment); component.preserveAspect = true; ((Graphic)component).raycastTarget = false; AddLoadoutTooltip(((Component)val).gameObject, option); EventTrigger obj = ((Component)val).gameObject.GetComponent() ?? ((Component)val).gameObject.AddComponent(); Entry val5 = new Entry { eventID = (EventTriggerType)4 }; ((UnityEvent)(object)val5.callback).AddListener((UnityAction)delegate(BaseEventData data) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Invalid comparison between Unknown and I4 PointerEventData val6 = (PointerEventData)(object)((data is PointerEventData) ? data : null); if (val6 != null && (int)val6.button == 1) { PvPStartingLoadoutManager.RequestSelectionChange(loadoutCategory, option.DefinitionIndex, option.IsEquipment, -1); RefreshLoadoutPage(); } }); obj.triggers.Add(val5); loadoutButtons.Add((val, option, componentInChildren)); } } private static void AddLoadoutTooltip(GameObject target, StartingLoadoutOption option) { //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_011a: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_0136: Unknown result type (might be due to invalid IL or missing references) //IL_013b: Unknown result type (might be due to invalid IL or missing references) //IL_0140: Unknown result type (might be due to invalid IL or missing references) //IL_012e: Unknown result type (might be due to invalid IL or missing references) //IL_0145: Unknown result type (might be due to invalid IL or missing references) TooltipProvider val = target.GetComponent() ?? target.AddComponent(); val.overrideTitleText = string.Empty; val.overrideBodyText = string.Empty; val.bodyColor = Color.white; val.AllowTooltipOnNavigationSelect = true; val.disableTitleRichText = false; val.disableBodyRichText = false; if (option.IsEquipment) { EquipmentDef equipmentDef = EquipmentCatalog.GetEquipmentDef((EquipmentIndex)option.DefinitionIndex); if (!Object.op_Implicit((Object)(object)equipmentDef)) { val.titleToken = string.Empty; val.bodyToken = string.Empty; } else { val.titleToken = equipmentDef.nameToken; val.bodyToken = (string.IsNullOrEmpty(equipmentDef.descriptionToken) ? equipmentDef.pickupToken : equipmentDef.descriptionToken); val.titleColor = Color32.op_Implicit(ColorCatalog.GetColor(equipmentDef.colorIndex)); } return; } ItemDef itemDef = ItemCatalog.GetItemDef((ItemIndex)option.DefinitionIndex); if (!Object.op_Implicit((Object)(object)itemDef)) { val.titleToken = string.Empty; val.bodyToken = string.Empty; return; } val.titleToken = itemDef.nameToken; val.bodyToken = (string.IsNullOrEmpty(itemDef.descriptionToken) ? itemDef.pickupToken : itemDef.descriptionToken); ItemTierDef itemTierDef = ItemTierCatalog.GetItemTierDef(itemDef.tier); val.titleColor = (Object.op_Implicit((Object)(object)itemTierDef) ? Color32.op_Implicit(ColorCatalog.GetColor(itemTierDef.colorIndex)) : Color.white); } private void RefreshLoadoutPage() { //IL_0179: Unknown result type (might be due to invalid IL or missing references) //IL_015e: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)loadoutCategoryText) || !Object.op_Implicit((Object)(object)loadoutBudgetText) || !Object.op_Implicit((Object)(object)loadoutSelectedText)) { return; } int clientBudget = PvPStartingLoadoutManager.GetClientBudget(loadoutCategory); int clientSelectedCount = PvPStartingLoadoutManager.GetClientSelectedCount(loadoutCategory); ((TMP_Text)loadoutCategoryText).text = Language.GetString(GetLoadoutCategoryToken(loadoutCategory)); ((TMP_Text)loadoutBudgetText).text = clientBudget.ToString(); ((TMP_Text)loadoutSelectedText).text = string.Format(Language.GetString("WATERBUCKET_PVP_LOADOUT_SELECTED"), clientSelectedCount, clientBudget); ((Selectable)loadoutBudgetDecreaseButton).interactable = NetworkServer.active && clientBudget > 0; ((Selectable)loadoutBudgetIncreaseButton).interactable = NetworkServer.active && clientBudget < PvPStartingLoadoutManager.GetMaximumBudget(loadoutCategory); RefreshLoadoutPresetButtons(); foreach (var loadoutButton in loadoutButtons) { MPButton item = loadoutButton.Button; StartingLoadoutOption item2 = loadoutButton.Option; TMP_Text item3 = loadoutButton.Label; int clientChoiceCount = PvPStartingLoadoutManager.GetClientChoiceCount(loadoutCategory, item2.DefinitionIndex, item2.IsEquipment); string definitionName = PvPStartingLoadoutManager.GetDefinitionName(loadoutCategory, item2.DefinitionIndex, item2.IsEquipment); item3.text = ((clientChoiceCount > 0) ? $"{definitionName}\n×{clientChoiceCount}" : definitionName); ((Graphic)item3).color = (Color)((clientChoiceCount > 0) ? new Color(1f, 0.76f, 0.3f, 1f) : Color.white); ((Selectable)item).interactable = clientChoiceCount > 0 || clientSelectedCount < clientBudget; } } private GameObject CreatePage(Transform parent, string name, float preferredHeight) { //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_0044: 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_0068: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Expected O, but got Unknown GameObject val = new GameObject(name, new Type[3] { typeof(RectTransform), typeof(VerticalLayoutGroup), typeof(LayoutElement) }) { layer = ((Component)parent).gameObject.layer }; val.transform.SetParent(parent, false); LayoutElement component = val.GetComponent(); component.preferredHeight = preferredHeight; component.flexibleHeight = 1f; VerticalLayoutGroup component2 = val.GetComponent(); ((HorizontalOrVerticalLayoutGroup)component2).spacing = 3f; ((LayoutGroup)component2).childAlignment = (TextAnchor)1; ((HorizontalOrVerticalLayoutGroup)component2).childControlHeight = true; ((HorizontalOrVerticalLayoutGroup)component2).childControlWidth = true; ((HorizontalOrVerticalLayoutGroup)component2).childForceExpandHeight = false; ((HorizontalOrVerticalLayoutGroup)component2).childForceExpandWidth = true; return val; } private void CreateSectionHeader(Transform parent, string textOrToken, bool tokenized = true) { //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Expected O, but got Unknown //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Expected O, but got Unknown //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("SectionHeader", new Type[3] { typeof(RectTransform), typeof(Image), typeof(LayoutElement) }); val.layer = ((Component)parent).gameObject.layer; val.transform.SetParent(parent, false); val.GetComponent().preferredHeight = 27f; ((Graphic)val.GetComponent()).color = new Color(0.08f, 0.16f, 0.21f, 0.92f); HGTextMeshProUGUI obj = CreateText(val.transform, textOrToken, 15f, (FontStyles)1, (TextAlignmentOptions)4097, 27f, tokenized); RectTransform val2 = (RectTransform)((TMP_Text)obj).transform; Stretch(val2); val2.offsetMin = new Vector2(12f, 0f); val2.offsetMax = new Vector2(-8f, 0f); ((Graphic)obj).color = new Color(0.49f, 0.82f, 0.96f, 1f); } private void CreateTeamButton(Transform parent, int teamId) { //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Expected O, but got Unknown MPButton val = CloneButton(parent, GetTeamButtonText(teamId), tokenized: false, 206f, 54f); ((UnityEvent)((Button)val).onClick).AddListener((UnityAction)delegate { ChooseTeam(teamId); }); teamButtons.Add((val, teamId)); } private void AddModuleToggleRow(Transform parent, string label, ResonatorModules.ModuleKind module) { //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Expected O, but got Unknown Transform val = CreateRow(parent); LayoutElement component = ((Component)CreateText(val, label, 17f, (FontStyles)0, (TextAlignmentOptions)4097, 36f, tokenized: false)).GetComponent(); component.preferredWidth = 400f; component.flexibleWidth = 2.8f; HGTextMeshProUGUI valueText = CreateValueText(val); MPButton toggleButton = CloneButton(val, "切换", tokenized: false, 124f, 38f); ((UnityEvent)((Button)toggleButton).onClick).AddListener((UnityAction)delegate { if (NetworkServer.active) { bool lobbyEnabled = ResonatorModules.GetLobbyEnabled(module); ResonatorModules.SetHostEnabled(module, !lobbyEnabled); RefreshValues(); RefreshPvPTabAvailability(force: true); } }); valueRefreshers.Add(delegate { ((TMP_Text)valueText).text = BoolText(ResonatorModules.GetLobbyEnabled(module)); ((Selectable)toggleButton).interactable = NetworkServer.active; }); } private void AddToggleRow(Transform parent, string labelToken, Func getValue, Action toggle) { //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Expected O, but got Unknown //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Expected O, but got Unknown Transform val = CreateRow(parent); CreateRowLabel(val, labelToken); HGTextMeshProUGUI valueText = CreateValueText(val); MPButton val2 = CloneButton(val, "‹", tokenized: false, 58f, 38f); MPButton obj = CloneButton(val, "›", tokenized: false, 58f, 38f); ((UnityEvent)((Button)val2).onClick).AddListener((UnityAction)delegate { toggle(); RefreshValues(); }); ((UnityEvent)((Button)obj).onClick).AddListener((UnityAction)delegate { toggle(); RefreshValues(); }); if (firstRulesButton == null) { firstRulesButton = val2; } valueRefreshers.Add(delegate { ((TMP_Text)valueText).text = getValue(); }); } private void AddChoiceRow(Transform parent, string labelToken, Func getValue, Action previousChoice, Action nextChoice) { //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Expected O, but got Unknown //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Expected O, but got Unknown Transform val = CreateRow(parent); CreateRowLabel(val, labelToken); HGTextMeshProUGUI valueText = CreateValueText(val); MPButton val2 = CloneButton(val, "‹", tokenized: false, 58f, 38f); MPButton obj = CloneButton(val, "›", tokenized: false, 58f, 38f); ((UnityEvent)((Button)val2).onClick).AddListener((UnityAction)delegate { previousChoice(); RefreshValues(); }); ((UnityEvent)((Button)obj).onClick).AddListener((UnityAction)delegate { nextChoice(); RefreshValues(); }); valueRefreshers.Add(delegate { ((TMP_Text)valueText).text = getValue(); }); } private void AddIntegerRow(Transform parent, string labelToken, ConfigEntry entry, int step, int minimum, Func getMaximum) { //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Expected O, but got Unknown //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Expected O, but got Unknown Transform val = CreateRow(parent); CreateRowLabel(val, labelToken); HGTextMeshProUGUI valueText = CreateValueText(val); MPButton val2 = CloneButton(val, "−", tokenized: false, 58f, 38f); MPButton obj = CloneButton(val, "+", tokenized: false, 58f, 38f); ((UnityEvent)((Button)val2).onClick).AddListener((UnityAction)delegate { entry.Value = Math.Clamp(entry.Value - step, minimum, getMaximum()); RefreshValues(); }); ((UnityEvent)((Button)obj).onClick).AddListener((UnityAction)delegate { entry.Value = Math.Clamp(entry.Value + step, minimum, getMaximum()); RefreshValues(); }); if (firstRulesButton == null) { firstRulesButton = val2; } valueRefreshers.Add(delegate { ((TMP_Text)valueText).text = entry.Value.ToString(); }); } private void AddFloatRow(Transform parent, string labelToken, ConfigEntry entry, float step, float minimum, float maximum, Func formatter) { //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Expected O, but got Unknown //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Expected O, but got Unknown Transform val = CreateRow(parent); CreateRowLabel(val, labelToken); HGTextMeshProUGUI valueText = CreateValueText(val); MPButton val2 = CloneButton(val, "−", tokenized: false, 58f, 38f); MPButton obj = CloneButton(val, "+", tokenized: false, 58f, 38f); ((UnityEvent)((Button)val2).onClick).AddListener((UnityAction)delegate { entry.Value = Mathf.Clamp(entry.Value - step, minimum, maximum); RefreshValues(); }); ((UnityEvent)((Button)obj).onClick).AddListener((UnityAction)delegate { entry.Value = Mathf.Clamp(entry.Value + step, minimum, maximum); RefreshValues(); }); if (firstRulesButton == null) { firstRulesButton = val2; } valueRefreshers.Add(delegate { ((TMP_Text)valueText).text = formatter(entry.Value); }); } private void AddDynamicFloatRow(Transform parent, string labelToken, Func getValue, Action setValue, float step, float minimum, Func getMaximum, Func formatter) { //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Expected O, but got Unknown //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Expected O, but got Unknown Transform val = CreateRow(parent); CreateRowLabel(val, labelToken); HGTextMeshProUGUI valueText = CreateValueText(val); MPButton val2 = CloneButton(val, "−", tokenized: false, 58f, 38f); MPButton obj = CloneButton(val, "+", tokenized: false, 58f, 38f); ((UnityEvent)((Button)val2).onClick).AddListener((UnityAction)delegate { setValue(Mathf.Clamp(getValue() - step, minimum, getMaximum())); RefreshValues(); }); ((UnityEvent)((Button)obj).onClick).AddListener((UnityAction)delegate { setValue(Mathf.Clamp(getValue() + step, minimum, getMaximum())); RefreshValues(); }); valueRefreshers.Add(delegate { ((TMP_Text)valueText).text = formatter(getValue()); }); } private Transform CreateRow(Transform parent) { //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0048: 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_0070: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("SettingRow", new Type[3] { typeof(RectTransform), typeof(HorizontalLayoutGroup), typeof(LayoutElement) }) { layer = ((Component)parent).gameObject.layer }; val.transform.SetParent(parent, false); LayoutElement component = val.GetComponent(); component.preferredHeight = 38f; component.minHeight = 32f; HorizontalLayoutGroup component2 = val.GetComponent(); ((HorizontalOrVerticalLayoutGroup)component2).spacing = 8f; ((LayoutGroup)component2).childAlignment = (TextAnchor)4; ((HorizontalOrVerticalLayoutGroup)component2).childControlHeight = true; ((HorizontalOrVerticalLayoutGroup)component2).childControlWidth = true; ((HorizontalOrVerticalLayoutGroup)component2).childForceExpandHeight = true; ((HorizontalOrVerticalLayoutGroup)component2).childForceExpandWidth = false; return val.transform; } private void CreateRowLabel(Transform row, string labelToken) { LayoutElement component = ((Component)CreateText(row, labelToken, 17f, (FontStyles)0, (TextAlignmentOptions)4097, 36f, tokenized: true)).GetComponent(); component.preferredWidth = 400f; component.flexibleWidth = 2.8f; } private HGTextMeshProUGUI CreateValueText(Transform row) { HGTextMeshProUGUI obj = CreateText(row, string.Empty, 17f, (FontStyles)1, (TextAlignmentOptions)514, 36f, tokenized: false); LayoutElement component = ((Component)obj).GetComponent(); component.preferredWidth = 145f; component.flexibleWidth = 1f; return obj; } private HGTextMeshProUGUI CreateText(Transform parent, string textOrToken, float fontSize, FontStyles style, TextAlignmentOptions alignment, float preferredHeight, bool tokenized) { //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("Text", new Type[2] { typeof(RectTransform), typeof(LayoutElement) }) { layer = ((Component)parent).gameObject.layer }; val.SetActive(false); val.transform.SetParent(parent, false); HGTextMeshProUGUI val2 = val.AddComponent(); TMP_Text componentInChildren = ((Component)buttonTemplate).GetComponentInChildren(true); if (Object.op_Implicit((Object)(object)componentInChildren)) { ((TMP_Text)val2).font = componentInChildren.font; ((TMP_Text)val2).fontSharedMaterial = componentInChildren.fontSharedMaterial; } ((TMP_Text)val2).fontSize = fontSize; ((TMP_Text)val2).fontStyle = style; ((TMP_Text)val2).alignment = alignment; ((Graphic)val2).color = Color.white; ((Graphic)val2).raycastTarget = false; ((TMP_Text)val2).enableWordWrapping = false; ((TMP_Text)val2).text = (tokenized ? Language.GetString(textOrToken) : textOrToken); LayoutElement component = val.GetComponent(); component.preferredHeight = preferredHeight; component.minHeight = Math.Min(24f, preferredHeight); val.SetActive(true); return val2; } private MPButton CloneButton(Transform parent, string textOrToken, bool tokenized, float preferredWidth, float preferredHeight) { GameObject val = Object.Instantiate(((Component)buttonTemplate).gameObject, parent, false); ((Object)val).name = "PvPSettingButton"; val.SetActive(true); MPButton component = val.GetComponent(); ResetButton(component, textOrToken, tokenized); ApplyNativeSettingsStyle(component); LayoutElement val2 = val.GetComponent() ?? val.AddComponent(); if (preferredWidth > 0f) { val2.preferredWidth = preferredWidth; } else { val2.flexibleWidth = 1f; } val2.preferredHeight = preferredHeight; val2.minHeight = Math.Min(32f, preferredHeight); return component; } private static void ResetButton(MPButton button, string textOrToken, bool tokenized) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Expected O, but got Unknown //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) ((Button)button).onClick = new ButtonClickedEvent(); ((Selectable)button).interactable = true; Navigation navigation = default(Navigation); ((Navigation)(ref navigation)).mode = (Mode)3; ((Selectable)button).navigation = navigation; button.defaultFallbackButton = false; HGButton val = (HGButton)(object)((button is HGButton) ? button : null); if (val != null) { val.updateTextOnHover = false; val.hoverToken = string.Empty; ((MPButton)val).defaultFallbackButton = false; } TMP_Text componentInChildren = ((Component)button).GetComponentInChildren(true); if (!Object.op_Implicit((Object)(object)componentInChildren)) { return; } LanguageTextMeshController component = ((Component)componentInChildren).GetComponent(); if (tokenized && Object.op_Implicit((Object)(object)component)) { ((Behaviour)component).enabled = true; component.token = textOrToken; return; } if (Object.op_Implicit((Object)(object)component)) { ((Behaviour)component).enabled = false; } componentInChildren.text = (tokenized ? Language.GetString(textOrToken) : textOrToken); } private void LoadNativeSettingsStyle() { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) GameObject val = Addressables.LoadAssetAsync((object)"RoR2/Base/UI/Generic UI/Prefab/SettingsEntryButton, Carousel.prefab").WaitForCompletion(); settingsStyleTemplate = (Object.op_Implicit((Object)(object)val) ? val.GetComponentInChildren(true) : null); if (Object.op_Implicit((Object)(object)settingsStyleTemplate)) { Plugin.Log.LogDebug((object)"Using native settings button style from 'RoR2/Base/UI/Generic UI/Prefab/SettingsEntryButton, Carousel.prefab'."); } else { Plugin.Log.LogWarning((object)"Could not find an MPButton in 'RoR2/Base/UI/Generic UI/Prefab/SettingsEntryButton, Carousel.prefab'; using the neutral settings fallback."); } GameObject val2 = Addressables.LoadAssetAsync((object)"RoR2/Base/UI/Generic UI/Prefab/SettingsSubPanel.prefab").WaitForCompletion(); settingsPanelStyleTemplate = (Object.op_Implicit((Object)(object)val2) ? val2.GetComponent() : null); } private void ApplyNativePanelStyle(Image targetImage) { //IL_0039: 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) Image val = settingsPanelStyleTemplate; if (val != null && Object.op_Implicit((Object)(object)val)) { targetImage.sprite = val.sprite; targetImage.overrideSprite = val.overrideSprite; ((Graphic)targetImage).material = ((Graphic)val).material; targetImage.type = val.type; targetImage.preserveAspect = val.preserveAspect; targetImage.fillCenter = val.fillCenter; targetImage.pixelsPerUnitMultiplier = val.pixelsPerUnitMultiplier; ((Graphic)targetImage).color = ((Graphic)val).color; } } private void ApplyNativeSettingsStyle(MPButton button) { //IL_010e: Unknown result type (might be due to invalid IL or missing references) //IL_0113: Unknown result type (might be due to invalid IL or missing references) //IL_012a: Unknown result type (might be due to invalid IL or missing references) //IL_014a: Unknown result type (might be due to invalid IL or missing references) //IL_016a: Unknown result type (might be due to invalid IL or missing references) //IL_018a: Unknown result type (might be due to invalid IL or missing references) //IL_01aa: Unknown result type (might be due to invalid IL or missing references) //IL_01c1: Unknown result type (might be due to invalid IL or missing references) //IL_01e5: 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_0026: 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_0098: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) MPButton val = settingsStyleTemplate; Image[] componentsInChildren; if (val != null && Object.op_Implicit((Object)(object)val)) { ((Selectable)button).transition = ((Selectable)val).transition; ((Selectable)button).colors = ((Selectable)val).colors; ((Selectable)button).spriteState = ((Selectable)val).spriteState; ((Selectable)button).animationTriggers = ((Selectable)val).animationTriggers; Graphic targetGraphic = ((Selectable)val).targetGraphic; Image val2 = (Image)(object)((targetGraphic is Image) ? targetGraphic : null); if (val2 != null) { Graphic targetGraphic2 = ((Selectable)button).targetGraphic; Image val3 = (Image)(object)((targetGraphic2 is Image) ? targetGraphic2 : null); if (val3 != null) { val3.sprite = val2.sprite; val3.overrideSprite = val2.overrideSprite; ((Graphic)val3).material = ((Graphic)val2).material; val3.type = val2.type; val3.preserveAspect = val2.preserveAspect; val3.fillCenter = val2.fillCenter; val3.pixelsPerUnitMultiplier = val2.pixelsPerUnitMultiplier; ((Graphic)val3).color = ((Graphic)val2).color; componentsInChildren = ((Component)button).GetComponentsInChildren(true); foreach (Image val4 in componentsInChildren) { if ((Object)(object)val4 != (Object)(object)val3) { ((Behaviour)val4).enabled = false; } } return; } } } ColorBlock colors = ((Selectable)button).colors; ((ColorBlock)(ref colors)).normalColor = new Color(0.2f, 0.25f, 0.27f, 1f); ((ColorBlock)(ref colors)).highlightedColor = new Color(0.34f, 0.48f, 0.53f, 1f); ((ColorBlock)(ref colors)).pressedColor = new Color(0.12f, 0.18f, 0.21f, 1f); ((ColorBlock)(ref colors)).selectedColor = new Color(0.31f, 0.43f, 0.48f, 1f); ((ColorBlock)(ref colors)).disabledColor = new Color(0.13f, 0.15f, 0.16f, 0.72f); ((ColorBlock)(ref colors)).colorMultiplier = 1f; ((Selectable)button).colors = colors; Graphic targetGraphic3 = ((Selectable)button).targetGraphic; Image val5 = (Image)(object)((targetGraphic3 is Image) ? targetGraphic3 : null); if (val5 == null) { return; } val5.sprite = null; val5.overrideSprite = null; ((Graphic)val5).color = Color.white; componentsInChildren = ((Component)button).GetComponentsInChildren(true); foreach (Image val6 in componentsInChildren) { if ((Object)(object)val6 != (Object)(object)val5) { ((Behaviour)val6).enabled = false; } } } private void OpenPanel() { //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Unknown result type (might be due to invalid IL or missing references) NetworkUser localNetworkUser = GetLocalNetworkUser(); if (NetworkServer.active && localNetworkUser != null && Object.op_Implicit((Object)(object)localNetworkUser) && PvPTeamManager.TryGetLobbySelection(localNetworkUser, out var teamId)) { localLobbySelection = teamId; } Plugin.Log.LogInfo((object)"Opening Resonators of the Soul lobby settings panel."); overlayObject.transform.SetAsLastSibling(); overlayObject.SetActive(true); ResonatorModules.RequestSync(); RefreshPvPTabAvailability(force: true); if (IsPvPConfigurationAvailable()) { PvPStartingLoadoutManager.RequestSync(); } ShowPage(0); RefreshValues(); if (IsPvPConfigurationAvailable()) { RefreshTeamPage(); } Canvas.ForceUpdateCanvases(); ManualLogSource log = Plugin.Log; Rect rect = overlayRect.rect; object arg = ((Rect)(ref rect)).width; rect = overlayRect.rect; string text = $"Resonators of the Soul settings panel active: overlay={arg:0}x{((Rect)(ref rect)).height:0}, "; rect = panelRect.rect; object arg2 = ((Rect)(ref rect)).width; rect = panelRect.rect; log.LogDebug((object)(text + $"panel={arg2:0}x{((Rect)(ref rect)).height:0}.")); } private void ShowPage(int requestedPage) { int num = Math.Clamp(requestedPage, 0, 4); bool flag = IsPvPConfigurationAvailable(); if (num != 0 && !flag) { num = 0; } else if (!NetworkServer.active && (num == 1 || num == 2)) { num = 0; } currentPage = num; modulesPageObject.SetActive(currentPage == 0); modePageObject.SetActive(currentPage == 1); rulesPageObject.SetActive(currentPage == 2); teamsPageObject.SetActive(currentPage == 3); loadoutPageObject.SetActive(currentPage == 4); HGTextMeshProUGUI val = pageHintText; string text = ((currentPage != 0) ? Language.GetString(currentPage switch { 1 => "WATERBUCKET_PVP_SETTINGS_MODE_HINT", 2 => "WATERBUCKET_PVP_SETTINGS_HINT", 3 => "WATERBUCKET_PVP_SETTINGS_TEAM_HINT", _ => "WATERBUCKET_PVP_LOADOUT_HINT", }) : (NetworkServer.active ? "选择本房间启用的功能模块;设置会同步给所有玩家。" : "当前显示房主同步的模块设置;只有房主可以修改。")); ((TMP_Text)val).text = text; ((Selectable)modulesTabButton).interactable = true; ((Selectable)modeTabButton).interactable = flag && NetworkServer.active; ((Selectable)rulesTabButton).interactable = flag && NetworkServer.active; ((Selectable)teamsTabButton).interactable = flag; ((Selectable)loadoutTabButton).interactable = flag; SetTabVisual(modulesTabButton, currentPage == 0); SetTabVisual(modeTabButton, currentPage == 1); SetTabVisual(rulesTabButton, currentPage == 2); SetTabVisual(teamsTabButton, currentPage == 3); SetTabVisual(loadoutTabButton, currentPage == 4); if (currentPage == 0) { RefreshValues(); ((Selectable)modulesTabButton).Select(); } else if (currentPage == 1 || currentPage == 2) { RefreshValues(); ((Selectable)((currentPage == 1) ? modeTabButton : rulesTabButton)).Select(); } else if (currentPage == 3) { RefreshTeamPage(); MPButton item = teamButtons.FirstOrDefault<(MPButton, int)>(((MPButton Button, int TeamId) entry) => entry.TeamId == localLobbySelection).Item1; if (item != null) { ((Selectable)item).Select(); } } else { PvPStartingLoadoutManager.RequestSync(); RefreshLoadoutPage(); ((Selectable)loadoutTabButton).Select(); } } private void RefreshPvPTabAvailability(bool force) { if (!Object.op_Implicit((Object)(object)modulesTabButton)) { return; } bool flag = IsPvPConfigurationAvailable(); if (force || flag != wasPvPConfigurationAvailable) { wasPvPConfigurationAvailable = flag; ((Component)modeTabButton).gameObject.SetActive(flag); ((Component)rulesTabButton).gameObject.SetActive(flag); ((Component)teamsTabButton).gameObject.SetActive(flag); ((Component)loadoutTabButton).gameObject.SetActive(flag); if (!flag && currentPage != 0) { ShowPage(0); return; } ((Selectable)modeTabButton).interactable = flag && NetworkServer.active; ((Selectable)rulesTabButton).interactable = flag && NetworkServer.active; ((Selectable)teamsTabButton).interactable = flag; ((Selectable)loadoutTabButton).interactable = flag; } } private static void SetTabVisual(MPButton button, bool selected) { //IL_0051: 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) TMP_Text componentInChildren = ((Component)button).GetComponentInChildren(true); if (Object.op_Implicit((Object)(object)componentInChildren)) { componentInChildren.fontStyle = (FontStyles)(selected ? 1 : 0); ((Graphic)componentInChildren).color = (selected ? new Color(1f, 0.72f, 0.28f, 1f) : new Color(0.78f, 0.86f, 0.9f, 1f)); } } private void ChooseTeam(int teamId) { NetworkUser localNetworkUser = GetLocalNetworkUser(); if (localNetworkUser == null || !Object.op_Implicit((Object)(object)localNetworkUser) || !IsPvPModeSelected()) { return; } NetworkUser val = localNetworkUser; if (NetworkServer.active) { if (!PvPTeamManager.SetLobbySelection(val, teamId)) { return; } } else { string text = "WATERBUCKET_PVP_TEAM:" + teamId; Console.instance.SubmitCmd(val, "say \"" + text + "\"", false); } localLobbySelection = teamId; RefreshTeamPage(); } private void RefreshTeamPage() { //IL_00fa: Unknown result type (might be due to invalid IL or missing references) //IL_00f3: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)currentChoiceText) || !Object.op_Implicit((Object)(object)rosterText)) { return; } NetworkUser localNetworkUser = GetLocalNetworkUser(); if (NetworkServer.active && localNetworkUser != null && Object.op_Implicit((Object)(object)localNetworkUser)) { localLobbySelection = (PvPTeamManager.TryGetLobbySelection(localNetworkUser, out var teamId) ? teamId : (-1)); } ((TMP_Text)currentChoiceText).text = Language.GetString("WATERBUCKET_PVP_SETTINGS_TEAM_CURRENT") + ":" + GetTeamButtonText(localLobbySelection); foreach (var teamButton in teamButtons) { MPButton item = teamButton.Button; int item2 = teamButton.TeamId; bool flag = item2 == localLobbySelection; TMP_Text componentInChildren = ((Component)item).GetComponentInChildren(true); if (Object.op_Implicit((Object)(object)componentInChildren)) { componentInChildren.text = (flag ? ("◆ " + GetTeamButtonText(item2)) : GetTeamButtonText(item2)); componentInChildren.fontStyle = (FontStyles)(flag ? 1 : 0); ((Graphic)componentInChildren).color = (flag ? Color.white : GetTeamColor(item2)); } } List list = new List(); foreach (NetworkUser item3 in NetworkUser.readOnlyInstancesList.Where((NetworkUser user) => Object.op_Implicit((Object)(object)user)).OrderBy((NetworkUser user) => user.userName, StringComparer.CurrentCultureIgnoreCase)) { int teamId2 = -1; bool flag2 = false; if (NetworkServer.active) { flag2 = PvPTeamManager.TryGetLobbySelection(item3, out teamId2); } else if (Object.op_Implicit((Object)(object)localNetworkUser) && (Object)(object)item3 == (Object)(object)localNetworkUser) { teamId2 = localLobbySelection; flag2 = teamId2 >= 0; } string text = (flag2 ? Language.GetString(PvPTeamRegistry.GetTeamNameToken(teamId2)) : Language.GetString("WATERBUCKET_PVP_SETTINGS_TEAM_PENDING")); string text2 = ((Object.op_Implicit((Object)(object)localNetworkUser) && (Object)(object)item3 == (Object)(object)localNetworkUser) ? "◆" : "•"); list.Add(text2 + " " + EscapeRichText(item3.userName) + " " + text + ""); } ((TMP_Text)rosterText).text = ((list.Count > 0) ? string.Join("\n", list) : "—"); } private void ClosePanel() { if (Object.op_Implicit((Object)(object)overlayObject)) { overlayObject.SetActive(false); } if (Object.op_Implicit((Object)(object)openButtonObject)) { MPButton component = openButtonObject.GetComponent(); if (Object.op_Implicit((Object)(object)component)) { ((Selectable)component).Select(); } } } private void RefreshValues() { for (int i = 0; i < valueRefreshers.Count; i++) { valueRefreshers[i](); } } private static NetworkUser? GetLocalNetworkUser() { LocalUser firstLocalUser = LocalUserManager.GetFirstLocalUser(); if (firstLocalUser == null) { return null; } return firstLocalUser.currentNetworkUser; } private static string GetTeamButtonText(int teamId) { if (teamId >= 0) { return Language.GetString(PvPTeamRegistry.GetTeamNameToken(teamId)); } return Language.GetString("WATERBUCKET_PVP_SETTINGS_TEAM_AUTO"); } private static string GetMatchModeText() { return Language.GetString(PvPConfig.CurrentMatchMode switch { PvPConfig.MatchModeKind.Unlimited => "WATERBUCKET_PVP_SETTINGS_MATCH_UNLIMITED", PvPConfig.MatchModeKind.TimedKills => "WATERBUCKET_PVP_SETTINGS_MATCH_TIMED", _ => "WATERBUCKET_PVP_SETTINGS_MATCH_LIMITED", }); } private static string GetLoadoutCategoryToken(StartingLoadoutCategory category) { return category switch { StartingLoadoutCategory.White => "WATERBUCKET_PVP_LOADOUT_WHITE", StartingLoadoutCategory.Green => "WATERBUCKET_PVP_LOADOUT_GREEN", StartingLoadoutCategory.Yellow => "WATERBUCKET_PVP_LOADOUT_YELLOW", StartingLoadoutCategory.Orange => "WATERBUCKET_PVP_LOADOUT_ORANGE", StartingLoadoutCategory.Red => "WATERBUCKET_PVP_LOADOUT_RED", StartingLoadoutCategory.Blue => "WATERBUCKET_PVP_LOADOUT_BLUE", StartingLoadoutCategory.VoidWhite => "WATERBUCKET_PVP_LOADOUT_VOID_WHITE", StartingLoadoutCategory.VoidGreen => "WATERBUCKET_PVP_LOADOUT_VOID_GREEN", StartingLoadoutCategory.VoidRed => "WATERBUCKET_PVP_LOADOUT_VOID_RED", _ => string.Empty, }; } private static void CycleMatchMode(int direction) { PvPConfig.MatchModeKind currentMatchMode = PvPConfig.CurrentMatchMode; int length = Enum.GetValues(typeof(PvPConfig.MatchModeKind)).Length; int num = (int)(currentMatchMode + direction) % length; if (num < 0) { num += length; } ConfigEntry matchMode = PvPConfig.MatchMode; PvPConfig.MatchModeKind matchModeKind = (PvPConfig.MatchModeKind)num; matchMode.Value = matchModeKind.ToString(); } private static Color GetTeamColor(int teamId) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0068: 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_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_009e: 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_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) Color[] array = (Color[])(object)new Color[8] { new Color(0.5f, 0.82f, 1f), new Color(1f, 0.48f, 0.43f), new Color(0.46f, 0.91f, 0.58f), new Color(1f, 0.82f, 0.37f), new Color(0.76f, 0.58f, 1f), new Color(0.38f, 0.94f, 0.91f), new Color(1f, 0.62f, 0.31f), new Color(1f, 0.55f, 0.78f) }; if (teamId >= 0) { return array[teamId % array.Length]; } return new Color(0.78f, 0.86f, 0.9f, 1f); } private static string EscapeRichText(string value) { return value.Replace("<", "‹").Replace(">", "›"); } private static string BoolText(bool value) { return Language.GetString(value ? "WATERBUCKET_PVP_SETTINGS_ENABLED" : "WATERBUCKET_PVP_SETTINGS_DISABLED"); } private static string SecondsText(float value) { return $"{value:0.#} s"; } private static void Stretch(RectTransform rect) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0017: 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) rect.anchorMin = Vector2.zero; rect.anchorMax = Vector2.one; rect.offsetMin = Vector2.zero; rect.offsetMax = Vector2.zero; } } internal static class PvPRespawnCountdownUI { private readonly struct CountdownState { internal float Deadline { get; } internal int RemainingLives { get; } internal CountdownState(float deadline, int remainingLives) { Deadline = deadline; RemainingLives = remainingLives; } } [CompilerGenerated] private static class <>O { public static hook_Awake <0>__HudAwake; public static Action <1>__OnRunDestroy; } private static readonly Dictionary Countdowns = new Dictionary(); private static bool installed; internal static void Install() { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Expected O, but got Unknown if (!installed) { installed = true; object obj = <>O.<0>__HudAwake; if (obj == null) { hook_Awake val = HudAwake; <>O.<0>__HudAwake = val; obj = (object)val; } HUD.Awake += (hook_Awake)obj; Run.onRunDestroyGlobal += OnRunDestroy; } } internal static void Uninstall() { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Expected O, but got Unknown if (installed) { installed = false; object obj = <>O.<0>__HudAwake; if (obj == null) { hook_Awake val = HudAwake; <>O.<0>__HudAwake = val; obj = (object)val; } HUD.Awake -= (hook_Awake)obj; Run.onRunDestroyGlobal -= OnRunDestroy; Countdowns.Clear(); } } internal static void SetCountdown(NetworkInstanceId masterNetId, float deadline, int remainingLives) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) Countdowns[masterNetId] = new CountdownState(deadline, Mathf.Max(0, remainingLives)); } internal static void ClearCountdown(NetworkInstanceId masterNetId) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) Countdowns.Remove(masterNetId); } internal static bool TryGetCountdown(NetworkUser user, out float remainingSeconds, out int remainingLives) { //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_008c: 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) remainingSeconds = 0f; remainingLives = 0; if (!Plugin.IsPvPModeActive || !Object.op_Implicit((Object)(object)user) || !Object.op_Implicit((Object)(object)user.master) || !Object.op_Implicit((Object)(object)user.master.networkIdentity)) { return false; } NetworkInstanceId netId = user.master.networkIdentity.netId; CharacterBody body = user.master.GetBody(); if (Object.op_Implicit((Object)(object)body) && Object.op_Implicit((Object)(object)body.healthComponent) && body.healthComponent.alive) { Countdowns.Remove(netId); return false; } if (!Countdowns.TryGetValue(netId, out var value)) { return false; } Run instance = Run.instance; if (!Object.op_Implicit((Object)(object)instance)) { return false; } remainingSeconds = value.Deadline - instance.fixedTime; remainingLives = value.RemainingLives; return true; } private static void HudAwake(orig_Awake orig, HUD self) { orig.Invoke(self); if (!Object.op_Implicit((Object)(object)((Component)self).GetComponent())) { ((Component)self).gameObject.AddComponent(); } } private static void OnRunDestroy(Run run) { Countdowns.Clear(); } } internal sealed class PvPRespawnCountdownHud : MonoBehaviour { private HUD hud; private GameObject panelObject; private HGTextMeshProUGUI countdownText; private void Start() { //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Expected O, but got Unknown //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Unknown result type (might be due to invalid IL or missing references) //IL_010d: Unknown result type (might be due to invalid IL or missing references) //IL_0117: Unknown result type (might be due to invalid IL or missing references) //IL_0118: Unknown result type (might be due to invalid IL or missing references) //IL_012c: Unknown result type (might be due to invalid IL or missing references) //IL_0156: Unknown result type (might be due to invalid IL or missing references) //IL_0186: Unknown result type (might be due to invalid IL or missing references) //IL_019a: 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) //IL_01c2: Expected O, but got Unknown //IL_01f0: Unknown result type (might be due to invalid IL or missing references) //IL_01f5: Unknown result type (might be due to invalid IL or missing references) //IL_01f6: Unknown result type (might be due to invalid IL or missing references) //IL_0200: Unknown result type (might be due to invalid IL or missing references) //IL_0201: Unknown result type (might be due to invalid IL or missing references) //IL_020b: Unknown result type (might be due to invalid IL or missing references) //IL_0216: Unknown result type (might be due to invalid IL or missing references) //IL_022a: Unknown result type (might be due to invalid IL or missing references) //IL_02a9: Unknown result type (might be due to invalid IL or missing references) hud = ((Component)this).GetComponent(); if (!Object.op_Implicit((Object)(object)hud) || !Object.op_Implicit((Object)(object)hud.mainContainer)) { ((Behaviour)this).enabled = false; return; } Transform val = (Object.op_Implicit((Object)(object)hud.gameModeUiRoot) ? hud.gameModeUiRoot : hud.mainContainer.transform); panelObject = new GameObject("WaterBucketPvPRespawnCountdown", new Type[3] { typeof(RectTransform), typeof(Image), typeof(Outline) }); panelObject.layer = ((Component)val).gameObject.layer; panelObject.transform.SetParent(val, false); RectTransform val2 = (RectTransform)panelObject.transform; val2.anchorMin = new Vector2(0.5f, 0.72f); val2.anchorMax = new Vector2(0.5f, 0.72f); val2.pivot = new Vector2(0.5f, 0.5f); val2.anchoredPosition = Vector2.zero; val2.sizeDelta = new Vector2(470f, 76f); Image component = panelObject.GetComponent(); ((Graphic)component).color = new Color(0.02f, 0.035f, 0.05f, 0.88f); ((Graphic)component).raycastTarget = false; Outline component2 = panelObject.GetComponent(); ((Shadow)component2).effectColor = new Color(0.34f, 0.75f, 0.93f, 0.72f); ((Shadow)component2).effectDistance = new Vector2(1f, -1f); GameObject val3 = new GameObject("CountdownText", new Type[1] { typeof(RectTransform) }); val3.layer = panelObject.layer; val3.transform.SetParent(panelObject.transform, false); RectTransform val4 = (RectTransform)val3.transform; val4.anchorMin = Vector2.zero; val4.anchorMax = Vector2.one; val4.offsetMin = new Vector2(14f, 6f); val4.offsetMax = new Vector2(-14f, -6f); countdownText = val3.AddComponent(); TMP_Text componentInChildren = ((Component)hud).GetComponentInChildren(true); if (Object.op_Implicit((Object)(object)componentInChildren)) { ((TMP_Text)countdownText).font = componentInChildren.font; ((TMP_Text)countdownText).fontSharedMaterial = componentInChildren.fontSharedMaterial; } ((TMP_Text)countdownText).fontSize = 25f; ((TMP_Text)countdownText).fontStyle = (FontStyles)1; ((TMP_Text)countdownText).alignment = (TextAlignmentOptions)514; ((Graphic)countdownText).color = Color.white; ((TMP_Text)countdownText).enableWordWrapping = false; ((Graphic)countdownText).raycastTarget = false; panelObject.SetActive(false); } private void Update() { if (Object.op_Implicit((Object)(object)panelObject) && Object.op_Implicit((Object)(object)hud)) { LocalUser localUserViewer = hud.localUserViewer; NetworkUser val = ((localUserViewer != null) ? localUserViewer.currentNetworkUser : null); if (val == null || !Object.op_Implicit((Object)(object)val) || !PvPRespawnCountdownUI.TryGetCountdown(val, out var remainingSeconds, out var remainingLives)) { panelObject.SetActive(false); return; } panelObject.SetActive(true); ((TMP_Text)countdownText).text = ((remainingSeconds > 0f) ? string.Format(Language.GetString("WATERBUCKET_PVP_RESPAWN_COUNTDOWN"), Mathf.CeilToInt(remainingSeconds), remainingLives) : string.Format(Language.GetString("WATERBUCKET_PVP_RESPAWN_NOW"), remainingLives)); } } } internal static class PvPScoreboardPrivacy { [CompilerGenerated] private static class <>O { public static hook_SetMaster <0>__ScoreboardStripSetMaster; public static hook_Update <1>__ScoreboardStripUpdate; public static hook_SelectFirstItem <2>__ScoreboardStripSelectFirstItem; public static hook_ItemClicked <3>__ItemIconItemClicked; public static hook_TrySelect <4>__EquipmentIconTrySelect; public static hook_ItemClicked <5>__EquipmentIconItemClicked; } private static bool installed; internal static void Install() { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Expected O, but got Unknown //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Expected O, but got Unknown //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Expected O, but got Unknown //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Expected O, but got Unknown //IL_009e: 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_00a9: Expected O, but got Unknown //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Expected O, but got Unknown if (!installed) { installed = true; object obj = <>O.<0>__ScoreboardStripSetMaster; if (obj == null) { hook_SetMaster val = ScoreboardStripSetMaster; <>O.<0>__ScoreboardStripSetMaster = val; obj = (object)val; } ScoreboardStrip.SetMaster += (hook_SetMaster)obj; object obj2 = <>O.<1>__ScoreboardStripUpdate; if (obj2 == null) { hook_Update val2 = ScoreboardStripUpdate; <>O.<1>__ScoreboardStripUpdate = val2; obj2 = (object)val2; } ScoreboardStrip.Update += (hook_Update)obj2; object obj3 = <>O.<2>__ScoreboardStripSelectFirstItem; if (obj3 == null) { hook_SelectFirstItem val3 = ScoreboardStripSelectFirstItem; <>O.<2>__ScoreboardStripSelectFirstItem = val3; obj3 = (object)val3; } ScoreboardStrip.SelectFirstItem += (hook_SelectFirstItem)obj3; object obj4 = <>O.<3>__ItemIconItemClicked; if (obj4 == null) { hook_ItemClicked val4 = ItemIconItemClicked; <>O.<3>__ItemIconItemClicked = val4; obj4 = (object)val4; } ItemIcon.ItemClicked += (hook_ItemClicked)obj4; object obj5 = <>O.<4>__EquipmentIconTrySelect; if (obj5 == null) { hook_TrySelect val5 = EquipmentIconTrySelect; <>O.<4>__EquipmentIconTrySelect = val5; obj5 = (object)val5; } EquipmentIcon.TrySelect += (hook_TrySelect)obj5; object obj6 = <>O.<5>__EquipmentIconItemClicked; if (obj6 == null) { hook_ItemClicked val6 = EquipmentIconItemClicked; <>O.<5>__EquipmentIconItemClicked = val6; obj6 = (object)val6; } EquipmentIcon.ItemClicked += (hook_ItemClicked)obj6; } } internal static void Uninstall() { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Expected O, but got Unknown //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Expected O, but got Unknown //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Expected O, but got Unknown //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Expected O, but got Unknown //IL_009e: 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_00a9: Expected O, but got Unknown //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Expected O, but got Unknown if (!installed) { return; } installed = false; object obj = <>O.<0>__ScoreboardStripSetMaster; if (obj == null) { hook_SetMaster val = ScoreboardStripSetMaster; <>O.<0>__ScoreboardStripSetMaster = val; obj = (object)val; } ScoreboardStrip.SetMaster -= (hook_SetMaster)obj; object obj2 = <>O.<1>__ScoreboardStripUpdate; if (obj2 == null) { hook_Update val2 = ScoreboardStripUpdate; <>O.<1>__ScoreboardStripUpdate = val2; obj2 = (object)val2; } ScoreboardStrip.Update -= (hook_Update)obj2; object obj3 = <>O.<2>__ScoreboardStripSelectFirstItem; if (obj3 == null) { hook_SelectFirstItem val3 = ScoreboardStripSelectFirstItem; <>O.<2>__ScoreboardStripSelectFirstItem = val3; obj3 = (object)val3; } ScoreboardStrip.SelectFirstItem -= (hook_SelectFirstItem)obj3; object obj4 = <>O.<3>__ItemIconItemClicked; if (obj4 == null) { hook_ItemClicked val4 = ItemIconItemClicked; <>O.<3>__ItemIconItemClicked = val4; obj4 = (object)val4; } ItemIcon.ItemClicked -= (hook_ItemClicked)obj4; object obj5 = <>O.<4>__EquipmentIconTrySelect; if (obj5 == null) { hook_TrySelect val5 = EquipmentIconTrySelect; <>O.<4>__EquipmentIconTrySelect = val5; obj5 = (object)val5; } EquipmentIcon.TrySelect -= (hook_TrySelect)obj5; object obj6 = <>O.<5>__EquipmentIconItemClicked; if (obj6 == null) { hook_ItemClicked val6 = EquipmentIconItemClicked; <>O.<5>__EquipmentIconItemClicked = val6; obj6 = (object)val6; } EquipmentIcon.ItemClicked -= (hook_ItemClicked)obj6; PvPScoreboardPrivacyState[] array = Resources.FindObjectsOfTypeAll(); foreach (PvPScoreboardPrivacyState pvPScoreboardPrivacyState in array) { if (Object.op_Implicit((Object)(object)pvPScoreboardPrivacyState)) { ScoreboardStrip component = ((Component)pvPScoreboardPrivacyState).GetComponent(); if (Object.op_Implicit((Object)(object)component)) { RestoreGear(component, pvPScoreboardPrivacyState.TargetMaster); } Object.Destroy((Object)(object)pvPScoreboardPrivacyState); } } } private static void ScoreboardStripSetMaster(orig_SetMaster orig, ScoreboardStrip self, CharacterMaster newMaster) { orig.Invoke(self, newMaster); PvPScoreboardPrivacyState orAddState = GetOrAddState(self); orAddState.TargetMaster = newMaster; ApplyPrivacy(self, orAddState, forceRefresh: true); } private static void ScoreboardStripUpdate(orig_Update orig, ScoreboardStrip self) { orig.Invoke(self); PvPScoreboardPrivacyState pvPScoreboardPrivacyState = ((Component)self).GetComponent(); if (!Object.op_Implicit((Object)(object)pvPScoreboardPrivacyState) && Plugin.IsPvPModeActive) { pvPScoreboardPrivacyState = GetOrAddState(self); } if (Object.op_Implicit((Object)(object)pvPScoreboardPrivacyState)) { ApplyPrivacy(self, pvPScoreboardPrivacyState, forceRefresh: false); } } private static void ScoreboardStripSelectFirstItem(orig_SelectFirstItem orig, ScoreboardStrip self) { if (!IsGearHidden(self)) { orig.Invoke(self); } } private static bool EquipmentIconTrySelect(orig_TrySelect orig, EquipmentIcon self) { ScoreboardStrip componentInParent = ((Component)self).GetComponentInParent(); if (!Object.op_Implicit((Object)(object)componentInParent) || !IsGearHidden(componentInParent)) { return orig.Invoke(self); } return false; } private static void ItemIconItemClicked(orig_ItemClicked orig, ItemIcon self) { ScoreboardStrip componentInParent = ((Component)self).GetComponentInParent(); if (!Object.op_Implicit((Object)(object)componentInParent) || !IsGearHidden(componentInParent)) { orig.Invoke(self); } } private static void EquipmentIconItemClicked(orig_ItemClicked orig, EquipmentIcon self) { ScoreboardStrip componentInParent = ((Component)self).GetComponentInParent(); if (!Object.op_Implicit((Object)(object)componentInParent) || !IsGearHidden(componentInParent)) { orig.Invoke(self); } } private static PvPScoreboardPrivacyState GetOrAddState(ScoreboardStrip strip) { PvPScoreboardPrivacyState component = ((Component)strip).GetComponent(); if (!Object.op_Implicit((Object)(object)component)) { return ((Component)strip).gameObject.AddComponent(); } return component; } private static void ApplyPrivacy(ScoreboardStrip strip, PvPScoreboardPrivacyState state, bool forceRefresh) { bool flag = ShouldHideGear(strip, state.TargetMaster); if (flag) { bool flag2 = !state.HideGear; if (forceRefresh || flag2) { ClearAndHideGear(strip, flag2); } else { EnforceHiddenGear(strip); } } else if (forceRefresh || state.HideGear) { RestoreGear(strip, state.TargetMaster); } state.HideGear = flag; } private static void ClearAndHideGear(ScoreboardStrip strip, bool closeInspectPanel) { //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) //IL_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_0125: Unknown result type (might be due to invalid IL or missing references) ClearGearSelection(strip); if (Object.op_Implicit((Object)(object)strip.itemInventoryDisplay)) { strip.itemInventoryDisplay.SetSubscribedInventory((Inventory)null); strip.itemInventoryDisplay.ResetItems(); if (((Behaviour)strip.itemInventoryDisplay).isActiveAndEnabled) { strip.itemInventoryDisplay.UpdateDisplay(); } ((Component)strip.itemInventoryDisplay).gameObject.SetActive(false); } if (Object.op_Implicit((Object)(object)strip.equipmentIcon)) { strip.equipmentIcon.targetInventory = null; if (Object.op_Implicit((Object)(object)strip.equipmentIcon.tooltipProvider)) { strip.equipmentIcon.tooltipProvider.titleToken = null; strip.equipmentIcon.tooltipProvider.bodyToken = null; strip.equipmentIcon.tooltipProvider.overrideTitleText = string.Empty; strip.equipmentIcon.tooltipProvider.overrideBodyText = string.Empty; strip.equipmentIcon.tooltipProvider.titleColor = Color.clear; strip.equipmentIcon.tooltipProvider.bodyColor = Color.clear; } if (Object.op_Implicit((Object)(object)strip.equipmentIcon.iconImage)) { strip.equipmentIcon.iconImage.texture = null; ((Graphic)strip.equipmentIcon.iconImage).color = Color.clear; } if (closeInspectPanel) { InspectPanelController inspectPanel = strip.equipmentIcon.inspectPanel; if (inspectPanel != null) { inspectPanel.OnCloseButtonClicked(); } } ((Component)strip.equipmentIcon).gameObject.SetActive(false); } if (Object.op_Implicit((Object)(object)strip.itemCountText)) { ((Component)strip.itemCountText).gameObject.SetActive(false); } } private static void EnforceHiddenGear(ScoreboardStrip strip) { if (Object.op_Implicit((Object)(object)strip.itemInventoryDisplay)) { strip.itemInventoryDisplay.SetSubscribedInventory((Inventory)null); ((Component)strip.itemInventoryDisplay).gameObject.SetActive(false); } if (Object.op_Implicit((Object)(object)strip.equipmentIcon)) { strip.equipmentIcon.targetInventory = null; ((Component)strip.equipmentIcon).gameObject.SetActive(false); } if (Object.op_Implicit((Object)(object)strip.itemCountText)) { ((Component)strip.itemCountText).gameObject.SetActive(false); } } private static void RestoreGear(ScoreboardStrip strip, CharacterMaster? targetMaster) { Inventory val = ((targetMaster != null && Object.op_Implicit((Object)(object)targetMaster)) ? targetMaster.inventory : null); if (Object.op_Implicit((Object)(object)strip.itemInventoryDisplay)) { strip.itemInventoryDisplay.SetSubscribedInventory(val); if (!Object.op_Implicit((Object)(object)val)) { strip.itemInventoryDisplay.ResetItems(); } ((Component)strip.itemInventoryDisplay).gameObject.SetActive(true); if (((Behaviour)strip.itemInventoryDisplay).isActiveAndEnabled) { strip.itemInventoryDisplay.UpdateDisplay(); } } if (Object.op_Implicit((Object)(object)strip.equipmentIcon)) { strip.equipmentIcon.targetInventory = val; ((Component)strip.equipmentIcon).gameObject.SetActive(true); } if (Object.op_Implicit((Object)(object)strip.itemCountText)) { ((Component)strip.itemCountText).gameObject.SetActive(true); } } private static void ClearGearSelection(ScoreboardStrip strip) { MPEventSystem val = ((Object.op_Implicit((Object)(object)strip.eventSystemLocator) && Object.op_Implicit((Object)(object)strip.eventSystemLocator.eventSystem)) ? strip.eventSystemLocator.eventSystem : null); GameObject val2 = ((val != null && Object.op_Implicit((Object)(object)val)) ? ((EventSystem)val).currentSelectedGameObject : null); if (val2 != null && Object.op_Implicit((Object)(object)val2)) { bool num = Object.op_Implicit((Object)(object)strip.itemInventoryDisplay) && ((Object)(object)val2.transform == (Object)(object)((Component)strip.itemInventoryDisplay).transform || val2.transform.IsChildOf(((Component)strip.itemInventoryDisplay).transform)); bool flag = Object.op_Implicit((Object)(object)strip.equipmentIcon) && ((Object)(object)val2.transform == (Object)(object)((Component)strip.equipmentIcon).transform || val2.transform.IsChildOf(((Component)strip.equipmentIcon).transform)); if (num || flag) { val.SetSelectedObject((GameObject)null); } } } private static bool IsGearHidden(ScoreboardStrip strip) { if (!Plugin.IsPvPModeActive) { return false; } PvPScoreboardPrivacyState component = ((Component)strip).GetComponent(); if (Object.op_Implicit((Object)(object)component)) { return component.HideGear; } return true; } private static bool ShouldHideGear(ScoreboardStrip strip, CharacterMaster? targetMaster) { //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Unknown result type (might be due to invalid IL or missing references) if (!Plugin.IsPvPModeActive) { return false; } if (targetMaster == null || !Object.op_Implicit((Object)(object)targetMaster) || !Object.op_Implicit((Object)(object)targetMaster.inventory) || !Object.op_Implicit((Object)(object)targetMaster.playerCharacterMasterController) || !PvPTeamRegistry.IsPvPTeam(targetMaster.teamIndex)) { return true; } LocalUser val = null; if (Object.op_Implicit((Object)(object)strip.eventSystemLocator) && Object.op_Implicit((Object)(object)strip.eventSystemLocator.eventSystem)) { val = strip.eventSystemLocator.eventSystem.localUser; } if (val == null && LocalUserManager.readOnlyLocalUsersList.Count == 1) { val = LocalUserManager.readOnlyLocalUsersList[0]; } NetworkUser val2 = ((val != null) ? val.currentNetworkUser : null); CharacterMaster val3 = ((val2 != null && Object.op_Implicit((Object)(object)val2) && Object.op_Implicit((Object)(object)val2.master)) ? val2.master : null); if (val3 != null && Object.op_Implicit((Object)(object)val3) && PvPTeamRegistry.IsPvPTeam(val3.teamIndex)) { return val3.teamIndex != targetMaster.teamIndex; } return true; } } internal sealed class PvPScoreboardPrivacyState : MonoBehaviour { internal CharacterMaster? TargetMaster; internal bool HideGear; } } namespace PvPMode.Teams { internal static class PvPRelationService { internal readonly struct Combatant { internal TeamIndex TeamIndex { get; } internal CharacterMaster? DirectMaster { get; } internal CharacterMaster? RootMaster { get; } internal bool IsDirectPlayer { get { if (DirectMaster != null && Object.op_Implicit((Object)(object)DirectMaster)) { return Object.op_Implicit((Object)(object)DirectMaster.playerCharacterMasterController); } return false; } } internal bool IsOwnedMinion { get { if (DirectMaster != null && Object.op_Implicit((Object)(object)DirectMaster) && RootMaster != null && Object.op_Implicit((Object)(object)RootMaster)) { return (Object)(object)DirectMaster != (Object)(object)RootMaster; } return false; } } internal Combatant(TeamIndex teamIndex, CharacterMaster? directMaster, CharacterMaster? rootMaster) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) TeamIndex = teamIndex; DirectMaster = directMaster; RootMaster = rootMaster; } } internal static bool AreAllies(TeamIndex a, TeamIndex b) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Invalid comparison between Unknown and I4 //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) if ((int)a != -1) { return a == b; } return false; } internal static bool AreEnemies(TeamIndex a, TeamIndex b) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Invalid comparison between Unknown and I4 //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Invalid comparison between Unknown and I4 //IL_000a: 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_0012: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) if ((int)a == -1 || (int)b == -1) { return false; } if (PvPTeamRegistry.IsPvPTeam(a) || PvPTeamRegistry.IsPvPTeam(b)) { if ((int)a == 0 || (int)b == 0) { return false; } return a != b; } return a != b; } internal static bool TryResolve(GameObject? gameObject, out Combatant combatant) { //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Invalid comparison between Unknown and I4 //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_007e: 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) combatant = default(Combatant); if (!Object.op_Implicit((Object)(object)gameObject)) { return false; } CharacterBody component = gameObject.GetComponent(); CharacterMaster val = ((component != null && Object.op_Implicit((Object)(object)component)) ? component.master : gameObject.GetComponent()); CharacterMaster val2 = ResolveRootOwner(val); TeamIndex val3 = (TeamIndex)(-1); val3 = ((val2 != null && Object.op_Implicit((Object)(object)val2) && PvPTeamRegistry.IsPvPTeam(val2.teamIndex)) ? val2.teamIndex : ((component == null || !Object.op_Implicit((Object)(object)component) || !Object.op_Implicit((Object)(object)component.teamComponent)) ? TeamComponent.GetObjectTeam(gameObject) : component.teamComponent.teamIndex)); combatant = new Combatant(val3, val, val2); return (int)val3 != -1; } internal static CharacterMaster? ResolveRootOwner(CharacterMaster? master) { if (!Object.op_Implicit((Object)(object)master)) { return null; } HashSet hashSet = new HashSet(); CharacterMaster val = master; while (val != null && Object.op_Implicit((Object)(object)val) && hashSet.Add(val)) { CharacterMaster val2 = (Object.op_Implicit((Object)(object)val.minionOwnership) ? val.minionOwnership.ownerMaster : null); if (!Object.op_Implicit((Object)(object)val2)) { return val; } val = val2; } return val; } } internal static class PvPTeamManager { private static readonly Dictionary Assignments = new Dictionary(); private static readonly Dictionary LobbySelections = new Dictionary(); private static bool installed; internal static void Install() { if (!installed) { installed = true; Run.onRunStartGlobal += OnRunStart; Run.onRunDestroyGlobal += OnRunDestroy; PlayerCharacterMasterController.onLinkedToNetworkUserServerGlobal += OnPlayerLinked; CharacterBody.onBodyStartGlobal += OnBodyStart; } } internal static void Uninstall() { if (installed) { installed = false; Run.onRunStartGlobal -= OnRunStart; Run.onRunDestroyGlobal -= OnRunDestroy; PlayerCharacterMasterController.onLinkedToNetworkUserServerGlobal -= OnPlayerLinked; CharacterBody.onBodyStartGlobal -= OnBodyStart; Assignments.Clear(); LobbySelections.Clear(); } } private static void OnRunStart(Run run) { Assignments.Clear(); if (!Plugin.IsPvPModeActive || !NetworkServer.active) { return; } foreach (NetworkUser item in NetworkUser.readOnlyInstancesList.Where((NetworkUser user) => Object.op_Implicit((Object)(object)user) && user.isParticipating).OrderBy((NetworkUser user) => ((object)user.id/*cast due to .constrained prefix*/).ToString(), StringComparer.Ordinal)) { AssignUser(item); } } private static void OnRunDestroy(Run run) { Assignments.Clear(); LobbySelections.Clear(); } private static void OnPlayerLinked(PlayerCharacterMasterController controller) { if (Plugin.IsPvPModeActive && NetworkServer.active && Object.op_Implicit((Object)(object)controller) && Object.op_Implicit((Object)(object)controller.networkUser)) { AssignUser(controller.networkUser); } } private static void OnBodyStart(CharacterBody body) { if (!Plugin.IsPvPModeActive || !NetworkServer.active || !Object.op_Implicit((Object)(object)body) || !Object.op_Implicit((Object)(object)body.master)) { return; } PlayerCharacterMasterController playerCharacterMasterController = body.master.playerCharacterMasterController; if (Object.op_Implicit((Object)(object)playerCharacterMasterController) && Object.op_Implicit((Object)(object)playerCharacterMasterController.networkUser)) { if (!Assignments.TryGetValue(playerCharacterMasterController.networkUser, out var value)) { value = AssignUser(playerCharacterMasterController.networkUser); } ApplyTeam(body.master, value); } } private static int AssignUser(NetworkUser user) { //IL_00a0: Unknown result type (might be due to invalid IL or missing references) if (Assignments.TryGetValue(user, out var value)) { return value; } int num; if (LobbySelections.TryGetValue(user, out var value2) && value2 >= 0 && value2 < PvPTeamRegistry.Count) { num = value2; } else if (PvPConfig.IsFfa) { num = GetNextFfaTeam(); } else { int num2 = Math.Clamp(PvPConfig.TeamCount.Value, 2, PvPTeamRegistry.Count); num = Assignments.Count % num2; } Assignments[user] = num; if (Object.op_Implicit((Object)(object)user.master)) { ApplyTeam(user.master, num); } Plugin.Log.LogInfo((object)$"Assigned {user.userName} to PvP team {num + 1} ({PvPTeamRegistry.GetTeamIndex(num)})."); return num; } private static int GetNextFfaTeam() { for (int i = 0; i < PvPTeamRegistry.Count; i++) { if (!Assignments.ContainsValue(i) && !LobbySelections.ContainsValue(i)) { return i; } } return Assignments.Count % PvPTeamRegistry.Count; } internal static void ApplyTeam(CharacterMaster master, int teamId) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0008: 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) TeamIndex teamIndex = (master.teamIndex = PvPTeamRegistry.GetTeamIndex(teamId)); CharacterBody body = master.GetBody(); if (body != null && Object.op_Implicit((Object)(object)body) && Object.op_Implicit((Object)(object)body.teamComponent)) { body.teamComponent.teamIndex = teamIndex; } } internal static bool TryGetTeamId(NetworkUser user, out int teamId) { return Assignments.TryGetValue(user, out teamId); } internal static bool TryGetTeamId(CharacterMaster master, out int teamId) { //IL_0020: Unknown result type (might be due to invalid IL or missing references) teamId = -1; if (!Object.op_Implicit((Object)(object)master)) { return false; } CharacterMaster val = PvPRelationService.ResolveRootOwner(master); if (val != null && Object.op_Implicit((Object)(object)val)) { return PvPTeamRegistry.TryGetPvPTeamId(val.teamIndex, out teamId); } return false; } internal static IReadOnlyDictionary GetAssignments() { return Assignments; } internal static IReadOnlyDictionary GetLobbySelections() { return LobbySelections; } internal static bool TryGetLobbySelection(NetworkUser user, out int teamId) { return LobbySelections.TryGetValue(user, out teamId); } internal static bool SetLobbySelection(NetworkUser user, int requestedTeamId) { if (!NetworkServer.active || !Object.op_Implicit((Object)(object)user)) { return false; } if (requestedTeamId < 0) { LobbySelections.Remove(user); Plugin.Log.LogInfo((object)(user.userName + " will use automatic PvP team assignment.")); return true; } if (requestedTeamId >= PvPTeamRegistry.Count) { return false; } LobbySelections[user] = requestedTeamId; Plugin.Log.LogInfo((object)$"{user.userName} selected PvP team {requestedTeamId + 1} in the lobby."); return true; } internal static bool SetTeam(NetworkUser user, int requestedTeamId) { if (!Plugin.IsPvPModeActive || !NetworkServer.active || !Object.op_Implicit((Object)(object)user)) { return false; } int num = (requestedTeamId % PvPTeamRegistry.Count + PvPTeamRegistry.Count) % PvPTeamRegistry.Count; Assignments[user] = num; if (Object.op_Implicit((Object)(object)user.master)) { ApplyTeam(user.master, num); } return true; } } internal static class PvPTeamRegistry { private static readonly List TeamIndices = new List(); private static readonly Dictionary TeamIds = new Dictionary(); internal static int Count => TeamIndices.Count; internal static void RegisterTeams(int requestedCount) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0038: 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_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Expected O, but got Unknown //IL_0065: Expected O, but got Unknown //IL_0060: 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_0066: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Invalid comparison between Unknown and I4 //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) int num = Math.Clamp(requestedCount, 2, 16); for (int i = 0; i < num; i++) { TeamIndex val = TeamsAPI.RegisterTeam(new TeamDef { nameToken = GetTeamNameToken(i), softCharacterLimit = int.MaxValue, friendlyFireScaling = 1f, levelUpEffect = null, levelUpSound = string.Empty }, new TeamBehavior($"WaterBucketPvPTeam{i}", (TeamClassification)4)); if ((int)val == -1) { throw new InvalidOperationException($"Could not register PvP team {i}."); } TeamIndices.Add(val); TeamIds.Add(val, i); } } internal static string GetTeamNameToken(int teamId) { return $"WATERBUCKET_PVP_TEAM_{teamId}_NAME"; } internal static TeamIndex GetTeamIndex(int teamId) { //IL_0037: Unknown result type (might be due to invalid IL or missing references) if (TeamIndices.Count == 0) { return (TeamIndex)(-1); } int index = (teamId % TeamIndices.Count + TeamIndices.Count) % TeamIndices.Count; return TeamIndices[index]; } internal static bool IsPvPTeam(TeamIndex teamIndex) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) return TeamIds.ContainsKey(teamIndex); } internal static bool TryGetPvPTeamId(TeamIndex teamIndex, out int teamId) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) return TeamIds.TryGetValue(teamIndex, out teamId); } } } namespace PvPMode.Spawn { internal static class PvPSpawnManager { private readonly struct NodeCandidate { internal NodeIndex Node { get; } internal Vector3 Position { get; } internal NodeCandidate(NodeIndex node, Vector3 position) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) Node = node; Position = position; } } [CompilerGenerated] private static class <>O { public static GenerateSpawnPointsDelegate <0>__OnPreGeneratePlayerSpawnPointsServer; public static hook_OnPlayerSpawnPointsPlaced <1>__RunOnPlayerSpawnPointsPlaced; public static hook_RespawnCharacter <2>__StageRespawnCharacter; public static hook_GetPlayerSpawnTransform <3>__StageGetPlayerSpawnTransform; public static Action <4>__OnBodyStart; public static Action <5>__OnRunDestroy; } private static readonly HashSet SpawnedThisStage = new HashSet(); private static readonly HashSet PositionedByVanillaSpawn = new HashSet(); private static readonly Dictionary TeamAnchors = new Dictionary(); private static readonly Dictionary TeamAnchorNodes = new Dictionary(); private static readonly Dictionary TeamAnchorSpawnPoints = new Dictionary(); private static readonly Dictionary> TeamSpawnPointPools = new Dictionary>(); private static readonly Dictionary InitialPlayerSpawnAssignments = new Dictionary(); private static readonly HashSet ReservedTeamSpawnPoints = new HashSet(); private static readonly HashSet ClaimedInitialSpawnPoints = new HashSet(); private static readonly HashSet UsedSpawnNodes = new HashSet(); private static readonly List PlannedNodeCandidates = new List(); private static readonly List PlannedAnchorCandidates = new List(); private static readonly Dictionary PlannedNodesByIndex = new Dictionary(); private static readonly List CreatedTeamSpawnPoints = new List(); private static readonly List SpawnPointsBeforeGeneration = new List(); private static CharacterMaster? currentInitialSpawnMaster; private static NodeGraph? plannedNodeGraph; private static Xoroshiro128Plus? plannedSpawnRng; private static int stageStamp = int.MinValue; private static int stageInstanceId = int.MinValue; private static int sceneInstanceId = int.MinValue; private static Vector3 stageOrigin; private static bool hasStageOrigin; private static bool teamSpawnPlanPrepared; private static bool installed; internal static void Install() { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Expected O, but got Unknown //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Expected O, but got Unknown //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Expected O, but got Unknown //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Expected O, but got Unknown if (!installed) { installed = true; object obj = <>O.<0>__OnPreGeneratePlayerSpawnPointsServer; if (obj == null) { GenerateSpawnPointsDelegate val = OnPreGeneratePlayerSpawnPointsServer; <>O.<0>__OnPreGeneratePlayerSpawnPointsServer = val; obj = (object)val; } SceneDirector.onPreGeneratePlayerSpawnPointsServer += (GenerateSpawnPointsDelegate)obj; object obj2 = <>O.<1>__RunOnPlayerSpawnPointsPlaced; if (obj2 == null) { hook_OnPlayerSpawnPointsPlaced val2 = RunOnPlayerSpawnPointsPlaced; <>O.<1>__RunOnPlayerSpawnPointsPlaced = val2; obj2 = (object)val2; } Run.OnPlayerSpawnPointsPlaced += (hook_OnPlayerSpawnPointsPlaced)obj2; object obj3 = <>O.<2>__StageRespawnCharacter; if (obj3 == null) { hook_RespawnCharacter val3 = StageRespawnCharacter; <>O.<2>__StageRespawnCharacter = val3; obj3 = (object)val3; } Stage.RespawnCharacter += (hook_RespawnCharacter)obj3; object obj4 = <>O.<3>__StageGetPlayerSpawnTransform; if (obj4 == null) { hook_GetPlayerSpawnTransform val4 = StageGetPlayerSpawnTransform; <>O.<3>__StageGetPlayerSpawnTransform = val4; obj4 = (object)val4; } Stage.GetPlayerSpawnTransform += (hook_GetPlayerSpawnTransform)obj4; CharacterBody.onBodyStartGlobal += OnBodyStart; Run.onRunDestroyGlobal += OnRunDestroy; } } internal static void Uninstall() { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Expected O, but got Unknown //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Expected O, but got Unknown //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Expected O, but got Unknown //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Expected O, but got Unknown if (installed) { installed = false; object obj = <>O.<0>__OnPreGeneratePlayerSpawnPointsServer; if (obj == null) { GenerateSpawnPointsDelegate val = OnPreGeneratePlayerSpawnPointsServer; <>O.<0>__OnPreGeneratePlayerSpawnPointsServer = val; obj = (object)val; } SceneDirector.onPreGeneratePlayerSpawnPointsServer -= (GenerateSpawnPointsDelegate)obj; object obj2 = <>O.<1>__RunOnPlayerSpawnPointsPlaced; if (obj2 == null) { hook_OnPlayerSpawnPointsPlaced val2 = RunOnPlayerSpawnPointsPlaced; <>O.<1>__RunOnPlayerSpawnPointsPlaced = val2; obj2 = (object)val2; } Run.OnPlayerSpawnPointsPlaced -= (hook_OnPlayerSpawnPointsPlaced)obj2; object obj3 = <>O.<2>__StageRespawnCharacter; if (obj3 == null) { hook_RespawnCharacter val3 = StageRespawnCharacter; <>O.<2>__StageRespawnCharacter = val3; obj3 = (object)val3; } Stage.RespawnCharacter -= (hook_RespawnCharacter)obj3; object obj4 = <>O.<3>__StageGetPlayerSpawnTransform; if (obj4 == null) { hook_GetPlayerSpawnTransform val4 = StageGetPlayerSpawnTransform; <>O.<3>__StageGetPlayerSpawnTransform = val4; obj4 = (object)val4; } Stage.GetPlayerSpawnTransform -= (hook_GetPlayerSpawnTransform)obj4; CharacterBody.onBodyStartGlobal -= OnBodyStart; Run.onRunDestroyGlobal -= OnRunDestroy; Reset(); } } private static void OnPreGeneratePlayerSpawnPointsServer(SceneDirector sceneDirector, ref Action generationMethod) { if (Plugin.IsPvPModeActive && NetworkServer.active && CanUseMapWideTeamSpawns()) { EnsureStageState(); SpawnPointsBeforeGeneration.Clear(); SpawnPointsBeforeGeneration.AddRange(GetValidSpawnPoints()); } } private static void RunOnPlayerSpawnPointsPlaced(orig_OnPlayerSpawnPointsPlaced orig, Run self, SceneDirector sceneDirector) { orig.Invoke(self, sceneDirector); if (!Plugin.IsPvPModeActive || !NetworkServer.active || !CanUseMapWideTeamSpawns()) { return; } try { PrepareDistributedTeamSpawnPlan(sceneDirector, new List(SpawnPointsBeforeGeneration)); } catch (Exception arg) { ClearSpawnPlan(); Plugin.Log.LogError((object)$"Could not prepare map-wide PvP team spawns; vanilla spawns will be used. {arg}"); } } private static void StageRespawnCharacter(orig_RespawnCharacter orig, Stage self, CharacterMaster characterMaster) { if (!Plugin.IsPvPModeActive || !NetworkServer.active || !Object.op_Implicit((Object)(object)characterMaster)) { orig.Invoke(self, characterMaster); return; } CharacterMaster val = currentInitialSpawnMaster; currentInitialSpawnMaster = characterMaster; try { orig.Invoke(self, characterMaster); } finally { currentInitialSpawnMaster = val; } } private static Transform StageGetPlayerSpawnTransform(orig_GetPlayerSpawnTransform orig, Stage self) { CharacterMaster val = currentInitialSpawnMaster; if (!Plugin.IsPvPModeActive || !NetworkServer.active) { return orig.Invoke(self); } EnsureStageState(); if (val == null || !Object.op_Implicit((Object)(object)val)) { if (teamSpawnPlanPrepared && CanUseMapWideTeamSpawns() && TryConsumeUnreservedSpawnPoint(out Transform transform)) { return transform; } return orig.Invoke(self); } if (!PvPTeamManager.TryGetTeamId(val, out var teamId)) { return orig.Invoke(self); } if (!CanUseMapWideTeamSpawns()) { Transform obj = orig.Invoke(self); if (Object.op_Implicit((Object)(object)obj)) { PositionedByVanillaSpawn.Add(val); } return obj; } if (TryGetPlannedPlayerSpawnPoint(val, teamId, out SpawnPoint spawnPoint)) { spawnPoint.consumed = true; PositionedByVanillaSpawn.Add(val); return ((Component)spawnPoint).transform; } Transform transform2; Transform obj2 = ((teamSpawnPlanPrepared && TryConsumeUnreservedSpawnPoint(out transform2)) ? transform2 : orig.Invoke(self)); if (Object.op_Implicit((Object)(object)obj2)) { PositionedByVanillaSpawn.Add(val); } return obj2; } private static void OnBodyStart(CharacterBody body) { //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) if (!Plugin.IsPvPModeActive || !NetworkServer.active || !Object.op_Implicit((Object)(object)body) || !Object.op_Implicit((Object)(object)body.master) || !body.isPlayerControlled) { return; } EnsureStageState(body); if (SpawnedThisStage.Add(body.master) && PvPTeamManager.TryGetTeamId(body.master, out var teamId)) { if (!PositionedByVanillaSpawn.Remove(body.master) && CanUseMapWideTeamSpawns()) { Vector3 spawnPosition = GetSpawnPosition(body, teamId, isRespawn: false); TeleportHelper.TeleportBody(body, spawnPosition, true); } AddProtection(body, PvPConfig.SpawnInvulnerabilitySeconds.Value); } } private static void EnsureStageState() { Stage instance = Stage.instance; SceneInfo instance2 = SceneInfo.instance; int num = (Object.op_Implicit((Object)(object)Run.instance) ? Run.instance.stageClearCount : 0); int num2 = (Object.op_Implicit((Object)(object)instance) ? ((Object)instance).GetInstanceID() : 0); int num3 = (Object.op_Implicit((Object)(object)instance2) ? ((Object)instance2).GetInstanceID() : 0); if (stageStamp != num || stageInstanceId != num2 || sceneInstanceId != num3) { ClearStageState(); stageStamp = num; stageInstanceId = num2; sceneInstanceId = num3; } } private static void EnsureStageState(CharacterBody body) { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) EnsureStageState(); if (!hasStageOrigin) { stageOrigin = body.footPosition; hasStageOrigin = true; } } private static bool CanUseMapWideTeamSpawns() { //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Invalid comparison between Unknown and I4 Stage instance = Stage.instance; SceneInfo instance2 = SceneInfo.instance; if (instance == null || !Object.op_Implicit((Object)(object)instance) || instance2 == null || !Object.op_Implicit((Object)(object)instance2) || !Object.op_Implicit((Object)(object)instance2.groundNodes)) { return false; } SceneDef sceneDef = instance2.sceneDef; if (Object.op_Implicit((Object)(object)sceneDef) && Object.op_Implicit((Object)(object)((Component)instance2).GetComponent()) && (int)sceneDef.sceneType == 1 && !sceneDef.isFinalStage && !sceneDef.preventStageAdvanceCounter && !sceneDef.suppressPlayerEntry && !Object.op_Implicit((Object)(object)MeridianEventTriggerInteraction.instance)) { return !Object.op_Implicit((Object)(object)SpawnPointLimiter.Instance); } return false; } private static void PrepareDistributedTeamSpawnPlan(SceneDirector sceneDirector, List spawnPointsBeforeGeneration) { //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Unknown result type (might be due to invalid IL or missing references) //IL_0143: Unknown result type (might be due to invalid IL or missing references) //IL_014d: Expected O, but got Unknown //IL_015a: Unknown result type (might be due to invalid IL or missing references) //IL_03c0: Unknown result type (might be due to invalid IL or missing references) //IL_03c5: Unknown result type (might be due to invalid IL or missing references) EnsureStageState(); ClearSpawnPlan(); List> participatingPlayers = GetParticipatingPlayers(); if (participatingPlayers.Count == 0) { return; } SortedDictionary sortedDictionary = new SortedDictionary(); for (int i = 0; i < participatingPlayers.Count; i++) { int value = participatingPlayers[i].Value; sortedDictionary.TryGetValue(value, out var value2); sortedDictionary[value] = value2 + 1; } List list = new List(sortedDictionary.Keys); List validSpawnPoints = GetValidSpawnPoints(); Vector3 position; bool flag = TryGetVanillaRegionPosition(sceneDirector, spawnPointsBeforeGeneration, validSpawnPoints, out position); NodeGraph groundNodes = SceneInfo.instance.groundNodes; List list2 = BuildMapWideCandidates(groundNodes, flag ? new Vector3?(position) : ((Vector3?)null)); if (list2.Count == 0) { Plugin.Log.LogWarning((object)"No eligible map-wide nodes were found for PvP spawns; keeping the vanilla spawn cluster."); return; } plannedNodeGraph = groundNodes; PlannedNodeCandidates.AddRange(list2); for (int j = 0; j < list2.Count; j++) { PlannedNodesByIndex[list2[j].Node] = list2[j]; } BuildVanillaStyleAnchorCandidates(sceneDirector); plannedSpawnRng = new Xoroshiro128Plus((Object.op_Implicit((Object)(object)Run.instance) ? Run.instance.seed : 0) ^ ((ulong)(uint)stageStamp << 32) ^ 0x505650535041574EL); int num = list[0]; if (flag && TryFindClosestCandidate(position, out var closest) && !TryCreateTeamAnchorAtNode(num, closest)) { Plugin.Log.LogWarning((object)"Could not recreate the vanilla starting region for the first PvP team."); } if (!TeamAnchorSpawnPoints.ContainsKey(num) && !TryCreateTeamAnchor(num, sceneDirector, preferTeleporterDistance: true)) { Plugin.Log.LogWarning((object)"Could not create the first PvP team anchor; keeping vanilla spawn selection."); ClearSpawnPlan(); return; } for (int k = 1; k < list.Count; k++) { if (!TryCreateTeamAnchor(list[k], sceneDirector, preferTeleporterDistance: false)) { Plugin.Log.LogWarning((object)$"Could not create a separated spawn anchor for PvP team {list[k] + 1}."); } } for (int l = 0; l < list.Count; l++) { int num2 = list[l]; if (TeamAnchorSpawnPoints.TryGetValue(num2, out SpawnPoint value3) && Object.op_Implicit((Object)(object)value3)) { int num3 = Math.Max(1, sortedDictionary[num2]); List list3 = new List(num3); AddPointToTeamPool(list3, value3); SpawnPoint spawnPoint; while (list3.Count < num3 && TryCreateNearbyTeamSpawnPoint(num2, out spawnPoint)) { AddPointToTeamPool(list3, spawnPoint); } if (list3.Count < num3) { Plugin.Log.LogWarning((object)$"PvP team {num2 + 1} has {num3} players but only {list3.Count} unique initial spawn points; its anchor may be reused."); } TeamSpawnPointPools[num2] = list3; } } Dictionary dictionary = new Dictionary(); for (int m = 0; m < participatingPlayers.Count; m++) { NetworkUser key = participatingPlayers[m].Key; int value4 = participatingPlayers[m].Value; CharacterMaster val = ((Object.op_Implicit((Object)(object)key) && Object.op_Implicit((Object)(object)key.master)) ? key.master : null); if (Object.op_Implicit((Object)(object)val) && TeamSpawnPointPools.TryGetValue(value4, out List value5) && value5.Count != 0) { dictionary.TryGetValue(value4, out var value6); SpawnPoint val2 = value5[Math.Min(value6, value5.Count - 1)]; dictionary[value4] = value6 + 1; InitialPlayerSpawnAssignments[val] = val2; ClaimedInitialSpawnPoints.Add(val2); } } teamSpawnPlanPrepared = TeamSpawnPointPools.Count > 0; if (teamSpawnPlanPrepared) { stageOrigin = TeamAnchors[num]; hasStageOrigin = true; LogTeamAnchorSeparation(list); } } private static List> GetParticipatingPlayers() { List> list = new List>(); foreach (KeyValuePair assignment in PvPTeamManager.GetAssignments()) { if (Object.op_Implicit((Object)(object)assignment.Key) && assignment.Key.isParticipating) { list.Add(assignment); } } list.Sort((KeyValuePair left, KeyValuePair right) => StringComparer.Ordinal.Compare(((object)left.Key.id/*cast due to .constrained prefix*/).ToString(), ((object)right.Key.id/*cast due to .constrained prefix*/).ToString())); return list; } private static List GetValidSpawnPoints() { List list = new List(); ReadOnlyCollection readOnlyInstancesList = SpawnPoint.readOnlyInstancesList; for (int i = 0; i < readOnlyInstancesList.Count; i++) { if (Object.op_Implicit((Object)(object)readOnlyInstancesList[i])) { list.Add(readOnlyInstancesList[i]); } } return list; } private static bool TryGetVanillaRegionPosition(SceneDirector sceneDirector, List spawnPointsBeforeGeneration, List spawnPointsAfterGeneration, out Vector3 position) { //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) HashSet hashSet = new HashSet(spawnPointsBeforeGeneration); List list = new List(); for (int i = 0; i < spawnPointsAfterGeneration.Count; i++) { SpawnPoint val = spawnPointsAfterGeneration[i]; if (Object.op_Implicit((Object)(object)val) && !hashSet.Contains(val)) { list.Add(val); } } if (TrySelectSpawnPointPosition(list, out position)) { return true; } List list2 = new List(); for (int j = 0; j < spawnPointsBeforeGeneration.Count; j++) { if (Object.op_Implicit((Object)(object)spawnPointsBeforeGeneration[j])) { list2.Add(spawnPointsBeforeGeneration[j]); } } if (Object.op_Implicit((Object)(object)sceneDirector) && Object.op_Implicit((Object)(object)sceneDirector.teleporterInstance) && list2.Count > RoR2Application.maxPlayers) { Vector3 teleporterPosition = sceneDirector.teleporterInstance.transform.position; list2.Sort(delegate(SpawnPoint left, SpawnPoint right) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) Vector3 val2 = ((Component)left).transform.position - teleporterPosition; float sqrMagnitude = ((Vector3)(ref val2)).sqrMagnitude; val2 = ((Component)right).transform.position - teleporterPosition; return sqrMagnitude.CompareTo(((Vector3)(ref val2)).sqrMagnitude); }); list2.RemoveRange(0, list2.Count - RoR2Application.maxPlayers); } return TrySelectSpawnPointPosition(list2, out position); } private static bool TrySelectSpawnPointPosition(List points, out Vector3 position) { //IL_002d: 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_007f: 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) for (int i = 0; i < points.Count; i++) { if (Object.op_Implicit((Object)(object)points[i]) && !points[i].consumed) { position = ((Component)points[i]).transform.position; return true; } } for (int j = 0; j < points.Count; j++) { if (Object.op_Implicit((Object)(object)points[j])) { position = ((Component)points[j]).transform.position; return true; } } position = default(Vector3); return false; } private static List BuildMapWideCandidates(NodeGraph groundNodes, Vector3? vanillaRegionPosition) { //IL_0114: Unknown result type (might be due to invalid IL or missing references) //IL_011f: Unknown result type (might be due to invalid IL or missing references) //IL_0124: Unknown result type (might be due to invalid IL or missing references) //IL_0126: Unknown result type (might be due to invalid IL or missing references) //IL_0128: Unknown result type (might be due to invalid IL or missing references) //IL_0135: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_01a6: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_01b8: Unknown result type (might be due to invalid IL or missing references) //IL_01bd: 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_0159: Unknown result type (might be due to invalid IL or missing references) //IL_016a: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Unknown result type (might be due to invalid IL or missing references) List list = groundNodes.GetActiveNodesForHullMaskWithFlagConditions((HullMask)2, (NodeFlags)0, (NodeFlags)4); if (Object.op_Implicit((Object)(object)Stage.instance) && Stage.instance.usePod) { List list2 = new List(); NodeFlags val = default(NodeFlags); for (int i = 0; i < list.Count; i++) { if (groundNodes.GetNodeFlags(list[i], ref val) && (val & 1) != 0) { list2.Add(list[i]); } } if (list2.Count > 0) { list = list2; } } if (PlayerSpawnInhibitor.readOnlyInstancesList.Count > 0) { List list3 = new List(); for (int j = 0; j < list.Count; j++) { bool flag = false; foreach (PlayerSpawnInhibitor readOnlyInstances in PlayerSpawnInhibitor.readOnlyInstancesList) { if (Object.op_Implicit((Object)(object)readOnlyInstances) && readOnlyInstances.IsInhibiting(groundNodes, list[j])) { flag = true; break; } } if (!flag) { list3.Add(list[j]); } } if (list3.Count > 0) { list = list3; } } if (vanillaRegionPosition.HasValue) { NodeIndex val2 = groundNodes.FindClosestNode(vanillaRegionPosition.Value, (HullClassification)0, float.PositiveInfinity); if (val2 != NodeIndex.invalid) { HashSet hashSet = CollectConnectedHumanNodes(groundNodes, val2); if (hashSet.Count > 0) { List list4 = new List(); for (int k = 0; k < list.Count; k++) { if (hashSet.Contains(list[k])) { list4.Add(list[k]); } } if (list4.Count > 0) { list = list4; } } } } List list5 = new List(list.Count); Vector3 position = default(Vector3); for (int l = 0; l < list.Count; l++) { if (groundNodes.GetNodePosition(list[l], ref position)) { list5.Add(new NodeCandidate(list[l], position)); } } return list5; } private static HashSet CollectConnectedHumanNodes(NodeGraph groundNodes, NodeIndex startNode) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Expected O, but got Unknown //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) HashSet hashSet = new HashSet(); NodeGraphSpider val = new NodeGraphSpider(groundNodes, (HullMask)1); val.AddNodeForNextStep(startNode); int i = 0; while (val.PerformStep()) { for (List collectedSteps = val.collectedSteps; i < collectedSteps.Count; i++) { hashSet.Add(collectedSteps[i].node); } } return hashSet; } private static bool TryCreateTeamAnchor(int teamId, SceneDirector? sceneDirector, bool preferTeleporterDistance) { if (plannedNodeGraph == null || !Object.op_Implicit((Object)(object)plannedNodeGraph) || plannedSpawnRng == null) { return false; } if (!TrySelectFarthestAnchor(sceneDirector, preferTeleporterDistance, out var selected)) { return false; } return TryCreateTeamAnchorAtNode(teamId, selected); } private static bool TryCreateTeamAnchorAtNode(int teamId, NodeCandidate selected) { //IL_0021: 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_0061: 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) if (plannedNodeGraph == null || !Object.op_Implicit((Object)(object)plannedNodeGraph) || plannedSpawnRng == null || !TryAddSpawnPoint(plannedNodeGraph, selected.Node, plannedSpawnRng, teamId, out SpawnPoint spawnPoint)) { return false; } TeamAnchorNodes[teamId] = selected.Node; TeamAnchorSpawnPoints[teamId] = spawnPoint; TeamAnchors[teamId] = ((Component)spawnPoint).transform.position; UsedSpawnNodes.Add(selected.Node); return true; } private static void BuildVanillaStyleAnchorCandidates(SceneDirector sceneDirector) { //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) PlannedAnchorCandidates.Clear(); GameObject val = ((Object.op_Implicit((Object)(object)sceneDirector) && Object.op_Implicit((Object)(object)sceneDirector.teleporterInstance)) ? sceneDirector.teleporterInstance : null); if (!Object.op_Implicit((Object)(object)val)) { PlannedAnchorCandidates.AddRange(PlannedNodeCandidates); return; } Vector3 teleporterPosition = val.transform.position; List list = new List(PlannedNodeCandidates); list.Sort(delegate(NodeCandidate left, NodeCandidate right) { //IL_0002: 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_0012: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) Vector3 val2 = left.Position - teleporterPosition; float sqrMagnitude = ((Vector3)(ref val2)).sqrMagnitude; val2 = right.Position - teleporterPosition; return sqrMagnitude.CompareTo(((Vector3)(ref val2)).sqrMagnitude); }); for (int num = list.Count * 3 / 4; num < list.Count; num++) { PlannedAnchorCandidates.Add(list[num]); } if (PlannedAnchorCandidates.Count == 0) { PlannedAnchorCandidates.AddRange(PlannedNodeCandidates); } } private static bool TrySelectFarthestAnchor(SceneDirector? sceneDirector, bool preferTeleporterDistance, out NodeCandidate selected) { //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0036: 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_007c: 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_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: 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_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) selected = default(NodeCandidate); bool flag = false; float num = float.NegativeInfinity; GameObject val = ((sceneDirector != null && Object.op_Implicit((Object)(object)sceneDirector)) ? sceneDirector.teleporterInstance : null); bool flag2 = Object.op_Implicit((Object)(object)val); Vector3 val2; Vector3 val3; if (!flag2) { val2 = default(Vector3); val3 = val2; } else { val3 = val.transform.position; } Vector3 val4 = val3; List list = ((PlannedAnchorCandidates.Count > 0) ? PlannedAnchorCandidates : PlannedNodeCandidates); for (int i = 0; i < list.Count; i++) { NodeCandidate nodeCandidate = list[i]; if (UsedSpawnNodes.Contains(nodeCandidate.Node)) { continue; } float num2; if (TeamAnchors.Count > 0) { num2 = float.PositiveInfinity; foreach (Vector3 value in TeamAnchors.Values) { num2 = Mathf.Min(num2, RegionDistanceSqr(nodeCandidate.Position, value)); } } else if (preferTeleporterDistance && flag2) { val2 = nodeCandidate.Position - val4; num2 = ((Vector3)(ref val2)).sqrMagnitude; } else { num2 = (float)nodeCandidate.Node.nodeIndex * 0.0001f; } if (!flag || num2 > num) { flag = true; num = num2; selected = nodeCandidate; } } return flag; } private static bool TryCreateNearbyTeamSpawnPoint(int teamId, out SpawnPoint spawnPoint) { //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Expected O, but got Unknown //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_015d: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_0179: 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_00df: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: 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_0109: Unknown result type (might be due to invalid IL or missing references) //IL_0125: Unknown result type (might be due to invalid IL or missing references) spawnPoint = null; if (plannedNodeGraph == null || !Object.op_Implicit((Object)(object)plannedNodeGraph) || plannedSpawnRng == null || !TeamAnchors.TryGetValue(teamId, out var value) || !TeamAnchorNodes.TryGetValue(teamId, out var value2)) { return false; } float num = Mathf.Max(0f, PvPConfig.IsFfa ? 0f : PvPConfig.TeamSpawnRadius.Value); float num2 = num * num; bool flag = false; NodeCandidate nodeCandidate = default(NodeCandidate); NodeGraphSpider val = new NodeGraphSpider(plannedNodeGraph, (HullMask)1); val.AddNodeForNextStep(value2); int i = 0; while (val.PerformStep()) { for (List collectedSteps = val.collectedSteps; i < collectedSteps.Count; i++) { NodeIndex node = collectedSteps[i].node; if (UsedSpawnNodes.Contains(node) || !PlannedNodesByIndex.TryGetValue(node, out var value3) || !IsNodeOwnedByTeam(value3, teamId)) { continue; } if (!flag) { flag = true; nodeCandidate = value3; } Vector3 val2 = value3.Position - value; float sqrMagnitude = ((Vector3)(ref val2)).sqrMagnitude; if (num > 0f && sqrMagnitude <= num2) { if (!TryAddSpawnPoint(plannedNodeGraph, value3.Node, plannedSpawnRng, teamId, out spawnPoint)) { return false; } UsedSpawnNodes.Add(value3.Node); return true; } } } if (!flag || !TryAddSpawnPoint(plannedNodeGraph, nodeCandidate.Node, plannedSpawnRng, teamId, out spawnPoint)) { return false; } UsedSpawnNodes.Add(nodeCandidate.Node); return true; } private static bool IsNodeOwnedByTeam(NodeCandidate candidate, int teamId) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) if (!TeamAnchors.TryGetValue(teamId, out var value)) { return false; } float num = RegionDistanceSqr(candidate.Position, value); foreach (KeyValuePair teamAnchor in TeamAnchors) { if (teamAnchor.Key != teamId) { float num2 = RegionDistanceSqr(candidate.Position, teamAnchor.Value); if (num2 < num || (Mathf.Approximately(num2, num) && teamAnchor.Key < teamId)) { return false; } } } return true; } private static float RegionDistanceSqr(Vector3 left, Vector3 right) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) float num = left.x - right.x; float num2 = left.z - right.z; return num * num + num2 * num2; } private static bool TryAddSpawnPoint(NodeGraph nodeGraph, NodeIndex node, Xoroshiro128Plus rng, int teamId, out SpawnPoint spawnPoint) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) spawnPoint = null; int count = SpawnPoint.readOnlyInstancesList.Count; SpawnPoint.AddSpawnPoint(nodeGraph, node, rng); ReadOnlyCollection readOnlyInstancesList = SpawnPoint.readOnlyInstancesList; for (int num = readOnlyInstancesList.Count - 1; num >= count; num--) { if (Object.op_Implicit((Object)(object)readOnlyInstancesList[num])) { spawnPoint = readOnlyInstancesList[num]; ((Object)((Component)spawnPoint).gameObject).name = $"PvP Team {teamId + 1} Spawn Point"; CreatedTeamSpawnPoints.Add(spawnPoint); return true; } } return false; } private static void AddPointToTeamPool(List pool, SpawnPoint point) { //IL_0036: 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) if (Object.op_Implicit((Object)(object)point) && ReservedTeamSpawnPoints.Add(point)) { pool.Add(point); if (plannedNodeGraph != null && Object.op_Implicit((Object)(object)plannedNodeGraph) && TryFindClosestCandidate(((Component)point).transform.position, out var closest)) { UsedSpawnNodes.Add(closest.Node); } } } private static bool TryConsumeUnreservedSpawnPoint(out Transform transform) { ReadOnlyCollection readOnlyInstancesList = SpawnPoint.readOnlyInstancesList; for (int i = 0; i < 2; i++) { for (int j = 0; j < readOnlyInstancesList.Count; j++) { SpawnPoint val = readOnlyInstancesList[j]; if (Object.op_Implicit((Object)(object)val) && !ReservedTeamSpawnPoints.Contains(val) && (i != 0 || !val.consumed)) { val.consumed = true; transform = ((Component)val).transform; return true; } } } transform = null; return false; } private static bool TryFindClosestCandidate(Vector3 position, out NodeCandidate closest) { //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) closest = default(NodeCandidate); bool result = false; float num = float.PositiveInfinity; for (int i = 0; i < PlannedNodeCandidates.Count; i++) { Vector3 val = PlannedNodeCandidates[i].Position - position; float sqrMagnitude = ((Vector3)(ref val)).sqrMagnitude; if (!(sqrMagnitude >= num)) { result = true; num = sqrMagnitude; closest = PlannedNodeCandidates[i]; } } return result; } private static bool TryGetPlannedPlayerSpawnPoint(CharacterMaster master, int teamId, out SpawnPoint spawnPoint) { spawnPoint = null; if (!teamSpawnPlanPrepared) { return false; } if (InitialPlayerSpawnAssignments.TryGetValue(master, out SpawnPoint value) && Object.op_Implicit((Object)(object)value)) { spawnPoint = value; return true; } if (!TryEnsureLateTeamPool(teamId, out List pool) || pool.Count == 0) { return false; } for (int i = 0; i < pool.Count; i++) { if (Object.op_Implicit((Object)(object)pool[i]) && !ClaimedInitialSpawnPoints.Contains(pool[i])) { spawnPoint = pool[i]; break; } } if (!Object.op_Implicit((Object)(object)spawnPoint) && TryCreateNearbyTeamSpawnPoint(teamId, out SpawnPoint spawnPoint2)) { AddPointToTeamPool(pool, spawnPoint2); spawnPoint = spawnPoint2; } if (!Object.op_Implicit((Object)(object)spawnPoint) && TeamAnchorSpawnPoints.TryGetValue(teamId, out SpawnPoint value2) && Object.op_Implicit((Object)(object)value2)) { Plugin.Log.LogWarning((object)$"Reusing PvP team {teamId + 1}'s anchor for a late initial spawn."); spawnPoint = value2; } if (!Object.op_Implicit((Object)(object)spawnPoint)) { return false; } InitialPlayerSpawnAssignments[master] = spawnPoint; ClaimedInitialSpawnPoints.Add(spawnPoint); return true; } private static bool TryEnsureLateTeamPool(int teamId, out List pool) { if (TeamSpawnPointPools.TryGetValue(teamId, out List value)) { pool = value; return true; } pool = new List(); if (!TryCreateTeamAnchor(teamId, null, preferTeleporterDistance: false) || !TeamAnchorSpawnPoints.TryGetValue(teamId, out SpawnPoint value2) || !Object.op_Implicit((Object)(object)value2)) { return false; } AddPointToTeamPool(pool, value2); TeamSpawnPointPools[teamId] = pool; Plugin.Log.LogInfo((object)$"Created a map-wide spawn region for late PvP team {teamId + 1}."); return true; } private static void LogTeamAnchorSeparation(List teamIds) { //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) float value = PvPConfig.MinimumSpawnDistance.Value; for (int i = 0; i < teamIds.Count; i++) { int num = teamIds[i]; if (!TeamAnchors.TryGetValue(num, out var value2)) { continue; } float num2 = float.PositiveInfinity; for (int j = 0; j < teamIds.Count; j++) { if (i != j && TeamAnchors.TryGetValue(teamIds[j], out var value3)) { num2 = Mathf.Min(num2, Mathf.Sqrt(RegionDistanceSqr(value2, value3))); } } if (float.IsPositiveInfinity(num2)) { Plugin.Log.LogInfo((object)$"Planned PvP team {num + 1} initial spawn at {value2}."); } else { Plugin.Log.LogInfo((object)$"Planned PvP team {num + 1} initial spawn at {value2}; nearest rival region is {num2:0.0} horizontal meters away."); } if (!float.IsPositiveInfinity(num2) && num2 < value) { Plugin.Log.LogWarning((object)$"This stage could only separate PvP team {num + 1} by {num2:0.0} m (desired {value:0.0} m). The farthest valid region was used."); } } } internal static Vector3 GetSpawnPosition(CharacterBody body, int teamId, bool isRespawn) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_0093: 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_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: 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_0063: Unknown result type (might be due to invalid IL or missing references) EnsureStageState(body); Vector3 value; if (isRespawn) { value = FindSeparatedFallback(body, teamId, randomizeAngle: true); } else if (!TeamAnchors.TryGetValue(teamId, out value)) { if (!TryGetPlannedSpawnAnchor(teamId, out value)) { value = FindSeparatedFallback(body, teamId, randomizeAngle: false); } TeamAnchors[teamId] = value; } float num = (PvPConfig.IsFfa ? 0f : PvPConfig.TeamSpawnRadius.Value); if (num <= 0f) { return value; } float num2 = Run.instance.spawnRng.nextNormalizedFloat * MathF.PI * 2f; float num3 = Run.instance.spawnRng.nextNormalizedFloat * num; Vector3 desired = value + new Vector3(Mathf.Cos(num2), 0f, Mathf.Sin(num2)) * num3; return FindSafePosition(body, desired); } private static bool TryGetPlannedSpawnAnchor(int teamId, out Vector3 anchor) { //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) if (TeamAnchors.TryGetValue(teamId, out anchor)) { return true; } if (TeamAnchorSpawnPoints.TryGetValue(teamId, out SpawnPoint value) && Object.op_Implicit((Object)(object)value)) { anchor = ((Component)value).transform.position; return true; } anchor = default(Vector3); return false; } private static Vector3 FindSeparatedFallback(CharacterBody body, int teamId, bool randomizeAngle) { //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0088: 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_008b: Unknown result type (might be due to invalid IL or missing references) int num = Math.Max(2, PvPConfig.IsFfa ? PvPTeamRegistry.Count : PvPConfig.TeamCount.Value); float num2 = MathF.PI * 2f * (float)teamId / (float)num; if (randomizeAngle) { num2 += Run.instance.spawnRng.nextNormalizedFloat * 0.5f; } float num3 = PvPConfig.MinimumSpawnDistance.Value * (1f + 0.25f * (float)(teamId % 3)); Vector3 desired = stageOrigin + new Vector3(Mathf.Cos(num2), 0f, Mathf.Sin(num2)) * num3; return FindSafePosition(body, desired); } private static Vector3 FindSafePosition(CharacterBody body, Vector3 desired) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) Vector3? val = TeleportHelper.FindSafeTeleportDestination(desired, body, Run.instance.spawnRng); if (val.HasValue) { return val.Value; } Vector3? val2 = TeleportHelper.FindSafeTeleportDestination(stageOrigin, body, Run.instance.spawnRng); if (val2.HasValue) { return val2.Value; } Plugin.Log.LogWarning((object)$"No safe PvP spawn destination found near {desired}; using the known stage origin."); return stageOrigin; } internal static void AddProtection(CharacterBody body, float seconds) { if (Object.op_Implicit((Object)(object)body) && seconds > 0f) { body.AddTimedBuff(Buffs.Immune, seconds); } } private static void OnRunDestroy(Run run) { Reset(); } private static void ClearSpawnPlan() { for (int i = 0; i < CreatedTeamSpawnPoints.Count; i++) { SpawnPoint val = CreatedTeamSpawnPoints[i]; if (Object.op_Implicit((Object)(object)val)) { Object.Destroy((Object)(object)((Component)val).gameObject); } } CreatedTeamSpawnPoints.Clear(); TeamAnchors.Clear(); TeamAnchorNodes.Clear(); TeamAnchorSpawnPoints.Clear(); TeamSpawnPointPools.Clear(); InitialPlayerSpawnAssignments.Clear(); ReservedTeamSpawnPoints.Clear(); ClaimedInitialSpawnPoints.Clear(); UsedSpawnNodes.Clear(); PlannedNodeCandidates.Clear(); PlannedAnchorCandidates.Clear(); PlannedNodesByIndex.Clear(); SpawnPointsBeforeGeneration.Clear(); plannedNodeGraph = null; plannedSpawnRng = null; teamSpawnPlanPrepared = false; hasStageOrigin = false; } private static void ClearStageState() { SpawnedThisStage.Clear(); PositionedByVanillaSpawn.Clear(); ClearSpawnPlan(); } private static void Reset() { ClearStageState(); currentInitialSpawnMaster = null; stageStamp = int.MinValue; stageInstanceId = int.MinValue; sceneInstanceId = int.MinValue; } } } namespace PvPMode.Routes { internal static class PvPStageRouteManager { private const string SkyMeadowSceneName = "skymeadow"; internal static void Install() { Stage.onStageStartGlobal += OnStageStart; } internal static void Uninstall() { Stage.onStageStartGlobal -= OnStageStart; } private static void OnStageStart(Stage stage) { if (NetworkServer.active && Plugin.IsPvPModeActive && Object.op_Implicit((Object)(object)stage) && Object.op_Implicit((Object)(object)stage.sceneDef) && stage.sceneDef.baseSceneName.Equals("skymeadow", StringComparison.OrdinalIgnoreCase)) { ((MonoBehaviour)Plugin.Instance).StartCoroutine(ApplyRouteWhenReady(stage)); } } private static IEnumerator ApplyRouteWhenReady(Stage expectedStage) { for (int frame = 0; frame < 600; frame++) { if (!((Object)(object)Stage.instance == (Object)(object)expectedStage)) { break; } TeleporterInteraction instance = TeleporterInteraction.instance; if (Object.op_Implicit((Object)(object)instance) && TryFindLunarStateMachine(((Component)instance).gameObject, out EntityStateMachine result)) { bool stageFiveDefaultsToLoop = PvPConfig.StageFiveDefaultsToLoop; EntityState nextState = (EntityState)(stageFiveDefaultsToLoop ? new Idle() : new Active()); result.SetNextState(nextState); Plugin.Log.LogInfo((object)("Sky Meadow primordial teleporter defaulted to " + (stageFiveDefaultsToLoop ? "Loop" : "Moon") + ". Players may still rotate it.")); yield break; } yield return null; } Plugin.Log.LogWarning((object)"Could not find Sky Meadow's primordial teleporter state machine; its vanilla alignment was left unchanged."); } private static bool TryFindLunarStateMachine(GameObject teleporterObject, out EntityStateMachine result) { EntityStateMachine[] componentsInChildren = teleporterObject.GetComponentsInChildren(true); foreach (EntityStateMachine val in componentsInChildren) { if (IsLunarState(((object)val.state)?.GetType()) || IsLunarState(((SerializableEntityStateType)(ref val.initialStateType)).stateType) || IsLunarState(((SerializableEntityStateType)(ref val.mainStateType)).stateType)) { result = val; return true; } } result = null; return false; } private static bool IsLunarState(Type? stateType) { return stateType?.Namespace == typeof(LunarTeleporterBaseState).Namespace; } } } namespace PvPMode.Respawn { internal static class PvPRespawnManager { private readonly struct PendingRespawn { internal int Generation { get; } internal float Deadline { get; } internal PendingRespawn(int generation, float deadline) { Generation = generation; Deadline = deadline; } } private sealed class RespawnCountdownMessage : MessageBase { internal NetworkInstanceId MasterNetId; internal bool Active; internal float Deadline; internal int RemainingLives; public override void Serialize(NetworkWriter writer) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) writer.Write(MasterNetId); writer.Write(Active); writer.Write(Deadline); writer.Write(RemainingLives); } public override void Deserialize(NetworkReader reader) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) MasterNetId = reader.ReadNetworkId(); Active = reader.ReadBoolean(); Deadline = reader.ReadSingle(); RemainingLives = reader.ReadInt32(); } } [CompilerGenerated] private static class <>O { public static Action <0>__OnCharacterDeath; public static Action <1>__OnBodyStart; public static NetworkUserGenericDelegate <2>__OnNetworkUserLost; public static Action <3>__OnStartClient; public static hook_BeginGameOver <4>__RunBeginGameOver; public static Action <5>__OnRunDestroy; public static NetworkMessageDelegate <6>__ClientHandleCountdown; } private const short CountdownMessageType = 19736; private static readonly Dictionary PendingRespawns = new Dictionary(); private static bool installed; private static int nextGeneration; internal static void Install() { //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Expected O, but got Unknown //IL_009e: 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_00a9: Expected O, but got Unknown if (!installed) { installed = true; GlobalEventManager.onCharacterDeathGlobal += OnCharacterDeath; CharacterBody.onBodyStartGlobal += OnBodyStart; object obj = <>O.<2>__OnNetworkUserLost; if (obj == null) { NetworkUserGenericDelegate val = OnNetworkUserLost; <>O.<2>__OnNetworkUserLost = val; obj = (object)val; } NetworkUser.onNetworkUserLost += (NetworkUserGenericDelegate)obj; NetworkManagerSystem.onStartClientGlobal += OnStartClient; object obj2 = <>O.<4>__RunBeginGameOver; if (obj2 == null) { hook_BeginGameOver val2 = RunBeginGameOver; <>O.<4>__RunBeginGameOver = val2; obj2 = (object)val2; } Run.BeginGameOver += (hook_BeginGameOver)obj2; Run.onRunDestroyGlobal += OnRunDestroy; PvPRespawnCountdownUI.Install(); NetworkClient val3 = (Object.op_Implicit((Object)(object)NetworkManagerSystem.singleton) ? ((NetworkManager)NetworkManagerSystem.singleton).client : null); if (val3 != null) { OnStartClient(val3); } } } internal static void Uninstall() { //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Expected O, but got Unknown //IL_009e: 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_00a9: Expected O, but got Unknown if (installed) { installed = false; GlobalEventManager.onCharacterDeathGlobal -= OnCharacterDeath; CharacterBody.onBodyStartGlobal -= OnBodyStart; object obj = <>O.<2>__OnNetworkUserLost; if (obj == null) { NetworkUserGenericDelegate val = OnNetworkUserLost; <>O.<2>__OnNetworkUserLost = val; obj = (object)val; } NetworkUser.onNetworkUserLost -= (NetworkUserGenericDelegate)obj; NetworkManagerSystem.onStartClientGlobal -= OnStartClient; object obj2 = <>O.<4>__RunBeginGameOver; if (obj2 == null) { hook_BeginGameOver val2 = RunBeginGameOver; <>O.<4>__RunBeginGameOver = val2; obj2 = (object)val2; } Run.BeginGameOver -= (hook_BeginGameOver)obj2; Run.onRunDestroyGlobal -= OnRunDestroy; PendingRespawns.Clear(); PvPRespawnCountdownUI.Uninstall(); } } private static void OnStartClient(NetworkClient client) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Expected O, but got Unknown object obj = <>O.<6>__ClientHandleCountdown; if (obj == null) { NetworkMessageDelegate val = ClientHandleCountdown; <>O.<6>__ClientHandleCountdown = val; obj = (object)val; } client.RegisterHandler((short)19736, (NetworkMessageDelegate)obj); } private static void ClientHandleCountdown(NetworkMessage networkMessage) { //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) RespawnCountdownMessage respawnCountdownMessage = networkMessage.ReadMessage(); if (respawnCountdownMessage.Active) { PvPRespawnCountdownUI.SetCountdown(respawnCountdownMessage.MasterNetId, respawnCountdownMessage.Deadline, respawnCountdownMessage.RemainingLives); } else { PvPRespawnCountdownUI.ClearCountdown(respawnCountdownMessage.MasterNetId); } } private static void OnCharacterDeath(DamageReport report) { if (!Plugin.IsPvPModeActive || !NetworkServer.active) { return; } CharacterMaster victimMaster = report.victimMaster; if (!Object.op_Implicit((Object)(object)victimMaster) || !Object.op_Implicit((Object)(object)victimMaster.playerCharacterMasterController)) { return; } if (!PvPMatchManager.CanRespawn(victimMaster)) { CancelPendingRespawn(victimMaster); } else if (!PendingRespawns.ContainsKey(victimMaster)) { float currentRespawnDelaySeconds = PvPConfig.CurrentRespawnDelaySeconds; Run instance = Run.instance; float deadline = (Object.op_Implicit((Object)(object)instance) ? instance.fixedTime : Time.fixedTime) + currentRespawnDelaySeconds; PendingRespawn value = new PendingRespawn(++nextGeneration, deadline); PendingRespawns[victimMaster] = value; if (PvPConfig.CurrentMatchMode == PvPConfig.MatchModeKind.LimitedLives) { SendCountdown(victimMaster, active: true, deadline); } ((MonoBehaviour)Plugin.Instance).StartCoroutine(RespawnAfterDelay(victimMaster, value.Generation, currentRespawnDelaySeconds)); } } private static IEnumerator RespawnAfterDelay(CharacterMaster master, int generation, float delay) { yield return (object)new WaitForSeconds(delay); if (!IsCurrentGeneration(master, generation)) { yield break; } if (!Plugin.IsPvPModeActive || !NetworkServer.active || !Object.op_Implicit((Object)(object)master) || !PvPMatchManager.CanRespawn(master)) { CancelPendingRespawn(master, generation); yield break; } CharacterBody body = master.GetBody(); if (body != null && Object.op_Implicit((Object)(object)body) && Object.op_Implicit((Object)(object)body.healthComponent) && body.healthComponent.alive) { CancelPendingRespawn(master, generation); yield break; } if (!PvPTeamManager.TryGetTeamId(master, out var teamId)) { CancelPendingRespawn(master, generation); yield break; } CharacterBody val = (Object.op_Implicit((Object)(object)master.bodyPrefab) ? master.bodyPrefab.GetComponent() : null); if (val == null || !Object.op_Implicit((Object)(object)val)) { Plugin.Log.LogError((object)("Cannot respawn " + ((Object)master).name + ": body prefab is unavailable.")); CancelPendingRespawn(master, generation); yield break; } Vector3 spawnPosition = PvPSpawnManager.GetSpawnPosition(val, teamId, isRespawn: true); CharacterBody val2 = master.Respawn(spawnPosition, Quaternion.Euler(0f, Run.instance.spawnRng.RangeFloat(0f, 360f), 0f), true); PvPTeamManager.ApplyTeam(master, teamId); if (val2 != null) { PvPSpawnManager.AddProtection(val2, PvPConfig.RespawnInvulnerabilitySeconds.Value); } CancelPendingRespawn(master, generation); } private static void OnBodyStart(CharacterBody body) { if (NetworkServer.active && Object.op_Implicit((Object)(object)body) && Object.op_Implicit((Object)(object)body.master)) { CancelPendingRespawn(body.master); } } private static void OnNetworkUserLost(NetworkUser user) { CharacterMaster val = ((Object.op_Implicit((Object)(object)user) && Object.op_Implicit((Object)(object)user.master)) ? user.master : null); if (val != null) { CancelPendingRespawn(val); } } private static bool IsCurrentGeneration(CharacterMaster master, int generation) { if (master != null && PendingRespawns.TryGetValue(master, out var value)) { return value.Generation == generation; } return false; } private static void CancelPendingRespawn(CharacterMaster master, int? generation = null) { if (master != null && PendingRespawns.TryGetValue(master, out var value) && (!generation.HasValue || value.Generation == generation.Value)) { PendingRespawns.Remove(master); if (Object.op_Implicit((Object)(object)master)) { SendCountdown(master, active: false, 0f); } } } private static void SendCountdown(CharacterMaster master, bool active, float deadline) { //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_009f: 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) if (!Object.op_Implicit((Object)(object)master) || !Object.op_Implicit((Object)(object)master.networkIdentity)) { return; } PlayerCharacterMasterController playerCharacterMasterController = master.playerCharacterMasterController; NetworkUser val = (Object.op_Implicit((Object)(object)playerCharacterMasterController) ? playerCharacterMasterController.networkUser : null); if (!Object.op_Implicit((Object)(object)val)) { return; } RespawnCountdownMessage respawnCountdownMessage = new RespawnCountdownMessage { MasterNetId = master.networkIdentity.netId, Active = active, Deadline = deadline, RemainingLives = PvPMatchManager.GetRemainingLives(val) }; NetworkConnection connectionToClient = ((NetworkBehaviour)val).connectionToClient; if (connectionToClient != null) { connectionToClient.Send((short)19736, (MessageBase)(object)respawnCountdownMessage); } if (((NetworkBehaviour)val).isLocalPlayer) { if (active) { PvPRespawnCountdownUI.SetCountdown(respawnCountdownMessage.MasterNetId, deadline, respawnCountdownMessage.RemainingLives); } else { PvPRespawnCountdownUI.ClearCountdown(respawnCountdownMessage.MasterNetId); } } } private static void RunBeginGameOver(orig_BeginGameOver orig, Run self, GameEndingDef gameEndingDef) { if (Plugin.IsPvPModeActive && !PvPMatchManager.IsEndingTriggered) { Plugin.Log.LogDebug((object)"Suppressed a non-match ending while a PvP match is active."); } else { orig.Invoke(self, gameEndingDef); } } private static void OnRunDestroy(Run run) { PendingRespawns.Clear(); nextGeneration = 0; } } } namespace PvPMode.Minions { internal static class PvPMinionTeamController { private static bool installed; internal static void Install() { if (!installed) { installed = true; MinionOwnership.onMinionOwnerChangedGlobal += OnMinionOwnerChanged; CharacterBody.onBodyStartGlobal += OnBodyStart; } } internal static void Uninstall() { if (installed) { installed = false; MinionOwnership.onMinionOwnerChangedGlobal -= OnMinionOwnerChanged; CharacterBody.onBodyStartGlobal -= OnBodyStart; } } private static void OnMinionOwnerChanged(MinionOwnership ownership) { if (Plugin.IsPvPModeActive && NetworkServer.active && Object.op_Implicit((Object)(object)ownership)) { ApplyOwnerTeam(((Component)ownership).GetComponent()); } } private static void OnBodyStart(CharacterBody body) { if (Plugin.IsPvPModeActive && NetworkServer.active && Object.op_Implicit((Object)(object)body) && Object.op_Implicit((Object)(object)body.master)) { ApplyOwnerTeam(body.master); } } private static void ApplyOwnerTeam(CharacterMaster minionMaster) { //IL_003b: 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_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)minionMaster) || !Object.op_Implicit((Object)(object)minionMaster.minionOwnership) || !Object.op_Implicit((Object)(object)minionMaster.minionOwnership.ownerMaster)) { return; } CharacterMaster val = PvPRelationService.ResolveRootOwner(minionMaster); if (val != null && Object.op_Implicit((Object)(object)val) && PvPTeamRegistry.IsPvPTeam(val.teamIndex)) { minionMaster.teamIndex = val.teamIndex; CharacterBody body = minionMaster.GetBody(); if (body != null && Object.op_Implicit((Object)(object)body) && Object.op_Implicit((Object)(object)body.teamComponent)) { body.teamComponent.teamIndex = val.teamIndex; } if (PvPConfig.VerboseMinions.Value) { Plugin.Log.LogInfo((object)$"Minion {((Object)minionMaster).name} inherited PvP team {val.teamIndex} from {((Object)val).name}."); } } } } } namespace PvPMode.Match { internal static class PvPMatchManager { [CompilerGenerated] private static class <>O { public static Action <0>__OnRunStart; public static Action <1>__OnRunDestroy; public static Action <2>__OnCharacterDeath; public static Action <3>__OnPlayerLinked; public static NetworkUserGenericDelegate <4>__OnNetworkUserLost; } private static readonly Dictionary RemainingLives = new Dictionary(); private static readonly Dictionary TeamKills = new Dictionary(); private static readonly HashSet MatchTeams = new HashSet(); private static readonly HashSet DisconnectedUsers = new HashSet(); private static Run? activeRun; private static bool installed; private static bool endingTriggered; private static bool overtime; internal static bool IsEndingTriggered => endingTriggered; internal static void Install() { //IL_009e: 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_00a9: Expected O, but got Unknown if (!installed) { installed = true; Run.onRunStartGlobal += OnRunStart; Run.onRunDestroyGlobal += OnRunDestroy; GlobalEventManager.onCharacterDeathGlobal += OnCharacterDeath; PlayerCharacterMasterController.onLinkedToNetworkUserServerGlobal += OnPlayerLinked; object obj = <>O.<4>__OnNetworkUserLost; if (obj == null) { NetworkUserGenericDelegate val = OnNetworkUserLost; <>O.<4>__OnNetworkUserLost = val; obj = (object)val; } NetworkUser.onNetworkUserLost += (NetworkUserGenericDelegate)obj; } } internal static void Uninstall() { //IL_009e: 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_00a9: Expected O, but got Unknown if (installed) { installed = false; Run.onRunStartGlobal -= OnRunStart; Run.onRunDestroyGlobal -= OnRunDestroy; GlobalEventManager.onCharacterDeathGlobal -= OnCharacterDeath; PlayerCharacterMasterController.onLinkedToNetworkUserServerGlobal -= OnPlayerLinked; object obj = <>O.<4>__OnNetworkUserLost; if (obj == null) { NetworkUserGenericDelegate val = OnNetworkUserLost; <>O.<4>__OnNetworkUserLost = val; obj = (object)val; } NetworkUser.onNetworkUserLost -= (NetworkUserGenericDelegate)obj; ResetState(); } } private static void OnRunStart(Run run) { ResetState(); if (!Plugin.IsPvPModeActive || !NetworkServer.active) { return; } activeRun = run; foreach (var (val2, teamId) in PvPTeamManager.GetAssignments()) { if (Object.op_Implicit((Object)(object)val2) && val2.isParticipating) { AddPlayer(val2, teamId); } } AnnounceMatchStart(); if (PvPConfig.CurrentMatchMode == PvPConfig.MatchModeKind.TimedKills) { ((MonoBehaviour)Plugin.Instance).StartCoroutine(TimedMatchRoutine(run)); } } private static void OnRunDestroy(Run run) { ResetState(); } private static void OnPlayerLinked(PlayerCharacterMasterController controller) { if (Plugin.IsPvPModeActive && NetworkServer.active && Object.op_Implicit((Object)(object)controller) && Object.op_Implicit((Object)(object)controller.networkUser) && PvPTeamManager.TryGetTeamId(controller.networkUser, out var teamId)) { AddPlayer(controller.networkUser, teamId); } } private static void AddPlayer(NetworkUser user, int teamId) { DisconnectedUsers.Remove(user); RemainingLives.TryAdd(user, Math.Max(1, PvPConfig.LivesPerPlayer.Value)); TeamKills.TryAdd(teamId, 0); MatchTeams.Add(teamId); } private static void OnNetworkUserLost(NetworkUser user) { if (Plugin.IsPvPModeActive && NetworkServer.active && Object.op_Implicit((Object)(object)user)) { DisconnectedUsers.Add(user); if (PvPConfig.CurrentMatchMode == PvPConfig.MatchModeKind.LimitedLives) { EvaluateLimitedLivesWinner(); } } } private static void OnCharacterDeath(DamageReport report) { if (!Plugin.IsPvPModeActive || !NetworkServer.active || endingTriggered) { return; } CharacterMaster victimMaster = report.victimMaster; PlayerCharacterMasterController val = (Object.op_Implicit((Object)(object)victimMaster) ? victimMaster.playerCharacterMasterController : null); NetworkUser val2 = (Object.op_Implicit((Object)(object)val) ? val.networkUser : null); if (!Object.op_Implicit((Object)(object)val2)) { return; } bool flag = false; if (PvPConfig.CurrentMatchMode == PvPConfig.MatchModeKind.LimitedLives) { int num = Math.Max(0, GetRemainingLives(val2) - 1); RemainingLives[val2] = num; Broadcast("WATERBUCKET_PVP_MATCH_LIVES_MESSAGE", val2.userName, num.ToString()); flag = num == 0; } if (TryGetValidKillerTeam(report, out var killerTeamId, out var victimTeamId)) { int value2; int value = ((!TeamKills.TryGetValue(killerTeamId, out value2)) ? 1 : (value2 + 1)); TeamKills[killerTeamId] = value; MatchTeams.Add(killerTeamId); MatchTeams.Add(victimTeamId); Broadcast("WATERBUCKET_PVP_MATCH_SCORE_MESSAGE", PvPTeamRegistry.GetTeamNameToken(killerTeamId), value.ToString()); if (PvPConfig.CurrentMatchMode == PvPConfig.MatchModeKind.TimedKills && overtime) { EvaluateTimedWinner(); } } if (flag) { ((MonoBehaviour)Plugin.Instance).StartCoroutine(EvaluateLimitedLivesAfterReviveWindow()); } } private static IEnumerator EvaluateLimitedLivesAfterReviveWindow() { yield return (object)new WaitForSeconds(2.5f); if (Plugin.IsPvPModeActive && NetworkServer.active && !endingTriggered && PvPConfig.CurrentMatchMode == PvPConfig.MatchModeKind.LimitedLives) { EvaluateLimitedLivesWinner(); } } private static bool TryGetValidKillerTeam(DamageReport report, out int killerTeamId, out int victimTeamId) { killerTeamId = -1; victimTeamId = -1; if (!Object.op_Implicit((Object)(object)report.victimMaster) || !PvPTeamManager.TryGetTeamId(report.victimMaster, out victimTeamId)) { return false; } CharacterMaster val = (Object.op_Implicit((Object)(object)report.attackerMaster) ? report.attackerMaster : report.attackerOwnerMaster); if (!Object.op_Implicit((Object)(object)val) || !PvPTeamManager.TryGetTeamId(val, out killerTeamId)) { return false; } return killerTeamId != victimTeamId; } private static void EvaluateLimitedLivesWinner() { if (MatchTeams.Count == 0) { return; } HashSet hashSet = new HashSet(); foreach (KeyValuePair assignment in PvPTeamManager.GetAssignments()) { assignment.Deconstruct(out var key, out var value); NetworkUser val = key; int item = value; bool flag = Object.op_Implicit((Object)(object)val) && Object.op_Implicit((Object)(object)val.master) && val.master.hasBody && Object.op_Implicit((Object)(object)val.master.GetBody()) && Object.op_Implicit((Object)(object)val.master.GetBody().healthComponent) && val.master.GetBody().healthComponent.alive; if (Object.op_Implicit((Object)(object)val) && val.isParticipating && !DisconnectedUsers.Contains(val) && (GetRemainingLives(val) > 0 || flag)) { hashSet.Add(item); } } if (hashSet.Count == 1 && MatchTeams.Count >= 2) { TriggerWinner(hashSet.First()); } else if (hashSet.Count == 0) { TriggerNoViableTeams(); } } private static IEnumerator TimedMatchRoutine(Run run) { float finishTime = run.GetRunStopwatch() + (float)Math.Max(1, PvPConfig.TimeLimitMinutes.Value) * 60f; while ((Object)(object)activeRun == (Object)(object)run && Plugin.IsPvPModeActive && !endingTriggered && run.GetRunStopwatch() < finishTime) { yield return (object)new WaitForSeconds(1f); } if (!((Object)(object)activeRun != (Object)(object)run) && Plugin.IsPvPModeActive && !endingTriggered) { EvaluateTimedWinner(); } } private static void EvaluateTimedWinner() { int[] array = (from pair in PvPTeamManager.GetAssignments() where Object.op_Implicit((Object)(object)pair.Key) && pair.Key.isParticipating && !DisconnectedUsers.Contains(pair.Key) select pair.Value).Distinct().ToArray(); if (array.Length != 0) { int value; int highScore = array.Max((int teamId) => TeamKills.TryGetValue(teamId, out value) ? value : 0); int[] array2 = array.Where((int teamId) => (TeamKills.TryGetValue(teamId, out value) ? value : 0) == highScore).ToArray(); if (array2.Length == 1) { TriggerWinner(array2[0]); } else if (!overtime) { overtime = true; Broadcast("WATERBUCKET_PVP_MATCH_OVERTIME"); } } } private static void TriggerWinner(int teamId) { if (!endingTriggered) { endingTriggered = true; Broadcast("WATERBUCKET_PVP_MATCH_WINNER", PvPTeamRegistry.GetTeamNameToken(teamId)); Plugin.Log.LogInfo((object)$"PvP match won by team {teamId + 1}."); ((MonoBehaviour)Plugin.Instance).StartCoroutine(FinishMatchAfterAnnouncement()); } } private static void TriggerNoViableTeams() { if (!endingTriggered) { endingTriggered = true; Broadcast("WATERBUCKET_PVP_MATCH_NO_VIABLE_TEAMS"); Plugin.Log.LogInfo((object)"PvP match ended because no team has any lives or living players remaining."); ((MonoBehaviour)Plugin.Instance).StartCoroutine(FinishMatchAfterAnnouncement(useLossEnding: true)); } } private static IEnumerator FinishMatchAfterAnnouncement(bool useLossEnding = false) { yield return (object)new WaitForSeconds(2f); GameEndingDef val = (useLossEnding ? Plugin.GetLossEnding() : Plugin.GetMatchEnding()); Run instance = Run.instance; if (NetworkServer.active && instance != null && Object.op_Implicit((Object)(object)instance) && val != null && Object.op_Implicit((Object)(object)val)) { Plugin.Log.LogInfo((object)$"Beginning PvP game over with ending '{val.cachedName}' (loss={useLossEnding})."); instance.BeginGameOver(val); yield break; } Plugin.Log.LogError((object)($"Could not begin PvP game over: server={NetworkServer.active}, " + "run=" + BooleanText((Object?)(object)Run.instance) + ", ending=" + BooleanText((Object?)(object)val) + ".")); } private static string BooleanText(Object? value) { if (!Object.op_Implicit(value)) { return "missing"; } return "available"; } private static void AnnounceMatchStart() { switch (PvPConfig.CurrentMatchMode) { case PvPConfig.MatchModeKind.LimitedLives: Broadcast("WATERBUCKET_PVP_MATCH_START_LIVES", PvPConfig.LivesPerPlayer.Value.ToString()); break; case PvPConfig.MatchModeKind.Unlimited: Broadcast("WATERBUCKET_PVP_MATCH_START_UNLIMITED"); break; case PvPConfig.MatchModeKind.TimedKills: Broadcast("WATERBUCKET_PVP_MATCH_START_TIMED", PvPConfig.TimeLimitMinutes.Value.ToString()); break; } } internal static bool CanRespawn(CharacterMaster master) { if (!Plugin.IsPvPModeActive || endingTriggered || !Object.op_Implicit((Object)(object)master)) { return false; } if (PvPConfig.CurrentMatchMode != PvPConfig.MatchModeKind.LimitedLives) { return true; } PlayerCharacterMasterController playerCharacterMasterController = master.playerCharacterMasterController; if (Object.op_Implicit((Object)(object)playerCharacterMasterController) && Object.op_Implicit((Object)(object)playerCharacterMasterController.networkUser)) { return GetRemainingLives(playerCharacterMasterController.networkUser) > 0; } return false; } internal static void PrepareSeekerRevive(CharacterMaster master) { if (Plugin.IsPvPModeActive && NetworkServer.active && !endingTriggered && Object.op_Implicit((Object)(object)master) && PvPConfig.CurrentMatchMode == PvPConfig.MatchModeKind.LimitedLives) { PlayerCharacterMasterController playerCharacterMasterController = master.playerCharacterMasterController; NetworkUser val = (Object.op_Implicit((Object)(object)playerCharacterMasterController) ? playerCharacterMasterController.networkUser : null); if (Object.op_Implicit((Object)(object)val) && GetRemainingLives(val) <= 0) { RemainingLives[val] = 1; Broadcast("WATERBUCKET_PVP_MATCH_SEEKER_LIFE", val.userName); Plugin.Log.LogInfo((object)("Seeker restored one limited life to eliminated player " + val.userName + ".")); } } } internal static int GetRemainingLives(NetworkUser user) { if (!RemainingLives.TryGetValue(user, out var value)) { return Math.Max(1, PvPConfig.LivesPerPlayer.Value); } return value; } internal static int GetTeamKills(int teamId) { if (!TeamKills.TryGetValue(teamId, out var value)) { return 0; } return value; } private static void Broadcast(string token, params string[] parameters) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Expected O, but got Unknown Chat.SendBroadcastChat((ChatMessageBase)new SimpleChatMessage { baseToken = token, paramTokens = parameters }); } private static void ResetState() { activeRun = null; endingTriggered = false; overtime = false; RemainingLives.Clear(); TeamKills.Clear(); MatchTeams.Clear(); DisconnectedUsers.Clear(); } } } namespace PvPMode.Loadouts { internal readonly struct LoadoutPresetLoadResult { internal bool Success { get; } internal IReadOnlyDictionary Selections { get; } internal int SavedCount { get; } internal int MissingCount { get; } internal LoadoutPresetLoadResult(bool success, IReadOnlyDictionary selections, int savedCount, int missingCount) { Success = success; Selections = selections; SavedCount = savedCount; MissingCount = missingCount; } } internal static class PvPLoadoutPresetStore { [Serializable] private sealed class PresetPayload { public int version; public SerializedPresetEntry[] entries = Array.Empty(); } [Serializable] private sealed class SerializedPresetEntry { public int category; public bool equipment; public string internalName = string.Empty; public int count; } internal const int SlotCount = 5; private const int FormatVersion = 1; private static readonly ConfigEntry[] Slots = new ConfigEntry[5]; private static bool bound; internal static void Bind(ConfigFile config) { if (!bound) { bound = true; for (int i = 0; i < Slots.Length; i++) { int num = i + 1; Slots[i] = config.Bind("PvP.StartingLoadout.LocalPresets", $"Slot{num}", string.Empty, $"Local starting-loadout preset slot {num}. This value is not synchronized over the network."); } } } internal static bool IsSlotSaved(int slotIndex) { if (IsValidSlot(slotIndex)) { return !string.IsNullOrWhiteSpace(Slots[slotIndex].Value); } return false; } internal static int SaveSlot(int slotIndex) { if (!IsValidSlot(slotIndex)) { return 0; } List list = new List(); for (int i = 0; i < 9; i++) { StartingLoadoutCategory category = (StartingLoadoutCategory)i; foreach (StartingLoadoutOption availableDefinition in PvPStartingLoadoutManager.GetAvailableDefinitions(category)) { int clientChoiceCount = PvPStartingLoadoutManager.GetClientChoiceCount(category, availableDefinition.DefinitionIndex, availableDefinition.IsEquipment); if (clientChoiceCount > 0) { string internalName = GetInternalName(availableDefinition.DefinitionIndex, availableDefinition.IsEquipment); if (!string.IsNullOrEmpty(internalName)) { list.Add(new SerializedPresetEntry { category = i, equipment = availableDefinition.IsEquipment, internalName = internalName, count = clientChoiceCount }); } } } } PresetPayload presetPayload = new PresetPayload { version = 1, entries = list.ToArray() }; Slots[slotIndex].Value = JsonUtility.ToJson((object)presetPayload); return list.Sum((SerializedPresetEntry entry) => entry.count); } internal static LoadoutPresetLoadResult LoadSlot(int slotIndex) { Dictionary dictionary = new Dictionary(); if (!IsSlotSaved(slotIndex)) { return new LoadoutPresetLoadResult(success: false, dictionary, 0, 0); } try { PresetPayload presetPayload = JsonUtility.FromJson(Slots[slotIndex].Value); if (presetPayload == null || presetPayload.version != 1 || presetPayload.entries == null) { return new LoadoutPresetLoadResult(success: false, dictionary, 0, 0); } int num = 0; int num2 = 0; SerializedPresetEntry[] entries = presetPayload.entries; foreach (SerializedPresetEntry serializedPresetEntry in entries) { if (serializedPresetEntry != null && serializedPresetEntry.count > 0) { int num3 = Math.Clamp(serializedPresetEntry.count, 1, 99); num += num3; if (!TryResolveEntry(serializedPresetEntry, out var choice)) { num2 += num3; continue; } dictionary.TryGetValue(choice, out var value); dictionary[choice] = Math.Clamp(value + num3, 1, 99); } } return new LoadoutPresetLoadResult(success: true, dictionary, num, num2); } catch (Exception ex) { Plugin.Log.LogWarning((object)$"Could not read local PvP loadout preset slot {slotIndex + 1}: {ex.Message}"); return new LoadoutPresetLoadResult(success: false, dictionary, 0, 0); } } private static bool TryResolveEntry(SerializedPresetEntry entry, out StartingLoadoutChoice choice) { choice = default(StartingLoadoutChoice); if (entry.category < 0 || entry.category >= 9 || string.IsNullOrEmpty(entry.internalName)) { return false; } StartingLoadoutCategory category = (StartingLoadoutCategory)entry.category; foreach (StartingLoadoutOption availableDefinition in PvPStartingLoadoutManager.GetAvailableDefinitions(category)) { if (availableDefinition.IsEquipment == entry.equipment && string.Equals(GetInternalName(availableDefinition.DefinitionIndex, availableDefinition.IsEquipment), entry.internalName, StringComparison.Ordinal)) { choice = new StartingLoadoutChoice(category, availableDefinition.DefinitionIndex, availableDefinition.IsEquipment); return true; } } return false; } private static string GetInternalName(int definitionIndex, bool isEquipment) { if (isEquipment) { EquipmentDef equipmentDef = EquipmentCatalog.GetEquipmentDef((EquipmentIndex)definitionIndex); if (!Object.op_Implicit((Object)(object)equipmentDef)) { return string.Empty; } return ((Object)equipmentDef).name; } ItemDef itemDef = ItemCatalog.GetItemDef((ItemIndex)definitionIndex); if (!Object.op_Implicit((Object)(object)itemDef)) { return string.Empty; } return ((Object)itemDef).name; } private static bool IsValidSlot(int slotIndex) { if (bound && slotIndex >= 0) { return slotIndex < Slots.Length; } return false; } } internal enum StartingLoadoutCategory : byte { White, Green, Yellow, Orange, Red, Blue, VoidWhite, VoidGreen, VoidRed, Count } internal readonly struct StartingLoadoutChoice : IEquatable { internal StartingLoadoutCategory Category { get; } internal int DefinitionIndex { get; } internal bool IsEquipment { get; } internal StartingLoadoutChoice(StartingLoadoutCategory category, int definitionIndex, bool isEquipment) { Category = category; DefinitionIndex = definitionIndex; IsEquipment = isEquipment; } public bool Equals(StartingLoadoutChoice other) { if (Category == other.Category && DefinitionIndex == other.DefinitionIndex) { return IsEquipment == other.IsEquipment; } return false; } public override bool Equals(object? obj) { if (obj is StartingLoadoutChoice other) { return Equals(other); } return false; } public override int GetHashCode() { return ((((int)Category * 397) ^ DefinitionIndex) * 397) ^ (IsEquipment ? 1 : 0); } } internal readonly struct StartingLoadoutOption { internal int DefinitionIndex { get; } internal bool IsEquipment { get; } internal StartingLoadoutOption(int definitionIndex, bool isEquipment) { DefinitionIndex = definitionIndex; IsEquipment = isEquipment; } } internal static class PvPStartingLoadoutManager { private sealed class LoadoutRequestMessage : MessageBase { internal const byte SyncOperation = 0; internal const byte ChangeOperation = 1; internal const byte ReplaceOperation = 2; internal const byte ClearCategoryOperation = 3; internal byte Operation; internal StartingLoadoutCategory Category; internal int DefinitionIndex; internal bool IsEquipment; internal int Delta; internal LoadoutStateEntry[] Entries = Array.Empty(); public override void Serialize(NetworkWriter writer) { writer.Write(Operation); writer.Write((byte)Category); writer.Write(DefinitionIndex); writer.Write(IsEquipment); writer.Write(Delta); int num = Math.Min(Entries.Length, 1024); writer.Write((ushort)num); for (int i = 0; i < num; i++) { LoadoutStateEntry loadoutStateEntry = Entries[i]; writer.Write((byte)loadoutStateEntry.Category); writer.Write(loadoutStateEntry.DefinitionIndex); writer.Write(loadoutStateEntry.IsEquipment); writer.Write(loadoutStateEntry.Count); } } public override void Deserialize(NetworkReader reader) { Operation = reader.ReadByte(); Category = (StartingLoadoutCategory)reader.ReadByte(); DefinitionIndex = reader.ReadInt32(); IsEquipment = reader.ReadBoolean(); Delta = reader.ReadInt32(); int num = reader.ReadUInt16(); if (num > 1024) { Operation = byte.MaxValue; Entries = Array.Empty(); return; } Entries = new LoadoutStateEntry[num]; for (int i = 0; i < num; i++) { Entries[i] = new LoadoutStateEntry { Category = (StartingLoadoutCategory)reader.ReadByte(), DefinitionIndex = reader.ReadInt32(), IsEquipment = reader.ReadBoolean(), Count = reader.ReadInt32() }; } } } private struct LoadoutStateEntry { internal StartingLoadoutCategory Category; internal int DefinitionIndex; internal bool IsEquipment; internal int Count; } private sealed class LoadoutStateMessage : MessageBase { internal int[] Budgets = Array.Empty(); internal LoadoutStateEntry[] Entries = Array.Empty(); public override void Serialize(NetworkWriter writer) { writer.Write((byte)Budgets.Length); int[] budgets = Budgets; foreach (int num in budgets) { writer.Write(num); } writer.Write((ushort)Entries.Length); LoadoutStateEntry[] entries = Entries; for (int i = 0; i < entries.Length; i++) { LoadoutStateEntry loadoutStateEntry = entries[i]; writer.Write((byte)loadoutStateEntry.Category); writer.Write(loadoutStateEntry.DefinitionIndex); writer.Write(loadoutStateEntry.IsEquipment); writer.Write(loadoutStateEntry.Count); } } public override void Deserialize(NetworkReader reader) { Budgets = new int[reader.ReadByte()]; for (int i = 0; i < Budgets.Length; i++) { Budgets[i] = reader.ReadInt32(); } Entries = new LoadoutStateEntry[reader.ReadUInt16()]; for (int j = 0; j < Entries.Length; j++) { Entries[j] = new LoadoutStateEntry { Category = (StartingLoadoutCategory)reader.ReadByte(), DefinitionIndex = reader.ReadInt32(), IsEquipment = reader.ReadBoolean(), Count = reader.ReadInt32() }; } } } [CompilerGenerated] private static class <>O { public static Action <0>__OnStartServer; public static Action <1>__OnStartClient; public static NetworkUserGenericDelegate <2>__OnNetworkUserLost; public static Action <3>__OnRunStart; public static Action <4>__OnRunDestroy; public static Action <5>__OnBodyStart; public static NetworkMessageDelegate <6>__ServerHandleRequest; public static NetworkMessageDelegate <7>__ClientHandleState; public static Func <8>__GetServerBudget; } private const short RequestMessageType = 19734; private const short StateMessageType = 19735; private const int MaxReplacementEntries = 1024; private static readonly Dictionary> LobbySelections = new Dictionary>(); private static readonly Dictionary ClientSelection = new Dictionary(); private static readonly HashSet GrantedMasters = new HashSet(); private static readonly int[] ClientBudgets = new int[9]; private static bool installed; internal static event Action? ClientStateChanged; internal static void Install() { //IL_006d: 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_0078: Expected O, but got Unknown if (!installed) { installed = true; PvPLoadoutPresetStore.Bind(Plugin.Instance.Config); NetworkManagerSystem.onStartServerGlobal += OnStartServer; NetworkManagerSystem.onStartClientGlobal += OnStartClient; object obj = <>O.<2>__OnNetworkUserLost; if (obj == null) { NetworkUserGenericDelegate val = OnNetworkUserLost; <>O.<2>__OnNetworkUserLost = val; obj = (object)val; } NetworkUser.onNetworkUserLost += (NetworkUserGenericDelegate)obj; Run.onRunStartGlobal += OnRunStart; Run.onRunDestroyGlobal += OnRunDestroy; CharacterBody.onBodyStartGlobal += OnBodyStart; if (NetworkServer.active) { OnStartServer(); } NetworkClient val2 = (Object.op_Implicit((Object)(object)NetworkManagerSystem.singleton) ? ((NetworkManager)NetworkManagerSystem.singleton).client : null); if (val2 != null) { OnStartClient(val2); } CopyServerBudgetsToClient(); } } internal static void Uninstall() { //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Expected O, but got Unknown if (installed) { installed = false; NetworkManagerSystem.onStartServerGlobal -= OnStartServer; NetworkManagerSystem.onStartClientGlobal -= OnStartClient; object obj = <>O.<2>__OnNetworkUserLost; if (obj == null) { NetworkUserGenericDelegate val = OnNetworkUserLost; <>O.<2>__OnNetworkUserLost = val; obj = (object)val; } NetworkUser.onNetworkUserLost -= (NetworkUserGenericDelegate)obj; Run.onRunStartGlobal -= OnRunStart; Run.onRunDestroyGlobal -= OnRunDestroy; CharacterBody.onBodyStartGlobal -= OnBodyStart; LobbySelections.Clear(); ClientSelection.Clear(); GrantedMasters.Clear(); } } private static void OnStartServer() { //IL_0015: 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_0020: Expected O, but got Unknown object obj = <>O.<6>__ServerHandleRequest; if (obj == null) { NetworkMessageDelegate val = ServerHandleRequest; <>O.<6>__ServerHandleRequest = val; obj = (object)val; } NetworkServer.RegisterHandler((short)19734, (NetworkMessageDelegate)obj); } private static void OnStartClient(NetworkClient client) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Expected O, but got Unknown object obj = <>O.<7>__ClientHandleState; if (obj == null) { NetworkMessageDelegate val = ClientHandleState; <>O.<7>__ClientHandleState = val; obj = (object)val; } client.RegisterHandler((short)19735, (NetworkMessageDelegate)obj); } private static void ServerHandleRequest(NetworkMessage networkMessage) { LoadoutRequestMessage loadoutRequestMessage = networkMessage.ReadMessage(); NetworkUser val = FindUser(networkMessage.conn); if (val == null || !Object.op_Implicit((Object)(object)val) || !IsPvPLobbySelected()) { return; } if (loadoutRequestMessage.Operation == 0) { SendState(networkMessage.conn, val); } else if (loadoutRequestMessage.Operation == 2) { ReplaceSelection(val, loadoutRequestMessage.Entries); SendState(networkMessage.conn, val); } else if (loadoutRequestMessage.Operation == 3) { if ((int)loadoutRequestMessage.Category < 9) { ClearServerCategory(val, loadoutRequestMessage.Category); SendState(networkMessage.conn, val); } } else if (loadoutRequestMessage.Operation == 1 && Enum.IsDefined(typeof(StartingLoadoutCategory), loadoutRequestMessage.Category) && loadoutRequestMessage.Category != StartingLoadoutCategory.Count && (loadoutRequestMessage.Delta == 1 || loadoutRequestMessage.Delta == -1)) { TryChangeSelection(val, loadoutRequestMessage.Category, loadoutRequestMessage.DefinitionIndex, loadoutRequestMessage.IsEquipment, loadoutRequestMessage.Delta); SendState(networkMessage.conn, val); } } private static void ClientHandleState(NetworkMessage networkMessage) { LoadoutStateMessage loadoutStateMessage = networkMessage.ReadMessage(); Array.Clear(ClientBudgets, 0, ClientBudgets.Length); for (int i = 0; i < Math.Min(ClientBudgets.Length, loadoutStateMessage.Budgets.Length); i++) { ClientBudgets[i] = loadoutStateMessage.Budgets[i]; } ClientSelection.Clear(); LoadoutStateEntry[] entries = loadoutStateMessage.Entries; for (int j = 0; j < entries.Length; j++) { LoadoutStateEntry loadoutStateEntry = entries[j]; if (loadoutStateEntry.Count > 0 && (int)loadoutStateEntry.Category < 9) { ClientSelection[new StartingLoadoutChoice(loadoutStateEntry.Category, loadoutStateEntry.DefinitionIndex, loadoutStateEntry.IsEquipment)] = loadoutStateEntry.Count; } } PvPStartingLoadoutManager.ClientStateChanged?.Invoke(); } internal static void RequestSync() { if (NetworkServer.active) { NetworkUser localNetworkUser = GetLocalNetworkUser(); if (localNetworkUser != null && Object.op_Implicit((Object)(object)localNetworkUser)) { CopyServerStateToClient(localNetworkUser); } } else { SendRequest(new LoadoutRequestMessage { Operation = 0 }); } } internal static void RequestSelectionChange(StartingLoadoutCategory category, int definitionIndex, bool isEquipment, int delta) { NetworkUser localNetworkUser = GetLocalNetworkUser(); if (localNetworkUser != null && Object.op_Implicit((Object)(object)localNetworkUser) && IsPvPLobbySelected()) { if (NetworkServer.active) { TryChangeSelection(localNetworkUser, category, definitionIndex, isEquipment, delta); CopyServerStateToClient(localNetworkUser); return; } SendRequest(new LoadoutRequestMessage { Operation = 1, Category = category, DefinitionIndex = definitionIndex, IsEquipment = isEquipment, Delta = delta }); } } internal static int RequestSelectionReplacement(IReadOnlyDictionary requestedSelection) { NetworkUser localNetworkUser = GetLocalNetworkUser(); if (localNetworkUser == null || !Object.op_Implicit((Object)(object)localNetworkUser) || !IsPvPLobbySelected()) { return 0; } Dictionary dictionary = NormalizeSelection(requestedSelection, (StartingLoadoutCategory category) => GetClientBudget(category)); if (NetworkServer.active) { ReplaceSelection(localNetworkUser, dictionary.Select((KeyValuePair pair) => new LoadoutStateEntry { Category = pair.Key.Category, DefinitionIndex = pair.Key.DefinitionIndex, IsEquipment = pair.Key.IsEquipment, Count = pair.Value })); CopyServerStateToClient(localNetworkUser); } else { SendRequest(new LoadoutRequestMessage { Operation = 2, Entries = dictionary.Select((KeyValuePair pair) => new LoadoutStateEntry { Category = pair.Key.Category, DefinitionIndex = pair.Key.DefinitionIndex, IsEquipment = pair.Key.IsEquipment, Count = pair.Value }).ToArray() }); } return dictionary.Values.Sum(); } internal static void ClearCategory(StartingLoadoutCategory category) { NetworkUser localNetworkUser = GetLocalNetworkUser(); if (localNetworkUser != null && Object.op_Implicit((Object)(object)localNetworkUser)) { if (NetworkServer.active) { ClearServerCategory(localNetworkUser, category); CopyServerStateToClient(localNetworkUser); } else { SendRequest(new LoadoutRequestMessage { Operation = 3, Category = category }); } } } private static void ClearServerCategory(NetworkUser user, StartingLoadoutCategory category) { if (LobbySelections.TryGetValue(user, out Dictionary value)) { StartingLoadoutChoice[] array = value.Keys.Where((StartingLoadoutChoice startingLoadoutChoice) => startingLoadoutChoice.Category == category).ToArray(); foreach (StartingLoadoutChoice key in array) { value.Remove(key); } } } private static void SendRequest(LoadoutRequestMessage request) { NetworkClient val = (Object.op_Implicit((Object)(object)NetworkManagerSystem.singleton) ? ((NetworkManager)NetworkManagerSystem.singleton).client : null); if (val != null && val.isConnected) { val.Send((short)19734, (MessageBase)(object)request); } } private static bool TryChangeSelection(NetworkUser user, StartingLoadoutCategory category, int definitionIndex, bool isEquipment, int delta) { if (!IsValidDefinition(category, definitionIndex, isEquipment)) { return false; } Dictionary orCreateSelection = GetOrCreateSelection(user); StartingLoadoutChoice key = new StartingLoadoutChoice(category, definitionIndex, isEquipment); orCreateSelection.TryGetValue(key, out var value); if (delta < 0) { if (value <= 0) { return false; } if (value == 1) { orCreateSelection.Remove(key); } else { orCreateSelection[key] = value - 1; } return true; } int serverBudget = GetServerBudget(category); if (orCreateSelection.Where((KeyValuePair pair) => pair.Key.Category == category).Sum((KeyValuePair pair) => pair.Value) >= serverBudget) { return false; } orCreateSelection[key] = value + 1; return true; } private static void ReplaceSelection(NetworkUser user, IEnumerable entries) { Dictionary dictionary = new Dictionary(); foreach (LoadoutStateEntry item in entries.Take(1024)) { if (item.Count > 0 && (int)item.Category < 9) { StartingLoadoutChoice key = new StartingLoadoutChoice(item.Category, item.DefinitionIndex, item.IsEquipment); dictionary.TryGetValue(key, out var value); dictionary[key] = (int)Math.Min(99L, (long)value + (long)item.Count); } } LobbySelections[user] = NormalizeSelection(dictionary, GetServerBudget); } private static Dictionary NormalizeSelection(IEnumerable> requested, Func getBudget) { Dictionary dictionary = new Dictionary(); HashSet hashSet = BuildValidChoiceSet(); int[] array = new int[9]; for (int i = 0; i < array.Length; i++) { array[i] = Math.Max(0, getBudget((StartingLoadoutCategory)i)); } foreach (var (startingLoadoutChoice2, num2) in from pair in requested orderby pair.Key.Category, pair.Key.IsEquipment, pair.Key.DefinitionIndex select pair) { if ((int)startingLoadoutChoice2.Category < 9 && num2 > 0 && hashSet.Contains(startingLoadoutChoice2)) { int category = (int)startingLoadoutChoice2.Category; int num3 = Math.Min(Math.Min(num2, 99), array[category]); if (num3 > 0) { dictionary[startingLoadoutChoice2] = num3; array[category] -= num3; } } } return dictionary; } private static HashSet BuildValidChoiceSet() { HashSet hashSet = new HashSet(); for (int i = 0; i < 9; i++) { StartingLoadoutCategory category = (StartingLoadoutCategory)i; foreach (StartingLoadoutOption availableDefinition in GetAvailableDefinitions(category)) { hashSet.Add(new StartingLoadoutChoice(category, availableDefinition.DefinitionIndex, availableDefinition.IsEquipment)); } } return hashSet; } internal static void NotifyHostBudgetsChanged() { if (NetworkServer.active) { TrimAllSelections(); CopyServerBudgetsToClient(); BroadcastStates(); } } private static void TrimAllSelections() { foreach (Dictionary value in LobbySelections.Values) { foreach (StartingLoadoutCategory category in Enum.GetValues(typeof(StartingLoadoutCategory))) { if (category == StartingLoadoutCategory.Count) { continue; } int num = GetServerBudget(category); StartingLoadoutChoice[] array = (from startingLoadoutChoice in value.Keys where startingLoadoutChoice.Category == category orderby startingLoadoutChoice.DefinitionIndex select startingLoadoutChoice).ToArray(); foreach (StartingLoadoutChoice key in array) { int num3 = Math.Min(value[key], num); if (num3 <= 0) { value.Remove(key); } else { value[key] = num3; } num -= num3; } } } } private static void BroadcastStates() { foreach (NetworkConnection connection in NetworkServer.connections) { if (connection != null) { NetworkUser val = FindUser(connection); if (val != null && Object.op_Implicit((Object)(object)val)) { SendState(connection, val); } } } } private static void SendState(NetworkConnection connection, NetworkUser user) { Dictionary orCreateSelection = GetOrCreateSelection(user); LoadoutStateMessage loadoutStateMessage = new LoadoutStateMessage { Budgets = GetServerBudgets(), Entries = orCreateSelection.Select((KeyValuePair pair) => new LoadoutStateEntry { Category = pair.Key.Category, DefinitionIndex = pair.Key.DefinitionIndex, IsEquipment = pair.Key.IsEquipment, Count = pair.Value }).ToArray() }; connection.Send((short)19735, (MessageBase)(object)loadoutStateMessage); } private static void CopyServerStateToClient(NetworkUser user) { CopyServerBudgetsToClient(); ClientSelection.Clear(); foreach (var (key, value) in GetOrCreateSelection(user)) { ClientSelection[key] = value; } PvPStartingLoadoutManager.ClientStateChanged?.Invoke(); } private static void CopyServerBudgetsToClient() { int[] serverBudgets = GetServerBudgets(); Array.Copy(serverBudgets, ClientBudgets, serverBudgets.Length); } internal static int GetClientBudget(StartingLoadoutCategory category) { return ClientBudgets[(uint)category]; } internal static int GetClientSelectedCount(StartingLoadoutCategory category) { return ClientSelection.Where((KeyValuePair pair) => pair.Key.Category == category).Sum((KeyValuePair pair) => pair.Value); } internal static int GetClientChoiceCount(StartingLoadoutCategory category, int definitionIndex, bool isEquipment) { if (!ClientSelection.TryGetValue(new StartingLoadoutChoice(category, definitionIndex, isEquipment), out var value)) { return 0; } return value; } internal static int GetServerBudget(StartingLoadoutCategory category) { return GetBudgetEntry(category).Value; } internal static ConfigEntry GetBudgetEntry(StartingLoadoutCategory category) { return (ConfigEntry)(category switch { StartingLoadoutCategory.White => PvPConfig.StartingWhiteItems, StartingLoadoutCategory.Green => PvPConfig.StartingGreenItems, StartingLoadoutCategory.Yellow => PvPConfig.StartingYellowItems, StartingLoadoutCategory.Orange => PvPConfig.StartingOrangeEquipment, StartingLoadoutCategory.Red => PvPConfig.StartingRedItems, StartingLoadoutCategory.Blue => PvPConfig.StartingBlueItems, StartingLoadoutCategory.VoidWhite => PvPConfig.StartingVoidWhiteItems, StartingLoadoutCategory.VoidGreen => PvPConfig.StartingVoidGreenItems, StartingLoadoutCategory.VoidRed => PvPConfig.StartingVoidRedItems, _ => throw new ArgumentOutOfRangeException("category"), }); } internal static int GetMaximumBudget(StartingLoadoutCategory category) { return 99; } private static int[] GetServerBudgets() { int[] array = new int[9]; for (int i = 0; i < array.Length; i++) { array[i] = GetServerBudget((StartingLoadoutCategory)i); } return array; } internal static IReadOnlyList GetAvailableDefinitions(StartingLoadoutCategory category) { //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0105: Unknown result type (might be due to invalid IL or missing references) if (category == StartingLoadoutCategory.Orange) { return (from index in (IEnumerable)(object)EquipmentCatalog.allEquipment select EquipmentCatalog.GetEquipmentDef(index) into def where Object.op_Implicit((Object)(object)def) && def.canDrop && def.appearsInMultiPlayer && !def.isLunar && !def.isBoss select new StartingLoadoutOption((int)def.equipmentIndex, isEquipment: true)).OrderBy((StartingLoadoutOption option) => GetDefinitionName(category, option.DefinitionIndex, option.IsEquipment), StringComparer.CurrentCultureIgnoreCase).ToArray(); } ItemTier tier = GetItemTier(category); IEnumerable enumerable = from def in (IEnumerable)(object)ItemCatalog.allItemDefs where Object.op_Implicit((Object)(object)def) && !def.hidden && !def.isConsumed && def.tier == tier select new StartingLoadoutOption((int)def.itemIndex, isEquipment: false); if (category == StartingLoadoutCategory.Blue) { IEnumerable second = from index in (IEnumerable)(object)EquipmentCatalog.allEquipment select EquipmentCatalog.GetEquipmentDef(index) into def where Object.op_Implicit((Object)(object)def) && def.canDrop && def.appearsInMultiPlayer && def.isLunar select new StartingLoadoutOption((int)def.equipmentIndex, isEquipment: true); enumerable = enumerable.Concat(second); } return enumerable.OrderBy((StartingLoadoutOption option) => GetDefinitionName(category, option.DefinitionIndex, option.IsEquipment), StringComparer.CurrentCultureIgnoreCase).ToArray(); } internal static string GetDefinitionName(StartingLoadoutCategory category, int definitionIndex, bool isEquipment) { if (!isEquipment) { return Language.GetString(ItemCatalog.GetItemDef((ItemIndex)definitionIndex)?.nameToken ?? string.Empty); } return Language.GetString(EquipmentCatalog.GetEquipmentDef((EquipmentIndex)definitionIndex)?.nameToken ?? string.Empty); } internal static Sprite? GetDefinitionIcon(StartingLoadoutCategory category, int definitionIndex, bool isEquipment) { if (!isEquipment) { return ItemCatalog.GetItemDef((ItemIndex)definitionIndex)?.pickupIconSprite; } return EquipmentCatalog.GetEquipmentDef((EquipmentIndex)definitionIndex)?.pickupIconSprite; } private static bool IsValidDefinition(StartingLoadoutCategory category, int definitionIndex, bool isEquipment) { return GetAvailableDefinitions(category).Any((StartingLoadoutOption option) => option.DefinitionIndex == definitionIndex && option.IsEquipment == isEquipment); } private static ItemTier GetItemTier(StartingLoadoutCategory category) { //IL_002d: 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_0035: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) return (ItemTier)(category switch { StartingLoadoutCategory.White => 0, StartingLoadoutCategory.Green => 1, StartingLoadoutCategory.Yellow => 4, StartingLoadoutCategory.Red => 2, StartingLoadoutCategory.Blue => 3, StartingLoadoutCategory.VoidWhite => 6, StartingLoadoutCategory.VoidGreen => 7, StartingLoadoutCategory.VoidRed => 8, _ => 5, }); } private static void OnRunStart(Run run) { GrantedMasters.Clear(); } private static void OnBodyStart(CharacterBody body) { if (Plugin.IsPvPModeActive && NetworkServer.active && Object.op_Implicit((Object)(object)body) && Object.op_Implicit((Object)(object)body.master) && body.isPlayerControlled) { PlayerCharacterMasterController playerCharacterMasterController = body.master.playerCharacterMasterController; if (Object.op_Implicit((Object)(object)playerCharacterMasterController) && Object.op_Implicit((Object)(object)playerCharacterMasterController.networkUser)) { TryGrant(playerCharacterMasterController.networkUser, body); } } } private static void TryGrant(NetworkUser user, CharacterBody body) { //IL_0161: Unknown result type (might be due to invalid IL or missing references) //IL_0175: Unknown result type (might be due to invalid IL or missing references) //IL_017b: Unknown result type (might be due to invalid IL or missing references) CharacterMaster master = user.master; if (!Object.op_Implicit((Object)(object)master) || !Object.op_Implicit((Object)(object)master.inventory) || !GrantedMasters.Add(master) || !LobbySelections.TryGetValue(user, out Dictionary value)) { return; } foreach (var (startingLoadoutChoice2, num2) in value) { if (num2 > 0 && !startingLoadoutChoice2.IsEquipment && IsValidDefinition(startingLoadoutChoice2.Category, startingLoadoutChoice2.DefinitionIndex, isEquipment: false)) { master.inventory.GiveItemPermanent((ItemIndex)startingLoadoutChoice2.DefinitionIndex, num2); } } List list = (from pair in value where pair.Key.IsEquipment && pair.Value > 0 && IsValidDefinition(pair.Key.Category, pair.Key.DefinitionIndex, isEquipment: true) orderby (pair.Key.Category != StartingLoadoutCategory.Blue) ? 1 : 0, pair.Key.DefinitionIndex select pair).SelectMany((KeyValuePair pair) => Enumerable.Repeat((EquipmentIndex)pair.Key.DefinitionIndex, pair.Value)).ToList(); int num3 = Math.Min(1, list.Count); if (num3 > 0) { master.inventory.SetEquipmentIndexForSlot(list[0], 0u, 0u); } for (int num4 = num3; num4 < list.Count; num4++) { SpawnEquipmentNearPlayer(list[num4], body.corePosition, num4 - num3); } Plugin.Log.LogInfo((object)($"Granted {value.Values.Sum()} configured starting selections to {user.userName}: " + $"{num3} equipment placed in the first slot, {list.Count - num3} dropped nearby.")); } private static void SpawnEquipmentNearPlayer(EquipmentIndex equipmentIndex, Vector3 origin, int dropIndex) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_006d: 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_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) PickupIndex val = PickupCatalog.FindPickupIndex(equipmentIndex); if (!(val == PickupIndex.none)) { int num = dropIndex / 8; float num2 = (float)dropIndex * 2.3999631f; float num3 = 2.5f + (float)num * 1.5f; Vector3 val2 = default(Vector3); ((Vector3)(ref val2))..ctor(Mathf.Cos(num2), 0f, Mathf.Sin(num2)); Vector3 val3 = origin + val2 * num3 + Vector3.up * 1.2f; Vector3 val4 = val2 * 3.5f + Vector3.up * 6f; PickupDropletController.CreatePickupDroplet(new UniquePickup(val), val3, val4, false); } } private static void OnRunDestroy(Run run) { LobbySelections.Clear(); ClientSelection.Clear(); GrantedMasters.Clear(); } private static void OnNetworkUserLost(NetworkUser user) { LobbySelections.Remove(user); } private static Dictionary GetOrCreateSelection(NetworkUser user) { if (!LobbySelections.TryGetValue(user, out Dictionary value)) { value = new Dictionary(); LobbySelections[user] = value; } return value; } private static NetworkUser? FindUser(NetworkConnection connection) { return ((IEnumerable)NetworkUser.readOnlyInstancesList).FirstOrDefault((Func)((NetworkUser user) => Object.op_Implicit((Object)(object)user) && ((NetworkBehaviour)user).connectionToClient == connection)); } private static NetworkUser? GetLocalNetworkUser() { LocalUser firstLocalUser = LocalUserManager.GetFirstLocalUser(); if (firstLocalUser == null) { return null; } return firstLocalUser.currentNetworkUser; } private static bool IsPvPLobbySelected() { //IL_0011: Unknown result type (might be due to invalid IL or missing references) PreGameController instance = PreGameController.instance; if (!Object.op_Implicit((Object)(object)instance)) { return false; } Run gameModePrefabComponent = GameModeCatalog.GetGameModePrefabComponent(instance.gameModeIndex); if (Object.op_Implicit((Object)(object)gameModePrefabComponent)) { return ((Object)((Component)gameModePrefabComponent).gameObject).name == "WaterBucketPvPModeRun"; } return false; } } } namespace PvPMode.Equipment { internal static class PvPRadarScannerNames { private sealed class ScannerRevealMessage : MessageBase { internal float Duration; internal Vector3 Origin; internal int SceneIndex; internal int StageStamp; internal int AuthorizedTeamId; public override void Serialize(NetworkWriter writer) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) writer.Write(Duration); writer.Write(Origin); writer.Write(SceneIndex); writer.Write(StageStamp); writer.Write(AuthorizedTeamId); } public override void Deserialize(NetworkReader reader) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) Duration = reader.ReadSingle(); Origin = reader.ReadVector3(); SceneIndex = reader.ReadInt32(); StageStamp = reader.ReadInt32(); AuthorizedTeamId = reader.ReadInt32(); } } [CompilerGenerated] private static class <>O { public static hook_FireScanner <0>__EquipmentSlotFireScanner; public static hook_Pulse <1>__ChestRevealerPulse; public static hook_TrySetTeleporterIndicatorDiscovered <2>__TeleporterInteractionTrySetTeleporterIndicatorDiscovered; public static Action <3>__OnStartClient; public static Action <4>__OnStopClient; public static Action <5>__ClientUpdate; public static Action <6>__OnRunDestroy; public static NetworkMessageDelegate <7>__ClientHandleScannerReveal; } private const short ScannerRevealMessageType = 19738; private const float FallbackScannerDuration = 10f; private const float MaximumAcceptedDuration = 60f; private static readonly Dictionary ClientIndicators = new Dictionary(); private static readonly List ClientScanners = new List(); private static readonly Color EnemyNameColor = new Color(1f, 0.12f, 0.08f, 1f); private static bool installed; private static float scannerDuration = 10f; private static float clientRevealEndTime = float.NegativeInfinity; private static int clientRevealSceneIndex = -1; private static int clientRevealStageStamp = -1; private static int clientRevealTeamId = -1; private static int privateScannerPulseDepth; private static GameObject? playerIndicatorPrefab; private static GameObject? chestScannerPrefab; internal static void Install() { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Expected O, but got Unknown //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Expected O, but got Unknown //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) //IL_006e: Expected O, but got Unknown if (!installed) { installed = true; ResolveVanillaAssets(); object obj = <>O.<0>__EquipmentSlotFireScanner; if (obj == null) { hook_FireScanner val = EquipmentSlotFireScanner; <>O.<0>__EquipmentSlotFireScanner = val; obj = (object)val; } EquipmentSlot.FireScanner += (hook_FireScanner)obj; object obj2 = <>O.<1>__ChestRevealerPulse; if (obj2 == null) { hook_Pulse val2 = ChestRevealerPulse; <>O.<1>__ChestRevealerPulse = val2; obj2 = (object)val2; } ChestRevealer.Pulse += (hook_Pulse)obj2; object obj3 = <>O.<2>__TeleporterInteractionTrySetTeleporterIndicatorDiscovered; if (obj3 == null) { hook_TrySetTeleporterIndicatorDiscovered val3 = TeleporterInteractionTrySetTeleporterIndicatorDiscovered; <>O.<2>__TeleporterInteractionTrySetTeleporterIndicatorDiscovered = val3; obj3 = (object)val3; } TeleporterInteraction.TrySetTeleporterIndicatorDiscovered += (hook_TrySetTeleporterIndicatorDiscovered)obj3; NetworkManagerSystem.onStartClientGlobal += OnStartClient; NetworkManagerSystem.onStopClientGlobal += OnStopClient; RoR2Application.onUpdate += ClientUpdate; Run.onRunDestroyGlobal += OnRunDestroy; NetworkClient val4 = (Object.op_Implicit((Object)(object)NetworkManagerSystem.singleton) ? ((NetworkManager)NetworkManagerSystem.singleton).client : null); if (val4 != null) { OnStartClient(val4); } } } internal static void Uninstall() { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Expected O, but got Unknown //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Expected O, but got Unknown //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Expected O, but got Unknown if (installed) { installed = false; object obj = <>O.<0>__EquipmentSlotFireScanner; if (obj == null) { hook_FireScanner val = EquipmentSlotFireScanner; <>O.<0>__EquipmentSlotFireScanner = val; obj = (object)val; } EquipmentSlot.FireScanner -= (hook_FireScanner)obj; object obj2 = <>O.<1>__ChestRevealerPulse; if (obj2 == null) { hook_Pulse val2 = ChestRevealerPulse; <>O.<1>__ChestRevealerPulse = val2; obj2 = (object)val2; } ChestRevealer.Pulse -= (hook_Pulse)obj2; object obj3 = <>O.<2>__TeleporterInteractionTrySetTeleporterIndicatorDiscovered; if (obj3 == null) { hook_TrySetTeleporterIndicatorDiscovered val3 = TeleporterInteractionTrySetTeleporterIndicatorDiscovered; <>O.<2>__TeleporterInteractionTrySetTeleporterIndicatorDiscovered = val3; obj3 = (object)val3; } TeleporterInteraction.TrySetTeleporterIndicatorDiscovered -= (hook_TrySetTeleporterIndicatorDiscovered)obj3; NetworkManagerSystem.onStartClientGlobal -= OnStartClient; NetworkManagerSystem.onStopClientGlobal -= OnStopClient; RoR2Application.onUpdate -= ClientUpdate; Run.onRunDestroyGlobal -= OnRunDestroy; NetworkClient obj4 = (Object.op_Implicit((Object)(object)NetworkManagerSystem.singleton) ? ((NetworkManager)NetworkManagerSystem.singleton).client : null); if (obj4 != null) { obj4.UnregisterHandler((short)19738); } privateScannerPulseDepth = 0; ClearClientReveal(); } } private static void ResolveVanillaAssets() { playerIndicatorPrefab = LegacyResourcesAPI.Load("Prefabs/PositionIndicators/PlayerPositionIndicator"); chestScannerPrefab = LegacyResourcesAPI.Load("Prefabs/NetworkedObjects/ChestScanner"); if (!Object.op_Implicit((Object)(object)chestScannerPrefab)) { return; } DestroyOnTimer component = chestScannerPrefab.GetComponent(); if (Object.op_Implicit((Object)(object)component) && IsFinitePositive(component.duration)) { scannerDuration = Mathf.Clamp(component.duration, 0.1f, 60f); return; } ChestRevealer component2 = chestScannerPrefab.GetComponent(); if (Object.op_Implicit((Object)(object)component2) && IsFinitePositive(component2.revealDuration)) { scannerDuration = Mathf.Clamp(component2.revealDuration, 0.1f, 60f); } } private static void OnStartClient(NetworkClient client) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Expected O, but got Unknown object obj = <>O.<7>__ClientHandleScannerReveal; if (obj == null) { NetworkMessageDelegate val = ClientHandleScannerReveal; <>O.<7>__ClientHandleScannerReveal = val; obj = (object)val; } client.RegisterHandler((short)19738, (NetworkMessageDelegate)obj); } private static void OnStopClient() { ClearClientReveal(); } private static void OnRunDestroy(Run run) { ClearClientReveal(); } private static bool EquipmentSlotFireScanner(orig_FireScanner orig, EquipmentSlot slot) { //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) if (!Plugin.IsPvPModeActive || !NetworkServer.active || !Object.op_Implicit((Object)(object)slot) || !Object.op_Implicit((Object)(object)slot.characterBody) || !Object.op_Implicit((Object)(object)slot.characterBody.master) || !PvPTeamManager.TryGetTeamId(slot.characterBody.master, out var teamId)) { return orig.Invoke(slot); } ResolveVanillaAssets(); ScannerRevealMessage scannerRevealMessage = new ScannerRevealMessage { Duration = SanitizeDuration(scannerDuration), Origin = slot.characterBody.corePosition, SceneIndex = GetCurrentSceneIndex(), StageStamp = (Object.op_Implicit((Object)(object)Run.instance) ? Run.instance.stageClearCount : (-1)), AuthorizedTeamId = teamId }; foreach (KeyValuePair assignment in PvPTeamManager.GetAssignments()) { NetworkUser key = assignment.Key; if (!Object.op_Implicit((Object)(object)key) || !key.isParticipating || assignment.Value != teamId) { continue; } if (((NetworkBehaviour)key).isLocalPlayer) { ActivateClientReveal(scannerRevealMessage); continue; } NetworkConnection connectionToClient = ((NetworkBehaviour)key).connectionToClient; if (connectionToClient != null) { connectionToClient.Send((short)19738, (MessageBase)(object)scannerRevealMessage); } } return true; } private static void ClientHandleScannerReveal(NetworkMessage networkMessage) { ActivateClientReveal(networkMessage.ReadMessage()); } private static void ActivateClientReveal(ScannerRevealMessage message) { //IL_0049: 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 (Plugin.IsPvPModeActive && message.SceneIndex == GetCurrentSceneIndex() && Object.op_Implicit((Object)(object)Run.instance) && message.StageStamp == Run.instance.stageClearCount && message.AuthorizedTeamId >= 0 && message.AuthorizedTeamId < PvPTeamRegistry.Count && IsFinite(message.Origin) && TryGetLocalTeamId(out var teamId) && teamId == message.AuthorizedTeamId) { if (clientRevealTeamId >= 0 && clientRevealTeamId != message.AuthorizedTeamId) { ClearClientReveal(); } SpawnLocalVanillaScanner(message.Origin); clientRevealSceneIndex = message.SceneIndex; clientRevealStageStamp = message.StageStamp; clientRevealTeamId = message.AuthorizedTeamId; clientRevealEndTime = Mathf.Max(clientRevealEndTime, Time.time + SanitizeDuration(message.Duration)); RefreshClientIndicators(); } } private static void SpawnLocalVanillaScanner(Vector3 origin) { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)chestScannerPrefab)) { ResolveVanillaAssets(); if (!Object.op_Implicit((Object)(object)chestScannerPrefab)) { return; } } GameObject val = Object.Instantiate(chestScannerPrefab, origin, Quaternion.identity); ((Object)val).name = "PvP Team-Private ChestScanner"; val.AddComponent(); ClientScanners.Add(val); } private static void ChestRevealerPulse(orig_Pulse orig, ChestRevealer self) { if (!Object.op_Implicit((Object)(object)self) || !Object.op_Implicit((Object)(object)((Component)self).GetComponentInParent())) { orig.Invoke(self); return; } privateScannerPulseDepth++; try { orig.Invoke(self); } finally { privateScannerPulseDepth = Math.Max(0, privateScannerPulseDepth - 1); } } private static bool TeleporterInteractionTrySetTeleporterIndicatorDiscovered(orig_TrySetTeleporterIndicatorDiscovered orig, TeleporterInteraction self, bool newDiscoveredState) { if (privateScannerPulseDepth > 0 && NetworkServer.active) { return false; } return orig.Invoke(self, newDiscoveredState); } private static void ClientUpdate() { bool flag = clientRevealSceneIndex != GetCurrentSceneIndex() || !Object.op_Implicit((Object)(object)Run.instance) || clientRevealStageStamp != Run.instance.stageClearCount; int teamId; bool flag2 = !TryGetLocalTeamId(out teamId) || teamId != clientRevealTeamId; if (Time.time >= clientRevealEndTime || !Plugin.IsPvPModeActive || flag || flag2) { if (!float.IsNegativeInfinity(clientRevealEndTime) || ClientIndicators.Count > 0 || ClientScanners.Count > 0) { ClearClientReveal(); } } else { RefreshClientIndicators(); } } private static void RefreshClientIndicators() { //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) LocalUser firstLocalUser = LocalUserManager.GetFirstLocalUser(); NetworkUser val = ((firstLocalUser != null) ? firstLocalUser.currentNetworkUser : null); if (val == null || !Object.op_Implicit((Object)(object)val) || !Object.op_Implicit((Object)(object)val.master) || !PvPTeamRegistry.TryGetPvPTeamId(val.master.teamIndex, out var teamId) || teamId != clientRevealTeamId) { RemoveInvalidIndicators(null); return; } TeamIndex teamIndex = PvPTeamRegistry.GetTeamIndex(clientRevealTeamId); foreach (CharacterBody readOnlyInstances in CharacterBody.readOnlyInstancesList) { if (ShouldReveal(readOnlyInstances, teamIndex) && !ClientIndicators.ContainsKey(readOnlyInstances)) { TryCreateVanillaNameplate(readOnlyInstances); } } RemoveInvalidIndicators(teamIndex); } private static bool ShouldReveal(CharacterBody? body, TeamIndex localTeam) { //IL_0033: 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_0046: Unknown result type (might be due to invalid IL or missing references) if (body != null && Object.op_Implicit((Object)(object)body) && body.isPlayerControlled && Object.op_Implicit((Object)(object)body.master) && Object.op_Implicit((Object)(object)body.teamComponent) && PvPTeamRegistry.IsPvPTeam(body.teamComponent.teamIndex)) { return PvPRelationService.AreEnemies(localTeam, body.teamComponent.teamIndex); } return false; } private static void TryCreateVanillaNameplate(CharacterBody body) { //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_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) if (!Object.op_Implicit((Object)(object)playerIndicatorPrefab)) { ResolveVanillaAssets(); if (!Object.op_Implicit((Object)(object)playerIndicatorPrefab)) { return; } } GameObject val = Object.Instantiate(playerIndicatorPrefab, body.transform); PositionIndicator component = val.GetComponent(); Nameplate component2 = val.GetComponent(); if (component == null || !Object.op_Implicit((Object)(object)component) || component2 == null || !Object.op_Implicit((Object)(object)component2)) { Object.Destroy((Object)(object)val); return; } component.targetTransform = body.coreTransform; component2.baseColor = EnemyNameColor; component2.combatColor = EnemyNameColor; component2.Initialize(body); ClientIndicators[body] = val; } private static void RemoveInvalidIndicators(TeamIndex? localTeam) { //IL_0035: Unknown result type (might be due to invalid IL or missing references) KeyValuePair[] array = ClientIndicators.ToArray(); for (int i = 0; i < array.Length; i++) { KeyValuePair keyValuePair = array[i]; var (val3, val4) = (KeyValuePair)(ref keyValuePair); if (!localTeam.HasValue || !ShouldReveal(val3, localTeam.Value) || !Object.op_Implicit((Object)(object)val4)) { if (Object.op_Implicit((Object)(object)val4)) { Object.Destroy((Object)(object)val4); } ClientIndicators.Remove(val3); } } } private static void ClearClientReveal() { clientRevealEndTime = float.NegativeInfinity; clientRevealSceneIndex = -1; clientRevealStageStamp = -1; clientRevealTeamId = -1; foreach (GameObject value in ClientIndicators.Values) { if (Object.op_Implicit((Object)(object)value)) { Object.Destroy((Object)(object)value); } } ClientIndicators.Clear(); for (int i = 0; i < ClientScanners.Count; i++) { if (Object.op_Implicit((Object)(object)ClientScanners[i])) { Object.Destroy((Object)(object)ClientScanners[i]); } } ClientScanners.Clear(); } private static bool IsFinitePositive(float value) { if (value > 0f && !float.IsNaN(value)) { return !float.IsInfinity(value); } return false; } private static bool IsFinite(Vector3 value) { //IL_0000: 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_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) if (!float.IsNaN(value.x) && !float.IsInfinity(value.x) && !float.IsNaN(value.y) && !float.IsInfinity(value.y) && !float.IsNaN(value.z)) { return !float.IsInfinity(value.z); } return false; } private static float SanitizeDuration(float duration) { if (!IsFinitePositive(duration)) { return 10f; } return Mathf.Clamp(duration, 0.1f, 60f); } private static int GetCurrentSceneIndex() { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Expected I4, but got Unknown SceneInfo instance = SceneInfo.instance; if (!Object.op_Implicit((Object)(object)instance) || !Object.op_Implicit((Object)(object)instance.sceneDef)) { return -1; } return (int)instance.sceneDef.sceneDefIndex; } private static bool TryGetLocalTeamId(out int teamId) { //IL_0033: Unknown result type (might be due to invalid IL or missing references) teamId = -1; LocalUser firstLocalUser = LocalUserManager.GetFirstLocalUser(); NetworkUser val = ((firstLocalUser != null) ? firstLocalUser.currentNetworkUser : null); if (val != null && Object.op_Implicit((Object)(object)val) && Object.op_Implicit((Object)(object)val.master)) { return PvPTeamRegistry.TryGetPvPTeamId(val.master.teamIndex, out teamId); } return false; } } internal sealed class PvPTeamPrivateScannerMarker : MonoBehaviour { } } namespace PvPMode.Debugging { internal static class PvPCommands { [CompilerGenerated] private static class <>O { public static hook_CCSay <0>__ChatCCSay; } internal const string LobbyTeamMessagePrefix = "WATERBUCKET_PVP_TEAM:"; private static bool installed; internal static void Install() { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Expected O, but got Unknown if (!installed) { installed = true; object obj = <>O.<0>__ChatCCSay; if (obj == null) { hook_CCSay val = ChatCCSay; <>O.<0>__ChatCCSay = val; obj = (object)val; } Chat.CCSay += (hook_CCSay)obj; } } internal static void Uninstall() { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Expected O, but got Unknown if (installed) { installed = false; object obj = <>O.<0>__ChatCCSay; if (obj == null) { hook_CCSay val = ChatCCSay; <>O.<0>__ChatCCSay = val; obj = (object)val; } Chat.CCSay -= (hook_CCSay)obj; } } [ConCommand(/*Could not decode attribute arguments.*/)] private static void Status(ConCommandArgs args) { //IL_00d3: Unknown result type (might be due to invalid IL or missing references) Plugin.Log.LogMessage((object)$"PvP active={Plugin.IsPvPModeActive}, assignment={PvPConfig.AssignmentMode.Value}, registeredTeams={PvPTeamRegistry.Count}"); Plugin.Log.LogMessage((object)$"Damage P>P={PvPConfig.PlayerToPlayerDamage.Value}, M>P={PvPConfig.MinionToPlayerDamage.Value}, P>M={PvPConfig.PlayerToMinionDamage.Value}, M>M={PvPConfig.MinionToMinionDamage.Value}"); foreach (KeyValuePair assignment in PvPTeamManager.GetAssignments()) { Plugin.Log.LogMessage((object)$"{assignment.Key.userName}: PvP team {assignment.Value + 1}, TeamIndex={PvPTeamRegistry.GetTeamIndex(assignment.Value)}"); } } [ConCommand(/*Could not decode attribute arguments.*/)] private static void ListTeams(ConCommandArgs args) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) for (int i = 0; i < PvPTeamRegistry.Count; i++) { Plugin.Log.LogMessage((object)$"{i}: {PvPTeamRegistry.GetTeamIndex(i)}"); } } [ConCommand(/*Could not decode attribute arguments.*/)] private static void SetTeam(ConCommandArgs args) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) if (!NetworkServer.active) { throw new ConCommandException("Server only."); } int argInt = ((ConCommandArgs)(ref args)).GetArgInt(0); int argInt2 = ((ConCommandArgs)(ref args)).GetArgInt(1); NetworkUser[] array = NetworkUser.readOnlyInstancesList.Where((NetworkUser user) => Object.op_Implicit((Object)(object)user) && user.isParticipating).ToArray(); if (argInt < 0 || argInt >= array.Length) { throw new ConCommandException("Player index is out of range."); } if (!PvPTeamManager.SetTeam(array[argInt], argInt2)) { throw new ConCommandException("Team change failed."); } Plugin.Log.LogMessage((object)$"Moved {array[argInt].userName} to PvP team {argInt2 % PvPTeamRegistry.Count + 1}."); } private static void ChatCCSay(orig_CCSay orig, ConCommandArgs args) { //IL_0020: 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_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) if (((ConCommandArgs)(ref args)).Count < 1 || !((ConCommandArgs)(ref args))[0].StartsWith("WATERBUCKET_PVP_TEAM:", StringComparison.Ordinal)) { orig.Invoke(args); return; } string s = ((ConCommandArgs)(ref args))[0].Substring("WATERBUCKET_PVP_TEAM:".Length); if (!NetworkServer.active || !Object.op_Implicit((Object)(object)args.sender) || !IsPvPLobbySelected() || !int.TryParse(s, out var result) || result < -1 || result >= PvPTeamRegistry.Count) { Plugin.Log.LogWarning((object)"Rejected an invalid PvP lobby team selection message."); } else if (!PvPTeamManager.SetLobbySelection(args.sender, result)) { Plugin.Log.LogWarning((object)("Could not apply the lobby team selection sent by " + args.sender.userName + ".")); } } private static bool IsPvPLobbySelected() { //IL_0011: Unknown result type (might be due to invalid IL or missing references) PreGameController instance = PreGameController.instance; if (!Object.op_Implicit((Object)(object)instance)) { return false; } Run gameModePrefabComponent = GameModeCatalog.GetGameModePrefabComponent(instance.gameModeIndex); if (Object.op_Implicit((Object)(object)gameModePrefabComponent)) { return ((Object)((Component)gameModePrefabComponent).gameObject).name == "WaterBucketPvPModeRun"; } return false; } } } namespace PvPMode.Config { internal static class PvPConfig { internal enum MatchModeKind { LimitedLives, Unlimited, TimedKills } internal static ConfigEntry MatchMode { get; private set; } internal static ConfigEntry LivesPerPlayer { get; private set; } internal static ConfigEntry TimeLimitMinutes { get; private set; } internal static ConfigEntry StageFiveRoute { get; private set; } internal static ConfigEntry StartingWhiteItems { get; private set; } internal static ConfigEntry StartingGreenItems { get; private set; } internal static ConfigEntry StartingYellowItems { get; private set; } internal static ConfigEntry StartingOrangeEquipment { get; private set; } internal static ConfigEntry StartingRedItems { get; private set; } internal static ConfigEntry StartingBlueItems { get; private set; } internal static ConfigEntry StartingVoidWhiteItems { get; private set; } internal static ConfigEntry StartingVoidGreenItems { get; private set; } internal static ConfigEntry StartingVoidRedItems { get; private set; } internal static ConfigEntry AssignmentMode { get; private set; } internal static ConfigEntry MaxPvPTeams { get; private set; } internal static ConfigEntry TeamCount { get; private set; } internal static ConfigEntry FriendlyFire { get; private set; } internal static ConfigEntry PlayerToPlayerDamage { get; private set; } internal static ConfigEntry MinionToPlayerDamage { get; private set; } internal static ConfigEntry PlayerToMinionDamage { get; private set; } internal static ConfigEntry MinionToMinionDamage { get; private set; } internal static ConfigEntry PlayerControlDurationMultiplier { get; private set; } internal static ConfigEntry MinimumSpawnDistance { get; private set; } internal static ConfigEntry TeamSpawnRadius { get; private set; } internal static ConfigEntry SpawnInvulnerabilitySeconds { get; private set; } internal static ConfigEntry RespawnDelaySeconds { get; private set; } internal static ConfigEntry LimitedLivesRespawnDelaySeconds { get; private set; } internal static ConfigEntry RespawnInvulnerabilitySeconds { get; private set; } internal static ConfigEntry VerboseRelations { get; private set; } internal static ConfigEntry VerboseDamage { get; private set; } internal static ConfigEntry VerboseMinions { get; private set; } internal static bool IsFfa => !AssignmentMode.Value.Equals("Team", StringComparison.OrdinalIgnoreCase); internal static MatchModeKind CurrentMatchMode { get { string text = MatchMode.Value.ToLowerInvariant(); if (!(text == "unlimited")) { if (text == "timedkills") { return MatchModeKind.TimedKills; } return MatchModeKind.LimitedLives; } return MatchModeKind.Unlimited; } } internal static float CurrentRespawnDelaySeconds { get { if (CurrentMatchMode != MatchModeKind.LimitedLives) { return RespawnDelaySeconds.Value; } return LimitedLivesRespawnDelaySeconds.Value; } } internal static bool StageFiveDefaultsToLoop => !StageFiveRoute.Value.Equals("Moon", StringComparison.OrdinalIgnoreCase); internal static void Bind(ConfigFile config) { //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Expected O, but got Unknown //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Expected O, but got Unknown //IL_0178: Unknown result type (might be due to invalid IL or missing references) //IL_0182: Expected O, but got Unknown //IL_01a5: Unknown result type (might be due to invalid IL or missing references) //IL_01af: Expected O, but got Unknown //IL_024c: Unknown result type (might be due to invalid IL or missing references) //IL_0256: Expected O, but got Unknown //IL_0284: Unknown result type (might be due to invalid IL or missing references) //IL_028e: Expected O, but got Unknown //IL_02bc: Unknown result type (might be due to invalid IL or missing references) //IL_02c6: Expected O, but got Unknown //IL_02f4: Unknown result type (might be due to invalid IL or missing references) //IL_02fe: Expected O, but got Unknown //IL_032c: Unknown result type (might be due to invalid IL or missing references) //IL_0336: Expected O, but got Unknown //IL_0364: Unknown result type (might be due to invalid IL or missing references) //IL_036e: Expected O, but got Unknown //IL_039c: Unknown result type (might be due to invalid IL or missing references) //IL_03a6: Expected O, but got Unknown MatchMode = config.Bind("Match", "Mode", "LimitedLives", "LimitedLives, Unlimited, or TimedKills."); LivesPerPlayer = config.Bind("Match", "LivesPerPlayer", 3, new ConfigDescription("Total lives per player in LimitedLives mode.", (AcceptableValueBase)(object)new AcceptableValueRange(1, 99), Array.Empty())); TimeLimitMinutes = config.Bind("Match", "TimeLimitMinutes", 10, new ConfigDescription("Round duration in TimedKills mode. A tied lead enters overtime.", (AcceptableValueBase)(object)new AcceptableValueRange(1, 120), Array.Empty())); StageFiveRoute = config.Bind("Match", "StageFiveRoute", "Loop", "Default primordial teleporter alignment on Sky Meadow: Loop or Moon. Players may still rotate it afterward."); StartingWhiteItems = BindStartingCount(config, "White", 99); StartingGreenItems = BindStartingCount(config, "Green", 99); StartingYellowItems = BindStartingCount(config, "Yellow", 99); StartingOrangeEquipment = BindStartingCount(config, "OrangeEquipment", 99); StartingRedItems = BindStartingCount(config, "Red", 99); StartingBlueItems = BindStartingCount(config, "Blue", 99); StartingVoidWhiteItems = BindStartingCount(config, "VoidWhite", 99); StartingVoidGreenItems = BindStartingCount(config, "VoidGreen", 99); StartingVoidRedItems = BindStartingCount(config, "VoidRed", 99); AssignmentMode = config.Bind("General", "Mode", "FFA", "FFA gives every player a team. Team distributes players across TeamCount teams."); MaxPvPTeams = config.Bind("General", "MaxPvPTeams", 8, new ConfigDescription("Number of custom teams registered during startup. Restart required.", (AcceptableValueBase)(object)new AcceptableValueRange(2, 16), Array.Empty())); TeamCount = config.Bind("General", "TeamCount", 2, new ConfigDescription("Team count when Mode=Team.", (AcceptableValueBase)(object)new AcceptableValueRange(2, 16), Array.Empty())); FriendlyFire = config.Bind("PvP", "FriendlyFire", false, "Allow damage between members of the same PvP team."); PlayerToPlayerDamage = BindMultiplier(config, "PlayerToPlayerDamageMultiplier", 0.35f); MinionToPlayerDamage = BindMultiplier(config, "MinionToPlayerDamageMultiplier", 0.35f); PlayerToMinionDamage = BindMultiplier(config, "PlayerToMinionDamageMultiplier", 0.5f); MinionToMinionDamage = BindMultiplier(config, "MinionToMinionDamageMultiplier", 0.5f); PlayerControlDurationMultiplier = config.Bind("PvP", "PlayerControlDurationMultiplier", 1f, new ConfigDescription("Duration multiplier for explicit hard control applied to PvP players (stun, freeze, normal/red shock, and the immobilize safety timeout). Does not alter ordinary debuffs or damage hit-stun.", (AcceptableValueBase)(object)new AcceptableValueRange(0f, 5f), Array.Empty())); MinimumSpawnDistance = config.Bind("PvP.Spawn", "MinimumSpawnDistance", 40f, new ConfigDescription("Desired distance between rival spawns.", (AcceptableValueBase)(object)new AcceptableValueRange(10f, 200f), Array.Empty())); TeamSpawnRadius = config.Bind("PvP.Spawn", "TeamSpawnRadius", 10f, new ConfigDescription("Maximum offset between allies spawning together.", (AcceptableValueBase)(object)new AcceptableValueRange(0f, 50f), Array.Empty())); SpawnInvulnerabilitySeconds = config.Bind("PvP.Spawn", "SpawnInvulnerabilitySeconds", 3f, new ConfigDescription("Protection after an initial stage spawn.", (AcceptableValueBase)(object)new AcceptableValueRange(0f, 15f), Array.Empty())); RespawnDelaySeconds = config.Bind("PvP.Respawn", "RespawnDelaySeconds", 5f, new ConfigDescription("Respawn delay.", (AcceptableValueBase)(object)new AcceptableValueRange(0.5f, 60f), Array.Empty())); LimitedLivesRespawnDelaySeconds = config.Bind("PvP.Respawn", "LimitedLivesRespawnDelaySeconds", 75f, new ConfigDescription("Respawn countdown in LimitedLives mode.", (AcceptableValueBase)(object)new AcceptableValueRange(1f, 180f), Array.Empty())); RespawnInvulnerabilitySeconds = config.Bind("PvP.Respawn", "RespawnInvulnerabilitySeconds", 3f, new ConfigDescription("Protection after respawn.", (AcceptableValueBase)(object)new AcceptableValueRange(0f, 15f), Array.Empty())); VerboseRelations = config.Bind("Debug", "VerboseRelations", false, "Log team relation decisions."); VerboseDamage = config.Bind("Debug", "VerboseDamage", false, "Log PvP damage scaling decisions."); VerboseMinions = config.Bind("Debug", "VerboseMinions", false, "Log minion team inheritance."); } private static ConfigEntry BindMultiplier(ConfigFile config, string key, float value) { //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Expected O, but got Unknown return config.Bind("PvP", key, value, new ConfigDescription("Final multiplier applied after normal reductions and immediately before one-shot protection.", (AcceptableValueBase)(object)new AcceptableValueRange(0f, 5f), Array.Empty())); } private static ConfigEntry BindStartingCount(ConfigFile config, string key, int maximum) { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Expected O, but got Unknown return config.Bind("PvP.StartingLoadout", key, 0, new ConfigDescription("Per-player starting selection allowance.", (AcceptableValueBase)(object)new AcceptableValueRange(0, maximum), Array.Empty())); } } } namespace PvPMode.Compatibility { internal static class PvPSurvivorMechanics { [CompilerGenerated] private static class <>O { public static hook_HurtBoxPassesRequirements <0>__RepossessHurtBoxPassesRequirements; public static hook_BagObject <1>__RepossessExitBagObject; public static hook_AssignPassenger <2>__DrifterBagAssignPassenger; } private static bool installed; internal static void Install() { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Expected O, but got Unknown //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Expected O, but got Unknown //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Expected O, but got Unknown if (!installed) { installed = true; object obj = <>O.<0>__RepossessHurtBoxPassesRequirements; if (obj == null) { hook_HurtBoxPassesRequirements val = RepossessHurtBoxPassesRequirements; <>O.<0>__RepossessHurtBoxPassesRequirements = val; obj = (object)val; } RepossessBullseyeSearch.HurtBoxPassesRequirements += (hook_HurtBoxPassesRequirements)obj; object obj2 = <>O.<1>__RepossessExitBagObject; if (obj2 == null) { hook_BagObject val2 = RepossessExitBagObject; <>O.<1>__RepossessExitBagObject = val2; obj2 = (object)val2; } RepossessExit.BagObject += (hook_BagObject)obj2; object obj3 = <>O.<2>__DrifterBagAssignPassenger; if (obj3 == null) { hook_AssignPassenger val3 = DrifterBagAssignPassenger; <>O.<2>__DrifterBagAssignPassenger = val3; obj3 = (object)val3; } DrifterBagController.AssignPassenger += (hook_AssignPassenger)obj3; } } internal static void Uninstall() { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Expected O, but got Unknown //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Expected O, but got Unknown //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Expected O, but got Unknown if (installed) { installed = false; object obj = <>O.<0>__RepossessHurtBoxPassesRequirements; if (obj == null) { hook_HurtBoxPassesRequirements val = RepossessHurtBoxPassesRequirements; <>O.<0>__RepossessHurtBoxPassesRequirements = val; obj = (object)val; } RepossessBullseyeSearch.HurtBoxPassesRequirements -= (hook_HurtBoxPassesRequirements)obj; object obj2 = <>O.<1>__RepossessExitBagObject; if (obj2 == null) { hook_BagObject val2 = RepossessExitBagObject; <>O.<1>__RepossessExitBagObject = val2; obj2 = (object)val2; } RepossessExit.BagObject -= (hook_BagObject)obj2; object obj3 = <>O.<2>__DrifterBagAssignPassenger; if (obj3 == null) { hook_AssignPassenger val3 = DrifterBagAssignPassenger; <>O.<2>__DrifterBagAssignPassenger = val3; obj3 = (object)val3; } DrifterBagController.AssignPassenger -= (hook_AssignPassenger)obj3; } } private static bool RepossessHurtBoxPassesRequirements(orig_HurtBoxPassesRequirements orig, RepossessBullseyeSearch self, HurtBox hurtBox) { if (!orig.Invoke(self, hurtBox)) { return false; } if (!Plugin.IsPvPModeActive || !Object.op_Implicit((Object)(object)((BullseyeSearch)self).viewer)) { return true; } CharacterBody targetBody = ((Object.op_Implicit((Object)(object)hurtBox) && Object.op_Implicit((Object)(object)hurtBox.healthComponent)) ? hurtBox.healthComponent.body : null); return !IsEnemyPlayer(((BullseyeSearch)self).viewer, targetBody); } private static void RepossessExitBagObject(orig_BagObject orig, RepossessExit self) { CharacterBody ownerBody = (Object.op_Implicit((Object)(object)((EntityState)self).gameObject) ? ((EntityState)self).gameObject.GetComponent() : null); CharacterBody targetBody = ResolveTargetBody(self.chosenTarget); if (Plugin.IsPvPModeActive && IsEnemyPlayer(ownerBody, targetBody)) { self.chosenTarget = null; } else { orig.Invoke(self); } } private static void DrifterBagAssignPassenger(orig_AssignPassenger orig, DrifterBagController self, GameObject passenger) { CharacterBody val = (Object.op_Implicit((Object)(object)self) ? ((Component)self).GetComponent() : null); CharacterBody val2 = ResolveTargetBody(passenger); if (Plugin.IsPvPModeActive && IsEnemyPlayer(val, val2)) { Plugin.Log.LogDebug((object)("Rejected Drifter Repossess from " + ((Object)val).name + " against enemy player " + ((Object)val2).name + ".")); } else { orig.Invoke(self, passenger); } } private static CharacterBody? ResolveTargetBody(GameObject? target) { if (!Object.op_Implicit((Object)(object)target)) { return null; } CharacterBody component = target.GetComponent(); if (Object.op_Implicit((Object)(object)component)) { return component; } HurtBox component2 = target.GetComponent(); if (Object.op_Implicit((Object)(object)component2) && Object.op_Implicit((Object)(object)component2.healthComponent)) { return component2.healthComponent.body; } return target.GetComponentInParent(); } private static bool IsEnemyPlayer(CharacterBody? ownerBody, CharacterBody? targetBody) { if (!Object.op_Implicit((Object)(object)ownerBody) || !Object.op_Implicit((Object)(object)targetBody) || !ownerBody.isPlayerControlled || !targetBody.isPlayerControlled || !Object.op_Implicit((Object)(object)ownerBody.master) || !Object.op_Implicit((Object)(object)targetBody.master) || !PvPTeamManager.TryGetTeamId(ownerBody.master, out var teamId) || !PvPTeamManager.TryGetTeamId(targetBody.master, out var teamId2)) { return false; } return teamId != teamId2; } } internal static class VanillaPlayerTeamCompatibility { [CompilerGenerated] private static class <>O { public static hook_GetTeamMembers <0>__TeamComponentGetTeamMembers; public static hook_OnChangeTeam <1>__TeamComponentOnChangeTeam; public static hook_AddTeam <2>__TeamMaskAddTeam; public static hook_GetItemCountForTeam <3>__UtilGetItemCountForTeam; public static hook_Fire <4>__BlastAttackFire; public static hook_FireNoDamage <5>__BlastAttackFireNoDamage; public static Manipulator <6>__PatchMapZone; public static Manipulator <7>__PatchCharacterBodyStats; public static Manipulator <8>__PatchCharacterBodyCulling; public static Manipulator <9>__PatchCharacterMasterBodyStart; public static Manipulator <10>__PatchHealthComponentHeal; public static Manipulator <11>__PatchHealthComponentDamage; public static Manipulator <12>__PatchGroundImpact; public static Manipulator <13>__PatchAffixBeadDamage; public static Manipulator <14>__PatchTeamExperience; public static Manipulator <15>__PatchUnlockPickup; public static Manipulator <16>__PatchDoppelgangerInvasion; public static Manipulator <17>__PatchSwarmsArtifact; public static Manipulator <18>__PatchGoldTitanTeam; public static Manipulator <19>__PatchHoldoutObjective; public static Manipulator <20>__PatchExtractionObjective; public static Manipulator <21>__PatchSolusOverlayJoin; public static Manipulator <22>__PatchSolusFreezeJoin; public static Manipulator <23>__PatchSeekerHealingPulse; public static Manipulator <24>__PatchSeekerReviveTeamFilter; public static Manipulator <25>__PatchMeridiansWillTargeting; public static Manipulator <26>__PatchWarBondsTargeting; public static Manipulator <27>__PatchDroneTechTargetReticle; public static Manipulator <28>__PatchFlyingVerminPlayerTarget; public static Manipulator <29>__PatchBellPlayerTarget; public static Manipulator <30>__PatchAmmoPickup; public static Manipulator <31>__PatchBuffPickup; public static Manipulator <32>__PatchHealthPickup; public static Manipulator <33>__PatchMoneyPickup; public static Manipulator <34>__PatchElusiveAntlersPickup; public static Manipulator <35>__PatchGravitatePickup; public static Manipulator <36>__PatchJunkPickup; public static Func <37>__NormalizePvPTeamAsPlayer; public static Func <38>__MatchesLegacyPlayerFilter; public static Func <39>__CanSeekerAffectMaster; public static Action <40>__PrepareSeekerRevive; } private static ReadOnlyCollection cachedVirtualPlayerMembers = new List().AsReadOnly(); private static int cachedVirtualPlayerMembersFrame = -1; private static bool installed; internal static void Install() { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Expected O, but got Unknown //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Expected O, but got Unknown //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Expected O, but got Unknown //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Expected O, but got Unknown //IL_009e: 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_00a9: Expected O, but got Unknown //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Expected O, but got Unknown //IL_00de: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Expected O, but got Unknown //IL_00fe: 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_0109: Expected O, but got Unknown //IL_011e: Unknown result type (might be due to invalid IL or missing references) //IL_0123: Unknown result type (might be due to invalid IL or missing references) //IL_0129: Expected O, but got Unknown //IL_013e: Unknown result type (might be due to invalid IL or missing references) //IL_0143: Unknown result type (might be due to invalid IL or missing references) //IL_0149: Expected O, but got Unknown //IL_015e: Unknown result type (might be due to invalid IL or missing references) //IL_0163: Unknown result type (might be due to invalid IL or missing references) //IL_0169: Expected O, but got Unknown //IL_017e: Unknown result type (might be due to invalid IL or missing references) //IL_0183: Unknown result type (might be due to invalid IL or missing references) //IL_0189: Expected O, but got Unknown //IL_019e: Unknown result type (might be due to invalid IL or missing references) //IL_01a3: Unknown result type (might be due to invalid IL or missing references) //IL_01a9: Expected O, but got Unknown //IL_01be: Unknown result type (might be due to invalid IL or missing references) //IL_01c3: Unknown result type (might be due to invalid IL or missing references) //IL_01c9: Expected O, but got Unknown //IL_01de: Unknown result type (might be due to invalid IL or missing references) //IL_01e3: Unknown result type (might be due to invalid IL or missing references) //IL_01e9: Expected O, but got Unknown //IL_01fe: Unknown result type (might be due to invalid IL or missing references) //IL_0203: Unknown result type (might be due to invalid IL or missing references) //IL_0209: Expected O, but got Unknown //IL_021e: 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_0229: Expected O, but got Unknown //IL_023e: Unknown result type (might be due to invalid IL or missing references) //IL_0243: Unknown result type (might be due to invalid IL or missing references) //IL_0249: Expected O, but got Unknown //IL_025e: Unknown result type (might be due to invalid IL or missing references) //IL_0263: Unknown result type (might be due to invalid IL or missing references) //IL_0269: Expected O, but got Unknown //IL_027e: Unknown result type (might be due to invalid IL or missing references) //IL_0283: Unknown result type (might be due to invalid IL or missing references) //IL_0289: Expected O, but got Unknown //IL_029e: Unknown result type (might be due to invalid IL or missing references) //IL_02a3: Unknown result type (might be due to invalid IL or missing references) //IL_02a9: Expected O, but got Unknown //IL_02be: Unknown result type (might be due to invalid IL or missing references) //IL_02c3: Unknown result type (might be due to invalid IL or missing references) //IL_02c9: Expected O, but got Unknown //IL_02de: Unknown result type (might be due to invalid IL or missing references) //IL_02e3: Unknown result type (might be due to invalid IL or missing references) //IL_02e9: Expected O, but got Unknown //IL_02fe: Unknown result type (might be due to invalid IL or missing references) //IL_0303: Unknown result type (might be due to invalid IL or missing references) //IL_0309: Expected O, but got Unknown //IL_031e: 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_0329: Expected O, but got Unknown //IL_033e: Unknown result type (might be due to invalid IL or missing references) //IL_0343: Unknown result type (might be due to invalid IL or missing references) //IL_0349: Expected O, but got Unknown //IL_035e: Unknown result type (might be due to invalid IL or missing references) //IL_0363: Unknown result type (might be due to invalid IL or missing references) //IL_0369: Expected O, but got Unknown //IL_037e: Unknown result type (might be due to invalid IL or missing references) //IL_0383: Unknown result type (might be due to invalid IL or missing references) //IL_0389: Expected O, but got Unknown //IL_039e: Unknown result type (might be due to invalid IL or missing references) //IL_03a3: Unknown result type (might be due to invalid IL or missing references) //IL_03a9: Expected O, but got Unknown //IL_03be: Unknown result type (might be due to invalid IL or missing references) //IL_03c3: Unknown result type (might be due to invalid IL or missing references) //IL_03c9: Expected O, but got Unknown //IL_03de: Unknown result type (might be due to invalid IL or missing references) //IL_03e3: Unknown result type (might be due to invalid IL or missing references) //IL_03e9: Expected O, but got Unknown //IL_03fe: Unknown result type (might be due to invalid IL or missing references) //IL_0403: Unknown result type (might be due to invalid IL or missing references) //IL_0409: Expected O, but got Unknown //IL_041e: Unknown result type (might be due to invalid IL or missing references) //IL_0423: Unknown result type (might be due to invalid IL or missing references) //IL_0429: Expected O, but got Unknown //IL_043e: Unknown result type (might be due to invalid IL or missing references) //IL_0443: Unknown result type (might be due to invalid IL or missing references) //IL_0449: Expected O, but got Unknown //IL_045e: Unknown result type (might be due to invalid IL or missing references) //IL_0463: Unknown result type (might be due to invalid IL or missing references) //IL_0469: Expected O, but got Unknown //IL_047e: Unknown result type (might be due to invalid IL or missing references) //IL_0483: Unknown result type (might be due to invalid IL or missing references) //IL_0489: Expected O, but got Unknown //IL_049e: Unknown result type (might be due to invalid IL or missing references) //IL_04a3: Unknown result type (might be due to invalid IL or missing references) //IL_04a9: Expected O, but got Unknown if (!installed) { installed = true; object obj = <>O.<0>__TeamComponentGetTeamMembers; if (obj == null) { hook_GetTeamMembers val = TeamComponentGetTeamMembers; <>O.<0>__TeamComponentGetTeamMembers = val; obj = (object)val; } TeamComponent.GetTeamMembers += (hook_GetTeamMembers)obj; object obj2 = <>O.<1>__TeamComponentOnChangeTeam; if (obj2 == null) { hook_OnChangeTeam val2 = TeamComponentOnChangeTeam; <>O.<1>__TeamComponentOnChangeTeam = val2; obj2 = (object)val2; } TeamComponent.OnChangeTeam += (hook_OnChangeTeam)obj2; object obj3 = <>O.<2>__TeamMaskAddTeam; if (obj3 == null) { hook_AddTeam val3 = TeamMaskAddTeam; <>O.<2>__TeamMaskAddTeam = val3; obj3 = (object)val3; } TeamMask.AddTeam += (hook_AddTeam)obj3; object obj4 = <>O.<3>__UtilGetItemCountForTeam; if (obj4 == null) { hook_GetItemCountForTeam val4 = UtilGetItemCountForTeam; <>O.<3>__UtilGetItemCountForTeam = val4; obj4 = (object)val4; } Util.GetItemCountForTeam += (hook_GetItemCountForTeam)obj4; object obj5 = <>O.<4>__BlastAttackFire; if (obj5 == null) { hook_Fire val5 = BlastAttackFire; <>O.<4>__BlastAttackFire = val5; obj5 = (object)val5; } BlastAttack.Fire += (hook_Fire)obj5; object obj6 = <>O.<5>__BlastAttackFireNoDamage; if (obj6 == null) { hook_FireNoDamage val6 = BlastAttackFireNoDamage; <>O.<5>__BlastAttackFireNoDamage = val6; obj6 = (object)val6; } BlastAttack.FireNoDamage += (hook_FireNoDamage)obj6; object obj7 = <>O.<6>__PatchMapZone; if (obj7 == null) { Manipulator val7 = PatchMapZone; <>O.<6>__PatchMapZone = val7; obj7 = (object)val7; } MapZone.TryZoneStart += (Manipulator)obj7; object obj8 = <>O.<7>__PatchCharacterBodyStats; if (obj8 == null) { Manipulator val8 = PatchCharacterBodyStats; <>O.<7>__PatchCharacterBodyStats = val8; obj8 = (object)val8; } CharacterBody.RecalculateStats += (Manipulator)obj8; object obj9 = <>O.<8>__PatchCharacterBodyCulling; if (obj9 == null) { Manipulator val9 = PatchCharacterBodyCulling; <>O.<8>__PatchCharacterBodyCulling = val9; obj9 = (object)val9; } CharacterBody.IsCullable += (Manipulator)obj9; object obj10 = <>O.<9>__PatchCharacterMasterBodyStart; if (obj10 == null) { Manipulator val10 = PatchCharacterMasterBodyStart; <>O.<9>__PatchCharacterMasterBodyStart = val10; obj10 = (object)val10; } CharacterMaster.OnBodyStart += (Manipulator)obj10; object obj11 = <>O.<10>__PatchHealthComponentHeal; if (obj11 == null) { Manipulator val11 = PatchHealthComponentHeal; <>O.<10>__PatchHealthComponentHeal = val11; obj11 = (object)val11; } HealthComponent.Heal += (Manipulator)obj11; object obj12 = <>O.<11>__PatchHealthComponentDamage; if (obj12 == null) { Manipulator val12 = PatchHealthComponentDamage; <>O.<11>__PatchHealthComponentDamage = val12; obj12 = (object)val12; } HealthComponent.TakeDamageProcess += (Manipulator)obj12; object obj13 = <>O.<12>__PatchGroundImpact; if (obj13 == null) { Manipulator val13 = PatchGroundImpact; <>O.<12>__PatchGroundImpact = val13; obj13 = (object)val13; } GlobalEventManager.OnCharacterHitGroundServer += (Manipulator)obj13; object obj14 = <>O.<13>__PatchAffixBeadDamage; if (obj14 == null) { Manipulator val14 = PatchAffixBeadDamage; <>O.<13>__PatchAffixBeadDamage = val14; obj14 = (object)val14; } AffixBeadAttachment.FireProjectile += (Manipulator)obj14; object obj15 = <>O.<14>__PatchTeamExperience; if (obj15 == null) { Manipulator val15 = PatchTeamExperience; <>O.<14>__PatchTeamExperience = val15; obj15 = (object)val15; } TeamManager.GiveTeamExperience += (Manipulator)obj15; object obj16 = <>O.<15>__PatchUnlockPickup; if (obj16 == null) { Manipulator val16 = PatchUnlockPickup; <>O.<15>__PatchUnlockPickup = val16; obj16 = (object)val16; } UnlockPickup.OnTriggerStay += (Manipulator)obj16; object obj17 = <>O.<16>__PatchDoppelgangerInvasion; if (obj17 == null) { Manipulator val17 = PatchDoppelgangerInvasion; <>O.<16>__PatchDoppelgangerInvasion = val17; obj17 = (object)val17; } DoppelgangerInvasionManager.PerformInvasion += (Manipulator)obj17; object obj18 = <>O.<17>__PatchSwarmsArtifact; if (obj18 == null) { Manipulator val18 = PatchSwarmsArtifact; <>O.<17>__PatchSwarmsArtifact = val18; obj18 = (object)val18; } SwarmsArtifactManager.OnSpawnCardOnSpawnedServerGlobal += (Manipulator)obj18; object obj19 = <>O.<18>__PatchGoldTitanTeam; if (obj19 == null) { Manipulator val19 = PatchGoldTitanTeam; <>O.<18>__PatchGoldTitanTeam = val19; obj19 = (object)val19; } GoldTitanManager.TryStartChannelingTitansServer += (Manipulator)obj19; object obj20 = <>O.<19>__PatchHoldoutObjective; if (obj20 == null) { Manipulator val20 = PatchHoldoutObjective; <>O.<19>__PatchHoldoutObjective = val20; obj20 = (object)val20; } HoldoutZoneController.OnCollectObjectiveSources += (Manipulator)obj20; object obj21 = <>O.<20>__PatchExtractionObjective; if (obj21 == null) { Manipulator val21 = PatchExtractionObjective; <>O.<20>__PatchExtractionObjective = val21; obj21 = (object)val21; } EscapeSequenceExtractionZone.ReportObjectives += (Manipulator)obj21; object obj22 = <>O.<21>__PatchSolusOverlayJoin; if (obj22 == null) { Manipulator val22 = PatchSolusOverlayJoin; <>O.<21>__PatchSolusOverlayJoin = val22; obj22 = (object)val22; } OfferingAccepted.AddOverlayToNewMember += (Manipulator)obj22; object obj23 = <>O.<22>__PatchSolusFreezeJoin; if (obj23 == null) { Manipulator val23 = PatchSolusFreezeJoin; <>O.<22>__PatchSolusFreezeJoin = val23; obj23 = (object)val23; } OfferingAccepted.FreezeNewMember += (Manipulator)obj23; object obj24 = <>O.<23>__PatchSeekerHealingPulse; if (obj24 == null) { Manipulator val24 = PatchSeekerHealingPulse; <>O.<23>__PatchSeekerHealingPulse = val24; obj24 = (object)val24; } SeekerController.CmdTriggerHealPulse += (Manipulator)obj24; object obj25 = <>O.<24>__PatchSeekerReviveTeamFilter; if (obj25 == null) { Manipulator val25 = PatchSeekerReviveTeamFilter; <>O.<24>__PatchSeekerReviveTeamFilter = val25; obj25 = (object)val25; } SeekerController.UnlockGateEffects += (Manipulator)obj25; object obj26 = <>O.<25>__PatchMeridiansWillTargeting; if (obj26 == null) { Manipulator val26 = PatchMeridiansWillTargeting; <>O.<25>__PatchMeridiansWillTargeting = val26; obj26 = (object)val26; } MeridiansWillAim.OnEnter += (Manipulator)obj26; object obj27 = <>O.<26>__PatchWarBondsTargeting; if (obj27 == null) { Manipulator val27 = PatchWarBondsTargeting; <>O.<26>__PatchWarBondsTargeting = val27; obj27 = (object)val27; } BarrageOnBossBehaviour.OnEnable += (Manipulator)obj27; object obj28 = <>O.<27>__PatchDroneTechTargetReticle; if (obj28 == null) { Manipulator val28 = PatchDroneTechTargetReticle; <>O.<27>__PatchDroneTechTargetReticle = val28; obj28 = (object)val28; } DroneTechSurvivorUIController.UpdateTarget += (Manipulator)obj28; object obj29 = <>O.<28>__PatchFlyingVerminPlayerTarget; if (obj29 == null) { Manipulator val29 = PatchFlyingVerminPlayerTarget; <>O.<28>__PatchFlyingVerminPlayerTarget = val29; obj29 = (object)val29; } Spit.FireProjectile += (Manipulator)obj29; object obj30 = <>O.<29>__PatchBellPlayerTarget; if (obj30 == null) { Manipulator val30 = PatchBellPlayerTarget; <>O.<29>__PatchBellPlayerTarget = val30; obj30 = (object)val30; } ChargeTrioBomb.FixedUpdate += (Manipulator)obj30; object obj31 = <>O.<30>__PatchAmmoPickup; if (obj31 == null) { Manipulator val31 = PatchAmmoPickup; <>O.<30>__PatchAmmoPickup = val31; obj31 = (object)val31; } AmmoPickup.OnTriggerStay += (Manipulator)obj31; object obj32 = <>O.<31>__PatchBuffPickup; if (obj32 == null) { Manipulator val32 = PatchBuffPickup; <>O.<31>__PatchBuffPickup = val32; obj32 = (object)val32; } BuffPickup.OnTriggerStay += (Manipulator)obj32; object obj33 = <>O.<32>__PatchHealthPickup; if (obj33 == null) { Manipulator val33 = PatchHealthPickup; <>O.<32>__PatchHealthPickup = val33; obj33 = (object)val33; } HealthPickup.OnTriggerStay += (Manipulator)obj33; object obj34 = <>O.<33>__PatchMoneyPickup; if (obj34 == null) { Manipulator val34 = PatchMoneyPickup; <>O.<33>__PatchMoneyPickup = val34; obj34 = (object)val34; } MoneyPickup.OnTriggerStay += (Manipulator)obj34; object obj35 = <>O.<34>__PatchElusiveAntlersPickup; if (obj35 == null) { Manipulator val35 = PatchElusiveAntlersPickup; <>O.<34>__PatchElusiveAntlersPickup = val35; obj35 = (object)val35; } ElusiveAntlersPickup.OnTriggerStay += (Manipulator)obj35; object obj36 = <>O.<35>__PatchGravitatePickup; if (obj36 == null) { Manipulator val36 = PatchGravitatePickup; <>O.<35>__PatchGravitatePickup = val36; obj36 = (object)val36; } GravitatePickup.StartGravitate += (Manipulator)obj36; object obj37 = <>O.<36>__PatchJunkPickup; if (obj37 == null) { Manipulator val37 = PatchJunkPickup; <>O.<36>__PatchJunkPickup = val37; obj37 = (object)val37; } JunkPickup.OnTriggerStay += (Manipulator)obj37; } } internal static void Uninstall() { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Expected O, but got Unknown //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Expected O, but got Unknown //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Expected O, but got Unknown //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Expected O, but got Unknown //IL_009e: 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_00a9: Expected O, but got Unknown //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Expected O, but got Unknown //IL_00de: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Expected O, but got Unknown //IL_00fe: 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_0109: Expected O, but got Unknown //IL_011e: Unknown result type (might be due to invalid IL or missing references) //IL_0123: Unknown result type (might be due to invalid IL or missing references) //IL_0129: Expected O, but got Unknown //IL_013e: Unknown result type (might be due to invalid IL or missing references) //IL_0143: Unknown result type (might be due to invalid IL or missing references) //IL_0149: Expected O, but got Unknown //IL_015e: Unknown result type (might be due to invalid IL or missing references) //IL_0163: Unknown result type (might be due to invalid IL or missing references) //IL_0169: Expected O, but got Unknown //IL_017e: Unknown result type (might be due to invalid IL or missing references) //IL_0183: Unknown result type (might be due to invalid IL or missing references) //IL_0189: Expected O, but got Unknown //IL_019e: Unknown result type (might be due to invalid IL or missing references) //IL_01a3: Unknown result type (might be due to invalid IL or missing references) //IL_01a9: Expected O, but got Unknown //IL_01be: Unknown result type (might be due to invalid IL or missing references) //IL_01c3: Unknown result type (might be due to invalid IL or missing references) //IL_01c9: Expected O, but got Unknown //IL_01de: Unknown result type (might be due to invalid IL or missing references) //IL_01e3: Unknown result type (might be due to invalid IL or missing references) //IL_01e9: Expected O, but got Unknown //IL_01fe: Unknown result type (might be due to invalid IL or missing references) //IL_0203: Unknown result type (might be due to invalid IL or missing references) //IL_0209: Expected O, but got Unknown //IL_021e: 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_0229: Expected O, but got Unknown //IL_023e: Unknown result type (might be due to invalid IL or missing references) //IL_0243: Unknown result type (might be due to invalid IL or missing references) //IL_0249: Expected O, but got Unknown //IL_025e: Unknown result type (might be due to invalid IL or missing references) //IL_0263: Unknown result type (might be due to invalid IL or missing references) //IL_0269: Expected O, but got Unknown //IL_027e: Unknown result type (might be due to invalid IL or missing references) //IL_0283: Unknown result type (might be due to invalid IL or missing references) //IL_0289: Expected O, but got Unknown //IL_029e: Unknown result type (might be due to invalid IL or missing references) //IL_02a3: Unknown result type (might be due to invalid IL or missing references) //IL_02a9: Expected O, but got Unknown //IL_02be: Unknown result type (might be due to invalid IL or missing references) //IL_02c3: Unknown result type (might be due to invalid IL or missing references) //IL_02c9: Expected O, but got Unknown //IL_02de: Unknown result type (might be due to invalid IL or missing references) //IL_02e3: Unknown result type (might be due to invalid IL or missing references) //IL_02e9: Expected O, but got Unknown //IL_02fe: Unknown result type (might be due to invalid IL or missing references) //IL_0303: Unknown result type (might be due to invalid IL or missing references) //IL_0309: Expected O, but got Unknown //IL_031e: 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_0329: Expected O, but got Unknown //IL_033e: Unknown result type (might be due to invalid IL or missing references) //IL_0343: Unknown result type (might be due to invalid IL or missing references) //IL_0349: Expected O, but got Unknown //IL_035e: Unknown result type (might be due to invalid IL or missing references) //IL_0363: Unknown result type (might be due to invalid IL or missing references) //IL_0369: Expected O, but got Unknown //IL_037e: Unknown result type (might be due to invalid IL or missing references) //IL_0383: Unknown result type (might be due to invalid IL or missing references) //IL_0389: Expected O, but got Unknown //IL_039e: Unknown result type (might be due to invalid IL or missing references) //IL_03a3: Unknown result type (might be due to invalid IL or missing references) //IL_03a9: Expected O, but got Unknown //IL_03be: Unknown result type (might be due to invalid IL or missing references) //IL_03c3: Unknown result type (might be due to invalid IL or missing references) //IL_03c9: Expected O, but got Unknown //IL_03de: Unknown result type (might be due to invalid IL or missing references) //IL_03e3: Unknown result type (might be due to invalid IL or missing references) //IL_03e9: Expected O, but got Unknown //IL_03fe: Unknown result type (might be due to invalid IL or missing references) //IL_0403: Unknown result type (might be due to invalid IL or missing references) //IL_0409: Expected O, but got Unknown //IL_041e: Unknown result type (might be due to invalid IL or missing references) //IL_0423: Unknown result type (might be due to invalid IL or missing references) //IL_0429: Expected O, but got Unknown //IL_043e: Unknown result type (might be due to invalid IL or missing references) //IL_0443: Unknown result type (might be due to invalid IL or missing references) //IL_0449: Expected O, but got Unknown //IL_045e: Unknown result type (might be due to invalid IL or missing references) //IL_0463: Unknown result type (might be due to invalid IL or missing references) //IL_0469: Expected O, but got Unknown //IL_047e: Unknown result type (might be due to invalid IL or missing references) //IL_0483: Unknown result type (might be due to invalid IL or missing references) //IL_0489: Expected O, but got Unknown //IL_049e: Unknown result type (might be due to invalid IL or missing references) //IL_04a3: Unknown result type (might be due to invalid IL or missing references) //IL_04a9: Expected O, but got Unknown if (installed) { installed = false; object obj = <>O.<0>__TeamComponentGetTeamMembers; if (obj == null) { hook_GetTeamMembers val = TeamComponentGetTeamMembers; <>O.<0>__TeamComponentGetTeamMembers = val; obj = (object)val; } TeamComponent.GetTeamMembers -= (hook_GetTeamMembers)obj; object obj2 = <>O.<1>__TeamComponentOnChangeTeam; if (obj2 == null) { hook_OnChangeTeam val2 = TeamComponentOnChangeTeam; <>O.<1>__TeamComponentOnChangeTeam = val2; obj2 = (object)val2; } TeamComponent.OnChangeTeam -= (hook_OnChangeTeam)obj2; object obj3 = <>O.<2>__TeamMaskAddTeam; if (obj3 == null) { hook_AddTeam val3 = TeamMaskAddTeam; <>O.<2>__TeamMaskAddTeam = val3; obj3 = (object)val3; } TeamMask.AddTeam -= (hook_AddTeam)obj3; object obj4 = <>O.<3>__UtilGetItemCountForTeam; if (obj4 == null) { hook_GetItemCountForTeam val4 = UtilGetItemCountForTeam; <>O.<3>__UtilGetItemCountForTeam = val4; obj4 = (object)val4; } Util.GetItemCountForTeam -= (hook_GetItemCountForTeam)obj4; object obj5 = <>O.<4>__BlastAttackFire; if (obj5 == null) { hook_Fire val5 = BlastAttackFire; <>O.<4>__BlastAttackFire = val5; obj5 = (object)val5; } BlastAttack.Fire -= (hook_Fire)obj5; object obj6 = <>O.<5>__BlastAttackFireNoDamage; if (obj6 == null) { hook_FireNoDamage val6 = BlastAttackFireNoDamage; <>O.<5>__BlastAttackFireNoDamage = val6; obj6 = (object)val6; } BlastAttack.FireNoDamage -= (hook_FireNoDamage)obj6; object obj7 = <>O.<6>__PatchMapZone; if (obj7 == null) { Manipulator val7 = PatchMapZone; <>O.<6>__PatchMapZone = val7; obj7 = (object)val7; } MapZone.TryZoneStart -= (Manipulator)obj7; object obj8 = <>O.<7>__PatchCharacterBodyStats; if (obj8 == null) { Manipulator val8 = PatchCharacterBodyStats; <>O.<7>__PatchCharacterBodyStats = val8; obj8 = (object)val8; } CharacterBody.RecalculateStats -= (Manipulator)obj8; object obj9 = <>O.<8>__PatchCharacterBodyCulling; if (obj9 == null) { Manipulator val9 = PatchCharacterBodyCulling; <>O.<8>__PatchCharacterBodyCulling = val9; obj9 = (object)val9; } CharacterBody.IsCullable -= (Manipulator)obj9; object obj10 = <>O.<9>__PatchCharacterMasterBodyStart; if (obj10 == null) { Manipulator val10 = PatchCharacterMasterBodyStart; <>O.<9>__PatchCharacterMasterBodyStart = val10; obj10 = (object)val10; } CharacterMaster.OnBodyStart -= (Manipulator)obj10; object obj11 = <>O.<10>__PatchHealthComponentHeal; if (obj11 == null) { Manipulator val11 = PatchHealthComponentHeal; <>O.<10>__PatchHealthComponentHeal = val11; obj11 = (object)val11; } HealthComponent.Heal -= (Manipulator)obj11; object obj12 = <>O.<11>__PatchHealthComponentDamage; if (obj12 == null) { Manipulator val12 = PatchHealthComponentDamage; <>O.<11>__PatchHealthComponentDamage = val12; obj12 = (object)val12; } HealthComponent.TakeDamageProcess -= (Manipulator)obj12; object obj13 = <>O.<12>__PatchGroundImpact; if (obj13 == null) { Manipulator val13 = PatchGroundImpact; <>O.<12>__PatchGroundImpact = val13; obj13 = (object)val13; } GlobalEventManager.OnCharacterHitGroundServer -= (Manipulator)obj13; object obj14 = <>O.<13>__PatchAffixBeadDamage; if (obj14 == null) { Manipulator val14 = PatchAffixBeadDamage; <>O.<13>__PatchAffixBeadDamage = val14; obj14 = (object)val14; } AffixBeadAttachment.FireProjectile -= (Manipulator)obj14; object obj15 = <>O.<14>__PatchTeamExperience; if (obj15 == null) { Manipulator val15 = PatchTeamExperience; <>O.<14>__PatchTeamExperience = val15; obj15 = (object)val15; } TeamManager.GiveTeamExperience -= (Manipulator)obj15; object obj16 = <>O.<15>__PatchUnlockPickup; if (obj16 == null) { Manipulator val16 = PatchUnlockPickup; <>O.<15>__PatchUnlockPickup = val16; obj16 = (object)val16; } UnlockPickup.OnTriggerStay -= (Manipulator)obj16; object obj17 = <>O.<16>__PatchDoppelgangerInvasion; if (obj17 == null) { Manipulator val17 = PatchDoppelgangerInvasion; <>O.<16>__PatchDoppelgangerInvasion = val17; obj17 = (object)val17; } DoppelgangerInvasionManager.PerformInvasion -= (Manipulator)obj17; object obj18 = <>O.<17>__PatchSwarmsArtifact; if (obj18 == null) { Manipulator val18 = PatchSwarmsArtifact; <>O.<17>__PatchSwarmsArtifact = val18; obj18 = (object)val18; } SwarmsArtifactManager.OnSpawnCardOnSpawnedServerGlobal -= (Manipulator)obj18; object obj19 = <>O.<18>__PatchGoldTitanTeam; if (obj19 == null) { Manipulator val19 = PatchGoldTitanTeam; <>O.<18>__PatchGoldTitanTeam = val19; obj19 = (object)val19; } GoldTitanManager.TryStartChannelingTitansServer -= (Manipulator)obj19; object obj20 = <>O.<19>__PatchHoldoutObjective; if (obj20 == null) { Manipulator val20 = PatchHoldoutObjective; <>O.<19>__PatchHoldoutObjective = val20; obj20 = (object)val20; } HoldoutZoneController.OnCollectObjectiveSources -= (Manipulator)obj20; object obj21 = <>O.<20>__PatchExtractionObjective; if (obj21 == null) { Manipulator val21 = PatchExtractionObjective; <>O.<20>__PatchExtractionObjective = val21; obj21 = (object)val21; } EscapeSequenceExtractionZone.ReportObjectives -= (Manipulator)obj21; object obj22 = <>O.<21>__PatchSolusOverlayJoin; if (obj22 == null) { Manipulator val22 = PatchSolusOverlayJoin; <>O.<21>__PatchSolusOverlayJoin = val22; obj22 = (object)val22; } OfferingAccepted.AddOverlayToNewMember -= (Manipulator)obj22; object obj23 = <>O.<22>__PatchSolusFreezeJoin; if (obj23 == null) { Manipulator val23 = PatchSolusFreezeJoin; <>O.<22>__PatchSolusFreezeJoin = val23; obj23 = (object)val23; } OfferingAccepted.FreezeNewMember -= (Manipulator)obj23; object obj24 = <>O.<23>__PatchSeekerHealingPulse; if (obj24 == null) { Manipulator val24 = PatchSeekerHealingPulse; <>O.<23>__PatchSeekerHealingPulse = val24; obj24 = (object)val24; } SeekerController.CmdTriggerHealPulse -= (Manipulator)obj24; object obj25 = <>O.<24>__PatchSeekerReviveTeamFilter; if (obj25 == null) { Manipulator val25 = PatchSeekerReviveTeamFilter; <>O.<24>__PatchSeekerReviveTeamFilter = val25; obj25 = (object)val25; } SeekerController.UnlockGateEffects -= (Manipulator)obj25; object obj26 = <>O.<25>__PatchMeridiansWillTargeting; if (obj26 == null) { Manipulator val26 = PatchMeridiansWillTargeting; <>O.<25>__PatchMeridiansWillTargeting = val26; obj26 = (object)val26; } MeridiansWillAim.OnEnter -= (Manipulator)obj26; object obj27 = <>O.<26>__PatchWarBondsTargeting; if (obj27 == null) { Manipulator val27 = PatchWarBondsTargeting; <>O.<26>__PatchWarBondsTargeting = val27; obj27 = (object)val27; } BarrageOnBossBehaviour.OnEnable -= (Manipulator)obj27; object obj28 = <>O.<27>__PatchDroneTechTargetReticle; if (obj28 == null) { Manipulator val28 = PatchDroneTechTargetReticle; <>O.<27>__PatchDroneTechTargetReticle = val28; obj28 = (object)val28; } DroneTechSurvivorUIController.UpdateTarget -= (Manipulator)obj28; object obj29 = <>O.<28>__PatchFlyingVerminPlayerTarget; if (obj29 == null) { Manipulator val29 = PatchFlyingVerminPlayerTarget; <>O.<28>__PatchFlyingVerminPlayerTarget = val29; obj29 = (object)val29; } Spit.FireProjectile -= (Manipulator)obj29; object obj30 = <>O.<29>__PatchBellPlayerTarget; if (obj30 == null) { Manipulator val30 = PatchBellPlayerTarget; <>O.<29>__PatchBellPlayerTarget = val30; obj30 = (object)val30; } ChargeTrioBomb.FixedUpdate -= (Manipulator)obj30; object obj31 = <>O.<30>__PatchAmmoPickup; if (obj31 == null) { Manipulator val31 = PatchAmmoPickup; <>O.<30>__PatchAmmoPickup = val31; obj31 = (object)val31; } AmmoPickup.OnTriggerStay -= (Manipulator)obj31; object obj32 = <>O.<31>__PatchBuffPickup; if (obj32 == null) { Manipulator val32 = PatchBuffPickup; <>O.<31>__PatchBuffPickup = val32; obj32 = (object)val32; } BuffPickup.OnTriggerStay -= (Manipulator)obj32; object obj33 = <>O.<32>__PatchHealthPickup; if (obj33 == null) { Manipulator val33 = PatchHealthPickup; <>O.<32>__PatchHealthPickup = val33; obj33 = (object)val33; } HealthPickup.OnTriggerStay -= (Manipulator)obj33; object obj34 = <>O.<33>__PatchMoneyPickup; if (obj34 == null) { Manipulator val34 = PatchMoneyPickup; <>O.<33>__PatchMoneyPickup = val34; obj34 = (object)val34; } MoneyPickup.OnTriggerStay -= (Manipulator)obj34; object obj35 = <>O.<34>__PatchElusiveAntlersPickup; if (obj35 == null) { Manipulator val35 = PatchElusiveAntlersPickup; <>O.<34>__PatchElusiveAntlersPickup = val35; obj35 = (object)val35; } ElusiveAntlersPickup.OnTriggerStay -= (Manipulator)obj35; object obj36 = <>O.<35>__PatchGravitatePickup; if (obj36 == null) { Manipulator val36 = PatchGravitatePickup; <>O.<35>__PatchGravitatePickup = val36; obj36 = (object)val36; } GravitatePickup.StartGravitate -= (Manipulator)obj36; object obj37 = <>O.<36>__PatchJunkPickup; if (obj37 == null) { Manipulator val37 = PatchJunkPickup; <>O.<36>__PatchJunkPickup = val37; obj37 = (object)val37; } JunkPickup.OnTriggerStay -= (Manipulator)obj37; cachedVirtualPlayerMembers = new List().AsReadOnly(); cachedVirtualPlayerMembersFrame = -1; } } private static ReadOnlyCollection TeamComponentGetTeamMembers(orig_GetTeamMembers orig, TeamIndex teamIndex) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Invalid comparison between Unknown and I4 //IL_003f: Unknown result type (might be due to invalid IL or missing references) if (!Plugin.IsPvPModeActive || (int)teamIndex != 1) { return orig.Invoke(teamIndex); } if (cachedVirtualPlayerMembersFrame == Time.frameCount) { return cachedVirtualPlayerMembers; } List list = new List(); AddMembers(list, orig.Invoke((TeamIndex)1)); for (int i = 0; i < PvPTeamRegistry.Count; i++) { AddMembers(list, orig.Invoke(PvPTeamRegistry.GetTeamIndex(i))); } cachedVirtualPlayerMembers = list.AsReadOnly(); cachedVirtualPlayerMembersFrame = Time.frameCount; return cachedVirtualPlayerMembers; } private static void AddMembers(List destination, ReadOnlyCollection source) { for (int i = 0; i < source.Count; i++) { TeamComponent val = source[i]; if (Object.op_Implicit((Object)(object)val) && !destination.Contains(val)) { destination.Add(val); } } } private static void TeamComponentOnChangeTeam(orig_OnChangeTeam orig, TeamComponent self, TeamIndex newTeamIndex) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) orig.Invoke(self, newTeamIndex); cachedVirtualPlayerMembersFrame = -1; } private static void TeamMaskAddTeam(orig_AddTeam orig, ref TeamMask self, TeamIndex teamIndex) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Invalid comparison between Unknown and I4 //IL_001b: Unknown result type (might be due to invalid IL or missing references) orig.Invoke(ref self, teamIndex); if (Plugin.IsPvPModeActive && (int)teamIndex == 1) { for (int i = 0; i < PvPTeamRegistry.Count; i++) { orig.Invoke(ref self, PvPTeamRegistry.GetTeamIndex(i)); } } } private static int UtilGetItemCountForTeam(orig_GetItemCountForTeam orig, TeamIndex teamIndex, ItemIndex itemIndex, bool requiresAlive, bool requiresConnected) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Invalid comparison between Unknown and I4 //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) int num = orig.Invoke(teamIndex, itemIndex, requiresAlive, requiresConnected); if (!Plugin.IsPvPModeActive || (int)teamIndex != 1) { return num; } for (int i = 0; i < PvPTeamRegistry.Count; i++) { num += orig.Invoke(PvPTeamRegistry.GetTeamIndex(i), itemIndex, requiresAlive, requiresConnected); } return num; } private static Result BlastAttackFire(orig_Fire orig, BlastAttack self) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) CorrectPlayerOwnedBlastTeam(self); return orig.Invoke(self); } private static Result BlastAttackFireNoDamage(orig_FireNoDamage orig, BlastAttack self) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) CorrectPlayerOwnedBlastTeam(self); return orig.Invoke(self); } private static void CorrectPlayerOwnedBlastTeam(BlastAttack blastAttack) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Invalid comparison between Unknown and I4 //IL_002f: 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_0043: Unknown result type (might be due to invalid IL or missing references) if (Plugin.IsPvPModeActive && (int)blastAttack.teamIndex == 1 && Object.op_Implicit((Object)(object)blastAttack.attacker) && PvPRelationService.TryResolve(blastAttack.attacker, out var combatant) && PvPTeamRegistry.IsPvPTeam(combatant.TeamIndex)) { blastAttack.teamIndex = combatant.TeamIndex; } } private static TeamIndex NormalizePvPTeamAsPlayer(TeamIndex teamIndex) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) if (!Plugin.IsPvPModeActive || !PvPTeamRegistry.IsPvPTeam(teamIndex)) { return teamIndex; } return (TeamIndex)1; } private static TeamIndex GetBodyTeamOrPlayer(CharacterBody? body) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) if (!Plugin.IsPvPModeActive || body == null || !Object.op_Implicit((Object)(object)body)) { return (TeamIndex)1; } TeamComponent teamComponent = body.teamComponent; if (!Object.op_Implicit((Object)(object)teamComponent) || !PvPTeamRegistry.IsPvPTeam(teamComponent.teamIndex)) { return (TeamIndex)1; } return teamComponent.teamIndex; } private static bool MatchesLegacyPlayerFilter(TeamIndex objectTeam, TeamIndex filterTeam) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Invalid comparison between Unknown and I4 //IL_000f: Unknown result type (might be due to invalid IL or missing references) if (objectTeam != filterTeam) { if (Plugin.IsPvPModeActive && (int)filterTeam == 1) { return PvPTeamRegistry.IsPvPTeam(objectTeam); } return false; } return true; } private static void PatchMapZone(ILContext il) { PatchTeamComponentPlayerComparisons(il, "MapZone.TryZoneStart", 2); } private static void PatchCharacterBodyStats(ILContext il) { PatchTeamComponentPlayerComparisons(il, "CharacterBody.RecalculateStats", 5); } private static void PatchCharacterBodyCulling(ILContext il) { PatchTeamComponentPlayerComparisons(il, "CharacterBody.IsCullable", 1); } private static void PatchHealthComponentHeal(ILContext il) { PatchTeamComponentPlayerComparisons(il, "HealthComponent.Heal", 1); } private static void PatchHealthComponentDamage(ILContext il) { PatchTeamComponentPlayerComparisons(il, "HealthComponent.TakeDamageProcess", 1); } private static void PatchGroundImpact(ILContext il) { PatchTeamComponentPlayerComparisons(il, "GlobalEventManager.OnCharacterHitGroundServer", 1); } private static void PatchUnlockPickup(ILContext il) { PatchTeamComponentPlayerComparisons(il, "UnlockPickup.OnTriggerStay", 1); } private static void PatchCharacterMasterBodyStart(ILContext il) { PatchTeamIndexGetterPlayerComparisons(il, "CharacterMaster.OnBodyStart", 1); } private static void PatchDoppelgangerInvasion(ILContext il) { PatchTeamIndexGetterPlayerComparisons(il, "DoppelgangerInvasionManager.PerformInvasion", 1); } private static void PatchSwarmsArtifact(ILContext il) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown ILCursor val = new ILCursor(il); int num = 0; while (val.TryGotoNext((MoveType)2, new Func[1] { delegate(Instruction instruction) { object operand = instruction.Operand; MethodReference val2 = (MethodReference)((operand is MethodReference) ? operand : null); return val2 != null && ((MemberReference)val2).Name == "GetValueOrDefault" && ((MemberReference)((MemberReference)val2).DeclaringType).FullName.Contains("System.Nullable`1"); } })) { val.EmitDelegate>((Func)NormalizePvPTeamAsPlayer); num++; } ReportPatchCount("SwarmsArtifactManager.OnSpawnCardOnSpawnedServerGlobal", num, 1); } private static void PatchGoldTitanTeam(ILContext il) { //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Expected O, but got Unknown //IL_007a: Unknown result type (might be due to invalid IL or missing references) VariableDefinition val = null; for (int i = 0; i < il.Body.Variables.Count; i++) { VariableDefinition val2 = il.Body.Variables[i]; if (((MemberReference)((VariableReference)val2).VariableType).FullName == typeof(TeamIndex).FullName) { val = val2; break; } } if (val == null) { ReportPatchCount("GoldTitanManager.TryStartChannelingTitansServer", 0, 1); return; } ILCursor val3 = new ILCursor(il); int num = 0; while (val3.TryGotoNext((MoveType)0, new Func[3] { (Instruction instruction) => ILPatternMatchingExt.MatchLdcI4(instruction, 1), delegate(Instruction instruction) { object operand = instruction.Operand; MethodReference val4 = (MethodReference)((operand is MethodReference) ? operand : null); return val4 != null && ((MemberReference)val4).Name == ".ctor" && ((MemberReference)((MemberReference)val4).DeclaringType).FullName.Contains("System.Nullable`1"); }, (Instruction instruction) => ILPatternMatchingExt.MatchStfld(instruction, "teamIndexOverride") })) { val3.Remove(); val3.Emit(OpCodes.Ldloc, val); num++; } ReportPatchCount("GoldTitanManager.TryStartChannelingTitansServer", num, 1); } private static void PatchHoldoutObjective(ILContext il) { PatchTeamEqualityBranch(il, delegate(Instruction instruction) { object operand = instruction.Operand; MethodReference val = (MethodReference)((operand is MethodReference) ? operand : null); return val != null && ((MemberReference)val).Name == "get_teamIndex" && ((MemberReference)((MemberReference)val).DeclaringType).FullName == typeof(CharacterMaster).FullName; }, (TeamIndex filterTeam, TeamIndex objectTeam) => MatchesLegacyPlayerFilter(objectTeam, filterTeam), "HoldoutZoneController.OnCollectObjectiveSources"); } private static void PatchExtractionObjective(ILContext il) { PatchTeamEqualityBranch(il, delegate(Instruction instruction) { object operand = instruction.Operand; FieldReference val = (FieldReference)((operand is FieldReference) ? operand : null); return val != null && ((MemberReference)val).Name == "teamIndex" && ((MemberReference)((MemberReference)val).DeclaringType).FullName == typeof(EscapeSequenceExtractionZone).FullName; }, MatchesLegacyPlayerFilter, "EscapeSequenceExtractionZone.ReportObjectives"); } private static void PatchSolusOverlayJoin(ILContext il) { PatchArgumentPlayerComparisons(il, 2, "SolusHeartFinaleSequence.AddOverlayToNewMember", 1); } private static void PatchSolusFreezeJoin(ILContext il) { PatchArgumentPlayerComparisons(il, 2, "SolusHeartFinaleSequence.FreezeNewMember", 1); } private static void PatchAffixBeadDamage(ILContext il) { PatchFieldPlayerComparisons(il, "teamIndex", "AffixBeadAttachment.FireProjectile", 1); } private static void PatchTeamExperience(ILContext il) { PatchArgumentPlayerComparisons(il, 1, "TeamManager.GiveTeamExperience", 1); } private static void PatchTeamComponentPlayerComparisons(ILContext il, string patchName, int expectedCount) { PatchTeamIndexGetterPlayerComparisons(il, patchName, expectedCount); } private static void PatchTeamIndexGetterPlayerComparisons(ILContext il, string patchName, int expectedCount) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown ILCursor val = new ILCursor(il); int num = 0; while (val.TryGotoNext((MoveType)2, new Func[1] { (Instruction instruction) => ILPatternMatchingExt.MatchCallOrCallvirt(instruction, "get_teamIndex") })) { if (val.Next != null && ILPatternMatchingExt.MatchLdcI4(val.Next, 1)) { val.EmitDelegate>((Func)NormalizePvPTeamAsPlayer); num++; } } ReportPatchCount(patchName, num, expectedCount); } private static void PatchFieldPlayerComparisons(ILContext il, string fieldName, string patchName, int expectedCount) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Expected O, but got Unknown ILCursor val = new ILCursor(il); int num = 0; while (val.TryGotoNext((MoveType)2, new Func[1] { (Instruction instruction) => ILPatternMatchingExt.MatchLdfld(instruction, fieldName) })) { if (val.Next != null && ILPatternMatchingExt.MatchLdcI4(val.Next, 1)) { val.EmitDelegate>((Func)NormalizePvPTeamAsPlayer); num++; } } ReportPatchCount(patchName, num, expectedCount); } private static void PatchArgumentPlayerComparisons(ILContext il, int argumentIndex, string patchName, int expectedCount) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Expected O, but got Unknown ILCursor val = new ILCursor(il); int num = 0; while (val.TryGotoNext((MoveType)2, new Func[1] { (Instruction instruction) => ILPatternMatchingExt.MatchLdarg(instruction, argumentIndex) })) { if (val.Next != null && ILPatternMatchingExt.MatchLdcI4(val.Next, 1)) { val.EmitDelegate>((Func)NormalizePvPTeamAsPlayer); num++; } } ReportPatchCount(patchName, num, expectedCount); } private static void PatchSeekerHealingPulse(ILContext il) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown //IL_0013: Unknown result type (might be due to invalid IL or missing references) ILCursor val = new ILCursor(il); int num = 0; while (val.TryGotoNext((MoveType)0, new Func[2] { (Instruction instruction) => ILPatternMatchingExt.MatchLdcI4(instruction, 1), (Instruction instruction) => ILPatternMatchingExt.MatchStfld(instruction, "teamIndex") })) { val.Remove(); val.Emit(OpCodes.Ldarg_0); val.EmitDelegate>((Func)((SeekerController controller) => GetBodyTeamOrPlayer(Object.op_Implicit((Object)(object)controller) ? ((Component)controller).GetComponent() : null))); num++; } ReportPatchCount("SeekerController.CmdTriggerHealPulse", num, 1); } private static void PatchSeekerReviveTeamFilter(ILContext il) { //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Expected O, but got Unknown //IL_010c: Unknown result type (might be due to invalid IL or missing references) //IL_0112: Expected O, but got Unknown //IL_01a9: Unknown result type (might be due to invalid IL or missing references) //IL_01b0: Expected O, but got Unknown //IL_0156: Unknown result type (might be due to invalid IL or missing references) //IL_0162: Unknown result type (might be due to invalid IL or missing references) //IL_0196: Unknown result type (might be due to invalid IL or missing references) //IL_0218: Unknown result type (might be due to invalid IL or missing references) VariableDefinition playerEnumerator = null; VariableDefinition targetMaster = null; for (int i = 0; i < il.Body.Variables.Count; i++) { VariableDefinition val = il.Body.Variables[i]; if (((MemberReference)((VariableReference)val).VariableType).FullName.Contains("IEnumerator`1")) { playerEnumerator = val; } else if (((MemberReference)((VariableReference)val).VariableType).FullName == typeof(CharacterMaster).FullName) { targetMaster = val; } } if (playerEnumerator == null || targetMaster == null) { ReportPatchCount("SeekerController.UnlockGateEffects", 0, 1); return; } ILCursor val2 = new ILCursor(il); if (!val2.TryGotoNext((MoveType)0, new Func[2] { (Instruction instruction) => ILPatternMatchingExt.MatchLdloc(instruction, ((VariableReference)playerEnumerator).Index), delegate(Instruction instruction) { object operand = instruction.Operand; MethodReference val5 = (MethodReference)((operand is MethodReference) ? operand : null); return val5 != null && ((MemberReference)val5).Name == "MoveNext"; } })) { ReportPatchCount("SeekerController.UnlockGateEffects", 0, 1); return; } Instruction next = val2.Next; ILCursor val3 = new ILCursor(il); int num = 0; if (val3.TryGotoNext((MoveType)2, new Func[2] { (Instruction instruction) => ILPatternMatchingExt.MatchCallOrCallvirt(instruction, "get_master"), (Instruction instruction) => ILPatternMatchingExt.MatchStloc(instruction, ((VariableReference)targetMaster).Index) })) { val3.Emit(OpCodes.Ldarg_0); val3.Emit(OpCodes.Ldloc, targetMaster); val3.EmitDelegate>((Func)CanSeekerAffectMaster); val3.Emit(OpCodes.Brfalse, next); num++; } ILCursor val4 = new ILCursor(il); int num2 = 0; if (val4.TryGotoNext((MoveType)0, new Func[3] { (Instruction instruction) => ILPatternMatchingExt.MatchLdloc(instruction, ((VariableReference)targetMaster).Index), (Instruction instruction) => ILPatternMatchingExt.MatchLdcI4(instruction, 1), delegate(Instruction instruction) { object operand = instruction.Operand; MethodReference val5 = (MethodReference)((operand is MethodReference) ? operand : null); return val5 != null && ((MemberReference)val5).Name == "set_seekerRevivedOnce"; } })) { val4.Emit(OpCodes.Ldloc, targetMaster); val4.EmitDelegate>((Action)PvPMatchManager.PrepareSeekerRevive); num2++; } ReportPatchCount("SeekerController.UnlockGateEffects", num, 1); ReportPatchCount("SeekerController.UnlockGateEffects.PrepareLimitedLife", num2, 1); } private static bool CanSeekerAffectMaster(SeekerController controller, CharacterMaster targetMaster) { //IL_0063: 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) if (!Plugin.IsPvPModeActive) { return true; } if (!Object.op_Implicit((Object)(object)controller) || !Object.op_Implicit((Object)(object)targetMaster)) { return false; } CharacterBody component = ((Component)controller).GetComponent(); CharacterMaster val = ((Object.op_Implicit((Object)(object)component) && Object.op_Implicit((Object)(object)component.master)) ? component.master : null); if (val == null) { return false; } if (!((!PvPTeamManager.TryGetTeamId(val, out var teamId) || !PvPTeamManager.TryGetTeamId(targetMaster, out var teamId2)) ? (val.teamIndex == targetMaster.teamIndex) : (teamId == teamId2))) { return false; } if (PvPConfig.CurrentMatchMode == PvPConfig.MatchModeKind.LimitedLives) { CharacterBody body = targetMaster.GetBody(); if (body != null && Object.op_Implicit((Object)(object)body) && Object.op_Implicit((Object)(object)body.healthComponent) && body.healthComponent.alive) { return false; } } return true; } private static void PatchMeridiansWillTargeting(ILContext il) { PatchRemovePlayerTeamArgument(il, (MeridiansWillAim state) => GetBodyTeamOrPlayer((state != null) ? ((EntityState)state).characterBody : null), "MeridiansWillAim.OnEnter"); } private static void PatchWarBondsTargeting(ILContext il) { PatchRemovePlayerTeamArgument(il, (BarrageOnBossBehaviour behavior) => GetBodyTeamOrPlayer(((ItemBehavior)(behavior?)).body), "BarrageOnBossBehaviour.OnEnable"); } private static void PatchDroneTechTargetReticle(ILContext il) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown //IL_0013: Unknown result type (might be due to invalid IL or missing references) ILCursor val = new ILCursor(il); int num = 0; while (val.TryGotoNext((MoveType)0, new Func[2] { (Instruction instruction) => ILPatternMatchingExt.MatchLdcI4(instruction, 1), (Instruction instruction) => instruction.OpCode == OpCodes.Bne_Un || instruction.OpCode == OpCodes.Bne_Un_S })) { val.Remove(); val.Emit(OpCodes.Ldarg_0); val.EmitDelegate>((Func)((DroneTechSurvivorUIController controller) => GetBodyTeamOrPlayer(Object.op_Implicit((Object)(object)controller) ? ((Component)controller).GetComponent() : null))); num++; } ReportPatchCount("DroneTechSurvivorUIController.UpdateTarget", num, 1); } private static void PatchFlyingVerminPlayerTarget(ILContext il) { PatchTeamComponentPlayerComparisons(il, "FlyingVermin.Spit.FireProjectile", 1); } private static void PatchBellPlayerTarget(ILContext il) { PatchTeamComponentPlayerComparisons(il, "Bell.ChargeTrioBomb.FixedUpdate", 1); } private static void PatchRemovePlayerTeamArgument(ILContext il, Func getTeam, string patchName) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown //IL_0013: Unknown result type (might be due to invalid IL or missing references) ILCursor val = new ILCursor(il); int num = 0; while (val.TryGotoNext((MoveType)0, new Func[2] { (Instruction instruction) => ILPatternMatchingExt.MatchLdcI4(instruction, 1), (Instruction instruction) => ILPatternMatchingExt.MatchCallOrCallvirt(instruction, "RemoveTeam") })) { val.Remove(); val.Emit(OpCodes.Ldarg_0); val.EmitDelegate>(getTeam); num++; } ReportPatchCount(patchName, num, 1); } private static void PatchAmmoPickup(ILContext il) { PatchTeamFilterComparison(il, "AmmoPickup.OnTriggerStay"); } private static void PatchBuffPickup(ILContext il) { PatchTeamFilterComparison(il, "BuffPickup.OnTriggerStay"); } private static void PatchHealthPickup(ILContext il) { PatchTeamFilterComparison(il, "HealthPickup.OnTriggerStay"); } private static void PatchMoneyPickup(ILContext il) { PatchTeamFilterComparison(il, "MoneyPickup.OnTriggerStay"); } private static void PatchElusiveAntlersPickup(ILContext il) { PatchTeamFilterComparison(il, "ElusiveAntlersPickup.OnTriggerStay"); } private static void PatchGravitatePickup(ILContext il) { PatchTeamFilterComparison(il, "GravitatePickup.StartGravitate"); } private static void PatchJunkPickup(ILContext il) { PatchTeamFilterComparison(il, "JunkPickup.OnTriggerStay"); } private static void PatchTeamFilterComparison(ILContext il, string patchName) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_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_0042: 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_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_009c: 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) ILCursor val = new ILCursor(il); int num = 0; while (val.TryGotoNext((MoveType)2, new Func[1] { delegate(Instruction instruction) { object operand = instruction.Operand; MethodReference val2 = (MethodReference)((operand is MethodReference) ? operand : null); return val2 != null && ((MemberReference)val2).Name == "get_teamIndex" && ((MemberReference)((MemberReference)val2).DeclaringType).FullName == typeof(TeamFilter).FullName; } })) { Instruction next = val.Next; if (next != null) { bool flag = next.OpCode == OpCodes.Beq || next.OpCode == OpCodes.Beq_S; bool flag2 = next.OpCode == OpCodes.Bne_Un || next.OpCode == OpCodes.Bne_Un_S; if (flag || flag2) { val.EmitDelegate>((Func)MatchesLegacyPlayerFilter); next.OpCode = (flag ? OpCodes.Brtrue : OpCodes.Brfalse); num++; } } } ReportPatchCount(patchName, num, 1); } private static void PatchTeamEqualityBranch(ILContext il, Func secondTeamProducer, Func comparison, string patchName) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Expected O, but got Unknown //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) ILCursor val = new ILCursor(il); int num = 0; while (val.TryGotoNext((MoveType)2, new Func[1] { (Instruction instruction) => secondTeamProducer(instruction) })) { Instruction next = val.Next; if (next != null) { bool flag = next.OpCode == OpCodes.Beq || next.OpCode == OpCodes.Beq_S; bool flag2 = next.OpCode == OpCodes.Bne_Un || next.OpCode == OpCodes.Bne_Un_S; if (flag || flag2) { val.EmitDelegate>(comparison); next.OpCode = (flag ? OpCodes.Brtrue : OpCodes.Brfalse); num++; } } } ReportPatchCount(patchName, num, 1); } private static void ReportPatchCount(string patchName, int actualCount, int expectedCount) { if (actualCount != expectedCount) { Plugin.Log.LogError((object)$"Compatibility patch {patchName} changed {actualCount} locations; expected {expectedCount}."); } } } } namespace PvPMode.Combat { internal static class PvPDamageController { private sealed class ControlDurationStateMessage : MessageBase { internal float Multiplier; public override void Serialize(NetworkWriter writer) { writer.Write(Multiplier); } public override void Deserialize(NetworkReader reader) { Multiplier = reader.ReadSingle(); } } [CompilerGenerated] private static class <>O { public static hook_TakeDamage <0>__HealthComponentTakeDamage; public static hook_SetImmobilize <1>__SetStateOnHurtSetImmobilize; public static hook_SetStun <2>__SetStateOnHurtSetStun; public static hook_OverrideStun <3>__SetStateOnHurtOverrideStun; public static hook_SetFrozen <4>__SetStateOnHurtSetFrozen; public static hook_SetShock <5>__SetStateOnHurtSetShock; public static hook_SetCustomState <6>__SetStateOnHurtSetCustomState; public static Manipulator <7>__PatchFinalDamageBeforeOneShotProtection; public static Manipulator <8>__PatchFrozenExecuteCheck; public static Manipulator <9>__PatchCustomControlStateDuration; public static Manipulator <10>__PatchImmobilizeGiveupDuration; public static Action <11>__EnableExplicitControlEffectsForPvPPlayer; public static Action <12>__OnStartClient; public static NetworkUserGenericDelegate <13>__OnPostNetworkUserStart; public static Action <14>__OnRunStart; public static EventHandler <15>__OnControlDurationSettingChanged; public static Func <16>__ScaleImmobilizeGiveupDuration; public static Func <17>__ScaleCustomControlState; public static NetworkMessageDelegate <18>__ClientHandleControlDurationState; public static Func <19>__AllowFrozenExecute; public static Func <20>__ApplyFinalPvPDamageMultiplier; } private const short ControlDurationStateMessageType = 19737; private static bool installed; private static float clientControlDurationMultiplier = 1f; internal static void Install() { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Expected O, but got Unknown //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Expected O, but got Unknown //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Expected O, but got Unknown //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Expected O, but got Unknown //IL_009e: 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_00a9: Expected O, but got Unknown //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Expected O, but got Unknown //IL_00de: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Expected O, but got Unknown //IL_00fe: 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_0109: Expected O, but got Unknown //IL_011e: Unknown result type (might be due to invalid IL or missing references) //IL_0123: Unknown result type (might be due to invalid IL or missing references) //IL_0129: Expected O, but got Unknown //IL_013e: Unknown result type (might be due to invalid IL or missing references) //IL_0143: Unknown result type (might be due to invalid IL or missing references) //IL_0149: Expected O, but got Unknown //IL_015e: Unknown result type (might be due to invalid IL or missing references) //IL_0163: Unknown result type (might be due to invalid IL or missing references) //IL_0169: Expected O, but got Unknown //IL_017e: Unknown result type (might be due to invalid IL or missing references) //IL_0183: Unknown result type (might be due to invalid IL or missing references) //IL_0189: Expected O, but got Unknown //IL_01de: Unknown result type (might be due to invalid IL or missing references) //IL_01e3: Unknown result type (might be due to invalid IL or missing references) //IL_01e9: Expected O, but got Unknown if (!installed) { installed = true; object obj = <>O.<0>__HealthComponentTakeDamage; if (obj == null) { hook_TakeDamage val = HealthComponentTakeDamage; <>O.<0>__HealthComponentTakeDamage = val; obj = (object)val; } HealthComponent.TakeDamage += (hook_TakeDamage)obj; object obj2 = <>O.<1>__SetStateOnHurtSetImmobilize; if (obj2 == null) { hook_SetImmobilize val2 = SetStateOnHurtSetImmobilize; <>O.<1>__SetStateOnHurtSetImmobilize = val2; obj2 = (object)val2; } SetStateOnHurt.SetImmobilize += (hook_SetImmobilize)obj2; object obj3 = <>O.<2>__SetStateOnHurtSetStun; if (obj3 == null) { hook_SetStun val3 = SetStateOnHurtSetStun; <>O.<2>__SetStateOnHurtSetStun = val3; obj3 = (object)val3; } SetStateOnHurt.SetStun += (hook_SetStun)obj3; object obj4 = <>O.<3>__SetStateOnHurtOverrideStun; if (obj4 == null) { hook_OverrideStun val4 = SetStateOnHurtOverrideStun; <>O.<3>__SetStateOnHurtOverrideStun = val4; obj4 = (object)val4; } SetStateOnHurt.OverrideStun += (hook_OverrideStun)obj4; object obj5 = <>O.<4>__SetStateOnHurtSetFrozen; if (obj5 == null) { hook_SetFrozen val5 = SetStateOnHurtSetFrozen; <>O.<4>__SetStateOnHurtSetFrozen = val5; obj5 = (object)val5; } SetStateOnHurt.SetFrozen += (hook_SetFrozen)obj5; object obj6 = <>O.<5>__SetStateOnHurtSetShock; if (obj6 == null) { hook_SetShock val6 = SetStateOnHurtSetShock; <>O.<5>__SetStateOnHurtSetShock = val6; obj6 = (object)val6; } SetStateOnHurt.SetShock += (hook_SetShock)obj6; object obj7 = <>O.<6>__SetStateOnHurtSetCustomState; if (obj7 == null) { hook_SetCustomState val7 = SetStateOnHurtSetCustomState; <>O.<6>__SetStateOnHurtSetCustomState = val7; obj7 = (object)val7; } SetStateOnHurt.SetCustomState += (hook_SetCustomState)obj7; object obj8 = <>O.<7>__PatchFinalDamageBeforeOneShotProtection; if (obj8 == null) { Manipulator val8 = PatchFinalDamageBeforeOneShotProtection; <>O.<7>__PatchFinalDamageBeforeOneShotProtection = val8; obj8 = (object)val8; } HealthComponent.TakeDamageProcess += (Manipulator)obj8; object obj9 = <>O.<8>__PatchFrozenExecuteCheck; if (obj9 == null) { Manipulator val9 = PatchFrozenExecuteCheck; <>O.<8>__PatchFrozenExecuteCheck = val9; obj9 = (object)val9; } HealthComponent.TakeDamageProcess += (Manipulator)obj9; object obj10 = <>O.<8>__PatchFrozenExecuteCheck; if (obj10 == null) { Manipulator val10 = PatchFrozenExecuteCheck; <>O.<8>__PatchFrozenExecuteCheck = val10; obj10 = (object)val10; } HealthComponent.GetHealthBarValues += (Manipulator)obj10; object obj11 = <>O.<9>__PatchCustomControlStateDuration; if (obj11 == null) { Manipulator val11 = PatchCustomControlStateDuration; <>O.<9>__PatchCustomControlStateDuration = val11; obj11 = (object)val11; } SetStateOnHurt.SetCustomStateInternal += (Manipulator)obj11; object obj12 = <>O.<10>__PatchImmobilizeGiveupDuration; if (obj12 == null) { Manipulator val12 = PatchImmobilizeGiveupDuration; <>O.<10>__PatchImmobilizeGiveupDuration = val12; obj12 = (object)val12; } ImmobilizeState.FixedUpdate += (Manipulator)obj12; CharacterBody.onBodyStartGlobal += EnableExplicitControlEffectsForPvPPlayer; NetworkManagerSystem.onStartClientGlobal += OnStartClient; object obj13 = <>O.<13>__OnPostNetworkUserStart; if (obj13 == null) { NetworkUserGenericDelegate val13 = OnPostNetworkUserStart; <>O.<13>__OnPostNetworkUserStart = val13; obj13 = (object)val13; } NetworkUser.onPostNetworkUserStart += (NetworkUserGenericDelegate)obj13; Run.onRunStartGlobal += OnRunStart; PvPConfig.PlayerControlDurationMultiplier.SettingChanged += OnControlDurationSettingChanged; NetworkClient val14 = (Object.op_Implicit((Object)(object)NetworkManagerSystem.singleton) ? ((NetworkManager)NetworkManagerSystem.singleton).client : null); if (val14 != null) { OnStartClient(val14); } } } internal static void Uninstall() { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Expected O, but got Unknown //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Expected O, but got Unknown //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Expected O, but got Unknown //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Expected O, but got Unknown //IL_009e: 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_00a9: Expected O, but got Unknown //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Expected O, but got Unknown //IL_00de: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Expected O, but got Unknown //IL_00fe: 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_0109: Expected O, but got Unknown //IL_011e: Unknown result type (might be due to invalid IL or missing references) //IL_0123: Unknown result type (might be due to invalid IL or missing references) //IL_0129: Expected O, but got Unknown //IL_013e: Unknown result type (might be due to invalid IL or missing references) //IL_0143: Unknown result type (might be due to invalid IL or missing references) //IL_0149: Expected O, but got Unknown //IL_015e: Unknown result type (might be due to invalid IL or missing references) //IL_0163: Unknown result type (might be due to invalid IL or missing references) //IL_0169: Expected O, but got Unknown //IL_017e: Unknown result type (might be due to invalid IL or missing references) //IL_0183: Unknown result type (might be due to invalid IL or missing references) //IL_0189: Expected O, but got Unknown //IL_01de: Unknown result type (might be due to invalid IL or missing references) //IL_01e3: Unknown result type (might be due to invalid IL or missing references) //IL_01e9: Expected O, but got Unknown if (installed) { installed = false; object obj = <>O.<0>__HealthComponentTakeDamage; if (obj == null) { hook_TakeDamage val = HealthComponentTakeDamage; <>O.<0>__HealthComponentTakeDamage = val; obj = (object)val; } HealthComponent.TakeDamage -= (hook_TakeDamage)obj; object obj2 = <>O.<1>__SetStateOnHurtSetImmobilize; if (obj2 == null) { hook_SetImmobilize val2 = SetStateOnHurtSetImmobilize; <>O.<1>__SetStateOnHurtSetImmobilize = val2; obj2 = (object)val2; } SetStateOnHurt.SetImmobilize -= (hook_SetImmobilize)obj2; object obj3 = <>O.<2>__SetStateOnHurtSetStun; if (obj3 == null) { hook_SetStun val3 = SetStateOnHurtSetStun; <>O.<2>__SetStateOnHurtSetStun = val3; obj3 = (object)val3; } SetStateOnHurt.SetStun -= (hook_SetStun)obj3; object obj4 = <>O.<3>__SetStateOnHurtOverrideStun; if (obj4 == null) { hook_OverrideStun val4 = SetStateOnHurtOverrideStun; <>O.<3>__SetStateOnHurtOverrideStun = val4; obj4 = (object)val4; } SetStateOnHurt.OverrideStun -= (hook_OverrideStun)obj4; object obj5 = <>O.<4>__SetStateOnHurtSetFrozen; if (obj5 == null) { hook_SetFrozen val5 = SetStateOnHurtSetFrozen; <>O.<4>__SetStateOnHurtSetFrozen = val5; obj5 = (object)val5; } SetStateOnHurt.SetFrozen -= (hook_SetFrozen)obj5; object obj6 = <>O.<5>__SetStateOnHurtSetShock; if (obj6 == null) { hook_SetShock val6 = SetStateOnHurtSetShock; <>O.<5>__SetStateOnHurtSetShock = val6; obj6 = (object)val6; } SetStateOnHurt.SetShock -= (hook_SetShock)obj6; object obj7 = <>O.<6>__SetStateOnHurtSetCustomState; if (obj7 == null) { hook_SetCustomState val7 = SetStateOnHurtSetCustomState; <>O.<6>__SetStateOnHurtSetCustomState = val7; obj7 = (object)val7; } SetStateOnHurt.SetCustomState -= (hook_SetCustomState)obj7; object obj8 = <>O.<7>__PatchFinalDamageBeforeOneShotProtection; if (obj8 == null) { Manipulator val8 = PatchFinalDamageBeforeOneShotProtection; <>O.<7>__PatchFinalDamageBeforeOneShotProtection = val8; obj8 = (object)val8; } HealthComponent.TakeDamageProcess -= (Manipulator)obj8; object obj9 = <>O.<8>__PatchFrozenExecuteCheck; if (obj9 == null) { Manipulator val9 = PatchFrozenExecuteCheck; <>O.<8>__PatchFrozenExecuteCheck = val9; obj9 = (object)val9; } HealthComponent.TakeDamageProcess -= (Manipulator)obj9; object obj10 = <>O.<8>__PatchFrozenExecuteCheck; if (obj10 == null) { Manipulator val10 = PatchFrozenExecuteCheck; <>O.<8>__PatchFrozenExecuteCheck = val10; obj10 = (object)val10; } HealthComponent.GetHealthBarValues -= (Manipulator)obj10; object obj11 = <>O.<9>__PatchCustomControlStateDuration; if (obj11 == null) { Manipulator val11 = PatchCustomControlStateDuration; <>O.<9>__PatchCustomControlStateDuration = val11; obj11 = (object)val11; } SetStateOnHurt.SetCustomStateInternal -= (Manipulator)obj11; object obj12 = <>O.<10>__PatchImmobilizeGiveupDuration; if (obj12 == null) { Manipulator val12 = PatchImmobilizeGiveupDuration; <>O.<10>__PatchImmobilizeGiveupDuration = val12; obj12 = (object)val12; } ImmobilizeState.FixedUpdate -= (Manipulator)obj12; CharacterBody.onBodyStartGlobal -= EnableExplicitControlEffectsForPvPPlayer; NetworkManagerSystem.onStartClientGlobal -= OnStartClient; object obj13 = <>O.<13>__OnPostNetworkUserStart; if (obj13 == null) { NetworkUserGenericDelegate val13 = OnPostNetworkUserStart; <>O.<13>__OnPostNetworkUserStart = val13; obj13 = (object)val13; } NetworkUser.onPostNetworkUserStart -= (NetworkUserGenericDelegate)obj13; Run.onRunStartGlobal -= OnRunStart; PvPConfig.PlayerControlDurationMultiplier.SettingChanged -= OnControlDurationSettingChanged; clientControlDurationMultiplier = 1f; } } private static void EnableExplicitControlEffectsForPvPPlayer(CharacterBody body) { if (Plugin.IsPvPModeActive && NetworkServer.active && Object.op_Implicit((Object)(object)body) && Object.op_Implicit((Object)(object)body.master) && body.isPlayerControlled && PvPTeamManager.TryGetTeamId(body.master, out var _)) { SetStateOnHurt component = ((Component)body).GetComponent(); if (Object.op_Implicit((Object)(object)component)) { component.canBeHitStunned = false; component.canBeStunned = true; component.canBeFrozen = true; } } } private static void SetStateOnHurtSetImmobilize(orig_SetImmobilize orig, SetStateOnHurt self, GameObject attacker, GameObject inflictor) { if (!IsPvPPlayerControlTarget(self) || !(GetControlDurationMultiplier() <= 0f)) { orig.Invoke(self, attacker, inflictor); } } private static void SetStateOnHurtSetStun(orig_SetStun orig, SetStateOnHurt self, float duration) { if (!IsPvPPlayerControlTarget(self)) { orig.Invoke(self, duration); } else if (!(duration <= 0f)) { float num = duration * GetControlDurationMultiplier(); if (num > 0f) { orig.Invoke(self, num); } } } private static void SetStateOnHurtOverrideStun(orig_OverrideStun orig, SetStateOnHurt self, float duration) { if (IsPvPPlayerControlTarget(self) && duration > 0f) { duration *= GetControlDurationMultiplier(); } orig.Invoke(self, duration); } private static void SetStateOnHurtSetFrozen(orig_SetFrozen orig, SetStateOnHurt self, float duration) { if (!IsPvPPlayerControlTarget(self)) { orig.Invoke(self, duration); } else if (!(duration <= 0f)) { float num = duration * GetControlDurationMultiplier(); if (num > 0f) { orig.Invoke(self, num); } } } private static void SetStateOnHurtSetShock(orig_SetShock orig, SetStateOnHurt self, float duration) { if (!IsPvPPlayerControlTarget(self)) { orig.Invoke(self, duration); } else if (!(duration <= 0f)) { float num = duration * GetControlDurationMultiplier(); if (num > 0f) { orig.Invoke(self, num); } } } private static void SetStateOnHurtSetCustomState(orig_SetCustomState orig, SetStateOnHurt self, EntityStateIndex stateIndex, InterruptPriority interruptPriority) { //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) if (!IsPvPPlayerControlTarget(self) || stateIndex != EntityStateCatalog.GetStateIndex(typeof(ShockStateRed)) || !(GetControlDurationMultiplier() <= 0f)) { orig.Invoke(self, stateIndex, interruptPriority); } } private static bool IsPvPPlayerControlTarget(SetStateOnHurt setStateOnHurt) { if (!Plugin.IsPvPModeActive || !NetworkServer.active || !Object.op_Implicit((Object)(object)setStateOnHurt)) { return false; } return IsDirectPvPPlayer(((Component)setStateOnHurt).GetComponent()); } private static bool IsPvPPlayerControlTargetOnThisPeer(SetStateOnHurt setStateOnHurt) { if (!Plugin.IsPvPModeActive || !Object.op_Implicit((Object)(object)setStateOnHurt)) { return false; } return IsDirectPvPPlayer(((Component)setStateOnHurt).GetComponent()); } private static bool IsDirectPvPPlayer(CharacterBody body) { //IL_0023: Unknown result type (might be due to invalid IL or missing references) if (Object.op_Implicit((Object)(object)body) && body.isPlayerControlled && Object.op_Implicit((Object)(object)body.teamComponent)) { return PvPTeamRegistry.IsPvPTeam(body.teamComponent.teamIndex); } return false; } private static float GetControlDurationMultiplier() { float num = (NetworkServer.active ? PvPConfig.PlayerControlDurationMultiplier.Value : clientControlDurationMultiplier); if (!float.IsNaN(num) && !float.IsInfinity(num)) { return Mathf.Clamp(num, 0f, 5f); } return 1f; } private static void PatchImmobilizeGiveupDuration(ILContext il) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown //IL_0049: Unknown result type (might be due to invalid IL or missing references) ILCursor val = new ILCursor(il); if (!val.TryGotoNext((MoveType)2, new Func[1] { delegate(Instruction instruction) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Invalid comparison between Unknown and I4 OpCode opCode = instruction.OpCode; if ((int)((OpCode)(ref opCode)).Code == 123) { object operand = instruction.Operand; FieldReference val2 = (FieldReference)((operand is FieldReference) ? operand : null); if (val2 != null && ((MemberReference)((MemberReference)val2).DeclaringType).FullName == typeof(ImmobilizeState).FullName) { return ((MemberReference)val2).Name == "GiveupDuration"; } } return false; } })) { Plugin.Log.LogError((object)"Could not locate ImmobilizeState.GiveupDuration; PvP immobilize timeout scaling was not installed."); return; } val.Emit(OpCodes.Ldarg_0); val.EmitDelegate>((Func)ScaleImmobilizeGiveupDuration); } private static void PatchCustomControlStateDuration(ILContext il) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown //IL_0049: Unknown result type (might be due to invalid IL or missing references) ILCursor val = new ILCursor(il); if (!val.TryGotoNext((MoveType)2, new Func[1] { delegate(Instruction instruction) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Invalid comparison between Unknown and I4 //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Invalid comparison between Unknown and I4 OpCode opCode = instruction.OpCode; if ((int)((OpCode)(ref opCode)).Code != 39) { opCode = instruction.OpCode; if ((int)((OpCode)(ref opCode)).Code != 110) { goto IL_009f; } } object operand = instruction.Operand; MethodReference val2 = (MethodReference)((operand is MethodReference) ? operand : null); if (val2 != null && ((MemberReference)((MemberReference)val2).DeclaringType).FullName == typeof(EntityStateCatalog).FullName && ((MemberReference)val2).Name == "InstantiateState" && val2.Parameters.Count == 1) { return ((MemberReference)((ParameterReference)val2.Parameters[0]).ParameterType).FullName == typeof(EntityStateIndex).FullName; } goto IL_009f; IL_009f: return false; } })) { Plugin.Log.LogError((object)"Could not locate custom-state creation; PvP red-shock duration scaling was not installed."); return; } val.Emit(OpCodes.Ldarg_0); val.EmitDelegate>((Func)ScaleCustomControlState); } private static EntityState ScaleCustomControlState(EntityState state, SetStateOnHurt setStateOnHurt) { ShockStateRed val = (ShockStateRed)(object)((state is ShockStateRed) ? state : null); if (val != null && IsPvPPlayerControlTargetOnThisPeer(setStateOnHurt)) { ((ShockState)val).shockDuration = ((ShockState)val).shockDuration * GetControlDurationMultiplier(); } return state; } private static float ScaleImmobilizeGiveupDuration(float vanillaDuration, ImmobilizeState state) { if (!Plugin.IsPvPModeActive || state == null || !IsDirectPvPPlayer(((EntityState)state).GetComponent())) { return vanillaDuration; } return vanillaDuration * GetControlDurationMultiplier(); } private static void OnStartClient(NetworkClient client) { //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Expected O, but got Unknown clientControlDurationMultiplier = 1f; object obj = <>O.<18>__ClientHandleControlDurationState; if (obj == null) { NetworkMessageDelegate val = ClientHandleControlDurationState; <>O.<18>__ClientHandleControlDurationState = val; obj = (object)val; } client.RegisterHandler((short)19737, (NetworkMessageDelegate)obj); } private static void ClientHandleControlDurationState(NetworkMessage networkMessage) { clientControlDurationMultiplier = SanitizeControlDurationMultiplier(networkMessage.ReadMessage().Multiplier); } private static void OnPostNetworkUserStart(NetworkUser user) { if (NetworkServer.active && Object.op_Implicit((Object)(object)user) && ((NetworkBehaviour)user).connectionToClient != null) { SendControlDurationState(((NetworkBehaviour)user).connectionToClient); } } private static void OnRunStart(Run run) { if (NetworkServer.active) { BroadcastControlDurationState(); } } private static void OnControlDurationSettingChanged(object sender, EventArgs eventArgs) { if (NetworkServer.active) { BroadcastControlDurationState(); } } private static void BroadcastControlDurationState() { foreach (NetworkConnection connection in NetworkServer.connections) { if (connection != null) { SendControlDurationState(connection); } } } private static void SendControlDurationState(NetworkConnection connection) { connection.Send((short)19737, (MessageBase)(object)new ControlDurationStateMessage { Multiplier = SanitizeControlDurationMultiplier(PvPConfig.PlayerControlDurationMultiplier.Value) }); } private static float SanitizeControlDurationMultiplier(float multiplier) { if (!float.IsNaN(multiplier) && !float.IsInfinity(multiplier)) { return Mathf.Clamp(multiplier, 0f, 5f); } return 1f; } private static void PatchFrozenExecuteCheck(ILContext il) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown //IL_000c: Unknown result type (might be due to invalid IL or missing references) ILCursor val = new ILCursor(il); int num = 0; while (val.TryGotoNext((MoveType)2, new Func[1] { delegate(Instruction instruction) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Invalid comparison between Unknown and I4 //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Invalid comparison between Unknown and I4 OpCode opCode = instruction.OpCode; if ((int)((OpCode)(ref opCode)).Code != 39) { opCode = instruction.OpCode; if ((int)((OpCode)(ref opCode)).Code != 110) { goto IL_0065; } } object operand = instruction.Operand; MethodReference val2 = (MethodReference)((operand is MethodReference) ? operand : null); if (val2 != null && ((MemberReference)((MemberReference)val2).DeclaringType).FullName == typeof(HealthComponent).FullName) { return ((MemberReference)val2).Name == "get_isInFrozenState"; } goto IL_0065; IL_0065: return false; } })) { val.Emit(OpCodes.Ldarg_0); val.EmitDelegate>((Func)AllowFrozenExecute); num++; } if (num != 1) { Plugin.Log.LogError((object)$"Frozen-execute compatibility patch changed {num} locations in {((MemberReference)il.Method).FullName}; expected 1."); } } private static bool AllowFrozenExecute(bool isFrozen, HealthComponent healthComponent) { if (isFrozen) { if (Plugin.IsPvPModeActive && Object.op_Implicit((Object)(object)healthComponent)) { return !IsDirectPvPPlayer(healthComponent.body); } return true; } return false; } private static void HealthComponentTakeDamage(orig_TakeDamage orig, HealthComponent self, DamageInfo damageInfo) { //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0083: 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) PvPRelationService.Combatant combatant; PvPRelationService.Combatant combatant2; if (!Plugin.IsPvPModeActive || !NetworkServer.active || !Object.op_Implicit((Object)(object)self) || !Object.op_Implicit((Object)(object)self.body) || !Object.op_Implicit((Object)(object)damageInfo.attacker)) { orig.Invoke(self, damageInfo); } else if (!PvPRelationService.TryResolve(damageInfo.attacker, out combatant) || !PvPRelationService.TryResolve(((Component)self.body).gameObject, out combatant2) || !PvPTeamRegistry.IsPvPTeam(combatant.TeamIndex) || !PvPTeamRegistry.IsPvPTeam(combatant2.TeamIndex)) { orig.Invoke(self, damageInfo); } else if (combatant.TeamIndex == combatant2.TeamIndex && !PvPConfig.FriendlyFire.Value) { if (PvPConfig.VerboseDamage.Value) { Plugin.Log.LogInfo((object)("Rejected same-team PvP damage on " + ((Object)self.body).name + " from " + ((Object)damageInfo.attacker).name + ".")); } } else { orig.Invoke(self, damageInfo); } } private static void PatchFinalDamageBeforeOneShotProtection(ILContext il) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_013c: Unknown result type (might be due to invalid IL or missing references) //IL_0142: Expected O, but got Unknown //IL_0160: Unknown result type (might be due to invalid IL or missing references) //IL_0167: Expected O, but got Unknown //IL_0198: Unknown result type (might be due to invalid IL or missing references) //IL_01a6: Unknown result type (might be due to invalid IL or missing references) //IL_01b3: Unknown result type (might be due to invalid IL or missing references) //IL_01c1: Unknown result type (might be due to invalid IL or missing references) //IL_01ce: 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_020d: Unknown result type (might be due to invalid IL or missing references) FieldReference val = null; Instruction oneShotProtectionCall = null; Enumerator enumerator = il.Body.Instructions.GetEnumerator(); try { while (enumerator.MoveNext()) { Instruction current = enumerator.Current; if (val == null) { object operand = current.Operand; FieldReference val2 = (FieldReference)((operand is FieldReference) ? operand : null); if (val2 != null && ((MemberReference)val2).Name == "damageInfo" && ((MemberReference)val2.FieldType).FullName == typeof(DamageInfo).FullName) { val = val2; } } object operand2 = current.Operand; MethodReference val3 = (MethodReference)((operand2 is MethodReference) ? operand2 : null); if (val3 != null && ((MemberReference)((MemberReference)val3).DeclaringType).FullName == typeof(CharacterBody).FullName && ((MemberReference)val3).Name == "get_hasOneShotProtection") { oneShotProtectionCall = current; } } } finally { ((IDisposable)enumerator/*cast due to .constrained prefix*/).Dispose(); } if (val == null || oneShotProtectionCall == null) { Plugin.Log.LogError((object)"Failed to locate DamageInfo or the one-shot-protection gate in HealthComponent.TakeDamageProcess; the final PvP damage multiplier was not installed."); return; } VariableDefinition val4 = FindFinalDamageLocal(il, oneShotProtectionCall); if (val4 == null) { Plugin.Log.LogError((object)"Failed to locate the final damage local before one-shot protection in HealthComponent.TakeDamageProcess; the final PvP damage multiplier was not installed."); return; } VariableDefinition val5 = new VariableDefinition(((MemberReference)il.Method).Module.ImportReference(typeof(bool))); il.Body.Variables.Add(val5); il.Body.InitLocals = true; ILCursor val6 = new ILCursor(il); if (!val6.TryGotoNext((MoveType)2, new Func[1] { (Instruction instruction) => instruction == oneShotProtectionCall })) { Plugin.Log.LogError((object)"Failed to position the final PvP damage multiplier before one-shot protection."); return; } val6.Emit(OpCodes.Stloc, val5); val6.Emit(OpCodes.Ldloc_0); val6.Emit(OpCodes.Ldfld, val); val6.Emit(OpCodes.Ldarg_0); val6.Emit(OpCodes.Ldloc, val4); val6.EmitDelegate>((Func)ApplyFinalPvPDamageMultiplier); val6.Emit(OpCodes.Stloc, val4); val6.Emit(OpCodes.Ldloc, val5); Plugin.Log.LogDebug((object)$"Installed final PvP damage multiplier immediately before OSP using damage local V_{((VariableReference)val4).Index}."); } private static VariableDefinition? FindFinalDamageLocal(ILContext il, Instruction oneShotProtectionCall) { Instruction next = oneShotProtectionCall.Next; int num = 0; while (next != null && num < 48) { object operand = next.Operand; MethodReference val = (MethodReference)((operand is MethodReference) ? operand : null); if (val != null && !(((MemberReference)((MemberReference)val).DeclaringType).FullName != typeof(Mathf).FullName) && !(((MemberReference)val).Name != "Min")) { return GetStoredLocal(next.Next, il.Body); } num++; next = next.Next; } return null; } private static VariableDefinition? GetStoredLocal(Instruction? instruction, MethodBody body) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Expected I4, but got Unknown //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Invalid comparison between Unknown and I4 //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Invalid comparison between Unknown and I4 if (instruction == null) { return null; } OpCode opCode = instruction.OpCode; Code code = ((OpCode)(ref opCode)).Code; switch (code - 10) { default: if ((int)code == 19 || (int)code == 204) { object operand = instruction.Operand; return (VariableDefinition?)((operand is VariableDefinition) ? operand : null); } return null; case 0: return body.Variables[0]; case 1: return body.Variables[1]; case 2: return body.Variables[2]; case 3: return body.Variables[3]; } } private static float ApplyFinalPvPDamageMultiplier(DamageInfo damageInfo, HealthComponent victimHealth, float finalDamage) { //IL_0062: 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_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Unknown result type (might be due to invalid IL or missing references) if (!Plugin.IsPvPModeActive || !NetworkServer.active || finalDamage <= 0f || !Object.op_Implicit((Object)(object)victimHealth) || !Object.op_Implicit((Object)(object)victimHealth.body) || damageInfo == null || !Object.op_Implicit((Object)(object)damageInfo.attacker)) { return finalDamage; } if (!PvPRelationService.TryResolve(damageInfo.attacker, out var combatant) || !PvPRelationService.TryResolve(((Component)victimHealth.body).gameObject, out var combatant2) || !PvPTeamRegistry.IsPvPTeam(combatant.TeamIndex) || !PvPTeamRegistry.IsPvPTeam(combatant2.TeamIndex) || combatant.TeamIndex == combatant2.TeamIndex) { return finalDamage; } float num = SelectMultiplier(combatant, combatant2); float num2 = finalDamage * num; if (PvPConfig.VerboseDamage.Value) { Plugin.Log.LogInfo((object)($"Applied final PvP damage multiplier x{num:0.###} before OSP: " + $"{finalDamage:0.###} -> {num2:0.###}, {combatant.TeamIndex} -> {combatant2.TeamIndex}.")); } return num2; } private static float SelectMultiplier(PvPRelationService.Combatant attacker, PvPRelationService.Combatant victim) { bool isDirectPlayer = attacker.IsDirectPlayer; bool isDirectPlayer2 = victim.IsDirectPlayer; if (isDirectPlayer && isDirectPlayer2) { return PvPConfig.PlayerToPlayerDamage.Value; } if (!isDirectPlayer && isDirectPlayer2) { return PvPConfig.MinionToPlayerDamage.Value; } if (isDirectPlayer) { return PvPConfig.PlayerToMinionDamage.Value; } return PvPConfig.MinionToMinionDamage.Value; } } } namespace HurricaneDifficulty { public abstract class CalamityChallengeAchievement : BaseAchievement { protected abstract string AchievementIdentifier { get; } public override void OnInstall() { ((BaseAchievement)this).OnInstall(); Run.onClientGameOverGlobal += OnClientGameOverGlobal; } public override void OnUninstall() { Run.onClientGameOverGlobal -= OnClientGameOverGlobal; ((BaseAchievement)this).OnUninstall(); } private void OnClientGameOverGlobal(Run run, RunReport runReport) { if (CalamityChallengesLogbookModule.MeetsRequirements(AchievementIdentifier, run, runReport, ((BaseAchievement)this).localUser, out var _)) { ((BaseAchievement)this).Grant(); } } } [RegisterAchievement("CalamityLoaderDestinyDesolation", "", null, 0u, null)] public sealed class LoaderDestinyDesolationAchievement : CalamityChallengeAchievement { public const string Identifier = "CalamityLoaderDestinyDesolation"; protected override string AchievementIdentifier => "CalamityLoaderDestinyDesolation"; } [RegisterAchievement("CalamityHuntressAtrophy", "", null, 0u, null)] public sealed class HuntressAtrophyAchievement : CalamityChallengeAchievement { public const string Identifier = "CalamityHuntressAtrophy"; protected override string AchievementIdentifier => "CalamityHuntressAtrophy"; } [RegisterAchievement("CalamityCaptainUltimateStrike", "", null, 0u, null)] public sealed class CaptainUltimateStrikeAchievement : CalamityChallengeAchievement { public const string Identifier = "CalamityCaptainUltimateStrike"; protected override string AchievementIdentifier => "CalamityCaptainUltimateStrike"; } [RegisterAchievement("CalamityEngineerArmsRace", "", null, 0u, null)] public sealed class EngineerArmsRaceAchievement : CalamityChallengeAchievement { public const string Identifier = "CalamityEngineerArmsRace"; protected override string AchievementIdentifier => "CalamityEngineerArmsRace"; } [RegisterAchievement("CalamityRadiance", "", null, 0u, null)] public sealed class RadianceAchievement : CalamityChallengeAchievement { public const string Identifier = "CalamityRadiance"; protected override string AchievementIdentifier => "CalamityRadiance"; } internal static class ArtifactHooks { private static bool installed; internal static void Install(ManualLogSource logger) { if (!installed) { installed = true; DirectorArtifactHooks.Install(logger); EconomyPickupArtifactHooks.Install(logger); PlayerArtifactHooks.Install(logger); MonsterEventArtifactHooks.Install(logger); DamageArtifactHooks.Install(logger); TeleporterArtifactHooks.Install(logger); VoidArtifactHooks.Install(logger); } } internal static void Uninstall() { if (installed) { installed = false; VoidArtifactHooks.Uninstall(); TeleporterArtifactHooks.Uninstall(); DamageArtifactHooks.Uninstall(); MonsterEventArtifactHooks.Uninstall(); PlayerArtifactHooks.Uninstall(); EconomyPickupArtifactHooks.Uninstall(); DirectorArtifactHooks.Uninstall(); } } } internal static class ArtifactRegistry { private const string ResourcePrefix = "HurricaneDifficulty.Assets.Artifacts."; internal static ArtifactDef Apex { get; private set; } = null; internal static ArtifactDef Bounty { get; private set; } = null; internal static ArtifactDef Revival { get; private set; } = null; internal static ArtifactDef Destiny { get; private set; } = null; internal static ArtifactDef Atrophy { get; private set; } = null; internal static ArtifactDef Mirror { get; private set; } = null; internal static ArtifactDef Warp { get; private set; } = null; internal static ArtifactDef Infinite { get; private set; } = null; internal static ArtifactDef Radiance { get; private set; } = null; internal static ArtifactDef Desolation { get; private set; } = null; internal static ArtifactDef Mountainous { get; private set; } = null; internal static ArtifactDef Behemoth { get; private set; } = null; internal static ArtifactDef Void { get; private set; } = null; internal static ArtifactDef Flaw { get; private set; } = null; internal static BuffDef AtrophyHealthLossBuff { get; private set; } = null; internal static BuffDef AtrophyShieldLossBuff { get; private set; } = null; internal static BuffDef BehemothBossBuff { get; private set; } = null; internal static ArtifactDef[] All { get; private set; } = Array.Empty(); internal static void RegisterAll(Func loadSprite) { RegisterLanguageTokens(); AtrophyHealthLossBuff = RegisterHiddenStateBuff("EnhancedDifficulties_AtrophyHealthLoss"); AtrophyShieldLossBuff = RegisterHiddenStateBuff("EnhancedDifficulties_AtrophyShieldLoss"); BehemothBossBuff = RegisterHiddenStateBuff("CataclysmResonator_BehemothTeleporterBoss"); Apex = RegisterArtifact(loadSprite, "Apex", "apex"); Bounty = RegisterArtifact(loadSprite, "Bounty", "bounty"); Revival = RegisterArtifact(loadSprite, "Revival", "revival"); Destiny = RegisterArtifact(loadSprite, "Destiny", "destiny"); Atrophy = RegisterArtifact(loadSprite, "Atrophy", "atrophy"); Mirror = RegisterArtifact(loadSprite, "Mirror", "mirror"); Warp = RegisterArtifact(loadSprite, "Warp", "warp"); Infinite = RegisterArtifact(loadSprite, "Infinite", "infinite"); Radiance = RegisterArtifact(loadSprite, "Radiance", "radiance"); Desolation = RegisterArtifact(loadSprite, "Desolation", "desolation"); Mountainous = RegisterArtifact(loadSprite, "Mountainous", "mountainous"); Behemoth = RegisterArtifact(loadSprite, "Behemoth", "behemoth"); Void = RegisterArtifact(loadSprite, "Void", "void"); Flaw = RegisterArtifact(loadSprite, "Flaw", "flaw"); All = (ArtifactDef[])(object)new ArtifactDef[14] { Apex, Bounty, Revival, Destiny, Atrophy, Mirror, Warp, Infinite, Radiance, Desolation, Mountainous, Behemoth, Void, Flaw }; } internal static bool IsEnabled(ArtifactDef artifactDef) { RunArtifactManager instance = RunArtifactManager.instance; if (instance == null || !instance.IsArtifactEnabled(artifactDef)) { return false; } if (!ResonatorModules.ArtifactsActive) { if ((Object)(object)artifactDef == (Object)(object)Radiance) { return PantheonModule.IsRadianceActive; } return false; } return true; } private static ArtifactDef RegisterArtifact(Func loadSprite, string internalName, string resourceStem) { string text = "ENHANCEDDIFFICULTIES_ARTIFACT_" + internalName.ToUpperInvariant(); ArtifactDef obj = ScriptableObject.CreateInstance(); obj.cachedName = "EnhancedDifficultiesArtifact" + internalName; obj.nameToken = text + "_NAME"; obj.descriptionToken = text + "_DESCRIPTION"; obj.smallIconSelectedSprite = loadSprite("HurricaneDifficulty.Assets.Artifacts." + resourceStem + "_selected.png", "texArtifact" + internalName + "Selected"); obj.smallIconDeselectedSprite = loadSprite("HurricaneDifficulty.Assets.Artifacts." + resourceStem + "_deselected.png", "texArtifact" + internalName + "Deselected"); if (!ContentAddition.AddArtifactDef(obj)) { throw new InvalidOperationException("R2API rejected artifact definition " + internalName + "."); } return obj; } private static BuffDef RegisterHiddenStateBuff(string internalName) { //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) BuffDef obj = ScriptableObject.CreateInstance(); ((Object)obj).name = internalName; obj.canStack = true; obj.isHidden = true; obj.isDebuff = false; obj.isDOT = false; obj.ignoreGrowthNectar = true; obj.buffColor = Color32.op_Implicit(new Color32((byte)93, (byte)66, (byte)126, byte.MaxValue)); if (!ContentAddition.AddBuffDef(obj)) { throw new InvalidOperationException("R2API rejected hidden state buff " + internalName + "."); } return obj; } private static void RegisterLanguageTokens() { AddArtifactLanguage("APEX", "Artifact of Apex", "High-tier monsters appear earlier.", "顶点神器", "高阶怪物会更早出现。"); AddArtifactLanguage("BOUNTY", "Artifact of Bounty", "All gold interactions are free.", "得宝神器", "所有金币交互免费。"); AddArtifactLanguage("REVIVAL", "Artifact of Revival", "Each player can revive once per stage.", "复苏神器", "每名玩家每层可复活一次。"); AddArtifactLanguage("DESTINY", "Artifact of Destiny", "Players remain at level 1.", "命运神器", "玩家等级固定为 1。"); AddArtifactLanguage("ATROPHY", "Artifact of Atrophy", "Damage also reduces maximum health or shields.", "凋亡神器", "受到伤害时,生命值或护盾上限也会降低。"); AddArtifactLanguage("MIRROR", "Artifact of Mirrors", "New monsters inherit the players' items.", "镜像神器", "新生成的怪物会继承玩家的道具。"); AddArtifactLanguage("WARP", "Artifact of Warp", "Defeating the teleporter bosses fully charges the teleporter.", "折跃神器", "击败传送器首领后,传送器立即充满。"); AddArtifactLanguage("INFINITE", "Artifact of Infinity", "Greatly raises the monster and ambient level cap.", "无极神器", "大幅提高怪物与环境等级上限。"); AddArtifactLanguage("RADIANCE", "Artifact of Radiance", "Enemy attacks are instantly fatal.", "辐辉神器", "敌人的攻击会一击致命。"); AddArtifactLanguage("DESOLATION", "Artifact of Desolation", "Ordinary items cannot be picked up.", "荒芜神器", "不能拾取常规物品。"); AddArtifactLanguage("MOUNTAINOUS", "Artifact of Mountain Ranges", "Teleporters gain additional Challenges of the Mountain.", "群峦神器", "传送器会获得额外的山之挑战。"); AddArtifactLanguage("BEHEMOTH", "Artifact of Behemoths", "Teleporter bosses have 10 times their health.", "巨兽神器", "传送器首领拥有十倍生命值。"); AddArtifactLanguage("VOID", "Artifact of the Void", "All infectable enemies are Voidtouched, and every stage contains a Void Seed.", "虚空神器", "所有可侵染的敌怪均被虚空侵染,地图必定出现虚空种子。"); AddArtifactLanguage("FLAW", "Artifact of Deficiency", "Equipment cannot be picked up.", "缺憾神器", "不能拾取装备。"); } private static void AddArtifactLanguage(string key, string englishName, string englishDescription, string chineseName, string chineseDescription) { string text = "ENHANCEDDIFFICULTIES_ARTIFACT_" + key; LanguageAPI.Add(text + "_NAME", englishName); LanguageAPI.Add(text + "_DESCRIPTION", englishDescription); LanguageAPI.Add(text + "_NAME", chineseName, "zh-CN"); LanguageAPI.Add(text + "_DESCRIPTION", chineseDescription, "zh-CN"); } } internal static class DamageArtifactHooks { private sealed class DamageScope { internal readonly HealthComponent Victim; internal readonly bool RadianceHit; internal bool RevivedDuringDamage; internal bool SawLethalHealthAssignment; internal float HealthLoss; internal float ShieldLoss; internal DamageScope(HealthComponent victim, DamageInfo damageInfo) { Victim = victim; RadianceHit = IsRadianceHit(victim, damageInfo); } } [CompilerGenerated] private static class <>O { public static Manipulator <0>__HealthComponent_TakeDamageProcess_IL; public static hook_TakeDamageProcess <1>__HealthComponent_TakeDamageProcess; public static Action <2>__CaptureHealthAssignment; public static Action <3>__CaptureShieldAssignment; public static Func <4>__AllowOneShotProtectionForAtrophy; } [ThreadStatic] private static Stack? damageScopes; private static ManualLogSource log; private static bool damageCapturePatchSucceeded; private static bool atrophyOneShotProtectionPatchSucceeded; internal static void Install(ManualLogSource logger) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Expected O, but got Unknown //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_0041: Expected O, but got Unknown log = logger; object obj = <>O.<0>__HealthComponent_TakeDamageProcess_IL; if (obj == null) { Manipulator val = HealthComponent_TakeDamageProcess_IL; <>O.<0>__HealthComponent_TakeDamageProcess_IL = val; obj = (object)val; } HealthComponent.TakeDamageProcess += (Manipulator)obj; object obj2 = <>O.<1>__HealthComponent_TakeDamageProcess; if (obj2 == null) { hook_TakeDamageProcess val2 = HealthComponent_TakeDamageProcess; <>O.<1>__HealthComponent_TakeDamageProcess = val2; obj2 = (object)val2; } HealthComponent.TakeDamageProcess += (hook_TakeDamageProcess)obj2; } internal static void Uninstall() { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Expected O, but got Unknown //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Expected O, but got Unknown object obj = <>O.<0>__HealthComponent_TakeDamageProcess_IL; if (obj == null) { Manipulator val = HealthComponent_TakeDamageProcess_IL; <>O.<0>__HealthComponent_TakeDamageProcess_IL = val; obj = (object)val; } HealthComponent.TakeDamageProcess -= (Manipulator)obj; object obj2 = <>O.<1>__HealthComponent_TakeDamageProcess; if (obj2 == null) { hook_TakeDamageProcess val2 = HealthComponent_TakeDamageProcess; <>O.<1>__HealthComponent_TakeDamageProcess = val2; obj2 = (object)val2; } HealthComponent.TakeDamageProcess -= (hook_TakeDamageProcess)obj2; damageScopes?.Clear(); } private static void HealthComponent_TakeDamageProcess_IL(ILContext il) { atrophyOneShotProtectionPatchSucceeded = InjectAtrophyOneShotProtectionGate(il) == 1; int num = InjectAssignmentCapture(il, "set_Networkhealth", CaptureHealthAssignment); int num2 = InjectAssignmentCapture(il, "set_Networkshield", CaptureShieldAssignment); damageCapturePatchSucceeded = num == 4 && num2 == 3; if (!atrophyOneShotProtectionPatchSucceeded) { log.LogError((object)"Atrophy: failed to locate the one-shot-protection gate. Exact lethal damage may still be clamped by vanilla OSP."); } if (!damageCapturePatchSucceeded) { log.LogError((object)$"Atrophy: failed to patch final health/shield assignments (health={num}, shield={num2}). Atrophy damage replacement is disabled to avoid incorrect post-mitigation values."); } else { log.LogDebug((object)$"Atrophy patched {num} health and {num2} shield assignments."); } } private static int InjectAtrophyOneShotProtectionGate(ILContext il) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Expected O, but got Unknown //IL_00b1: 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) List calls = new List(); Enumerator enumerator = il.Body.Instructions.GetEnumerator(); try { while (enumerator.MoveNext()) { Instruction current = enumerator.Current; if (ILPatternMatchingExt.MatchCallOrCallvirt(current, "get_hasOneShotProtection")) { calls.Add(current); } } } finally { ((IDisposable)enumerator/*cast due to .constrained prefix*/).Dispose(); } if (calls.Count != 1) { return 0; } VariableDefinition val = FindFinalDamageLocal(il, calls[0]); if (val == null) { return 0; } ILCursor val2 = new ILCursor(il); if (!val2.TryGotoNext((MoveType)2, new Func[1] { (Instruction instruction) => instruction == calls[0] })) { return 0; } val2.Emit(OpCodes.Ldarg_0); val2.Emit(OpCodes.Ldloc, val); val2.EmitDelegate>((Func)AllowOneShotProtectionForAtrophy); return 1; } private static bool AllowOneShotProtectionForAtrophy(bool hasOneShotProtection, HealthComponent healthComponent, float finalDamage) { if (!hasOneShotProtection || !PlayerArtifactHooks.AtrophyStatsPatchSucceeded || !ArtifactRegistry.IsEnabled(ArtifactRegistry.Atrophy) || !PlayerArtifactHooks.IsAtrophyEligiblePlayer(healthComponent) || finalDamage <= Mathf.Max(0f, healthComponent.barrier)) { return hasOneShotProtection; } return false; } private static VariableDefinition? FindFinalDamageLocal(ILContext il, Instruction oneShotProtectionCall) { Instruction next = oneShotProtectionCall.Next; int num = 0; while (next != null && num < 48) { if (ILPatternMatchingExt.MatchCall(next, typeof(Mathf), "Min")) { return GetStoredLocal(next.Next, il.Body); } num++; next = next.Next; } return null; } private static VariableDefinition? GetStoredLocal(Instruction? instruction, MethodBody body) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Expected I4, but got Unknown //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Invalid comparison between Unknown and I4 //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Invalid comparison between Unknown and I4 if (instruction == null) { return null; } OpCode opCode = instruction.OpCode; Code code = ((OpCode)(ref opCode)).Code; switch (code - 10) { default: if ((int)code == 19 || (int)code == 204) { object operand = instruction.Operand; return (VariableDefinition?)((operand is VariableDefinition) ? operand : null); } return null; case 0: return body.Variables[0]; case 1: return body.Variables[1]; case 2: return body.Variables[2]; case 3: return body.Variables[3]; } } private static int InjectAssignmentCapture(ILContext il, string setterName, Action capture) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Expected O, but got Unknown //IL_0019: Unknown result type (might be due to invalid IL or missing references) ILCursor val = new ILCursor(il); int num = 0; while (val.TryGotoNext((MoveType)0, new Func[1] { (Instruction instruction) => ILPatternMatchingExt.MatchCallOrCallvirt(instruction, setterName) })) { val.Emit(OpCodes.Dup); val.EmitDelegate>(capture); num++; int index = val.Index; val.Index = index + 1; } return num; } private static void HealthComponent_TakeDamageProcess(orig_TakeDamageProcess orig, HealthComponent self, DamageInfo damageInfo) { //IL_0085: Unknown result type (might be due to invalid IL or missing references) if (!NetworkServer.active) { orig.Invoke(self, damageInfo); return; } DamageScope damageScope = new DamageScope(self, damageInfo); Stack stack = damageScopes ?? (damageScopes = new Stack()); stack.Push(damageScope); try { orig.Invoke(self, damageInfo); } finally { stack.Pop(); } if (damageScope.SawLethalHealthAssignment && self.alive) { damageScope.RevivedDuringDamage = true; NotifyRevival(self); } if (damageScope.RadianceHit) { if (self.alive) { self.Suicide(damageInfo.attacker, damageInfo.inflictor, DamageTypeCombo.op_Implicit((DamageType)262208)); } } else if (damageScope.RevivedDuringDamage && self.alive) { PlayerArtifactHooks.ResetAtrophyAfterInlineRevival(self); } else if (damageCapturePatchSucceeded && self.alive) { PlayerArtifactHooks.RecordAtrophyDamage(self, damageScope.HealthLoss, damageScope.ShieldLoss, damageInfo); } } internal static void NotifyRevival(HealthComponent healthComponent) { Stack stack = damageScopes; if (stack == null) { return; } foreach (DamageScope item in stack) { if ((Object)(object)item.Victim == (Object)(object)healthComponent) { item.RevivedDuringDamage = true; } } } private static void CaptureHealthAssignment(float newHealth) { DamageScope currentScope = GetCurrentScope(); if (currentScope != null && currentScope.Victim != null) { float num = Mathf.Max(0f, currentScope.Victim.health); float num2 = Mathf.Max(0f, newHealth); if (num > 0f && num2 <= 0f) { currentScope.SawLethalHealthAssignment = true; } else if (currentScope.SawLethalHealthAssignment && num <= 0f && num2 > 0f) { currentScope.RevivedDuringDamage = true; } currentScope.HealthLoss += Mathf.Clamp(num - num2, 0f, num); } } private static void CaptureShieldAssignment(float newShield) { DamageScope currentScope = GetCurrentScope(); if (currentScope != null && currentScope.Victim != null) { float num = Mathf.Max(0f, currentScope.Victim.shield); float num2 = Mathf.Max(0f, newShield); currentScope.ShieldLoss += Mathf.Clamp(num - num2, 0f, num); } } private static DamageScope? GetCurrentScope() { Stack stack = damageScopes; if (stack == null || stack.Count <= 0) { return null; } return stack.Peek(); } private static bool IsRadianceHit(HealthComponent victim, DamageInfo damageInfo) { //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) if (!ArtifactRegistry.IsEnabled(ArtifactRegistry.Radiance) || victim == null || !victim.alive || victim.body == null || !victim.body.isPlayerControlled || damageInfo == null) { return false; } GameObject val = (Object.op_Implicit((Object)(object)damageInfo.attacker) ? damageInfo.attacker : damageInfo.inflictor); if (!Object.op_Implicit((Object)(object)val) || (Object)(object)val == (Object)(object)((Component)victim).gameObject) { return false; } if (victim.body.master != null && victim.body.master.GetInRemoteOp()) { return false; } TeamIndex objectTeam = TeamComponent.GetObjectTeam(val); return FriendlyFireManager.ShouldDirectHitProceed(victim, objectTeam); } } internal static class DirectorArtifactHooks { [CompilerGenerated] private static class <>O { public static hook_RebuildCards <0>__ClassicStageInfo_RebuildCards; public static hook_IsAvailable <1>__DirectorCard_IsAvailable; public static Action <2>__Run_onRunDestroyGlobal; } [ThreadStatic] private static int apexRebuildDepth; private static readonly HashSet ApexStageCards = new HashSet(); private static ManualLogSource log = null; internal static void Install(ManualLogSource logger) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Expected O, but got Unknown //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_0041: Expected O, but got Unknown log = logger; object obj = <>O.<0>__ClassicStageInfo_RebuildCards; if (obj == null) { hook_RebuildCards val = ClassicStageInfo_RebuildCards; <>O.<0>__ClassicStageInfo_RebuildCards = val; obj = (object)val; } ClassicStageInfo.RebuildCards += (hook_RebuildCards)obj; object obj2 = <>O.<1>__DirectorCard_IsAvailable; if (obj2 == null) { hook_IsAvailable val2 = DirectorCard_IsAvailable; <>O.<1>__DirectorCard_IsAvailable = val2; obj2 = (object)val2; } DirectorCard.IsAvailable += (hook_IsAvailable)obj2; Run.onRunDestroyGlobal += Run_onRunDestroyGlobal; } internal static void Uninstall() { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Expected O, but got Unknown //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Expected O, but got Unknown object obj = <>O.<0>__ClassicStageInfo_RebuildCards; if (obj == null) { hook_RebuildCards val = ClassicStageInfo_RebuildCards; <>O.<0>__ClassicStageInfo_RebuildCards = val; obj = (object)val; } ClassicStageInfo.RebuildCards -= (hook_RebuildCards)obj; object obj2 = <>O.<1>__DirectorCard_IsAvailable; if (obj2 == null) { hook_IsAvailable val2 = DirectorCard_IsAvailable; <>O.<1>__DirectorCard_IsAvailable = val2; obj2 = (object)val2; } DirectorCard.IsAvailable -= (hook_IsAvailable)obj2; Run.onRunDestroyGlobal -= Run_onRunDestroyGlobal; ApexStageCards.Clear(); apexRebuildDepth = 0; } private static void ClassicStageInfo_RebuildCards(orig_RebuildCards orig, ClassicStageInfo self, DirectorCardCategorySelection forcedMonsterCategory, DirectorCardCategorySelection forcedInteractableCategory) { //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) bool num = forcedMonsterCategory == null; bool flag = num && ArtifactRegistry.IsEnabled(ArtifactRegistry.Apex); if (num) { ApexStageCards.Clear(); } if (flag) { apexRebuildDepth++; } try { orig.Invoke(self, forcedMonsterCategory, forcedInteractableCategory); } finally { if (flag) { apexRebuildDepth--; } } if (!flag || self.monsterSelection == null) { return; } ChoiceInfo[] choices = self.monsterSelection.choices; for (int i = 0; i < choices.Length; i++) { ChoiceInfo val = choices[i]; if (val.value != null) { ApexStageCards.Add(val.value); } } log.LogDebug((object)$"Apex retained {ApexStageCards.Count} cards for the current stage."); } private static bool DirectorCard_IsAvailable(orig_IsAvailable orig, DirectorCard self) { Run instance = Run.instance; if (instance == null || !ArtifactRegistry.IsEnabled(ArtifactRegistry.Apex) || (apexRebuildDepth <= 0 && !ApexStageCards.Contains(self)) || self.minimumStageCompletions <= instance.stageClearCount || !(self.GetSpawnCard() is CharacterSpawnCard)) { return orig.Invoke(self); } int minimumStageCompletions = self.minimumStageCompletions; self.minimumStageCompletions = 0; try { return orig.Invoke(self); } finally { self.minimumStageCompletions = minimumStageCompletions; } } private static void Run_onRunDestroyGlobal(Run run) { ApexStageCards.Clear(); apexRebuildDepth = 0; } } internal static class EconomyPickupArtifactHooks { [CompilerGenerated] private static class <>O { public static hook_IsAffordable <0>__CostTypeDef_IsAffordable; public static hook_PayCost <1>__CostTypeDef_PayCost; public static hook_CanBeAffordedByInteractor <2>__PurchaseInteraction_CanBeAffordedByInteractor; public static hook_GetContextString <3>__PurchaseInteraction_GetContextString; public static hook_UpdateHologramContent <4>__PurchaseInteraction_UpdateHologramContent; public static Manipulator <5>__PurchaseInteraction_OnInteractionBegin_IL; public static hook_GetDroneCost <6>__RemoteOperationDronePickerPanel_GetDroneCost; public static hook_SpawnRemoteOperationDrone <7>__CharacterMaster_SpawnRemoteOperationDrone; public static Manipulator <8>__GoldSiphonNearbyBodyController_DrainGold_IL; public static hook_BodyHasPickupPermission <9>__GenericPickupController_BodyHasPickupPermission; public static hook_AttemptGrant <10>__GenericPickupController_AttemptGrant; public static Func <11>__GetFreeUnlockCountForPurchase; public static Func <12>__GetHalcyoniteShrineVisibleMoney; public static Action <13>__PayHalcyoniteShrineMoney; } private static ManualLogSource log; private static bool goldSiphonPatchSucceeded; private static bool freeUnlockPatchSucceeded; internal static void Install(ManualLogSource logger) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Expected O, but got Unknown //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_0041: Expected O, but got Unknown //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Expected O, but got Unknown //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Expected O, but got Unknown //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Expected O, but got Unknown //IL_00b6: 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_00c1: Expected O, but got Unknown //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Expected O, but got Unknown //IL_00f6: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Expected O, but got Unknown //IL_0116: 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_0121: Expected O, but got Unknown //IL_0136: Unknown result type (might be due to invalid IL or missing references) //IL_013b: Unknown result type (might be due to invalid IL or missing references) //IL_0141: Expected O, but got Unknown //IL_0156: Unknown result type (might be due to invalid IL or missing references) //IL_015b: Unknown result type (might be due to invalid IL or missing references) //IL_0161: Expected O, but got Unknown log = logger; object obj = <>O.<0>__CostTypeDef_IsAffordable; if (obj == null) { hook_IsAffordable val = CostTypeDef_IsAffordable; <>O.<0>__CostTypeDef_IsAffordable = val; obj = (object)val; } CostTypeDef.IsAffordable += (hook_IsAffordable)obj; object obj2 = <>O.<1>__CostTypeDef_PayCost; if (obj2 == null) { hook_PayCost val2 = CostTypeDef_PayCost; <>O.<1>__CostTypeDef_PayCost = val2; obj2 = (object)val2; } CostTypeDef.PayCost += (hook_PayCost)obj2; object obj3 = <>O.<2>__PurchaseInteraction_CanBeAffordedByInteractor; if (obj3 == null) { hook_CanBeAffordedByInteractor val3 = PurchaseInteraction_CanBeAffordedByInteractor; <>O.<2>__PurchaseInteraction_CanBeAffordedByInteractor = val3; obj3 = (object)val3; } PurchaseInteraction.CanBeAffordedByInteractor += (hook_CanBeAffordedByInteractor)obj3; object obj4 = <>O.<3>__PurchaseInteraction_GetContextString; if (obj4 == null) { hook_GetContextString val4 = PurchaseInteraction_GetContextString; <>O.<3>__PurchaseInteraction_GetContextString = val4; obj4 = (object)val4; } PurchaseInteraction.GetContextString += (hook_GetContextString)obj4; object obj5 = <>O.<4>__PurchaseInteraction_UpdateHologramContent; if (obj5 == null) { hook_UpdateHologramContent val5 = PurchaseInteraction_UpdateHologramContent; <>O.<4>__PurchaseInteraction_UpdateHologramContent = val5; obj5 = (object)val5; } PurchaseInteraction.UpdateHologramContent += (hook_UpdateHologramContent)obj5; object obj6 = <>O.<5>__PurchaseInteraction_OnInteractionBegin_IL; if (obj6 == null) { Manipulator val6 = PurchaseInteraction_OnInteractionBegin_IL; <>O.<5>__PurchaseInteraction_OnInteractionBegin_IL = val6; obj6 = (object)val6; } PurchaseInteraction.OnInteractionBegin += (Manipulator)obj6; object obj7 = <>O.<6>__RemoteOperationDronePickerPanel_GetDroneCost; if (obj7 == null) { hook_GetDroneCost val7 = RemoteOperationDronePickerPanel_GetDroneCost; <>O.<6>__RemoteOperationDronePickerPanel_GetDroneCost = val7; obj7 = (object)val7; } RemoteOperationDronePickerPanel.GetDroneCost += (hook_GetDroneCost)obj7; object obj8 = <>O.<7>__CharacterMaster_SpawnRemoteOperationDrone; if (obj8 == null) { hook_SpawnRemoteOperationDrone val8 = CharacterMaster_SpawnRemoteOperationDrone; <>O.<7>__CharacterMaster_SpawnRemoteOperationDrone = val8; obj8 = (object)val8; } CharacterMaster.SpawnRemoteOperationDrone += (hook_SpawnRemoteOperationDrone)obj8; object obj9 = <>O.<8>__GoldSiphonNearbyBodyController_DrainGold_IL; if (obj9 == null) { Manipulator val9 = GoldSiphonNearbyBodyController_DrainGold_IL; <>O.<8>__GoldSiphonNearbyBodyController_DrainGold_IL = val9; obj9 = (object)val9; } GoldSiphonNearbyBodyController.DrainGold += (Manipulator)obj9; object obj10 = <>O.<9>__GenericPickupController_BodyHasPickupPermission; if (obj10 == null) { hook_BodyHasPickupPermission val10 = GenericPickupController_BodyHasPickupPermission; <>O.<9>__GenericPickupController_BodyHasPickupPermission = val10; obj10 = (object)val10; } GenericPickupController.BodyHasPickupPermission += (hook_BodyHasPickupPermission)obj10; object obj11 = <>O.<10>__GenericPickupController_AttemptGrant; if (obj11 == null) { hook_AttemptGrant val11 = GenericPickupController_AttemptGrant; <>O.<10>__GenericPickupController_AttemptGrant = val11; obj11 = (object)val11; } GenericPickupController.AttemptGrant += (hook_AttemptGrant)obj11; } internal static void Uninstall() { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Expected O, but got Unknown //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Expected O, but got Unknown //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Expected O, but got Unknown //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Expected O, but got Unknown //IL_0090: 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_009b: Expected O, but got Unknown //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Expected O, but got Unknown //IL_00d0: 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_00db: Expected O, but got Unknown //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Expected O, but got Unknown //IL_0110: Unknown result type (might be due to invalid IL or missing references) //IL_0115: Unknown result type (might be due to invalid IL or missing references) //IL_011b: Expected O, but got Unknown //IL_0130: Unknown result type (might be due to invalid IL or missing references) //IL_0135: Unknown result type (might be due to invalid IL or missing references) //IL_013b: Expected O, but got Unknown //IL_0150: Unknown result type (might be due to invalid IL or missing references) //IL_0155: Unknown result type (might be due to invalid IL or missing references) //IL_015b: Expected O, but got Unknown object obj = <>O.<0>__CostTypeDef_IsAffordable; if (obj == null) { hook_IsAffordable val = CostTypeDef_IsAffordable; <>O.<0>__CostTypeDef_IsAffordable = val; obj = (object)val; } CostTypeDef.IsAffordable -= (hook_IsAffordable)obj; object obj2 = <>O.<1>__CostTypeDef_PayCost; if (obj2 == null) { hook_PayCost val2 = CostTypeDef_PayCost; <>O.<1>__CostTypeDef_PayCost = val2; obj2 = (object)val2; } CostTypeDef.PayCost -= (hook_PayCost)obj2; object obj3 = <>O.<2>__PurchaseInteraction_CanBeAffordedByInteractor; if (obj3 == null) { hook_CanBeAffordedByInteractor val3 = PurchaseInteraction_CanBeAffordedByInteractor; <>O.<2>__PurchaseInteraction_CanBeAffordedByInteractor = val3; obj3 = (object)val3; } PurchaseInteraction.CanBeAffordedByInteractor -= (hook_CanBeAffordedByInteractor)obj3; object obj4 = <>O.<3>__PurchaseInteraction_GetContextString; if (obj4 == null) { hook_GetContextString val4 = PurchaseInteraction_GetContextString; <>O.<3>__PurchaseInteraction_GetContextString = val4; obj4 = (object)val4; } PurchaseInteraction.GetContextString -= (hook_GetContextString)obj4; object obj5 = <>O.<4>__PurchaseInteraction_UpdateHologramContent; if (obj5 == null) { hook_UpdateHologramContent val5 = PurchaseInteraction_UpdateHologramContent; <>O.<4>__PurchaseInteraction_UpdateHologramContent = val5; obj5 = (object)val5; } PurchaseInteraction.UpdateHologramContent -= (hook_UpdateHologramContent)obj5; object obj6 = <>O.<5>__PurchaseInteraction_OnInteractionBegin_IL; if (obj6 == null) { Manipulator val6 = PurchaseInteraction_OnInteractionBegin_IL; <>O.<5>__PurchaseInteraction_OnInteractionBegin_IL = val6; obj6 = (object)val6; } PurchaseInteraction.OnInteractionBegin -= (Manipulator)obj6; object obj7 = <>O.<6>__RemoteOperationDronePickerPanel_GetDroneCost; if (obj7 == null) { hook_GetDroneCost val7 = RemoteOperationDronePickerPanel_GetDroneCost; <>O.<6>__RemoteOperationDronePickerPanel_GetDroneCost = val7; obj7 = (object)val7; } RemoteOperationDronePickerPanel.GetDroneCost -= (hook_GetDroneCost)obj7; object obj8 = <>O.<7>__CharacterMaster_SpawnRemoteOperationDrone; if (obj8 == null) { hook_SpawnRemoteOperationDrone val8 = CharacterMaster_SpawnRemoteOperationDrone; <>O.<7>__CharacterMaster_SpawnRemoteOperationDrone = val8; obj8 = (object)val8; } CharacterMaster.SpawnRemoteOperationDrone -= (hook_SpawnRemoteOperationDrone)obj8; object obj9 = <>O.<8>__GoldSiphonNearbyBodyController_DrainGold_IL; if (obj9 == null) { Manipulator val9 = GoldSiphonNearbyBodyController_DrainGold_IL; <>O.<8>__GoldSiphonNearbyBodyController_DrainGold_IL = val9; obj9 = (object)val9; } GoldSiphonNearbyBodyController.DrainGold -= (Manipulator)obj9; object obj10 = <>O.<9>__GenericPickupController_BodyHasPickupPermission; if (obj10 == null) { hook_BodyHasPickupPermission val10 = GenericPickupController_BodyHasPickupPermission; <>O.<9>__GenericPickupController_BodyHasPickupPermission = val10; obj10 = (object)val10; } GenericPickupController.BodyHasPickupPermission -= (hook_BodyHasPickupPermission)obj10; object obj11 = <>O.<10>__GenericPickupController_AttemptGrant; if (obj11 == null) { hook_AttemptGrant val11 = GenericPickupController_AttemptGrant; <>O.<10>__GenericPickupController_AttemptGrant = val11; obj11 = (object)val11; } GenericPickupController.AttemptGrant -= (hook_AttemptGrant)obj11; } private static bool CostTypeDef_IsAffordable(orig_IsAffordable orig, CostTypeDef self, int cost, Interactor activator) { if (IsMoneyCost(self) && IsPlayerInteractor(activator)) { return true; } return orig.Invoke(self, cost, activator); } private static void CostTypeDef_PayCost(orig_PayCost orig, CostTypeDef self, PayCostContext context, PayCostResults result) { if (!IsMoneyCost(self) || !IsPlayerMaster(context.activatorMaster)) { orig.Invoke(self, context, result); return; } int cost = context.cost; context.cost = 0; try { orig.Invoke(self, context, result); } finally { context.cost = cost; } } private static bool PurchaseInteraction_CanBeAffordedByInteractor(orig_CanBeAffordedByInteractor orig, PurchaseInteraction self, Interactor activator) { if (IsFreePlayerMoneyPurchase(self, activator)) { return true; } return orig.Invoke(self, activator); } private static void PurchaseInteraction_OnInteractionBegin_IL(ILContext il) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown //IL_000c: Unknown result type (might be due to invalid IL or missing references) ILCursor val = new ILCursor(il); int num = 0; while (val.TryGotoNext((MoveType)2, new Func[1] { (Instruction instruction) => ILPatternMatchingExt.MatchCallOrCallvirt(instruction, "GetBuffCount") })) { val.Emit(OpCodes.Ldarg_0); val.EmitDelegate>((Func)GetFreeUnlockCountForPurchase); num++; int index = val.Index; val.Index = index + 1; } freeUnlockPatchSucceeded = num == 1; if (!freeUnlockPatchSucceeded) { log.LogError((object)$"Bounty: failed to isolate PurchaseInteraction's Free Unlock check (matches={num}). The purchase remains free, but a Free Unlock buff may be consumed."); } } private static int GetFreeUnlockCountForPurchase(int actualCount, PurchaseInteraction purchase) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Invalid comparison between Unknown and I4 if (!freeUnlockPatchSucceeded || !ArtifactRegistry.IsEnabled(ArtifactRegistry.Bounty) || (int)purchase.costType != 1) { return actualCount; } return 0; } private static string PurchaseInteraction_GetContextString(orig_GetContextString orig, PurchaseInteraction self, Interactor activator) { if (!IsFreePlayerMoneyPurchase(self, activator)) { return orig.Invoke(self, activator); } int cost = self.cost; self.cost = 0; try { return orig.Invoke(self, activator); } finally { self.cost = cost; } } private static void PurchaseInteraction_UpdateHologramContent(orig_UpdateHologramContent orig, PurchaseInteraction self, GameObject hologramContentObject, Transform viewer) { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Invalid comparison between Unknown and I4 if (!ArtifactRegistry.IsEnabled(ArtifactRegistry.Bounty) || (int)self.costType != 1) { orig.Invoke(self, hologramContentObject, viewer); return; } int cost = self.cost; self.cost = 0; try { orig.Invoke(self, hologramContentObject, viewer); } finally { self.cost = cost; } } private static int RemoteOperationDronePickerPanel_GetDroneCost(orig_GetDroneCost orig, RemoteOperationDronePickerPanel self, DroneDef drone) { if (!ArtifactRegistry.IsEnabled(ArtifactRegistry.Bounty)) { return orig.Invoke(self, drone); } return 0; } private static void CharacterMaster_SpawnRemoteOperationDrone(orig_SpawnRemoteOperationDrone orig, CharacterMaster self, string droneBodyToSpawn, uint moneyToUse) { if (ArtifactRegistry.IsEnabled(ArtifactRegistry.Bounty) && IsPlayerMaster(self)) { moneyToUse = 0u; } orig.Invoke(self, droneBodyToSpawn, moneyToUse); } private static void GoldSiphonNearbyBodyController_DrainGold_IL(ILContext il) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Expected O, but got Unknown ILCursor val = new ILCursor(il); int num = 0; while (val.TryGotoNext((MoveType)2, new Func[1] { (Instruction instruction) => ILPatternMatchingExt.MatchCallOrCallvirt(instruction, "get_money") })) { val.EmitDelegate>((Func)GetHalcyoniteShrineVisibleMoney); num++; int index = val.Index; val.Index = index + 1; } ILCursor val2 = new ILCursor(il); int num2 = 0; while (val2.TryGotoNext((MoveType)0, new Func[1] { (Instruction instruction) => ILPatternMatchingExt.MatchCallOrCallvirt(instruction, "set_money") })) { val2.Remove(); val2.EmitDelegate>((Action)PayHalcyoniteShrineMoney); num2++; } goldSiphonPatchSucceeded = num == 4 && num2 == 1; if (goldSiphonPatchSucceeded) { log.LogDebug((object)$"Bounty patched Halcyonite Shrine gold siphon ({num} reads, {num2} write)."); } else { log.LogError((object)$"Bounty: failed to patch Halcyonite Shrine gold siphon safely (reads={num}, writes={num2})."); } } private static uint GetHalcyoniteShrineVisibleMoney(uint actualMoney) { if (!goldSiphonPatchSucceeded || !ArtifactRegistry.IsEnabled(ArtifactRegistry.Bounty)) { return actualMoney; } return 1000000u; } private static void PayHalcyoniteShrineMoney(CharacterMaster master, uint newMoney) { if (!goldSiphonPatchSucceeded || !ArtifactRegistry.IsEnabled(ArtifactRegistry.Bounty)) { master.money = newMoney; } } private static bool GenericPickupController_BodyHasPickupPermission(orig_BodyHasPickupPermission orig, CharacterBody body, UniquePickup pickupState) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) if (ShouldBlockPickup(body, pickupState.pickupIndex)) { return false; } return orig.Invoke(body, pickupState); } private static void GenericPickupController_AttemptGrant(orig_AttemptGrant orig, GenericPickupController self, CharacterBody body) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) if (!ShouldBlockPickup(body, self.pickup.pickupIndex)) { orig.Invoke(self, body); } } private static bool IsMoneyCost(CostTypeDef costTypeDef) { if (ArtifactRegistry.IsEnabled(ArtifactRegistry.Bounty)) { return costTypeDef == CostTypeCatalog.GetCostTypeDef((CostTypeIndex)1); } return false; } private static bool IsFreePlayerMoneyPurchase(PurchaseInteraction purchase, Interactor activator) { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Invalid comparison between Unknown and I4 if (ArtifactRegistry.IsEnabled(ArtifactRegistry.Bounty) && (int)purchase.costType == 1) { return IsPlayerInteractor(activator); } return false; } private static bool IsPlayerInteractor(Interactor? interactor) { if (interactor != null) { CharacterBody component = ((Component)interactor).GetComponent(); return IsPlayerMaster((component != null) ? component.master : null); } return false; } private static bool IsPlayerMaster(CharacterMaster? master) { if (master != null) { return master.playerCharacterMasterController != null; } return false; } private static bool ShouldBlockPickup(CharacterBody? body, PickupIndex pickupIndex) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Invalid comparison between Unknown and I4 //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Invalid comparison between Unknown and I4 //IL_004d: Unknown result type (might be due to invalid IL or missing references) if (body == null || !IsPlayerMaster(body.master)) { return false; } PickupDef pickupDef = PickupCatalog.GetPickupDef(pickupIndex); if (pickupDef == null) { return false; } if (ArtifactRegistry.IsEnabled(ArtifactRegistry.Flaw) && (int)pickupDef.equipmentIndex != -1) { return true; } if (!ArtifactRegistry.IsEnabled(ArtifactRegistry.Desolation) || (int)pickupDef.itemIndex == -1) { return false; } ItemDef itemDef = ItemCatalog.GetItemDef(pickupDef.itemIndex); if (itemDef != null) { return !IsDesolationException(itemDef); } return false; } private static bool IsDesolationException(ItemDef itemDef) { if (!itemDef.canRemove || itemDef.hidden) { return true; } if (!itemDef.ContainsTag((ItemTag)33) && !itemDef.ContainsTag((ItemTag)26) && !itemDef.ContainsTag((ItemTag)9)) { return itemDef.ContainsTag((ItemTag)21); } return true; } } internal static class MonsterEventArtifactHooks { [CompilerGenerated] private static class <>O { public static hook_SpawnBody <0>__CharacterMaster_SpawnBody; public static hook_OnDestroy <1>__CharacterMaster_OnDestroy; public static hook_RecalculateDifficultyCoefficent <2>__Run_RecalculateDifficultyCoefficent; public static Action <3>__BossGroup_onBossGroupDefeatedServer; public static Action <4>__Run_onRunDestroyGlobal; } private const int InfiniteAmbientLevelCap = 9999; private static readonly HashSet MirroredMasters = new HashSet(); private static readonly FieldInfo? AmbientLevelCapField = typeof(Run).GetField("ambientLevelCap", BindingFlags.Static | BindingFlags.NonPublic); private static ManualLogSource log = null; internal static void Install(ManualLogSource logger) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Expected O, but got Unknown //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_0041: Expected O, but got Unknown //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Expected O, but got Unknown log = logger; object obj = <>O.<0>__CharacterMaster_SpawnBody; if (obj == null) { hook_SpawnBody val = CharacterMaster_SpawnBody; <>O.<0>__CharacterMaster_SpawnBody = val; obj = (object)val; } CharacterMaster.SpawnBody += (hook_SpawnBody)obj; object obj2 = <>O.<1>__CharacterMaster_OnDestroy; if (obj2 == null) { hook_OnDestroy val2 = CharacterMaster_OnDestroy; <>O.<1>__CharacterMaster_OnDestroy = val2; obj2 = (object)val2; } CharacterMaster.OnDestroy += (hook_OnDestroy)obj2; object obj3 = <>O.<2>__Run_RecalculateDifficultyCoefficent; if (obj3 == null) { hook_RecalculateDifficultyCoefficent val3 = Run_RecalculateDifficultyCoefficent; <>O.<2>__Run_RecalculateDifficultyCoefficent = val3; obj3 = (object)val3; } Run.RecalculateDifficultyCoefficent += (hook_RecalculateDifficultyCoefficent)obj3; BossGroup.onBossGroupDefeatedServer += BossGroup_onBossGroupDefeatedServer; Run.onRunDestroyGlobal += Run_onRunDestroyGlobal; if ((object)AmbientLevelCapField == null) { log.LogError((object)"Infinity: Run.ambientLevelCap was not found."); } } internal static void Uninstall() { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Expected O, but got Unknown //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Expected O, but got Unknown //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Expected O, but got Unknown object obj = <>O.<0>__CharacterMaster_SpawnBody; if (obj == null) { hook_SpawnBody val = CharacterMaster_SpawnBody; <>O.<0>__CharacterMaster_SpawnBody = val; obj = (object)val; } CharacterMaster.SpawnBody -= (hook_SpawnBody)obj; object obj2 = <>O.<1>__CharacterMaster_OnDestroy; if (obj2 == null) { hook_OnDestroy val2 = CharacterMaster_OnDestroy; <>O.<1>__CharacterMaster_OnDestroy = val2; obj2 = (object)val2; } CharacterMaster.OnDestroy -= (hook_OnDestroy)obj2; object obj3 = <>O.<2>__Run_RecalculateDifficultyCoefficent; if (obj3 == null) { hook_RecalculateDifficultyCoefficent val3 = Run_RecalculateDifficultyCoefficent; <>O.<2>__Run_RecalculateDifficultyCoefficent = val3; obj3 = (object)val3; } Run.RecalculateDifficultyCoefficent -= (hook_RecalculateDifficultyCoefficent)obj3; BossGroup.onBossGroupDefeatedServer -= BossGroup_onBossGroupDefeatedServer; Run.onRunDestroyGlobal -= Run_onRunDestroyGlobal; MirroredMasters.Clear(); } private static CharacterBody CharacterMaster_SpawnBody(orig_SpawnBody orig, CharacterMaster self, Vector3 position, Quaternion rotation) { //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Invalid comparison between Unknown and I4 if (NetworkServer.active && ArtifactRegistry.IsEnabled(ArtifactRegistry.Mirror) && (int)self.teamIndex == 2 && self.inventory != null && MirroredMasters.Add(self)) { ApplyPlayerItemSnapshot(self.inventory); } return orig.Invoke(self, position, rotation); } private static void CharacterMaster_OnDestroy(orig_OnDestroy orig, CharacterMaster self) { MirroredMasters.Remove(self); orig.Invoke(self); } private static void ApplyPlayerItemSnapshot(Inventory monsterInventory) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: 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_0072: Unknown result type (might be due to invalid IL or missing references) int itemCount = ItemCatalog.itemCount; for (int i = 0; i < itemCount; i++) { ItemIndex val = (ItemIndex)i; ItemDef itemDef = ItemCatalog.GetItemDef(val); if (itemDef == null || !CanMirror(itemDef)) { continue; } long num = 0L; foreach (PlayerCharacterMasterController instance in PlayerCharacterMasterController.instances) { if (!Object.op_Implicit((Object)(object)instance) || !instance.isConnected) { continue; } CharacterMaster master = instance.master; Inventory val2 = ((master != null) ? master.inventory : null); if (val2 != null) { num += Math.Max(0, val2.GetItemCountPermanent(val)); if (num >= int.MaxValue) { num = 2147483647L; break; } } } int itemCountPermanent = monsterInventory.GetItemCountPermanent(val); int num2 = (int)Math.Max(0L, num - itemCountPermanent); if (num2 > 0) { monsterInventory.GiveItemPermanent(val, num2); } } } private static bool CanMirror(ItemDef itemDef) { if (itemDef.canRemove && itemDef.DoesNotContainTag((ItemTag)13) && itemDef.DoesNotContainTag((ItemTag)4)) { return itemDef.DoesNotContainTag((ItemTag)11); } return false; } private static void Run_RecalculateDifficultyCoefficent(orig_RecalculateDifficultyCoefficent orig, Run self) { if ((object)AmbientLevelCapField == null || !ArtifactRegistry.IsEnabled(ArtifactRegistry.Infinite)) { orig.Invoke(self); return; } int num = ((AmbientLevelCapField.GetValue(null) is int num2) ? num2 : 99); AmbientLevelCapField.SetValue(null, Math.Max(num, 9999)); try { orig.Invoke(self); } finally { AmbientLevelCapField.SetValue(null, num); } } private static void BossGroup_onBossGroupDefeatedServer(BossGroup defeatedBossGroup) { if (NetworkServer.active && ArtifactRegistry.IsEnabled(ArtifactRegistry.Warp)) { TeleporterInteraction instance = TeleporterInteraction.instance; if (instance != null && instance.isCharging && (Object)(object)instance.bossGroup == (Object)(object)defeatedBossGroup && instance.holdoutZoneController != null) { instance.holdoutZoneController.FullyChargeHoldoutZone(); } } } private static void Run_onRunDestroyGlobal(Run run) { MirroredMasters.Clear(); } } internal static class PlayerArtifactHooks { private sealed class AtrophyState { internal float HealthLoss; internal float ShieldLoss; internal bool HealthMaximumExhausted; } [CompilerGenerated] private static class <>O { public static Manipulator <0>__TeamManager_SetTeamExperience_IL; public static Manipulator <1>__CharacterBody_RecalculateStats_Destiny_IL; public static Manipulator <2>__CharacterBody_RecalculateStats_Atrophy_IL; public static Manipulator <3>__CharacterMaster_OnBodyDeath_IL; public static hook_GetTeamLevel <4>__TeamManager_GetTeamLevel; public static hook_GetHealthBarValues <5>__HealthComponent_GetHealthBarValues; public static hook_OnBodyDeath <6>__CharacterMaster_OnBodyDeath; public static hook_OnBodyStart <7>__CharacterMaster_OnBodyStart; public static hook_ReviveCharacterInvisibly <8>__HealthComponent_ReviveCharacterInvisibly; public static hook_OnServerCharacterDeathGlobal <9>__TeamDeathArtifactManager_OnServerCharacterDeathGlobal; public static Action <10>__Stage_onServerStageBegin; public static Action <11>__Run_onRunDestroyGlobal; public static ArtifactStateChangeDelegate <12>__RunArtifactManager_onArtifactStateChanged; public static Func <13>__FreezeDestinyTeamLevel; public static Action <14>__ForceDestinyBodyLevel; public static Action <15>__ApplyAtrophyMaximumLossBeforeVanillaReconcile; public static Func <16>__TryUseArtifactRevival; } private static readonly HashSet RevivalUsedThisStage = new HashSet(); private static readonly Dictionary AtrophyStates = new Dictionary(); private static readonly HashSet AwaitingNewLife = new HashSet(); private static readonly FieldInfo? LevelField = FindBackingField("level"); private static readonly FieldInfo? MaxHealthField = FindBackingField("maxHealth"); private static readonly FieldInfo? MaxShieldField = FindBackingField("maxShield"); private static ManualLogSource log = null; private static bool revivalPatchSucceeded; private static bool atrophyStatsPatchSucceeded; internal static bool AtrophyStatsPatchSucceeded => atrophyStatsPatchSucceeded; internal static bool IsAtrophyEligiblePlayer(HealthComponent? healthComponent) { if (NetworkServer.active && healthComponent != null && healthComponent.body != null && healthComponent.body.isPlayerControlled) { return IsPlayerMaster(healthComponent.body.master); } return false; } internal static void Install(ManualLogSource logger) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Expected O, but got Unknown //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_0041: Expected O, but got Unknown //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Expected O, but got Unknown //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Expected O, but got Unknown //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Expected O, but got Unknown //IL_00b6: 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_00c1: Expected O, but got Unknown //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Expected O, but got Unknown //IL_00f6: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Expected O, but got Unknown //IL_0116: 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_0121: Expected O, but got Unknown //IL_0136: Unknown result type (might be due to invalid IL or missing references) //IL_013b: Unknown result type (might be due to invalid IL or missing references) //IL_0141: Expected O, but got Unknown //IL_0196: Unknown result type (might be due to invalid IL or missing references) //IL_019b: Unknown result type (might be due to invalid IL or missing references) //IL_01a1: Expected O, but got Unknown //IL_01b6: Unknown result type (might be due to invalid IL or missing references) //IL_01bb: Unknown result type (might be due to invalid IL or missing references) //IL_01c1: Expected O, but got Unknown log = logger; object obj = <>O.<0>__TeamManager_SetTeamExperience_IL; if (obj == null) { Manipulator val = TeamManager_SetTeamExperience_IL; <>O.<0>__TeamManager_SetTeamExperience_IL = val; obj = (object)val; } TeamManager.SetTeamExperience += (Manipulator)obj; object obj2 = <>O.<1>__CharacterBody_RecalculateStats_Destiny_IL; if (obj2 == null) { Manipulator val2 = CharacterBody_RecalculateStats_Destiny_IL; <>O.<1>__CharacterBody_RecalculateStats_Destiny_IL = val2; obj2 = (object)val2; } CharacterBody.RecalculateStats += (Manipulator)obj2; object obj3 = <>O.<2>__CharacterBody_RecalculateStats_Atrophy_IL; if (obj3 == null) { Manipulator val3 = CharacterBody_RecalculateStats_Atrophy_IL; <>O.<2>__CharacterBody_RecalculateStats_Atrophy_IL = val3; obj3 = (object)val3; } CharacterBody.RecalculateStats += (Manipulator)obj3; object obj4 = <>O.<3>__CharacterMaster_OnBodyDeath_IL; if (obj4 == null) { Manipulator val4 = CharacterMaster_OnBodyDeath_IL; <>O.<3>__CharacterMaster_OnBodyDeath_IL = val4; obj4 = (object)val4; } CharacterMaster.OnBodyDeath += (Manipulator)obj4; object obj5 = <>O.<4>__TeamManager_GetTeamLevel; if (obj5 == null) { hook_GetTeamLevel val5 = TeamManager_GetTeamLevel; <>O.<4>__TeamManager_GetTeamLevel = val5; obj5 = (object)val5; } TeamManager.GetTeamLevel += (hook_GetTeamLevel)obj5; object obj6 = <>O.<5>__HealthComponent_GetHealthBarValues; if (obj6 == null) { hook_GetHealthBarValues val6 = HealthComponent_GetHealthBarValues; <>O.<5>__HealthComponent_GetHealthBarValues = val6; obj6 = (object)val6; } HealthComponent.GetHealthBarValues += (hook_GetHealthBarValues)obj6; object obj7 = <>O.<6>__CharacterMaster_OnBodyDeath; if (obj7 == null) { hook_OnBodyDeath val7 = CharacterMaster_OnBodyDeath; <>O.<6>__CharacterMaster_OnBodyDeath = val7; obj7 = (object)val7; } CharacterMaster.OnBodyDeath += (hook_OnBodyDeath)obj7; object obj8 = <>O.<7>__CharacterMaster_OnBodyStart; if (obj8 == null) { hook_OnBodyStart val8 = CharacterMaster_OnBodyStart; <>O.<7>__CharacterMaster_OnBodyStart = val8; obj8 = (object)val8; } CharacterMaster.OnBodyStart += (hook_OnBodyStart)obj8; object obj9 = <>O.<8>__HealthComponent_ReviveCharacterInvisibly; if (obj9 == null) { hook_ReviveCharacterInvisibly val9 = HealthComponent_ReviveCharacterInvisibly; <>O.<8>__HealthComponent_ReviveCharacterInvisibly = val9; obj9 = (object)val9; } HealthComponent.ReviveCharacterInvisibly += (hook_ReviveCharacterInvisibly)obj9; object obj10 = <>O.<9>__TeamDeathArtifactManager_OnServerCharacterDeathGlobal; if (obj10 == null) { hook_OnServerCharacterDeathGlobal val10 = TeamDeathArtifactManager_OnServerCharacterDeathGlobal; <>O.<9>__TeamDeathArtifactManager_OnServerCharacterDeathGlobal = val10; obj10 = (object)val10; } TeamDeathArtifactManager.OnServerCharacterDeathGlobal += (hook_OnServerCharacterDeathGlobal)obj10; Stage.onServerStageBegin += Stage_onServerStageBegin; Run.onRunDestroyGlobal += Run_onRunDestroyGlobal; object obj11 = <>O.<12>__RunArtifactManager_onArtifactStateChanged; if (obj11 == null) { ArtifactStateChangeDelegate val11 = RunArtifactManager_onArtifactStateChanged; <>O.<12>__RunArtifactManager_onArtifactStateChanged = val11; obj11 = (object)val11; } RunArtifactManager.onArtifactEnabledGlobal += (ArtifactStateChangeDelegate)obj11; object obj12 = <>O.<12>__RunArtifactManager_onArtifactStateChanged; if (obj12 == null) { ArtifactStateChangeDelegate val12 = RunArtifactManager_onArtifactStateChanged; <>O.<12>__RunArtifactManager_onArtifactStateChanged = val12; obj12 = (object)val12; } RunArtifactManager.onArtifactDisabledGlobal += (ArtifactStateChangeDelegate)obj12; if ((object)LevelField == null || (object)MaxHealthField == null || (object)MaxShieldField == null) { log.LogError((object)"One or more CharacterBody stat backing fields were not found; Destiny or Atrophy cannot be applied safely."); } } internal static void Uninstall() { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Expected O, but got Unknown //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Expected O, but got Unknown //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Expected O, but got Unknown //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Expected O, but got Unknown //IL_0090: 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_009b: Expected O, but got Unknown //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Expected O, but got Unknown //IL_00d0: 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_00db: Expected O, but got Unknown //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Expected O, but got Unknown //IL_0110: Unknown result type (might be due to invalid IL or missing references) //IL_0115: Unknown result type (might be due to invalid IL or missing references) //IL_011b: Expected O, but got Unknown //IL_0130: Unknown result type (might be due to invalid IL or missing references) //IL_0135: Unknown result type (might be due to invalid IL or missing references) //IL_013b: Expected O, but got Unknown //IL_0190: Unknown result type (might be due to invalid IL or missing references) //IL_0195: Unknown result type (might be due to invalid IL or missing references) //IL_019b: Expected O, but got Unknown //IL_01b0: Unknown result type (might be due to invalid IL or missing references) //IL_01b5: Unknown result type (might be due to invalid IL or missing references) //IL_01bb: Expected O, but got Unknown object obj = <>O.<0>__TeamManager_SetTeamExperience_IL; if (obj == null) { Manipulator val = TeamManager_SetTeamExperience_IL; <>O.<0>__TeamManager_SetTeamExperience_IL = val; obj = (object)val; } TeamManager.SetTeamExperience -= (Manipulator)obj; object obj2 = <>O.<2>__CharacterBody_RecalculateStats_Atrophy_IL; if (obj2 == null) { Manipulator val2 = CharacterBody_RecalculateStats_Atrophy_IL; <>O.<2>__CharacterBody_RecalculateStats_Atrophy_IL = val2; obj2 = (object)val2; } CharacterBody.RecalculateStats -= (Manipulator)obj2; object obj3 = <>O.<1>__CharacterBody_RecalculateStats_Destiny_IL; if (obj3 == null) { Manipulator val3 = CharacterBody_RecalculateStats_Destiny_IL; <>O.<1>__CharacterBody_RecalculateStats_Destiny_IL = val3; obj3 = (object)val3; } CharacterBody.RecalculateStats -= (Manipulator)obj3; object obj4 = <>O.<3>__CharacterMaster_OnBodyDeath_IL; if (obj4 == null) { Manipulator val4 = CharacterMaster_OnBodyDeath_IL; <>O.<3>__CharacterMaster_OnBodyDeath_IL = val4; obj4 = (object)val4; } CharacterMaster.OnBodyDeath -= (Manipulator)obj4; object obj5 = <>O.<4>__TeamManager_GetTeamLevel; if (obj5 == null) { hook_GetTeamLevel val5 = TeamManager_GetTeamLevel; <>O.<4>__TeamManager_GetTeamLevel = val5; obj5 = (object)val5; } TeamManager.GetTeamLevel -= (hook_GetTeamLevel)obj5; object obj6 = <>O.<5>__HealthComponent_GetHealthBarValues; if (obj6 == null) { hook_GetHealthBarValues val6 = HealthComponent_GetHealthBarValues; <>O.<5>__HealthComponent_GetHealthBarValues = val6; obj6 = (object)val6; } HealthComponent.GetHealthBarValues -= (hook_GetHealthBarValues)obj6; object obj7 = <>O.<6>__CharacterMaster_OnBodyDeath; if (obj7 == null) { hook_OnBodyDeath val7 = CharacterMaster_OnBodyDeath; <>O.<6>__CharacterMaster_OnBodyDeath = val7; obj7 = (object)val7; } CharacterMaster.OnBodyDeath -= (hook_OnBodyDeath)obj7; object obj8 = <>O.<7>__CharacterMaster_OnBodyStart; if (obj8 == null) { hook_OnBodyStart val8 = CharacterMaster_OnBodyStart; <>O.<7>__CharacterMaster_OnBodyStart = val8; obj8 = (object)val8; } CharacterMaster.OnBodyStart -= (hook_OnBodyStart)obj8; object obj9 = <>O.<8>__HealthComponent_ReviveCharacterInvisibly; if (obj9 == null) { hook_ReviveCharacterInvisibly val9 = HealthComponent_ReviveCharacterInvisibly; <>O.<8>__HealthComponent_ReviveCharacterInvisibly = val9; obj9 = (object)val9; } HealthComponent.ReviveCharacterInvisibly -= (hook_ReviveCharacterInvisibly)obj9; object obj10 = <>O.<9>__TeamDeathArtifactManager_OnServerCharacterDeathGlobal; if (obj10 == null) { hook_OnServerCharacterDeathGlobal val10 = TeamDeathArtifactManager_OnServerCharacterDeathGlobal; <>O.<9>__TeamDeathArtifactManager_OnServerCharacterDeathGlobal = val10; obj10 = (object)val10; } TeamDeathArtifactManager.OnServerCharacterDeathGlobal -= (hook_OnServerCharacterDeathGlobal)obj10; Stage.onServerStageBegin -= Stage_onServerStageBegin; Run.onRunDestroyGlobal -= Run_onRunDestroyGlobal; object obj11 = <>O.<12>__RunArtifactManager_onArtifactStateChanged; if (obj11 == null) { ArtifactStateChangeDelegate val11 = RunArtifactManager_onArtifactStateChanged; <>O.<12>__RunArtifactManager_onArtifactStateChanged = val11; obj11 = (object)val11; } RunArtifactManager.onArtifactEnabledGlobal -= (ArtifactStateChangeDelegate)obj11; object obj12 = <>O.<12>__RunArtifactManager_onArtifactStateChanged; if (obj12 == null) { ArtifactStateChangeDelegate val12 = RunArtifactManager_onArtifactStateChanged; <>O.<12>__RunArtifactManager_onArtifactStateChanged = val12; obj12 = (object)val12; } RunArtifactManager.onArtifactDisabledGlobal -= (ArtifactStateChangeDelegate)obj12; RevivalUsedThisStage.Clear(); AtrophyStates.Clear(); AwaitingNewLife.Clear(); atrophyStatsPatchSucceeded = false; } internal static void RecordAtrophyDamage(HealthComponent healthComponent, float healthLoss, float shieldLoss, DamageInfo damageInfo) { //IL_0113: Unknown result type (might be due to invalid IL or missing references) if (!IsAtrophyEligiblePlayer(healthComponent) || !atrophyStatsPatchSucceeded || !ArtifactRegistry.IsEnabled(ArtifactRegistry.Atrophy) || !healthComponent.alive || healthComponent.body == null) { return; } healthLoss = SanitizeLoss(healthLoss); shieldLoss = SanitizeLoss(shieldLoss); if (!(healthLoss <= 0f) || !(shieldLoss <= 0f)) { CharacterBody body = healthComponent.body; CharacterMaster master = body.master; if (!AtrophyStates.TryGetValue(master, out AtrophyState value)) { value = new AtrophyState { HealthLoss = DecodeLoss(body.GetBuffCount(ArtifactRegistry.AtrophyHealthLossBuff)), ShieldLoss = DecodeLoss(body.GetBuffCount(ArtifactRegistry.AtrophyShieldLossBuff)) }; AtrophyStates.Add(master, value); } value.HealthLoss = Mathf.Min(float.MaxValue, value.HealthLoss + healthLoss); value.ShieldLoss = Mathf.Min(float.MaxValue, value.ShieldLoss + shieldLoss); ApplyAtrophyStateToBody(body, value); body.RecalculateStats(); if (value.HealthMaximumExhausted && healthComponent.alive) { healthComponent.Suicide(damageInfo?.attacker, damageInfo?.inflictor, DamageTypeCombo.op_Implicit((DamageType)262208)); } } } internal static void ResetAtrophyAfterInlineRevival(HealthComponent healthComponent) { if (IsAtrophyEligiblePlayer(healthComponent) && ArtifactRegistry.IsEnabled(ArtifactRegistry.Atrophy) && healthComponent.alive && healthComponent.body != null) { CharacterBody body = healthComponent.body; float health = healthComponent.health; float shield = healthComponent.shield; ClearAtrophyState(body.master, body); body.RecalculateStats(); healthComponent.Networkhealth = Mathf.Min(health, healthComponent.fullHealth); healthComponent.Networkshield = Mathf.Min(shield, healthComponent.fullShield); } } private static void TeamManager_SetTeamExperience_IL(ILContext il) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown //IL_0049: Unknown result type (might be due to invalid IL or missing references) ILCursor val = new ILCursor(il); if (!val.TryGotoNext((MoveType)2, new Func[1] { (Instruction instruction) => ILPatternMatchingExt.MatchCall(instruction, typeof(TeamManager), "FindLevelForExperience") })) { log.LogError((object)"Destiny: failed to patch TeamManager.SetTeamExperience; raw experience remains safe, but internal level-up events may still occur."); return; } val.Emit(OpCodes.Ldarg_1); val.EmitDelegate>((Func)FreezeDestinyTeamLevel); } private static uint FreezeDestinyTeamLevel(uint calculatedLevel, TeamIndex teamIndex) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Invalid comparison between Unknown and I4 if (!ArtifactRegistry.IsEnabled(ArtifactRegistry.Destiny) || (int)teamIndex != 1) { return calculatedLevel; } return 1u; } private static void CharacterBody_RecalculateStats_Destiny_IL(ILContext il) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown //IL_0055: Unknown result type (might be due to invalid IL or missing references) ILCursor val = new ILCursor(il); for (int i = 0; i < 3; i++) { if (!val.TryGotoNext((MoveType)2, new Func[1] { (Instruction instruction) => ILPatternMatchingExt.MatchCallOrCallvirt(instruction, "set_level") })) { log.LogError((object)"Destiny: failed to locate the final CharacterBody level assignment."); return; } } val.Emit(OpCodes.Ldarg_0); val.EmitDelegate>((Action)ForceDestinyBodyLevel); } private static void CharacterBody_RecalculateStats_Atrophy_IL(ILContext il) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown //IL_011b: Unknown result type (might be due to invalid IL or missing references) ILCursor val = new ILCursor(il); if (!val.TryGotoNext((MoveType)0, new Func[7] { (Instruction instruction) => ILPatternMatchingExt.MatchLdarg(instruction, 0), (Instruction instruction) => ILPatternMatchingExt.MatchLdarg(instruction, 0), (Instruction instruction) => ILPatternMatchingExt.MatchCallOrCallvirt(instruction, "get_maxHealth"), (Instruction instruction) => ILPatternMatchingExt.MatchLdarg(instruction, 0), (Instruction instruction) => ILPatternMatchingExt.MatchCallOrCallvirt(instruction, "get_maxShield"), (Instruction instruction) => instruction.OpCode == OpCodes.Add, (Instruction instruction) => ILPatternMatchingExt.MatchCallOrCallvirt(instruction, "set_maxBarrier") })) { atrophyStatsPatchSucceeded = false; log.LogError((object)"Atrophy: failed to patch final CharacterBody maxima before vanilla health/shield reconciliation; Atrophy maximum loss is disabled to avoid unintended healing."); } else { val.Emit(OpCodes.Ldarg_0); val.EmitDelegate>((Action)ApplyAtrophyMaximumLossBeforeVanillaReconcile); atrophyStatsPatchSucceeded = true; } } private static void ApplyAtrophyMaximumLossBeforeVanillaReconcile(CharacterBody body) { if (!ArtifactRegistry.IsEnabled(ArtifactRegistry.Atrophy) || !body.isPlayerControlled || (object)MaxHealthField == null || (object)MaxShieldField == null) { return; } float num = DecodeLoss(body.GetBuffCount(ArtifactRegistry.AtrophyHealthLossBuff)); float num2 = DecodeLoss(body.GetBuffCount(ArtifactRegistry.AtrophyShieldLossBuff)); if (!(num <= 0f) || !(num2 <= 0f)) { float num3 = body.maxHealth - num; MaxHealthField.SetValue(body, Mathf.Max(1f, num3)); MaxShieldField.SetValue(body, Mathf.Max(0f, body.maxShield - num2)); if (NetworkServer.active && body.master != null && AtrophyStates.TryGetValue(body.master, out AtrophyState value)) { value.HealthMaximumExhausted = num3 <= 0f; } } } private static void ForceDestinyBodyLevel(CharacterBody body) { if ((object)LevelField != null && body != null && body.isPlayerControlled && ArtifactRegistry.IsEnabled(ArtifactRegistry.Destiny)) { LevelField.SetValue(body, 1f); } } private static void CharacterMaster_OnBodyDeath_IL(ILContext il) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) ILCursor val = new ILCursor(il); if (!val.TryGotoNext((MoveType)2, new Func[1] { (Instruction instruction) => ILPatternMatchingExt.MatchCallOrCallvirt(instruction, "TryReviveOnBodyDeath") })) { log.LogError((object)"Revival: failed to locate CharacterMaster.TryReviveOnBodyDeath."); return; } val.Emit(OpCodes.Ldarg_0); val.Emit(OpCodes.Ldarg_1); val.EmitDelegate>((Func)TryUseArtifactRevival); revivalPatchSucceeded = true; } private static bool TryUseArtifactRevival(bool vanillaRevivalStarted, CharacterMaster master, CharacterBody body) { if (vanillaRevivalStarted) { return true; } if (!NetworkServer.active || !HasArtifactRevivalAvailable(master)) { return false; } RevivalUsedThisStage.Add(master); ((MonoBehaviour)master).Invoke("RespawnExtraLifeShrine", 2f); ((MonoBehaviour)master).Invoke("PlayExtraLifeSFX", 1f); return true; } private static uint TeamManager_GetTeamLevel(orig_GetTeamLevel orig, TeamManager self, TeamIndex teamIndex) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Invalid comparison between Unknown and I4 uint result = orig.Invoke(self, teamIndex); if (!ArtifactRegistry.IsEnabled(ArtifactRegistry.Destiny) || (int)teamIndex != 1) { return result; } return 1u; } private static HealthBarValues HealthComponent_GetHealthBarValues(orig_GetHealthBarValues orig, HealthComponent self) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Unknown result type (might be due to invalid IL or missing references) HealthBarValues val = orig.Invoke(self); if (!ArtifactRegistry.IsEnabled(ArtifactRegistry.Atrophy) || self.body == null || !self.body.isPlayerControlled) { return val; } float num = DecodeLoss(self.body.GetBuffCount(ArtifactRegistry.AtrophyHealthLossBuff)) + DecodeLoss(self.body.GetBuffCount(ArtifactRegistry.AtrophyShieldLossBuff)); float num2 = Mathf.Max(0f, self.fullCombinedHealth); float num3 = num2 + num; if (num <= 0f || num3 <= 0f) { return val; } float num4 = num2 / num3; val.healthFraction *= num4; val.shieldFraction *= num4; val.barrierFraction *= num4; val.magneticFraction *= num4; val.echoFraction *= num4; val.cullFraction *= num4; val.ospFraction *= num4; val.curseFraction = 1f - (1f - val.curseFraction) * num4; return val; } private static void CharacterMaster_OnBodyDeath(orig_OnBodyDeath orig, CharacterMaster self, CharacterBody body) { if (NetworkServer.active && ArtifactRegistry.IsEnabled(ArtifactRegistry.Atrophy) && IsPlayerMaster(self)) { AwaitingNewLife.Add(self); } orig.Invoke(self, body); } private static void CharacterMaster_OnBodyStart(orig_OnBodyStart orig, CharacterMaster self, CharacterBody body) { if (NetworkServer.active && IsPlayerMaster(self)) { AtrophyState value; if (AwaitingNewLife.Remove(self)) { ClearAtrophyState(self, body); } else if (ArtifactRegistry.IsEnabled(ArtifactRegistry.Atrophy) && AtrophyStates.TryGetValue(self, out value)) { ApplyAtrophyStateToBody(body, value); } } orig.Invoke(self, body); } private static void HealthComponent_ReviveCharacterInvisibly(orig_ReviveCharacterInvisibly orig, HealthComponent self) { DamageArtifactHooks.NotifyRevival(self); if (NetworkServer.active && self.body != null && IsPlayerMaster(self.body.master)) { ClearAtrophyState(self.body.master, self.body); self.body.RecalculateStats(); } orig.Invoke(self); } private static void TeamDeathArtifactManager_OnServerCharacterDeathGlobal(orig_OnServerCharacterDeathGlobal orig, DamageReport damageReport) { CharacterMaster victimMaster = damageReport.victimMaster; if (!NetworkServer.active || !HasArtifactRevivalAvailable(victimMaster)) { orig.Invoke(damageReport); } } private static bool HasArtifactRevivalAvailable(CharacterMaster? master) { if (revivalPatchSucceeded && ArtifactRegistry.IsEnabled(ArtifactRegistry.Revival) && IsPlayerMaster(master)) { return !RevivalUsedThisStage.Contains(master); } return false; } private static void Stage_onServerStageBegin(Stage stage) { RevivalUsedThisStage.Clear(); } private static void Run_onRunDestroyGlobal(Run run) { RevivalUsedThisStage.Clear(); AtrophyStates.Clear(); AwaitingNewLife.Clear(); } private static void RunArtifactManager_onArtifactStateChanged(RunArtifactManager manager, ArtifactDef artifactDef) { if ((Object)(object)artifactDef == (Object)(object)ArtifactRegistry.Destiny) { if (NetworkServer.active && TeamManager.instance != null) { TeamManager.instance.GiveTeamExperience((TeamIndex)1, 0uL); } foreach (TeamComponent teamMember in TeamComponent.GetTeamMembers((TeamIndex)1)) { CharacterBody body = teamMember.body; if (body != null) { body.MarkAllStatsDirty(); } } } if (!((Object)(object)artifactDef == (Object)(object)ArtifactRegistry.Atrophy) || ArtifactRegistry.IsEnabled(ArtifactRegistry.Atrophy) || !NetworkServer.active) { return; } foreach (KeyValuePair atrophyState in AtrophyStates) { atrophyState.Deconstruct(out var key, out var _); CharacterBody body2 = key.GetBody(); if (body2 != null) { ClearAtrophyBuffs(body2); body2.RecalculateStats(); } } AtrophyStates.Clear(); AwaitingNewLife.Clear(); } private static void ApplyAtrophyStateToBody(CharacterBody body, AtrophyState state) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) body.SetBuffCount(ArtifactRegistry.AtrophyHealthLossBuff.buffIndex, EncodeLoss(state.HealthLoss)); body.SetBuffCount(ArtifactRegistry.AtrophyShieldLossBuff.buffIndex, EncodeLoss(state.ShieldLoss)); } private static void ClearAtrophyState(CharacterMaster master, CharacterBody? body) { AtrophyStates.Remove(master); AwaitingNewLife.Remove(master); if (body != null) { ClearAtrophyBuffs(body); body.MarkAllStatsDirty(); } } private static void ClearAtrophyBuffs(CharacterBody body) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) body.SetBuffCount(ArtifactRegistry.AtrophyHealthLossBuff.buffIndex, 0); body.SetBuffCount(ArtifactRegistry.AtrophyShieldLossBuff.buffIndex, 0); } private static bool IsPlayerMaster(CharacterMaster? master) { if (master != null && master.playerCharacterMasterController != null && master.playerCharacterMasterController.isConnected) { return !master.GetInRemoteOp(); } return false; } private static int EncodeLoss(float value) { value = SanitizeLoss(value); if (!(value <= 0f)) { return BitConverter.SingleToInt32Bits(value); } return 0; } private static float DecodeLoss(int encoded) { if (encoded <= 0) { return 0f; } return SanitizeLoss(BitConverter.Int32BitsToSingle(encoded)); } private static float SanitizeLoss(float value) { if (!float.IsNaN(value) && !float.IsInfinity(value) && !(value <= 0f)) { return value; } return 0f; } private static FieldInfo? FindBackingField(string propertyName) { return typeof(CharacterBody).GetField("<" + propertyName + ">k__BackingField", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); } } internal static class TeleporterArtifactHooks { [CompilerGenerated] private static class <>O { public static hook_Awake <0>__TeleporterInteraction_Awake; public static hook_OnDestroy <1>__TeleporterInteraction_OnDestroy; public static hook_Start <2>__TeleporterInteraction_Start; public static Manipulator <3>__CharacterBody_RecalculateStats_IL; public static Action <4>__CharacterBody_onBodyStartGlobal; public static Action <5>__ApplyBehemothMaximumBeforeVanillaReconcile; } private const float BehemothHealthMultiplier = 10f; private static readonly UnityAction TeleporterBossSpawnedAction = OnTeleporterBossSpawnedServer; private static bool installed; private static bool behemothStatsPatchSucceeded; private static ManualLogSource? log; internal static void Install(ManualLogSource logger) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Expected O, but got Unknown //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Expected O, but got Unknown //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Expected O, but got Unknown //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_008f: Expected O, but got Unknown if (!installed) { installed = true; log = logger; object obj = <>O.<0>__TeleporterInteraction_Awake; if (obj == null) { hook_Awake val = TeleporterInteraction_Awake; <>O.<0>__TeleporterInteraction_Awake = val; obj = (object)val; } TeleporterInteraction.Awake += (hook_Awake)obj; object obj2 = <>O.<1>__TeleporterInteraction_OnDestroy; if (obj2 == null) { hook_OnDestroy val2 = TeleporterInteraction_OnDestroy; <>O.<1>__TeleporterInteraction_OnDestroy = val2; obj2 = (object)val2; } TeleporterInteraction.OnDestroy += (hook_OnDestroy)obj2; object obj3 = <>O.<2>__TeleporterInteraction_Start; if (obj3 == null) { hook_Start val3 = TeleporterInteraction_Start; <>O.<2>__TeleporterInteraction_Start = val3; obj3 = (object)val3; } TeleporterInteraction.Start += (hook_Start)obj3; object obj4 = <>O.<3>__CharacterBody_RecalculateStats_IL; if (obj4 == null) { Manipulator val4 = CharacterBody_RecalculateStats_IL; <>O.<3>__CharacterBody_RecalculateStats_IL = val4; obj4 = (object)val4; } CharacterBody.RecalculateStats += (Manipulator)obj4; CharacterBody.onBodyStartGlobal += CharacterBody_onBodyStartGlobal; } } internal static void Uninstall() { //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Expected O, but got Unknown //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Expected O, but got Unknown //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Expected O, but got Unknown //IL_009e: 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_00a9: Expected O, but got Unknown if (installed) { installed = false; CharacterBody.onBodyStartGlobal -= CharacterBody_onBodyStartGlobal; object obj = <>O.<3>__CharacterBody_RecalculateStats_IL; if (obj == null) { Manipulator val = CharacterBody_RecalculateStats_IL; <>O.<3>__CharacterBody_RecalculateStats_IL = val; obj = (object)val; } CharacterBody.RecalculateStats -= (Manipulator)obj; object obj2 = <>O.<2>__TeleporterInteraction_Start; if (obj2 == null) { hook_Start val2 = TeleporterInteraction_Start; <>O.<2>__TeleporterInteraction_Start = val2; obj2 = (object)val2; } TeleporterInteraction.Start -= (hook_Start)obj2; object obj3 = <>O.<1>__TeleporterInteraction_OnDestroy; if (obj3 == null) { hook_OnDestroy val3 = TeleporterInteraction_OnDestroy; <>O.<1>__TeleporterInteraction_OnDestroy = val3; obj3 = (object)val3; } TeleporterInteraction.OnDestroy -= (hook_OnDestroy)obj3; object obj4 = <>O.<0>__TeleporterInteraction_Awake; if (obj4 == null) { hook_Awake val4 = TeleporterInteraction_Awake; <>O.<0>__TeleporterInteraction_Awake = val4; obj4 = (object)val4; } TeleporterInteraction.Awake -= (hook_Awake)obj4; behemothStatsPatchSucceeded = false; log = null; } } private static void TeleporterInteraction_Awake(orig_Awake orig, TeleporterInteraction self) { orig.Invoke(self); if (NetworkServer.active) { AddBossDirectorListener(self.bossDirector); if ((Object)(object)self.companionBoss != (Object)(object)self.bossDirector) { AddBossDirectorListener(self.companionBoss); } } } private static void TeleporterInteraction_OnDestroy(orig_OnDestroy orig, TeleporterInteraction self) { if (NetworkServer.active) { RemoveBossDirectorListener(self.bossDirector); if ((Object)(object)self.companionBoss != (Object)(object)self.bossDirector) { RemoveBossDirectorListener(self.companionBoss); } } orig.Invoke(self); } private static void TeleporterInteraction_Start(orig_Start orig, TeleporterInteraction self) { orig.Invoke(self); if (!NetworkServer.active || !ArtifactRegistry.IsEnabled(ArtifactRegistry.Mountainous)) { return; } if (!Object.op_Implicit((Object)(object)self.bossGroup)) { ManualLogSource? obj = log; if (obj != null) { obj.LogWarning((object)("Mountainous artifact found teleporter '" + ((Object)self).name + "' without a BossGroup; the two mountain stacks could not be applied.")); } } else { self.AddShrineStack(); self.AddShrineStack(); } } private static void AddBossDirectorListener(CombatDirector? director) { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Expected O, but got Unknown //IL_0025: Expected O, but got Unknown if (director != null && Object.op_Implicit((Object)(object)director)) { OnSpawnedServer obj = director.onSpawnedServer; if (obj == null) { OnSpawnedServer val = new OnSpawnedServer(); OnSpawnedServer val2 = val; director.onSpawnedServer = val; obj = val2; } ((UnityEvent)(object)obj).RemoveListener(TeleporterBossSpawnedAction); ((UnityEvent)(object)obj).AddListener(TeleporterBossSpawnedAction); } } private static void RemoveBossDirectorListener(CombatDirector? director) { if (director != null && Object.op_Implicit((Object)(object)director)) { ((UnityEvent)(object)director.onSpawnedServer)?.RemoveListener(TeleporterBossSpawnedAction); } } private static void OnTeleporterBossSpawnedServer(GameObject spawnedObject) { //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Invalid comparison between Unknown and I4 if (!NetworkServer.active || !Object.op_Implicit((Object)(object)spawnedObject) || !ArtifactRegistry.IsEnabled(ArtifactRegistry.Behemoth)) { return; } CharacterMaster val = spawnedObject.GetComponent(); if (!Object.op_Implicit((Object)(object)val)) { CharacterBody component = spawnedObject.GetComponent(); val = (Object.op_Implicit((Object)(object)component) ? component.master : null); } if (val != null && Object.op_Implicit((Object)(object)val) && (int)val.teamIndex != 1 && !Object.op_Implicit((Object)(object)((Component)val).GetComponent())) { if (!Object.op_Implicit((Object)(object)((Component)val).GetComponent())) { ((Component)val).gameObject.AddComponent(); } CharacterBody body = val.GetBody(); if (Object.op_Implicit((Object)(object)body)) { ApplyBehemothToBody(body); } } } private static void CharacterBody_onBodyStartGlobal(CharacterBody body) { if (NetworkServer.active) { ApplyBehemothToBody(body); } } private static void ApplyBehemothToBody(CharacterBody body) { CharacterMaster master = body.master; if (behemothStatsPatchSucceeded && ArtifactRegistry.IsEnabled(ArtifactRegistry.Behemoth) && Object.op_Implicit((Object)(object)master) && Object.op_Implicit((Object)(object)((Component)master).GetComponent()) && !body.HasBuff(ArtifactRegistry.BehemothBossBuff)) { HealthComponent healthComponent = body.healthComponent; float num = (Object.op_Implicit((Object)(object)healthComponent) ? healthComponent.health : 0f); body.AddBuff(ArtifactRegistry.BehemothBossBuff); body.RecalculateStats(); if (Object.op_Implicit((Object)(object)healthComponent) && num > 0f) { healthComponent.Networkhealth = Mathf.Min(healthComponent.fullHealth, num * 10f); } } } private static void CharacterBody_RecalculateStats_IL(ILContext il) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown //IL_0120: Unknown result type (might be due to invalid IL or missing references) ILCursor val = new ILCursor(il); if (!val.TryGotoNext((MoveType)0, new Func[7] { (Instruction instruction) => ILPatternMatchingExt.MatchLdarg(instruction, 0), (Instruction instruction) => ILPatternMatchingExt.MatchLdarg(instruction, 0), (Instruction instruction) => ILPatternMatchingExt.MatchCallOrCallvirt(instruction, "get_maxHealth"), (Instruction instruction) => ILPatternMatchingExt.MatchLdarg(instruction, 0), (Instruction instruction) => ILPatternMatchingExt.MatchCallOrCallvirt(instruction, "get_maxShield"), (Instruction instruction) => instruction.OpCode == OpCodes.Add, (Instruction instruction) => ILPatternMatchingExt.MatchCallOrCallvirt(instruction, "set_maxBarrier") })) { behemothStatsPatchSucceeded = false; ManualLogSource? obj = log; if (obj != null) { obj.LogError((object)"Behemoth: failed to patch final CharacterBody maxima before vanilla health reconciliation; the x10 boss-health modifier is disabled to avoid health loss on later stat recalculations."); } } else { val.Emit(OpCodes.Ldarg_0); val.EmitDelegate>((Action)ApplyBehemothMaximumBeforeVanillaReconcile); behemothStatsPatchSucceeded = true; } } private static void ApplyBehemothMaximumBeforeVanillaReconcile(CharacterBody body) { if (ArtifactRegistry.IsEnabled(ArtifactRegistry.Behemoth) && body.HasBuff(ArtifactRegistry.BehemothBossBuff)) { body.maxHealth *= 10f; } } } internal sealed class TeleporterBehemothMasterMarker : MonoBehaviour { } internal static class VoidArtifactHooks { private static readonly string[] VoidCampSpawnCardAddresses = new string[3] { "RoR2/DLC1/VoidCamp/iscVoidCamp.asset", "RoR2/DLC1/Interactables/VoidCamp/iscVoidCamp.asset", "Assets/RoR2/DLC1/Interactables/VoidCamp/iscVoidCamp.asset" }; private const int SpawnAttempts = 32; private static ManualLogSource log = null; private static InteractableSpawnCard? voidCampSpawnCard; private static string? lastLoggedInfestationScene; private static bool missingVoidEliteLogged; internal static void Install(ManualLogSource logger) { //IL_0015: 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) log = logger; string[] voidCampSpawnCardAddresses = VoidCampSpawnCardAddresses; foreach (string text in voidCampSpawnCardAddresses) { try { voidCampSpawnCard = Addressables.LoadAssetAsync((object)text).WaitForCompletion(); if (Object.op_Implicit((Object)(object)voidCampSpawnCard)) { log.LogInfo((object)("Void artifact loaded the Void Seed spawn card from " + text + ".")); break; } } catch (Exception ex) { log.LogDebug((object)("Void artifact rejected spawn-card address " + text + ": " + ex.Message)); } } CharacterBody.onBodyStartGlobal += CharacterBody_onBodyStartGlobal; SceneDirector.onPostPopulateSceneServer += SceneDirector_onPostPopulateSceneServer; if (!Object.op_Implicit((Object)(object)voidCampSpawnCard)) { log.LogError((object)"Void artifact: could not load the Void Seed spawn card."); } } internal static void Uninstall() { CharacterBody.onBodyStartGlobal -= CharacterBody_onBodyStartGlobal; SceneDirector.onPostPopulateSceneServer -= SceneDirector_onPostPopulateSceneServer; voidCampSpawnCard = null; lastLoggedInfestationScene = null; missingVoidEliteLogged = false; } private static void CharacterBody_onBodyStartGlobal(CharacterBody body) { if (!NetworkServer.active || !ArtifactRegistry.IsEnabled(ArtifactRegistry.Void) || !Object.op_Implicit((Object)(object)body)) { return; } CharacterMaster master = body.master; if (Object.op_Implicit((Object)(object)master) && ApplyVoidInfestation(master, body)) { string text = (Object.op_Implicit((Object)(object)SceneCatalog.mostRecentSceneDef) ? SceneCatalog.mostRecentSceneDef.baseSceneName : "unknown scene"); if (!string.Equals(lastLoggedInfestationScene, text, StringComparison.Ordinal)) { lastLoggedInfestationScene = text; log.LogInfo((object)("Void artifact began infecting enemies on " + text + ".")); } } } private static bool ApplyVoidInfestation(CharacterMaster master, CharacterBody body) { //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Invalid comparison between Unknown and I4 //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0058: 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) if (Object.op_Implicit((Object)(object)master) && Object.op_Implicit((Object)(object)body) && !body.isPlayerControlled && Object.op_Implicit((Object)(object)body.teamComponent) && Object.op_Implicit((Object)(object)body.inventory) && (int)master.teamIndex != 4) { TeamMask enemyTeams = TeamMask.GetEnemyTeams((TeamIndex)1); if (((TeamMask)(ref enemyTeams)).HasTeam(master.teamIndex) && (body.bodyFlags & 2) == 0) { EliteDef val = Elites.Void; EquipmentDef val2 = (Object.op_Implicit((Object)(object)val) ? val.eliteEquipmentDef : null); if (!Object.op_Implicit((Object)(object)val2)) { if (!missingVoidEliteLogged) { missingVoidEliteLogged = true; log.LogWarning((object)"Void artifact could not resolve the Voidtouched elite equipment."); } return false; } master.teamIndex = (TeamIndex)4; body.teamComponent.teamIndex = (TeamIndex)4; body.inventory.SetEquipmentIndex(val2.equipmentIndex, false); BaseAI component = ((Component)master).GetComponent(); if (Object.op_Implicit((Object)(object)component)) { component.enemyAttention = 0f; component.ForceAcquireNearestEnemyIfNoCurrentEnemy(); } body.MarkAllStatsDirty(); return true; } } return false; } private static void SceneDirector_onPostPopulateSceneServer(SceneDirector sceneDirector) { //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Invalid comparison between Unknown and I4 //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_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Expected O, but got Unknown //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Expected O, but got Unknown if (!NetworkServer.active || !ArtifactRegistry.IsEnabled(ArtifactRegistry.Void) || !Object.op_Implicit((Object)(object)voidCampSpawnCard) || !Object.op_Implicit((Object)(object)DirectorCore.instance) || HasVoidCamp()) { return; } SceneDef mostRecentSceneDef = SceneCatalog.mostRecentSceneDef; if (!Object.op_Implicit((Object)(object)mostRecentSceneDef) || (int)mostRecentSceneDef.sceneType != 1) { return; } Xoroshiro128Plus val = Run.instance?.stageRng; if (val == null) { return; } for (int i = 0; i < 32; i++) { DirectorPlacementRule val2 = new DirectorPlacementRule { placementMode = (PlacementMode)4, preventOverhead = true }; DirectorSpawnRequest val3 = new DirectorSpawnRequest((SpawnCard)(object)voidCampSpawnCard, val2, val); if (Object.op_Implicit((Object)(object)DirectorCore.instance.TrySpawnObject(val3))) { log.LogInfo((object)("Void artifact spawned a Void Seed on " + mostRecentSceneDef.baseSceneName + ".")); return; } } log.LogWarning((object)("Void artifact could not place a Void Seed on " + mostRecentSceneDef.baseSceneName + ".")); } private static bool HasVoidCamp() { CampDirector[] array = Object.FindObjectsOfType(); foreach (CampDirector val in array) { if (Object.op_Implicit((Object)(object)val) && ((Object)((Component)val).gameObject).name.IndexOf("VoidCamp", StringComparison.OrdinalIgnoreCase) >= 0) { return true; } } return false; } } internal static class CalamityChallengesLogbookModule { private sealed class ChallengeDefinition { internal string Identifier { get; } internal string NameToken => "ACHIEVEMENT_" + Identifier.ToUpperInvariant() + "_NAME"; internal string DescriptionToken => "ACHIEVEMENT_" + Identifier.ToUpperInvariant() + "_DESCRIPTION"; internal string BodyName { get; } internal bool RequiresRainstorm { get; } internal bool RequiresLoop { get; } internal Func GetRequiredArtifacts { get; } internal string IconBodyName { get; } internal bool UsesRadianceAchievementIcon { get; } internal string ScoreStatName { get; } internal string IndexStatName { get; } internal StatDef? HighestDifficultyScoreStat { get; set; } internal StatDef? HighestDifficultyIndexStat { get; set; } internal ChallengeDefinition(string identifier, string bodyName, bool requiresRainstorm, bool requiresLoop, Func getRequiredArtifacts, string iconBodyName, bool usesRadianceAchievementIcon, string scoreStatName, string indexStatName) { Identifier = identifier; BodyName = bodyName; RequiresRainstorm = requiresRainstorm; RequiresLoop = requiresLoop; GetRequiredArtifacts = getRequiredArtifacts; IconBodyName = iconBodyName; UsesRadianceAchievementIcon = usesRadianceAchievementIcon; ScoreStatName = scoreStatName; IndexStatName = indexStatName; } } [CompilerGenerated] private static class <>O { public static Action <0>__PrepareAchievementDefinitions; public static Action <1>__InjectCategory; public static Action <2>__RecordHighestCompletedDifficulties; public static BuildEntriesDelegate <3>__BuildEntries; public static Action <4>__InitializeChallenge; public static GetStatusDelegate <5>__GetChallengeStatus; public static GetTooltipContentDelegate <6>__GetChallengeTooltip; } private const string CategoryToken = "LOGBOOK_CATEGORY_CALAMITY_CHALLENGES"; private const string HighestDifficultyToken = "CALAMITY_CHALLENGE_HIGHEST_DIFFICULTY"; private const string NotCompletedToken = "CALAMITY_CHALLENGE_NOT_COMPLETED"; private const string RadianceIconResourceName = "HurricaneDifficulty.Assets.Challenges.radiance_achievement.png"; private static readonly ChallengeDefinition[] Challenges = new ChallengeDefinition[5] { new ChallengeDefinition("CalamityLoaderDestinyDesolation", "LoaderBody", requiresRainstorm: true, requiresLoop: false, () => (ArtifactDef?[])(object)new ArtifactDef[2] { ArtifactRegistry.Destiny, ArtifactRegistry.Desolation }, "LoaderBody", usesRadianceAchievementIcon: false, "calamityChallengeLoaderDestinyDesolationHighestDifficultyScore", "calamityChallengeLoaderDestinyDesolationHighestDifficultyIndex"), new ChallengeDefinition("CalamityHuntressAtrophy", "HuntressBody", requiresRainstorm: true, requiresLoop: false, () => (ArtifactDef?[])(object)new ArtifactDef[1] { ArtifactRegistry.Atrophy }, "HuntressBody", usesRadianceAchievementIcon: false, "calamityChallengeHuntressAtrophyHighestDifficultyScore", "calamityChallengeHuntressAtrophyHighestDifficultyIndex"), new ChallengeDefinition("CalamityCaptainUltimateStrike", "CaptainBody", requiresRainstorm: true, requiresLoop: false, () => (ArtifactDef?[])(object)new ArtifactDef[3] { Artifacts.Prestige, ArtifactRegistry.Mountainous, ArtifactRegistry.Behemoth }, "CaptainBody", usesRadianceAchievementIcon: false, "calamityChallengeCaptainUltimateStrikeHighestDifficultyScore", "calamityChallengeCaptainUltimateStrikeHighestDifficultyIndex"), new ChallengeDefinition("CalamityEngineerArmsRace", "EngiBody", requiresRainstorm: true, requiresLoop: true, () => (ArtifactDef?[])(object)new ArtifactDef[2] { ArtifactRegistry.Infinite, ArtifactRegistry.Mirror }, "EngiBody", usesRadianceAchievementIcon: false, "calamityChallengeEngineerArmsRaceHighestDifficultyScore", "calamityChallengeEngineerArmsRaceHighestDifficultyIndex"), new ChallengeDefinition("CalamityRadiance", string.Empty, requiresRainstorm: false, requiresLoop: false, () => (ArtifactDef?[])(object)new ArtifactDef[1] { ArtifactRegistry.Radiance }, string.Empty, usesRadianceAchievementIcon: true, "calamityChallengeRadianceHighestDifficultyScore", "calamityChallengeRadianceHighestDifficultyIndex") }; private static readonly Dictionary ChallengeByIdentifier = Challenges.ToDictionary((ChallengeDefinition challenge) => challenge.Identifier, StringComparer.Ordinal); private static readonly HashSet ChallengeIdentifiers = new HashSet(Challenges.Select((ChallengeDefinition challenge) => challenge.Identifier), StringComparer.Ordinal); private static readonly Dictionary PortraitSprites = new Dictionary(StringComparer.Ordinal); private static ManualLogSource log = null; private static Sprite? radianceAchievementIcon; private static bool installed; internal static void Install(ManualLogSource logger) { if (!installed) { installed = true; log = logger; radianceAchievementIcon = Plugin.LoadEmbeddedSprite("HurricaneDifficulty.Assets.Challenges.radiance_achievement.png", "texCalamityRadianceAchievement"); RegisterLanguageTokens(); RegisterStats(); AchievementManager.onAchievementsRegistered += PrepareAchievementDefinitions; LogBookController.OnViewablesRegistered += InjectCategory; Run.onClientGameOverGlobal += RecordHighestCompletedDifficulties; if (((ResourceAvailability)(ref AchievementManager.availability)).available) { PrepareAchievementDefinitions(); } if (((ResourceAvailability)(ref BodyCatalog.availability)).available) { PrepareAchievementDefinitions(); } else { ((ResourceAvailability)(ref BodyCatalog.availability)).CallWhenAvailable((Action)PrepareAchievementDefinitions); } if (LogBookController.IsStaticDataReady) { InjectCategory(); } } } internal static void Uninstall() { if (installed) { installed = false; AchievementManager.onAchievementsRegistered -= PrepareAchievementDefinitions; LogBookController.OnViewablesRegistered -= InjectCategory; Run.onClientGameOverGlobal -= RecordHighestCompletedDifficulties; } } private static void RegisterLanguageTokens() { LanguageAPI.Add("LOGBOOK_CATEGORY_CALAMITY_CHALLENGES", "Calamity Challenges"); LanguageAPI.Add("LOGBOOK_CATEGORY_CALAMITY_CHALLENGES", "灾荒挑战", "zh-CN"); AddChallengeLanguage("CalamityLoaderDestinyDesolation", "Fist of Binding Chains", "As Loader, complete the game on Rainstorm or higher with only the Artifacts of Destiny and Desolation enabled; Command is optional.", "缚锁之拳", "使用装卸工,除可选的统率神器外,仅携带命运神器与荒芜神器,在暴雨或更高难度下通关游戏。"); AddChallengeLanguage("CalamityHuntressAtrophy", "Withering Dance", "As Huntress, complete the game on Rainstorm or higher with only the Artifact of Atrophy enabled; Command is optional.", "凋零之舞", "使用女猎人,除可选的统率神器外,仅携带凋亡神器,在暴雨或更高难度下通关游戏。"); AddChallengeLanguage("CalamityCaptainUltimateStrike", "Ultimate Strike", "As Captain, complete the game on Rainstorm or higher with only the Artifacts of Prestige, Mountain Ranges, and Behemoths enabled; Command is optional.", "终极打击", "使用船长,除可选的统率神器外,仅携带威望神器、群峦神器与巨兽神器,在暴雨或更高难度下通关游戏。"); AddChallengeLanguage("CalamityEngineerArmsRace", "Arms Race", "As Engineer, complete the game on Rainstorm or higher after at least one loop with only the Artifacts of Infinity and Mirrors enabled; Command is optional.", "军备竞赛", "使用工程师,除可选的统率神器外,仅携带无极神器与镜像神器,在暴雨或更高难度下完成至少一次循环后通关游戏。"); AddChallengeLanguage("CalamityRadiance", "Radiance", "Complete the game with only the Artifact of Radiance enabled; Command is optional.", "辐辉", "除可选的统率神器外,仅携带辐辉神器通关游戏。"); LanguageAPI.Add("CALAMITY_CHALLENGE_HIGHEST_DIFFICULTY", "Highest completed difficulty: {0}"); LanguageAPI.Add("CALAMITY_CHALLENGE_HIGHEST_DIFFICULTY", "已完成的最高难度:{0}", "zh-CN"); LanguageAPI.Add("CALAMITY_CHALLENGE_NOT_COMPLETED", "Not completed"); LanguageAPI.Add("CALAMITY_CHALLENGE_NOT_COMPLETED", "尚未完成", "zh-CN"); } private static void AddChallengeLanguage(string identifier, string englishName, string englishDescription, string chineseName, string chineseDescription) { string text = "ACHIEVEMENT_" + identifier.ToUpperInvariant(); LanguageAPI.Add(text + "_NAME", englishName); LanguageAPI.Add(text + "_DESCRIPTION", englishDescription); LanguageAPI.Add(text + "_NAME", chineseName, "zh-CN"); LanguageAPI.Add(text + "_DESCRIPTION", chineseDescription, "zh-CN"); } private static void RegisterStats() { ChallengeDefinition[] challenges = Challenges; foreach (ChallengeDefinition challengeDefinition in challenges) { challengeDefinition.HighestDifficultyScoreStat = StatDef.Find(challengeDefinition.ScoreStatName) ?? StatDef.Register(challengeDefinition.ScoreStatName, (StatRecordType)1, (StatDataType)1, 0.0, (DisplayValueFormatterDelegate)null); challengeDefinition.HighestDifficultyIndexStat = StatDef.Find(challengeDefinition.IndexStatName) ?? StatDef.Register(challengeDefinition.IndexStatName, (StatRecordType)2, (StatDataType)0, 0.0, (DisplayValueFormatterDelegate)null); } } private static void PrepareAchievementDefinitions() { if (!installed || !((ResourceAvailability)(ref AchievementManager.availability)).available) { return; } ChallengeDefinition[] challenges = Challenges; foreach (ChallengeDefinition challengeDefinition in challenges) { AchievementDef achievementDef = AchievementManager.GetAchievementDef(challengeDefinition.Identifier); if (achievementDef == null) { log.LogWarning((object)("Calamity challenge achievement definition was not registered: " + challengeDefinition.Identifier + ".")); continue; } Sprite val = (challengeDefinition.UsesRadianceAchievementIcon ? radianceAchievementIcon : GetPortraitSprite(challengeDefinition.IconBodyName)); if (Object.op_Implicit((Object)(object)val)) { achievementDef.SetAchievedIcon(val); } } } private static Sprite? GetPortraitSprite(string bodyName) { //IL_0028: 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_0093: Unknown result type (might be due to invalid IL or missing references) if (string.IsNullOrEmpty(bodyName) || !((ResourceAvailability)(ref BodyCatalog.availability)).available) { return null; } if (PortraitSprites.TryGetValue(bodyName, out Sprite value)) { return value; } Texture obj = BodyCatalog.GetBodyPrefabBodyComponent(BodyCatalog.FindBodyIndex(bodyName))?.portraitIcon; Texture2D val = (Texture2D)(object)((obj is Texture2D) ? obj : null); if (val == null || !Object.op_Implicit((Object)(object)val)) { log.LogWarning((object)("Portrait texture was unavailable for challenge body " + bodyName + ".")); return null; } Sprite val2 = Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f), 100f); ((Object)val2).name = "texCalamityChallenge" + bodyName; PortraitSprites.Add(bodyName, val2); return val2; } private static void InjectCategory() { //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_006f: 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_0097: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Expected O, but got Unknown //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Expected O, but got Unknown CategoryDef[] categories = LogBookController.categories; if (categories == null || categories.Length == 0) { return; } FilterChallengesOutOfVanillaCategory(categories); DisableVanillaChallengeViewables(); if (categories.Any((CategoryDef category) => category.nameToken == "LOGBOOK_CATEGORY_CALAMITY_CHALLENGES")) { return; } GameObject achievementEntryIcon = CommonAssets.achievementEntryIcon; if (!Object.op_Implicit((Object)(object)achievementEntryIcon)) { log.LogWarning((object)"The achievement logbook prefab was unavailable; Calamity Challenges was not added."); return; } CategoryDef val = new CategoryDef { nameToken = "LOGBOOK_CATEGORY_CALAMITY_CHALLENGES", iconPrefab = achievementEntryIcon }; object obj = <>O.<3>__BuildEntries; if (obj == null) { BuildEntriesDelegate val2 = BuildEntries; <>O.<3>__BuildEntries = val2; obj = (object)val2; } val.buildEntries = (BuildEntriesDelegate)obj; val.initializeElementGraphics = InitializeChallenge; val.viewableNode = EnsureViewableTree(); CategoryDef val3 = val; int num = Array.FindIndex(categories, (CategoryDef category) => category.nameToken == "LOGBOOK_CATEGORY_ACHIEVEMENTS"); int num2 = ((num >= 0) ? (num + 1) : categories.Length); CategoryDef[] array = (CategoryDef[])(object)new CategoryDef[categories.Length + 1]; Array.Copy(categories, 0, array, 0, num2); array[num2] = val3; Array.Copy(categories, num2, array, num2 + 1, categories.Length - num2); LogBookController.categories = array; log.LogInfo((object)$"Added {Challenges.Length} Calamity Challenges after the vanilla Challenges category."); } private static void FilterChallengesOutOfVanillaCategory(CategoryDef[] categories) { //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Expected O, but got Unknown CategoryDef val = ((IEnumerable)categories).FirstOrDefault((Func)((CategoryDef category) => category.nameToken == "LOGBOOK_CATEGORY_ACHIEVEMENTS")); if (val == null) { return; } Entry[] array = val.BuildEntries((UserProfile)null); Entry[] filteredEntries = array.Where(delegate(Entry entry) { object extraData = entry.extraData; AchievementDef val2 = (AchievementDef)((extraData is AchievementDef) ? extraData : null); return val2 == null || !ChallengeIdentifiers.Contains(val2.identifier); }).ToArray(); if (filteredEntries.Length != array.Length) { val.buildEntries = (BuildEntriesDelegate)((UserProfile _) => filteredEntries); } } private static void DisableVanillaChallengeViewables() { ChallengeDefinition[] challenges = Challenges; foreach (ChallengeDefinition challengeDefinition in challenges) { Node val = ViewablesCatalog.FindNode("Logbook/LOGBOOK_CATEGORY_ACHIEVEMENTS/" + challengeDefinition.NameToken); if (val != null) { val.shouldShowUnviewed = (UserProfile _) => false; } } } private static Node EnsureViewableTree() { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Expected O, but got Unknown //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Expected O, but got Unknown Node val = ViewablesCatalog.FindNode("LOGBOOK_CATEGORY_CALAMITY_CHALLENGES/"); if (val != null) { return val; } Node val2 = new Node("LOGBOOK_CATEGORY_CALAMITY_CHALLENGES", true, (Node)null); ChallengeDefinition[] challenges = Challenges; foreach (ChallengeDefinition challenge in challenges) { Node entryNode = new Node(challenge.NameToken, false, val2); entryNode.shouldShowUnviewed = (UserProfile viewerProfile) => viewerProfile.HasAchievement(challenge.Identifier) && !viewerProfile.HasViewedViewable(entryNode.fullName); } ViewablesCatalog.AddNodeToRoot(val2); return val2; } private static Entry[] BuildEntries(UserProfile viewerProfile) { //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_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_0064: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Expected O, but got Unknown //IL_00ce: Expected O, but got Unknown //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Expected O, but got Unknown List list = new List(Challenges.Length); ChallengeDefinition[] challenges = Challenges; foreach (ChallengeDefinition challengeDefinition in challenges) { AchievementDef achievementDef = AchievementManager.GetAchievementDef(challengeDefinition.Identifier); if (achievementDef != null) { Entry val = new Entry { nameToken = achievementDef.nameToken, color = Color32.op_Implicit(ColorCatalog.GetColor((ColorIndex)16)), iconSprite = achievementDef.GetAchievedIcon(), extraData = achievementDef, viewableNode = ViewablesCatalog.FindNode("LOGBOOK_CATEGORY_CALAMITY_CHALLENGES/" + challengeDefinition.NameToken) }; object obj = <>O.<5>__GetChallengeStatus; if (obj == null) { GetStatusDelegate val2 = GetChallengeStatus; <>O.<5>__GetChallengeStatus = val2; obj = (object)val2; } val.getStatusImplementation = (GetStatusDelegate)obj; object obj2 = <>O.<6>__GetChallengeTooltip; if (obj2 == null) { GetTooltipContentDelegate val3 = GetChallengeTooltip; <>O.<6>__GetChallengeTooltip = val3; obj2 = (object)val3; } val.getTooltipContentImplementation = (GetTooltipContentDelegate)obj2; list.Add(val); } } return list.ToArray(); } private static EntryStatus GetChallengeStatus(in Entry entry, UserProfile viewerProfile) { ChallengeDefinition challengeDefinition = GetChallengeDefinition(in entry); if (challengeDefinition != null && viewerProfile.HasAchievement(challengeDefinition.Identifier)) { return (EntryStatus)4; } return (EntryStatus)3; } private static TooltipContent GetChallengeTooltip(in Entry entry, UserProfile viewerProfile, EntryStatus entryStatus) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0032: 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_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) ChallengeDefinition challengeDefinition = GetChallengeDefinition(in entry); if (challengeDefinition == null) { return default(TooltipContent); } return new TooltipContent { titleToken = challengeDefinition.NameToken, titleColor = entry.color, overrideBodyText = BuildChallengeDescription(challengeDefinition, viewerProfile), bodyColor = Color.white }; } private static ChallengeDefinition? GetChallengeDefinition(in Entry entry) { object extraData = entry.extraData; AchievementDef val = (AchievementDef)((extraData is AchievementDef) ? extraData : null); if (val == null || !ChallengeByIdentifier.TryGetValue(val.identifier, out ChallengeDefinition value)) { return null; } return value; } internal static bool MeetsRequirements(string identifier, Run run, RunReport runReport, LocalUser localUser, out DifficultyIndex difficultyIndex) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Expected I4, but got Unknown //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_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Invalid comparison between Unknown and I4 //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) difficultyIndex = (DifficultyIndex)(int)runReport.ruleBook.FindDifficulty(); if (!ChallengeByIdentifier.TryGetValue(identifier, out ChallengeDefinition value) || !Object.op_Implicit((Object)(object)runReport.gameEnding) || !runReport.gameEnding.isWin) { return false; } DifficultyDef difficultyDef = DifficultyCatalog.GetDifficultyDef(difficultyIndex); if (difficultyDef == null) { return false; } if (value.RequiresRainstorm) { DifficultyDef difficultyDef2 = DifficultyCatalog.GetDifficultyDef((DifficultyIndex)1); if (difficultyDef2 == null || difficultyDef.scalingValue < difficultyDef2.scalingValue) { return false; } } if (!string.IsNullOrEmpty(value.BodyName)) { PlayerInfo val = runReport.FindPlayerInfo(localUser); BodyIndex val2 = BodyCatalog.FindBodyIndex(value.BodyName); if (val == null || (int)val2 == -1 || val.bodyIndex != val2) { return false; } } if (value.RequiresLoop && run.loopClearCount < 1) { return false; } if (!ResonatorModules.ArtifactsActive) { return false; } return HasOnlyRequiredArtifacts(runReport.ruleBook, value.GetRequiredArtifacts()); } private static bool HasOnlyRequiredArtifacts(RuleBook ruleBook, ArtifactDef?[] requiredArtifactDefs) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Invalid comparison between Unknown and I4 //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Invalid comparison between Unknown and I4 //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) HashSet hashSet = new HashSet(); foreach (ArtifactDef val in requiredArtifactDefs) { if (val == null || (int)val.artifactIndex == -1) { return false; } hashSet.Add(val.artifactIndex); } HashSet hashSet2 = new HashSet(); for (int j = 0; j < RuleCatalog.ruleCount; j++) { ArtifactIndex artifactIndex = ruleBook.GetRuleChoice(j).artifactIndex; if ((int)artifactIndex != -1) { hashSet2.Add(artifactIndex); } } if (!hashSet.All(hashSet2.Contains)) { return false; } hashSet2.ExceptWith(hashSet); hashSet2.Remove(Artifacts.Command.artifactIndex); return hashSet2.Count == 0; } private static void RecordHighestCompletedDifficulties(Run run, RunReport runReport) { //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) foreach (LocalUser readOnlyLocalUsers in LocalUserManager.readOnlyLocalUsersList) { ChallengeDefinition[] challenges = Challenges; foreach (ChallengeDefinition challengeDefinition in challenges) { if (!MeetsRequirements(challengeDefinition.Identifier, run, runReport, readOnlyLocalUsers, out var difficultyIndex)) { continue; } UserProfile userProfile = readOnlyLocalUsers.userProfile; if (!CanAccessStats(userProfile, challengeDefinition)) { continue; } DifficultyDef difficultyDef = DifficultyCatalog.GetDifficultyDef(difficultyIndex); if (difficultyDef != null) { double difficultyScore = GetDifficultyScore(difficultyIndex, difficultyDef); double statValueDouble = userProfile.statSheet.GetStatValueDouble(challengeDefinition.HighestDifficultyScoreStat); if (!(difficultyScore <= statValueDouble)) { userProfile.statSheet.PushStatValue(challengeDefinition.HighestDifficultyScoreStat, difficultyScore); userProfile.statSheet.PushStatValue(challengeDefinition.HighestDifficultyIndexStat, EncodeDifficultyIndex(difficultyIndex)); userProfile.RequestEventualSave(); } } } } } private static bool CanAccessStats(UserProfile userProfile, ChallengeDefinition challenge) { StatDef highestDifficultyScoreStat = challenge.HighestDifficultyScoreStat; StatDef highestDifficultyIndexStat = challenge.HighestDifficultyIndexStat; int num = userProfile.statSheet.fields.Length; if (highestDifficultyScoreStat != null && highestDifficultyIndexStat != null && highestDifficultyScoreStat.index >= 0 && highestDifficultyScoreStat.index < num && highestDifficultyIndexStat.index >= 0) { return highestDifficultyIndexStat.index < num; } return false; } private static double GetDifficultyScore(DifficultyIndex difficultyIndex, DifficultyDef difficultyDef) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Invalid comparison between Unknown and I4 //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Invalid comparison between Unknown and I4 //IL_0012: 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_0016: Unknown result type (might be due to invalid IL or missing references) double num = difficultyDef.scalingValue; if ((int)difficultyIndex >= 3 && (int)difficultyIndex <= 10) { num += (double)(difficultyIndex - 3 + 1) * 0.001; } return num; } private static ulong EncodeDifficultyIndex(DifficultyIndex difficultyIndex) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Expected I4, but got Unknown int num = (int)difficultyIndex; return (ulong)(uint)((num << 1) ^ (num >> 31)) + 1uL; } private static DifficultyIndex DecodeDifficultyIndex(ulong encodedValue) { uint num = (uint)(encodedValue - 1); return (DifficultyIndex)((num >> 1) ^ (0 - (num & 1))); } private static DifficultyDef? GetHighestCompletedDifficulty(UserProfile viewerProfile, ChallengeDefinition challenge) { //IL_003d: Unknown result type (might be due to invalid IL or missing references) if (!CanAccessStats(viewerProfile, challenge) || viewerProfile.statSheet.GetStatValueDouble(challenge.HighestDifficultyScoreStat) <= 0.0) { return null; } ulong statValueULong = viewerProfile.statSheet.GetStatValueULong(challenge.HighestDifficultyIndexStat); if (statValueULong != 0L) { return DifficultyCatalog.GetDifficultyDef(DecodeDifficultyIndex(statValueULong)); } return null; } private static string BuildChallengeDescription(ChallengeDefinition challenge, UserProfile viewerProfile) { //IL_0031: Unknown result type (might be due to invalid IL or missing references) string text = Language.GetString(challenge.DescriptionToken); DifficultyDef highestCompletedDifficulty = GetHighestCompletedDifficulty(viewerProfile, challenge); string text2; if (highestCompletedDifficulty == null) { text2 = Language.GetString("CALAMITY_CHALLENGE_NOT_COMPLETED"); } else { string text3 = Language.GetString(highestCompletedDifficulty.nameToken); string text4 = ColorUtility.ToHtmlStringRGB(highestCompletedDifficulty.color); text2 = "" + text3 + ""; } return text + "\n\n" + Language.GetStringFormatted("CALAMITY_CHALLENGE_HIGHEST_DIFFICULTY", new object[1] { text2 }); } private static void InitializeChallenge(GameObject gameObject, Entry entry, EntryStatus status, UserProfile userProfile) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Expected O, but got Unknown //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Expected I4, but got Unknown //IL_00da: 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_0125: Unknown result type (might be due to invalid IL or missing references) //IL_012a: Unknown result type (might be due to invalid IL or missing references) //IL_01db: Unknown result type (might be due to invalid IL or missing references) //IL_0215: Unknown result type (might be due to invalid IL or missing references) //IL_021a: Unknown result type (might be due to invalid IL or missing references) //IL_0224: Unknown result type (might be due to invalid IL or missing references) //IL_0239: Unknown result type (might be due to invalid IL or missing references) //IL_024e: Unknown result type (might be due to invalid IL or missing references) //IL_0263: Unknown result type (might be due to invalid IL or missing references) //IL_027b: Unknown result type (might be due to invalid IL or missing references) //IL_0284: Unknown result type (might be due to invalid IL or missing references) //IL_02a0: Unknown result type (might be due to invalid IL or missing references) AchievementDef val = (AchievementDef)entry.extraData; ChallengeDefinition challenge = ChallengeByIdentifier[val.identifier]; ChildLocator component = gameObject.GetComponent(); HGButton component2 = gameObject.GetComponent(); if (Object.op_Implicit((Object)(object)component2)) { ((MPButton)component2).disablePointerClick = true; ((MPButton)component2).disableGamepadClick = true; } TextMeshProUGUI component3 = ((Component)component.FindChild("NameLabel")).GetComponent(); TextMeshProUGUI component4 = ((Component)component.FindChild("DescriptionLabel")).GetComponent(); RawImage component5 = ((Component)component.FindChild("RewardImage")).GetComponent(); ((TMP_Text)component3).text = Language.GetString(val.nameToken); ((TMP_Text)component4).text = BuildChallengeDescription(challenge, userProfile); Texture val2 = null; Sprite val3 = null; Color color = Color.white; switch ((int)status) { case 1: val2 = (Texture)(object)CommonAssets.wipIcon; break; case 2: val2 = (Texture)(object)CommonAssets.lockIcon; color = Color.black; ((TMP_Text)component3).text = Language.GetString("UNIDENTIFIED"); ((TMP_Text)component4).text = Language.GetString("UNIDENTIFIED_DESCRIPTION"); ((Component)component.FindChild("CantBeAchieved")).gameObject.SetActive(true); break; case 3: val2 = (Texture)(object)CommonAssets.lockIcon; color = Color.gray; ((Component)component.FindChild("ProgressTowardsUnlocking")).GetComponent().fillAmount = 0f; break; case 4: val3 = entry.iconSprite; ((Component)component.FindChild("HasBeenUnlocked")).gameObject.SetActive(true); break; case 5: val3 = entry.iconSprite; ((Color)(ref color))..ctor(1f, 0.8f, 0.5f, 1f); ((Component)component.FindChild("HasBeenUnlocked")).gameObject.SetActive(true); break; case 0: ((Component)component.FindChild("RewardImageContainer")).gameObject.SetActive(true); ((TMP_Text)component3).text = string.Empty; ((TMP_Text)component4).text = string.Empty; break; default: throw new ArgumentOutOfRangeException("status", status, null); } if (Object.op_Implicit((Object)(object)val3)) { Sprite obj = val3; Texture2D texture = obj.texture; Vector2 val4 = default(Vector2); ((Vector2)(ref val4))..ctor((float)((Texture)texture).width, (float)((Texture)texture).height); Rect rect = obj.rect; ((Rect)(ref rect)).x = ((Rect)(ref rect)).x / val4.x; ((Rect)(ref rect)).y = ((Rect)(ref rect)).y / val4.y; ((Rect)(ref rect)).width = ((Rect)(ref rect)).width / val4.x; ((Rect)(ref rect)).height = ((Rect)(ref rect)).height / val4.y; component5.texture = (Texture)(object)texture; component5.uvRect = rect; ((Graphic)component5).color = color; } else if (Object.op_Implicit((Object)(object)val2)) { component5.texture = val2; ((Graphic)component5).color = color; } else { ((Behaviour)component5).enabled = false; } } } internal static class CommandTooltipsModule { [CompilerGenerated] private static class <>O { public static EventHandler <0>__OnSettingChanged; public static hook_SetPickupOptions <1>__PickupPickerPanelSetPickupOptions; public static UnityAction <2>__ConfigureOrClearTooltip; } private const string LegacyPluginGuid = "com.waterbucket.commandtooltips"; private static bool installed; private static bool hookInstalled; internal static void Install(ManualLogSource logger) { //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Expected O, but got Unknown if (installed) { return; } installed = true; if (Chainloader.PluginInfos.ContainsKey("com.waterbucket.commandtooltips")) { logger.LogWarning((object)"The standalone Command Tooltips plugin is still enabled. Its integrated hook was skipped; remove the old package after upgrading."); return; } hookInstalled = true; ResonatorModules.CommandTooltipsEnabled.SettingChanged += OnSettingChanged; object obj = <>O.<1>__PickupPickerPanelSetPickupOptions; if (obj == null) { hook_SetPickupOptions val = PickupPickerPanelSetPickupOptions; <>O.<1>__PickupPickerPanelSetPickupOptions = val; obj = (object)val; } PickupPickerPanel.SetPickupOptions += (hook_SetPickupOptions)obj; logger.LogInfo((object)"Installed the integrated, client-local Command Tooltips module."); } internal static void Uninstall() { //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Expected O, but got Unknown if (!installed) { return; } installed = false; if (hookInstalled) { hookInstalled = false; ResonatorModules.CommandTooltipsEnabled.SettingChanged -= OnSettingChanged; object obj = <>O.<1>__PickupPickerPanelSetPickupOptions; if (obj == null) { hook_SetPickupOptions val = PickupPickerPanelSetPickupOptions; <>O.<1>__PickupPickerPanelSetPickupOptions = val; obj = (object)val; } PickupPickerPanel.SetPickupOptions -= (hook_SetPickupOptions)obj; } ClearAllOwnedTooltips(); } private static void OnSettingChanged(object sender, EventArgs eventArgs) { if (!ResonatorModules.CommandTooltipsEnabled.Value) { ClearAllOwnedTooltips(); } } private static void PickupPickerPanelSetPickupOptions(orig_SetPickupOptions orig, PickupPickerPanel self, Option[] options) { if (!Object.op_Implicit((Object)(object)self) || self.pickupBaseContentReady == null || !ResonatorModules.CommandTooltipsEnabled.Value) { orig.Invoke(self, options); return; } ((UnityEvent)(object)self.pickupBaseContentReady).AddListener((UnityAction)ConfigureOrClearTooltip); try { orig.Invoke(self, options); } finally { ((UnityEvent)(object)self.pickupBaseContentReady).RemoveListener((UnityAction)ConfigureOrClearTooltip); } } private static void ConfigureOrClearTooltip(MPButton button, PickupDef pickupDef) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Invalid comparison between Unknown and I4 //IL_0020: 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_007f: Invalid comparison between Unknown and I4 //IL_002f: 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_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) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)button)) { return; } if (pickupDef == null) { ClearOwnedTooltip(button); return; } ItemDef val = (((int)pickupDef.itemIndex != -1) ? ItemCatalog.GetItemDef(pickupDef.itemIndex) : null); if (val != null) { ItemTierDef itemTierDef = ItemTierCatalog.GetItemTierDef(val.tier); SetTooltip(button, val.nameToken, FullDescriptionOrPickup(val.descriptionToken, val.pickupToken), Object.op_Implicit((Object)(object)itemTierDef) ? Color32.op_Implicit(ColorCatalog.GetColor(itemTierDef.colorIndex)) : pickupDef.baseColor); return; } EquipmentDef val2 = (((int)pickupDef.equipmentIndex != -1) ? EquipmentCatalog.GetEquipmentDef(pickupDef.equipmentIndex) : null); if (val2 != null) { SetTooltip(button, val2.nameToken, FullDescriptionOrPickup(val2.descriptionToken, val2.pickupToken), Color32.op_Implicit(ColorCatalog.GetColor(val2.colorIndex))); } else { ClearOwnedTooltip(button); } } private static void SetTooltip(MPButton button, string titleToken, string bodyToken, Color titleColor) { //IL_003f: 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_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) TooltipProvider orCreateOwnedTooltip = GetOrCreateOwnedTooltip(button); if (orCreateOwnedTooltip != null && Object.op_Implicit((Object)(object)orCreateOwnedTooltip)) { ((Behaviour)orCreateOwnedTooltip).enabled = true; orCreateOwnedTooltip.titleToken = titleToken; orCreateOwnedTooltip.bodyToken = bodyToken; orCreateOwnedTooltip.overrideTitleText = string.Empty; orCreateOwnedTooltip.overrideBodyText = string.Empty; orCreateOwnedTooltip.titleColor = titleColor; orCreateOwnedTooltip.bodyColor = Color.white; orCreateOwnedTooltip.disableTitleRichText = false; orCreateOwnedTooltip.disableBodyRichText = false; orCreateOwnedTooltip.AllowTooltipOnNavigationSelect = true; } } private static TooltipProvider? GetOrCreateOwnedTooltip(MPButton button) { CommandTooltipMarker commandTooltipMarker = ((Component)button).GetComponent(); if (commandTooltipMarker != null && Object.op_Implicit((Object)(object)commandTooltipMarker)) { TooltipProvider tooltip = commandTooltipMarker.Tooltip; if (tooltip != null && Object.op_Implicit((Object)(object)tooltip)) { return tooltip; } } TooltipProvider component = ((Component)button).GetComponent(); if (component != null && Object.op_Implicit((Object)(object)component)) { return null; } TooltipProvider val = ((Component)button).gameObject.AddComponent(); if (commandTooltipMarker == null || !Object.op_Implicit((Object)(object)commandTooltipMarker)) { commandTooltipMarker = ((Component)button).gameObject.AddComponent(); } commandTooltipMarker.Tooltip = val; return val; } private static void ClearOwnedTooltip(MPButton button) { CommandTooltipMarker component = ((Component)button).GetComponent(); if (component != null && Object.op_Implicit((Object)(object)component)) { TooltipProvider tooltip = component.Tooltip; if (tooltip != null && Object.op_Implicit((Object)(object)tooltip)) { ClearTooltip(tooltip); } } } private static void ClearAllOwnedTooltips() { CommandTooltipMarker[] array = Resources.FindObjectsOfTypeAll(); foreach (CommandTooltipMarker commandTooltipMarker in array) { if (Object.op_Implicit((Object)(object)commandTooltipMarker)) { TooltipProvider tooltip = commandTooltipMarker.Tooltip; if (tooltip != null && Object.op_Implicit((Object)(object)tooltip)) { ClearTooltip(tooltip); } } } } private static void ClearTooltip(TooltipProvider tooltip) { tooltip.titleToken = string.Empty; tooltip.bodyToken = string.Empty; tooltip.overrideTitleText = string.Empty; tooltip.overrideBodyText = string.Empty; ((Behaviour)tooltip).enabled = false; } private static string FullDescriptionOrPickup(string descriptionToken, string pickupToken) { if (!string.IsNullOrEmpty(descriptionToken)) { return descriptionToken; } return pickupToken; } } [DisallowMultipleComponent] internal sealed class CommandTooltipMarker : MonoBehaviour { [SerializeField] private TooltipProvider? tooltip; internal TooltipProvider? Tooltip { get { return tooltip; } set { tooltip = value; } } } [BepInPlugin("com.waterbucket.cataclysmresonator", "Resonators of the Soul", "0.25.33")] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [NetworkCompatibility(/*Could not decode attribute arguments.*/)] public sealed class Plugin : BaseUnityPlugin { [CompilerGenerated] private static class <>O { public static Func <0>__LoadEmbeddedSprite; public static StatHookEventHandler <1>__ApplyPlayerStats; public static hook_StartRun <2>__PreGameController_StartRun; public static Func <3>__GetBaseCardAffordabilityCredit; } public const string PluginGuid = "com.waterbucket.cataclysmresonator"; public const string PluginName = "Resonators of the Soul"; public const string PluginVersion = "0.25.33"; private const string CycloneNameToken = "CYCLONE_DIFFICULTY_NAME"; private const string CycloneDescriptionToken = "CYCLONE_DIFFICULTY_DESCRIPTION"; private const string CycloneIconResourceName = "HurricaneDifficulty.Assets.cyclone.png"; private const string HurricaneNameToken = "HURRICANE_DIFFICULTY_NAME"; private const string HurricaneDescriptionToken = "HURRICANE_DIFFICULTY_DESCRIPTION"; private const string HurricaneIconResourceName = "HurricaneDifficulty.Assets.hurricane.png"; private const string TempestNameToken = "TEMPEST_DIFFICULTY_NAME"; private const string TempestDescriptionToken = "TEMPEST_DIFFICULTY_DESCRIPTION"; private const string TempestIconResourceName = "HurricaneDifficulty.Assets.tempest.png"; private const string CataclysmNameToken = "CATACLYSM_DIFFICULTY_NAME"; private const string CataclysmDescriptionToken = "CATACLYSM_DIFFICULTY_DESCRIPTION"; private const string CataclysmIconResourceName = "HurricaneDifficulty.Assets.cataclysm.png"; private const string SolarStormNameToken = "SOLAR_STORM_DIFFICULTY_NAME"; private const string SolarStormDescriptionToken = "SOLAR_STORM_DIFFICULTY_DESCRIPTION"; private const string SolarStormIconResourceName = "HurricaneDifficulty.Assets.solarstorm.png"; private const string RuinDustwindNameToken = "RUIN_DUSTWIND_DIFFICULTY_NAME"; private const string RuinDustwindDescriptionToken = "RUIN_DUSTWIND_DIFFICULTY_DESCRIPTION"; private const string RuinDustwindIconResourceName = "HurricaneDifficulty.Assets.ruindustwind.png"; private const string ButianNameToken = "BUTIAN_DIFFICULTY_NAME"; private const string ButianDescriptionToken = "BUTIAN_DIFFICULTY_DESCRIPTION"; private const string ButianIconResourceName = "HurricaneDifficulty.Assets.butian.png"; private const float CycloneScalingValue = 3.7f; private const float HurricaneScalingValue = 4.4f; private const float TempestScalingValue = 5.6f; private const float CataclysmScalingValue = 7f; private const float SolarStormScalingValue = 8.4f; private const float RuinDustwindScalingValue = 12f; private const float ButianScalingValue = 15.32f; private const float AdditionalRegenMultiplier = 0.5f; private const float CycloneAdditionalRegenMultiplier = 0.75f; private const float SolarStormAdditionalRegenMultiplier = 0.25f; private const float InheritedDirectorThresholdMultiplier = 2f; private const float SolarStormMonsterCooldownMultiplier = 0.5f; private const float RuinDustwindAdditionalRegenMultiplier = 1f / 6f; public static DifficultyIndex CycloneDifficultyIndex { get; private set; } = (DifficultyIndex)(-1); public static DifficultyIndex HurricaneDifficultyIndex { get; private set; } = (DifficultyIndex)(-1); public static DifficultyIndex TempestDifficultyIndex { get; private set; } = (DifficultyIndex)(-1); public static DifficultyIndex CataclysmDifficultyIndex { get; private set; } = (DifficultyIndex)(-1); public static DifficultyIndex SolarStormDifficultyIndex { get; private set; } = (DifficultyIndex)(-1); public static DifficultyIndex RuinDustwindDifficultyIndex { get; private set; } = (DifficultyIndex)(-1); public static DifficultyIndex ButianDifficultyIndex { get; private set; } = (DifficultyIndex)(-1); private void Awake() { //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Expected O, but got Unknown //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Expected O, but got Unknown //IL_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_010b: Unknown result type (might be due to invalid IL or missing references) //IL_012a: Unknown result type (might be due to invalid IL or missing references) //IL_0149: Unknown result type (might be due to invalid IL or missing references) //IL_0168: Unknown result type (might be due to invalid IL or missing references) //IL_0187: Unknown result type (might be due to invalid IL or missing references) //IL_01a6: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Expected O, but got Unknown ResonatorModules.Bind(((BaseUnityPlugin)this).Config); ResonatorModules.Install(((BaseUnityPlugin)this).Logger); RiskOfOptionsIntegration.Install(((BaseUnityPlugin)this).Logger); CommandTooltipsModule.Install(((BaseUnityPlugin)this).Logger); RegisterLanguageTokens(); RegisterDifficulties(); ArtifactRegistry.RegisterAll(LoadEmbeddedSprite); ResonatorPrototypeModule.Register(((BaseUnityPlugin)this).Logger); CalamityChallengesLogbookModule.Install(((BaseUnityPlugin)this).Logger); ArtifactHooks.Install(((BaseUnityPlugin)this).Logger); object obj = <>O.<1>__ApplyPlayerStats; if (obj == null) { StatHookEventHandler val = ApplyPlayerStats; <>O.<1>__ApplyPlayerStats = val; obj = (object)val; } RecalculateStatsAPI.GetStatCoefficients += (StatHookEventHandler)obj; CombatDirector.AttemptSpawnOnTarget += new Manipulator(CombatDirector_AttemptSpawnOnTarget_IL); object obj2 = <>O.<2>__PreGameController_StartRun; if (obj2 == null) { hook_StartRun val2 = PreGameController_StartRun; <>O.<2>__PreGameController_StartRun = val2; obj2 = (object)val2; } PreGameController.StartRun += (hook_StartRun)obj2; PvPMode.Plugin.Initialize((BaseUnityPlugin)(object)this, ((BaseUnityPlugin)this).Logger); PantheonModule.Initialize((BaseUnityPlugin)(object)this, ((BaseUnityPlugin)this).Logger); ((BaseUnityPlugin)this).Logger.LogInfo((object)$"Registered Cyclone difficulty with index {CycloneDifficultyIndex}."); ((BaseUnityPlugin)this).Logger.LogInfo((object)$"Registered Hurricane difficulty with index {HurricaneDifficultyIndex}."); ((BaseUnityPlugin)this).Logger.LogInfo((object)$"Registered Tempest difficulty with index {TempestDifficultyIndex}."); ((BaseUnityPlugin)this).Logger.LogInfo((object)$"Registered Cataclysm difficulty with index {CataclysmDifficultyIndex}."); ((BaseUnityPlugin)this).Logger.LogInfo((object)$"Registered Solar Storm difficulty with index {SolarStormDifficultyIndex}."); ((BaseUnityPlugin)this).Logger.LogInfo((object)$"Registered Ruin Dustwind difficulty with index {RuinDustwindDifficultyIndex}."); ((BaseUnityPlugin)this).Logger.LogInfo((object)$"Registered Butian difficulty with index {ButianDifficultyIndex}."); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Resonators of the Soul 0.25.33 loaded as one modular plugin."); } private void OnDestroy() { //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Expected O, but got Unknown //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_0039: Expected O, but got Unknown //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Expected O, but got Unknown PantheonModule.Shutdown(); PvPMode.Plugin.Shutdown(); ResonatorSkillModule.Uninstall(); CalamityChallengesLogbookModule.Uninstall(); CommandTooltipsModule.Uninstall(); ArtifactHooks.Uninstall(); object obj = <>O.<1>__ApplyPlayerStats; if (obj == null) { StatHookEventHandler val = ApplyPlayerStats; <>O.<1>__ApplyPlayerStats = val; obj = (object)val; } RecalculateStatsAPI.GetStatCoefficients -= (StatHookEventHandler)obj; CombatDirector.AttemptSpawnOnTarget -= new Manipulator(CombatDirector_AttemptSpawnOnTarget_IL); object obj2 = <>O.<2>__PreGameController_StartRun; if (obj2 == null) { hook_StartRun val2 = PreGameController_StartRun; <>O.<2>__PreGameController_StartRun = val2; obj2 = (object)val2; } PreGameController.StartRun -= (hook_StartRun)obj2; RiskOfOptionsIntegration.Uninstall(); ResonatorModules.Uninstall(); } private static void RegisterLanguageTokens() { LanguageAPI.Add("CYCLONE_DIFFICULTY_NAME", "Cyclone"); LanguageAPI.Add("CYCLONE_DIFFICULTY_DESCRIPTION", "The winds begin to tighten.\n\n>Player Health Regeneration: -55%\n>Difficulty Adjustment: +85%"); LanguageAPI.Add("CYCLONE_DIFFICULTY_NAME", "气旋", "zh-CN"); LanguageAPI.Add("CYCLONE_DIFFICULTY_DESCRIPTION", "风势渐紧。\n\n>玩家生命值再生速度:-55%\n>难度调整:+85%", "zh-CN"); LanguageAPI.Add("HURRICANE_DIFFICULTY_NAME", "Hurricane"); LanguageAPI.Add("HURRICANE_DIFFICULTY_DESCRIPTION", "The storm has no eye.\n\n>Player Health Regeneration: -70%\n>Difficulty Adjustment: +120%"); LanguageAPI.Add("HURRICANE_DIFFICULTY_NAME", "飓风", "zh-CN"); LanguageAPI.Add("HURRICANE_DIFFICULTY_DESCRIPTION", "风暴无眼。\n\n>玩家生命值再生速度:-70%\n>难度调整:+120%", "zh-CN"); LanguageAPI.Add("TEMPEST_DIFFICULTY_NAME", "Tempest"); LanguageAPI.Add("TEMPEST_DIFFICULTY_DESCRIPTION", "The wild wind never relents.\n\n>Player Health Regeneration: -70%\n>Difficulty Adjustment: +180%\n>High-tier Monster Threshold: 50%"); LanguageAPI.Add("TEMPEST_DIFFICULTY_NAME", "荒风", "zh-CN"); LanguageAPI.Add("TEMPEST_DIFFICULTY_DESCRIPTION", "荒风永不停息。\n\n>玩家生命值再生速度:-70%\n>难度调整:+180%\n>高级怪物出现门槛:原来的50%", "zh-CN"); LanguageAPI.Add("CATACLYSM_DIFFICULTY_NAME", "Cataclysm"); LanguageAPI.Add("CATACLYSM_DIFFICULTY_DESCRIPTION", "The world breaks before you do.\n\n>Player Health Regeneration: -70%\n>Difficulty Adjustment: +250%\n>High-tier Monster Threshold: 50%"); LanguageAPI.Add("CATACLYSM_DIFFICULTY_NAME", "灾变", "zh-CN"); LanguageAPI.Add("CATACLYSM_DIFFICULTY_DESCRIPTION", "万物终将崩毁。\n\n>玩家生命值再生速度:-70%\n>难度调整:+250%\n>高级怪物出现门槛:原来的50%", "zh-CN"); LanguageAPI.Add("SOLAR_STORM_DIFFICULTY_NAME", "Solar Storm"); LanguageAPI.Add("SOLAR_STORM_DIFFICULTY_DESCRIPTION", "The sun itself turns hostile.\n\n>Player Health Regeneration: -85%\n>Difficulty Adjustment: +320%\n>High-tier Monster Threshold: 50%\n>Monster Skill Cooldowns: -50%"); LanguageAPI.Add("SOLAR_STORM_DIFFICULTY_NAME", "太阳风暴", "zh-CN"); LanguageAPI.Add("SOLAR_STORM_DIFFICULTY_DESCRIPTION", "烈日亦成为敌人。\n\n>玩家生命值再生速度:-85%\n>难度调整:+320%\n>高级怪物出现门槛:原来的50%\n>怪物技能冷却时间:-50%", "zh-CN"); LanguageAPI.Add("RUIN_DUSTWIND_DIFFICULTY_NAME", "Ruin Dustwind"); LanguageAPI.Add("RUIN_DUSTWIND_DIFFICULTY_DESCRIPTION", "All things are ground into dust.\n\n>Player Health Regeneration: -90%\n>Difficulty Adjustment: +500%\n>High-tier Monster Threshold: 50%\n>Monster Skill Cooldowns: -50%"); LanguageAPI.Add("RUIN_DUSTWIND_DIFFICULTY_NAME", "破灭尘风", "zh-CN"); LanguageAPI.Add("RUIN_DUSTWIND_DIFFICULTY_DESCRIPTION", "万物皆归于尘。\n\n>玩家生命值再生速度:-90%\n>难度调整:+500%\n>高级怪物出现门槛:原来的50%\n>怪物技能冷却时间:-50%", "zh-CN"); LanguageAPI.Add("BUTIAN_DIFFICULTY_NAME", "Butian"); LanguageAPI.Add("BUTIAN_DIFFICULTY_DESCRIPTION", "The heavens set the final measure.\n\n>Player Health Regeneration: -90%\n>Difficulty Adjustment: +666%\n>High-tier Monster Threshold: 50%\n>Monster Skill Cooldowns: -50%"); LanguageAPI.Add("BUTIAN_DIFFICULTY_NAME", "步天", "zh-CN"); LanguageAPI.Add("BUTIAN_DIFFICULTY_DESCRIPTION", "步天而行,万象失序。\n\n>玩家生命值再生速度:-90%\n>难度调整:+666%\n>高级怪物出现门槛:原来的50%\n>怪物技能冷却时间:-50%", "zh-CN"); } private void RegisterDifficulties() { //IL_0035: 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_0045: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Expected O, but got Unknown //IL_004b: 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_005b: Invalid comparison between Unknown and I4 //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Expected O, but got Unknown //IL_00b3: 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_00c3: Invalid comparison between Unknown and I4 //IL_0105: Unknown result type (might be due to invalid IL or missing references) //IL_010a: Unknown result type (might be due to invalid IL or missing references) //IL_0115: Unknown result type (might be due to invalid IL or missing references) //IL_0120: Expected O, but got Unknown //IL_011b: Unknown result type (might be due to invalid IL or missing references) //IL_0125: Unknown result type (might be due to invalid IL or missing references) //IL_012b: Invalid comparison between Unknown and I4 //IL_016a: Unknown result type (might be due to invalid IL or missing references) //IL_016f: Unknown result type (might be due to invalid IL or missing references) //IL_017a: Unknown result type (might be due to invalid IL or missing references) //IL_0185: Expected O, but got Unknown //IL_0180: Unknown result type (might be due to invalid IL or missing references) //IL_018a: Unknown result type (might be due to invalid IL or missing references) //IL_0190: Invalid comparison between Unknown and I4 //IL_01d3: Unknown result type (might be due to invalid IL or missing references) //IL_01d8: Unknown result type (might be due to invalid IL or missing references) //IL_01e3: Unknown result type (might be due to invalid IL or missing references) //IL_01ef: Expected O, but got Unknown //IL_01ea: Unknown result type (might be due to invalid IL or missing references) //IL_01f4: Unknown result type (might be due to invalid IL or missing references) //IL_01fa: Invalid comparison between Unknown and I4 //IL_023a: Unknown result type (might be due to invalid IL or missing references) //IL_023f: Unknown result type (might be due to invalid IL or missing references) //IL_024a: Unknown result type (might be due to invalid IL or missing references) //IL_0256: Expected O, but got Unknown //IL_0251: Unknown result type (might be due to invalid IL or missing references) //IL_025b: Unknown result type (might be due to invalid IL or missing references) //IL_0261: Invalid comparison between Unknown and I4 //IL_02a4: Unknown result type (might be due to invalid IL or missing references) //IL_02a9: Unknown result type (might be due to invalid IL or missing references) //IL_02b4: Unknown result type (might be due to invalid IL or missing references) //IL_02c0: Expected O, but got Unknown //IL_02bb: Unknown result type (might be due to invalid IL or missing references) //IL_02c5: Unknown result type (might be due to invalid IL or missing references) //IL_02cb: Invalid comparison between Unknown and I4 Sprite val = LoadEmbeddedSprite("HurricaneDifficulty.Assets.cyclone.png", "texCycloneDifficulty"); CycloneDifficultyIndex = DifficultyAPI.AddDifficulty(new DifficultyDef(3.7f, "CYCLONE_DIFFICULTY_NAME", string.Empty, "CYCLONE_DIFFICULTY_DESCRIPTION", Color32.op_Implicit(new Color32(byte.MaxValue, (byte)92, (byte)174, byte.MaxValue)), "CYCL", true), val); if ((int)CycloneDifficultyIndex == -1) { throw new InvalidOperationException("Cyclone difficulty was registered too late or rejected by DifficultyAPI."); } Sprite val2 = LoadEmbeddedSprite("HurricaneDifficulty.Assets.hurricane.png", "texHurricaneDifficulty"); HurricaneDifficultyIndex = DifficultyAPI.AddDifficulty(new DifficultyDef(4.4f, "HURRICANE_DIFFICULTY_NAME", string.Empty, "HURRICANE_DIFFICULTY_DESCRIPTION", Color32.op_Implicit(new Color32((byte)173, (byte)103, byte.MaxValue, byte.MaxValue)), "HUR", true), val2); if ((int)HurricaneDifficultyIndex == -1) { throw new InvalidOperationException("Hurricane difficulty was registered too late or rejected by DifficultyAPI."); } Sprite val3 = LoadEmbeddedSprite("HurricaneDifficulty.Assets.tempest.png", "texTempestDifficulty"); TempestDifficultyIndex = DifficultyAPI.AddDifficulty(new DifficultyDef(5.6f, "TEMPEST_DIFFICULTY_NAME", string.Empty, "TEMPEST_DIFFICULTY_DESCRIPTION", Color32.op_Implicit(new Color32((byte)57, (byte)190, (byte)211, byte.MaxValue)), "TEMP", true), val3); if ((int)TempestDifficultyIndex == -1) { throw new InvalidOperationException("Tempest difficulty was registered too late or rejected by DifficultyAPI."); } Sprite val4 = LoadEmbeddedSprite("HurricaneDifficulty.Assets.cataclysm.png", "texCataclysmDifficulty"); CataclysmDifficultyIndex = DifficultyAPI.AddDifficulty(new DifficultyDef(7f, "CATACLYSM_DIFFICULTY_NAME", string.Empty, "CATACLYSM_DIFFICULTY_DESCRIPTION", Color32.op_Implicit(new Color32(byte.MaxValue, (byte)126, (byte)34, byte.MaxValue)), "CATA", true), val4); if ((int)CataclysmDifficultyIndex == -1) { throw new InvalidOperationException("Cataclysm difficulty was registered too late or rejected by DifficultyAPI."); } Sprite val5 = LoadEmbeddedSprite("HurricaneDifficulty.Assets.solarstorm.png", "texSolarStormDifficulty"); SolarStormDifficultyIndex = DifficultyAPI.AddDifficulty(new DifficultyDef(8.4f, "SOLAR_STORM_DIFFICULTY_NAME", string.Empty, "SOLAR_STORM_DIFFICULTY_DESCRIPTION", Color32.op_Implicit(new Color32(byte.MaxValue, (byte)196, (byte)38, byte.MaxValue)), "SOLR", true), val5); if ((int)SolarStormDifficultyIndex == -1) { throw new InvalidOperationException("Solar Storm difficulty was registered too late or rejected by DifficultyAPI."); } Sprite val6 = LoadEmbeddedSprite("HurricaneDifficulty.Assets.ruindustwind.png", "texRuinDustwindDifficulty"); RuinDustwindDifficultyIndex = DifficultyAPI.AddDifficulty(new DifficultyDef(12f, "RUIN_DUSTWIND_DIFFICULTY_NAME", string.Empty, "RUIN_DUSTWIND_DIFFICULTY_DESCRIPTION", Color32.op_Implicit(new Color32(byte.MaxValue, (byte)38, (byte)38, byte.MaxValue)), "RUIN", true), val6); if ((int)RuinDustwindDifficultyIndex == -1) { throw new InvalidOperationException("Ruin Dustwind difficulty was registered too late or rejected by DifficultyAPI."); } Sprite val7 = LoadEmbeddedSprite("HurricaneDifficulty.Assets.butian.png", "texButianDifficulty"); ButianDifficultyIndex = DifficultyAPI.AddDifficulty(new DifficultyDef(15.32f, "BUTIAN_DIFFICULTY_NAME", string.Empty, "BUTIAN_DIFFICULTY_DESCRIPTION", Color32.op_Implicit(new Color32((byte)116, (byte)205, byte.MaxValue, byte.MaxValue)), "BTAN", true), val7); if ((int)ButianDifficultyIndex == -1) { throw new InvalidOperationException("Butian difficulty was registered too late or rejected by DifficultyAPI."); } } private static void ApplyPlayerStats(CharacterBody body, StatHookEventArgs args) { //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_0042: 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_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Invalid comparison between Unknown and I4 //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) //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) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_009e: 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_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) if (!ResonatorModules.DifficultiesActive) { return; } Run instance = Run.instance; if (instance == null) { return; } if (body.isPlayerControlled) { if (instance.selectedDifficulty == CycloneDifficultyIndex) { args.regenTotalMult *= 0.75f; } else if (instance.selectedDifficulty == SolarStormDifficultyIndex) { args.regenTotalMult *= 0.25f; } else if (instance.selectedDifficulty == RuinDustwindDifficultyIndex || instance.selectedDifficulty == ButianDifficultyIndex) { args.regenTotalMult *= 1f / 6f; } else if (instance.selectedDifficulty == HurricaneDifficultyIndex || instance.selectedDifficulty == TempestDifficultyIndex || instance.selectedDifficulty == CataclysmDifficultyIndex) { args.regenTotalMult *= 0.5f; } } if ((instance.selectedDifficulty == SolarStormDifficultyIndex || instance.selectedDifficulty == RuinDustwindDifficultyIndex || instance.selectedDifficulty == ButianDifficultyIndex) && body.teamComponent != null && (int)body.teamComponent.teamIndex == 2) { args.allSkills.cooldownMultiplier *= 0.5f; } } private static void PreGameController_StartRun(orig_StartRun orig, PreGameController self) { if (NetworkServer.active) { EnforceEnabledDifficultyModule(self); EnforceEnabledArtifactModule(self); EnforceEnabledPvPModule(self); } orig.Invoke(self); } private static void EnforceEnabledDifficultyModule(PreGameController preGame) { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Expected O, but got Unknown if (!ResonatorModules.DifficultiesActive && IsCustomDifficulty(preGame.readOnlyRuleBook.FindDifficulty())) { RuleChoiceDef val = RuleCatalog.FindRuleDef("Difficulty")?.choices.Find((RuleChoiceDef choice) => (int)choice.difficultyIndex == 2); if (val != null) { RuleBook val2 = new RuleBook(); val2.Copy(preGame.readOnlyRuleBook); val2.ApplyChoice(val); preGame.SetRuleBook(val2); } } } private static void EnforceEnabledPvPModule(PreGameController preGame) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Invalid comparison between Unknown and I4 //IL_0056: Unknown result type (might be due to invalid IL or missing references) if (ResonatorModules.PvPActive) { return; } Run gameModePrefabComponent = GameModeCatalog.GetGameModePrefabComponent(preGame.gameModeIndex); if (Object.op_Implicit((Object)(object)gameModePrefabComponent) && !(((Object)((Component)gameModePrefabComponent).gameObject).name != "WaterBucketPvPModeRun")) { GameModeIndex val = GameModeCatalog.FindGameModeIndex("ClassicRun"); if ((int)val >= 0) { Console.instance.SubmitCmd((NetworkUser)null, "gamemode ClassicRun", false); preGame.gameModeIndex = val; } } } private static void EnforceEnabledArtifactModule(PreGameController preGame) { //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Expected O, but got Unknown if (ResonatorModules.ArtifactsActive) { return; } RuleBook readOnlyRuleBook = preGame.readOnlyRuleBook; RuleBook val = null; ArtifactDef[] all = ArtifactRegistry.All; foreach (ArtifactDef val2 in all) { RuleDef val3 = RuleCatalog.FindRuleDef("Artifacts." + val2.cachedName); if (val3 != null && val3.choices.Count >= 2 && readOnlyRuleBook.IsChoiceActive(val3.choices[0])) { if (val == null) { val = new RuleBook(); val.Copy(readOnlyRuleBook); } val.ApplyChoice(val3.choices[1]); } } if (val != null) { preGame.SetRuleBook(val); } } private static bool IsCustomDifficulty(DifficultyIndex difficultyIndex) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) if (difficultyIndex != CycloneDifficultyIndex && difficultyIndex != HurricaneDifficultyIndex && difficultyIndex != TempestDifficultyIndex && difficultyIndex != CataclysmDifficultyIndex && difficultyIndex != SolarStormDifficultyIndex && difficultyIndex != RuinDustwindDifficultyIndex) { return difficultyIndex == ButianDifficultyIndex; } return true; } private void CombatDirector_AttemptSpawnOnTarget_IL(ILContext il) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_012b: Unknown result type (might be due to invalid IL or missing references) //IL_0131: Expected O, but got Unknown //IL_0161: 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_009a: 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_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Invalid comparison between Unknown and I4 Instruction affordabilityCreditRead = null; Enumerator enumerator = il.Body.Instructions.GetEnumerator(); try { while (enumerator.MoveNext()) { Instruction current = enumerator.Current; if (!ILPatternMatchingExt.MatchLdfld(current, "monsterCredit") || current.Previous == null || !ILPatternMatchingExt.MatchLdarg(current.Previous, 0) || current.Next == null || !ILPatternMatchingExt.MatchLdloc(current.Next, 0)) { continue; } Instruction next = current.Next; if (next == null) { continue; } Instruction next2 = next.Next; Code? obj; if (next2 == null) { obj = null; } else { OpCode opCode = next2.OpCode; obj = ((OpCode)(ref opCode)).Code; } Code? val = obj; if ((int)val.GetValueOrDefault() == 106 && IsUnsignedGreaterThanOrEqualBranch(current.Next.Next.Next)) { if (affordabilityCreditRead != null) { ((BaseUnityPlugin)this).Logger.LogError((object)"High-tier monster threshold patch found multiple affordability gates; the patch was not installed to avoid changing elite or spawn-budget logic."); return; } affordabilityCreditRead = current; } } } finally { ((IDisposable)enumerator/*cast due to .constrained prefix*/).Dispose(); } if (affordabilityCreditRead == null) { ((BaseUnityPlugin)this).Logger.LogError((object)"High-tier monster threshold patch could not find the base-card affordability gate. All Combat Director behavior remains vanilla."); return; } ILCursor val2 = new ILCursor(il); if (!val2.TryGotoNext((MoveType)2, new Func[1] { (Instruction instruction) => instruction == affordabilityCreditRead })) { ((BaseUnityPlugin)this).Logger.LogError((object)"High-tier monster threshold patch could not position its IL cursor."); return; } val2.Emit(OpCodes.Ldarg_0); val2.EmitDelegate>((Func)GetBaseCardAffordabilityCredit); ((BaseUnityPlugin)this).Logger.LogDebug((object)"Installed high-tier normal-monster affordability threshold patch."); } private static float GetBaseCardAffordabilityCredit(float actualCredit, CombatDirector director) { if (actualCredit <= 0f || !ShouldApplyInheritedDirectorRules(director) || CombatDirector.IsEliteOnlyArtifactActive()) { return actualCredit; } return actualCredit * 2f; } private static bool IsUnsignedGreaterThanOrEqualBranch(Instruction? instruction) { //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Invalid comparison between Unknown and I4 //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Invalid comparison between Unknown and I4 if (instruction != null) { OpCode opCode = instruction.OpCode; if ((int)((OpCode)(ref opCode)).Code != 64) { opCode = instruction.OpCode; return (int)((OpCode)(ref opCode)).Code == 51; } return true; } return false; } private static bool ShouldApplyInheritedDirectorRules(CombatDirector director) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Invalid comparison between Unknown and I4 //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002d: 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_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_0047: 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) if (!ResonatorModules.DifficultiesActive) { return false; } Run instance = Run.instance; if (instance != null && (instance.selectedDifficulty == TempestDifficultyIndex || instance.selectedDifficulty == CataclysmDifficultyIndex || instance.selectedDifficulty == SolarStormDifficultyIndex || instance.selectedDifficulty == RuinDustwindDifficultyIndex || instance.selectedDifficulty == ButianDifficultyIndex) && (int)director.teamIndex == 2 && director.targetPlayers && !director.shouldSpawnOneWave) { return !director.HasOverrideBoss(); } return false; } internal static Sprite LoadEmbeddedSprite(string resourceName, string textureName) { //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003e: 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_004d: Expected O, but got Unknown //IL_0086: 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) using Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(resourceName) ?? throw new InvalidOperationException("Missing embedded resource: " + resourceName); using MemoryStream memoryStream = new MemoryStream(); stream.CopyTo(memoryStream); Texture2D val = new Texture2D(2, 2, (TextureFormat)5, false) { name = textureName, filterMode = (FilterMode)0, wrapMode = (TextureWrapMode)1 }; if (!ImageConversion.LoadImage(val, memoryStream.ToArray(), true)) { throw new InvalidOperationException("Failed to decode the embedded icon: " + resourceName); } return Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f), 100f); } } internal sealed class ResonanceCrosshairController : MonoBehaviour { private static readonly Color MeterBlue = new Color(0.24f, 0.78f, 1f, 1f); private static readonly Color MeterDarkBlue = new Color(0.015f, 0.08f, 0.13f, 1f); [SerializeField] private Transform? meterRoot; private HudElement? hudElement; private ImageFillController[] fillControllers = Array.Empty(); private Image? meterFill; private CharacterBody? targetBody; private bool initialized; internal void Configure(Transform junkMeterRoot) { meterRoot = junkMeterRoot; } internal void SetTargetBody(CharacterBody body) { targetBody = body; } private void Start() { InitializeMeter(); } private void Update() { if (!initialized) { InitializeMeter(); } CharacterBody val = targetBody; if (val == null) { val = (Object.op_Implicit((Object)(object)hudElement) ? hudElement.targetCharacterBody : null); } if (val == null) { LocalUser firstLocalUser = LocalUserManager.GetFirstLocalUser(); val = ((firstLocalUser != null) ? firstLocalUser.cachedBody : null); } float num = (float)ResonatorSkillModule.GetResonanceUnits(val) / 1000f; for (int i = 0; i < fillControllers.Length; i++) { fillControllers[i].SetTValue(num); } if (Object.op_Implicit((Object)(object)meterFill)) { meterFill.fillAmount = num; } } private void InitializeMeter() { //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_0089: 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_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: 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_00de: 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) hudElement = ((Component)this).GetComponent() ?? ((Component)this).GetComponentInChildren(true); if (!Object.op_Implicit((Object)(object)meterRoot)) { meterRoot = FindDescendant(((Component)this).transform, "ResonatorJunkMeter") ?? FindDescendant(((Component)this).transform, "Junk UI"); } if (!Object.op_Implicit((Object)(object)meterRoot)) { return; } fillControllers = ((Component)meterRoot).GetComponentsInChildren(true); Graphic[] componentsInChildren = ((Component)meterRoot).GetComponentsInChildren(true); foreach (Graphic obj in componentsInChildren) { Color color = obj.color; float num = color.r * 0.21f + color.g * 0.72f + color.b * 0.07f; Color val = Color.Lerp(MeterDarkBlue, MeterBlue, Mathf.Clamp01(num)); obj.color = new Color(val.r, val.g, val.b, color.a); } Image[] componentsInChildren2 = ((Component)meterRoot).GetComponentsInChildren(true); foreach (Image val2 in componentsInChildren2) { string name = ((Object)val2).name; if (!Object.op_Implicit((Object)(object)meterFill) && name.IndexOf("fill", StringComparison.OrdinalIgnoreCase) >= 0) { meterFill = val2; } } ((Component)meterRoot).gameObject.SetActive(true); initialized = fillControllers.Length != 0 || Object.op_Implicit((Object)(object)meterFill); } private static Transform? FindDescendant(Transform root, string name) { if (string.Equals(((Object)root).name, name, StringComparison.OrdinalIgnoreCase)) { return root; } for (int i = 0; i < root.childCount; i++) { Transform val = FindDescendant(root.GetChild(i), name); if (Object.op_Implicit((Object)(object)val)) { return val; } } return null; } } internal sealed class ResonanceHudOverlayController : MonoBehaviour { private const string HudAnchor = "CrosshairExtras"; private CharacterBody? body; [SerializeField] private GameObject? overlayPrefab; private OverlayController? overlayController; internal static GameObject? SharedOverlayPrefab { get; set; } internal void Configure(GameObject prefab) { overlayPrefab = prefab; } private void Awake() { body = ((Component)this).GetComponent(); } private void OnEnable() { TryCreateOverlay(); } private void Start() { TryCreateOverlay(); } private void OnDisable() { RemoveOverlay(); } private void TryCreateOverlay() { //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) if (body == null) { body = ((Component)this).GetComponent(); } GameObject val = (Object.op_Implicit((Object)(object)overlayPrefab) ? overlayPrefab : SharedOverlayPrefab); if (((Behaviour)this).isActiveAndEnabled && Object.op_Implicit((Object)(object)body) && Object.op_Implicit((Object)(object)val) && overlayController == null) { OverlayCreationParams val2 = new OverlayCreationParams { prefab = val, childLocatorEntry = "CrosshairExtras" }; overlayController = HudOverlayManager.AddOverlay(((Component)this).gameObject, val2); overlayController.onInstanceAdded += OnOverlayInstanceAdded; for (int i = 0; i < overlayController.instancesList.Count; i++) { OnOverlayInstanceAdded(overlayController, overlayController.instancesList[i]); } } } private void RemoveOverlay() { if (overlayController != null) { overlayController.onInstanceAdded -= OnOverlayInstanceAdded; HudOverlayManager.RemoveOverlay(overlayController); overlayController = null; } } private void OnOverlayInstanceAdded(OverlayController _, GameObject instance) { ResonanceCrosshairController resonanceCrosshairController = instance.GetComponent() ?? instance.GetComponentInChildren(true); if (Object.op_Implicit((Object)(object)resonanceCrosshairController) && Object.op_Implicit((Object)(object)body)) { resonanceCrosshairController.SetTargetBody(body); } } } internal sealed class ResonanceProjectileAcceleration : MonoBehaviour { internal float acceleration = 28f; private ProjectileSimple? projectileSimple; private void Awake() { projectileSimple = ((Component)this).GetComponent(); } private void FixedUpdate() { if (Object.op_Implicit((Object)(object)projectileSimple)) { ProjectileSimple? obj = projectileSimple; obj.desiredForwardSpeed += acceleration * Time.fixedDeltaTime; } } } internal sealed class ResonanceProjectileGhostHealing : MonoBehaviour { private const float HealFraction = 0.1f; private const float ResonanceCost = 0.5f; private const float ContactPadding = 0.75f; private readonly HashSet healedGhosts = new HashSet(); private ProjectileController? projectileController; private Vector3 previousPosition; private void Awake() { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) projectileController = ((Component)this).GetComponent(); previousPosition = ((Component)this).transform.position; } private void FixedUpdate() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_0173: Unknown result type (might be due to invalid IL or missing references) //IL_0174: Unknown result type (might be due to invalid IL or missing references) //IL_0115: 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_0120: Unknown result type (might be due to invalid IL or missing references) //IL_0151: Unknown result type (might be due to invalid IL or missing references) //IL_0157: Unknown result type (might be due to invalid IL or missing references) Vector3 position = ((Component)this).transform.position; if (!NetworkServer.active || !Object.op_Implicit((Object)(object)projectileController) || !Object.op_Implicit((Object)(object)projectileController.owner)) { previousPosition = position; return; } CharacterBody component = projectileController.owner.GetComponent(); CharacterMaster val = (Object.op_Implicit((Object)(object)component) ? component.master : null); if (!Object.op_Implicit((Object)(object)val)) { previousPosition = position; return; } IReadOnlyList readOnlyInstancesList = CharacterBody.readOnlyInstancesList; for (int i = 0; i < readOnlyInstancesList.Count; i++) { CharacterBody val2 = readOnlyInstancesList[i]; CharacterMaster val3 = (Object.op_Implicit((Object)(object)val2) ? val2.master : null); HealthComponent val4 = (Object.op_Implicit((Object)(object)val2) ? val2.healthComponent : null); if (!Object.op_Implicit((Object)(object)val3) || !Object.op_Implicit((Object)(object)val4) || !val4.alive || (Object)(object)ResonatorSkillModule.GetResonatorGhostOwner(val3) != (Object)(object)val) { continue; } int instanceID = ((Object)val3).GetInstanceID(); if (!healedGhosts.Contains(instanceID)) { float num = Mathf.Max(val2.radius, 0.5f) + 0.75f; if (!(DistanceToSegmentSquared(val2.corePosition, previousPosition, position) > num * num) && ResonatorSkillModule.TrySpendResonance(component, 0.5f)) { healedGhosts.Add(instanceID); val4.HealFraction(0.1f, default(ProcChainMask)); } } } previousPosition = position; } internal static float DistanceToSegmentSquared(Vector3 point, Vector3 start, Vector3 end) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) Vector3 val = end - start; float sqrMagnitude = ((Vector3)(ref val)).sqrMagnitude; Vector3 val2; if (sqrMagnitude <= Mathf.Epsilon) { val2 = point - start; return ((Vector3)(ref val2)).sqrMagnitude; } float num = Mathf.Clamp01(Vector3.Dot(point - start, val) / sqrMagnitude); val2 = point - (start + val * num); return ((Vector3)(ref val2)).sqrMagnitude; } } internal sealed class ResonatorEchoGhostController : MonoBehaviour { private CharacterMaster? ghostMaster; private float decayPauseTimer; private int suspendedHealthDecayStacks; private bool naturalDecayDisabled; internal CharacterMaster? OwnerMaster { get; private set; } internal bool IsEchoSoulbindGhost { get; private set; } internal float BaseDamageMultiplier { get; private set; } = 1f; private void Awake() { ghostMaster = ((Component)this).GetComponent(); } internal void Initialize(CharacterMaster? ownerMaster, float baseDamageMultiplier = 1f, bool isEchoSoulbindGhost = false) { OwnerMaster = ownerMaster; BaseDamageMultiplier = Mathf.Max(0f, baseDamageMultiplier); IsEchoSoulbindGhost |= isEchoSoulbindGhost; } internal void PauseNaturalDecay(float duration) { //IL_006c: Unknown result type (might be due to invalid IL or missing references) if (!NetworkServer.active || naturalDecayDisabled || duration <= 0f || !Object.op_Implicit((Object)(object)ghostMaster) || !Object.op_Implicit((Object)(object)ghostMaster.inventory)) { return; } Inventory inventory = ghostMaster.inventory; if (suspendedHealthDecayStacks <= 0) { suspendedHealthDecayStacks = inventory.GetItemCountEffective(Items.HealthDecay); if (suspendedHealthDecayStacks > 0) { inventory.ResetItemPermanent(Items.HealthDecay.itemIndex); CharacterBody body = ghostMaster.GetBody(); if (body != null) { body.MarkAllStatsDirty(); } } } decayPauseTimer = Mathf.Max(decayPauseTimer, duration); } internal void StopNaturalDecayPermanently() { //IL_0050: Unknown result type (might be due to invalid IL or missing references) if (NetworkServer.active && Object.op_Implicit((Object)(object)ghostMaster) && Object.op_Implicit((Object)(object)ghostMaster.inventory)) { naturalDecayDisabled = true; decayPauseTimer = 0f; suspendedHealthDecayStacks = 0; ghostMaster.inventory.ResetItemPermanent(Items.HealthDecay.itemIndex); CharacterBody body = ghostMaster.GetBody(); if (body != null) { body.MarkAllStatsDirty(); } } } private void FixedUpdate() { if (!NetworkServer.active || naturalDecayDisabled || decayPauseTimer <= 0f) { return; } decayPauseTimer -= Time.fixedDeltaTime; if (!(decayPauseTimer > 0f) && suspendedHealthDecayStacks > 0 && Object.op_Implicit((Object)(object)ghostMaster) && Object.op_Implicit((Object)(object)ghostMaster.inventory)) { ghostMaster.inventory.GiveItemPermanent(Items.HealthDecay, suspendedHealthDecayStacks); suspendedHealthDecayStacks = 0; CharacterBody body = ghostMaster.GetBody(); if (body != null) { body.MarkAllStatsDirty(); } } } } public sealed class ResonatorEchoSoulLockState : BaseSkillState { private HurtBox? targetHurtBox; private ResonatorTargetTracker? targetTracker; public override void OnEnter() { ((BaseState)this).OnEnter(); if (((EntityState)this).isAuthority) { targetTracker = ((EntityState)this).GetComponent(); targetHurtBox = targetTracker?.CurrentTarget; } } public override void FixedUpdate() { //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) ((EntityState)this).FixedUpdate(); if (!((EntityState)this).isAuthority) { return; } targetHurtBox = targetTracker?.CurrentTarget; if (!((BaseSkillState)this).IsKeyDownAuthority()) { NetworkInstanceId targetNetId = NetworkInstanceId.Invalid; CharacterBody obj = targetHurtBox?.healthComponent?.body; NetworkIdentity val = ((obj != null) ? obj.networkIdentity : null); if (Object.op_Implicit((Object)(object)val)) { targetNetId = val.netId; } ((EntityState)this).outer.SetNextState((EntityState)(object)new ResonatorEchoSoulFireState(targetNetId)); } } public override void OnExit() { ((EntityState)this).OnExit(); } public override InterruptPriority GetMinimumInterruptPriority() { return (InterruptPriority)1; } } public sealed class ResonatorEchoSoulFireState : BaseSkillState { private const float ExitDuration = 0.15f; private NetworkInstanceId targetBodyNetId = NetworkInstanceId.Invalid; public ResonatorEchoSoulFireState() { }//IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) internal ResonatorEchoSoulFireState(NetworkInstanceId targetNetId) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) targetBodyNetId = targetNetId; } public override void OnEnter() { //IL_000f: Unknown result type (might be due to invalid IL or missing references) ((BaseState)this).OnEnter(); if (NetworkServer.active) { GameObject val = NetworkServer.FindLocalObject(targetBodyNetId); CharacterBody val2 = (Object.op_Implicit((Object)(object)val) ? val.GetComponent() : null); ResonatorSkillModule.ExecuteEchoSoulbind(((EntityState)this).characterBody, (val2 != null) ? val2.mainHurtBox : null); } } public override void FixedUpdate() { ((EntityState)this).FixedUpdate(); if (((EntityState)this).fixedAge >= 0.15f && ((EntityState)this).isAuthority) { ((EntityState)this).outer.SetNextStateToMain(); } } public override InterruptPriority GetMinimumInterruptPriority() { return (InterruptPriority)1; } public override void OnSerialize(NetworkWriter writer) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) ((BaseSkillState)this).OnSerialize(writer); writer.Write(targetBodyNetId); } public override void OnDeserialize(NetworkReader reader) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) ((BaseSkillState)this).OnDeserialize(reader); targetBodyNetId = reader.ReadNetworkId(); } } public sealed class ResonatorEmpathicLockState : BaseSkillState { private HurtBox? targetHurtBox; private ResonatorTargetTracker? targetTracker; public override void OnEnter() { ((BaseState)this).OnEnter(); if (((EntityState)this).isAuthority) { targetTracker = ((EntityState)this).GetComponent(); targetHurtBox = targetTracker?.CurrentTarget; } } public override void FixedUpdate() { //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) ((EntityState)this).FixedUpdate(); if (!((EntityState)this).isAuthority) { return; } targetHurtBox = targetTracker?.CurrentTarget; if (!((BaseSkillState)this).IsKeyDownAuthority()) { NetworkInstanceId targetNetId = NetworkInstanceId.Invalid; CharacterBody obj = targetHurtBox?.healthComponent?.body; NetworkIdentity val = ((obj != null) ? obj.networkIdentity : null); if (Object.op_Implicit((Object)(object)val)) { targetNetId = val.netId; } ((EntityState)this).outer.SetNextState((EntityState)(object)new ResonatorEmpathicLockFireState(targetNetId)); } } public override InterruptPriority GetMinimumInterruptPriority() { return (InterruptPriority)1; } } public sealed class ResonatorEmpathicLockFireState : BaseSkillState { private const float ExitDuration = 0.15f; private NetworkInstanceId targetBodyNetId = NetworkInstanceId.Invalid; public ResonatorEmpathicLockFireState() { }//IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) internal ResonatorEmpathicLockFireState(NetworkInstanceId targetNetId) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) targetBodyNetId = targetNetId; } public override void OnEnter() { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) ((BaseState)this).OnEnter(); GameObject val = (NetworkServer.active ? NetworkServer.FindLocalObject(targetBodyNetId) : ClientScene.FindLocalObject(targetBodyNetId)); CharacterBody val2 = (Object.op_Implicit((Object)(object)val) ? val.GetComponent() : null); ResonatorSkillModule.ExecuteEmpathicLock(((EntityState)this).characterBody, (val2 != null) ? val2.mainHurtBox : null); } public override void FixedUpdate() { ((EntityState)this).FixedUpdate(); if (((EntityState)this).fixedAge >= 0.15f && ((EntityState)this).isAuthority) { ((EntityState)this).outer.SetNextStateToMain(); } } public override InterruptPriority GetMinimumInterruptPriority() { return (InterruptPriority)1; } public override void OnSerialize(NetworkWriter writer) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) ((BaseSkillState)this).OnSerialize(writer); writer.Write(targetBodyNetId); } public override void OnDeserialize(NetworkReader reader) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) ((BaseSkillState)this).OnDeserialize(reader); targetBodyNetId = reader.ReadNetworkId(); } } internal sealed class ResonatorHappiestMaskController : MonoBehaviour { private CharacterBody? characterBody; private void Awake() { characterBody = ((Component)this).GetComponent(); } private void Start() { //IL_0056: Unknown result type (might be due to invalid IL or missing references) if (NetworkServer.active && Object.op_Implicit((Object)(object)characterBody) && Object.op_Implicit((Object)(object)characterBody.master)) { CharacterMaster master = characterBody.master; if ((!Object.op_Implicit((Object)(object)master.playerStatsComponent) || !(master.playerStatsComponent.currentStats.GetStatValueDouble(PerBodyStatDef.totalTimeAlive, BodyCatalog.GetBodyName(characterBody.bodyIndex)) > 0.0)) && Object.op_Implicit((Object)(object)master.inventory) && master.inventory.GetItemCountEffective(Items.GhostOnKill) <= 0) { master.inventory.GiveItemPermanent(Items.GhostOnKill, 1); } } } } internal sealed class ResonatorMarkedTargetController : MonoBehaviour { internal const float MarkDuration = 60f; private const float GhostRetargetInterval = 0.1f; [SerializeField] private GameObject? indicatorPrefab; private CharacterBody? ownerBody; private CharacterBody? markedTarget; private Indicator? indicator; private DroneTechIndicatorController? indicatorController; private float remainingDuration; private float retargetStopwatch; internal CharacterBody? MarkedTarget => markedTarget; internal void Configure(GameObject targetIndicatorPrefab) { indicatorPrefab = targetIndicatorPrefab; } private void Awake() { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Expected O, but got Unknown ownerBody = ((Component)this).GetComponent(); if (Object.op_Implicit((Object)(object)indicatorPrefab)) { indicator = new Indicator(((Component)this).gameObject, indicatorPrefab); } } private void OnEnable() { if (indicator != null) { indicator.active = true; } if (NetworkServer.active) { GlobalEventManager.onCharacterDeathGlobal += OnCharacterDeath; } } private void OnDisable() { GlobalEventManager.onCharacterDeathGlobal -= OnCharacterDeath; ClearMarkedTarget(); if (indicator != null) { indicator.active = false; } } internal void SetMarkedTarget(CharacterBody? targetBody) { markedTarget = targetBody; remainingDuration = (Object.op_Implicit((Object)(object)targetBody) ? 60f : 0f); retargetStopwatch = 0f; UpdateIndicatorTarget(); } internal bool IsMarkedTarget(CharacterBody? targetBody) { if (Object.op_Implicit((Object)(object)targetBody) && (Object)(object)markedTarget == (Object)(object)targetBody) { return remainingDuration > 0f; } return false; } private void FixedUpdate() { if (!Object.op_Implicit((Object)(object)markedTarget)) { UpdateIndicatorReticle(); return; } remainingDuration -= Time.fixedDeltaTime; if (remainingDuration <= 0f || !Object.op_Implicit((Object)(object)markedTarget.healthComponent) || !markedTarget.healthComponent.alive) { ClearMarkedTarget(); return; } UpdateIndicatorReticle(); if (NetworkServer.active) { retargetStopwatch -= Time.fixedDeltaTime; if (retargetStopwatch <= 0f) { retargetStopwatch += 0.1f; RetargetOwnedGhosts(); } } } private void OnCharacterDeath(DamageReport damageReport) { CharacterBody victimBody = damageReport.victimBody; if (NetworkServer.active && Object.op_Implicit((Object)(object)ownerBody) && IsMarkedTarget(victimBody)) { ClearMarkedTarget(); ResonatorSkillModule.TryCreateMarkedTargetGhost(ownerBody, victimBody); } } private void RetargetOwnedGhosts() { if (!Object.op_Implicit((Object)(object)ownerBody) || !Object.op_Implicit((Object)(object)ownerBody.master) || !Object.op_Implicit((Object)(object)markedTarget) || !Object.op_Implicit((Object)(object)markedTarget.mainHurtBox)) { return; } foreach (CharacterMaster readOnlyInstances in CharacterMaster.readOnlyInstancesList) { if (Object.op_Implicit((Object)(object)readOnlyInstances) && !((Object)(object)ResonatorSkillModule.GetResonatorGhostOwner(readOnlyInstances) != (Object)(object)ownerBody.master)) { BaseAI[] components = ((Component)readOnlyInstances).GetComponents(); foreach (BaseAI obj in components) { obj.currentEnemy.gameObject = ((Component)markedTarget).gameObject; obj.currentEnemy.bestHurtBox = markedTarget.mainHurtBox; } } } } private void ClearMarkedTarget() { markedTarget = null; remainingDuration = 0f; retargetStopwatch = 0f; UpdateIndicatorTarget(); } private void UpdateIndicatorTarget() { if (indicator != null) { indicator.targetTransform = ((Object.op_Implicit((Object)(object)markedTarget) && Object.op_Implicit((Object)(object)markedTarget.mainHurtBox)) ? ((Component)markedTarget.mainHurtBox).transform : null); } } private void UpdateIndicatorReticle() { if (indicator != null && indicator.hasVisualizer) { if (indicatorController == null) { indicatorController = indicator.visualizerInstance.GetComponent(); } if (Object.op_Implicit((Object)(object)indicatorController)) { indicatorController.ShowNeutralReticle(false); indicatorController.ShowHealReticle(false); indicatorController.ShowAttackReticle(Object.op_Implicit((Object)(object)markedTarget)); } } } } internal static class ResonatorPrototypeModule { private const string BodyNameToken = "RESONATOR_BODY_NAME"; private const string BodySubtitleToken = "RESONATOR_BODY_SUBTITLE"; private const string SurvivorDescriptionToken = "RESONATOR_DESCRIPTION"; private const string SurvivorOutroToken = "RESONATOR_OUTRO_FLAVOR"; private const string SurvivorFailureToken = "RESONATOR_MAIN_ENDING_ESCAPE_FAILURE_FLAVOR"; private const string DefaultSkinNameToken = "RESONATOR_SKIN_DEFAULT_NAME"; private const string PortraitResourceName = "HurricaneDifficulty.Assets.Survivors.resonator_portrait.png"; private const string SeekerBodyAddress = "RoR2/DLC2/Seeker/SeekerBody.prefab"; private const string SeekerMasterAddress = "RoR2/DLC2/Seeker/SeekerMonsterMaster.prefab"; private const string SeekerDisplayAddress = "RoR2/DLC2/Seeker/SeekerDisplay.prefab"; private const string SeekerDefaultSkinAddress = "RoR2/DLC2/Seeker/skinSeekerDefault.asset"; private const string SeekerLotusAddress = "RoR2/DLC2/Seeker/mdlSeekerLotus_prefab.prefab"; private const string SeekerAnimatorAddress = "RoR2/DLC2/Seeker/animSeeker.controller"; private const string VoidSurvivorDisplayAddress = "RoR2/DLC1/VoidSurvivor/VoidSurvivorDisplay.prefab"; private const string BoneCrownDisplayAddress = "RoR2/Base/GoldOnHit/DisplayBoneCrown.prefab"; private const string LunarWispCoreAddress = "RoR2/Base/moon/LunarWispCore.prefab"; private static readonly Color ResonatorBlue = new Color(0.18f, 0.66f, 1f, 1f); private static readonly Dictionary BlueMaterialCache = new Dictionary(); private static readonly Dictionary FaceOrbMaterialCache = new Dictionary(); private static readonly Dictionary LotusMaterialCache = new Dictionary(); private static readonly Dictionary FaceOrbRemapCache = new Dictionary(); private static Texture2D? blueRemapTexture; internal static GameObject? BodyPrefab { get; private set; } internal static GameObject? MasterPrefab { get; private set; } internal static SurvivorDef? SurvivorDef { get; private set; } internal static AnimationClip? StandingIdleClip { get; private set; } internal static void Register(ManualLogSource logger) { //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_01eb: Unknown result type (might be due to invalid IL or missing references) //IL_01f0: Unknown result type (might be due to invalid IL or missing references) RegisterLanguageTokens(); try { GameObject obj = LoadAsset((object)"RoR2/DLC2/Seeker/SeekerBody.prefab"); GameObject val = LoadAsset((object)"RoR2/DLC2/Seeker/SeekerMonsterMaster.prefab"); GameObject val2 = LoadAsset((object)"RoR2/DLC2/Seeker/SeekerDisplay.prefab"); SkinDef sourceSkin = LoadAsset((object)"RoR2/DLC2/Seeker/skinSeekerDefault.asset"); StandingIdleClip = FindAnimationClip(LoadAsset((object)"RoR2/DLC2/Seeker/animSeeker.controller"), "SeekerArmature|Idle"); if (!Object.op_Implicit((Object)(object)StandingIdleClip)) { logger.LogWarning((object)"Could not find SeekerArmature|Idle; the Resonator display will keep its source animation."); } else { logger.LogDebug((object)("Using " + ((Object)StandingIdleClip).name + " for the Resonator standing display pose.")); } BodyPrefab = PrefabAPI.InstantiateClone(obj, "ResonatorBody", true); MasterPrefab = PrefabAPI.InstantiateClone(val, "ResonatorMonsterMaster", true); GameObject val3 = PrefabAPI.InstantiateClone(val2, "ResonatorDisplay", false); CharacterBody component = BodyPrefab.GetComponent(); if (!Object.op_Implicit((Object)(object)component)) { throw new InvalidOperationException("The cloned Seeker body has no CharacterBody component."); } component.baseNameToken = "RESONATOR_BODY_NAME"; component.subtitleNameToken = "RESONATOR_BODY_SUBTITLE"; component.bodyColor = ResonatorBlue; component.skinIndex = 0u; BodyPrefab.AddComponent(); ResonatorSkillModule.Register(BodyPrefab, logger); Sprite val4 = Plugin.LoadEmbeddedSprite("HurricaneDifficulty.Assets.Survivors.resonator_portrait.png", "texResonatorBodyIcon"); component.portraitIcon = (Texture)(object)val4.texture; Sprite skinIcon = CreateSkinIcon(); PrepareModel(BodyPrefab, sourceSkin, skinIcon, "Body", logger); PrepareModel(val3, sourceSkin, skinIcon, "Display", logger); CharacterMaster component2 = MasterPrefab.GetComponent(); if (!Object.op_Implicit((Object)(object)component2)) { throw new InvalidOperationException("The cloned Seeker master has no CharacterMaster component."); } component2.bodyPrefab = BodyPrefab; SurvivorDef = ScriptableObject.CreateInstance(); SurvivorDef.cachedName = "Resonator"; SurvivorDef.bodyPrefab = BodyPrefab; SurvivorDef.displayPrefab = val3; SurvivorDef.displayNameToken = "RESONATOR_BODY_NAME"; SurvivorDef.descriptionToken = "RESONATOR_DESCRIPTION"; SurvivorDef.outroFlavorToken = "RESONATOR_OUTRO_FLAVOR"; SurvivorDef.mainEndingEscapeFailureFlavorToken = "RESONATOR_MAIN_ENDING_ESCAPE_FAILURE_FLAVOR"; SurvivorDef.primaryColor = ResonatorBlue; SurvivorDef.desiredSortPosition = (Object.op_Implicit((Object)(object)Survivors.Drifter) ? (Survivors.Drifter.desiredSortPosition + 0.1f) : 1000f); SurvivorDef.hidden = false; bool flag = ContentAddition.AddBody(BodyPrefab); bool flag2 = ContentAddition.AddMaster(MasterPrefab); bool flag3 = ContentAddition.AddSurvivorDef(SurvivorDef); if (!flag || !flag2 || !flag3) { throw new InvalidOperationException($"Content registration failed (body={flag}, master={flag2}, survivor={flag3})."); } logger.LogInfo((object)"Registered Resonator with its first custom primary and passive skills."); } catch (Exception arg) { logger.LogError((object)$"Could not register the Resonator visual prototype: {arg}"); } } private static void RegisterLanguageTokens() { LanguageAPI.Add("RESONATOR_BODY_NAME", "Resonator"); LanguageAPI.Add("RESONATOR_BODY_SUBTITLE", "Bearer of Departed Echoes"); LanguageAPI.Add("RESONATOR_DESCRIPTION", "A vessel tuned to the voices left behind, binding fractured souls into a circling chorus."); LanguageAPI.Add("RESONATOR_OUTRO_FLAVOR", "...and so they left, followed by voices no one else could hear."); LanguageAPI.Add("RESONATOR_MAIN_ENDING_ESCAPE_FAILURE_FLAVOR", "...and so they vanished, one echo among countless others."); LanguageAPI.Add("RESONATOR_SKIN_DEFAULT_NAME", "Soulbound"); LanguageAPI.Add("RESONATOR_BODY_NAME", "回响者", "zh-CN"); LanguageAPI.Add("RESONATOR_BODY_SUBTITLE", "亡者余音的载体", "zh-CN"); LanguageAPI.Add("RESONATOR_DESCRIPTION", "以亡者余响校准自身的容器,将破碎灵魂缚成环绕不息的合声。", "zh-CN"); LanguageAPI.Add("RESONATOR_OUTRO_FLAVOR", "……于是,回响者离开了,身后仍跟随着无人可闻的声音。", "zh-CN"); LanguageAPI.Add("RESONATOR_MAIN_ENDING_ESCAPE_FAILURE_FLAVOR", "……于是,回响者消逝了,成为无数余音中的一道。", "zh-CN"); LanguageAPI.Add("RESONATOR_SKIN_DEFAULT_NAME", "缚魂", "zh-CN"); } private static void PrepareModel(GameObject ownerPrefab, SkinDef sourceSkin, Sprite? skinIcon, string modelKind, ManualLogSource logger) { //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0085: 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) Transform val = FindModelRoot(ownerPrefab); CharacterModel component = ((Component)val).GetComponent(); ModelSkinController component2 = ((Component)val).GetComponent(); if (!Object.op_Implicit((Object)(object)component) || !Object.op_Implicit((Object)(object)component2)) { throw new InvalidOperationException("The Resonator " + modelKind + " model is missing its skin components."); } bool flag = string.Equals(modelKind, "Display", StringComparison.Ordinal); AttachFaceOrb(val, component); AttachPermanentLotus(val, flag); AttachPermanentItemDisplay(val, component, Items.GoldOnHit, "GoldOnHit", "RoR2/Base/GoldOnHit/DisplayBoneCrown.prefab", "Head", new Vector3(0f, 0.2f, 0f), Vector3.zero, Vector3.one * 0.75f, 1.05f, "ResonatorBoneCrown"); AttachSoulCore(val); AttachSoulHalo(val); ResonatorPrototypeVisualController resonatorPrototypeVisualController = ((Component)val).GetComponent(); if (!Object.op_Implicit((Object)(object)resonatorPrototypeVisualController)) { resonatorPrototypeVisualController = ((Component)val).gameObject.AddComponent(); } resonatorPrototypeVisualController.Configure(flag); SkinDef val2 = CreateBlueSkin(((Component)val).gameObject, component, sourceSkin, skinIcon, modelKind); component2.skins = (SkinDef[])(object)new SkinDef[1] { val2 }; logger.LogDebug((object)$"Prepared Resonator {modelKind.ToLowerInvariant()} model with {val2.skinDefParams.rendererInfos.Length} tinted renderers."); } private static Transform FindModelRoot(GameObject ownerPrefab) { ModelLocator component = ownerPrefab.GetComponent(); if (Object.op_Implicit((Object)(object)component) && Object.op_Implicit((Object)(object)component.modelTransform)) { return component.modelTransform; } CharacterModel componentInChildren = ownerPrefab.GetComponentInChildren(true); if (Object.op_Implicit((Object)(object)componentInChildren)) { return ((Component)componentInChildren).transform; } throw new InvalidOperationException("Could not locate a CharacterModel under " + ((Object)ownerPrefab).name + "."); } private static SkinDef CreateBlueSkin(GameObject modelRoot, CharacterModel characterModel, SkinDef sourceSkin, Sprite? skinIcon, string modelKind) { //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_002e: 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_0057: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) Renderer[] componentsInChildren = modelRoot.GetComponentsInChildren(true); List list = new List(componentsInChildren.Length); foreach (Renderer val in componentsInChildren) { RendererInfo val2 = FindRendererInfo(characterModel.baseRendererInfos, val); Material val3 = (Object.op_Implicit((Object)(object)val2.defaultMaterial) ? val2.defaultMaterial : val.sharedMaterial); if (!Object.op_Implicit((Object)(object)val3)) { AssetReferenceT defaultMaterialAddress = val2.defaultMaterialAddress; if (defaultMaterialAddress != null && ((AssetReference)defaultMaterialAddress).RuntimeKeyIsValid()) { val3 = LoadAsset(((AssetReference)val2.defaultMaterialAddress).RuntimeKey); } } if (Object.op_Implicit((Object)(object)val3)) { val2.renderer = val; val2.defaultMaterial = GetBlueMaterial(val3); val2.defaultMaterialAddress = null; val2.defaultShadowCastingMode = val.shadowCastingMode; val2.hideOnDeath = true; list.Add(val2); } } SkinDefParams val4 = ScriptableObject.CreateInstance(); ((Object)val4).name = "skinResonator" + modelKind + "Params"; val4.rendererInfos = list.ToArray(); SkinDef val5 = ScriptableObject.CreateInstance(); ((Object)val5).name = "skinResonator" + modelKind; val5.baseSkins = (SkinDef[])((!Object.op_Implicit((Object)(object)sourceSkin)) ? ((Array)Array.Empty()) : ((Array)new SkinDef[1] { sourceSkin })); val5.icon = skinIcon; val5.nameToken = "RESONATOR_SKIN_DEFAULT_NAME"; val5.rootObject = modelRoot; val5.skinDefParams = val4; return val5; } private static RendererInfo FindRendererInfo(RendererInfo[] rendererInfos, Renderer renderer) { //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_006c: 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) for (int i = 0; i < rendererInfos.Length; i++) { if ((Object)(object)rendererInfos[i].renderer == (Object)(object)renderer) { return rendererInfos[i]; } } return new RendererInfo { renderer = renderer, defaultMaterial = renderer.sharedMaterial, defaultShadowCastingMode = renderer.shadowCastingMode, ignoreOverlays = true, hideOnDeath = true, ignoresMaterialOverrides = false }; } internal static Material GetBlueMaterial(Material source) { //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Expected O, but got Unknown //IL_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_0123: Unknown result type (might be due to invalid IL or missing references) //IL_0108: Unknown result type (might be due to invalid IL or missing references) //IL_0128: Unknown result type (might be due to invalid IL or missing references) //IL_0130: Unknown result type (might be due to invalid IL or missing references) //IL_013c: Unknown result type (might be due to invalid IL or missing references) //IL_0148: Unknown result type (might be due to invalid IL or missing references) //IL_0155: Unknown result type (might be due to invalid IL or missing references) if (((Object)source).name.EndsWith("_ResonatorBlue", StringComparison.Ordinal) || ((Object)source).name.EndsWith("_ResonatorFaceOrb", StringComparison.Ordinal) || ((Object)source).name.EndsWith("_ResonatorLotus", StringComparison.Ordinal)) { return source; } int instanceID = ((Object)source).GetInstanceID(); if (BlueMaterialCache.TryGetValue(instanceID, out Material value) && Object.op_Implicit((Object)(object)value)) { return value; } Material val = new Material(source) { name = ((Object)source).name + "_ResonatorBlue" }; int num; Color val2; if (((Object)source).name.IndexOf("bone", StringComparison.OrdinalIgnoreCase) < 0 && ((Object)source).name.IndexOf("mask", StringComparison.OrdinalIgnoreCase) < 0) { num = ((((Object)source).name.IndexOf("crown", StringComparison.OrdinalIgnoreCase) >= 0) ? 1 : 0); if (num == 0) { val2 = new Color(0.58f, 0.78f, 1f, 1f); goto IL_00f1; } } else { num = 1; } val2 = new Color(0.76f, 0.9f, 1f, 1f); goto IL_00f1; IL_00f1: Color targetHue = val2; Color targetHue2 = ((num != 0) ? new Color(0.5f, 0.78f, 1f, 1f) : new Color(0.38f, 0.72f, 1f, 1f)); ShiftMaterialColor(val, "_Color", targetHue); ShiftMaterialColor(val, "_TintColor", targetHue); ShiftMaterialColor(val, "_EmColor", targetHue2); ShiftMaterialColor(val, "_EmissionColor", targetHue2); TintMainTexture(val, source); if (val.HasProperty("_RemapTex")) { val.SetTexture("_RemapTex", (Texture)(object)GetBlueRemapTexture()); } BlueMaterialCache[instanceID] = val; return val; } private static Material GetFaceOrbMaterial(Material source) { //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_0052: Expected O, but got Unknown //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Unknown result type (might be due to invalid IL or missing references) if (((Object)source).name.EndsWith("_ResonatorFaceOrb", StringComparison.Ordinal)) { return source; } int instanceID = ((Object)source).GetInstanceID(); if (FaceOrbMaterialCache.TryGetValue(instanceID, out Material value) && Object.op_Implicit((Object)(object)value)) { return value; } Material val = new Material(source) { name = ((Object)source).name + "_ResonatorFaceOrb" }; ShiftMaterialColor(val, "_Color", new Color(0.68f, 0.9f, 1f, 1f)); ShiftMaterialColor(val, "_TintColor", new Color(0.68f, 0.9f, 1f, 1f)); ShiftMaterialColor(val, "_EmColor", new Color(0.58f, 0.86f, 1f, 1f)); ShiftMaterialColor(val, "_EmissionColor", new Color(0.58f, 0.86f, 1f, 1f)); if (val.HasProperty("_RemapTex")) { Texture texture = source.GetTexture("_RemapTex"); if (Object.op_Implicit((Object)(object)texture)) { val.SetTexture("_RemapTex", GetFaceOrbRemapTexture(texture)); } } FaceOrbMaterialCache[instanceID] = val; return val; } private static void ShiftMaterialColor(Material material, string propertyName, Color targetHue) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_004f: 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_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) if (material.HasProperty(propertyName)) { Color color = material.GetColor(propertyName); float num = Mathf.Max(color.r, Mathf.Max(color.g, color.b)); if (!(num <= 0.001f)) { float num2 = num * 1.08f; targetHue.a = color.a; material.SetColor(propertyName, new Color(targetHue.r * num2, targetHue.g * num2, targetHue.b * num2, targetHue.a)); } } } private static Material GetLotusMaterial(Material source) { //IL_003b: 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_0057: Expected O, but got Unknown if (((Object)source).name.EndsWith("_ResonatorLotus", StringComparison.Ordinal)) { return source; } int instanceID = ((Object)source).GetInstanceID(); if (LotusMaterialCache.TryGetValue(instanceID, out Material value) && Object.op_Implicit((Object)(object)value)) { return value; } Material val = new Material(GetBlueMaterial(source)) { name = ((Object)source).name + "_ResonatorLotus" }; ResonatorSkillModule.TuneGhostMaterial(val); if (val.HasProperty("_Fade")) { val.SetFloat("_Fade", 0.42f); } if (val.HasProperty("_ExternalAlpha")) { val.SetFloat("_ExternalAlpha", 0.48f); } if (val.HasProperty("_ZWrite")) { val.SetFloat("_ZWrite", 0f); } LotusMaterialCache[instanceID] = val; return val; } private static void SetMaterialColor(Material material, string propertyName, Color color) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) if (material.HasProperty(propertyName)) { color.a = material.GetColor(propertyName).a; material.SetColor(propertyName, color); } } private static Texture2D GetBlueRemapTexture() { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_002a: 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_003d: Expected O, but got Unknown //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_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) if (Object.op_Implicit((Object)(object)blueRemapTexture)) { return blueRemapTexture; } blueRemapTexture = new Texture2D(256, 4, (TextureFormat)4, false) { name = "texResonatorBlueRemap", filterMode = (FilterMode)1, wrapMode = (TextureWrapMode)1 }; Color[] array = (Color[])(object)new Color[1024]; for (int i = 0; i < 256; i++) { float num = (float)i / 255f; Color val = Color.Lerp(new Color(0.015f, 0.12f, 0.38f, 0f), new Color(0.48f, 0.9f, 1.8f, 1f), num); for (int j = 0; j < 4; j++) { array[j * 256 + i] = val; } } blueRemapTexture.SetPixels(array); blueRemapTexture.Apply(false, false); return blueRemapTexture; } private static Texture GetFaceOrbRemapTexture(Texture source) { //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Expected O, but got Unknown //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Unknown result type (might be due to invalid IL or missing references) //IL_0108: 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) int instanceID = ((Object)source).GetInstanceID(); if (FaceOrbRemapCache.TryGetValue(instanceID, out Texture2D value) && Object.op_Implicit((Object)(object)value)) { return (Texture)(object)value; } RenderTexture temporary = RenderTexture.GetTemporary(source.width, source.height, 0, (RenderTextureFormat)0, (RenderTextureReadWrite)2); RenderTexture active = RenderTexture.active; try { Graphics.Blit(source, temporary); RenderTexture.active = temporary; Texture2D val = new Texture2D(source.width, source.height, (TextureFormat)4, false) { name = ((Object)source).name + "_ResonatorFaceOrb", filterMode = source.filterMode, wrapMode = source.wrapMode }; val.ReadPixels(new Rect(0f, 0f, (float)source.width, (float)source.height), 0, 0); Color[] pixels = val.GetPixels(); for (int i = 0; i < pixels.Length; i++) { Color val2 = pixels[i]; float num = Mathf.Max(val2.r, Mathf.Max(val2.g, val2.b)); pixels[i] = new Color(num * 0.68f, num * 0.9f, num, val2.a); } val.SetPixels(pixels); val.Apply(false, false); FaceOrbRemapCache[instanceID] = val; return (Texture)(object)val; } catch { return source; } finally { RenderTexture.active = active; RenderTexture.ReleaseTemporary(temporary); } } private static void TintMainTexture(Material material, Material source) { if (!source.HasProperty("_MainTex")) { return; } Texture texture = source.GetTexture("_MainTex"); if (Object.op_Implicit((Object)(object)texture)) { Texture2D val = CreateBlueTexture(texture, ((Object)texture).name + "_ResonatorBlue"); if (Object.op_Implicit((Object)(object)val)) { material.SetTexture("_MainTex", (Texture)(object)val); } } } private static void AttachFaceOrb(Transform modelRoot, CharacterModel characterModel) { //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) ChildLocator component = ((Component)modelRoot).GetComponent(); ItemDisplayRule? val = FindItemDisplayRule(characterModel.itemDisplayRuleSet, Items.GhostOnKill, "GhostOnKill"); Transform val2 = null; Vector3 localPos = default(Vector3); ((Vector3)(ref localPos))..ctor(0.0029f, 0.0519f, 0.0695f); Vector3 localAngles = default(Vector3); ((Vector3)(ref localAngles))..ctor(355.744f, 0.15f, 0f); if (val.HasValue) { ItemDisplayRule valueOrDefault = val.GetValueOrDefault(); val2 = FindModelChild(modelRoot, component, valueOrDefault.childName); localPos = valueOrDefault.localPos; localAngles = valueOrDefault.localAngles; } if (val2 == null) { val2 = FindModelChild(modelRoot, component, "Head") ?? modelRoot; } CreateFaceOrbVisual(val2, "ResonatorFaceOrb", localPos + new Vector3(0f, 0f, 0.045f), localAngles, 0.28f); } internal static GameObject CreateFaceOrbVisual(Transform parent, string objectName, Vector3 localPosition, Vector3 localEulerAngles, float localScale) { //IL_0044: 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_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) Transform? obj = FindDescendant(LoadAsset((object)"RoR2/DLC1/VoidSurvivor/VoidSurvivorDisplay.prefab").transform, "VoidSurvivorChargeCrabCannon"); if (!Object.op_Implicit((Object)(object)obj)) { throw new InvalidOperationException("Could not find VoidSurvivorChargeCrabCannon under the Void Fiend display prefab."); } GameObject obj2 = Object.Instantiate(((Component)obj).gameObject, parent); ((Object)obj2).name = objectName; obj2.transform.localPosition = localPosition; obj2.transform.localEulerAngles = localEulerAngles; obj2.transform.localScale = Vector3.one * localScale; Transform val = FindDescendant(obj2.transform, "FistExplosion"); if (Object.op_Implicit((Object)(object)val)) { ((Component)val).gameObject.SetActive(false); } StripGameplayComponents(obj2); ApplyFaceOrbVisuals(obj2); obj2.SetActive(true); return obj2; } private static void ApplyFaceOrbVisuals(GameObject orb) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0105: Unknown result type (might be due to invalid IL or missing references) ParticleSystem[] componentsInChildren = orb.GetComponentsInChildren(true); foreach (ParticleSystem obj in componentsInChildren) { obj.Stop(true, (ParticleSystemStopBehavior)0); MainModule main = obj.main; ((MainModule)(ref main)).simulationSpace = (ParticleSystemSimulationSpace)0; TrailModule trails = obj.trails; if (((TrailModule)(ref trails)).enabled) { ((TrailModule)(ref trails)).enabled = false; } obj.Clear(true); } TrailRenderer[] componentsInChildren2 = orb.GetComponentsInChildren(true); for (int j = 0; j < componentsInChildren2.Length; j++) { componentsInChildren2[j].emitting = false; componentsInChildren2[j].Clear(); } Renderer[] componentsInChildren3 = orb.GetComponentsInChildren(true); for (int k = 0; k < componentsInChildren3.Length; k++) { Material[] sharedMaterials = componentsInChildren3[k].sharedMaterials; for (int l = 0; l < sharedMaterials.Length; l++) { if (Object.op_Implicit((Object)(object)sharedMaterials[l])) { sharedMaterials[l] = GetFaceOrbMaterial(sharedMaterials[l]); } } componentsInChildren3[k].sharedMaterials = sharedMaterials; } Light[] componentsInChildren4 = orb.GetComponentsInChildren(true); for (int m = 0; m < componentsInChildren4.Length; m++) { componentsInChildren4[m].color = new Color(0.62f, 0.92f, 1f, 1f); } for (int n = 0; n < componentsInChildren.Length; n++) { componentsInChildren[n].Play(true); } } private static void AttachPermanentLotus(Transform modelRoot, bool isDisplayModel) { //IL_005c: 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_0081: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) Transform val = (isDisplayModel ? FindDescendant(modelRoot, "mdlSeekerLotus") : null); if (!Object.op_Implicit((Object)(object)val)) { Transform val2 = FindDescendant(modelRoot, "Root") ?? modelRoot; val = Object.Instantiate(LoadAsset((object)"RoR2/DLC2/Seeker/mdlSeekerLotus_prefab.prefab"), val2).transform; } ((Object)val).name = "ResonatorPermanentLotus"; val.localPosition = new Vector3(0f, 0.973f, 0.017f); val.localEulerAngles = new Vector3(13f, 0f, 0f); val.localScale = Vector3.one * 0.78f; ((Component)val).gameObject.SetActive(true); StripGameplayComponents(((Component)val).gameObject); ApplyLotusVisuals(((Component)val).gameObject); } private static void ApplyLotusVisuals(GameObject lotus) { //IL_0069: 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_0086: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Unknown result type (might be due to invalid IL or missing references) Renderer[] componentsInChildren = lotus.GetComponentsInChildren(true); for (int i = 0; i < componentsInChildren.Length; i++) { Material[] sharedMaterials = componentsInChildren[i].sharedMaterials; for (int j = 0; j < sharedMaterials.Length; j++) { if (Object.op_Implicit((Object)(object)sharedMaterials[j])) { sharedMaterials[j] = GetLotusMaterial(sharedMaterials[j]); } } componentsInChildren[i].sharedMaterials = sharedMaterials; } ParticleSystem[] componentsInChildren2 = lotus.GetComponentsInChildren(true); for (int k = 0; k < componentsInChildren2.Length; k++) { MainModule main = componentsInChildren2[k].main; ((MainModule)(ref main)).startColor = MinMaxGradient.op_Implicit(new Color(0.45f, 0.9f, 1f, 0.42f)); } Light[] componentsInChildren3 = lotus.GetComponentsInChildren(true); for (int l = 0; l < componentsInChildren3.Length; l++) { componentsInChildren3[l].color = new Color(0.38f, 0.86f, 1f, 1f); Light obj = componentsInChildren3[l]; obj.intensity *= 0.55f; } } private static AnimationClip? FindAnimationClip(RuntimeAnimatorController animatorController, string clipName) { AnimationClip[] animationClips = animatorController.animationClips; for (int i = 0; i < animationClips.Length; i++) { if (Object.op_Implicit((Object)(object)animationClips[i]) && string.Equals(((Object)animationClips[i]).name, clipName, StringComparison.OrdinalIgnoreCase)) { return animationClips[i]; } } return null; } private static void AttachPermanentItemDisplay(Transform modelRoot, CharacterModel characterModel, ItemDef? itemDef, string itemAssetName, string fallbackAddress, string fallbackChild, Vector3 fallbackPosition, Vector3 fallbackAngles, Vector3 fallbackScale, float scaleMultiplier, string objectName) { //IL_0019: 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_001d: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_0037: 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_007d: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) ChildLocator component = ((Component)modelRoot).GetComponent(); ItemDisplayRule? val = FindItemDisplayRule(characterModel.itemDisplayRuleSet, itemDef, itemAssetName); GameObject val2 = null; Transform val3 = null; Vector3 localPosition = fallbackPosition; Vector3 localEulerAngles = fallbackAngles; Vector3 localScale = fallbackScale; if (val.HasValue) { ItemDisplayRule valueOrDefault = val.GetValueOrDefault(); val2 = valueOrDefault.followerPrefab; if (!Object.op_Implicit((Object)(object)val2)) { AssetReferenceGameObject followerPrefabAddress = valueOrDefault.followerPrefabAddress; if (followerPrefabAddress != null && ((AssetReference)followerPrefabAddress).RuntimeKeyIsValid()) { val2 = LoadAsset(((AssetReference)valueOrDefault.followerPrefabAddress).RuntimeKey); } } val3 = FindModelChild(modelRoot, component, valueOrDefault.childName); localPosition = valueOrDefault.localPos; localEulerAngles = valueOrDefault.localAngles; localScale = valueOrDefault.localScale * scaleMultiplier; } if (val2 == null) { val2 = LoadAsset((object)fallbackAddress); } if (val3 == null) { val3 = FindModelChild(modelRoot, component, fallbackChild) ?? modelRoot; } GameObject obj = Object.Instantiate(val2, val3); ((Object)obj).name = objectName; obj.transform.localPosition = localPosition; obj.transform.localEulerAngles = localEulerAngles; obj.transform.localScale = localScale; StripGameplayComponents(obj); } private static ItemDisplayRule? FindItemDisplayRule(ItemDisplayRuleSet? ruleSet, ItemDef? itemDef, string itemAssetName) { //IL_0025: 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_002a: 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_010b: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: 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_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)ruleSet)) { return null; } DisplayRuleGroup val = (Object.op_Implicit((Object)(object)itemDef) ? ruleSet.FindDisplayRuleGroup((Object)(object)itemDef) : DisplayRuleGroup.empty); if (((DisplayRuleGroup)(ref val)).isEmpty) { for (int i = 0; i < ruleSet.keyAssetRuleGroups.Length; i++) { KeyAssetRuleGroup val2 = ruleSet.keyAssetRuleGroups[i]; string a = (Object.op_Implicit(val2.keyAsset) ? val2.keyAsset.name : string.Empty); IDRSKeyAssetReference keyAssetAddress = val2.keyAssetAddress; string text = ((keyAssetAddress == null) ? null : ((AssetReference)keyAssetAddress).RuntimeKey?.ToString()) ?? string.Empty; if (string.Equals(a, itemAssetName, StringComparison.OrdinalIgnoreCase) || text.IndexOf(itemAssetName, StringComparison.OrdinalIgnoreCase) >= 0) { val = val2.displayRuleGroup; break; } } } if (val.rules == null) { return null; } for (int j = 0; j < val.rules.Length; j++) { if ((int)val.rules[j].ruleType == 0) { return val.rules[j]; } } return null; } private static void AttachSoulCore(Transform modelRoot) { //IL_0051: 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_0080: 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_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) Transform val = FindDescendant(modelRoot, "Spine2") ?? FindDescendant(modelRoot, "Chest") ?? modelRoot; GameObject val2 = Object.Instantiate(LoadAsset((object)"RoR2/Base/moon/LunarWispCore.prefab"), val); ((Object)val2).name = "ResonatorSoulCore"; val2.transform.localPosition = new Vector3(0f, 0.08f, -0.18f); val2.transform.localEulerAngles = new Vector3(0f, 180f, 0f); val2.transform.localScale = Vector3.one * 0.075f; StripGameplayComponents(val2); GameObject val3 = new GameObject("ResonatorSoulLight"); val3.transform.SetParent(val2.transform, false); Light obj = val3.AddComponent(); obj.type = (LightType)2; obj.color = new Color(0.18f, 0.72f, 1f, 1f); obj.range = 1.15f; obj.intensity = 0.34f; } private static void AttachSoulHalo(Transform modelRoot) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Expected O, but got Unknown //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_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_00df: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("ResonatorSoulHalo"); val.transform.SetParent(modelRoot, false); val.transform.localPosition = new Vector3(0f, 1.16f, 0f); GameObject val2 = LoadAsset((object)"RoR2/DLC2/Seeker/mdlSeekerLotus_prefab.prefab"); for (int i = 0; i < 3; i++) { float num = (float)i * 120f; float num2 = num * (MathF.PI / 180f); GameObject obj = Object.Instantiate(val2, val.transform); ((Object)obj).name = $"ResonatorSoulPetal{i + 1}"; obj.transform.localPosition = new Vector3(Mathf.Cos(num2) * 0.72f, 0f, Mathf.Sin(num2) * 0.72f); obj.transform.localEulerAngles = new Vector3(12f, 90f - num, 16f); obj.transform.localScale = Vector3.one * 0.14f; StripGameplayComponents(obj); } } private static Transform? FindModelChild(Transform root, ChildLocator? childLocator, string childName) { if (Object.op_Implicit((Object)(object)childLocator) && !string.IsNullOrEmpty(childName)) { Transform val = childLocator.FindChild(childName); if (Object.op_Implicit((Object)(object)val)) { return val; } } return FindDescendant(root, childName); } private static Transform? FindDescendant(Transform root, string name) { if (((Object)root).name == name) { return root; } for (int i = 0; i < root.childCount; i++) { Transform val = FindDescendant(root.GetChild(i), name); if (Object.op_Implicit((Object)(object)val)) { return val; } } return null; } private static void StripGameplayComponents(GameObject instance) { DestroyOnTimer[] componentsInChildren = instance.GetComponentsInChildren(true); for (int i = 0; i < componentsInChildren.Length; i++) { Object.DestroyImmediate((Object)(object)componentsInChildren[i]); } DestroyOnParticleEnd[] componentsInChildren2 = instance.GetComponentsInChildren(true); for (int j = 0; j < componentsInChildren2.Length; j++) { Object.DestroyImmediate((Object)(object)componentsInChildren2[j]); } Collider[] componentsInChildren3 = instance.GetComponentsInChildren(true); for (int k = 0; k < componentsInChildren3.Length; k++) { Object.DestroyImmediate((Object)(object)componentsInChildren3[k]); } Rigidbody[] componentsInChildren4 = instance.GetComponentsInChildren(true); for (int l = 0; l < componentsInChildren4.Length; l++) { Object.DestroyImmediate((Object)(object)componentsInChildren4[l]); } NetworkIdentity[] componentsInChildren5 = instance.GetComponentsInChildren(true); for (int m = 0; m < componentsInChildren5.Length; m++) { Object.DestroyImmediate((Object)(object)componentsInChildren5[m]); } } private static Texture2D? CreateBlueTexture(Texture? source, string textureName) { //IL_0042: 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_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Expected O, but got Unknown //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: 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_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_0106: 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_0112: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)source)) { return null; } RenderTexture temporary = RenderTexture.GetTemporary(source.width, source.height, 0, (RenderTextureFormat)0, (RenderTextureReadWrite)2); RenderTexture active = RenderTexture.active; try { Graphics.Blit(source, temporary); RenderTexture.active = temporary; Texture2D val = new Texture2D(source.width, source.height, (TextureFormat)4, false) { name = textureName, filterMode = source.filterMode, wrapMode = (TextureWrapMode)1 }; val.ReadPixels(new Rect(0f, 0f, (float)source.width, (float)source.height), 0, 0); Color[] pixels = val.GetPixels(); for (int i = 0; i < pixels.Length; i++) { Color val2 = pixels[i]; float num = Mathf.Pow(val2.r * 0.21f + val2.g * 0.72f + val2.b * 0.07f, 0.9f); pixels[i] = new Color(num * 0.42f, num * 0.72f, Mathf.Clamp01(num * 1.02f + val2.b * 0.06f), val2.a); } val.SetPixels(pixels); val.Apply(false, false); return val; } catch { return null; } finally { RenderTexture.active = active; RenderTexture.ReleaseTemporary(temporary); } } private static Sprite CreateSkinIcon() { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Expected O, but got Unknown //IL_0146: Unknown result type (might be due to invalid IL or missing references) //IL_0155: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: 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) Texture2D val = new Texture2D(128, 128, (TextureFormat)4, false) { name = "texResonatorSkinIcon", filterMode = (FilterMode)0, wrapMode = (TextureWrapMode)1 }; Color val2 = default(Color); ((Color)(ref val2))..ctor(0.72f, 0.86f, 1f, 1f); Color val3 = default(Color); ((Color)(ref val3))..ctor(0.2f, 0.76f, 1f, 1f); Color val4 = default(Color); ((Color)(ref val4))..ctor(0.06f, 0.16f, 0.34f, 1f); Color val5 = default(Color); ((Color)(ref val5))..ctor(0.28f, 0.3f, 0.56f, 1f); Color[] array = (Color[])(object)new Color[16384]; float num = 63.5f; for (int i = 0; i < 128; i++) { for (int j = 0; j < 128; j++) { float num2 = (float)j - num; float num3 = (float)i - num; array[i * 128 + j] = ((Mathf.Abs(num2) > Mathf.Abs(num3)) ? ((num2 < 0f) ? val5 : val3) : ((num3 < 0f) ? val4 : val2)); } } val.SetPixels(array); val.Apply(false, true); Sprite obj = Sprite.Create(val, new Rect(0f, 0f, 128f, 128f), new Vector2(0.5f, 0.5f), 100f); ((Object)obj).name = "sprResonatorSkinIcon"; return obj; } private static T LoadAsset(object address) where T : Object { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) T val = Addressables.LoadAssetAsync(address).WaitForCompletion(); if (!Object.op_Implicit((Object)(object)val)) { throw new InvalidOperationException($"Addressable asset could not be loaded: {address}"); } return val; } } internal sealed class ResonatorPrototypeVisualController : MonoBehaviour { private static readonly FieldInfo? LimbFlagSetField = typeof(CharacterModel).GetField("limbFlagSet", BindingFlags.Instance | BindingFlags.NonPublic); private static readonly MethodInfo? AddLimbFlagsMethod = LimbFlagSetField?.FieldType.GetMethod("AddFlags", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[1] { typeof(LimbFlags) }, null); private Transform? soulHalo; private Light? soulLight; private Transform? faceOrb; private Vector3 faceOrbBasePosition; private Vector3[] petalBasePositions = Array.Empty(); private ModelSkinController? skinController; private CharacterModel? characterModel; private Animator? animator; private AnimatorOverrideController? displayOverrideController; private bool isDisplayInstance; private bool headMaskApplied; [SerializeField] private bool useStandingDisplayPose; internal void Configure(bool standingDisplayPose) { useStandingDisplayPose = standingDisplayPose; isDisplayInstance |= standingDisplayPose; } private void Awake() { //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_0123: Unknown result type (might be due to invalid IL or missing references) //IL_0128: Unknown result type (might be due to invalid IL or missing references) soulHalo = FindDescendant(((Component)this).transform, "ResonatorSoulHalo"); Transform? obj = FindDescendant(((Component)this).transform, "ResonatorSoulLight"); soulLight = ((obj != null) ? ((Component)obj).GetComponent() : null); faceOrb = FindDescendant(((Component)this).transform, "ResonatorFaceOrb"); if (Object.op_Implicit((Object)(object)faceOrb)) { faceOrbBasePosition = faceOrb.localPosition; } skinController = ((Component)this).GetComponent(); characterModel = ((Component)this).GetComponent(); animator = ((Component)this).GetComponent(); isDisplayInstance = useStandingDisplayPose || ((Object)((Component)this).transform.root).name.IndexOf("ResonatorDisplay", StringComparison.OrdinalIgnoreCase) >= 0; if (Object.op_Implicit((Object)(object)skinController)) { skinController.onSkinApplied += OnSkinApplied; } ApplyHeadMask(); if (Object.op_Implicit((Object)(object)soulHalo)) { Transform val = soulHalo; petalBasePositions = (Vector3[])(object)new Vector3[val.childCount]; for (int i = 0; i < val.childCount; i++) { petalBasePositions[i] = val.GetChild(i).localPosition; } } } private IEnumerator Start() { for (int frame = 0; frame < 300; frame++) { if ((!Object.op_Implicit((Object)(object)skinController) || skinController.currentSkinIndex >= 0) && (!isDisplayInstance || (Object.op_Implicit((Object)(object)animator) && Object.op_Implicit((Object)(object)animator.runtimeAnimatorController)))) { break; } yield return null; } ApplyBlueVisuals(); ApplyHeadMask(); EnsureStandingDisplayPose(); } private void OnDestroy() { if (Object.op_Implicit((Object)(object)skinController)) { skinController.onSkinApplied -= OnSkinApplied; } } private void OnSkinApplied(int skinIndex) { ApplyBlueVisuals(); ApplyHeadMask(); if (isDisplayInstance) { displayOverrideController = null; EnsureStandingDisplayPose(); } } private void ApplyHeadMask() { if (!headMaskApplied && Object.op_Implicit((Object)(object)characterModel) && (object)LimbFlagSetField != null && (object)AddLimbFlagsMethod != null) { object value = LimbFlagSetField.GetValue(characterModel); if (value != null) { AddLimbFlagsMethod.Invoke(value, new object[1] { (object)(LimbFlags)1 }); headMaskApplied = true; characterModel.forceUpdate = true; } } } private void ApplyBlueVisuals() { //IL_0148: 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) if (Object.op_Implicit((Object)(object)characterModel)) { RendererInfo[] baseRendererInfos = characterModel.baseRendererInfos; for (int i = 0; i < baseRendererInfos.Length; i++) { Material defaultMaterial = baseRendererInfos[i].defaultMaterial; if (Object.op_Implicit((Object)(object)defaultMaterial)) { baseRendererInfos[i].defaultMaterial = ResonatorPrototypeModule.GetBlueMaterial(defaultMaterial); baseRendererInfos[i].defaultMaterialAddress = null; } } characterModel.baseRendererInfos = baseRendererInfos; characterModel.forceUpdate = true; } Renderer[] componentsInChildren = ((Component)this).GetComponentsInChildren(true); foreach (Renderer val in componentsInChildren) { Material[] sharedMaterials = val.sharedMaterials; bool flag = false; for (int k = 0; k < sharedMaterials.Length; k++) { Material val2 = sharedMaterials[k]; if (Object.op_Implicit((Object)(object)val2)) { Material blueMaterial = ResonatorPrototypeModule.GetBlueMaterial(val2); if ((Object)(object)sharedMaterials[k] != (Object)(object)blueMaterial) { sharedMaterials[k] = blueMaterial; flag = true; } } } if (flag) { val.sharedMaterials = sharedMaterials; } } Light[] componentsInChildren2 = ((Component)this).GetComponentsInChildren(true); for (int l = 0; l < componentsInChildren2.Length; l++) { componentsInChildren2[l].color = (HasNamedAncestor(((Component)componentsInChildren2[l]).transform, "ResonatorFaceOrb") ? new Color(0.62f, 0.92f, 1f, 1f) : new Color(0.3f, 0.82f, 1f, 1f)); } } private void EnsureStandingDisplayPose() { //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Expected O, but got Unknown if (!isDisplayInstance || !Object.op_Implicit((Object)(object)ResonatorPrototypeModule.StandingIdleClip) || !Object.op_Implicit((Object)(object)animator) || !Object.op_Implicit((Object)(object)animator.runtimeAnimatorController) || (Object.op_Implicit((Object)(object)displayOverrideController) && (Object)(object)animator.runtimeAnimatorController == (Object)(object)displayOverrideController)) { return; } AnimationClip standingIdleClip = ResonatorPrototypeModule.StandingIdleClip; AnimatorOverrideController val = new AnimatorOverrideController(animator.runtimeAnimatorController) { name = "animResonatorDisplayOverride" }; List> list = new List>(); val.GetOverrides(list); for (int i = 0; i < list.Count; i++) { AnimationClip key = list[i].Key; if (Object.op_Implicit((Object)(object)key)) { list[i] = new KeyValuePair(key, standingIdleClip); } } val.ApplyOverrides((IList>)list); displayOverrideController = val; animator.runtimeAnimatorController = (RuntimeAnimatorController)(object)val; animator.Rebind(); animator.Update(0f); } private void Update() { //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) if (Object.op_Implicit((Object)(object)soulHalo)) { Transform val = soulHalo; val.Rotate(0f, 20f * Time.deltaTime, 0f, (Space)1); for (int i = 0; i < val.childCount && i < petalBasePositions.Length; i++) { Transform child = val.GetChild(i); Vector3 localPosition = petalBasePositions[i]; localPosition.y += Mathf.Sin(Time.time * 1.8f + (float)i * 2.094f) * 0.035f; child.localPosition = localPosition; } } if (Object.op_Implicit((Object)(object)soulLight)) { soulLight.intensity = 0.34f + Mathf.Sin(Time.time * 2.4f) * 0.06f; } if (Object.op_Implicit((Object)(object)faceOrb)) { Vector3 localPosition2 = faceOrbBasePosition; localPosition2.y += Mathf.Sin(Time.time * 1.35f) * 0.014f; faceOrb.localPosition = localPosition2; } } private void LateUpdate() { EnsureStandingDisplayPose(); } private static Transform? FindDescendant(Transform root, string name) { if (((Object)root).name == name) { return root; } for (int i = 0; i < root.childCount; i++) { Transform val = FindDescendant(root.GetChild(i), name); if (Object.op_Implicit((Object)(object)val)) { return val; } } return null; } private static bool HasNamedAncestor(Transform transform, string name) { Transform val = transform; while (Object.op_Implicit((Object)(object)val)) { if (string.Equals(((Object)val).name, name, StringComparison.Ordinal)) { return true; } val = val.parent; } return false; } } internal static class ResonatorSkillModule { [CompilerGenerated] private static class <>O { public static hook_OnEnter <0>__SpiritPunchOnEnter; public static hook_OnEnter <1>__SojournBaseOnEnter; public static hook_OnEnable <2>__SeekerControllerOnEnable; public static hook_Start <3>__SeekerControllerStart; public static hook_FixedUpdate <4>__SeekerControllerFixedUpdate; public static hook_OnFixedUpdateForTenthSecond <5>__SojournVehicleOnFixedUpdateForTenthSecond; public static hook_EndSojournVehicle <6>__SojournVehicleEndSojournVehicle; public static hook_TakeDamageProcess <7>__HealthComponentTakeDamageProcess; public static Action <8>__OnServerDamageDealt; public static Action <9>__OnCharacterDeath; public static StatHookEventHandler <10>__ApplyEchoGhostStats; } internal const int MaxResonance = 100; internal const int ResonanceUnitsPerPoint = 10; internal const int MaxResonanceUnits = 1000; private const float EchoGhostBaseDamageMultiplier = 2.4f; private const string PrimaryNameToken = "RESONATOR_PRIMARY_RESONANT_IMPACT_NAME"; private const string PrimaryDescriptionToken = "RESONATOR_PRIMARY_RESONANT_IMPACT_DESCRIPTION"; private const string SecondaryNameToken = "RESONATOR_SECONDARY_ECHO_SOUL_NAME"; private const string SecondaryDescriptionToken = "RESONATOR_SECONDARY_ECHO_SOUL_DESCRIPTION"; private const string EmpathicLockNameToken = "RESONATOR_SECONDARY_EMPATHIC_LOCK_NAME"; private const string EmpathicLockDescriptionToken = "RESONATOR_SECONDARY_EMPATHIC_LOCK_DESCRIPTION"; private const string PassiveNameToken = "RESONATOR_PASSIVE_RESONANCE_NAME"; private const string PassiveDescriptionToken = "RESONATOR_PASSIVE_RESONANCE_DESCRIPTION"; private const string UtilityNameToken = "RESONATOR_UTILITY_SOUL_ROAM_NAME"; private const string UtilityDescriptionToken = "RESONATOR_UTILITY_SOUL_ROAM_DESCRIPTION"; private const string SpecialNameToken = "RESONATOR_SPECIAL_SOUL_DOMAIN_NAME"; private const string SpecialDescriptionToken = "RESONATOR_SPECIAL_SOUL_DOMAIN_DESCRIPTION"; private const string SoulBeamNameToken = "RESONATOR_SPECIAL_SOUL_BEAM_NAME"; private const string SoulBeamDescriptionToken = "RESONATOR_SPECIAL_SOUL_BEAM_DESCRIPTION"; private const string PassiveIconResourceName = "HurricaneDifficulty.Assets.Survivors.resonator_skill_passive.png"; private const string PrimaryIconResourceName = "HurricaneDifficulty.Assets.Survivors.resonator_skill_primary.png"; private const string SecondaryIconResourceName = "HurricaneDifficulty.Assets.Survivors.resonator_skill_secondary.png"; private const string EmpathicLockIconResourceName = "HurricaneDifficulty.Assets.Survivors.resonator_skill_empathic_lock.png"; private const string UtilityIconResourceName = "HurricaneDifficulty.Assets.Survivors.resonator_skill_utility.png"; private const string SpecialIconResourceName = "HurricaneDifficulty.Assets.Survivors.resonator_skill_special.png"; private const string SoulBeamIconResourceName = "HurricaneDifficulty.Assets.Survivors.resonator_skill_soul_beam.png"; private const string SpiritPunchProjectileAddress = "RoR2/DLC2/Seeker/SpiritPunchProjectile.prefab"; private const string SpiritPunchGhostAddress = "RoR2/DLC2/Seeker/SpiritPunchGhost.prefab"; private const string DrifterCrosshairAddress = "RoR2/DLC3/Drifter/DrifterCrosshair.prefab"; private const string DrifterJunkUiAddress = "RoR2/DLC3/Drifter/Junk UI.prefab"; private const string DroneTechTargetIndicatorAddress = "RoR2/DLC3/Drone Tech/DroneTechTrackingIndicator.prefab"; private const string SojournVehicleAddress = "RoR2/DLC2/Seeker/SojournVehicle/SojournVehicle.prefab"; private const string VoidBeamTracerAddress = "RoR2/DLC1/VoidSurvivor/VoidSurvivorBeamTracer.prefab"; private const string VoidBeamImpactAddress = "RoR2/DLC1/VoidSurvivor/VoidSurvivorBeamImpact.prefab"; private const string VoidBeamMuzzleflashAddress = "RoR2/DLC1/VoidSurvivor/VoidSurvivorBeamMuzzleflash.prefab"; private static readonly Dictionary GhostMaterialCache = new Dictionary(); private static readonly FieldInfo? DefaultCrosshairPrefabField = typeof(CharacterBody).GetField("_defaultCrosshairPrefab", BindingFlags.Instance | BindingFlags.NonPublic); private static readonly FieldInfo? SkillFamilyField = typeof(GenericSkill).GetField("_skillFamily", BindingFlags.Instance | BindingFlags.NonPublic); private static readonly FieldInfo? SeekerOverlayControllerField = typeof(SeekerController).GetField("overlayController", BindingFlags.Instance | BindingFlags.NonPublic); private static bool installed; internal static BuffDef? ResonanceBuffDef { get; private set; } internal static GameObject? ProjectilePrefab { get; private set; } internal static GameObject? EchoSoulTargetIndicatorPrefab { get; private set; } internal static GameObject? EchoSoulMarkedIndicatorPrefab { get; private set; } internal static GameObject? SoulRoamVehiclePrefab { get; private set; } internal static GameObject? SoulDomainPrefab { get; private set; } internal static GameObject? SoulBeamTracerPrefab { get; private set; } internal static GameObject? SoulBeamImpactPrefab { get; private set; } internal static GameObject? SoulBeamMuzzleflashPrefab { get; private set; } private static Sprite? PassiveIcon { get; set; } private static Sprite? PrimaryIcon { get; set; } private static Sprite? SecondaryIcon { get; set; } private static Sprite? EmpathicLockIcon { get; set; } private static Sprite? UtilityIcon { get; set; } private static Sprite? SpecialIcon { get; set; } private static Sprite? SoulBeamIcon { get; set; } internal static void Register(GameObject bodyPrefab, ManualLogSource logger) { //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Expected O, but got Unknown //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Expected O, but got Unknown //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Expected O, but got Unknown //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Expected O, but got Unknown //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Expected O, but got Unknown //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Expected O, but got Unknown //IL_010f: Unknown result type (might be due to invalid IL or missing references) //IL_0114: Unknown result type (might be due to invalid IL or missing references) //IL_011a: Expected O, but got Unknown //IL_012f: Unknown result type (might be due to invalid IL or missing references) //IL_0134: Unknown result type (might be due to invalid IL or missing references) //IL_013a: Expected O, but got Unknown //IL_018f: Unknown result type (might be due to invalid IL or missing references) //IL_0194: Unknown result type (might be due to invalid IL or missing references) //IL_019a: Expected O, but got Unknown RegisterLanguageTokens(); RegisterSkillIcons(); RegisterResonanceBuff(); RegisterProjectile(); RegisterEchoSoulAssets(bodyPrefab); RegisterSoulRoamAssets(); RegisterSoulDomainAssets(); RegisterSoulBeamAssets(); RegisterCrosshair(bodyPrefab); RegisterSkills(bodyPrefab); if (!installed) { object obj = <>O.<0>__SpiritPunchOnEnter; if (obj == null) { hook_OnEnter val = SpiritPunchOnEnter; <>O.<0>__SpiritPunchOnEnter = val; obj = (object)val; } SpiritPunch.OnEnter += (hook_OnEnter)obj; object obj2 = <>O.<1>__SojournBaseOnEnter; if (obj2 == null) { hook_OnEnter val2 = SojournBaseOnEnter; <>O.<1>__SojournBaseOnEnter = val2; obj2 = (object)val2; } SojournBase.OnEnter += (hook_OnEnter)obj2; object obj3 = <>O.<2>__SeekerControllerOnEnable; if (obj3 == null) { hook_OnEnable val3 = SeekerControllerOnEnable; <>O.<2>__SeekerControllerOnEnable = val3; obj3 = (object)val3; } SeekerController.OnEnable += (hook_OnEnable)obj3; object obj4 = <>O.<3>__SeekerControllerStart; if (obj4 == null) { hook_Start val4 = SeekerControllerStart; <>O.<3>__SeekerControllerStart = val4; obj4 = (object)val4; } SeekerController.Start += (hook_Start)obj4; object obj5 = <>O.<4>__SeekerControllerFixedUpdate; if (obj5 == null) { hook_FixedUpdate val5 = SeekerControllerFixedUpdate; <>O.<4>__SeekerControllerFixedUpdate = val5; obj5 = (object)val5; } SeekerController.FixedUpdate += (hook_FixedUpdate)obj5; object obj6 = <>O.<5>__SojournVehicleOnFixedUpdateForTenthSecond; if (obj6 == null) { hook_OnFixedUpdateForTenthSecond val6 = SojournVehicleOnFixedUpdateForTenthSecond; <>O.<5>__SojournVehicleOnFixedUpdateForTenthSecond = val6; obj6 = (object)val6; } SojournVehicle.OnFixedUpdateForTenthSecond += (hook_OnFixedUpdateForTenthSecond)obj6; object obj7 = <>O.<6>__SojournVehicleEndSojournVehicle; if (obj7 == null) { hook_EndSojournVehicle val7 = SojournVehicleEndSojournVehicle; <>O.<6>__SojournVehicleEndSojournVehicle = val7; obj7 = (object)val7; } SojournVehicle.EndSojournVehicle += (hook_EndSojournVehicle)obj7; object obj8 = <>O.<7>__HealthComponentTakeDamageProcess; if (obj8 == null) { hook_TakeDamageProcess val8 = HealthComponentTakeDamageProcess; <>O.<7>__HealthComponentTakeDamageProcess = val8; obj8 = (object)val8; } HealthComponent.TakeDamageProcess += (hook_TakeDamageProcess)obj8; GlobalEventManager.onServerDamageDealt += OnServerDamageDealt; GlobalEventManager.onCharacterDeathGlobal += OnCharacterDeath; object obj9 = <>O.<10>__ApplyEchoGhostStats; if (obj9 == null) { StatHookEventHandler val9 = ApplyEchoGhostStats; <>O.<10>__ApplyEchoGhostStats = val9; obj9 = (object)val9; } RecalculateStatsAPI.GetStatCoefficients += (StatHookEventHandler)obj9; installed = true; } logger.LogInfo((object)"Registered Resonator's default and alternate skills, plus Resonance."); } internal static void Uninstall() { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Expected O, but got Unknown //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Expected O, but got Unknown //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_0063: Expected O, but got Unknown //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Expected O, but got Unknown //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Expected O, but got Unknown //IL_00b8: 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_00c3: Expected O, 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) //IL_00e3: Expected O, but got Unknown //IL_00f8: 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_0103: Expected O, but got Unknown //IL_0158: Unknown result type (might be due to invalid IL or missing references) //IL_015d: Unknown result type (might be due to invalid IL or missing references) //IL_0163: Expected O, but got Unknown if (installed) { object obj = <>O.<0>__SpiritPunchOnEnter; if (obj == null) { hook_OnEnter val = SpiritPunchOnEnter; <>O.<0>__SpiritPunchOnEnter = val; obj = (object)val; } SpiritPunch.OnEnter -= (hook_OnEnter)obj; object obj2 = <>O.<1>__SojournBaseOnEnter; if (obj2 == null) { hook_OnEnter val2 = SojournBaseOnEnter; <>O.<1>__SojournBaseOnEnter = val2; obj2 = (object)val2; } SojournBase.OnEnter -= (hook_OnEnter)obj2; object obj3 = <>O.<2>__SeekerControllerOnEnable; if (obj3 == null) { hook_OnEnable val3 = SeekerControllerOnEnable; <>O.<2>__SeekerControllerOnEnable = val3; obj3 = (object)val3; } SeekerController.OnEnable -= (hook_OnEnable)obj3; object obj4 = <>O.<3>__SeekerControllerStart; if (obj4 == null) { hook_Start val4 = SeekerControllerStart; <>O.<3>__SeekerControllerStart = val4; obj4 = (object)val4; } SeekerController.Start -= (hook_Start)obj4; object obj5 = <>O.<4>__SeekerControllerFixedUpdate; if (obj5 == null) { hook_FixedUpdate val5 = SeekerControllerFixedUpdate; <>O.<4>__SeekerControllerFixedUpdate = val5; obj5 = (object)val5; } SeekerController.FixedUpdate -= (hook_FixedUpdate)obj5; object obj6 = <>O.<5>__SojournVehicleOnFixedUpdateForTenthSecond; if (obj6 == null) { hook_OnFixedUpdateForTenthSecond val6 = SojournVehicleOnFixedUpdateForTenthSecond; <>O.<5>__SojournVehicleOnFixedUpdateForTenthSecond = val6; obj6 = (object)val6; } SojournVehicle.OnFixedUpdateForTenthSecond -= (hook_OnFixedUpdateForTenthSecond)obj6; object obj7 = <>O.<6>__SojournVehicleEndSojournVehicle; if (obj7 == null) { hook_EndSojournVehicle val7 = SojournVehicleEndSojournVehicle; <>O.<6>__SojournVehicleEndSojournVehicle = val7; obj7 = (object)val7; } SojournVehicle.EndSojournVehicle -= (hook_EndSojournVehicle)obj7; object obj8 = <>O.<7>__HealthComponentTakeDamageProcess; if (obj8 == null) { hook_TakeDamageProcess val8 = HealthComponentTakeDamageProcess; <>O.<7>__HealthComponentTakeDamageProcess = val8; obj8 = (object)val8; } HealthComponent.TakeDamageProcess -= (hook_TakeDamageProcess)obj8; GlobalEventManager.onServerDamageDealt -= OnServerDamageDealt; GlobalEventManager.onCharacterDeathGlobal -= OnCharacterDeath; object obj9 = <>O.<10>__ApplyEchoGhostStats; if (obj9 == null) { StatHookEventHandler val9 = ApplyEchoGhostStats; <>O.<10>__ApplyEchoGhostStats = val9; obj9 = (object)val9; } RecalculateStatsAPI.GetStatCoefficients -= (StatHookEventHandler)obj9; installed = false; } } internal static int GetResonanceUnits(CharacterBody? body) { if (!Object.op_Implicit((Object)(object)body) || !Object.op_Implicit((Object)(object)ResonanceBuffDef)) { return 0; } return Mathf.Min(body.GetBuffCount(ResonanceBuffDef), 1000); } internal static float GetResonance(CharacterBody? body) { return (float)GetResonanceUnits(body) / 10f; } internal static void AddResonance(CharacterBody? body, float amount) { //IL_0041: Unknown result type (might be due to invalid IL or missing references) BuffDef resonanceBuffDef = ResonanceBuffDef; if (Object.op_Implicit((Object)(object)body) && Object.op_Implicit((Object)(object)resonanceBuffDef) && !(amount <= 0f)) { int resonanceUnits = GetResonanceUnits(body); int num = Mathf.Min(Mathf.RoundToInt(amount * 10f), 1000 - resonanceUnits); body.SetBuffCount(resonanceBuffDef.buffIndex, resonanceUnits + num); } } internal static bool TrySpendResonance(CharacterBody? body, float amount) { //IL_0040: Unknown result type (might be due to invalid IL or missing references) BuffDef resonanceBuffDef = ResonanceBuffDef; if (!Object.op_Implicit((Object)(object)body) || !Object.op_Implicit((Object)(object)resonanceBuffDef) || amount <= 0f) { return false; } int num = Mathf.RoundToInt(amount * 10f); int resonanceUnits = GetResonanceUnits(body); if (num <= 0 || resonanceUnits < num) { return false; } body.SetBuffCount(resonanceBuffDef.buffIndex, resonanceUnits - num); return true; } internal static float ConsumeAllResonance(CharacterBody? body) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) BuffDef resonanceBuffDef = ResonanceBuffDef; if (!Object.op_Implicit((Object)(object)body) || !Object.op_Implicit((Object)(object)resonanceBuffDef)) { return 0f; } float resonance = GetResonance(body); body.SetBuffCount(resonanceBuffDef.buffIndex, 0); return resonance; } private static void RegisterLanguageTokens() { LanguageAPI.Add("RESONATOR_PRIMARY_RESONANT_IMPACT_NAME", "Resonant Impact"); LanguageAPI.Add("RESONATOR_PRIMARY_RESONANT_IMPACT_DESCRIPTION", "Fire an accelerating spectral projectile for 200% damage. Gain 0.8 Resonance when it hits an enemy. Passing through a ghost consumes 0.5 Resonance to heal it for 10% maximum health."); LanguageAPI.Add("RESONATOR_PASSIVE_RESONANCE_NAME", "Resonance"); LanguageAPI.Add("RESONATOR_PASSIVE_RESONANCE_DESCRIPTION", "Begin each run with a Happiest Mask. Hold up to 100 Resonance. Your ghosts gain 0.2 Resonance for you whenever their attacks hit. Kills by you or your minions grant 3 Resonance."); LanguageAPI.Add("RESONATOR_SECONDARY_ECHO_SOUL_NAME", "Echo Soulbind"); LanguageAPI.Add("RESONATOR_SECONDARY_ECHO_SOUL_DESCRIPTION", "Lock onto a monster and consume all Resonance to deal 15% damage per Resonance, then summon a ghost of it with 240% base damage that preserves its elite aspect. More Resonance extends its lifetime."); LanguageAPI.Add("RESONATOR_SECONDARY_EMPATHIC_LOCK_NAME", "Empathic Lock"); LanguageAPI.Add("RESONATOR_SECONDARY_EMPATHIC_LOCK_DESCRIPTION", "Mark a monster for 60 seconds. Your ghosts prioritize it and deal 100% increased damage to it. If it dies while marked, summon a ghost with 240% base damage. Only one target can be marked at a time."); LanguageAPI.Add("RESONATOR_UTILITY_SOUL_ROAM_NAME", "Soul Roam"); LanguageAPI.Add("RESONATOR_UTILITY_SOUL_ROAM_DESCRIPTION", "Become a pale spirit, then detonate for 800% damage. Consumes 2 Resonance per second and detonates when Resonance is depleted. Gain 4 Resonance per enemy hit. Touching a ghost pauses its natural decay for 8 seconds."); LanguageAPI.Add("RESONATOR_SPECIAL_SOUL_DOMAIN_NAME", "Soul Domain"); LanguageAPI.Add("RESONATOR_SPECIAL_SOUL_DOMAIN_DESCRIPTION", "Create a 20m domain for 12 seconds. Monsters that die within consume 10 Resonance to become equipment-inheriting elite ghosts with 240% base damage that last 30 seconds."); LanguageAPI.Add("RESONATOR_SPECIAL_SOUL_BEAM_NAME", "Soul-Brewing Beam"); LanguageAPI.Add("RESONATOR_SPECIAL_SOUL_BEAM_DESCRIPTION", "Fire a non-piercing beam for 2000% damage. Hitting a monster consumes 10 Resonance, if available, to summon an equipment-inheriting elite ghost with 240% base damage for 60 seconds. Hitting one of your ghosts permanently stops its natural decay."); LanguageAPI.Add("RESONATOR_SECONDARY_ECHO_SOUL_NAME", "回响牵魂", "zh-CN"); LanguageAPI.Add("RESONATOR_SECONDARY_ECHO_SOUL_DESCRIPTION", "锁定一只怪物,消耗所有共鸣造成每点共鸣15%伤害,并召唤一个拥有240%基础伤害、保留精英状态的同类幽灵。共鸣越高,幽灵存留越久。", "zh-CN"); LanguageAPI.Add("RESONATOR_SECONDARY_EMPATHIC_LOCK_NAME", "共感锁定", "zh-CN"); LanguageAPI.Add("RESONATOR_SECONDARY_EMPATHIC_LOCK_DESCRIPTION", "标记一只怪物60秒。你的幽灵会优先攻击该目标,并对其造成100%额外伤害。目标在标记期间死亡时,变为拥有240%基础伤害的幽灵。同一时间只能标记一个目标。", "zh-CN"); LanguageAPI.Add("RESONATOR_UTILITY_SOUL_ROAM_NAME", "魂灵游", "zh-CN"); LanguageAPI.Add("RESONATOR_UTILITY_SOUL_ROAM_DESCRIPTION", "化为浅蓝魂灵飞行,结束时爆发造成800%伤害,每秒消耗2共鸣,共鸣耗尽时强制结束并爆炸。每命中一个单位获得4共鸣;飞行期间接触幽灵会使其停止自然衰减8秒。", "zh-CN"); LanguageAPI.Add("RESONATOR_SPECIAL_SOUL_DOMAIN_NAME", "亡魂领域", "zh-CN"); LanguageAPI.Add("RESONATOR_SPECIAL_SOUL_DOMAIN_DESCRIPTION", "以自身为中心展开一个半径20米、持续12秒的领域。领域内死亡的怪物会消耗10共鸣,变为继承装备与精英状态、拥有240%基础伤害且存留30秒的幽灵。", "zh-CN"); LanguageAPI.Add("RESONATOR_SPECIAL_SOUL_BEAM_NAME", "酝魂光束", "zh-CN"); LanguageAPI.Add("RESONATOR_SPECIAL_SOUL_BEAM_DESCRIPTION", "发射一道不可穿透的酝魂光束,击中怪物造成2000%伤害,并在共鸣足够时消耗10共鸣,生成一个继承装备与精英状态、拥有240%基础伤害且期望存续60秒的同类幽灵。击中自己的幽灵会使其永久停止自然衰减。", "zh-CN"); LanguageAPI.Add("RESONATOR_PRIMARY_RESONANT_IMPACT_NAME", "谐振冲击", "zh-CN"); LanguageAPI.Add("RESONATOR_PRIMARY_RESONANT_IMPACT_DESCRIPTION", "发射不断加速的幽灵弹体,造成200%伤害。命中敌人时获得0.8共鸣;穿过幽灵时消耗0.5共鸣,为其恢复10%最大生命值。", "zh-CN"); LanguageAPI.Add("RESONATOR_PASSIVE_RESONANCE_NAME", "共鸣", "zh-CN"); LanguageAPI.Add("RESONATOR_PASSIVE_RESONANCE_DESCRIPTION", "开局获得一个快乐面具。最多拥有100共鸣。你的幽灵每次攻击命中都会为你获得0.2共鸣。你或你的随从击杀敌人时获得3共鸣。", "zh-CN"); } private static void RegisterResonanceBuff() { //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) ResonanceBuffDef = ScriptableObject.CreateInstance(); ((Object)ResonanceBuffDef).name = "bdResonatorResonance"; ResonanceBuffDef.canStack = true; ResonanceBuffDef.isHidden = true; ResonanceBuffDef.isDebuff = false; ResonanceBuffDef.buffColor = new Color(0.25f, 0.78f, 1f, 1f); if (!ContentAddition.AddBuffDef(ResonanceBuffDef)) { throw new InvalidOperationException("Could not register the Resonance buff."); } } private static void RegisterSkillIcons() { PassiveIcon = Plugin.LoadEmbeddedSprite("HurricaneDifficulty.Assets.Survivors.resonator_skill_passive.png", "texResonatorPassiveIcon"); PrimaryIcon = Plugin.LoadEmbeddedSprite("HurricaneDifficulty.Assets.Survivors.resonator_skill_primary.png", "texResonantImpactIcon"); SecondaryIcon = Plugin.LoadEmbeddedSprite("HurricaneDifficulty.Assets.Survivors.resonator_skill_secondary.png", "texEchoSoulbindIcon"); EmpathicLockIcon = Plugin.LoadEmbeddedSprite("HurricaneDifficulty.Assets.Survivors.resonator_skill_empathic_lock.png", "texEmpathicLockIcon"); UtilityIcon = Plugin.LoadEmbeddedSprite("HurricaneDifficulty.Assets.Survivors.resonator_skill_utility.png", "texSoulRoamIcon"); SpecialIcon = Plugin.LoadEmbeddedSprite("HurricaneDifficulty.Assets.Survivors.resonator_skill_special.png", "texSoulDomainIcon"); SoulBeamIcon = Plugin.LoadEmbeddedSprite("HurricaneDifficulty.Assets.Survivors.resonator_skill_soul_beam.png", "texSoulBeamIcon"); } private static void RegisterProjectile() { GameObject obj = LoadAsset((object)"RoR2/DLC2/Seeker/SpiritPunchProjectile.prefab"); GameObject val = PrefabAPI.InstantiateClone(LoadAsset((object)"RoR2/DLC2/Seeker/SpiritPunchGhost.prefab"), "ResonatorResonantImpactGhost", false); ApplyGhostVisuals(val); ProjectilePrefab = PrefabAPI.InstantiateClone(obj, "ResonatorResonantImpactProjectile", true); ProjectileController obj2 = ProjectilePrefab.GetComponent() ?? throw new InvalidOperationException("Spirit Punch projectile has no ProjectileController."); obj2.ghostPrefab = val; obj2.ghostPrefabReference = null; obj2.procCoefficient = 1f; ProjectileSimple component = ProjectilePrefab.GetComponent(); ProjectileImpactExplosion component2 = ProjectilePrefab.GetComponent(); if (Object.op_Implicit((Object)(object)component2)) { component2.impactEffect = CloneBlueEffect(component2.impactEffect, "ResonatorResonantImpactHitVFX"); ((ProjectileExplosion)component2).explosionEffect = CloneBlueEffect(((ProjectileExplosion)component2).explosionEffect, "ResonatorResonantImpactExplosionVFX"); ((ProjectileExplosion)component2).blastImpactEffect = CloneBlueEffect(((ProjectileExplosion)component2).blastImpactEffect, "ResonatorResonantImpactBlastHitVFX"); } if (Object.op_Implicit((Object)(object)component)) { float num = component.lifetime; if (Object.op_Implicit((Object)(object)component2) && component2.lifetime > 0f) { num = Mathf.Min(num, component2.lifetime); } float num2 = GetAcceleratingTravelDistance(component.desiredForwardSpeed, 28f, num); if (Object.op_Implicit((Object)(object)component2) && component2.destroyOnDistance) { num2 = Mathf.Min(num2, component2.maxDistance); } float num3 = num2 * 2.5f; float lifetime = (component.lifetime = GetTravelTimeForDistance(component.desiredForwardSpeed, 28f, num3)); if (Object.op_Implicit((Object)(object)component2)) { component2.lifetime = lifetime; if (component2.destroyOnDistance) { component2.maxDistance = num3; } } } ProjectilePrefab.AddComponent().acceleration = 28f; ProjectilePrefab.AddComponent(); if (!ContentAddition.AddProjectile(ProjectilePrefab)) { throw new InvalidOperationException("Could not register the Resonant Impact projectile."); } } private static void RegisterEchoSoulAssets(GameObject bodyPrefab) { //IL_0036: 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) GameObject obj = LoadAsset((object)"RoR2/DLC3/Drone Tech/DroneTechTrackingIndicator.prefab"); EchoSoulTargetIndicatorPrefab = PrefabAPI.InstantiateClone(obj, "ResonatorEchoSoulTargetIndicator", false); EchoSoulMarkedIndicatorPrefab = PrefabAPI.InstantiateClone(obj, "ResonatorEchoSoulMarkedIndicator", false); Transform transform = EchoSoulMarkedIndicatorPrefab.transform; transform.localScale *= 0.5f; ApplyBlueMaterials(EchoSoulMarkedIndicatorPrefab); ApplyPaleBlueEffects(EchoSoulMarkedIndicatorPrefab); (bodyPrefab.GetComponent() ?? bodyPrefab.AddComponent()).Configure(EchoSoulTargetIndicatorPrefab); (bodyPrefab.GetComponent() ?? bodyPrefab.AddComponent()).Configure(EchoSoulMarkedIndicatorPrefab); } private static void RegisterSoulRoamAssets() { //IL_005a: Unknown result type (might be due to invalid IL or missing references) SoulRoamVehiclePrefab = PrefabAPI.InstantiateClone(LoadAsset((object)"RoR2/DLC2/Seeker/SojournVehicle/SojournVehicle.prefab"), "ResonatorSoulRoamVehicle", true); SojournVehicle val = SoulRoamVehiclePrefab.GetComponent() ?? throw new InvalidOperationException("Seeker's Sojourn vehicle has no SojournVehicle component."); VehicleSeat obj = SoulRoamVehiclePrefab.GetComponent() ?? throw new InvalidOperationException("Seeker's Sojourn vehicle has no VehicleSeat component."); ((SojournVehicleBase)val).blastDamageCoefficient = 8f; ((SojournVehicleBase)val).blastFalloffModel = (FalloffModel)0; val.dmgAddedPerSecond = 0f; val.incrementalFlightDamage = 0f; val.delayedIncreasedFlightDamage = 0f; obj.disableAllCollidersAndHurtboxes = false; obj.disableColliders = true; SoulRoamVehiclePrefab.AddComponent(); ApplySoulRoamGhostVisuals(SoulRoamVehiclePrefab); if (Object.op_Implicit((Object)(object)((SojournVehicleBase)val).explosionEffectPrefab)) { GameObject val2 = PrefabAPI.InstantiateClone(((SojournVehicleBase)val).explosionEffectPrefab, "ResonatorSoulRoamExplosionVFX", false); ApplyBlueMaterials(val2); ApplyPaleBlueEffects(val2); ((SojournVehicleBase)val).explosionEffectPrefab = val2; ContentAddition.AddEffect(val2); } if (!ContentAddition.AddNetworkedObject(SoulRoamVehiclePrefab)) { throw new InvalidOperationException("Could not register Soul Roam's vehicle prefab."); } } private static void RegisterSoulDomainAssets() { //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) GameObject obj = LegacyResourcesAPI.Load("Prefabs/NetworkedObjects/WarbannerWard"); if (!Object.op_Implicit((Object)(object)obj)) { throw new InvalidOperationException("Could not load Warbanner's ward prefab."); } SoulDomainPrefab = PrefabAPI.InstantiateClone(obj, "ResonatorSoulDomain", true); BuffWard val = SoulDomainPrefab.GetComponent() ?? throw new InvalidOperationException("Warbanner's ward prefab has no BuffWard component."); val.shape = (BuffWardShape)0; val.radius = 20f; val.buffDef = null; val.expires = true; val.expireDuration = 12f; val.animateRadius = false; DisableWardVisuals(SoulDomainPrefab, val.rangeIndicator); ResonatorPrototypeModule.CreateFaceOrbVisual(SoulDomainPrefab.transform, "ResonatorSoulDomainOrb", new Vector3(0f, 2.6f, 0f), Vector3.zero, 3.36f); if (Object.op_Implicit((Object)(object)val.rangeIndicator)) { ((Component)val.rangeIndicator).gameObject.SetActive(true); ApplyBlueMaterials(((Component)val.rangeIndicator).gameObject); ApplyPaleBlueEffects(((Component)val.rangeIndicator).gameObject); } SoulDomainPrefab.AddComponent(); if (!ContentAddition.AddNetworkedObject(SoulDomainPrefab)) { throw new InvalidOperationException("Could not register Soul Domain's ward prefab."); } } private static void RegisterSoulBeamAssets() { SoulBeamTracerPrefab = CloneBlueEffect(LoadAsset((object)"RoR2/DLC1/VoidSurvivor/VoidSurvivorBeamTracer.prefab"), "ResonatorSoulBeamTracer"); SoulBeamImpactPrefab = CloneBlueEffect(LoadAsset((object)"RoR2/DLC1/VoidSurvivor/VoidSurvivorBeamImpact.prefab"), "ResonatorSoulBeamImpact"); SoulBeamMuzzleflashPrefab = CloneBlueEffect(LoadAsset((object)"RoR2/DLC1/VoidSurvivor/VoidSurvivorBeamMuzzleflash.prefab"), "ResonatorSoulBeamMuzzleflash"); if (!Object.op_Implicit((Object)(object)SoulBeamTracerPrefab) || !Object.op_Implicit((Object)(object)SoulBeamImpactPrefab) || !Object.op_Implicit((Object)(object)SoulBeamMuzzleflashPrefab)) { throw new InvalidOperationException("Could not register Soul-Brewing Beam's effects."); } } private static void RegisterCrosshair(GameObject bodyPrefab) { GameObject obj = LoadAsset((object)"RoR2/DLC3/Drifter/DrifterCrosshair.prefab"); GameObject val = LoadAsset((object)"RoR2/DLC3/Drifter/Junk UI.prefab"); CharacterBody obj2 = bodyPrefab.GetComponent() ?? throw new InvalidOperationException("Resonator body has no CharacterBody."); GameObject val2 = PrefabAPI.InstantiateClone(obj, "ResonatorCrosshair", false); Transform val3 = FindDescendant(val2.transform, "Junk UI"); if (Object.op_Implicit((Object)(object)val3)) { ((Component)val3).gameObject.SetActive(false); } GameObject val4 = PrefabAPI.InstantiateClone(val, "ResonatorResonanceHud", false); val4.AddComponent().Configure(val4.transform); ResonanceHudOverlayController.SharedOverlayPrefab = val4; bodyPrefab.AddComponent().Configure(val4); if ((object)DefaultCrosshairPrefabField == null) { throw new MissingFieldException(typeof(CharacterBody).FullName, "_defaultCrosshairPrefab"); } DefaultCrosshairPrefabField.SetValue(obj2, val2); } private static void RegisterSkills(GameObject bodyPrefab) { //IL_0123: Unknown result type (might be due to invalid IL or missing references) //IL_0131: Unknown result type (might be due to invalid IL or missing references) //IL_0133: Unknown result type (might be due to invalid IL or missing references) //IL_0167: Unknown result type (might be due to invalid IL or missing references) //IL_016c: Unknown result type (might be due to invalid IL or missing references) //IL_01a3: Unknown result type (might be due to invalid IL or missing references) //IL_01a5: Unknown result type (might be due to invalid IL or missing references) SkillLocator val = bodyPrefab.GetComponent() ?? throw new InvalidOperationException("Resonator body has no SkillLocator."); if ((object)SkillFamilyField == null) { throw new MissingFieldException(typeof(GenericSkill).FullName, "_skillFamily"); } ReplaceSeekerPassiveSkillSlot(bodyPrefab, val); RegisterSecondarySkill(val); RegisterUtilitySkill(val); RegisterSpecialSkill(val); GenericSkill val2 = val.primary ?? throw new InvalidOperationException("Resonator body has no primary skill slot."); SkillDef val3 = (val2.skillFamily ?? throw new InvalidOperationException("Resonator primary has no skill family.")).defaultSkillDef ?? throw new InvalidOperationException("Seeker primary family has no default skill."); SteppedSkillDef val4 = ScriptableObject.CreateInstance(); CopySkillDef(val3, (SkillDef)(object)val4); ((Object)val4).name = "ResonatorBodyResonantImpact"; ((SkillDef)val4).skillName = "ResonantImpact"; ((SkillDef)val4).skillNameToken = "RESONATOR_PRIMARY_RESONANT_IMPACT_NAME"; ((SkillDef)val4).skillDescriptionToken = "RESONATOR_PRIMARY_RESONANT_IMPACT_DESCRIPTION"; ((SkillDef)val4).icon = PrimaryIcon; val4.stepCount = 2; val4.stepGraceDuration = ((SteppedSkillDef)(((val3 is SteppedSkillDef) ? val3 : null)?)).stepGraceDuration ?? 0.5f; SkillFamily val5 = ScriptableObject.CreateInstance(); ((Object)val5).name = "ResonatorBodyPrimaryFamily"; val5.defaultVariantIndex = 0u; val5.variants = (Variant[])(object)new Variant[1] { new Variant { skillDef = (SkillDef)(object)val4 } }; if (!ContentAddition.AddSkillDef((SkillDef)(object)val4) || !ContentAddition.AddSkillFamily(val5)) { throw new InvalidOperationException("Could not register Resonant Impact's skill content."); } SkillFamilyField.SetValue(val2, val5); PassiveSkill passiveSkill = val.passiveSkill; passiveSkill.enabled = false; passiveSkill.skillNameToken = string.Empty; passiveSkill.skillDescriptionToken = string.Empty; passiveSkill.keywordToken = string.Empty; passiveSkill.icon = null; val.passiveSkill = passiveSkill; } private static void RegisterSecondarySkill(SkillLocator skillLocator) { //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_0049: 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_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: 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_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_0108: Unknown result type (might be due to invalid IL or missing references) //IL_0117: Unknown result type (might be due to invalid IL or missing references) //IL_0119: Unknown result type (might be due to invalid IL or missing references) GenericSkill val = skillLocator.secondary ?? throw new InvalidOperationException("Resonator body has no secondary skill slot."); SkillDef source = (val.skillFamily ?? throw new InvalidOperationException("Resonator secondary has no skill family.")).defaultSkillDef ?? throw new InvalidOperationException("Seeker secondary family has no default skill."); bool flag = default(bool); SerializableEntityStateType activationState = ContentAddition.AddEntityState(ref flag); bool flag2 = default(bool); ContentAddition.AddEntityState(ref flag2); bool flag3 = default(bool); SerializableEntityStateType activationState2 = ContentAddition.AddEntityState(ref flag3); bool flag4 = default(bool); ContentAddition.AddEntityState(ref flag4); if (!flag || !flag2 || !flag3 || !flag4) { throw new InvalidOperationException("Could not register Resonator's secondary entity states."); } SkillDef val2 = CreateSingleStockSkill(source, "ResonatorBodyEchoSoulbind", "EchoSoulbind", "RESONATOR_SECONDARY_ECHO_SOUL_NAME", "RESONATOR_SECONDARY_ECHO_SOUL_DESCRIPTION", SecondaryIcon, activationState, 10f); SkillDef val3 = CreateSingleStockSkill(source, "ResonatorBodyEmpathicLock", "EmpathicLock", "RESONATOR_SECONDARY_EMPATHIC_LOCK_NAME", "RESONATOR_SECONDARY_EMPATHIC_LOCK_DESCRIPTION", EmpathicLockIcon, activationState2, 10f); SkillFamily val4 = ScriptableObject.CreateInstance(); ((Object)val4).name = "ResonatorBodySecondaryFamily"; val4.defaultVariantIndex = 0u; val4.variants = (Variant[])(object)new Variant[2] { new Variant { skillDef = val2 }, new Variant { skillDef = val3 } }; if (!ContentAddition.AddSkillDef(val2) || !ContentAddition.AddSkillDef(val3) || !ContentAddition.AddSkillFamily(val4)) { throw new InvalidOperationException("Could not register Resonator's secondary skill content."); } SkillFamilyField.SetValue(val, val4); } private static void RegisterUtilitySkill(SkillLocator skillLocator) { //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) GenericSkill val = skillLocator.utility ?? throw new InvalidOperationException("Resonator body has no utility skill slot."); SkillDef source = (val.skillFamily ?? throw new InvalidOperationException("Resonator utility has no skill family.")).defaultSkillDef ?? throw new InvalidOperationException("Seeker utility family has no default skill."); SkillDef val2 = ScriptableObject.CreateInstance(); CopySkillDef(source, val2); ((Object)val2).name = "ResonatorBodySoulRoam"; val2.skillName = "SoulRoam"; val2.skillNameToken = "RESONATOR_UTILITY_SOUL_ROAM_NAME"; val2.skillDescriptionToken = "RESONATOR_UTILITY_SOUL_ROAM_DESCRIPTION"; val2.icon = UtilityIcon; SkillFamily val3 = ScriptableObject.CreateInstance(); ((Object)val3).name = "ResonatorBodyUtilityFamily"; val3.defaultVariantIndex = 0u; val3.variants = (Variant[])(object)new Variant[1] { new Variant { skillDef = val2 } }; if (!ContentAddition.AddSkillDef(val2) || !ContentAddition.AddSkillFamily(val3)) { throw new InvalidOperationException("Could not register Soul Roam's skill content."); } SkillFamilyField.SetValue(val, val3); } private static void RegisterSpecialSkill(SkillLocator skillLocator) { //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_007b: 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_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_010e: Unknown result type (might be due to invalid IL or missing references) //IL_0110: Unknown result type (might be due to invalid IL or missing references) GenericSkill val = skillLocator.special ?? throw new InvalidOperationException("Resonator body has no special skill slot."); SkillDef source = (val.skillFamily ?? throw new InvalidOperationException("Resonator special has no skill family.")).defaultSkillDef ?? throw new InvalidOperationException("Seeker special family has no default skill."); bool flag = default(bool); SerializableEntityStateType activationState = ContentAddition.AddEntityState(ref flag); bool flag2 = default(bool); SerializableEntityStateType activationState2 = ContentAddition.AddEntityState(ref flag2); if (!flag || !flag2) { throw new InvalidOperationException("Could not register Resonator's special entity states."); } SkillDef val2 = CreateSingleStockSkill(source, "ResonatorBodySoulDomain", "SoulDomain", "RESONATOR_SPECIAL_SOUL_DOMAIN_NAME", "RESONATOR_SPECIAL_SOUL_DOMAIN_DESCRIPTION", SpecialIcon, activationState, 20f); SkillDef val3 = CreateSingleStockSkill(source, "ResonatorBodySoulBeam", "SoulBeam", "RESONATOR_SPECIAL_SOUL_BEAM_NAME", "RESONATOR_SPECIAL_SOUL_BEAM_DESCRIPTION", SoulBeamIcon, activationState2, 20f); val2.interruptPriority = (InterruptPriority)2; val3.interruptPriority = (InterruptPriority)2; SkillFamily val4 = ScriptableObject.CreateInstance(); ((Object)val4).name = "ResonatorBodySpecialFamily"; val4.defaultVariantIndex = 0u; val4.variants = (Variant[])(object)new Variant[2] { new Variant { skillDef = val2 }, new Variant { skillDef = val3 } }; if (!ContentAddition.AddSkillDef(val2) || !ContentAddition.AddSkillDef(val3) || !ContentAddition.AddSkillFamily(val4)) { throw new InvalidOperationException("Could not register Resonator's special skill content."); } SkillFamilyField.SetValue(val, val4); } private static SkillDef ReplaceSeekerPassiveSkillSlot(GameObject bodyPrefab, SkillLocator skillLocator) { //IL_0160: Unknown result type (might be due to invalid IL or missing references) //IL_016f: Unknown result type (might be due to invalid IL or missing references) //IL_0171: Unknown result type (might be due to invalid IL or missing references) GenericSkill[] components = bodyPrefab.GetComponents(); foreach (GenericSkill val in components) { if ((Object)(object)val == (Object)(object)skillLocator.primary || (Object)(object)val == (Object)(object)skillLocator.secondary || (Object)(object)val == (Object)(object)skillLocator.utility || (Object)(object)val == (Object)(object)skillLocator.special) { continue; } SkillFamily skillFamily = val.skillFamily; string obj = (Object.op_Implicit((Object)(object)skillFamily) ? ((Object)skillFamily).name : string.Empty); SkillDef val2 = (Object.op_Implicit((Object)(object)skillFamily) ? skillFamily.defaultSkillDef : null); if (obj.IndexOf("SeekerBodyPassiveFamily", StringComparison.OrdinalIgnoreCase) >= 0 || (Object.op_Implicit((Object)(object)val2) && !string.IsNullOrEmpty(val2.skillNameToken) && val2.skillNameToken.IndexOf("INNER_STRENGTH", StringComparison.OrdinalIgnoreCase) >= 0)) { if (!Object.op_Implicit((Object)(object)val2)) { break; } SkillDef val3 = ScriptableObject.CreateInstance(); CopySkillDef(val2, val3); ((Object)val3).name = "ResonatorBodyResonance"; val3.skillName = "Resonance"; val3.skillNameToken = "RESONATOR_PASSIVE_RESONANCE_NAME"; val3.skillDescriptionToken = "RESONATOR_PASSIVE_RESONANCE_DESCRIPTION"; val3.icon = PassiveIcon; val3.keywordTokens = Array.Empty(); val3.isCombatSkill = false; SkillFamily val4 = ScriptableObject.CreateInstance(); ((Object)val4).name = "ResonatorBodyPassiveFamily"; val4.defaultVariantIndex = 0u; val4.variants = (Variant[])(object)new Variant[1] { new Variant { skillDef = val3 } }; if (!ContentAddition.AddSkillDef(val3) || !ContentAddition.AddSkillFamily(val4)) { throw new InvalidOperationException("Could not register Resonance's passive skill content."); } SkillFamilyField.SetValue(val, val4); return val3; } } throw new InvalidOperationException("Could not find Seeker's passive skill slot to replace."); } private static void CopySkillDef(SkillDef source, SkillDef destination) { //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_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) destination.keywordTokens = Array.Empty(); destination.icon = source.icon; destination.activationStateMachineName = source.activationStateMachineName; destination.activationState = source.activationState; destination.interruptPriority = source.interruptPriority; destination.baseRechargeInterval = source.baseRechargeInterval; destination.baseMaxStock = source.baseMaxStock; destination.rechargeStock = source.rechargeStock; destination.requiredStock = source.requiredStock; destination.stockToConsume = source.stockToConsume; destination.attackSpeedBuffsRestockSpeed = source.attackSpeedBuffsRestockSpeed; destination.attackSpeedBuffsRestockSpeed_Multiplier = source.attackSpeedBuffsRestockSpeed_Multiplier; destination.resetCooldownTimerOnUse = source.resetCooldownTimerOnUse; destination.fullRestockOnAssign = source.fullRestockOnAssign; destination.dontAllowPastMaxStocks = source.dontAllowPastMaxStocks; destination.beginSkillCooldownOnSkillEnd = source.beginSkillCooldownOnSkillEnd; destination.isCooldownBlockedUntilManuallyReset = source.isCooldownBlockedUntilManuallyReset; destination.cancelSprintingOnActivation = source.cancelSprintingOnActivation; destination.forceSprintDuringState = source.forceSprintDuringState; destination.canceledFromSprinting = source.canceledFromSprinting; destination.isCombatSkill = source.isCombatSkill; destination.mustKeyPress = source.mustKeyPress; destination.triggeredByPressRelease = source.triggeredByPressRelease; destination.autoHandleLuminousShot = source.autoHandleLuminousShot; destination.suppressSkillActivation = source.suppressSkillActivation; destination.hideStockCount = source.hideStockCount; destination.hideCooldown = source.hideCooldown; } private static SkillDef CreateSingleStockSkill(SkillDef source, string objectName, string skillName, string nameToken, string descriptionToken, Sprite? icon, SerializableEntityStateType activationState, float cooldown) { //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) SkillDef val = ScriptableObject.CreateInstance(); CopySkillDef(source, val); ((Object)val).name = objectName; val.skillName = skillName; val.skillNameToken = nameToken; val.skillDescriptionToken = descriptionToken; val.icon = icon; val.activationState = activationState; val.baseRechargeInterval = cooldown; val.baseMaxStock = 1; val.rechargeStock = 1; val.requiredStock = 1; val.stockToConsume = 1; val.beginSkillCooldownOnSkillEnd = true; val.mustKeyPress = true; val.triggeredByPressRelease = false; return val; } private static void SpiritPunchOnEnter(orig_OnEnter orig, SpiritPunch self) { bool flag = IsResonator(Object.op_Implicit((Object)(object)((EntityState)self).outer) ? ((Component)((EntityState)self).outer).GetComponent() : null); orig.Invoke(self); if (Object.op_Implicit((Object)(object)ProjectilePrefab) && flag) { self.projectilePrefab = ProjectilePrefab; self.projectileFinisherPrefab = ProjectilePrefab; self.damageCoefficient = 2f; self.comboDamageCoefficient = 2f; self.procCoefficient = 1f; self.dmgBuffIncrease = 0f; } } private static void SeekerControllerOnEnable(orig_OnEnable orig, SeekerController self) { orig.Invoke(self); if (IsResonator(((Component)self).GetComponent())) { object? obj = SeekerOverlayControllerField?.GetValue(self); OverlayController val = (OverlayController)((obj is OverlayController) ? obj : null); if (val != null) { HudOverlayManager.RemoveOverlay(val); SeekerOverlayControllerField.SetValue(self, null); } } } private static void SeekerControllerStart(orig_Start orig, SeekerController self) { if (!IsResonator(((Component)self).GetComponent())) { orig.Invoke(self); } } private static void SeekerControllerFixedUpdate(orig_FixedUpdate orig, SeekerController self) { if (!IsResonator(((Component)self).GetComponent())) { orig.Invoke(self); } } private static void SojournBaseOnEnter(orig_OnEnter orig, SojournBase self) { CharacterBody body = (Object.op_Implicit((Object)(object)((EntityState)self).outer) ? ((Component)((EntityState)self).outer).GetComponent() : null); if (Object.op_Implicit((Object)(object)SoulRoamVehiclePrefab) && IsResonator(body)) { self.vehiclePrefab = SoulRoamVehiclePrefab; } orig.Invoke(self); } private static void SojournVehicleOnFixedUpdateForTenthSecond(orig_OnFixedUpdateForTenthSecond orig, SojournVehicle self) { if (!Object.op_Implicit((Object)(object)((Component)self).GetComponent())) { orig.Invoke(self); } } private static void SojournVehicleEndSojournVehicle(orig_EndSojournVehicle orig, SojournVehicle self) { ResonatorSoulRoamVehicleController component = ((Component)self).GetComponent(); if (!Object.op_Implicit((Object)(object)component)) { orig.Invoke(self); return; } component.IsDetonating = true; try { orig.Invoke(self); } finally { component.IsDetonating = false; } } private static void OnServerDamageDealt(DamageReport damageReport) { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) if (damageReport.damageDealt <= 0f || !Object.op_Implicit((Object)(object)damageReport.attackerBody) || damageReport.attackerTeamIndex == damageReport.victimTeamIndex) { return; } GameObject inflictor = damageReport.damageInfo.inflictor; ResonatorSoulRoamVehicleController obj = (Object.op_Implicit((Object)(object)inflictor) ? inflictor.GetComponent() : null); if (obj != null && obj.IsDetonating && IsResonator(damageReport.attackerBody)) { AddResonance(damageReport.attackerBody, 4f); return; } if (Object.op_Implicit((Object)(object)inflictor) && Object.op_Implicit((Object)(object)inflictor.GetComponent())) { AddResonance(damageReport.attackerBody, 0.8f); return; } CharacterMaster resonatorGhostOwner = GetResonatorGhostOwner(damageReport.attackerBody.master); if (Object.op_Implicit((Object)(object)resonatorGhostOwner) && IsResonator(resonatorGhostOwner.GetBody())) { AddResonance(resonatorGhostOwner.GetBody(), 0.2f); } } private static void OnCharacterDeath(DamageReport damageReport) { //IL_0015: 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) if (NetworkServer.active && Object.op_Implicit((Object)(object)damageReport.attackerBody) && damageReport.attackerTeamIndex != damageReport.victimTeamIndex) { CharacterMaster val = ResolveResonatorCombatOwner(damageReport.attackerBody.master); if (Object.op_Implicit((Object)(object)val)) { AddResonance(val.GetBody(), 3f); } } } private static void HealthComponentTakeDamageProcess(orig_TakeDamageProcess orig, HealthComponent self, DamageInfo damageInfo) { if (NetworkServer.active && Object.op_Implicit((Object)(object)self) && Object.op_Implicit((Object)(object)self.body) && Object.op_Implicit((Object)(object)damageInfo.attacker)) { CharacterBody component = damageInfo.attacker.GetComponent(); CharacterMaster resonatorGhostOwner = GetResonatorGhostOwner((component != null) ? component.master : null); CharacterBody val = (Object.op_Implicit((Object)(object)resonatorGhostOwner) ? resonatorGhostOwner.GetBody() : null); ResonatorMarkedTargetController obj = (Object.op_Implicit((Object)(object)val) ? ((Component)val).GetComponent() : null); if (obj != null && obj.IsMarkedTarget(self.body)) { damageInfo.damage *= 2f; } } orig.Invoke(self, damageInfo); } internal static CharacterMaster? GetResonatorGhostOwner(CharacterMaster? ghostMaster) { if (!Object.op_Implicit((Object)(object)ghostMaster) || !Object.op_Implicit((Object)(object)ghostMaster.inventory) || ghostMaster.inventory.GetItemCountEffective(Items.Ghost) <= 0) { return null; } CharacterMaster val = ((Component)ghostMaster).GetComponent()?.OwnerMaster; if (Object.op_Implicit((Object)(object)val) && IsResonator(val.GetBody())) { return val; } return FindResonatorOwner(ghostMaster); } private static CharacterMaster? ResolveResonatorCombatOwner(CharacterMaster? attackerMaster) { if (!Object.op_Implicit((Object)(object)attackerMaster)) { return null; } if (IsResonator(attackerMaster.GetBody())) { return attackerMaster; } CharacterMaster resonatorGhostOwner = GetResonatorGhostOwner(attackerMaster); if (!Object.op_Implicit((Object)(object)resonatorGhostOwner)) { return FindResonatorOwner(attackerMaster); } return resonatorGhostOwner; } private static CharacterMaster? FindResonatorOwner(CharacterMaster minionMaster) { CharacterMaster val = minionMaster; for (int i = 0; i < 8; i++) { if (!Object.op_Implicit((Object)(object)val)) { break; } MinionOwnership minionOwnership = val.minionOwnership; CharacterMaster val2 = ((minionOwnership != null) ? minionOwnership.ownerMaster : null); if (!Object.op_Implicit((Object)(object)val2) || (Object)(object)val2 == (Object)(object)val) { return null; } if (IsResonator(val2.GetBody())) { return val2; } val = val2; } return null; } internal static void ExecuteEchoSoulbind(CharacterBody ownerBody, HurtBox? targetHurtBox) { //IL_0047: 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_007a: 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_0080: 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_009e: 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_00af: 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_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_00fd: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Unknown result type (might be due to invalid IL or missing references) //IL_010d: Unknown result type (might be due to invalid IL or missing references) //IL_0113: Unknown result type (might be due to invalid IL or missing references) //IL_0119: Unknown result type (might be due to invalid IL or missing references) //IL_011b: Unknown result type (might be due to invalid IL or missing references) //IL_0120: Unknown result type (might be due to invalid IL or missing references) //IL_0122: Unknown result type (might be due to invalid IL or missing references) //IL_0127: Unknown result type (might be due to invalid IL or missing references) //IL_012e: Expected O, but got Unknown if (!NetworkServer.active || !Object.op_Implicit((Object)(object)ownerBody) || !Object.op_Implicit((Object)(object)targetHurtBox)) { return; } HealthComponent healthComponent = targetHurtBox.healthComponent; CharacterBody val = (Object.op_Implicit((Object)(object)healthComponent) ? healthComponent.body : null); TeamIndex val2 = (TeamIndex)((!Object.op_Implicit((Object)(object)ownerBody.teamComponent)) ? 1 : ((int)ownerBody.teamComponent.teamIndex)); if (Object.op_Implicit((Object)(object)healthComponent) && healthComponent.alive && Object.op_Implicit((Object)(object)val) && Object.op_Implicit((Object)(object)val.teamComponent) && !val.isPlayerControlled) { TeamMask enemyTeams = TeamMask.GetEnemyTeams(val2); if (((TeamMask)(ref enemyTeams)).HasTeam(val.teamComponent.teamIndex)) { float num = ConsumeAllResonance(ownerBody); DamageInfo val3 = new DamageInfo { attacker = ((Component)ownerBody).gameObject, inflictor = ((Component)ownerBody).gameObject, damage = ownerBody.damage * (0.15f * num), crit = Util.CheckRoll(ownerBody.crit, ownerBody.master), position = ((Component)targetHurtBox).transform.position, force = Vector3.zero, procCoefficient = 1f, procChainMask = default(ProcChainMask), damageColorIndex = (DamageColorIndex)0, damageType = DamageTypeCombo.op_Implicit((DamageSource)2) }; healthComponent.TakeDamage(val3); GlobalEventManager.instance.OnHitEnemy(val3, ((Component)val).gameObject); GlobalEventManager.instance.OnHitAll(val3, ((Component)val).gameObject); int duration = Mathf.RoundToInt(Mathf.Lerp(1f, 60f, num / 100f)); CreateOwnedGhost(val, ownerBody, duration, 2.4f, isEchoSoulbindGhost: true); } } } internal static void ExecuteEmpathicLock(CharacterBody ownerBody, HurtBox? targetHurtBox) { //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_0073: 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_0082: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)ownerBody) || !Object.op_Implicit((Object)(object)targetHurtBox)) { return; } HealthComponent healthComponent = targetHurtBox.healthComponent; CharacterBody val = (Object.op_Implicit((Object)(object)healthComponent) ? healthComponent.body : null); TeamIndex val2 = (TeamIndex)((!Object.op_Implicit((Object)(object)ownerBody.teamComponent)) ? 1 : ((int)ownerBody.teamComponent.teamIndex)); if (Object.op_Implicit((Object)(object)healthComponent) && healthComponent.alive && Object.op_Implicit((Object)(object)val) && Object.op_Implicit((Object)(object)val.teamComponent) && !val.isPlayerControlled) { TeamMask enemyTeams = TeamMask.GetEnemyTeams(val2); if (((TeamMask)(ref enemyTeams)).HasTeam(val.teamComponent.teamIndex)) { ((Component)ownerBody).GetComponent()?.SetMarkedTarget(val); } } } internal static void TryCreateMarkedTargetGhost(CharacterBody ownerBody, CharacterBody targetBody) { if (NetworkServer.active && Object.op_Implicit((Object)(object)ownerBody) && Object.op_Implicit((Object)(object)targetBody)) { CreateOwnedGhost(targetBody, ownerBody, 60, 2.4f, isEchoSoulbindGhost: true); } } internal static void DeploySoulDomain(CharacterBody? ownerBody) { //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) if (NetworkServer.active && Object.op_Implicit((Object)(object)ownerBody) && Object.op_Implicit((Object)(object)ownerBody.master) && Object.op_Implicit((Object)(object)SoulDomainPrefab)) { GameObject obj = Object.Instantiate(SoulDomainPrefab, ownerBody.footPosition, Quaternion.identity); TeamFilter component = obj.GetComponent(); if (Object.op_Implicit((Object)(object)component) && Object.op_Implicit((Object)(object)ownerBody.teamComponent)) { component.teamIndex = ownerBody.teamComponent.teamIndex; } (obj.GetComponent() ?? throw new InvalidOperationException("Soul Domain prefab has no controller.")).Initialize(ownerBody.master); NetworkServer.Spawn(obj); } } internal static void TryCreateSoulDomainGhost(CharacterBody ownerBody, CharacterBody targetBody) { if (NetworkServer.active && Object.op_Implicit((Object)(object)ownerBody) && Object.op_Implicit((Object)(object)targetBody) && TrySpendResonance(ownerBody, 10f) && !Object.op_Implicit((Object)(object)CreateOwnedGhost(targetBody, ownerBody, 30, 2.4f, isEchoSoulbindGhost: false))) { AddResonance(ownerBody, 10f); } } internal static void TryCreateSoulBeamGhost(CharacterBody ownerBody, CharacterBody targetBody) { if (NetworkServer.active && Object.op_Implicit((Object)(object)ownerBody) && Object.op_Implicit((Object)(object)targetBody) && TrySpendResonance(ownerBody, 10f) && !Object.op_Implicit((Object)(object)CreateOwnedGhost(targetBody, ownerBody, 60, 2.4f, isEchoSoulbindGhost: false))) { AddResonance(ownerBody, 10f); } } internal static bool IsEnemyMonster(CharacterBody? ownerBody, CharacterBody? targetBody) { //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)ownerBody) || !Object.op_Implicit((Object)(object)targetBody) || !Object.op_Implicit((Object)(object)targetBody.healthComponent) || !targetBody.healthComponent.alive || targetBody.isPlayerControlled || !Object.op_Implicit((Object)(object)ownerBody.teamComponent) || !Object.op_Implicit((Object)(object)targetBody.teamComponent)) { return false; } TeamMask enemyTeams = TeamMask.GetEnemyTeams(ownerBody.teamComponent.teamIndex); return ((TeamMask)(ref enemyTeams)).HasTeam(targetBody.teamComponent.teamIndex); } internal static bool IsOwnedGhost(CharacterBody? ownerBody, CharacterBody? targetBody) { CharacterMaster val = (Object.op_Implicit((Object)(object)targetBody) ? targetBody.master : null); if (Object.op_Implicit((Object)(object)ownerBody) && Object.op_Implicit((Object)(object)ownerBody.master) && Object.op_Implicit((Object)(object)val)) { return (Object)(object)GetResonatorGhostOwner(val) == (Object)(object)ownerBody.master; } return false; } internal static void StopGhostNaturalDecay(CharacterBody ownerBody, CharacterBody ghostBody) { if (NetworkServer.active && IsOwnedGhost(ownerBody, ghostBody) && Object.op_Implicit((Object)(object)ghostBody.master) && Object.op_Implicit((Object)(object)ghostBody.master.inventory)) { ResonatorEchoGhostController resonatorEchoGhostController = ((Component)ghostBody.master).GetComponent(); if (!Object.op_Implicit((Object)(object)resonatorEchoGhostController)) { resonatorEchoGhostController = ((Component)ghostBody.master).gameObject.AddComponent(); resonatorEchoGhostController.Initialize(ownerBody.master); } resonatorEchoGhostController.StopNaturalDecayPermanently(); } } private static CharacterBody? CreateOwnedGhost(CharacterBody targetBody, CharacterBody ownerBody, int duration, float baseDamageMultiplier, bool isEchoSoulbindGhost) { //IL_00e4: 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_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Unknown result type (might be due to invalid IL or missing references) //IL_0105: Unknown result type (might be due to invalid IL or missing references) //IL_010a: Unknown result type (might be due to invalid IL or missing references) //IL_010f: 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_0112: Unknown result type (might be due to invalid IL or missing references) //IL_0117: Unknown result type (might be due to invalid IL or missing references) //IL_0123: Unknown result type (might be due to invalid IL or missing references) //IL_012f: Unknown result type (might be due to invalid IL or missing references) //IL_013b: Unknown result type (might be due to invalid IL or missing references) //IL_013c: Unknown result type (might be due to invalid IL or missing references) //IL_0198: Unknown result type (might be due to invalid IL or missing references) //IL_019d: Unknown result type (might be due to invalid IL or missing references) if (!NetworkServer.active || !Object.op_Implicit((Object)(object)targetBody) || !Object.op_Implicit((Object)(object)ownerBody) || !Object.op_Implicit((Object)(object)ownerBody.inventory) || !Object.op_Implicit((Object)(object)ownerBody.master)) { return null; } Inventory ownerInventory = ownerBody.inventory; CharacterMaster ownerMaster = ownerBody.master; GameObject targetBodyPrefab = BodyCatalog.FindBodyPrefab(targetBody); CharacterMaster val = (Object.op_Implicit((Object)(object)targetBodyPrefab) ? MasterCatalog.allAiMasters.FirstOrDefault((Func)((CharacterMaster candidate) => Object.op_Implicit((Object)(object)candidate) && (Object)(object)candidate.bodyPrefab == (Object)(object)targetBodyPrefab)) : null); if (!Object.op_Implicit((Object)(object)targetBodyPrefab) || !Object.op_Implicit((Object)(object)val)) { return null; } List eliteBuffs = GetEliteBuffs(targetBody); CharacterDirection component = ((Component)targetBody).GetComponent(); Quaternion rotation = (Object.op_Implicit((Object)(object)component) ? Quaternion.Euler(0f, component.yaw, 0f) : targetBody.transform.rotation); MasterSummon val2 = new MasterSummon { masterPrefab = ((Component)val).gameObject, ignoreTeamMemberLimit = false, position = targetBody.footPosition, rotation = rotation, summonerBodyObject = ((Component)ownerBody).gameObject, inventoryToCopy = ownerInventory, useAmbientLevel = null }; val2.preSpawnSetupCallback = (Action)Delegate.Combine(val2.preSpawnSetupCallback, (Action)delegate(CharacterMaster ghostMaster) { //IL_002b: 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_004b: Unknown result type (might be due to invalid IL or missing references) Inventory inventory = ghostMaster.inventory; inventory.CleanInventory(); inventory.CopyItemsFrom(ownerInventory); inventory.CopyEquipmentFrom(ownerInventory, true); inventory.ResetItemPermanent(Items.Ghost.itemIndex); inventory.ResetItemPermanent(Items.HealthDecay.itemIndex); inventory.ResetItemPermanent(Items.BoostDamage.itemIndex); inventory.GiveItemPermanent(Items.Ghost, 1); inventory.GiveItemPermanent(Items.HealthDecay, duration); ((Component)ghostMaster).gameObject.AddComponent().Initialize(ownerMaster, baseDamageMultiplier, isEchoSoulbindGhost); }); CharacterMaster val3 = val2.Perform(); CharacterBody val4 = (Object.op_Implicit((Object)(object)val3) ? val3.GetBody() : null); if (!Object.op_Implicit((Object)(object)val4)) { return null; } EntityStateMachine[] components = ((Component)val4).GetComponents(); foreach (EntityStateMachine obj in components) { obj.initialStateType = obj.mainStateType; } for (int num2 = 0; num2 < eliteBuffs.Count; num2++) { BuffDef val5 = eliteBuffs[num2]; if (!val4.HasBuff(val5)) { val4.AddBuff(val5); } } val4.MarkAllStatsDirty(); return val4; } private static List GetEliteBuffs(CharacterBody targetBody) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) List list = new List(); for (int i = 0; i < EliteCatalog.eliteList.Count; i++) { EliteDef eliteDef = EliteCatalog.GetEliteDef(EliteCatalog.eliteList[i]); BuffDef val = ((Object.op_Implicit((Object)(object)eliteDef) && Object.op_Implicit((Object)(object)eliteDef.eliteEquipmentDef)) ? eliteDef.eliteEquipmentDef.passiveBuffDef : null); if (Object.op_Implicit((Object)(object)val) && targetBody.HasBuff(val) && !list.Contains(val)) { list.Add(val); } } return list; } private static void ApplyEchoGhostStats(CharacterBody body, StatHookEventArgs args) { ResonatorEchoGhostController resonatorEchoGhostController = (Object.op_Implicit((Object)(object)body.master) ? ((Component)body.master).GetComponent() : null); if (Object.op_Implicit((Object)(object)resonatorEchoGhostController)) { args.damageMultAdd += resonatorEchoGhostController.BaseDamageMultiplier - 1f; } } private static bool IsResonator(CharacterBody? body) { if (Object.op_Implicit((Object)(object)body) && Object.op_Implicit((Object)(object)ResonatorPrototypeModule.BodyPrefab)) { return ((Object)((Component)body).gameObject).name.StartsWith(((Object)ResonatorPrototypeModule.BodyPrefab).name, StringComparison.Ordinal); } return false; } private static void ApplyGhostVisuals(GameObject ghost) { //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Expected O, but got Unknown RemoveProjectileTrails(ghost); Renderer[] componentsInChildren = ghost.GetComponentsInChildren(true); Material val = null; for (int i = 0; i < componentsInChildren.Length; i++) { if (!componentsInChildren[i].enabled) { continue; } Material[] sharedMaterials = componentsInChildren[i].sharedMaterials; for (int j = 0; j < sharedMaterials.Length; j++) { Material val2 = sharedMaterials[j]; if (Object.op_Implicit((Object)(object)val2)) { int instanceID = ((Object)val2).GetInstanceID(); if (!GhostMaterialCache.TryGetValue(instanceID, out Material value)) { value = new Material(ResonatorPrototypeModule.GetBlueMaterial(val2)) { name = ((Object)val2).name + "_ResonatorSpectral" }; TuneGhostMaterial(value); GhostMaterialCache[instanceID] = value; } sharedMaterials[j] = value; if (val == null) { val = value; } } } componentsInChildren[i].sharedMaterials = sharedMaterials; } if (Object.op_Implicit((Object)(object)val)) { AddWireRings(ghost.transform, val); } } private static void RemoveProjectileTrails(GameObject ghost) { //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_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) TrailRenderer[] componentsInChildren = ghost.GetComponentsInChildren(true); for (int i = 0; i < componentsInChildren.Length; i++) { componentsInChildren[i].emitting = false; componentsInChildren[i].Clear(); ((Renderer)componentsInChildren[i]).enabled = false; } ParticleSystem[] componentsInChildren2 = ghost.GetComponentsInChildren(true); foreach (ParticleSystem val in componentsInChildren2) { TrailModule trails = val.trails; if (((TrailModule)(ref trails)).enabled) { ((TrailModule)(ref trails)).enabled = false; } string name = ((Object)((Component)val).gameObject).name; if (name.IndexOf("trail", StringComparison.OrdinalIgnoreCase) >= 0 || name.IndexOf("streak", StringComparison.OrdinalIgnoreCase) >= 0 || name.IndexOf("ribbon", StringComparison.OrdinalIgnoreCase) >= 0) { val.Stop(true, (ParticleSystemStopBehavior)0); EmissionModule emission = val.emission; ((EmissionModule)(ref emission)).enabled = false; ParticleSystemRenderer component = ((Component)val).GetComponent(); if (Object.op_Implicit((Object)(object)component)) { ((Renderer)component).enabled = false; } } } } private static void ApplyBlueMaterials(GameObject prefab) { Renderer[] componentsInChildren = prefab.GetComponentsInChildren(true); for (int i = 0; i < componentsInChildren.Length; i++) { Material[] sharedMaterials = componentsInChildren[i].sharedMaterials; for (int j = 0; j < sharedMaterials.Length; j++) { if (Object.op_Implicit((Object)(object)sharedMaterials[j])) { sharedMaterials[j] = ResonatorPrototypeModule.GetBlueMaterial(sharedMaterials[j]); } } componentsInChildren[i].sharedMaterials = sharedMaterials; } } private static GameObject? CloneBlueEffect(GameObject? source, string cloneName) { if (!Object.op_Implicit((Object)(object)source)) { return null; } GameObject obj = PrefabAPI.InstantiateClone(source, cloneName, false); ApplyBlueMaterials(obj); ApplyPaleBlueEffects(obj); ContentAddition.AddEffect(obj); return obj; } private static void DisableWardVisuals(GameObject wardPrefab, Transform? originalRangeIndicator) { Renderer[] componentsInChildren = wardPrefab.GetComponentsInChildren(true); for (int i = 0; i < componentsInChildren.Length; i++) { if (!IsPartOfRangeIndicator(((Component)componentsInChildren[i]).transform, originalRangeIndicator)) { componentsInChildren[i].enabled = false; } } ParticleSystem[] componentsInChildren2 = wardPrefab.GetComponentsInChildren(true); for (int j = 0; j < componentsInChildren2.Length; j++) { if (!IsPartOfRangeIndicator(((Component)componentsInChildren2[j]).transform, originalRangeIndicator)) { componentsInChildren2[j].Stop(true, (ParticleSystemStopBehavior)0); } } Light[] componentsInChildren3 = wardPrefab.GetComponentsInChildren(true); for (int k = 0; k < componentsInChildren3.Length; k++) { if (!IsPartOfRangeIndicator(((Component)componentsInChildren3[k]).transform, originalRangeIndicator)) { ((Behaviour)componentsInChildren3[k]).enabled = false; } } } private static bool IsPartOfRangeIndicator(Transform candidate, Transform? rangeIndicator) { if (Object.op_Implicit((Object)(object)rangeIndicator)) { if (!((Object)(object)candidate == (Object)(object)rangeIndicator)) { return candidate.IsChildOf(rangeIndicator); } return true; } return false; } private static void ApplySoulRoamGhostVisuals(GameObject prefab) { //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_004c: Expected O, but got Unknown Renderer[] componentsInChildren = prefab.GetComponentsInChildren(true); for (int i = 0; i < componentsInChildren.Length; i++) { Material[] sharedMaterials = componentsInChildren[i].sharedMaterials; for (int j = 0; j < sharedMaterials.Length; j++) { Material val = sharedMaterials[j]; if (Object.op_Implicit((Object)(object)val)) { Material val2 = new Material(ResonatorPrototypeModule.GetBlueMaterial(val)) { name = ((Object)val).name + "_SoulRoamGhost" }; TuneGhostMaterial(val2); sharedMaterials[j] = val2; } } componentsInChildren[i].sharedMaterials = sharedMaterials; } ApplyPaleBlueEffects(prefab); } private static void ApplyPaleBlueEffects(GameObject prefab) { //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) Color val = default(Color); ((Color)(ref val))..ctor(0.45f, 0.9f, 1f, 0.72f); ParticleSystem[] componentsInChildren = prefab.GetComponentsInChildren(true); for (int i = 0; i < componentsInChildren.Length; i++) { MainModule main = componentsInChildren[i].main; ((MainModule)(ref main)).startColor = MinMaxGradient.op_Implicit(val); } Light[] componentsInChildren2 = prefab.GetComponentsInChildren(true); for (int j = 0; j < componentsInChildren2.Length; j++) { componentsInChildren2[j].color = new Color(0.38f, 0.86f, 1f, 1f); } } internal static void TuneGhostMaterial(Material material) { //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0062: 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_0075: Unknown result type (might be due to invalid IL or missing references) Color val = default(Color); ((Color)(ref val))..ctor(0.25f, 0.82f, 1f, 0.38f); string[] array = new string[3] { "_Color", "_TintColor", "_EmColor" }; foreach (string text in array) { if (material.HasProperty(text)) { Color color = material.GetColor(text); material.SetColor(text, new Color(val.r, val.g, val.b, color.a * 0.48f)); } } SetFloatIfPresent(material, "_AlphaBoost", 0.5f); SetFloatIfPresent(material, "_FresnelPower", 1.8f); SetFloatIfPresent(material, "_FresnelBoost", 2.2f); SetFloatIfPresent(material, "_Boost", 1.35f); } private static void AddWireRings(Transform parent, Material sourceMaterial) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Expected O, but got Unknown //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_003b: 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_0056: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_00fd: Unknown result type (might be due to invalid IL or missing references) //IL_0141: Unknown result type (might be due to invalid IL or missing references) Material val = new Material(sourceMaterial) { name = "matResonantImpactWire" }; TuneGhostMaterial(val); Vector3[] array = (Vector3[])(object)new Vector3[3] { Vector3.zero, new Vector3(90f, 0f, 0f), new Vector3(0f, 90f, 0f) }; for (int i = 0; i < array.Length; i++) { GameObject val2 = new GameObject($"ResonantWireRing{i + 1}"); val2.transform.SetParent(parent, false); val2.transform.localRotation = Quaternion.Euler(array[i]); LineRenderer val3 = val2.AddComponent(); val3.useWorldSpace = false; val3.loop = true; val3.positionCount = 40; val3.startWidth = 0.018f; val3.endWidth = 0.018f; ((Renderer)val3).sharedMaterial = val; val3.startColor = new Color(0.52f, 0.92f, 1f, 0.56f); val3.endColor = val3.startColor; for (int j = 0; j < val3.positionCount; j++) { float num = MathF.PI * 2f * (float)j / (float)val3.positionCount; val3.SetPosition(j, new Vector3(Mathf.Cos(num) * 0.38f, Mathf.Sin(num) * 0.38f, 0f)); } } } private static void SetFloatIfPresent(Material material, string property, float value) { if (material.HasProperty(property)) { material.SetFloat(property, value); } } private static float GetAcceleratingTravelDistance(float initialSpeed, float acceleration, float time) { return initialSpeed * time + 0.5f * acceleration * time * time; } private static float GetTravelTimeForDistance(float initialSpeed, float acceleration, float distance) { if (acceleration <= 0f) { return distance / Mathf.Max(initialSpeed, 0.01f); } return (0f - initialSpeed + Mathf.Sqrt(initialSpeed * initialSpeed + 2f * acceleration * distance)) / acceleration; } private static Transform? FindDescendant(Transform root, string name) { if (string.Equals(((Object)root).name, name, StringComparison.OrdinalIgnoreCase)) { return root; } for (int i = 0; i < root.childCount; i++) { Transform val = FindDescendant(root.GetChild(i), name); if (Object.op_Implicit((Object)(object)val)) { return val; } } return null; } private static T LoadAsset(object address) where T : Object { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) T val = Addressables.LoadAssetAsync(address).WaitForCompletion(); if (!Object.op_Implicit((Object)(object)val)) { throw new InvalidOperationException($"Addressable asset could not be loaded: {address}"); } return val; } } public sealed class ResonatorSoulBeamState : BaseSkillState { private const float BaseDuration = 0.8f; private const float FireFraction = 0.2f; private const float DamageCoefficient = 20f; private const float MaxDistance = 1000f; private const float BulletRadius = 0.35f; private const string MuzzleName = "MuzzleEnergyBomb"; private float duration; private bool hasFired; private bool beamWasBlocked; private CharacterBody? blockingGhost; public override void OnEnter() { //IL_001a: Unknown result type (might be due to invalid IL or missing references) ((BaseState)this).OnEnter(); duration = 0.8f / ((BaseState)this).attackSpeedStat; ((BaseState)this).StartAimMode(((BaseState)this).GetAimRay(), 2f, false); ((EntityState)this).PlayCrossfade("Gesture, Override", "SpiritPunchFinisher", "FireGauntlet.playbackRate", duration, 0.05f); } public override void FixedUpdate() { ((EntityState)this).FixedUpdate(); if (!hasFired && ((EntityState)this).fixedAge >= duration * 0.2f) { FireBeam(); hasFired = true; } if (((EntityState)this).fixedAge >= duration && ((EntityState)this).isAuthority) { ((EntityState)this).outer.SetNextStateToMain(); } } private void FireBeam() { //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: 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_0104: 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_0121: Unknown result type (might be due to invalid IL or missing references) //IL_012c: Unknown result type (might be due to invalid IL or missing references) //IL_0148: Unknown result type (might be due to invalid IL or missing references) //IL_014a: Unknown result type (might be due to invalid IL or missing references) //IL_014f: Unknown result type (might be due to invalid IL or missing references) //IL_0154: 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_016a: Unknown result type (might be due to invalid IL or missing references) //IL_0172: Unknown result type (might be due to invalid IL or missing references) //IL_017c: Expected O, but got Unknown //IL_017c: Unknown result type (might be due to invalid IL or missing references) //IL_0184: Unknown result type (might be due to invalid IL or missing references) //IL_018e: Expected O, but got Unknown //IL_01cd: Unknown result type (might be due to invalid IL or missing references) //IL_01d4: Unknown result type (might be due to invalid IL or missing references) //IL_01d9: Unknown result type (might be due to invalid IL or missing references) Util.PlaySound("Play_voidman_m1_shoot", ((EntityState)this).gameObject); if (Object.op_Implicit((Object)(object)ResonatorSkillModule.SoulBeamMuzzleflashPrefab)) { EffectManager.SimpleMuzzleFlash(ResonatorSkillModule.SoulBeamMuzzleflashPrefab, ((EntityState)this).gameObject, "MuzzleEnergyBomb", false); } if (!NetworkServer.active || !Object.op_Implicit((Object)(object)((EntityState)this).characterBody) || !Object.op_Implicit((Object)(object)((EntityState)this).characterBody.master)) { return; } Ray aimRay = ((BaseState)this).GetAimRay(); float num = FindNearestOwnedGhost(aimRay, out blockingGhost); float num2 = (Object.op_Implicit((Object)(object)blockingGhost) ? num : 1000f); beamWasBlocked = false; new BulletAttack { owner = ((EntityState)this).gameObject, weapon = ((EntityState)this).gameObject, origin = ((Ray)(ref aimRay)).origin, aimVector = ((Ray)(ref aimRay)).direction, muzzleName = "MuzzleEnergyBomb", maxDistance = num2, minSpread = 0f, maxSpread = 0f, radius = 0.35f, falloffModel = (FalloffModel)0, smartCollision = true, damage = 20f * ((BaseState)this).damageStat, procCoefficient = 1f, force = 0f, isCrit = Util.CheckRoll(((BaseState)this).critStat, ((EntityState)this).characterBody.master), damageType = DamageTypeCombo.op_Implicit((DamageSource)8), tracerEffectPrefab = ResonatorSkillModule.SoulBeamTracerPrefab, hitEffectPrefab = ResonatorSkillModule.SoulBeamImpactPrefab, filterCallback = new FilterCallback(FilterBeamHit), hitCallback = new HitCallback(HandleBeamHit) }.Fire(); if (!beamWasBlocked && Object.op_Implicit((Object)(object)blockingGhost)) { ResonatorSkillModule.StopGhostNaturalDecay(((EntityState)this).characterBody, blockingGhost); if (Object.op_Implicit((Object)(object)ResonatorSkillModule.SoulBeamImpactPrefab)) { EffectManager.SimpleImpactEffect(ResonatorSkillModule.SoulBeamImpactPrefab, ((Ray)(ref aimRay)).GetPoint(num2), -((Ray)(ref aimRay)).direction, true); } } } private bool FilterBeamHit(BulletAttack bulletAttack, ref BulletHit hitInfo) { CharacterBody val = hitInfo.hitHurtBox?.healthComponent?.body; if (!Object.op_Implicit((Object)(object)val)) { return true; } if (ResonatorSkillModule.IsOwnedGhost(((EntityState)this).characterBody, val)) { return true; } return ResonatorSkillModule.IsEnemyMonster(((EntityState)this).characterBody, val); } private bool HandleBeamHit(BulletAttack bulletAttack, ref BulletHit hitInfo) { beamWasBlocked = true; CharacterBody val = hitInfo.hitHurtBox?.healthComponent?.body; bool num = Object.op_Implicit((Object)(object)val) && ResonatorSkillModule.IsEnemyMonster(((EntityState)this).characterBody, val); bool flag = Object.op_Implicit((Object)(object)val) && ResonatorSkillModule.IsOwnedGhost(((EntityState)this).characterBody, val); if (num) { ResonatorSkillModule.TryCreateSoulBeamGhost(((EntityState)this).characterBody, val); } else if (flag) { ResonatorSkillModule.StopGhostNaturalDecay(((EntityState)this).characterBody, val); } return BulletAttack.defaultHitCallback.Invoke(bulletAttack, ref hitInfo); } private float FindNearestOwnedGhost(Ray aimRay, out CharacterBody? nearestGhost) { //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0086: 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) nearestGhost = null; float num = 1000f; IReadOnlyList readOnlyInstancesList = CharacterBody.readOnlyInstancesList; for (int i = 0; i < readOnlyInstancesList.Count; i++) { CharacterBody val = readOnlyInstancesList[i]; if (!Object.op_Implicit((Object)(object)val) || !Object.op_Implicit((Object)(object)val.healthComponent) || !val.healthComponent.alive || !ResonatorSkillModule.IsOwnedGhost(((EntityState)this).characterBody, val)) { continue; } float num2 = Mathf.Max(val.radius, 0.5f) + 0.35f; Vector3 val2 = val.corePosition - ((Ray)(ref aimRay)).origin; float num3 = Vector3.Dot(val2, ((Ray)(ref aimRay)).direction); if (num3 <= 0f || num3 - num2 >= num) { continue; } float num4 = ((Vector3)(ref val2)).sqrMagnitude - num3 * num3; float num5 = num2 * num2; if (!(num4 > num5)) { float num6 = Mathf.Max(0.1f, num3 - Mathf.Sqrt(Mathf.Max(0f, num5 - num4))); if (num6 < num) { num = num6; nearestGhost = val; } } } return num; } public override InterruptPriority GetMinimumInterruptPriority() { return (InterruptPriority)1; } } internal sealed class ResonatorSoulDomainController : MonoBehaviour { internal const float Radius = 20f; internal const float Duration = 12f; private CharacterMaster? ownerMaster; internal void Initialize(CharacterMaster? newOwnerMaster) { ownerMaster = newOwnerMaster; } private void OnEnable() { if (NetworkServer.active) { GlobalEventManager.onCharacterDeathGlobal += OnCharacterDeath; } } private void OnDisable() { GlobalEventManager.onCharacterDeathGlobal -= OnCharacterDeath; } private void OnCharacterDeath(DamageReport damageReport) { //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) CharacterBody val = (Object.op_Implicit((Object)(object)ownerMaster) ? ownerMaster.GetBody() : null); CharacterBody victimBody = damageReport.victimBody; if (!NetworkServer.active || !Object.op_Implicit((Object)(object)val) || !Object.op_Implicit((Object)(object)victimBody) || victimBody.isPlayerControlled || !Object.op_Implicit((Object)(object)victimBody.teamComponent) || !Object.op_Implicit((Object)(object)val.teamComponent)) { return; } TeamMask enemyTeams = TeamMask.GetEnemyTeams(val.teamComponent.teamIndex); if (((TeamMask)(ref enemyTeams)).HasTeam(victimBody.teamComponent.teamIndex)) { Vector3 val2 = victimBody.corePosition - ((Component)this).transform.position; if (!(((Vector3)(ref val2)).sqrMagnitude > 400f)) { ResonatorSkillModule.TryCreateSoulDomainGhost(val, victimBody); } } } } public sealed class ResonatorSoulDomainState : BaseSkillState { private const float ExitDuration = 0.2f; public override void OnEnter() { ((BaseState)this).OnEnter(); ResonatorSkillModule.DeploySoulDomain(((EntityState)this).characterBody); } public override void FixedUpdate() { ((EntityState)this).FixedUpdate(); if (((EntityState)this).fixedAge >= 0.2f && ((EntityState)this).isAuthority) { ((EntityState)this).outer.SetNextStateToMain(); } } public override InterruptPriority GetMinimumInterruptPriority() { return (InterruptPriority)1; } } internal sealed class ResonatorSoulRoamVehicleController : MonoBehaviour { private const float GhostDecayPauseDuration = 8f; private const float ContactPadding = 1.5f; private const float ResonanceCostPerSecond = 2f; private VehicleSeat? vehicleSeat; private Vector3 previousPosition; private float pendingResonanceCost; internal bool IsDetonating { get; set; } private void Awake() { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) vehicleSeat = ((Component)this).GetComponent(); previousPosition = ((Component)this).transform.position; } private void FixedUpdate() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0076: 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_0149: Unknown result type (might be due to invalid IL or missing references) //IL_014a: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: Unknown result type (might be due to invalid IL or missing references) Vector3 position = ((Component)this).transform.position; if (!NetworkServer.active || !Object.op_Implicit((Object)(object)vehicleSeat) || !Object.op_Implicit((Object)(object)vehicleSeat.currentPassengerBody)) { previousPosition = position; return; } CharacterBody currentPassengerBody = vehicleSeat.currentPassengerBody; CharacterMaster val = (Object.op_Implicit((Object)(object)currentPassengerBody) ? currentPassengerBody.master : null); if (!Object.op_Implicit((Object)(object)val)) { previousPosition = position; return; } if (!ConsumeFlightResonance(Time.fixedDeltaTime)) { previousPosition = position; ForceEjectPassenger(); return; } IReadOnlyList readOnlyInstancesList = CharacterBody.readOnlyInstancesList; for (int i = 0; i < readOnlyInstancesList.Count; i++) { CharacterBody val2 = readOnlyInstancesList[i]; CharacterMaster val3 = (Object.op_Implicit((Object)(object)val2) ? val2.master : null); if (!Object.op_Implicit((Object)(object)val3) || (Object)(object)ResonatorSkillModule.GetResonatorGhostOwner(val3) != (Object)(object)val) { continue; } float num = Mathf.Max(val2.radius, 0.5f) + 1.5f; if (!(ResonanceProjectileGhostHealing.DistanceToSegmentSquared(val2.corePosition, previousPosition, position) > num * num)) { ResonatorEchoGhostController resonatorEchoGhostController = ((Component)val3).GetComponent(); if (!Object.op_Implicit((Object)(object)resonatorEchoGhostController)) { resonatorEchoGhostController = ((Component)val3).gameObject.AddComponent(); resonatorEchoGhostController.Initialize(val); } resonatorEchoGhostController.PauseNaturalDecay(8f); } } previousPosition = position; } internal bool ConsumeFlightResonance(float interval) { if (!NetworkServer.active || !Object.op_Implicit((Object)(object)vehicleSeat) || !Object.op_Implicit((Object)(object)vehicleSeat.currentPassengerBody)) { return true; } CharacterBody currentPassengerBody = vehicleSeat.currentPassengerBody; if (ResonatorSkillModule.GetResonanceUnits(currentPassengerBody) <= 0) { return false; } pendingResonanceCost += 2f * Mathf.Max(interval, 0f); int num = Mathf.FloorToInt(pendingResonanceCost * 10f + 0.0001f); if (num <= 0) { return true; } float num2 = (float)num / 10f; pendingResonanceCost -= num2; if (!ResonatorSkillModule.TrySpendResonance(currentPassengerBody, num2)) { return false; } return ResonatorSkillModule.GetResonanceUnits(currentPassengerBody) > 0; } internal void ForceEjectPassenger() { if (NetworkServer.active && Object.op_Implicit((Object)(object)vehicleSeat) && Object.op_Implicit((Object)(object)vehicleSeat.currentPassengerBody)) { vehicleSeat.CallCmdEjectPassenger(); } } } internal sealed class ResonatorTargetTracker : MonoBehaviour { private const float UpdateInterval = 0.05f; private const float MaxTargetDistance = 1000f; private const float MaxTargetAngle = 30f; private const float LostTargetGraceDuration = 0.35f; [SerializeField] private GameObject? indicatorPrefab; private CharacterBody? body; private InputBankTest? inputBank; private Indicator? indicator; private DroneTechIndicatorController? indicatorController; private float updateStopwatch; private float lostTargetStopwatch; internal HurtBox? CurrentTarget { get; private set; } internal void Configure(GameObject targetIndicatorPrefab) { indicatorPrefab = targetIndicatorPrefab; } private void Awake() { //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Expected O, but got Unknown body = ((Component)this).GetComponent(); inputBank = ((Component)this).GetComponent(); if (Object.op_Implicit((Object)(object)indicatorPrefab)) { indicator = new Indicator(((Component)this).gameObject, indicatorPrefab); } } private void OnEnable() { if (indicator != null) { indicator.active = true; } } private void OnDisable() { SetTarget(null); if (indicator != null) { indicator.active = false; } } private void FixedUpdate() { //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)body) || !Object.op_Implicit((Object)(object)inputBank) || !Util.HasEffectiveAuthority(((Component)this).gameObject)) { return; } updateStopwatch -= Time.fixedDeltaTime; if (updateStopwatch > 0f) { UpdateIndicatorReticle(); return; } updateStopwatch += 0.05f; HurtBox val = FindBestTarget(body, new Ray(inputBank.aimOrigin, inputBank.aimDirection)); if (Object.op_Implicit((Object)(object)val)) { lostTargetStopwatch = 0f; SetTarget(val); } else if (Object.op_Implicit((Object)(object)CurrentTarget) && IsTargetValid(CurrentTarget)) { lostTargetStopwatch += 0.05f; if (lostTargetStopwatch >= 0.35f) { SetTarget(null); } } else { SetTarget(null); } UpdateIndicatorReticle(); } private void SetTarget(HurtBox? target) { CurrentTarget = target; if (indicator != null) { indicator.targetTransform = (Object.op_Implicit((Object)(object)target) ? ((Component)target).transform : null); } } private void UpdateIndicatorReticle() { if (indicator != null && indicator.hasVisualizer) { if (indicatorController == null) { indicatorController = indicator.visualizerInstance.GetComponent(); } if (Object.op_Implicit((Object)(object)indicatorController)) { indicatorController.ShowNeutralReticle(false); indicatorController.ShowHealReticle(false); indicatorController.ShowAttackReticle(Object.op_Implicit((Object)(object)CurrentTarget)); } } } private static HurtBox? FindBestTarget(CharacterBody viewer, Ray aimRay) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_006b: 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_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_0084: Unknown result type (might be due to invalid IL or missing references) TeamIndex val = (TeamIndex)((!Object.op_Implicit((Object)(object)viewer.teamComponent)) ? 1 : ((int)viewer.teamComponent.teamIndex)); BullseyeSearch val2 = new BullseyeSearch { viewer = viewer, searchOrigin = ((Ray)(ref aimRay)).origin, searchDirection = ((Ray)(ref aimRay)).direction, minDistanceFilter = 0f, maxDistanceFilter = 1000f, teamMaskFilter = TeamMask.GetEnemyTeams(val), filterByLoS = true, filterByDistinctEntity = true, sortMode = (SortMode)2, maxAngleFilter = 30f }; val2.RefreshCandidates(); return val2.GetResults().FirstOrDefault((Func)IsTargetValid); } private static bool IsTargetValid(HurtBox? hurtBox) { CharacterBody val = hurtBox?.healthComponent?.body; if (Object.op_Implicit((Object)(object)hurtBox) && Object.op_Implicit((Object)(object)hurtBox.healthComponent) && hurtBox.healthComponent.alive && Object.op_Implicit((Object)(object)val)) { return !val.isPlayerControlled; } return false; } } } namespace HurricaneDifficulty.Pantheon { internal enum PantheonLoadoutCategory : byte { White, Green, Lunar, Equipment, Boss, Red, VoidWhite, VoidGreen, VoidRed, DroneWhite, DroneGreen, DroneRed, Count } internal enum PantheonLoadoutDefinitionKind : byte { Item, Equipment, Drone } internal readonly struct PantheonLoadoutChoice : IEquatable { internal int DefinitionIndex { get; } internal PantheonLoadoutDefinitionKind Kind { get; } internal bool IsEquipment => Kind == PantheonLoadoutDefinitionKind.Equipment; internal bool IsDrone => Kind == PantheonLoadoutDefinitionKind.Drone; internal PantheonLoadoutChoice(int definitionIndex, PantheonLoadoutDefinitionKind kind) { DefinitionIndex = definitionIndex; Kind = kind; } public bool Equals(PantheonLoadoutChoice other) { if (DefinitionIndex == other.DefinitionIndex) { return Kind == other.Kind; } return false; } public override bool Equals(object? obj) { if (obj is PantheonLoadoutChoice other) { return Equals(other); } return false; } public override int GetHashCode() { return (DefinitionIndex * 397) ^ (int)Kind; } } internal readonly struct PantheonLoadoutOption { internal PantheonLoadoutCategory Category { get; } internal int DefinitionIndex { get; } internal PantheonLoadoutDefinitionKind Kind { get; } internal bool IsEquipment => Kind == PantheonLoadoutDefinitionKind.Equipment; internal bool IsDrone => Kind == PantheonLoadoutDefinitionKind.Drone; internal PantheonLoadoutOption(PantheonLoadoutCategory category, int definitionIndex, PantheonLoadoutDefinitionKind kind) { Category = category; DefinitionIndex = definitionIndex; Kind = kind; } } internal static class PantheonLoadoutManager { private sealed class LoadoutRequestMessage : MessageBase { internal const byte Sync = 0; internal const byte Change = 1; internal const byte Clear = 2; internal const byte ReadyOperation = 3; internal byte Operation; internal int DefinitionIndex; internal PantheonLoadoutDefinitionKind Kind; internal int Delta; internal bool Ready; public override void Serialize(NetworkWriter writer) { writer.Write(Operation); writer.Write(DefinitionIndex); writer.Write((byte)Kind); writer.Write(Delta); writer.Write(Ready); } public override void Deserialize(NetworkReader reader) { Operation = reader.ReadByte(); DefinitionIndex = reader.ReadInt32(); Kind = (PantheonLoadoutDefinitionKind)reader.ReadByte(); Delta = reader.ReadInt32(); Ready = reader.ReadBoolean(); } } private struct LoadoutStateEntry { internal int DefinitionIndex; internal PantheonLoadoutDefinitionKind Kind; internal int Count; } private sealed class LoadoutStateMessage : MessageBase { internal PantheonPhase Phase; internal int Budget; internal int EncounterIndex; internal bool Ready; internal int ReadyCount; internal int PlayerCount; internal LoadoutStateEntry[] Entries = Array.Empty(); public override void Serialize(NetworkWriter writer) { writer.Write((byte)Phase); writer.Write(Budget); writer.Write(EncounterIndex); writer.Write(Ready); writer.Write(ReadyCount); writer.Write(PlayerCount); int num = Math.Min(256, Entries.Length); writer.Write((ushort)num); for (int i = 0; i < num; i++) { writer.Write(Entries[i].DefinitionIndex); writer.Write((byte)Entries[i].Kind); writer.Write(Entries[i].Count); } } public override void Deserialize(NetworkReader reader) { Phase = (PantheonPhase)reader.ReadByte(); Budget = reader.ReadInt32(); EncounterIndex = reader.ReadInt32(); Ready = reader.ReadBoolean(); ReadyCount = reader.ReadInt32(); PlayerCount = reader.ReadInt32(); int num = Math.Min(256, (int)reader.ReadUInt16()); Entries = new LoadoutStateEntry[num]; for (int i = 0; i < num; i++) { Entries[i] = new LoadoutStateEntry { DefinitionIndex = reader.ReadInt32(), Kind = (PantheonLoadoutDefinitionKind)reader.ReadByte(), Count = reader.ReadInt32() }; } } } [CompilerGenerated] private static class <>O { public static Action <0>__OnStartServer; public static Action <1>__OnStartClient; public static NetworkUserGenericDelegate <2>__OnNetworkUserLost; public static Action <3>__OnRunDestroy; public static Func <4>__GetDefinitionName; public static Func <5>__GetEquipmentDef; public static NetworkMessageDelegate <6>__ServerHandleRequest; public static NetworkMessageDelegate <7>__ClientHandleState; } private const short RequestMessageType = 19814; private const short StateMessageType = 19815; private const int MaxEntries = 256; private static readonly Dictionary> Selections = new Dictionary>(); private static readonly Dictionary ReadyStates = new Dictionary(); private static readonly Dictionary> BaselineItems = new Dictionary>(); private static readonly Dictionary> LoadoutDrones = new Dictionary>(); private static readonly Dictionary ClientSelection = new Dictionary(); private static bool installed; private static int serverBudget; internal static bool ClientResting { get; private set; } internal static bool ClientReady { get; private set; } internal static int ClientBudget { get; private set; } internal static int ClientEncounterIndex { get; private set; } internal static int ClientReadyCount { get; private set; } internal static int ClientPlayerCount { get; private set; } internal static int ParticipatingPlayerCount => ParticipatingUsers().Count(); internal static event Action? ClientStateChanged; internal static event Action? ServerReadinessChanged; internal static void Install() { //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Expected O, but got Unknown if (!installed) { installed = true; NetworkManagerSystem.onStartServerGlobal += OnStartServer; NetworkManagerSystem.onStartClientGlobal += OnStartClient; object obj = <>O.<2>__OnNetworkUserLost; if (obj == null) { NetworkUserGenericDelegate val = OnNetworkUserLost; <>O.<2>__OnNetworkUserLost = val; obj = (object)val; } NetworkUser.onNetworkUserLost += (NetworkUserGenericDelegate)obj; Run.onRunDestroyGlobal += OnRunDestroy; if (NetworkServer.active) { OnStartServer(); } NetworkClient val2 = (Object.op_Implicit((Object)(object)NetworkManagerSystem.singleton) ? ((NetworkManager)NetworkManagerSystem.singleton).client : null); if (val2 != null) { OnStartClient(val2); } } } internal static void Uninstall() { //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Expected O, but got Unknown if (installed) { installed = false; Run.onRunDestroyGlobal -= OnRunDestroy; object obj = <>O.<2>__OnNetworkUserLost; if (obj == null) { NetworkUserGenericDelegate val = OnNetworkUserLost; <>O.<2>__OnNetworkUserLost = val; obj = (object)val; } NetworkUser.onNetworkUserLost -= (NetworkUserGenericDelegate)obj; NetworkManagerSystem.onStartClientGlobal -= OnStartClient; NetworkManagerSystem.onStartServerGlobal -= OnStartServer; ResetState(); } } internal static void BeginRest(int encounterIndex, int budget) { if (!NetworkServer.active) { return; } serverBudget = budget; CaptureBaselines(); foreach (NetworkUser item in ParticipatingUsers()) { DestroyLoadoutDrones(item); ReadyStates[item] = false; TrimSelectionToBudget(GetOrCreateSelection(item)); } BroadcastStates(); PantheonLoadoutManager.ServerReadinessChanged?.Invoke(); } internal static void ApplySelectionsAndCloseRest() { if (!NetworkServer.active) { return; } foreach (NetworkUser item in ParticipatingUsers()) { ApplySelection(item); } BroadcastStates(); } internal static void BroadcastPhase() { if (NetworkServer.active) { BroadcastStates(); } } internal static bool AreAllParticipatingPlayersReady() { NetworkUser[] array = ParticipatingUsers().ToArray(); bool value; if (array.Length != 0) { return array.All((NetworkUser user) => ReadyStates.TryGetValue(user, out value) && value); } return false; } internal static IReadOnlyList GetAvailableDefinitions(PantheonLoadoutCategory category) { //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_0120: Unknown result type (might be due to invalid IL or missing references) //IL_0125: Unknown result type (might be due to invalid IL or missing references) //IL_012a: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0161: Unknown result type (might be due to invalid IL or missing references) if (IsDroneCategory(category)) { ItemTier droneTier = GetDroneTier(category); return (from def in DroneCatalog.orderedDroneDefs where IsSelectableDrone(def, droneTier) select new PantheonLoadoutOption(category, (int)def.droneIndex, PantheonLoadoutDefinitionKind.Drone)).OrderBy(GetDefinitionName, StringComparer.CurrentCultureIgnoreCase).ToArray(); } if (category == PantheonLoadoutCategory.Equipment) { return (from def in ((IEnumerable)(object)EquipmentCatalog.allEquipment).Select((Func)EquipmentCatalog.GetEquipmentDef) where IsSelectableEquipment(def, lunar: false) select new PantheonLoadoutOption(category, (int)def.equipmentIndex, PantheonLoadoutDefinitionKind.Equipment)).OrderBy(GetDefinitionName, StringComparer.CurrentCultureIgnoreCase).ToArray(); } ItemTier tier = GetItemTier(category); IEnumerable enumerable = from def in (IEnumerable)(object)ItemCatalog.allItemDefs where IsSelectableItem(def, tier) select new PantheonLoadoutOption(category, (int)def.itemIndex, PantheonLoadoutDefinitionKind.Item); if (category == PantheonLoadoutCategory.Lunar) { enumerable = enumerable.Concat(from def in ((IEnumerable)(object)EquipmentCatalog.allEquipment).Select((Func)EquipmentCatalog.GetEquipmentDef) where IsSelectableEquipment(def, lunar: true) select new PantheonLoadoutOption(category, (int)def.equipmentIndex, PantheonLoadoutDefinitionKind.Equipment)); } return enumerable.OrderBy(GetDefinitionName, StringComparer.CurrentCultureIgnoreCase).ToArray(); } internal static int GetPointCost(PantheonLoadoutCategory category) { return category switch { PantheonLoadoutCategory.White => 1, PantheonLoadoutCategory.Green => 3, PantheonLoadoutCategory.Lunar => 4, PantheonLoadoutCategory.Equipment => 5, PantheonLoadoutCategory.Boss => 7, PantheonLoadoutCategory.Red => 10, PantheonLoadoutCategory.VoidWhite => 2, PantheonLoadoutCategory.VoidGreen => 4, PantheonLoadoutCategory.VoidRed => 11, PantheonLoadoutCategory.DroneWhite => 3, PantheonLoadoutCategory.DroneGreen => 7, PantheonLoadoutCategory.DroneRed => 14, _ => int.MaxValue, }; } internal static string GetCategoryName(PantheonLoadoutCategory category) { return category switch { PantheonLoadoutCategory.White => "白色 · 1", PantheonLoadoutCategory.Green => "绿色 · 3", PantheonLoadoutCategory.Lunar => "月球 · 4", PantheonLoadoutCategory.Equipment => "装备 · 5", PantheonLoadoutCategory.Boss => "首领 · 7", PantheonLoadoutCategory.Red => "红色 · 10", PantheonLoadoutCategory.VoidWhite => "虚空白 · 2", PantheonLoadoutCategory.VoidGreen => "虚空绿 · 4", PantheonLoadoutCategory.VoidRed => "虚空红 · 11", PantheonLoadoutCategory.DroneWhite => "白机 · 3+", PantheonLoadoutCategory.DroneGreen => "绿机 · 7+", PantheonLoadoutCategory.DroneRed => "红机 · 14+", _ => string.Empty, }; } internal static string GetDefinitionName(PantheonLoadoutOption option) { if (!option.IsDrone) { if (!option.IsEquipment) { return Language.GetString(ItemCatalog.GetItemDef((ItemIndex)option.DefinitionIndex)?.nameToken ?? string.Empty); } return Language.GetString(EquipmentCatalog.GetEquipmentDef((EquipmentIndex)option.DefinitionIndex)?.nameToken ?? string.Empty); } return Language.GetString(DroneCatalog.GetDroneDef((DroneIndex)option.DefinitionIndex)?.nameToken ?? string.Empty); } internal static Sprite? GetDefinitionIcon(PantheonLoadoutOption option) { if (!option.IsDrone) { if (!option.IsEquipment) { return ItemCatalog.GetItemDef((ItemIndex)option.DefinitionIndex)?.pickupIconSprite; } return EquipmentCatalog.GetEquipmentDef((EquipmentIndex)option.DefinitionIndex)?.pickupIconSprite; } return DroneCatalog.GetDroneDef((DroneIndex)option.DefinitionIndex)?.iconSprite; } internal static int GetClientCount(PantheonLoadoutOption option) { if (!ClientSelection.TryGetValue(new PantheonLoadoutChoice(option.DefinitionIndex, option.Kind), out var value)) { return 0; } return value; } internal static int GetClientUsedPoints() { return GetUsedPoints(ClientSelection); } internal static int GetClientNextPointCost(PantheonLoadoutOption option) { return GetNextPointCost(ClientSelection, option.Category); } internal static void RequestSync() { SendRequest(new LoadoutRequestMessage { Operation = 0 }); } internal static void RequestChange(PantheonLoadoutOption option, int delta) { SendRequest(new LoadoutRequestMessage { Operation = 1, DefinitionIndex = option.DefinitionIndex, Kind = option.Kind, Delta = delta }); } internal static void RequestClear() { SendRequest(new LoadoutRequestMessage { Operation = 2 }); } internal static void RequestReady(bool ready) { SendRequest(new LoadoutRequestMessage { Operation = 3, Ready = ready }); } private static void OnStartServer() { //IL_0015: 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_0020: Expected O, but got Unknown object obj = <>O.<6>__ServerHandleRequest; if (obj == null) { NetworkMessageDelegate val = ServerHandleRequest; <>O.<6>__ServerHandleRequest = val; obj = (object)val; } NetworkServer.RegisterHandler((short)19814, (NetworkMessageDelegate)obj); } private static void OnStartClient(NetworkClient client) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Expected O, but got Unknown object obj = <>O.<7>__ClientHandleState; if (obj == null) { NetworkMessageDelegate val = ClientHandleState; <>O.<7>__ClientHandleState = val; obj = (object)val; } client.RegisterHandler((short)19815, (NetworkMessageDelegate)obj); } private static void ServerHandleRequest(NetworkMessage message) { LoadoutRequestMessage loadoutRequestMessage = message.ReadMessage(); NetworkUser val = FindUser(message.conn); PantheonRunController instance = PantheonRunController.Instance; if (val != null && Object.op_Implicit((Object)(object)val) && Object.op_Implicit((Object)(object)instance) && instance.Phase == PantheonPhase.Resting) { switch (loadoutRequestMessage.Operation) { default: return; case 0: SendState(message.conn, val); return; case 2: GetOrCreateSelection(val).Clear(); ReadyStates[val] = false; break; case 1: TryChangeSelection(val, loadoutRequestMessage.DefinitionIndex, loadoutRequestMessage.Kind, loadoutRequestMessage.Delta); ReadyStates[val] = false; break; case 3: ReadyStates[val] = loadoutRequestMessage.Ready; break; } BroadcastStates(); PantheonLoadoutManager.ServerReadinessChanged?.Invoke(); } } private static void ClientHandleState(NetworkMessage message) { LoadoutStateMessage loadoutStateMessage = message.ReadMessage(); ClientResting = loadoutStateMessage.Phase == PantheonPhase.Resting; ClientReady = loadoutStateMessage.Ready; ClientBudget = loadoutStateMessage.Budget; ClientEncounterIndex = loadoutStateMessage.EncounterIndex; ClientReadyCount = loadoutStateMessage.ReadyCount; ClientPlayerCount = loadoutStateMessage.PlayerCount; ClientSelection.Clear(); LoadoutStateEntry[] entries = loadoutStateMessage.Entries; for (int i = 0; i < entries.Length; i++) { LoadoutStateEntry loadoutStateEntry = entries[i]; if (loadoutStateEntry.Count > 0) { ClientSelection[new PantheonLoadoutChoice(loadoutStateEntry.DefinitionIndex, loadoutStateEntry.Kind)] = loadoutStateEntry.Count; } } PantheonLoadoutManager.ClientStateChanged?.Invoke(); } private static bool TryChangeSelection(NetworkUser user, int definitionIndex, PantheonLoadoutDefinitionKind kind, int delta) { PantheonLoadoutChoice pantheonLoadoutChoice = new PantheonLoadoutChoice(definitionIndex, kind); PantheonLoadoutCategory? pantheonLoadoutCategory = FindCategory(pantheonLoadoutChoice); if ((kind == PantheonLoadoutDefinitionKind.Item || kind == PantheonLoadoutDefinitionKind.Equipment || kind == PantheonLoadoutDefinitionKind.Drone) && pantheonLoadoutCategory.HasValue) { switch (delta) { case -1: case 1: { Dictionary orCreateSelection = GetOrCreateSelection(user); orCreateSelection.TryGetValue(pantheonLoadoutChoice, out var value); if (delta < 0) { if (value <= 0) { return false; } if (value == 1) { orCreateSelection.Remove(pantheonLoadoutChoice); } else { orCreateSelection[pantheonLoadoutChoice] = value - 1; } return true; } if (GetUsedPoints(orCreateSelection) + GetNextPointCost(orCreateSelection, pantheonLoadoutCategory.Value) > serverBudget) { return false; } if (pantheonLoadoutChoice.IsEquipment) { int num = ((!Object.op_Implicit((Object)(object)user.master) || !Object.op_Implicit((Object)(object)user.master.inventory)) ? 1 : Math.Max(1, user.master.inventory.GetEquipmentSlotCount())); if (orCreateSelection.Where((KeyValuePair pair) => pair.Key.IsEquipment).Sum((KeyValuePair pair) => pair.Value) >= num) { return false; } } else if (!pantheonLoadoutChoice.IsDrone) { RemoveVoidConflict(orCreateSelection, (ItemIndex)definitionIndex); if (GetUsedPoints(orCreateSelection) + GetNextPointCost(orCreateSelection, pantheonLoadoutCategory.Value) > serverBudget) { return false; } } orCreateSelection[pantheonLoadoutChoice] = value + 1; return true; } } } return false; } private static void RemoveVoidConflict(Dictionary selection, ItemIndex itemIndex) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Invalid comparison between Unknown and I4 //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Invalid comparison between Unknown and I4 //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Expected I4, but got Unknown //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Expected I4, but got Unknown ItemIndex transformedItemIndex = ContagiousItemManager.GetTransformedItemIndex(itemIndex); ItemIndex originalItemIndex = ContagiousItemManager.GetOriginalItemIndex(itemIndex); if ((int)transformedItemIndex != -1) { selection.Remove(new PantheonLoadoutChoice((int)transformedItemIndex, PantheonLoadoutDefinitionKind.Item)); } if ((int)originalItemIndex != -1) { selection.Remove(new PantheonLoadoutChoice((int)originalItemIndex, PantheonLoadoutDefinitionKind.Item)); } } private static void ApplySelection(NetworkUser user) { //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_01f6: Unknown result type (might be due to invalid IL or missing references) DestroyLoadoutDrones(user); CharacterMaster val = (Object.op_Implicit((Object)(object)user) ? user.master : null); Inventory val2 = (Object.op_Implicit((Object)(object)val) ? val.inventory : null); if (!Object.op_Implicit((Object)(object)val) || !Object.op_Implicit((Object)(object)val2)) { return; } CaptureBaseline(val); Enumerator enumerator = ItemCatalog.allItemDefs.GetEnumerator(); try { while (enumerator.MoveNext()) { ItemDef current = enumerator.Current; if (Object.op_Implicit((Object)(object)current) && GetCategory(current.tier).HasValue) { val2.ResetItemPermanent(current.itemIndex); } } } finally { ((IDisposable)enumerator/*cast due to .constrained prefix*/).Dispose(); } int value2; if (BaselineItems.TryGetValue(val, out Dictionary value)) { foreach (KeyValuePair item in value) { item.Deconstruct(out var key, out value2); ItemIndex val3 = key; int num = value2; if (num > 0) { val2.GiveItemPermanent(val3, num); } } } int num2 = Math.Max(1, val2.GetEquipmentSlotCount()); for (uint num3 = 0u; num3 < num2; num3++) { val2.SetEquipmentIndexForSlot((EquipmentIndex)(-1), num3, 0u); } if (!Selections.TryGetValue(user, out Dictionary value3)) { return; } List list = new List(); List list2 = new List(); foreach (KeyValuePair item2 in value3) { item2.Deconstruct(out var key2, out value2); PantheonLoadoutChoice pantheonLoadoutChoice = key2; int num4 = value2; if (pantheonLoadoutChoice.IsEquipment) { for (int i = 0; i < num4; i++) { list.Add((EquipmentIndex)pantheonLoadoutChoice.DefinitionIndex); } } else if (pantheonLoadoutChoice.IsDrone) { for (int j = 0; j < num4; j++) { list2.Add((DroneIndex)pantheonLoadoutChoice.DefinitionIndex); } } else { val2.GiveItemPermanent((ItemIndex)pantheonLoadoutChoice.DefinitionIndex, num4); } } for (uint num5 = 0u; num5 < list.Count && num5 < num2; num5++) { val2.SetEquipmentIndexForSlot(list[(int)num5], num5, 0u); } SpawnLoadoutDrones(user, val, list2); } private static void SpawnLoadoutDrones(NetworkUser user, CharacterMaster ownerMaster, IReadOnlyList drones) { //IL_0027: 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_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_009e: 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_00a5: 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_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00be: 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_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Unknown result type (might be due to invalid IL or missing references) //IL_0108: Unknown result type (might be due to invalid IL or missing references) //IL_0114: Unknown result type (might be due to invalid IL or missing references) CharacterBody body = ownerMaster.GetBody(); if (!Object.op_Implicit((Object)(object)body) || drones.Count == 0) { return; } List list = new List(); for (int i = 0; i < drones.Count; i++) { DroneDef droneDef = DroneCatalog.GetDroneDef(drones[i]); if (IsSelectableDrone(droneDef, (ItemTier)((!Object.op_Implicit((Object)(object)droneDef)) ? 5 : ((int)droneDef.tier))) && Object.op_Implicit((Object)(object)droneDef.masterPrefab)) { float num = 360f * (float)i / (float)Math.Max(1, drones.Count); Vector3 val = Quaternion.Euler(0f, num, 0f) * Vector3.forward * 3f; Vector3 position = body.footPosition + val + Vector3.up * 1.5f; CharacterMaster val2 = new MasterSummon { masterPrefab = droneDef.masterPrefab, position = position, rotation = Quaternion.LookRotation(-((Vector3)(ref val)).normalized, Vector3.up), summonerBodyObject = ((Component)body).gameObject, ignoreTeamMemberLimit = true, useAmbientLevel = true, enablePrintController = true }.Perform(); if (Object.op_Implicit((Object)(object)val2)) { list.Add(val2); } } } if (list.Count > 0) { LoadoutDrones[user] = list; } } private static void DestroyLoadoutDrones(NetworkUser user) { if (!LoadoutDrones.TryGetValue(user, out List value)) { return; } foreach (CharacterMaster item in value) { if (Object.op_Implicit((Object)(object)item)) { NetworkServer.Destroy(((Component)item).gameObject); } } LoadoutDrones.Remove(user); } private static void DestroyAllLoadoutDrones() { if (NetworkServer.active) { NetworkUser[] array = LoadoutDrones.Keys.ToArray(); for (int i = 0; i < array.Length; i++) { DestroyLoadoutDrones(array[i]); } } else { LoadoutDrones.Clear(); } } private static void CaptureBaselines() { foreach (NetworkUser item in ParticipatingUsers()) { CharacterMaster val = (Object.op_Implicit((Object)(object)item) ? item.master : null); if (Object.op_Implicit((Object)(object)val)) { CaptureBaseline(val); } } } private static void CaptureBaseline(CharacterMaster master) { //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) if (BaselineItems.ContainsKey(master) || !Object.op_Implicit((Object)(object)master.inventory)) { return; } Dictionary dictionary = new Dictionary(); Enumerator enumerator = ItemCatalog.allItemDefs.GetEnumerator(); try { while (enumerator.MoveNext()) { ItemDef current = enumerator.Current; if (Object.op_Implicit((Object)(object)current) && GetCategory(current.tier).HasValue) { int itemCountPermanent = master.inventory.GetItemCountPermanent(current.itemIndex); if (itemCountPermanent > 0) { dictionary[current.itemIndex] = itemCountPermanent; } } } } finally { ((IDisposable)enumerator/*cast due to .constrained prefix*/).Dispose(); } BaselineItems[master] = dictionary; } private static void TrimSelectionToBudget(Dictionary selection) { while (GetUsedPoints(selection) > serverBudget && selection.Count > 0) { PantheonLoadoutChoice key = selection.Keys.Last(); if (selection[key] <= 1) { selection.Remove(key); } else { selection[key]--; } } } private static int GetUsedPoints(Dictionary selection) { int[] array = new int[12]; foreach (KeyValuePair item in selection) { item.Deconstruct(out var key, out var value); PantheonLoadoutChoice choice = key; int num = value; PantheonLoadoutCategory? pantheonLoadoutCategory = FindCategory(choice); if (pantheonLoadoutCategory.HasValue) { array[(uint)pantheonLoadoutCategory.Value] += num; } } int num2 = 0; for (int i = 0; i < array.Length; i++) { num2 += GetCategoryPointCost((PantheonLoadoutCategory)i, array[i]); } return num2; } private static int GetNextPointCost(Dictionary selection, PantheonLoadoutCategory category) { int num = 0; foreach (var (choice, num3) in selection) { if (FindCategory(choice) == category) { num += num3; } } return GetPointCost(category) + GetPointIncrement(category) * num; } private static int GetCategoryPointCost(PantheonLoadoutCategory category, int count) { if (count <= 0) { return 0; } int pointCost = GetPointCost(category); int pointIncrement = GetPointIncrement(category); return pointCost * count + pointIncrement * count * (count - 1) / 2; } private static int GetPointIncrement(PantheonLoadoutCategory category) { return category switch { PantheonLoadoutCategory.DroneWhite => 1, PantheonLoadoutCategory.DroneGreen => 2, PantheonLoadoutCategory.DroneRed => 3, _ => 0, }; } private static PantheonLoadoutCategory? FindCategory(PantheonLoadoutChoice choice) { //IL_0020: 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_0037: 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) if (choice.IsDrone) { DroneDef droneDef = DroneCatalog.GetDroneDef((DroneIndex)choice.DefinitionIndex); if (!Object.op_Implicit((Object)(object)droneDef) || !IsSelectableDrone(droneDef, droneDef.tier)) { return null; } return GetDroneCategory(droneDef.tier); } if (choice.IsEquipment) { EquipmentDef equipmentDef = EquipmentCatalog.GetEquipmentDef((EquipmentIndex)choice.DefinitionIndex); if (!Object.op_Implicit((Object)(object)equipmentDef) || !IsSelectableEquipment(equipmentDef, equipmentDef.isLunar)) { return null; } return equipmentDef.isLunar ? PantheonLoadoutCategory.Lunar : PantheonLoadoutCategory.Equipment; } ItemDef itemDef = ItemCatalog.GetItemDef((ItemIndex)choice.DefinitionIndex); if (!Object.op_Implicit((Object)(object)itemDef) || !IsSelectableItem(itemDef, itemDef.tier)) { return null; } return GetCategory(itemDef.tier); } private static bool IsSelectableItem(ItemDef? itemDef, ItemTier expectedTier) { //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)itemDef) || itemDef.hidden || itemDef.isConsumed || !itemDef.canRemove || itemDef.tier != expectedTier || !GetCategory(expectedTier).HasValue) { return false; } string name = ((Object)itemDef).name; if (name.IndexOf("Scrap", StringComparison.OrdinalIgnoreCase) < 0 && name.IndexOf("ArtifactKey", StringComparison.OrdinalIgnoreCase) < 0) { return name.IndexOf("TitanGoldDuringTP", StringComparison.OrdinalIgnoreCase) < 0; } return false; } private static bool IsSelectableEquipment(EquipmentDef? equipmentDef, bool lunar) { if (!Object.op_Implicit((Object)(object)equipmentDef) || !equipmentDef.canDrop || equipmentDef.isConsumed || !equipmentDef.appearsInMultiPlayer || equipmentDef.isBoss || equipmentDef.isLunar != lunar) { return false; } string name = ((Object)equipmentDef).name; if (name.IndexOf("BossHunter", StringComparison.OrdinalIgnoreCase) < 0) { return name.IndexOf("Quest", StringComparison.OrdinalIgnoreCase) < 0; } return false; } private static bool IsSelectableDrone(DroneDef? droneDef, ItemTier expectedTier) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) if (Object.op_Implicit((Object)(object)droneDef) && droneDef.canDrop && droneDef.tier == expectedTier && GetDroneCategory(expectedTier).HasValue && Object.op_Implicit((Object)(object)droneDef.masterPrefab)) { return Object.op_Implicit((Object)(object)droneDef.iconSprite); } return false; } private static bool IsDroneCategory(PantheonLoadoutCategory category) { if (category != PantheonLoadoutCategory.DroneWhite && category != PantheonLoadoutCategory.DroneGreen) { return category == PantheonLoadoutCategory.DroneRed; } return true; } private static PantheonLoadoutCategory? GetDroneCategory(ItemTier tier) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Expected I4, but got Unknown return (int)tier switch { 0 => PantheonLoadoutCategory.DroneWhite, 1 => PantheonLoadoutCategory.DroneGreen, 2 => PantheonLoadoutCategory.DroneRed, _ => null, }; } private static ItemTier GetDroneTier(PantheonLoadoutCategory category) { //IL_0018: 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_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) return (ItemTier)(category switch { PantheonLoadoutCategory.DroneWhite => 0, PantheonLoadoutCategory.DroneGreen => 1, PantheonLoadoutCategory.DroneRed => 2, _ => 5, }); } private static PantheonLoadoutCategory? GetCategory(ItemTier tier) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Expected I4, but got Unknown return (int)tier switch { 0 => PantheonLoadoutCategory.White, 1 => PantheonLoadoutCategory.Green, 3 => PantheonLoadoutCategory.Lunar, 4 => PantheonLoadoutCategory.Boss, 2 => PantheonLoadoutCategory.Red, 6 => PantheonLoadoutCategory.VoidWhite, 7 => PantheonLoadoutCategory.VoidGreen, 8 => PantheonLoadoutCategory.VoidRed, _ => null, }; } private static ItemTier GetItemTier(PantheonLoadoutCategory category) { //IL_002d: 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_0035: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) return (ItemTier)(category switch { PantheonLoadoutCategory.White => 0, PantheonLoadoutCategory.Green => 1, PantheonLoadoutCategory.Lunar => 3, PantheonLoadoutCategory.Boss => 4, PantheonLoadoutCategory.Red => 2, PantheonLoadoutCategory.VoidWhite => 6, PantheonLoadoutCategory.VoidGreen => 7, PantheonLoadoutCategory.VoidRed => 8, _ => 5, }); } private static IEnumerable ParticipatingUsers() { return NetworkUser.readOnlyInstancesList.Where((NetworkUser user) => Object.op_Implicit((Object)(object)user) && user.isParticipating); } private static Dictionary GetOrCreateSelection(NetworkUser user) { if (!Selections.TryGetValue(user, out Dictionary value)) { value = new Dictionary(); Selections[user] = value; } return value; } private static void BroadcastStates() { foreach (NetworkConnection connection in NetworkServer.connections) { if (connection != null) { NetworkUser val = FindUser(connection); if (val != null && Object.op_Implicit((Object)(object)val)) { SendState(connection, val); } } } } private static void SendState(NetworkConnection connection, NetworkUser user) { PantheonRunController instance = PantheonRunController.Instance; Dictionary orCreateSelection = GetOrCreateSelection(user); NetworkUser[] array = ParticipatingUsers().ToArray(); bool value; bool value2; LoadoutStateMessage loadoutStateMessage = new LoadoutStateMessage { Phase = (Object.op_Implicit((Object)(object)instance) ? instance.Phase : PantheonPhase.Loading), Budget = serverBudget, EncounterIndex = (Object.op_Implicit((Object)(object)instance) ? instance.CurrentEncounterIndex : 0), Ready = (ReadyStates.TryGetValue(user, out value) && value), ReadyCount = array.Count((NetworkUser participant) => ReadyStates.TryGetValue(participant, out value2) && value2), PlayerCount = array.Length, Entries = orCreateSelection.Select((KeyValuePair pair) => new LoadoutStateEntry { DefinitionIndex = pair.Key.DefinitionIndex, Kind = pair.Key.Kind, Count = pair.Value }).ToArray() }; connection.Send((short)19815, (MessageBase)(object)loadoutStateMessage); } private static void SendRequest(LoadoutRequestMessage request) { NetworkClient val = (Object.op_Implicit((Object)(object)NetworkManagerSystem.singleton) ? ((NetworkManager)NetworkManagerSystem.singleton).client : null); if (val != null && val.isConnected) { val.Send((short)19814, (MessageBase)(object)request); } } private static NetworkUser? FindUser(NetworkConnection connection) { return ((IEnumerable)NetworkUser.readOnlyInstancesList).FirstOrDefault((Func)((NetworkUser user) => Object.op_Implicit((Object)(object)user) && ((NetworkBehaviour)user).connectionToClient == connection)); } private static void OnNetworkUserLost(NetworkUser user) { if (NetworkServer.active) { DestroyLoadoutDrones(user); } Selections.Remove(user); ReadyStates.Remove(user); if (NetworkServer.active) { BroadcastStates(); PantheonLoadoutManager.ServerReadinessChanged?.Invoke(); } } private static void OnRunDestroy(Run run) { if (Object.op_Implicit((Object)(object)run) && Object.op_Implicit((Object)(object)((Component)run).GetComponent())) { ResetState(); } } private static void ResetState() { DestroyAllLoadoutDrones(); Selections.Clear(); ReadyStates.Clear(); BaselineItems.Clear(); ClientSelection.Clear(); ClientResting = false; ClientReady = false; ClientBudget = 0; ClientEncounterIndex = 0; ClientReadyCount = 0; ClientPlayerCount = 0; } } internal static class PantheonLoadoutUI { [CompilerGenerated] private static class <>O { public static hook_Awake <0>__HudAwake; } private static bool installed; internal static void Install() { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Expected O, but got Unknown if (!installed) { installed = true; object obj = <>O.<0>__HudAwake; if (obj == null) { hook_Awake val = HudAwake; <>O.<0>__HudAwake = val; obj = (object)val; } HUD.Awake += (hook_Awake)obj; } } internal static void Uninstall() { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Expected O, but got Unknown if (installed) { installed = false; object obj = <>O.<0>__HudAwake; if (obj == null) { hook_Awake val = HudAwake; <>O.<0>__HudAwake = val; obj = (object)val; } HUD.Awake -= (hook_Awake)obj; } } private static void HudAwake(orig_Awake orig, HUD self) { orig.Invoke(self); if (Object.op_Implicit((Object)(object)self) && !Object.op_Implicit((Object)(object)((Component)self).GetComponent())) { ((Component)self).gameObject.AddComponent(); } } } internal sealed class PantheonLoadoutPanel : MonoBehaviour { [CompilerGenerated] private static class <>O { public static UnityAction <0>__RequestClear; } [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static UnityAction <>9__20_0; internal void b__20_0() { PantheonLoadoutManager.RequestReady(!PantheonLoadoutManager.ClientReady); } } private readonly List<(PantheonLoadoutOption Option, MPButton Button, TMP_Text Label)> optionButtons = new List<(PantheonLoadoutOption, MPButton, TMP_Text)>(); private HUD hud; private GameObject root; private Transform categoryRow; private RectTransform grid; private MPButton buttonTemplate; private bool ownsButtonTemplate; private HGTextMeshProUGUI encounterText; private HGTextMeshProUGUI pointsText; private HGTextMeshProUGUI readinessText; private MPButton readyButton; private TMP_Text readyButtonLabel; private PantheonLoadoutCategory category; private bool wasVisible; private void Awake() { hud = ((Component)this).GetComponent(); LoadButtonTemplate(); BuildPanel(); PantheonLoadoutManager.ClientStateChanged += OnClientStateChanged; root.SetActive(false); } private void OnDestroy() { PantheonLoadoutManager.ClientStateChanged -= OnClientStateChanged; if (ownsButtonTemplate && Object.op_Implicit((Object)(object)buttonTemplate)) { Object.Destroy((Object)(object)((Component)buttonTemplate).gameObject); } } private void Update() { bool flag = PantheonModule.IsActive && PantheonLoadoutManager.ClientResting; if (root.activeSelf != flag) { root.SetActive(flag); } if (flag && !wasVisible) { PantheonLoadoutManager.RequestSync(); Refresh(); } wasVisible = flag; } private void OnClientStateChanged() { if (Object.op_Implicit((Object)(object)this) && Object.op_Implicit((Object)(object)root)) { Refresh(); } } private void LoadButtonTemplate() { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) GameObject val = Addressables.LoadAssetAsync((object)"RoR2/Base/UI/Generic UI/Prefab/SettingsEntryButton, Carousel.prefab").WaitForCompletion(); buttonTemplate = (Object.op_Implicit((Object)(object)val) ? val.GetComponentInChildren(true) : null); if (!Object.op_Implicit((Object)(object)buttonTemplate)) { buttonTemplate = CreateFallbackButtonTemplate(); ownsButtonTemplate = true; } } private MPButton CreateFallbackButtonTemplate() { //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Expected O, but got Unknown //IL_006a: 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_0094: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: Unknown result type (might be due to invalid IL or missing references) //IL_0114: Unknown result type (might be due to invalid IL or missing references) //IL_0136: Unknown result type (might be due to invalid IL or missing references) //IL_0162: Unknown result type (might be due to invalid IL or missing references) //IL_0167: Unknown result type (might be due to invalid IL or missing references) //IL_0173: Unknown result type (might be due to invalid IL or missing references) //IL_0185: Unknown result type (might be due to invalid IL or missing references) //IL_018b: Unknown result type (might be due to invalid IL or missing references) //IL_0190: Unknown result type (might be due to invalid IL or missing references) //IL_0196: Expected O, but got Unknown //IL_0196: Unknown result type (might be due to invalid IL or missing references) //IL_01a1: Unknown result type (might be due to invalid IL or missing references) //IL_01b5: Unknown result type (might be due to invalid IL or missing references) //IL_020d: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("PantheonButtonTemplate", new Type[3] { typeof(RectTransform), typeof(Image), typeof(MPButton) }); val.layer = ((Component)hud).gameObject.layer; Image component = val.GetComponent(); ((Graphic)component).color = new Color(0.11f, 0.17f, 0.2f, 0.98f); MPButton component2 = val.GetComponent(); ((Selectable)component2).targetGraphic = (Graphic)(object)component; ((Selectable)component2).transition = (Transition)1; ColorBlock colors = default(ColorBlock); ((ColorBlock)(ref colors)).normalColor = Color.white; ((ColorBlock)(ref colors)).highlightedColor = new Color(0.72f, 0.9f, 1f, 1f); ((ColorBlock)(ref colors)).pressedColor = new Color(0.42f, 0.72f, 0.9f, 1f); ((ColorBlock)(ref colors)).selectedColor = new Color(0.72f, 0.9f, 1f, 1f); ((ColorBlock)(ref colors)).disabledColor = new Color(0.35f, 0.38f, 0.4f, 0.65f); ((ColorBlock)(ref colors)).colorMultiplier = 1f; ((ColorBlock)(ref colors)).fadeDuration = 0.08f; ((Selectable)component2).colors = colors; GameObject val2 = new GameObject("Label", new Type[2] { typeof(RectTransform), typeof(HGTextMeshProUGUI) }) { layer = val.layer }; val2.transform.SetParent(val.transform, false); RectTransform val3 = (RectTransform)val2.transform; Stretch(val3); val3.offsetMin = new Vector2(8f, 4f); val3.offsetMax = new Vector2(-8f, -4f); HGTextMeshProUGUI component3 = val2.GetComponent(); TMP_Text componentInChildren = ((Component)hud).GetComponentInChildren(true); if (Object.op_Implicit((Object)(object)componentInChildren)) { ((TMP_Text)component3).font = componentInChildren.font; ((TMP_Text)component3).fontSharedMaterial = componentInChildren.fontSharedMaterial; } ((TMP_Text)component3).fontSize = 16f; ((TMP_Text)component3).alignment = (TextAlignmentOptions)514; ((Graphic)component3).color = Color.white; ((Graphic)component3).raycastTarget = false; ((TMP_Text)component3).enableWordWrapping = true; val.SetActive(false); return component2; } private void BuildPanel() { //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_0060: 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_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_011a: Unknown result type (might be due to invalid IL or missing references) //IL_0149: Unknown result type (might be due to invalid IL or missing references) //IL_014f: Expected O, but got Unknown //IL_017d: Unknown result type (might be due to invalid IL or missing references) //IL_0182: Unknown result type (might be due to invalid IL or missing references) //IL_0188: Expected O, but got Unknown //IL_0188: Unknown result type (might be due to invalid IL or missing references) //IL_0193: Unknown result type (might be due to invalid IL or missing references) //IL_01a7: Unknown result type (might be due to invalid IL or missing references) //IL_021a: Unknown result type (might be due to invalid IL or missing references) //IL_02ad: Unknown result type (might be due to invalid IL or missing references) //IL_02b3: Expected O, but got Unknown //IL_0370: Unknown result type (might be due to invalid IL or missing references) //IL_0377: Expected O, but got Unknown //IL_03b7: Unknown result type (might be due to invalid IL or missing references) //IL_041c: Unknown result type (might be due to invalid IL or missing references) //IL_0423: Expected O, but got Unknown //IL_0451: Unknown result type (might be due to invalid IL or missing references) //IL_045b: Expected O, but got Unknown //IL_046b: Unknown result type (might be due to invalid IL or missing references) //IL_0485: Unknown result type (might be due to invalid IL or missing references) //IL_049f: Unknown result type (might be due to invalid IL or missing references) //IL_04af: Unknown result type (might be due to invalid IL or missing references) //IL_04bf: Unknown result type (might be due to invalid IL or missing references) //IL_04db: Unknown result type (might be due to invalid IL or missing references) //IL_04f0: Unknown result type (might be due to invalid IL or missing references) //IL_04ff: Unknown result type (might be due to invalid IL or missing references) //IL_0509: Expected O, but got Unknown //IL_0532: Unknown result type (might be due to invalid IL or missing references) //IL_053c: Expected O, but got Unknown //IL_05dd: Unknown result type (might be due to invalid IL or missing references) //IL_05a1: Unknown result type (might be due to invalid IL or missing references) //IL_05a6: Unknown result type (might be due to invalid IL or missing references) //IL_05ac: Expected O, but got Unknown //IL_0630: Unknown result type (might be due to invalid IL or missing references) //IL_0635: Unknown result type (might be due to invalid IL or missing references) //IL_063b: Expected O, but got Unknown Transform val = (Object.op_Implicit((Object)(object)hud.mainContainer) ? hud.mainContainer.transform : ((Component)hud).transform); root = new GameObject("PantheonLoadoutPanel", new Type[2] { typeof(RectTransform), typeof(Image) }); root.SetActive(false); root.layer = ((Component)val).gameObject.layer; root.transform.SetParent(val, false); root.AddComponent(); root.AddComponent(); RectTransform val2 = (RectTransform)root.transform; val2.anchorMin = new Vector2(0.08f, 0.06f); val2.anchorMax = new Vector2(0.92f, 0.94f); val2.offsetMin = Vector2.zero; val2.offsetMax = Vector2.zero; ((Graphic)root.GetComponent()).color = new Color(0.025f, 0.04f, 0.055f, 0.97f); GameObject val3 = new GameObject("Content", new Type[2] { typeof(RectTransform), typeof(VerticalLayoutGroup) }); val3.layer = root.layer; val3.transform.SetParent(root.transform, false); RectTransform val4 = (RectTransform)val3.transform; Stretch(val4); val4.offsetMin = new Vector2(22f, 18f); val4.offsetMax = new Vector2(-22f, -18f); VerticalLayoutGroup component = val3.GetComponent(); ((HorizontalOrVerticalLayoutGroup)component).spacing = 8f; ((HorizontalOrVerticalLayoutGroup)component).childControlWidth = true; ((HorizontalOrVerticalLayoutGroup)component).childControlHeight = true; ((HorizontalOrVerticalLayoutGroup)component).childForceExpandWidth = true; ((HorizontalOrVerticalLayoutGroup)component).childForceExpandHeight = false; Transform parent = CreateRow(val3.transform, 58f); ((Graphic)CreateText(parent, "黄金万神殿", 27f, (FontStyles)1, 260f)).color = new Color(1f, 0.78f, 0.24f, 1f); encounterText = CreateText(parent, string.Empty, 18f, (FontStyles)1, 260f); pointsText = CreateText(parent, string.Empty, 18f, (FontStyles)1, 180f); readinessText = CreateText(parent, string.Empty, 16f, (FontStyles)0, 180f); GameObject val5 = new GameObject("Categories", new Type[3] { typeof(RectTransform), typeof(HorizontalLayoutGroup), typeof(LayoutElement) }); val5.layer = root.layer; val5.transform.SetParent(val3.transform, false); val5.GetComponent().preferredHeight = 46f; HorizontalLayoutGroup component2 = val5.GetComponent(); ((HorizontalOrVerticalLayoutGroup)component2).spacing = 5f; ((HorizontalOrVerticalLayoutGroup)component2).childControlWidth = true; ((HorizontalOrVerticalLayoutGroup)component2).childControlHeight = true; ((HorizontalOrVerticalLayoutGroup)component2).childForceExpandWidth = true; ((HorizontalOrVerticalLayoutGroup)component2).childForceExpandHeight = true; categoryRow = val5.transform; BuildCategoryButtons(); GameObject val6 = new GameObject("LoadoutScroll", new Type[5] { typeof(RectTransform), typeof(Image), typeof(ScrollRect), typeof(LayoutElement), typeof(Mask) }); val6.layer = root.layer; val6.transform.SetParent(val3.transform, false); ((Graphic)val6.GetComponent()).color = new Color(0.055f, 0.075f, 0.09f, 0.96f); val6.GetComponent().showMaskGraphic = true; LayoutElement component3 = val6.GetComponent(); component3.flexibleHeight = 1f; component3.minHeight = 280f; GameObject val7 = new GameObject("Grid", new Type[3] { typeof(RectTransform), typeof(GridLayoutGroup), typeof(ContentSizeFitter) }); val7.layer = root.layer; val7.transform.SetParent(val6.transform, false); grid = (RectTransform)val7.transform; grid.anchorMin = new Vector2(0f, 1f); grid.anchorMax = new Vector2(1f, 1f); grid.pivot = new Vector2(0.5f, 1f); grid.anchoredPosition = Vector2.zero; grid.sizeDelta = Vector2.zero; GridLayoutGroup component4 = val7.GetComponent(); component4.cellSize = new Vector2(190f, 68f); component4.spacing = new Vector2(6f, 6f); ((LayoutGroup)component4).padding = new RectOffset(8, 8, 8, 8); component4.constraint = (Constraint)1; component4.constraintCount = 5; val7.GetComponent().verticalFit = (FitMode)2; ScrollRect component5 = val6.GetComponent(); component5.viewport = (RectTransform)val6.transform; component5.content = grid; component5.horizontal = false; component5.vertical = true; component5.movementType = (MovementType)2; component5.scrollSensitivity = 30f; Transform parent2 = CreateRow(val3.transform, 50f); ButtonClickedEvent onClick = ((Button)CloneButton(parent2, "清空", 130f)).onClick; object obj = <>O.<0>__RequestClear; if (obj == null) { UnityAction val8 = PantheonLoadoutManager.RequestClear; <>O.<0>__RequestClear = val8; obj = (object)val8; } ((UnityEvent)onClick).AddListener((UnityAction)obj); ((Graphic)CreateText(parent2, "左键添加,右键移除。无人机同色越多,下一架价格越高。", 15f, (FontStyles)0, 520f)).color = new Color(0.72f, 0.8f, 0.84f, 1f); readyButton = CloneButton(parent2, "准备", 180f); readyButtonLabel = ((Component)readyButton).GetComponentInChildren(true); ButtonClickedEvent onClick2 = ((Button)readyButton).onClick; object obj2 = <>c.<>9__20_0; if (obj2 == null) { UnityAction val9 = delegate { PantheonLoadoutManager.RequestReady(!PantheonLoadoutManager.ClientReady); }; <>c.<>9__20_0 = val9; obj2 = (object)val9; } ((UnityEvent)onClick2).AddListener((UnityAction)obj2); RebuildGrid(); } private void BuildCategoryButtons() { //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Expected O, but got Unknown for (int i = 0; i < 12; i++) { PantheonLoadoutCategory buttonCategory = (PantheonLoadoutCategory)i; ((UnityEvent)((Button)CloneButton(categoryRow, PantheonLoadoutManager.GetCategoryName(buttonCategory), 110f)).onClick).AddListener((UnityAction)delegate { category = buttonCategory; RebuildGrid(); Refresh(); }); } } private void RebuildGrid() { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Expected O, but got Unknown //IL_00fe: 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_0104: Unknown result type (might be due to invalid IL or missing references) //IL_0113: Unknown result type (might be due to invalid IL or missing references) //IL_0118: Unknown result type (might be due to invalid IL or missing references) //IL_0147: Unknown result type (might be due to invalid IL or missing references) //IL_014c: Unknown result type (might be due to invalid IL or missing references) //IL_015d: Unknown result type (might be due to invalid IL or missing references) //IL_0170: Unknown result type (might be due to invalid IL or missing references) //IL_0176: Unknown result type (might be due to invalid IL or missing references) //IL_017b: Unknown result type (might be due to invalid IL or missing references) //IL_0186: Unknown result type (might be due to invalid IL or missing references) //IL_0190: Unknown result type (might be due to invalid IL or missing references) //IL_019b: Unknown result type (might be due to invalid IL or missing references) //IL_01a5: Unknown result type (might be due to invalid IL or missing references) //IL_01b0: Unknown result type (might be due to invalid IL or missing references) //IL_01ba: Unknown result type (might be due to invalid IL or missing references) //IL_01c5: Unknown result type (might be due to invalid IL or missing references) //IL_01d9: Unknown result type (might be due to invalid IL or missing references) foreach (Transform item in (Transform)grid) { Object.Destroy((Object)(object)((Component)item).gameObject); } optionButtons.Clear(); foreach (PantheonLoadoutOption option in PantheonLoadoutManager.GetAvailableDefinitions(category)) { MPButton val = CloneButton((Transform)(object)grid, string.Empty, 190f); LayoutElement obj = ((Component)val).GetComponent() ?? ((Component)val).gameObject.AddComponent(); obj.preferredWidth = 190f; obj.preferredHeight = 68f; ((UnityEvent)((Button)val).onClick).AddListener((UnityAction)delegate { PantheonLoadoutManager.RequestChange(option, 1); }); TMP_Text componentInChildren = ((Component)val).GetComponentInChildren(true); componentInChildren.fontSize = 13f; componentInChildren.alignment = (TextAlignmentOptions)514; componentInChildren.enableWordWrapping = true; RectTransform val2 = (RectTransform)componentInChildren.transform; val2.offsetMin += new Vector2(48f, 0f); GameObject val3 = new GameObject("Icon", new Type[2] { typeof(RectTransform), typeof(Image) }) { layer = root.layer }; val3.transform.SetParent(((Component)val).transform, false); RectTransform val4 = (RectTransform)val3.transform; val4.anchorMin = new Vector2(0f, 0.5f); val4.anchorMax = new Vector2(0f, 0.5f); val4.pivot = new Vector2(0f, 0.5f); val4.anchoredPosition = new Vector2(7f, 0f); val4.sizeDelta = new Vector2(42f, 42f); Image component = val3.GetComponent(); component.sprite = PantheonLoadoutManager.GetDefinitionIcon(option); component.preserveAspect = true; ((Graphic)component).raycastTarget = false; AddTooltip(((Component)val).gameObject, option); ((Component)val).gameObject.AddComponent().Configure(option); optionButtons.Add((option, val, componentInChildren)); } Refresh(); } private void Refresh() { //IL_00b5: 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_01d0: Unknown result type (might be due to invalid IL or missing references) //IL_01b5: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)root)) { return; } int num = PantheonLoadoutManager.ClientEncounterIndex + 1; int num2 = Mathf.Clamp(PantheonLoadoutManager.ClientEncounterIndex, 0, PantheonModule.Encounters.Length - 1); string bossDisplayName = PantheonModule.Encounters[num2].GetBossDisplayName(); ((TMP_Text)encounterText).text = $"第 {num} / {PantheonModule.Encounters.Length} 战 下一场:{bossDisplayName}"; int clientUsedPoints = PantheonLoadoutManager.GetClientUsedPoints(); int clientBudget = PantheonLoadoutManager.ClientBudget; ((TMP_Text)pointsText).text = $"配装 {clientUsedPoints} / {clientBudget}"; ((Graphic)pointsText).color = (Color)((clientUsedPoints <= clientBudget) ? new Color(0.65f, 0.9f, 1f, 1f) : Color.red); ((TMP_Text)readinessText).text = $"准备 {PantheonLoadoutManager.ClientReadyCount} / {PantheonLoadoutManager.ClientPlayerCount}"; readyButtonLabel.text = (PantheonLoadoutManager.ClientReady ? "取消准备" : "准备"); foreach (var optionButton in optionButtons) { PantheonLoadoutOption item = optionButton.Option; MPButton item2 = optionButton.Button; TMP_Text item3 = optionButton.Label; int clientCount = PantheonLoadoutManager.GetClientCount(item); string definitionName = PantheonLoadoutManager.GetDefinitionName(item); int clientNextPointCost = PantheonLoadoutManager.GetClientNextPointCost(item); item3.text = (item.IsDrone ? ((clientCount > 0) ? $"{definitionName} ×{clientCount}\n下一架 {clientNextPointCost} 点" : $"{definitionName}\n{clientNextPointCost} 点") : ((clientCount > 0) ? $"{definitionName}\n×{clientCount}" : definitionName)); ((Graphic)item3).color = (Color)((clientCount > 0) ? new Color(1f, 0.78f, 0.24f, 1f) : Color.white); ((Selectable)item2).interactable = clientCount > 0 || clientUsedPoints + clientNextPointCost <= clientBudget; } } private MPButton CloneButton(Transform parent, string text, float width) { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Expected O, but got Unknown MPButton val = Object.Instantiate(buttonTemplate, parent, false); ((Component)val).gameObject.SetActive(true); ((Button)val).onClick = new ButtonClickedEvent(); ((Selectable)val).interactable = true; LayoutElement obj = ((Component)val).GetComponent() ?? ((Component)val).gameObject.AddComponent(); obj.preferredWidth = width; obj.preferredHeight = 44f; TMP_Text componentInChildren = ((Component)val).GetComponentInChildren(true); LanguageTextMeshController component = ((Component)componentInChildren).GetComponent(); if (Object.op_Implicit((Object)(object)component)) { ((Behaviour)component).enabled = false; } componentInChildren.text = text; return val; } private HGTextMeshProUGUI CreateText(Transform parent, string text, float size, FontStyles style, float width) { //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0048: 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_0098: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("Text", new Type[3] { typeof(RectTransform), typeof(HGTextMeshProUGUI), typeof(LayoutElement) }) { layer = root.layer }; val.transform.SetParent(parent, false); HGTextMeshProUGUI component = val.GetComponent(); TMP_Text componentInChildren = ((Component)hud).GetComponentInChildren(true); if (Object.op_Implicit((Object)(object)componentInChildren)) { ((TMP_Text)component).font = componentInChildren.font; ((TMP_Text)component).fontSharedMaterial = componentInChildren.fontSharedMaterial; } ((TMP_Text)component).text = text; ((TMP_Text)component).fontSize = size; ((TMP_Text)component).fontStyle = style; ((TMP_Text)component).alignment = (TextAlignmentOptions)4097; ((TMP_Text)component).enableWordWrapping = true; LayoutElement component2 = val.GetComponent(); component2.preferredWidth = width; component2.flexibleWidth = 1f; return component; } private Transform CreateRow(Transform parent, float height) { //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0048: 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_0061: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("Row", new Type[3] { typeof(RectTransform), typeof(HorizontalLayoutGroup), typeof(LayoutElement) }) { layer = root.layer }; val.transform.SetParent(parent, false); val.GetComponent().preferredHeight = height; HorizontalLayoutGroup component = val.GetComponent(); ((HorizontalOrVerticalLayoutGroup)component).spacing = 8f; ((LayoutGroup)component).childAlignment = (TextAnchor)3; ((HorizontalOrVerticalLayoutGroup)component).childControlWidth = true; ((HorizontalOrVerticalLayoutGroup)component).childControlHeight = true; ((HorizontalOrVerticalLayoutGroup)component).childForceExpandWidth = false; ((HorizontalOrVerticalLayoutGroup)component).childForceExpandHeight = true; return val.transform; } private static void AddTooltip(GameObject target, PantheonLoadoutOption option) { //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_016f: Unknown result type (might be due to invalid IL or missing references) //IL_010b: Unknown result type (might be due to invalid IL or missing references) //IL_0110: Unknown result type (might be due to invalid IL or missing references) //IL_0115: 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_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_011a: Unknown result type (might be due to invalid IL or missing references) //IL_018e: Unknown result type (might be due to invalid IL or missing references) //IL_0193: Unknown result type (might be due to invalid IL or missing references) //IL_0198: Unknown result type (might be due to invalid IL or missing references) //IL_0185: Unknown result type (might be due to invalid IL or missing references) //IL_019d: Unknown result type (might be due to invalid IL or missing references) TooltipProvider val = target.GetComponent() ?? target.AddComponent(); val.overrideTitleText = string.Empty; val.overrideBodyText = string.Empty; val.AllowTooltipOnNavigationSelect = true; val.disableTitleRichText = false; val.disableBodyRichText = false; if (option.IsDrone) { DroneDef droneDef = DroneCatalog.GetDroneDef((DroneIndex)option.DefinitionIndex); val.titleToken = droneDef?.nameToken ?? string.Empty; val.bodyToken = droneDef?.descriptionToken ?? string.Empty; val.titleColor = (Object.op_Implicit((Object)(object)droneDef) ? Color32.op_Implicit(ColorCatalog.GetColor(droneDef.color)) : Color.white); } else if (option.IsEquipment) { EquipmentDef equipmentDef = EquipmentCatalog.GetEquipmentDef((EquipmentIndex)option.DefinitionIndex); val.titleToken = equipmentDef?.nameToken ?? string.Empty; val.bodyToken = equipmentDef?.descriptionToken ?? string.Empty; val.titleColor = (Object.op_Implicit((Object)(object)equipmentDef) ? Color32.op_Implicit(ColorCatalog.GetColor(equipmentDef.colorIndex)) : Color.white); } else { ItemDef itemDef = ItemCatalog.GetItemDef((ItemIndex)option.DefinitionIndex); val.titleToken = itemDef?.nameToken ?? string.Empty; val.bodyToken = itemDef?.descriptionToken ?? string.Empty; ItemTierDef val2 = (Object.op_Implicit((Object)(object)itemDef) ? ItemTierCatalog.GetItemTierDef(itemDef.tier) : null); val.titleColor = (Object.op_Implicit((Object)(object)val2) ? Color32.op_Implicit(ColorCatalog.GetColor(val2.colorIndex)) : Color.white); } } private static void Stretch(RectTransform rect) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0017: 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) rect.anchorMin = Vector2.zero; rect.anchorMax = Vector2.one; rect.offsetMin = Vector2.zero; rect.offsetMax = Vector2.zero; } } internal sealed class PantheonLoadoutRightClick : MonoBehaviour, IPointerClickHandler, IEventSystemHandler { private PantheonLoadoutOption option; internal void Configure(PantheonLoadoutOption configuredOption) { option = configuredOption; } public void OnPointerClick(PointerEventData eventData) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Invalid comparison between Unknown and I4 if ((int)eventData.button == 1) { PantheonLoadoutManager.RequestChange(option, -1); } } } internal enum PantheonGameVariant : byte { Attunement, Elite, Radiance, EliteRadiance } internal static class PantheonGameVariantRules { internal static bool UsesRadiance(this PantheonGameVariant variant) { if (variant - 2 <= PantheonGameVariant.Elite) { return true; } return false; } internal static bool UsesElites(this PantheonGameVariant variant) { if (variant == PantheonGameVariant.Elite || variant == PantheonGameVariant.EliteRadiance) { return true; } return false; } internal static string GetDisplayName(this PantheonGameVariant variant) { return variant switch { PantheonGameVariant.Elite => "精英", PantheonGameVariant.Radiance => "辐辉", PantheonGameVariant.EliteRadiance => "精英辐辉", _ => "调谐", }; } } internal static class PantheonLobbyUI { [CompilerGenerated] private static class <>O { public static UnityAction <0>__SceneManagerSceneLoaded; public static hook_OnEnter <1>__BaseMainMenuScreenOnEnter; } private static bool installed; private static bool pantheonContextActive; internal static PantheonGameVariant SelectedGameVariant { get; private set; } internal static void Install() { //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Expected O, but got Unknown if (!installed) { installed = true; SceneManager.sceneLoaded += SceneManagerSceneLoaded; object obj = <>O.<1>__BaseMainMenuScreenOnEnter; if (obj == null) { hook_OnEnter val = BaseMainMenuScreenOnEnter; <>O.<1>__BaseMainMenuScreenOnEnter = val; obj = (object)val; } BaseMainMenuScreen.OnEnter += (hook_OnEnter)obj; } } internal static void Uninstall() { //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Expected O, but got Unknown if (installed) { installed = false; SceneManager.sceneLoaded -= SceneManagerSceneLoaded; object obj = <>O.<1>__BaseMainMenuScreenOnEnter; if (obj == null) { hook_OnEnter val = BaseMainMenuScreenOnEnter; <>O.<1>__BaseMainMenuScreenOnEnter = val; obj = (object)val; } BaseMainMenuScreen.OnEnter -= (hook_OnEnter)obj; pantheonContextActive = false; } } internal static void OpenPantheonScene() { pantheonContextActive = true; Console.instance.SubmitCmd((NetworkUser)null, "transition_command \"set_scene eclipseworld\"", false); } internal static void BeginLaunch(SurvivorDef survivor, PantheonGameVariant gameVariant) { LocalUser firstLocalUser = LocalUserManager.GetFirstLocalUser(); if (firstLocalUser != null) { UserProfile userProfile = firstLocalUser.userProfile; if (userProfile != null) { userProfile.SetSurvivorPreference(survivor); } } SelectedGameVariant = gameVariant; Console.instance.SubmitCmd((NetworkUser)null, "transition_command \"gamemode ResonatorsPantheonRun; host 0;\"", false); } private static void BaseMainMenuScreenOnEnter(orig_OnEnter orig, BaseMainMenuScreen self, MainMenuController mainMenuController) { orig.Invoke(self, mainMenuController); if (Object.op_Implicit((Object)(object)mainMenuController) && (Object)(object)self == (Object)(object)mainMenuController.extraGameModeMenuScreen && !Object.op_Implicit((Object)(object)((Component)self).GetComponent())) { ((Component)self).gameObject.AddComponent(); } } private static void SceneManagerSceneLoaded(Scene scene, LoadSceneMode loadSceneMode) { //IL_003c: Unknown result type (might be due to invalid IL or missing references) if (string.Equals(((Scene)(ref scene)).name, "title", StringComparison.OrdinalIgnoreCase)) { pantheonContextActive = false; } else if (pantheonContextActive && string.Equals(((Scene)(ref scene)).name, "eclipseworld", StringComparison.OrdinalIgnoreCase)) { ((MonoBehaviour)RoR2Application.instance).StartCoroutine(InitializePantheonScene(scene)); } } private static IEnumerator InitializePantheonScene(Scene scene) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) for (int frame = 0; frame < 120; frame++) { GameObject[] rootGameObjects = ((Scene)(ref scene)).GetRootGameObjects(); for (int i = 0; i < rootGameObjects.Length; i++) { EclipseRunScreenController componentInChildren = rootGameObjects[i].GetComponentInChildren(true); if (Object.op_Implicit((Object)(object)componentInChildren)) { (((Component)componentInChildren).GetComponent() ?? ((Component)componentInChildren).gameObject.AddComponent()).InitializeScene(componentInChildren); yield break; } } yield return null; } PantheonModule.Log.LogError((object)"Pantheon entered eclipseworld, but the Eclipse menu controller was not found."); } } internal static class PantheonCompletionRecords { private const string ConfigSection = "Pantheon Completion Records"; internal static bool IsCompleted(UserProfile? profile, SurvivorDef? survivor, PantheonGameVariant gameVariant) { if (profile == null || survivor == null || !Object.op_Implicit((Object)(object)survivor)) { return false; } return GetEntry(profile, survivor, gameVariant).Value; } internal static void MarkCurrentSurvivorCompleted(PantheonGameVariant gameVariant) { LocalUser firstLocalUser = LocalUserManager.GetFirstLocalUser(); UserProfile val = ((firstLocalUser != null) ? firstLocalUser.userProfile : null); SurvivorDef val2 = ((val != null) ? val.GetSurvivorPreference() : null); if (val != null && val2 != null && Object.op_Implicit((Object)(object)val2)) { ConfigEntry entry = GetEntry(val, val2, gameVariant); if (!entry.Value) { entry.Value = true; PantheonModule.Owner.Config.Save(); PantheonModule.Log.LogInfo((object)($"Recorded Pantheon of Gold ({gameVariant}) completion for " + $"{val2.cachedName} in profile {val.saveID}.")); } } } private static ConfigEntry GetEntry(UserProfile profile, SurvivorDef survivor, PantheonGameVariant gameVariant) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) string value = (string.IsNullOrWhiteSpace(survivor.cachedName) ? ((object)survivor.survivorIndex/*cast due to .constrained prefix*/).ToString() : survivor.cachedName); string arg = gameVariant switch { PantheonGameVariant.Elite => ".Elite", PantheonGameVariant.Radiance => ".Radiance", PantheonGameVariant.EliteRadiance => ".EliteRadiance", _ => string.Empty, }; string text = $"{profile.saveID:X16}.{Sanitize(value)}.PantheonOfGold{arg}"; return PantheonModule.Owner.Config.Bind("Pantheon Completion Records", text, false, $"Whether this profile has completed Pantheon of Gold ({gameVariant}) with this survivor."); } private static string Sanitize(string value) { return new string(value.Select((char character) => (!char.IsLetterOrDigit(character)) ? '_' : character).ToArray()); } } internal sealed class PantheonMenuInjector : MonoBehaviour { private IEnumerator Start() { while (Object.op_Implicit((Object)(object)this)) { MPButton val = FindPantheonButton(); if (Object.op_Implicit((Object)(object)val)) { ((Component)this).gameObject.AddComponent().Initialize(val); break; } yield return null; } } private MPButton? FindPantheonButton() { string b = Language.GetString("RESONATORS_PANTHEON_NAME"); MPButton[] componentsInChildren = ((Component)this).GetComponentsInChildren(true); foreach (MPButton val in componentsInChildren) { TMP_Text componentInChildren = ((Component)val).GetComponentInChildren(true); LanguageTextMeshController val2 = (Object.op_Implicit((Object)(object)componentInChildren) ? ((Component)componentInChildren).GetComponent() : null); if ((Object.op_Implicit((Object)(object)val2) && val2.token == "RESONATORS_PANTHEON_NAME") || (Object.op_Implicit((Object)(object)componentInChildren) && string.Equals(componentInChildren.text, b, StringComparison.Ordinal))) { return val; } } return null; } } internal sealed class PantheonFrontMenu : MonoBehaviour { [CompilerGenerated] private static class <>O { public static UnityAction <0>__OpenPantheonScene; } private const string CarouselAddress = "RoR2/Base/UI/SettingsEntryButton, Carousel.prefab"; private GameObject overlay; private EclipseRunScreenController eclipseController; private CharacterSelectBarController survivorBar; private MPButton beginButton; private TMP_Text pantheonValue; private TMP_Text gameVariantValue; private HGTextMeshProUGUI gameVariantDescription; private bool sceneInitialized; private bool challengeSelected; private PantheonGameVariant selectedGameVariant; internal void Initialize(MPButton pantheonButton) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Expected O, but got Unknown //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Expected O, but got Unknown ((Button)pantheonButton).onClick = new ButtonClickedEvent(); ButtonClickedEvent onClick = ((Button)pantheonButton).onClick; object obj = <>O.<0>__OpenPantheonScene; if (obj == null) { UnityAction val = PantheonLobbyUI.OpenPantheonScene; <>O.<0>__OpenPantheonScene = val; obj = (object)val; } ((UnityEvent)onClick).AddListener((UnityAction)obj); } internal void InitializeScene(EclipseRunScreenController controller) { if (sceneInitialized) { return; } sceneInitialized = true; overlay = ((Component)controller).gameObject; eclipseController = controller; survivorBar = overlay.GetComponentInChildren(true); if (!Object.op_Implicit((Object)(object)survivorBar)) { throw new InvalidOperationException("The Eclipse scene is missing its survivor controller."); } ((Behaviour)eclipseController).enabled = false; HGGamepadInputEvent[] componentsInChildren = overlay.GetComponentsInChildren(true); foreach (HGGamepadInputEvent val in componentsInChildren) { if (val.actionName == "UISubmitAlt") { ((Behaviour)val).enabled = false; } } ((UnityEvent)(object)survivorBar.onSurvivorPicked).AddListener((UnityAction)OnSurvivorPicked); UserProfile.onSurvivorPreferenceChangedGlobal += OnSurvivorPreferenceChanged; ReplaceEclipseLabels(); PatchNavigationButtons(); PrepareRecordMedal(); CreatePantheonSelector(); challengeSelected = true; RefreshScreen(); PantheonModule.Log.LogDebug((object)"Pantheon initialized inside the vanilla eclipseworld scene."); } private void OnDestroy() { if (sceneInitialized) { UserProfile.onSurvivorPreferenceChangedGlobal -= OnSurvivorPreferenceChanged; if (Object.op_Implicit((Object)(object)survivorBar)) { ((UnityEvent)(object)survivorBar.onSurvivorPicked).RemoveListener((UnityAction)OnSurvivorPicked); } } } private void ReplaceEclipseLabels() { LanguageTextMeshController[] componentsInChildren = overlay.GetComponentsInChildren(true); foreach (LanguageTextMeshController val in componentsInChildren) { string text = val.token switch { "TITLE_ECLIPSE" => "万神殿", "TITLE_ECLIPSE_DESC" => "连续挑战首领,并在每场战斗前重新配置装备。", "ECLIPSE_GAMEMODE_DESCRIPTION" => "选择万神殿、游戏模式与幸存者,完成连续首领挑战。", "ECLIPSE_GAMEMODE_START" => "开始", _ => string.Empty, }; if (text.Length > 0) { SetDirectText(val, text); } } string b = Language.GetString("TITLE_ECLIPSE"); TMP_Text[] componentsInChildren2 = overlay.GetComponentsInChildren(true); foreach (TMP_Text val2 in componentsInChildren2) { string a = val2.text?.Trim() ?? string.Empty; if (string.Equals(a, b, StringComparison.Ordinal) || string.Equals(a, "日食", StringComparison.Ordinal) || string.Equals(a, "Eclipse", StringComparison.OrdinalIgnoreCase)) { LanguageTextMeshController component = ((Component)val2).GetComponent(); if (Object.op_Implicit((Object)(object)component)) { ((Behaviour)component).enabled = false; } val2.text = "万神殿"; } } } private void PatchNavigationButtons() { //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Expected O, but got Unknown //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Expected O, but got Unknown //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Expected O, but got Unknown MPButton val = null; MPButton[] componentsInChildren = overlay.GetComponentsInChildren(true); foreach (MPButton val2 in componentsInChildren) { bool flag = false; for (int j = 0; j < ((UnityEventBase)((Button)val2).onClick).GetPersistentEventCount(); j++) { if (((UnityEventBase)((Button)val2).onClick).GetPersistentTarget(j) == (Object)(object)eclipseController && ((UnityEventBase)((Button)val2).onClick).GetPersistentMethodName(j) == "BeginGamemode") { flag = true; break; } } bool flag2 = GetButtonLanguageToken(val2) == "ECLIPSE_GAMEMODE_START"; if (flag && flag2) { val = val2; ((Button)val2).onClick = new ButtonClickedEvent(); ((UnityEvent)((Button)val2).onClick).AddListener(new UnityAction(Begin)); SetButtonText(val2, "开始"); } else if (flag) { ((Button)val2).onClick = new ButtonClickedEvent(); ((Selectable)val2).interactable = false; ((Component)val2).gameObject.SetActive(false); } } if (!Object.op_Implicit((Object)(object)val)) { throw new InvalidOperationException("The Eclipse menu start button could not be identified."); } beginButton = val; } private void PrepareRecordMedal() { EclipseDifficultyMedalDisplay[] componentsInChildren = overlay.GetComponentsInChildren(true); if (componentsInChildren.Length != 0) { for (int i = 0; i < componentsInChildren.Length; i++) { ((Component)componentsInChildren[i]).gameObject.SetActive(false); } } } private void CreatePantheonSelector() { //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Expected O, but got Unknown //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_007b: 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_0090: 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_009b: 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_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Expected O, but got Unknown //IL_014f: Unknown result type (might be due to invalid IL or missing references) //IL_01d9: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("PantheonSelector", new Type[2] { typeof(RectTransform), typeof(VerticalLayoutGroup) }); val.SetActive(false); val.layer = overlay.layer; val.transform.SetParent(overlay.transform, false); val.transform.SetAsLastSibling(); RectTransform val2 = (RectTransform)val.transform; val2.anchorMin = new Vector2(0.028f, 0.22f); val2.anchorMax = new Vector2(0.245f, 0.54f); val2.offsetMin = Vector2.zero; val2.offsetMax = Vector2.zero; VerticalLayoutGroup component = val.GetComponent(); ((LayoutGroup)component).padding = new RectOffset(0, 0, 0, 0); ((HorizontalOrVerticalLayoutGroup)component).spacing = 8f; ((LayoutGroup)component).childAlignment = (TextAnchor)1; ((HorizontalOrVerticalLayoutGroup)component).childControlWidth = true; ((HorizontalOrVerticalLayoutGroup)component).childControlHeight = true; ((HorizontalOrVerticalLayoutGroup)component).childForceExpandWidth = true; ((HorizontalOrVerticalLayoutGroup)component).childForceExpandHeight = false; pantheonValue = CreateCarouselRow(val.transform, "万神殿", 52f, null, null); pantheonValue.text = "黄金万神殿"; ((Graphic)CreateText(val.transform, "六场首领战\n角色等级 5 · 暴雨\n配装点数 14 / 18", 14f, (FontStyles)0, 74f)).color = new Color(0.72f, 0.77f, 0.8f, 1f); gameVariantValue = CreateCarouselRow(val.transform, "游戏模式", 52f, SelectPreviousGameVariant, SelectNextGameVariant); gameVariantDescription = CreateText(val.transform, string.Empty, 14f, (FontStyles)0, 32f); ((TMP_Text)gameVariantDescription).alignment = (TextAlignmentOptions)258; ((Graphic)gameVariantDescription).color = new Color(0.72f, 0.77f, 0.8f, 1f); RefreshGameVariant(); val.SetActive(true); } private void SelectPreviousGameVariant() { ChangeGameVariant(-1); } private void SelectNextGameVariant() { ChangeGameVariant(1); } private void ChangeGameVariant(int direction) { selectedGameVariant = (PantheonGameVariant)(((int)selectedGameVariant + direction + 4) % 4); RefreshGameVariant(); RefreshSurvivorRecord(); } private void RefreshGameVariant() { if (Object.op_Implicit((Object)(object)gameVariantValue)) { gameVariantValue.text = selectedGameVariant.GetDisplayName(); } if (Object.op_Implicit((Object)(object)gameVariantDescription)) { HGTextMeshProUGUI val = gameVariantDescription; ((TMP_Text)val).text = selectedGameVariant switch { PantheonGameVariant.Elite => "首领与随从获得指定精英状态", PantheonGameVariant.Radiance => "启用辐辉神器", PantheonGameVariant.EliteRadiance => "精英规则并启用辐辉神器", _ => "标准万神殿规则", }; } } private void OnSurvivorPicked(SurvivorPickInfo pick) { //IL_0000: 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_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) if (pick.localUser != null && Object.op_Implicit((Object)(object)pick.pickedSurvivor)) { pick.localUser.userProfile.SetSurvivorPreference(pick.pickedSurvivor); } RefreshSurvivorRecord(); } private void OnSurvivorPreferenceChanged(UserProfile profile) { if (Object.op_Implicit((Object)(object)overlay) && overlay.activeSelf) { RefreshSurvivorRecord(); } } private void RefreshSurvivorRecord() { LocalUser firstLocalUser = LocalUserManager.GetFirstLocalUser(); object obj; if (firstLocalUser == null) { obj = null; } else { UserProfile userProfile = firstLocalUser.userProfile; obj = ((userProfile != null) ? userProfile.GetSurvivorPreference() : null); } SurvivorDef val = (SurvivorDef)obj; bool flag = Object.op_Implicit((Object)(object)val) && ((firstLocalUser != null) ? firstLocalUser.userProfile : null) != null; bool flag2 = flag && PantheonCompletionRecords.IsCompleted(firstLocalUser.userProfile, val, selectedGameVariant); if (Object.op_Implicit((Object)(object)eclipseController)) { SetDirectText(eclipseController.survivorName, flag ? Language.GetString(val.displayNameToken) : string.Empty); SetDirectText(eclipseController.eclipseDifficultyName, "黄金万神殿 · " + selectedGameVariant.GetDisplayName()); SetDirectText(eclipseController.eclipseDifficultyDescription, flag2 ? "完成记录:已完成" : "完成记录:未完成"); } if (Object.op_Implicit((Object)(object)beginButton)) { ((Selectable)beginButton).interactable = challengeSelected && flag; } } private void Begin() { LocalUser firstLocalUser = LocalUserManager.GetFirstLocalUser(); object obj; if (firstLocalUser == null) { obj = null; } else { UserProfile userProfile = firstLocalUser.userProfile; obj = ((userProfile != null) ? userProfile.GetSurvivorPreference() : null); } SurvivorDef val = (SurvivorDef)obj; if (challengeSelected && Object.op_Implicit((Object)(object)val)) { ((Selectable)beginButton).interactable = false; PantheonLobbyUI.BeginLaunch(val, selectedGameVariant); } } private TMP_Text CreateCarouselRow(Transform parent, string headingText, float height, Action? onPrevious, Action? onNext) { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0107: Unknown result type (might be due to invalid IL or missing references) //IL_0111: Expected O, but got Unknown //IL_0192: Unknown result type (might be due to invalid IL or missing references) //IL_019c: Expected O, but got Unknown //IL_01c0: Unknown result type (might be due to invalid IL or missing references) //IL_01ce: Unknown result type (might be due to invalid IL or missing references) //IL_01d9: Unknown result type (might be due to invalid IL or missing references) //IL_01e7: Unknown result type (might be due to invalid IL or missing references) //IL_01b2: Unknown result type (might be due to invalid IL or missing references) //IL_01bc: Expected O, but got Unknown GameObject obj = Addressables.LoadAssetAsync((object)"RoR2/Base/UI/SettingsEntryButton, Carousel.prefab").WaitForCompletion(); if (!Object.op_Implicit((Object)(object)obj)) { throw new InvalidOperationException("The vanilla carousel prefab is unavailable."); } GameObject val = Object.Instantiate(obj, parent, false); ((Object)val).name = "PantheonCarousel_" + headingText; val.layer = overlay.layer; LanguageTextMeshController[] componentsInChildren = val.GetComponentsInChildren(true); for (int i = 0; i < componentsInChildren.Length; i++) { ((Behaviour)componentsInChildren[i]).enabled = false; } CarouselController componentInChildren = val.GetComponentInChildren(true); if (!Object.op_Implicit((Object)(object)componentInChildren) || !Object.op_Implicit((Object)(object)componentInChildren.leftArrowButton) || !Object.op_Implicit((Object)(object)componentInChildren.rightArrowButton)) { Object.Destroy((Object)(object)val); throw new InvalidOperationException("The vanilla carousel is missing its arrow controls."); } ((Behaviour)componentInChildren).enabled = false; Transform val2 = FindDescendant(val.transform, "BoolButton"); if (Object.op_Implicit((Object)(object)val2)) { ((Component)val2).gameObject.SetActive(false); } Button[] componentsInChildren2 = val.GetComponentsInChildren