Decompiled source of LBOLMP v0.8.9
LBOLMP.dll
Decompiled 21 hours ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Concurrent; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.Linq; using System.Net; using System.Net.Sockets; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using System.Threading; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using Cysharp.Threading.Tasks; using Cysharp.Threading.Tasks.CompilerServices; using HarmonyLib; using LBOLMP.Entities; using LBOLMP.Net; using LBOLMP.Patches; using LBOLMP.Session; using LBOLMP.Session.Battle; using LBOLMP.Session.Messages; using LBOLMP.UI; using LBoL.Base; using LBoL.ConfigData; using LBoL.Core; using LBoL.Core.Adventures; using LBoL.Core.Battle; using LBoL.Core.Battle.BattleActions; using LBoL.Core.Cards; using LBoL.Core.Dialogs; using LBoL.Core.PlatformHandlers; using LBoL.Core.SaveData; using LBoL.Core.Stations; using LBoL.Core.StatusEffects; using LBoL.Core.Units; using LBoL.EntityLib.Adventures.FirstPlace; using LBoL.EntityLib.Cards.Misfortune; using LBoL.EntityLib.EnemyUnits.Character; using LBoL.EntityLib.Exhibits.Adventure; using LBoL.EntityLib.Stages.NormalStages; using LBoL.EntityLib.StatusEffects.Cirno; using LBoL.EntityLib.StatusEffects.Enemy; using LBoL.EntityLib.StatusEffects.Neutral.TwoColor; using LBoL.Presentation; using LBoL.Presentation.UI; using LBoL.Presentation.UI.ExtraWidgets; using LBoL.Presentation.UI.Panels; using LBoL.Presentation.UI.Widgets; using LBoL.Presentation.Units; using LBoLEntitySideloader; using LBoLEntitySideloader.Attributes; using LBoLEntitySideloader.Entities; using LBoLEntitySideloader.Resource; using Microsoft.CodeAnalysis; using Steamworks; using UnityEngine; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: IgnoresAccessChecksTo("LBoL.Base")] [assembly: IgnoresAccessChecksTo("LBoL.ConfigData")] [assembly: IgnoresAccessChecksTo("LBoL.Core")] [assembly: IgnoresAccessChecksTo("LBoL.EntityLib")] [assembly: IgnoresAccessChecksTo("LBoL.Presentation")] [assembly: IgnoresAccessChecksTo("Untitled.ConfigDataBuilder.Base")] [assembly: AssemblyCompany("LBOLMP")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("0.8.9.0")] [assembly: AssemblyInformationalVersion("0.8.9+e55d67b57f461bca56ebe2e38d779c1eede32587")] [assembly: AssemblyProduct("LBOLMP")] [assembly: AssemblyTitle("LBOLMP")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("0.8.9.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace LBOLMP { public static class L10n { private const string Marker = "mp:"; private const char Separator = '|'; private const char Escape = '\\'; public static Locale Current { get { //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_000a: 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_000f: Invalid comparison between Unknown and I4 //IL_0019: 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_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Invalid comparison between Unknown and I4 Locale currentLocale; try { currentLocale = Localization.CurrentLocale; } catch { return (Locale)0; } if ((int)currentLocale != 1 && (int)currentLocale != 2) { return (Locale)0; } return currentLocale; } } public static string Get(MpText key) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) return Format(Lookup(key, Current), null); } public static string Get(MpText key, params object[] args) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) return Format(Lookup(key, Current), args); } private static string Get(MpText key, Locale locale, object[] args) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) return Format(Lookup(key, locale), args); } public static string En(MpText key) { return Format(Lookup(key, (Locale)0), null); } public static string En(MpText key, params object[] args) { return Format(Lookup(key, (Locale)0), args); } public static string Encode(MpText key, params object[] args) { StringBuilder stringBuilder = new StringBuilder("mp:").Append(key.ToString()); if (args != null) { foreach (object obj in args) { stringBuilder.Append('|').Append(EscapeArg(Convert.ToString(obj, CultureInfo.InvariantCulture))); } } return stringBuilder.ToString(); } public static string Decode(string text) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) return Decode(text, Current); } public static string DecodeEn(string text) { return Decode(text, (Locale)0); } private static string Decode(string text, Locale locale) { //IL_007d: Unknown result type (might be due to invalid IL or missing references) if (string.IsNullOrEmpty(text) || !text.StartsWith("mp:", StringComparison.Ordinal)) { return text ?? string.Empty; } List<string> list = SplitArgs(text.Substring("mp:".Length)); if (list.Count == 0 || !Enum.TryParse<MpText>(list[0], out var result)) { return text; } object[] array = new object[list.Count - 1]; for (int i = 1; i < list.Count; i++) { array[i - 1] = list[i]; } return Get(result, locale, array); } private static string Lookup(MpText key, Locale locale) { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Invalid comparison between Unknown and I4 //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Invalid comparison between Unknown and I4 //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Invalid comparison between Unknown and I4 if (!MpStrings.Table.TryGetValue(key, out var value)) { return key.ToString(); } if ((int)locale == 2 && !string.IsNullOrWhiteSpace(value.ZhHant)) { return value.ZhHant; } if (((int)locale == 1 || (int)locale == 2) && !string.IsNullOrWhiteSpace(value.ZhHans)) { return value.ZhHans; } if (!string.IsNullOrEmpty(value.En)) { return value.En; } return key.ToString(); } private static string Format(string pattern, object[] args) { if (args == null || args.Length == 0) { return pattern; } try { return string.Format(CultureInfo.InvariantCulture, pattern, args); } catch (FormatException) { ManualLogSource log = MpPlugin.Log; if (log != null) { log.LogWarning((object)("Malformed localised text: '" + pattern + "'")); } return pattern; } } private static string EscapeArg(string value) { if (string.IsNullOrEmpty(value)) { return string.Empty; } return value.Replace('\\'.ToString(), "\\\\").Replace('|'.ToString(), "\\|"); } private static List<string> SplitArgs(string body) { List<string> list = new List<string>(); StringBuilder stringBuilder = new StringBuilder(); bool flag = false; foreach (char c in body) { if (flag) { stringBuilder.Append(c); flag = false; continue; } switch (c) { case '\\': flag = true; break; case '|': list.Add(stringBuilder.ToString()); stringBuilder.Length = 0; break; default: stringBuilder.Append(c); break; } } list.Add(stringBuilder.ToString()); return list; } internal static void Verify() { List<string> list = new List<string>(); foreach (MpText value in Enum.GetValues(typeof(MpText))) { if (!MpStrings.Table.ContainsKey(value)) { list.Add(value.ToString()); } } if (list.Count > 0) { MpPlugin.Log.LogWarning((object)string.Format("{0} text key(s) have no entry in MpStrings: {1}", list.Count, string.Join(", ", list))); } } } public enum MpText { LobbyWindowTitle, LobbyNotConnected, LobbyYourName, LobbyDirectConnection, LobbyPort, LobbyHostSession, LobbyHostAddress, LobbyJoinSession, LobbyPortNotANumber, LobbyOfflineHelp, LobbySteam, LobbySteamUnavailable, LobbyHostOverSteam, LobbySteamHelp, LobbyHosting, LobbyConnected, LobbyHostingDirectIp, LobbyHostingSteam, LobbyConnectedDirectIp, LobbyConnectedSteam, LobbyInviteFriends, LobbyTagHost, LobbyTagYou, LobbyChoosing, LobbyPlayerRow, LobbyLockedIn, LobbySeed, LobbyMapVoteHint, LobbyLeaveSession, LobbyBalanceSettings, SettingsWindowTitle, SettingsIntro, SettingsHostNote, SettingsNextRunNote, SettingsLockedForThisRun, SettingsDefault, SettingsResetAll, SettingsClose, SettingsNothingToShow, SettingEnemyHpScaleName, SettingEnemyHpScaleHelp, SettingEscalationName, SettingEscalationHelp, SettingReviveHpName, SettingReviveHpHelp, SettingResilienceName, SettingResilienceHelp, HudParty, HudPlayerRow, HudVoteNode, HudVoteStillChoosing, StateInLobby, StateReady, StateResuming, StateHp, StateDisconnected, BoardDefeated, BoardSittingOut, BoardWaitingForOne, BoardWaitingForOneToFinish, BoardWaitingForMany, BoardLostContact, BoardBlock, BoardShield, ActivitySpectating, ActivityDownSpectating, ActivityDone, ActivityDown, ActivityTurnOver, ActivityHand, EmoteNice, EmoteNegative, EmoteHurryUp, MapWaitingForOne, MapWaitingForMany, MapMovingToNode, MapPartySplit, MapPick, MapHeadingTo, RestartPartyMoving, InspectBanner, InspectZoneTitle, StatusHostFailed, StatusHostingOnPort, StatusHostSteamFailed, StatusOpeningSteamLobby, StatusHostingOverSteam, StatusConnecting, StatusConnectFailed, StatusAlreadyInSession, StatusConnectingSteam, StatusConnectSteamFailed, StatusConnectedAsPlayer, StatusRejected, StatusWaitingForPlayers, StatusWaitingForNames, StatusWaitingToResume, StatusRunStarted, StatusRunResumed, StatusBackInLobby, NoticeResumeStaggered, StatusPlayerLeft, StatusDisconnected, StatusSteamLobbyFailed, StatusSteamJoinFailed, ReasonProtocolMismatch, ReasonRunInProgress, ReasonStartSplit, ReasonResumeDifferentRuns, ReasonSessionFull, ReasonYouLeft, ReasonRemoteClosed, ReasonConnectionFailed, ReasonSteamClosed, ReasonReadFailed, ReasonWriteFailed, ReasonSendFailed, ReasonTimedOut, ErrorSteamUnavailable, ErrorSteamListenFailed, ErrorSteamConnectFailed } internal readonly struct MpPhrase { internal readonly string En; internal readonly string ZhHans; internal readonly string ZhHant; internal MpPhrase(string en, string zhHans, string zhHant) { En = en; ZhHans = zhHans; ZhHant = zhHant; } } internal static class MpStrings { internal static readonly Dictionary<MpText, MpPhrase> Table = new Dictionary<MpText, MpPhrase> { [MpText.LobbyWindowTitle] = P("LBOL MP v{0}", "LBOL MP v{0}", "LBOL MP v{0}"), [MpText.LobbyNotConnected] = P("Not connected", "未连接", "未連接"), [MpText.LobbyYourName] = P("Your name", "你的名字", "你的名字"), [MpText.LobbyDirectConnection] = P("Direct connection", "直接连接", "直接連接"), [MpText.LobbyPort] = P("Port", "端口", "端口"), [MpText.LobbyHostSession] = P("Host session", "创建房间", "建立房間"), [MpText.LobbyHostAddress] = P("Host address", "房主 IP 地址", "房主 IP 位址"), [MpText.LobbyJoinSession] = P("Join session", "加入房间", "加入房間"), [MpText.LobbyPortNotANumber] = P("Port is not a number", "端口必须是数字", "端口必須是數字"), [MpText.LobbyOfflineHelp] = P("Host should host a session, have everyone else join, then all of you pick a character on the Start Game screen. The run begins once everybody has confirmed.", "由房主建立房间,其他人加入,然后所有人在正常的开始游戏画面选择角色。所有人确认后开始游戏。", "由房主建立房間,其他人加入,然後所有人在正常的開始遊戲畫面選擇角色。所有人確認後開始遊戲。"), [MpText.LobbySteam] = P("Steam", "Steam", "Steam"), [MpText.LobbySteamUnavailable] = P("Steam is currently not available, only direct IP connections can be used.", "当前无法使用 Steam,只能使用直接 IP 连接。", "目前無法使用 Steam,只能使用直接 IP 連接。"), [MpText.LobbyHostOverSteam] = P("Host over Steam", "通过 Steam 创建房间", "通過 Steam 建立房間"), [MpText.LobbySteamHelp] = P("Once the session is hosted, invite friends from the Steam overlay. To join someone else, accept their invite or join via Steam.", "创建房间后,可从 Steam 介面邀请好友。请接受对方的邀请以加入房间,或通过 Steam 加入房间。", "建立房間後,可從 Steam 介面邀請好友。請接受對方的邀請以加入房間,或透過 Steam 加入房間。"), [MpText.LobbyHosting] = P("Hosting", "主持中", "主持中"), [MpText.LobbyConnected] = P("Connected", "已连接", "已連接"), [MpText.LobbyHostingDirectIp] = P("Hosting over direct IP, port {0}", "正在通过直接 IP 主持房间,端口 {0}", "正在透過直接 IP 主持房間,端口 {0}"), [MpText.LobbyHostingSteam] = P("Hosting over Steam", "正在通过 Steam 主持房间", "正在透過 Steam 主持房間"), [MpText.LobbyConnectedDirectIp] = P("Connected over direct IP to {0}:{1}", "已通过直接 IP 连接到 {0}:{1}", "已透過直接 IP 連接到 {0}:{1}"), [MpText.LobbyConnectedSteam] = P("Connected over Steam to {0}", "已通过 Steam 连接到房主 {0}", "已透過 Steam 連接到房主 {0}"), [MpText.LobbyInviteFriends] = P("Invite friends...", "邀请好友⋯⋯", "邀請好友⋯⋯"), [MpText.LobbyTagHost] = P(" [host]", " [房主]", " [房主]"), [MpText.LobbyTagYou] = P(" [you]", " [你]", " [你]"), [MpText.LobbyChoosing] = P("choosing...", "选择中⋯⋯", "選擇中⋯⋯"), [MpText.LobbyPlayerRow] = P("#{0} {1}{2} {3} {4}", "#{0} {1}{2} {3} {4}", "#{0} {1}{2} {3} {4}"), [MpText.LobbyLockedIn] = P("Locked in. Waiting for everyone else to confirm their character.", "已锁定。等待其他人确认角色。", "已鎖定。等待其他人確認角色。"), [MpText.LobbySeed] = P("Seed {0}", "种子 {0}", "種子 {0}"), [MpText.LobbyMapVoteHint] = P("Click a map node to vote for it. The party moves once everyone has voted for the same node.", "点击地图节点以投票。所有人投给同一个节点后,队伍才会前进。", "點擊地圖節點以投票。所有人投給同一個節點後,隊伍才會前進。"), [MpText.LobbyLeaveSession] = P("Leave session", "离开房间", "離開房間"), [MpText.LobbyBalanceSettings] = P("Balance settings...", "平衡性设定⋯⋯", "平衡性設定⋯⋯"), [MpText.SettingsWindowTitle] = P("Balance settings", "平衡性设定", "平衡性設定"), [MpText.SettingsIntro] = P("How much harder the game gets with more players.", "人数越多,游戏难度提升多少。", "人數越多,遊戲難度提升多少。"), [MpText.SettingsHostNote] = P("All of these are decided by the host. If you join someone else's session, theirs are used and yours are ignored.", "以下所有设定均由房主决定。加入别人的房间时仅使用房主的设定。", "以下所有設定均由房主決定。加入別人的房間時僅使用房主的設定。"), [MpText.SettingsNextRunNote] = P("Changes are saved straight away and apply from the next run onwards.", "修改会立即保存,并从下一局开始生效。", "修改會立即儲存,並從下一局開始生效。"), [MpText.SettingsLockedForThisRun] = P("A run is in progress, changes won't apply until the next run.", "当前有正在进行的游戏。本局沿用开始时的数值,此处的修改将在下一局生效。", "目前有正在進行的遊戲。本局沿用開始時的數值,此處的修改將在下一局生效。"), [MpText.SettingsDefault] = P("Default", "预设", "預設"), [MpText.SettingsResetAll] = P("Reset all to defaults", "全部恢复预设", "全部恢復預設"), [MpText.SettingsClose] = P("Close", "关闭", "關閉"), [MpText.SettingsNothingToShow] = P("No balance settings were found.", "未找到平衡性设定。", "未找到平衡性設定。"), [MpText.SettingEnemyHpScaleName] = P("Enemy health per extra player", "每位额外玩家的敌人生命值", "每位額外玩家的敵人生命值"), [MpText.SettingEnemyHpScaleHelp] = P("Extra max HP every enemy gets for each player beyond the first.", "除第一位玩家外,每多一位玩家,敌人最大生命值增加的比例。", "除第一位玩家外,每多一位玩家,敵人最大生命值增加的比例。"), [MpText.SettingEscalationName] = P("Act {0} escalation", "第 {0} 章额外加成", "第 {0} 章額外加成"), [MpText.SettingEscalationHelp] = P("Extra enemy max HP in this act, on top of the setting above. This stacks an additional time for each extra player, adding progressively more HP with more players. 0 turns it off for this act.", "本章中在上一项设定之外额外增加的敌人最大生命值,并且会叠加:每多一位玩家,加成都比前一位多一份。设为 0.1 时,第 2 位玩家增加 +10%,第 3 位再增加 +20%,第 4 位再增加 +30%。与上一项相加,而非相乘。设为 0 则本章不启用。", "本章中在上一項設定之外額外增加的敵人最大生命值,並且會疊加:每多一位玩家,加成都比前一位多一份。設為 0.1 時,第 2 位玩家增加 +10%,第 3 位再增加 +20%,第 4 位再增加 +30%。與上一項相加,而非相乘。設為 0 則本章不啟用。"), [MpText.SettingReviveHpName] = P("Revive health", "复活时的生命值", "復活時的生命值"), [MpText.SettingReviveHpHelp] = P("How much of their max health a defeated player comes back with when the party wins the fight. Between 0 and 1 (0%-100%). Players always revive with at least 1 HP.", "队伍获胜时,被击倒的玩家按最大生命值的多少比例复活。取值 0 到 1,且至少为 1 点生命。", "隊伍獲勝時,被擊倒的玩家按最大生命值的多少比例復活。取值 0 到 1,且至少為 1 點生命。"), [MpText.SettingResilienceName] = P("Enemies are Resilient", "敌人拥有「坚韧」", "敵人擁有「堅韌」"), [MpText.SettingResilienceHelp] = P("Give every enemy the Resilient status effect. For each extra player, enemies lose debuffs faster. Disable this to make debuffs decay as fast as in single player.", "让每个敌人获得「坚韧」状态。除第一位玩家外,每多一位玩家,敌人在回合结束时额外失去 1 层虚弱、易伤和锁定,并且获得的失去火力减少 1 点,但不低于 1 点。关闭后,减益效果与单人游戏时完全相同。", "讓每個敵人獲得「堅韌」狀態。除第一位玩家外,每多一位玩家,敵人在回合結束時額外失去 1 層虛弱、易傷和鎖定,並且獲得的失去火力減少 1 點,但不低於 1 點。關閉後,減益效果與單人遊戲時完全相同。"), [MpText.HudParty] = P("Party ({0})", "队伍 ({0})", "隊伍 ({0})"), [MpText.HudPlayerRow] = P("{0} {1}/{2}{3}", "{0} {1}/{2}{3}", "{0} {1}/{2}{3}"), [MpText.HudVoteNode] = P(" -> ({0},{1})", " -> ({0},{1})", " -> ({0},{1})"), [MpText.HudVoteStillChoosing] = P(" -> still choosing", " -> 仍在选择", " -> 仍在選擇"), [MpText.StateInLobby] = P("in lobby", "在房间中", "在房間中"), [MpText.StateReady] = P("ready", "已准备", "已準備"), [MpText.StateResuming] = P("ready to continue", "已准备继续", "已準備繼續"), [MpText.StateHp] = P("{0}/{1} HP", "{0}/{1} 生命", "{0}/{1} 生命"), [MpText.StateDisconnected] = P("disconnected", "已失去连接", "已失去連接"), [MpText.BoardDefeated] = P("You've been defeated. Wait for your partners to finish the combat.", "你已被击败。等待队友结束这场战斗。", "你已被擊敗。等待隊友結束這場戰鬥。"), [MpText.BoardSittingOut] = P("You're spectating this fight.", "你正在观战这场战斗。", "你正在觀戰這場戰鬥。"), [MpText.BoardWaitingForOne] = P("Waiting for {0} to finish their turn", "等待 {0} 结束回合", "等待 {0} 結束回合"), [MpText.BoardWaitingForOneToFinish] = P("Waiting for {0} to finish the fight", "等待 {0} 结束战斗", "等待 {0} 結束戰鬥"), [MpText.BoardWaitingForMany] = P("Waiting for {0}", "等待 {0}", "等待 {0}"), [MpText.BoardLostContact] = P("Connection with {0} lost. Continuing without them for now.", "连接已断开:{0}。 暂时先不等他们了。", "連接已中斷:{0}。 暫時先不等他們了。"), [MpText.BoardBlock] = P("BLK {0}", "格挡 {0}", "格擋 {0}"), [MpText.BoardShield] = P("SHD {0}", "护盾 {0}", "護盾 {0}"), [MpText.ActivitySpectating] = P("spectating", "观战中", "觀戰中"), [MpText.ActivityDownSpectating] = P("down, spectating", "已倒下,观战中", "已倒下,觀戰中"), [MpText.ActivityDone] = P("done", "已结束战斗", "已結束戰鬥"), [MpText.ActivityDown] = P("down", "已倒下", "已倒下"), [MpText.ActivityTurnOver] = P("turn over", "回合已结束", "回合已結束"), [MpText.ActivityHand] = P("hand {0}", "手牌 {0}", "手牌 {0}"), [MpText.EmoteNice] = P("Nice!", "漂亮!", "漂亮!"), [MpText.EmoteNegative] = P("...", "……", "……"), [MpText.EmoteHurryUp] = P("Any day now...", "快点吧……", "快點吧……"), [MpText.MapWaitingForOne] = P("Waiting for {0} to pick a node", "等待 {0} 选择节点", "等待 {0} 選擇節點"), [MpText.MapWaitingForMany] = P("Waiting for {0}", "等待 {0}", "等待 {0}"), [MpText.MapMovingToNode] = P("Moving to voted node", "正在前往投票选中的节点", "正在前往投票選中的節點"), [MpText.MapPartySplit] = P("Party is split: {0}", "队伍意见不一:{0}", "隊伍意見不一:{0}"), [MpText.MapPick] = P("{0} -> ({1},{2})", "{0} -> ({1},{2})", "{0} -> ({1},{2})"), [MpText.MapHeadingTo] = P("Heading to ({0}, {1})", "正在前往 ({0}, {1})", "正在前往 ({0}, {1})"), [MpText.RestartPartyMoving] = P("Can't restart while the party is moving to the next node. Try again once you arrive.", "队伍正在前往下一个节点,此时无法重来。抵达之后再试一次。", "隊伍正在前往下一個節點,此時無法重來。抵達之後再試一次。"), [MpText.InspectBanner] = P("Viewing {0}'s hand. Right-click or Esc to go back", "查看 {0} 的手牌中。按右键或 Esc 键以退回。", "查看 {0} 的手牌中。按右鍵或 Esc 鍵以退回。"), [MpText.InspectZoneTitle] = P("{0} - {1}", "{0} - {1}", "{0} - {1}"), [MpText.StatusHostFailed] = P("Could not host: {0}", "无法创建房间:{0}", "無法建立房間:{0}"), [MpText.StatusHostingOnPort] = P("Hosting on port {0}", "正在端口 {0} 上主持房间", "正在端口 {0} 上主持房間"), [MpText.StatusHostSteamFailed] = P("Could not host over Steam: {0}", "无法通过 Steam 创建房间:{0}", "無法透過 Steam 建立房間:{0}"), [MpText.StatusOpeningSteamLobby] = P("Opening a Steam lobby...", "正在创建 Steam 房间⋯⋯", "正在建立 Steam 房間⋯⋯"), [MpText.StatusHostingOverSteam] = P("Hosting over Steam. Invite friends from the overlay.", "正在通过 Steam 主持房间。可从 Steam 介面邀请好友。", "正在透過 Steam 主持房間。可從 Steam 介面邀請好友。"), [MpText.StatusConnecting] = P("Connecting...", "正在连接⋯⋯", "正在連接⋯⋯"), [MpText.StatusConnectFailed] = P("Could not connect: {0}", "无法连接:{0}", "無法連接:{0}"), [MpText.StatusAlreadyInSession] = P("Leave your current session before joining another", "加入其他房间前,请先离开当前房间", "加入其他房間前,請先離開當前房間"), [MpText.StatusConnectingSteam] = P("Connecting over Steam...", "正在通过 Steam 连接⋯⋯", "正在透過 Steam 連接⋯⋯"), [MpText.StatusConnectSteamFailed] = P("Could not connect over Steam: {0}", "无法通过 Steam 连接:{0}", "無法透過 Steam 連接:{0}"), [MpText.StatusConnectedAsPlayer] = P("Connected as player {0}", "已作为玩家 {0} 连接", "已作為玩家 {0} 連接"), [MpText.StatusRejected] = P("Rejected: {0}", "已被拒绝:{0}", "已被拒絕:{0}"), [MpText.StatusWaitingForPlayers] = P("Waiting for the other players...", "等待其他玩家⋯⋯", "等待其他玩家⋯⋯"), [MpText.StatusWaitingForNames] = P("Waiting for {0}...", "等待 {0}⋯⋯", "等待 {0}⋯⋯"), [MpText.StatusWaitingToResume] = P("Ready to continue. Waiting for the rest of the party...", "已准备继续。等待其他玩家⋯⋯", "已準備繼續。等待其他玩家⋯⋯"), [MpText.StatusRunStarted] = P("Run started (seed {0})", "游戏已开始(种子 {0})", "遊戲已開始(種子 {0})"), [MpText.StatusRunResumed] = P("Run continued (seed {0})", "游戏已继续(种子 {0})", "遊戲已繼續(種子 {0})"), [MpText.StatusBackInLobby] = P("Back in the lobby. Start a new run, or continue this one together.", "已回到房间。可以开始新游戏,或一起继续这局。", "已回到房間。可以開始新遊戲,或一起繼續這局。"), [MpText.NoticeResumeStaggered] = P("Not everyone saved at the same point. Whoever is behind will catch the party up.", "并非所有人都在同一处保存。落后的玩家会赶上大家。", "並非所有人都在同一處保存。落後的玩家會趕上大家。"), [MpText.StatusPlayerLeft] = P("{0} left: {1}", "{0} 已离开:{1}", "{0} 已離開:{1}"), [MpText.StatusDisconnected] = P("Disconnected: {0}", "连接已断开:{0}", "連接已中斷:{0}"), [MpText.StatusSteamLobbyFailed] = P("Cannot open a Steam lobby", "Steam 未能创建房间,无法邀请好友", "Steam 未能建立房間,無法邀請好友"), [MpText.StatusSteamJoinFailed] = P("Could not join that Steam lobby", "无法加入该 Steam 房间", "無法加入該 Steam 房間"), [MpText.ReasonProtocolMismatch] = P("Version mismatch: host runs protocol {0}, you run {1}, please ensure the mod is up to date", "版本不一致:房主使用协议 {0},你使用协议 {1}", "版本不一致:房主使用協定 {0},你使用協定 {1}"), [MpText.ReasonRunInProgress] = P("The run has already started, cannot join", "游戏已经开始了", "遊戲已經開始了"), [MpText.ReasonStartSplit] = P("Some of the party started a new run and others continued a saved one. Everyone has to do the same thing.", "有人开始了新游戏,有人却在继续存档。所有人必须做同样的选择。", "有人開始了新遊戲,有人卻在繼續存檔。所有人必須做同樣的選擇。"), [MpText.ReasonResumeDifferentRuns] = P("These saves are not the same run. Everyone has to continue the run you were playing together.", "这些存档不是同一局游戏。所有人都要继续你们一起玩的那一局。", "這些存檔不是同一局遊戲。所有人都要繼續你們一起玩的那一局。"), [MpText.ReasonSessionFull] = P("Session is full, cannot join", "房间已满", "房間已滿"), [MpText.ReasonYouLeft] = P("You left the session", "你离开了房间", "你離開了房間"), [MpText.ReasonRemoteClosed] = P("Remote closed the connection", "对方关闭了连接", "對方關閉了連接"), [MpText.ReasonConnectionFailed] = P("Connection failed", "连接失败", "連接失敗"), [MpText.ReasonSteamClosed] = P("Steam connection closed", "Steam 连接已关闭", "Steam 連接已關閉"), [MpText.ReasonReadFailed] = P("Read failed: {0}", "读取失败:{0}", "讀取失敗:{0}"), [MpText.ReasonWriteFailed] = P("Write failed: {0}", "写入失败:{0}", "寫入失敗:{0}"), [MpText.ReasonSendFailed] = P("Send failed: {0}", "发送失败:{0}", "傳送失敗:{0}"), [MpText.ReasonTimedOut] = P("Timed out connecting to {0}:{1}", "连接 {0}:{1} 超时", "連接 {0}:{1} 逾時"), [MpText.ErrorSteamUnavailable] = P("Steam is not available", "Steam 不可用", "Steam 無法使用"), [MpText.ErrorSteamListenFailed] = P("Steam refused to open a listen socket", "Steam 拒绝开启监听端口", "Steam 拒絕開啟監聽端口"), [MpText.ErrorSteamConnectFailed] = P("Steam refused to open a connection", "Steam 拒绝建立连接", "Steam 拒絕建立連接") }; private static MpPhrase P(string en, string zhHans, string zhHant) { return new MpPhrase(en, zhHans, zhHant); } } public static class MpInfo { public const string Guid = "rokk.lbol.multiplayer.LBOLMP"; public const string Name = "LBOL MP"; public const string Version = "0.8.9"; public const int ProtocolVersion = 34; public const int MaxPlayers = 4; } [BepInPlugin("rokk.lbol.multiplayer.LBOLMP", "LBOL MP", "0.8.9")] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInProcess("LBoL.exe")] public sealed class MpPlugin : BaseUnityPlugin { private static readonly Harmony HarmonyInstance = new Harmony("rokk.lbol.multiplayer.LBOLMP"); public static ConfigEntry<int> DefaultPort; public static ConfigEntry<string> LastJoinAddress; public static ConfigEntry<string> PlayerName; public static ConfigEntry<KeyCode> LobbyHotkey; public static ConfigEntry<KeyCode> DiagnosticsHotkey; public static ConfigEntry<float> EnemyHpScalePerExtraPlayer; public static ConfigEntry<float>[] EnemyHpEscalationByAct; public static ConfigEntry<bool> EnableEnemyResilience; public static ConfigEntry<float> ReviveHpFraction; public static ConfigEntry<bool> VerboseLogging; public static ConfigEntry<bool> ForceCombatEvents; public static ConfigEntry<bool> ForceDoremyEvent; private bool _runInBackgroundForced; private bool _runInBackgroundBefore; public static MpPlugin Instance { get; private set; } internal static ManualLogSource Log { get; private set; } public static bool ShowDiagnostics { get; private set; } private void Awake() { Instance = this; Log = ((BaseUnityPlugin)this).Logger; Object.DontDestroyOnLoad((Object)(object)((Component)this).gameObject); ((Object)((Component)this).gameObject).hideFlags = (HideFlags)61; SetupConfig(); Log.LogInfo((object)"LBOL MP v0.8.9 starting up"); L10n.Verify(); try { EntityManager.RegisterSelf(); MessageRegistry.RegisterAll(Assembly.GetExecutingAssembly()); HarmonyInstance.PatchAll(Assembly.GetExecutingAssembly()); Log.LogInfo((object)"Harmony patches applied"); } catch (Exception arg) { Log.LogError((object)$"Failed to initialise LBOL MP: {arg}"); } MpSession.EnsureHandlers(); ((Component)this).gameObject.AddComponent<LobbyOverlay>(); ((Component)this).gameObject.AddComponent<RemotePlayerBoard>(); } private void SetupConfig() { DefaultPort = ((BaseUnityPlugin)this).Config.Bind<int>("Network", "DefaultPort", 7777, "Port used when hosting, and the default port offered when joining."); LastJoinAddress = ((BaseUnityPlugin)this).Config.Bind<string>("Network", "LastJoinAddress", "127.0.0.1", "Remembered address of the last session you joined."); PlayerName = ((BaseUnityPlugin)this).Config.Bind<string>("Network", "PlayerName", "Player", "The name other players see you as."); LobbyHotkey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("Interface", "LobbyHotkey", (KeyCode)283, "Key that toggles the multiplayer lobby overlay."); DiagnosticsHotkey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("Interface", "DiagnosticsHotkey", (KeyCode)284, "Key that toggles the combat sync diagnostics overlay."); EnemyHpScalePerExtraPlayer = ((BaseUnityPlugin)this).Config.Bind<float>("Balance", "EnemyHpScalePerExtraPlayer", 1f, "Extra enemy max HP per additional player, as a fraction. 1 means a 100 HP enemy has 200 HP with two players. The host's setting is used."); float[] array = new float[4] { 0f, 0.1f, 0.15f, 0.2f }; EnemyHpEscalationByAct = new ConfigEntry<float>[4]; for (int i = 1; i <= 4; i++) { EnemyHpEscalationByAct[i - 1] = ((BaseUnityPlugin)this).Config.Bind<float>("Balance", $"EnemyHpScalePerExtraPlayerEscalationAct{i}", array[i - 1], $"Additional enemy HP in Act {i}. This stacks one more time for each player. If the value is 0.1, the 2nd player will add +10% HP, the 3rd player will add +20% HP, for +30% total HP. Stacks additively with EnemyHpScalePerExtraPlayer."); } EnableEnemyResilience = ((BaseUnityPlugin)this).Config.Bind<bool>("Balance", "EnableEnemyResilience", true, "Give every enemy the Resilient status effect in multiplayer. For each player past the first, an enemy loses 1 more Weak, Vulnerable and Lock On at the end of its turn, and gains 1 less Firepower Down (never less than 1). Turn this off to leave debuffs exactly as strong as they are in single player. The host's setting is used."); ReviveHpFraction = ((BaseUnityPlugin)this).Config.Bind<float>("Balance", "ReviveHpFraction", 0.2f, "How much of their max health should a defeated player be revived with. Number between 0-1. You always revive with at least 1 HP. The host's setting is used."); ForceCombatEvents = ((BaseUnityPlugin)this).Config.Bind<bool>("Debug", "ForceCombatEvents", false, "DEBUG: Force Yachie or Miyoi events at event nodes."); ForceDoremyEvent = ((BaseUnityPlugin)this).Config.Bind<bool>("Debug", "ForceDoremyEvent", false, "DEBUG: Force Doremy event at event nodes."); VerboseLogging = ((BaseUnityPlugin)this).Config.Bind<bool>("Debug", "VerboseLogging", false, "Log every network message. Very noisy, but useful when a desync happens."); } private void Update() { //IL_0005: Unknown result type (might be due to invalid IL or missing references) if (Input.GetKeyDown(DiagnosticsHotkey.Value)) { ShowDiagnostics = !ShowDiagnostics; if (ShowDiagnostics) { Log.LogInfo((object)("Combat sync state: " + MpBattleSync.DescribeTurnState())); } } SteamNet.EnsureCallbacks(); MpPortraits.Warm(); KeepRunningWhileOnline(); MpNet.Pump(); MpSession.Update(); MpBattleDriver.Update(); } private void KeepRunningWhileOnline() { bool isOnline = MpNet.IsOnline; if (isOnline == _runInBackgroundForced) { return; } if (isOnline) { _runInBackgroundBefore = Application.runInBackground; Application.runInBackground = true; if (!_runInBackgroundBefore) { Log.LogInfo((object)"Keeping the game running while unfocused for the duration of the session"); } } else { Application.runInBackground = _runInBackgroundBefore; } _runInBackgroundForced = isOnline; } private void OnApplicationQuit() { MpNet.Shutdown("Application quit"); SteamNet.LeaveLobby(); } private void OnDestroy() { MpNet.Shutdown("Plugin unloaded"); SteamNet.LeaveLobby(); Harmony harmonyInstance = HarmonyInstance; if (harmonyInstance != null) { harmonyInstance.UnpatchSelf(); } } } public static class MpSafe { public static void Run(string what, Action action) { try { action(); } catch (Exception arg) { MpPlugin.Log.LogError((object)$"[{what}] caught exception: {arg}"); } } public static T Run<T>(string what, Func<T> action, T fallback) { try { return action(); } catch (Exception arg) { MpPlugin.Log.LogError((object)$"[{what}] caught exception: {arg}"); return fallback; } } } } namespace LBOLMP.UI { public static class AllyCardPopup { private const float HoldSeconds = 1.15f; private const float FadeSeconds = 0.35f; private const float RiseSeconds = 0.18f; private const float RisePixels = 40f; private const float Scale = 0.25f; private const float HoldAlpha = 0.85f; private static readonly Dictionary<int, GameObject> Active = new Dictionary<int, GameObject>(); private static RectTransform _layer; public static void Show(int playerId, string cardId, bool upgraded) { MpSafe.Run("AllyCardPopup", delegate { //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Unknown result type (might be due to invalid IL or missing references) Dismiss(playerId); PlayBoard panel = UiManager.GetPanel<PlayBoard>(); CardWidget val = ((panel == null) ? null : panel.CardUi?.cardPrefab); if (!((Object)(object)val == (Object)null)) { RectTransform ownLayer = GetOwnLayer(); if (!((Object)(object)ownLayer == (Object)null)) { Card val2 = Library.TryCreateCard(cardId, upgraded, (int?)null); if (val2 == null) { MpPlugin.Log.LogWarning((object)("Unknown card over the wire: " + cardId)); } else { GameMaster instance = Singleton<GameMaster>.Instance; ((GameEntity)val2).GameRun = ((instance != null) ? instance.CurrentGameRun : null); CardWidget val3 = Object.Instantiate<CardWidget>(val, (Transform)(object)ownLayer); ((Object)((Component)val3).gameObject).name = "MpAllyCard: " + cardId; val3.Card = val2; val3.TooltipEnabled = false; RectTransform rectTransform = val3.RectTransform; ((Transform)rectTransform).localScale = Vector3.one * 0.25f; ((Transform)rectTransform).SetAsLastSibling(); Active[playerId] = ((Component)val3).gameObject; ((MonoBehaviour)MpPlugin.Instance).StartCoroutine(Run(playerId, val3, ownLayer)); } } } }); } private static IEnumerator Run(int playerId, CardWidget widget, RectTransform parent) { CanvasGroup group = widget.CanvasGroup; float elapsed = 0f; Vector2 val2 = default(Vector2); while ((Object)(object)widget != (Object)null && elapsed < 1.68f) { elapsed += Time.unscaledDeltaTime; float num = ((elapsed < 0.18f) ? (40f * (1f - Mathf.Pow(1f - elapsed / 0.18f, 3f))) : 40f); if (MpAllyUnits.TryGetHeadScreenPoint(playerId, out var position)) { Camera val = ResolveCamera(parent); if (RectTransformUtility.ScreenPointToLocalPointInRectangle(parent, position, val, ref val2)) { widget.RectTransform.anchoredPosition = val2 + new Vector2(0f, num); } } if ((Object)(object)group != (Object)null) { float num2 = 1.3299999f; group.alpha = ((elapsed <= num2) ? 0.85f : (0.85f * Mathf.Clamp01(1f - (elapsed - num2) / 0.35f))); } yield return null; } Dismiss(playerId); } private static RectTransform GetOwnLayer() { //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_0023: 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_0052: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_layer != (Object)null) { return _layer; } GameObject val = new GameObject("MpAllyCardLayer"); Object.DontDestroyOnLoad((Object)val); Canvas obj = val.AddComponent<Canvas>(); obj.renderMode = (RenderMode)0; obj.sortingOrder = 500; CanvasScaler obj2 = val.AddComponent<CanvasScaler>(); obj2.uiScaleMode = (ScaleMode)1; obj2.referenceResolution = new Vector2(1920f, 1080f); obj2.matchWidthOrHeight = 0.5f; _layer = val.GetComponent<RectTransform>(); return _layer; } private static Camera ResolveCamera(RectTransform parent) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) Canvas componentInParent = ((Component)parent).GetComponentInParent<Canvas>(); if ((Object)(object)componentInParent == (Object)null) { return null; } if ((int)componentInParent.renderMode != 0) { return componentInParent.worldCamera; } return null; } public static void Dismiss(int playerId) { if (Active.TryGetValue(playerId, out var value)) { Active.Remove(playerId); if ((Object)(object)value != (Object)null) { Object.Destroy((Object)(object)value); } } } public static void DismissAll() { foreach (int item in new List<int>(Active.Keys)) { Dismiss(item); } } } internal sealed class BalanceSettingsWindow { private const int WindowId = 6914; private const string Section = "Balance"; internal bool Visible; private Rect _window = new Rect(120f, 90f, 560f, 520f); private Vector2 _scroll; private readonly Dictionary<string, string> _typing = new Dictionary<string, string>(); private GUIStyle _nameStyle; private GUIStyle _helpStyle; private GUIStyle _noteStyle; internal void Draw() { //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_0038: Expected O, but got Unknown //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) if (Visible) { EnsureStyles(); _window = GUI.Window(6914, _window, new WindowFunction(DrawWindow), L10n.Get(MpText.SettingsWindowTitle), MpGui.Window); } } private void EnsureStyles() { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_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_0034: Expected O, but got Unknown //IL_003f: 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_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0058: 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_0070: 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_0083: Expected O, but got Unknown if (_nameStyle == null) { _nameStyle = new GUIStyle(GUI.skin.label) { fontSize = 14, fontStyle = (FontStyle)1, wordWrap = true }; _helpStyle = new GUIStyle(GUI.skin.label) { fontSize = 12, wordWrap = true }; _noteStyle = new GUIStyle(GUI.skin.label) { fontSize = 12, fontStyle = (FontStyle)2, wordWrap = true }; } } private void DrawWindow(int id) { //IL_0093: 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_00a2: 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) GUILayout.Space(4f); GUILayout.Label(L10n.Get(MpText.SettingsIntro), _helpStyle, Array.Empty<GUILayoutOption>()); GUILayout.Space(2f); GUILayout.Label(L10n.Get(MpText.SettingsHostNote), _noteStyle, Array.Empty<GUILayoutOption>()); if (MpSession.IsInRun) { GUILayout.Label(L10n.Get(MpText.SettingsLockedForThisRun), _noteStyle, Array.Empty<GUILayoutOption>()); } GUILayout.Space(6f); List<ConfigEntryBase> list = BalanceEntries(); if (list.Count == 0) { GUILayout.Label(L10n.Get(MpText.SettingsNothingToShow), _helpStyle, Array.Empty<GUILayoutOption>()); } else { _scroll = GUILayout.BeginScrollView(_scroll, Array.Empty<GUILayoutOption>()); foreach (ConfigEntryBase item in list) { DrawEntry(item); } GUILayout.EndScrollView(); } GUILayout.Space(4f); GUILayout.Label(L10n.Get(MpText.SettingsNextRunNote), _noteStyle, Array.Empty<GUILayoutOption>()); GUILayout.Space(4f); GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); if (GUILayout.Button(L10n.Get(MpText.SettingsResetAll), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(190f) })) { foreach (ConfigEntryBase item2 in list) { Reset(item2); } } GUILayout.FlexibleSpace(); if (GUILayout.Button(L10n.Get(MpText.SettingsClose), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(100f) })) { Visible = false; } GUILayout.EndHorizontal(); GUI.DragWindow(new Rect(0f, 0f, 10000f, 20f)); } private static List<ConfigEntryBase> BalanceEntries() { MpPlugin instance = MpPlugin.Instance; ConfigFile val = ((instance != null) ? ((BaseUnityPlugin)instance).Config : null); if (val == null) { return new List<ConfigEntryBase>(); } return (from pair in ((IEnumerable<KeyValuePair<ConfigDefinition, ConfigEntryBase>>)val).Where((KeyValuePair<ConfigDefinition, ConfigEntryBase> pair) => pair.Key.Section == "Balance").OrderBy<KeyValuePair<ConfigDefinition, ConfigEntryBase>, string>((KeyValuePair<ConfigDefinition, ConfigEntryBase> pair) => pair.Key.Key, StringComparer.Ordinal) select pair.Value).ToList(); } private void DrawEntry(ConfigEntryBase entry) { Describe(entry, out var name, out var help); GUILayout.Space(6f); GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); GUILayout.Label(name, _nameStyle, Array.Empty<GUILayoutOption>()); GUILayout.FlexibleSpace(); DrawEditor(entry); if (GUILayout.Button(L10n.Get(MpText.SettingsDefault), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(76f) })) { Reset(entry); } GUILayout.EndHorizontal(); if (!string.IsNullOrEmpty(help)) { GUILayout.Label(help, _helpStyle, Array.Empty<GUILayoutOption>()); } } private static void Describe(ConfigEntryBase entry, out string name, out string help) { if ((object)entry == MpPlugin.EnemyHpScalePerExtraPlayer) { name = L10n.Get(MpText.SettingEnemyHpScaleName); help = L10n.Get(MpText.SettingEnemyHpScaleHelp); return; } if ((object)entry == MpPlugin.ReviveHpFraction) { name = L10n.Get(MpText.SettingReviveHpName); help = L10n.Get(MpText.SettingReviveHpHelp); return; } if ((object)entry == MpPlugin.EnableEnemyResilience) { name = L10n.Get(MpText.SettingResilienceName); help = L10n.Get(MpText.SettingResilienceHelp); return; } ConfigEntry<float>[] enemyHpEscalationByAct = MpPlugin.EnemyHpEscalationByAct; int num = 0; while (enemyHpEscalationByAct != null && num < enemyHpEscalationByAct.Length) { if ((object)entry == enemyHpEscalationByAct[num]) { name = L10n.Get(MpText.SettingEscalationName, num + 1); help = L10n.Get(MpText.SettingEscalationHelp); return; } num++; } name = entry.Definition.Key; ConfigDescription description = entry.Description; help = ((description != null) ? description.Description : null); } private void DrawEditor(ConfigEntryBase entry) { if (entry.SettingType == typeof(bool)) { bool flag = (bool)entry.BoxedValue; bool flag2 = GUILayout.Toggle(flag, GUIContent.none, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(90f) }); if (flag2 != flag) { entry.BoxedValue = flag2; } return; } string key = entry.Definition.Key; if (!_typing.TryGetValue(key, out var value)) { value = Serialize(entry); } string text = GUILayout.TextField(value, 12, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(90f) }); if (!(text == value)) { _typing[key] = text; Commit(entry, text); } } private static void Commit(ConfigEntryBase entry, string text) { MpSafe.Run("BalanceSettings.Commit", delegate { if (entry.SettingType == typeof(float)) { if (float.TryParse(text, NumberStyles.Float, CultureInfo.InvariantCulture, out var result)) { entry.BoxedValue = result; } } else { if (!(entry.SettingType == typeof(int))) { try { entry.SetSerializedValue(text); return; } catch (Exception) { return; } } if (int.TryParse(text, NumberStyles.Integer, CultureInfo.InvariantCulture, out var result2)) { entry.BoxedValue = result2; } } }); } private void Reset(ConfigEntryBase entry) { MpSafe.Run("BalanceSettings.Reset", delegate { entry.BoxedValue = entry.DefaultValue; _typing.Remove(entry.Definition.Key); }); } private static string Serialize(ConfigEntryBase entry) { if (entry.BoxedValue is float num) { return num.ToString("0.####", CultureInfo.InvariantCulture); } return Convert.ToString(entry.BoxedValue, CultureInfo.InvariantCulture) ?? string.Empty; } } public sealed class LobbyOverlay : MonoBehaviour { private const int WindowId = 6913; private static readonly Color HostColour = new Color(1f, 0.85f, 0.4f); private static readonly Color LocalColour = new Color(0.6f, 1f, 0.7f); private static readonly Color DeadColour = new Color(0.7f, 0.35f, 0.35f); private bool _visible; private Rect _window = new Rect(40f, 40f, 460f, 420f); private string _address = "127.0.0.1"; private string _port = "7777"; private string _name = "Player"; private GUIStyle _headerStyle; private GUIStyle _rowStyle; private GUIStyle _hudStyle; private readonly BalanceSettingsWindow _balance = new BalanceSettingsWindow(); private const float HudPadding = 8f; private const float HudMargin = 8f; private void Start() { _address = MpPlugin.LastJoinAddress.Value; _port = MpPlugin.DefaultPort.Value.ToString(); _name = MpPlugin.PlayerName.Value; } private void Update() { //IL_0005: Unknown result type (might be due to invalid IL or missing references) if (Input.GetKeyDown(MpPlugin.LobbyHotkey.Value)) { _visible = !_visible; } } private void EnsureStyles() { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_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_0034: Expected O, but got Unknown //IL_003f: 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_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0058: 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_0070: 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_007d: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Expected O, but got Unknown if (_headerStyle == null) { _headerStyle = new GUIStyle(GUI.skin.label) { fontSize = 15, fontStyle = (FontStyle)1, wordWrap = true }; _rowStyle = new GUIStyle(GUI.skin.label) { fontSize = 13, wordWrap = true }; GUIStyle val = new GUIStyle(GUI.skin.label) { fontSize = 13, alignment = (TextAnchor)0 }; val.normal.textColor = Color.white; _hudStyle = MpGui.SingleLine(val); } } private void OnGUI() { //IL_0028: 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_0057: Expected O, but got Unknown //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) EnsureStyles(); DrawCornerHud(); DrawVoteBanner(); DrawNotice(); if (_visible) { _window = GUI.Window(6913, _window, new WindowFunction(DrawWindow), L10n.Get(MpText.LobbyWindowTitle, "0.8.9"), MpGui.Window); _balance.Draw(); } } private void DrawVoteBanner() { //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_0038: 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_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) //IL_0096: 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_00c0: 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) if (MpSession.IsActive && MpSession.IsInRun && MapSync.VoteInProgress && !MapSync.PartyAgrees) { string text = MapSync.DescribeVoteState(); Vector2 val = MpGui.Measure(_hudStyle, text); Rect val2 = default(Rect); ((Rect)(ref val2))..ctor(((float)Screen.width - val.x) * 0.5f - 14f, 64f, val.x + 28f, val.y + 12f); GUI.color = new Color(0f, 0f, 0f, 0.7f); GUI.Box(val2, GUIContent.none); GUI.color = Color.white; GUI.Label(new Rect(((Rect)(ref val2)).x + 14f, ((Rect)(ref val2)).y + 6f, val.x, val.y), text, _hudStyle); } } private void DrawNotice() { //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_0024: 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_0048: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_0091: 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: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Unknown result type (might be due to invalid IL or missing references) string current = MpNotice.Current; if (current.Length != 0) { Vector2 val = MpGui.Measure(_hudStyle, current); Rect val2 = default(Rect); ((Rect)(ref val2))..ctor(((float)Screen.width - val.x) * 0.5f - 14f, 96f, val.x + 28f, val.y + 12f); GUI.color = new Color(0f, 0f, 0f, 0.8f); GUI.Box(val2, GUIContent.none); GUI.color = new Color(1f, 0.85f, 0.4f); GUI.Label(new Rect(((Rect)(ref val2)).x + 14f, ((Rect)(ref val2)).y + 6f, val.x, val.y), current, _hudStyle); GUI.color = Color.white; } } private void DrawCornerHud() { //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_013f: Unknown result type (might be due to invalid IL or missing references) //IL_0138: 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_019a: Unknown result type (might be due to invalid IL or missing references) //IL_0226: Unknown result type (might be due to invalid IL or missing references) //IL_0230: Unknown result type (might be due to invalid IL or missing references) //IL_023c: Unknown result type (might be due to invalid IL or missing references) //IL_025a: Unknown result type (might be due to invalid IL or missing references) //IL_0262: Unknown result type (might be due to invalid IL or missing references) //IL_028a: Unknown result type (might be due to invalid IL or missing references) if (!MpSession.IsActive) { return; } List<MpPlayer> list = MpSession.Players.Where((MpPlayer p) => !p.IsLocal).ToList(); if (list.Count == 0) { return; } List<string> list2 = new List<string>(); list2.Add(L10n.Get(MpText.HudParty, MpSession.ConnectedCount)); List<string> list3 = list2; List<Color> list4 = new List<Color> { Color.white }; foreach (MpPlayer item in list) { string text = string.Empty; if (MapSync.CurrentVotes.TryGetValue(item.Id, out (int, int) value)) { text = L10n.Get(MpText.HudVoteNode, value.Item1, value.Item2); } else if (MapSync.VoteInProgress) { text = L10n.Get(MpText.HudVoteStillChoosing); } list3.Add(L10n.Get(MpText.HudPlayerRow, item.Name, item.Hp, item.MaxHp, text)); list4.Add((item.State == MpPlayerState.Disconnected) ? DeadColour : Color.white); } Vector2[] array = (Vector2[])(object)new Vector2[list3.Count]; float num = 0f; float num2 = 0f; for (int num3 = 0; num3 < list3.Count; num3++) { array[num3] = MpGui.Measure(_hudStyle, list3[num3]); num = Mathf.Max(num, array[num3].x); num2 += array[num3].y; } Rect val = default(Rect); ((Rect)(ref val))..ctor(Mathf.Max(8f, (float)Screen.width - num - 16f - 8f), 8f, num + 16f, num2 + 16f); GUI.color = new Color(0f, 0f, 0f, 0.55f); GUI.Box(val, GUIContent.none); GUI.color = Color.white; float num4 = ((Rect)(ref val)).y + 8f; for (int num5 = 0; num5 < list3.Count; num5++) { Color contentColor = GUI.contentColor; GUI.contentColor = list4[num5]; GUI.Label(new Rect(((Rect)(ref val)).x + 8f, num4, num, array[num5].y), list3[num5], _hudStyle); GUI.contentColor = contentColor; num4 += array[num5].y; } } private void DrawWindow(int id) { //IL_00a2: Unknown result type (might be due to invalid IL or missing references) GUILayout.Space(4f); if (!MpNet.IsOnline) { DrawOfflineControls(); } else { DrawOnlineControls(); } GUILayout.Space(8f); if (GUILayout.Button(L10n.Get(MpText.LobbyBalanceSettings), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(180f) })) { _balance.Visible = !_balance.Visible; } if (!string.IsNullOrEmpty(MpSession.StatusLine)) { GUILayout.Space(6f); GUILayout.Label(MpSession.StatusLine, _rowStyle, Array.Empty<GUILayoutOption>()); } GUI.DragWindow(new Rect(0f, 0f, 10000f, 20f)); } private void DrawOfflineControls() { GUILayout.Label(L10n.Get(MpText.LobbyNotConnected), _headerStyle, Array.Empty<GUILayoutOption>()); GUILayout.Space(6f); GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); GUILayout.Label(L10n.Get(MpText.LobbyYourName), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(90f) }); string text = GUILayout.TextField(_name, 24, Array.Empty<GUILayoutOption>()); if (text != _name) { _name = text; MpPlugin.PlayerName.Value = text; } GUILayout.EndHorizontal(); DrawSteamControls(); GUILayout.Space(8f); GUILayout.Label(L10n.Get(MpText.LobbyDirectConnection), _headerStyle, Array.Empty<GUILayoutOption>()); GUILayout.Space(2f); GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); GUILayout.Label(L10n.Get(MpText.LobbyPort), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(90f) }); _port = GUILayout.TextField(_port, 6, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(80f) }); if (GUILayout.Button(L10n.Get(MpText.LobbyHostSession), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(140f) })) { if (int.TryParse(_port, out var result)) { MpPlugin.DefaultPort.Value = result; MpSession.Host(result); } else { MpSession.StatusLine = L10n.Get(MpText.LobbyPortNotANumber); } } GUILayout.EndHorizontal(); GUILayout.Space(4f); GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); GUILayout.Label(L10n.Get(MpText.LobbyHostAddress), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(90f) }); _address = GUILayout.TextField(_address, 64, Array.Empty<GUILayoutOption>()); GUILayout.EndHorizontal(); if (GUILayout.Button(L10n.Get(MpText.LobbyJoinSession), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(140f) })) { if (int.TryParse(_port, out var result2)) { MpPlugin.LastJoinAddress.Value = _address; MpPlugin.DefaultPort.Value = result2; MpSession.Join(_address, result2); } else { MpSession.StatusLine = L10n.Get(MpText.LobbyPortNotANumber); } } GUILayout.Space(10f); GUILayout.Label(L10n.Get(MpText.LobbyOfflineHelp), _rowStyle, Array.Empty<GUILayoutOption>()); } private void DrawSteamControls() { GUILayout.Space(8f); GUILayout.Label(L10n.Get(MpText.LobbySteam), _headerStyle, Array.Empty<GUILayoutOption>()); GUILayout.Space(2f); if (!SteamNet.IsAvailable) { GUILayout.Label(L10n.Get(MpText.LobbySteamUnavailable), _rowStyle, Array.Empty<GUILayoutOption>()); return; } if (GUILayout.Button(L10n.Get(MpText.LobbyHostOverSteam), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(180f) })) { MpSession.HostSteam(); } GUILayout.Label(L10n.Get(MpText.LobbySteamHelp), _rowStyle, Array.Empty<GUILayoutOption>()); } private void DrawOnlineControls() { //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_00a3: 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_00cb: 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) string text = L10n.Decode(MpNet.TransportName); if (string.IsNullOrEmpty(text)) { text = L10n.Get(MpNet.IsHost ? MpText.LobbyHosting : MpText.LobbyConnected); } GUILayout.Label(text, _headerStyle, Array.Empty<GUILayoutOption>()); GUILayout.Space(4f); if (MpNet.IsSteamSession && !MpSession.IsInRun && SteamNet.InLobby && GUILayout.Button(L10n.Get(MpText.LobbyInviteFriends), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(180f) })) { SteamNet.OpenInviteDialog(); } foreach (MpPlayer player in MpSession.Players) { Color contentColor = GUI.contentColor; if (player.State == MpPlayerState.Disconnected) { GUI.contentColor = DeadColour; } else if (player.IsLocal) { GUI.contentColor = LocalColour; } else if (player.IsHost) { GUI.contentColor = HostColour; } string text2 = string.Empty; if (player.IsHost) { text2 += L10n.Get(MpText.LobbyTagHost); } if (player.IsLocal) { text2 += L10n.Get(MpText.LobbyTagYou); } string text3 = (string.IsNullOrEmpty(player.CharacterId) ? L10n.Get(MpText.LobbyChoosing) : player.CharacterId); GUILayout.Label(L10n.Get(MpText.LobbyPlayerRow, player.Id, player.Name, text2, text3, DescribeState(player)), _rowStyle, Array.Empty<GUILayoutOption>()); GUI.contentColor = contentColor; } GUILayout.Space(8f); if (MpSession.State == MpSessionState.WaitingForPlayers) { GUILayout.Label(L10n.Get(MpText.LobbyLockedIn), _rowStyle, Array.Empty<GUILayoutOption>()); GUILayout.Label(MpSession.DescribeRunWait(), _rowStyle, Array.Empty<GUILayoutOption>()); } if (MpSession.IsInRun) { GUILayout.Label(L10n.Get(MpText.LobbySeed, MpSession.RunSeed), _rowStyle, Array.Empty<GUILayoutOption>()); GUILayout.Label(L10n.Get(MpText.LobbyMapVoteHint), _rowStyle, Array.Empty<GUILayoutOption>()); } GUILayout.Space(8f); if (GUILayout.Button(L10n.Get(MpText.LobbyLeaveSession), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(140f) })) { MpSession.Leave(MpText.ReasonYouLeft); } } private static string DescribeState(MpPlayer player) { return player.State switch { MpPlayerState.Lobby => L10n.Get(MpText.StateInLobby), MpPlayerState.Ready => L10n.Get(MpText.StateReady), MpPlayerState.Resuming => L10n.Get(MpText.StateResuming), MpPlayerState.InRun => L10n.Get(MpText.StateHp, player.Hp, player.MaxHp), MpPlayerState.Disconnected => L10n.Get(MpText.StateDisconnected), _ => string.Empty, }; } } public static class MapVoteMarkers { private const string MarkerName = "MpVoteMarker"; private static readonly Dictionary<int, GameObject> Markers = new Dictionary<int, GameObject>(); private static readonly List<int> Voted = new List<int>(); public static void Update() { MpSafe.Run("MapVoteMarkers", Refresh); } public static void Clear() { MpSafe.Run("MapVoteMarkers.Clear", delegate { foreach (GameObject value in Markers.Values) { if ((Object)(object)value != (Object)null) { Object.Destroy((Object)(object)value); } } Markers.Clear(); }); } private static void Refresh() { if (!MpSession.IsActive || !MpSession.IsInRun) { HideAll(); return; } MapPanel val = TryGetPanel<MapPanel>(); if ((Object)(object)val == (Object)null || MapSync.CurrentVotes.Count == 0) { HideAll(); return; } IReadOnlyDictionary<int, (int, int)> currentVotes = MapSync.CurrentVotes; Voted.Clear(); Dictionary<(int, int), List<int>> dictionary = new Dictionary<(int, int), List<int>>(); foreach (MpPlayer player in MpSession.Players) { if (currentVotes.TryGetValue(player.Id, out var value)) { if (!dictionary.TryGetValue(value, out var value2)) { value2 = (dictionary[value] = new List<int>()); } value2.Add(player.Id); Voted.Add(player.Id); } } foreach (KeyValuePair<(int, int), List<int>> item in dictionary) { MapNodeWidget val2 = WidgetAt(val, item.Key.Item1, item.Key.Item2); if (!((Object)(object)val2 == (Object)null)) { for (int i = 0; i < item.Value.Count; i++) { Place(item.Value[i], val2, i, item.Value.Count); } } } foreach (KeyValuePair<int, GameObject> marker in Markers) { if (!Voted.Contains(marker.Key) && (Object)(object)marker.Value != (Object)null) { marker.Value.SetActive(false); } } } private static void Place(int playerId, MapNodeWidget widget, int index, int count) { //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_00d1: 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_00e7: Expected O, but got Unknown //IL_0126: 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_0144: 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_0160: Unknown result type (might be due to invalid IL or missing references) //IL_0165: Unknown result type (might be due to invalid IL or missing references) //IL_01b8: Unknown result type (might be due to invalid IL or missing references) //IL_01bf: Unknown result type (might be due to invalid IL or missing references) //IL_01c1: Unknown result type (might be due to invalid IL or missing references) //IL_01c2: Unknown result type (might be due to invalid IL or missing references) //IL_01c9: Unknown result type (might be due to invalid IL or missing references) //IL_01d5: Unknown result type (might be due to invalid IL or missing references) //IL_01e0: Unknown result type (might be due to invalid IL or missing references) //IL_017b: Unknown result type (might be due to invalid IL or missing references) //IL_0180: Unknown result type (might be due to invalid IL or missing references) //IL_021e: Unknown result type (might be due to invalid IL or missing references) //IL_0276: Unknown result type (might be due to invalid IL or missing references) //IL_0268: 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_0282: Unknown result type (might be due to invalid IL or missing references) //IL_0287: Unknown result type (might be due to invalid IL or missing references) //IL_0288: Unknown result type (might be due to invalid IL or missing references) //IL_0289: Unknown result type (might be due to invalid IL or missing references) //IL_029b: Unknown result type (might be due to invalid IL or missing references) //IL_02a2: Unknown result type (might be due to invalid IL or missing references) //IL_02a4: Unknown result type (might be due to invalid IL or missing references) //IL_02a5: Unknown result type (might be due to invalid IL or missing references) //IL_02ac: Unknown result type (might be due to invalid IL or missing references) //IL_02b3: 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_02bb: Unknown result type (might be due to invalid IL or missing references) //IL_02bc: Unknown result type (might be due to invalid IL or missing references) //IL_02c6: Unknown result type (might be due to invalid IL or missing references) GameObject val = Ensure(playerId); if ((Object)(object)val == (Object)null) { return; } Sprite val2 = MpPortraits.For(MpSession.Get(playerId)?.CharacterId); if ((Object)(object)val2 == (Object)null) { val.SetActive(false); return; } Image component = val.GetComponent<Image>(); component.sprite = MpPortraits.Frame; ((Behaviour)component).enabled = (Object)(object)component.sprite != (Object)null; RawImage component2 = ((Component)val.transform.GetChild(0)).GetComponent<RawImage>(); Rect textureRect = val2.textureRect; component2.texture = (Texture)(object)val2.texture; component2.uvRect = new Rect(((Rect)(ref textureRect)).x / (float)((Texture)val2.texture).width, ((Rect)(ref textureRect)).y / (float)((Texture)val2.texture).height, ((Rect)(ref textureRect)).width / (float)((Texture)val2.texture).width, ((Rect)(ref textureRect)).height / (float)((Texture)val2.texture).height); RectTransform val3 = (RectTransform)val.transform; if ((Object)(object)((Transform)val3).parent != (Object)(object)((Component)widget).transform) { ((Transform)val3).SetParent(((Component)widget).transform, false); } ((Transform)val3).SetAsLastSibling(); Transform transform = ((Component)widget).transform; RectTransform val4 = (RectTransform)(object)((transform is RectTransform) ? transform : null); Rect rect; float num; if ((Object)(object)val4 != (Object)null) { rect = val4.rect; if (((Rect)(ref rect)).height > 1f) { rect = val4.rect; num = ((Rect)(ref rect)).height; goto IL_0152; } } num = 60f; goto IL_0152; IL_0189: float num3; float num2 = num3; float num5; float num4 = Mathf.Clamp(num5 * 0.85f, 38f, 84f); Vector2 val5 = default(Vector2); ((Vector2)(ref val5))..ctor(0.5f, 0.5f); val3.pivot = val5; Vector2 anchorMin = (val3.anchorMax = val5); val3.anchorMin = anchorMin; val3.sizeDelta = new Vector2(num4, num4); ((Transform)val3).localScale = Vector3.one; val3.anchoredPosition = new Vector2(0f - (num2 * 0.5f + num4 * 0.45f), ((float)(count - 1) * 0.5f - (float)index) * (num4 * ((count > 2) ? 0.62f : 0.8f))); float num6 = num4 * MpPortraits.HeadScale(); float num7 = ((((Rect)(ref textureRect)).height > 0f) ? (((Rect)(ref textureRect)).width / ((Rect)(ref textureRect)).height) : 1f); Vector2 sizeDelta = ((num7 > 1f) ? new Vector2(num6, num6 / num7) : new Vector2(num6 * num7, num6)); RectTransform val7 = (RectTransform)((Component)component2).transform; ((Vector2)(ref val5))..ctor(0.5f, 0.5f); val7.pivot = val5; anchorMin = (val7.anchorMax = val5); val7.anchorMin = anchorMin; val7.sizeDelta = sizeDelta; val7.anchoredPosition = Vector2.zero; ((Transform)val7).localScale = Vector3.one; val.SetActive(true); return; IL_0152: num5 = num; if ((Object)(object)val4 != (Object)null) { rect = val4.rect; if (((Rect)(ref rect)).width > 1f) { rect = val4.rect; num3 = ((Rect)(ref rect)).width; goto IL_0189; } } num3 = num5; goto IL_0189; } private static GameObject Ensure(int playerId) { //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Expected O, but got Unknown //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) if (Markers.TryGetValue(playerId, out var value) && (Object)(object)value != (Object)null && value.transform.childCount > 0 && (Object)(object)((Component)value.transform.GetChild(0)).GetComponent<RawImage>() != (Object)null) { return value; } if ((Object)(object)value != (Object)null) { Object.Destroy((Object)(object)value); } GameObject val = new GameObject(string.Format("{0}_{1}", "MpVoteMarker", playerId), new Type[2] { typeof(RectTransform), typeof(Image) }); Image component = val.GetComponent<Image>(); component.preserveAspect = true; Configure((Graphic)(object)component); GameObject val2 = new GameObject("Head", new Type[2] { typeof(RectTransform), typeof(RawImage) }); val2.transform.SetParent(val.transform, false); Configure((Graphic)(object)val2.GetComponent<RawImage>()); Markers[playerId] = val; return val; } private static void Configure(Graphic graphic) { graphic.raycastTarget = false; } private static void HideAll() { foreach (GameObject value in Markers.Values) { if ((Object)(object)value != (Object)null && value.activeSelf) { value.SetActive(false); } } } private static MapNodeWidget WidgetAt(MapPanel panel, int x, int y) { GameMaster instance = Singleton<GameMaster>.Instance; object obj; if (instance == null) { obj = null; } else { GameRunController currentGameRun = instance.CurrentGameRun; obj = ((currentGameRun != null) ? currentGameRun.CurrentMap : null); } GameMap val = (GameMap)obj; if (val == null || x < 0 || y < 0 || x >= val.Levels || y >= val.Width) { return null; } try { return panel.GetMapNodeWidget(x, y); } catch (IndexOutOfRangeException) { return null; } } private static TPanel TryGetPanel<TPanel>() where TPanel : UiPanelBase { try { return UiManager.GetPanel<TPanel>(); } catch (InvalidOperationException) { return default(TPanel); } } } public static class MpAllyUnits { private sealed class Ally { public int PlayerId; public string CharacterId; public PlayerUnit Unit; public UnitView View; public GameObject Root; public bool Loading; public bool Shooting; public bool Hidden; public int LastHp = int.MinValue; public int LastBlock = int.MinValue; public int LastShield = int.MinValue; } [StructLayout(LayoutKind.Auto)] [CompilerGenerated] private struct <LoadAllyAsync>d__11 : IAsyncStateMachine { public int <>1__state; public AsyncUniTaskMethodBuilder <>t__builder; public MpPlayer player; public Ally ally; public int slot; private GameDirector <director>5__2; private UnitView <view>5__3; private Awaiter <>u__1; private void MoveNext() { //IL_01bd: Unknown result type (might be due to invalid IL or missing references) //IL_01c2: Unknown result type (might be due to invalid IL or missing references) //IL_01ca: 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: Expected O, but got Unknown //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0083: 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_00a4: 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_017f: 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_0188: Unknown result type (might be due to invalid IL or missing references) //IL_018d: Unknown result type (might be due to invalid IL or missing references) //IL_01a2: Unknown result type (might be due to invalid IL or missing references) //IL_01a4: Unknown result type (might be due to invalid IL or missing references) int num = <>1__state; try { try { Awaiter val5; if (num != 0) { <director>5__2 = Singleton<GameDirector>.Instance; GameObject val = new GameObject($"MpAlly_{player.Id}_{ally.CharacterId}"); val.transform.SetParent(<director>5__2.playerRoot, false); Vector2 val2 = Offsets[Mathf.Clamp(slot, 0, Offsets.Length - 1)]; val.transform.localPosition = new Vector3(val2.x, val2.y, 0f); val.transform.localScale = Vector3.one * 0.92f; ally.Root = val; GameObject val3 = Object.Instantiate<GameObject>(<director>5__2.unitPrefab, val.transform); <view>5__3 = val3.GetComponent<UnitView>(); <view>5__3.Unit = (Unit)(object)ally.Unit; UnitStatusHud panel = UiManager.GetPanel<UnitStatusHud>(); if ((Object)(object)panel != (Object)null) { <view>5__3.SetStatusWidget(panel.CreateStatusWidget((Unit)(object)ally.Unit), 1f); <view>5__3.SetInfoWidget(panel.CreateInfoWidget((Unit)(object)ally.Unit), 1f); } <view>5__3.IsHidden = false; UniTask val4 = <view>5__3.LoadUnitModelAsync(ally.Unit.ModelName, true, (float?)null); val5 = ((UniTask)(ref val4)).GetAwaiter(); if (!((Awaiter)(ref val5)).IsCompleted) { num = (<>1__state = 0); <>u__1 = val5; ((AsyncUniTaskMethodBuilder)(ref <>t__builder)).AwaitUnsafeOnCompleted<Awaiter, <LoadAllyAsync>d__11>(ref val5, ref this); return; } } else { val5 = <>u__1; <>u__1 = default(Awaiter); num = (<>1__state = -1); } ((Awaiter)(ref val5)).GetResult(); ((Unit)ally.Unit).SetView((IUnitView)(object)<view>5__3); <view>5__3.SetPlayerHpBarLength(((Unit)ally.Unit).MaxHp); ally.View = <view>5__3; ally.Loading = false; ally.Hidden = (Object)(object)<director>5__2.PlayerUnitView != (Object)null && <director>5__2.PlayerUnitView.IsHidden; if (ally.Hidden) { <view>5__3.IsHidden = true; } else { <view>5__3.Show(true); <view>5__3.SetStatusVisible(true, true); } MpPlugin.Log.LogInfo((object)("Spawned ally unit for " + player.Name + " (" + ally.CharacterId + ")")); <director>5__2 = null; <view>5__3 = null; } catch (Exception arg) { MpPlugin.Log.LogError((object)$"Failed to spawn ally unit for player {player.Id}: {arg}"); ally.Loading = false; } } catch (Exception exception) { <>1__state = -2; ((AsyncUniTaskMethodBuilder)(ref <>t__builder)).SetException(exception); return; } <>1__state = -2; ((AsyncUniTaskMethodBuilder)(ref <>t__builder)).SetResult(); } void IAsyncStateMachine.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext this.MoveNext(); } [DebuggerHidden] private void SetStateMachine(IAsyncStateMachine stateMachine) { ((AsyncUniTaskMethodBuilder)(ref <>t__builder)).SetStateMachine(stateMachine); } void IAsyncStateMachine.SetStateMachine(IAsyncStateMachine stateMachine) { //ILSpy generated this explicit interface implementation from .override directive in SetStateMachine this.SetStateMachine(stateMachine); } } private static readonly Dictionary<int, Ally> Allies = new Dictionary<int, Ally>(); private const float AllyVolume = 0.5f; private static readonly Vector2[] Offsets = (Vector2[])(object)new Vector2[3] { new Vector2(-1.35f, -1.45f), new Vector2(-2.6f, 0.55f), new Vector2(-3.85f, -2.6f) }; private const float ShootTimeLimit = 8f; private static GunHitArgs _allyGunHit; private static GunHitArgs _displacedGunHit; public static PlayerUnit GetUnit(int playerId) { if (!Allies.TryGetValue(playerId, out var value)) { return null; } return value.Unit; } public static bool IsMirror(Unit unit) { if (unit == null) { return false; } foreach (Ally value in Allies.Values) { if ((object)value.Unit == unit) { return true; } } return false; } public static UnitView GetView(int playerId) { if (!Allies.TryGetValue(playerId, out var value) || value.Loading) { return null; } return value.View; } public static int PlayerFor(UnitView view) { if ((Object)(object)view == (Object)null) { return -1; } foreach (Ally value in Allies.Values) { if (value.View == view) { return value.PlayerId; } } return -1; } public static UnitView GetView(Unit unit) { if (unit == null) { return null; } foreach (Ally value in Allies.Values) { if ((object)value.Unit == unit) { return value.View; } } return null; } public static void Tick() { if (!MpSession.IsActive || !MpSession.IsInRun) { if (Allies.Count > 0) { DespawnAll(); } return; } GameDirector instance = Singleton<GameDirector>.Instance; if ((Object)(object)instance == (Object)null || (Object)(object)instance.PlayerUnitView == (Object)null || (Object)(object)instance.playerRoot == (Object)null) { if (Allies.Count > 0) { DespawnAll(); } return; } foreach (int item in Allies.Keys.ToList()) { MpPlayer mpPlayer = MpSession.Get(item); if (mpPlayer == null || mpPlayer.State == MpPlayerState.Disconnected) { Despawn(item); } } int num = 0; foreach (MpPlayer connectedPlayer in MpSession.ConnectedPlayers) { if (!connectedPlayer.IsLocal) { if (!Allies.ContainsKey(connectedPlayer.Id) && !string.IsNullOrEmpty(connectedPlayer.CharacterId)) { Spawn(connectedPlayer, num); } num++; } } } private static void Spawn(MpPlayer player, int slot) { //IL_012f: Unknown result type (might be due to invalid IL or missing references) PlayerUnit val = MpSafe.Run("MpAllyUnits.Create", () => Library.TryCreatePlayerUnit(player.CharacterId), null); if (val == null) { MpPlugin.Log.LogWarning((object)("Unknown character id over the wire: " + player.CharacterId)); Allies[player.Id] = new Ally { PlayerId = player.Id, CharacterId = player.CharacterId }; return; } int num = ((player.MaxHp > 0) ? player.MaxHp : ((Unit)val).MaxHp); int num2 = ((player.Hp > 0) ? Mathf.Min(player.Hp, num) : num); ((Unit)val).SetMaxHp(num2, num); Ally ally = new Ally { PlayerId = player.Id, CharacterId = player.CharacterId, Unit = val, Loading = true, LastHp = num2 }; Allies[player.Id] = ally; UniTaskExtensions.Forget(LoadAllyAsync(ally, player, slot)); } [AsyncStateMachine(typeof(<LoadAllyAsync>d__11))] private static UniTask LoadAllyAsync(Ally ally, MpPlayer player, int slot) { //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_0041: Unknown result type (might be due to invalid IL or missing references) <LoadAllyAsync>d__11 <LoadAllyAsync>d__ = default(<LoadAllyAsync>d__11); <LoadAllyAsync>d__.<>t__builder = AsyncUniTaskMethodBuilder.Create(); <LoadAllyAsync>d__.ally = ally; <LoadAllyAsync>d__.player = player; <LoadAllyAsync>d__.slot = slot; <LoadAllyAsync>d__.<>1__state = -1; ((AsyncUniTaskMethodBuilder)(ref <LoadAllyAsync>d__.<>t__builder)).Start<<LoadAllyAsync>d__11>(ref <LoadAllyAsync>d__); return ((AsyncUniTaskMethodBuilder)(ref <LoadAllyAsync>d__.<>t__builder)).Task; } private static void Despawn(int playerId) { if (!Allies.TryGetValue(playerId, out var ally)) { return; } MpSafe.Run("MpAllyUnits.Despawn", delegate { if ((Object)(object)ally.View != (Object)null) { Object.Destroy((Object)(object)((Component)ally.View).gameObject); } if ((Object)(object)ally.Root != (Object)null) { Object.Destroy((Object)(object)ally.Root); } }); Allies.Remove(playerId); } public static void DespawnAll() { foreach (int item in Allies.Keys.ToList()) { Despawn(item); } } public static void TickViews() { if (Allies.Count == 0) { return; } foreach (Ally value in Allies.Values) { UnitView view = value.View; if (!((Object)(object)view == (Object)null) && !value.Loading) { MpSafe.Run("MpAllyUnits.TickView", delegate { view.Tick(); }); } } } public static void SyncVitals(MpBattleSeat seat) { if (!Allies.TryGetValue(seat.PlayerId, out var ally) || ally.Unit == null) { return; } MpSafe.Run("MpAllyUnits.SyncVitals", delegate { //IL_0151: Unknown result type (might be due to invalid IL or missing references) //IL_0236: Unknown result type (might be due to invalid IL or missing references) //IL_0253: Unknown result type (might be due to invalid IL or missing references) PlayerUnit unit = ally.Unit; UnitView view = ally.View; if (seat.MaxHp > 0 && ((Unit)unit).MaxHp != seat.MaxHp) { ((Unit)unit).SetMaxHp(Mathf.Clamp(seat.Hp, 0, seat.MaxHp), seat.MaxHp); if (view != null) { view.SetPlayerHpBarLength(seat.MaxHp); } if (view != null) { view.OnMaxHpChanged(); } } int num = ((seat.MaxHp > 0) ? Mathf.Clamp(seat.Hp, 0, seat.MaxHp) : seat.Hp); int num2 = ((ally.LastHp != int.MinValue) ? (num - ally.LastHp) : 0); int num3 = Mathf.Max(0, seat.Block); int num4 = Mathf.Max(0, seat.Shield); bool num5 = num3 != ally.LastBlock || num4 != ally.LastShield; ((Unit)unit).Block = num3; ((Unit)unit).Shield = num4; ((Unit)unit).Hp = num; if (num2 < 0 && (Object)(object)view != (Object)null) { view.OnDamageReceived(DamageInfo.HpLose((float)(-num2), true)); } else if (num2 > 0 && (Object)(object)view != (Object)null) { view.OnHealingReceived(num2); } if (num5 && (Object)(object)view != (Object)null) { view.UpdateShieldColliders(); UnitStatusWidget statusWidget = view._statusWidget; if (statusWidget != null) { statusWidget.OnBlockShieldChanged(); } if (ally.LastShield != int.MinValue) { bool flag = false; if (num4 > ally.LastShield) { view.CreateLocalShieldEffect("GainShield", true); flag = true; } if (num3 > ally.LastBlock) { view.CreateLocalShieldEffect("GainBlock", false); flag = true; } if (flag) { AudioManager.PlaySfx("ShieldCast", 0.5f); } } } ally.LastHp = num; ally.LastBlock = num3; ally.LastShield = num4; SyncStatusEffects(ally, seat); if (num <= 0 && (int)((Unit)unit).Status == 0) { ((Unit)unit).Status = (UnitStatus)2; if (view != null) { view.DeathAnimation(); } } else if (num > 0 && (int)((Unit)unit).Status != 0) { Revive(ally); } }); } public static void Revive(int playerId) { if (Allies.TryGetValue(playerId, out var ally)) { MpSafe.Run("MpAllyUnits.Revive", delegate { Revive(ally); }); } } private static void Revive(Ally ally) { if (ally.Unit != null) { ((Unit)ally.Unit).Status = (UnitStatus)0; } UnitView view = ally.View; if (!((Object)(object)view == (Object)null)) { view._invincible = false; view.SpineIdle(false); } } private static void SyncStatusEffects(Ally ally, MpBattleSeat seat) { PlayerUnit unit = ally.Unit; Dictionary<string, (int, int, string)> dictionary = new Dictionary<string, (int, int, string)>(); foreach (string statusEffect in seat.StatusEffects) { string[] array = statusEffect.Split(':'); if (array.Length >= 3) { int.TryParse(array[1], out var result); int.TryParse(array[2], out var result2); dictionary[array[0]] = (result, result2, (array.Length > 3) ? array[3] : string.Empty); } } foreach (StatusEffect item in ((Unit)unit).StatusEffects.ToList()) { if (!dictionary.ContainsKey(((GameEntity)item).Id)) { ((Unit)unit)._statusEffects.Remove(item); item.Owner = null; UnitView view = ally.View; if (view != null) { view.OnRemoveStatusEffect(item); } } } foreach (KeyValuePair<string, (int, int, string)> entry in dictionary) { StatusEffect val = ((IEnumerable<StatusEffect>)((Unit)unit).StatusEffects).FirstOrDefault((Func<StatusEffect, bool>)((StatusEffect s) => ((GameEntity)s).Id == entry.Key)); if (val == null) { StatusEffect val2 = Library.TryCreateStatusEffect(entry.Key); if (val2 != null) { if (val2.HasLevel && entry.Value.Item1 >= 0) { val2.Level = entry.Value.Item1; } if (val2.HasDuration && entry.Value.Item2 >= 0) { val2.Duration = entry.Value.Item2; } if (!string.IsNullOrEmpty(entry.Value.Item3)) { val2.SourceCard = Library.TryCreateCard(entry.Value.Item3, false, (int?)null); } val2.Owner = (Unit)(object)unit; ((Unit)unit)._statusEffects.Add(val2); UnitView view2 = ally.View; if (view2 != null) { view2.OnAddStatusEffect(val2, (StatusEffectAddResult)0); } } } else { if (val.HasLevel && entry.Value.Item1 >= 0 && val.Level != entry.Value.Item1) { val.Level = entry.Value.Item1; } if (val.HasDuration && entry.Value.Item2 >= 0 && val.Duration != entry.Value.Item2) { val.Duration = entry.Value.Item2; } } } } public static void PlayDebut() { foreach (Ally value in Allies.Values) { UnitView view = value.View; if (!((Object)(object)view == (Object)null) && !value.Loading && !value.Hidden) { MpSafe.Run("MpAllyUnits.PlayDebut", delegate { view.DebutAnimation(); }); } } } public static void SetHidden(bool hidden, bool withStatus) { foreach (Ally value in Allies.Values) { value.Hidden = hidden; UnitView view = value.View; if ((Object)(object)view == (Object)null) { continue; } MpSafe.Run("MpAllyUnits.SetHidden", delegate { if (hidden) { view.IsHidden = true; } else { view.Show(withStatus); } }); } } public static void PlayAnimation(int playerId, string animationName) { //IL_0067: Unknown result type (might be due to invalid IL or missing references) if (!string.IsNullOrEmpty(animationName) && Allies.TryGetValue(playerId, out var ally) && !((Object)(object)ally.View == (Object)null) && !ally.Loading && !ally.Shooting && (int)ally.View._status == 0) { MpSafe.Run("MpAllyUnits.PlayAnimation", delegate { ally.View.PlayAnimation(animationName); }); } } public static void PlayHit(int playerId, DamageInfo info) { //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) if (Allies.TryGetValue(playerId, out var ally) && !((Object)(object)ally.View == (Object)null) && !ally.Loading) { MpSafe.Run("MpAllyUnits.PlayHit", delegate { //IL_0013: Unknown result type (might be due to invalid IL or missing references) UnitView view = ally.View; view.UpdateShieldColliders(); view.ComingDamage = info; view.Hit(false, 1f, false); }); } } public static void AimAt(int playerId, int targetEnemyIndex) { if (Allies.TryGetValue(playerId, out var ally) && !((Object)(object)ally.View == (Object)null)) { MpSafe.Run("MpAllyUnits.AimAt", delegate { AimInternal(ally, targetEnemyIndex); }); } } private static UnitView AimInternal(Ally ally, int targetEnemyIndex) { GameMaster instance = Singleton<GameMaster>.Instance; object obj; if (instance == null) { obj = null; } else { GameRunController currentGameRun = instance.CurrentGameRun; obj = ((currentGameRun != null) ? currentGameRun.Battle : null); } BattleController val = (BattleController)obj; if (val == null || (Object)(object)ally.View == (Object)null) { return null; } EnemyUnit val2 = ((IEnumerable<EnemyUnit>)val.EnemyGroup).FirstOrDefault((Func<EnemyUnit, bool>)((EnemyUnit e) => e.Index == targetEnemyIndex && ((Unit)e).IsAlive)) ?? val.FirstAliveEnemy; UnitView val3 = ((val2 != null) ? GameDirector.GetEnemy(val2) : null); if ((Object)(object)val3 == (Object)null) { return null; } ally.View.Target = val3; ally.View.Targets = new List<UnitView> { val3 }; return val3; } public static void PlayShoot(int playerId, string gunName, int targetEnemyIndex) { if (string.IsNullOrEmpty(gunName) || gunName == "Instant" || gunName == "Empty" || !Allies.TryGetValue(playerId, out var ally) || (Object)(object)ally.View == (Object)null || ally.Shooting) { return; } MpSafe.Run("MpAllyUnits.PlayShoot", delegate { UnitView val = AimInternal(ally, targetEnemyIndex); if (!((Object)(object)val == (Object)null)) { StageGunHit(val, gunName); ally.Shooting = true; ((MonoBehaviour)MpPlugin.Instance).StartCoroutine(ShootRoutine(ally, gunName)); } }); } private static IEnumerator ShootRoutine(Ally ally, string gunName) { if (MpSafe.Run("MpAllyUnits.StartShoot", delegate { ((MonoBehaviour)MpPlugin.Instance).StartCoroutine(ally.View.Shoot(gunName, (GunType)0)); return true; }, fallback: false)) { float waited = 0f; while (waited < 8f && (Object)(object)ally.View != (Object)null && (int)ally.View._status != 0) { waited += Time.unscaledDeltaTime; yield return null; } } MpSafe.Run("MpAllyUnits.EndShoot", delegate { ForceIdle(ally); }); ally.Shooting = false; } private static void ForceIdle(Ally ally) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) UnitView view = ally.View; if (!((Object)(object)view == (Object)null) && (int)view._status != 0) { MpPlugin.Log.LogWarning((object)("Ally shot never finished; forcing " + ally.CharacterId + " back to idle")); view._shootCounting = false; view.ShowEndActs(); } } private static void StageGunHit(UnitView targetView, string gunName) { //IL_0018: 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_0032: Expected O, but got Unknown _displacedGunHit = GameDirector._gunHitArgs; _allyGunHit = new GunHitArgs(false, (IList<ValueTuple<UnitView, DamageInfo>>)new List<(UnitView, DamageInfo)> { (targetView, DamageInfo.Attack(0f, false)) }, gunName); GameDirector._gunHitArgs = _allyGunHit; } internal static bool TryHandleAllyGunHit() { GunHitArgs gunHitArgs = GameDirector._gunHitArgs; if (gunHitArgs == null) { return true; } if (gunHitArgs != _allyGunHit) { return false; } GameDirector._gunHitArgs = _displacedGunHit; _allyGunHit = null; _displacedGunHit = null; foreach (var pair in gunHitArgs.Pairs) { if ((Object)(object)pair.Item1 != (Object)null) { pair.Item1.HitEnd(); } } return true; } public static bool TryGetHeadScreenPoint(int playerId, out Vector2 position) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_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_0080: 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_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) position = default(Vector2); if (!Allies.TryGetValue(playerId, out var value) || (Object)(object)value.View == (Object)null) { return false; } Camera main = Camera.main; if ((Object)(object)main == (Object)null) { return false; } Transform val = (((Object)(object)value.View.ChatPoint != (Object)null) ? value.View.ChatPoint : ((Component)value.View).transform); Vector3 val2 = main.WorldToScreenPoint(val.position); if (val2.z < 0f) { return false; } position = new Vector2(val2.x, val2.y); return true; } } public static class MpEmotes { private readonly struct Emote { internal readonly MpText Line; internal readonly string Animation; internal readonly bool ClockTick; internal Emote(MpText line, string animation, bool clockTick) { Line = line; Animation = animation; ClockTick = clockTick; } } private static readonly Emote[] Emotes = new Emote[3] { new Emote(MpText.EmoteNice, null, clockTick: false), new Emote(MpText.EmoteNegative, null, clockTick: false), new Emote(MpText.EmoteHurryUp, "skill", clockTick: true) }; private static readonly KeyCode[] Keys; private static readonly KeyCode[] NumpadKeys; private const float BubbleSeconds = 2.5f; private const float Cooldown = 1.2f; private const float TickVolume = 0.5f; private static float _nextEmote; private static string _clockTick; public static bool Available { get { if (!MpSession.IsActive || !MpBattleSync.InBattle) { return false; } if (MpDownedPlayers.OutOfFight || MpBattleSync.AtEndOfBattleGate) { return true; } if (MpBattleSync.LocalTurnComplete) { return !MpBattleSync.AllSeatsCompleted(MpBattleSync.CurrentRound); } return false; } } private static string ClockTick { get { if (_clockTick != null) { return _clockTick; } string text = MpSafe.Run("MpEmotes.ClockTick", delegate { StatusEffectConfig obj = StatusEffectConfig.FromId("TimeAuraSe"); return (obj == null) ? null : obj.SFX; }, null); _clockTick = ((string.IsNullOrEmpty(text) || text == "Default") ? "Buff" : text); MpPlugin.Log.LogInfo((object)("Hurry-up emote will play the Time Pulse c