Decompiled source of Airport Remixed v3.0.0
tony4twentys.Airport_Remixed.dll
Decompiled a month ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; 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 BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using ExitGames.Client.Photon; using HarmonyLib; using Photon.Pun; using Photon.Realtime; using TMPro; using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.Events; using UnityEngine.SceneManagement; using UnityEngine.UI; using Zorro.Core; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: IgnoresAccessChecksTo("Assembly-CSharp")] [assembly: AssemblyTitle("Airport Remixed")] [assembly: AssemblyDescription("A BepInEx plugin for PEAK that remixes airport functionality")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("tony4twentys")] [assembly: AssemblyProduct("Airport Remixed")] [assembly: AssemblyCopyright("Copyright © tony4twentys 2025")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("3d39d492-4184-4d83-8b4a-1227283ca458")] [assembly: AssemblyFileVersion("3.0.0.0")] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("3.0.0.0")] [module: UnverifiableCode] namespace System.Runtime.CompilerServices { [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] internal sealed class IgnoresAccessChecksToAttribute : Attribute { public IgnoresAccessChecksToAttribute(string assemblyName) { } } } namespace tony4twentys.Airport_Remixed { [BepInPlugin("tony4twentys.Airport_Remixed", "Airport Remixed", "3.0.0")] [BepInProcess("PEAK.exe")] public class AirportRemixedPlugin : BaseUnityPlugin { public static ManualLogSource Logger; private const float MirrorCamToggleDuration = 20f; private ConfigEntry<KeyCode> muralModeModifierKey; private ConfigEntry<KeyCode> muralModeMainKey; private ConfigEntry<bool> muralModeRequireModifier; private bool isAirportScene; private bool holdLayoutForEditor; private bool mirrorCamToggled; private float mirrorCamToggleTime; private void Awake() { //IL_0025: Unknown result type (might be due to invalid IL or missing references) Logger = ((BaseUnityPlugin)this).Logger; Logger.LogInfo((object)"Plugin tony4twentys.Airport_Remixed is loaded."); BindConfig(); new Harmony("tony4twentys.Airport_Remixed.menu").PatchAll(); } private void BindConfig() { muralModeRequireModifier = ((BaseUnityPlugin)this).Config.Bind<bool>("MuralMode", "RequireModifierKey", true, "Whether MuralMode requires a modifier key to be held down"); muralModeModifierKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("MuralMode", "ModifierKey", (KeyCode)308, "The modifier key for MuralMode (only used if RequireModifierKey is true)"); muralModeMainKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("MuralMode", "MainKey", (KeyCode)112, "The main key to trigger MuralMode"); } private void OnEnable() { SceneManager.sceneLoaded += OnSceneLoaded; } private void OnDisable() { SceneManager.sceneLoaded -= OnSceneLoaded; ResetAirportState(); } private void Update() { if (CheckMuralModeKey()) { ToggleMirrorCam(); } AirportMoveRuntime.Tick(); if (mirrorCamToggled && Time.time - mirrorCamToggleTime >= 20f) { RestoreMirrorCam(); } } private void OnSceneLoaded(Scene scene, LoadSceneMode mode) { isAirportScene = ((Scene)(ref scene)).name == "Airport"; ResetAirportState(); if (isAirportScene) { holdLayoutForEditor = AirportLayoutLoader.IsAirportEditorLoaded(); if (holdLayoutForEditor) { Logger.LogInfo((object)"Airport editor is loaded — leaving vanilla. The editor loads Parents projects."); } else { ((MonoBehaviour)this).StartCoroutine(ApplyLayoutRoutine()); } } } private void OnGUI() { AirportLayoutLoadFlow.OnGUI(); } private void ResetAirportState() { ((MonoBehaviour)this).StopAllCoroutines(); AirportLayoutLoadFlow.Cancel(); mirrorCamToggled = false; AirportMoveRuntime.Clear(); } private IEnumerator ApplyLayoutRoutine() { IEnumerator steps = AirportLayoutLoadFlow.Run(); while (true) { object current; try { if (!steps.MoveNext()) { break; } current = steps.Current; } catch (Exception ex) { AirportLayoutLoadFlow.Cancel(); Logger.LogError((object)("Failed to apply airport layout: " + ex.Message)); break; } yield return current; } } private bool CheckMuralModeKey() { //IL_0006: 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) if (!Input.GetKeyDown(muralModeMainKey.Value)) { return false; } if (muralModeRequireModifier.Value) { return Input.GetKey(muralModeModifierKey.Value); } return true; } private void ToggleMirrorCam() { GameObject val = GameObject.Find("Map/Mirror (1)/Mirror Cam"); if ((Object)(object)val == (Object)null) { Logger.LogWarning((object)"Mirror Cam not found at path: Map/Mirror (1)/Mirror Cam"); return; } val.SetActive(false); mirrorCamToggled = true; mirrorCamToggleTime = Time.time; } private void RestoreMirrorCam() { GameObject val = GameObject.Find("Map/Mirror (1)/Mirror Cam"); if (!((Object)(object)val == (Object)null)) { val.SetActive(true); mirrorCamToggled = false; } } } public static class PluginInfo { public const string PLUGIN_GUID = "tony4twentys.Airport_Remixed"; public const string PLUGIN_NAME = "Airport Remixed"; public const string PLUGIN_VERSION = "3.0.0"; } [Serializable] public class AirportLayoutFile { public const string CurrentVersion = "5"; public string version = "5"; public LayoutBehavior[] behaviors; public LayoutTrigger[] triggers; public LayoutFunction[] functions; public LayoutPlacement[] placements; public static AirportLayoutFile Parse(string json) { if (string.IsNullOrEmpty(json)) { return null; } if (json[0] == '\ufeff') { json = json.Substring(1); } AirportLayoutFile airportLayoutFile = new AirportLayoutFile(); if (TryParseFunctions(json, out var array, out var hasKey) && hasKey) { airportLayoutFile.functions = array ?? new LayoutFunction[0]; } return airportLayoutFile; } public static bool TryParseFunctions(string json, out LayoutFunction[] functions, out bool hasKey) { functions = null; hasKey = false; if (string.IsNullOrEmpty(json)) { return false; } int num = json.IndexOf("\"functions\"", StringComparison.Ordinal); if (num < 0) { return false; } hasKey = true; int num2 = json.IndexOf('[', num); if (num2 < 0) { functions = new LayoutFunction[0]; return true; } int num3 = MatchingBracket(json, num2); if (num3 < 0) { functions = new LayoutFunction[0]; return true; } List<string> list = TopLevelObjects(json.Substring(num2, num3 - num2 + 1)); List<LayoutFunction> list2 = new List<LayoutFunction>(list.Count); for (int i = 0; i < list.Count; i++) { LayoutFunction layoutFunction = ParseOneFunction(list[i]); if (layoutFunction != null && !string.IsNullOrEmpty(layoutFunction.id)) { list2.Add(layoutFunction); } } functions = list2.ToArray(); return true; } private static LayoutFunction ParseOneFunction(string objectJson) { LayoutFunction layoutFunction = JsonUtility.FromJson<LayoutFunction>(objectJson); if (layoutFunction == null) { return null; } LayoutStep[] array = ParseSteps(objectJson); if (array.Length != 0 || layoutFunction.steps == null) { layoutFunction.steps = array; } else { FillMissingPoses(layoutFunction.steps, objectJson); } layoutFunction.states = ParseStates(objectJson, layoutFunction.states); layoutFunction.buttons = ParseButtons(objectJson, layoutFunction.buttons); return layoutFunction; } private static LayoutStep[] ParseSteps(string json) { string text = ExtractNamedArray(json, "steps"); if (string.IsNullOrEmpty(text)) { return new LayoutStep[0]; } List<string> list = TopLevelObjects(text); List<LayoutStep> list2 = new List<LayoutStep>(list.Count); for (int i = 0; i < list.Count; i++) { LayoutStep layoutStep = JsonUtility.FromJson<LayoutStep>(list[i]); if (layoutStep != null) { LayoutPose[] array = ParsePoses(list[i]); if (array.Length != 0 || layoutStep.poses == null) { layoutStep.poses = array; } list2.Add(layoutStep); } } return list2.ToArray(); } private static LayoutPose[] ParsePoses(string stepJson) { string text = ExtractNamedArray(stepJson, "poses"); if (string.IsNullOrEmpty(text)) { return new LayoutPose[0]; } List<string> list = TopLevelObjects(text); List<LayoutPose> list2 = new List<LayoutPose>(list.Count); for (int i = 0; i < list.Count; i++) { LayoutPose layoutPose = JsonUtility.FromJson<LayoutPose>(list[i]); if (layoutPose != null) { list2.Add(layoutPose); } } return list2.ToArray(); } private static void FillMissingPoses(LayoutStep[] steps, string functionJson) { if (steps == null || steps.Length == 0) { return; } string text = ExtractNamedArray(functionJson, "steps"); if (string.IsNullOrEmpty(text)) { return; } List<string> list = TopLevelObjects(text); int num = Mathf.Min(steps.Length, list.Count); for (int i = 0; i < num; i++) { if (steps[i] != null && (steps[i].poses == null || steps[i].poses.Length == 0)) { steps[i].poses = ParsePoses(list[i]); } } } private static LayoutFnState[] ParseStates(string functionJson, LayoutFnState[] fallback) { string text = ExtractNamedArray(functionJson, "states"); if (string.IsNullOrEmpty(text)) { return fallback ?? new LayoutFnState[0]; } List<string> list = TopLevelObjects(text); if (list.Count == 0) { return fallback ?? new LayoutFnState[0]; } List<LayoutFnState> list2 = new List<LayoutFnState>(list.Count); for (int i = 0; i < list.Count; i++) { LayoutFnState layoutFnState = JsonUtility.FromJson<LayoutFnState>(list[i]); if (layoutFnState != null) { LayoutStep[] array = ParseSteps(list[i]); if (array.Length != 0 || layoutFnState.steps == null) { layoutFnState.steps = array; } list2.Add(layoutFnState); } } return list2.ToArray(); } private static LayoutMenuButton[] ParseButtons(string functionJson, LayoutMenuButton[] fallback) { string text = ExtractNamedArray(functionJson, "buttons"); if (string.IsNullOrEmpty(text)) { return fallback ?? new LayoutMenuButton[0]; } List<string> list = TopLevelObjects(text); if (list.Count == 0) { return fallback ?? new LayoutMenuButton[0]; } List<LayoutMenuButton> list2 = new List<LayoutMenuButton>(list.Count); for (int i = 0; i < list.Count; i++) { LayoutMenuButton layoutMenuButton = JsonUtility.FromJson<LayoutMenuButton>(list[i]); if (layoutMenuButton != null) { LayoutStep[] array = ParseSteps(list[i]); if (array.Length != 0 || layoutMenuButton.steps == null) { layoutMenuButton.steps = array; } list2.Add(layoutMenuButton); } } return list2.ToArray(); } private static string ExtractNamedArray(string json, string name) { int num = json.IndexOf("\"" + name + "\"", StringComparison.Ordinal); if (num < 0) { return null; } int num2 = json.IndexOf('[', num); if (num2 < 0) { return null; } int num3 = MatchingBracket(json, num2); if (num3 < 0) { return null; } return json.Substring(num2, num3 - num2 + 1); } private static List<string> TopLevelObjects(string arrayJson) { List<string> list = new List<string>(); if (string.IsNullOrEmpty(arrayJson)) { return list; } int i; for (i = 0; i < arrayJson.Length && arrayJson[i] != '['; i++) { } i++; while (i < arrayJson.Length) { switch (arrayJson[i]) { default: i++; continue; case '{': { int num = MatchingBrace(arrayJson, i); if (num >= 0) { list.Add(arrayJson.Substring(i, num - i + 1)); i = num + 1; continue; } break; } case ']': break; } break; } return list; } private static int MatchingBrace(string json, int open) { int num = 0; bool flag = false; bool flag2 = false; for (int i = open; i < json.Length; i++) { char c = json[i]; if (flag) { if (flag2) { flag2 = false; continue; } switch (c) { case '\\': flag2 = true; break; case '"': flag = false; break; } continue; } switch (c) { case '"': flag = true; break; case '{': num++; break; case '}': num--; if (num == 0) { return i; } break; } } return -1; } public static string WithoutPlacements(string json) { if (string.IsNullOrEmpty(json)) { return json; } int num = json.IndexOf("\"functions\"", StringComparison.Ordinal); if (num < 0) { return json; } int num2 = json.IndexOf('[', num); if (num2 < 0) { return json; } int num3 = MatchingBracket(json, num2); if (num3 < 0) { return json; } return json.Substring(0, num3 + 1) + "\n}"; } private static int MatchingBracket(string json, int open) { int num = 0; bool flag = false; bool flag2 = false; for (int i = open; i < json.Length; i++) { char c = json[i]; if (flag) { if (flag2) { flag2 = false; continue; } switch (c) { case '\\': flag2 = true; break; case '"': flag = false; break; } continue; } switch (c) { case '"': flag = true; break; case '[': num++; break; case ']': num--; if (num == 0) { return i; } break; } } return -1; } } [Serializable] public class LayoutBehavior { public string id; public string kind; public string target; public string targetId; public bool enabled = true; public string component; public string member; public string text; public string extra; public Vector3 vector; public Vector3 start; public Vector3 end; public Vector3 startEuler; public Vector3 endEuler; public float number; public bool flag; } [Serializable] public class LayoutTrigger { public string id; public string target; public string targetId; public bool enabled = true; public string kind = "prompt"; public string mode = "cycle"; public string prompt = "Open"; public float speed = 1f; public int startStop; public LayoutStop[] stops; } [Serializable] public class LayoutStop { public string id; public string name; public string prompt; public string menuLabel; public Vector3 position; public Vector3 euler; } [Serializable] public class LayoutFunction { public string id; public string kind = "menu"; public string target; public string targetId; public bool enabled = true; public string name = "Menu"; public string triggerKind = "prompt"; public string title; public string prompt = "Open"; public string listenButtonId; public string action = "none"; public string actionMenuId; public Vector3 end; public Vector3 endEuler; public Vector3 endScale; public bool hasEnd; public float speed = 1f; public bool loop; public int loopCount; public bool random; public LayoutStep[] steps; public LayoutFnState[] states; public int startState; public LayoutMenuButton[] buttons; } [Serializable] public class LayoutFnState { public string id; public string name = "State"; public string title; public string prompt = "Open"; public LayoutStep[] steps; public int next = -1; public float autoAfter; } [Serializable] public class LayoutMenuButton { public string id; public string label = "Button"; public string action = "none"; public string actionMenuId; public string target; public string targetId; public Vector3 end; public Vector3 endEuler; public bool hasEnd; public float speed = 1f; public LayoutStep[] steps; } [Serializable] public class LayoutStep { public string kind = "move"; public float delay; public float speed = 1f; public bool random; public string actionMenuId; public string clipName; public string animTarget; public string animTargetId; public bool together; public string material; public bool flag; public bool uninterruptible; public bool easeIn; public bool easeOut; public bool curve; public bool facePath; public float tilt; public float bend = 1f; public float lifetime; public string spawnId; public LayoutPose[] poses; } [Serializable] public class LayoutPose { public Vector3 position; public Vector3 euler; public Vector3 scale; public bool hasScale; public string target; public string targetId; public string material; public bool setColor; public Color color; public bool setUv; public Vector2 tile = Vector2.one; public Vector2 offset; } [Serializable] public class LayoutPlacement { public string id; public string group; public string op; public string source; public string parent; public string name; public bool setPosition; public Vector3 position; public bool setRotation; public Vector3 euler; public bool setScale; public Vector3 scale; public string material; public string texture; public bool setTexture; public bool setColor; public Color color; public bool setUv; public Vector2 tile = Vector2.one; public Vector2 offset; public bool setActive; public bool active = true; public bool solid; } internal static class AirportPhotoboothLoad { private const string BoothPath = "Map/Photobooth"; private const string MenuScreenPath = "Airport Remixed/AR_Main/AR_Photobooth_Stuff/Screen"; private static Quaternion _vanillaRotation = Quaternion.identity; private static bool _captured; internal static void CaptureVanilla() { //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_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) _captured = false; _vanillaRotation = Quaternion.identity; GameObject val = AirportLayoutLoader.FindSceneObject("Map/Photobooth"); if (!((Object)(object)val == (Object)null)) { _vanillaRotation = val.transform.rotation; _captured = true; } } internal static GameObject FindMenuScreen() { GameObject val = AirportLayoutLoader.FindSceneObject("Airport Remixed/AR_Main/AR_Photobooth_Stuff/Screen"); if ((Object)(object)val != (Object)null) { return val; } AirportRemixedPiece[] array = Object.FindObjectsByType<AirportRemixedPiece>((FindObjectsInactive)1, (FindObjectsSortMode)0); for (int i = 0; i < array.Length; i++) { if ((Object)(object)array[i] != (Object)null && string.Equals(array[i].id, "edit-335759fb", StringComparison.Ordinal)) { return ((Component)array[i]).gameObject; } } return null; } internal static bool IsOccupied(AirportPhotoboothKiosk kiosk, Vector3 worldPoint) { //IL_0000: 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_006f: 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_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_007e: Unknown result type (might be due to invalid IL or missing references) if (IsInsideBooth(worldPoint)) { return true; } if ((Object)(object)kiosk == (Object)null || (Object)(object)kiosk.insidePlaneTf == (Object)null) { return false; } GameObject val = AirportLayoutLoader.FindSceneObject("Map/Photobooth"); if ((Object)(object)val != (Object)null) { Vector3 val2 = kiosk.insidePlaneTf.position - val.transform.position; if (((Vector3)(ref val2)).sqrMagnitude > 144f) { return false; } } if (worldPoint.x < kiosk.insidePlaneTf.position.x) { return true; } return IsCharacterInside(kiosk, worldPoint); } internal static bool IsCharacterInside(AirportPhotoboothKiosk kiosk, Vector3 worldPoint) { //IL_0049: 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_004e: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_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_0069: 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_008a: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_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) if ((Object)(object)kiosk == (Object)null || (Object)(object)kiosk.insidePlaneTf == (Object)null) { return false; } GameObject val = AirportLayoutLoader.FindSceneObject("Map/Photobooth"); Transform obj = (((Object)(object)val != (Object)null) ? val.transform : ((Component)kiosk).transform); Quaternion val2 = (_captured ? _vanillaRotation : Quaternion.identity); Vector3 val3 = obj.rotation * Quaternion.Inverse(val2) * Vector3.right; if (((Vector3)(ref val3)).sqrMagnitude < 0.0001f) { val3 = Vector3.right; } return Vector3.Dot(worldPoint - kiosk.insidePlaneTf.position, val3) < 0f; } internal static bool IsRemixedMenuScreen(GameObject screen) { if ((Object)(object)screen == (Object)null) { return false; } Transform val = screen.transform; while ((Object)(object)val != (Object)null) { if (((Object)val).name == "Airport Remixed") { return true; } val = val.parent; } return false; } internal static void KeepMenuScreenOn(AirportPhotoboothKiosk kiosk) { GameObject val = FindMenuScreen(); if (!((Object)(object)val == (Object)null)) { if ((Object)(object)kiosk != (Object)null && ((Object)(object)kiosk.screen == (Object)null || (Object)(object)kiosk.screen != (Object)(object)val)) { kiosk.screen = val; } if (!val.activeSelf) { val.SetActive(true); } } } private static bool IsInsideBooth(Vector3 worldPoint) { //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_002c: 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) //IL_00b5: 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_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_00d9: 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_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_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_0098: 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) GameObject val = AirportLayoutLoader.FindSceneObject("Map/Photobooth"); if ((Object)(object)val == (Object)null) { return false; } Vector3 position = val.transform.position; Renderer[] componentsInChildren = val.GetComponentsInChildren<Renderer>(true); Bounds val2 = default(Bounds); bool flag = false; foreach (Renderer val3 in componentsInChildren) { if ((Object)(object)val3 == (Object)null || !val3.enabled) { continue; } Vector3 val4 = ((Component)val3).transform.position - position; if (!(((Vector3)(ref val4)).sqrMagnitude > 100f) && !IsKioskBranch(((Component)val3).transform)) { if (!flag) { val2 = val3.bounds; flag = true; } else { ((Bounds)(ref val2)).Encapsulate(val3.bounds); } } } if (!flag) { ((Bounds)(ref val2))..ctor(position + Vector3.up * 1.8f, new Vector3(4.5f, 4f, 4.5f)); return ((Bounds)(ref val2)).Contains(worldPoint); } ((Bounds)(ref val2)).Expand(1.25f); return ((Bounds)(ref val2)).Contains(worldPoint); } private static bool IsKioskBranch(Transform t) { while ((Object)(object)t != (Object)null) { if ((((Object)t).name ?? string.Empty).StartsWith("Kiosk", StringComparison.OrdinalIgnoreCase)) { return true; } t = t.parent; } return false; } } [HarmonyPatch(typeof(AirportPhotoboothKiosk), "Update")] internal static class Patch_PhotoboothInside { private static bool _logged; private static void Postfix(AirportPhotoboothKiosk __instance) { //IL_0025: Unknown result type (might be due to invalid IL or missing references) try { if (!((Object)(object)__instance == (Object)null)) { AirportPhotoboothLoad.KeepMenuScreenOn(__instance); Character localCharacter = Character.localCharacter; bool enabled = (__instance.inPhotobooth = (Object)(object)localCharacter != (Object)null && AirportPhotoboothLoad.IsOccupied(__instance, localCharacter.Center)); if ((Object)(object)__instance.displayCamera != (Object)null) { ((Behaviour)__instance.displayCamera).enabled = enabled; } } } catch (Exception ex) { if (!_logged) { _logged = true; ManualLogSource logger = AirportRemixedPlugin.Logger; if (logger != null) { logger.LogError((object)("Photobooth Update failed: " + ex)); } } } } } internal static class AirportUi { private static readonly Color ButtonColor = new Color(0.1792453f, 0.1253449f, 0.09046815f, 62f / 85f); private static readonly Color ButtonHover = new Color(0.26f, 0.18f, 0.13f, 0.92f); private static readonly Color Accent = new Color(0.55f, 0.42f, 0.22f, 0.95f); private static readonly Color Cream = new Color(0.95f, 0.93f, 0.88f, 1f); private static GameObject _buttonDonor; private static TMP_FontAsset _cachedFont; internal static Button CreatePeakButton(Transform parent, string label, UnityAction onClick) { GameObject val = TryClonePauseButton(parent, label) ?? CreatePlainButton(parent, label); LayoutElement obj = val.GetComponent<LayoutElement>() ?? val.AddComponent<LayoutElement>(); obj.minHeight = 34f; obj.preferredHeight = 34f; obj.flexibleWidth = 1f; NormalizeLabel(val, label); Button val2 = val.GetComponent<Button>() ?? val.AddComponent<Button>(); ((UnityEventBase)val2.onClick).RemoveAllListeners(); if (onClick != null) { ((UnityEvent)val2.onClick).AddListener(onClick); } Canvas.ForceUpdateCanvases(); return val2; } internal static void ApplyFont(TextMeshProUGUI text) { if (!((Object)(object)text == (Object)null)) { TMP_FontAsset gameFont = GetGameFont(); if ((Object)(object)gameFont != (Object)null) { ((TMP_Text)text).font = gameFont; } } } private static GameObject TryClonePauseButton(Transform parent, string label) { try { GameObject val = ResolveButtonDonor(); if ((Object)(object)val == (Object)null) { return null; } GameObject val2 = Object.Instantiate<GameObject>(val, parent, false); ((Object)val2).name = "AR_Btn_" + Sanitize(label); val2.SetActive(true); LocalizedText[] componentsInChildren = val2.GetComponentsInChildren<LocalizedText>(true); for (int i = 0; i < componentsInChildren.Length; i++) { if ((Object)(object)componentsInChildren[i] != (Object)null) { ((Behaviour)componentsInChildren[i]).enabled = false; } } return val2; } catch { _buttonDonor = null; return null; } } private static GameObject ResolveButtonDonor() { if ((Object)(object)_buttonDonor != (Object)null) { return _buttonDonor; } try { PauseMenuMainPage val = (((Object)(object)GUIManager.instance != (Object)null) ? GUIManager.instance.pauseMenuMainPage : null); if ((Object)(object)val == (Object)null) { val = Object.FindFirstObjectByType<PauseMenuMainPage>((FindObjectsInactive)1); } Button val2 = (((Object)(object)val != (Object)null) ? (val.m_resumeButton ?? val.m_settingsButton ?? val.m_quitButton) : null); if ((Object)(object)val2 != (Object)null) { _buttonDonor = ((Component)val2).gameObject; } } catch { } return _buttonDonor; } private static GameObject CreatePlainButton(Transform parent, string label) { //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Expected O, but got Unknown //IL_0065: 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_0082: 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_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_00a7: 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_00ca: 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_00e3: 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_00f9: 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_012e: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("AR_Btn_" + Sanitize(label), new Type[4] { typeof(RectTransform), typeof(CanvasRenderer), typeof(Image), typeof(Button) }); val.transform.SetParent(parent, false); Image component = val.GetComponent<Image>(); ((Graphic)component).color = ButtonColor; Button component2 = val.GetComponent<Button>(); ((Selectable)component2).targetGraphic = (Graphic)(object)component; ColorBlock colors = ((Selectable)component2).colors; ((ColorBlock)(ref colors)).normalColor = ButtonColor; ((ColorBlock)(ref colors)).highlightedColor = ButtonHover; ((ColorBlock)(ref colors)).pressedColor = Accent; ((Selectable)component2).colors = colors; GameObject val2 = new GameObject("Text", new Type[1] { typeof(RectTransform) }); val2.transform.SetParent(val.transform, false); RectTransform component3 = val2.GetComponent<RectTransform>(); component3.anchorMin = Vector2.zero; component3.anchorMax = Vector2.one; component3.offsetMin = Vector2.zero; component3.offsetMax = Vector2.zero; TextMeshProUGUI obj = val2.AddComponent<TextMeshProUGUI>(); ((TMP_Text)obj).text = label ?? string.Empty; ((TMP_Text)obj).alignment = (TextAlignmentOptions)514; ((Graphic)obj).color = Cream; ApplyFont(obj); return val; } private static void NormalizeLabel(GameObject button, string label) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Expected O, but got Unknown //IL_00a0: Unknown result type (might be due to invalid IL or missing references) HorizontalOrVerticalLayoutGroup component = button.GetComponent<HorizontalOrVerticalLayoutGroup>(); if ((Object)(object)component != (Object)null) { ((LayoutGroup)component).childAlignment = (TextAnchor)4; ((LayoutGroup)component).padding = new RectOffset(8, 8, 2, 2); component.childForceExpandWidth = true; component.childForceExpandHeight = true; } ContentSizeFitter component2 = button.GetComponent<ContentSizeFitter>(); if ((Object)(object)component2 != (Object)null) { component2.horizontalFit = (FitMode)0; } TextMeshProUGUI[] componentsInChildren = button.GetComponentsInChildren<TextMeshProUGUI>(true); foreach (TextMeshProUGUI val in componentsInChildren) { if ((Object)(object)val == (Object)null) { continue; } ((Component)val).gameObject.SetActive(true); ((Behaviour)val).enabled = true; ((TMP_Text)val).text = label ?? string.Empty; ((TMP_Text)val).alignment = (TextAlignmentOptions)514; ((Graphic)val).color = Cream; ((TMP_Text)val).enableAutoSizing = true; ((TMP_Text)val).fontSizeMin = 11f; ((TMP_Text)val).fontSizeMax = 20f; ((TMP_Text)val).overflowMode = (TextOverflowModes)1; ((TMP_Text)val).enableWordWrapping = false; ApplyFont(val); Transform val2 = ((TMP_Text)val).transform; while ((Object)(object)val2 != (Object)null && (Object)(object)val2 != (Object)(object)button.transform) { ((Component)val2).gameObject.SetActive(true); RectTransform val3 = (RectTransform)(object)((val2 is RectTransform) ? val2 : null); if ((Object)(object)val3 != (Object)null) { bool flag = (Object)(object)val2 == (Object)(object)((TMP_Text)val).transform; Stretch(val3, flag ? 8f : 0f, flag ? 2f : 0f); } ContentSizeFitter component3 = ((Component)val2).GetComponent<ContentSizeFitter>(); if ((Object)(object)component3 != (Object)null) { component3.horizontalFit = (FitMode)0; } val2 = val2.parent; } } } private static void Stretch(RectTransform rt, float padX, float padY) { //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_0019: 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) rt.anchorMin = Vector2.zero; rt.anchorMax = Vector2.one; rt.offsetMin = new Vector2(padX, padY); rt.offsetMax = new Vector2(0f - padX, 0f - padY); } private static TMP_FontAsset GetGameFont() { if ((Object)(object)_cachedFont != (Object)null) { return _cachedFont; } try { if ((Object)(object)GUIManager.instance != (Object)null) { TextMeshProUGUI componentInChildren = ((Component)GUIManager.instance).GetComponentInChildren<TextMeshProUGUI>(true); if ((Object)(object)componentInChildren != (Object)null && (Object)(object)((TMP_Text)componentInChildren).font != (Object)null) { _cachedFont = ((TMP_Text)componentInChildren).font; return _cachedFont; } } TextMeshProUGUI val = Object.FindFirstObjectByType<TextMeshProUGUI>((FindObjectsInactive)1); if ((Object)(object)val != (Object)null && (Object)(object)((TMP_Text)val).font != (Object)null) { _cachedFont = ((TMP_Text)val).font; } } catch { } return _cachedFont; } private static string Sanitize(string s) { if (string.IsNullOrEmpty(s)) { return "Btn"; } char[] array = s.ToCharArray(); for (int i = 0; i < array.Length; i++) { if (!char.IsLetterOrDigit(array[i])) { array[i] = '_'; } } return new string(array); } } internal static class AirportPickupLoad { private struct SavedPickup { public string path; public Vector3 position; public Vector3 euler; public Vector3 scale; public bool active; } private static readonly List<SavedPickup> Saved = new List<SavedPickup>(); internal static void Clear() { Saved.Clear(); } internal static void Remember(string path, GameObject go, Vector3 position, Vector3 euler, Vector3 scale, bool active) { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_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) if (LayoutSkip.IsAirportPickup(path) || LayoutSkip.IsAirportPickup(go)) { SavedPickup item = new SavedPickup { path = path, position = position, euler = euler, scale = scale, active = active }; Saved.Add(item); HoldPhysics(go); } } internal static void Reapply() { //IL_0068: 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_008a: Unknown result type (might be due to invalid IL or missing references) int num = 0; for (int i = 0; i < Saved.Count; i++) { SavedPickup savedPickup = Saved[i]; GameObject val = AirportLayoutLoader.FindSceneObject(savedPickup.path); if ((Object)(object)val == (Object)null) { val = GameObject.Find(savedPickup.path); } if ((Object)(object)val == (Object)null) { ManualLogSource logger = AirportRemixedPlugin.Logger; if (logger != null) { logger.LogWarning((object)("Pickup still missing after load: " + savedPickup.path)); } } else { val.transform.localPosition = savedPickup.position; val.transform.localEulerAngles = savedPickup.euler; val.transform.localScale = savedPickup.scale; val.transform.hasChanged = true; val.SetActive(savedPickup.active); HoldPhysics(val); num++; } } if (num > 0) { ManualLogSource logger2 = AirportRemixedPlugin.Logger; if (logger2 != null) { logger2.LogInfo((object)("Reapplied " + num + " moved airport pickup(s).")); } } } private static void HoldPhysics(GameObject go) { //IL_002b: 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) if ((Object)(object)go == (Object)null) { return; } Rigidbody[] componentsInChildren = go.GetComponentsInChildren<Rigidbody>(true); foreach (Rigidbody val in componentsInChildren) { if (!((Object)(object)val == (Object)null)) { val.isKinematic = true; val.linearVelocity = Vector3.zero; val.angularVelocity = Vector3.zero; } } } } internal static class AirportBehaviorBinder { private static readonly HashSet<string> UnknownKinds = new HashSet<string>(); public static void ApplySaved() { Apply(TryLoad(out var json), json); } public static void Apply(AirportLayoutFile layout) { Apply(layout, null); } public static void Apply(AirportLayoutFile layout, string rawJson) { AirportMoveRuntime.Clear(); int num = 0; int num2 = 0; bool flag = AirportLayoutLoader.IsAirportEditorLoaded() && ShouldUseJsonFunctions(layout, rawJson); if (flag) { for (int i = 0; i < layout.functions.Length; i++) { if (AirportMoveRuntime.Bind(layout.functions[i])) { num++; } else { num2++; } } } else { num += BakedAirportFunctions.Bind(); } AirportMoveRuntime.FinishBind(); LayoutBehavior[] array = layout?.behaviors; if (array != null) { foreach (LayoutBehavior layoutBehavior in array) { if (layoutBehavior == null || !layoutBehavior.enabled) { continue; } if (string.IsNullOrEmpty(layoutBehavior.kind)) { num2++; continue; } if (string.Equals(layoutBehavior.kind, "move", StringComparison.OrdinalIgnoreCase)) { if (AirportMoveRuntime.BindLegacyMove(layoutBehavior)) { num++; } else { num2++; } continue; } if (!UnknownKinds.Contains(layoutBehavior.kind)) { UnknownKinds.Add(layoutBehavior.kind); ManualLogSource logger = AirportRemixedPlugin.Logger; if (logger != null) { logger.LogWarning((object)("Airport Remixed has no handler yet for behavior kind '" + layoutBehavior.kind + "'. Target: " + layoutBehavior.target + ". The scene still loaded.")); } } num2++; } } ManualLogSource logger2 = AirportRemixedPlugin.Logger; if (logger2 != null) { logger2.LogInfo((object)("Airport layout behaviors: " + num + " bound, " + num2 + " skipped" + (flag ? (" (" + layout.functions.Length + " functions from editor JSON).") : " (last editor bake)."))); } if (num == 0) { ManualLogSource logger3 = AirportRemixedPlugin.Logger; if (logger3 != null) { logger3.LogWarning((object)"No airport functions bound — nothing was saved in the editor function list."); } } } private static bool ShouldUseJsonFunctions(AirportLayoutFile layout, string rawJson) { if (layout == null || layout.functions == null) { return false; } if (layout.functions.Length != 0) { return true; } return LooksLikeEmptyFunctionsArray(rawJson); } private static bool LooksLikeEmptyFunctionsArray(string json) { if (string.IsNullOrEmpty(json)) { return false; } int num = json.IndexOf("\"functions\"", StringComparison.Ordinal); if (num < 0) { return false; } int num2 = json.IndexOf('[', num); if (num2 < 0) { return false; } for (int i = num2 + 1; i < json.Length; i++) { char c = json[i]; if (c != ' ' && c != '\n' && c != '\r' && c != '\t') { return c == ']'; } } return false; } private static void CountNested(AirportLayoutFile file, out int buttons, out int poses) { buttons = 0; poses = 0; if (file == null || file.functions == null) { return; } for (int i = 0; i < file.functions.Length; i++) { LayoutFunction layoutFunction = file.functions[i]; if (layoutFunction == null) { continue; } if (layoutFunction.buttons != null) { buttons += layoutFunction.buttons.Length; } AddPoses(layoutFunction.steps, ref poses); if (layoutFunction.states == null) { continue; } for (int j = 0; j < layoutFunction.states.Length; j++) { if (layoutFunction.states[j] != null) { AddPoses(layoutFunction.states[j].steps, ref poses); } } if (layoutFunction.buttons == null) { continue; } for (int k = 0; k < layoutFunction.buttons.Length; k++) { if (layoutFunction.buttons[k] != null) { AddPoses(layoutFunction.buttons[k].steps, ref poses); } } } } private static void AddPoses(LayoutStep[] steps, ref int poses) { if (steps == null) { return; } for (int i = 0; i < steps.Length; i++) { if (steps[i] != null && steps[i].poses != null) { poses += steps[i].poses.Length; } } } private static AirportLayoutFile TryLoad(out string json) { json = null; try { json = AirportLayoutLoader.LoadLayoutJsonForBehaviors(); if (string.IsNullOrEmpty(json)) { return null; } AirportLayoutFile airportLayoutFile = AirportLayoutFile.Parse(json); int num = ((airportLayoutFile != null && airportLayoutFile.functions != null) ? airportLayoutFile.functions.Length : 0); int buttons = 0; int poses = 0; CountNested(airportLayoutFile, out buttons, out poses); ManualLogSource logger = AirportRemixedPlugin.Logger; if (logger != null) { logger.LogInfo((object)("Parsed airport functions JSON: " + num + " function(s), " + buttons + " menu button(s), " + poses + " pose(s), " + ((json != null) ? json.Length : 0) + " chars after strip.")); } return airportLayoutFile; } catch (Exception ex) { ManualLogSource logger2 = AirportRemixedPlugin.Logger; if (logger2 != null) { logger2.LogWarning((object)("Could not load layout behaviors: " + ex.Message)); } return null; } } } internal static class AirportMoveRuntime { private sealed class AutoWait { public string id; public float wait; public LayoutFunction fn; } private sealed class MoveTrack { public GameObject go; public Vector3 fromPos; public Quaternion fromRot; public Vector3 toPos; public Quaternion toRot; public float speed; public bool easeIn; public bool easeOut; public bool curve; public bool facePath; public bool useTurn; public float tilt; public float bend; public Quaternion pathFromRot; public float t; } private sealed class SeqJob { public string id; public LayoutStep[] steps; public bool random; public bool advanceState; public bool fromLocal; public bool uninterruptible; public bool loop; public int wraps; public readonly List<int> lockIds = new List<int>(); public GameObject fallback; public int step; public readonly List<MoveTrack> moves = new List<MoveTrack>(); public float wait; } internal const byte EventCode = 187; internal const string Magic = "tony4twentys.Airport_Remixed"; private static readonly List<LayoutFunction> Functions = new List<LayoutFunction>(); private static readonly Dictionary<GameObject, AirportFnPrompt> Prompts = new Dictionary<GameObject, AirportFnPrompt>(); private static readonly List<SeqJob> Jobs = new List<SeqJob>(); private static readonly Dictionary<string, int> PoseCursor = new Dictionary<string, int>(); private static readonly Dictionary<string, int> StateCursor = new Dictionary<string, int>(); private static readonly List<AutoWait> Autos = new List<AutoWait>(); private static readonly List<GameObject> TargetScratch = new List<GameObject>(8); private static readonly List<int> IncomingLock = new List<int>(8); private static readonly HashSet<string> StartedBackground = new HashSet<string>(); private static readonly HashSet<string> WarnedEmptyLoop = new HashSet<string>(); private static readonly Dictionary<int, Vector3> LoopPos = new Dictionary<int, Vector3>(8); private static readonly Dictionary<int, Quaternion> LoopRot = new Dictionary<int, Quaternion>(8); private static AirportMoveNet _net; public static int PromptCount => Prompts.Count; public static bool Bind(LayoutFunction function) { if (function == null || !function.enabled) { return false; } AirportAnimPlayback.Normalize(function); Functions.Add(function); EnsureNet(); return true; } public static bool BindLegacyMove(LayoutBehavior behavior) { //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_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) if (behavior == null) { return false; } return Bind(new LayoutFunction { id = behavior.id, kind = "trigger", triggerKind = "prompt", target = behavior.target, targetId = behavior.targetId, prompt = (string.IsNullOrEmpty(behavior.text) ? "Open" : behavior.text), action = "move", end = behavior.end, endEuler = behavior.endEuler, hasEnd = true, speed = ((behavior.number <= 0f) ? 1f : behavior.number) }); } public static void FinishBind() { RebuildPrompts(); ArmBackground(); } public static void NotifySceneReady() { ArmBackground(); } public static void Tick() { AirportAnimMenu.Tick(); foreach (KeyValuePair<GameObject, AirportFnPrompt> prompt in Prompts) { if (prompt.Value != null) { prompt.Value.Follow(); } } for (int num = Jobs.Count - 1; num >= 0; num--) { if (!StepJob(Jobs[num])) { SeqJob seqJob = Jobs[num]; Jobs.RemoveAt(num); if (seqJob != null && seqJob.advanceState) { ArmAutoAfter(seqJob.id); } } } for (int num2 = Autos.Count - 1; num2 >= 0; num2--) { Autos[num2].wait -= Time.deltaTime; if (!(Autos[num2].wait > 0f)) { LayoutFunction fn = Autos[num2].fn; Autos.RemoveAt(num2); RunFunction(fn, broadcast: true); } } if (AirportFunctionLoop.RoomChanged()) { if (AirportFunctionLoop.HasEpoch) { ReseekLoops(); } else { BroadcastLoopRequest(); } } ArmBackground(); } internal static string PromptOf(LayoutFunction fn) { LayoutFnState layoutFnState = AirportAnimPlayback.StateAt(fn, StateIndex(fn)); if (layoutFnState != null) { return Sanitize(layoutFnState.prompt, "Open"); } return Sanitize(fn?.prompt, "Open"); } internal static string TitleOf(LayoutFunction fn) { LayoutFnState layoutFnState = AirportAnimPlayback.StateAt(fn, StateIndex(fn)); string text = ((layoutFnState != null) ? layoutFnState.title : fn?.title); if (!string.IsNullOrEmpty(text)) { return text.Trim(); } return PromptOf(fn); } public static void Clear() { AirportAnimMenu.Close(); foreach (KeyValuePair<GameObject, AirportFnPrompt> prompt in Prompts) { if (prompt.Value != null) { prompt.Value.Teardown(); } } Prompts.Clear(); AirportFnContact[] array = Object.FindObjectsByType<AirportFnContact>((FindObjectsInactive)1, (FindObjectsSortMode)0); for (int i = 0; i < array.Length; i++) { if ((Object)(object)array[i] != (Object)null) { Object.Destroy((Object)(object)array[i]); } } Functions.Clear(); Jobs.Clear(); PoseCursor.Clear(); StateCursor.Clear(); Autos.Clear(); StartedBackground.Clear(); WarnedEmptyLoop.Clear(); AirportFunctionLoop.ClearAll(); } internal static void RunButton(string buttonId, bool fromLocal) { if (string.IsNullOrEmpty(buttonId)) { return; } LayoutFunction menu; LayoutMenuButton layoutMenuButton = FindMenuButton(buttonId, out menu); if (fromLocal) { AirportAnimMenu.Close(); if (AirportAnimPlayback.ButtonHasWorldEffect(layoutMenuButton) || HasButtonListeners(buttonId)) { Broadcast("button", buttonId); } } if (layoutMenuButton != null) { if (layoutMenuButton.action == "openMenu") { if (fromLocal) { OpenMenu(layoutMenuButton.actionMenuId); } } else { StartSteps(layoutMenuButton.id, layoutMenuButton.steps, menu?.random ?? false, FindTarget(layoutMenuButton.target, layoutMenuButton.targetId) ?? ((menu != null) ? FindTarget(menu.target, menu.targetId) : null), advanceState: false, fromLocal); if (layoutMenuButton.steps == null || layoutMenuButton.steps.Length == 0) { LayoutFunction layoutFunction = FindFunctionById(layoutMenuButton.actionMenuId) ?? FindPhotoboothMenuFunction(layoutMenuButton); if (layoutFunction != null) { RunFunction(layoutFunction, fromLocal); } } } } for (int i = 0; i < Functions.Count; i++) { LayoutFunction layoutFunction2 = Functions[i]; if (layoutFunction2 != null && string.Equals(layoutFunction2.kind, "trigger", StringComparison.OrdinalIgnoreCase) && string.Equals(layoutFunction2.triggerKind, "button", StringComparison.OrdinalIgnoreCase) && string.Equals(layoutFunction2.listenButtonId, buttonId, StringComparison.Ordinal)) { RunFunction(layoutFunction2, broadcast: false); } } } private static LayoutMenuButton FindMenuButton(string buttonId, out LayoutFunction menu) { menu = null; if (string.IsNullOrEmpty(buttonId)) { return null; } for (int i = 0; i < Functions.Count; i++) { LayoutFunction layoutFunction = Functions[i]; if (layoutFunction == null || layoutFunction.buttons == null || !string.Equals(layoutFunction.kind, "menu", StringComparison.OrdinalIgnoreCase)) { continue; } for (int j = 0; j < layoutFunction.buttons.Length; j++) { LayoutMenuButton layoutMenuButton = layoutFunction.buttons[j]; if (layoutMenuButton != null && string.Equals(layoutMenuButton.id, buttonId, StringComparison.Ordinal)) { menu = layoutFunction; return layoutMenuButton; } } } return null; } private static bool HasButtonListeners(string buttonId) { if (string.IsNullOrEmpty(buttonId)) { return false; } for (int i = 0; i < Functions.Count; i++) { LayoutFunction layoutFunction = Functions[i]; if (layoutFunction != null && string.Equals(layoutFunction.kind, "trigger", StringComparison.OrdinalIgnoreCase) && string.Equals(layoutFunction.triggerKind, "button", StringComparison.OrdinalIgnoreCase) && string.Equals(layoutFunction.listenButtonId, buttonId, StringComparison.Ordinal)) { return true; } } return false; } internal static void RunFunction(LayoutFunction fn, bool broadcast) { if (fn == null || FunctionBlocked(fn)) { return; } if (fn.action == "openMenu") { if (broadcast) { PlayFunction(fn, fromLocal: true); } return; } if (broadcast && AirportAnimPlayback.FunctionHasWorldEffect(fn)) { Broadcast("seq", fn.id); } PlayFunction(fn, broadcast); } private static void PlayFunction(LayoutFunction fn, bool fromLocal) { if (fn == null) { return; } if (fn.action == "openMenu") { if (fromLocal) { OpenMenu(fn.actionMenuId); } return; } if (fn.action == "runFn" && !AirportAnimPlayback.HasPlayableSteps(fn)) { PlayFunction(FindFunctionById(fn.actionMenuId), fromLocal); return; } CancelAuto(fn.id); int num = StateIndex(fn); LayoutFnState layoutFnState = AirportAnimPlayback.StateAt(fn, num); LayoutStep[] steps = ((layoutFnState != null && layoutFnState.steps != null) ? layoutFnState.steps : fn.steps); GameObject fallback = FindTarget(fn.target, fn.targetId); FillLockIds(steps, fallback, IncomingLock); if (!BlockedByRunning(fn.id, IncomingLock)) { bool flag = string.Equals(fn.kind, "trigger", StringComparison.OrdinalIgnoreCase); if (flag && AirportAnimPlayback.StateCount(fn) > 0) { StateCursor[fn.id] = AirportAnimPlayback.NextStateIndex(fn, num); RefreshPrompt(); } StartSteps(fn.id, steps, fn.random, fallback, flag, fromLocal); } } private static LayoutFunction FindFunctionById(string id) { if (string.IsNullOrEmpty(id)) { return null; } if (string.Equals(id, "fn-38920e94", StringComparison.Ordinal)) { id = "fn-a322b4e5"; } for (int i = 0; i < Functions.Count; i++) { if (Functions[i] != null && string.Equals(Functions[i].id, id, StringComparison.Ordinal)) { return Functions[i]; } } return null; } private static LayoutFunction FindPhotoboothMenuFunction(LayoutMenuButton button) { if (button == null) { return null; } if (string.Equals(button.id, "btn-078ba4e2", StringComparison.Ordinal)) { return FindFunctionById("fn-5b4b2393"); } if (string.Equals(button.id, "btn-18ab9384", StringComparison.Ordinal)) { return FindFunctionById("fn-eaeacc6c"); } if (string.Equals(button.id, "btn-014d5437", StringComparison.Ordinal)) { return FindFunctionById("fn-1457e09e"); } return null; } internal static void RefreshPrompt() { GUIManager instance = GUIManager.instance; if ((Object)(object)instance != (Object)null) { instance.RefreshInteractablePrompt(); } } internal static void RunFunction(LayoutFunction fn) { RunFunction(fn, broadcast: true); } internal static void OpenMenu(string menuId) { for (int i = 0; i < Functions.Count; i++) { LayoutFunction layoutFunction = Functions[i]; if (layoutFunction != null && string.Equals(layoutFunction.kind, "menu", StringComparison.OrdinalIgnoreCase) && string.Equals(layoutFunction.id, menuId, StringComparison.Ordinal)) { AirportAnimMenu.Open(layoutFunction); break; } } } internal static void RunSeqId(string id) { RunSeqIdLocal(id, fromLocal: false); } private static void RunSeqIdLocal(string id, bool fromLocal) { PlayFunction(FindFunctionById(id), fromLocal); } internal static string Sanitize(string text, string fallback) { if (string.IsNullOrEmpty(text)) { return fallback; } text = text.Trim(); if (text.Length != 0) { return text; } return fallback; } private static void ArmBackground() { if (!AirportFunctionLoop.CanRun()) { return; } EnsureNet(); if (AirportFunctionLoop.WaitForHostClock()) { return; } AirportFunctionLoop.EnsureEpoch(); for (int i = 0; i < Functions.Count; i++) { LayoutFunction layoutFunction = Functions[i]; if (layoutFunction != null && string.Equals(layoutFunction.kind, "trigger", StringComparison.OrdinalIgnoreCase) && !HasJob(layoutFunction.id)) { if (AirportFunctionLoop.IsLoop(layoutFunction)) { StartLoopJob(layoutFunction); } else if (string.Equals(layoutFunction.triggerKind, "auto", StringComparison.OrdinalIgnoreCase) && !StartedBackground.Contains(layoutFunction.id ?? string.Empty)) { StartedBackground.Add(layoutFunction.id ?? string.Empty); StartSteps(layoutFunction.id, layoutFunction.steps, layoutFunction.random, FindTarget(layoutFunction.target, layoutFunction.targetId), advanceState: false, fromLocal: false); } } } } internal static void BroadcastLoopClock() { //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_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Expected O, but got Unknown //IL_0050: Unknown result type (might be due to invalid IL or missing references) try { if (PhotonNetwork.InRoom && AirportFunctionLoop.HasEpoch) { object[] array = new object[4] { "tony4twentys.Airport_Remixed", "loopclk", string.Empty, AirportFunctionLoop.Epoch }; RaiseEventOptions val = new RaiseEventOptions { Receivers = (ReceiverGroup)0 }; PhotonNetwork.RaiseEvent((byte)187, (object)array, val, SendOptions.SendReliable); } } catch { } } internal static void BroadcastLoopRequest() { //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_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Expected O, but got Unknown //IL_003c: Unknown result type (might be due to invalid IL or missing references) try { if (PhotonNetwork.InRoom) { object[] array = new object[3] { "tony4twentys.Airport_Remixed", "loopreq", string.Empty }; RaiseEventOptions val = new RaiseEventOptions { Receivers = (ReceiverGroup)2 }; PhotonNetwork.RaiseEvent((byte)187, (object)array, val, SendOptions.SendReliable); } } catch { } } internal static void ApplyLoopClock(double epoch) { AirportFunctionLoop.SetEpoch(epoch); ReseekLoops(); } private static void ReseekLoops() { for (int num = Jobs.Count - 1; num >= 0; num--) { if (Jobs[num] != null && Jobs[num].loop) { Jobs.RemoveAt(num); } } ArmBackground(); } private static bool HasJob(string id) { if (string.IsNullOrEmpty(id)) { return false; } for (int i = 0; i < Jobs.Count; i++) { if (Jobs[i] != null && string.Equals(Jobs[i].id, id, StringComparison.Ordinal)) { return true; } } return false; } private static void StartLoopJob(LayoutFunction fn) { if (fn == null || HasJob(fn.id)) { return; } LayoutStep[] steps = fn.steps; if (steps == null || steps.Length == 0) { return; } GameObject fallback = FindTarget(fn.target, fn.targetId); CaptureLoopTargets(steps, fallback); float num = LoopCycleSeconds(steps, fallback); if (num < 0.05f) { string text = fn.id ?? string.Empty; if (WarnedEmptyLoop.Add(text)) { ManualLogSource logger = AirportRemixedPlugin.Logger; if (logger != null) { logger.LogWarning((object)("Loop '" + text + "' has no move/wait time, so it was not started.")); } } return; } SeqJob seqJob = new SeqJob(); seqJob.id = fn.id ?? string.Empty; seqJob.steps = steps; seqJob.random = false; seqJob.fallback = fallback; seqJob.loop = true; float num2 = AirportFunctionLoop.Phase(num); if (num2 > 0.001f && SeekLoop(seqJob, num2)) { Jobs.Add(seqJob); return; } seqJob.step = 0; if (BeginStep(seqJob)) { Jobs.Add(seqJob); } } private static void CaptureLoopTargets(LayoutStep[] steps, GameObject fallback) { AirportFunctionLoop.Capture(fallback); if (steps == null) { return; } foreach (LayoutStep layoutStep in steps) { if (layoutStep == null) { continue; } AirportFunctionLoop.Capture(FindTarget(layoutStep.animTarget, layoutStep.animTargetId)); if (layoutStep.poses == null) { continue; } for (int j = 0; j < layoutStep.poses.Length; j++) { if (layoutStep.poses[j] != null) { AirportFunctionLoop.Capture(FindTarget(layoutStep.poses[j].target, layoutStep.poses[j].targetId)); } } } } private static float LoopCycleSeconds(LayoutStep[] steps, GameObject fallback) { LoopPos.Clear(); LoopRot.Clear(); SeedLoopPose(fallback); if (steps == null) { return 0f; } float num = 0f; int num2 = 0; while (num2 < steps.Length) { int num3 = AirportAnimPlayback.GroupEnd(steps, num2); float num4 = 0f; for (int i = num2; i <= num3; i++) { num4 = Mathf.Max(num4, StepLoopSeconds(steps[i], fallback)); } for (int j = num2; j <= num3; j++) { CommitLoopPose(steps[j], fallback); } num += num4; num2 = num3 + 1; } return num; } private static bool SeekLoop(SeqJob job, float phase) { LoopPos.Clear(); LoopRot.Clear(); SeedLoopPose(job.fallback); float num = 0f; int num2 = 0; while (num2 < job.steps.Length) { int num3 = AirportAnimPlayback.GroupEnd(job.steps, num2); float num4 = 0f; for (int i = num2; i <= num3; i++) { num4 = Mathf.Max(num4, StepLoopSeconds(job.steps[i], job.fallback)); } if (phase <= num + num4 || num3 == job.steps.Length - 1) { float num5 = Mathf.Max(0f, phase - num); job.moves.Clear(); job.wait = 0f; job.step = num3; for (int j = num2; j <= num3; j++) { SeekOne(job, job.steps[j], j, (num4 > 0f) ? Mathf.Clamp01(num5 / num4) : 1f); } if (job.moves.Count <= 0 && !(job.wait > 0f)) { return BeginStepAfterSeek(job); } return true; } for (int k = num2; k <= num3; k++) { SnapLoopStep(job.steps[k], job.fallback); CommitLoopPose(job.steps[k], job.fallback); } num += num4; num2 = num3 + 1; } return false; } private static bool BeginStepAfterSeek(SeqJob job) { if (job.moves.Count > 0 || job.wait > 0f) { return true; } job.step++; if (job.step < job.steps.Length) { return BeginStep(job); } job.step = 0; return BeginStep(job); } private static void SeedLoopPose(GameObject go) { //IL_0042: 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_0023: 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) if (!((Object)(object)go == (Object)null)) { int instanceID = ((Object)go).GetInstanceID(); if (AirportFunctionLoop.TryRest(go, out var pos, out var rot)) { LoopPos[instanceID] = pos; LoopRot[instanceID] = rot; } else { LoopPos[instanceID] = go.transform.position; LoopRot[instanceID] = go.transform.rotation; } } } private static GameObject StepLoopTarget(LayoutStep step, GameObject fallback) { if (step == null) { return fallback; } if (step.poses != null && step.poses.Length != 0 && step.poses[0] != null) { GameObject val = FindTarget(step.poses[0].target, step.poses[0].targetId); if ((Object)(object)val != (Object)null) { return val; } } GameObject val2 = FindTarget(step.animTarget, step.animTargetId); if (!((Object)(object)val2 != (Object)null)) { return fallback; } return val2; } private static float StepLoopSeconds(LayoutStep step, GameObject fallback) { //IL_00a8: 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_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Unknown result type (might be due to invalid IL or missing references) if (step == null) { return 0f; } string text = step.kind ?? "move"; if (text == "delay") { return Mathf.Clamp(step.delay, 0f, 30f); } if (AirportAnimPlayback.IsAnimKind(text)) { return 0.5f; } if (text != "move") { return 0f; } if (step.poses == null || step.poses.Length == 0 || step.poses[0] == null) { return 0f; } GameObject val = StepLoopTarget(step, fallback); if ((Object)(object)val == (Object)null) { return 0f; } SeedLoopPose(val); int instanceID = ((Object)val).GetInstanceID(); return AirportAnimPlayback.MoveDuration(LoopPos[instanceID], step.poses[0].position, LoopRot[instanceID], Quaternion.Euler(step.poses[0].euler), step.speed); } private static void CommitLoopPose(LayoutStep step, GameObject fallback) { //IL_0058: 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) if (step != null && !(step.kind != "move") && step.poses != null && step.poses.Length != 0 && step.poses[0] != null) { GameObject val = StepLoopTarget(step, fallback); if (!((Object)(object)val == (Object)null)) { int instanceID = ((Object)val).GetInstanceID(); LoopPos[instanceID] = step.poses[0].position; LoopRot[instanceID] = Quaternion.Euler(step.poses[0].euler); } } } private static void SnapLoopStep(LayoutStep step, GameObject fallback) { //IL_00a1: 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) if (step == null) { return; } string text = step.kind ?? "move"; GameObject val = StepLoopTarget(step, fallback); if (AirportAnimPlayback.IsToggleKind(text) && (Object)(object)val != (Object)null) { AirportAnimPlayback.ApplyToggle(val, step.flag); } else if (AirportAnimPlayback.IsMaterialKind(text) && (Object)(object)val != (Object)null) { string text2 = AirportAnimPlayback.MaterialName(step); if (!string.IsNullOrEmpty(text2)) { LayoutMaterials.Apply(val, text2); } } else if (text == "move" && (Object)(object)val != (Object)null && step.poses != null && step.poses.Length != 0 && step.poses[0] != null) { val.transform.position = step.poses[0].position; val.transform.rotation = Quaternion.Euler(step.poses[0].euler); } } private static void SeekOne(SeqJob job, LayoutStep step, int index, float u) { //IL_00aa: 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_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_00c5: 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_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_00de: 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_00f2: 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_00fb: 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_0104: 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_010d: 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_0187: Unknown result type (might be due to invalid IL or missing references) if (job == null || step == null) { return; } string text = step.kind ?? "move"; if (text == "delay") { float num = Mathf.Clamp(step.delay, 0f, 30f); job.wait = Mathf.Max(job.wait, num * (1f - u)); } else if (!(text != "move") && step.poses != null && step.poses.Length != 0 && step.poses[0] != null) { GameObject val = StepLoopTarget(step, job.fallback); if (!((Object)(object)val == (Object)null)) { SeedLoopPose(val); int instanceID = ((Object)val).GetInstanceID(); Vector3 fromPos = LoopPos[instanceID]; Quaternion fromRot = LoopRot[instanceID]; Vector3 position = step.poses[0].position; Quaternion toRot = Quaternion.Euler(step.poses[0].euler); MoveTrack moveTrack = new MoveTrack(); moveTrack.go = val; moveTrack.fromPos = fromPos; moveTrack.fromRot = fromRot; moveTrack.toPos = position; moveTrack.toRot = toRot; moveTrack.speed = step.speed; moveTrack.easeIn = step.easeIn; moveTrack.easeOut = step.easeOut; moveTrack.t = u; BindCurveAuthored(moveTrack, job, val, index); FillPath(moveTrack, step); float u2 = AirportAnimPlayback.Ease01(u, step.easeIn, step.easeOut); EvalMove(moveTrack, u2, out var pos, out var rot); val.transform.position = pos; val.transform.rotation = rot; job.moves.Add(moveTrack); } } } private static void StartSteps(string id, LayoutStep[] steps, bool random, GameObject fallback, bool advanceState, bool fromLocal) { if (steps == null || steps.Length == 0) { return; } FillLockIds(steps, fallback, IncomingLock); if (BlockedByRunning(id, IncomingLock)) { return; } for (int num = Jobs.Count - 1; num >= 0; num--) { if (Jobs[num] != null && string.Equals(Jobs[num].id, id, StringComparison.Ordinal)) { Jobs.RemoveAt(num); } } SeqJob seqJob = new SeqJob(); seqJob.id = id ?? string.Empty; seqJob.steps = steps; seqJob.random = random; seqJob.fallback = fallback; seqJob.advanceState = advanceState; seqJob.fromLocal = fromLocal; seqJob.uninterruptible = AirportAnimPlayback.AnyUninterruptible(steps); if (seqJob.uninterruptible) { for (int i = 0; i < IncomingLock.Count; i++) { seqJob.lockIds.Add(IncomingLock[i]); } } seqJob.step = 0; if (BeginStep(seqJob)) { Jobs.Add(seqJob); } } private static bool FunctionBlocked(LayoutFunction fn) { if (fn == null) { return false; } int index = StateIndex(fn); LayoutFnState layoutFnState = AirportAnimPlayback.StateAt(fn, index); FillLockIds((layoutFnState != null && layoutFnState.steps != null) ? layoutFnState.steps : fn.steps, FindTarget(fn.target, fn.targetId), IncomingLock); return BlockedByRunning(fn.id, IncomingLock); } private static bool BlockedByRunning(string id, List<int> incoming) { for (int i = 0; i < Jobs.Count; i++) { SeqJob seqJob = Jobs[i]; if (seqJob != null && seqJob.uninterruptible) { if (!string.IsNullOrEmpty(id) && string.Equals(seqJob.id, id, StringComparison.Ordinal)) { return true; } if (LocksOverlap(seqJob.lockIds, incoming)) { return true; } } } return false; } private static bool LocksOverlap(List<int> a, List<int> b) { if (a == null || b == null || a.Count == 0 || b.Count == 0) { return false; } for (int i = 0; i < a.Count; i++) { for (int j = 0; j < b.Count; j++) { if (a[i] == b[j]) { return true; } } } return false; } private static void FillLockIds(LayoutStep[] steps, GameObject fallback, List<int> dest) { dest.Clear(); if (steps != null) { foreach (LayoutStep layoutStep in steps) { if (layoutStep == null) { continue; } AddLock(dest, FindTarget(layoutStep.animTarget, layoutStep.animTargetId)); if (layoutStep.poses == null) { continue; } for (int j = 0; j < layoutStep.poses.Length; j++) { if (layoutStep.poses[j] != null) { AddLock(dest, FindTarget(layoutStep.poses[j].target, layoutStep.poses[j].targetId)); } } } } if (dest.Count == 0 && (Object)(object)fallback != (Object)null) { AddLock(dest, fallback); } } private static void AddLock(List<int> dest, GameObject go) { if (!((Object)(object)go == (Object)null)) { int instanceID = ((Object)go).GetInstanceID(); if (!dest.Contains(instanceID)) { dest.Add(instanceID); } } } private static bool BeginStep(SeqJob job) { if (job == null || job.steps == null || job.step < 0 || job.step >= job.steps.Length) { return false; } int step = job.step; int num = AirportAnimPlayback.GroupEnd(job.steps, step); job.moves.Clear(); job.wait = 0f; for (int i = step; i <= num; i++) { StartOne(job, job.steps[i], i); } if (job.moves.Count == 0 && job.wait <= 0f) { job.step = num; return Advance(job); } job.step = num; return true; } private static void StartOne(SeqJob job, LayoutStep step, int index) { //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_0240: Unknown result type (might be due to invalid IL or missing references) //IL_0245: Unknown result type (might be due to invalid IL or missing references) //IL_0251: Unknown result type (might be due to invalid IL or missing references) //IL_0256: Unknown result type (might be due to invalid IL or missing references) //IL_025d: 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_0269: Unknown result type (might be due to invalid IL or missing references) //IL_026e: Unknown result type (might be due to invalid IL or missing references) //IL_0273: Unknown result type (might be due to invalid IL or missing references) if (job == null || step == null) { return; } string text = step.kind ?? "move"; switch (text) { case "openMenu": if (job.fromLocal) { OpenMenu(step.actionMenuId); } return; case "closeMenu": if (job.fromLocal) { AirportAnimMenu.CloseTarget(step.actionMenuId); } return; case "delay": job.wait = Mathf.Max(job.wait, Mathf.Clamp(step.delay, 0f, 30f)); return; case "runFn": RunSeqIdLocal(step.actionMenuId, job.fromLocal); return; case "teleport": if (job.fromLocal) { LayoutPose layoutPose2 = PickPose(job, step, index); if (layoutPose2 != null) { AirportFnFx.Teleport(layoutPose2.position); } } return; case "afflict": if (job.fromLocal) { AirportFnFx.Afflict(step); } return; case "interact": if (job.fromLocal) { LayoutPose layoutPose = PickPose(job, step, index); AirportFnFx.Interact((layoutPose != null) ? (FindTarget(layoutPose.target, layoutPose.targetId) ?? job.fallback) : job.fallback); } return; case "spawn": { LayoutPose layoutPose3 = PickPose(job, step, index); AirportFnFx.SpawnClone((layoutPose3 != null) ? (FindTarget(layoutPose3.target, layoutPose3.targetId) ?? job.fallback) : job.fallback, layoutPose3, step); return; } } if (AirportAnimPlayback.IsAnimKind(text)) { AirportAnimPlayback.PlayAction(FindTarget(step.animTarget, step.animTargetId) ?? job.fallback, text, step.clipName, out var duration); job.wait = Mathf.Max(job.wait, duration); return; } if (AirportAnimPlayback.IsToggleKind(text) || AirportAnimPlayback.IsMaterialKind(text)) { ApplyFx(job, step, text); return; } LayoutPose layoutPose4 = PickPose(job, step, index); GameObject val = ((layoutPose4 != null) ? (FindTarget(layoutPose4.target, layoutPose4.targetId) ?? job.fallback) : job.fallback); if (!((Object)(object)val == (Object)null) && layoutPose4 != null) { MoveTrack moveTrack = new MoveTrack(); moveTrack.go = val; moveTrack.fromPos = val.transform.position; moveTrack.fromRot = val.transform.rotation; moveTrack.toPos = layoutPose4.position; moveTrack.toRot = Quaternion.Euler(layoutPose4.euler); moveTrack.speed = step.speed; moveTrack.easeIn = step.easeIn; moveTrack.easeOut = step.easeOut; moveTrack.t = 0f; BindCurveAuthored(moveTrack, job, val, index); FillPath(moveTrack, step); job.moves.Add(moveTrack); } } private static void BindCurveAuthored(MoveTrack move, SeqJob job, GameObject target, int index) { //IL_0015: 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) if (move != null) { move.useTurn = FindPrevMoveRot(job, target, index, out var rot); move.pathFromRot = rot; } } private static bool FindPrevMoveRot(SeqJob job, GameObject target, int index, out Quaternion rot) { //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_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_009f: Unknown result type (might be due to invalid IL or missing references) rot = Quaternion.identity; if (job == null || job.steps == null || (Object)(object)target == (Object)null) { return false; } for (int num = index - 1; num >= 0; num--) { LayoutStep layoutStep = job.steps[num]; if (layoutStep != null && (layoutStep.kind == null || !(layoutStep.kind != "move"))) { LayoutPose layoutPose = ((layoutStep.poses != null && layoutStep.poses.Length != 0) ? layoutStep.poses[0] : null); if (layoutPose != null && !((Object)(object)(FindTarget(layoutPose.target, layoutPose.targetId) ?? job.fallback) != (Object)(object)target)) { rot = Quaternion.Euler(layoutPose.euler); return true; } } } return false; } private static void FillPath(MoveTrack move, LayoutStep step) { if (move != null && step != null) { move.curve = step.curve; move.facePath = step.facePath; move.tilt = AirportAnimPlayback.ClampTilt(step.tilt); move.bend = AirportAnimPlayback.ClampBend((step.bend == 0f && step.curve) ? 1f : step.bend); } } private static void EvalMove(MoveTrack move, float u, out Vector3 pos, out Quaternion rot) { //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_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_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_0019: 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_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_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_00d3: 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_00d5: 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_00af: 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_001e: 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_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_0030: 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_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005b: 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_0072: 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_017b: Unknown result type (might be due to invalid IL or missing references) //IL_017c: Unknown result type (might be due to invalid IL or missing references) //IL_018d: Unknown result type (might be due to invalid IL or missing references) //IL_0192: Unknown result type (might be due to invalid IL or missing references) //IL_0193: 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_0197: Unknown result type (might be due to invalid IL or missing references) //IL_019c: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: 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_00f7: 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) //IL_0100: Unknown result type (might be due to invalid IL or missing references) //IL_0105: Unknown result type (might be due to invalid IL or missing references) //IL_0108: Unknown result type (might be due to invalid IL or missing references) //IL_011e: Unknown result type (might be due to invalid IL or missing references) //IL_0123: Unknown result type (might be due to invalid IL or missing references) //IL_0125: Unknown result type (might be due to invalid IL or missing references) //IL_012b: 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_0133: 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_014e: Unknown result type (might be due to invalid IL or missing references) //IL_0150: 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_015b: Unknown result type (might be due to invalid IL or missing references) //IL_015e: Unknown result type (might be due to invalid IL or missing references) //IL_0174: 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) Vector3 tangent; if (move.curve) { Quaternion aRot = (move.useTurn ? move.pathFromRot : move.fromRot); pos = AirportAnimPlayback.CurvePoint(move.fromPos, move.toPos, aRot, move.toRot, move.bend, u, move.useTurn); tangent = AirportAnimPlayback.CurveTangent(move.fromPos, move.toPos, aRot, move.toRot, move.bend, u, move.useTurn); } else { pos = Vector3.Lerp(move.fromPos, move.toPos, u); tangent = move.toPos - move.fromPos; } if (!move.facePath) { rot = Quaternion.Slerp(move.fromRot, move.toRot, u); return; } Vector3 val = move.toPos - move.fromPos; Vector3 val2 = val; Vector3 tanEnd = val; if (move.curve) { Quaternion aRot2 = (move.useTurn ? move.pathFromRot : move.fromRot); val = AirportAnimPlayback.CurveTangent(move.fromPos, move.toPos, aRot2, move.toRot, move.bend, 0f, move.useTurn); val2 = AirportAnimPlayback.CurveTangent(move.fromPos, move.toPos, aRot2, move.toRot, move.bend, 0.5f, move.useTurn); tanEnd = AirportAnimPlayback.CurveTangent(move.fromPos, move.toPos, aRot2, move.toRot, move.bend, 1f, move.useTurn); } float bank = AirportAnimPlayback.TiltBank(val, val2, tanEnd, move.tilt, u); rot = AirportAnimPlayback.FaceAlong(move.fromRot, tangent, val, val2, bank); } private static void ApplyFx(SeqJob job, LayoutStep step, string kind) { List<GameObject> list = CollectTargets(job, step); if (AirportAnimPlayback.IsToggleKind(kind)) { bool flag = step.flag; for (int i = 0; i < list.Count; i++) { AirportAnimPlayback.ApplyToggle(list[i], flag); } return; } string text = AirportAnimPlayback.MaterialName(step); if (!string.IsNullOrEmpty(text)) { for (int j = 0; j < list.Count; j++) { LayoutMaterials.Apply(list[j], text); } } } private static List<GameObject> CollectTargets(SeqJob job, LayoutStep step) { TargetScratch.Clear(); if (step != null && step.poses != null) { for (int i = 0; i < step.poses.Length; i++) { LayoutPose layoutPose = step.poses[i]; if (layoutPose != null) { GameObject val = FindTarget(layoutPose.target, layoutPose.targetId); if ((Object)(object)val != (Object)null && !TargetScratch.Contains(val)) { TargetScratch.Add(val); } } } } if (TargetScratch.Count == 0 && job != null && (Object)(object)job.fallback != (Object)null) { TargetScratch.Add(job.fallback); } return TargetScratch; } private static LayoutPose PickPose(SeqJob job, LayoutStep step, int stepIndex) { if (step == null || step.poses == null || step.poses.Length == 0) { return null; } int num; if (job.random || step.random) { num = Random.Range(0, step.poses.Length); } else { string key = job.id + ":" + stepIndex; if (!PoseCursor.TryGetValue(key, out var value)) { value = 0; } num = value % step.poses.Length; PoseCursor[key] = num + 1; } return step.poses[num]; } private static bool StepJob(SeqJob job) { //IL_003a: 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_004c: 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_00b3: Unknown result type (might be due to invalid IL or missing references) if (job == null) { return false; } job.wraps = 0; bool flag = true; for (int i = 0; i < job.moves.Count; i++) { MoveTrack moveTrack = job.moves[i]; if (moveTrack != null && !((Object)(object)moveTrack.go == (Object)null)) { float num = AirportAnimPlayback.MoveDuration(moveTrack.fromPos, moveTrack.toPos, moveTrack.fromRot, moveTrack.toRot, moveTrack.speed); moveTrack.t += Time.deltaTime / num; float u = AirportAnimPlayback.Ease01(moveTrack.t, moveTrack.easeIn, moveTrack.easeOut); EvalMove(moveTrack, u, out var pos, out var rot); moveTrack.go.transform.position = pos; moveTrack.go.transform.rotation = rot; if (moveTrack.t < 1f) { flag = false; } } } job.wait -= Time.deltaTime; if (!flag || job.wait > 0f) { return true; } return Advance(job); } private static bool Advance(SeqJob job) { job.step++; if (job.step < job.steps.Length) { return BeginStep(job); } if (job.loop) { job.wraps++; if (job.wraps > 1) { return false; } job.step = 0; job.moves.Clear(); job.wait = 0f; return BeginStep(job); } return false; } private static int StateIndex(LayoutFunction fn) { if (fn == null) { return 0; } if (string.IsNullOrEmpty(fn.id) || !StateCursor.TryGetValue(fn.id, out var value)) { value = fn.startState; } int num = AirportAnimPlayback.StateCount(fn); if (num <= 0) { return 0; } return Mathf.Clamp(value, 0, num - 1); } private static void ArmAutoAfter(string id) { LayoutFunction layoutFunction = null; for (int i = 0; i < Functions.Count; i++) { if (Functions[i] != null && string.Equals(Functions[i].id, id, StringComparison.Ordinal)) { layoutFunction = Functions[i]; break; } } if (layoutFunction != null && string.Equals(layoutFunction.kind, "trigger", StringComparison.OrdinalIgnoreCase)) { LayoutFnState layoutFnState = AirportAnimPlayback.StateAt(layoutFunction, StateIndex(layoutFunction)); if (layoutFnState != null && !(layoutFnState.autoAfter <= 0f) && (!PhotonNetwork.InRoom || PhotonNetwork.IsMasterClient)) { CancelAuto(layoutFunction.id); AutoWait autoWait = new AutoWait(); autoWait.id = layoutFunction.id; autoWait.wait = layoutFnState.autoAfter; autoWait.fn = layoutFunction; Autos.Add(autoWait); } } } private static void CancelAuto(string id) { if (string.IsNullOrEmpty(id)) { return; } for (int num = Autos.Count - 1; num >= 0; num--) { if (Autos[num] != null && string.Equals(Autos[num].id, id, StringComparison.Ordinal)) { Autos.RemoveAt(num); } } } private static void RebuildPrompts() { //IL_0232: Unknown result type (might be due to invalid IL or missing references) //IL_0237: Unknown result type (might be due to invalid IL or missing references) foreach (KeyValuePair<GameObject, AirportFnPrompt> prompt in Prompts) { if (prompt.Value != null) { prompt.Value.Teardown(); } } Prompts.Clear(); for (int i = 0; i < Functions.Count; i++) { LayoutFunction layoutFunction = Functions[i]; if (layoutFunction == null || !string.Equals(layoutFunction.kind, "trigger", StringComparison.OrdinalIgnoreCase) || string.Equals(layoutFunction.triggerKind, "button", StringComparison.OrdinalIgnoreCase) || string.Equals(layoutFunction.triggerKind, "auto", StringComparison.OrdinalIgnoreCase) || AirportFunctionLoop.IsLoop(layoutFunction)) { continue; } GameObject val = FindTarget(layoutFunction.target, layoutFunction.targetId); if ((Object)(object)val == (Object)null && AirportAnimPlayback.IsArea(layoutFunction) && layoutFunction.hasEnd) { val = AirportFnContact.EnsureVolume(layoutFunction); } if ((Object)(object)val == (Object)null) { ManualLogSource logger = AirportRemixedPlugin.Logger; if (logger != null) { logger.LogWarning((object)("Function '" + layoutFunction.id + "' target not found: " + layoutFunction.target + " (photobooth=" + ((Object)(object)AirportLayoutLoader.FindSceneObject("Map/Photobooth") != (Object)null) + ")")); } continue; } if (AirportAnimPlayback.IsArea(layoutFunction) || AirportAnimPlayback.IsTouch(layoutFunction)) { AirportFnContact airportFnContact = val.GetComponent<AirportFnContact>(); if ((Object)(object)airportFnContact == (Object)null) { airportFnContact = val.AddComponent<AirportFnContact>(); } airportFnContact.Arm(layoutFunction, AirportAnimPlayback.IsArea(layoutFunction)); ManualLogSource logger2 = AirportRemixedPlugin.Logger; if (logger2 != null) { logger2.LogInfo((object)((AirportAnimPlayback.IsArea(layoutFunction) ? "Area" : "Touch") + " trigger on '" + ((Object)val).name + "'.")); } continue; } AirportFnPrompt airportFnPrompt = new AirportFnPrompt(); airportFnPrompt.Attach(val, layoutFunction); Prompts[val] = airportFnPrompt; ManualLogSource logger3 = AirportRemixedPlugin.Logger; if (logger3 != null) { logger3.LogInfo((object)("Prompt on '" + ((Object)val).name + "' at " + ((object)val.transform.position/*cast due to .constrained prefix*/).ToString() + " text='" + airportFnPrompt.Text() + "'")); } } ManualLogSource logger4 = AirportRemixedPlugin.Logger; if (logger4 != null) { logger4.LogInfo((object)("Airport function prompts attached: " + Prompts.Count + ".")); } } private static GameObject FindTarget(string path, string id) { if (!string.IsNullOrEmpty(id)) { AirportRemixedPiece[] array = Object.FindObjectsByType<AirportRemixedPiece>((FindObjectsInactive)1, (FindObjectsSortMode)0); for (int i = 0; i < array.Length; i++) { if (!((Object)(object)array[i] == (Object)null) && string.Equals(array[i].id, id, StringComparison.Ordinal)) { Transform transform = ((Component)array[i]).transform; if (!((Object)(object)transform != (Object)null) || !(((Object)transform).name == "Cube") || !((Object)(object)transform.parent != (Object)null) || !(((Object)transform.parent).name == "Map")) { return ((Component)array[i]).gameObject; } } } } GameObject val = AirportLayoutLoader.FindSceneObject(path); if ((Object)(object)val != (Object)null) { return val; } GameObject val2 = FindRemappedTarget(path); if ((Object)(object)val2 != (Object)null) { return val2; } GameObject val3 = FindByExactName(path, !string.IsNullOrEmpty(id)); if ((Object)(object)val3 != (Object)null) { return val3; } if (!string.IsNullOrEmpty(id)) { return null; } GameObject val4 = FindByLeafName(path); if ((Object)(object)val4 != (Object)null) { return val4; } return FindPhotoboothFallback(path); } private static GameObject FindByExactName(string path, bool anyLeaf) { if (string.IsNullOrEmpty(path)) { return null; } int num = path.LastIndexOf('/'); string text = ((num < 0) ? path : path.Substring(num + 1)); if (string.IsNullOrEmpty(text) || (!anyLeaf && !text.StartsWith("AR_", StringComparison.Ordinal))) { return null; } Transform[] array = Object.FindObjectsByType<Transform>((FindObjectsInactive)1, (FindObjectsSortMode)0); GameObject val = null; for (int i = 0; i < array.Length; i++) { if (!((Object)(object)array[i] == (Object)null)) { if (((Object)array[i]).name == text) { return ((Component)array[i]).gameObject; } if ((Object)(object)val == (Object)null && AirportLayoutLoader.NamesMatchLoose(((Object)array[i]).name, text)) { val = ((Component)array[i]).gameObject; } } } return val; } private static GameObject FindByLeafName(string path) { if (string.IsNullOrEmpty(path)) { return null; } int num = path.LastIndexOf('/'); string text = ((num < 0) ? path : path.Substring(num + 1)); if (string.IsNullOrEmpty(text)) { return null; } GameObject val = FindPhotoboothRoot(); if ((Object)(object)val == (Object)null) { return null; } Transform[] componentsInChildren = val.GetComponentsInChildren<Transform>(true); for (int i = 0; i < componentsInChildren.Length; i++) { if ((Object)(object)componentsInChildren[i] != (Object)null && ((Object)componentsInChildren[i]).name == text) { return ((Component)componentsInChildren[i]).gameObject; } } return null; } private static GameObject FindPhotoboothRoot() { //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) GameObject val = AirportLayoutLoader.FindSceneObject("Map/Photobooth"); if ((Object)(object)val != (Object)null) { return val; } Scene activeScene = SceneManager.GetActiveScene(); if (!((Scene)(ref activeScene)).IsValid()) { return null; } GameObject[] rootGameObjects = ((Scene)(ref activeScene)).GetRootGameObjects(); for (int i = 0; i < rootGameObjects.Length; i++) { if ((Object)(object)rootGameObjects[i] == (Object)null) { continue; } Transform[] componentsInChildren = rootGameObjects[i].GetComponentsInChildren<Transform>(true); for (int j = 0; j < componentsInChildren.Length; j++) { if ((Object)(object)componentsInChildren[j] != (Object)null && ((Object)componentsInChildren[j]).name == "Photobooth") { return ((Component)componentsInChildren[j]).gameObject; } } } return null; } private static GameObject FindPhotoboothFallback(string path) { if (string.IsNullOrEm