Decompiled source of CompetitiveCompany v0.2.0
plugins/CompetitiveCompany.dll
Decompiled 2 months 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.Diagnostics.CodeAnalysis; using System.IO; using System.Linq; using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; 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 CompetitiveCompany; using CompetitiveCompany.Compat; using CompetitiveCompany.Game; using CompetitiveCompany.NetcodePatcher; using CompetitiveCompany.UI; using CompetitiveCompany.Util; using FlowTween; using GameNetcodeStuff; using HarmonyLib; using IL; using IL.GameNetcodeStuff; using LethalAPI.LibTerminal; using LethalAPI.LibTerminal.Attributes; using LethalCompanyInputUtils.Api; using LethalConfig; using LethalConfig.ConfigItems; using LethalConfig.ConfigItems.Options; using LethalLib.Modules; using Microsoft.CodeAnalysis; using Mono.Cecil.Cil; using MonoMod.Cil; using Newtonsoft.Json; using On; using On.GameNetcodeStuff; using RuntimeNetcodeRPCValidator; using TMPro; using Unity.Collections; using Unity.Netcode; using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.Events; using UnityEngine.InputSystem; using UnityEngine.InputSystem.Controls; using UnityEngine.Rendering; using UnityEngine.Rendering.HighDefinition; 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("")] [assembly: AssemblyCompany("CompetitiveCompany")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("0.2.0.0")] [assembly: AssemblyInformationalVersion("0.2.0+cc25a41a846858a13b8048296e53c14accd96bfc")] [assembly: AssemblyProduct("CompetitiveCompany")] [assembly: AssemblyTitle("CompetitiveCompany")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("0.2.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] [module: NetcodePatchedAssembly] internal class <Module> { static <Module>() { NetworkVariableSerializationTypes.InitializeSerializer_UnmanagedINetworkSerializable<Player.TeamRef>(); NetworkVariableSerializationTypes.InitializeEqualityChecker_UnmanagedValueEquals<Player.TeamRef>(); NetworkVariableSerializationTypes.InitializeSerializer_UnmanagedByMemcpy<bool>(); NetworkVariableSerializationTypes.InitializeEqualityChecker_UnmanagedIEquatable<bool>(); NetworkVariableSerializationTypes.InitializeSerializer_UnmanagedINetworkSerializable<NetworkedSettings>(); NetworkVariableSerializationTypes.InitializeEqualityChecker_UnmanagedValueEquals<NetworkedSettings>(); NetworkVariableSerializationTypes.InitializeSerializer_FixedString<FixedString128Bytes>(); NetworkVariableSerializationTypes.InitializeEqualityChecker_UnmanagedIEquatable<FixedString128Bytes>(); NetworkVariableSerializationTypes.InitializeSerializer_UnmanagedByMemcpy<Color>(); NetworkVariableSerializationTypes.InitializeEqualityChecker_UnmanagedIEquatable<Color>(); } } namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace CompetitiveCompany { internal static class Assets { public static AssetBundle Bundle { get; } public static RoundReport RoundReportPrefab { get; } public static MatchEndScreen MatchEndScreenPrefab { get; } public static Material TeamSuitMaterial { get; } static Assets() { string location = Assembly.GetExecutingAssembly().Location; location = Path.GetDirectoryName(location); location = Path.Combine(location, "competitive-company"); Bundle = AssetBundle.LoadFromFile(location); GameObject val = Bundle.LoadAsset<GameObject>("Assets/CC2/Prefabs/RoundReport.prefab"); RoundReportPrefab = val.GetComponent<RoundReport>(); val = Bundle.LoadAsset<GameObject>("Assets/CC2/Prefabs/MatchEndScreen.prefab"); MatchEndScreenPrefab = val.GetComponent<MatchEndScreen>(); TeamSuitMaterial = Bundle.LoadAsset<Material>("Assets/CC2/Materials/TeamSuit.mat"); } public static void Load() { } } public class Config { public Keybinds Keybinds { get; } = new Keybinds(); public ConfigEntry<bool> ForceSuits { get; } = file.Bind<bool>("General", "ForceSuits", true, "Whether to force players to wear suits according to their team's color."); public ConfigEntry<bool> FriendlyFire { get; } = file.Bind<bool>("General", "FriendlyFire", false, "Whether players can damage their teammates."); public ConfigEntry<int> NumberOfRounds { get; } = file.Bind<int>("General", "NumberOfRounds", 3, new ConfigDescription("Number of rounds to play before the game ends.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 25), Array.Empty<object>())); public ConfigEntry<float> ShipSafeRadius { get; } = file.Bind<float>("General", "ShipSafeRadius", 20f, "The radius in meters around the ship's center where players can't damage eachother.\nBoth the attacker and the victim are required to be outside the radius for damage to be dealt.\nFor scale, the distance to the edge of the ship's balcony is about 13 meters.The entrance to Experimentation is approximately 100 meters away."); public ConfigEntry<bool> DisableAutoPilot { get; } = file.Bind<bool>("General", "DisableAutoPilot", true, "Whether to disable the \"vote-to-leave\" spectator vote."); public ConfigEntry<float> MinLeaveTime { get; } = file.Bind<float>("General", "MinimumLeaveTime", 15f, new ConfigDescription("The earliest in-game time a player can pull the lever to starting leaving the current moon.Specified in hours on a 24-hour clock (the ship arrives at 8 and leaves at 24).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(8f, 24f), Array.Empty<object>())); public ConfigEntry<float> TimeToLeave { get; } = file.Bind<float>("General", "TimeToLeave", 3f, new ConfigDescription("How many in-game hours it takes for the ship to leave after the lever is pulled.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 16f), Array.Empty<object>())); public ConfigEntry<Permission> JoinTeamPerm { get; } = file.Bind<Permission>("Permissions", "JoinTeam", Permission.Everyone, "Who can use the 'join' command."); public ConfigEntry<Permission> EditTeamPerm { get; } = file.Bind<Permission>("Permissions", "EditTeam", Permission.Everyone, "Who can use the 'set-team-color' and 'set-team-name' commands."); public ConfigEntry<Permission> CreateAndDeleteTeamPerm { get; } = file.Bind<Permission>("Permissions", "CreateAndDeleteTeam", Permission.HostOnly, "Who can use the 'create-team' and 'delete-team' commands."); public ConfigEntry<bool> ShowMouseOnRoundReport { get; } = file.Bind<bool>("Client", "ShowMouseOnRoundReport", false, "If true, you can use the mouse while the round report is shown.If false, the mouse will be locked and hidden and the report will close after a set time."); public ConfigEntry<bool> ShowEndOfMatchCutscene { get; } = file.Bind<bool>("Client", "ShowEndOfMatchCutscene", true, "Whether to show a special cutscene after the last round of the match or just another round report."); public ConfigEntry<Emote> EndOfMatchEmote { get; } = file.Bind<Emote>("Client", "EndOfMatchEmote", Emote.Dance, "The emote to play at the end of the match. Only Dance and Point are available unless BetterEmotes by KlutzyBubbles is installed."); public Config(ConfigFile file) { }//IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Expected O, but got Unknown //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Expected O, but got Unknown //IL_0110: Unknown result type (might be due to invalid IL or missing references) //IL_011a: Expected O, but got Unknown } public enum Permission : byte { Everyone, HostOnly } internal class SpectatorController : MonoBehaviour { private const float CamMoveSpeed = 5f; private readonly Light[] _lights = (Light[])(object)new Light[4]; private PlayerControllerB _localPlayer; private Camera _cam; private InputAction _upAction; private InputAction _downAction; private InputAction _sprintAction; private InputAction _moveAction; private bool _controlsHidden = true; public static SpectatorController Instance { get; private set; } public static void Spawn() { //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Expected O, but got Unknown GameObject val = new GameObject("SpectatorController", new Type[3] { typeof(Camera), typeof(SpectatorController), typeof(AudioListener) }); Object.DontDestroyOnLoad((Object)(object)val); } private void Awake() { //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_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_0078: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: 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_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Expected O, but got Unknown //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: 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) if ((Object)(object)Instance != (Object)null) { Object.Destroy((Object)(object)this); return; } Instance = this; for (int i = 0; i < 4; i++) { Vector3 eulerAngles = (Vector3)(i switch { 0 => new Vector3(50f, 0f, 0f), 1 => new Vector3(120f, 0f, 0f), 2 => new Vector3(50f, 90f, 0f), 3 => new Vector3(50f, -90f, 0f), _ => default(Vector3), }); GameObject val = new GameObject("GhostLight" + i); Light val2 = val.AddComponent<Light>(); HDAdditionalLightData val3 = val.AddComponent<HDAdditionalLightData>(); val.transform.eulerAngles = eulerAngles; val2.type = (LightType)1; val2.shadows = (LightShadows)0; val2.intensity = 10f; ((Object)val).hideFlags = (HideFlags)52; val3.affectsVolumetric = false; _lights[i] = val2; } InputActionAsset actions = IngamePlayerSettings.Instance.playerInput.actions; _upAction = actions.FindAction("Jump", false); _downAction = actions.FindAction("Crouch", false); _sprintAction = actions.FindAction("Sprint", false); _moveAction = actions.FindAction("Move", false); _cam = ((Component)this).GetComponent<Camera>(); DisableCam(); } public void EnableCam() { //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) if (!((Component)this).gameObject.activeSelf) { ((Component)this).gameObject.SetActive(true); ((Component)this).transform.parent = null; StartOfRound instance = StartOfRound.Instance; Camera activeCamera = instance.activeCamera; _cam.CopyFrom(activeCamera); int num = LayerMask.NameToLayer("HelmetVisor"); Camera cam = _cam; cam.cullingMask &= ~(1 << num); Camera cam2 = _cam; cam2.cullingMask |= 0x800000; ((Component)this).transform.position = ((Component)activeCamera).transform.position; ((Component)this).transform.rotation = ((Component)activeCamera).transform.rotation; instance.localPlayerController.ChangeAudioListenerToObject(((Component)this).gameObject); ((Behaviour)instance.localPlayerController.gameplayCamera).enabled = false; instance.SwitchCamera(_cam); UpdateControlText(); Log.Debug("Spectator camera enabled!"); } } public void DisableCam() { if (((Component)this).gameObject.activeSelf) { ((Component)this).gameObject.SetActive(false); Light[] lights = _lights; foreach (Light val in lights) { ((Behaviour)val).enabled = false; } HUDManager instance = HUDManager.Instance; if (instance != null) { instance.ClearControlTips(); } } } private void UpdateControlText() { Keybinds keybinds = Plugin.Config.Keybinds; InputActionAsset actions = IngamePlayerSettings.Instance.playerInput.actions; if (_controlsHidden) { HUDManager.Instance.ChangeControlTip(0, "Show Spectator Controls : [" + _(keybinds.ToggleSpectatorControls) + "]", true); return; } HUDManager.Instance.ChangeControlTip(0, string.Format("Hide Spectator Controls : [{0}]\r\nUp : [{1}]\r\nDown : [{2}]\r\nToggle Light : [{3}]\r\nTeleport to Player : [0-{4}]\r\nExit Spectator Mode : [{5}]", _(keybinds.ToggleSpectatorControls), _(actions["Jump"]), _(actions["Crouch"]), _(keybinds.SpectatorToggleLight), StartOfRound.Instance.connectedPlayersAmount - 1, _(keybinds.ExitSpectator)), true); static string _(InputAction action) { return InputActionRebindingExtensions.GetBindingDisplayString(action, (DisplayStringOptions)0, (string)null); } } private void ToggleLight(CallbackContext context) { if (!((CallbackContext)(ref context)).performed) { return; } PlayerControllerB localPlayer = _localPlayer; if (localPlayer != null && localPlayer.isPlayerDead && !localPlayer.isTypingChat && !_localPlayer.quickMenuManager.isMenuOpen) { Light[] lights = _lights; foreach (Light val in lights) { ((Behaviour)val).enabled = !((Behaviour)val).enabled; } } } public void TeleportToPlayer(PlayerControllerB player) { //IL_009a: 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_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) if (player.isPlayerDead) { if ((Object)(object)player.deadBody != (Object)null && !player.deadBody.deactivated) { ((Component)this).transform.position = ((Component)player.deadBody).transform.position + Vector3.up; } else { HUDManager.Instance.DisplayTip("Can't Teleport", "Specified player is dead with no body!", true, false, "LC_Tip1"); } } if (!player.isPlayerControlled) { HUDManager.Instance.DisplayTip("Can't Teleport", "Specified player is not connected!", true, false, "LC_Tip1"); return; } ((Component)this).transform.position = ((Component)player.gameplayCamera).transform.position; ((Component)this).transform.rotation = ((Component)player.gameplayCamera).transform.rotation; _localPlayer.spectatedPlayerScript = player; _localPlayer.SetSpectatedPlayerEffects(false); } private void ToggleControls(CallbackContext context) { if (!_localPlayer.isTypingChat && !_localPlayer.quickMenuManager.isMenuOpen) { _controlsHidden = !_controlsHidden; UpdateControlText(); } } private void ExitSpectator(CallbackContext context) { if (!_localPlayer.isTypingChat && !_localPlayer.quickMenuManager.isMenuOpen) { if ((Object)(object)Player.Local.Team != (Object)null) { HUDManager.Instance.DisplayTip("Can't Exit", "Currently not allowed to leave spectator!", true, false, "LC_Tip1"); } else { Player.Local.StopSpectatingServerRpc(); } } } private void OnEnable() { Keybinds keybinds = Plugin.Config.Keybinds; keybinds.SpectatorToggleLight.performed += ToggleLight; keybinds.ToggleSpectatorControls.performed += ToggleControls; keybinds.ExitSpectator.performed += ExitSpectator; } private void OnDisable() { Keybinds keybinds = Plugin.Config.Keybinds; keybinds.SpectatorToggleLight.performed -= ToggleLight; keybinds.ToggleSpectatorControls.performed -= ToggleControls; keybinds.ExitSpectator.performed -= ExitSpectator; } private void OnDestroy() { Log.Debug("SpectatorController destroyed"); Light[] lights = _lights; foreach (Light val in lights) { if ((Object)(object)val != (Object)null) { Object.Destroy((Object)(object)((Component)val).gameObject); } } } private void LateUpdate() { //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_0052: 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_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_00b6: 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_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_015f: Unknown result type (might be due to invalid IL or missing references) //IL_016e: 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_0197: Unknown result type (might be due to invalid IL or missing references) //IL_019d: Unknown result type (might be due to invalid IL or missing references) //IL_01a4: Unknown result type (might be due to invalid IL or missing references) //IL_01ae: Unknown result type (might be due to invalid IL or missing references) //IL_01b3: Unknown result type (might be due to invalid IL or missing references) //IL_01bb: Unknown result type (might be due to invalid IL or missing references) //IL_01c0: Unknown result type (might be due to invalid IL or missing references) //IL_01c6: Unknown result type (might be due to invalid IL or missing references) //IL_01cd: Unknown result type (might be due to invalid IL or missing references) //IL_01d7: Unknown result type (might be due to invalid IL or missing references) //IL_01dc: Unknown result type (might be due to invalid IL or missing references) //IL_01e5: Unknown result type (might be due to invalid IL or missing references) //IL_01ea: Unknown result type (might be due to invalid IL or missing references) //IL_01ec: Unknown result type (might be due to invalid IL or missing references) //IL_01ee: Unknown result type (might be due to invalid IL or missing references) //IL_01f3: 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_022b: Unknown result type (might be due to invalid IL or missing references) //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) //IL_0246: Unknown result type (might be due to invalid IL or missing references) //IL_0137: Unknown result type (might be due to invalid IL or missing references) //IL_0146: Unknown result type (might be due to invalid IL or missing references) //IL_0116: Unknown result type (might be due to invalid IL or missing references) //IL_0125: Unknown result type (might be due to invalid IL or missing references) //IL_026c: Unknown result type (might be due to invalid IL or missing references) //IL_0270: Invalid comparison between Unknown and I4 //IL_024f: Unknown result type (might be due to invalid IL or missing references) //IL_0266: 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_026a: 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_0261: Unknown result type (might be due to invalid IL or missing references) //IL_0264: Expected I4, but got Unknown //IL_02f7: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_localPlayer == (Object)null) { _localPlayer = StartOfRound.Instance.localPlayerController; if ((Object)(object)_localPlayer == (Object)null) { return; } } Vector2 val = _moveAction.ReadValue<Vector2>(); MovementActions movement = _localPlayer.playerActions.Movement; Vector2 val2 = ((MovementActions)(ref movement)).Look.ReadValue<Vector2>() * 0.008f * (float)IngamePlayerSettings.Instance.settings.lookSensitivity; if (!IngamePlayerSettings.Instance.settings.invertYAxis) { val2.y *= -1f; } bool flag = _sprintAction.ReadValue<float>() > 0.3f; ((Component)this).transform.Rotate(0f, val2.x, 0f, (Space)0); float num = ((Component)this).transform.eulerAngles.x % 360f + val2.y; if (num < 270f && num > 90f) { ((Component)this).transform.eulerAngles = ((270f - num < num - 90f) ? new Vector3(270f, ((Component)this).transform.eulerAngles.y, 0f) : new Vector3(90f, ((Component)this).transform.eulerAngles.y, 0f)); } else { ((Component)this).transform.eulerAngles = new Vector3(num, ((Component)this).transform.eulerAngles.y, 0f); } float num2 = 5f; if (flag) { num2 *= 5f; } Vector3 val3 = ((Component)this).transform.right * val.x * num2 * Time.deltaTime; Vector3 val4 = ((Component)this).transform.forward * val.y * num2 * Time.deltaTime; Transform transform = ((Component)this).transform; transform.position += val3 + val4; float num3 = (_upAction.ReadValue<float>() - _downAction.ReadValue<float>()) * num2 * Time.deltaTime; Transform transform2 = ((Component)this).transform; transform2.position += Vector3.up * num3; int num4 = -1; for (Key val5 = (Key)41; (int)val5 <= 50; val5 = (Key)(val5 + 1)) { if (((ButtonControl)Keyboard.current[val5]).wasPressedThisFrame) { num4 = val5 - 41; break; } } if (num4 != -1) { PlayerControllerB[] allPlayerScripts = StartOfRound.Instance.allPlayerScripts; if (num4 >= allPlayerScripts.Length) { HUDManager.Instance.DisplayTip("Cannot Teleport", "Specified player index is invalid!", true, false, "LC_Tip1"); } else { TeleportToPlayer(allPlayerScripts[num4]); } } PlayerControllerB[] allPlayerScripts2 = StartOfRound.Instance.allPlayerScripts; foreach (PlayerControllerB val6 in allPlayerScripts2) { if (!((Object)(object)val6 == (Object)(object)_localPlayer) && val6.isPlayerControlled) { val6.ShowNameBillboard(); val6.usernameBillboard.LookAt(((Component)this).transform.position); } } ((Behaviour)_localPlayer.playerScreen).enabled = true; } } public class Keybinds : LcInputActions { [InputAction(/*Could not decode attribute arguments.*/)] public InputAction ToggleSpectatorControls { get; private set; } [InputAction(/*Could not decode attribute arguments.*/)] public InputAction SpectatorToggleLight { get; private set; } [InputAction(/*Could not decode attribute arguments.*/)] public InputAction ExitSpectator { get; private set; } } internal static class Log { public static ManualLogSource Source { get; private set; } static Log() { Source = Logger.CreateLogSource("CompetitiveCompany"); } public static void Fatal(string message) { Source.LogFatal((object)message); } public static void Error(string message) { Source.LogError((object)message); } public static void Warning(string message) { Source.LogWarning((object)message); } public static void Message(string message) { Source.LogMessage((object)message); } public static void Info(string message) { Source.LogInfo((object)message); } public static void Debug(string message) { Source.LogDebug((object)message); } } public struct NetworkedSettings : INetworkSerializable { public bool ForceSuits; public bool FriendlyFire; public int NumberOfRounds; public float ShipSafeRadius; public bool DisableAutoPilot; public float MinLeaveTime; public float TimeToLeave; public Permission JoinTeamPerm; public Permission CreateAndDeleteTeamPerm; public Permission EditTeamPerm; public NetworkedSettings(Config config) { ForceSuits = config.ForceSuits.Value; FriendlyFire = config.FriendlyFire.Value; NumberOfRounds = config.NumberOfRounds.Value; ShipSafeRadius = config.ShipSafeRadius.Value; DisableAutoPilot = config.DisableAutoPilot.Value; MinLeaveTime = config.MinLeaveTime.Value; TimeToLeave = config.TimeToLeave.Value; JoinTeamPerm = config.JoinTeamPerm.Value; CreateAndDeleteTeamPerm = config.CreateAndDeleteTeamPerm.Value; EditTeamPerm = config.EditTeamPerm.Value; } public unsafe void NetworkSerialize<T>(BufferSerializer<T> serializer) where T : IReaderWriter { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0036: 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_004c: 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_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_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_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Unknown result type (might be due to invalid IL or missing references) ((BufferSerializer<bool>*)(&serializer))->SerializeValue<bool>(ref ForceSuits, default(ForPrimitives)); ((BufferSerializer<bool>*)(&serializer))->SerializeValue<bool>(ref FriendlyFire, default(ForPrimitives)); ((BufferSerializer<int>*)(&serializer))->SerializeValue<int>(ref NumberOfRounds, default(ForPrimitives)); ((BufferSerializer<float>*)(&serializer))->SerializeValue<float>(ref ShipSafeRadius, default(ForPrimitives)); ((BufferSerializer<bool>*)(&serializer))->SerializeValue<bool>(ref DisableAutoPilot, default(ForPrimitives)); ((BufferSerializer<float>*)(&serializer))->SerializeValue<float>(ref MinLeaveTime, default(ForPrimitives)); ((BufferSerializer<float>*)(&serializer))->SerializeValue<float>(ref TimeToLeave, default(ForPrimitives)); ((BufferSerializer<Permission>*)(&serializer))->SerializeValue<Permission>(ref JoinTeamPerm, default(ForEnums)); ((BufferSerializer<Permission>*)(&serializer))->SerializeValue<Permission>(ref CreateAndDeleteTeamPerm, default(ForEnums)); ((BufferSerializer<Permission>*)(&serializer))->SerializeValue<Permission>(ref EditTeamPerm, default(ForEnums)); } } internal static class NetworkPrefabs { public static Session Session { get; } public static Team Team { get; } static NetworkPrefabs() { Session = NetworkPrefabs.CreateNetworkPrefab("Session").AddComponent<Session>(); Team = NetworkPrefabs.CreateNetworkPrefab("Team").AddComponent<Team>(); Log.Debug("Created NetworkPrefabs"); } public static void Initialize() { } } [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInIncompatibility("ShaosilGaming.GeneralImprovements")] [BepInPlugin("com.kesomannen.competitivecompany", "CompetitiveCompany", "0.2.0")] public class Plugin : BaseUnityPlugin { public const string Guid = "com.kesomannen.competitivecompany"; private const string Name = "CompetitiveCompany"; private const string Version = "0.2.0"; public const int MinTeams = 2; public const int MaxTeams = 8; public static Config Config { get; private set; } private void Awake() { //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Expected O, but got Unknown //IL_010d: Unknown result type (might be due to invalid IL or missing references) //IL_0113: Expected O, but got Unknown Stopwatch stopwatch = Stopwatch.StartNew(); Log.Debug("Loading config..."); Config = new Config(((BaseUnityPlugin)this).Config); Log.Debug("Patching..."); Harmony val = new Harmony("com.kesomannen.competitivecompany"); val.PatchAll(typeof(ChatPatches)); Player.Patch(); MatchEndScreen.Patch(); RoundReport.Patch(); MiscPatches.Patch(); Team.Patch(); Session.Patch(); LeverPatches.Patch(); Log.Debug("Running InitializeOnLoad methods..."); RunInitializeOnLoadMethods(); Log.Debug("Initializing terminal commands..."); TerminalCommands.Initialize(); Log.Debug("Initializing prefabs..."); NetworkPrefabs.Initialize(); Log.Debug("Loading assets..."); Assets.Load(); Log.Debug("Checking for soft dependencies and compatibility patches..."); SoftDependencyHelper.CheckFor("LethalConfig", "ainavt.lc.lethalconfig", LethalConfigCompat.Initialize); SoftDependencyHelper.CheckFor("BetterEmotes", "BetterEmotes", delegate { }); NetcodeValidator val2 = new NetcodeValidator("com.kesomannen.competitivecompany"); val2.BindToPreExistingObjectByBehaviour<Player, PlayerControllerB>(); Session.OnSessionStarted += delegate { SpectatorController.Spawn(); }; Session.OnSessionEnded += delegate { SpectatorController instance = SpectatorController.Instance; if ((Object)(object)instance != (Object)null) { Object.Destroy((Object)(object)((Component)instance).gameObject); } }; Log.Info($"Plugin loaded in {stopwatch.ElapsedMilliseconds}ms"); } private static void RunInitializeOnLoadMethods() { Type[] types = Assembly.GetExecutingAssembly().GetTypes(); Type[] array = types; foreach (Type type in array) { try { MethodInfo[] methods = type.GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic); MethodInfo[] array2 = methods; foreach (MethodInfo methodInfo in array2) { object[] customAttributes = methodInfo.GetCustomAttributes(typeof(RuntimeInitializeOnLoadMethodAttribute), inherit: false); if (customAttributes.Length != 0) { methodInfo.Invoke(null, null); } } } catch (FileNotFoundException) { } } } } internal class TerminalCommands { private const string NoPermsMessage = "You do not have permission to use this command!"; private const string AlreadyPlayingMessage = "You cannot use this command while a round is active!"; private TerminalCommands() { } internal static void Initialize() { TerminalRegistry.CreateTerminalRegistry().RegisterFrom<TerminalCommands>(new TerminalCommands()); } [TerminalCommand("settings", true)] [CommandInfo("Show the current game settings.", "")] private string SettingsCommand() { NetworkedSettings settings = Session.Current.Settings; return "Current game settings:\n\nFriendly fire: " + FormatBool(settings.FriendlyFire) + "\n" + $"Number of rounds: {settings.NumberOfRounds}\n" + $"Ship safe radius: {settings.ShipSafeRadius}m\n" + "Autopilot: " + FormatBool(!settings.DisableAutoPilot) + "\nEarliest ship start time: " + FormatTimeOfDay(settings.MinLeaveTime) + "\nShip leave time: " + FormatTimeSpan(settings.TimeToLeave); static string FormatBool(bool value) { if (!value) { return "Disabled"; } return "Enabled"; } static string FormatTimeOfDay(float hours) { TimeSpan timeSpan2 = TimeSpan.FromHours(hours); string arg = ((timeSpan2.Hours < 12) ? "AM" : "PM"); hours = timeSpan2.Hours % 12; if (hours == 0f) { hours = 12f; } return $"{hours}:{timeSpan2.Minutes:D2} {arg}"; } static string FormatTimeSpan(float hours) { TimeSpan timeSpan = TimeSpan.FromHours(hours); if (timeSpan.Minutes != 0) { return $"{timeSpan.Hours}h {timeSpan.Minutes}m"; } return $"{timeSpan.Hours}h"; } } [TerminalCommand("join", true)] [CommandInfo("Join a team. Host can join other players by specifying their username after the team name.", "<team> [player]")] private string JoinCommand([RemainingText] string input) { string input2 = input; if (Session.Current.IsRoundActive) { return "You cannot use this command while a round is active!"; } if (!CheckPerms((NetworkedSettings settings) => settings.JoinTeamPerm)) { return "You do not have permission to use this command!"; } if (NetworkManager.Singleton.IsServer) { return Server(); } return Client(); string Client() { //IL_005b: Unknown result type (might be due to invalid IL or missing references) if (!Session.Current.Teams.TryGet(input2, out Team team)) { return "Team '" + input2 + "' not found!"; } Player local = Player.Local; if ((Object)(object)local.Team == (Object)(object)team) { return "You are already in team " + team.ColoredName + "!"; } local.SetTeamServerRpc(NetworkBehaviourReference.op_Implicit((NetworkBehaviour)(object)team)); return "Joined team " + team.ColoredName + "."; } string Server() { //IL_019b: Unknown result type (might be due to invalid IL or missing references) int[] array = (from t in input2.Select((char c, int i) => (c, i)) where t.c == ' ' select t.i).Append(input2.Length).ToArray(); string text = null; Player player = null; Team team2 = null; for (int j = 0; j < array.Length; j++) { string name = input2.Substring(0, array[j]); if (Session.Current.Teams.TryGet(name, out team2)) { if (j == array.Length - 1) { player = Player.Local; break; } string text2 = input2; int num = array[j] + 1; text = text2.Substring(num, text2.Length - num); if (Session.Current.Players.TryGetByName(text, out player)) { break; } } } if ((Object)(object)team2 == (Object)null || (Object)(object)player == (Object)null) { if (text != null) { return "Player '" + text + "' not found!"; } return "Invalid team or player name!"; } if ((Object)(object)player.Team == (Object)(object)team2) { if (!((NetworkBehaviour)player).IsOwner) { return "Player " + text + " is already in team " + team2.ColoredName + "!"; } return "You are already in team " + team2.ColoredName + "!"; } player.SetTeamFromServer(NetworkBehaviourReference.op_Implicit((NetworkBehaviour)(object)team2)); if (!((NetworkBehaviour)player).IsOwner) { return "Moved " + text + " to team " + team2.ColoredName; } return "Joined team " + team2.ColoredName + "."; } } [TerminalCommand("scramble-teams", true)] [CommandInfo("Randomly assign players to teams. Host only.", "")] private string ScrambleTeams() { //IL_00ff: Unknown result type (might be due to invalid IL or missing references) if (Session.Current.IsRoundActive) { return "You cannot use this command while a round is active!"; } if (!NetworkManager.Singleton.IsHost) { return "You do not have permission to use this command!"; } Dictionary<Team, int> dictionary = new Dictionary<Team, int>(); foreach (Team team in Session.Current.Teams) { dictionary[team] = 0; } foreach (Player player in Session.Current.Players) { if (!((Object)(object)player.Team == (Object)null)) { KeyValuePair<Team, int>[] array = (from kvp in dictionary group kvp by kvp.Value into grouping orderby grouping.Key select grouping).First().ToArray(); Team key = array[Random.Range(0, array.Length)].Key; player.SetTeamFromServer(NetworkBehaviourReference.op_Implicit((NetworkBehaviour)(object)key)); dictionary[key]++; } } return "Teams scrambled!"; } [TerminalCommand("create-team", true)] [CommandInfo("Create a new team with a name and random color.", "<name>")] private string CreateTeam([RemainingText] string teamName) { //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) if (Session.Current.IsRoundActive) { return "You cannot use this command while a round is active!"; } if (!CheckPerms((NetworkedSettings settings) => settings.CreateAndDeleteTeamPerm)) { return "You do not have permission to use this command!"; } if (Session.Current.Teams.Count >= 8) { return "Maximum number of teams reached!"; } if (Session.Current.Teams.TryGet(teamName, out Team _)) { return "Team " + teamName + " already exists!"; } if (teamName.Length > 128) { return "Team name is too long!"; } Color color = Random.ColorHSV(0f, 1f, 1f, 1f, 1f, 1f); Session.Current.CreateTeamServerRpc(FixedString128Bytes.op_Implicit(teamName), color); return "Created team " + teamName + "."; } [TerminalCommand("delete-team", true)] [CommandInfo("Delete an empty team.", "<team>")] private string DeleteTeam([RemainingText] string teamName) { if (Session.Current.IsRoundActive) { return "You cannot use this command while a round is active!"; } if (!CheckPerms((NetworkedSettings settings) => settings.CreateAndDeleteTeamPerm)) { return "You do not have permission to use this command!"; } if (Session.Current.Teams.Count <= 2) { return "Minimum number of teams reached!"; } if (!Session.Current.Teams.TryGet(teamName, out Team team)) { return "Team " + teamName + " not found!"; } if (team.Members.Any()) { return "Team " + teamName + " still has members!"; } team.DeleteServerRpc(); return "Deleted team " + teamName + "."; } [TerminalCommand("teams", true)] [CommandInfo("Lists all teams and their scores.", "")] private string ListTeams() { return string.Join('\n', Session.Current.Teams.PrettyPrint(51, color: true)); } [TerminalCommand("set-team-color", true)] [CommandInfo("Set the color of your current team.", "<color>")] private string ColorCommand([RemainingText] string input) { //IL_0091: 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) if (Session.Current.IsRoundActive) { return "You cannot use this command while a round is active!"; } if (!CheckPerms((NetworkedSettings settings) => settings.EditTeamPerm)) { return "You do not have permission to use this command!"; } Team team = Player.Local.Team; if ((Object)(object)team == (Object)null) { return "You are not in a team!"; } Color? val = ColorUtil.ParseColor(input); if (!val.HasValue) { string text = string.Join(", ", ColorUtil.ColorNames.Keys); return "Invalid color! Please use hex format (e.g. #FF0000) or one of the following: " + text + "."; } team.SetColorServerRpc(val.Value); string text2 = (input.StartsWith("#") ? input : ("#" + ColorUtility.ToHtmlStringRGB(val.Value))); return "Set color of team " + team.Name + " to <color=" + text2 + ">" + input + "</color>."; } [TerminalCommand("set-team-name", true)] [CommandInfo("Rename your current team.", "<name>")] private string RenameCommand([RemainingText] string name) { //IL_008f: Unknown result type (might be due to invalid IL or missing references) if (Session.Current.IsRoundActive) { return "You cannot use this command while a round is active!"; } if (!CheckPerms((NetworkedSettings settings) => settings.EditTeamPerm)) { return "You do not have permission to use this command!"; } Team team = Player.Local.Team; if ((Object)(object)team == (Object)null) { return "You are not in a team!"; } if (Session.Current.Teams.TryGet(name, out Team _)) { return "Team " + name + " already exists!"; } if (name.Length > 64) { return "Team name is too long!"; } team.SetNameServerRpc(FixedString128Bytes.op_Implicit(name)); return "Renamed team to " + name + "."; } private static bool CheckPerms(Func<NetworkedSettings, Permission> getPerms) { NetworkedSettings settings = Session.Current.Settings; if (!NetworkManager.Singleton.IsHost) { return getPerms(settings) == Permission.Everyone; } return true; } } internal static class SuitUtil { public static UnlockableItem GetOriginalSuit() { return StartOfRound.Instance.unlockablesList.unlockables.Find((UnlockableItem item) => (Object)(object)item.suitMaterial != (Object)null && item.alreadyUnlocked); } public static UnlockableItem CreateSuit(string name) { //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_0012: 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_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_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_005a: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0072: 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_008a: 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_00a2: 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_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: 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_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Expected O, but got Unknown UnlockableItem originalSuit = GetOriginalSuit(); return new UnlockableItem { unlockableName = name, prefabObject = originalSuit.prefabObject, unlockableType = originalSuit.unlockableType, shopSelectionNode = originalSuit.shopSelectionNode, alwaysInStock = originalSuit.alwaysInStock, IsPlaceable = originalSuit.IsPlaceable, hasBeenMoved = originalSuit.hasBeenMoved, placedPosition = originalSuit.placedPosition, placedRotation = originalSuit.placedRotation, inStorage = originalSuit.inStorage, canBeStored = originalSuit.canBeStored, maxNumber = originalSuit.maxNumber, hasBeenUnlockedByPlayer = originalSuit.hasBeenUnlockedByPlayer, suitMaterial = originalSuit.suitMaterial, headCostumeObject = originalSuit.headCostumeObject, lowerTorsoCostumeObject = originalSuit.lowerTorsoCostumeObject, alreadyUnlocked = originalSuit.alreadyUnlocked, unlockedInChallengeFile = originalSuit.unlockedInChallengeFile, spawnPrefab = originalSuit.spawnPrefab, jumpAudio = originalSuit.jumpAudio }; } } } namespace CompetitiveCompany.Util { public static class ColorUtil { private static readonly Dictionary<string, Color> _colorNames = new Dictionary<string, Color> { { "red", Color.red }, { "green", Color.green }, { "blue", Color.blue }, { "yellow", Color.yellow }, { "cyan", Color.cyan }, { "magenta", Color.magenta }, { "white", Color.white }, { "black", Color.black } }; public static IReadOnlyDictionary<string, Color> ColorNames => _colorNames; public static Color? ParseColor(string str) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) if (_colorNames.TryGetValue(str, out var value)) { return value; } if (ColorUtility.TryParseHtmlString(str, ref value)) { return value; } return null; } } public enum Emote { Dance = 1, Point, MiddleFinger, Clap, Shy, Griddy, Twerk, Salute, Prisyadka } public static class EmoteUtil { public static bool IsVanilla(int emoteID) { if ((uint)(emoteID - 1) <= 1u) { return true; } return false; } } public static class TerminalUtil { private static Terminal? _terminal; public static Terminal Instance { get { if ((Object)(object)_terminal != (Object)null) { return _terminal; } Terminal val = Object.FindObjectOfType<Terminal>(); if ((Object)(object)val == (Object)null) { throw new Exception("Terminal not found in scene"); } return _terminal = val; } } } public static class TimeUtil { public static TimeSpan NormalizedToGameTime(float normalizedTime) { TimeOfDay instance = TimeOfDay.Instance; return TimeSpan.FromHours(normalizedTime * (float)instance.numberOfHours + 6f); } public static TimeSpan GetCurrentGameTime() { return NormalizedToGameTime(TimeOfDay.Instance.normalizedTimeOfDay); } } } namespace CompetitiveCompany.UI { internal class MatchEndScreen : MonoBehaviour { [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static hook_OnEnable <>9__23_0; public static hook_OnDisable <>9__23_1; internal void <Patch>b__23_0(orig_OnEnable orig, HUDManager self) { orig.Invoke(self); _instance = Object.Instantiate<MatchEndScreen>(Assets.MatchEndScreenPrefab); } internal void <Patch>b__23_1(orig_OnDisable orig, HUDManager self) { if ((Object)(object)_instance != (Object)null) { Object.Destroy((Object)(object)_instance); _instance = null; } orig.Invoke(self); } } [SerializeField] private Light _spotLight; [SerializeField] private Light _pointLight; [SerializeField] private GameObject _cameraContainer; [SerializeField] private Transform _playerPosition; [SerializeField] private float _playerRadius = 3f; [SerializeField] private float _playerSpacing = MathF.PI / 8f; [SerializeField] private float _showDuration; [SerializeField] private float _showDelay; [SerializeField] private GameObject _ui; [SerializeField] private TMP_Text _title; [SerializeField] private Image _titleBackground; private Camera _camera; private Camera _gameplayCamera; private readonly List<(GameObject, Player)> _playerModels = new List<(GameObject, Player)>(); private readonly Dictionary<Light, bool> _lightStates = new Dictionary<Light, bool>(); private static readonly int _emoteNumberID = Animator.StringToHash("emoteNumber"); private static MatchEndScreen? _instance; private IEnumerator Start() { Session.Current.OnMatchEnded += OnMatchEnded; yield return null; _ui.transform.SetParent(RoundReport.GetVanillaElement().parent); } private void OnDestroy() { Session.Current.OnMatchEnded -= OnMatchEnded; } private void OnMatchEnded(MatchEndedContext ctx) { if (!Plugin.Config.ShowEndOfMatchCutscene.Value) { return; } ValueTweens.DelayedCall((Object)(object)this, _showDelay, (Action)delegate { //IL_0078: 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_0100: Unknown result type (might be due to invalid IL or missing references) //IL_0105: Unknown result type (might be due to invalid IL or missing references) //IL_0107: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Unknown result type (might be due to invalid IL or missing references) //IL_0110: Unknown result type (might be due to invalid IL or missing references) //IL_0112: Unknown result type (might be due to invalid IL or missing references) //IL_012d: Unknown result type (might be due to invalid IL or missing references) //IL_0134: Expected O, but got Unknown if ((Object)(object)_camera == (Object)null) { CreateCamera(); } Light[] array = Object.FindObjectsOfType<Light>(); foreach (Light val in array) { _lightStates[val] = ((Component)val).gameObject.activeSelf; ((Component)val).gameObject.SetActive(false); } _pointLight.color = ctx.WinningTeam.Color; _title.text = $"{ctx.WinningTeam.RawName} win!"; int num = 0; IReadOnlyCollection<Player> members = ctx.WinningTeam.Members; SkinnedMeshRenderer val5 = default(SkinnedMeshRenderer); foreach (Player item3 in members) { Transform val2 = ((Component)item3).transform.Find("ScavengerModel"); (Vector3, Quaternion) tuple = CalculatePlayerPosition(num, members.Count); Vector3 item = tuple.Item1; Quaternion item2 = tuple.Item2; Transform val3 = Object.Instantiate<Transform>(val2, item, item2); foreach (Transform item4 in val3) { Transform val4 = item4; ((Component)val4).gameObject.SetActive(true); if (((Component)val4).TryGetComponent<SkinnedMeshRenderer>(ref val5)) { ((Renderer)val5).enabled = true; ((Renderer)val5).shadowCastingMode = (ShadowCastingMode)1; } } Transform val6 = val3.Find("metarig"); Animator component = ((Component)val6).GetComponent<Animator>(); int endOfMatchEmoteChecked = item3.EndOfMatchEmoteChecked; Log.Debug($"Setting emote ID for {item3.DebugName} to {endOfMatchEmoteChecked}"); component.SetInteger(_emoteNumberID, endOfMatchEmoteChecked); component.SetLayerWeight(component.GetLayerIndex("UpperBodyEmotes"), 0f); component.SetLayerWeight(component.GetLayerIndex("EmotesNoArms"), 1f); ((Component)val6.Find("ScavengerModelArmsOnly")).gameObject.SetActive(false); ((Component)val6.Find("CameraContainer")).gameObject.SetActive(false); _playerModels.Add((((Component)val3).gameObject, item3)); num++; } foreach (Player player in Session.Current.Players) { if (player.IsControlled) { ((Component)player.Controller).gameObject.SetActive(false); } } _cameraContainer.SetActive(true); ((Component)_spotLight).gameObject.SetActive(true); ((Component)_pointLight).gameObject.SetActive(true); _camera.fieldOfView = 65f; StartOfRound.Instance.SwitchCamera(_camera); HUDManager.Instance.HideHUD(true); ((MonoBehaviour)this).StartCoroutine(WaitThenHide()); }); IEnumerator WaitThenHide() { yield return DisablingExtensions.SetObjectEnabledRoutine(_ui, true, true); yield return (object)new WaitForSeconds(_showDuration); yield return DisablingExtensions.SetObjectEnabledRoutine(_ui, false, true); Hide(); } } private void Hide() { foreach (var (val2, active) in _lightStates) { if (!((Object)(object)val2 == (Object)null)) { ((Component)val2).gameObject.SetActive(active); } } _lightStates.Clear(); foreach (var (val3, player) in _playerModels) { Object.Destroy((Object)(object)val3); ((Component)player.Controller).gameObject.SetActive(true); } _playerModels.Clear(); foreach (Player player2 in Session.Current.Players) { if (player2.IsControlled) { ((Component)player2.Controller).gameObject.SetActive(true); } } _cameraContainer.SetActive(false); ((Component)_spotLight).gameObject.SetActive(false); ((Component)_pointLight).gameObject.SetActive(false); StartOfRound.Instance.SwitchCamera(_gameplayCamera); HUDManager.Instance.HideHUD(false); } private void CreateCamera() { //IL_0075: 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) _gameplayCamera = Player.Local.Controller.gameplayCamera; _camera = _cameraContainer.AddComponent<Camera>(); _camera.CopyFrom(_gameplayCamera); int num = LayerMask.NameToLayer("HelmetVisor"); Camera camera = _camera; camera.cullingMask &= ~(1 << num); ((Component)_camera).transform.rotation = Quaternion.Euler(0f, 270f, 0f); ((Component)_camera).transform.localPosition = new Vector3(7.5f, 1.9f, -14.3f); } private (Vector3, Quaternion) CalculatePlayerPosition(int index, int totalPlayers) { //IL_0006: 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_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0043: 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_0077: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) Vector3 val = _playerPosition.position + new Vector3(_playerRadius, 0f, 0f); float num = (float)index - (float)(totalPlayers - 1) / 2f; float num2 = MathF.PI - num * _playerSpacing; float num3 = val.x + _playerRadius * Mathf.Cos(num2); float num4 = val.z + _playerRadius * Mathf.Sin(num2); Vector3 val2 = default(Vector3); ((Vector3)(ref val2))..ctor(num3, _playerPosition.position.y, num4); Quaternion item = Quaternion.LookRotation(val - val2); return (val2, item); } public static void Patch() { //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_001f: Expected O, but got Unknown //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Expected O, but got Unknown object obj = <>c.<>9__23_0; if (obj == null) { hook_OnEnable val = delegate(orig_OnEnable orig, HUDManager self) { orig.Invoke(self); _instance = Object.Instantiate<MatchEndScreen>(Assets.MatchEndScreenPrefab); }; <>c.<>9__23_0 = val; obj = (object)val; } HUDManager.OnEnable += (hook_OnEnable)obj; object obj2 = <>c.<>9__23_1; if (obj2 == null) { hook_OnDisable val2 = delegate(orig_OnDisable orig, HUDManager self) { if ((Object)(object)_instance != (Object)null) { Object.Destroy((Object)(object)_instance); _instance = null; } orig.Invoke(self); }; <>c.<>9__23_1 = val2; obj2 = (object)val2; } HUDManager.OnDisable += (hook_OnDisable)obj2; } } public class MockTeam : ITeam { private static readonly MockTeam[] _mockTeams = new MockTeam[4] { new MockTeam { Name = "Manticoils", Color = Color.red, RoundScore = 100, TotalScore = 1000 }, new MockTeam { Name = "Hoarding bugs", Color = Color.green, RoundScore = 200, TotalScore = 800 }, new MockTeam { Name = "Brackens", Color = Color.blue, RoundScore = 300, TotalScore = 1200 }, new MockTeam { Name = "Locust Bees", Color = Color.yellow, RoundScore = 400, TotalScore = 400 } }; public string Name { get; set; } public Color Color { get; set; } public int RoundScore { get; set; } public int TotalScore { get; set; } public static IReadOnlyList<MockTeam> Teams => _mockTeams; } internal class RoundReport : MonoBehaviour { [Serializable] private class Tab { public TabButton Button; public GameObject[] Content; } [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static hook_OnEnable <>9__20_0; public static hook_OnDisable <>9__20_1; internal void <Patch>b__20_0(orig_OnEnable orig, HUDManager self) { //IL_002c: 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) orig.Invoke(self); Transform vanillaElement = GetVanillaElement(); _instance = Object.Instantiate<RoundReport>(Assets.RoundReportPrefab, vanillaElement.parent); ((Component)_instance).transform.localScale = Vector3.one * 0.4f; Log.Debug("RoundReport mounted"); } internal void <Patch>b__20_1(orig_OnDisable orig, HUDManager self) { if ((Object)(object)_instance != (Object)null) { Object.Destroy((Object)(object)((Component)_instance).gameObject); _instance = null; Log.Debug("RoundReport destroyed"); } orig.Invoke(self); } } [SerializeField] private float _autoScrollDuration; [SerializeField] private RectTransform _autoScrollBar; [SerializeField] private GameObject _panel; [SerializeField] private Tab[] _tabs; [Space] [SerializeField] private RoundResultsPage _roundResultsPage; [SerializeField] private StandingsPage _standingsPage; [SerializeField] private TeamPerformancePage _teamPerformancePage; private Tab? _selectedTab; private Coroutine? _autoScrollCoroutine; private const float Scale = 0.4f; private static RoundReport? _instance; private void Start() { Tab[] tabs = _tabs; foreach (Tab tab in tabs) { tab.Button.OnClicked += OnTabButtonClicked; } if (Application.isEditor) { OnRoundEnded(default(RoundEndedContext)); } else { Session.Current.OnRoundEnded += OnRoundEnded; } } private void OnDestroy() { Tab[] tabs = _tabs; foreach (Tab tab in tabs) { tab.Button.OnClicked -= OnTabButtonClicked; } if (!Application.isEditor) { Session.Current.OnRoundEnded -= OnRoundEnded; } } private void OnRoundEnded(RoundEndedContext ctx) { if (!Application.isEditor) { ((Component)GetVanillaElement()).gameObject.SetActive(false); } if (!ctx.WasLastRound) { _roundResultsPage.Populate(); _standingsPage.Populate(); _teamPerformancePage.Populate(); SwitchTab(_tabs[0]); if (Plugin.Config.ShowMouseOnRoundReport.Value) { Cursor.lockState = (CursorLockMode)0; Cursor.visible = true; Player.Local.Controller.quickMenuManager.isMenuOpen = true; } else { _autoScrollCoroutine = ((MonoBehaviour)this).StartCoroutine(AutoScroll()); } _panel.SetActive(true); } } public void Hide() { if (Plugin.Config.ShowMouseOnRoundReport.Value) { Cursor.lockState = (CursorLockMode)1; Cursor.visible = false; Player.Local.Controller.quickMenuManager.isMenuOpen = false; } DisablingExtensions.DisableObject(_panel, true); StopCoroutineIfNotNull(ref _autoScrollCoroutine); } private void OnTabButtonClicked(TabButton tabButton) { StopCoroutineIfNotNull(ref _autoScrollCoroutine); ((Component)_autoScrollBar).gameObject.SetActive(false); Tab[] tabs = _tabs; foreach (Tab tab in tabs) { if (!((Object)(object)tab.Button != (Object)(object)tabButton)) { SwitchTab(tab); break; } } } private void SwitchTab(Tab tab) { if (_selectedTab == tab) { return; } if (_selectedTab != null) { _selectedTab.Button.Selected = false; GameObject[] content = _selectedTab.Content; foreach (GameObject val in content) { val.SetActive(false); } } _selectedTab = tab; _selectedTab.Button.Selected = true; GameObject[] content2 = _selectedTab.Content; foreach (GameObject val2 in content2) { val2.SetActive(true); } } private IEnumerator AutoScroll() { ((Component)_autoScrollBar).gameObject.SetActive(true); for (int i = 1; i <= 3; i++) { float t = 0f; _autoScrollBar.anchorMax = Vector2.zero; for (; t < _autoScrollDuration; t += Time.deltaTime) { float num = Mathf.SmoothStep(0f, 1f, t / _autoScrollDuration); _autoScrollBar.anchorMax = new Vector2(num, 0f); yield return null; } if (i == 3) { Hide(); } else { SwitchTab(_tabs[i]); } } } private void StopCoroutineIfNotNull(ref Coroutine? coroutine) { if (coroutine != null) { ((MonoBehaviour)this).StopCoroutine(coroutine); coroutine = null; } } internal static Transform GetVanillaElement() { return ((Component)HUDManager.Instance.statsUIElements.allPlayersDeadOverlay).transform.parent.parent; } internal static void Patch() { //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_001f: Expected O, but got Unknown //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Expected O, but got Unknown object obj = <>c.<>9__20_0; if (obj == null) { hook_OnEnable val = delegate(orig_OnEnable orig, HUDManager self) { //IL_002c: 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) orig.Invoke(self); Transform vanillaElement = GetVanillaElement(); _instance = Object.Instantiate<RoundReport>(Assets.RoundReportPrefab, vanillaElement.parent); ((Component)_instance).transform.localScale = Vector3.one * 0.4f; Log.Debug("RoundReport mounted"); }; <>c.<>9__20_0 = val; obj = (object)val; } HUDManager.OnEnable += (hook_OnEnable)obj; object obj2 = <>c.<>9__20_1; if (obj2 == null) { hook_OnDisable val2 = delegate(orig_OnDisable orig, HUDManager self) { if ((Object)(object)_instance != (Object)null) { Object.Destroy((Object)(object)((Component)_instance).gameObject); _instance = null; Log.Debug("RoundReport destroyed"); } orig.Invoke(self); }; <>c.<>9__20_1 = val2; obj2 = (object)val2; } HUDManager.OnDisable += (hook_OnDisable)obj2; } } internal class RoundResultsPage : MonoBehaviour { [SerializeField] private TeamResultsPage _teamResultsPage; public void Populate() { _teamResultsPage.Reset(); IReadOnlyList<ITeam> readOnlyList; if (!Application.isEditor) { IReadOnlyList<ITeam> teams = Session.Current.Teams; readOnlyList = teams; } else { IReadOnlyList<ITeam> teams = MockTeam.Teams; readOnlyList = teams; } IReadOnlyList<ITeam> teams2 = readOnlyList; _teamResultsPage.Populate(teams2, TeamMetric.RoundScore, showWinner: true); } } internal class StandingsPage : MonoBehaviour { [SerializeField] private TeamResultsPage _teamResultsPage; public void Populate() { _teamResultsPage.Reset(); bool showWinner; IReadOnlyList<ITeam> teams; if (Application.isEditor) { showWinner = true; teams = MockTeam.Teams; } else { showWinner = Session.Current.RoundNumber == Session.Current.Settings.NumberOfRounds; teams = Session.Current.Teams; } _teamResultsPage.Populate(teams, TeamMetric.TotalScore, showWinner); } } internal class TabButton : MonoBehaviour, IPointerDownHandler, IEventSystemHandler, IPointerEnterHandler, IPointerExitHandler { [SerializeField] private TMP_Text _label; [SerializeField] private Image _background; [Space] [SerializeField] private Sprite _defaultBackground; [SerializeField] private Color _unselectedTextColor; [SerializeField] private Color _selectedTextColor; [Space] [SerializeField] private UnityEvent _onSelected; [SerializeField] private UnityEvent _onDeselected; private bool _selected; public bool Selected { get { return _selected; } set { _selected = value; SetState(value); } } public event Action<TabButton>? OnClicked; public void OnPointerDown(PointerEventData eventData) { this.OnClicked?.Invoke(this); } public void OnPointerEnter(PointerEventData eventData) { if (!Selected) { SetState(selected: true, invokeEvents: false); } } public void OnPointerExit(PointerEventData eventData) { if (!Selected) { SetState(selected: false, invokeEvents: false); } } private void SetState(bool selected, bool invokeEvents = true) { //IL_0012: 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) ((Graphic)_label).color = (selected ? _selectedTextColor : _unselectedTextColor); _background.sprite = (selected ? null : _defaultBackground); if (invokeEvents) { if (selected) { _onSelected.Invoke(); } else { _onDeselected.Invoke(); } } } } internal class TeamPerformanceMember : MonoBehaviour { [SerializeField] private TMP_Text _nameText; [SerializeField] private TMP_Text _notesText; [Space] [SerializeField] private Image _outcomeImage; [SerializeField] private Sprite _survivedIcon; [SerializeField] private Sprite _dieIcon; [SerializeField] private Sprite _missingIcon; public void Initialize(string name, IEnumerable<string> notes, Outcome outcome) { _nameText.text = name; StringBuilder stringBuilder = new StringBuilder("Notes:\n"); foreach (string note in notes) { stringBuilder.Append("* "); stringBuilder.AppendLine(note); } _notesText.text = stringBuilder.ToString(); Image outcomeImage = _outcomeImage; outcomeImage.sprite = (Sprite)(outcome switch { Outcome.Survived => _survivedIcon, Outcome.Died => _dieIcon, Outcome.Missing => _missingIcon, _ => throw new ArgumentOutOfRangeException("outcome", outcome, null), }); } } public enum Outcome { Survived, Died, Missing } internal class TeamPerformancePage : MonoBehaviour { [SerializeField] private TeamPerformanceMember _memberPrefab; [SerializeField] private Transform _memberContainer; [SerializeField] private TMP_Text _gradeText; [SerializeField] private TMP_Text _collectedText; private readonly List<TeamPerformanceMember> _memberUIs = new List<TeamPerformanceMember>(); public void Populate() { //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Invalid comparison between Unknown and I4 if (Application.isEditor) { return; } foreach (TeamPerformanceMember memberUI in _memberUIs) { Object.Destroy((Object)(object)((Component)memberUI).gameObject); } _memberUIs.Clear(); Team team = Player.Local.Team; if ((Object)(object)team == (Object)null) { return; } foreach (Player member in team.Members) { Outcome outcome = (member.Controller.isPlayerDead ? (((int)member.Controller.causeOfDeath != 10) ? Outcome.Died : Outcome.Missing) : Outcome.Survived); PlayerStats val = StartOfRound.Instance.gameStats.allPlayerStats[member.Controller.playerClientId]; TeamPerformanceMember teamPerformanceMember = Object.Instantiate<TeamPerformanceMember>(_memberPrefab, _memberContainer); teamPerformanceMember.Initialize(member.Name, val.playerNotes, outcome); _memberUIs.Add(teamPerformanceMember); } _gradeText.text = CalculateGrade(team); _collectedText.text = $"{team.RoundScore}\n{RoundManager.Instance.totalScrapValueInLevel}"; } private static string CalculateGrade(Team team) { if (team.Members.All((Player player) => player.Controller.isPlayerDead)) { return "F"; } float num = RoundManager.Instance.totalScrapValueInLevel / (float)Session.Current.Teams.Count; float num2 = (float)team.RoundScore / num; if (!(num2 > 2f)) { if (!(num2 > 1.5f)) { if (!(num2 > 1f)) { if (!(num2 > 0.75f)) { if (!(num2 > 0.5f)) { if (num2 > 0.33f) { return "C"; } return "D"; } return "B"; } return "A"; } return "S"; } return "S+"; } return "SS"; } } internal class TeamResultsPage : MonoBehaviour { [SerializeField] private TeamRoundResult _teamPrefab; [SerializeField] private Transform _teamContainer; private readonly List<TeamRoundResult> _teamUIs = new List<TeamRoundResult>(); public void Populate(IEnumerable<ITeam> teams, TeamMetric metric, bool showWinner) { ITeam[] array = teams.OrderByDescending((ITeam team) => team.GetScore(metric)).ToArray(); int score = array[0].GetScore(metric); ITeam[] array2 = array; foreach (ITeam team2 in array2) { TeamRoundResult teamRoundResult = Object.Instantiate<TeamRoundResult>(_teamPrefab, _teamContainer); int score2 = team2.GetScore(metric); teamRoundResult.Initialize(team2, score2, score, showWinner && score2 == score); _teamUIs.Add(teamRoundResult); } } public void Reset() { foreach (TeamRoundResult teamUI in _teamUIs) { Object.Destroy((Object)(object)((Component)teamUI).gameObject); } _teamUIs.Clear(); } } internal class TeamRoundResult : MonoBehaviour { [SerializeField] private TMP_Text _nameText; [SerializeField] private Image _colorImage; [SerializeField] private Image _scoreBar; [SerializeField] private TMP_Text _scoreText; [SerializeField] private GameObject _winnerIcon; public void Initialize(ITeam team, int score, int maxScore, bool isWinner) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0050: 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_0067: 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_0081: 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_00d4: Unknown result type (might be due to invalid IL or missing references) ((Graphic)_colorImage).color = team.Color; _winnerIcon.SetActive(isWinner); ((Graphic)_nameText).color = team.Color; _nameText.text = team.Name; ((Behaviour)_scoreText).enabled = score > 0; float num = team.Color.r + team.Color.g + team.Color.b; ((Graphic)_scoreText).color = ((num > 1.5f) ? Color.black : Color.white); _scoreText.text = "$" + score; ((Graphic)_scoreBar).color = team.Color; ((Graphic)_scoreBar).rectTransform.anchorMax = new Vector2((float)score / (float)maxScore, 1f); } } } namespace CompetitiveCompany.Game { [HarmonyPatch(typeof(HUDManager), "AddChatMessage")] internal static class ChatPatches { private static readonly Color _noTeamColor = Color.red; private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions) { Log.Debug("Patching HUDManager.AddChatMessage..."); foreach (CodeInstruction instruction in instructions) { if (instruction.opcode == OpCodes.Ldarg_2) { yield return new CodeInstruction(OpCodes.Ldarg_0, (object)null); yield return new CodeInstruction(OpCodes.Ldarg_1, (object)null); yield return new CodeInstruction(OpCodes.Ldarg_2, (object)null); yield return new CodeInstruction(OpCodes.Call, (object)AccessTools.Method(typeof(ChatPatches), "HandleChatMessage", (Type[])null, (Type[])null)); yield return new CodeInstruction(OpCodes.Ret, (object)null); yield break; } yield return instruction; } Log.Error("Failed to find target instruction in HUDManager.AddChatMessage!"); } private static void HandleChatMessage(HUDManager instance, string chatMessage, string playerNameWhoSent) { //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) string item; if (string.IsNullOrEmpty(playerNameWhoSent)) { item = "<color=#7069ff>" + chatMessage + "</color>"; } else { Team team = Player.Local.Team; Team team2 = Session.Current.Players.GetByName(playerNameWhoSent)?.Team; if ((Object)(object)team != (Object)null && (Object)(object)team2 != (Object)null && (Object)(object)team != (Object)(object)team2) { return; } string text = ColorUtility.ToHtmlStringRGB(team2?.Color ?? _noTeamColor); string text2 = playerNameWhoSent; if ((Object)(object)team2 != (Object)null) { text2 = text2 + " (" + team2.Name + ")"; } item = "<color=#" + text + ">" + text2 + "</color>: <color=#FFFF00>'" + chatMessage + "'</color>"; } instance.ChatMessageHistory.Add(item); ((TMP_Text)instance.chatText).text = string.Join('\n', instance.ChatMessageHistory); } } public class Combat { public delegate DamagePredicateResult DamagePredicate(Player attacker, Player victim); private readonly List<DamagePredicate> _predicates; public IReadOnlyList<DamagePredicate> Predicates => _predicates; public Combat() { _predicates = new List<DamagePredicate>(); } public Combat(List<DamagePredicate> predicates) { _predicates = predicates; } public void AddPredicate(DamagePredicate predicate, int index = -1) { if (index < 0) { _predicates.Add(predicate); } else { _predicates.Insert(index, predicate); } } public bool RemovePredicate(DamagePredicate predicate) { return _predicates.Remove(predicate); } public DamagePredicateResult CanDamage(Player attacker, Player victim) { foreach (DamagePredicate predicate in _predicates) { DamagePredicateResult damagePredicateResult = predicate(attacker, victim); if (!damagePredicateResult) { return damagePredicateResult; } } return DamagePredicateResult.Allow(); } } public readonly struct DamagePredicateResult { public readonly bool Result; public readonly string? Reason; private DamagePredicateResult(bool result, string? reason = null) { Result = result; Reason = reason; } public static DamagePredicateResult Allow() { return new DamagePredicateResult(result: true); } public static DamagePredicateResult Deny(string reason) { return new DamagePredicateResult(result: false, reason); } public static implicit operator bool(DamagePredicateResult predicateResult) { return predicateResult.Result; } } public static class DefaultTeams { private static readonly TeamDefinition[] _fallback = new TeamDefinition[2] { new TeamDefinition("Loot bugs", new Color(0.99f, 0.55f, 0.11f)), new TeamDefinition("Manticoils", new Color(0.2f, 0.57f, 0.16f)) }; private const string FileName = "default_teams.json"; public static IReadOnlyList<TeamDefinition> Fallback => _fallback; public static IReadOnlyList<TeamDefinition> Get() { string text = Path.Join((ReadOnlySpan<char>)Paths.ConfigPath, (ReadOnlySpan<char>)"default_teams.json"); Log.Debug("Looking for default_teams.json at " + text + "."); if (!File.Exists(text)) { Log.Info("default_teams.json file not found, using fallback."); return _fallback; } try { string text2 = File.ReadAllText(text); TeamDefinition[] array = JsonConvert.DeserializeObject<TeamDefinition[]>(text2); int num = array.Length; if (num >= 2) { if (num > 8) { throw new Exception("Too many teams defined."); } return array; } throw new Exception("Too few teams defined."); } catch (Exception ex) { Log.Error("Failed to read default_teams.json: " + ex.Message + ", using fallback."); return _fallback; } } } public class TeamDefinition { public string Name { get; } public Color Color { get; } public string[] Players { get; } public TeamDefinition(string name, Color color, string[]? players = null) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) Name = name; Color = color; Players = players ?? Array.Empty<string>(); } [JsonConstructor] public TeamDefinition(string name, string color, string[]? players = null) { //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) Name = name; Color = ColorUtil.ParseColor(color) ?? throw new Exception("Invalid color: " + color); Players = players ?? Array.Empty<string>(); } } public readonly struct MatchEndedContext { public readonly Team WinningTeam; public readonly Session Session; internal MatchEndedContext(Session session, Team winningTeam) { WinningTeam = winningTeam; Session = session; } } public readonly struct MatchStartedContext { public readonly Session Session; internal MatchStartedContext(Session session) { Session = session; } } public readonly struct RoundEndedContext { public readonly bool WasLastRound; public readonly int RoundNumber; public readonly Session Session; internal RoundEndedContext(Session session, bool wasLastRound, int roundNumber) { Session = session; WasLastRound = wasLastRound; RoundNumber = roundNumber; } } public readonly struct RoundStartedContext { public readonly int RoundNumber; public readonly Session Session; internal RoundStartedContext(Session session, int roundNumber) { Session = session; RoundNumber = roundNumber; } } internal static class LeverPatches { [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static Func<Instruction, bool> <>9__0_4; public static Func<Instruction, bool> <>9__0_5; public static Func<Instruction, bool> <>9__0_6; public static Func<Instruction, bool> <>9__0_7; public static Func<Instruction, bool> <>9__0_8; public static Action<StartMatchLever> <>9__0_9; public static Manipulator <>9__0_0; public static hook_DisplaySpectatorVoteTip <>9__0_1; public static hook_Update <>9__0_2; public static hook_EndGame <>9__0_3; internal void <Patch>b__0_0(ILContext il) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown ILCursor val = new ILCursor(il); val.GotoNext(new Func<Instruction, bool>[5] { (Instruction x) => ILPatternMatchingExt.MatchLdarg(x, 0), (Instruction x) => ILPatternMatchingExt.MatchLdfld<StartMatchLever>(x, "triggerScript"), (Instruction x) => ILPatternMatchingExt.MatchLdstr(x, "Start ship : [LMB]"), (Instruction x) => ILPatternMatchingExt.MatchStfld<InteractTrigger>(x, "hoverTip"), (Instruction x) => ILPatternMatchingExt.MatchRet(x) }); val.GotoNext(Array.Empty<Func<Instruction, bool>>()); val.RemoveRange(4); val.EmitDelegate<Action<StartMatchLever>>((Action<StartMatchLever>)delegate(StartMatchLever self) { bool flag = TimeUtil.GetCurrentGameTime().TotalHours >= (double)Session.Current.Settings.MinLeaveTime; self.triggerScript.hoverTip = (flag ? "Start ship : [LMB]" : "[Too early to start ship]"); self.triggerScript.interactable = flag; }); } internal bool <Patch>b__0_4(Instruction x) { return ILPatternMatchingExt.MatchLdarg(x, 0); } internal bool <Patch>b__0_5(Instruction x) { return ILPatternMatchingExt.MatchLdfld<StartMatchLever>(x, "triggerScript"); } internal bool <Patch>b__0_6(Instruction x) { return ILPatternMatchingExt.MatchLdstr(x, "Start ship : [LMB]"); } internal bool <Patch>b__0_7(Instruction x) { return ILPatternMatchingExt.MatchStfld<InteractTrigger>(x, "hoverTip"); } internal bool <Patch>b__0_8(Instruction x) { return ILPatternMatchingExt.MatchRet(x); } internal void <Patch>b__0_9(StartMatchLever self) { bool flag = TimeUtil.GetCurrentGameTime().TotalHours >= (double)Session.Current.Settings.MinLeaveTime; self.triggerScript.hoverTip = (flag ? "Start ship : [LMB]" : "[Too early to start ship]"); self.triggerScript.interactable = flag; } internal void <Patch>b__0_1(orig_DisplaySpectatorVoteTip orig, HUDManager self) { if (!Session.Current.Settings.DisableAutoPilot) { orig.Invoke(self); } } internal void <Patch>b__0_2(orig_Update orig, HUDManager self) { orig.Invoke(self); if (Session.Current.Settings.DisableAutoPilot) { self.holdButtonToEndGameEarlyHoldTime = 0f; } } internal void <Patch>b__0_3(orig_EndGame orig, StartMatchLever self) { StartOfRound instance = StartOfRound.Instance; if ((!Player.Local.Controller.isPlayerDead && !instance.shipHasLanded) || instance.shipIsLeaving || instance.shipLeftAutomatically) { return; } Session current = Session.Current; if (current.Settings.TimeToLeave <= 0f) { Log.Info("TimeToLeave is 0, starting ship immediately."); orig.Invoke(self); return; } if (current.Teams.GetLiving().Count() == 1) { Log.Info("Only one team left, starting ship immediately."); orig.Invoke(self); return; } Team team = Player.Local.Team; if ((Object)(object)team == (Object)null) { Log.Warning("Player without a team pulled the lever!"); } else { team.StartLeavingServerRpc(); } } } public static void Patch() { //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_001f: Expected O, but got Unknown //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Expected O, but got Unknown //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Expected O, but got Unknown //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Expected O, but got Unknown object obj = <>c.<>9__0_0; if (obj == null) { Manipulator val = delegate(ILContext il) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown ILCursor val5 = new ILCursor(il); val5.GotoNext(new Func<Instruction, bool>[5] { (Instruction x) => ILPatternMatchingExt.MatchLdarg(x, 0), (Instruction x) => ILPatternMatchingExt.MatchLdfld<StartMatchLever>(x, "triggerScript"), (Instruction x) => ILPatternMatchingExt.MatchLdstr(x, "Start ship : [LMB]"), (Instruction x) => ILPatternMatchingExt.MatchStfld<InteractTrigger>(x, "hoverTip"), (Instruction x) => ILPatternMatchingExt.MatchRet(x) }); val5.GotoNext(Array.Empty<Func<Instruction, bool>>()); val5.RemoveRange(4); val5.EmitDelegate<Action<StartMatchLever>>((Action<StartMatchLever>)delegate(StartMatchLever self) { bool flag = TimeUtil.GetCurrentGameTime().TotalHours >= (double)Session.Current.Settings.MinLeaveTime; self.triggerScript.hoverTip = (flag ? "Start ship : [LMB]" : "[Too early to start ship]"); self.triggerScript.interactable = flag; }); }; <>c.<>9__0_0 = val; obj = (object)val; } StartMatchLever.Update += (Manipulator)obj; object obj2 = <>c.<>9__0_1; if (obj2 == null) { hook_DisplaySpectatorVoteTip val2 = delegate(orig_DisplaySpectatorVoteTip orig, HUDManager self) { if (!Session.Current.Settings.DisableAutoPilot) { orig.Invoke(self); } }; <>c.<>9__0_1 = val2; obj2 = (object)val2; } HUDManager.DisplaySpectatorVoteTip += (hook_DisplaySpectatorVoteTip)obj2; object obj3 = <>c.<>9__0_2; if (obj3 == null) { hook_Update val3 = delegate(orig_Update orig, HUDManager self) { orig.Invoke(self); if (Session.Current.Settings.DisableAutoPilot) { self.holdButtonToEndGameEarlyHoldTime = 0f; } }; <>c.<>9__0_2 = val3; obj3 = (object)val3; } HUDManager.Update += (hook_Update)obj3; object obj4 = <>c.<>9__0_3; if (obj4 == null) { hook_EndGame val4 = delegate(orig_EndGame orig, StartMatchLever self) { StartOfRound instance = StartOfRound.Instance; if ((Player.Local.Controller.isPlayerDead || instance.shipHasLanded) && !instance.shipIsLeaving && !instance.shipLeftAutomatically) { Session current = Session.Current; if (current.Settings.TimeToLeave <= 0f) { Log.Info("TimeToLeave is 0, starting ship immediately."); orig.Invoke(self); } else if (current.Teams.GetLiving().Count() == 1) { Log.Info("Only one team left, starting ship immediately."); orig.Invoke(self); } else { Team team = Player.Local.Team; if ((Object)(object)team == (Object)null) { Log.Warning("Player without a team pulled the lever!"); } else { team.StartLeavingServerRpc(); } } } }; <>c.<>9__0_3 = val4; obj4 = (object)val4; } StartMatchLever.EndGame += (hook_EndGame)obj4; } } internal static class MiscPatches { [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static hook_UpdateProfitQuotaCurrentTime <>9__0_0; public static Func<Instruction, bool> <>9__2_1; public static Func<Instruction, bool> <>9__2_2; public static Func<Instruction, bool> <>9__2_3; public static Func<Instruction, bool> <>9__2_4; public static Func<Instruction, bool> <>9__2_5; public static Func<Instruction, bool> <>9__2_6; public static Manipulator <>9__2_0; internal void <Patch>b__0_0(orig_UpdateProfitQuotaCurrentTime _, TimeOfDay _) { StartOfRound instance = StartOfRound.Instance; if (!((Object)(object)instance.localPlayerController == (Object)null)) { Session current = Session.Current; int num = current.Settings.NumberOfRounds - Mathf.Max(current.RoundNumber, 0); ((TMP_Text)instance.deadlineMonitorText).text = ((num == 1) ? "DEADLINE: LAST ROUND!" : $"DEADLINE: {num} ROUNDS LEFT"); Team team = Player.Local.Team; ((TMP_Text)instance.profitQuotaMonitorText).text = (((Object)(object)team == (Object)null) ? "TEAM CREDITS: N/A" : $"TEAM CREDITS: ${team.Credits}"); } } internal void <NoCompanyMoonPatch>b__2_0(ILContext il) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: Unknown result type (might be due to invalid IL or missing references) //IL_0114: Unknown result type (might be due to invalid IL or missing references) //IL_0120: Unknown result type (might be due to invalid IL or missing references) //IL_012d: Unknown result type (might be due to invalid IL or missing references) //IL_0139: Unknown result type (might be due to invalid IL or missing references) //IL_0159: Unknown result type (might be due to invalid IL or missing references) //IL_017b: Unknown result type (might be due to invalid IL or missing references) ILCursor val = new ILCursor(il); val.GotoNext(new Func<Instruction, bool>[6] { (Instruction x) => ILPatternMatchingExt.MatchLdloc(x, 0), (Instruction x) => ILPatternMatchingExt.MatchLdarg(x, 1), (Instruction x) => ILPatternMatchingExt.MatchLdfld<TerminalNode>(x, "buyRerouteToMoon"), (Instruction x) => ILPatternMatchingExt.MatchLdarg(x, 0), (Instruction x) => ILPatternMatchingExt.MatchLdfld<Terminal>(x, "groupCredits"), (Instruction x) => ILPatternMatchingExt.MatchCallvirt<StartOfRound>(x, "ChangeLevelServerRpc") }); Instruction next = val.Next; val.Emit(OpCodes.Ldarg_1); val.Emit(OpCodes.Ldfld, AccessTools.Field(typeof(TerminalNode), "buyRerouteToMoon")); val.Emit(OpCodes.Ldc_I4_3); val.Emit(OpCodes.Bne_Un_S, next); val.Emit(OpCodes.Ldarg_0); val.Emit(OpCodes.Ldsfld, AccessTools.Field(typeof(MiscPatches), "_refuseCompanyMoonNode")); val.Emit(OpCodes.Call, (MethodBase)AccessTools.Method(typeof(Terminal), "LoadNewNode", (Type[])null, (Type[])null)); val.Emit(OpCodes.Ret); } internal bool <NoCompanyMoonPatch>b__2_1(Instruction x) { return ILPatternMatchingExt.MatchLdloc(x, 0); } internal bool <NoCompanyMoonPatch>b__2_2(Instruction x) { return ILPatternMatchingExt.MatchLdarg(x, 1); } internal bool <NoCompanyMoonPatch>b__2_3(Instruction x) { return ILPatternMatchingExt.MatchLdfld<TerminalNode>(x, "buyRerouteToMoon"); } internal bool <NoCompanyMoonPatch>b__2_4(Instruction x) { return ILPatternMatchingExt.MatchLdarg(x, 0); } internal bool <NoCompanyMoonPatch>b__2_5(Instruction x) { return ILPatternMatchingExt.MatchLdfld<Terminal>(x, "groupCredits"); } internal bool <NoCompanyMoonPatch>b__2_6(Instruction x) { return ILPatternMatchingExt.MatchCallvirt<StartOfRound>(x, "ChangeLevelServerRpc"); } } private static TerminalNode? _refuseCompanyMoonNode; public static void Patch() { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Expected O, but got Unknown NoCompanyMoonPatch(); object obj = <>c.<>9__0_0; if (obj == null) { hook_UpdateProfitQuotaCurrentTime val = delegate { StartOfRound instance = StartOfRound.Instance; if (!((Object)(object)instance.localPlayerController == (Object)null)) { Session current = Session.Current; int num = current.Settings.NumberOfRounds - Mathf.Max(current.RoundNumber, 0); ((TMP_Text)instance.deadlineMonitorText).text = ((num == 1) ? "DEADLINE: LAST ROUND!" : $"DEADLINE: {num} ROUNDS LEFT"); Team team = Player.Local.Team; ((TMP_Text)instance.profitQuotaMonitorText).text = (((Object)(object)team == (Object)null) ? "TEAM CREDITS: N/A" : $"TEAM CREDITS: ${team.Credits}"); } }; <>c.<>9__0_0 = val; obj = (object)val; } TimeOfDay.UpdateProfitQuotaCurrentTime += (hook_UpdateProfitQuotaCurrentTime)obj; } private static void NoCompanyMoonPatch() { //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Expected O, but got Unknown _refuseCompanyMoonNode = ScriptableObject.CreateInstance<TerminalNode>(); _refuseCompanyMoonNode.displayText = "Company moon is disabled by CompetitiveCompany."; _refuseCompanyMoonNode.clearPreviousText = true; object obj = <>c.<>9__2_0; if (obj == null) { Manipulator val = delegate(ILContext il) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: Unknown result type (might be due to invalid IL or missing references) //IL_0114: Unknown result type (might be due to invalid IL or missing references) //IL_0120: Unknown result type (might be due to invalid IL or missing references) //IL_012d: Unknown result type (might be due to invalid IL or missing references) //IL_0139: Unknown result type (might be due to invalid IL or missing references) //IL_0159: Unknown result type (might be due to invalid IL or missing references) //IL_017b: Unknown result type (might be due to invalid IL or missing references) ILCursor val2 = new ILCursor(il); val2.GotoNext(new Func<Instruction, bool>[6] { (Instruction x) => ILPatternMatchingExt.MatchLdloc(x, 0), (Instruction x) => ILPatternMatchingExt.MatchLdarg(x, 1), (Instruction x) => ILPatternMatchingExt.MatchLdfld<TerminalNode>(x, "buyRerouteToMoon"), (Instruction x) => ILPatternMatchingExt.MatchLdarg(x, 0), (Instruction x) => ILPatternMatchingExt.MatchLdfld<Terminal>(x, "groupCredits"), (Instruction x) => ILPatternMatchingExt.MatchCallvirt<StartOfRound>(x, "ChangeLevelServerRpc") }); Instruction next = val2.Next; val2.Emit(OpCodes.Ldarg_1); val2.Emit(OpCodes.Ldfld, AccessTools.Field(typeof(TerminalNode), "buyRerouteToMoon")); val2.Emit(OpCodes.Ldc_I4_3); val2.Emit(OpCodes.Bne_Un_S, next); val2.Emit(OpCodes.Ldarg_0); val2.Emit(OpCodes.Ldsfld, AccessTools.Field(typeof(MiscPatches), "_refuseCompanyMoonNode")); val2.Emit(OpCodes.Call, (MethodBase)AccessTools.Method(typeof(Terminal), "LoadNewNode", (Type[])null, (Type[])null)); val2.Emit(OpCodes.Ret); }; <>c.<>9__2_0 = val; obj = (object)val; } Terminal.LoadNewNodeIfAffordable += (Manipulator)obj; } } public class Player : NetworkBehaviour { private struct TeamRef : INetworkSerializable { public bool HasValue; public NetworkBehaviourReference Ref; public unsafe void NetworkSerialize<T>(BufferSerializer<T> serializer) where T : IReaderWriter { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) ((BufferSerializer<bool>*)(&serializer))->SerializeValue<bool>(ref HasValue, default(ForPrimitives)); if (HasValue) { ((BufferSerializer<NetworkBehaviourReference>*)(&serializer))->SerializeValue<NetworkBehaviourReference>(ref Ref, default(ForNetworkSerializable)); } } public bool TryGet([NotNullWhen(true)] out Team? team) { if (!HasValue) { team = null; return false; } NetworkBehaviour val = default(NetworkBehaviour); if (((NetworkBehaviourReference)(ref Ref)).TryGet(ref val, (NetworkManager)null) && val is Team team2) { team = team2; return true; } Log.Warning("Invalid team reference"); team = null; return false; } public override string ToString() { if (!HasValue) { return "[NONE]"; } NetworkBehaviour val = default(NetworkBehaviour); if (!((NetworkBehaviourReference)(ref Ref)).TryGet(ref val, (NetworkManager)null)) { return "[INVALID]"; } return ((object)val).ToString(); } } [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static hook_SetItemInElevator <>9__57_0; public static hook_SendNewPlayerValuesClientRpc <>9__57_1; public static Func<Instruction, bool> <>9__57_3; public static Func<Instruction, bool> <>9__57_4; public static Func<Instruction, bool> <>9__57_5; public static Action<PlayerControllerB, GrabbableObject> <>9__57_6; public static Manipulator <>9__57_2; internal void <Patch>b__57_0(orig_SetItemInElevator orig, PlayerControllerB self, bool inShip, bool inElevator, GrabbableObject item) { orig.Invoke(self, inShip, inElevator, item); if (((NetworkBehaviour)self).IsServer) { ((Component)self).GetComponent<Player>().SetItemInElevator(item, inShip); } } internal void <Patch>b__57_1(orig_SendNewPlayerValuesClientRpc orig, PlayerControllerB self, ulong[] playerIds) { orig.Invoke(self, playerIds); ((Component)self).GetComponent<Player>().RefreshUsernameText(); } internal void <Patch>b__57_2(ILContext il) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown //IL_0083: 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) ILCursor val = new ILCursor(il); val.GotoNext(new Func<Instruction, bool>[3] { (Instruction x) => ILPatternMatchingExt.MatchCall(x, typeof(RoundManager), "get_Instance")
plugins/FlowTween.dll
Decompiled 2 months agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using FlowTween.Components; using FlowTween.Sequencing; using FlowTween.Templates; using JetBrains.Annotations; using UnityEngine; using UnityEngine.Events; 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("")] [assembly: AssemblyCompany("FlowTween")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("FlowTween")] [assembly: AssemblyTitle("FlowTween")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] namespace FlowTween { [Serializable] public struct Ease { public EaseType Type; public EaseDirection Direction; public Ease(EaseType type, EaseDirection direction) { Type = type; Direction = direction; } public static Ease In(EaseType type) { return new Ease(type, EaseDirection.In); } public static Ease Out(EaseType type) { return new Ease(type, EaseDirection.Out); } public static Ease InOut(EaseType type) { return new Ease(type, EaseDirection.InOut); } public Func<float, float> GetFunction() { return Type switch { EaseType.Linear => Easings.Linear, EaseType.Sine => Direction switch { EaseDirection.In => Easings.SineIn, EaseDirection.Out => Easings.SineOut, EaseDirection.InOut => Easings.SineInOut, _ => throw new ArgumentOutOfRangeException(), }, EaseType.Quad => Direction switch { EaseDirection.In => Easings.QuadIn, EaseDirection.Out => Easings.QuadOut, EaseDirection.InOut => Easings.QuadInOut, _ => throw new ArgumentOutOfRangeException(), }, EaseType.Cubic => Direction switch { EaseDirection.In => Easings.CubicIn, EaseDirection.Out => Easings.CubicOut, EaseDirection.InOut => Easings.CubicInOut, _ => throw new ArgumentOutOfRangeException(), }, EaseType.Quart => Direction switch { EaseDirection.In => Easings.QuartIn, EaseDirection.Out => Easings.QuartOut, EaseDirection.InOut => Easings.QuartInOut, _ => throw new ArgumentOutOfRangeException(), }, EaseType.Quint => Direction switch { EaseDirection.In => Easings.QuintIn, EaseDirection.Out => Easings.QuintOut, EaseDirection.InOut => Easings.QuintInOut, _ => throw new ArgumentOutOfRangeException(), }, EaseType.Expo => Direction switch { EaseDirection.In => Easings.ExpoIn, EaseDirection.Out => Easings.ExpoOut, EaseDirection.InOut => Easings.ExpoInOut, _ => throw new ArgumentOutOfRangeException(), }, EaseType.Circ => Direction switch { EaseDirection.In => Easings.CircIn, EaseDirection.Out => Easings.CircOut, EaseDirection.InOut => Easings.CircInOut, _ => throw new ArgumentOutOfRangeException(), }, EaseType.Back => Direction switch { EaseDirection.In => Easings.BackIn, EaseDirection.Out => Easings.BackOut, EaseDirection.InOut => Easings.BackInOut, _ => throw new ArgumentOutOfRangeException(), }, EaseType.Elastic => Direction switch { EaseDirection.In => Easings.ElasticIn, EaseDirection.Out => Easings.ElasticOut, EaseDirection.InOut => Easings.ElasticInOut, _ => throw new ArgumentOutOfRangeException(), }, EaseType.Bounce => Direction switch { EaseDirection.In => Easings.BounceIn, EaseDirection.Out => Easings.BounceOut, EaseDirection.InOut => Easings.BounceInOut, _ => throw new ArgumentOutOfRangeException(), }, _ => throw new ArgumentOutOfRangeException(), }; } } [Flags] public enum EaseDirection { In = 1, Out = 2, InOut = 3 } public enum EaseType { Linear, Sine, Quad, Cubic, Quart, Quint, Expo, Circ, Back, Elastic, Bounce } public static class Easings { private const float HalfPI = MathF.PI / 2f; private const float C1 = 1.70158f; private const float C2 = 2.5949094f; private const float C3 = 2.70158f; private const float C4 = MathF.PI * 2f / 3f; private const float N1 = 7.5625f; private const float D1 = 2.75f; public static float Linear(float t) { return t; } public static float SineIn(float t) { return 1f - Mathf.Cos(t * (MathF.PI / 2f)); } public static float SineOut(float t) { return Mathf.Sin(t * (MathF.PI / 2f)); } public static float SineInOut(float t) { return (0f - (Mathf.Cos(MathF.PI * t) - 1f)) / 2f; } public static float QuadIn(float t) { return PolyIn(t, 2); } public static float QuadOut(float t) { return PolyOut(t, 2); } public static float QuadInOut(float t) { return PolyInOut(t, 2); } public static float CubicIn(float t) { return PolyIn(t, 3); } public static float CubicOut(float t) { return PolyOut(t, 3); } public static float CubicInOut(float t) { return PolyInOut(t, 3); } public static float QuartIn(float t) { return PolyIn(t, 4); } public static float QuartOut(float t) { return PolyOut(t, 4); } public static float QuartInOut(float t) { return PolyInOut(t, 4); } public static float QuintIn(float t) { return PolyIn(t, 5); } public static float QuintOut(float t) { return PolyOut(t, 5); } public static float QuintInOut(float t) { return PolyInOut(t, 5); } public static float ExpoIn(float t) { if (t != 0f) { return Mathf.Pow(2f, 10f * t - 10f); } return 0f; } public static float ExpoOut(float t) { if (!Equal(t, 1f)) { return 1f - Mathf.Pow(2f, -10f * t); } return 1f; } public static float ExpoInOut(float t) { if (t != 0f) { if (!Equal(t, 1f)) { if (!(t < 0.5f)) { return (2f - Mathf.Pow(2f, -20f * t + 10f)) / 2f; } return Mathf.Pow(2f, 20f * t - 10f) / 2f; } return 1f; } return 0f; } public static float CircIn(float t) { return 1f - Mathf.Sqrt(1f - Mathf.Pow(t, 2f)); } public static float CircOut(float t) { return Mathf.Sqrt(1f - Mathf.Pow(t - 1f, 2f)); } public static float CircInOut(float t) { if (!(t < 0.5f)) { return (Mathf.Sqrt(1f - Mathf.Pow(-2f * t + 2f, 2f)) + 1f) / 2f; } return (1f - Mathf.Sqrt(1f - Mathf.Pow(2f * t, 2f))) / 2f; } public static float BackIn(float t) { return 2.70158f * t * t * t - 1.70158f * t * t; } public static float BackOut(float t) { return 1f + 2.70158f * Mathf.Pow(t - 1f, 3f) + 1.70158f * Mathf.Pow(t - 1f, 2f); } public static float BackInOut(float t) { if (!(t < 0.5f)) { return (Mathf.Pow(2f * t - 2f, 2f) * (3.5949094f * (t * 2f - 2f) + 2.5949094f) + 2f) / 2f; } return Mathf.Pow(2f * t, 2f) * (7.189819f * t - 2.5949094f) / 2f; } public static float ElasticIn(float t) { if (!Equal(t, 0f)) { if (!Equal(t, 1f)) { return (0f - Mathf.Pow(2f, 10f * t - 10f)) * Mathf.Sin((t * 10f - 10.75f) * (MathF.PI * 2f / 3f)); } return 1f; } return 0f; } public static float ElasticOut(float t) { if (!Equal(t, 0f)) { if (!Equal(t, 1f)) { return Mathf.Pow(2f, -10f * t) * Mathf.Sin((t * 10f - 0.75f) * (MathF.PI * 2f / 3f)) + 1f; } return 1f; } return 0f; } public static float ElasticInOut(float t) { if (!Equal(t, 0f)) { if (!Equal(t, 1f)) { if (!(t < 0.5f)) { return Mathf.Pow(2f, -20f * t + 10f) * Mathf.Sin((20f * t - 11.125f) * (MathF.PI * 2f / 3f)) / 2f + 1f; } return (0f - Mathf.Pow(2f, 20f * t - 10f) * Mathf.Sin((20f * t - 11.125f) * (MathF.PI * 2f / 3f))) / 2f; } return 1f; } return 0f; } public static float BounceIn(float t) { return 1f - BounceOut(1f - t); } public static float BounceOut(float t) { if (!(t < 0.36363637f)) { if (t < 0.72727275f) { return 7.5625f * (t -= 0.54545456f) * t + 0.75f; } if ((double)t < 0.9090909090909091) { return 7.5625f * (t -= 0.8181818f) * t + 0.9375f; } return 7.5625f * (t -= 21f / 22f) * t + 63f / 64f; } return 7.5625f * t * t; } public static float BounceInOut(float t) { if (!(t < 0.5f)) { return (1f + BounceOut(2f * t - 1f)) / 2f; } return (1f - BounceOut(1f - 2f * t)) / 2f; } public static float PolyIn(float t, int power) { return Mathf.Pow(t, (float)power); } public static float PolyOut(float t, int power) { return 1f - Mathf.Pow(1f - t, (float)power); } public static float PolyInOut(float t, int power) { if (!(t < 0.5f)) { return 1f - Mathf.Pow(-2f * t + 2f, (float)power) / 2f; } return Mathf.Pow(2f * t, (float)power) / 2f; } private static bool Equal(float a, float b) { return Math.Abs(a - b) < 0.0001f; } } public enum LoopMode { None, Loop, PingPong } public abstract class Runnable : IEnumerator { private float _time; public bool IsCancelled { get; set; } public bool IsPaused { get; set; } public Action CompleteAction { get; set; } public LoopMode LoopMode { get; set; } public int? Loops { get; set; } public virtual float Duration { get; } public float TotalDuration => Duration * (float)((LoopMode == LoopMode.None || !Loops.HasValue) ? 1 : Loops.Value) + Delay; public float Delay { get; set; } public float Progress => GetProgress(_time); public bool IgnoreTimescale { get; set; } public virtual bool IsComplete { get { if (IsCancelled) { return true; } if (LoopMode == LoopMode.None) { return _time >= Duration + Delay; } if (Loops.HasValue) { return _time >= Duration * (float)Loops.Value + Delay; } return false; } } object IEnumerator.Current => null; public void Update(float deltaTime) { if (!IsPaused) { _time += deltaTime; if (!(_time < Delay)) { OnUpdate(deltaTime); } } } public virtual void Cancel(bool safe) { IsCancelled = true; CompleteAction?.Invoke(); } protected abstract void OnUpdate(float deltaTime); public virtual void Reset() { CompleteAction = null; _time = 0f; IsCancelled = false; IsPaused = false; } protected virtual float GetProgress(float time) { if (Duration == 0f) { Debug.LogWarning((object)"Runnable duration is 0! Please ensure it is greater than 0 before the runnable starts running."); return 0f; } float num = Mathf.Max(time - Delay, 0f) / Duration; return LoopMode switch { LoopMode.None => num, LoopMode.Loop => num % 1f, LoopMode.PingPong => Mathf.PingPong(num, 1f), _ => throw new ArgumentOutOfRangeException(), }; } bool IEnumerator.MoveNext() { return !IsComplete; } void IEnumerator.Reset() { } } public static class RunnableExtensions { public static T Pause<T>(this T runnable) where T : Runnable { runnable.IsPaused = true; return runnable; } public static T Resume<T>(this T runnable) where T : Runnable { runnable.IsPaused = false; return runnable; } public static T OnComplete<T>(this T runnable, Action action) where T : Runnable { runnable.CompleteAction = (Action)Delegate.Combine(runnable.CompleteAction, action); return runnable; } public static T SetDelay<T>(this T runnable, float delay) where T : Runnable { runnable.Delay = delay; return runnable; } public static T Loop<T>(this T runnable, LoopMode mode = LoopMode.Loop, int? loops = null) where T : Runnable { runnable.LoopMode = mode; runnable.Loops = loops; return runnable; } } public class Tween<T> : TweenBase { public T Start { get; set; } public T End { get; set; } public Action<T> UpdateAction { get; set; } public LerpFunction<T> LerpFunction { get; set; } public T Value => LerpFunction(Start, End, base.Progress); protected override void OnUpdate(float deltaTime) { UpdateAction?.Invoke(Value); } public override void Cancel(bool safe) { if (!safe) { UpdateAction?.Invoke(End); } base.Cancel(safe); } public override void Reset() { base.Reset(); UpdateAction = null; Start = default(T); End = default(T); } public Tween<T> OnUpdate(Action<T> onUpdate) { UpdateAction = onUpdate; return this; } public Tween<T> From(T start) { Start = start; return this; } public Tween<T> To(T end) { End = end; return this; } public Tween<T> Lerp(LerpFunction<T> lerp) { LerpFunction = lerp; return this; } } public delegate T LerpFunction<T>(T from, T to, float t); public abstract class TweenBase : Runnable { private float _duration; private Func<float, float> _easeFunction; public override float Duration => _duration; public Func<float, float> EaseFunction { get { return _easeFunction ?? new Func<float, float>(Easings.Linear); } set { _easeFunction = value; } } public override void Reset() { base.Reset(); EaseFunction = null; _duration = 0f; } protected override float GetProgress(float time) { return EaseFunction(base.GetProgress(time)); } internal void SetDurationInternal(float duration) { _duration = duration; } } public static class TweenBaseExtensions { public static T Ease<T>(this T tween, Func<float, float> ease) where T : TweenBase { tween.EaseFunction = ease; return tween; } public static T Ease<T>(this T tween, Ease ease) where T : TweenBase { return tween.Ease(ease.GetFunction()); } public static T Ease<T>(this T tween, EaseType type, EaseDirection direction) where T : TweenBase { return tween.Ease(new Ease { Type = type, Direction = direction }); } public static T EaseIn<T>(this T tween, EaseType type) where T : TweenBase { return tween.Ease(type, EaseDirection.In); } public static T EaseOut<T>(this T tween, EaseType type) where T : TweenBase { return tween.Ease(type, EaseDirection.Out); } public static T EaseInOut<T>(this T tween, EaseType type) where T : TweenBase { return tween.Ease(type, EaseDirection.InOut); } public static T Ease<T>(this T tween, AnimationCurve curve) where T : TweenBase { tween.EaseFunction = curve.Evaluate; return tween; } public static T Apply<T>(this T tween, TweenSettings settings) where T : TweenBase { settings.Apply(tween); return tween; } public static T SetDuration<T>(this T tween, float duration) where T : TweenBase { tween.SetDurationInternal(duration); return tween; } public static T SetIgnoreTimescale<T>(this T tween, bool ignoreTimeScale = true) where T : TweenBase { tween.IgnoreTimescale = ignoreTimeScale; return tween; } } [DisallowMultipleComponent] [AddComponentMenu("FlowTween/Tween Manager")] public class TweenManager : MonoBehaviour { public readonly struct RunnableInstance { public readonly Runnable Runnable; public readonly GameObject Owner; public readonly bool HasOwner; public RunnableInstance(Runnable runnable, GameObject owner, bool hasOwner) { Runnable = runnable; Owner = owner; HasOwner = hasOwner; } public static RunnableInstance From(Runnable tween, GameObject owner) { return new RunnableInstance(tween, owner, (Object)(object)owner != (Object)null); } } [SerializeField] private bool _enabled = true; [SerializeField] private bool _doNullChecks = true; [SerializeField] private bool _hasMaxTweens = true; [SerializeField] private int _maxTweens = 1000; private static TweenManager _singleton; private readonly Dictionary<Type, Queue<Runnable>> _inactive = new Dictionary<Type, Queue<Runnable>>(); private readonly List<RunnableInstance> _active = new List<RunnableInstance>(); [CanBeNull] public static TweenManager Singleton { get { //IL_0042: Unknown result type (might be due to invalid IL or missing references) if (!Application.isPlaying) { return null; } if ((Object)(object)_singleton != (Object)null) { if (!_singleton._enabled) { return null; } return _singleton; } TweenManager[] array = Object.FindObjectsOfType<TweenManager>(); switch (array.Length) { case 0: _singleton = new GameObject("TweenManager").AddComponent<TweenManager>(); Object.DontDestroyOnLoad((Object)(object)_singleton); break; case 1: _singleton = array[0]; break; default: _singleton = array[0]; Debug.LogWarning((object)"Multiple TweenManagers found in scene! Please ensure there is only one."); break; } if (!_singleton._enabled) { return null; } return _singleton; } } public bool DoNullChecks { get { return _doNullChecks; } set { _doNullChecks = value; } } public int? MaxTweens { get { if (!_hasMaxTweens) { return null; } return _maxTweens; } set { _hasMaxTweens = value.HasValue; _maxTweens = value.GetValueOrDefault(); } } public int ActiveTweenCount => _active.Count; public int InactiveTweenCount => _inactive.Values.Sum((Queue<Runnable> q) => q.Count); public int TotalTweenCount => ActiveTweenCount + InactiveTweenCount; public IReadOnlyDictionary<Type, Queue<Runnable>> InactiveTweens => _inactive; public IReadOnlyList<RunnableInstance> ActiveTweens => _active; private void Update() { for (int i = 0; i < _active.Count; i++) { RunnableInstance runnableInstance = _active[i]; Runnable runnable = runnableInstance.Runnable; bool flag = DoNullChecks && runnableInstance.HasOwner && (Object)(object)runnableInstance.Owner == (Object)null; if (!flag) { runnable.Update(runnable.IgnoreTimescale ? Time.unscaledDeltaTime : Time.deltaTime); if (!runnable.IsComplete) { continue; } } runnable.Cancel(!flag); _active.RemoveAt(i); Return(runnable); i--; } } private void Return(Runnable runnable) { Type type = runnable.GetType(); if (!_inactive.TryGetValue(type, out var value)) { _inactive.Add(type, value = new Queue<Runnable>()); } value.Enqueue(runnable); } public void Cancel(Runnable tween, bool callOnComplete = false) { if (callOnComplete) { tween.Cancel(safe: false); } _active.RemoveAll((RunnableInstance t) => t.Runnable == tween); Return(tween); } public void CancelObject(GameObject obj, bool callOnComplete = false) { for (int i = 0; i < _active.Count; i++) { RunnableInstance runnableInstance = _active[i]; if (!((Object)(object)runnableInstance.Owner != (Object)(object)obj)) { Cancel(runnableInstance.Runnable, callOnComplete); i--; } } } public T Get<T>(Object owner = null) where T : Runnable, new() { GameObject val = (GameObject)(object)((owner is GameObject) ? owner : null); GameObject val3; if (val == null) { Component val2 = (Component)(object)((owner is Component) ? owner : null); val3 = ((val2 == null) ? null : val2.gameObject); } else { val3 = val; } GameObject owner2 = val3; Type typeFromHandle = typeof(T); T val4; if (_inactive.TryGetValue(typeFromHandle, out var value) && value.TryDequeue(out var result)) { result.Reset(); val4 = (T)result; } else { if (MaxTweens.HasValue && TotalTweenCount >= MaxTweens) { throw new InvalidOperationException($"Max tween count reached ({MaxTweens}). This number can be changed in the TweenManager."); } val4 = new T(); } _active.Add(RunnableInstance.From(val4, owner2)); return val4; } public Tween<T> NewTween<T>(Object owner = null) { return Get<Tween<T>>(owner); } public TweenSequence NewSequence(Object owner = null) { return Get<TweenSequence>(owner); } public static bool TryAccess(Action<TweenManager> action) { if ((Object)(object)Singleton == (Object)null) { return false; } action(Singleton); return true; } public static bool TryAccess<T>(Func<TweenManager, T> func, out T result) { if ((Object)(object)Singleton == (Object)null) { result = default(T); return false; } result = func(Singleton); return true; } } [Serializable] public class TweenSettings { public enum EasingType { Preset, Custom } [Min(0f)] [SerializeField] private float _duration = 1f; [Min(0f)] [SerializeField] private float _delay; [SerializeField] private EasingType _easeType; [SerializeField] private Ease _presetEase; [SerializeField] private AnimationCurve _customEase; [SerializeField] private LoopMode _loopMode; [SerializeField] private int _loopCount = -1; public float Duration { get { return _duration; } set { _duration = Mathf.Max(0f, value); } } public float Delay { get { return _delay; } set { _delay = Mathf.Max(0f, value); } } public Ease PresetEase { get { return _presetEase; } set { _presetEase = value; _easeType = EasingType.Preset; } } public AnimationCurve CustomEase { get { return _customEase; } set { _customEase = value; _easeType = EasingType.Custom; } } public EasingType EaseType { get { return _easeType; } set { _easeType = value; } } public LoopMode LoopMode { get { return _loopMode; } set { _loopMode = value; } } public int? LoopCount { get { if (_loopCount != -1) { return _loopCount; } return null; } set { _loopCount = value.GetValueOrDefault(-1); } } public TweenSettings() { } public TweenSettings(float duration, Ease ease) { Duration = duration; PresetEase = ease; } public TweenSettings(float duration, AnimationCurve curve) { Duration = duration; CustomEase = curve; } public TweenSettings(TweenSettings settings) { _duration = settings._duration; _delay = settings._delay; _easeType = settings._easeType; _presetEase = settings._presetEase; _customEase = settings._customEase; _loopMode = settings._loopMode; _loopCount = settings._loopCount; } public void Apply(TweenBase tween) { tween.SetDuration(_duration); tween.Delay = _delay; tween.LoopMode = _loopMode; tween.Loops = LoopCount; switch (_easeType) { case EasingType.Preset: tween.Ease(_presetEase); break; case EasingType.Custom: tween.Ease(_customEase); break; default: throw new ArgumentOutOfRangeException(); } } } public class ColorTweenFactory<T> : TweenFactory<Color, T>, ICompositeTweenFactory<Color, T, float, RGBA>, ITweenFactory<Color, T>, ICompositeTweenFactory<Color, T, float, HSV> { public ColorTweenFactory(Func<T, Color> getter, Action<T, Color> setter) : base(getter, setter, (LerpFunction<Color>)Color.LerpUnclamped) { } public static ColorTweenFactory<T> From(string propertyName) { return ReflectionTweenFactory.Create<ColorTweenFactory<T>>(propertyName); } public void SetComponent(ref Color composite, RGBA component, float value) { ((Color)(ref composite))[(int)component] = value; } public float GetComponent(Color composite, RGBA component) { return ((Color)(ref composite))[(int)component]; } public void SetComponent(ref Color composite, HSV component, float value) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) float num = default(float); float num2 = default(float); float num3 = default(float); Color.RGBToHSV(composite, ref num, ref num2, ref num3); switch (component) { case HSV.H: num = value; break; case HSV.S: num2 = value; break; case HSV.V: num3 = value; break; default: throw new ArgumentOutOfRangeException("component", component, null); } composite = Color.HSVToRGB(num, num2, num3); } public float GetComponent(Color composite, HSV component) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) float num = default(float); float num2 = default(float); float num3 = default(float); Color.RGBToHSV(composite, ref num, ref num2, ref num3); return component switch { HSV.H => num, HSV.S => num2, HSV.V => num3, _ => throw new ArgumentOutOfRangeException("component", component, null), }; } public float Lerp(float from, float to, float t) { return Mathf.LerpUnclamped(from, to, t); } public ICompositeTweenFactory<Color, T, float, RGBA> AsRGBA() { return this; } public ICompositeTweenFactory<Color, T, float, HSV> AsHSV() { return this; } } public enum RGBA { R, G, B, A } public enum HSV { H, S, V } public class FloatTweenFactory<T> : TweenFactory<float, T> { public FloatTweenFactory(Func<T, float> getter, Action<T, float> setter) : base(getter, setter, (LerpFunction<float>)Mathf.LerpUnclamped) { } public static FloatTweenFactory<T> From(string propertyName) { return ReflectionTweenFactory.Create<FloatTweenFactory<T>>(propertyName); } } public interface ICompositeTweenFactory<T, in THolder, TComponent, in TComponentId> : ITweenFactory<T, THolder> { void SetComponent(ref T composite, TComponentId component, TComponent value); TComponent GetComponent(T composite, TComponentId component); TComponent Lerp(TComponent from, TComponent to, float t); Tween<TComponent> Apply(Tween<TComponent> tween, THolder holder, TComponentId part) { return tween.OnUpdate(delegate(TComponent v) { T composite = Get(holder); SetComponent(ref composite, part, v); Set(holder, composite); }).Lerp(Lerp).From(GetComponent(Get(holder), part)); } Tween<T> Apply(Tween<T> tween, THolder holder, IReadOnlyCollection<TComponentId> parts) { return tween.OnUpdate(delegate(T v) { T composite = Get(holder); foreach (TComponentId part in parts) { SetComponent(ref composite, part, GetComponent(v, part)); } Set(holder, composite); }).Lerp(Lerp).From(Get(holder)); } ITweenFactory<TComponent, THolder> WithPart(TComponentId part) { return new ComponentTweenFactory<T, THolder, TComponent, TComponentId>(this, part); } } internal class ComponentTweenFactory<T, THolder, TComponent, TComponentId> : ITweenFactory<TComponent, THolder> { private readonly ICompositeTweenFactory<T, THolder, TComponent, TComponentId> _factory; private readonly TComponentId _part; public ComponentTweenFactory(ICompositeTweenFactory<T, THolder, TComponent, TComponentId> factory, TComponentId part) { _factory = factory; _part = part; } public void Set(THolder holder, TComponent value) { T composite = _factory.Get(holder); _factory.SetComponent(ref composite, _part, value); _factory.Set(holder, composite); } public TComponent Get(THolder holder) { return _factory.GetComponent(_factory.Get(holder), _part); } public TComponent Lerp(TComponent from, TComponent to, float t) { return _factory.Lerp(from, to, t); } } public static class CompositeTweenFactoryTweenExtensions { public static Tween<TComponent> Apply<T, THolder, TComponent, TComponentId>(this Tween<TComponent> tween, ICompositeTweenFactory<T, THolder, TComponent, TComponentId> factory, THolder holder, TComponentId part) { return factory.Apply(tween, holder, part); } public static Tween<TComponent> Tween<T, THolder, TComponent, TComponentId>(this THolder holder, ICompositeTweenFactory<T, THolder, TComponent, TComponentId> factory, TComponentId component, TComponent to) where THolder : Object { return ((Object)(object)holder).Tween(to).Apply(factory, holder, component); } public static Tween<T> Apply<T, THolder, TPart, TPartId>(this Tween<T> tween, ICompositeTweenFactory<T, THolder, TPart, TPartId> factory, THolder holder, IReadOnlyCollection<TPartId> parts) where THolder : Object { return factory.Apply(tween, holder, parts); } public static Tween<T> Tween<T, THolder, TComponent, TComponentId>(this THolder holder, ICompositeTweenFactory<T, THolder, TComponent, TComponentId> factory, IReadOnlyCollection<TComponentId> parts, T to) where THolder : Object { return ((Object)(object)holder).Tween(to).Apply(factory, holder, parts); } } public class QuaternionTweenFactory<T> : TweenFactory<Quaternion, T>, ICompositeTweenFactory<Quaternion, T, float, Axis4>, ITweenFactory<Quaternion, T>, ICompositeTweenFactory<Vector3, T, float, Axis>, ITweenFactory<Vector3, T> { public QuaternionTweenFactory(Func<T, Quaternion> getter, Action<T, Quaternion> setter) : base(getter, setter, (LerpFunction<Quaternion>)Quaternion.LerpUnclamped) { } public static QuaternionTweenFactory<T> From(string propertyName) { return ReflectionTweenFactory.Create<QuaternionTweenFactory<T>>(propertyName); } public void SetComponent(ref Quaternion composite, Axis4 component, float value) { ((Quaternion)(ref composite))[(int)component] = value; } public float GetComponent(Quaternion composite, Axis4 component) { return ((Quaternion)(ref composite))[(int)component]; } public void SetComponent(ref Vector3 composite, Axis component, float value) { ((Vector3)(ref composite))[(int)component] = value; } public float GetComponent(Vector3 composite, Axis component) { return ((Vector3)(ref composite))[(int)component]; } public float Lerp(float from, float to, float t) { return Mathf.LerpUnclamped(from, to, t); } void ITweenFactory<Vector3, T>.Set(T holder, Vector3 value) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Unknown result type (might be due to invalid IL or missing references) Set(holder, Quaternion.Euler(value)); } Vector3 ITweenFactory<Vector3, T>.Get(T holder) { //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_000a: Unknown result type (might be due to invalid IL or missing references) Quaternion val = Get(holder); return ((Quaternion)(ref val)).eulerAngles; } Vector3 ITweenFactory<Vector3, T>.Lerp(Vector3 from, Vector3 to, float t) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Unknown result type (might be due to invalid IL or missing references) return Vector3.LerpUnclamped(from, to, t); } } public enum Axis4 { X, Y, Z, W } public static class ReflectionTweenFactory { private struct SupportedType { public Type FactoryType; public Type TweenerTargetType; public SupportedType(Type factoryType = null, Type tweenerTargetType = null) { FactoryType = factoryType; TweenerTargetType = tweenerTargetType; } } private static readonly Dictionary<Type, SupportedType> _supportedTypes = new Dictionary<Type, SupportedType> { { typeof(float), new SupportedType(typeof(FloatTweenFactory<>), typeof(FloatFromToTweenerTarget<>)) }, { typeof(Vector2), new SupportedType(typeof(Vector2TweenFactory<>), typeof(Vector2FromToTweenerTarget<>)) }, { typeof(Vector3), new SupportedType(typeof(Vector3TweenFactory<>), typeof(Vector3FromToTweenerTarget<>)) }, { typeof(Quaternion), new SupportedType(typeof(QuaternionTweenFactory<>)) }, { typeof(Color), new SupportedType(typeof(ColorTweenFactory<>), typeof(ColorFromToTweenerTarget<>)) } }; public static ITweenerTarget CreateTweenerTarget<T, THolder>(string propertyName) where THolder : Object { return CreateTweenerTargetAutoTyped(GetProperty(propertyName, typeof(THolder), typeof(T))); } public static Tween<T> Tween<T, THolder>(this THolder obj, string propertyName, T to) where THolder : Object { return CreateTween(obj, propertyName, to); } public static Tween<T> CreateTween<T, THolder>(THolder holder, string propertyName, T to) where THolder : Object { return holder.Tween(Create<T, THolder>(propertyName), to); } public static ITweenFactory<T, THolder> Create<T, THolder>(string propertyName) where THolder : Object { return (ITweenFactory<T, THolder>)CreateFactoryAutoTyped(GetProperty(propertyName, typeof(THolder), typeof(T))); } public static TFactory Create<TFactory>(string propertyName) { return (TFactory)CreateFactoryWithType(propertyName, typeof(TFactory)); } public static TFactory Create<T, THolder, TFactory>(string propertyName) where TFactory : TweenFactory<T, THolder> { return (TFactory)CreateFactoryWithType(GetProperty(propertyName, typeof(THolder), typeof(T)), typeof(TFactory)); } internal static ITweenerTarget CreateTweenerTargetAutoTyped(PropertyInfo property) { object obj = CreateFactoryAutoTyped(property); Type propertyType = property.PropertyType; if (!_supportedTypes.TryGetValue(propertyType, out var value)) { throw new ArgumentException($"Type {propertyType} is not supported"); } return (ITweenerTarget)Activator.CreateInstance(value.TweenerTargetType.MakeGenericType(property.DeclaringType), obj); } private static object CreateFactoryAutoTyped(PropertyInfo property) { Type propertyType = property.PropertyType; if (!_supportedTypes.TryGetValue(propertyType, out var value)) { throw new ArgumentException($"Type {propertyType} is not supported"); } return CreateFactoryWithType(property, value.FactoryType.MakeGenericType(property.DeclaringType)); } private static object CreateFactoryWithType(string propertyName, Type factoryType) { Type baseType = factoryType.BaseType; if ((object)baseType == null || !baseType.IsGenericType || baseType.GetGenericTypeDefinition() != typeof(TweenFactory<, >)) { throw new ArgumentException($"Type {factoryType} does not inherit from TweenFactory"); } Type propertyType = baseType.GetGenericArguments()[0]; Type[] genericArguments = factoryType.GetGenericArguments(); if (genericArguments.Length != 1) { throw new ArgumentException($"Type {factoryType} does not have 1 generic arguments"); } Type type = genericArguments[0]; if (!type.IsSubclassOf(typeof(Object))) { throw new ArgumentException($"Type {type} is not a subclass of UnityEngine.Object"); } return CreateFactoryWithType(GetProperty(propertyName, type, propertyType), factoryType); } private static object CreateFactoryWithType(PropertyInfo property, Type factoryType) { Type type = typeof(Func<, >).MakeGenericType(property.DeclaringType, property.PropertyType); Type type2 = typeof(Action<, >).MakeGenericType(property.DeclaringType, property.PropertyType); ConstructorInfo? constructor = factoryType.GetConstructor(new Type[2] { type, type2 }); if (constructor == null) { throw new ArgumentException($"Type {factoryType} does not have a constructor with the required arguments"); } return constructor.Invoke(new object[2] { Delegate.CreateDelegate(type, property.GetGetMethod()), Delegate.CreateDelegate(type2, property.GetSetMethod()) }); } private static PropertyInfo GetProperty(string name, Type holderType, Type propertyType = null) { PropertyInfo property = holderType.GetProperty(name); if (property == null) { throw new ArgumentException($"Property '{name}' not found on type {holderType}"); } if (propertyType != null && property.PropertyType != propertyType) { throw new ArgumentException($"Property '{name}' on type {holderType} is not of type {propertyType}"); } return property; } } public interface ITweenFactory<T, in THolder> { void Set(THolder holder, T value); T Get(THolder holder); T Lerp(T from, T to, float t); Tween<T> Apply(Tween<T> tween, THolder holder) { return tween.Lerp(Lerp).OnUpdate(delegate(T v) { Set(holder, v); }).From(Get(holder)); } } public class TweenFactory<T, THolder> : ITweenFactory<T, THolder> { private readonly Func<THolder, T> _getFunction; private readonly Action<THolder, T> _setAction; private readonly LerpFunction<T> _lerpFunction; public TweenFactory(Func<THolder, T> getter, Action<THolder, T> setter, LerpFunction<T> lerp) { _getFunction = getter; _setAction = setter; _lerpFunction = lerp; } public T Get(THolder holder) { return _getFunction(holder); } public void Set(THolder holder, T value) { _setAction(holder, value); } public T Lerp(T from, T to, float t) { return _lerpFunction(from, to, t); } } public static class TweenFactoryTweenExtensions { public static Tween<T> Apply<T, THolder>(this Tween<T> tween, ITweenFactory<T, THolder> factory, THolder holder) { return factory.Apply(tween, holder); } public static Tween<T> Tween<T, THolder>(this THolder holder, ITweenFactory<T, THolder> factory, T to) where THolder : Object { return ((Object)(object)holder).Tween(to).Apply(factory, holder); } } public class Vector2TweenFactory<T> : TweenFactory<Vector2, T>, ICompositeTweenFactory<Vector2, T, float, Axis2>, ITweenFactory<Vector2, T> { public Vector2TweenFactory(Func<T, Vector2> getter, Action<T, Vector2> setter) : base(getter, setter, (LerpFunction<Vector2>)Vector2.LerpUnclamped) { } public static Vector2TweenFactory<T> From(string propertyName) { return ReflectionTweenFactory.Create<Vector2TweenFactory<T>>(propertyName); } public void SetComponent(ref Vector2 composite, Axis2 component, float value) { ((Vector2)(ref composite))[(int)component] = value; } public float GetComponent(Vector2 composite, Axis2 component) { return ((Vector2)(ref composite))[(int)component]; } public float Lerp(float from, float to, float t) { return Mathf.LerpUnclamped(from, to, t); } } public enum Axis2 { X, Y } public class Vector3TweenFactory<T> : TweenFactory<Vector3, T>, ICompositeTweenFactory<Vector3, T, float, Axis>, ITweenFactory<Vector3, T> { public ICompositeTweenFactory<Vector3, T, float, Axis> Composite => this; public Vector3TweenFactory(Func<T, Vector3> getter, Action<T, Vector3> setter) : base(getter, setter, (LerpFunction<Vector3>)Vector3.LerpUnclamped) { } public static Vector3TweenFactory<T> From(string propertyName) { return ReflectionTweenFactory.Create<Vector3TweenFactory<T>>(propertyName); } public void SetComponent(ref Vector3 composite, Axis component, float value) { ((Vector3)(ref composite))[(int)component] = value; } public float GetComponent(Vector3 composite, Axis component) { return ((Vector3)(ref composite))[(int)component]; } public float Lerp(float from, float to, float t) { return Mathf.LerpUnclamped(from, to, t); } } public enum Axis { X, Y, Z } public static class AudioTweens { public static FloatTweenFactory<AudioSource> Volume { get; } = new FloatTweenFactory<AudioSource>((AudioSource c) => c.volume, delegate(AudioSource c, float v) { c.volume = v; }); public static FloatTweenFactory<AudioSource> Pitch { get; } = new FloatTweenFactory<AudioSource>((AudioSource c) => c.pitch, delegate(AudioSource c, float v) { c.pitch = v; }); public static FloatTweenFactory<AudioSource> PanStereo { get; } = new FloatTweenFactory<AudioSource>((AudioSource c) => c.panStereo, delegate(AudioSource c, float v) { c.panStereo = v; }); public static Tween<float> TweenVolume(this AudioSource audioSource, float volume) { return audioSource.Tween<float, AudioSource>((ITweenFactory<float, AudioSource>)Volume, volume); } public static Tween<float> TweenPitch(this AudioSource audioSource, float pitch) { return audioSource.Tween<float, AudioSource>((ITweenFactory<float, AudioSource>)Pitch, pitch); } public static Tween<float> TweenPan(this AudioSource audioSource, float panStereo) { return audioSource.Tween<float, AudioSource>((ITweenFactory<float, AudioSource>)PanStereo, panStereo); } } public static class CameraTweens { public static FloatTweenFactory<Camera> FieldOfView { get; } = new FloatTweenFactory<Camera>((Camera c) => c.fieldOfView, delegate(Camera c, float fov) { c.fieldOfView = fov; }); public static Tween<float> TweenFOV(this Camera camera, float fov) { return camera.Tween<float, Camera>((ITweenFactory<float, Camera>)FieldOfView, fov); } } public static class CanvasGroupTweens { public static FloatTweenFactory<CanvasGroup> Alpha { get; } = new FloatTweenFactory<CanvasGroup>((CanvasGroup c) => c.alpha, delegate(CanvasGroup c, float alpha) { c.alpha = alpha; }); public static Tween<float> TweenAlpha(this CanvasGroup canvasGroup, float alpha) { return canvasGroup.Tween<float, CanvasGroup>((ITweenFactory<float, CanvasGroup>)Alpha, alpha); } } public static class GraphicTweens { private static readonly RGBA[] _rgb = new RGBA[3] { RGBA.R, RGBA.G, RGBA.B }; public static ColorTweenFactory<Graphic> Color { get; } = new ColorTweenFactory<Graphic>((Graphic c) => c.color, delegate(Graphic c, Color color) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) c.color = color; }); public static Tween<Color> TweenColor(this Graphic graphic, Color color) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) return graphic.Tween<Color, Graphic>((ITweenFactory<Color, Graphic>)Color, color); } public static Tween<Color> TweenRGB(this Graphic graphic, Color color) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) return graphic.Tween<Color, Graphic, float, RGBA>(Color.AsRGBA(), (IReadOnlyCollection<RGBA>)(object)_rgb, color); } public static Tween<float> TweenRed(this Graphic graphic, float value) { return graphic.Tween<Color, Graphic, float, RGBA>(Color.AsRGBA(), RGBA.R, value); } public static Tween<float> TweenGreen(this Graphic graphic, float value) { return graphic.Tween<Color, Graphic, float, RGBA>(Color.AsRGBA(), RGBA.G, value); } public static Tween<float> TweenBlue(this Graphic graphic, float value) { return graphic.Tween<Color, Graphic, float, RGBA>(Color.AsRGBA(), RGBA.B, value); } public static Tween<float> TweenAlpha(this Graphic graphic, float value) { return graphic.Tween<Color, Graphic, float, RGBA>(Color.AsRGBA(), RGBA.A, value); } public static Tween<float> TweenHue(this Graphic graphic, float value) { return graphic.Tween<Color, Graphic, float, HSV>(Color.AsHSV(), HSV.H, value); } public static Tween<float> TweenSaturation(this Graphic graphic, float value) { return graphic.Tween<Color, Graphic, float, HSV>(Color.AsHSV(), HSV.S, value); } public static Tween<float> TweenValue(this Graphic graphic, float value) { return graphic.Tween<Color, Graphic, float, HSV>(Color.AsHSV(), HSV.V, value); } public static Tween<float> TweenGradient(this Graphic graphic, Gradient gradient) { return ((Object)(object)graphic).TweenValue(0f, 1f).OnUpdate(delegate(float v) { //IL_000d: Unknown result type (might be due to invalid IL or missing references) graphic.color = gradient.Evaluate(v); }); } } public static class RectTransformTweens { public static Vector2TweenFactory<RectTransform> AnchoredPosition { get; } = new Vector2TweenFactory<RectTransform>((RectTransform t) => t.anchoredPosition, delegate(RectTransform t, Vector2 v) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) t.anchoredPosition = v; }); public static Vector2TweenFactory<RectTransform> SizeDelta { get; } = new Vector2TweenFactory<RectTransform>((RectTransform t) => t.sizeDelta, delegate(RectTransform t, Vector2 v) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) t.sizeDelta = v; }); public static Vector2TweenFactory<RectTransform> AnchorMin { get; } = new Vector2TweenFactory<RectTransform>((RectTransform t) => t.anchorMin, delegate(RectTransform t, Vector2 v) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) t.anchorMin = v; }); public static Vector2TweenFactory<RectTransform> AnchorMax { get; } = new Vector2TweenFactory<RectTransform>((RectTransform t) => t.anchorMax, delegate(RectTransform t, Vector2 v) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) t.anchorMax = v; }); public static Tween<Vector2> TweenAnchoredPosition(this RectTransform rectTransform, Vector2 to) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) return rectTransform.Tween<Vector2, RectTransform>((ITweenFactory<Vector2, RectTransform>)AnchoredPosition, to); } public static Tween<float> TweenAnchoredX(this RectTransform rectTransform, float to) { return rectTransform.Tween<Vector2, RectTransform, float, Axis2>((ICompositeTweenFactory<Vector2, RectTransform, float, Axis2>)AnchoredPosition, Axis2.X, to); } public static Tween<float> TweenAnchoredY(this RectTransform rectTransform, float to) { return rectTransform.Tween<Vector2, RectTransform, float, Axis2>((ICompositeTweenFactory<Vector2, RectTransform, float, Axis2>)AnchoredPosition, Axis2.Y, to); } public static Tween<Vector2> TweenSizeDelta(this RectTransform rectTransform, Vector2 to) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) return rectTransform.Tween<Vector2, RectTransform>((ITweenFactory<Vector2, RectTransform>)SizeDelta, to); } public static Tween<float> TweenSizeDeltaX(this RectTransform rectTransform, float to) { return rectTransform.Tween<Vector2, RectTransform, float, Axis2>((ICompositeTweenFactory<Vector2, RectTransform, float, Axis2>)SizeDelta, Axis2.X, to); } public static Tween<float> TweenSizeDeltaY(this RectTransform rectTransform, float to) { return rectTransform.Tween<Vector2, RectTransform, float, Axis2>((ICompositeTweenFactory<Vector2, RectTransform, float, Axis2>)SizeDelta, Axis2.Y, to); } public static Tween<Vector2> TweenAnchorMin(this RectTransform rectTransform, Vector2 to) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) return rectTransform.Tween<Vector2, RectTransform>((ITweenFactory<Vector2, RectTransform>)AnchorMin, to); } public static Tween<float> TweenAnchorMinX(this RectTransform rectTransform, float to) { return rectTransform.Tween<Vector2, RectTransform, float, Axis2>((ICompositeTweenFactory<Vector2, RectTransform, float, Axis2>)AnchorMin, Axis2.X, to); } public static Tween<float> TweenAnchorMinY(this RectTransform rectTransform, float to) { return rectTransform.Tween<Vector2, RectTransform, float, Axis2>((ICompositeTweenFactory<Vector2, RectTransform, float, Axis2>)AnchorMin, Axis2.Y, to); } public static Tween<Vector2> TweenAnchorMax(this RectTransform rectTransform, Vector2 to) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) return rectTransform.Tween<Vector2, RectTransform>((ITweenFactory<Vector2, RectTransform>)AnchorMax, to); } public static Tween<float> TweenAnchorMaxX(this RectTransform rectTransform, float to) { return rectTransform.Tween<Vector2, RectTransform, float, Axis2>((ICompositeTweenFactory<Vector2, RectTransform, float, Axis2>)AnchorMax, Axis2.X, to); } public static Tween<float> TweenAnchorMaxY(this RectTransform rectTransform, float to) { return rectTransform.Tween<Vector2, RectTransform, float, Axis2>((ICompositeTweenFactory<Vector2, RectTransform, float, Axis2>)AnchorMax, Axis2.Y, to); } } public static class SpriteRendererTweens { public static ColorTweenFactory<SpriteRenderer> Color { get; } = new ColorTweenFactory<SpriteRenderer>((SpriteRenderer r) => r.color, delegate(SpriteRenderer r, Color c) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) r.color = c; }); public static Tween<Color> TweenColor(this SpriteRenderer renderer, Color to) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) return renderer.Tween<Color, SpriteRenderer>((ITweenFactory<Color, SpriteRenderer>)Color, to); } public static Tween<float> TweenRed(this SpriteRenderer renderer, float red) { return renderer.Tween<Color, SpriteRenderer, float, RGBA>(Color.AsRGBA(), RGBA.R, red); } public static Tween<float> TweenGreen(this SpriteRenderer renderer, float green) { return renderer.Tween<Color, SpriteRenderer, float, RGBA>(Color.AsRGBA(), RGBA.G, green); } public static Tween<float> TweenBlue(this SpriteRenderer renderer, float blue) { return renderer.Tween<Color, SpriteRenderer, float, RGBA>(Color.AsRGBA(), RGBA.B, blue); } public static Tween<float> TweenAlpha(this SpriteRenderer renderer, float alpha) { return renderer.Tween<Color, SpriteRenderer, float, RGBA>(Color.AsRGBA(), RGBA.A, alpha); } public static Tween<float> TweenHue(this SpriteRenderer renderer, float hue) { return renderer.Tween<Color, SpriteRenderer, float, HSV>(Color.AsHSV(), HSV.H, hue); } public static Tween<float> TweenSaturation(this SpriteRenderer renderer, float saturation) { return renderer.Tween<Color, SpriteRenderer, float, HSV>(Color.AsHSV(), HSV.S, saturation); } public static Tween<float> TweenBrightness(this SpriteRenderer renderer, float value) { return renderer.Tween<Color, SpriteRenderer, float, HSV>(Color.AsHSV(), HSV.V, value); } public static Tween<float> TweenGradient(this SpriteRenderer renderer, Gradient gradient) { return ((Object)(object)renderer).TweenValue(0f, 1f).OnUpdate(delegate(float v) { //IL_000d: Unknown result type (might be due to invalid IL or missing references) renderer.color = gradient.Evaluate(v); }); } } public static class TransformTweens { private static readonly Axis[] _2d = new Axis[2] { Axis.X, Axis.Y }; public static Vector3TweenFactory<Transform> Position { get; } = new Vector3TweenFactory<Transform>((Transform t) => t.position, delegate(Transform t, Vector3 v) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) t.position = v; }); public static Vector3TweenFactory<Transform> LocalPosition { get; } = new Vector3TweenFactory<Transform>((Transform t) => t.localPosition, delegate(Transform t, Vector3 v) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) t.localPosition = v; }); public static Vector3TweenFactory<Transform> Scale { get; } = new Vector3TweenFactory<Transform>((Transform t) => t.localScale, delegate(Transform t, Vector3 v) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) t.localScale = v; }); public static FloatTweenFactory<Transform> UniformScale { get; } = new FloatTweenFactory<Transform>((Transform t) => t.localScale.x, delegate(Transform t, float v) { //IL_0001: 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) t.localScale = Vector3.one * v; }); public static QuaternionTweenFactory<Transform> Rotation { get; } = new QuaternionTweenFactory<Transform>((Transform t) => t.rotation, delegate(Transform t, Quaternion v) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) t.rotation = v; }); public static QuaternionTweenFactory<Transform> LocalRotation { get; } = new QuaternionTweenFactory<Transform>((Transform t) => t.localRotation, delegate(Transform t, Quaternion v) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) t.localRotation = v; }); public static Vector3TweenFactory<Transform> EulerAngles { get; } = new Vector3TweenFactory<Transform>((Transform t) => t.eulerAngles, delegate(Transform t, Vector3 v) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) t.eulerAngles = v; }); public static Vector3TweenFactory<Transform> LocalEulerAngles { get; } = new Vector3TweenFactory<Transform>((Transform t) => t.localEulerAngles, delegate(Transform t, Vector3 v) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) t.localEulerAngles = v; }); public static Tween<Vector3> TweenPosition(this Transform transform, Vector3 position) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) return transform.Tween<Vector3, Transform>((ITweenFactory<Vector3, Transform>)Position, position); } public static Tween<Vector3> TweenPosition(this Transform transform, Vector2 position) { //IL_000b: 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) return transform.Tween<Vector3, Transform, float, Axis>((ICompositeTweenFactory<Vector3, Transform, float, Axis>)Position, (IReadOnlyCollection<Axis>)(object)_2d, Vector2.op_Implicit(position)); } public static Tween<float> TweenX(this Transform transform, float x) { return transform.Tween<Vector3, Transform, float, Axis>((ICompositeTweenFactory<Vector3, Transform, float, Axis>)Position, Axis.X, x); } public static Tween<float> TweenY(this Transform transform, float y) { return transform.Tween<Vector3, Transform, float, Axis>((ICompositeTweenFactory<Vector3, Transform, float, Axis>)Position, Axis.Y, y); } public static Tween<float> TweenZ(this Transform transform, float z) { return transform.Tween<Vector3, Transform, float, Axis>((ICompositeTweenFactory<Vector3, Transform, float, Axis>)Position, Axis.Z, z); } public static Tween<Vector3> TweenLocalPosition(this Transform transform, Vector3 position) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) return transform.Tween<Vector3, Transform>((ITweenFactory<Vector3, Transform>)LocalPosition, position); } public static Tween<Vector3> TweenLocalPosition(this Transform transform, Vector2 position) { //IL_000b: 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) return transform.Tween<Vector3, Transform, float, Axis>((ICompositeTweenFactory<Vector3, Transform, float, Axis>)LocalPosition, (IReadOnlyCollection<Axis>)(object)_2d, Vector2.op_Implicit(position)); } public static Tween<float> TweenLocalX(this Transform transform, float x) { return transform.Tween<Vector3, Transform, float, Axis>((ICompositeTweenFactory<Vector3, Transform, float, Axis>)LocalPosition, Axis.X, x); } public static Tween<float> TweenLocalY(this Transform transform, float y) { return transform.Tween<Vector3, Transform, float, Axis>((ICompositeTweenFactory<Vector3, Transform, float, Axis>)LocalPosition, Axis.Y, y); } public static Tween<float> TweenLocalZ(this Transform transform, float z) { return transform.Tween<Vector3, Transform, float, Axis>((ICompositeTweenFactory<Vector3, Transform, float, Axis>)LocalPosition, Axis.Z, z); } public static Tween<Vector3> TweenScale(this Transform transform, Vector3 scale) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) return transform.Tween<Vector3, Transform>((ITweenFactory<Vector3, Transform>)Scale, scale); } public static Tween<Vector3> TweenScale(this Transform transform, Vector2 scale) { //IL_000b: 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) return transform.Tween<Vector3, Transform, float, Axis>((ICompositeTweenFactory<Vector3, Transform, float, Axis>)Scale, (IReadOnlyCollection<Axis>)(object)_2d, Vector2.op_Implicit(scale)); } public static Tween<float> TweenScaleX(this Transform transform, float x) { return transform.Tween<Vector3, Transform, float, Axis>((ICompositeTweenFactory<Vector3, Transform, float, Axis>)Scale, Axis.X, x); } public static Tween<float> TweenScaleY(this Transform transform, float y) { return transform.Tween<Vector3, Transform, float, Axis>((ICompositeTweenFactory<Vector3, Transform, float, Axis>)Scale, Axis.Y, y); } public static Tween<float> TweenScaleZ(this Transform transform, float z) { return transform.Tween<Vector3, Transform, float, Axis>((ICompositeTweenFactory<Vector3, Transform, float, Axis>)Scale, Axis.Z, z); } public static Tween<float> TweenScaleUniform(this Transform transform, float scale) { return transform.Tween<float, Transform>((ITweenFactory<float, Transform>)UniformScale, scale); } public static Tween<Quaternion> TweenRotation(this Transform transform, Vector3 rotation) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) return transform.Tween<Quaternion, Transform>((ITweenFactory<Quaternion, Transform>)Rotation, Quaternion.Euler(rotation)); } public static Tween<float> TweenRotationX(this Transform transform, float x) { return transform.Tween<Vector3, Transform, float, Axis>((ICompositeTweenFactory<Vector3, Transform, float, Axis>)EulerAngles, Axis.X, x); } public static Tween<float> TweenRotationY(this Transform transform, float y) { return transform.Tween<Vector3, Transform, float, Axis>((ICompositeTweenFactory<Vector3, Transform, float, Axis>)EulerAngles, Axis.Y, y); } public static Tween<float> TweenRotationZ(this Transform transform, float z) { return transform.Tween<Vector3, Transform, float, Axis>((ICompositeTweenFactory<Vector3, Transform, float, Axis>)EulerAngles, Axis.Z, z); } public static Tween<Quaternion> TweenLocalRotation(this Transform transform, Vector3 rotation) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) return transform.Tween<Quaternion, Transform>((ITweenFactory<Quaternion, Transform>)LocalRotation, Quaternion.Euler(rotation)); } public static Tween<float> TweenLocalRotationX(this Transform transform, float x) { return transform.Tween<Vector3, Transform, float, Axis>((ICompositeTweenFactory<Vector3, Transform, float, Axis>)LocalEulerAngles, Axis.X, x); } public static Tween<float> TweenLocalRotationY(this Transform transform, float y) { return transform.Tween<Vector3, Transform, float, Axis>((ICompositeTweenFactory<Vector3, Transform, float, Axis>)LocalEulerAngles, Axis.Y, y); } public static Tween<float> TweenLocalRotationZ(this Transform transform, float z) { return transform.Tween<Vector3, Transform, float, Axis>((ICompositeTweenFactory<Vector3, Transform, float, Axis>)LocalEulerAngles, Axis.Z, z); } } public static class ValueTweens { public static FloatTweenFactory<Object> Value { get; } = new FloatTweenFactory<Object>((Object _) => 0f, delegate { }); public static Tween<float> TweenValue(this Object obj, float from, float to) { return obj.Tween<float, Object>((ITweenFactory<float, Object>)Value, to).From(from); } public static Tween<float> TweenValue(this Object obj, float from, float to, float duration) { return obj.Tween<float, Object>((ITweenFactory<float, Object>)Value, to).From(from).SetDuration(duration); } public static Tween<float> TweenValue01(this Object obj, float duration = 0f) { return obj.TweenValue(0f, 1f).SetDuration(duration); } public static Tween<float> Delay(this Object obj, float duration) { return obj.Tween<float, Object>((ITweenFactory<float, Object>)Value, 0f).SetDuration(duration); } public static Tween<float> DelayedCall(this Object obj, float duration, Action callback) { return obj.Delay(duration).OnComplete(callback); } } public static class CoroutineUtil { public static IEnumerator Yield(this object obj) { yield return obj; } } [AddComponentMenu("FlowTween/Disabler")] public class Disabler : MonoBehaviour { [Tooltip("Whether or not to cache the IOnDisableRoutine components. This avoids a GetComponentInChildren call, but in dynamic hierarchies can cause issues.")] public bool Cached = true; public void DisableObject(MonoBehaviour behaviour) { Disabling.DisableObject(behaviour, Cached); } public void DisableThisObject() { DisableObject((MonoBehaviour)(object)this); } } public static class Disabling { private static readonly Dictionary<GameObject, IOnDisableRoutine[]> _cache = new Dictionary<GameObject, IOnDisableRoutine[]>(); public static void DisableObject(MonoBehaviour behaviour, bool cached = true) { IOnDisableRoutine[] onDisables = GetOnDisables(((Component)behaviour).gameObject, cached); if (onDisables.Length == 0) { ((Component)behaviour).gameObject.SetActive(false); } else { behaviour.StartCoroutine(DisableObjectRoutine(behaviour, (IReadOnlyCollection<IOnDisableRoutine>)(object)onDisables)); } } public static IEnumerator DisableObjectRoutine(MonoBehaviour behaviour, bool cached = true) { IOnDisableRoutine[] onDisables = GetOnDisables(((Component)behaviour).gameObject, cached); if (onDisables.Length == 0) { ((Component)behaviour).gameObject.SetActive(false); } else { yield return DisableObjectRoutine(behaviour, (IReadOnlyCollection<IOnDisableRoutine>)(object)onDisables); } } private static IEnumerator DisableObjectRoutine(MonoBehaviour behaviour, IReadOnlyCollection<IOnDisableRoutine> onDisables) { int toComplete = onDisables.Count; foreach (IOnDisableRoutine onDisable in onDisables) { behaviour.StartCoroutine(Await(onDisable.OnDisableRoutine())); } yield return (object)new WaitUntil((Func<bool>)(() => toComplete == 0)); ((Component)behaviour).gameObject.SetActive(false); IEnumerator Await(IEnumerator routine) { yield return routine; toComplete--; } } private static IOnDisableRoutine[] GetOnDisables(GameObject gameObject, bool cached) { if (!gameObject.activeSelf) { return Array.Empty<IOnDisableRoutine>(); } if (!cached) { return gameObject.GetComponentsInChildren<IOnDisableRoutine>(); } if (!_cache.TryGetValue(gameObject, out var value)) { return _cache[gameObject] = gameObject.GetComponentsInChildren<IOnDisableRoutine>(); } return value; } [RuntimeInitializeOnLoadMethod(/*Could not decode attribute arguments.*/)] private static void Init() { _cache.Clear(); } } public static class DisablingExtensions { public static void DisableObject(this MonoBehaviour behaviour, bool cached = true) { Disabling.DisableObject(behaviour, cached); } public static IEnumerator DisableObjectRoutine(this MonoBehaviour behaviour, bool cached = true) { return Disabling.DisableObjectRoutine(behaviour, cached); } public static void SetObjectEnabled(this MonoBehaviour behaviour, bool enabled, bool cached = true) { if (enabled) { ((Component)behaviour).gameObject.SetActive(true); } else { behaviour.DisableObject(cached); } } public static IEnumerator SetObjectEnabledRoutine(this GameObject gameObject, bool enabled, bool cached = true) { if (enabled) { gameObject.SetActive(true); } else { yield return gameObject.DisableObjectRoutine(cached); } } public static void DisableObject(this GameObject gameObject, bool cached = true) { MonoBehaviour behaviour = default(MonoBehaviour); if (!gameObject.TryGetComponent<MonoBehaviour>(ref behaviour)) { gameObject.SetActive(false); } else { Disabling.DisableObject(behaviour, cached); } } public static IEnumerator DisableObjectRoutine(this GameObject gameObject, bool cached = true) { MonoBehaviour behaviour = default(MonoBehaviour); if (!gameObject.TryGetComponent<MonoBehaviour>(ref behaviour)) { gameObject.SetActive(false); } else { yield return Disabling.DisableObjectRoutine(behaviour, cached); } } } public interface IOnDisableRoutine { IEnumerator OnDisableRoutine(); } public interface IOnDisablingStarted : IOnDisableRoutine { void OnDisablingStarted(); IEnumerator IOnDisableRoutine.OnDisableRoutine() { OnDisablingStarted(); yield break; } } public static class TweenUtilExtensions { public static T CancelTweens<T>(this T obj, bool callOnComplete = false) where T : Component { ((Component)obj).gameObject.CancelTweens(callOnComplete); return obj; } public static GameObject CancelTweens(this GameObject obj, bool callOnComplete = false) { TweenManager.TryAccess(delegate(TweenManager manager) { manager.CancelObject(obj, callOnComplete); }); return obj; } private static T Get<T>(this Object obj) where T : Runnable, new() { if (!TweenManager.TryAccess((TweenManager manager) => manager.Get<T>(obj), out var result)) { return new T(); } return result; } public static TweenSequence Sequence(this Object obj) { return obj.Get<TweenSequence>(); } public static Tween<T> Tween<T>(this Object obj) { return obj.Get<Tween<T>>(); } internal static Tween<T> Tween<T>(this Object obj, T to) { return obj.Tween<T>().To(to); } public static ITweenFactory<TPart, THolder> WithPart<T, THolder, TPart, TPartId>(this ICompositeTweenFactory<T, THolder, TPart, TPartId> factory, TPartId part) { return factory.WithPart(part); } } } namespace FlowTween.Components { public class FromToTweenerTarget<T, THolder, TData> : ITweenerTarget<T, THolder, TData>, ITweenerTarget where THolder : Component where TData : FromToTweenerTargetData<T>, new() { private readonly ITweenFactory<T, THolder> _factory; public Action<THolder, T, T> DrawGizmos; public FromToTweenerTarget(ITweenFactory<T, THolder> factory) { _factory = factory; } public T TakeSnapshot(THolder holder) { return _factory.Get(holder); } public void ApplySnapshot(THolder holder, T snapshot) { _factory.Set(holder, snapshot); } public virtual TweenBase GetTween(THolder holder, TData data) { var (start, to) = GetValues(data, holder); return holder.Tween<T, THolder>(_factory, to).From(start); } public void OnDrawGizmos(THolder holder, TData data) { var (arg, arg2) = GetValues(data, holder); DrawGizmos?.Invoke(holder, arg, arg2); } public object GetData() { TData val = new TData(); val.Init(typeof(THolder)); return val; } protected virtual (T, T) GetValues(TData data, THolder holder) { return (Evaluate(data, holder, data.Start), Evaluate(data, holder, data.End)); } protected T Evaluate(TData data, THolder holder, FromToTweenerTargetValue<T> value) { if (!value.Relative) { return value.Value; } T arg = _factory.Get(GetSource(value, holder)); return data.GetOperations()[value.OperationName](arg, value.Value); } protected THolder GetSource<_>(FromToTweenerTargetValue<@_> value, THolder holder) { if ((Object)(object)value.Source == (Object)null) { return holder; } Component source = value.Source; THolder val = (THolder)(object)((source is THolder) ? source : null); if (val != null) { return val; } Debug.LogError((object)$"Source component {value.Source} is not of type {typeof(THolder)}"); return holder; } } public class FloatFromToTweenerTarget<T> : FromToTweenerTarget<float, T, FloatTweenerTargetData> where T : Component { public FloatFromToTweenerTarget(ITweenFactory<float, T> factory) : base(factory) { } } public class Vector3FromToTweenerTarget<T> : FromToTweenerTarget<Vector3, T, Vector3TweenerTargetData> where T : Component { public Vector3FromToTweenerTarget(ITweenFactory<Vector3, T> factory) : base(factory) { } } public class Vector2FromToTweenerTarget<T> : FromToTweenerTarget<Vector2, T, Vector2TweenerTargetData> where T : Component { public Vector2FromToTweenerTarget(ITweenFactory<Vector2, T> factory) : base(factory) { } } public class ColorFromToTweenerTarget<T> : FromToTweenerTarget<Color, T, ColorTweenerTargetData> where T : Component { public ColorFromToTweenerTarget(ITweenFactory<Color, T> factory) : base(factory) { } } [Serializable] public class FromToTweenerTargetValue<T> { public bool Relative = true; public T Value; public string OperationName; public Component Source; } [Serializable] public abstract class FromToTweenerTargetData<T> { [SerializeField] private FromToTweenerTargetValue<T> _start = new FromToTweenerTargetValue<T>(); [SerializeField] private FromToTweenerTargetValue<T> _end = new FromToTweenerTargetValue<T>(); [SerializeField] private string _sourceTypeName; public FromToTweenerTargetValue<T> Start { get { return _start; } set { _start = value; } } public FromToTweenerTargetValue<T> End { get { return _end; } set { _end = value; } } public FromToTweenerTargetData() { } public FromToTweenerTargetData(Type componentType) { Init(componentType); } public void Init(Type componentType) { _sourceTypeName = componentType.AssemblyQualifiedName; string operationName = GetOperations().Keys.First(); _start.OperationName = operationName; _end.OperationName = operationName; } public abstract IReadOnlyDictionary<string, Func<T, T, T>> GetOperations(); } [Serializable] public class Vector3TweenerTargetData : FromToTweenerTargetData<Vector3> { public static IReadOnlyDictionary<string, Func<Vector3, Vector3, Vector3>> Operations = new Dictionary<string, Func<Vector3, Vector3, Vector3>> { { "Add", (Vector3 a, Vector3 b) => a + b }, { "Subtract", (Vector3 a, Vector3 b) => a - b } }; public override IReadOnlyDictionary<string, Func<Vector3, Vector3, Vector3>> GetOperations() { return Operations; } public Vector3TweenerTargetData() { } public Vector3TweenerTargetData(Type componentType) : base(componentType) { } public static Vector3TweenerTargetData Create<THolder>() where THolder : Component { return new Vector3TweenerTargetData(typeof(THolder)); } } [Serializable] public class Vector2TweenerTargetData : FromToTweenerTargetData<Vector2> { public static IReadOnlyDictionary<string, Func<Vector2, Vector2, Vector2>> Operations = new Dictionary<string, Func<Vector2, Vector2, Vector2>> { { "Add", (Vector2 a, Vector2 b) => a + b }, { "Subtract", (Vector2 a, Vector2 b) => a - b }, { "Multiply", (Vector2 a, Vector2 b) => a * b }, { "Divide", (Vector2 a, Vector2 b) => a / b } }; public override IReadOnlyDictionary<string, Func<Vector2, Vector2, Vector2>> GetOperations() { return Operations; } public Vector2TweenerTargetData() { } public Vector2TweenerTargetData(Type componentType) : base(componentType) { } public static Vector2TweenerTargetData Create<THolder>() where THolder : Component { return new Vector2TweenerTargetData(typeof(THolder)); } } [Serializable] public class ColorTweenerTargetData : FromToTweenerTargetData<Color> { public static IReadOnlyDictionary<string, Func<Color, Color, Color>> Operations = new Dictionary<string, Func<Color, Color, Color>> { { "Multiply", (Color a, Color b) => a * b }, { "Add", (Color a, Color b) => a + b }, { "Subtract", (Color a, Color b) => a - b } }; public override IReadOnlyDictionary<string, Func<Color, Color, Color>> GetOperations() { return Operations; } public ColorTweenerTargetData() { } public ColorTweenerTargetData(Type componentType) : base(componentType) { } public static ColorTweenerTargetData Create<THolder>() where THolder : Component { return new ColorTweenerTargetData(typeof(THolder)); } } [Serializable] public class FloatTweenerTargetData : FromToTweenerTargetData<float> { public static IReadOnlyDictionary<string, Func<float, float, float>> Operations = new Dictionary<string, Func<float, float, float>> { { "Add", (float a, float b) => a + b }, { "Subtract", (float a, float b) => a - b }, { "Multiply", (float a, float b) => a * b }, { "Divide", (float a, float b) => a / b } }; public override IReadOnlyDictionary<string, Func<float, float, float>> GetOperations() { return Operations; } public FloatTweenerTargetData() { } public FloatTweenerTargetData(Type componentType) : base(componentType) { } public static FloatTweenerTargetData Create<THolder>() where THolder : Component { return new FloatTweenerTargetData(typeof(THolder)); } } public class GradientTweenerTarget<T> : ITweenerTarget<Color, T, GradientData>, ITweenerTarget where T : Component { private readonly Func<T, Color> _getter; private readonly Action<T, Color> _setter; public GradientTweenerTarget(Func<T, Color> getter, Action<T, Color> setter) { _getter = getter; _setter = setter; } public GradientTweenerTarget(ITweenFactory<Color, T> factory) { _getter = factory.Get; _setter = factory.Set; } public object GetData() { return new GradientData(); } public Color TakeSnapshot(T holder) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) return _getter(holder); } public void ApplySnapshot(T holder, Color snapshot) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) _setter(holder, snapshot); } public TweenBase GetTween(T holder, GradientData data) { return ((Object)(object)holder).TweenValue(0f, 1f).OnUpdate(delegate(float t) { //IL_001d: Unknown result type (might be due to invalid IL or missing references) _setter(holder, data.Gradient.Evaluate(t)); }); } } [Serializable] public class GradientData { public Gradient Gradient; } public interface ITweenerTarget { Type ComponentType { get; } object TakeSnapshot(Component component); void ApplySnapshot(Component component, object snapshot); object GetData(); TweenBase GetTween(Component component, object data); void OnDrawGizmos(Component component, object data) { } } public interface ITweenerTarget<T, in THolder, in TData> : ITweenerTarget where THolder : Component where TData : class { Type ITweenerTarget.ComponentType => typeof(THolder); T TakeSnapshot(THolder holder); void ApplySnapshot(THolder holder, T snapshot); TweenBase GetTween(THolder holder, TData data); void OnDrawGizmos(THolder holder, TData data) { } void ITweenerTarget.ApplySnapshot(Component component, object snapshot) { ApplySnapshot(AssertComponentType(component), AssertSnapshotType(snapshot)); } object ITweenerTarget.TakeSnapshot(Component component) { return TakeSnapshot(AssertComponentType(component)); } TweenBase ITweenerTarget.GetTween(Component component, object data) { return GetTween(AssertComponentType(component), AssertDataType(data)); } void ITweenerTarget.OnDrawGizmos(Component component, object obj) { OnDrawGizmos(AssertComponentType(component), AssertDataType(obj)); } protected static THolder AssertComponentType(Component component) { THolder val = (THolder)(object)((component is THolder) ? component : null); if (val != null) { return val; } throw new InvalidOperationException($"Component {component} is not of type {typeof(THolder)}"); } protected static TData AssertDataType(object obj) { if (obj is TData result) { return result; } throw new InvalidOperationException($"Component {obj} is not of type {typeof(TData)}"); } protected static T AssertSnapshotType(object obj) { if (obj is T) { return (T)obj; } throw new InvalidOperationException($"Component {obj} is not of type {typeof(T)}"); } } [AddComponentMenu("FlowTween/Tweener")] public class Tweener : MonoBehaviour, IOnDisableRoutine { private struct TweenQueueItem { public TweenerTargetConfig Config; public Action<TweenBase> Callback; } [SerializeField] private List<TweenerTargetConfig> _tweens = new List<TweenerTargetConfig>(); [SerializeField] private bool _preventOverlapping; [SerializeField] private bool _sequential; private Queue<TweenQueueItem> _tweenQueue; public List<TweenerTargetConfig> Tweens => _tweens; public bool PreventOverlapping { get { return _preventOverlapping; } set { _preventOverlapping = value; } } public bool Sequential { get { return _sequential; } set { _sequential = value; } } private void OnEnable() { PlayTweens(_tweens.Where((TweenerTargetConfig tween) => tween.PlayOnEnable)); } private void OnValidate() { foreach (TweenerTargetConfig tween in _tweens) { tween.Validate(((Component)this).gameObject); } } private void Reset() { _tweens.Clear(); AddTween(out var _); } private void OnDrawGizmosSelected() { foreach (TweenerTargetConfig tween in _tweens) { tween.DrawGizmos(((Component)this).gameObject); } } public void Play(int index) { PlayTween(index); } public void PlayAll() { PlayTweens(_tweens); } public TweenBase PlayTween(int index, Action<TweenBase> callback = null) { BeforePlay(); return PlayTweenInternal(index, callback); } public TweenBase PlayTween(TweenerTargetConfig tween, Action<TweenBase> callback = null) { BeforePlay(); return PlayTweenInternal(tween, callback); } public void PlayTweens(IEnumerable<TweenerTargetConfig> tweens, Action<TweenBase> callback = null) { BeforePlay(); foreach (TweenerTargetConfig tween in tweens) { PlayTweenInternal(tween, callback); } } public void PlayTweens(IEnumerable<int> indices, Action<TweenBase> callback = null) { BeforePlay(); foreach (int index in indices) { PlayTweenInternal(index, callback); } } public TweenBase[] PlayTweensAndReturn(IEnumerable<TweenerTargetConfig> tweens, Action<TweenBase> callback = null) { BeforePlay(); return tweens.Select((TweenerTargetConfig config) => PlayTweenInternal(config, callback)).ToArray(); } public TweenBase[] PlayTweensAndReturn(IEnumerable<int> indices, Action<TweenBase> callback = null) { BeforePlay(); return indices.Select((int index) => PlayTweenInternal(index, callback)).ToArray(); } private TweenBase PlayTweenInternal(int index, Action<TweenBase> callback) { if (index >= 0 && index < _tweens.Count) { PlayTweenInternal(_tweens[index], callback); } Debug.LogWarning((object)$"Tried to play tween at index out of range: {index}", (Object)(object)this); return null; } private TweenBase PlayTweenInternal(TweenerTargetConfig config, Action<TweenBase> callback) { if (!_tweens.Contains(config)) { Debug.LogWarning((object)"Tried to play a tween that is not owned by this tweener", (Object)(object)this); return null; } if (!_sequential) { TweenBase tween = config.GetTween(((Component)this).gameObject); callback?.Invoke(tween); return tween; } if (_tweenQueue == null) { _tweenQueue = new Queue<TweenQueueItem>(); } _tweenQueue.Enqueue(new TweenQueueItem { Config = config, Callback = callback }); if (_tweenQueue.Count == 1) { ((MonoBehaviour)this).StartCoroutine(PlaySequentialLoop()); } return null; } private void BeforePlay() { if (_preventOverlapping) { ((Component)this).gameObject.CancelTweens(); } } private IEnumerator PlaySequentialLoop() { TweenQueueItem result; while (_tweenQueue.TryPeek(out result)) { TweenBase tween = result.Config.GetTween(((Component)this).gameObject); result.Callback?.Invoke(tween); yield return tween; _tweenQueue.Dequeue(); } } public int AddTween(TweenerTargetConfig config) { _tweens.Add(config); return _tweens.Count - 1; } public TweenBase AddTweenAndPlay(TweenerTargetConfig config, Action<TweenBase> callback = null) { return PlayTween(AddTween(config), callback); } public TweenerTargetConfig AddTween(out int index) { TweenerTargetConfig tweenerTargetConfig = new TweenerTargetConfig(); index = AddTween(tweenerTargetConfig); return tweenerTargetConfig; } public bool RemoveTween(TweenerTargetConfig config) { return _tweens.Remove(config); } public bool RemoveTween(int index) { if (index < 0 || index >= _tweens.Count) { return false; } _tweens.RemoveAt(index); return true; } IEnumerator IOnDisableRoutine.OnDisableRoutine() { if (!_tweens.Any((TweenerTargetConfig tween) => tween.PlayOnDisable)) { yield break; } TweenerTargetConfig[] toPlay = _tweens.Where((TweenerTargetConfig tween) => tween.PlayOnDisable).ToArray(); ((Component)this).gameObject.CancelTweens(); foreach (TweenerTargetConfig item in toPlay.Where((TweenerTargetConfig t) => t.ResetOnDisable)) { item.TakeSnapshot(((Component)this).gameObject); } int completed = 0; TweenBase[] tweens = PlayTweensAndReturn(toPlay); TweenBase[] array = tweens; foreach (TweenBase tween2 in array) { ((MonoBehaviour)this).StartCoroutine(AwaitTween(tween2)); } yield return (object)new WaitUntil((Func<bool>)(() => completed == tweens.Length)); IEnumerator AwaitTween(TweenBase tween) { yield return tween; completed++; if (completed == tweens.Length) { foreach (TweenerTargetConfig item2 in toPlay.Where((TweenerTargetConfig t) => t.ResetOnDisable)) { item2.ApplySnapshot(((Component)this).gameObject); } } } } private void OnDisable() { _tweenQueue?.Clear(); } } [Serializable] public class TweenerTargetConfig { [SerializeField] private string _targetId = "TransformPosition"; [SerializeField] private string _prevTargetId = "TransformPosition"; [SerializeReference] private object _data; [SerializeField] private TweenSettingsProperty _settings = new TweenSettingsProperty(); [SerializeField] private bool _playOnEnable; [SerializeField] private bool _playOnDisable; [SerializeField] private bool _resetOnDisable = true; [SerializeField] private bool _ignoreTimescale; [SerializeField] private UnityEvent _onStart; [SerializeField] private UnityEvent _onComplete; [SerializeField] private bool _selected; private Component _cachedComponent; private Type _cachedComponentType; private object _snapshot; public const string FallbackTargetId = "TransformPosition"; public bool IsSelected => _selected; public string TargetId { get { GetTarget(); return _targetId; } } public TweenSettingsProperty Settings { get { return _settings; } set { _settings = value; } } public bool PlayOnEnable { get { return _playOnEnable; } set { _playOnEnable = value; } } public bool PlayOnDisable { get { return _playOnDisable; } set { _playOnDisable = value; } } public bool ResetOnDisable { get { return _resetOnDisable; } set { _resetOnDisable = value; } } public TweenerTargetConfig() { RefreshTarget(); } public TweenerTargetConfig(string targetId, object data) { SetTargetId(targetId, data); } public TweenBase GetTween(GameObject gameObject) { ITweenerTarget target = GetTarget(); Component component = GetComponent(gameObject); if ((Object)(object)component != (Object)null) { _onStart.Invoke(); return target.GetTween(component, _data).SetIgnoreTimescale(_ignoreTimescale).OnComplete((Action)_onComplete.Invoke) .Apply(Settings.Value); } Debug.LogError((object)$"Target component of type {target.ComponentType} is missing", (Object)(object)component); return null; } public void TakeSnapshot(GameObject gameObject) { _snapshot = GetTarget().TakeSnapshot(GetComponent(gameObject)); } public void ApplySnapshot(GameObject gameObject) { if (_snapshot != null) { GetTarget().ApplySnapshot(GetComponent(gameObject), _snapshot); _snapshot = null; } } public void DrawGizmos(GameObject gameObject) { if (_selected) { Component component = GetComponent(gameObject, logError: false); if (!((Object)(object)component == (Object)null)) { GetTarget().OnDrawGizmos(component, _data); } } } public void Validate(GameObject gameObject) { if (!(_targetId == _prevTargetId)) { RefreshTarget(); GetComponent(gameObject); } } public TweenerTargetConfig SetTargetId(string targetId, object data) { if (targetId == _targetId) { return this; } _targetId = targetId; RefreshTarget(); if (_data.GetType() == data.GetType()) { _data = data; return this; } throw new ArgumentException($"Data type mismatch: {_data.GetType()} != {data.GetType()}"); } public TweenerTargetConfig SetTargetUntyped(ITweenerTarget target, object data) { string key = TweenerTargets.Targets.FirstOrDefault((KeyValuePair<string, ITweenerTarget> pair) => pair.Value == target).Key; if (key == null) { throw new ArgumentException($"Target {target} is not registered in TweenerTargets"); } return SetTargetId(key, data); } public TweenerTargetConfig SetTarget<T, THolder, TData>(ITweenerTarget<T, THolder, TData> target, TData data) where THolder : Component where TData : class { return SetTargetUntyped(target, data); } private void RefreshTarget() { _prevTargetId = _targetId; _data = GetTarget().GetData(); } private ITweenerTarget GetTarget() { if (_targetId != null && TweenerTargets.Targets.TryGetValue(_targetId, out var value)) { return value; } _targetId = "TransformPosition"; return TweenerTargets.Targets[_targetId]; } private Component GetComponent(GameObject gameObject, bool logError = true) { ITweenerTarget target = GetTarget(); if ((Object)(object)_cachedComponent != (Object)null && _cachedComponentType == target.ComponentType && (Object)(object)_cachedComponent.gameObject == (Object)(object)gameObject) { return _cachedComponent; } _cachedComponentType = target.ComponentType; _cachedComponent = gameObject.GetComponent(target.ComponentType); if ((Object)(object)_cachedComponent != (Object)null) { return _cachedComponent; } if (logError) { Debug.LogWarning((object)$"Tween type {_targetId} requires component of type {_cachedComponentType}", (Object)(object)gameObject); } return null; } } public static class TweenerTargets { private static RectTransform _canvas; private static readonly Dictionary<string, ITweenerTarget> _targets = new Dictionary<string, ITweenerTarget> { { "TransformPosition", new Vector3FromToTweenerTarget<Transform>(TransformTweens.Position) { DrawGizmos = delegate(Transform _, Vector3 start, Vector3 end) { //IL_0000: 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_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) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) Gizmos.color = Color.green; Gizmos.DrawSphere(start, 0.05f); Gizmos.DrawLine(start, end); Gizmos.color = Color.red; Gizmos.DrawSphere(end, 0.05f); } } }, { "TransformLocalPosition", new Vector3FromToTweenerTarget<Transform>(TransformTweens.LocalPosition) { DrawGizmos = delegate(Transform transform, Vector3 start, Vector3 end) { //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_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0012: 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_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) Vector3 position = transform.position; Gizmos.color = Color.green; Gizmos.DrawSphere(position + start, 0.05f); Gizmos.DrawLine(position + start, end); Gizmos.color = Color.red; Gizmos.DrawSphere(position + end, 0.05f); } } }, { "TransformRotation", new Vector3FromToTweenerTarget<Transform>(TransformTweens.EulerAngles) }, { "TransformLocalRotation", new Vector3FromToTweenerTarget<Transform>(TransformTweens.LocalEulerAngles) }, { "TransformScale", new Vector3FromToTweenerTarget<Transform>(TransformTweens.Scale) }, { "TransformScale (Uniform)", new FloatFromToTweenerTarget<Transform>(TransformTweens.UniformScale) }, { "RectTransformAnchoredPosition", new Vector2FromToTweenerTarget<RectTransform>(RectTransformTweens.AnchoredPosition) }, { "RectTransformSizeDelta", new Vector2FromToTweenerTarget<RectTransform>(RectTransformTweens.SizeDelta) }, { "GraphicColor", new ColorFromToTweenerTarget<Graphic>(GraphicTweens.Color) }, { "GraphicAlpha", new FloatFromToTweenerTarget<Graphic>(GraphicTweens.Color.AsRGBA().WithPart(RGBA.A)) }, { "GraphicColor (Gradient)", new GradientTweenerTarget<Graphic>(GraphicTweens.Color) }, { "CanvasGroupAlpha", new FloatFromToTweenerTarget<CanvasGroup>(CanvasGroupTweens.Alpha) }, { "SpriteRendererColor", new ColorFromToTweenerTarget<SpriteRenderer>(SpriteRendererTweens.Color) }, { "SpriteRendererColor (Gradient)", new GradientTweenerTarget<SpriteRenderer>(SpriteRendererTweens.Color) }, { "CameraFieldOfView", new FloatFromToTweenerTarget<Camera>(CameraTweens.FieldOfView) } }; public static IReadOnlyDictionary<string, ITweenerTarget> Targets => _targets; public static void Register(string id, ITweenerTarget target) { _targets[id] = target; } } } namespace FlowTween.Templates { public abstract class TemplateAsset<T> : ScriptableObject { [SerializeField] private T _template; public T Template { get { return _template; } set { _template = value; } } } [Serializable] public abstract class TemplateProperty<T> { [SerializeField] private bool _useTemplate; [SerializeField] private TemplateAsset<T> _templateValue; [SerializeField] private T _inlineValue; public bool UsingTemplate => _useTemplate; public T Value { get { if (!_useTemplate) { return _inlineValue; } T template = _templateValue.Template; if (template == null) { return _inlineValue; } return template; } } public TemplateAsset<T> TemplateValue { get { return _templateValue; } set { _templateValue = value; _useTemplate = (Object)(object)_templateValue != (Object)null; } } public T InlineValue { get { return _inlineValue; } set { _inlineValue = value; _useTemplate = false; } } protected TemplateProperty() { } protected TemplateProperty(T value) { InlineValue = value; } protected TemplateProperty(TemplateAsset<T> template) { TemplateValue = template; } } [Serializable] public class TweenSettingsProperty : TemplateProperty<TweenSettings> { public TweenSettingsProperty() { } public TweenSettingsProperty(TweenSettings inlineValue) : base(inlineValue) { } public TweenSettingsProperty(TemplateAsset<TweenSettings> templateValue) : base(templateValue) { } public static implicit operator TweenSettings(TweenSettingsProperty property) { return property.Value; } public static implicit operator TweenSettingsProperty(TweenSettings value) { return new TweenSettingsProperty(value); } public static implicit operator TweenSettingsProperty(TemplateAsset<TweenSettings> template) { return new TweenSettingsProperty(template); } } [CreateAssetMenu(menuName = "FlowTween/Tween Settings", order = 0, fileName = "New Tween Settings")] public class TweenSettingsTemplateAsset : TemplateAsset<TweenSettings> { } } namespace FlowTween.Sequencing { public class TweenSequence : Runnable { public struct Item { private float _duration; public bool Overlay; [CanBeNull] public Action Action; public float Duration { get { return _duration; } set { _duration = Mathf.Max(0f, value); } } } private readonly List<Item> _items = new List<Item>(); private int _lastItemIndex = -1; public override float Duration => _items.Sum((Item i) => i.Duration); protected override void OnUpdate(float deltaTime) { if (_items.Count == 0) { return; } int itemIndex = GetItemIndex(base.Progress); while (_lastItemIndex != itemIndex) { if (itemIndex > _lastItemIndex) { _lastItemIndex++; } else { _lastItemIndex--; } _items[_lastItemIndex].Action?.Invoke(); } } private int GetItemIndex(float progress) { float duration = Duration; float num = 0f; for (int i = 0; i < _items.Count; i++) { if (_items[i].Overlay) { continue; } num += _items[i].Duration / duration; if (!(num <= progress)) { for (; i < _items.Count - 1 && _items[i + 1].Overlay; i++) { } return i; } } return _items.Count - 1; } public override void Reset() { base.Reset(); _items.Clear(); _lastItemIndex = -1; } public TweenSequence Add(Item item) { _items.Add(item); return this; } public TweenSequence AddDelay(float seconds) { return Add(new Item { Duration = seconds }); } public TweenSequence Add(Action action, bool overlay = false) { return Add(new Item { Action = action, Overlay = overlay }); } public TweenSequence AddNow(Runnable runnable, bool overlay = false) { runnable.IsPaused = true; return Add(new Item { Duration = runnable.TotalDuration, Action = delegate { runnable.IsPaused = false; }, Overlay = overlay }); } public TweenSequence Add<T>(Func<Tween<T>> createTween, float duration, float delay = 0f, bool overlay = false) { return Add(new Item { Duration = duration + delay, Action = delegate { createTween().SetDuration(duration).SetDelay(delay); }, Overlay = overlay }); } public TweenSequence Add<T>(Func<Tween<T>> createTween, TweenSettings settings, bool overlay = false) { return Add(new Item { Duration = settings.Duration + settings.Delay, Action = delegate { createTween().Apply(settings); }, Overlay = overlay }); } } } namespace System.Runtime.CompilerServices { [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] internal sealed class IgnoresAccessChecksToAttribute : Attribute { public IgnoresAccessChecksToAttribute(string assemblyName) { } } }