diff options
author | chai <chaifix@163.com> | 2020-12-30 20:59:04 +0800 |
---|---|---|
committer | chai <chaifix@163.com> | 2020-12-30 20:59:04 +0800 |
commit | e9ea621b93fbb58d9edfca8375918791637bbd52 (patch) | |
tree | 19ce3b1c1f2d51eda6878c9d0f2c9edc27f13650 /Client/Assembly-CSharp |
+init
Diffstat (limited to 'Client/Assembly-CSharp')
381 files changed, 37356 insertions, 0 deletions
diff --git a/Client/Assembly-CSharp/AcceptDivertPowerGame.cs b/Client/Assembly-CSharp/AcceptDivertPowerGame.cs new file mode 100644 index 0000000..14867f1 --- /dev/null +++ b/Client/Assembly-CSharp/AcceptDivertPowerGame.cs @@ -0,0 +1,84 @@ +using System; +using System.Collections; +using UnityEngine; + +public class AcceptDivertPowerGame : Minigame +{ + private LineRenderer[] LeftWires; + + private LineRenderer[] RightWires; + + public GameObject RightWireParent; + + public GameObject LeftWireParent; + + public SpriteRenderer Switch; + + public AudioClip SwitchSound; + + private bool done; + + public void Start() + { + this.LeftWires = this.LeftWireParent.GetComponentsInChildren<LineRenderer>(); + this.RightWires = this.RightWireParent.GetComponentsInChildren<LineRenderer>(); + for (int i = 0; i < this.LeftWires.Length; i++) + { + this.LeftWires[i].material.SetColor("_Color", Color.yellow); + } + } + + public void DoSwitch() + { + if (this.done) + { + return; + } + this.done = true; + if (Constants.ShouldPlaySfx()) + { + SoundManager.Instance.PlaySound(this.SwitchSound, false, 1f); + } + base.StartCoroutine(this.CoDoSwitch()); + } + + private IEnumerator CoDoSwitch() + { + yield return new WaitForLerp(0.25f, delegate(float t) + { + this.Switch.transform.localEulerAngles = new Vector3(0f, 0f, Mathf.Lerp(0f, 90f, t)); + }); + this.LeftWires[0].SetPosition(1, new Vector3(1.265f, 0f, 0f)); + for (int i = 0; i < this.RightWires.Length; i++) + { + this.RightWires[i].enabled = true; + this.RightWires[i].material.SetColor("_Color", Color.yellow); + } + for (int j = 0; j < this.LeftWires.Length; j++) + { + this.LeftWires[j].material.SetColor("_Color", Color.yellow); + } + if (this.MyNormTask) + { + this.MyNormTask.NextStep(); + } + base.StartCoroutine(base.CoStartClose(0.75f)); + yield break; + } + + public void Update() + { + for (int i = 0; i < this.LeftWires.Length; i++) + { + Vector2 textureOffset = this.LeftWires[i].material.GetTextureOffset("_MainTex"); + textureOffset.x -= Time.fixedDeltaTime * 3f; + this.LeftWires[i].material.SetTextureOffset("_MainTex", textureOffset); + } + for (int j = 0; j < this.RightWires.Length; j++) + { + Vector2 textureOffset2 = this.RightWires[j].material.GetTextureOffset("_MainTex"); + textureOffset2.x += Time.fixedDeltaTime * 3f; + this.RightWires[j].material.SetTextureOffset("_MainTex", textureOffset2); + } + } +} diff --git a/Client/Assembly-CSharp/AdDataCollectScreen.cs b/Client/Assembly-CSharp/AdDataCollectScreen.cs new file mode 100644 index 0000000..35212f6 --- /dev/null +++ b/Client/Assembly-CSharp/AdDataCollectScreen.cs @@ -0,0 +1,65 @@ +using System; +using System.Collections; +using UnityEngine; + +public class AdDataCollectScreen : MonoBehaviour +{ + public ToggleButtonBehaviour PersonalizedAdsButton; + + private void Start() + { + this.UpdateButtons(); + } + + public IEnumerator Show() + { + if (!SaveManager.ShowAdsScreen.HasFlag(ShowAdsState.Accepted) && !SaveManager.BoughtNoAds) + { + base.gameObject.SetActive(true); + while (base.gameObject.activeSelf) + { + yield return null; + } + } + yield break; + } + + public void Close() + { + SaveManager.ShowAdsScreen |= ShowAdsState.Accepted; + } + + public void Update() + { + if (SaveManager.BoughtNoAds) + { + base.GetComponent<TransitionOpen>().Close(); + } + } + + public void TogglePersonalizedAd() + { + ShowAdsState showAdsState = SaveManager.ShowAdsScreen & (ShowAdsState)127; + if (showAdsState != ShowAdsState.Personalized) + { + if (showAdsState == ShowAdsState.NonPersonalized) + { + SaveManager.ShowAdsScreen = ShowAdsState.Personalized; + goto IL_34; + } + if (showAdsState == ShowAdsState.Purchased) + { + SaveManager.ShowAdsScreen = ShowAdsState.Purchased; + goto IL_34; + } + } + SaveManager.ShowAdsScreen = ShowAdsState.NonPersonalized; + IL_34: + this.UpdateButtons(); + } + + public void UpdateButtons() + { + this.PersonalizedAdsButton.UpdateText(!SaveManager.ShowAdsScreen.HasFlag(ShowAdsState.NonPersonalized)); + } +} diff --git a/Client/Assembly-CSharp/AdPlayer.cs b/Client/Assembly-CSharp/AdPlayer.cs new file mode 100644 index 0000000..92ab040 --- /dev/null +++ b/Client/Assembly-CSharp/AdPlayer.cs @@ -0,0 +1,118 @@ +using System; +using System.Collections; +using GoogleMobileAds.Api; +using InnerNet; +using UnityEngine; + +public static class AdPlayer +{ + private static InterstitialAd interstitial; + + private const string appId = "unexpected_platform"; + + private const string adUnitId = "unexpected_platform"; + + public static void ShowInterstitial(MonoBehaviour parent, bool playAgain) + { + parent.StartCoroutine(AdPlayer.CoShowAd(playAgain)); + } + + private static IEnumerator CoShowAd(bool playAgain) + { + if (playAgain) + { + yield return DestroyableSingleton<EndGameManager>.Instance.CoJoinGame(); + } + else + { + AmongUsClient.Instance.ExitGame(DisconnectReasons.ExitGame); + } + yield break; + } + + public static void RequestInterstitial() + { + try + { + MobileAds.Initialize("unexpected_platform"); + if (AdPlayer.interstitial == null) + { + AdPlayer.interstitial = new InterstitialAd("unexpected_platform"); + AdRequest adRequest = new AdRequest.Builder().Build(); + if (SaveManager.ShowAdsScreen.HasFlag(ShowAdsState.NonPersonalized)) + { + adRequest.Extras.Add("npa", "1"); + } + AdPlayer.interstitial.OnAdLoaded += AdPlayer.Interstitial_OnAdLoaded; + AdPlayer.interstitial.OnAdFailedToLoad += AdPlayer.Interstitial_OnAdFailedToLoad; + AdPlayer.interstitial.OnAdClosed += AdPlayer.Interstitial_OnAdClosed; + AdPlayer.interstitial.OnAdLeavingApplication += AdPlayer.Interstitial_OnAdLeavingApplication; + AdPlayer.interstitial.LoadAd(adRequest); + } + } + catch + { + try + { + if (AdPlayer.interstitial != null) + { + AdPlayer.interstitial.Destroy(); + } + } + catch + { + } + AdPlayer.interstitial = null; + } + } + + private static void Interstitial_OnAdLoaded(object sender, EventArgs e) + { + } + + private static void Interstitial_OnAdLeavingApplication(object sender, EventArgs e) + { + try + { + if (AdPlayer.interstitial != null) + { + AdPlayer.interstitial.Destroy(); + } + } + finally + { + AdPlayer.interstitial = null; + } + } + + private static void Interstitial_OnAdFailedToLoad(object sender, AdFailedToLoadEventArgs e) + { + try + { + if (AdPlayer.interstitial != null) + { + AdPlayer.interstitial.Destroy(); + Debug.LogError("Couldn't load ad: " + (e.Message ?? "No Message")); + } + } + finally + { + AdPlayer.interstitial = null; + } + } + + private static void Interstitial_OnAdClosed(object sender, EventArgs e) + { + try + { + if (AdPlayer.interstitial != null) + { + AdPlayer.interstitial.Destroy(); + } + } + finally + { + AdPlayer.interstitial = null; + } + } +} diff --git a/Client/Assembly-CSharp/AlignGame.cs b/Client/Assembly-CSharp/AlignGame.cs new file mode 100644 index 0000000..1ee70f0 --- /dev/null +++ b/Client/Assembly-CSharp/AlignGame.cs @@ -0,0 +1,146 @@ +using System; +using System.Collections; +using UnityEngine; + +public class AlignGame : Minigame +{ + private Controller myController = new Controller(); + + public FloatRange YRange = new FloatRange(-0.425f, 0.425f); + + public AnimationCurve curve; + + public LineRenderer centerline; + + public LineRenderer[] guidelines; + + public SpriteRenderer engine; + + public Collider2D col; + + public TextController StatusText; + + private float pulseTimer; + + public override void Begin(PlayerTask task) + { + base.Begin(task); + float value = AlignGame.FromByte(this.MyNormTask.Data[base.ConsoleId]); + bool flag = AlignGame.IsSuccess(this.MyNormTask.Data[base.ConsoleId]); + Vector3 localPosition = this.col.transform.localPosition; + localPosition.y = this.YRange.Clamp(value); + float num = this.YRange.ReverseLerp(localPosition.y); + localPosition.x = this.curve.Evaluate(num); + this.col.transform.eulerAngles = new Vector3(0f, 0f, Mathf.Lerp(20f, -20f, num)); + this.engine.transform.eulerAngles = new Vector3(0f, 0f, Mathf.Lerp(45f, -45f, num)); + this.centerline.material.SetColor("_Color", flag ? Color.green : Color.red); + this.engine.color = (flag ? Color.green : Color.red); + this.col.transform.localPosition = localPosition; + this.guidelines[0].enabled = flag; + this.guidelines[1].enabled = flag; + this.StatusText.gameObject.SetActive(flag); + } + + public void Update() + { + this.centerline.material.SetTextureOffset("_MainTex", new Vector2(Time.time, 0f)); + this.guidelines[0].material.SetTextureOffset("_MainTex", new Vector2(Time.time, 0f)); + this.guidelines[1].material.SetTextureOffset("_MainTex", new Vector2(Time.time, 0f)); + if (this.MyTask && this.MyNormTask.IsComplete) + { + return; + } + Vector3 localPosition = this.col.transform.localPosition; + bool flag = AlignGame.IsSuccess(this.MyNormTask.Data[base.ConsoleId]); + bool flag2 = AlignGame.IsSuccess(AlignGame.ToByte(localPosition.y)); + this.myController.Update(); + switch (this.myController.CheckDrag(this.col, false)) + { + case DragState.TouchStart: + this.pulseTimer = 0f; + break; + case DragState.Dragging: + if (!flag) + { + Vector2 vector = this.myController.DragPosition - base.transform.position; + float num = this.YRange.ReverseLerp(localPosition.y); + localPosition.y = this.YRange.Clamp(vector.y); + float num2 = this.YRange.ReverseLerp(localPosition.y); + localPosition.x = this.curve.Evaluate(num2); + this.col.transform.eulerAngles = new Vector3(0f, 0f, Mathf.Lerp(20f, -20f, num2)); + this.engine.transform.eulerAngles = new Vector3(0f, 0f, Mathf.Lerp(45f, -45f, num2)); + this.centerline.material.SetColor("_Color", flag2 ? Color.green : Color.red); + if (Mathf.Abs(num2 - num) > 0.001f) + { + this.pulseTimer += Time.deltaTime * 25f; + int num3 = (int)this.pulseTimer % 3; + if (num3 > 1) + { + if (num3 == 2) + { + this.engine.color = Color.clear; + } + } + else + { + this.engine.color = Color.red; + } + } + else + { + this.engine.color = Color.red; + } + } + break; + case DragState.Released: + if (!flag && flag2) + { + base.StartCoroutine(this.LockEngine()); + this.MyNormTask.Data[base.ConsoleId] = AlignGame.ToByte(localPosition.y); + this.MyNormTask.NextStep(); + base.StartCoroutine(base.CoStartClose(0.75f)); + } + break; + } + this.col.transform.localPosition = localPosition; + } + + private IEnumerator LockEngine() + { + int num; + for (int i = 0; i < 3; i = num) + { + this.guidelines[0].enabled = true; + this.guidelines[1].enabled = true; + yield return new WaitForSeconds(0.1f); + this.guidelines[0].enabled = false; + this.guidelines[1].enabled = false; + yield return new WaitForSeconds(0.1f); + num = i + 1; + } + this.StatusText.gameObject.SetActive(true); + Color green = new Color(0f, 0.7f, 0f); + yield return new WaitForLerp(1f, delegate(float t) + { + this.engine.color = Color.Lerp(Color.white, green, t); + }); + this.guidelines[0].enabled = true; + this.guidelines[1].enabled = true; + yield break; + } + + public static float FromByte(byte b) + { + return (float)b * 0.025f - 3f; + } + + public static byte ToByte(float y) + { + return (byte)((y + 3f) / 0.025f); + } + + public static bool IsSuccess(byte b) + { + return Mathf.Abs(AlignGame.FromByte(b)) <= 0.05f; + } +} diff --git a/Client/Assembly-CSharp/AlphaBlink.cs b/Client/Assembly-CSharp/AlphaBlink.cs new file mode 100644 index 0000000..4813ba6 --- /dev/null +++ b/Client/Assembly-CSharp/AlphaBlink.cs @@ -0,0 +1,44 @@ +using System; +using UnityEngine; + +public class AlphaBlink : MonoBehaviour +{ + public float Period = 1f; + + public float Ratio = 0.5f; + + private SpriteRenderer rend; + + private MeshRenderer mesh; + + public FloatRange AlphaRange = new FloatRange(0.2f, 0.5f); + + public Color baseColor = Color.white; + + public void SetColor(Color c) + { + this.Start(); + this.baseColor = c; + this.Update(); + } + + private void Start() + { + this.mesh = base.GetComponent<MeshRenderer>(); + this.rend = base.GetComponent<SpriteRenderer>(); + } + + public void Update() + { + float num = Time.time % this.Period / this.Period; + num = (float)((num < this.Ratio) ? 1 : 0); + if (this.rend) + { + this.rend.color = new Color(this.baseColor.r, this.baseColor.g, this.baseColor.b, this.AlphaRange.Lerp(num)); + } + if (this.mesh) + { + this.mesh.material.SetColor("_Color", new Color(this.baseColor.r, this.baseColor.g, this.baseColor.b, this.AlphaRange.Lerp(num))); + } + } +} diff --git a/Client/Assembly-CSharp/AlphaPulse.cs b/Client/Assembly-CSharp/AlphaPulse.cs new file mode 100644 index 0000000..e28579e --- /dev/null +++ b/Client/Assembly-CSharp/AlphaPulse.cs @@ -0,0 +1,43 @@ +using System; +using UnityEngine; + +public class AlphaPulse : MonoBehaviour +{ + public float Offset = 1f; + + public float Duration = 2.5f; + + private SpriteRenderer rend; + + private MeshRenderer mesh; + + public FloatRange AlphaRange = new FloatRange(0.2f, 0.5f); + + public Color baseColor = Color.white; + + public void SetColor(Color c) + { + this.Start(); + this.baseColor = c; + this.Update(); + } + + private void Start() + { + this.mesh = base.GetComponent<MeshRenderer>(); + this.rend = base.GetComponent<SpriteRenderer>(); + } + + public void Update() + { + float v = Mathf.Abs(Mathf.Cos((this.Offset + Time.time) * 3.1415927f / this.Duration)); + if (this.rend) + { + this.rend.color = new Color(this.baseColor.r, this.baseColor.g, this.baseColor.b, this.AlphaRange.Lerp(v)); + } + if (this.mesh) + { + this.mesh.material.SetColor("_Color", new Color(this.baseColor.r, this.baseColor.g, this.baseColor.b, this.AlphaRange.Lerp(v))); + } + } +} diff --git a/Client/Assembly-CSharp/AmongUsClient.cs b/Client/Assembly-CSharp/AmongUsClient.cs new file mode 100644 index 0000000..5726992 --- /dev/null +++ b/Client/Assembly-CSharp/AmongUsClient.cs @@ -0,0 +1,497 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using Assets.CoreScripts; +using InnerNet; +using UnityEngine; +using UnityEngine.SceneManagement; + +public class AmongUsClient : InnerNetClient +{ + public static AmongUsClient Instance; + + public GameModes GameMode; + + public string OnlineScene; + + public string MainMenuScene; + + public GameData GameDataPrefab; + + public PlayerControl PlayerPrefab; + + public List<ShipStatus> ShipPrefabs; + + public float SpawnRadius = 1.75f; + + public DiscoveryState discoverState; + + public List<IDisconnectHandler> DisconnectHandlers = new List<IDisconnectHandler>(); + + public List<IGameListHandler> GameListHandlers = new List<IGameListHandler>(); + + public void Awake() + { + if (AmongUsClient.Instance) + { + if (AmongUsClient.Instance != this) + { + UnityEngine.Object.Destroy(base.gameObject); + } + return; + } + AmongUsClient.Instance = this; + UnityEngine.Object.DontDestroyOnLoad(base.gameObject); + Application.targetFrameRate = 30; + } + + protected override byte[] GetConnectionData() + { + byte[] result; + using (MemoryStream memoryStream = new MemoryStream()) + { + using (BinaryWriter binaryWriter = new BinaryWriter(memoryStream)) + { + binaryWriter.Write(Constants.GetBroadcastVersion()); + binaryWriter.Write(SaveManager.PlayerName); + binaryWriter.Flush(); + result = memoryStream.ToArray(); + } + } + return result; + } + + public void StartGame() + { + base.SendStartGame(); + this.discoverState = DiscoveryState.Off; + } + + public void ExitGame(DisconnectReasons reason = DisconnectReasons.ExitGame) + { + if (DestroyableSingleton<WaitForHostPopup>.InstanceExists) + { + DestroyableSingleton<WaitForHostPopup>.Instance.Hide(); + } + SoundManager.Instance.StopAllSound(); + this.discoverState = DiscoveryState.Off; + this.DisconnectHandlers.Clear(); + base.DisconnectInternal(reason, null); + SceneManager.LoadScene(this.MainMenuScene); + } + + protected override void OnGetGameList(int totalGames, List<GameListing> availableGames) + { + for (int i = 0; i < this.GameListHandlers.Count; i++) + { + try + { + this.GameListHandlers[i].HandleList(totalGames, availableGames); + } + catch + { + } + } + } + + protected override void OnGameCreated(string gameIdString) + { + } + + protected override void OnWaitForHost(string gameIdString) + { + if (this.GameState != InnerNetClient.GameStates.Joined) + { + Debug.Log("Waiting for host: " + gameIdString); + if (DestroyableSingleton<WaitForHostPopup>.InstanceExists) + { + DestroyableSingleton<WaitForHostPopup>.Instance.Show(); + } + } + } + + protected override void OnStartGame() + { + Debug.Log("Received game start: " + base.AmHost.ToString()); + base.StartCoroutine(this.CoStartGame()); + } + + private IEnumerator CoStartGame() + { + yield return null; + while (!DestroyableSingleton<HudManager>.InstanceExists) + { + yield return null; + } + while (!PlayerControl.LocalPlayer) + { + yield return null; + } + PlayerControl.LocalPlayer.moveable = false; + CustomPlayerMenu customPlayerMenu = UnityEngine.Object.FindObjectOfType<CustomPlayerMenu>(); + if (customPlayerMenu) + { + customPlayerMenu.Close(false); + } + if (DestroyableSingleton<GameStartManager>.InstanceExists) + { + this.DisconnectHandlers.Remove(DestroyableSingleton<GameStartManager>.Instance); + UnityEngine.Object.Destroy(DestroyableSingleton<GameStartManager>.Instance.gameObject); + } + if (DestroyableSingleton<DiscordManager>.InstanceExists) + { + DestroyableSingleton<DiscordManager>.Instance.SetPlayingGame(); + } + yield return DestroyableSingleton<HudManager>.Instance.CoFadeFullScreen(Color.clear, Color.black, 0.2f); + while (!GameData.Instance) + { + yield return null; + } + while (!base.AmHost) + { + while (PlayerControl.LocalPlayer.Data == null && !base.AmHost) + { + yield return null; + } + if (!base.AmHost) + { + base.SendClientReady(); + while (!ShipStatus.Instance && !base.AmHost) + { + yield return null; + } + if (!base.AmHost) + { + IL_324: + for (int i = 0; i < GameData.Instance.PlayerCount; i++) + { + PlayerControl @object = GameData.Instance.AllPlayers[i].Object; + if (@object) + { + @object.moveable = true; + @object.NetTransform.enabled = true; + @object.MyPhysics.enabled = true; + @object.MyPhysics.Awake(); + @object.MyPhysics.ResetAnim(true); + @object.Collider.enabled = true; + Vector2 spawnLocation = ShipStatus.Instance.GetSpawnLocation(i, GameData.Instance.PlayerCount); + @object.NetTransform.SnapTo(spawnLocation); + } + } + yield break; + } + } + } + GameData.Instance.SetDirty(); + base.SendClientReady(); + float timer = 0f; + for (;;) + { + bool stopWaiting = true; + List<ClientData> allClients = this.allClients; + lock (allClients) + { + for (int j = 0; j < this.allClients.Count; j++) + { + ClientData clientData = this.allClients[j]; + if (!clientData.IsReady) + { + if (timer < 5f) + { + stopWaiting = false; + } + else + { + base.SendLateRejection(clientData.Id, DisconnectReasons.Error); + clientData.IsReady = true; + this.OnPlayerLeft(clientData, DisconnectReasons.Error); + } + } + } + } + yield return null; + if (stopWaiting) + { + break; + } + timer += Time.deltaTime; + } + if (LobbyBehaviour.Instance) + { + LobbyBehaviour.Instance.Despawn(); + } + if (!ShipStatus.Instance) + { + int index = Mathf.Clamp((int)PlayerControl.GameOptions.MapId, 0, this.ShipPrefabs.Count - 1); + ShipStatus.Instance = UnityEngine.Object.Instantiate<ShipStatus>(this.ShipPrefabs[index]); + } + base.Spawn(ShipStatus.Instance, -2, SpawnFlags.None); + ShipStatus.Instance.SelectInfected(); + ShipStatus.Instance.Begin(); + goto IL_324; + } + + protected override void OnBecomeHost() + { + ClientData clientData = base.FindClientById(this.ClientId); + if (!clientData.Character) + { + this.OnGameJoined(null, clientData); + } + Debug.Log("Became Host"); + base.RemoveUnownedObjects(); + } + + protected override void OnGameEnd(GameOverReason gameOverReason, bool showAd) + { + StatsManager.Instance.BanPoints -= 1.5f; + StatsManager.Instance.LastGameStarted = DateTime.MinValue; + this.DisconnectHandlers.Clear(); + if (Minigame.Instance) + { + Minigame.Instance.Close(); + Minigame.Instance.Close(); + } + try + { + if (SaveManager.SendTelemetry) + { + DestroyableSingleton<Telemetry>.Instance.EndGame(gameOverReason); + } + } + catch + { + } + TempData.EndReason = gameOverReason; + TempData.showAd = showAd; + bool flag = TempData.DidHumansWin(gameOverReason); + TempData.winners = new List<WinningPlayerData>(); + for (int i = 0; i < GameData.Instance.PlayerCount; i++) + { + GameData.PlayerInfo playerInfo = GameData.Instance.AllPlayers[i]; + if (gameOverReason == GameOverReason.HumansDisconnect || gameOverReason == GameOverReason.ImpostorDisconnect || flag != playerInfo.IsImpostor) + { + TempData.winners.Add(new WinningPlayerData(playerInfo)); + } + } + base.StartCoroutine(this.CoEndGame()); + } + + public IEnumerator CoEndGame() + { + yield return DestroyableSingleton<HudManager>.Instance.CoFadeFullScreen(Color.clear, Color.black, 0.5f); + SceneManager.LoadScene("EndGame"); + yield break; + } + + protected override void OnPlayerJoined(ClientData data) + { + if (DestroyableSingleton<GameStartManager>.InstanceExists) + { + DestroyableSingleton<GameStartManager>.Instance.ResetStartState(); + } + if (base.AmHost && data.InScene) + { + this.CreatePlayer(data); + } + } + + protected override void OnGameJoined(string gameIdString, ClientData data) + { + if (DestroyableSingleton<WaitForHostPopup>.InstanceExists) + { + DestroyableSingleton<WaitForHostPopup>.Instance.Hide(); + } + if (!string.IsNullOrWhiteSpace(this.OnlineScene)) + { + SceneManager.LoadScene(this.OnlineScene); + } + } + + protected override void OnPlayerLeft(ClientData data, DisconnectReasons reason) + { + if (DestroyableSingleton<GameStartManager>.InstanceExists) + { + DestroyableSingleton<GameStartManager>.Instance.ResetStartState(); + } + PlayerControl character = data.Character; + if (character) + { + for (int i = this.DisconnectHandlers.Count - 1; i > -1; i--) + { + try + { + this.DisconnectHandlers[i].HandleDisconnect(character, reason); + } + catch (Exception exception) + { + Debug.LogException(exception); + this.DisconnectHandlers.RemoveAt(i); + } + } + UnityEngine.Object.Destroy(character.gameObject); + } + else + { + Debug.LogWarning(string.Format("A player without a character disconnected: {0}: {1}", data.Id, data.InScene)); + for (int j = this.DisconnectHandlers.Count - 1; j > -1; j--) + { + try + { + this.DisconnectHandlers[j].HandleDisconnect(); + } + catch (Exception exception2) + { + Debug.LogException(exception2); + this.DisconnectHandlers.RemoveAt(j); + } + } + } + if (base.AmHost) + { + GameOptionsData gameOptions = PlayerControl.GameOptions; + if (gameOptions != null && gameOptions.isDefaults) + { + PlayerControl.GameOptions.SetRecommendations(GameData.Instance.PlayerCount, AmongUsClient.Instance.GameMode); + PlayerControl localPlayer = PlayerControl.LocalPlayer; + if (localPlayer != null) + { + localPlayer.RpcSyncSettings(PlayerControl.GameOptions); + } + } + } + base.RemoveUnownedObjects(); + } + + protected override void OnDisconnected() + { + SceneManager.LoadScene(this.MainMenuScene); + } + + //c 切换场景 + protected override void OnPlayerChangedScene(ClientData client, string currentScene) + { + client.InScene = true; + if (!base.AmHost) + { + return; + } + if (currentScene.Equals("Tutorial")) + { + GameData.Instance = UnityEngine.Object.Instantiate<GameData>(this.GameDataPrefab); + base.Spawn(GameData.Instance, -2, SpawnFlags.None); + base.Spawn(UnityEngine.Object.Instantiate<ShipStatus>(this.ShipPrefabs.Last<ShipStatus>()), -2, SpawnFlags.None); + this.CreatePlayer(client); + return; + } + if (currentScene.Equals("OnlineGame")) + { + if (client.Id != this.ClientId) + { + base.SendInitialData(client.Id); + } + else + { + if (this.GameMode == GameModes.LocalGame) + { + base.StartCoroutine(this.CoBroadcastManager()); + } + if (!GameData.Instance) + { + GameData.Instance = UnityEngine.Object.Instantiate<GameData>(this.GameDataPrefab); + base.Spawn(GameData.Instance, -2, SpawnFlags.None); + } + } + this.CreatePlayer(client); + } + } + + [ContextMenu("Spawn Tester")] + private void SpawnTester() + { + sbyte availableId = GameData.Instance.GetAvailableId(); + Vector2 v = Vector2.up.Rotate((float)availableId * (360f / (float)Palette.PlayerColors.Length)) * this.SpawnRadius; + PlayerControl playerControl = UnityEngine.Object.Instantiate<PlayerControl>(this.PlayerPrefab, v, Quaternion.identity); + playerControl.PlayerId = (byte)availableId; + GameData.Instance.AddPlayer(playerControl); + base.Spawn(playerControl, -2, SpawnFlags.None); + playerControl.CmdCheckName("Test"); + playerControl.CmdCheckColor(0); + if (DestroyableSingleton<HatManager>.InstanceExists) + { + playerControl.RpcSetHat((uint)((int)availableId % DestroyableSingleton<HatManager>.Instance.AllHats.Count)); + playerControl.RpcSetSkin((uint)((int)availableId % DestroyableSingleton<HatManager>.Instance.AllSkins.Count)); + playerControl.RpcSetPet((uint)availableId); + } + } + + private void CreatePlayer(ClientData clientData) + { + if (clientData.Character) + { + return; + } + if (!base.AmHost) + { + Debug.Log("Waiting for host to make my player"); + return; + } + if (!GameData.Instance) + { + GameData.Instance = UnityEngine.Object.Instantiate<GameData>(this.GameDataPrefab); + base.Spawn(GameData.Instance, -2, SpawnFlags.None); + } + sbyte availableId = GameData.Instance.GetAvailableId(); + if (availableId == -1) + { + base.SendLateRejection(clientData.Id, DisconnectReasons.GameFull); + Debug.Log("Overfilled room."); + return; + } + Vector2 v = Vector2.zero; + if (ShipStatus.Instance) + { + v = ShipStatus.Instance.GetSpawnLocation((int)availableId, Palette.PlayerColors.Length); + } + else if (DestroyableSingleton<TutorialManager>.InstanceExists) + { + v = new Vector2(-1.9f, 3.25f); + } + Debug.Log(string.Format("Spawned player {0} for client {1}", availableId, clientData.Id)); + PlayerControl playerControl = UnityEngine.Object.Instantiate<PlayerControl>(this.PlayerPrefab, v, Quaternion.identity); + playerControl.PlayerId = (byte)availableId; + clientData.Character = playerControl; + base.Spawn(playerControl, clientData.Id, SpawnFlags.IsClientCharacter); + GameData.Instance.AddPlayer(playerControl); + if (PlayerControl.GameOptions.isDefaults) + { + PlayerControl.GameOptions.SetRecommendations(GameData.Instance.PlayerCount, AmongUsClient.Instance.GameMode); + } + playerControl.RpcSyncSettings(PlayerControl.GameOptions); + } + + private IEnumerator CoBroadcastManager() + { + while (!GameData.Instance) + { + yield return null; + } + int lastPlayerCount = 0; + this.discoverState = DiscoveryState.Broadcast; + while (this.discoverState == DiscoveryState.Broadcast) + { + if (lastPlayerCount != GameData.Instance.PlayerCount) + { + lastPlayerCount = GameData.Instance.PlayerCount; + string data = string.Format("{0}~Open~{1}~", SaveManager.PlayerName, GameData.Instance.PlayerCount); + DestroyableSingleton<InnerDiscover>.Instance.Interval = 1f; + DestroyableSingleton<InnerDiscover>.Instance.StartAsServer(data); + } + yield return null; + } + DestroyableSingleton<InnerDiscover>.Instance.StopServer(); + yield break; + } +} diff --git a/Client/Assembly-CSharp/AmongUsProduct.cs b/Client/Assembly-CSharp/AmongUsProduct.cs new file mode 100644 index 0000000..29e6d2d --- /dev/null +++ b/Client/Assembly-CSharp/AmongUsProduct.cs @@ -0,0 +1,9 @@ +using System; + +[Serializable] +public struct AmongUsProduct +{ + public string ProductId; + + public HatBehaviour HatData; +} diff --git a/Client/Assembly-CSharp/Announcement.cs b/Client/Assembly-CSharp/Announcement.cs new file mode 100644 index 0000000..25d3a48 --- /dev/null +++ b/Client/Assembly-CSharp/Announcement.cs @@ -0,0 +1,10 @@ +using System; + +public struct Announcement +{ + public int DateFetched; + + public uint Id; + + public string AnnounceText; +} diff --git a/Client/Assembly-CSharp/AnnouncementPopUp.cs b/Client/Assembly-CSharp/AnnouncementPopUp.cs new file mode 100644 index 0000000..42b96b0 --- /dev/null +++ b/Client/Assembly-CSharp/AnnouncementPopUp.cs @@ -0,0 +1,154 @@ +using System; +using System.Collections; +using System.Net; +using Hazel; +using Hazel.Udp; +using UnityEngine; + +public class AnnouncementPopUp : MonoBehaviour +{ + private const uint AnnouncementVersion = 1U; + + private UdpClientConnection connection; + + private static AnnouncementPopUp.AnnounceState AskedForUpdate; + + public TextRenderer AnnounceText; + + private Announcement announcementUpdate; + + private enum AnnounceState + { + Fetching, + Failed, + Success, + Cached + } + + private static bool IsSuccess(AnnouncementPopUp.AnnounceState state) + { + return state == AnnouncementPopUp.AnnounceState.Success || state == AnnouncementPopUp.AnnounceState.Cached; + } + + public IEnumerator Init() + { + if (AnnouncementPopUp.AskedForUpdate != AnnouncementPopUp.AnnounceState.Fetching) + { + yield break; + } + yield return DestroyableSingleton<ServerManager>.Instance.WaitForServers(); + this.connection = new UdpClientConnection(new IPEndPoint(IPAddress.Parse(DestroyableSingleton<ServerManager>.Instance.OnlineNetAddress), 22024), IPMode.IPv4); + this.connection.DataReceived += this.Connection_DataReceived; + this.connection.Disconnected += this.Connection_Disconnected; + Announcement lastAnnouncement = SaveManager.LastAnnouncement; + try + { + MessageWriter messageWriter = MessageWriter.Get(SendOption.None); + messageWriter.WritePacked(1U); + messageWriter.WritePacked(lastAnnouncement.Id); + this.connection.ConnectAsync(messageWriter.ToByteArray(true), 5000); + messageWriter.Recycle(); + yield break; + } + catch + { + AnnouncementPopUp.AskedForUpdate = AnnouncementPopUp.AnnounceState.Failed; + yield break; + } + yield break; + } + + private void Connection_Disconnected(object sender, DisconnectedEventArgs e) + { + AnnouncementPopUp.AskedForUpdate = AnnouncementPopUp.AnnounceState.Failed; + this.connection.Dispose(); + this.connection = null; + } + + private void Connection_DataReceived(DataReceivedEventArgs e) + { + MessageReader message = e.Message; + try + { + if (message.Length > 4) + { + this.announcementUpdate = default(Announcement); + this.announcementUpdate.DateFetched = DateTime.UtcNow.DayOfYear; + this.announcementUpdate.Id = message.ReadPackedUInt32(); + this.announcementUpdate.AnnounceText = message.ReadString(); + AnnouncementPopUp.AskedForUpdate = AnnouncementPopUp.AnnounceState.Success; + } + else + { + AnnouncementPopUp.AskedForUpdate = AnnouncementPopUp.AnnounceState.Cached; + } + } + finally + { + message.Recycle(); + } + try + { + this.connection.Dispose(); + this.connection = null; + } + catch + { + } + } + + public IEnumerator Show() + { + float timer = 0f; + while (AnnouncementPopUp.AskedForUpdate == AnnouncementPopUp.AnnounceState.Fetching && this.connection != null && timer < 5f) + { + timer += Time.deltaTime; + yield return null; + } + if (!AnnouncementPopUp.IsSuccess(AnnouncementPopUp.AskedForUpdate)) + { + Announcement lastAnnouncement = SaveManager.LastAnnouncement; + if (lastAnnouncement.Id == 0U) + { + this.AnnounceText.Text = "Couldn't get announcement."; + } + else + { + this.AnnounceText.Text = "Couldn't get announcement. Last Known:\r\n" + lastAnnouncement.AnnounceText; + } + } + else if (this.announcementUpdate.Id != SaveManager.LastAnnouncement.Id) + { + if (AnnouncementPopUp.AskedForUpdate != AnnouncementPopUp.AnnounceState.Cached) + { + base.gameObject.SetActive(true); + } + if (this.announcementUpdate.Id == 0U) + { + this.announcementUpdate = SaveManager.LastAnnouncement; + this.announcementUpdate.DateFetched = DateTime.UtcNow.DayOfYear; + } + SaveManager.LastAnnouncement = this.announcementUpdate; + this.AnnounceText.Text = this.announcementUpdate.AnnounceText; + } + while (base.gameObject.activeSelf) + { + yield return null; + } + yield break; + } + + public void Close() + { + base.gameObject.SetActive(false); + } + + private void OnDestroy() + { + if (this.connection != null) + { + this.connection.Dispose(); + this.connection = null; + } + } +} diff --git a/Client/Assembly-CSharp/ArrowBehaviour.cs b/Client/Assembly-CSharp/ArrowBehaviour.cs new file mode 100644 index 0000000..8e9365c --- /dev/null +++ b/Client/Assembly-CSharp/ArrowBehaviour.cs @@ -0,0 +1,47 @@ +using System; +using UnityEngine; + +public class ArrowBehaviour : MonoBehaviour +{ + public Vector3 target; + + public float perc = 0.925f; + + [HideInInspector] + public SpriteRenderer image; + + public void Awake() + { + this.image = base.GetComponent<SpriteRenderer>(); + } + + public void Update() + { + Camera main = Camera.main; + Vector2 vector = this.target - main.transform.position; + float num = vector.magnitude / (main.orthographicSize * this.perc); + this.image.enabled = ((double)num > 0.3); + Vector2 vector2 = main.WorldToViewportPoint(this.target); + if (this.Between(vector2.x, 0f, 1f) && this.Between(vector2.y, 0f, 1f)) + { + base.transform.position = this.target - vector.normalized * 0.6f; + float num2 = Mathf.Clamp(num, 0f, 1f); + base.transform.localScale = new Vector3(num2, num2, num2); + } + else + { + Vector2 vector3 = new Vector2(Mathf.Clamp(vector2.x * 2f - 1f, -1f, 1f), Mathf.Clamp(vector2.y * 2f - 1f, -1f, 1f)); + float orthographicSize = main.orthographicSize; + float num3 = main.orthographicSize * main.aspect; + Vector3 b = new Vector3(Mathf.LerpUnclamped(0f, num3 * 0.88f, vector3.x), Mathf.LerpUnclamped(0f, orthographicSize * 0.79f, vector3.y), 0f); + base.transform.position = main.transform.position + b; + base.transform.localScale = Vector3.one; + } + base.transform.LookAt2d(this.target); + } + + private bool Between(float value, float min, float max) + { + return value > min && value < max; + } +} diff --git a/Client/Assembly-CSharp/AspectPosition.cs b/Client/Assembly-CSharp/AspectPosition.cs new file mode 100644 index 0000000..60654df --- /dev/null +++ b/Client/Assembly-CSharp/AspectPosition.cs @@ -0,0 +1,86 @@ +using System; +using UnityEngine; + +public class AspectPosition : MonoBehaviour +{ + public Camera parentCam; + + private const int LeftFlag = 1; + + private const int RightFlag = 2; + + private const int BottomFlag = 4; + + private const int TopFlag = 8; + + public Vector3 DistanceFromEdge; + + public AspectPosition.EdgeAlignments Alignment; + + public enum EdgeAlignments + { + RightBottom = 6, + LeftBottom = 5, + RightTop = 10, + Left = 1, + Right, + Top = 8, + Bottom = 4, + LeftTop = 9 + } + + private void OnEnable() + { + this.AdjustPosition(); + ResolutionManager.ResolutionChanged += this.AdjustPosition; + } + + private void OnDisable() + { + ResolutionManager.ResolutionChanged -= this.AdjustPosition; + } + + public void AdjustPosition() + { + Camera camera = this.parentCam ? this.parentCam : Camera.main; + float aspect = camera.aspect; + this.AdjustPosition(camera.aspect); + } + + public void AdjustPosition(float aspect) + { + float orthographicSize = (this.parentCam ? this.parentCam : Camera.main).orthographicSize; + base.transform.localPosition = AspectPosition.ComputePosition(this.Alignment, this.DistanceFromEdge, orthographicSize, aspect); + } + + public static Vector3 ComputePosition(AspectPosition.EdgeAlignments alignment, Vector3 relativePos) + { + Camera main = Camera.main; + float aspect = main.aspect; + float orthographicSize = main.orthographicSize; + return AspectPosition.ComputePosition(alignment, relativePos, orthographicSize, aspect); + } + + public static Vector3 ComputePosition(AspectPosition.EdgeAlignments alignment, Vector3 relativePos, float cHeight, float aspect) + { + float num = cHeight * aspect; + Vector3 vector = relativePos; + if ((alignment & AspectPosition.EdgeAlignments.Left) != (AspectPosition.EdgeAlignments)0) + { + vector.x -= num; + } + else if ((alignment & AspectPosition.EdgeAlignments.Right) != (AspectPosition.EdgeAlignments)0) + { + vector.x = num - vector.x; + } + if ((alignment & AspectPosition.EdgeAlignments.Bottom) != (AspectPosition.EdgeAlignments)0) + { + vector.y -= cHeight; + } + else if ((alignment & AspectPosition.EdgeAlignments.Top) != (AspectPosition.EdgeAlignments)0) + { + vector.y = cHeight - vector.y; + } + return vector; + } +} diff --git a/Client/Assembly-CSharp/AspectSize.cs b/Client/Assembly-CSharp/AspectSize.cs new file mode 100644 index 0000000..c0c8fe8 --- /dev/null +++ b/Client/Assembly-CSharp/AspectSize.cs @@ -0,0 +1,32 @@ +using System; +using UnityEngine; + +public class AspectSize : MonoBehaviour +{ + public Sprite Background; + + public SpriteRenderer Renderer; + + public float PercentWidth = 0.95f; + + public void OnEnable() + { + Camera main = Camera.main; + float num = main.orthographicSize * main.aspect; + float num2 = (this.Background ? this.Background : this.Renderer.sprite).bounds.size.x / 2f; + float num3 = num / num2 * this.PercentWidth; + if (num3 < 1f) + { + base.transform.localScale = new Vector3(num3, num3, num3); + } + } + + public static float CalculateSize(Vector3 parentPos, Sprite sprite) + { + Camera main = Camera.main; + float num = main.orthographicSize * main.aspect + parentPos.x; + float x = sprite.bounds.size.x; + float b = num / x * 0.98f; + return Mathf.Min(1f, b); + } +} diff --git a/Client/Assembly-CSharp/Assembly-CSharp.csproj b/Client/Assembly-CSharp/Assembly-CSharp.csproj new file mode 100644 index 0000000..a97f617 --- /dev/null +++ b/Client/Assembly-CSharp/Assembly-CSharp.csproj @@ -0,0 +1,464 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" /> + <PropertyGroup> + <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> + <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> + <ProjectGuid>{4D37C17B-28D8-4D17-A439-F712A18E4C22}</ProjectGuid> + <OutputType>Library</OutputType> + <RootNamespace>Assembly-CSharp</RootNamespace> + <AssemblyName>Assembly-CSharp</AssemblyName> + <TargetFrameworkVersion>v4.0</TargetFrameworkVersion> + <FileAlignment>512</FileAlignment> + </PropertyGroup> + <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> + <PlatformTarget>AnyCPU</PlatformTarget> + <DebugSymbols>true</DebugSymbols> + <DebugType>full</DebugType> + <Optimize>false</Optimize> + <OutputPath>bin\Debug\</OutputPath> + <DefineConstants>DEBUG;TRACE</DefineConstants> + <ErrorReport>prompt</ErrorReport> + <WarningLevel>4</WarningLevel> + </PropertyGroup> + <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> + <PlatformTarget>AnyCPU</PlatformTarget> + <DebugType>pdbonly</DebugType> + <Optimize>true</Optimize> + <OutputPath>bin\Release\</OutputPath> + <DefineConstants>TRACE</DefineConstants> + <ErrorReport>prompt</ErrorReport> + <WarningLevel>4</WarningLevel> + </PropertyGroup> + <ItemGroup> + <Reference Include="Assembly-CSharp-firstpass"> + <HintPath>..\..\..\Program Files (x86)\Steam\steamapps\common\Among Us\Among Us_Data\Managed\Assembly-CSharp-firstpass.dll</HintPath> + </Reference> + <Reference Include="Hazel"> + <HintPath>..\..\..\Program Files (x86)\Steam\steamapps\common\Among Us\Among Us_Data\Managed\Hazel.dll</HintPath> + </Reference> + <Reference Include="System"> + <HintPath>..\..\..\Program Files (x86)\Steam\steamapps\common\Among Us\Among Us_Data\Managed\System.dll</HintPath> + </Reference> + <Reference Include="System.Core"> + <HintPath>..\..\..\Program Files (x86)\Steam\steamapps\common\Among Us\Among Us_Data\Managed\System.Core.dll</HintPath> + </Reference> + <Reference Include="UnityEngine.AnimationModule"> + <HintPath>..\..\..\Program Files (x86)\Steam\steamapps\common\Among Us\Among Us_Data\Managed\UnityEngine.AnimationModule.dll</HintPath> + </Reference> + <Reference Include="UnityEngine.AudioModule"> + <HintPath>..\..\..\Program Files (x86)\Steam\steamapps\common\Among Us\Among Us_Data\Managed\UnityEngine.AudioModule.dll</HintPath> + </Reference> + <Reference Include="UnityEngine.CoreModule"> + <HintPath>..\..\..\Program Files (x86)\Steam\steamapps\common\Among Us\Among Us_Data\Managed\UnityEngine.CoreModule.dll</HintPath> + </Reference> + <Reference Include="UnityEngine.ImageConversionModule"> + <HintPath>..\..\..\Program Files (x86)\Steam\steamapps\common\Among Us\Among Us_Data\Managed\UnityEngine.ImageConversionModule.dll</HintPath> + </Reference> + <Reference Include="UnityEngine.ParticleSystemModule"> + <HintPath>..\..\..\Program Files (x86)\Steam\steamapps\common\Among Us\Among Us_Data\Managed\UnityEngine.ParticleSystemModule.dll</HintPath> + </Reference> + <Reference Include="UnityEngine.Physics2DModule"> + <HintPath>..\..\..\Program Files (x86)\Steam\steamapps\common\Among Us\Among Us_Data\Managed\UnityEngine.Physics2DModule.dll</HintPath> + </Reference> + <Reference Include="UnityEngine.Purchasing"> + <HintPath>..\..\..\Program Files (x86)\Steam\steamapps\common\Among Us\Among Us_Data\Managed\UnityEngine.Purchasing.dll</HintPath> + </Reference> + <Reference Include="UnityEngine.ScreenCaptureModule"> + <HintPath>..\..\..\Program Files (x86)\Steam\steamapps\common\Among Us\Among Us_Data\Managed\UnityEngine.ScreenCaptureModule.dll</HintPath> + </Reference> + <Reference Include="UnityEngine.SpriteMaskModule"> + <HintPath>..\..\..\Program Files (x86)\Steam\steamapps\common\Among Us\Among Us_Data\Managed\UnityEngine.SpriteMaskModule.dll</HintPath> + </Reference> + <Reference Include="UnityEngine.UI"> + <HintPath>..\..\..\Program Files (x86)\Steam\steamapps\common\Among Us\Among Us_Data\Managed\UnityEngine.UI.dll</HintPath> + </Reference> + <Reference Include="UnityEngine.UnityAnalyticsModule"> + <HintPath>..\..\..\Program Files (x86)\Steam\steamapps\common\Among Us\Among Us_Data\Managed\UnityEngine.UnityAnalyticsModule.dll</HintPath> + </Reference> + </ItemGroup> + <ItemGroup> + <AppDesigner Include="Properties\" /> + </ItemGroup> + <ItemGroup> + <Compile Include="AcceptDivertPowerGame.cs" /> + <Compile Include="AdDataCollectScreen.cs" /> + <Compile Include="AdPlayer.cs" /> + <Compile Include="AlignGame.cs" /> + <Compile Include="AlphaBlink.cs" /> + <Compile Include="AlphaPulse.cs" /> + <Compile Include="AmongUsClient.cs" /> + <Compile Include="AmongUsProduct.cs" /> + <Compile Include="Announcement.cs" /> + <Compile Include="AnnouncementPopUp.cs" /> + <Compile Include="ArrowBehaviour.cs" /> + <Compile Include="AspectPosition.cs" /> + <Compile Include="AspectSize.cs" /> + <Compile Include="Assets\CoreScripts\Telemetry.cs" /> + <Compile Include="Asteroid.cs" /> + <Compile Include="AutoOpenDoor.cs" /> + <Compile Include="BanButton.cs" /> + <Compile Include="BanMenu.cs" /> + <Compile Include="BlockedWords.cs" /> + <Compile Include="BoolRange.cs" /> + <Compile Include="ButtonBehavior.cs" /> + <Compile Include="ButtonRolloverHandler.cs" /> + <Compile Include="CardSlideGame.cs" /> + <Compile Include="ChainBehaviour.cs" /> + <Compile Include="ChatBubble.cs" /> + <Compile Include="ChatController.cs" /> + <Compile Include="ChatNoteTypes.cs" /> + <Compile Include="CloudGenerator.cs" /> + <Compile Include="ColorChip.cs" /> + <Compile Include="ConditionalHide.cs" /> + <Compile Include="ConditionalStore.cs" /> + <Compile Include="Console.cs" /> + <Compile Include="Constants.cs" /> + <Compile Include="Controller.cs" /> + <Compile Include="CooldownHelpers.cs" /> + <Compile Include="CounterArea.cs" /> + <Compile Include="CourseMinigame.cs" /> + <Compile Include="CourseStarBehaviour.cs" /> + <Compile Include="CreateGameOptions.cs" /> + <Compile Include="CreateOptionsPicker.cs" /> + <Compile Include="CreateStoreButton.cs" /> + <Compile Include="CrewVisualizer.cs" /> + <Compile Include="CrossFadeImages.cs" /> + <Compile Include="CrossFader.cs" /> + <Compile Include="CrystalBehaviour.cs" /> + <Compile Include="CrystalMinigame.cs" /> + <Compile Include="CustomNetworkTransform.cs" /> + <Compile Include="CustomPlayerMenu.cs" /> + <Compile Include="DataCollectScreen.cs" /> + <Compile Include="DeadBody.cs" /> + <Compile Include="DeathReason.cs" /> + <Compile Include="DeconSystem.cs" /> + <Compile Include="DefaultPool.cs" /> + <Compile Include="DemoKeyboardStick.cs" /> + <Compile Include="DestroyableSingleton.cs" /> + <Compile Include="DialBehaviour.cs" /> + <Compile Include="DialogueBox.cs" /> + <Compile Include="DisconnectPopup.cs" /> + <Compile Include="DiscordManager.cs" /> + <Compile Include="DiscoveryState.cs" /> + <Compile Include="DiscussBehaviour.cs" /> + <Compile Include="DivertPowerMetagame.cs" /> + <Compile Include="DivertPowerMinigame.cs" /> + <Compile Include="DivertPowerTask.cs" /> + <Compile Include="DoorsSystemType.cs" /> + <Compile Include="DotAligner.cs" /> + <Compile Include="DragState.cs" /> + <Compile Include="DummyBehaviour.cs" /> + <Compile Include="DummyConsole.cs" /> + <Compile Include="DynamicSound.cs" /> + <Compile Include="Effects.cs" /> + <Compile Include="ElectricTask.cs" /> + <Compile Include="EmergencyMinigame.cs" /> + <Compile Include="EmptyGarbageMinigame.cs" /> + <Compile Include="EndGameManager.cs" /> + <Compile Include="EngineBehaviour.cs" /> + <Compile Include="EnterCodeMinigame.cs" /> + <Compile Include="ExileController.cs" /> + <Compile Include="ExitGameButton.cs" /> + <Compile Include="Extensions.cs" /> + <Compile Include="FindAGameManager.cs" /> + <Compile Include="FindGameButton.cs" /> + <Compile Include="FingerBehaviour.cs" /> + <Compile Include="FixedActionConsole.cs" /> + <Compile Include="FlatWaveBehaviour.cs" /> + <Compile Include="FloatRange.cs" /> + <Compile Include="FollowerCamera.cs" /> + <Compile Include="FontCache.cs" /> + <Compile Include="FontData.cs" /> + <Compile Include="FontExtensionData.cs" /> + <Compile Include="FontLoader.cs" /> + <Compile Include="GameData.cs" /> + <Compile Include="GameDiscovery.cs" /> + <Compile Include="GameModes.cs" /> + <Compile Include="GameObjectExtensions.cs" /> + <Compile Include="GameOptionsData.cs" /> + <Compile Include="GameOptionsMenu.cs" /> + <Compile Include="GameOverReason.cs" /> + <Compile Include="GameSettingMenu.cs" /> + <Compile Include="GameStartManager.cs" /> + <Compile Include="GarbageBehaviour.cs" /> + <Compile Include="GoogleMobileAds\Api\AdapterState.cs" /> + <Compile Include="GoogleMobileAds\Api\AdapterStatus.cs" /> + <Compile Include="GoogleMobileAds\Api\AdErrorEventArgs.cs" /> + <Compile Include="GoogleMobileAds\Api\AdFailedToLoadEventArgs.cs" /> + <Compile Include="GoogleMobileAds\Api\AdLoader.cs" /> + <Compile Include="GoogleMobileAds\Api\AdPosition.cs" /> + <Compile Include="GoogleMobileAds\Api\AdRequest.cs" /> + <Compile Include="GoogleMobileAds\Api\AdSize.cs" /> + <Compile Include="GoogleMobileAds\Api\BannerView.cs" /> + <Compile Include="GoogleMobileAds\Api\CustomNativeEventArgs.cs" /> + <Compile Include="GoogleMobileAds\Api\CustomNativeTemplateAd.cs" /> + <Compile Include="GoogleMobileAds\Api\Gender.cs" /> + <Compile Include="GoogleMobileAds\Api\InterstitialAd.cs" /> + <Compile Include="GoogleMobileAds\Api\Mediation\MediationExtras.cs" /> + <Compile Include="GoogleMobileAds\Api\MobileAds.cs" /> + <Compile Include="GoogleMobileAds\Api\NativeAdType.cs" /> + <Compile Include="GoogleMobileAds\Api\Reward.cs" /> + <Compile Include="GoogleMobileAds\Api\RewardBasedVideoAd.cs" /> + <Compile Include="GoogleMobileAds\Api\RewardedAd.cs" /> + <Compile Include="GoogleMobileAds\Api\ServerSideVerificationOptions.cs" /> + <Compile Include="GoogleMobileAds\Common\DummyClient.cs" /> + <Compile Include="GoogleMobileAds\Common\IAdLoaderClient.cs" /> + <Compile Include="GoogleMobileAds\Common\IBannerClient.cs" /> + <Compile Include="GoogleMobileAds\Common\ICustomNativeTemplateClient.cs" /> + <Compile Include="GoogleMobileAds\Common\IInterstitialClient.cs" /> + <Compile Include="GoogleMobileAds\Common\IMobileAdsClient.cs" /> + <Compile Include="GoogleMobileAds\Common\IRewardBasedVideoAdClient.cs" /> + <Compile Include="GoogleMobileAds\Common\IRewardedAdClient.cs" /> + <Compile Include="GoogleMobileAds\Common\MobileAdsEventExecutor.cs" /> + <Compile Include="GoogleMobileAds\Common\RewardedAdDummyClient.cs" /> + <Compile Include="GoogleMobileAds\Common\Utils.cs" /> + <Compile Include="GoogleMobileAds\GoogleMobileAdsClientFactory.cs" /> + <Compile Include="HashRandom.cs" /> + <Compile Include="HatBehaviour.cs" /> + <Compile Include="HatManager.cs" /> + <Compile Include="HatsTab.cs" /> + <Compile Include="HorizontalGauge.cs" /> + <Compile Include="HostGameButton.cs" /> + <Compile Include="HowToPlayController.cs" /> + <Compile Include="HudManager.cs" /> + <Compile Include="HudOverrideSystemType.cs" /> + <Compile Include="HudOverrideTask.cs" /> + <Compile Include="IActivatable.cs" /> + <Compile Include="IBuyable.cs" /> + <Compile Include="IBytesSerializable.cs" /> + <Compile Include="IConnectButton.cs" /> + <Compile Include="IDisconnectHandler.cs" /> + <Compile Include="IFocusHolder.cs" /> + <Compile Include="IGameListHandler.cs" /> + <Compile Include="ILocationActivate.cs" /> + <Compile Include="ImageData.cs" /> + <Compile Include="ImageNames.cs" /> + <Compile Include="ImageTranslator.cs" /> + <Compile Include="ImportantTextTask.cs" /> + <Compile Include="InfectedOverlay.cs" /> + <Compile Include="InnerNet\AlterGameTags.cs" /> + <Compile Include="InnerNet\ClientData.cs" /> + <Compile Include="InnerNet\DisconnectReasons.cs" /> + <Compile Include="InnerNet\GameKeywords.cs" /> + <Compile Include="InnerNet\GameListing.cs" /> + <Compile Include="InnerNet\GameStates.cs" /> + <Compile Include="InnerNet\InnerDiscover.cs" /> + <Compile Include="InnerNet\InnerNetClient.cs" /> + <Compile Include="InnerNet\InnerNetObject.cs" /> + <Compile Include="InnerNet\InnerNetServer.cs" /> + <Compile Include="InnerNet\JoinFailureReasons.cs" /> + <Compile Include="InnerNet\LimboStates.cs" /> + <Compile Include="InnerNet\MatchMakerModes.cs" /> + <Compile Include="InnerNet\MessageExtensions.cs" /> + <Compile Include="InnerNet\SpawnFlags.cs" /> + <Compile Include="InnerNet\Tags.cs" /> + <Compile Include="IntRange.cs" /> + <Compile Include="IntroCutscene.cs" /> + <Compile Include="IObjectPool.cs" /> + <Compile Include="ISoundPlayer.cs" /> + <Compile Include="ISystemType.cs" /> + <Compile Include="ITranslatedText.cs" /> + <Compile Include="IUsable.cs" /> + <Compile Include="IVirtualJoystick.cs" /> + <Compile Include="JoinGameButton.cs" /> + <Compile Include="KerningPair.cs" /> + <Compile Include="KeyboardJoystick.cs" /> + <Compile Include="KeypadGame.cs" /> + <Compile Include="KillAnimation.cs" /> + <Compile Include="KillAnimType.cs" /> + <Compile Include="KillButtonManager.cs" /> + <Compile Include="KillOverlay.cs" /> + <Compile Include="LanguageButton.cs" /> + <Compile Include="LanguageSetter.cs" /> + <Compile Include="LanguageUnit.cs" /> + <Compile Include="LeafBehaviour.cs" /> + <Compile Include="LeafMinigame.cs" /> + <Compile Include="LetterTree.cs" /> + <Compile Include="LifeSuppSystemType.cs" /> + <Compile Include="LightSource.cs" /> + <Compile Include="LobbyBehaviour.cs" /> + <Compile Include="MainMenuManager.cs" /> + <Compile Include="ManualDoor.cs" /> + <Compile Include="MapBehaviour.cs" /> + <Compile Include="MapConsole.cs" /> + <Compile Include="MapCountOverlay.cs" /> + <Compile Include="MapRoom.cs" /> + <Compile Include="MapTaskOverlay.cs" /> + <Compile Include="MatchMaker.cs" /> + <Compile Include="MatchMakerGameButton.cs" /> + <Compile Include="MedScanMinigame.cs" /> + <Compile Include="MedScanSystem.cs" /> + <Compile Include="MeetingHud.cs" /> + <Compile Include="MeetingRoomManager.cs" /> + <Compile Include="MemSafeStringExtensions.cs" /> + <Compile Include="MeshRendererExtensions.cs" /> + <Compile Include="Minigame.cs" /> + <Compile Include="MMOnlineManager.cs" /> + <Compile Include="MonoPInvokeCallbackAttribute.cs" /> + <Compile Include="NameTextBehaviour.cs" /> + <Compile Include="NavigationMinigame.cs" /> + <Compile Include="NoOxyTask.cs" /> + <Compile Include="NormalPlayerTask.cs" /> + <Compile Include="NoShadowBehaviour.cs" /> + <Compile Include="NotificationPopper.cs" /> + <Compile Include="NumberOption.cs" /> + <Compile Include="ObjectPoolBehavior.cs" /> + <Compile Include="OffsetAdjustment.cs" /> + <Compile Include="OneWayShadows.cs" /> + <Compile Include="OptionBehaviour.cs" /> + <Compile Include="OptionsConsole.cs" /> + <Compile Include="OptionsMenuBehaviour.cs" /> + <Compile Include="OverlayKillAnimation.cs" /> + <Compile Include="Palette.cs" /> + <Compile Include="ParallaxController.cs" /> + <Compile Include="ParticleInfo.cs" /> + <Compile Include="PassiveButton.cs" /> + <Compile Include="PassiveButtonManager.cs" /> + <Compile Include="PetBehaviour.cs" /> + <Compile Include="PetsTab.cs" /> + <Compile Include="PhysicsHelpers.cs" /> + <Compile Include="PingTracker.cs" /> + <Compile Include="PlayerAnimator.cs" /> + <Compile Include="PlayerControl.cs" /> + <Compile Include="PlayerParticle.cs" /> + <Compile Include="PlayerParticleInfo.cs" /> + <Compile Include="PlayerParticles.cs" /> + <Compile Include="PlayerPhysics.cs" /> + <Compile Include="PlayerTab.cs" /> + <Compile Include="PlayerTask.cs" /> + <Compile Include="PlayerVoteArea.cs" /> + <Compile Include="PoolableBehavior.cs" /> + <Compile Include="PoolablePlayer.cs" /> + <Compile Include="PooledMapIcon.cs" /> + <Compile Include="PowerTools\SpriteAnim.cs" /> + <Compile Include="PowerTools\SpriteAnimEventHandler.cs" /> + <Compile Include="PowerTools\SpriteAnimNodes.cs" /> + <Compile Include="PowerTools\SpriteAnimNodeSync.cs" /> + <Compile Include="PowerTools\WaitForAnimationFinish.cs" /> + <Compile Include="ProgressTracker.cs" /> + <Compile Include="Properties\AssemblyInfo.cs" /> + <Compile Include="PurchaseButton.cs" /> + <Compile Include="PurchaseStates.cs" /> + <Compile Include="RadioWaveBehaviour.cs" /> + <Compile Include="RandomFill.cs" /> + <Compile Include="ReactorMinigame.cs" /> + <Compile Include="ReactorRoomWire.cs" /> + <Compile Include="ReactorShipRoom.cs" /> + <Compile Include="ReactorSystemType.cs" /> + <Compile Include="ReactorTask.cs" /> + <Compile Include="RefuelMinigame.cs" /> + <Compile Include="RefuelStage.cs" /> + <Compile Include="ReportButtonManager.cs" /> + <Compile Include="ResolutionManager.cs" /> + <Compile Include="ResolutionSlider.cs" /> + <Compile Include="ResSetter.cs" /> + <Compile Include="RingBuffer.cs" /> + <Compile Include="RoomTracker.cs" /> + <Compile Include="SabotageSystemType.cs" /> + <Compile Include="SabotageTask.cs" /> + <Compile Include="SampleMinigame.cs" /> + <Compile Include="SaveManager.cs" /> + <Compile Include="Scene0Controller.cs" /> + <Compile Include="Scene1Controller.cs" /> + <Compile Include="SceneChanger.cs" /> + <Compile Include="SceneController.cs" /> + <Compile Include="ScreenJoystick.cs" /> + <Compile Include="Scroller.cs" /> + <Compile Include="SecurityCameraSystemType.cs" /> + <Compile Include="ServerInfo.cs" /> + <Compile Include="ServerManager.cs" /> + <Compile Include="ServerSelector.cs" /> + <Compile Include="ServerSelectUi.cs" /> + <Compile Include="SettingsMode.cs" /> + <Compile Include="ShadowCamera.cs" /> + <Compile Include="ShhhBehaviour.cs" /> + <Compile Include="ShieldMinigame.cs" /> + <Compile Include="ShipRoom.cs" /> + <Compile Include="ShipStatus.cs" /> + <Compile Include="ShowAdsState.cs" /> + <Compile Include="SimonSaysGame.cs" /> + <Compile Include="SinglePopHelp.cs" /> + <Compile Include="SkinData.cs" /> + <Compile Include="SkinLayer.cs" /> + <Compile Include="SkinsTab.cs" /> + <Compile Include="SlideBar.cs" /> + <Compile Include="SortGameObject.cs" /> + <Compile Include="SortMinigame.cs" /> + <Compile Include="SoundGroup.cs" /> + <Compile Include="SoundManager.cs" /> + <Compile Include="SoundStarter.cs" /> + <Compile Include="SpinAnimator.cs" /> + <Compile Include="SpriteParticle.cs" /> + <Compile Include="StarGen.cs" /> + <Compile Include="StatsManager.cs" /> + <Compile Include="StatsPopup.cs" /> + <Compile Include="SteamBehaviour.cs" /> + <Compile Include="SteamManager.cs" /> + <Compile Include="SteamPurchasingModule.cs" /> + <Compile Include="StoreMenu.cs" /> + <Compile Include="StringExtensions.cs" /> + <Compile Include="StringNames.cs" /> + <Compile Include="StringOption.cs" /> + <Compile Include="SubString.cs" /> + <Compile Include="SubStringReader.cs" /> + <Compile Include="SurvCamera.cs" /> + <Compile Include="SurveillanceMinigame.cs" /> + <Compile Include="SweepMinigame.cs" /> + <Compile Include="SwitchMinigame.cs" /> + <Compile Include="SwitchSystem.cs" /> + <Compile Include="SystemConsole.cs" /> + <Compile Include="SystemTypeHelpers.cs" /> + <Compile Include="SystemTypes.cs" /> + <Compile Include="TabButton.cs" /> + <Compile Include="TabGroup.cs" /> + <Compile Include="TaskAddButton.cs" /> + <Compile Include="TaskAdderGame.cs" /> + <Compile Include="TaskFolder.cs" /> + <Compile Include="TaskPanelBehaviour.cs" /> + <Compile Include="TaskSet.cs" /> + <Compile Include="TaskTypes.cs" /> + <Compile Include="TaskTypesHelpers.cs" /> + <Compile Include="TempData.cs" /> + <Compile Include="TextBox.cs" /> + <Compile Include="TextController.cs" /> + <Compile Include="TextLink.cs" /> + <Compile Include="TextRenderer.cs" /> + <Compile Include="TextTranslator.cs" /> + <Compile Include="ToggleButtonBehaviour.cs" /> + <Compile Include="ToggleOption.cs" /> + <Compile Include="TowerBehaviour.cs" /> + <Compile Include="TransitionOpen.cs" /> + <Compile Include="TransitionType.cs" /> + <Compile Include="TranslatedImageSet.cs" /> + <Compile Include="TranslationController.cs" /> + <Compile Include="TumbleBoxBehaviour.cs" /> + <Compile Include="TuneRadioMinigame.cs" /> + <Compile Include="TutorialManager.cs" /> + <Compile Include="TutorialStatsManager.cs" /> + <Compile Include="TwitterLink.cs" /> + <Compile Include="UnlockManifoldsMinigame.cs" /> + <Compile Include="UnlockPopUp.cs" /> + <Compile Include="UploadDataGame.cs" /> + <Compile Include="UploadDataTask.cs" /> + <Compile Include="UseButtonManager.cs" /> + <Compile Include="Vector2Range.cs" /> + <Compile Include="VendingMinigame.cs" /> + <Compile Include="VendingSlot.cs" /> + <Compile Include="Vent.cs" /> + <Compile Include="VersionShower.cs" /> + <Compile Include="VerticalGauge.cs" /> + <Compile Include="VirtualJoystick.cs" /> + <Compile Include="VoteBanSystem.cs" /> + <Compile Include="WaitForHostPopup.cs" /> + <Compile Include="WaitForLerp.cs" /> + <Compile Include="WeaponsMinigame.cs" /> + <Compile Include="WeatherMinigame.cs" /> + <Compile Include="WinningPlayerData.cs" /> + <Compile Include="Wire.cs" /> + <Compile Include="WireMinigame.cs" /> + <Compile Include="WireNode.cs" /> + <Compile Include="XXHash.cs" /> + </ItemGroup> + <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> +</Project>
\ No newline at end of file diff --git a/Client/Assembly-CSharp/Assets/CoreScripts/Telemetry.cs b/Client/Assembly-CSharp/Assets/CoreScripts/Telemetry.cs new file mode 100644 index 0000000..6d81ae0 --- /dev/null +++ b/Client/Assembly-CSharp/Assets/CoreScripts/Telemetry.cs @@ -0,0 +1,300 @@ +using System; +using System.Collections.Generic; +using InnerNet; +using UnityEngine; +using UnityEngine.Analytics; + +namespace Assets.CoreScripts +{ + public class Telemetry : DestroyableSingleton<Telemetry> + { + private static readonly string[] ColorNames = new string[] + { + "Red", + "Blue", + "Green", + "Pink", + "Orange", + "Yellow", + "Black", + "White", + "Purple", + "Brown" + }; + + private bool amHost; + + private bool gameStarted; + + private DateTime timeStarted; + + public bool IsInitialized; + + public Guid CurrentGuid; + + public void Initialize() + { + this.Initialize(Guid.NewGuid()); + } + + public void Initialize(Guid gameGuid) + { + this.IsInitialized = true; + this.CurrentGuid = gameGuid; + } + + public void StartGame(bool sendName, bool isHost, int playerCount, int impostorCount, GameModes gameMode, uint timesImpostor, uint gamesPlayed, uint crewStreak) + { + if (!SaveManager.SendTelemetry) + { + return; + } + this.gameStarted = true; + this.amHost = isHost; + this.timeStarted = DateTime.UtcNow; + Dictionary<string, object> dictionary = new Dictionary<string, object> + { + { + "Platform", + (byte)Application.platform + }, + { + "TimesImpostor", + timesImpostor + }, + { + "CrewStreak", + crewStreak + }, + { + "GamesPlayed", + gamesPlayed + }, + { + "GameMode", + gameMode + } + }; + if (this.amHost) + { + dictionary.Add("PlayerCount", playerCount); + dictionary.Add("InfectedCount", impostorCount); + } + Analytics.CustomEvent("StartGame", dictionary); + } + + public void WriteMeetingStarted(bool isEmergency) + { + if (!SaveManager.SendTelemetry) + { + return; + } + if (!this.amHost) + { + return; + } + Analytics.CustomEvent("MeetingStarted", new Dictionary<string, object> + { + { + "IsEmergency", + isEmergency + } + }); + } + + public void WriteMeetingEnded(byte[] results, float duration) + { + if (!SaveManager.SendTelemetry) + { + return; + } + if (!this.amHost) + { + return; + } + Analytics.CustomEvent("MeetingEnded", new Dictionary<string, object> + { + { + "IsEmergency", + duration + } + }); + } + + public void WritePosition(byte playerNum, Vector2 worldPos) + { + } + + public void WriteMurder(byte sourcePlayerNum, byte targetPlayerNum, Vector3 worldPos) + { + if (!SaveManager.SendTelemetry) + { + return; + } + if (!this.gameStarted) + { + return; + } + Analytics.CustomEvent("Murder"); + } + + public void WriteSabotageUsed(SystemTypes systemType) + { + if (!SaveManager.SendTelemetry) + { + return; + } + if (!this.gameStarted) + { + return; + } + Analytics.CustomEvent("SabotageUsed", new Dictionary<string, object> + { + { + "SystemType", + systemType + } + }); + } + + public void WriteUse(byte playerNum, TaskTypes taskType, Vector3 worldPos) + { + if (!SaveManager.SendTelemetry) + { + return; + } + if (!this.gameStarted) + { + return; + } + Analytics.CustomEvent("ConsoleUsed", new Dictionary<string, object> + { + { + "TaskType", + taskType + } + }); + } + + public void WriteCompleteTask(byte playerNum, TaskTypes taskType) + { + if (!SaveManager.SendTelemetry) + { + return; + } + if (!this.gameStarted) + { + return; + } + Analytics.CustomEvent("TaskComplete", new Dictionary<string, object> + { + { + "TaskType", + taskType + } + }); + } + + internal void WriteDisconnect(DisconnectReasons reason) + { + if (!SaveManager.SendTelemetry) + { + return; + } + if (!this.gameStarted) + { + return; + } + Analytics.CustomEvent("Disconnect", new Dictionary<string, object> + { + { + "Reason", + reason + } + }); + } + + public void EndGame(GameOverReason endReason) + { + if (!SaveManager.SendTelemetry) + { + return; + } + if (!this.gameStarted) + { + return; + } + Dictionary<string, object> dictionary = new Dictionary<string, object> + { + { + "Reason", + endReason + } + }; + if (this.amHost) + { + dictionary.Add("DurationSec", (DateTime.UtcNow - this.timeStarted).TotalSeconds); + } + Analytics.CustomEvent("EndGame", dictionary); + } + + public void SendWho() + { + if (!SaveManager.SendTelemetry) + { + return; + } + if (!this.gameStarted) + { + return; + } + Analytics.CustomEvent("SentWho"); + } + + public void SelectInfected(int colorId, uint hatId) + { + if (!SaveManager.SendTelemetry) + { + return; + } + if (!this.gameStarted) + { + return; + } + Analytics.CustomEvent("SelectInfected", new Dictionary<string, object> + { + { + "Color", + Telemetry.ColorNames[colorId] + }, + { + "Hat", + DestroyableSingleton<HatManager>.Instance.GetHatById(hatId).name + } + }); + } + + public void WonGame(int colorId, uint hatId) + { + if (!SaveManager.SendTelemetry) + { + return; + } + if (!this.gameStarted) + { + return; + } + Analytics.CustomEvent("WonGame", new Dictionary<string, object> + { + { + "Color", + Telemetry.ColorNames[colorId] + }, + { + "Hat", + DestroyableSingleton<HatManager>.Instance.GetHatById(hatId).name + } + }); + } + } +} diff --git a/Client/Assembly-CSharp/Asteroid.cs b/Client/Assembly-CSharp/Asteroid.cs new file mode 100644 index 0000000..a633bef --- /dev/null +++ b/Client/Assembly-CSharp/Asteroid.cs @@ -0,0 +1,71 @@ +using System; +using System.Collections; +using UnityEngine; + +public class Asteroid : PoolableBehavior +{ + public Vector3 TargetPosition { get; internal set; } + + public Sprite[] AsteroidImages; + + public Sprite[] BrokenImages; + + private int imgIdx; + + public FloatRange MoveSpeed = new FloatRange(2f, 5f); + + public FloatRange RotateSpeed = new FloatRange(-10f, 10f); + + public SpriteRenderer Explosion; + + public void FixedUpdate() + { + base.transform.localRotation = Quaternion.Euler(0f, 0f, base.transform.localRotation.eulerAngles.z + this.RotateSpeed.Last * Time.fixedDeltaTime); + Vector3 a = this.TargetPosition - base.transform.localPosition; + if (a.sqrMagnitude > 0.05f) + { + a.Normalize(); + base.transform.localPosition += a * this.MoveSpeed.Last * Time.fixedDeltaTime; + return; + } + this.OwnerPool.Reclaim(this); + } + + public override void Reset() + { + base.enabled = true; + this.Explosion.enabled = false; + SpriteRenderer component = base.GetComponent<SpriteRenderer>(); + this.imgIdx = this.AsteroidImages.RandomIdx<Sprite>(); + component.sprite = this.AsteroidImages[this.imgIdx]; + component.enabled = true; + ButtonBehavior component2 = base.GetComponent<ButtonBehavior>(); + component2.enabled = true; + component2.OnClick.RemoveAllListeners(); + base.transform.Rotate(0f, 0f, this.RotateSpeed.Next()); + this.MoveSpeed.Next(); + base.Reset(); + } + + public IEnumerator CoBreakApart() + { + base.enabled = false; + base.GetComponent<ButtonBehavior>().enabled = false; + this.Explosion.enabled = true; + yield return new WaitForLerp(0.1f, delegate(float t) + { + this.Explosion.transform.localScale = new Vector3(t, t, t); + }); + yield return new WaitForSeconds(0.05f); + yield return new WaitForLerp(0.05f, delegate(float t) + { + this.Explosion.transform.localScale = new Vector3(1f - t, 1f - t, 1f - t); + }); + SpriteRenderer rend = base.GetComponent<SpriteRenderer>(); + yield return null; + rend.sprite = this.BrokenImages[this.imgIdx]; + yield return new WaitForSeconds(0.2f); + this.OwnerPool.Reclaim(this); + yield break; + } +} diff --git a/Client/Assembly-CSharp/AutoOpenDoor.cs b/Client/Assembly-CSharp/AutoOpenDoor.cs new file mode 100644 index 0000000..da09c70 --- /dev/null +++ b/Client/Assembly-CSharp/AutoOpenDoor.cs @@ -0,0 +1,37 @@ +using System; + +public class AutoOpenDoor : ManualDoor +{ + private const float ClosedDuration = 10f; + + public SystemTypes Room; + + public float ClosedTimer; + + public float CooldownTimer; + + public bool DoUpdate(float dt) + { + this.CooldownTimer = Math.Max(this.CooldownTimer - dt, 0f); + if (this.ClosedTimer > 0f) + { + this.ClosedTimer = Math.Max(this.ClosedTimer - dt, 0f); + if (this.ClosedTimer == 0f) + { + this.SetDoorway(true); + return true; + } + } + return false; + } + + public override void SetDoorway(bool open) + { + if (!open) + { + this.ClosedTimer = 10f; + this.CooldownTimer = 30f; + } + base.SetDoorway(open); + } +} diff --git a/Client/Assembly-CSharp/BanButton.cs b/Client/Assembly-CSharp/BanButton.cs new file mode 100644 index 0000000..0ed57a6 --- /dev/null +++ b/Client/Assembly-CSharp/BanButton.cs @@ -0,0 +1,52 @@ +using System; +using System.Collections; +using UnityEngine; + +public class BanButton : MonoBehaviour +{ + public BanMenu Parent { get; set; } + + public TextRenderer NameText; + + public SpriteRenderer Background; + + public int TargetClientId; + + public int numVotes; + + public void Start() + { + this.Background.SetCooldownNormalizedUvs(); + } + + public void Select() + { + this.Background.color = new Color(1f, 1f, 1f, 1f); + this.Parent.Select(this.TargetClientId); + } + + public void Unselect() + { + this.Background.color = new Color(0.3f, 0.3f, 0.3f, 0.5f); + } + + public void SetVotes(int newVotes) + { + base.StopAllCoroutines(); + base.StartCoroutine(this.CoSetVotes(this.numVotes, newVotes)); + this.numVotes = newVotes; + } + + private IEnumerator CoSetVotes(int oldNum, int newNum) + { + float num = (float)oldNum / 3f; + float end = (float)newNum / 3f; + for (float timer = 0f; timer < 0.2f; timer += Time.deltaTime) + { + this.Background.material.SetFloat("_Percent", Mathf.SmoothStep(end, end, timer / 0.2f)); + yield return null; + } + this.Background.material.SetFloat("_Percent", end); + yield break; + } +} diff --git a/Client/Assembly-CSharp/BanMenu.cs b/Client/Assembly-CSharp/BanMenu.cs new file mode 100644 index 0000000..eaa7440 --- /dev/null +++ b/Client/Assembly-CSharp/BanMenu.cs @@ -0,0 +1,153 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using InnerNet; +using UnityEngine; + +public class BanMenu : MonoBehaviour +{ + public BanButton BanButtonPrefab; + + public SpriteRenderer Background; + + public SpriteRenderer BanButton; + + public SpriteRenderer KickButton; + + public GameObject ContentParent; + + public int selected = -1; + + [HideInInspector] + public List<BanButton> allButtons = new List<BanButton>(); + + public void SetVisible(bool show) + { + show &= (PlayerControl.LocalPlayer && PlayerControl.LocalPlayer.Data != null && !PlayerControl.LocalPlayer.Data.IsDead); + show &= AmongUsClient.Instance.CanKick(); + show &= (MeetingHud.Instance || !ShipStatus.Instance); + this.BanButton.gameObject.SetActive(AmongUsClient.Instance.CanBan()); + this.KickButton.gameObject.SetActive(AmongUsClient.Instance.CanKick()); + base.GetComponent<SpriteRenderer>().enabled = show; + base.GetComponent<PassiveButton>().enabled = show; + } + + private void Update() + { + for (int i = 0; i < AmongUsClient.Instance.allClients.Count; i++) + { + try + { + ClientData client = AmongUsClient.Instance.allClients[i]; + if (client == null) + { + break; + } + int[] source; + if (VoteBanSystem.Instance.HasMyVote(client.Id) && VoteBanSystem.Instance.Votes.TryGetValue(client.Id, out source)) + { + int num = source.Count((int c) => c != 0); + BanButton banButton = this.allButtons.FirstOrDefault((BanButton b) => b.TargetClientId == client.Id); + if (banButton && banButton.numVotes != num) + { + banButton.SetVotes(num); + } + } + } + catch + { + break; + } + } + } + + public void Show() + { + if (this.ContentParent.activeSelf) + { + this.Hide(); + return; + } + this.selected = -1; + this.KickButton.color = Color.gray; + this.BanButton.color = Color.gray; + this.ContentParent.SetActive(true); + int num = 0; + if (AmongUsClient.Instance) + { + List<ClientData> allClients = AmongUsClient.Instance.allClients; + for (int i = 0; i < allClients.Count; i++) + { + ClientData clientData = allClients[i]; + if (clientData.Id != AmongUsClient.Instance.ClientId && clientData.Character) + { + GameData.PlayerInfo data = clientData.Character.Data; + if (!string.IsNullOrWhiteSpace(data.PlayerName)) + { + BanButton banButton = UnityEngine.Object.Instantiate<BanButton>(this.BanButtonPrefab, this.ContentParent.transform); + banButton.transform.localPosition = new Vector3(-0.2f, -0.15f - 0.4f * (float)num, -1f); + banButton.Parent = this; + banButton.NameText.Text = data.PlayerName; + banButton.TargetClientId = clientData.Id; + banButton.Unselect(); + this.allButtons.Add(banButton); + num++; + } + } + } + } + this.KickButton.transform.localPosition = new Vector3(-0.8f, -0.15f - 0.4f * (float)num - 0.1f, -1f); + this.BanButton.transform.localPosition = new Vector3(0.3f, -0.15f - 0.4f * (float)num - 0.1f, -1f); + float num2 = 0.3f + (float)(num + 1) * 0.4f; + this.Background.size = new Vector2(3f, num2); + this.Background.GetComponent<BoxCollider2D>().size = new Vector2(3f, num2); + this.Background.transform.localPosition = new Vector3(0f, -num2 / 2f + 0.15f, 0.1f); + } + + public void Hide() + { + this.selected = -1; + this.ContentParent.SetActive(false); + for (int i = 0; i < this.allButtons.Count; i++) + { + UnityEngine.Object.Destroy(this.allButtons[i].gameObject); + } + this.allButtons.Clear(); + } + + public void Select(int client) + { + if (VoteBanSystem.Instance.HasMyVote(client)) + { + return; + } + this.selected = client; + for (int i = 0; i < this.allButtons.Count; i++) + { + BanButton banButton = this.allButtons[i]; + if (banButton.TargetClientId != client) + { + banButton.Unselect(); + } + } + this.KickButton.color = Color.white; + this.BanButton.color = Color.white; + } + + public void Kick(bool ban) + { + if (this.selected >= 0) + { + if (AmongUsClient.Instance.CanBan()) + { + AmongUsClient.Instance.KickPlayer(this.selected, ban); + this.Hide(); + } + else + { + VoteBanSystem.Instance.CmdAddVote(this.selected); + } + } + this.Select(-1); + } +} diff --git a/Client/Assembly-CSharp/BlockedWords.cs b/Client/Assembly-CSharp/BlockedWords.cs new file mode 100644 index 0000000..af08a2f --- /dev/null +++ b/Client/Assembly-CSharp/BlockedWords.cs @@ -0,0 +1,877 @@ +using System; +using System.Collections.Generic; +using System.Text; + +public static class BlockedWords +{ + public static readonly HashSet<char> SymbolChars = new HashSet<char> + { + '?', + '!', + ',', + '.', + '\'', + ':', + ';', + '(', + ')', + '/', + '\\', + '%', + '^', + '&', + '-', + '=' + }; + + private static readonly LetterTree SkipList; + + public static readonly string[] AllWords = new string[] + { + "anal~", + "analingus", + "anilingus", + "anus^", + "apeshit", + "areola", + "areole", + "arian~", + "arse~", + "arsehole", + "aryan~", + "ass^", + "assbandit", + "assbang", + "assbite", + "assclown", + "asscock", + "asscracker", + "asses~", + "assface", + "assfuck", + "assfukka", + "assgoblin", + "asshat", + "asshead", + "assho1e", + "asshole", + "asshopper", + "assjabber", + "assjacker", + "asslick", + "assmaster", + "assmonkey", + "assmucus", + "assmunch", + "assnigger", + "asspirate", + "asswad", + "asswhole", + "asswipe", + "autoerotic", + "axwound", + "azazel", + "azz", + "babybatter", + "babyjuice", + "ballbag", + "ballgag", + "ballgravy", + "ballkicking", + "balllicking", + "balls~", + "ballsac", + "ballsak", + "bampot", + "bangbros", + "bareback", + "barelylegal", + "barenaked", + "bastard", + "bastinado", + "battyboy", + "bawdy", + "bbw", + "bdsm", + "beaner", + "beardedclam", + "beastial", + "beatch", + "beaver", + "beefcurtain", + "beeyotch", + "bellend", + "beotch", + "bescumber", + "bestial", + "b!atch", + "b!gblack", + "b!gbreasts", + "b!gknockers", + "b!gtits", + "b!mbo", + "b!nt", + "b!rdlock", + "b!tch", + "bisexual", + "blackcock", + "blondeaction", + "bloodclaat", + "bloodyhell", + "blowjob", + "blowme", + "blowmud", + "blowyourload", + "bluewaffle", + "blumpkin", + "b0iolas", + "b0llock", + "b0llok", + "b0llox", + "b0ndage", + "b0ned", + "b0ner", + "b0ng", + "b00b", + "b00ger", + "b00kie", + "b00tee", + "b00tie", + "b00ty", + "b00ze", + "b00zy", + "b0som", + "breasts", + "breeder", + "brotherfucker", + "brownshowers", + "brunetteaction", + "buceta", + "bukkake", + "bulldyke", + "bulletvibe", + "bullshit", + "bullturds", + "buncombe", + "bung", + "bunnyfucker", + "bustaload", + "busty", + "buttcheeks", + "buttfuck", + "butthole", + "buttmuch", + "buttmunch", + "buttpirate", + "buttplug", + "caca", + "cahone", + "cameltoe", + "camgirl", + "camslut", + "camwhore", + "carpetmuncher", + "cawk", + "cervix", + "chesticle", + "chichiman", + "chickwithadick", + "childfucker", + "chinc", + "chink", + "choad", + "chocice", + "chocolaterosebuds", + "chode", + "chotabags", + "cipa~", + "circlejerk", + "clevelandsteamer", + "cl1max", + "cl1t", + "cloverclamps", + "clunge", + "clusterfuck", + "cnut", + "c0cain", + "c0ccydynia", + "c0ck", + "c0ffindodger", + "c0ital", + "c0k", + "c0mmie", + "c0ndom", + "c0ochie", + "c0ochy", + "c0on", + "c0oter", + "c0prolagnia", + "c0prophilia", + "c0psomewood", + "c0rksucker", + "c0rnhole", + "c0rpulent", + "c0rpwhore", + "c0x", + "crack", + "creampie", + "cretin", + "crikey", + "cripple", + "crotte", + "cum~", + "cumbubble", + "cumchugger", + "cumdump", + "cumfreak", + "cumguzzler", + "cumjockey", + "cums~", + "cumtart", + "cunilingus", + "cunnie", + "cunny", + "cunt", + "cutrope", + "cyalis", + "cyberfuc", + "dago", + "darkie", + "daterape", + "dawgiestyle", + "deepthroat", + "deggo", + "dendrophilia", + "dick", + "diddle", + "dike", + "dild0", + "diligaf", + "dillweed", + "dimwit", + "dingle", + "dink", + "dipship", + "dipshit", + "dirsa", + "dirtypillows", + "dirtysanchez", + "dlck", + "d0gfucker", + "d0ggiestyle", + "d0ggin", + "d0ggystyle", + "d0gstyle", + "d0lcett", + "d0mination", + "d0minatrix", + "d0mmes", + "d0ng", + "d0nkeypunch", + "d0nkeyribber", + "d0ochbag", + "d0ofus", + "d0okie", + "d0osh", + "d0pey", + "d0ubledong", + "d0ublelift", + "d0ublepenetration", + "d0uch3", + "dpaction", + "drilldo", + "dryhump", + "duche", + "dumass", + "dumbass", + "dumbcunt", + "dumbfuck", + "dumbshit", + "dummy", + "dumshit", + "dvda", + "dyke", + "eatadick", + "eathairpie", + "eatmyass", + "ecchi", + "ejaculate", + "ejaculating", + "ejaculation", + "ejakulate", + "erect", + "erotic", + "erotism", + "essohbee", + "eunuch", + "extacy", + "extasy", + "f4cial", + "f4ck", + "f4g", + "f4ig", + "f4nny", + "f4nyy", + "f4tass", + "fcuk", + "fecal", + "feck", + "feist", + "felch", + "fellate", + "fellatio", + "feltch", + "femalesquirting", + "femdom", + "fenian", + "figging", + "fingerbang", + "fingerfuck", + "fingering", + "fisted", + "fistfuck", + "fisting", + "fisty", + "flange", + "flaps", + "fleshflute", + "flogthelog", + "floozy", + "foad", + "foah", + "fondle", + "foobar", + "fook", + "footfetish", + "footjob", + "foreskin", + "freex", + "frenchify", + "frigg", + "frotting", + "fubar", + "fuc", + "fudgepacker", + "fuk", + "fuq", + "furfag", + "furryfag", + "futanari", + "fuck", + "fux", + "fvck", + "fxck", + "gangbang", + "ganja", + "gash", + "gassyass", + "gay", + "genderbender", + "genitals", + "gey~", + "gfy", + "ghay", + "ghey", + "giantcock", + "gigolo", + "gippo", + "girlon", + "girlsgonewild", + "glans", + "goatcx", + "goatse", + "gokkun", + "goldenshower", + "golliwog", + "gonad", + "gooch", + "googirl", + "gook", + "goregasm", + "gringo", + "grope", + "groupsex", + "gspot", + "guido", + "guro", + "hamflap", + "handjob", + "hardon", + "hell~", + "hells", + "hemp", + "homo^", + "hentai", + "heroin", + "heshe~", + "hircismus", + "hitler", + "hugefat", + "hump~", + "hussy", + "hymen", + "inbred", + "incest", + "injun", + "intercourse", + "jackass", + "jackhole", + "jackoff", + "jaggi", + "jagoff", + "jailbait", + "jellydonut", + "jigaboo", + "jiggerboo", + "jism", + "jiz", + "jock", + "juggs", + "junglebunny", + "junkie", + "junky", + "kafir", + "kawk", + "kike", + "kinbaku", + "kinkster", + "kinky", + "klan", + "kock", + "kondum", + "kooch", + "kootch", + "kraut", + "kum", + "kunilingus", + "kunja", + "kunt~", + "kwif", + "kyke", + "labia", + "lameass", + "lardass", + "l3i+ch", + "l3monparty", + "l3per", + "l3sbian", + "l3sbo~", + "l3z~", + "lolita", + "looney", + "lovemaking", + "lube", + "lust", + "m4fugly", + "m4kemecome", + "m4lesquirting", + "m4ms", + "m45ochist", + "m45sa", + "m45terbate", + "m45terbating", + "m45terbation", + "m45terb8", + "m45turbate", + "m45turbating", + "m45turbation", + "mcfagget", + "menageatrois", + "menses", + "menstruate", + "menstruation", + "meth~", + "mfucking", + "mick", + "microphallus", + "middlefinger", + "midget", + "milf", + "minge", + "missionaryposition", + "m0f0", + "m0lest", + "m0olie", + "m0omoofoofoo", + "m0ron", + "m0thafuck", + "m0therfuck", + "m0undofvenus", + "mrhands", + "muff", + "munging", + "munter", + "mutha", + "muther", + "naked", + "nambla", + "napalm", + "nappy", + "nawashi", + "nazi", + "ngga^", + "nggr", + "nlgger", + "nlgga", + "nlggr", + "n1gaboo", + "n1qqa", + "n1qqer", + "n1gga", + "n1bba", + "n1ggr", + "n1gger", + "n1ggle", + "n1glet", + "n1gnog", + "n1mphomania", + "n1mrod", + "n1nny", + "n1pple", + "nonce", + "nsfwimages", + "nude", + "nudity", + "numbnuts", + "nutbutter", + "nutsack", + "nutter", + "nympho", + "octopussy", + "oldbag", + "omorashi", + "onecuptwogirls", + "oneguyonejar", + "opiate", + "opium", + "orally", + "orgasim", + "orgasm", + "orgies", + "orgy", + "ovary", + "ovum", + "paedophile", + "paki~", + "panooch", + "pansy", + "pantie", + "panty", + "pecker", + "pedo~", + "pedophile", + "pegging", + "penetrate", + "penetration", + "penial", + "penile", + "penis", + "perversion", + "phallic", + "phonesex", + "phuck", + "phuk", + "phuq", + "pigfucker", + "pikey", + "pillowbiter", + "pimp", + "pinko~", + "playboy", + "pleasurechest", + "p0lack", + "p0lesmoker", + "p0llock", + "p0nyplay", + "p0on", + "p0rchmonkey", + "p0rn", + "prick", + "prig", + "princealbertpiercing", + "pron", + "prostitute", + "prude", + "psycho", + "pthc", + "pube", + "pubic", + "pubis", + "punani", + "punkass", + "punky", + "punta", + "puss", + "puta~", + "puto~", + "queaf", + "queef", + "queer", + "quicky", + "quim", + "racy", + "raghead", + "ragingboner", + "rape~", + "raper~", + "raping", + "rapist", + "ratard", + "raunch", + "rectal", + "rectum", + "rectus", + "reefer", + "reich", + "renob", + "retard", + "reversecowgirl", + "revue", + "rimjaw", + "rimjob", + "rimming", + "ritard", + "rosypalm", + "rtard", + "rubbish", + "rump", + "ruski", + "rustytrombone", + "sadism", + "sadist", + "sambo", + "sandbar", + "sandler", + "sandnigger", + "sanger", + "santorum", + "sausagequeen", + "scag", + "scantily", + "scat", + "schizo", + "schlong", + "scissoring", + "scroat", + "scrog", + "scrot", + "scrud", + "seaman", + "seamen", + "seks", + "semen", + "sex", + "shag", + "shamedame", + "shavedbeaver", + "shavedpussy", + "shemale", + "shibari", + "shirtlifter", + "shit^", + "shiz", + "shota", + "shrimping", + "sissy", + "skag", + "skank", + "skeet", + "skullfuck", + "slag", + "slanteye", + "slave", + "sleaze", + "sleazy", + "slope", + "slut", + "smartass", + "smut", + "snatch", + "snowballing", + "snuff", + "s0doff", + "s0dom", + "s0nofabitch", + "s0nofawhore", + "spade", + "sperm", + "spic~", + "spick", + "spik~", + "splooge", + "spooge", + "spreadlegs", + "spunk", + "stfu", + "stiffy", + "strapon", + "strappado", + "styledoggy", + "suckass", + "suckingass", + "suicidegirls", + "sultrywomen", + "sumofabiatch", + "swastika", + "swinger", + "taintedlove", + "tampon", + "tard", + "tastemy", + "tawdry", + "teabagging", + "teat", + "teets", + "teez", + "teste~", + "testes", + "testical", + "testicle", + "testis", + "threesome", + "throating", + "thundercunt", + "thot~", + "t1edup", + "t1ghtwhite", + "t1nkle", + "t1t`", + "t1ts`", + "t1tty", + "t1ttie", + "tongueina", + "toots", + "topless", + "tosser", + "towelhead", + "tramp", + "tranny", + "transsexual", + "trashy", + "tribadism", + "tubgirl", + "turd", + "tush", + "tw4t^", + "twink", + "twofingers", + "twogirlsonecup", + "twunt", + "unclefucker", + "undies", + "undressing", + "upskirt", + "urethraplay", + "urinal", + "urine", + "urophilia", + "uterus", + "vajayjay", + "vajj", + "valium", + "venusmound", + "veqtable", + "v14gra", + "v1brator", + "v1gra", + "v1oletwand", + "v1rgin", + "v1xen", + "vjayjay", + "vodka", + "vomit", + "vorarephilia", + "voyeur", + "vulgar", + "vulva", + "wang", + "wank", + "wazoo", + "wedgie", + "weed", + "weenie", + "weewee", + "weiner", + "wetback", + "wetdream", + "whitepower", + "whiz", + "wh0ar~", + "wh0ars", + "wh0ralicious", + "wh0re^", + "wh0ring^", + "wigger", + "windowlicker", + "wiseass", + "w0g~", + "w00se", + "w0p~", + "wrappingmen", + "wrinkledstarfish", + "xrated", + "xxx", + "yaoi", + "yeasty", + "yellowshowers", + "yiffy", + "yobbo", + "zibbi", + "zoophilia", + "zubb" + }; + + private class LengthCompare : IComparer<string> + { + public static readonly BlockedWords.LengthCompare Instance = new BlockedWords.LengthCompare(); + + public int Compare(string x, string y) + { + return -x.Length.CompareTo(y.Length); + } + } + + static BlockedWords() + { + BlockedWords.SkipList = new LetterTree(); + for (int i = 0; i < BlockedWords.AllWords.Length; i++) + { + BlockedWords.SkipList.AddWord(BlockedWords.AllWords[i]); + } + } + + public static bool ContainsWord(string chatText) + { + for (int i = 0; i < chatText.Length; i++) + { + if (BlockedWords.SkipList.Search(chatText, i) > 0) + { + return true; + } + } + return false; + } + + public static string CensorWords(string chatText) + { + StringBuilder stringBuilder = new StringBuilder(chatText); + for (int i = 0; i < chatText.Length; i++) + { + int num = BlockedWords.SkipList.Search(stringBuilder, i); + if (num > 0) + { + for (int j = 0; j < num; j++) + { + stringBuilder[i + j] = '*'; + } + i = i + num - 1; + } + } + return stringBuilder.ToString(); + } + + private static bool IsLetter(char letter) + { + return letter != ' ' && letter != '\r' && letter != '\n' && !BlockedWords.SymbolChars.Contains(letter); + } +} diff --git a/Client/Assembly-CSharp/BoolRange.cs b/Client/Assembly-CSharp/BoolRange.cs new file mode 100644 index 0000000..866c81b --- /dev/null +++ b/Client/Assembly-CSharp/BoolRange.cs @@ -0,0 +1,10 @@ +using System; +using UnityEngine; + +public class BoolRange +{ + public static bool Next(float p = 0.5f) + { + return UnityEngine.Random.value <= p; + } +} diff --git a/Client/Assembly-CSharp/ButtonBehavior.cs b/Client/Assembly-CSharp/ButtonBehavior.cs new file mode 100644 index 0000000..aa941c8 --- /dev/null +++ b/Client/Assembly-CSharp/ButtonBehavior.cs @@ -0,0 +1,64 @@ +using System; +using UnityEngine; +using UnityEngine.UI; + +public class ButtonBehavior : MonoBehaviour +{ + public bool OnUp = true; + + public bool OnDown; + + public bool Repeat; + + public Button.ButtonClickedEvent OnClick = new Button.ButtonClickedEvent(); + + private Controller myController = new Controller(); + + private Collider2D[] colliders; + + private float downTime; + + public void OnEnable() + { + this.colliders = base.GetComponents<Collider2D>(); + this.myController.Reset(); + } + + public void Update() + { + this.myController.Update(); + foreach (Collider2D coll in this.colliders) + { + switch (this.myController.CheckDrag(coll, false)) + { + case DragState.TouchStart: + if (this.OnDown) + { + this.OnClick.Invoke(); + } + break; + case DragState.Dragging: + if (this.Repeat) + { + this.downTime += Time.fixedDeltaTime; + if (this.downTime >= 0.3f) + { + this.downTime = 0f; + this.OnClick.Invoke(); + } + } + else + { + this.downTime = 0f; + } + break; + case DragState.Released: + if (this.OnUp) + { + this.OnClick.Invoke(); + } + break; + } + } + } +} diff --git a/Client/Assembly-CSharp/ButtonRolloverHandler.cs b/Client/Assembly-CSharp/ButtonRolloverHandler.cs new file mode 100644 index 0000000..963058d --- /dev/null +++ b/Client/Assembly-CSharp/ButtonRolloverHandler.cs @@ -0,0 +1,35 @@ +using System; +using UnityEngine; +using UnityEngine.Events; + +public class ButtonRolloverHandler : MonoBehaviour +{ + public SpriteRenderer Target; + + public Color OverColor = Color.green; + + public Color OutColor = Color.white; + + public AudioClip HoverSound; + + public void Start() + { + PassiveButton component = base.GetComponent<PassiveButton>(); + component.OnMouseOver.AddListener(new UnityAction(this.DoMouseOver)); + component.OnMouseOut.AddListener(new UnityAction(this.DoMouseOut)); + } + + public void DoMouseOver() + { + this.Target.color = this.OverColor; + if (this.HoverSound) + { + SoundManager.Instance.PlaySound(this.HoverSound, false, 1f); + } + } + + public void DoMouseOut() + { + this.Target.color = this.OutColor; + } +} diff --git a/Client/Assembly-CSharp/CardSlideGame.cs b/Client/Assembly-CSharp/CardSlideGame.cs new file mode 100644 index 0000000..3c423a5 --- /dev/null +++ b/Client/Assembly-CSharp/CardSlideGame.cs @@ -0,0 +1,190 @@ +using System; +using System.Collections; +using UnityEngine; + +public class CardSlideGame : Minigame +{ + private Color gray = new Color(0.45f, 0.45f, 0.45f); + + private Color green = new Color(0f, 0.8f, 0f); + + private CardSlideGame.TaskStages State; + + private Controller myController = new Controller(); + + private FloatRange XRange = new FloatRange(-2.38f, 2.38f); + + public FloatRange AcceptedTime = new FloatRange(0.4f, 0.6f); + + public Collider2D col; + + public SpriteRenderer redLight; + + public SpriteRenderer greenLight; + + public TextRenderer StatusText; + + public AudioClip AcceptSound; + + public AudioClip[] CardMove; + + public AudioClip WalletOut; + + public float dragTime; + + private bool moving; + + private enum TaskStages + { + Before, + Animating, + Inserted, + After + } + + public void Update() + { + if (this.MyNormTask.IsComplete) + { + return; + } + this.myController.Update(); + Vector3 localPosition = this.col.transform.localPosition; + switch (this.myController.CheckDrag(this.col, false)) + { + case DragState.NoTouch: + if (this.State == CardSlideGame.TaskStages.Inserted) + { + localPosition.x = Mathf.Lerp(localPosition.x, this.XRange.min, Time.deltaTime * 4f); + } + break; + case DragState.TouchStart: + this.dragTime = 0f; + break; + case DragState.Dragging: + if (this.State == CardSlideGame.TaskStages.Inserted) + { + Vector2 vector = this.myController.DragPosition - base.transform.position; + vector.x = this.XRange.Clamp(vector.x); + if (vector.x - localPosition.x > 0.01f) + { + this.dragTime += Time.deltaTime; + this.redLight.color = this.gray; + this.greenLight.color = this.gray; + if (!this.moving) + { + this.moving = true; + if (Constants.ShouldPlaySfx()) + { + SoundManager.Instance.PlaySound(this.CardMove.Random<AudioClip>(), false, 1f); + } + } + } + localPosition.x = vector.x; + } + break; + case DragState.Released: + this.moving = false; + if (this.State == CardSlideGame.TaskStages.Before) + { + this.State = CardSlideGame.TaskStages.Animating; + base.StartCoroutine(this.InsertCard()); + } + else if (this.State == CardSlideGame.TaskStages.Inserted) + { + if (this.XRange.max - localPosition.x < 0.05f) + { + if (this.AcceptedTime.Contains(this.dragTime)) + { + if (Constants.ShouldPlaySfx()) + { + SoundManager.Instance.PlaySound(this.AcceptSound, false, 1f); + } + this.State = CardSlideGame.TaskStages.After; + this.StatusText.Text = "Accepted. Thank you."; + base.StartCoroutine(this.PutCardBack()); + if (this.MyNormTask) + { + this.MyNormTask.NextStep(); + } + this.redLight.color = this.gray; + this.greenLight.color = this.green; + } + else + { + if (this.AcceptedTime.max < this.dragTime) + { + this.StatusText.Text = "Too slow. Try again"; + } + else + { + this.StatusText.Text = "Too fast. Try again."; + } + this.redLight.color = Color.red; + this.greenLight.color = this.gray; + } + } + else + { + this.StatusText.Text = "Bad read. Try again."; + this.redLight.color = Color.red; + this.greenLight.color = this.gray; + } + } + break; + } + this.col.transform.localPosition = localPosition; + } + + private IEnumerator PutCardBack() + { + if (Constants.ShouldPlaySfx()) + { + SoundManager.Instance.PlaySound(this.WalletOut, false, 1f); + } + Vector3 pos = this.col.transform.localPosition; + Vector3 targ = new Vector3(-1.11f, -1.9f, pos.z); + float time = 0f; + for (;;) + { + float t = Mathf.Min(1f, time / 0.6f); + this.col.transform.localPosition = Vector3.Lerp(pos, targ, t); + this.col.transform.localScale = Vector3.Lerp(Vector3.one, Vector3.one * 0.75f, t); + if (time > 0.6f) + { + break; + } + yield return null; + time += Time.deltaTime; + } + base.StartCoroutine(base.CoStartClose(0.75f)); + yield break; + } + + private IEnumerator InsertCard() + { + if (Constants.ShouldPlaySfx()) + { + SoundManager.Instance.PlaySound(this.WalletOut, false, 1f); + } + Vector3 pos = this.col.transform.localPosition; + Vector3 targ = new Vector3(this.XRange.min, 0.75f, pos.z); + float time = 0f; + for (;;) + { + float t = Mathf.Min(1f, time / 0.6f); + this.col.transform.localPosition = Vector3.Lerp(pos, targ, t); + this.col.transform.localScale = Vector3.Lerp(Vector3.one * 0.75f, Vector3.one, t); + if (time > 0.6f) + { + break; + } + yield return null; + time += Time.deltaTime; + } + this.StatusText.Text = "Please swipe card"; + this.greenLight.color = this.green; + this.State = CardSlideGame.TaskStages.Inserted; + yield break; + } +} diff --git a/Client/Assembly-CSharp/ChainBehaviour.cs b/Client/Assembly-CSharp/ChainBehaviour.cs new file mode 100644 index 0000000..38a5da5 --- /dev/null +++ b/Client/Assembly-CSharp/ChainBehaviour.cs @@ -0,0 +1,27 @@ +using System; +using UnityEngine; + +public class ChainBehaviour : MonoBehaviour +{ + public FloatRange SwingRange = new FloatRange(0f, 30f); + + public float SwingPeriod = 2f; + + public float swingTime; + + private Vector3 vec; + + public void Awake() + { + this.swingTime = FloatRange.Next(0f, this.SwingPeriod); + this.vec.z = this.SwingRange.Lerp(Mathf.Sin(this.swingTime)); + base.transform.eulerAngles = this.vec; + } + + public void Update() + { + this.swingTime += Time.deltaTime / this.SwingPeriod; + this.vec.z = this.SwingRange.Lerp(Mathf.Sin(this.swingTime * 3.1415927f) / 2f + 0.5f); + base.transform.eulerAngles = this.vec; + } +} diff --git a/Client/Assembly-CSharp/ChatBubble.cs b/Client/Assembly-CSharp/ChatBubble.cs new file mode 100644 index 0000000..3c26a40 --- /dev/null +++ b/Client/Assembly-CSharp/ChatBubble.cs @@ -0,0 +1,83 @@ +using System; +using UnityEngine; + +internal class ChatBubble : PoolableBehavior +{ + public SpriteRenderer ChatFace; + + public SpriteRenderer Xmark; + + public SpriteRenderer votedMark; + + public TextRenderer NameText; + + public TextRenderer TextArea; + + public SpriteRenderer Background; + + public void SetLeft() + { + base.transform.localPosition = new Vector3(-3f, 0f, 0f); + this.ChatFace.flipX = false; + this.ChatFace.transform.localScale = new Vector3(1f, 1f, 1f); + this.ChatFace.transform.localPosition = new Vector3(0f, 0.07f, 0f); + this.Xmark.transform.localPosition = new Vector3(-0.15f, -0.13f, -0.0001f); + this.votedMark.transform.localPosition = new Vector3(-0.15f, -0.13f, -0.0001f); + this.NameText.transform.localPosition = new Vector3(0.5f, 0.34f, 0f); + this.NameText.RightAligned = false; + this.TextArea.transform.localPosition = new Vector3(0.5f, 0.09f, 0f); + this.TextArea.RightAligned = false; + } + + public void SetNotification() + { + base.transform.localPosition = new Vector3(-2.75f, 0f, 0f); + this.ChatFace.flipX = false; + this.ChatFace.transform.localScale = new Vector3(0.75f, 0.75f, 1f); + this.ChatFace.transform.localPosition = new Vector3(0f, 0.18f, 0f); + this.Xmark.transform.localPosition = new Vector3(-0.15f, -0.13f, -0.0001f); + this.votedMark.transform.localPosition = new Vector3(-0.15f, -0.13f, -0.0001f); + this.NameText.transform.localPosition = new Vector3(0.5f, 0.34f, 0f); + this.NameText.RightAligned = false; + this.TextArea.transform.localPosition = new Vector3(0.5f, 0.09f, 0f); + this.TextArea.RightAligned = false; + this.TextArea.Text = string.Empty; + } + + public void SetRight() + { + base.transform.localPosition = new Vector3(-2.35f, 0f, 0f); + this.ChatFace.flipX = true; + this.ChatFace.transform.localScale = new Vector3(1f, 1f, 1f); + this.ChatFace.transform.localPosition = new Vector3(4.75f, 0.07f, 0f); + this.Xmark.transform.localPosition = new Vector3(0.15f, -0.13f, -0.0001f); + this.votedMark.transform.localPosition = new Vector3(0.15f, -0.13f, -0.0001f); + this.NameText.transform.localPosition = new Vector3(4.35f, 0.34f, 0f); + this.NameText.RightAligned = true; + this.TextArea.transform.localPosition = new Vector3(4.35f, 0.09f, 0f); + this.TextArea.RightAligned = true; + } + + public void SetName(string playerName, bool isDead, bool voted, Color color) + { + this.NameText.Text = (playerName ?? "..."); + this.NameText.Color = color; + this.NameText.RefreshMesh(); + if (isDead) + { + this.Xmark.enabled = true; + this.Background.color = Palette.HalfWhite; + } + if (voted) + { + this.votedMark.enabled = true; + } + } + + public override void Reset() + { + this.Xmark.enabled = false; + this.votedMark.enabled = false; + this.Background.color = Color.white; + } +} diff --git a/Client/Assembly-CSharp/ChatController.cs b/Client/Assembly-CSharp/ChatController.cs new file mode 100644 index 0000000..3658dd7 --- /dev/null +++ b/Client/Assembly-CSharp/ChatController.cs @@ -0,0 +1,326 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using UnityEngine; + +public class ChatController : MonoBehaviour +{ + public bool IsOpen + { + get + { + return this.Content.activeInHierarchy; + } + } + + public ObjectPoolBehavior chatBubPool; + + public Transform TypingArea; + + public SpriteRenderer TextBubble; + + public TextBox TextArea; + + public TextRenderer CharCount; + + public int MaxChat = 15; + + public Scroller scroller; + + public GameObject Content; + + public SpriteRenderer BackgroundImage; + + public SpriteRenderer ChatNotifyDot; + + public TextRenderer SendRateMessage; + + public Vector3 SourcePos = new Vector3(0f, 0f, -10f); + + public Vector3 TargetPos = new Vector3(-0.35f, 0.02f, -10f); + + private const float MaxChatSendRate = 3f; + + private float TimeSinceLastMessage = 3f; + + public AudioClip MessageSound; + + private bool animating; + + private Coroutine notificationRoutine; + + public BanMenu BanButton; + + public void Toggle() + { + PlayerControl localPlayer = PlayerControl.LocalPlayer; + CustomNetworkTransform customNetworkTransform = (localPlayer != null) ? localPlayer.NetTransform : null; + if (this.animating || !customNetworkTransform) + { + return; + } + base.StopAllCoroutines(); + if (this.IsOpen) + { + base.StartCoroutine(this.CoClose()); + return; + } + this.Content.SetActive(true); + customNetworkTransform.Halt(); + base.StartCoroutine(this.CoOpen()); + } + + public void SetVisible(bool visible) + { + Debug.Log("Chat is hidden: " + visible.ToString()); + this.ForceClosed(); + base.gameObject.SetActive(visible); + } + + public void ForceClosed() + { + base.StopAllCoroutines(); + this.Content.SetActive(false); + this.animating = false; + } + + public IEnumerator CoOpen() + { + this.animating = true; + Vector3 scale = Vector3.one; + this.BanButton.Hide(); + this.BanButton.SetVisible(true); + float targetScale = AspectSize.CalculateSize(base.transform.localPosition, this.BackgroundImage.sprite); + float timer = 0f; + while (timer < 0.15f) + { + timer += Time.deltaTime; + float num = Mathf.SmoothStep(0f, 1f, timer / 0.15f); + scale.y = (scale.x = Mathf.Lerp(0.1f, targetScale, num)); + this.Content.transform.localScale = scale; + this.Content.transform.localPosition = Vector3.Lerp(this.SourcePos, this.TargetPos, num) * targetScale; + this.BanButton.transform.localPosition = new Vector3(0f, -num * 0.75f, -20f); + yield return null; + } + this.ChatNotifyDot.enabled = false; + this.animating = false; + this.GiveFocus(); + yield break; + } + + public IEnumerator CoClose() + { + this.animating = true; + this.BanButton.Hide(); + Vector3 scale = Vector3.one; + float targetScale = AspectSize.CalculateSize(base.transform.localPosition, this.BackgroundImage.sprite); + for (float timer = 0f; timer < 0.15f; timer += Time.deltaTime) + { + float num = 1f - Mathf.SmoothStep(0f, 1f, timer / 0.15f); + scale.y = (scale.x = Mathf.Lerp(0.1f, targetScale, num)); + this.Content.transform.localScale = scale; + this.Content.transform.localPosition = Vector3.Lerp(this.SourcePos, this.TargetPos, num) * targetScale; + this.BanButton.transform.localPosition = new Vector3(0f, -num * 0.75f, -20f); + yield return null; + } + this.BanButton.SetVisible(false); + this.Content.SetActive(false); + this.animating = false; + yield break; + } + + public void SetPosition(MeetingHud meeting) + { + if (meeting) + { + base.transform.SetParent(meeting.transform); + base.transform.localPosition = new Vector3(3.1f, 2.2f, -10f); + return; + } + base.transform.SetParent(DestroyableSingleton<HudManager>.Instance.transform); + base.GetComponent<AspectPosition>().AdjustPosition(); + } + + public void UpdateCharCount() + { + Vector2 size = this.TextBubble.size; + size.y = Math.Max(0.62f, this.TextArea.TextHeight + 0.2f); + this.TextBubble.size = size; + Vector3 localPosition = this.TextBubble.transform.localPosition; + localPosition.y = (0.62f - size.y) / 2f; + this.TextBubble.transform.localPosition = localPosition; + Vector3 localPosition2 = this.TypingArea.localPosition; + localPosition2.y = -2.08f - localPosition.y * 2f; + this.TypingArea.localPosition = localPosition2; + int length = this.TextArea.text.Length; + this.CharCount.Text = length + "/100"; + if (length < 75) + { + this.CharCount.Color = Color.black; + return; + } + if (length < 100) + { + this.CharCount.Color = new Color(1f, 1f, 0f, 1f); + return; + } + this.CharCount.Color = Color.red; + } + + private void Update() + { + this.TimeSinceLastMessage += Time.deltaTime; + if (this.SendRateMessage.isActiveAndEnabled) + { + float num = 3f - this.TimeSinceLastMessage; + if (num < 0f) + { + this.SendRateMessage.gameObject.SetActive(false); + return; + } + this.SendRateMessage.Text = string.Format("Too fast. Wait {0} seconds", Mathf.CeilToInt(num)); + } + } + + public void SendChat() + { + float num = 3f - this.TimeSinceLastMessage; + if (num > 0f) + { + this.SendRateMessage.gameObject.SetActive(true); + this.SendRateMessage.Text = string.Format("Too fast. Wait {0} seconds", Mathf.CeilToInt(num)); + return; + } + if (!PlayerControl.LocalPlayer.RpcSendChat(this.TextArea.text)) + { + return; + } + this.TimeSinceLastMessage = 0f; + this.TextArea.Clear(); + } + + public void AddChatNote(GameData.PlayerInfo srcPlayer, ChatNoteTypes noteType) + { + if (srcPlayer == null) + { + return; + } + if (this.chatBubPool.NotInUse == 0) + { + this.chatBubPool.ReclaimOldest(); + } + ChatBubble chatBubble = this.chatBubPool.Get<ChatBubble>(); + PlayerControl.SetPlayerMaterialColors((int)srcPlayer.ColorId, chatBubble.ChatFace); + chatBubble.transform.SetParent(this.scroller.Inner); + chatBubble.transform.localScale = Vector3.one; + chatBubble.SetNotification(); + if (noteType == ChatNoteTypes.DidVote) + { + int votesRemaining = MeetingHud.Instance.GetVotesRemaining(); + chatBubble.SetName(string.Format("{0} has voted. {1} remaining.", srcPlayer.PlayerName, votesRemaining), false, true, Color.green); + } + chatBubble.TextArea.RefreshMesh(); + chatBubble.Background.size = new Vector2(5.52f, 0.2f + chatBubble.NameText.Height); + Vector3 localPosition = chatBubble.Background.transform.localPosition; + localPosition.y = chatBubble.NameText.transform.localPosition.y - chatBubble.Background.size.y / 2f + 0.05f; + chatBubble.Background.transform.localPosition = localPosition; + this.AlignAllBubbles(); + if (!this.IsOpen && this.notificationRoutine == null) + { + this.notificationRoutine = base.StartCoroutine(this.BounceDot()); + } + if (srcPlayer.Object != PlayerControl.LocalPlayer) + { + SoundManager.Instance.PlaySound(this.MessageSound, false, 1f).pitch = 0.5f + (float)srcPlayer.PlayerId / 10f; + } + } + + public void AddChat(PlayerControl sourcePlayer, string chatText) + { + if (!sourcePlayer || !PlayerControl.LocalPlayer) + { + return; + } + GameData.PlayerInfo data = PlayerControl.LocalPlayer.Data; + GameData.PlayerInfo data2 = sourcePlayer.Data; + if (data2 == null || data == null || (data2.IsDead && !data.IsDead)) + { + return; + } + if (this.chatBubPool.NotInUse == 0) + { + this.chatBubPool.ReclaimOldest(); + } + ChatBubble chatBubble = this.chatBubPool.Get<ChatBubble>(); + try + { + chatBubble.transform.SetParent(this.scroller.Inner); + chatBubble.transform.localScale = Vector3.one; + bool flag = sourcePlayer == PlayerControl.LocalPlayer; + if (flag) + { + chatBubble.SetRight(); + } + else + { + chatBubble.SetLeft(); + } + bool flag2 = data.IsImpostor && data2.IsImpostor; + bool voted = MeetingHud.Instance && MeetingHud.Instance.DidVote(sourcePlayer.PlayerId); + PlayerControl.SetPlayerMaterialColors((int)data2.ColorId, chatBubble.ChatFace); + chatBubble.SetName(data2.PlayerName, data2.IsDead, voted, flag2 ? Palette.ImpostorRed : Color.white); + if (SaveManager.CensorChat) + { + chatText = BlockedWords.CensorWords(chatText); + } + chatBubble.TextArea.Text = chatText; + chatBubble.TextArea.RefreshMesh(); + chatBubble.Background.size = new Vector2(5.52f, 0.2f + chatBubble.NameText.Height + chatBubble.TextArea.Height); + Vector3 localPosition = chatBubble.Background.transform.localPosition; + localPosition.y = chatBubble.NameText.transform.localPosition.y - chatBubble.Background.size.y / 2f + 0.05f; + chatBubble.Background.transform.localPosition = localPosition; + this.AlignAllBubbles(); + if (!this.IsOpen && this.notificationRoutine == null) + { + this.notificationRoutine = base.StartCoroutine(this.BounceDot()); + } + if (!flag) + { + SoundManager.Instance.PlaySound(this.MessageSound, false, 1f).pitch = 0.5f + (float)sourcePlayer.PlayerId / 10f; + } + } + catch + { + this.chatBubPool.Reclaim(chatBubble); + } + } + + private void AlignAllBubbles() + { + float num = 0f; + List<PoolableBehavior> activeChildren = this.chatBubPool.activeChildren; + for (int i = activeChildren.Count - 1; i >= 0; i--) + { + ChatBubble chatBubble = activeChildren[i] as ChatBubble; + num += chatBubble.Background.size.y; + Vector3 localPosition = chatBubble.transform.localPosition; + localPosition.y = -1.85f + num; + chatBubble.transform.localPosition = localPosition; + num += 0.1f; + } + this.scroller.YBounds.min = Mathf.Min(0f, -num + this.scroller.HitBox.bounds.size.y); + } + + private IEnumerator BounceDot() + { + this.ChatNotifyDot.enabled = true; + yield return Effects.Bounce(this.ChatNotifyDot.transform, 0.3f, 0.15f); + this.notificationRoutine = null; + yield break; + } + + public void GiveFocus() + { + this.TextArea.GiveFocus(); + } +} diff --git a/Client/Assembly-CSharp/ChatNoteTypes.cs b/Client/Assembly-CSharp/ChatNoteTypes.cs new file mode 100644 index 0000000..c8e3514 --- /dev/null +++ b/Client/Assembly-CSharp/ChatNoteTypes.cs @@ -0,0 +1,6 @@ +using System; + +public enum ChatNoteTypes +{ + DidVote +} diff --git a/Client/Assembly-CSharp/CloudGenerator.cs b/Client/Assembly-CSharp/CloudGenerator.cs new file mode 100644 index 0000000..e2821a2 --- /dev/null +++ b/Client/Assembly-CSharp/CloudGenerator.cs @@ -0,0 +1,159 @@ +using System; +using UnityEngine; + +public class CloudGenerator : MonoBehaviour +{ + public Sprite[] CloudImages; + + private Vector2[][] UvCache; + + private Vector2[] ExtentCache; + + public int NumClouds = 500; + + public float Length = 25f; + + public float Width = 25f; + + public Vector2 Direction = new Vector2(1f, 0f); + + private Vector2 NormDir = new Vector2(1f, 0f); + + private Vector2 Tangent = new Vector2(0f, 1f); + + private float tanLen; + + public FloatRange Rates = new FloatRange(0.25f, 1f); + + [HideInInspector] + private CloudGenerator.Cloud[] stars; + + [HideInInspector] + private Vector3[] verts; + + [HideInInspector] + private Mesh mesh; + + private struct Cloud + { + public int CloudIdx; + + public float Rate; + + public float PositionX; + + public float PositionY; + } + + public void Start() + { + this.UvCache = new Vector2[this.CloudImages.Length][]; + this.ExtentCache = new Vector2[this.CloudImages.Length]; + for (int i = 0; i < this.CloudImages.Length; i++) + { + Sprite sprite = this.CloudImages[i]; + this.UvCache[i] = sprite.uv; + this.ExtentCache[i] = sprite.bounds.extents; + } + this.stars = new CloudGenerator.Cloud[this.NumClouds]; + this.verts = new Vector3[this.NumClouds * 4]; + Vector2[] array = new Vector2[this.NumClouds * 4]; + int[] array2 = new int[this.NumClouds * 6]; + this.SetDirection(this.Direction); + MeshFilter component = base.GetComponent<MeshFilter>(); + this.mesh = new Mesh(); + this.mesh.MarkDynamic(); + component.mesh = this.mesh; + Vector3 vector = default(Vector3); + for (int j = 0; j < this.stars.Length; j++) + { + CloudGenerator.Cloud cloud = this.stars[j]; + int num = cloud.CloudIdx = this.CloudImages.RandomIdx<Sprite>(); + Vector2 vector2 = this.ExtentCache[num]; + Vector2[] array3 = this.UvCache[num]; + float num2 = FloatRange.Next(-1f, 1f) * this.Length; + float num3 = FloatRange.Next(-1f, 1f) * this.Width; + float num4 = cloud.PositionX = num2 * this.NormDir.x + num3 * this.Tangent.x; + float num5 = cloud.PositionY = num2 * this.NormDir.y + num3 * this.Tangent.y; + cloud.Rate = this.Rates.Next(); + this.stars[j] = cloud; + int num6 = j * 4; + vector.x = num4 - vector2.x; + vector.y = num5 + vector2.y; + this.verts[num6] = vector; + vector.x = num4 + vector2.x; + this.verts[num6 + 1] = vector; + vector.x = num4 - vector2.x; + vector.y = num5 - vector2.y; + this.verts[num6 + 2] = vector; + vector.x = num4 + vector2.x; + this.verts[num6 + 3] = vector; + array[num6] = array3[0]; + array[num6 + 1] = array3[1]; + array[num6 + 2] = array3[2]; + array[num6 + 3] = array3[3]; + int num7 = j * 6; + array2[num7] = num6; + array2[num7 + 1] = num6 + 1; + array2[num7 + 2] = num6 + 2; + array2[num7 + 3] = num6 + 2; + array2[num7 + 4] = num6 + 1; + array2[num7 + 5] = num6 + 3; + } + this.mesh.vertices = this.verts; + this.mesh.uv = array; + this.mesh.SetIndices(array2, MeshTopology.Triangles, 0); + } + + private void FixedUpdate() + { + float num = -0.99f * this.Length; + Vector2 vector = this.Direction * Time.fixedDeltaTime; + Vector3 vector2 = default(Vector3); + for (int i = 0; i < this.stars.Length; i++) + { + int num2 = i * 4; + CloudGenerator.Cloud cloud = this.stars[i]; + float num3 = cloud.PositionX; + float num4 = cloud.PositionY; + Vector2 vector3 = this.ExtentCache[cloud.CloudIdx]; + float rate = cloud.Rate; + num3 += rate * vector.x; + num4 += rate * vector.y; + if (this.OrthoDistance(num3, num4) > this.Length) + { + float num5 = FloatRange.Next(-1f, 1f) * this.Width; + num3 = num * this.NormDir.x + num5 * this.Tangent.x; + num4 = num * this.NormDir.y + num5 * this.Tangent.y; + cloud.Rate = this.Rates.Next(); + } + cloud.PositionX = num3; + cloud.PositionY = num4; + this.stars[i] = cloud; + vector2.x = num3 - vector3.x; + vector2.y = num4 + vector3.y; + this.verts[num2] = vector2; + vector2.x = num3 + vector3.x; + this.verts[num2 + 1] = vector2; + vector2.x = num3 - vector3.x; + vector2.y = num4 - vector3.y; + this.verts[num2 + 2] = vector2; + vector2.x = num3 + vector3.x; + this.verts[num2 + 3] = vector2; + } + this.mesh.vertices = this.verts; + } + + public void SetDirection(Vector2 dir) + { + this.Direction = dir; + this.NormDir = this.Direction.normalized; + this.Tangent = new Vector2(-this.NormDir.y, this.NormDir.x); + this.tanLen = Mathf.Sqrt(this.Tangent.y * this.Tangent.y + this.Tangent.x * this.Tangent.x); + } + + private float OrthoDistance(float pointx, float pointy) + { + return (this.Tangent.y * pointx - this.Tangent.x * pointy) / this.tanLen; + } +} diff --git a/Client/Assembly-CSharp/ColorChip.cs b/Client/Assembly-CSharp/ColorChip.cs new file mode 100644 index 0000000..7f61630 --- /dev/null +++ b/Client/Assembly-CSharp/ColorChip.cs @@ -0,0 +1,11 @@ +using System; +using UnityEngine; + +public class ColorChip : MonoBehaviour +{ + public SpriteRenderer Inner; + + public GameObject InUseForeground; + + public PassiveButton Button; +} diff --git a/Client/Assembly-CSharp/ConditionalHide.cs b/Client/Assembly-CSharp/ConditionalHide.cs new file mode 100644 index 0000000..5915f4f --- /dev/null +++ b/Client/Assembly-CSharp/ConditionalHide.cs @@ -0,0 +1,21 @@ +using System; +using UnityEngine; + +public class ConditionalHide : MonoBehaviour +{ + public RuntimePlatform[] HideForPlatforms = new RuntimePlatform[] + { + RuntimePlatform.WindowsPlayer + }; + + private void Awake() + { + for (int i = 0; i < this.HideForPlatforms.Length; i++) + { + if (this.HideForPlatforms[i] == RuntimePlatform.WindowsPlayer) + { + base.gameObject.SetActive(false); + } + } + } +} diff --git a/Client/Assembly-CSharp/ConditionalStore.cs b/Client/Assembly-CSharp/ConditionalStore.cs new file mode 100644 index 0000000..c549bff --- /dev/null +++ b/Client/Assembly-CSharp/ConditionalStore.cs @@ -0,0 +1,9 @@ +using System; +using UnityEngine; + +public class ConditionalStore : MonoBehaviour +{ + private void Awake() + { + } +} diff --git a/Client/Assembly-CSharp/Console.cs b/Client/Assembly-CSharp/Console.cs new file mode 100644 index 0000000..31f9aca --- /dev/null +++ b/Client/Assembly-CSharp/Console.cs @@ -0,0 +1,97 @@ +using System; +using Assets.CoreScripts; +using UnityEngine; + +public class Console : MonoBehaviour, IUsable +{ + public float UsableDistance + { + get + { + return this.usableDistance; + } + } + + public float PercentCool + { + get + { + return 0f; + } + } + + public float usableDistance = 1f; + + public int ConsoleId; + + public bool onlyFromBelow; + + public bool GhostsIgnored; + + public SystemTypes Room; + + public TaskTypes[] TaskTypes; + + public TaskSet[] ValidTasks; + + public SpriteRenderer Image; + + public void SetOutline(bool on, bool mainTarget) + { + if (this.Image) + { + this.Image.material.SetFloat("_Outline", (float)(on ? 1 : 0)); + this.Image.material.SetColor("_OutlineColor", Color.yellow); + this.Image.material.SetColor("_AddColor", mainTarget ? Color.yellow : Color.clear); + } + } + + public float CanUse(GameData.PlayerInfo pc, out bool canUse, out bool couldUse) + { + float num = float.MaxValue; + PlayerControl @object = pc.Object; + couldUse = ((!pc.IsDead || (PlayerControl.GameOptions.GhostsDoTasks && !this.GhostsIgnored)) && @object.CanMove && !pc.IsImpostor && (!this.onlyFromBelow || @object.transform.position.y < base.transform.position.y) && this.FindTask(@object)); + canUse = couldUse; + if (canUse) + { + num = Vector2.Distance(@object.GetTruePosition(), base.transform.position); + canUse &= (num <= this.UsableDistance); + } + return num; + } + + private PlayerTask FindTask(PlayerControl pc) + { + for (int i = 0; i < pc.myTasks.Count; i++) + { + PlayerTask playerTask = pc.myTasks[i]; + if (!playerTask.IsComplete && playerTask.ValidConsole(this)) + { + return playerTask; + } + } + return null; + } + + public void Use() + { + bool flag; + bool flag2; + this.CanUse(PlayerControl.LocalPlayer.Data, out flag, out flag2); + if (!flag) + { + return; + } + PlayerControl localPlayer = PlayerControl.LocalPlayer; + PlayerTask playerTask = this.FindTask(localPlayer); + if (playerTask.MinigamePrefab) + { + Minigame minigame = UnityEngine.Object.Instantiate<Minigame>(playerTask.MinigamePrefab); + minigame.transform.SetParent(Camera.main.transform, false); + minigame.transform.localPosition = new Vector3(0f, 0f, -50f); + minigame.Console = this; + minigame.Begin(playerTask); + DestroyableSingleton<Telemetry>.Instance.WriteUse(localPlayer.PlayerId, playerTask.TaskType, base.transform.position); + } + } +} diff --git a/Client/Assembly-CSharp/Constants.cs b/Client/Assembly-CSharp/Constants.cs new file mode 100644 index 0000000..5daa994 --- /dev/null +++ b/Client/Assembly-CSharp/Constants.cs @@ -0,0 +1,90 @@ +using System; +using UnityEngine; + +public static class Constants +{ + public const string LocalNetAddress = "127.0.0.1"; + + public const int GamePlayPort = 22023; + + public const int AnnouncementPort = 22024; + + public const int ServersPort = 22025; + + public const string InfinitySymbol = "∞"; + + public static readonly int ShipOnlyMask = LayerMask.GetMask(new string[] + { + "Ship" + }); + + public static readonly int ShipAndObjectsMask = LayerMask.GetMask(new string[] + { + "Ship", + "Objects" + }); + + public static readonly int ShipAndAllObjectsMask = LayerMask.GetMask(new string[] + { + "Ship", + "Objects", + "ShortObjects" + }); + + public static readonly int NotShipMask = ~LayerMask.GetMask(new string[] + { + "Ship" + }); + + public static readonly int Usables = ~LayerMask.GetMask(new string[] + { + "Ship", + "UI" + }); + + public static readonly int PlayersOnlyMask = LayerMask.GetMask(new string[] + { + "Players", + "Ghost" + }); + + public static readonly int ShadowMask = LayerMask.GetMask(new string[] + { + "Shadow", + "Objects", + "IlluminatedBlocking" + }); + + public static readonly int[] CompatVersions = new int[] + { + Constants.GetBroadcastVersion() + }; + + public const int Year = 2019; + + public const int Month = 6; + + public const int Day = 27; + + public const int Revision = 0; + + internal static int GetBroadcastVersion() + { + return 50487150; + } + + internal static int GetVersion(int year, int month, int day, int rev) + { + return year * 25000 + month * 1800 + day * 50 + rev; + } + + internal static byte[] GetBroadcastVersionBytes() + { + return BitConverter.GetBytes(Constants.GetBroadcastVersion()); + } + + public static bool ShouldPlaySfx() + { + return !AmongUsClient.Instance || AmongUsClient.Instance.GameMode != GameModes.LocalGame || DetectHeadset.Detect(); + } +} diff --git a/Client/Assembly-CSharp/Controller.cs b/Client/Assembly-CSharp/Controller.cs new file mode 100644 index 0000000..fd84caa --- /dev/null +++ b/Client/Assembly-CSharp/Controller.cs @@ -0,0 +1,157 @@ +using System; +using UnityEngine; + +public class Controller +{ + public bool AnyTouch + { + get + { + return this.Touches[0].IsDown || this.Touches[1].IsDown; + } + } + + public bool AnyTouchDown + { + get + { + return this.Touches[0].TouchStart || this.Touches[1].TouchStart; + } + } + + public bool AnyTouchUp + { + get + { + return this.Touches[0].TouchEnd || this.Touches[1].TouchEnd; + } + } + + public bool FirstDown + { + get + { + return this.Touches[0].TouchStart; + } + } + + public Vector2 DragPosition + { + get + { + return this.Touches[this.touchId].Position; + } + } + + public Vector2 DragStartPosition + { + get + { + return this.Touches[this.touchId].DownAt; + } + } + + public readonly Controller.TouchState[] Touches = new Controller.TouchState[2]; + + private Collider2D amTouching; + + private int touchId = -1; + + public class TouchState + { + public Vector2 DownAt; + + public Vector2 Position; + + public bool WasDown; + + public bool IsDown; + + public bool TouchStart; + + public bool TouchEnd; + } + + public Controller() + { + for (int i = 0; i < this.Touches.Length; i++) + { + this.Touches[i] = new Controller.TouchState(); + } + } + + public DragState CheckDrag(Collider2D coll, bool firstOnly = false) + { + if (!coll) + { + return DragState.NoTouch; + } + if (this.touchId <= -1) + { + if (firstOnly) + { + Controller.TouchState touchState = this.Touches[0]; + if (touchState.TouchStart && coll.OverlapPoint(touchState.Position)) + { + this.amTouching = coll; + this.touchId = 0; + return DragState.TouchStart; + } + } + else + { + for (int i = 0; i < this.Touches.Length; i++) + { + Controller.TouchState touchState2 = this.Touches[i]; + if (touchState2.TouchStart && coll.OverlapPoint(touchState2.Position)) + { + this.amTouching = coll; + this.touchId = i; + return DragState.TouchStart; + } + } + } + return DragState.NoTouch; + } + if (coll != this.amTouching) + { + return DragState.NoTouch; + } + if (this.Touches[this.touchId].IsDown) + { + return DragState.Dragging; + } + this.amTouching = null; + this.touchId = -1; + return DragState.Released; + } + + public void Update() + { + Controller.TouchState touchState = this.Touches[0]; + bool mouseButton = Input.GetMouseButton(0); + touchState.Position = Camera.main.ScreenToWorldPoint(Input.mousePosition); + touchState.TouchStart = (!touchState.IsDown && mouseButton); + if (touchState.TouchStart) + { + touchState.DownAt = touchState.Position; + } + touchState.TouchEnd = (touchState.IsDown && !mouseButton); + touchState.IsDown = mouseButton; + } + + public void Reset() + { + for (int i = 0; i < this.Touches.Length; i++) + { + this.Touches[i] = new Controller.TouchState(); + } + this.touchId = -1; + this.amTouching = null; + } + + public Controller.TouchState GetTouch(int i) + { + return this.Touches[i]; + } +} diff --git a/Client/Assembly-CSharp/CooldownHelpers.cs b/Client/Assembly-CSharp/CooldownHelpers.cs new file mode 100644 index 0000000..5177c2c --- /dev/null +++ b/Client/Assembly-CSharp/CooldownHelpers.cs @@ -0,0 +1,33 @@ +using System; +using UnityEngine; + +public static class CooldownHelpers +{ + public static void SetCooldownNormalizedUvs(this SpriteRenderer myRend) + { + Vector2[] uv = myRend.sprite.uv; + Vector4 vector = new Vector4(2f, -1f, 2f, -1f); + for (int i = 0; i < uv.Length; i++) + { + if (vector.x > uv[i].x) + { + vector.x = uv[i].x; + } + if (vector.y < uv[i].x) + { + vector.y = uv[i].x; + } + if (vector.z > uv[i].y) + { + vector.z = uv[i].y; + } + if (vector.w < uv[i].y) + { + vector.w = uv[i].y; + } + } + vector.y -= vector.x; + vector.w -= vector.z; + myRend.material.SetVector("_NormalizedUvs", vector); + } +} diff --git a/Client/Assembly-CSharp/CounterArea.cs b/Client/Assembly-CSharp/CounterArea.cs new file mode 100644 index 0000000..c399165 --- /dev/null +++ b/Client/Assembly-CSharp/CounterArea.cs @@ -0,0 +1,44 @@ +using System; +using System.Collections.Generic; +using UnityEngine; + +public class CounterArea : MonoBehaviour +{ + public SystemTypes RoomType; + + public ObjectPoolBehavior pool; + + private List<PoolableBehavior> myIcons = new List<PoolableBehavior>(); + + public float XOffset; + + public float YOffset; + + public int MaxWidth = 5; + + public void UpdateCount(int cnt) + { + bool flag = this.myIcons.Count != cnt; + while (this.myIcons.Count < cnt) + { + PoolableBehavior item = this.pool.Get<PoolableBehavior>(); + this.myIcons.Add(item); + } + while (this.myIcons.Count > cnt) + { + PoolableBehavior poolableBehavior = this.myIcons[this.myIcons.Count - 1]; + this.myIcons.RemoveAt(this.myIcons.Count - 1); + poolableBehavior.OwnerPool.Reclaim(poolableBehavior); + } + if (flag) + { + for (int i = 0; i < this.myIcons.Count; i++) + { + int num = i % 5; + int num2 = i / 5; + float num3 = (float)(Mathf.Min(cnt - num2 * 5, 5) - 1) * this.XOffset / -2f; + this.myIcons[i].transform.position = base.transform.position + new Vector3(num3 + (float)num * this.XOffset, (float)num2 * this.YOffset, -1f); + } + } + } +} diff --git a/Client/Assembly-CSharp/CourseMinigame.cs b/Client/Assembly-CSharp/CourseMinigame.cs new file mode 100644 index 0000000..562074b --- /dev/null +++ b/Client/Assembly-CSharp/CourseMinigame.cs @@ -0,0 +1,206 @@ +using System; +using System.Runtime.InteropServices; +using UnityEngine; + +public class CourseMinigame : Minigame +{ + public CourseStarBehaviour StarPrefab; + + public CourseStarBehaviour[] Stars; + + public SpriteRenderer DotPrefab; + + public Sprite DotLight; + + public SpriteRenderer[] Dots; + + public Collider2D Ship; + + public CourseStarBehaviour Destination; + + public Vector3[] PathPoints; + + public int NumPoints; + + public FloatRange XRange; + + public FloatRange YRange; + + public LineRenderer Path; + + public Controller myController = new Controller(); + + public float lineTimer; + + private CourseMinigame.UIntFloat Converter; + + public AudioClip SetCourseSound; + + public AudioClip SetCourseLastSound; + + [StructLayout(LayoutKind.Explicit)] + private struct UIntFloat + { + [FieldOffset(0)] + public float FloatValue; + + [FieldOffset(0)] + public int IntValue; + + public float GetFloat(byte[] bytes) + { + this.IntValue = ((int)bytes[0] | (int)bytes[1] << 8 | (int)bytes[2] << 16 | (int)bytes[3] << 24); + return this.FloatValue; + } + + public void GetBytes(float value, byte[] bytes) + { + this.FloatValue = value; + bytes[0] = (byte)(this.IntValue & 255); + bytes[1] = (byte)(this.IntValue >> 8 & 255); + bytes[2] = (byte)(this.IntValue >> 16 & 255); + bytes[3] = (byte)(this.IntValue >> 24 & 255); + } + } + + public override void Begin(PlayerTask task) + { + base.Begin(task); + this.PathPoints = new Vector3[this.NumPoints]; + this.Stars = new CourseStarBehaviour[this.NumPoints]; + this.Dots = new SpriteRenderer[this.NumPoints]; + for (int i = 0; i < this.PathPoints.Length; i++) + { + this.PathPoints[i].x = this.XRange.Lerp((float)i / ((float)this.PathPoints.Length - 1f)); + do + { + this.PathPoints[i].y = this.YRange.Next(); + } + while (i > 0 && Mathf.Abs(this.PathPoints[i - 1].y - this.PathPoints[i].y) < this.YRange.Width / 4f); + this.Dots[i] = UnityEngine.Object.Instantiate<SpriteRenderer>(this.DotPrefab, base.transform); + this.Dots[i].transform.localPosition = this.PathPoints[i]; + if (i == 0) + { + this.Dots[i].sprite = this.DotLight; + } + else + { + if (i == 1) + { + this.Ship.transform.localPosition = this.PathPoints[0]; + this.Ship.transform.eulerAngles = new Vector3(0f, 0f, Vector2.up.AngleSigned(this.PathPoints[1] - this.PathPoints[0])); + } + this.Stars[i] = UnityEngine.Object.Instantiate<CourseStarBehaviour>(this.StarPrefab, base.transform); + this.Stars[i].transform.localPosition = this.PathPoints[i]; + if (i == this.PathPoints.Length - 1) + { + this.Destination.transform.localPosition = this.PathPoints[i]; + } + } + } + this.Path.positionCount = this.PathPoints.Length; + this.Path.SetPositions(this.PathPoints); + } + + public void FixedUpdate() + { + float num = this.Converter.GetFloat(this.MyNormTask.Data); + int num2 = (int)num; + Vector2 b = this.PathPoints[num2]; + this.myController.Update(); + DragState dragState = this.myController.CheckDrag(this.Ship, false); + if (dragState != DragState.NoTouch) + { + if (dragState == DragState.Dragging) + { + if (num < (float)(this.PathPoints.Length - 1)) + { + Vector2 vector = this.PathPoints[num2 + 1] - b; + Vector2 a = new Vector2(1f, vector.y / vector.x); + Vector2 vector2 = base.transform.InverseTransformPoint(this.myController.DragPosition) - b; + if (vector2.x > 0f) + { + Vector2 vector3 = a * vector2.x; + if (Mathf.Abs(vector3.y - vector2.y) < 0.5f) + { + num = (float)num2 + Mathf.Min(1f, vector2.x / vector.x); + Vector3 localPosition = vector3 + b; + localPosition.z = -1f; + this.Ship.transform.localPosition = localPosition; + this.Ship.transform.localPosition = localPosition; + this.Ship.transform.eulerAngles = new Vector3(0f, 0f, Vector2.up.AngleSigned(vector)); + } + else + { + this.myController.Reset(); + } + } + } + else + { + Vector3 localPosition2 = this.PathPoints[this.PathPoints.Length - 1]; + localPosition2.z = -1f; + this.Ship.transform.localPosition = localPosition2; + } + } + } + else if (num < (float)(this.PathPoints.Length - 1)) + { + Vector2 vector4 = this.PathPoints[num2 + 1] - b; + Vector2 a2 = new Vector2(1f, vector4.y / vector4.x); + num = Mathf.Max((float)num2, Mathf.Lerp(num, (float)num2, Time.deltaTime * 5f)); + Vector3 localPosition3 = a2 * (num - (float)num2) + b; + localPosition3.z = -1f; + this.Ship.transform.localPosition = localPosition3; + } + else + { + Vector3 localPosition4 = this.PathPoints[this.PathPoints.Length - 1]; + localPosition4.z = -1f; + this.Ship.transform.localPosition = localPosition4; + } + if ((int)num > num2 && this.Stars[num2 + 1]) + { + UnityEngine.Object.Destroy(this.Stars[num2 + 1].gameObject); + this.Dots[num2 + 1].sprite = this.DotLight; + if (num2 == this.PathPoints.Length - 2) + { + if (Constants.ShouldPlaySfx()) + { + SoundManager.Instance.PlaySound(this.SetCourseLastSound, false, 1f).volume = 0.7f; + } + this.Destination.Speed *= 5f; + this.MyNormTask.NextStep(); + base.StartCoroutine(base.CoStartClose(0.75f)); + } + else if (Constants.ShouldPlaySfx()) + { + SoundManager.Instance.PlaySound(this.SetCourseSound, false, 1f).volume = 0.7f; + } + } + this.Converter.GetBytes(num, this.MyNormTask.Data); + this.SetLineDivision(num); + } + + private void SetLineDivision(float curVec) + { + int num = (int)curVec; + float num2 = 0f; + int num3 = 0; + while ((float)num3 <= curVec && num3 < this.PathPoints.Length - 1) + { + float num4 = Vector2.Distance(this.PathPoints[num3], this.PathPoints[num3 + 1]); + if (num3 == num) + { + num4 *= curVec - (float)num3; + } + num2 += num4; + num3++; + } + this.lineTimer -= Time.fixedDeltaTime; + Vector2 value = new Vector2(this.lineTimer, 0f); + this.Path.material.SetTextureOffset("_MainTex", value); + this.Path.material.SetTextureOffset("_AltTex", value); + this.Path.material.SetFloat("_Perc", num2 + this.lineTimer / 8f); + } +} diff --git a/Client/Assembly-CSharp/CourseStarBehaviour.cs b/Client/Assembly-CSharp/CourseStarBehaviour.cs new file mode 100644 index 0000000..2f5dbe9 --- /dev/null +++ b/Client/Assembly-CSharp/CourseStarBehaviour.cs @@ -0,0 +1,17 @@ +using System; +using UnityEngine; + +public class CourseStarBehaviour : MonoBehaviour +{ + public SpriteRenderer Upper; + + public SpriteRenderer Lower; + + public float Speed = 30f; + + public void Update() + { + this.Upper.transform.Rotate(0f, 0f, Time.deltaTime * this.Speed); + this.Lower.transform.Rotate(0f, 0f, Time.deltaTime * this.Speed); + } +} diff --git a/Client/Assembly-CSharp/CreateGameOptions.cs b/Client/Assembly-CSharp/CreateGameOptions.cs new file mode 100644 index 0000000..23251d4 --- /dev/null +++ b/Client/Assembly-CSharp/CreateGameOptions.cs @@ -0,0 +1,104 @@ +using System; +using System.Collections; +using InnerNet; +using PowerTools; +using UnityEngine; + +public class CreateGameOptions : MonoBehaviour, IConnectButton +{ + public AudioClip IntroMusic; + + public GameObject Content; + + public SpriteRenderer Foreground; + + public SpriteAnim connectIcon; + + public AnimationClip connectClip; + + public void Show() + { + if (NameTextBehaviour.Instance.ShakeIfInvalid()) + { + return; + } + if (StatsManager.Instance.AmBanned) + { + AmongUsClient.Instance.LastDisconnectReason = DisconnectReasons.IntentionalLeaving; + DestroyableSingleton<DisconnectPopup>.Instance.Show(); + return; + } + base.gameObject.SetActive(true); + this.Content.SetActive(false); + base.StartCoroutine(this.CoShow()); + } + + private IEnumerator CoShow() + { + yield return Effects.ColorFade(this.Foreground, Color.clear, Color.black, 0.1f); + this.Content.SetActive(true); + yield return Effects.ColorFade(this.Foreground, Color.black, Color.clear, 0.1f); + yield break; + } + + public void StartIcon() + { + if (!this.connectIcon) + { + return; + } + this.connectIcon.Play(this.connectClip, 1f); + } + + public void StopIcon() + { + if (!this.connectIcon) + { + return; + } + this.connectIcon.Stop(); + this.connectIcon.GetComponent<SpriteRenderer>().sprite = null; + } + + public void Hide() + { + base.StartCoroutine(this.CoHide()); + } + + private IEnumerator CoHide() + { + yield return Effects.ColorFade(this.Foreground, Color.clear, Color.black, 0.1f); + this.Content.SetActive(false); + yield return Effects.ColorFade(this.Foreground, Color.black, Color.clear, 0.1f); + base.gameObject.SetActive(false); + yield break; + } + + public void Confirm() + { + if (!DestroyableSingleton<MatchMaker>.Instance.Connecting(this)) + { + return; + } + base.StartCoroutine(this.CoStartGame()); + } + + private IEnumerator CoStartGame() + { + SoundManager.Instance.CrossFadeSound("MainBG", null, 0.5f, 1.5f); + yield return Effects.ColorFade(this.Foreground, Color.clear, Color.black, 0.2f); + AmongUsClient.Instance.GameMode = GameModes.OnlineGame; + AmongUsClient.Instance.SetEndpoint(DestroyableSingleton<ServerManager>.Instance.OnlineNetAddress, 22023); + AmongUsClient.Instance.MainMenuScene = "MMOnline"; + AmongUsClient.Instance.OnlineScene = "OnlineGame"; + AmongUsClient.Instance.Connect(MatchMakerModes.HostAndClient); + yield return AmongUsClient.Instance.WaitForConnectionOrFail(); + DestroyableSingleton<MatchMaker>.Instance.NotConnecting(); + if (AmongUsClient.Instance.mode == MatchMakerModes.None) + { + SoundManager.Instance.CrossFadeSound("MainBG", this.IntroMusic, 0.5f, 1.5f); + yield return Effects.ColorFade(this.Foreground, Color.black, Color.clear, 0.2f); + } + yield break; + } +} diff --git a/Client/Assembly-CSharp/CreateOptionsPicker.cs b/Client/Assembly-CSharp/CreateOptionsPicker.cs new file mode 100644 index 0000000..9210446 --- /dev/null +++ b/Client/Assembly-CSharp/CreateOptionsPicker.cs @@ -0,0 +1,165 @@ +using System; +using InnerNet; +using UnityEngine; + +public class CreateOptionsPicker : MonoBehaviour +{ + public SpriteRenderer[] MaxPlayerButtons; + + public SpriteRenderer[] ImpostorButtons; + + public SpriteRenderer[] LanguageButtons; + + public SpriteRenderer[] MapButtons; + + public SettingsMode mode; + + public CrewVisualizer CrewArea; + + public void Start() + { + this.MapButtons[1].gameObject.SetActive(false); + GameOptionsData targetOptions = this.GetTargetOptions(); + this.UpdateImpostorsButtons(targetOptions.NumImpostors); + this.UpdateMaxPlayersButtons(targetOptions); + this.UpdateLanguageButtons(targetOptions.Keywords & GameKeywords.AllLanguages); + this.UpdateMapButtons((int)targetOptions.MapId); + } + + private GameOptionsData GetTargetOptions() + { + if (this.mode == SettingsMode.Host) + { + return SaveManager.GameHostOptions; + } + GameOptionsData gameSearchOptions = SaveManager.GameSearchOptions; + if (gameSearchOptions.MapId == 0) + { + gameSearchOptions.ToggleMapFilter(0); + SaveManager.GameSearchOptions = gameSearchOptions; + } + return gameSearchOptions; + } + + private void SetTargetOptions(GameOptionsData data) + { + if (this.mode == SettingsMode.Host) + { + SaveManager.GameHostOptions = data; + return; + } + SaveManager.GameSearchOptions = data; + } + + public void SetMaxPlayersButtons(int maxPlayers) + { + GameOptionsData targetOptions = this.GetTargetOptions(); + if (maxPlayers < GameOptionsData.MinPlayers[targetOptions.NumImpostors]) + { + return; + } + targetOptions.MaxPlayers = maxPlayers; + this.SetTargetOptions(targetOptions); + if (DestroyableSingleton<FindAGameManager>.InstanceExists) + { + DestroyableSingleton<FindAGameManager>.Instance.ResetTimer(); + } + this.UpdateMaxPlayersButtons(targetOptions); + } + + private void UpdateMaxPlayersButtons(GameOptionsData opts) + { + if (this.CrewArea) + { + this.CrewArea.SetCrewSize(opts.MaxPlayers, opts.NumImpostors); + } + for (int i = 0; i < this.MaxPlayerButtons.Length; i++) + { + SpriteRenderer spriteRenderer = this.MaxPlayerButtons[i]; + spriteRenderer.enabled = (spriteRenderer.name == opts.MaxPlayers.ToString()); + spriteRenderer.GetComponentInChildren<TextRenderer>().Color = ((int.Parse(spriteRenderer.name) < GameOptionsData.MinPlayers[opts.NumImpostors]) ? Palette.DisabledGrey : Color.white); + } + } + + public void SetImpostorButtons(int numImpostors) + { + GameOptionsData targetOptions = this.GetTargetOptions(); + targetOptions.NumImpostors = numImpostors; + this.SetTargetOptions(targetOptions); + this.SetMaxPlayersButtons(Mathf.Max(targetOptions.MaxPlayers, GameOptionsData.MinPlayers[numImpostors])); + this.UpdateImpostorsButtons(numImpostors); + } + + private void UpdateImpostorsButtons(int numImpostors) + { + for (int i = 0; i < this.ImpostorButtons.Length; i++) + { + SpriteRenderer spriteRenderer = this.ImpostorButtons[i]; + spriteRenderer.enabled = (spriteRenderer.name == numImpostors.ToString()); + } + } + + public void SetMap(int mapid) + { + GameOptionsData targetOptions = this.GetTargetOptions(); + if (this.mode == SettingsMode.Host) + { + targetOptions.MapId = (byte)mapid; + } + else + { + targetOptions.ToggleMapFilter((byte)mapid); + } + this.SetTargetOptions(targetOptions); + if (DestroyableSingleton<FindAGameManager>.InstanceExists) + { + DestroyableSingleton<FindAGameManager>.Instance.ResetTimer(); + } + this.UpdateMapButtons(mapid); + } + + private void UpdateMapButtons(int mapid) + { + if (this.mode == SettingsMode.Host) + { + if (this.CrewArea) + { + this.CrewArea.SetMap(mapid); + } + for (int i = 0; i < this.MapButtons.Length; i++) + { + SpriteRenderer spriteRenderer = this.MapButtons[i]; + spriteRenderer.color = ((spriteRenderer.name == mapid.ToString()) ? Color.white : Palette.DisabledGrey); + } + return; + } + GameOptionsData targetOptions = this.GetTargetOptions(); + for (int j = 0; j < this.MapButtons.Length; j++) + { + SpriteRenderer spriteRenderer2 = this.MapButtons[j]; + spriteRenderer2.color = (targetOptions.FilterContainsMap(byte.Parse(spriteRenderer2.name)) ? Color.white : Palette.DisabledGrey); + } + } + + public void SetLanguageFilter(int keyword) + { + GameOptionsData targetOptions = this.GetTargetOptions(); + targetOptions.Keywords &= ~GameKeywords.AllLanguages; + targetOptions.Keywords |= (GameKeywords)keyword; + this.SetTargetOptions(targetOptions); + if (DestroyableSingleton<FindAGameManager>.InstanceExists) + { + DestroyableSingleton<FindAGameManager>.Instance.ResetTimer(); + } + this.UpdateLanguageButtons((GameKeywords)keyword); + } + + private void UpdateLanguageButtons(GameKeywords button) + { + for (int i = 0; i < this.LanguageButtons.Length; i++) + { + SpriteRenderer spriteRenderer = this.LanguageButtons[i]; + spriteRenderer.enabled = (spriteRenderer.name == button.ToString()); + } + } +} diff --git a/Client/Assembly-CSharp/CreateStoreButton.cs b/Client/Assembly-CSharp/CreateStoreButton.cs new file mode 100644 index 0000000..b08c3d5 --- /dev/null +++ b/Client/Assembly-CSharp/CreateStoreButton.cs @@ -0,0 +1,16 @@ +using System; +using UnityEngine; + +public class CreateStoreButton : MonoBehaviour +{ + public Transform Target; + + public StoreMenu StorePrefab; + + public void Click() + { + StoreMenu storeMenu = UnityEngine.Object.Instantiate<StoreMenu>(this.StorePrefab, this.Target); + storeMenu.transform.localPosition = new Vector3(0f, 0f, -100f); + storeMenu.transform.localScale = Vector3.zero; + } +} diff --git a/Client/Assembly-CSharp/CrewVisualizer.cs b/Client/Assembly-CSharp/CrewVisualizer.cs new file mode 100644 index 0000000..31e26e7 --- /dev/null +++ b/Client/Assembly-CSharp/CrewVisualizer.cs @@ -0,0 +1,63 @@ +using System; +using System.Collections.Generic; +using UnityEngine; + +public class CrewVisualizer : MonoBehaviour +{ + public ObjectPoolBehavior CrewPool; + + public SpriteRenderer Background; + + public Sprite[] MapBackgrounds; + + public float yOffset = 0.4f; + + public FloatRange BgWidth; + + public void SetCrewSize(int numPlayers, int numImpostors) + { + this.CrewPool.ReclaimAll(); + int num = numPlayers / 2; + int num2 = Mathf.CeilToInt((float)numPlayers / 2f); + List<SpriteRenderer> list = new List<SpriteRenderer>(); + Vector3 localPosition = new Vector3(0f, 0f, -1f); + for (int i = 0; i < numPlayers; i++) + { + SpriteRenderer component = this.CrewPool.Get<PoolableBehavior>().GetComponent<SpriteRenderer>(); + component.color = Color.white; + list.Add(component); + if (i < num) + { + float num3 = Mathf.Clamp((float)num / 5f * 1.3f, 0f, 1f) * 0.85f; + localPosition.z = -1.5f; + localPosition.y = -this.yOffset; + localPosition.x = this.BgWidth.Lerp((float)i / ((float)num - 1f)) * num3; + } + else + { + float num4 = Mathf.Clamp((float)num2 / 5f * 1.3f, 0f, 1f); + localPosition.z = -1f; + localPosition.y = this.yOffset; + localPosition.x = this.BgWidth.Lerp((float)(i - num) / ((float)num2 - 1f)) * num4; + } + component.transform.localPosition = localPosition; + } + int j = 0; + int num5 = 0; + while (j < numImpostors) + { + if (BoolRange.Next(1f / (float)list.Count)) + { + j++; + list[num5].color = Color.red; + list.RemoveAt(num5); + } + num5 = (num5 + 1) % list.Count; + } + } + + public void SetMap(int mapid) + { + this.Background.sprite = this.MapBackgrounds[mapid]; + } +} diff --git a/Client/Assembly-CSharp/CrossFadeImages.cs b/Client/Assembly-CSharp/CrossFadeImages.cs new file mode 100644 index 0000000..912bf23 --- /dev/null +++ b/Client/Assembly-CSharp/CrossFadeImages.cs @@ -0,0 +1,20 @@ +using System; +using UnityEngine; + +public class CrossFadeImages : MonoBehaviour +{ + public SpriteRenderer Image1; + + public SpriteRenderer Image2; + + public float Period = 5f; + + private void Update() + { + Color white = Color.white; + white.a = Mathf.Clamp((Mathf.Sin(3.1415927f * Time.time / this.Period) + 0.75f) * 0.75f, 0f, 1f); + this.Image1.color = white; + white.a = 1f - white.a; + this.Image2.color = white; + } +} diff --git a/Client/Assembly-CSharp/CrossFader.cs b/Client/Assembly-CSharp/CrossFader.cs new file mode 100644 index 0000000..39ccf82 --- /dev/null +++ b/Client/Assembly-CSharp/CrossFader.cs @@ -0,0 +1,74 @@ +using System; +using UnityEngine; + +public class CrossFader : ISoundPlayer +{ + public string Name { get; set; } + + public AudioSource Player { get; set; } + + public float MaxVolume = 1f; + + public AudioClip target; + + public float Duration = 1.5f; + + private float timer; + + private bool didSwitch; + + public void Update(float dt) + { + if (this.timer < this.Duration) + { + this.timer += dt; + float num = this.timer / this.Duration; + if (num < 0.5f) + { + this.Player.volume = (1f - num * 2f) * this.MaxVolume; + return; + } + if (!this.didSwitch) + { + this.didSwitch = true; + this.Player.Stop(); + this.Player.clip = this.target; + if (this.target) + { + this.Player.Play(); + } + } + this.Player.volume = (num - 0.5f) * 2f * this.MaxVolume; + } + } + + public void SetTarget(AudioClip clip) + { + if (!this.Player.clip) + { + this.didSwitch = false; + this.Player.volume = 0f; + this.timer = 0.5f; + } + else + { + if (this.Player.clip == clip) + { + return; + } + if (this.didSwitch) + { + this.didSwitch = false; + if (this.timer >= this.Duration) + { + this.timer = 0f; + } + else + { + this.timer = this.Duration - this.timer; + } + } + } + this.target = clip; + } +} diff --git a/Client/Assembly-CSharp/CrystalBehaviour.cs b/Client/Assembly-CSharp/CrystalBehaviour.cs new file mode 100644 index 0000000..ebb7b2b --- /dev/null +++ b/Client/Assembly-CSharp/CrystalBehaviour.cs @@ -0,0 +1,110 @@ +using System; +using System.Collections; +using UnityEngine; + +public class CrystalBehaviour : MonoBehaviour +{ + public CrystalBehaviour Above; + + public CrystalBehaviour Below; + + public CrystalBehaviour.Parentness ParentSide; + + public SpriteRenderer Renderer; + + public BoxCollider2D Collider; + + public FloatRange Padding; + + private const float Speed = 15f; + + private const float FloatMag = 0.05f; + + private const float FloatSpeed = 0.35f; + + public enum Parentness + { + None, + Above, + Below + } + + private void Update() + { + Vector3 position = base.transform.position; + Vector3 vector; + if (this.ParentSide == CrystalBehaviour.Parentness.Above) + { + if (!this.Above) + { + return; + } + vector = this.Above.transform.position - new Vector3(0f, this.Above.Padding.min + this.Padding.max, 0f); + } + else + { + if (this.ParentSide != CrystalBehaviour.Parentness.Below) + { + return; + } + if (!this.Below) + { + return; + } + vector = this.Below.transform.position + new Vector3(0f, this.Below.Padding.max + this.Padding.min, 0f); + } + float num = Time.time / 0.35f; + vector.x += (Mathf.PerlinNoise(num, position.z * 20f) * 2f - 1f) * 0.05f; + vector.y += (Mathf.PerlinNoise(position.z * 20f, num) * 2f - 1f) * 0.05f; + vector.z = position.z; + position.x = Mathf.SmoothStep(position.x, vector.x, Time.deltaTime * 15f); + position.y = Mathf.SmoothStep(position.y, vector.y, Time.deltaTime * 15f); + base.transform.position = position; + } + + public void FlashUp(float delay = 0f) + { + base.StopAllCoroutines(); + base.StartCoroutine(CrystalBehaviour.Flash(this, delay)); + if (this.Above) + { + this.Above.FlashUp(delay + 0.1f); + } + } + + public void FlashDown(float delay = 0f) + { + base.StopAllCoroutines(); + base.StartCoroutine(CrystalBehaviour.Flash(this, delay)); + if (this.Below) + { + this.Below.FlashDown(delay + 0.1f); + } + } + + private static IEnumerator Flash(CrystalBehaviour c, float delay) + { + for (float time = 0f; time < delay; time += Time.deltaTime) + { + yield return null; + } + Color col = Color.clear; + for (float time = 0f; time < 0.1f; time += Time.deltaTime) + { + float t = time / 0.1f; + col.r = (col.g = (col.b = Mathf.Lerp(0f, 1f, t))); + c.Renderer.material.SetColor("_AddColor", col); + yield return null; + } + for (float time = 0f; time < 0.1f; time += Time.deltaTime) + { + float t2 = time / 0.1f; + col.r = (col.g = (col.b = Mathf.Lerp(1f, 0f, t2))); + c.Renderer.material.SetColor("_AddColor", col); + yield return null; + } + col.r = (col.g = (col.b = 0f)); + c.Renderer.material.SetColor("_AddColor", col); + yield break; + } +} diff --git a/Client/Assembly-CSharp/CrystalMinigame.cs b/Client/Assembly-CSharp/CrystalMinigame.cs new file mode 100644 index 0000000..6e749f0 --- /dev/null +++ b/Client/Assembly-CSharp/CrystalMinigame.cs @@ -0,0 +1,120 @@ +using System; +using UnityEngine; + +public class CrystalMinigame : Minigame +{ + public CrystalBehaviour[] CrystalPieces; + + public FloatRange XRange; + + public FloatRange YRange; + + private Controller myController = new Controller(); + + public override void Begin(PlayerTask task) + { + base.Begin(task); + for (int i = 0; i < this.CrystalPieces.Length; i++) + { + this.CrystalPieces[i].transform.localPosition = new Vector3(this.XRange.Next(), this.YRange.Next(), ((float)i - (float)this.CrystalPieces.Length / 2f) / 100f); + } + } + + public void Update() + { + this.myController.Update(); + for (int i = 0; i < this.CrystalPieces.Length; i++) + { + CrystalBehaviour crystalBehaviour = this.CrystalPieces[i]; + switch (this.myController.CheckDrag(crystalBehaviour.Collider, false)) + { + case DragState.TouchStart: + this.Spread(i); + break; + case DragState.Dragging: + { + Vector3 position = this.myController.DragPosition; + position.z = base.transform.position.z; + crystalBehaviour.transform.position = position; + break; + } + case DragState.Released: + this.CheckSolution(); + break; + } + } + } + + private void Spread(int parent) + { + for (int i = 0; i < this.CrystalPieces.Length; i++) + { + if (i < parent) + { + this.CrystalPieces[i].ParentSide = CrystalBehaviour.Parentness.Below; + } + else if (i > parent) + { + this.CrystalPieces[i].ParentSide = CrystalBehaviour.Parentness.Above; + } + else + { + this.CrystalPieces[i].ParentSide = CrystalBehaviour.Parentness.None; + } + } + } + + private void CheckSolution() + { + bool flag = false; + for (int i = 0; i < this.CrystalPieces.Length; i++) + { + CrystalBehaviour crystalBehaviour = this.CrystalPieces[i]; + Vector3 position = crystalBehaviour.transform.position; + if (!crystalBehaviour.Above && i - 1 > -1) + { + CrystalBehaviour crystalBehaviour2 = this.CrystalPieces[i - 1]; + if (CrystalMinigame.AreTouching(crystalBehaviour2.Collider, crystalBehaviour.Collider)) + { + crystalBehaviour.Above = crystalBehaviour2; + crystalBehaviour2.Below = crystalBehaviour; + crystalBehaviour.FlashUp(0f); + } + else + { + flag = true; + } + } + if (!crystalBehaviour.Below && i + 1 < this.CrystalPieces.Length) + { + CrystalBehaviour crystalBehaviour3 = this.CrystalPieces[i + 1]; + if (CrystalMinigame.AreTouching(crystalBehaviour3.Collider, crystalBehaviour.Collider)) + { + crystalBehaviour.Below = crystalBehaviour3; + crystalBehaviour3.Above = crystalBehaviour; + crystalBehaviour.FlashDown(0f); + } + else + { + flag = true; + } + } + } + if (!flag) + { + this.MyNormTask.Complete(); + base.StartCoroutine(base.CoStartClose(0.75f)); + } + } + + private static bool AreTouching(BoxCollider2D a, BoxCollider2D b) + { + Vector2 a2 = a.transform.position + a.offset; + Vector2 a3 = b.transform.position + b.offset; + Vector2 vector = a2 - a.size / 2f; + Vector2 vector2 = a3 - b.size / 2f; + Vector2 vector3 = a2 + a.size / 2f; + Vector2 vector4 = a3 + b.size / 2f; + return ((vector.y < vector4.y && vector.y > vector2.y) || (vector3.y < vector4.y && vector3.y > vector2.y)) && ((vector.x < vector4.x && vector.x > vector2.x) || (vector3.x < vector4.x && vector3.x > vector2.x)); + } +} diff --git a/Client/Assembly-CSharp/CustomNetworkTransform.cs b/Client/Assembly-CSharp/CustomNetworkTransform.cs new file mode 100644 index 0000000..98a1969 --- /dev/null +++ b/Client/Assembly-CSharp/CustomNetworkTransform.cs @@ -0,0 +1,265 @@ +using System; +using Hazel; +using InnerNet; +using UnityEngine; + +//c 角色的位置和速度数据 +[DisallowMultipleComponent] +public class CustomNetworkTransform : InnerNetObject +{ + private const float LocalMovementThreshold = 0.0001f; + + private const float LocalVelocityThreshold = 0.0001f; + + private const float MoveAheadRatio = 0.1f; + + private readonly FloatRange XRange = new FloatRange(-40f, 40f); + + private readonly FloatRange YRange = new FloatRange(-40f, 40f); + + // 用来辅助设置位置 + [SerializeField] + private float sendInterval = 0.1f; + + [SerializeField] + private float snapThreshold = 5f; + + [SerializeField] + private float interpolateMovement = 1f; + + private Rigidbody2D body; + + private Vector2 targetSyncPosition; + + private Vector2 targetSyncVelocity; + + private ushort lastSequenceId; + + private Vector2 prevPosSent; + + private Vector2 prevVelSent; + + private enum RpcCalls + { + SnapTo + } + + private void Awake() + { + this.body = base.GetComponent<Rigidbody2D>(); + this.targetSyncPosition = (this.prevPosSent = base.transform.position); + this.targetSyncVelocity = (this.prevVelSent = Vector2.zero); + } + + public void OnEnable() + { + base.SetDirtyBit(3U); + } + + public void Halt() + { + ushort minSid = this.lastSequenceId + 1; + this.SnapTo(base.transform.position, minSid); + } + + public void RpcSnapTo(Vector2 position) + { + ushort minSid = this.lastSequenceId + 5; + if (AmongUsClient.Instance.AmClient) + { + this.SnapTo(position, minSid); + } + MessageWriter messageWriter = AmongUsClient.Instance.StartRpc(this.NetId, 0, SendOption.Reliable); + this.WriteVector2(position, messageWriter); + messageWriter.Write(this.lastSequenceId); + messageWriter.EndMessage(); + } + + public void SnapTo(Vector2 position) + { + ushort minSid = this.lastSequenceId + 3; + this.SnapTo(position, minSid); + } + + private void SnapTo(Vector2 position, ushort minSid) + { + if (!CustomNetworkTransform.SidGreaterThan(minSid, this.lastSequenceId)) + { + return; + } + this.lastSequenceId = minSid; + Transform transform = base.transform; + this.body.position = position; + this.targetSyncPosition = position; + transform.position = position; + this.targetSyncVelocity = (this.body.velocity = Vector2.zero); + this.prevPosSent = position; + this.prevVelSent = Vector2.zero; + } + + private void FixedUpdate() + { + if (base.AmOwner) + { + if (this.HasMoved()) + { + base.SetDirtyBit(3U); + return; + } + } + else + { + if (this.interpolateMovement != 0f) + { + Vector2 vector = this.targetSyncPosition - this.body.position; + if (vector.sqrMagnitude >= 0.0001f) + { + float num = this.interpolateMovement / this.sendInterval; + vector.x *= num; + vector.y *= num; + if (PlayerControl.LocalPlayer) + { + vector = Vector2.ClampMagnitude(vector, PlayerControl.LocalPlayer.MyPhysics.TrueSpeed); + } + this.body.velocity = vector; + } + else + { + this.body.velocity = Vector2.zero; + } + } + this.targetSyncPosition += this.targetSyncVelocity * Time.fixedDeltaTime * 0.1f; + } + } + + private bool HasMoved() + { + float num; + if (this.body != null) + { + num = Vector2.Distance(this.body.position, this.prevPosSent); + } + else + { + num = Vector2.Distance(base.transform.position, this.prevPosSent); + } + if (num > 0.0001f) + { + return true; + } + if (this.body != null) + { + num = Vector2.Distance(this.body.velocity, this.prevVelSent); + } + return num > 0.0001f; + } + + public override void HandleRpc(byte callId, MessageReader reader) + { + if (!base.isActiveAndEnabled) + { + return; + } + if (callId == 0) + { + Vector2 position = this.ReadVector2(reader); + ushort minSid = reader.ReadUInt16(); + this.SnapTo(position, minSid); + } + } + + //c 序列化角色位置数据 + public override bool Serialize(MessageWriter writer, bool initialState) + { + if (initialState) + { + writer.Write(this.lastSequenceId); + this.WriteVector2(this.body.position, writer); + this.WriteVector2(this.body.velocity, writer); + return true; + } + if (this.DirtyBits == 0U) + { + return false; + } + if (!base.isActiveAndEnabled) + { + this.DirtyBits = 0U; + return false; + } + this.lastSequenceId += 1; + writer.Write(this.lastSequenceId); + this.WriteVector2(this.body.position, writer); + this.WriteVector2(this.body.velocity, writer); + this.prevPosSent = this.body.position; + this.prevVelSent = this.body.velocity; + this.DirtyBits -= 1U; + return true; + } + + //c 反序列化角色数据 + public override void Deserialize(MessageReader reader, bool initialState) + { + if (initialState) + { + this.lastSequenceId = reader.ReadUInt16(); + this.targetSyncPosition = (base.transform.position = this.ReadVector2(reader)); + this.targetSyncVelocity = this.ReadVector2(reader); + return; + } + ushort newSid = reader.ReadUInt16(); + if (!CustomNetworkTransform.SidGreaterThan(newSid, this.lastSequenceId)) + { + return; + } + this.lastSequenceId = newSid; + if (!base.isActiveAndEnabled) + { + return; + } + this.targetSyncPosition = this.ReadVector2(reader); + this.targetSyncVelocity = this.ReadVector2(reader); + // 当本地计算的位置数据和网络传输的位置数据差别大于snapThreshold的时候直接用消息里的位置和速度数据 + if (Vector2.Distance(this.body.position, this.targetSyncPosition) > this.snapThreshold) + { + if (this.body) + { + this.body.position = this.targetSyncPosition; + this.body.velocity = this.targetSyncVelocity; + } + else + { + base.transform.position = this.targetSyncPosition; + } + } + if (this.interpolateMovement == 0f && this.body) + { + this.body.position = this.targetSyncPosition; + } + } + + private static bool SidGreaterThan(ushort newSid, ushort prevSid) + { + ushort num = prevSid + 32767; + if (prevSid < num) + { + return newSid > prevSid && newSid <= num; + } + return newSid > prevSid || newSid <= num; + } + + private void WriteVector2(Vector2 vec, MessageWriter writer) + { + ushort value = (ushort)(this.XRange.ReverseLerp(vec.x) * 65535f); + ushort value2 = (ushort)(this.YRange.ReverseLerp(vec.y) * 65535f); + writer.Write(value); + writer.Write(value2); + } + + private Vector2 ReadVector2(MessageReader reader) + { + float v = (float)reader.ReadUInt16() / 65535f; + float v2 = (float)reader.ReadUInt16() / 65535f; + return new Vector2(this.XRange.Lerp(v), this.YRange.Lerp(v2)); + } +} diff --git a/Client/Assembly-CSharp/CustomPlayerMenu.cs b/Client/Assembly-CSharp/CustomPlayerMenu.cs new file mode 100644 index 0000000..9213223 --- /dev/null +++ b/Client/Assembly-CSharp/CustomPlayerMenu.cs @@ -0,0 +1,41 @@ +using System; +using UnityEngine; + +public class CustomPlayerMenu : MonoBehaviour +{ + public static CustomPlayerMenu Instance; + + public TabButton[] Tabs; + + public Sprite NormalColor; + + public Sprite SelectedColor; + + public void Start() + { + CustomPlayerMenu.Instance = this; + } + + public void OpenTab(GameObject tab) + { + for (int i = 0; i < this.Tabs.Length; i++) + { + TabButton tabButton = this.Tabs[i]; + if (tabButton.Tab == tab) + { + tabButton.Tab.SetActive(true); + tabButton.Button.sprite = this.SelectedColor; + } + else + { + tabButton.Tab.SetActive(false); + tabButton.Button.sprite = this.NormalColor; + } + } + } + + public void Close(bool canMove) + { + UnityEngine.Object.Destroy(base.gameObject); + } +} diff --git a/Client/Assembly-CSharp/DataCollectScreen.cs b/Client/Assembly-CSharp/DataCollectScreen.cs new file mode 100644 index 0000000..7f89568 --- /dev/null +++ b/Client/Assembly-CSharp/DataCollectScreen.cs @@ -0,0 +1,56 @@ +using System; +using System.Collections; +using UnityEngine; + +public class DataCollectScreen : MonoBehaviour +{ + public static DataCollectScreen Instance; + + public ToggleButtonBehaviour SendNameButton; + + public ToggleButtonBehaviour SendTelemButton; + + public AdDataCollectScreen AdPolicy; + + private void Start() + { + DataCollectScreen.Instance = this; + this.UpdateButtons(); + } + + public IEnumerator Show() + { + if (!SaveManager.SendDataScreen) + { + base.gameObject.SetActive(true); + while (base.gameObject.activeSelf) + { + yield return null; + } + } + yield break; + } + + public void Close() + { + SaveManager.SendDataScreen = true; + } + + public void ToggleSendTelemetry() + { + SaveManager.SendTelemetry = !SaveManager.SendTelemetry; + this.UpdateButtons(); + } + + public void ToggleSendName() + { + SaveManager.SendName = !SaveManager.SendName; + this.UpdateButtons(); + } + + public void UpdateButtons() + { + this.SendNameButton.UpdateText(SaveManager.SendName); + this.SendTelemButton.UpdateText(SaveManager.SendTelemetry); + } +} diff --git a/Client/Assembly-CSharp/DeadBody.cs b/Client/Assembly-CSharp/DeadBody.cs new file mode 100644 index 0000000..5cab24a --- /dev/null +++ b/Client/Assembly-CSharp/DeadBody.cs @@ -0,0 +1,35 @@ +using System; +using UnityEngine; + +public class DeadBody : MonoBehaviour +{ + public Vector2 TruePosition + { + get + { + return base.transform.position + this.myCollider.offset; + } + } + + public bool Reported; + + public short KillIdx; + + public byte ParentId; + + public Collider2D myCollider; + + public void OnClick() + { + if (this.Reported) + { + return; + } + if (!PhysicsHelpers.AnythingBetween(PlayerControl.LocalPlayer.GetTruePosition(), this.TruePosition, Constants.ShipAndObjectsMask, false)) + { + this.Reported = true; + GameData.PlayerInfo playerById = GameData.Instance.GetPlayerById(this.ParentId); + PlayerControl.LocalPlayer.CmdReportDeadBody(playerById); + } + } +} diff --git a/Client/Assembly-CSharp/DeathReason.cs b/Client/Assembly-CSharp/DeathReason.cs new file mode 100644 index 0000000..f5d99e5 --- /dev/null +++ b/Client/Assembly-CSharp/DeathReason.cs @@ -0,0 +1,8 @@ +using System; + +public enum DeathReason +{ + Exile, + Kill, + Disconnect +} diff --git a/Client/Assembly-CSharp/DeconSystem.cs b/Client/Assembly-CSharp/DeconSystem.cs new file mode 100644 index 0000000..0eb0b9d --- /dev/null +++ b/Client/Assembly-CSharp/DeconSystem.cs @@ -0,0 +1,163 @@ +using System; +using Hazel; +using UnityEngine; + +public class DeconSystem : MonoBehaviour, ISystemType +{ + private const byte HeadUpCmd = 1; + + private const byte HeadDownCmd = 2; + + private const byte HeadUpInsideCmd = 3; + + private const byte HeadDownInsideCmd = 4; + + public ManualDoor UpperDoor; + + public ManualDoor LowerDoor; + + public float DoorOpenTime = 5f; + + public float DeconTime = 5f; + + private DeconSystem.States curState; + + private float timer; + + public TextRenderer FloorText; + + [Flags] + private enum States : byte + { + Idle = 0, + Enter = 1, + Closed = 2, + Exit = 4, + HeadingUp = 8 + } + + public bool Detoriorate(float dt) + { + int num = Mathf.CeilToInt(this.timer); + this.timer = Mathf.Max(0f, this.timer - dt); + int num2 = Mathf.CeilToInt(this.timer); + if (num != num2) + { + if (num2 == 0) + { + if (this.curState.HasFlag(DeconSystem.States.Enter)) + { + this.curState = ((this.curState & ~DeconSystem.States.Enter) | DeconSystem.States.Closed); + this.timer = this.DeconTime; + } + else if (this.curState.HasFlag(DeconSystem.States.Closed)) + { + this.curState = ((this.curState & ~DeconSystem.States.Closed) | DeconSystem.States.Exit); + this.timer = this.DoorOpenTime; + } + else if (this.curState.HasFlag(DeconSystem.States.Exit)) + { + this.curState = DeconSystem.States.Idle; + } + } + this.UpdateDoorsViaState(); + return true; + } + return false; + } + + public void OpenDoor(bool upper) + { + if (this.curState == DeconSystem.States.Idle) + { + ShipStatus.Instance.RpcRepairSystem(SystemTypes.Decontamination, upper ? 2 : 1); + } + } + + public void OpenFromInside(bool upper) + { + if (this.curState == DeconSystem.States.Idle) + { + ShipStatus.Instance.RpcRepairSystem(SystemTypes.Decontamination, upper ? 3 : 4); + } + } + + public void RepairDamage(PlayerControl player, byte amount) + { + if (this.curState != DeconSystem.States.Idle) + { + return; + } + switch (amount) + { + case 1: + this.curState = (DeconSystem.States.Enter | DeconSystem.States.HeadingUp); + this.timer = this.DoorOpenTime; + break; + case 2: + this.curState = DeconSystem.States.Enter; + this.timer = this.DoorOpenTime; + break; + case 3: + this.curState = (DeconSystem.States.Exit | DeconSystem.States.HeadingUp); + this.timer = this.DoorOpenTime; + break; + case 4: + this.curState = DeconSystem.States.Exit; + this.timer = this.DoorOpenTime; + break; + } + this.UpdateDoorsViaState(); + } + + public void Serialize(MessageWriter writer, bool initialState) + { + writer.Write((byte)Mathf.CeilToInt(this.timer)); + writer.Write((byte)this.curState); + } + + public void Deserialize(MessageReader reader, bool initialState) + { + this.timer = (float)reader.ReadByte(); + this.curState = (DeconSystem.States)reader.ReadByte(); + this.UpdateDoorsViaState(); + } + + private void UpdateDoorsViaState() + { + int num = Mathf.CeilToInt(this.timer); + if (num > 0) + { + this.FloorText.Text = string.Join("\n", new object[] + { + num, + num, + num, + num + }); + } + else + { + this.FloorText.Text = string.Empty; + } + if (this.curState.HasFlag(DeconSystem.States.Enter)) + { + bool flag = this.curState.HasFlag(DeconSystem.States.HeadingUp); + this.LowerDoor.SetDoorway(flag); + this.UpperDoor.SetDoorway(!flag); + return; + } + if (this.curState.HasFlag(DeconSystem.States.Closed) || this.curState == DeconSystem.States.Idle) + { + this.LowerDoor.SetDoorway(false); + this.UpperDoor.SetDoorway(false); + return; + } + if (this.curState.HasFlag(DeconSystem.States.Exit)) + { + bool flag2 = this.curState.HasFlag(DeconSystem.States.HeadingUp); + this.LowerDoor.SetDoorway(!flag2); + this.UpperDoor.SetDoorway(flag2); + } + } +} diff --git a/Client/Assembly-CSharp/DefaultPool.cs b/Client/Assembly-CSharp/DefaultPool.cs new file mode 100644 index 0000000..676c666 --- /dev/null +++ b/Client/Assembly-CSharp/DefaultPool.cs @@ -0,0 +1,82 @@ +using System; +using UnityEngine; + +public class DefaultPool : IObjectPool +{ + public override int InUse + { + get + { + return 0; + } + } + + public override int NotInUse + { + get + { + return 0; + } + } + + public static bool InstanceExists + { + get + { + return DefaultPool._instance; + } + } + + public static DefaultPool Instance + { + get + { + object @lock = DefaultPool._lock; + DefaultPool instance; + lock (@lock) + { + if (DefaultPool._instance == null) + { + DefaultPool._instance = UnityEngine.Object.FindObjectOfType<DefaultPool>(); + if (UnityEngine.Object.FindObjectsOfType<DefaultPool>().Length > 1) + { + Debug.LogError("[Singleton] Something went really wrong - there should never be more than 1 singleton! Reopening the scene might fix it."); + return DefaultPool._instance; + } + if (DefaultPool._instance == null) + { + GameObject gameObject = new GameObject(); + DefaultPool._instance = gameObject.AddComponent<DefaultPool>(); + gameObject.name = "(singleton) DefaultPool"; + } + } + instance = DefaultPool._instance; + } + return instance; + } + } + + private static DefaultPool _instance; + + private static object _lock = new object(); + + public void OnDestroy() + { + object @lock = DefaultPool._lock; + lock (@lock) + { + DefaultPool._instance = null; + } + } + + public override T Get<T>() + { + throw new NotImplementedException(); + } + + public override void Reclaim(PoolableBehavior obj) + { + Debug.Log("Default Pool: Destroying this thing."); + UnityEngine.Object.Destroy(obj.gameObject); + } +} diff --git a/Client/Assembly-CSharp/DemoKeyboardStick.cs b/Client/Assembly-CSharp/DemoKeyboardStick.cs new file mode 100644 index 0000000..bacd4d9 --- /dev/null +++ b/Client/Assembly-CSharp/DemoKeyboardStick.cs @@ -0,0 +1,25 @@ +using System; +using UnityEngine; + +public class DemoKeyboardStick : VirtualJoystick +{ + public SpriteRenderer UpKey; + + public SpriteRenderer DownKey; + + public SpriteRenderer LeftKey; + + public SpriteRenderer RightKey; + + protected override void FixedUpdate() + { + } + + public override void UpdateJoystick(FingerBehaviour finger, Vector2 velocity, bool syncFinger) + { + this.UpKey.enabled = (velocity.y > 0.1f); + this.DownKey.enabled = (velocity.y < -0.1f); + this.RightKey.enabled = (velocity.x > 0.1f); + this.LeftKey.enabled = (velocity.x < -0.1f); + } +} diff --git a/Client/Assembly-CSharp/DestroyableSingleton.cs b/Client/Assembly-CSharp/DestroyableSingleton.cs new file mode 100644 index 0000000..bcd8319 --- /dev/null +++ b/Client/Assembly-CSharp/DestroyableSingleton.cs @@ -0,0 +1,58 @@ +using System; +using UnityEngine; + +public class DestroyableSingleton<T> : MonoBehaviour where T : MonoBehaviour +{ + public static bool InstanceExists + { + get + { + return DestroyableSingleton<T>._instance; + } + } + + public static T Instance + { + get + { + if (!DestroyableSingleton<T>._instance) + { + DestroyableSingleton<T>._instance = UnityEngine.Object.FindObjectOfType<T>(); + if (!DestroyableSingleton<T>._instance) + { + DestroyableSingleton<T>._instance = new GameObject().AddComponent<T>(); + } + } + return DestroyableSingleton<T>._instance; + } + } + + private static T _instance; + + public bool DontDestroy; + + public virtual void Awake() + { + if (!DestroyableSingleton<T>._instance) + { + DestroyableSingleton<T>._instance = (this as T); + if (this.DontDestroy) + { + UnityEngine.Object.DontDestroyOnLoad(base.gameObject); + return; + } + } + else if (DestroyableSingleton<T>._instance != this) + { + UnityEngine.Object.Destroy(base.gameObject); + } + } + + public virtual void OnDestroy() + { + if (!this.DontDestroy) + { + DestroyableSingleton<T>._instance = default(T); + } + } +} diff --git a/Client/Assembly-CSharp/DialBehaviour.cs b/Client/Assembly-CSharp/DialBehaviour.cs new file mode 100644 index 0000000..d306e24 --- /dev/null +++ b/Client/Assembly-CSharp/DialBehaviour.cs @@ -0,0 +1,46 @@ +using System; +using UnityEngine; + +public class DialBehaviour : MonoBehaviour +{ + public FloatRange DialRange; + + public Collider2D collider; + + public Controller myController = new Controller(); + + public float Value; + + public bool Engaged; + + public Transform DialTrans; + + public Transform DialShadTrans; + + public void Update() + { + this.Engaged = false; + this.myController.Update(); + DragState dragState = this.myController.CheckDrag(this.collider, false); + if (dragState == DragState.Dragging) + { + Vector2 vector = this.myController.DragPosition - base.transform.position; + float num = Vector2.up.AngleSigned(vector); + if (num < -180f) + { + num += 360f; + } + num = this.DialRange.Clamp(num); + this.SetValue(num); + this.Engaged = true; + } + } + + public void SetValue(float angle) + { + this.Value = angle; + Vector3 localEulerAngles = new Vector3(0f, 0f, angle); + this.DialTrans.localEulerAngles = localEulerAngles; + this.DialShadTrans.localEulerAngles = localEulerAngles; + } +} diff --git a/Client/Assembly-CSharp/DialogueBox.cs b/Client/Assembly-CSharp/DialogueBox.cs new file mode 100644 index 0000000..63fe612 --- /dev/null +++ b/Client/Assembly-CSharp/DialogueBox.cs @@ -0,0 +1,27 @@ +using System; +using UnityEngine; + +public class DialogueBox : MonoBehaviour +{ + public TextRenderer target; + + public void Show(string dialogue) + { + this.target.Text = dialogue; + if (Minigame.Instance) + { + Minigame.Instance.Close(); + Minigame.Instance.Close(); + } + PlayerControl.LocalPlayer.moveable = false; + PlayerControl.LocalPlayer.NetTransform.Halt(); + base.gameObject.SetActive(true); + } + + public void Hide() + { + base.gameObject.SetActive(false); + PlayerControl.LocalPlayer.moveable = true; + Camera.main.GetComponent<FollowerCamera>().Locked = false; + } +} diff --git a/Client/Assembly-CSharp/DisconnectPopup.cs b/Client/Assembly-CSharp/DisconnectPopup.cs new file mode 100644 index 0000000..6feeed5 --- /dev/null +++ b/Client/Assembly-CSharp/DisconnectPopup.cs @@ -0,0 +1,112 @@ +using System; +using InnerNet; + +public class DisconnectPopup : DestroyableSingleton<DisconnectPopup> +{ + public TextRenderer TextArea; + + public void Start() + { + if (DestroyableSingleton<DisconnectPopup>.Instance == this) + { + this.Show(); + } + } + + public void Show() + { + base.gameObject.SetActive(true); + this.DoShow(); + } + + private void DoShow() + { + if (DestroyableSingleton<WaitForHostPopup>.InstanceExists) + { + DestroyableSingleton<WaitForHostPopup>.Instance.Hide(); + } + if (!AmongUsClient.Instance) + { + base.gameObject.SetActive(false); + return; + } + string text = InnerNetClient.IntToGameName(AmongUsClient.Instance.GameId); + string str = (text != null) ? (" from " + text) : " from the room"; + DisconnectReasons lastDisconnectReason = AmongUsClient.Instance.LastDisconnectReason; + switch (lastDisconnectReason) + { + case DisconnectReasons.ExitGame: + case DisconnectReasons.Destroy: + base.gameObject.SetActive(false); + break; + case DisconnectReasons.GameFull: + this.TextArea.Text = "The game you tried to join is full.\r\n\r\nCheck with the host to see if you can join next round."; + return; + case DisconnectReasons.GameStarted: + this.TextArea.Text = "The game you tried to join already started.\r\n\r\nCheck with the host to see if you can join next round."; + return; + case DisconnectReasons.GameNotFound: + case DisconnectReasons.IncorrectGame: + this.TextArea.Text = "Could not find the game you're looking for."; + return; + case (DisconnectReasons)4: + case (DisconnectReasons)9: + case (DisconnectReasons)10: + case (DisconnectReasons)11: + case (DisconnectReasons)12: + case (DisconnectReasons)13: + case (DisconnectReasons)14: + case (DisconnectReasons)15: + break; + case DisconnectReasons.IncorrectVersion: + this.TextArea.Text = "You are running an older version of the game.\r\n\r\nPlease update to play with others."; + return; + case DisconnectReasons.Banned: + this.TextArea.Text = "You were banned" + str + ".\r\n\r\nYou cannot rejoin that room."; + return; + case DisconnectReasons.Kicked: + this.TextArea.Text = "You were kicked" + str + ".\r\n\r\nYou can rejoin if the room hasn't started."; + return; + case DisconnectReasons.Custom: + this.TextArea.Text = (AmongUsClient.Instance.LastCustomDisconnect ?? "An unknown error disconnected you from the server."); + return; + case DisconnectReasons.Error: + if (AmongUsClient.Instance.GameMode == GameModes.OnlineGame) + { + this.TextArea.Text = "You disconnected from the server.\r\nIf this happens often, check your network strength.\r\nThis may also be a server issue."; + return; + } + this.TextArea.Text = "You disconnected from the host.\r\n\r\nIf this happens often, check your WiFi strength."; + return; + case DisconnectReasons.ServerRequest: + this.TextArea.Text = "The server stopped this game. Possibly due to inactivity."; + return; + case DisconnectReasons.ServerFull: + this.TextArea.Text = "The Among Us servers are overloaded.\r\n\r\nSorry! Please try again later!"; + return; + default: + if (lastDisconnectReason == DisconnectReasons.IntentionalLeaving) + { + this.TextArea.Text = string.Format("You may not join another game for another {0} minutes after intentionally disconnecting.", StatsManager.Instance.BanMinutesLeft); + return; + } + if (lastDisconnectReason != DisconnectReasons.FocusLost) + { + return; + } + this.TextArea.Text = "You were disconnected because Among Us was suspended by another app."; + return; + } + } + + public void ShowCustom(string message) + { + base.gameObject.SetActive(true); + this.TextArea.Text = message; + } + + public void Close() + { + base.gameObject.SetActive(false); + } +} diff --git a/Client/Assembly-CSharp/DiscordManager.cs b/Client/Assembly-CSharp/DiscordManager.cs new file mode 100644 index 0000000..0ee1ea6 --- /dev/null +++ b/Client/Assembly-CSharp/DiscordManager.cs @@ -0,0 +1,207 @@ +using System; +using System.Collections; +using InnerNet; +using UnityEngine; +using UnityEngine.SceneManagement; + +public class DiscordManager : DestroyableSingleton<DiscordManager> +{ + private DiscordRpc.RichPresence presence = new DiscordRpc.RichPresence(); + + public DiscordRpc.DiscordUser joinRequest; + + private DateTime? StartTime; + + private static readonly DateTime epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); + + public void Start() + { + if (DestroyableSingleton<DiscordManager>.Instance == this) + { + DiscordRpc.EventHandlers eventHandlers = default(DiscordRpc.EventHandlers); + eventHandlers.errorCallback = (DiscordRpc.ErrorCallback)Delegate.Combine(eventHandlers.errorCallback, new DiscordRpc.ErrorCallback(this.HandleError)); + eventHandlers.disconnectedCallback = (DiscordRpc.DisconnectedCallback)Delegate.Combine(eventHandlers.disconnectedCallback, new DiscordRpc.DisconnectedCallback(this.HandleError)); + eventHandlers.joinCallback = (DiscordRpc.JoinCallback)Delegate.Combine(eventHandlers.joinCallback, new DiscordRpc.JoinCallback(this.HandleJoinRequest)); + eventHandlers.requestCallback = (DiscordRpc.RequestCallback)Delegate.Combine(eventHandlers.requestCallback, new DiscordRpc.RequestCallback(this.HandleAutoJoin)); + DiscordRpc.Initialize("477175586805252107", ref eventHandlers, true, null); + this.SetInMenus(); + SceneManager.sceneLoaded += delegate(Scene scene, LoadSceneMode mode) + { + this.OnSceneChange(scene.name); + }; + } + } + + private void HandleError(int errorCode, string message) + { + Debug.LogError(message ?? string.Format("No message: {0}", errorCode)); + } + + private void OnSceneChange(string name) + { + if (name == "MatchMaking" || name == "MMOnline" || name == "MainMenu") + { + this.SetInMenus(); + } + } + + public void FixedUpdate() + { + DiscordRpc.RunCallbacks(); + } + + public void SetInMenus() + { + this.ClearPresence(); + this.StartTime = null; + this.presence.state = "In Menus"; + this.presence.largeImageKey = "icon"; + DiscordRpc.UpdatePresence(this.presence); + } + + public void SetPlayingGame() + { + if (this.StartTime == null) + { + this.StartTime = new DateTime?(DateTime.UtcNow); + } + this.presence.state = "In Game"; + this.presence.details = "Playing"; + this.presence.largeImageKey = "icon"; + this.presence.startTimestamp = DiscordManager.ToUnixTime(this.StartTime.Value); + DiscordRpc.UpdatePresence(this.presence); + } + + public void SetHowToPlay() + { + this.ClearPresence(); + this.presence.state = "In Freeplay"; + this.presence.largeImageKey = "icon"; + DiscordRpc.UpdatePresence(this.presence); + } + + public void SetInLobbyClient() + { + if (this.StartTime == null) + { + this.StartTime = new DateTime?(DateTime.UtcNow); + } + this.ClearPresence(); + this.presence.state = "In Lobby"; + this.presence.largeImageKey = "icon"; + this.presence.startTimestamp = DiscordManager.ToUnixTime(this.StartTime.Value); + DiscordRpc.UpdatePresence(this.presence); + } + + private void ClearPresence() + { + this.presence.startTimestamp = 0L; + this.presence.details = null; + this.presence.partyId = null; + this.presence.matchSecret = null; + this.presence.joinSecret = null; + this.presence.partySize = 0; + this.presence.partyMax = 0; + } + + public void SetInLobbyHost(int numPlayers, int gameId) + { + if (this.StartTime == null) + { + this.StartTime = new DateTime?(DateTime.UtcNow); + } + string text = InnerNetClient.IntToGameName(gameId); + this.presence.state = "In Lobby"; + this.presence.details = "Hosting a game"; + this.presence.partySize = numPlayers; + this.presence.partyMax = 10; + this.presence.smallImageKey = "icon"; + this.presence.largeImageText = "Ask to play!"; + this.presence.joinSecret = "join" + text; + this.presence.matchSecret = "match" + text; + this.presence.partyId = text; + DiscordRpc.UpdatePresence(this.presence); + } + + private void HandleAutoJoin(ref DiscordRpc.DiscordUser requestUser) + { + Debug.Log("Discord: request from " + requestUser.username); + if (AmongUsClient.Instance.IsGameStarted) + { + this.RequestRespondNo(); + return; + } + this.RequestRespondYes(); + } + + private void HandleJoinRequest(string joinSecret) + { + if (!joinSecret.StartsWith("join")) + { + Debug.LogWarning("Invalid join secret: " + joinSecret); + return; + } + if (!AmongUsClient.Instance) + { + Debug.LogWarning("Missing AmongUsClient"); + return; + } + if (!DestroyableSingleton<DiscordManager>.InstanceExists) + { + Debug.LogWarning("Missing DiscordManager"); + return; + } + if (AmongUsClient.Instance.mode != MatchMakerModes.None) + { + Debug.LogWarning("Already connected"); + return; + } + AmongUsClient.Instance.GameMode = GameModes.OnlineGame; + AmongUsClient.Instance.GameId = InnerNetClient.GameNameToInt(joinSecret.Substring(4)); + AmongUsClient.Instance.SetEndpoint(DestroyableSingleton<ServerManager>.Instance.OnlineNetAddress, 22023); + AmongUsClient.Instance.MainMenuScene = "MMOnline"; + AmongUsClient.Instance.OnlineScene = "OnlineGame"; + DestroyableSingleton<DiscordManager>.Instance.StopAllCoroutines(); + DestroyableSingleton<DiscordManager>.Instance.StartCoroutine(DestroyableSingleton<DiscordManager>.Instance.CoJoinGame()); + } + + public IEnumerator CoJoinGame() + { + while (DataCollectScreen.Instance && DataCollectScreen.Instance.isActiveAndEnabled) + { + yield return null; + } + AmongUsClient.Instance.Connect(MatchMakerModes.Client); + yield return AmongUsClient.Instance.WaitForConnectionOrFail(); + if (AmongUsClient.Instance.ClientId < 0) + { + SceneManager.LoadScene("MMOnline"); + } + yield break; + } + + public void RequestRespondYes() + { + DiscordRpc.Respond(this.joinRequest.userId, DiscordRpc.Reply.Yes); + } + + public void RequestRespondNo() + { + Debug.Log("Discord: responding no to Ask to Join request"); + DiscordRpc.Respond(this.joinRequest.userId, DiscordRpc.Reply.No); + } + + public override void OnDestroy() + { + base.OnDestroy(); + if (DestroyableSingleton<DiscordManager>.Instance == this) + { + DiscordRpc.Shutdown(); + } + } + + private static long ToUnixTime(DateTime time) + { + return (long)(time - DiscordManager.epoch).TotalSeconds; + } +} diff --git a/Client/Assembly-CSharp/DiscoveryState.cs b/Client/Assembly-CSharp/DiscoveryState.cs new file mode 100644 index 0000000..4da2cfc --- /dev/null +++ b/Client/Assembly-CSharp/DiscoveryState.cs @@ -0,0 +1,7 @@ +using System; + +public enum DiscoveryState +{ + Off, + Broadcast +} diff --git a/Client/Assembly-CSharp/DiscussBehaviour.cs b/Client/Assembly-CSharp/DiscussBehaviour.cs new file mode 100644 index 0000000..9a99207 --- /dev/null +++ b/Client/Assembly-CSharp/DiscussBehaviour.cs @@ -0,0 +1,65 @@ +using System; +using System.Collections; +using UnityEngine; + +public class DiscussBehaviour : MonoBehaviour +{ + public SpriteRenderer LeftPlayer; + + public SpriteRenderer RightPlayer; + + public SpriteRenderer Text; + + public FloatRange RotateRange = new FloatRange(-5f, 5f); + + public Vector2Range TextTarget; + + public AnimationCurve TextEasing; + + public float Delay = 0.1f; + + public float TextDuration = 0.5f; + + public float HoldDuration = 2f; + + private Vector3 vec; + + public IEnumerator PlayAnimation() + { + this.Text.transform.localPosition = this.TextTarget.min; + yield return this.AnimateText(); + yield return ShhhBehaviour.WaitWithInterrupt(this.HoldDuration); + yield break; + } + + public void Update() + { + this.vec.Set(0f, 0f, this.RotateRange.Lerp(Mathf.PerlinNoise(1f, Time.time * 8f))); + this.LeftPlayer.transform.eulerAngles = this.vec; + this.vec.Set(0f, 0f, this.RotateRange.Lerp(Mathf.PerlinNoise(2f, Time.time * 8f))); + this.RightPlayer.transform.eulerAngles = this.vec; + } + + private IEnumerator AnimateText() + { + for (float t = 0f; t < this.Delay; t += Time.deltaTime) + { + yield return null; + } + Vector3 vec = default(Vector3); + for (float t = 0f; t < this.TextDuration; t += Time.deltaTime) + { + float time = t / this.TextDuration; + this.UpdateText(ref vec, this.TextEasing.Evaluate(time)); + yield return null; + } + this.UpdateText(ref vec, 1f); + yield break; + } + + private void UpdateText(ref Vector3 vec, float p) + { + this.TextTarget.LerpUnclamped(ref vec, p, -7f); + this.Text.transform.localPosition = vec; + } +} diff --git a/Client/Assembly-CSharp/DivertPowerMetagame.cs b/Client/Assembly-CSharp/DivertPowerMetagame.cs new file mode 100644 index 0000000..1be1bf3 --- /dev/null +++ b/Client/Assembly-CSharp/DivertPowerMetagame.cs @@ -0,0 +1,25 @@ +using System; +using UnityEngine; + +public class DivertPowerMetagame : Minigame +{ + public Minigame DistributePrefab; + + public Minigame ReceivePrefab; + + public override void Begin(PlayerTask task) + { + base.Begin(task); + Minigame minigame; + if (this.MyNormTask.taskStep == 0) + { + minigame = UnityEngine.Object.Instantiate<Minigame>(this.DistributePrefab, base.transform.parent); + } + else + { + minigame = UnityEngine.Object.Instantiate<Minigame>(this.ReceivePrefab, base.transform.parent); + } + minigame.Begin(task); + UnityEngine.Object.Destroy(base.gameObject); + } +} diff --git a/Client/Assembly-CSharp/DivertPowerMinigame.cs b/Client/Assembly-CSharp/DivertPowerMinigame.cs new file mode 100644 index 0000000..64aa786 --- /dev/null +++ b/Client/Assembly-CSharp/DivertPowerMinigame.cs @@ -0,0 +1,91 @@ +using System; +using UnityEngine; + +public class DivertPowerMinigame : Minigame +{ + public SystemTypes[] SliderOrder = new SystemTypes[] + { + SystemTypes.LowerEngine, + SystemTypes.UpperEngine, + SystemTypes.Weapons, + SystemTypes.Shields, + SystemTypes.Nav, + SystemTypes.Comms, + SystemTypes.LifeSupp, + SystemTypes.Security + }; + + public Collider2D[] Sliders; + + public LineRenderer[] Wires; + + public VerticalGauge[] Gauges; + + private int sliderId; + + public FloatRange SliderY = new FloatRange(-1f, 1f); + + private Controller myController = new Controller(); + + public override void Begin(PlayerTask task) + { + base.Begin(task); + DivertPowerTask powerTask = (DivertPowerTask)task; + this.sliderId = this.SliderOrder.IndexOf((SystemTypes t) => t == powerTask.TargetSystem); + for (int i = 0; i < this.Sliders.Length; i++) + { + if (i != this.sliderId) + { + this.Sliders[i].GetComponent<SpriteRenderer>().color = new Color(0.5f, 0.5f, 0.5f); + } + } + } + + public void FixedUpdate() + { + this.myController.Update(); + float num = 0f; + for (int i = 0; i < this.Sliders.Length; i++) + { + num += this.SliderY.ReverseLerp(this.Sliders[i].transform.localPosition.y) / (float)this.Sliders.Length; + } + for (int j = 0; j < this.Sliders.Length; j++) + { + float num2 = this.SliderY.ReverseLerp(this.Sliders[j].transform.localPosition.y); + float num3 = num2 / num / 1.6f; + this.Gauges[j].value = num3 + (Mathf.PerlinNoise((float)j, Time.time * 51f) - 0.5f) * 0.04f; + Color value = Color.Lerp(Color.gray, Color.yellow, num2 * num2); + value.a = (float)((num3 < 0.1f) ? 0 : 1); + Vector2 textureOffset = this.Wires[j].material.GetTextureOffset("_MainTex"); + textureOffset.x -= Time.fixedDeltaTime * 3f * Mathf.Lerp(0.1f, 2f, num3); + this.Wires[j].material.SetTextureOffset("_MainTex", textureOffset); + this.Wires[j].material.SetColor("_Color", value); + } + if (this.sliderId < 0) + { + return; + } + Collider2D collider2D = this.Sliders[this.sliderId]; + Vector2 vector = collider2D.transform.localPosition; + DragState dragState = this.myController.CheckDrag(collider2D, false); + if (dragState == DragState.Dragging) + { + Vector2 vector2 = this.myController.DragPosition - collider2D.transform.parent.position; + vector2.y = this.SliderY.Clamp(vector2.y); + vector.y = vector2.y; + collider2D.transform.localPosition = vector; + return; + } + if (dragState != DragState.Released) + { + return; + } + if (this.SliderY.max - vector.y < 0.05f) + { + this.MyNormTask.NextStep(); + base.StartCoroutine(base.CoStartClose(0.75f)); + this.sliderId = -1; + collider2D.GetComponent<SpriteRenderer>().color = new Color(0.5f, 0.5f, 0.5f); + } + } +} diff --git a/Client/Assembly-CSharp/DivertPowerTask.cs b/Client/Assembly-CSharp/DivertPowerTask.cs new file mode 100644 index 0000000..f970ae3 --- /dev/null +++ b/Client/Assembly-CSharp/DivertPowerTask.cs @@ -0,0 +1,51 @@ +using System; +using System.Linq; +using System.Text; + +public class DivertPowerTask : NormalPlayerTask +{ + public SystemTypes TargetSystem; + + public override bool ValidConsole(global::Console console) + { + return (console.Room == this.TargetSystem && console.ValidTasks.Any((TaskSet set) => this.TaskType == set.taskType && set.taskStep.Contains(this.taskStep))) || (this.taskStep == 0 && console.TaskTypes.Contains(this.TaskType)); + } + + public override void AppendTaskText(StringBuilder sb) + { + if (this.taskStep > 0) + { + if (this.IsComplete) + { + sb.Append("[00DD00FF]"); + } + else + { + sb.Append("[FFFF00FF]"); + } + } + if (this.taskStep == 0) + { + sb.Append(DestroyableSingleton<TranslationController>.Instance.GetString(this.StartAt)); + sb.Append(": "); + sb.Append(DestroyableSingleton<TranslationController>.Instance.GetString(StringNames.DivertPowerTo, Array.Empty<object>())); + sb.Append(" "); + sb.Append(DestroyableSingleton<TranslationController>.Instance.GetString(this.TargetSystem)); + } + else + { + sb.Append(DestroyableSingleton<TranslationController>.Instance.GetString(this.TargetSystem)); + sb.Append(": "); + sb.Append(DestroyableSingleton<TranslationController>.Instance.GetString(StringNames.AcceptDivertedPower, Array.Empty<object>())); + } + sb.Append(" ("); + sb.Append(this.taskStep); + sb.Append("/"); + sb.Append(this.MaxStep); + sb.AppendLine(")"); + if (this.taskStep > 0) + { + sb.Append("[]"); + } + } +} diff --git a/Client/Assembly-CSharp/DoorsSystemType.cs b/Client/Assembly-CSharp/DoorsSystemType.cs new file mode 100644 index 0000000..e642713 --- /dev/null +++ b/Client/Assembly-CSharp/DoorsSystemType.cs @@ -0,0 +1,119 @@ +using System; +using System.Linq; +using Hazel; + +//c 管理场景中的门,同步门的开启状态 +public class DoorsSystemType : ISystemType, IActivatable +{ + public bool IsActive + { + get + { + return this.doors.Any((AutoOpenDoor b) => !b.Open); + } + } + + private AutoOpenDoor[] doors; // 场景所有的门 + + private uint dirtyBits; + + public void SetDoors(AutoOpenDoor[] doors) + { + this.doors = doors; + } + + public bool Detoriorate(float deltaTime) + { + if (this.doors == null) + { + return false; + } + for (int i = 0; i < this.doors.Length; i++) + { + if (this.doors[i].DoUpdate(deltaTime)) + { + this.dirtyBits |= 1U << i; + } + } + return this.dirtyBits > 0U; + } + + public void RepairDamage(PlayerControl player, byte amount) + { + } + + //c 同步场景中所有门的开启状态 + + public void Serialize(MessageWriter writer, bool initialState) + { + if (initialState) + { + for (int i = 0; i < this.doors.Length; i++) + { + this.doors[i].Serialize(writer); + } + return; + } + writer.WritePacked(this.dirtyBits); + for (int j = 0; j < this.doors.Length; j++) + { + if ((this.dirtyBits & 1U << j) != 0U) + { + this.doors[j].Serialize(writer); + } + } + this.dirtyBits = 0U; + } + + public void Deserialize(MessageReader reader, bool initialState) + { + if (initialState) + { + for (int i = 0; i < this.doors.Length; i++) + { + this.doors[i].Deserialize(reader); + } + return; + } + uint num = reader.ReadPackedUInt32(); + for (int j = 0; j < this.doors.Length; j++) + { + if ((num & 1U << j) != 0U) + { + this.doors[j].Deserialize(reader); + } + } + } + + public void SetDoor(AutoOpenDoor door, bool open) + { + door.SetDoorway(open); + this.dirtyBits |= 1U << this.doors.IndexOf(door); + } + + public void CloseDoorsOfType(SystemTypes room) + { + for (int i = 0; i < this.doors.Length; i++) + { + AutoOpenDoor autoOpenDoor = this.doors[i]; + if (autoOpenDoor.Room == room) + { + autoOpenDoor.SetDoorway(false); + this.dirtyBits |= 1U << i; + } + } + } + + public float GetTimer(SystemTypes room) + { + for (int i = 0; i < this.doors.Length; i++) + { + AutoOpenDoor autoOpenDoor = this.doors[i]; + if (autoOpenDoor.Room == room) + { + return autoOpenDoor.CooldownTimer; + } + } + return 0f; + } +} diff --git a/Client/Assembly-CSharp/DotAligner.cs b/Client/Assembly-CSharp/DotAligner.cs new file mode 100644 index 0000000..149f4c8 --- /dev/null +++ b/Client/Assembly-CSharp/DotAligner.cs @@ -0,0 +1,43 @@ +using System; +using UnityEngine; + +public class DotAligner : MonoBehaviour +{ + public float Width = 2f; + + public bool Even; + + public void Start() + { + int num = 0; + for (int i = 0; i < base.transform.childCount; i++) + { + if (base.transform.GetChild(i).gameObject.activeSelf) + { + num++; + } + } + float num2; + float num3; + if (this.Even) + { + num2 = -this.Width * (float)(num - 1) / 2f; + num3 = this.Width; + } + else + { + num2 = -this.Width / 2f; + num3 = this.Width / (float)(num - 1); + } + int num4 = 0; + for (int j = 0; j < base.transform.childCount; j++) + { + Transform child = base.transform.GetChild(j); + if (child.gameObject.activeSelf) + { + child.transform.localPosition = new Vector3(num2 + (float)num4 * num3, 0f, 0f); + num4++; + } + } + } +} diff --git a/Client/Assembly-CSharp/DragState.cs b/Client/Assembly-CSharp/DragState.cs new file mode 100644 index 0000000..6b99f71 --- /dev/null +++ b/Client/Assembly-CSharp/DragState.cs @@ -0,0 +1,9 @@ +using System; + +public enum DragState +{ + NoTouch, + TouchStart, + Dragging, + Released +} diff --git a/Client/Assembly-CSharp/DummyBehaviour.cs b/Client/Assembly-CSharp/DummyBehaviour.cs new file mode 100644 index 0000000..58beb6f --- /dev/null +++ b/Client/Assembly-CSharp/DummyBehaviour.cs @@ -0,0 +1,63 @@ +using System; +using System.Collections; +using UnityEngine; + +public class DummyBehaviour : MonoBehaviour +{ + private PlayerControl myPlayer; + + private FloatRange voteTime = new FloatRange(3f, 8f); + + private bool voted; + + public void Start() + { + this.myPlayer = base.GetComponent<PlayerControl>(); + } + + public void Update() + { + if (this.myPlayer.Data.IsDead) + { + return; + } + if (MeetingHud.Instance) + { + if (!this.voted) + { + this.voted = true; + base.StartCoroutine(this.DoVote()); + return; + } + } + else + { + this.voted = false; + } + } + + private IEnumerator DoVote() + { + yield return new WaitForSeconds(this.voteTime.Next()); + sbyte suspectIdx = -1; + int num = 0; + while (num < 100 && num != 99) + { + int num2 = IntRange.Next(-1, GameData.Instance.PlayerCount); + if (num2 < 0) + { + suspectIdx = (sbyte)num2; + break; + } + GameData.PlayerInfo playerInfo = GameData.Instance.AllPlayers[num2]; + if (!playerInfo.IsDead) + { + suspectIdx = (sbyte)playerInfo.PlayerId; + break; + } + num++; + } + MeetingHud.Instance.CmdCastVote(this.myPlayer.PlayerId, suspectIdx); + yield break; + } +} diff --git a/Client/Assembly-CSharp/DummyConsole.cs b/Client/Assembly-CSharp/DummyConsole.cs new file mode 100644 index 0000000..cb053ae --- /dev/null +++ b/Client/Assembly-CSharp/DummyConsole.cs @@ -0,0 +1,57 @@ +using System; +using UnityEngine; + +public class DummyConsole : MonoBehaviour +{ + public int ConsoleId; + + public PlayerAnimator[] Players; + + public float UseDistance; + + [HideInInspector] + private SpriteRenderer rend; + + public void Start() + { + this.rend = base.GetComponent<SpriteRenderer>(); + } + + public void FixedUpdate() + { + this.rend.material.SetColor("_OutlineColor", Color.yellow); + float num = float.MaxValue; + for (int i = 0; i < this.Players.Length; i++) + { + PlayerAnimator playerAnimator = this.Players[i]; + Vector2 vector = base.transform.position - playerAnimator.transform.position; + vector.y += 0.3636f; + float magnitude = vector.magnitude; + if (magnitude < num) + { + num = magnitude; + } + if (magnitude < this.UseDistance) + { + playerAnimator.NearbyConsoles |= 1 << this.ConsoleId; + } + else + { + playerAnimator.NearbyConsoles &= ~(1 << this.ConsoleId); + } + } + if (num >= this.UseDistance * 2f) + { + this.rend.material.SetFloat("_Outline", 0f); + this.rend.material.SetColor("_AddColor", Color.clear); + return; + } + this.rend.material.SetFloat("_Outline", 1f); + if (num < this.UseDistance) + { + this.rend.material.SetColor("_AddColor", Color.yellow); + return; + } + this.rend.material.SetColor("_AddColor", Color.clear); + } +} diff --git a/Client/Assembly-CSharp/DynamicSound.cs b/Client/Assembly-CSharp/DynamicSound.cs new file mode 100644 index 0000000..f91f63d --- /dev/null +++ b/Client/Assembly-CSharp/DynamicSound.cs @@ -0,0 +1,26 @@ +using System; +using UnityEngine; + +public class DynamicSound : ISoundPlayer +{ + public string Name { get; set; } + + public AudioSource Player { get; set; } + + public DynamicSound.GetDynamicsFunction volumeFunc; + + public delegate void GetDynamicsFunction(AudioSource source, float dt); + + public void Update(float dt) + { + this.volumeFunc(this.Player, dt); + } + + public void SetTarget(AudioClip clip, DynamicSound.GetDynamicsFunction volumeFunc) + { + this.volumeFunc = volumeFunc; + this.Player.clip = clip; + this.volumeFunc(this.Player, 1f); + this.Player.Play(); + } +} diff --git a/Client/Assembly-CSharp/Effects.cs b/Client/Assembly-CSharp/Effects.cs new file mode 100644 index 0000000..56b3efe --- /dev/null +++ b/Client/Assembly-CSharp/Effects.cs @@ -0,0 +1,248 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using UnityEngine; + +public static class Effects +{ + private static HashSet<Transform> activeShakes = new HashSet<Transform>(); + + public static IEnumerator Wait(float duration) + { + for (float t = 0f; t < duration; t += Time.deltaTime) + { + yield return null; + } + yield break; + } + + public static IEnumerator All(params IEnumerator[] items) + { + Stack<IEnumerator>[] enums = new Stack<IEnumerator>[items.Length]; + for (int i = 0; i < items.Length; i++) + { + enums[i] = new Stack<IEnumerator>(); + enums[i].Push(items[i]); + } + int num; + for (int cap = 0; cap < 100000; cap = num) + { + bool flag = false; + for (int j = 0; j < enums.Length; j++) + { + if (enums[j].Count > 0) + { + flag = true; + IEnumerator enumerator = enums[j].Peek(); + if (enumerator.MoveNext()) + { + if (enumerator.Current is IEnumerator) + { + enums[j].Push((IEnumerator)enumerator.Current); + } + } + else + { + enums[j].Pop(); + } + } + } + if (!flag) + { + break; + } + yield return null; + num = cap + 1; + } + yield break; + } + + internal static IEnumerator ScaleIn(Transform self, float source, float target, float duration) + { + if (!self) + { + yield break; + } + Vector3 localScale = default(Vector3); + for (float t = 0f; t < duration; t += Time.deltaTime) + { + localScale.x = (localScale.y = (localScale.z = Mathf.SmoothStep(source, target, t / duration))); + self.localScale = localScale; + yield return null; + } + localScale.z = target; + localScale.y = target; + localScale.x = target; + self.localScale = localScale; + yield break; + } + + internal static IEnumerator CycleColors(SpriteRenderer self, Color source, Color target, float rate, float duration) + { + if (!self) + { + yield break; + } + self.enabled = true; + for (float t = 0f; t < duration; t += Time.deltaTime) + { + float t2 = Mathf.Sin(t * 3.1415927f / rate) / 2f + 0.5f; + self.color = Color.Lerp(source, target, t2); + yield return null; + } + self.color = source; + yield break; + } + + internal static IEnumerator PulseColor(SpriteRenderer self, Color source, Color target, float duration = 0.5f) + { + if (!self) + { + yield break; + } + self.enabled = true; + for (float t = 0f; t < duration; t += Time.deltaTime) + { + self.color = Color.Lerp(target, source, t / duration); + yield return null; + } + self.color = source; + yield break; + } + + internal static IEnumerator PulseColor(TextRenderer self, Color source, Color target, float duration = 0.5f) + { + if (!self) + { + yield break; + } + for (float t = 0f; t < duration; t += Time.deltaTime) + { + self.Color = Color.Lerp(target, source, t / duration); + yield return null; + } + self.Color = source; + yield break; + } + + public static IEnumerator ColorFade(SpriteRenderer self, Color source, Color target, float duration) + { + if (!self) + { + yield break; + } + self.enabled = true; + for (float t = 0f; t < duration; t += Time.deltaTime) + { + self.color = Color.Lerp(source, target, t / duration); + yield return null; + } + self.color = target; + yield break; + } + + public static IEnumerator Rotate2D(Transform target, float source, float dest, float duration = 0.75f) + { + Vector3 temp = target.localEulerAngles; + for (float time = 0f; time < duration; time += Time.deltaTime) + { + float t = time / duration; + temp.z = Mathf.SmoothStep(source, dest, t); + target.localEulerAngles = temp; + yield return null; + } + temp.z = dest; + target.localEulerAngles = temp; + yield break; + } + + public static IEnumerator Slide2D(Transform target, Vector2 source, Vector2 dest, float duration = 0.75f) + { + Vector3 temp = default(Vector3); + temp.z = target.localPosition.z; + for (float time = 0f; time < duration; time += Time.deltaTime) + { + float t = time / duration; + temp.x = Mathf.SmoothStep(source.x, dest.x, t); + temp.y = Mathf.SmoothStep(source.y, dest.y, t); + target.localPosition = temp; + yield return null; + } + temp.x = dest.x; + temp.y = dest.y; + target.localPosition = temp; + yield break; + } + + public static IEnumerator Bounce(Transform target, float duration = 0.3f, float height = 0.15f) + { + if (!target) + { + yield break; + } + Vector3 origin = target.localPosition; + Vector3 temp = origin; + for (float timer = 0f; timer < duration; timer += Time.deltaTime) + { + float num = timer / duration; + float num2 = 1f - num; + temp.y = origin.y + height * Mathf.Abs(Mathf.Sin(num * 3.1415927f * 3f)) * num2; + if (!target) + { + yield break; + } + target.localPosition = temp; + yield return null; + } + if (target) + { + target.transform.localPosition = origin; + } + yield break; + } + + public static IEnumerator Shake(Transform target, float duration = 0.75f, float halfWidth = 0.25f) + { + if (Effects.activeShakes.Add(target)) + { + Vector3 origin = target.localPosition; + for (float timer = 0f; timer < duration; timer += Time.deltaTime) + { + float num = timer / duration; + target.localPosition = origin + Vector3.right * (halfWidth * Mathf.Sin(num * 30f) * (1f - num)); + yield return null; + } + target.transform.localPosition = origin; + Effects.activeShakes.Remove(target); + origin = default(Vector3); + } + yield break; + } + + public static IEnumerator Bloop(float delay, Transform target, float duration = 0.5f) + { + for (float t = 0f; t < delay; t += Time.deltaTime) + { + yield return null; + } + Vector3 localScale = default(Vector3); + for (float t = 0f; t < duration; t += Time.deltaTime) + { + float z = Effects.ElasticOut(t, duration); + localScale.x = (localScale.y = (localScale.z = z)); + target.localScale = localScale; + yield return null; + } + localScale.x = (localScale.y = (localScale.z = 1f)); + target.localScale = localScale; + yield break; + } + + private static float ElasticOut(float time, float duration) + { + time /= duration; + float num = time * time; + float num2 = num * time; + return 33f * num2 * num + -106f * num * num + 126f * num2 + -67f * num + 15f * time; + } +} diff --git a/Client/Assembly-CSharp/ElectricTask.cs b/Client/Assembly-CSharp/ElectricTask.cs new file mode 100644 index 0000000..1480462 --- /dev/null +++ b/Client/Assembly-CSharp/ElectricTask.cs @@ -0,0 +1,82 @@ +using System; +using System.Linq; +using System.Text; +using UnityEngine; + +public class ElectricTask : SabotageTask +{ + public override int TaskStep + { + get + { + if (!this.isComplete) + { + return 0; + } + return 1; + } + } + + public override bool IsComplete + { + get + { + return this.isComplete; + } + } + + private bool isComplete; + + private SwitchSystem system; + + private bool even; + + public override void Initialize() + { + ShipStatus instance = ShipStatus.Instance; + this.system = (SwitchSystem)instance.Systems[SystemTypes.Electrical]; + base.SetupArrows(); + } + + private void FixedUpdate() + { + if (this.isComplete) + { + return; + } + if (this.system.ExpectedSwitches == this.system.ActualSwitches) + { + this.Complete(); + } + } + + public override bool ValidConsole(global::Console console) + { + return console.TaskTypes.Contains(TaskTypes.FixLights); + } + + public override void Complete() + { + this.isComplete = true; + PlayerControl.LocalPlayer.RemoveTask(this); + if (this.didContribute) + { + StatsManager instance = StatsManager.Instance; + uint sabsFixed = instance.SabsFixed; + instance.SabsFixed = sabsFixed + 1U; + } + } + + public override void AppendTaskText(StringBuilder sb) + { + this.even = !this.even; + Color color = this.even ? Color.yellow : Color.red; + sb.Append(color.ToTextColor()); + sb.Append(DestroyableSingleton<TranslationController>.Instance.GetString(TaskTypes.FixLights)); + sb.AppendLine(" (%" + (int)(this.system.Level * 100f) + ")[]"); + for (int i = 0; i < this.Arrows.Length; i++) + { + this.Arrows[i].image.color = color; + } + } +} diff --git a/Client/Assembly-CSharp/EmergencyMinigame.cs b/Client/Assembly-CSharp/EmergencyMinigame.cs new file mode 100644 index 0000000..5b6bff6 --- /dev/null +++ b/Client/Assembly-CSharp/EmergencyMinigame.cs @@ -0,0 +1,120 @@ +using System; +using System.Collections; +using System.Linq; +using UnityEngine; + +public class EmergencyMinigame : Minigame +{ + public SpriteRenderer ClosedLid; + + public SpriteRenderer OpenLid; + + public Transform meetingButton; + + public TextRenderer StatusText; + + public TextRenderer NumberText; + + public bool ButtonActive = true; + + public AudioClip ButtonSound; + + private int state; + + public const int MinEmergencyTime = 15; + + public override void Begin(PlayerTask task) + { + base.Begin(task); + this.Update(); + } + + public void Update() + { + if (ShipStatus.Instance.Timer < 15f || ShipStatus.Instance.EmergencyCooldown > 0f) + { + int num = Mathf.CeilToInt(15f - ShipStatus.Instance.Timer); + num = Mathf.Max(Mathf.CeilToInt(ShipStatus.Instance.EmergencyCooldown), num); + this.ButtonActive = false; + this.StatusText.Text = DestroyableSingleton<TranslationController>.Instance.GetString(StringNames.EmergencyNotReady, Array.Empty<object>()); + this.NumberText.Text = num + "s"; + this.ClosedLid.gameObject.SetActive(true); + this.OpenLid.gameObject.SetActive(false); + return; + } + if (!PlayerControl.LocalPlayer.myTasks.Any(new Func<PlayerTask, bool>(PlayerTask.TaskIsEmergency))) + { + if (this.state == 1) + { + return; + } + this.state = 1; + int remainingEmergencies = PlayerControl.LocalPlayer.RemainingEmergencies; + this.StatusText.Text = DestroyableSingleton<TranslationController>.Instance.GetString(StringNames.EmergencyCount, new object[] + { + PlayerControl.LocalPlayer.Data.PlayerName + }); + this.NumberText.Text = remainingEmergencies.ToString(); + this.ButtonActive = (remainingEmergencies > 0); + this.ClosedLid.gameObject.SetActive(!this.ButtonActive); + this.OpenLid.gameObject.SetActive(this.ButtonActive); + return; + } + else + { + if (this.state == 2) + { + return; + } + this.state = 2; + this.ButtonActive = false; + this.StatusText.Text = DestroyableSingleton<TranslationController>.Instance.GetString(StringNames.EmergencyDuringCrisis, Array.Empty<object>()); + this.NumberText.Text = string.Empty; + this.ClosedLid.gameObject.SetActive(true); + this.OpenLid.gameObject.SetActive(false); + return; + } + } + + public void CallMeeting() + { + if (!PlayerControl.LocalPlayer.myTasks.Any(new Func<PlayerTask, bool>(PlayerTask.TaskIsEmergency)) && PlayerControl.LocalPlayer.RemainingEmergencies > 0 && this.ButtonActive) + { + this.StatusText.Text = DestroyableSingleton<TranslationController>.Instance.GetString(StringNames.EmergencyRequested, Array.Empty<object>()); + if (Constants.ShouldPlaySfx()) + { + SoundManager.Instance.PlaySound(this.ButtonSound, false, 1f); + } + PlayerControl.LocalPlayer.CmdReportDeadBody(null); + this.ButtonActive = false; + } + } + + private float easeOutElastic(float t) + { + float num = 0.3f; + return Mathf.Pow(2f, -10f * t) * Mathf.Sin((t - num / 4f) * 6.2831855f / num) + 1f; + } + + protected override IEnumerator CoAnimateOpen() + { + for (float timer = 0f; timer < 0.2f; timer += Time.deltaTime) + { + float t = timer / 0.2f; + base.transform.localPosition = new Vector3(0f, Mathf.SmoothStep(-8f, 0f, t), -50f); + yield return null; + } + base.transform.localPosition = new Vector3(0f, 0f, -50f); + Vector3 meetingPos = this.meetingButton.localPosition; + for (float timer = 0f; timer < 0.1f; timer += Time.deltaTime) + { + float num = timer / 0.1f; + meetingPos.y = Mathf.Sin(3.1415927f * num) * 1f / (num * 5f + 4f) - 0.882f; + this.meetingButton.localPosition = meetingPos; + yield return null; + } + meetingPos.y = -0.882f; + this.meetingButton.localPosition = meetingPos; + yield break; + } +} diff --git a/Client/Assembly-CSharp/EmptyGarbageMinigame.cs b/Client/Assembly-CSharp/EmptyGarbageMinigame.cs new file mode 100644 index 0000000..679d683 --- /dev/null +++ b/Client/Assembly-CSharp/EmptyGarbageMinigame.cs @@ -0,0 +1,195 @@ +using System; +using System.Collections; +using System.Linq; +using UnityEngine; + +public class EmptyGarbageMinigame : Minigame +{ + private const float GrinderVolume = 0.8f; + + public FloatRange HandleRange = new FloatRange(-0.65f, 0.65f); + + public Vector2Range SpawnRange; + + public Collider2D Blocker; + + public AreaEffector2D Popper; + + public Collider2D Handle; + + public SpriteRenderer Bars; + + private Controller controller = new Controller(); + + private bool finished; + + public int NumObjects = 15; + + private SpriteRenderer[] Objects; + + public SpriteRenderer[] GarbagePrefabs; + + public SpriteRenderer[] LeafPrefabs; + + public SpriteRenderer[] SpecialObjectPrefabs; + + public AudioClip LeverDown; + + public AudioClip LeverUp; + + public AudioClip GrinderStart; + + public AudioClip GrinderLoop; + + public AudioClip GrinderEnd; + + public override void Begin(PlayerTask task) + { + base.Begin(task); + int i = 0; + this.Objects = new SpriteRenderer[this.NumObjects]; + RandomFill<SpriteRenderer> randomFill = new RandomFill<SpriteRenderer>(); + NormalPlayerTask myNormTask = this.MyNormTask; + if (myNormTask != null && myNormTask.taskStep == 0) + { + if (this.MyNormTask.StartAt == SystemTypes.Cafeteria) + { + randomFill.Set(this.GarbagePrefabs); + } + else + { + randomFill.Set(this.LeafPrefabs); + } + } + else + { + randomFill.Set(this.GarbagePrefabs.Union(this.LeafPrefabs)); + while (i < this.SpecialObjectPrefabs.Length) + { + SpriteRenderer spriteRenderer = this.Objects[i] = UnityEngine.Object.Instantiate<SpriteRenderer>(this.SpecialObjectPrefabs[i]); + spriteRenderer.transform.SetParent(base.transform); + spriteRenderer.transform.localPosition = this.SpawnRange.Next(); + i++; + } + } + while (i < this.Objects.Length) + { + SpriteRenderer spriteRenderer2 = this.Objects[i] = UnityEngine.Object.Instantiate<SpriteRenderer>(randomFill.Get()); + spriteRenderer2.transform.SetParent(base.transform); + Vector3 vector = this.SpawnRange.Next(); + vector.z = FloatRange.Next(-0.5f, 0.5f); + spriteRenderer2.transform.localPosition = vector; + spriteRenderer2.GetComponent<SpriteRenderer>().color = Color.Lerp(Color.white, Color.black, (vector.z + 0.5f) * 0.7f); + i++; + } + } + + public void Update() + { + if (this.amClosing != Minigame.CloseState.None) + { + return; + } + this.controller.Update(); + Vector3 localPosition = this.Handle.transform.localPosition; + float num = this.HandleRange.ReverseLerp(localPosition.y); + switch (this.controller.CheckDrag(this.Handle, false)) + { + case DragState.NoTouch: + localPosition.y = Mathf.Lerp(localPosition.y, this.HandleRange.max, num + Time.deltaTime * 15f); + break; + case DragState.Dragging: + if (!this.finished) + { + if (num > 0.5f) + { + Vector2 vector = this.controller.DragPosition - base.transform.position; + float num2 = this.HandleRange.ReverseLerp(this.HandleRange.Clamp(vector.y)); + localPosition.y = this.HandleRange.Lerp(num2 / 2f + 0.5f); + } + else + { + localPosition.y = Mathf.Lerp(localPosition.y, this.HandleRange.min, num + Time.deltaTime * 15f); + if (this.Blocker.enabled) + { + if (Constants.ShouldPlaySfx()) + { + SoundManager.Instance.PlaySound(this.LeverDown, false, 1f); + SoundManager.Instance.PlaySound(this.GrinderStart, false, 0.8f); + SoundManager.Instance.StopSound(this.GrinderEnd); + SoundManager.Instance.StopSound(this.GrinderLoop); + } + this.Blocker.enabled = false; + base.StopAllCoroutines(); + base.StartCoroutine(this.PopObjects()); + base.StartCoroutine(this.AnimateObjects()); + } + } + } + break; + case DragState.Released: + if (!this.Blocker.enabled) + { + this.Blocker.enabled = true; + if (Constants.ShouldPlaySfx()) + { + SoundManager.Instance.PlaySound(this.LeverUp, false, 1f); + SoundManager.Instance.StopSound(this.GrinderStart); + SoundManager.Instance.StopSound(this.GrinderLoop); + SoundManager.Instance.PlaySound(this.GrinderEnd, false, 0.8f); + } + } + if (!this.finished) + { + if (this.Objects.All((SpriteRenderer o) => !o)) + { + this.finished = true; + this.MyNormTask.NextStep(); + base.StartCoroutine(base.CoStartClose(0.75f)); + } + } + break; + } + if (Constants.ShouldPlaySfx() && !this.Blocker.enabled && !SoundManager.Instance.SoundIsPlaying(this.GrinderStart)) + { + SoundManager.Instance.PlaySound(this.GrinderLoop, true, 0.8f); + } + this.Handle.transform.localPosition = localPosition; + Vector3 localScale = this.Bars.transform.localScale; + localScale.y = this.HandleRange.ChangeRange(localPosition.y, -1f, 1f); + this.Bars.transform.localScale = localScale; + } + + private IEnumerator PopObjects() + { + this.Popper.enabled = true; + yield return new WaitForSeconds(0.05f); + this.Popper.enabled = false; + yield break; + } + + private IEnumerator AnimateObjects() + { + Vector3 pos = base.transform.localPosition; + for (float t = 3f; t > 0f; t -= Time.deltaTime) + { + float d = t / 3f; + base.transform.localPosition = pos + Vector2Range.NextEdge() * d * 0.1f; + yield return null; + } + yield break; + } + + public override void Close() + { + SoundManager.Instance.StopSound(this.GrinderStart); + SoundManager.Instance.StopSound(this.GrinderLoop); + SoundManager.Instance.StopSound(this.GrinderEnd); + if (this.MyNormTask && this.MyNormTask.IsComplete) + { + ShipStatus.Instance.OpenHatch(); + PlayerControl.LocalPlayer.RpcPlayAnimation((byte)this.MyTask.TaskType); + } + base.Close(); + } +} diff --git a/Client/Assembly-CSharp/EndGameManager.cs b/Client/Assembly-CSharp/EndGameManager.cs new file mode 100644 index 0000000..7380913 --- /dev/null +++ b/Client/Assembly-CSharp/EndGameManager.cs @@ -0,0 +1,236 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using Assets.CoreScripts; +using InnerNet; +using UnityEngine; + +public class EndGameManager : DestroyableSingleton<EndGameManager> +{ + public TextRenderer WinText; + + public MeshRenderer BackgroundBar; + + public MeshRenderer Foreground; + + public FloatRange ForegroundRadius; + + public SpriteRenderer FrontMost; + + public PoolablePlayer PlayerPrefab; + + public Sprite GhostSprite; + + public SpriteRenderer PlayAgainButton; + + public SpriteRenderer ExitButton; + + public AudioClip DisconnectStinger; + + public AudioClip CrewStinger; + + public AudioClip ImpostorStinger; + + public float BaseY = -0.25f; + + private float stingerTime; + + public void Start() + { + if (TempData.showAd && !SaveManager.BoughtNoAds) + { + AdPlayer.RequestInterstitial(); + } + this.SetEverythingUp(); + base.StartCoroutine(this.CoBegin()); + base.Invoke("ShowButtons", 1.1f); + } + + private void ShowButtons() + { + this.FrontMost.gameObject.SetActive(false); + this.PlayAgainButton.gameObject.SetActive(true); + this.ExitButton.gameObject.SetActive(true); + } + + private void SetEverythingUp() + { + StatsManager instance = StatsManager.Instance; + uint gamesFinished = instance.GamesFinished; + instance.GamesFinished = gamesFinished + 1U; + bool flag = TempData.DidHumansWin(TempData.EndReason); + if (TempData.EndReason == GameOverReason.ImpostorDisconnect) + { + StatsManager.Instance.AddDrawReason(TempData.EndReason); + this.WinText.Text = DestroyableSingleton<TranslationController>.Instance.GetString(StringNames.ImpostorDisconnected, Array.Empty<object>()); + SoundManager.Instance.PlaySound(this.DisconnectStinger, false, 1f); + } + else if (TempData.EndReason == GameOverReason.HumansDisconnect) + { + StatsManager.Instance.AddDrawReason(TempData.EndReason); + this.WinText.Text = DestroyableSingleton<TranslationController>.Instance.GetString(StringNames.CrewmatesDisconnected, Array.Empty<object>()); + SoundManager.Instance.PlaySound(this.DisconnectStinger, false, 1f); + } + else + { + if (TempData.winners.Any((WinningPlayerData h) => h.IsYou)) + { + StatsManager.Instance.AddWinReason(TempData.EndReason); + this.WinText.Text = DestroyableSingleton<TranslationController>.Instance.GetString(StringNames.Victory, Array.Empty<object>()); + this.BackgroundBar.material.SetColor("_Color", Palette.CrewmateBlue); + WinningPlayerData winningPlayerData = TempData.winners.FirstOrDefault((WinningPlayerData h) => h.IsYou); + if (winningPlayerData != null) + { + DestroyableSingleton<Telemetry>.Instance.WonGame(winningPlayerData.ColorId, winningPlayerData.HatId); + } + } + else + { + StatsManager.Instance.AddLoseReason(TempData.EndReason); + this.WinText.Text = DestroyableSingleton<TranslationController>.Instance.GetString(StringNames.Defeat, Array.Empty<object>()); + this.WinText.Color = Color.red; + } + if (flag) + { + SoundManager.Instance.PlayDynamicSound("Stinger", this.CrewStinger, false, new DynamicSound.GetDynamicsFunction(this.GetStingerVol), false); + } + else + { + SoundManager.Instance.PlayDynamicSound("Stinger", this.ImpostorStinger, false, new DynamicSound.GetDynamicsFunction(this.GetStingerVol), false); + } + } + List<WinningPlayerData> list = TempData.winners.OrderBy(delegate(WinningPlayerData b) + { + if (!b.IsYou) + { + return 0; + } + return -1; + }).ToList<WinningPlayerData>(); + for (int i = 0; i < list.Count; i++) + { + WinningPlayerData winningPlayerData2 = list[i]; + int num = (i % 2 == 0) ? -1 : 1; + int num2 = (i + 1) / 2; + float num3 = 1f - (float)num2 * 0.075f; + float num4 = 1f - (float)num2 * 0.035f; + float num5 = (float)((i == 0) ? -8 : -1); + PoolablePlayer poolablePlayer = UnityEngine.Object.Instantiate<PoolablePlayer>(this.PlayerPrefab, base.transform); + poolablePlayer.transform.localPosition = new Vector3(0.8f * (float)num * (float)num2 * num4, this.BaseY - 0.25f + (float)num2 * 0.1f, num5 + (float)num2 * 0.01f) * 1.25f; + Vector3 vector = new Vector3(num3, num3, num3) * 1.25f; + poolablePlayer.transform.localScale = vector; + if (winningPlayerData2.IsDead) + { + poolablePlayer.Body.sprite = this.GhostSprite; + poolablePlayer.SetDeadFlipX(i % 2 != 0); + } + else + { + poolablePlayer.SetFlipX(i % 2 == 0); + } + if (!winningPlayerData2.IsDead) + { + DestroyableSingleton<HatManager>.Instance.SetSkin(poolablePlayer.SkinSlot, winningPlayerData2.SkinId); + } + else + { + poolablePlayer.HatSlot.color = new Color(1f, 1f, 1f, 0.5f); + } + PlayerControl.SetPlayerMaterialColors(winningPlayerData2.ColorId, poolablePlayer.Body); + PlayerControl.SetHatImage(winningPlayerData2.HatId, poolablePlayer.HatSlot); + PlayerControl.SetPetImage(winningPlayerData2.PetId, winningPlayerData2.ColorId, poolablePlayer.PetSlot); + if (flag) + { + poolablePlayer.NameText.gameObject.SetActive(false); + } + else + { + poolablePlayer.NameText.Text = winningPlayerData2.Name; + if (winningPlayerData2.IsImpostor) + { + poolablePlayer.NameText.Color = Palette.ImpostorRed; + } + poolablePlayer.NameText.transform.localScale = vector.Inv(); + } + } + } + + private void GetStingerVol(AudioSource source, float dt) + { + this.stingerTime += dt * 0.75f; + source.volume = Mathf.Clamp(1f / this.stingerTime, 0f, 1f); + } + + public IEnumerator CoBegin() + { + Color c = this.WinText.Color; + Color fade = Color.black; + Color white = Color.white; + Vector3 titlePos = this.WinText.transform.localPosition; + float timer = 0f; + while (timer < 3f) + { + timer += Time.deltaTime; + float num = Mathf.Min(1f, timer / 3f); + this.Foreground.material.SetFloat("_Rad", this.ForegroundRadius.ExpOutLerp(num * 2f)); + fade.a = Mathf.Lerp(1f, 0f, num * 3f); + this.FrontMost.color = fade; + c.a = Mathf.Clamp(FloatRange.ExpOutLerp(num, 0f, 1f), 0f, 1f); + this.WinText.Color = c; + titlePos.y = 2.7f - num * 0.3f; + this.WinText.transform.localPosition = titlePos; + yield return null; + } + this.FrontMost.gameObject.SetActive(false); + yield break; + } + + public void NextGame() + { + this.PlayAgainButton.gameObject.SetActive(false); + this.ExitButton.gameObject.SetActive(false); + if (TempData.showAd && !SaveManager.BoughtNoAds) + { + TempData.showAd = false; + AdPlayer.ShowInterstitial(this, true); + return; + } + base.StartCoroutine(this.CoJoinGame()); + } + + public IEnumerator CoJoinGame() + { + AmongUsClient.Instance.JoinGame(); + yield return EndGameManager.WaitWithTimeout(() => AmongUsClient.Instance.ClientId >= 0); + if (AmongUsClient.Instance.ClientId < 0) + { + AmongUsClient.Instance.ExitGame(AmongUsClient.Instance.LastDisconnectReason); + } + yield break; + } + + public void Exit() + { + this.PlayAgainButton.gameObject.SetActive(false); + this.ExitButton.gameObject.SetActive(false); + if (TempData.showAd && !SaveManager.BoughtNoAds) + { + TempData.showAd = false; + AdPlayer.ShowInterstitial(this, false); + return; + } + AmongUsClient.Instance.ExitGame(DisconnectReasons.ExitGame); + } + + public static IEnumerator WaitWithTimeout(Func<bool> success) + { + float timer = 0f; + while (timer < 5f && !success()) + { + yield return null; + timer += Time.deltaTime; + } + yield break; + } +} diff --git a/Client/Assembly-CSharp/EngineBehaviour.cs b/Client/Assembly-CSharp/EngineBehaviour.cs new file mode 100644 index 0000000..87bdccf --- /dev/null +++ b/Client/Assembly-CSharp/EngineBehaviour.cs @@ -0,0 +1,48 @@ +using System; +using UnityEngine; + +public class EngineBehaviour : MonoBehaviour +{ + public AudioClip ElectricSound; + + public AudioClip SteamSound; + + public float SoundDistance = 5f; + + public void PlayElectricSound() + { + if (Constants.ShouldPlaySfx()) + { + SoundManager.Instance.PlayDynamicSound("EngineShock" + base.name, this.ElectricSound, false, new DynamicSound.GetDynamicsFunction(this.GetSoundDistance), false); + } + } + + public void PlaySteamSound() + { + if (Constants.ShouldPlaySfx()) + { + float pitch = FloatRange.Next(0.7f, 1.1f); + SoundManager.Instance.PlayDynamicSound("EngineSteam" + base.name, this.SteamSound, false, delegate(AudioSource p, float d) + { + this.GetSoundDistance(p, d, pitch); + }, false); + } + } + + private void GetSoundDistance(AudioSource player, float dt) + { + this.GetSoundDistance(player, dt, 1f); + } + + private void GetSoundDistance(AudioSource player, float dt, float pitch) + { + float num = 1f; + if (PlayerControl.LocalPlayer) + { + float num2 = Vector2.Distance(base.transform.position, PlayerControl.LocalPlayer.GetTruePosition()); + num = 1f - num2 / this.SoundDistance; + } + player.volume = num * 0.8f; + player.pitch = pitch; + } +} diff --git a/Client/Assembly-CSharp/EnterCodeMinigame.cs b/Client/Assembly-CSharp/EnterCodeMinigame.cs new file mode 100644 index 0000000..4bbc0ef --- /dev/null +++ b/Client/Assembly-CSharp/EnterCodeMinigame.cs @@ -0,0 +1,121 @@ +using System; +using System.Collections; +using UnityEngine; + +public class EnterCodeMinigame : Minigame +{ + public TextRenderer NumberText; + + public TextRenderer TargetText; + + public int number; + + public string numString = string.Empty; + + private bool animating; + + public SpriteRenderer AcceptButton; + + private bool done; + + private int targetNumber; + + public void EnterDigit(int i) + { + if (this.animating) + { + return; + } + if (this.done) + { + return; + } + if (this.NumberText.Text.Length >= 5) + { + base.StartCoroutine(this.BlinkAccept()); + return; + } + this.numString += i; + this.number = this.number * 10 + i; + this.NumberText.Text = this.numString; + } + + public void ClearDigits() + { + if (this.animating) + { + return; + } + this.number = 0; + this.numString = string.Empty; + this.NumberText.Text = string.Empty; + } + + public void AcceptDigits() + { + if (this.animating) + { + return; + } + base.StartCoroutine(this.Animate()); + } + + public override void Begin(PlayerTask task) + { + base.Begin(task); + this.targetNumber = BitConverter.ToInt32(this.MyNormTask.Data, 0); + this.NumberText.Text = string.Empty; + this.TargetText.Text = this.targetNumber.ToString("D5"); + } + + private IEnumerator BlinkAccept() + { + int num; + for (int i = 0; i < 5; i = num) + { + this.AcceptButton.color = Color.gray; + yield return null; + yield return null; + this.AcceptButton.color = Color.white; + yield return null; + yield return null; + num = i + 1; + } + yield break; + } + + private IEnumerator Animate() + { + this.animating = true; + WaitForSeconds wait = new WaitForSeconds(0.1f); + yield return wait; + this.NumberText.Text = string.Empty; + yield return wait; + if (this.targetNumber == this.number) + { + this.done = true; + this.NumberText.Text = "OK"; + yield return wait; + this.NumberText.Text = string.Empty; + yield return wait; + this.NumberText.Text = "OK"; + yield return wait; + this.NumberText.Text = string.Empty; + yield return base.CoStartClose(0.5f); + } + else + { + this.NumberText.Text = "Bad"; + yield return wait; + this.NumberText.Text = string.Empty; + yield return wait; + this.NumberText.Text = "Bad"; + yield return wait; + this.numString = string.Empty; + this.number = 0; + this.NumberText.Text = this.numString; + } + this.animating = false; + yield break; + } +} diff --git a/Client/Assembly-CSharp/ExileController.cs b/Client/Assembly-CSharp/ExileController.cs new file mode 100644 index 0000000..4a52a4d --- /dev/null +++ b/Client/Assembly-CSharp/ExileController.cs @@ -0,0 +1,160 @@ +using System; +using System.Collections; +using System.Linq; +using UnityEngine; + +public class ExileController : MonoBehaviour +{ + public static ExileController Instance; + + public TextRenderer ImpostorText; + + public TextRenderer Text; + + public SpriteRenderer Player; + + public SpriteRenderer PlayerHat; + + public SpriteRenderer PlayerSkin; + + public AnimationCurve LerpCurve; + + public float Duration = 7f; + + public AudioClip TextSound; + + private string completeString = string.Empty; + + private GameData.PlayerInfo exiled; + + public void Begin(GameData.PlayerInfo exiled, bool tie) + { + ExileController.Instance = this; + this.exiled = exiled; + this.Text.gameObject.SetActive(false); + this.Text.Text = string.Empty; + int num = GameData.Instance.AllPlayers.Count((GameData.PlayerInfo p) => p.IsImpostor && !p.IsDead && !p.Disconnected); + if (exiled != null) + { + int num2 = GameData.Instance.AllPlayers.Count((GameData.PlayerInfo p) => p.IsImpostor); + if (exiled.IsImpostor) + { + if (num2 > 1) + { + this.completeString = DestroyableSingleton<TranslationController>.Instance.GetString(StringNames.ExileTextPP, new object[] + { + exiled.PlayerName + }); + } + else + { + this.completeString = DestroyableSingleton<TranslationController>.Instance.GetString(StringNames.ExileTextSP, new object[] + { + exiled.PlayerName + }); + } + } + else if (num2 > 1) + { + this.completeString = DestroyableSingleton<TranslationController>.Instance.GetString(StringNames.ExileTextPN, new object[] + { + exiled.PlayerName + }); + } + else + { + this.completeString = DestroyableSingleton<TranslationController>.Instance.GetString(StringNames.ExileTextSN, new object[] + { + exiled.PlayerName + }); + } + PlayerControl.SetPlayerMaterialColors((int)exiled.ColorId, this.Player); + PlayerControl.SetHatImage(exiled.HatId, this.PlayerHat); + this.PlayerSkin.sprite = DestroyableSingleton<HatManager>.Instance.GetSkinById(exiled.SkinId).EjectFrame; + if (exiled.IsImpostor) + { + num--; + } + } + else + { + if (tie) + { + this.completeString = DestroyableSingleton<TranslationController>.Instance.GetString(StringNames.NoExileTie, Array.Empty<object>()); + } + else + { + this.completeString = DestroyableSingleton<TranslationController>.Instance.GetString(StringNames.NoExileSkip, Array.Empty<object>()); + } + this.Player.gameObject.SetActive(false); + } + if (num == 1) + { + this.ImpostorText.Text = DestroyableSingleton<TranslationController>.Instance.GetString(StringNames.ImpostorsRemainS, new object[] + { + num + }); + } + else + { + this.ImpostorText.Text = DestroyableSingleton<TranslationController>.Instance.GetString(StringNames.ImpostorsRemainP, new object[] + { + num + }); + } + base.StartCoroutine(this.Animate()); + } + + private IEnumerator Animate() + { + yield return DestroyableSingleton<HudManager>.Instance.CoFadeFullScreen(Color.black, Color.clear, 0.2f); + yield return new WaitForSeconds(1f); + float d = Camera.main.orthographicSize * Camera.main.aspect + 1f; + Vector2 left = Vector2.left * d; + Vector2 right = Vector2.right * d; + for (float t = 0f; t <= this.Duration; t += Time.deltaTime) + { + float num = t / this.Duration; + this.Player.transform.localPosition = Vector2.Lerp(left, right, this.LerpCurve.Evaluate(num)); + float z = (t + 0.75f) * 25f / Mathf.Exp(t * 0.75f + 1f); + this.Player.transform.Rotate(new Vector3(0f, 0f, z)); + if (num >= 0.3f) + { + int num2 = (int)(Mathf.Min(1f, (num - 0.3f) / 0.3f) * (float)this.completeString.Length); + if (num2 > this.Text.Text.Length) + { + this.Text.Text = this.completeString.Substring(0, num2); + this.Text.gameObject.SetActive(true); + if (this.completeString[num2 - 1] != ' ') + { + SoundManager.Instance.PlaySoundImmediate(this.TextSound, false, 0.8f, 1f); + } + } + } + yield return null; + } + this.Text.Text = this.completeString; + this.ImpostorText.gameObject.SetActive(true); + yield return Effects.Bloop(0f, this.ImpostorText.transform, 0.5f); + yield return new WaitForSeconds(0.5f); + yield return DestroyableSingleton<HudManager>.Instance.CoFadeFullScreen(Color.clear, Color.black, 0.2f); + if (this.exiled != null) + { + PlayerControl @object = this.exiled.Object; + if (@object != null) + { + @object.Exiled(); + } + } + if (DestroyableSingleton<TutorialManager>.InstanceExists || !ShipStatus.Instance.IsGameOverDueToDeath()) + { + DestroyableSingleton<HudManager>.Instance.StartCoroutine(DestroyableSingleton<HudManager>.Instance.CoFadeFullScreen(Color.black, Color.clear, 0.2f)); + PlayerControl.LocalPlayer.SetKillTimer(PlayerControl.GameOptions.KillCooldown); + ShipStatus.Instance.EmergencyCooldown = (float)PlayerControl.GameOptions.EmergencyCooldown; + Camera.main.GetComponent<FollowerCamera>().Locked = false; + DestroyableSingleton<HudManager>.Instance.SetHudActive(true); + } + UnityEngine.Object.Destroy(base.gameObject); + yield break; + } +} diff --git a/Client/Assembly-CSharp/ExitGameButton.cs b/Client/Assembly-CSharp/ExitGameButton.cs new file mode 100644 index 0000000..6fbbc35 --- /dev/null +++ b/Client/Assembly-CSharp/ExitGameButton.cs @@ -0,0 +1,24 @@ +using System; +using InnerNet; +using UnityEngine; + +public class ExitGameButton : MonoBehaviour +{ + public void Start() + { + if (!DestroyableSingleton<HudManager>.InstanceExists) + { + base.gameObject.SetActive(false); + } + } + + public void OnClick() + { + if (AmongUsClient.Instance) + { + AmongUsClient.Instance.ExitGame(DisconnectReasons.ExitGame); + return; + } + SceneChanger.ChangeScene("MainMenu"); + } +} diff --git a/Client/Assembly-CSharp/Extensions.cs b/Client/Assembly-CSharp/Extensions.cs new file mode 100644 index 0000000..a653cea --- /dev/null +++ b/Client/Assembly-CSharp/Extensions.cs @@ -0,0 +1,409 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using UnityEngine; + +public static class Extensions +{ + private static string[] ByteHex = (from x in Enumerable.Range(0, 256) + select x.ToString("X2")).ToArray<string>(); + + public static void TrimEnd(this StringBuilder self) + { + for (int i = self.Length - 1; i >= 0; i--) + { + char c = self[i]; + if (c != ' ' && c != '\t' && c != '\n' && c != '\r') + { + break; + } + int length = self.Length; + self.Length = length - 1; + } + } + + public static void AddUnique<T>(this IList<T> self, T item) + { + if (!self.Contains(item)) + { + self.Add(item); + } + } + + public static string ToTextColor(this Color c) + { + return string.Concat(new string[] + { + "[", + Extensions.ByteHex[(int)((byte)(c.r * 255f))], + Extensions.ByteHex[(int)((byte)(c.g * 255f))], + Extensions.ByteHex[(int)((byte)(c.b * 255f))], + Extensions.ByteHex[(int)((byte)(c.a * 255f))], + "]" + }); + } + + public static int ToInteger(this Color c, bool alpha) + { + if (alpha) + { + return (int)((byte)(c.r * 256f)) << 24 | (int)((byte)(c.g * 256f)) << 16 | (int)((byte)(c.b * 256f)) << 8 | (int)((byte)(c.a * 256f)); + } + return (int)((byte)(c.r * 256f)) << 16 | (int)((byte)(c.g * 256f)) << 8 | (int)((byte)(c.b * 256f)); + } + + public static bool HasAnyBit(this int self, int bit) + { + return (self & bit) != 0; + } + + public static bool HasAnyBit(this byte self, byte bit) + { + return (self & bit) > 0; + } + + public static bool HasBit(this byte self, byte bit) + { + return (self & bit) == bit; + } + + public static int BitCount(this byte self) + { + int num = 0; + for (int i = 0; i < 8; i++) + { + if ((1 << i & (int)self) != 0) + { + num++; + } + } + return num; + } + + public static int IndexOf<T>(this T[] self, T item) where T : class + { + for (int i = 0; i < self.Length; i++) + { + if (self[i] == item) + { + return i; + } + } + return -1; + } + + public static int IndexOfMin<T>(this T[] self, Func<T, float> comparer) + { + float num = float.MaxValue; + int result = -1; + for (int i = 0; i < self.Length; i++) + { + float num2 = comparer(self[i]); + if (num2 <= num) + { + result = i; + num = num2; + } + } + return result; + } + + public static int IndexOfMax<T>(this T[] self, Func<T, int> comparer, out bool tie) + { + tie = false; + int num = int.MinValue; + int result = -1; + for (int i = 0; i < self.Length; i++) + { + int num2 = comparer(self[i]); + if (num2 > num) + { + result = i; + num = num2; + tie = false; + } + else if (num2 == num) + { + tie = true; + result = -1; + } + } + return result; + } + + public static void SetAll<T>(this IList<T> self, T value) + { + for (int i = 0; i < self.Count; i++) + { + self[i] = value; + } + } + + public static void AddAll<T>(this List<T> self, IList<T> other) + { + int num = self.Count + other.Count; + if (self.Capacity < num) + { + self.Capacity = num; + } + for (int i = 0; i < other.Count; i++) + { + self.Add(other[i]); + } + } + + public static void RemoveDupes<T>(this IList<T> self) where T : class + { + for (int i = 0; i < self.Count; i++) + { + T t = self[i]; + for (int j = self.Count - 1; j > i; j--) + { + if (self[j] == t) + { + self.RemoveAt(j); + } + } + } + } + + public static void Shuffle<T>(this IList<T> self) + { + for (int i = 0; i < self.Count - 1; i++) + { + T value = self[i]; + int index = UnityEngine.Random.Range(i, self.Count); + self[i] = self[index]; + self[index] = value; + } + } + + public static void Shuffle<T>(this System.Random r, IList<T> self) + { + for (int i = 0; i < self.Count; i++) + { + T value = self[i]; + int index = r.Next(self.Count); + self[i] = self[index]; + self[index] = value; + } + } + + public static T[] RandomSet<T>(this IList<T> self, int length) + { + T[] array = new T[length]; + self.RandomFill(array); + return array; + } + + public static void RandomFill<T>(this IList<T> self, T[] target) + { + HashSet<int> hashSet = new HashSet<int>(); + for (int i = 0; i < target.Length; i++) + { + int num; + do + { + num = self.RandomIdx<T>(); + } + while (hashSet.Contains(num)); + target[i] = self[num]; + hashSet.Add(num); + if (hashSet.Count == self.Count) + { + return; + } + } + } + + public static int RandomIdx<T>(this IList<T> self) + { + return UnityEngine.Random.Range(0, self.Count); + } + + public static int RandomIdx<T>(this IEnumerable<T> self) + { + return UnityEngine.Random.Range(0, self.Count<T>()); + } + + public static T Random<T>(this IEnumerable<T> self) + { + return self.ToArray<T>().Random<T>(); + } + + public static T Random<T>(this IList<T> self) + { + if (self.Count > 0) + { + return self[UnityEngine.Random.Range(0, self.Count)]; + } + return default(T); + } + + public static Vector2 Div(this Vector2 a, Vector2 b) + { + return new Vector2(a.x / b.x, a.y / b.y); + } + + public static Vector2 Mul(this Vector2 a, Vector2 b) + { + return new Vector2(a.x * b.x, a.y * b.y); + } + + public static Vector3 Mul(this Vector3 a, Vector3 b) + { + return new Vector3(a.x * b.x, a.y * b.y, a.z * b.z); + } + + public static Vector3 Inv(this Vector3 a) + { + return new Vector3(1f / a.x, 1f / a.y, 1f / a.z); + } + + public static Rect Lerp(this Rect source, Rect target, float t) + { + return new Rect + { + position = Vector2.Lerp(source.position, target.position, t), + size = Vector2.Lerp(source.size, target.size, t) + }; + } + + public static void ForEach<T>(this IList<T> self, Action<T> todo) + { + for (int i = 0; i < self.Count; i++) + { + todo(self[i]); + } + } + + public static T Max<T>(this IList<T> self, Func<T, float> comparer) + { + T t = self.First<T>(); + float num = comparer(t); + for (int i = 0; i < self.Count; i++) + { + T t2 = self[i]; + float num2 = comparer(t2); + if (num < num2 || (num == num2 && UnityEngine.Random.value > 0.5f)) + { + num = num2; + t = t2; + } + } + return t; + } + + public static T Max<T>(this IList<T> self, Func<T, decimal> comparer) + { + T t = self.First<T>(); + decimal d = comparer(t); + for (int i = 0; i < self.Count; i++) + { + T t2 = self[i]; + decimal num = comparer(t2); + if (d < num || (d == num && UnityEngine.Random.value > 0.5f)) + { + d = num; + t = t2; + } + } + return t; + } + + public static int Wrap(this int self, int max) + { + if (self >= 0) + { + return self % max; + } + return (self + -(self / max) * max + max) % max; + } + + public static int IndexOf<T>(this T[] self, Predicate<T> pred) + { + for (int i = 0; i < self.Length; i++) + { + if (pred(self[i])) + { + return i; + } + } + return -1; + } + + public static Vector2 MapToRectangle(this Vector2 del, Vector2 widthAndHeight) + { + del = del.normalized; + if (Mathf.Abs(del.x) > Mathf.Abs(del.y)) + { + return new Vector2(Mathf.Sign(del.x) * widthAndHeight.x, del.y * widthAndHeight.y / 0.70710677f); + } + return new Vector2(del.x * widthAndHeight.x / 0.70710677f, Mathf.Sign(del.y) * widthAndHeight.y); + } + + public static float AngleSignedRad(this Vector2 vector1, Vector2 vector2) + { + return Mathf.Atan2(vector2.y, vector2.x) - Mathf.Atan2(vector1.y, vector1.x); + } + + public static float AngleSigned(this Vector2 vector1, Vector2 vector2) + { + return vector1.AngleSignedRad(vector2) * 57.29578f; + } + + public static Vector2 Rotate(this Vector2 self, float degrees) + { + float f = 0.017453292f * degrees; + float num = Mathf.Cos(f); + float num2 = Mathf.Sin(f); + return new Vector2(self.x * num - num2 * self.y, self.x * num2 + num * self.y); + } + + public static Vector3 RotateY(this Vector3 self, float degrees) + { + float f = 0.017453292f * degrees; + float num = Mathf.Cos(f); + float num2 = Mathf.Sin(f); + return new Vector3(self.x * num - num2 * self.z, self.y, self.x * num2 + num * self.z); + } + + public static bool TryToEnum<TEnum>(this string strEnumValue, out TEnum enumValue) + { + enumValue = default(TEnum); + if (!Enum.IsDefined(typeof(TEnum), strEnumValue)) + { + return false; + } + enumValue = (TEnum)((object)Enum.Parse(typeof(TEnum), strEnumValue)); + return true; + } + + public static TEnum ToEnum<TEnum>(this string strEnumValue) + { + if (!Enum.IsDefined(typeof(TEnum), strEnumValue)) + { + return default(TEnum); + } + return (TEnum)((object)Enum.Parse(typeof(TEnum), strEnumValue)); + } + + public static TEnum ToEnum<TEnum>(this string strEnumValue, TEnum defaultValue) + { + if (!Enum.IsDefined(typeof(TEnum), strEnumValue)) + { + return defaultValue; + } + return (TEnum)((object)Enum.Parse(typeof(TEnum), strEnumValue)); + } + + public static bool IsNullOrWhiteSpace(this string s) + { + if (s == null) + { + return true; + } + return !s.Any((char c) => !char.IsWhiteSpace(c)); + } +} diff --git a/Client/Assembly-CSharp/FindAGameManager.cs b/Client/Assembly-CSharp/FindAGameManager.cs new file mode 100644 index 0000000..b428861 --- /dev/null +++ b/Client/Assembly-CSharp/FindAGameManager.cs @@ -0,0 +1,124 @@ +using System; +using System.Collections.Generic; +using InnerNet; +using UnityEngine; +using UnityEngine.SceneManagement; + +public class FindAGameManager : DestroyableSingleton<FindAGameManager>, IGameListHandler +{ + private const float RefreshTime = 5f; + + private float timer; + + public ObjectPoolBehavior buttonPool; + + public SpinAnimator RefreshSpinner; + + public Scroller TargetArea; + + public float ButtonStart = 1.75f; + + public float ButtonHeight = 0.6f; + + public const bool showPrivate = false; + + private class GameSorter : IComparer<GameListing> + { + public static readonly FindAGameManager.GameSorter Instance = new FindAGameManager.GameSorter(); + + public int Compare(GameListing x, GameListing y) + { + return -x.PlayerCount.CompareTo(y.PlayerCount); + } + } + + public void ResetTimer() + { + this.timer = 5f; + this.RefreshSpinner.Appear(); + this.RefreshSpinner.StartPulse(); + } + + public void Start() + { + if (!AmongUsClient.Instance) + { + AmongUsClient.Instance = UnityEngine.Object.FindObjectOfType<AmongUsClient>(); + if (!AmongUsClient.Instance) + { + SceneManager.LoadScene("MMOnline"); + return; + } + } + AmongUsClient.Instance.GameListHandlers.Add(this); + AmongUsClient.Instance.RequestGameList(false, SaveManager.GameSearchOptions); + } + + public void Update() + { + this.timer += Time.deltaTime; + GameOptionsData gameSearchOptions = SaveManager.GameSearchOptions; + if ((this.timer < 0f || this.timer > 5f) && gameSearchOptions.MapId != 0) + { + this.RefreshSpinner.Appear(); + } + else + { + this.RefreshSpinner.Disappear(); + } + if (Input.GetKeyUp(KeyCode.Escape)) + { + this.ExitGame(); + } + } + + public void RefreshList() + { + if (this.timer > 5f) + { + this.timer = -5f; + this.RefreshSpinner.Play(); + AmongUsClient.Instance.RequestGameList(false, SaveManager.GameSearchOptions); + } + } + + public override void OnDestroy() + { + if (AmongUsClient.Instance) + { + AmongUsClient.Instance.GameListHandlers.Remove(this); + } + base.OnDestroy(); + } + + public void HandleList(int totalGames, List<GameListing> availableGames) + { + Debug.Log(string.Format("TotalGames: {0}\tAvailable: {1}", totalGames, availableGames.Count)); + this.RefreshSpinner.Disappear(); + this.timer = 0f; + availableGames.Sort(FindAGameManager.GameSorter.Instance); + while (this.buttonPool.activeChildren.Count > availableGames.Count) + { + PoolableBehavior poolableBehavior = this.buttonPool.activeChildren[this.buttonPool.activeChildren.Count - 1]; + poolableBehavior.OwnerPool.Reclaim(poolableBehavior); + } + while (this.buttonPool.activeChildren.Count < availableGames.Count) + { + this.buttonPool.Get<PoolableBehavior>().transform.SetParent(this.TargetArea.Inner); + } + Vector3 vector = new Vector3(0f, this.ButtonStart, -1f); + for (int i = 0; i < this.buttonPool.activeChildren.Count; i++) + { + MatchMakerGameButton matchMakerGameButton = (MatchMakerGameButton)this.buttonPool.activeChildren[i]; + matchMakerGameButton.SetGame(availableGames[i]); + matchMakerGameButton.transform.localPosition = vector; + vector.y -= this.ButtonHeight; + } + this.TargetArea.YBounds.max = Mathf.Max(0f, -vector.y - this.ButtonStart); + } + + public void ExitGame() + { + AmongUsClient.Instance.ExitGame(DisconnectReasons.ExitGame); + } +} diff --git a/Client/Assembly-CSharp/FindGameButton.cs b/Client/Assembly-CSharp/FindGameButton.cs new file mode 100644 index 0000000..4b3eef9 --- /dev/null +++ b/Client/Assembly-CSharp/FindGameButton.cs @@ -0,0 +1,63 @@ +using System; +using System.Collections; +using InnerNet; +using PowerTools; +using UnityEngine; +using UnityEngine.SceneManagement; + +public class FindGameButton : MonoBehaviour, IConnectButton +{ + public SpriteAnim connectIcon; + + public AnimationClip connectClip; + + public void OnClick() + { + if (NameTextBehaviour.Instance.ShakeIfInvalid()) + { + return; + } + if (StatsManager.Instance.AmBanned) + { + AmongUsClient.Instance.LastDisconnectReason = DisconnectReasons.IntentionalLeaving; + DestroyableSingleton<DisconnectPopup>.Instance.Show(); + return; + } + if (!DestroyableSingleton<MatchMaker>.Instance.Connecting(this)) + { + return; + } + AmongUsClient.Instance.GameMode = GameModes.OnlineGame; + AmongUsClient.Instance.MainMenuScene = "MMOnline"; + base.StartCoroutine(this.ConnectForFindGame()); + } + + private IEnumerator ConnectForFindGame() + { + AmongUsClient.Instance.SetEndpoint(DestroyableSingleton<ServerManager>.Instance.OnlineNetAddress, 22023); + AmongUsClient.Instance.OnlineScene = "OnlineGame"; + AmongUsClient.Instance.mode = MatchMakerModes.Client; + yield return AmongUsClient.Instance.CoConnect(); + if (AmongUsClient.Instance.LastDisconnectReason != DisconnectReasons.ExitGame) + { + DestroyableSingleton<MatchMaker>.Instance.NotConnecting(); + } + else + { + AmongUsClient.Instance.HostId = AmongUsClient.Instance.ClientId; + SceneManager.LoadScene("FindAGame"); + } + yield break; + } + + public void StartIcon() + { + this.connectIcon.Play(this.connectClip, 1f); + } + + public void StopIcon() + { + this.connectIcon.Stop(); + this.connectIcon.GetComponent<SpriteRenderer>().sprite = null; + } +} diff --git a/Client/Assembly-CSharp/FingerBehaviour.cs b/Client/Assembly-CSharp/FingerBehaviour.cs new file mode 100644 index 0000000..b39ad65 --- /dev/null +++ b/Client/Assembly-CSharp/FingerBehaviour.cs @@ -0,0 +1,101 @@ +using System; +using System.Collections; +using UnityEngine; + +public class FingerBehaviour : MonoBehaviour +{ + public SpriteRenderer Finger; + + public SpriteRenderer Click; + + public float liftedAngle = -20f; + + public static class Quadratic + { + public static float InOut(float k) + { + if (k < 0f) + { + k = 0f; + } + if (k > 1f) + { + k = 1f; + } + if ((k *= 2f) < 1f) + { + return 0.5f * k * k; + } + return -0.5f * ((k -= 1f) * (k - 2f) - 1f); + } + } + + public IEnumerator DoClick(float duration) + { + for (float time = 0f; time < duration; time += Time.deltaTime) + { + float num = time / duration; + if (num < 0.4f) + { + float num2 = num / 0.4f; + num2 = num2 * 2f - 1f; + if (num2 < 0f) + { + float fingerAngle = Mathf.Lerp(this.liftedAngle, this.liftedAngle * 2f, 1f + Mathf.Abs(num2)); + this.SetFingerAngle(fingerAngle); + } + else + { + float fingerAngle2 = Mathf.Lerp(this.liftedAngle * 2f, 0f, num2); + this.SetFingerAngle(fingerAngle2); + } + } + else if (num < 0.7f) + { + this.ClickOn(); + } + else + { + float t = (num - 0.7f) / 0.3f; + this.Click.enabled = false; + float fingerAngle3 = Mathf.Lerp(0f, this.liftedAngle, t); + this.SetFingerAngle(fingerAngle3); + } + yield return null; + } + this.ClickOff(); + yield break; + } + + private void SetFingerAngle(float angle) + { + this.Finger.transform.localRotation = Quaternion.Euler(0f, 0f, angle); + } + + public void ClickOff() + { + this.Click.enabled = false; + this.SetFingerAngle(this.liftedAngle); + } + + public void ClickOn() + { + this.Click.enabled = true; + this.SetFingerAngle(0f); + } + + public IEnumerator MoveTo(Vector2 target, float duration) + { + Vector3 startPos = base.transform.position; + Vector3 targetPos = target; + targetPos.z = startPos.z; + for (float time = 0f; time < duration; time += Time.deltaTime) + { + float t = time / duration; + base.transform.position = Vector3.Lerp(startPos, targetPos, t); + yield return null; + } + base.transform.position = targetPos; + yield break; + } +} diff --git a/Client/Assembly-CSharp/FixedActionConsole.cs b/Client/Assembly-CSharp/FixedActionConsole.cs new file mode 100644 index 0000000..63707bb --- /dev/null +++ b/Client/Assembly-CSharp/FixedActionConsole.cs @@ -0,0 +1,64 @@ +using System; +using UnityEngine; +using UnityEngine.UI; + +public class FixedActionConsole : MonoBehaviour, IUsable +{ + public float UsableDistance + { + get + { + return this.usableDistance; + } + } + + public float PercentCool + { + get + { + return 0f; + } + } + + public float usableDistance = 1f; + + public SpriteRenderer Image; + + public Button.ButtonClickedEvent OnUse; + + public void SetOutline(bool on, bool mainTarget) + { + if (this.Image) + { + this.Image.material.SetFloat("_Outline", (float)(on ? 1 : 0)); + this.Image.material.SetColor("_OutlineColor", Color.white); + this.Image.material.SetColor("_AddColor", mainTarget ? Color.white : Color.clear); + } + } + + public float CanUse(GameData.PlayerInfo pc, out bool canUse, out bool couldUse) + { + float num = float.MaxValue; + PlayerControl @object = pc.Object; + couldUse = (pc.Object.CanMove && !pc.IsDead); + canUse = couldUse; + if (canUse) + { + num = Vector2.Distance(@object.GetTruePosition(), base.transform.position); + canUse &= (num <= this.UsableDistance); + } + return num; + } + + public void Use() + { + bool flag; + bool flag2; + this.CanUse(PlayerControl.LocalPlayer.Data, out flag, out flag2); + if (!flag) + { + return; + } + this.OnUse.Invoke(); + } +} diff --git a/Client/Assembly-CSharp/FlatWaveBehaviour.cs b/Client/Assembly-CSharp/FlatWaveBehaviour.cs new file mode 100644 index 0000000..4f10d5a --- /dev/null +++ b/Client/Assembly-CSharp/FlatWaveBehaviour.cs @@ -0,0 +1,75 @@ +using System; +using UnityEngine; + +[RequireComponent(typeof(MeshFilter))] +[RequireComponent(typeof(MeshRenderer))] +public class FlatWaveBehaviour : MonoBehaviour +{ + public int NumPoints = 128; + + public FloatRange Width; + + public FloatRange Delta; + + public float Center; + + private Mesh mesh; + + private Vector3[] vecs; + + public float TickRate = 0.1f; + + private float timer; + + public int Skip = 3; + + [Range(0f, 1f)] + public float NoiseP = 0.5f; + + public void Start() + { + this.mesh = new Mesh(); + base.GetComponent<MeshFilter>().mesh = this.mesh; + this.mesh.MarkDynamic(); + this.vecs = new Vector3[this.NumPoints]; + int[] array = new int[this.NumPoints]; + for (int i = 0; i < this.vecs.Length; i++) + { + Vector3 vector = this.vecs[i]; + vector.x = this.Width.Lerp((float)i / (float)this.vecs.Length); + vector.y = this.Center; + if (BoolRange.Next(this.NoiseP)) + { + vector.y += this.Delta.Next(); + } + this.vecs[i] = vector; + array[i] = i; + } + this.mesh.vertices = this.vecs; + this.mesh.SetIndices(array, MeshTopology.LineStrip, 0); + } + + public void Update() + { + this.timer += Time.deltaTime; + if (this.timer > this.TickRate) + { + this.timer = 0f; + for (int i = 0; i < this.vecs.Length - this.Skip; i++) + { + this.vecs[i].y = this.vecs[i + this.Skip].y; + } + for (int j = 1; j <= this.Skip; j++) + { + this.vecs[this.vecs.Length - j].y = this.Center; + if (BoolRange.Next(this.NoiseP)) + { + Vector3[] array = this.vecs; + int num = this.vecs.Length - j; + array[num].y = array[num].y + this.Delta.Next(); + } + } + this.mesh.vertices = this.vecs; + } + } +} diff --git a/Client/Assembly-CSharp/FloatRange.cs b/Client/Assembly-CSharp/FloatRange.cs new file mode 100644 index 0000000..ca7cfbd --- /dev/null +++ b/Client/Assembly-CSharp/FloatRange.cs @@ -0,0 +1,159 @@ +using System; +using System.Collections.Generic; +using UnityEngine; + +[Serializable] +public class FloatRange +{ + public float Last { get; private set; } + + public float Width + { + get + { + return this.max - this.min; + } + } + + public float min; + + public float max; + + public FloatRange(float min, float max) + { + this.min = min; + this.max = max; + } + + public float ChangeRange(float y, float min, float max) + { + return Mathf.Lerp(min, max, (y - this.min) / this.Width); + } + + public float Clamp(float value) + { + return Mathf.Clamp(value, this.min, this.max); + } + + public bool Contains(float t) + { + return this.min <= t && this.max >= t; + } + + public float CubicLerp(float v) + { + if (this.min >= this.max) + { + return this.min; + } + v = Mathf.Clamp(0f, 1f, v); + return v * v * v * (this.max - this.min) + this.min; + } + + public float EitherOr() + { + if (UnityEngine.Random.value <= 0.5f) + { + return this.max; + } + return this.min; + } + + public float LerpUnclamped(float v) + { + return Mathf.LerpUnclamped(this.min, this.max, v); + } + + public float Lerp(float v) + { + return Mathf.Lerp(this.min, this.max, v); + } + + public float ExpOutLerp(float v) + { + return this.Lerp(1f - Mathf.Pow(2f, -10f * v)); + } + + public static float ExpOutLerp(float v, float min, float max) + { + return Mathf.Lerp(min, max, 1f - Mathf.Pow(2f, -10f * v)); + } + + public static float Next(float min, float max) + { + return UnityEngine.Random.Range(min, max); + } + + public float Next() + { + return this.Last = UnityEngine.Random.Range(this.min, this.max); + } + + public IEnumerable<float> Range(int numStops) + { + float num; + for (float i = 0f; i <= (float)numStops; i = num) + { + yield return Mathf.Lerp(this.min, this.max, i / (float)numStops); + num = i + 1f; + } + yield break; + } + + public IEnumerable<float> RandomRange(int numStops) + { + float num; + for (float i = 0f; i <= (float)numStops; i = num) + { + yield return this.Next(); + num = i + 1f; + } + yield break; + } + + internal float ReverseLerp(float t) + { + return Mathf.Clamp((t - this.min) / this.Width, 0f, 1f); + } + + public static float ReverseLerp(float t, float min, float max) + { + float num = max - min; + return Mathf.Clamp((t - min) / num, 0f, 1f); + } + + public IEnumerable<float> SpreadToEdges(int stops) + { + return FloatRange.SpreadToEdges(this.min, this.max, stops); + } + + public IEnumerable<float> SpreadEvenly(int stops) + { + return FloatRange.SpreadEvenly(this.min, this.max, stops); + } + + public static IEnumerable<float> SpreadToEdges(float min, float max, int stops) + { + if (stops == 1) + { + yield break; + } + int num; + for (int i = 0; i < stops; i = num) + { + yield return Mathf.Lerp(min, max, (float)i / ((float)stops - 1f)); + num = i + 1; + } + yield break; + } + + public static IEnumerable<float> SpreadEvenly(float min, float max, int stops) + { + float step = 1f / ((float)stops + 1f); + for (float i = step; i < 1f; i += step) + { + yield return Mathf.Lerp(min, max, i); + } + yield break; + } +} diff --git a/Client/Assembly-CSharp/FollowerCamera.cs b/Client/Assembly-CSharp/FollowerCamera.cs new file mode 100644 index 0000000..3184542 --- /dev/null +++ b/Client/Assembly-CSharp/FollowerCamera.cs @@ -0,0 +1,54 @@ +using System; +using System.Collections; +using UnityEngine; + +internal class FollowerCamera : MonoBehaviour +{ + public MonoBehaviour Target; + + public Vector2 Offset; + + public bool Locked; + + public float shakeAmount; + + public float shakePeriod = 1f; + + public void FixedUpdate() + { + if (this.Target && !this.Locked) + { + base.transform.position = Vector3.Lerp(base.transform.position, this.Target.transform.position + this.Offset, 5f * Time.deltaTime); + if (this.shakeAmount > 0f) + { + float num = Mathf.PerlinNoise(0.5f, Time.time * this.shakePeriod) * 2f - 1f; + float num2 = Mathf.PerlinNoise(Time.time * this.shakePeriod, 0.5f) * 2f - 1f; + base.transform.Translate(num * this.shakeAmount, num2 * this.shakeAmount, 0f); + } + } + } + + public void ShakeScreen(float duration, float severity) + { + base.StartCoroutine(this.CoShakeScreen(duration, severity)); + } + + private IEnumerator CoShakeScreen(float duration, float severity) + { + WaitForFixedUpdate wait = new WaitForFixedUpdate(); + for (float t = duration; t > 0f; t -= Time.fixedDeltaTime) + { + float d = t / duration; + this.Offset = UnityEngine.Random.insideUnitCircle * d * severity; + yield return wait; + } + this.Offset = Vector2.zero; + yield break; + } + + internal void SetTarget(MonoBehaviour target) + { + this.Target = target; + base.transform.position = this.Target.transform.position + this.Offset; + } +} diff --git a/Client/Assembly-CSharp/FontCache.cs b/Client/Assembly-CSharp/FontCache.cs new file mode 100644 index 0000000..91dc7a0 --- /dev/null +++ b/Client/Assembly-CSharp/FontCache.cs @@ -0,0 +1,78 @@ +using System; +using System.Collections.Generic; +using UnityEngine; + +public class FontCache : MonoBehaviour +{ + public static FontCache Instance; + + private Dictionary<string, FontData> cache = new Dictionary<string, FontData>(); + + public List<FontExtensionData> extraData = new List<FontExtensionData>(); + + public List<TextAsset> DefaultFonts = new List<TextAsset>(); + + public List<Material> DefaultFontMaterials = new List<Material>(); + + public void OnEnable() + { + if (!FontCache.Instance) + { + FontCache.Instance = this; + UnityEngine.Object.DontDestroyOnLoad(base.gameObject); + return; + } + if (FontCache.Instance != null) + { + UnityEngine.Object.Destroy(base.gameObject); + } + } + + public void SetFont(TextRenderer self, string name) + { + if (self.FontData.name == name) + { + return; + } + for (int i = 0; i < this.DefaultFonts.Count; i++) + { + if (this.DefaultFonts[i].name == name) + { + MeshRenderer component = self.GetComponent<MeshRenderer>(); + Material material = component.material; + self.FontData = this.DefaultFonts[i]; + component.sharedMaterial = this.DefaultFontMaterials[i]; + component.material.SetColor("_OutlineColor", material.GetColor("_OutlineColor")); + component.material.SetInt("_Mask", material.GetInt("_Mask")); + return; + } + } + } + + public FontData LoadFont(TextAsset dataSrc) + { + if (this.cache == null) + { + this.cache = new Dictionary<string, FontData>(); + } + FontData fontData; + if (this.cache.TryGetValue(dataSrc.name, out fontData)) + { + return fontData; + } + int num = this.extraData.FindIndex((FontExtensionData ed) => ed.FontName.Equals(dataSrc.name, StringComparison.OrdinalIgnoreCase)); + FontExtensionData eData = null; + if (num >= 0) + { + eData = this.extraData[num]; + } + fontData = FontCache.LoadFontUncached(dataSrc, eData); + this.cache[dataSrc.name] = fontData; + return fontData; + } + + public static FontData LoadFontUncached(TextAsset dataSrc, FontExtensionData eData = null) + { + return FontLoader.FromBinary(dataSrc, eData); + } +} diff --git a/Client/Assembly-CSharp/FontData.cs b/Client/Assembly-CSharp/FontData.cs new file mode 100644 index 0000000..896d74c --- /dev/null +++ b/Client/Assembly-CSharp/FontData.cs @@ -0,0 +1,32 @@ +using System; +using System.Collections.Generic; +using UnityEngine; + +[Serializable] +public class FontData +{ + public Vector2 TextureSize = new Vector2(256f, 256f); + + public List<Vector4> bounds = new List<Vector4>(); + + public List<Vector3> offsets = new List<Vector3>(); + + public List<Vector4> Channels = new List<Vector4>(); + + public Dictionary<int, int> charMap; + + public float LineHeight; + + public Dictionary<int, Dictionary<int, float>> kernings; + + public float GetKerning(int last, int cur) + { + Dictionary<int, float> dictionary; + float result; + if (this.kernings.TryGetValue(last, out dictionary) && dictionary.TryGetValue(cur, out result)) + { + return result; + } + return 0f; + } +} diff --git a/Client/Assembly-CSharp/FontExtensionData.cs b/Client/Assembly-CSharp/FontExtensionData.cs new file mode 100644 index 0000000..8978b88 --- /dev/null +++ b/Client/Assembly-CSharp/FontExtensionData.cs @@ -0,0 +1,56 @@ +using System; +using System.Collections.Generic; +using UnityEngine; + +[CreateAssetMenu] +public class FontExtensionData : ScriptableObject +{ + public string FontName; + + public List<KerningPair> kernings = new List<KerningPair>(); + + public List<OffsetAdjustment> Offsets = new List<OffsetAdjustment>(); + + public void AdjustKernings(FontData target) + { + for (int i = 0; i < this.kernings.Count; i++) + { + KerningPair kerningPair = this.kernings[i]; + Dictionary<int, float> dictionary; + if (target.kernings.TryGetValue((int)kerningPair.First, out dictionary)) + { + float num; + if (dictionary.TryGetValue((int)kerningPair.Second, out num)) + { + dictionary[(int)kerningPair.Second] = num + (float)kerningPair.Pixels; + } + else + { + dictionary[(int)kerningPair.Second] = (float)kerningPair.Pixels; + } + } + else + { + Dictionary<int, float> dictionary2 = new Dictionary<int, float>(); + dictionary2[(int)kerningPair.Second] = (float)kerningPair.Pixels; + target.kernings[(int)kerningPair.First] = dictionary2; + } + } + } + + public void AdjustOffsets(FontData target) + { + for (int i = 0; i < this.Offsets.Count; i++) + { + OffsetAdjustment offsetAdjustment = this.Offsets[i]; + int index; + if (target.charMap.TryGetValue((int)offsetAdjustment.Char, out index)) + { + Vector3 value = target.offsets[index]; + value.x += (float)offsetAdjustment.OffsetX; + value.y += (float)offsetAdjustment.OffsetY; + target.offsets[index] = value; + } + } + } +} diff --git a/Client/Assembly-CSharp/FontLoader.cs b/Client/Assembly-CSharp/FontLoader.cs new file mode 100644 index 0000000..c65a693 --- /dev/null +++ b/Client/Assembly-CSharp/FontLoader.cs @@ -0,0 +1,106 @@ +using System; +using System.Collections.Generic; +using System.IO; +using UnityEngine; + +public static class FontLoader +{ + public static FontData FromBinary(TextAsset dataSrc, FontExtensionData eData) + { + FontData fontData = new FontData(); + using (MemoryStream memoryStream = new MemoryStream(dataSrc.bytes)) + { + using (BinaryReader binaryReader = new BinaryReader(memoryStream)) + { + if (memoryStream.ReadByte() != 66 || memoryStream.ReadByte() != 77 || memoryStream.ReadByte() != 70 || memoryStream.ReadByte() != 3) + { + throw new InvalidDataException("Wrong format font."); + } + long num = -1L; + while (memoryStream.Position < memoryStream.Length) + { + if (num == memoryStream.Position) + { + throw new InvalidDataException("Bad font."); + } + num = memoryStream.Position; + byte b = binaryReader.ReadByte(); + int num2 = binaryReader.ReadInt32(); + long position = memoryStream.Position; + switch (b) + { + default: + memoryStream.Position += (long)num2; + break; + case 2: + fontData.LineHeight = (float)binaryReader.ReadUInt16(); + memoryStream.Position += 2L; + fontData.TextureSize = new Vector2((float)binaryReader.ReadUInt16(), (float)binaryReader.ReadUInt16()); + memoryStream.Position = position + (long)num2; + break; + case 4: + { + int num3 = num2 / 20; + fontData.charMap = new Dictionary<int, int>(num3); + fontData.bounds.Capacity = num3; + fontData.offsets.Capacity = num3; + fontData.Channels.Capacity = num3; + fontData.kernings = new Dictionary<int, Dictionary<int, float>>(256); + for (int i = 0; i < num3; i++) + { + int key = binaryReader.ReadInt32(); + int num4 = (int)binaryReader.ReadUInt16(); + int num5 = (int)binaryReader.ReadUInt16(); + int num6 = (int)binaryReader.ReadUInt16(); + int num7 = (int)binaryReader.ReadUInt16(); + int num8 = (int)binaryReader.ReadInt16(); + int num9 = (int)binaryReader.ReadInt16(); + int num10 = (int)binaryReader.ReadInt16(); + binaryReader.ReadByte(); + int input = (int)binaryReader.ReadByte(); + fontData.charMap.Add(key, fontData.bounds.Count); + fontData.bounds.Add(new Vector4((float)num4, (float)num5, (float)num6, (float)num7)); + fontData.offsets.Add(new Vector3((float)num8, (float)num9, (float)num10)); + fontData.Channels.Add(FontLoader.IntToChannels(input)); + } + break; + } + case 5: + while (memoryStream.Position < position + (long)num2) + { + int key2 = binaryReader.ReadInt32(); + int key3 = binaryReader.ReadInt32(); + int num11 = (int)binaryReader.ReadInt16(); + Dictionary<int, float> dictionary; + if (!fontData.kernings.TryGetValue(key2, out dictionary)) + { + fontData.kernings.Add(key2, dictionary = new Dictionary<int, float>(256)); + } + dictionary.Add(key3, (float)num11); + } + break; + } + } + } + } + if (eData != null) + { + eData.AdjustKernings(fontData); + eData.AdjustOffsets(fontData); + } + return fontData; + } + + private static Vector4 IntToChannels(int input) + { + Vector4 result = default(Vector4); + for (int i = 0; i < 4; i++) + { + if ((input >> i & 1) == 1) + { + result[i] = 1f; + } + } + return result; + } +} diff --git a/Client/Assembly-CSharp/GameData.cs b/Client/Assembly-CSharp/GameData.cs new file mode 100644 index 0000000..4941bd6 --- /dev/null +++ b/Client/Assembly-CSharp/GameData.cs @@ -0,0 +1,556 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using Assets.CoreScripts; +using Hazel; +using InnerNet; +using UnityEngine; + +public class GameData : InnerNetObject, IDisconnectHandler +{ + public int PlayerCount + { + get + { + return this.AllPlayers.Count; + } + } + + public static GameData Instance; + + // 所有角色数据 + public List<GameData.PlayerInfo> AllPlayers = new List<GameData.PlayerInfo>(); + + public int TotalTasks; + + public int CompletedTasks; + + public const byte InvalidPlayerId = 255; + + public const byte DisconnectedPlayerId = 254; + + public class TaskInfo + { + public uint Id; + + public bool Complete; + + public void Serialize(MessageWriter writer) + { + writer.WritePacked(this.Id); + writer.Write(this.Complete); + } + + public void Deserialize(MessageReader reader) + { + this.Id = reader.ReadPackedUInt32(); + this.Complete = reader.ReadBoolean(); + } + } + + //c 角色数据,包括外观、装饰、是否是imposter、是否死亡 + public class PlayerInfo + { + public PlayerControl Object + { + get + { + if (!this._object) + { + this._object = PlayerControl.AllPlayerControls.FirstOrDefault((PlayerControl p) => p.PlayerId == this.PlayerId); + } + return this._object; + } + } + + public readonly byte PlayerId; + + public string PlayerName = string.Empty; + + public byte ColorId; + + public uint HatId; + + public uint PetId; + + public uint SkinId; + + public bool Disconnected; + + public List<GameData.TaskInfo> Tasks; + + public bool IsImpostor; + + public bool IsDead; + + private PlayerControl _object; + + public PlayerInfo(byte playerId) + { + this.PlayerId = playerId; + } + + public PlayerInfo(PlayerControl pc) : this(pc.PlayerId) + { + this._object = pc; + } + + public void Serialize(MessageWriter writer) + { + writer.Write(this.PlayerName); + writer.Write(this.ColorId); + writer.WritePacked(this.HatId); + writer.WritePacked(this.PetId); + writer.WritePacked(this.SkinId); + byte b = 0; + if (this.Disconnected) + { + b |= 1; + } + if (this.IsImpostor) + { + b |= 2; + } + if (this.IsDead) + { + b |= 4; + } + writer.Write(b); + if (this.Tasks != null) + { + writer.Write((byte)this.Tasks.Count); + for (int i = 0; i < this.Tasks.Count; i++) + { + this.Tasks[i].Serialize(writer); + } + return; + } + writer.Write(0); + } + + public void Deserialize(MessageReader reader) + { + this.PlayerName = reader.ReadString(); + this.ColorId = reader.ReadByte(); + this.HatId = reader.ReadPackedUInt32(); + this.PetId = reader.ReadPackedUInt32(); + this.SkinId = reader.ReadPackedUInt32(); + byte b = reader.ReadByte(); + this.Disconnected = ((b & 1) > 0); + this.IsImpostor = ((b & 2) > 0); + this.IsDead = ((b & 4) > 0); + byte b2 = reader.ReadByte(); + this.Tasks = new List<GameData.TaskInfo>((int)b2); + for (int i = 0; i < (int)b2; i++) + { + this.Tasks.Add(new GameData.TaskInfo()); + this.Tasks[i].Deserialize(reader); + } + } + + public GameData.TaskInfo FindTaskById(uint taskId) + { + for (int i = 0; i < this.Tasks.Count; i++) + { + if (this.Tasks[i].Id == taskId) + { + return this.Tasks[i]; + } + } + return null; + } + } + + private enum RpcCalls + { + SetTasks + } + + public void Awake() + { + if (GameData.Instance && GameData.Instance != this) + { + UnityEngine.Object.Destroy(base.gameObject); + return; + } + GameData.Instance = this; + if (AmongUsClient.Instance) + { + AmongUsClient.Instance.DisconnectHandlers.AddUnique(this); + } + } + + internal void SetDirty() + { + base.SetDirtyBit(uint.MaxValue); + } + + public GameData.PlayerInfo GetHost() + { + ClientData host = AmongUsClient.Instance.GetHost(); + if (host != null && host.Character) + { + return host.Character.Data; + } + return null; + } + + public sbyte GetAvailableId() + { + sbyte i; + sbyte j; + for (i = 0; i < 10; i = j + 1) + { + if (!this.AllPlayers.Any((GameData.PlayerInfo p) => p.PlayerId == (byte)i)) + { + return i; + } + j = i; + } + return -1; + } + + public GameData.PlayerInfo GetPlayerById(byte id) + { + if (id == 255) + { + return null; + } + for (int i = 0; i < this.AllPlayers.Count; i++) + { + if (this.AllPlayers[i].PlayerId == id) + { + return this.AllPlayers[i]; + } + } + return null; + } + + public void UpdateName(byte playerId, string name) + { + GameData.PlayerInfo playerById = this.GetPlayerById(playerId); + if (playerById != null) + { + playerById.PlayerName = name; + } + base.SetDirtyBit(1U << (int)playerId); + } + + public void UpdateColor(byte playerId, byte color) + { + GameData.PlayerInfo playerById = this.GetPlayerById(playerId); + if (playerById != null) + { + playerById.ColorId = color; + } + base.SetDirtyBit(1U << (int)playerId); + } + + public void UpdateHat(byte playerId, uint hat) + { + GameData.PlayerInfo playerById = this.GetPlayerById(playerId); + if (playerById != null) + { + playerById.HatId = hat; + } + base.SetDirtyBit(1U << (int)playerId); + } + + public void UpdatePet(byte playerId, uint petId) + { + GameData.PlayerInfo playerById = this.GetPlayerById(playerId); + if (playerById != null) + { + playerById.PetId = petId; + } + base.SetDirtyBit(1U << (int)playerId); + } + + public void UpdateSkin(byte playerId, uint skin) + { + GameData.PlayerInfo playerById = this.GetPlayerById(playerId); + if (playerById != null) + { + playerById.SkinId = skin; + } + base.SetDirtyBit(1U << (int)playerId); + } + + public void AddPlayer(PlayerControl pc) + { + GameData.PlayerInfo item = new GameData.PlayerInfo(pc); + this.AllPlayers.Add(item); + base.SetDirtyBit(1U << (int)pc.PlayerId); + } + + public bool RemovePlayer(byte playerId) + { + for (int i = 0; i < this.AllPlayers.Count; i++) + { + if (this.AllPlayers[i].PlayerId == playerId) + { + this.SetDirty(); + this.AllPlayers.RemoveAt(i); + return true; + } + } + return false; + } + + public void RecomputeTaskCounts() + { + this.TotalTasks = 0; + this.CompletedTasks = 0; + for (int i = 0; i < this.AllPlayers.Count; i++) + { + GameData.PlayerInfo playerInfo = this.AllPlayers[i]; + if (!playerInfo.Disconnected && playerInfo.Tasks != null && playerInfo.Object && (PlayerControl.GameOptions.GhostsDoTasks || !playerInfo.IsDead) && !playerInfo.IsImpostor) + { + for (int j = 0; j < playerInfo.Tasks.Count; j++) + { + this.TotalTasks++; + if (playerInfo.Tasks[j].Complete) + { + this.CompletedTasks++; + } + } + } + } + } + + public void TutOnlyRemoveTask(byte playerId, uint taskId) + { + GameData.PlayerInfo playerById = this.GetPlayerById(playerId); + GameData.TaskInfo item = playerById.FindTaskById(taskId); + playerById.Tasks.Remove(item); + this.RecomputeTaskCounts(); + } + + public void TutOnlyAddTask(byte playerId, uint taskId) + { + this.GetPlayerById(playerId).Tasks.Add(new GameData.TaskInfo + { + Id = taskId + }); + this.TotalTasks++; + } + + private void SetTasks(byte playerId, byte[] taskTypeIds) + { + GameData.PlayerInfo playerById = this.GetPlayerById(playerId); + if (playerById == null) + { + Debug.Log("Could not set tasks for player id: " + playerId); + return; + } + if (playerById.Disconnected) + { + return; + } + if (!playerById.Object) + { + Debug.Log(string.Concat(new object[] + { + "Could not set tasks for player (", + playerById.PlayerName, + "): ", + playerId + })); + return; + } + playerById.Tasks = new List<GameData.TaskInfo>(taskTypeIds.Length); + for (int i = 0; i < taskTypeIds.Length; i++) + { + playerById.Tasks.Add(new GameData.TaskInfo()); + playerById.Tasks[i].Id = (uint)i; + } + playerById.Object.SetTasks(taskTypeIds); + base.SetDirtyBit(1U << (int)playerById.PlayerId); + } + + public void CompleteTask(PlayerControl pc, uint taskId) + { + GameData.TaskInfo taskInfo = pc.Data.FindTaskById(taskId); + if (taskInfo == null) + { + Debug.LogWarning("Couldn't find task: " + taskId); + return; + } + if (!taskInfo.Complete) + { + taskInfo.Complete = true; + this.CompletedTasks++; + return; + } + Debug.LogWarning("Double complete task: " + taskId); + } + + public void HandleDisconnect(PlayerControl player, DisconnectReasons reason) + { + if (!player) + { + return; + } + GameData.PlayerInfo playerById = this.GetPlayerById(player.PlayerId); + if (playerById == null) + { + return; + } + if (AmongUsClient.Instance.IsGameStarted) + { + if (!playerById.Disconnected) + { + playerById.Disconnected = true; + TempData.LastDeathReason = DeathReason.Disconnect; + this.ShowNotification(playerById.PlayerName, reason); + } + } + else if (this.RemovePlayer(player.PlayerId)) + { + this.ShowNotification(playerById.PlayerName, reason); + } + this.RecomputeTaskCounts(); + } + + private void ShowNotification(string playerName, DisconnectReasons reason) + { + if (string.IsNullOrEmpty(playerName)) + { + return; + } + if (reason <= DisconnectReasons.Banned) + { + if (reason == DisconnectReasons.ExitGame) + { + DestroyableSingleton<HudManager>.Instance.Notifier.AddItem(playerName + " left the game."); + return; + } + if (reason == DisconnectReasons.Banned) + { + GameData.PlayerInfo data = AmongUsClient.Instance.GetHost().Character.Data; + DestroyableSingleton<HudManager>.Instance.Notifier.AddItem(playerName + " was banned by " + data.PlayerName + "."); + return; + } + } + else if (reason == DisconnectReasons.Kicked) + { + GameData.PlayerInfo data2 = AmongUsClient.Instance.GetHost().Character.Data; + DestroyableSingleton<HudManager>.Instance.Notifier.AddItem(playerName + " was kicked by " + data2.PlayerName + "."); + return; + } + DestroyableSingleton<HudManager>.Instance.Notifier.AddItem(playerName + " left the game due to error."); + } + + public void HandleDisconnect() + { + if (!AmongUsClient.Instance.IsGameStarted) + { + for (int i = this.AllPlayers.Count - 1; i >= 0; i--) + { + if (!this.AllPlayers[i].Object) + { + this.AllPlayers.RemoveAt(i); + } + } + } + } + + public override bool Serialize(MessageWriter writer, bool initialState) + { + if (initialState) + { + if (!DestroyableSingleton<Telemetry>.Instance.IsInitialized) + { + DestroyableSingleton<Telemetry>.Instance.Initialize(); + } + writer.WriteBytesAndSize(DestroyableSingleton<Telemetry>.Instance.CurrentGuid.ToByteArray()); + writer.WritePacked(this.AllPlayers.Count); + for (int i = 0; i < this.AllPlayers.Count; i++) + { + GameData.PlayerInfo playerInfo = this.AllPlayers[i]; + writer.Write(playerInfo.PlayerId); + playerInfo.Serialize(writer); + } + } + else + { + int position = writer.Position; + byte b = 0; + writer.Write(b); + for (int j = 0; j < this.AllPlayers.Count; j++) + { + GameData.PlayerInfo playerInfo2 = this.AllPlayers[j]; + if ((this.DirtyBits & 1U << (int)playerInfo2.PlayerId) != 0U) + { + writer.Write(playerInfo2.PlayerId); + playerInfo2.Serialize(writer); + b += 1; + } + } + writer.Position = position; + writer.Write(b); + writer.Position = writer.Length; + this.DirtyBits = 0U; + } + return true; + } + + public override void Deserialize(MessageReader reader, bool initialState) + { + if (initialState) + { + Guid gameGuid = new Guid(reader.ReadBytesAndSize()); + if (!DestroyableSingleton<Telemetry>.Instance.IsInitialized) + { + DestroyableSingleton<Telemetry>.Instance.Initialize(gameGuid); + } + int num = reader.ReadPackedInt32(); + for (int i = 0; i < num; i++) + { + GameData.PlayerInfo playerInfo = new GameData.PlayerInfo(reader.ReadByte()); + playerInfo.Deserialize(reader); + this.AllPlayers.Add(playerInfo); + } + } + else + { + byte b = reader.ReadByte(); + for (int j = 0; j < (int)b; j++) + { + byte b2 = reader.ReadByte(); + GameData.PlayerInfo playerInfo2 = this.GetPlayerById(b2); + if (playerInfo2 != null) + { + playerInfo2.Deserialize(reader); + } + else + { + playerInfo2 = new GameData.PlayerInfo(b2); + playerInfo2.Deserialize(reader); + this.AllPlayers.Add(playerInfo2); + } + } + } + this.RecomputeTaskCounts(); + } + + public void RpcSetTasks(byte playerId, byte[] taskTypeIds) + { + if (AmongUsClient.Instance.AmClient) + { + this.SetTasks(playerId, taskTypeIds); + } + MessageWriter messageWriter = AmongUsClient.Instance.StartRpc(this.NetId, 0, SendOption.Reliable); + messageWriter.Write(playerId); + messageWriter.WriteBytesAndSize(taskTypeIds); + messageWriter.EndMessage(); + } + + public override void HandleRpc(byte callId, MessageReader reader) + { + if (callId == 0) + { + this.SetTasks(reader.ReadByte(), reader.ReadBytesAndSize()); + } + } +} diff --git a/Client/Assembly-CSharp/GameDiscovery.cs b/Client/Assembly-CSharp/GameDiscovery.cs new file mode 100644 index 0000000..5742e43 --- /dev/null +++ b/Client/Assembly-CSharp/GameDiscovery.cs @@ -0,0 +1,83 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using Hazel.Udp; +using InnerNet; +using UnityEngine; + +public class GameDiscovery : MonoBehaviour +{ + public JoinGameButton ButtonPrefab; + + public Transform ItemLocation; + + public float YStart = 0.56f; + + public float YOffset = -0.75f; + + private Dictionary<string, JoinGameButton> received = new Dictionary<string, JoinGameButton>(); + + public void Start() + { + InnerDiscover component = base.GetComponent<InnerDiscover>(); + component.OnPacketGet += this.Receive; + component.StartAsClient(); + } + + public void Update() + { + float time = Time.time; + string[] array = this.received.Keys.ToArray<string>(); + int num = 0; + foreach (string key in array) + { + JoinGameButton joinGameButton = this.received[key]; + if (time - joinGameButton.timeRecieved > 3f) + { + this.received.Remove(key); + UnityEngine.Object.Destroy(joinGameButton.gameObject); + } + else + { + joinGameButton.transform.localPosition = new Vector3(0f, this.YStart + (float)num * this.YOffset, -1f); + num++; + } + } + } + + private void Receive(BroadcastPacket packet) + { + string[] array = packet.Data.Split(new char[] + { + '~' + }); + string address = packet.GetAddress(); + JoinGameButton joinGameButton; + if (this.received.TryGetValue(address, out joinGameButton)) + { + joinGameButton.timeRecieved = Time.time; + joinGameButton.SetGameName(array); + return; + } + if (array[1].Equals("Open")) + { + this.CreateButtonForAddess(address, array); + } + } + + private void CreateButtonForAddess(string fromAddress, string[] gameNameParts) + { + JoinGameButton joinGameButton; + if (this.received.TryGetValue(fromAddress, out joinGameButton)) + { + UnityEngine.Object.Destroy(joinGameButton.gameObject); + } + JoinGameButton joinGameButton2 = UnityEngine.Object.Instantiate<JoinGameButton>(this.ButtonPrefab, this.ItemLocation); + joinGameButton2.transform.localPosition = new Vector3(0f, this.YStart + (float)(this.ItemLocation.childCount - 1) * this.YOffset, -1f); + joinGameButton2.netAddress = fromAddress; + joinGameButton2.timeRecieved = Time.time; + joinGameButton2.SetGameName(gameNameParts); + joinGameButton2.GetComponentInChildren<MeshRenderer>().material.SetInt("_Mask", 4); + this.received[fromAddress] = joinGameButton2; + } +} diff --git a/Client/Assembly-CSharp/GameModes.cs b/Client/Assembly-CSharp/GameModes.cs new file mode 100644 index 0000000..67c0bac --- /dev/null +++ b/Client/Assembly-CSharp/GameModes.cs @@ -0,0 +1,8 @@ +using System; + +public enum GameModes +{ + LocalGame, + OnlineGame, + FreePlay +} diff --git a/Client/Assembly-CSharp/GameObjectExtensions.cs b/Client/Assembly-CSharp/GameObjectExtensions.cs new file mode 100644 index 0000000..57795eb --- /dev/null +++ b/Client/Assembly-CSharp/GameObjectExtensions.cs @@ -0,0 +1,77 @@ +using System; +using System.Collections.Generic; +using UnityEngine; + +public static class GameObjectExtensions +{ + public static T Find<T>(this List<T> self, GameObject toFind) where T : MonoBehaviour + { + for (int i = 0; i < self.Count; i++) + { + T t = self[i]; + if (t.gameObject == toFind) + { + return t; + } + } + return default(T); + } + + public static void SetZ(this Transform self, float z) + { + Vector3 localPosition = self.localPosition; + localPosition.z = z; + self.localPosition = localPosition; + } + + public static void LookAt2d(this Transform self, Vector3 target) + { + Vector3 vector = target - self.transform.position; + vector.Normalize(); + float num = Mathf.Atan2(vector.y, vector.x); + self.transform.rotation = Quaternion.Euler(0f, 0f, num * 57.29578f); + } + + public static void LookAt2d(this Transform self, Transform target) + { + self.LookAt2d(target.transform.position); + } + + public static void DestroyChildren(this Transform self) + { + for (int i = self.childCount - 1; i > -1; i--) + { + Transform child = self.GetChild(i); + child.transform.SetParent(null); + UnityEngine.Object.Destroy(child.gameObject); + } + } + + public static void DestroyChildren(this MonoBehaviour self) + { + for (int i = self.transform.childCount - 1; i > -1; i--) + { + UnityEngine.Object.Destroy(self.transform.GetChild(i).gameObject); + } + } + + public static void ForEachChild(this GameObject self, Action<GameObject> todo) + { + for (int i = self.transform.childCount - 1; i > -1; i--) + { + todo(self.transform.GetChild(i).gameObject); + } + } + + public static void ForEachChildBehavior<T>(this MonoBehaviour self, Action<T> todo) where T : MonoBehaviour + { + for (int i = self.transform.childCount - 1; i > -1; i--) + { + T component = self.transform.GetChild(i).GetComponent<T>(); + if (component) + { + todo(component); + } + } + } +} diff --git a/Client/Assembly-CSharp/GameOptionsData.cs b/Client/Assembly-CSharp/GameOptionsData.cs new file mode 100644 index 0000000..b3ef55f --- /dev/null +++ b/Client/Assembly-CSharp/GameOptionsData.cs @@ -0,0 +1,332 @@ +using System; +using System.IO; +using System.Text; +using InnerNet; +using UnityEngine; + +public class GameOptionsData : IBytesSerializable +{ + private const byte GameDataVersion = 1; + + public static readonly string[] MapNames = new string[] + { + "The Skeld", + "???", + "???" + }; + + public static readonly float[] KillDistances = new float[] + { + 1f, + 1.8f, + 2.5f + }; + + public static readonly string[] KillDistanceStrings = new string[] + { + "Short", + "Normal", + "Long" + }; + + public int MaxPlayers = 10; + + public GameKeywords Keywords = GameKeywords.English; + + public byte MapId; + + public float PlayerSpeedMod = 1f; + + public float CrewLightMod = 1f; + + public float ImpostorLightMod = 1.5f; + + public float KillCooldown = 15f; + + public int NumCommonTasks = 1; + + public int NumLongTasks = 1; + + public int NumShortTasks = 2; + + public int NumEmergencyMeetings = 1; + + public int EmergencyCooldown = 15; + + public int NumImpostors = 1; + + public bool GhostsDoTasks = true; + + public int KillDistance = 1; + + public int DiscussionTime = 15; + + public int VotingTime = 120; + + public bool isDefaults = true; + + private static readonly int[] RecommendedKillCooldown = new int[] + { + 0, + 0, + 0, + 0, + 45, + 30, + 15, + 35, + 30, + 25, + 20 + }; + + private static readonly int[] RecommendedImpostors = new int[] + { + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 2, + 2, + 2, + 2 + }; + + private static readonly int[] MaxImpostors = new int[] + { + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 2, + 2, + 3, + 3 + }; + + public static readonly int[] MinPlayers = new int[] + { + 4, + 4, + 7, + 9 + }; + + public void ToggleMapFilter(byte newId) + { + byte b = (byte)(((int)this.MapId ^ 1 << (int)newId) & 3); + if (b != 0) + { + this.MapId = b; + } + } + + public bool FilterContainsMap(byte newId) + { + int num = 1 << (int)newId; + return ((int)this.MapId & num) == num; + } + + public GameOptionsData() + { + try + { + SystemLanguage systemLanguage = Application.systemLanguage; + if (systemLanguage <= SystemLanguage.Portuguese) + { + if (systemLanguage != SystemLanguage.Korean) + { + if (systemLanguage == SystemLanguage.Portuguese) + { + this.Keywords = GameKeywords.Portuguese; + } + } + else + { + this.Keywords = GameKeywords.Korean; + } + } + else if (systemLanguage != SystemLanguage.Russian) + { + if (systemLanguage == SystemLanguage.Spanish) + { + this.Keywords = GameKeywords.Spanish; + } + } + else + { + this.Keywords = GameKeywords.Russian; + } + } + catch + { + } + } + + public void SetRecommendations(int numPlayers, GameModes modes) + { + numPlayers = Mathf.Clamp(numPlayers, 4, 10); + this.PlayerSpeedMod = 1f; + this.CrewLightMod = 1f; + this.ImpostorLightMod = 1.5f; + this.KillCooldown = (float)GameOptionsData.RecommendedKillCooldown[numPlayers]; + this.NumCommonTasks = 1; + this.NumLongTasks = 1; + this.NumShortTasks = 2; + this.NumEmergencyMeetings = 1; + if (modes != GameModes.OnlineGame) + { + this.NumImpostors = GameOptionsData.RecommendedImpostors[numPlayers]; + } + this.KillDistance = 1; + this.DiscussionTime = 15; + this.VotingTime = 120; + this.isDefaults = true; + this.EmergencyCooldown = ((modes == GameModes.OnlineGame) ? 15 : 0); + } + + public void Serialize(BinaryWriter writer) + { + writer.Write(1); + writer.Write((byte)this.MaxPlayers); + writer.Write((uint)this.Keywords); + writer.Write(this.MapId); + writer.Write(this.PlayerSpeedMod); + writer.Write(this.CrewLightMod); + writer.Write(this.ImpostorLightMod); + writer.Write(this.KillCooldown); + writer.Write((byte)this.NumCommonTasks); + writer.Write((byte)this.NumLongTasks); + writer.Write((byte)this.NumShortTasks); + writer.Write(this.NumEmergencyMeetings); + writer.Write((byte)this.NumImpostors); + writer.Write((byte)this.KillDistance); + writer.Write(this.DiscussionTime); + writer.Write(this.VotingTime); + writer.Write(this.isDefaults); + writer.Write((byte)this.EmergencyCooldown); + } + + public static GameOptionsData Deserialize(BinaryReader reader) + { + try + { + byte b = reader.ReadByte(); + if (b != 1 && b != 2) + { + return null; + } + GameOptionsData gameOptionsData = new GameOptionsData(); + gameOptionsData.MaxPlayers = (int)reader.ReadByte(); + gameOptionsData.Keywords = (GameKeywords)reader.ReadUInt32(); + gameOptionsData.MapId = reader.ReadByte(); + gameOptionsData.PlayerSpeedMod = reader.ReadSingle(); + gameOptionsData.CrewLightMod = reader.ReadSingle(); + gameOptionsData.ImpostorLightMod = reader.ReadSingle(); + gameOptionsData.KillCooldown = reader.ReadSingle(); + gameOptionsData.NumCommonTasks = (int)reader.ReadByte(); + gameOptionsData.NumLongTasks = (int)reader.ReadByte(); + gameOptionsData.NumShortTasks = (int)reader.ReadByte(); + gameOptionsData.NumEmergencyMeetings = reader.ReadInt32(); + gameOptionsData.NumImpostors = (int)reader.ReadByte(); + gameOptionsData.KillDistance = (int)reader.ReadByte(); + gameOptionsData.DiscussionTime = reader.ReadInt32(); + gameOptionsData.VotingTime = reader.ReadInt32(); + gameOptionsData.isDefaults = reader.ReadBoolean(); + try + { + gameOptionsData.EmergencyCooldown = (int)reader.ReadByte(); + } + catch + { + } + return gameOptionsData; + } + catch + { + } + return null; + } + + public byte[] ToBytes() + { + byte[] result; + using (MemoryStream memoryStream = new MemoryStream()) + { + using (BinaryWriter binaryWriter = new BinaryWriter(memoryStream)) + { + this.Serialize(binaryWriter); + binaryWriter.Flush(); + memoryStream.Position = 0L; + result = memoryStream.ToArray(); + } + } + return result; + } + + public static GameOptionsData FromBytes(byte[] bytes) + { + GameOptionsData result; + using (MemoryStream memoryStream = new MemoryStream(bytes)) + { + using (BinaryReader binaryReader = new BinaryReader(memoryStream)) + { + result = (GameOptionsData.Deserialize(binaryReader) ?? new GameOptionsData()); + } + } + return result; + } + + public override string ToString() + { + return this.ToHudString(10); + } + + public string ToHudString(int numPlayers) + { + numPlayers = Mathf.Clamp(numPlayers, 0, 10); + StringBuilder stringBuilder = new StringBuilder(256); + stringBuilder.AppendLine(DestroyableSingleton<TranslationController>.Instance.GetString(this.isDefaults ? StringNames.GameRecommendedSettings : StringNames.GameCustomSettings, Array.Empty<object>())); + int num = GameOptionsData.MaxImpostors[numPlayers]; + stringBuilder.AppendLine(DestroyableSingleton<TranslationController>.Instance.GetString(StringNames.GameMapName, Array.Empty<object>()) + ": " + GameOptionsData.MapNames[(int)this.MapId]); + stringBuilder.Append(string.Format("{0}: {1}", DestroyableSingleton<TranslationController>.Instance.GetString(StringNames.GameNumImpostors, Array.Empty<object>()), this.NumImpostors)); + if (this.NumImpostors > num) + { + stringBuilder.Append(string.Format(" ({0}: {1})", DestroyableSingleton<TranslationController>.Instance.GetString(StringNames.Limit, Array.Empty<object>()), num)); + } + stringBuilder.AppendLine(); + stringBuilder.AppendLine(string.Format("{0}: {1}", DestroyableSingleton<TranslationController>.Instance.GetString(StringNames.GameNumMeetings, Array.Empty<object>()), this.NumEmergencyMeetings)); + stringBuilder.AppendLine(string.Format("{0}: {1}s", DestroyableSingleton<TranslationController>.Instance.GetString(StringNames.GameEmergencyCooldown, Array.Empty<object>()), this.EmergencyCooldown)); + stringBuilder.AppendLine(string.Format("Discussion Time: {0}s", this.DiscussionTime)); + if (this.VotingTime > 0) + { + stringBuilder.AppendLine(string.Format("{0}: {1}s", DestroyableSingleton<TranslationController>.Instance.GetString(StringNames.GameVotingTime, Array.Empty<object>()), this.VotingTime)); + } + else + { + stringBuilder.AppendLine(DestroyableSingleton<TranslationController>.Instance.GetString(StringNames.GameVotingTime, Array.Empty<object>()) + ": ∞s"); + } + stringBuilder.AppendLine(string.Format("{0}: {1}x", DestroyableSingleton<TranslationController>.Instance.GetString(StringNames.GamePlayerSpeed, Array.Empty<object>()), this.PlayerSpeedMod)); + stringBuilder.AppendLine(string.Format("{0}: {1}x", DestroyableSingleton<TranslationController>.Instance.GetString(StringNames.GameCrewLight, Array.Empty<object>()), this.CrewLightMod)); + stringBuilder.AppendLine(string.Format("{0}: {1}x", DestroyableSingleton<TranslationController>.Instance.GetString(StringNames.GameImpostorLight, Array.Empty<object>()), this.ImpostorLightMod)); + stringBuilder.AppendLine(string.Format("{0}: {1}s", DestroyableSingleton<TranslationController>.Instance.GetString(StringNames.GameKillCooldown, Array.Empty<object>()), this.KillCooldown)); + stringBuilder.AppendLine(DestroyableSingleton<TranslationController>.Instance.GetString(StringNames.GameKillDistance, Array.Empty<object>()) + ": " + GameOptionsData.KillDistanceStrings[this.KillDistance]); + stringBuilder.AppendLine(string.Format("{0}: {1}", DestroyableSingleton<TranslationController>.Instance.GetString(StringNames.GameCommonTasks, Array.Empty<object>()), this.NumCommonTasks)); + stringBuilder.AppendLine(string.Format("{0}: {1}", DestroyableSingleton<TranslationController>.Instance.GetString(StringNames.GameLongTasks, Array.Empty<object>()), this.NumLongTasks)); + stringBuilder.Append(string.Format("{0}: {1}", DestroyableSingleton<TranslationController>.Instance.GetString(StringNames.GameShortTasks, Array.Empty<object>()), this.NumShortTasks)); + return stringBuilder.ToString(); + } + + public int GetAdjustedNumImpostors(int playerCount) + { + int numImpostors = PlayerControl.GameOptions.NumImpostors; + int max = GameOptionsData.MaxImpostors[GameData.Instance.PlayerCount]; + return Mathf.Clamp(numImpostors, 1, max); + } +} diff --git a/Client/Assembly-CSharp/GameOptionsMenu.cs b/Client/Assembly-CSharp/GameOptionsMenu.cs new file mode 100644 index 0000000..1c44375 --- /dev/null +++ b/Client/Assembly-CSharp/GameOptionsMenu.cs @@ -0,0 +1,133 @@ +using System; +using UnityEngine; + +public class GameOptionsMenu : MonoBehaviour +{ + private GameOptionsData cachedData; + + public GameObject ResetButton; + + private OptionBehaviour[] Children; + + public void Start() + { + this.Children = base.GetComponentsInChildren<OptionBehaviour>(); + this.cachedData = PlayerControl.GameOptions; + for (int i = 0; i < this.Children.Length; i++) + { + OptionBehaviour optionBehaviour = this.Children[i]; + optionBehaviour.OnValueChanged = new Action<OptionBehaviour>(this.ValueChanged); + if (AmongUsClient.Instance && !AmongUsClient.Instance.AmHost) + { + optionBehaviour.SetAsPlayer(); + } + } + } + + public void Update() + { + if (this.cachedData != PlayerControl.GameOptions) + { + this.cachedData = PlayerControl.GameOptions; + this.RefreshChildren(); + } + } + + private void RefreshChildren() + { + for (int i = 0; i < this.Children.Length; i++) + { + OptionBehaviour optionBehaviour = this.Children[i]; + optionBehaviour.enabled = false; + optionBehaviour.enabled = true; + } + } + + public void ValueChanged(OptionBehaviour option) + { + if (!AmongUsClient.Instance || !AmongUsClient.Instance.AmHost) + { + return; + } + if (option.Title == StringNames.GameRecommendedSettings) + { + if (this.cachedData.isDefaults) + { + this.cachedData.isDefaults = false; + } + else + { + this.cachedData.SetRecommendations(GameData.Instance.PlayerCount, AmongUsClient.Instance.GameMode); + } + this.RefreshChildren(); + } + else + { + GameOptionsData gameOptions = PlayerControl.GameOptions; + StringNames title = option.Title; + switch (title) + { + case StringNames.GameMapName: + gameOptions.MapId = (byte)option.GetInt(); + break; + case StringNames.GameNumImpostors: + gameOptions.NumImpostors = option.GetInt(); + break; + case StringNames.GameNumMeetings: + gameOptions.NumEmergencyMeetings = option.GetInt(); + break; + case StringNames.GameDiscussTime: + gameOptions.DiscussionTime = option.GetInt(); + break; + case StringNames.GameVotingTime: + gameOptions.VotingTime = option.GetInt(); + break; + case StringNames.GamePlayerSpeed: + gameOptions.PlayerSpeedMod = option.GetFloat(); + break; + case StringNames.GameCrewLight: + gameOptions.CrewLightMod = option.GetFloat(); + break; + case StringNames.GameImpostorLight: + gameOptions.ImpostorLightMod = option.GetFloat(); + break; + case StringNames.GameKillCooldown: + gameOptions.KillCooldown = option.GetFloat(); + break; + case StringNames.GameKillDistance: + gameOptions.KillDistance = option.GetInt(); + break; + case StringNames.GameCommonTasks: + gameOptions.NumCommonTasks = option.GetInt(); + break; + case StringNames.GameLongTasks: + gameOptions.NumLongTasks = option.GetInt(); + break; + case StringNames.GameShortTasks: + gameOptions.NumShortTasks = option.GetInt(); + break; + default: + if (title != StringNames.GameEmergencyCooldown) + { + Debug.Log("Ono, unrecognized setting: " + option.Title); + } + else + { + gameOptions.EmergencyCooldown = option.GetInt(); + } + break; + } + if (gameOptions.isDefaults && option.Title != StringNames.GameMapName) + { + gameOptions.isDefaults = false; + this.RefreshChildren(); + } + } + PlayerControl localPlayer = PlayerControl.LocalPlayer; + if (localPlayer == null) + { + return; + } + localPlayer.RpcSyncSettings(PlayerControl.GameOptions); + } +} diff --git a/Client/Assembly-CSharp/GameOverReason.cs b/Client/Assembly-CSharp/GameOverReason.cs new file mode 100644 index 0000000..6f11220 --- /dev/null +++ b/Client/Assembly-CSharp/GameOverReason.cs @@ -0,0 +1,12 @@ +using System; + +public enum GameOverReason +{ + HumansByVote, + HumansByTask, + ImpostorByVote, + ImpostorByKill, + ImpostorBySabotage, + ImpostorDisconnect, + HumansDisconnect +} diff --git a/Client/Assembly-CSharp/GameSettingMenu.cs b/Client/Assembly-CSharp/GameSettingMenu.cs new file mode 100644 index 0000000..d0d80dc --- /dev/null +++ b/Client/Assembly-CSharp/GameSettingMenu.cs @@ -0,0 +1,37 @@ +using System; +using UnityEngine; + +public class GameSettingMenu : MonoBehaviour +{ + public Transform[] AllItems; + + public float YStart; + + public float YOffset; + + public Transform[] HideForOnline; + + private void OnEnable() + { + int num = 0; + for (int i = 0; i < this.AllItems.Length; i++) + { + Transform transform = this.AllItems[i]; + if (transform.gameObject.activeSelf) + { + if ((AmongUsClient.Instance.GameMode == GameModes.OnlineGame && this.HideForOnline.IndexOf(transform) != -1) || transform.name == "MapName") + { + transform.gameObject.SetActive(false); + } + else + { + Vector3 localPosition = transform.localPosition; + localPosition.y = this.YStart - (float)num * this.YOffset; + transform.localPosition = localPosition; + num++; + } + } + } + base.GetComponent<Scroller>().YBounds.max = (float)num * this.YOffset / 2f + 0.1f; + } +} diff --git a/Client/Assembly-CSharp/GameStartManager.cs b/Client/Assembly-CSharp/GameStartManager.cs new file mode 100644 index 0000000..69f1967 --- /dev/null +++ b/Client/Assembly-CSharp/GameStartManager.cs @@ -0,0 +1,215 @@ +using System; +using InnerNet; +using UnityEngine; + +public class GameStartManager : DestroyableSingleton<GameStartManager>, IDisconnectHandler +{ + public int MinPlayers = 4; + + public TextRenderer PlayerCounter; + + private int LastPlayerCount = -1; + + public GameObject GameSizePopup; + + public TextRenderer GameRoomName; + + public LobbyBehaviour LobbyPrefab; + + public TextRenderer GameStartText; + + public SpriteRenderer StartButton; + + public SpriteRenderer MakePublicButton; + + public Sprite PublicGameImage; + + public Sprite PrivateGameImage; + + private GameStartManager.StartingStates startState; + + private float countDownTimer; + + private enum StartingStates + { + NotStarting, + Countdown, + Starting + } + + public void Start() + { + if (DestroyableSingleton<TutorialManager>.InstanceExists) + { + UnityEngine.Object.Destroy(base.gameObject); + return; + } + string text = InnerNetClient.IntToGameName(AmongUsClient.Instance.GameId); + if (text != null) + { + this.GameRoomName.Text = DestroyableSingleton<TranslationController>.Instance.GetString(StringNames.RoomCode, Array.Empty<object>()) + "\r\n" + text; + } + else + { + this.StartButton.transform.localPosition = new Vector3(0f, -0.2f, 0f); + this.PlayerCounter.transform.localPosition = new Vector3(0f, -0.8f, 0f); + } + AmongUsClient.Instance.DisconnectHandlers.AddUnique(this); + if (!AmongUsClient.Instance.AmHost) + { + this.StartButton.gameObject.SetActive(false); + } + else + { + LobbyBehaviour.Instance = UnityEngine.Object.Instantiate<LobbyBehaviour>(this.LobbyPrefab); + AmongUsClient.Instance.Spawn(LobbyBehaviour.Instance, -2, SpawnFlags.None); + } + this.MakePublicButton.gameObject.SetActive(AmongUsClient.Instance.GameMode == GameModes.OnlineGame); + } + + public void MakePublic() + { + if (AmongUsClient.Instance.AmHost) + { + AmongUsClient.Instance.ChangeGamePublic(!AmongUsClient.Instance.IsGamePublic); + } + } + + public void Update() + { + if (!GameData.Instance) + { + return; + } + this.MakePublicButton.sprite = (AmongUsClient.Instance.IsGamePublic ? this.PublicGameImage : this.PrivateGameImage); + if (GameData.Instance.PlayerCount != this.LastPlayerCount) + { + this.LastPlayerCount = GameData.Instance.PlayerCount; + string arg = "[FF0000FF]"; + if (this.LastPlayerCount > this.MinPlayers) + { + arg = "[00FF00FF]"; + } + if (this.LastPlayerCount == this.MinPlayers) + { + arg = "[FFFF00FF]"; + } + this.PlayerCounter.Text = string.Format("{0}{1}/{2}", arg, this.LastPlayerCount, PlayerControl.GameOptions.MaxPlayers); + this.StartButton.color = ((this.LastPlayerCount >= this.MinPlayers) ? Palette.EnabledColor : Palette.DisabledColor); + if (DestroyableSingleton<DiscordManager>.InstanceExists) + { + if (AmongUsClient.Instance.AmHost && AmongUsClient.Instance.GameMode == GameModes.OnlineGame) + { + DestroyableSingleton<DiscordManager>.Instance.SetInLobbyHost(this.LastPlayerCount, AmongUsClient.Instance.GameId); + } + else + { + DestroyableSingleton<DiscordManager>.Instance.SetInLobbyClient(); + } + } + } + if (AmongUsClient.Instance.AmHost) + { + if (this.startState == GameStartManager.StartingStates.Countdown) + { + int num = Mathf.CeilToInt(this.countDownTimer); + this.countDownTimer -= Time.deltaTime; + int num2 = Mathf.CeilToInt(this.countDownTimer); + this.GameStartText.Text = string.Format("Starting in {0}", num2); + if (num != num2) + { + PlayerControl.LocalPlayer.RpcSetStartCounter(num2); + } + if (num2 <= 0) + { + this.FinallyBegin(); + return; + } + } + else + { + this.GameStartText.Text = string.Empty; + } + } + } + + public void ResetStartState() + { + this.startState = GameStartManager.StartingStates.NotStarting; + if (this.StartButton && this.StartButton.gameObject) + { + this.StartButton.gameObject.SetActive(AmongUsClient.Instance.AmHost); + } + PlayerControl.LocalPlayer.RpcSetStartCounter(-1); + } + + public void SetStartCounter(sbyte sec) + { + if (sec == -1) + { + this.GameStartText.Text = string.Empty; + return; + } + this.GameStartText.Text = string.Format("Starting in {0}", sec); + } + + public void BeginGame() + { + if (this.startState != GameStartManager.StartingStates.NotStarting) + { + return; + } + if (SaveManager.ShowMinPlayerWarning && GameData.Instance.PlayerCount == this.MinPlayers) + { + this.GameSizePopup.SetActive(true); + return; + } + if (GameData.Instance.PlayerCount < this.MinPlayers) + { + base.StartCoroutine(Effects.Shake(this.PlayerCounter.transform, 0.75f, 0.25f)); + return; + } + this.ReallyBegin(false); + } + + public void ReallyBegin(bool neverShow) + { + this.startState = GameStartManager.StartingStates.Countdown; + if (neverShow) + { + SaveManager.ShowMinPlayerWarning = false; + } + this.StartButton.gameObject.SetActive(false); + this.countDownTimer = 10.0001f; + this.startState = GameStartManager.StartingStates.Countdown; + } + + public void FinallyBegin() + { + if (this.startState != GameStartManager.StartingStates.Countdown) + { + return; + } + this.startState = GameStartManager.StartingStates.Starting; + AmongUsClient.Instance.StartGame(); + AmongUsClient.Instance.DisconnectHandlers.Remove(this); + UnityEngine.Object.Destroy(base.gameObject); + } + + public void HandleDisconnect(PlayerControl pc, DisconnectReasons reason) + { + if (AmongUsClient.Instance.AmHost) + { + this.LastPlayerCount = -1; + if (this.StartButton) + { + this.StartButton.gameObject.SetActive(true); + } + } + } + + public void HandleDisconnect() + { + this.HandleDisconnect(null, DisconnectReasons.ExitGame); + } +} diff --git a/Client/Assembly-CSharp/GarbageBehaviour.cs b/Client/Assembly-CSharp/GarbageBehaviour.cs new file mode 100644 index 0000000..8fbc191 --- /dev/null +++ b/Client/Assembly-CSharp/GarbageBehaviour.cs @@ -0,0 +1,13 @@ +using System; +using UnityEngine; + +public class GarbageBehaviour : MonoBehaviour +{ + public void FixedUpdate() + { + if (base.transform.localPosition.y < -3.49f) + { + UnityEngine.Object.Destroy(base.gameObject); + } + } +} diff --git a/Client/Assembly-CSharp/GoogleMobileAds/Api/AdErrorEventArgs.cs b/Client/Assembly-CSharp/GoogleMobileAds/Api/AdErrorEventArgs.cs new file mode 100644 index 0000000..ab105d0 --- /dev/null +++ b/Client/Assembly-CSharp/GoogleMobileAds/Api/AdErrorEventArgs.cs @@ -0,0 +1,9 @@ +using System; + +namespace GoogleMobileAds.Api +{ + public class AdErrorEventArgs : EventArgs + { + public string Message { get; set; } + } +} diff --git a/Client/Assembly-CSharp/GoogleMobileAds/Api/AdFailedToLoadEventArgs.cs b/Client/Assembly-CSharp/GoogleMobileAds/Api/AdFailedToLoadEventArgs.cs new file mode 100644 index 0000000..42389fc --- /dev/null +++ b/Client/Assembly-CSharp/GoogleMobileAds/Api/AdFailedToLoadEventArgs.cs @@ -0,0 +1,9 @@ +using System; + +namespace GoogleMobileAds.Api +{ + public class AdFailedToLoadEventArgs : EventArgs + { + public string Message { get; set; } + } +} diff --git a/Client/Assembly-CSharp/GoogleMobileAds/Api/AdLoader.cs b/Client/Assembly-CSharp/GoogleMobileAds/Api/AdLoader.cs new file mode 100644 index 0000000..3116a90 --- /dev/null +++ b/Client/Assembly-CSharp/GoogleMobileAds/Api/AdLoader.cs @@ -0,0 +1,93 @@ +using System; +using System.Collections.Generic; +using System.Reflection; +using GoogleMobileAds.Common; + +namespace GoogleMobileAds.Api +{ + public class AdLoader + { + public Dictionary<string, Action<CustomNativeTemplateAd, string>> CustomNativeTemplateClickHandlers { get; private set; } + + public string AdUnitId { get; private set; } + + public HashSet<NativeAdType> AdTypes { get; private set; } + + public HashSet<string> TemplateIds { get; private set; } + + public event EventHandler<AdFailedToLoadEventArgs> OnAdFailedToLoad; + + public event EventHandler<CustomNativeEventArgs> OnCustomNativeTemplateAdLoaded; + + private IAdLoaderClient adLoaderClient; + + public class Builder + { + internal string AdUnitId { get; private set; } + + internal HashSet<NativeAdType> AdTypes { get; private set; } + + internal HashSet<string> TemplateIds { get; private set; } + + internal Dictionary<string, Action<CustomNativeTemplateAd, string>> CustomNativeTemplateClickHandlers { get; private set; } + + public Builder(string adUnitId) + { + this.AdUnitId = adUnitId; + this.AdTypes = new HashSet<NativeAdType>(); + this.TemplateIds = new HashSet<string>(); + this.CustomNativeTemplateClickHandlers = new Dictionary<string, Action<CustomNativeTemplateAd, string>>(); + } + + public AdLoader.Builder ForCustomNativeAd(string templateId) + { + this.TemplateIds.Add(templateId); + this.AdTypes.Add(NativeAdType.CustomTemplate); + return this; + } + + public AdLoader.Builder ForCustomNativeAd(string templateId, Action<CustomNativeTemplateAd, string> callback) + { + this.TemplateIds.Add(templateId); + this.CustomNativeTemplateClickHandlers[templateId] = callback; + this.AdTypes.Add(NativeAdType.CustomTemplate); + return this; + } + + public AdLoader Build() + { + return new AdLoader(this); + } + } + + private AdLoader(AdLoader.Builder builder) + { + this.AdUnitId = string.Copy(builder.AdUnitId); + this.CustomNativeTemplateClickHandlers = new Dictionary<string, Action<CustomNativeTemplateAd, string>>(builder.CustomNativeTemplateClickHandlers); + this.TemplateIds = new HashSet<string>(builder.TemplateIds); + this.AdTypes = new HashSet<NativeAdType>(builder.AdTypes); + MethodInfo method = Type.GetType("GoogleMobileAds.GoogleMobileAdsClientFactory,Assembly-CSharp").GetMethod("BuildAdLoaderClient", BindingFlags.Static | BindingFlags.Public); + this.adLoaderClient = (IAdLoaderClient)method.Invoke(null, new object[] + { + this + }); + Utils.CheckInitialization(); + this.adLoaderClient.OnCustomNativeTemplateAdLoaded += delegate(object sender, CustomNativeEventArgs args) + { + this.OnCustomNativeTemplateAdLoaded(this, args); + }; + this.adLoaderClient.OnAdFailedToLoad += delegate(object sender, AdFailedToLoadEventArgs args) + { + if (this.OnAdFailedToLoad != null) + { + this.OnAdFailedToLoad(this, args); + } + }; + } + + public void LoadAd(AdRequest request) + { + this.adLoaderClient.LoadAd(request); + } + } +} diff --git a/Client/Assembly-CSharp/GoogleMobileAds/Api/AdPosition.cs b/Client/Assembly-CSharp/GoogleMobileAds/Api/AdPosition.cs new file mode 100644 index 0000000..6bc2a49 --- /dev/null +++ b/Client/Assembly-CSharp/GoogleMobileAds/Api/AdPosition.cs @@ -0,0 +1,15 @@ +using System; + +namespace GoogleMobileAds.Api +{ + public enum AdPosition + { + Top, + Bottom, + TopLeft, + TopRight, + BottomLeft, + BottomRight, + Center + } +} diff --git a/Client/Assembly-CSharp/GoogleMobileAds/Api/AdRequest.cs b/Client/Assembly-CSharp/GoogleMobileAds/Api/AdRequest.cs new file mode 100644 index 0000000..a303ea9 --- /dev/null +++ b/Client/Assembly-CSharp/GoogleMobileAds/Api/AdRequest.cs @@ -0,0 +1,113 @@ +using System; +using System.Collections.Generic; +using GoogleMobileAds.Api.Mediation; + +namespace GoogleMobileAds.Api +{ + public class AdRequest + { + public List<string> TestDevices { get; private set; } + + public HashSet<string> Keywords { get; private set; } + + public DateTime? Birthday { get; private set; } + + public Gender? Gender { get; private set; } + + public bool? TagForChildDirectedTreatment { get; private set; } + + public Dictionary<string, string> Extras { get; private set; } + + public List<MediationExtras> MediationExtras { get; private set; } + + public const string Version = "3.17.0"; + + public const string TestDeviceSimulator = "SIMULATOR"; + + public class Builder + { + internal List<string> TestDevices { get; private set; } + + internal HashSet<string> Keywords { get; private set; } + + internal DateTime? Birthday { get; private set; } + + internal Gender? Gender { get; private set; } + + internal bool? ChildDirectedTreatmentTag { get; private set; } + + internal Dictionary<string, string> Extras { get; private set; } + + internal List<MediationExtras> MediationExtras { get; private set; } + + public Builder() + { + this.TestDevices = new List<string>(); + this.Keywords = new HashSet<string>(); + this.Birthday = null; + this.Gender = null; + this.ChildDirectedTreatmentTag = null; + this.Extras = new Dictionary<string, string>(); + this.MediationExtras = new List<MediationExtras>(); + } + + public AdRequest.Builder AddKeyword(string keyword) + { + this.Keywords.Add(keyword); + return this; + } + + public AdRequest.Builder AddTestDevice(string deviceId) + { + this.TestDevices.Add(deviceId); + return this; + } + + public AdRequest Build() + { + return new AdRequest(this); + } + + public AdRequest.Builder SetBirthday(DateTime birthday) + { + this.Birthday = new DateTime?(birthday); + return this; + } + + public AdRequest.Builder SetGender(Gender gender) + { + this.Gender = new Gender?(gender); + return this; + } + + public AdRequest.Builder AddMediationExtras(MediationExtras extras) + { + this.MediationExtras.Add(extras); + return this; + } + + public AdRequest.Builder TagForChildDirectedTreatment(bool tagForChildDirectedTreatment) + { + this.ChildDirectedTreatmentTag = new bool?(tagForChildDirectedTreatment); + return this; + } + + public AdRequest.Builder AddExtra(string key, string value) + { + this.Extras.Add(key, value); + return this; + } + } + + private AdRequest(AdRequest.Builder builder) + { + this.TestDevices = new List<string>(builder.TestDevices); + this.Keywords = new HashSet<string>(builder.Keywords); + this.Birthday = builder.Birthday; + this.Gender = builder.Gender; + this.TagForChildDirectedTreatment = builder.ChildDirectedTreatmentTag; + this.Extras = new Dictionary<string, string>(builder.Extras); + this.MediationExtras = builder.MediationExtras; + } + } +} diff --git a/Client/Assembly-CSharp/GoogleMobileAds/Api/AdSize.cs b/Client/Assembly-CSharp/GoogleMobileAds/Api/AdSize.cs new file mode 100644 index 0000000..ec5f3f1 --- /dev/null +++ b/Client/Assembly-CSharp/GoogleMobileAds/Api/AdSize.cs @@ -0,0 +1,88 @@ +using System; + +namespace GoogleMobileAds.Api +{ + public class AdSize + { + public int Width + { + get + { + return this.width; + } + } + + public int Height + { + get + { + return this.height; + } + } + + public bool IsSmartBanner + { + get + { + return this.isSmartBanner; + } + } + + private bool isSmartBanner; + + private int width; + + private int height; + + public static readonly AdSize Banner = new AdSize(320, 50); + + public static readonly AdSize MediumRectangle = new AdSize(300, 250); + + public static readonly AdSize IABBanner = new AdSize(468, 60); + + public static readonly AdSize Leaderboard = new AdSize(728, 90); + + public static readonly AdSize SmartBanner = new AdSize(true); + + public static readonly int FullWidth = -1; + + public AdSize(int width, int height) + { + this.isSmartBanner = false; + this.width = width; + this.height = height; + } + + private AdSize(bool isSmartBanner) : this(0, 0) + { + this.isSmartBanner = isSmartBanner; + } + + public override bool Equals(object obj) + { + if (obj == null || base.GetType() != obj.GetType()) + { + return false; + } + AdSize adSize = (AdSize)obj; + return this.width == adSize.width && this.height == adSize.height && this.isSmartBanner == adSize.isSmartBanner; + } + + public static bool operator ==(AdSize a, AdSize b) + { + return a.Equals(b); + } + + public static bool operator !=(AdSize a, AdSize b) + { + return !a.Equals(b); + } + + public override int GetHashCode() + { + int num = 71; + int num2 = 11; + return ((num * num2 ^ this.width.GetHashCode()) * num2 ^ this.height.GetHashCode()) * num2 ^ this.isSmartBanner.GetHashCode(); + } + } +} diff --git a/Client/Assembly-CSharp/GoogleMobileAds/Api/AdapterState.cs b/Client/Assembly-CSharp/GoogleMobileAds/Api/AdapterState.cs new file mode 100644 index 0000000..471e180 --- /dev/null +++ b/Client/Assembly-CSharp/GoogleMobileAds/Api/AdapterState.cs @@ -0,0 +1,10 @@ +using System; + +namespace GoogleMobileAds.Api +{ + public enum AdapterState + { + NotReady, + Ready + } +} diff --git a/Client/Assembly-CSharp/GoogleMobileAds/Api/AdapterStatus.cs b/Client/Assembly-CSharp/GoogleMobileAds/Api/AdapterStatus.cs new file mode 100644 index 0000000..31451e3 --- /dev/null +++ b/Client/Assembly-CSharp/GoogleMobileAds/Api/AdapterStatus.cs @@ -0,0 +1,20 @@ +using System; + +namespace GoogleMobileAds.Api +{ + public class AdapterStatus + { + public AdapterState InitializationState { get; private set; } + + public string Description { get; private set; } + + public int Latency { get; private set; } + + internal AdapterStatus(AdapterState state, string description, int latency) + { + this.InitializationState = state; + this.Description = description; + this.Latency = latency; + } + } +} diff --git a/Client/Assembly-CSharp/GoogleMobileAds/Api/BannerView.cs b/Client/Assembly-CSharp/GoogleMobileAds/Api/BannerView.cs new file mode 100644 index 0000000..7ad2724 --- /dev/null +++ b/Client/Assembly-CSharp/GoogleMobileAds/Api/BannerView.cs @@ -0,0 +1,121 @@ +using System; +using System.Reflection; +using GoogleMobileAds.Common; + +namespace GoogleMobileAds.Api +{ + public class BannerView + { + public event EventHandler<EventArgs> OnAdLoaded; + + public event EventHandler<AdFailedToLoadEventArgs> OnAdFailedToLoad; + + public event EventHandler<EventArgs> OnAdOpening; + + public event EventHandler<EventArgs> OnAdClosed; + + public event EventHandler<EventArgs> OnAdLeavingApplication; + + private IBannerClient client; + + public BannerView(string adUnitId, AdSize adSize, AdPosition position) + { + MethodInfo method = Type.GetType("GoogleMobileAds.GoogleMobileAdsClientFactory,Assembly-CSharp").GetMethod("BuildBannerClient", BindingFlags.Static | BindingFlags.Public); + this.client = (IBannerClient)method.Invoke(null, null); + this.client.CreateBannerView(adUnitId, adSize, position); + this.ConfigureBannerEvents(); + } + + public BannerView(string adUnitId, AdSize adSize, int x, int y) + { + MethodInfo method = Type.GetType("GoogleMobileAds.GoogleMobileAdsClientFactory,Assembly-CSharp").GetMethod("BuildBannerClient", BindingFlags.Static | BindingFlags.Public); + this.client = (IBannerClient)method.Invoke(null, null); + this.client.CreateBannerView(adUnitId, adSize, x, y); + this.ConfigureBannerEvents(); + } + + public void LoadAd(AdRequest request) + { + this.client.LoadAd(request); + } + + public void Hide() + { + this.client.HideBannerView(); + } + + public void Show() + { + this.client.ShowBannerView(); + } + + public void Destroy() + { + this.client.DestroyBannerView(); + } + + public float GetHeightInPixels() + { + return this.client.GetHeightInPixels(); + } + + public float GetWidthInPixels() + { + return this.client.GetWidthInPixels(); + } + + public void SetPosition(AdPosition adPosition) + { + this.client.SetPosition(adPosition); + } + + public void SetPosition(int x, int y) + { + this.client.SetPosition(x, y); + } + + private void ConfigureBannerEvents() + { + this.client.OnAdLoaded += delegate(object sender, EventArgs args) + { + if (this.OnAdLoaded != null) + { + this.OnAdLoaded(this, args); + } + }; + this.client.OnAdFailedToLoad += delegate(object sender, AdFailedToLoadEventArgs args) + { + if (this.OnAdFailedToLoad != null) + { + this.OnAdFailedToLoad(this, args); + } + }; + this.client.OnAdOpening += delegate(object sender, EventArgs args) + { + if (this.OnAdOpening != null) + { + this.OnAdOpening(this, args); + } + }; + this.client.OnAdClosed += delegate(object sender, EventArgs args) + { + if (this.OnAdClosed != null) + { + this.OnAdClosed(this, args); + } + }; + this.client.OnAdLeavingApplication += delegate(object sender, EventArgs args) + { + if (this.OnAdLeavingApplication != null) + { + this.OnAdLeavingApplication(this, args); + } + }; + } + + public string MediationAdapterClassName() + { + return this.client.MediationAdapterClassName(); + } + } +} diff --git a/Client/Assembly-CSharp/GoogleMobileAds/Api/CustomNativeEventArgs.cs b/Client/Assembly-CSharp/GoogleMobileAds/Api/CustomNativeEventArgs.cs new file mode 100644 index 0000000..692b54b --- /dev/null +++ b/Client/Assembly-CSharp/GoogleMobileAds/Api/CustomNativeEventArgs.cs @@ -0,0 +1,9 @@ +using System; + +namespace GoogleMobileAds.Api +{ + public class CustomNativeEventArgs : EventArgs + { + public CustomNativeTemplateAd nativeAd { get; set; } + } +} diff --git a/Client/Assembly-CSharp/GoogleMobileAds/Api/CustomNativeTemplateAd.cs b/Client/Assembly-CSharp/GoogleMobileAds/Api/CustomNativeTemplateAd.cs new file mode 100644 index 0000000..159341b --- /dev/null +++ b/Client/Assembly-CSharp/GoogleMobileAds/Api/CustomNativeTemplateAd.cs @@ -0,0 +1,52 @@ +using System; +using System.Collections.Generic; +using GoogleMobileAds.Common; +using UnityEngine; + +namespace GoogleMobileAds.Api +{ + public class CustomNativeTemplateAd + { + private ICustomNativeTemplateClient client; + + internal CustomNativeTemplateAd(ICustomNativeTemplateClient client) + { + this.client = client; + } + + public List<string> GetAvailableAssetNames() + { + return this.client.GetAvailableAssetNames(); + } + + public string GetCustomTemplateId() + { + return this.client.GetTemplateId(); + } + + public Texture2D GetTexture2D(string key) + { + byte[] imageByteArray = this.client.GetImageByteArray(key); + if (imageByteArray == null) + { + return null; + } + return Utils.GetTexture2DFromByteArray(imageByteArray); + } + + public string GetText(string key) + { + return this.client.GetText(key); + } + + public void PerformClick(string assetName) + { + this.client.PerformClick(assetName); + } + + public void RecordImpression() + { + this.client.RecordImpression(); + } + } +} diff --git a/Client/Assembly-CSharp/GoogleMobileAds/Api/Gender.cs b/Client/Assembly-CSharp/GoogleMobileAds/Api/Gender.cs new file mode 100644 index 0000000..afdd035 --- /dev/null +++ b/Client/Assembly-CSharp/GoogleMobileAds/Api/Gender.cs @@ -0,0 +1,11 @@ +using System; + +namespace GoogleMobileAds.Api +{ + public enum Gender + { + Unknown, + Male, + Female + } +} diff --git a/Client/Assembly-CSharp/GoogleMobileAds/Api/InterstitialAd.cs b/Client/Assembly-CSharp/GoogleMobileAds/Api/InterstitialAd.cs new file mode 100644 index 0000000..e9817bb --- /dev/null +++ b/Client/Assembly-CSharp/GoogleMobileAds/Api/InterstitialAd.cs @@ -0,0 +1,88 @@ +using System; +using System.Reflection; +using GoogleMobileAds.Common; + +namespace GoogleMobileAds.Api +{ + public class InterstitialAd + { + public event EventHandler<EventArgs> OnAdLoaded; + + public event EventHandler<AdFailedToLoadEventArgs> OnAdFailedToLoad; + + public event EventHandler<EventArgs> OnAdOpening; + + public event EventHandler<EventArgs> OnAdClosed; + + public event EventHandler<EventArgs> OnAdLeavingApplication; + + private IInterstitialClient client; + + public InterstitialAd(string adUnitId) + { + MethodInfo method = Type.GetType("GoogleMobileAds.GoogleMobileAdsClientFactory,Assembly-CSharp").GetMethod("BuildInterstitialClient", BindingFlags.Static | BindingFlags.Public); + this.client = (IInterstitialClient)method.Invoke(null, null); + this.client.CreateInterstitialAd(adUnitId); + this.client.OnAdLoaded += delegate(object sender, EventArgs args) + { + if (this.OnAdLoaded != null) + { + this.OnAdLoaded(this, args); + } + }; + this.client.OnAdFailedToLoad += delegate(object sender, AdFailedToLoadEventArgs args) + { + if (this.OnAdFailedToLoad != null) + { + this.OnAdFailedToLoad(this, args); + } + }; + this.client.OnAdOpening += delegate(object sender, EventArgs args) + { + if (this.OnAdOpening != null) + { + this.OnAdOpening(this, args); + } + }; + this.client.OnAdClosed += delegate(object sender, EventArgs args) + { + if (this.OnAdClosed != null) + { + this.OnAdClosed(this, args); + } + }; + this.client.OnAdLeavingApplication += delegate(object sender, EventArgs args) + { + if (this.OnAdLeavingApplication != null) + { + this.OnAdLeavingApplication(this, args); + } + }; + } + + public void LoadAd(AdRequest request) + { + this.client.LoadAd(request); + } + + public bool IsLoaded() + { + return this.client.IsLoaded(); + } + + public void Show() + { + this.client.ShowInterstitial(); + } + + public void Destroy() + { + this.client.DestroyInterstitial(); + } + + public string MediationAdapterClassName() + { + return this.client.MediationAdapterClassName(); + } + } +} diff --git a/Client/Assembly-CSharp/GoogleMobileAds/Api/Mediation/MediationExtras.cs b/Client/Assembly-CSharp/GoogleMobileAds/Api/Mediation/MediationExtras.cs new file mode 100644 index 0000000..1604ec7 --- /dev/null +++ b/Client/Assembly-CSharp/GoogleMobileAds/Api/Mediation/MediationExtras.cs @@ -0,0 +1,19 @@ +using System; +using System.Collections.Generic; + +namespace GoogleMobileAds.Api.Mediation +{ + public abstract class MediationExtras + { + public Dictionary<string, string> Extras { get; protected set; } + + public abstract string AndroidMediationExtraBuilderClassName { get; } + + public abstract string IOSMediationExtraBuilderClassName { get; } + + public MediationExtras() + { + this.Extras = new Dictionary<string, string>(); + } + } +} diff --git a/Client/Assembly-CSharp/GoogleMobileAds/Api/MobileAds.cs b/Client/Assembly-CSharp/GoogleMobileAds/Api/MobileAds.cs new file mode 100644 index 0000000..38199b3 --- /dev/null +++ b/Client/Assembly-CSharp/GoogleMobileAds/Api/MobileAds.cs @@ -0,0 +1,37 @@ +using System; +using System.Reflection; +using GoogleMobileAds.Common; + +namespace GoogleMobileAds.Api +{ + public class MobileAds + { + private static readonly IMobileAdsClient client = MobileAds.GetMobileAdsClient(); + + public static void Initialize(string appId) + { + MobileAds.client.Initialize(appId); + MobileAdsEventExecutor.Initialize(); + } + + public static void SetApplicationMuted(bool muted) + { + MobileAds.client.SetApplicationMuted(muted); + } + + public static void SetApplicationVolume(float volume) + { + MobileAds.client.SetApplicationVolume(volume); + } + + public static void SetiOSAppPauseOnBackground(bool pause) + { + MobileAds.client.SetiOSAppPauseOnBackground(pause); + } + + private static IMobileAdsClient GetMobileAdsClient() + { + return (IMobileAdsClient)Type.GetType("GoogleMobileAds.GoogleMobileAdsClientFactory,Assembly-CSharp").GetMethod("MobileAdsInstance", BindingFlags.Static | BindingFlags.Public).Invoke(null, null); + } + } +} diff --git a/Client/Assembly-CSharp/GoogleMobileAds/Api/NativeAdType.cs b/Client/Assembly-CSharp/GoogleMobileAds/Api/NativeAdType.cs new file mode 100644 index 0000000..98c1e39 --- /dev/null +++ b/Client/Assembly-CSharp/GoogleMobileAds/Api/NativeAdType.cs @@ -0,0 +1,9 @@ +using System; + +namespace GoogleMobileAds.Api +{ + public enum NativeAdType + { + CustomTemplate + } +} diff --git a/Client/Assembly-CSharp/GoogleMobileAds/Api/Reward.cs b/Client/Assembly-CSharp/GoogleMobileAds/Api/Reward.cs new file mode 100644 index 0000000..1e0beda --- /dev/null +++ b/Client/Assembly-CSharp/GoogleMobileAds/Api/Reward.cs @@ -0,0 +1,11 @@ +using System; + +namespace GoogleMobileAds.Api +{ + public class Reward : EventArgs + { + public string Type { get; set; } + + public double Amount { get; set; } + } +} diff --git a/Client/Assembly-CSharp/GoogleMobileAds/Api/RewardBasedVideoAd.cs b/Client/Assembly-CSharp/GoogleMobileAds/Api/RewardBasedVideoAd.cs new file mode 100644 index 0000000..90f069a --- /dev/null +++ b/Client/Assembly-CSharp/GoogleMobileAds/Api/RewardBasedVideoAd.cs @@ -0,0 +1,125 @@ +using System; +using System.Reflection; +using GoogleMobileAds.Common; + +namespace GoogleMobileAds.Api +{ + public class RewardBasedVideoAd + { + public static RewardBasedVideoAd Instance + { + get + { + return RewardBasedVideoAd.instance; + } + } + + public event EventHandler<EventArgs> OnAdLoaded; + + public event EventHandler<AdFailedToLoadEventArgs> OnAdFailedToLoad; + + public event EventHandler<EventArgs> OnAdOpening; + + public event EventHandler<EventArgs> OnAdStarted; + + public event EventHandler<EventArgs> OnAdClosed; + + public event EventHandler<Reward> OnAdRewarded; + + public event EventHandler<EventArgs> OnAdLeavingApplication; + + public event EventHandler<EventArgs> OnAdCompleted; + + private IRewardBasedVideoAdClient client; + + private static readonly RewardBasedVideoAd instance = new RewardBasedVideoAd(); + + private RewardBasedVideoAd() + { + MethodInfo method = Type.GetType("GoogleMobileAds.GoogleMobileAdsClientFactory,Assembly-CSharp").GetMethod("BuildRewardBasedVideoAdClient", BindingFlags.Static | BindingFlags.Public); + this.client = (IRewardBasedVideoAdClient)method.Invoke(null, null); + this.client.CreateRewardBasedVideoAd(); + this.client.OnAdLoaded += delegate(object sender, EventArgs args) + { + if (this.OnAdLoaded != null) + { + this.OnAdLoaded(this, args); + } + }; + this.client.OnAdFailedToLoad += delegate(object sender, AdFailedToLoadEventArgs args) + { + if (this.OnAdFailedToLoad != null) + { + this.OnAdFailedToLoad(this, args); + } + }; + this.client.OnAdOpening += delegate(object sender, EventArgs args) + { + if (this.OnAdOpening != null) + { + this.OnAdOpening(this, args); + } + }; + this.client.OnAdStarted += delegate(object sender, EventArgs args) + { + if (this.OnAdStarted != null) + { + this.OnAdStarted(this, args); + } + }; + this.client.OnAdClosed += delegate(object sender, EventArgs args) + { + if (this.OnAdClosed != null) + { + this.OnAdClosed(this, args); + } + }; + this.client.OnAdLeavingApplication += delegate(object sender, EventArgs args) + { + if (this.OnAdLeavingApplication != null) + { + this.OnAdLeavingApplication(this, args); + } + }; + this.client.OnAdRewarded += delegate(object sender, Reward args) + { + if (this.OnAdRewarded != null) + { + this.OnAdRewarded(this, args); + } + }; + this.client.OnAdCompleted += delegate(object sender, EventArgs args) + { + if (this.OnAdCompleted != null) + { + this.OnAdCompleted(this, args); + } + }; + } + + public void LoadAd(AdRequest request, string adUnitId) + { + this.client.LoadAd(request, adUnitId); + } + + public bool IsLoaded() + { + return this.client.IsLoaded(); + } + + public void Show() + { + this.client.ShowRewardBasedVideoAd(); + } + + public void SetUserId(string userId) + { + this.client.SetUserId(userId); + } + + public string MediationAdapterClassName() + { + return this.client.MediationAdapterClassName(); + } + } +} diff --git a/Client/Assembly-CSharp/GoogleMobileAds/Api/RewardedAd.cs b/Client/Assembly-CSharp/GoogleMobileAds/Api/RewardedAd.cs new file mode 100644 index 0000000..48a43ff --- /dev/null +++ b/Client/Assembly-CSharp/GoogleMobileAds/Api/RewardedAd.cs @@ -0,0 +1,97 @@ +using System; +using System.Reflection; +using GoogleMobileAds.Common; + +namespace GoogleMobileAds.Api +{ + public class RewardedAd + { + public event EventHandler<EventArgs> OnAdLoaded; + + public event EventHandler<AdErrorEventArgs> OnAdFailedToLoad; + + public event EventHandler<AdErrorEventArgs> OnAdFailedToShow; + + public event EventHandler<EventArgs> OnAdOpening; + + public event EventHandler<EventArgs> OnAdClosed; + + public event EventHandler<Reward> OnUserEarnedReward; + + private IRewardedAdClient client; + + public RewardedAd(string adUnitId) + { + MethodInfo method = Type.GetType("GoogleMobileAds.GoogleMobileAdsClientFactory,Assembly-CSharp").GetMethod("BuildRewardedAdClient", BindingFlags.Static | BindingFlags.Public); + this.client = (IRewardedAdClient)method.Invoke(null, null); + this.client.CreateRewardedAd(adUnitId); + this.client.OnAdLoaded += delegate(object sender, EventArgs args) + { + if (this.OnAdLoaded != null) + { + this.OnAdLoaded(this, args); + } + }; + this.client.OnAdFailedToLoad += delegate(object sender, AdErrorEventArgs args) + { + if (this.OnAdFailedToLoad != null) + { + this.OnAdFailedToLoad(this, args); + } + }; + this.client.OnAdFailedToShow += delegate(object sender, AdErrorEventArgs args) + { + if (this.OnAdFailedToShow != null) + { + this.OnAdFailedToShow(this, args); + } + }; + this.client.OnAdOpening += delegate(object sender, EventArgs args) + { + if (this.OnAdOpening != null) + { + this.OnAdOpening(this, args); + } + }; + this.client.OnAdClosed += delegate(object sender, EventArgs args) + { + if (this.OnAdClosed != null) + { + this.OnAdClosed(this, args); + } + }; + this.client.OnUserEarnedReward += delegate(object sender, Reward args) + { + if (this.OnUserEarnedReward != null) + { + this.OnUserEarnedReward(this, args); + } + }; + } + + public void LoadAd(AdRequest request) + { + this.client.LoadAd(request); + } + + public bool IsLoaded() + { + return this.client.IsLoaded(); + } + + public void Show() + { + this.client.Show(); + } + + public void SetServerSideVerificationOptions(ServerSideVerificationOptions serverSideVerificationOptions) + { + this.client.SetServerSideVerificationOptions(serverSideVerificationOptions); + } + + public string MediationAdapterClassName() + { + return this.client.MediationAdapterClassName(); + } + } +} diff --git a/Client/Assembly-CSharp/GoogleMobileAds/Api/ServerSideVerificationOptions.cs b/Client/Assembly-CSharp/GoogleMobileAds/Api/ServerSideVerificationOptions.cs new file mode 100644 index 0000000..6f0e920 --- /dev/null +++ b/Client/Assembly-CSharp/GoogleMobileAds/Api/ServerSideVerificationOptions.cs @@ -0,0 +1,41 @@ +using System; + +namespace GoogleMobileAds.Api +{ + public class ServerSideVerificationOptions + { + public string UserId { get; private set; } + + public string CustomData { get; private set; } + + public class Builder + { + internal string UserId { get; private set; } + + internal string CustomData { get; private set; } + + public ServerSideVerificationOptions.Builder SetUserId(string userId) + { + this.UserId = userId; + return this; + } + + public ServerSideVerificationOptions.Builder SetCustomData(string customData) + { + this.CustomData = customData; + return this; + } + + public ServerSideVerificationOptions Build() + { + return new ServerSideVerificationOptions(this); + } + } + + private ServerSideVerificationOptions(ServerSideVerificationOptions.Builder builder) + { + this.UserId = builder.UserId; + this.CustomData = builder.CustomData; + } + } +} diff --git a/Client/Assembly-CSharp/GoogleMobileAds/Common/DummyClient.cs b/Client/Assembly-CSharp/GoogleMobileAds/Common/DummyClient.cs new file mode 100644 index 0000000..91587cc --- /dev/null +++ b/Client/Assembly-CSharp/GoogleMobileAds/Common/DummyClient.cs @@ -0,0 +1,185 @@ +using System; +using System.Reflection; +using GoogleMobileAds.Api; +using UnityEngine; + +namespace GoogleMobileAds.Common +{ + public class DummyClient : IBannerClient, IInterstitialClient, IRewardBasedVideoAdClient, IAdLoaderClient, IMobileAdsClient + { + public string UserId + { + get + { + Debug.Log("Dummy " + MethodBase.GetCurrentMethod().Name); + return "UserId"; + } + set + { + Debug.Log("Dummy " + MethodBase.GetCurrentMethod().Name); + } + } + + public event EventHandler<EventArgs> OnAdLoaded; + + public event EventHandler<AdFailedToLoadEventArgs> OnAdFailedToLoad; + + public event EventHandler<EventArgs> OnAdOpening; + + public event EventHandler<EventArgs> OnAdStarted; + + public event EventHandler<EventArgs> OnAdClosed; + + public event EventHandler<Reward> OnAdRewarded; + + public event EventHandler<EventArgs> OnAdLeavingApplication; + + public event EventHandler<EventArgs> OnAdCompleted; + + public event EventHandler<CustomNativeEventArgs> OnCustomNativeTemplateAdLoaded; + + public DummyClient() + { + Debug.Log("Dummy " + MethodBase.GetCurrentMethod().Name); + } + + public void Initialize(string appId) + { + Debug.Log("Dummy " + MethodBase.GetCurrentMethod().Name); + } + + public void SetApplicationMuted(bool muted) + { + Debug.Log("Dummy " + MethodBase.GetCurrentMethod().Name); + } + + public void SetApplicationVolume(float volume) + { + Debug.Log("Dummy " + MethodBase.GetCurrentMethod().Name); + } + + public void SetiOSAppPauseOnBackground(bool pause) + { + Debug.Log("Dummy " + MethodBase.GetCurrentMethod().Name); + } + + public void CreateBannerView(string adUnitId, AdSize adSize, AdPosition position) + { + Debug.Log("Dummy " + MethodBase.GetCurrentMethod().Name); + } + + public void CreateBannerView(string adUnitId, AdSize adSize, int positionX, int positionY) + { + Debug.Log("Dummy " + MethodBase.GetCurrentMethod().Name); + } + + public void LoadAd(AdRequest request) + { + Debug.Log("Dummy " + MethodBase.GetCurrentMethod().Name); + } + + public void ShowBannerView() + { + Debug.Log("Dummy " + MethodBase.GetCurrentMethod().Name); + } + + public void HideBannerView() + { + Debug.Log("Dummy " + MethodBase.GetCurrentMethod().Name); + } + + public void DestroyBannerView() + { + Debug.Log("Dummy " + MethodBase.GetCurrentMethod().Name); + } + + public float GetHeightInPixels() + { + Debug.Log("Dummy " + MethodBase.GetCurrentMethod().Name); + return 0f; + } + + public float GetWidthInPixels() + { + Debug.Log("Dummy " + MethodBase.GetCurrentMethod().Name); + return 0f; + } + + public void SetPosition(AdPosition adPosition) + { + Debug.Log("Dummy " + MethodBase.GetCurrentMethod().Name); + } + + public void SetPosition(int x, int y) + { + Debug.Log("Dummy " + MethodBase.GetCurrentMethod().Name); + } + + public void CreateInterstitialAd(string adUnitId) + { + Debug.Log("Dummy " + MethodBase.GetCurrentMethod().Name); + } + + public bool IsLoaded() + { + Debug.Log("Dummy " + MethodBase.GetCurrentMethod().Name); + return true; + } + + public void ShowInterstitial() + { + Debug.Log("Dummy " + MethodBase.GetCurrentMethod().Name); + } + + public void DestroyInterstitial() + { + Debug.Log("Dummy " + MethodBase.GetCurrentMethod().Name); + } + + public void CreateRewardBasedVideoAd() + { + Debug.Log("Dummy " + MethodBase.GetCurrentMethod().Name); + } + + public void SetUserId(string userId) + { + Debug.Log("Dummy " + MethodBase.GetCurrentMethod().Name); + } + + public void LoadAd(AdRequest request, string adUnitId) + { + Debug.Log("Dummy " + MethodBase.GetCurrentMethod().Name); + } + + public void DestroyRewardBasedVideoAd() + { + Debug.Log("Dummy " + MethodBase.GetCurrentMethod().Name); + } + + public void ShowRewardBasedVideoAd() + { + Debug.Log("Dummy " + MethodBase.GetCurrentMethod().Name); + } + + public void CreateAdLoader(AdLoader.Builder builder) + { + Debug.Log("Dummy " + MethodBase.GetCurrentMethod().Name); + } + + public void Load(AdRequest request) + { + Debug.Log("Dummy " + MethodBase.GetCurrentMethod().Name); + } + + public void SetAdSize(AdSize adSize) + { + Debug.Log("Dummy " + MethodBase.GetCurrentMethod().Name); + } + + public string MediationAdapterClassName() + { + Debug.Log("Dummy " + MethodBase.GetCurrentMethod().Name); + return null; + } + } +} diff --git a/Client/Assembly-CSharp/GoogleMobileAds/Common/IAdLoaderClient.cs b/Client/Assembly-CSharp/GoogleMobileAds/Common/IAdLoaderClient.cs new file mode 100644 index 0000000..4f9f332 --- /dev/null +++ b/Client/Assembly-CSharp/GoogleMobileAds/Common/IAdLoaderClient.cs @@ -0,0 +1,14 @@ +using System; +using GoogleMobileAds.Api; + +namespace GoogleMobileAds.Common +{ + public interface IAdLoaderClient + { + event EventHandler<AdFailedToLoadEventArgs> OnAdFailedToLoad; + + event EventHandler<CustomNativeEventArgs> OnCustomNativeTemplateAdLoaded; + + void LoadAd(AdRequest request); + } +} diff --git a/Client/Assembly-CSharp/GoogleMobileAds/Common/IBannerClient.cs b/Client/Assembly-CSharp/GoogleMobileAds/Common/IBannerClient.cs new file mode 100644 index 0000000..96f2d37 --- /dev/null +++ b/Client/Assembly-CSharp/GoogleMobileAds/Common/IBannerClient.cs @@ -0,0 +1,40 @@ +using System; +using GoogleMobileAds.Api; + +namespace GoogleMobileAds.Common +{ + public interface IBannerClient + { + event EventHandler<EventArgs> OnAdLoaded; + + event EventHandler<AdFailedToLoadEventArgs> OnAdFailedToLoad; + + event EventHandler<EventArgs> OnAdOpening; + + event EventHandler<EventArgs> OnAdClosed; + + event EventHandler<EventArgs> OnAdLeavingApplication; + + void CreateBannerView(string adUnitId, AdSize adSize, AdPosition position); + + void CreateBannerView(string adUnitId, AdSize adSize, int x, int y); + + void LoadAd(AdRequest request); + + void ShowBannerView(); + + void HideBannerView(); + + void DestroyBannerView(); + + float GetHeightInPixels(); + + float GetWidthInPixels(); + + void SetPosition(AdPosition adPosition); + + void SetPosition(int x, int y); + + string MediationAdapterClassName(); + } +} diff --git a/Client/Assembly-CSharp/GoogleMobileAds/Common/ICustomNativeTemplateClient.cs b/Client/Assembly-CSharp/GoogleMobileAds/Common/ICustomNativeTemplateClient.cs new file mode 100644 index 0000000..8c5ae57 --- /dev/null +++ b/Client/Assembly-CSharp/GoogleMobileAds/Common/ICustomNativeTemplateClient.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; + +namespace GoogleMobileAds.Common +{ + public interface ICustomNativeTemplateClient + { + string GetTemplateId(); + + byte[] GetImageByteArray(string key); + + List<string> GetAvailableAssetNames(); + + string GetText(string key); + + void PerformClick(string assetName); + + void RecordImpression(); + } +} diff --git a/Client/Assembly-CSharp/GoogleMobileAds/Common/IInterstitialClient.cs b/Client/Assembly-CSharp/GoogleMobileAds/Common/IInterstitialClient.cs new file mode 100644 index 0000000..cd4e35a --- /dev/null +++ b/Client/Assembly-CSharp/GoogleMobileAds/Common/IInterstitialClient.cs @@ -0,0 +1,30 @@ +using System; +using GoogleMobileAds.Api; + +namespace GoogleMobileAds.Common +{ + public interface IInterstitialClient + { + event EventHandler<EventArgs> OnAdLoaded; + + event EventHandler<AdFailedToLoadEventArgs> OnAdFailedToLoad; + + event EventHandler<EventArgs> OnAdOpening; + + event EventHandler<EventArgs> OnAdClosed; + + event EventHandler<EventArgs> OnAdLeavingApplication; + + void CreateInterstitialAd(string adUnitId); + + void LoadAd(AdRequest request); + + bool IsLoaded(); + + void ShowInterstitial(); + + void DestroyInterstitial(); + + string MediationAdapterClassName(); + } +} diff --git a/Client/Assembly-CSharp/GoogleMobileAds/Common/IMobileAdsClient.cs b/Client/Assembly-CSharp/GoogleMobileAds/Common/IMobileAdsClient.cs new file mode 100644 index 0000000..a7735f2 --- /dev/null +++ b/Client/Assembly-CSharp/GoogleMobileAds/Common/IMobileAdsClient.cs @@ -0,0 +1,15 @@ +using System; + +namespace GoogleMobileAds.Common +{ + public interface IMobileAdsClient + { + void Initialize(string appId); + + void SetApplicationVolume(float volume); + + void SetApplicationMuted(bool muted); + + void SetiOSAppPauseOnBackground(bool pause); + } +} diff --git a/Client/Assembly-CSharp/GoogleMobileAds/Common/IRewardBasedVideoAdClient.cs b/Client/Assembly-CSharp/GoogleMobileAds/Common/IRewardBasedVideoAdClient.cs new file mode 100644 index 0000000..2e4589d --- /dev/null +++ b/Client/Assembly-CSharp/GoogleMobileAds/Common/IRewardBasedVideoAdClient.cs @@ -0,0 +1,36 @@ +using System; +using GoogleMobileAds.Api; + +namespace GoogleMobileAds.Common +{ + public interface IRewardBasedVideoAdClient + { + event EventHandler<EventArgs> OnAdLoaded; + + event EventHandler<AdFailedToLoadEventArgs> OnAdFailedToLoad; + + event EventHandler<EventArgs> OnAdOpening; + + event EventHandler<EventArgs> OnAdStarted; + + event EventHandler<Reward> OnAdRewarded; + + event EventHandler<EventArgs> OnAdClosed; + + event EventHandler<EventArgs> OnAdLeavingApplication; + + event EventHandler<EventArgs> OnAdCompleted; + + void CreateRewardBasedVideoAd(); + + void LoadAd(AdRequest request, string adUnitId); + + bool IsLoaded(); + + string MediationAdapterClassName(); + + void ShowRewardBasedVideoAd(); + + void SetUserId(string userId); + } +} diff --git a/Client/Assembly-CSharp/GoogleMobileAds/Common/IRewardedAdClient.cs b/Client/Assembly-CSharp/GoogleMobileAds/Common/IRewardedAdClient.cs new file mode 100644 index 0000000..10a8a6c --- /dev/null +++ b/Client/Assembly-CSharp/GoogleMobileAds/Common/IRewardedAdClient.cs @@ -0,0 +1,32 @@ +using System; +using GoogleMobileAds.Api; + +namespace GoogleMobileAds.Common +{ + public interface IRewardedAdClient + { + event EventHandler<EventArgs> OnAdLoaded; + + event EventHandler<AdErrorEventArgs> OnAdFailedToLoad; + + event EventHandler<AdErrorEventArgs> OnAdFailedToShow; + + event EventHandler<EventArgs> OnAdOpening; + + event EventHandler<Reward> OnUserEarnedReward; + + event EventHandler<EventArgs> OnAdClosed; + + void CreateRewardedAd(string adUnitId); + + void LoadAd(AdRequest request); + + bool IsLoaded(); + + string MediationAdapterClassName(); + + void Show(); + + void SetServerSideVerificationOptions(ServerSideVerificationOptions serverSideVerificationOptions); + } +} diff --git a/Client/Assembly-CSharp/GoogleMobileAds/Common/MobileAdsEventExecutor.cs b/Client/Assembly-CSharp/GoogleMobileAds/Common/MobileAdsEventExecutor.cs new file mode 100644 index 0000000..8afa69c --- /dev/null +++ b/Client/Assembly-CSharp/GoogleMobileAds/Common/MobileAdsEventExecutor.cs @@ -0,0 +1,72 @@ +using System; +using System.Collections.Generic; +using UnityEngine; + +namespace GoogleMobileAds.Common +{ + public class MobileAdsEventExecutor : MonoBehaviour + { + public static MobileAdsEventExecutor instance = null; + + private static List<Action> adEventsQueue = new List<Action>(); + + private static volatile bool adEventsQueueEmpty = true; + + public static void Initialize() + { + if (MobileAdsEventExecutor.IsActive()) + { + return; + } + GameObject gameObject = new GameObject("MobileAdsMainThreadExecuter"); + gameObject.hideFlags = HideFlags.HideAndDontSave; + UnityEngine.Object.DontDestroyOnLoad(gameObject); + MobileAdsEventExecutor.instance = gameObject.AddComponent<MobileAdsEventExecutor>(); + } + + public static bool IsActive() + { + return MobileAdsEventExecutor.instance != null; + } + + public void Awake() + { + UnityEngine.Object.DontDestroyOnLoad(base.gameObject); + } + + public static void ExecuteInUpdate(Action action) + { + List<Action> obj = MobileAdsEventExecutor.adEventsQueue; + lock (obj) + { + MobileAdsEventExecutor.adEventsQueue.Add(action); + MobileAdsEventExecutor.adEventsQueueEmpty = false; + } + } + + public void Update() + { + if (MobileAdsEventExecutor.adEventsQueueEmpty) + { + return; + } + List<Action> list = new List<Action>(); + List<Action> obj = MobileAdsEventExecutor.adEventsQueue; + lock (obj) + { + list.AddRange(MobileAdsEventExecutor.adEventsQueue); + MobileAdsEventExecutor.adEventsQueue.Clear(); + MobileAdsEventExecutor.adEventsQueueEmpty = true; + } + foreach (Action action in list) + { + action(); + } + } + + public void OnDisable() + { + MobileAdsEventExecutor.instance = null; + } + } +} diff --git a/Client/Assembly-CSharp/GoogleMobileAds/Common/RewardedAdDummyClient.cs b/Client/Assembly-CSharp/GoogleMobileAds/Common/RewardedAdDummyClient.cs new file mode 100644 index 0000000..1271c6d --- /dev/null +++ b/Client/Assembly-CSharp/GoogleMobileAds/Common/RewardedAdDummyClient.cs @@ -0,0 +1,59 @@ +using System; +using System.Reflection; +using GoogleMobileAds.Api; +using UnityEngine; + +namespace GoogleMobileAds.Common +{ + public class RewardedAdDummyClient : IRewardedAdClient + { + public event EventHandler<EventArgs> OnAdLoaded; + + public event EventHandler<AdErrorEventArgs> OnAdFailedToLoad; + + public event EventHandler<AdErrorEventArgs> OnAdFailedToShow; + + public event EventHandler<EventArgs> OnAdOpening; + + public event EventHandler<EventArgs> OnAdClosed; + + public event EventHandler<Reward> OnUserEarnedReward; + + public RewardedAdDummyClient() + { + Debug.Log("Dummy " + MethodBase.GetCurrentMethod().Name); + } + + public void CreateRewardedAd(string adUnitId) + { + Debug.Log("Dummy " + MethodBase.GetCurrentMethod().Name); + } + + public void LoadAd(AdRequest request) + { + Debug.Log("Dummy " + MethodBase.GetCurrentMethod().Name); + } + + public bool IsLoaded() + { + Debug.Log("Dummy " + MethodBase.GetCurrentMethod().Name); + return true; + } + + public void Show() + { + Debug.Log("Dummy " + MethodBase.GetCurrentMethod().Name); + } + + public string MediationAdapterClassName() + { + Debug.Log("Dummy " + MethodBase.GetCurrentMethod().Name); + return null; + } + + public void SetServerSideVerificationOptions(ServerSideVerificationOptions serverSideVerificationOptions) + { + Debug.Log("Dummy " + MethodBase.GetCurrentMethod().Name); + } + } +} diff --git a/Client/Assembly-CSharp/GoogleMobileAds/Common/Utils.cs b/Client/Assembly-CSharp/GoogleMobileAds/Common/Utils.cs new file mode 100644 index 0000000..cd20f95 --- /dev/null +++ b/Client/Assembly-CSharp/GoogleMobileAds/Common/Utils.cs @@ -0,0 +1,27 @@ +using System; +using UnityEngine; + +namespace GoogleMobileAds.Common +{ + internal class Utils + { + public static void CheckInitialization() + { + if (!MobileAdsEventExecutor.IsActive()) + { + Debug.Log("You intitialized an ad object but have not yet called MobileAds.Initialize(). We highly recommend you call MobileAds.Initialize() before interacting with the Google Mobile Ads SDK."); + } + MobileAdsEventExecutor.Initialize(); + } + + public static Texture2D GetTexture2DFromByteArray(byte[] img) + { + Texture2D texture2D = new Texture2D(1, 1); + if (!texture2D.LoadImage(img)) + { + throw new InvalidOperationException("Could not load custom native template\n image asset as texture"); + } + return texture2D; + } + } +} diff --git a/Client/Assembly-CSharp/GoogleMobileAds/GoogleMobileAdsClientFactory.cs b/Client/Assembly-CSharp/GoogleMobileAds/GoogleMobileAdsClientFactory.cs new file mode 100644 index 0000000..1e5fcaa --- /dev/null +++ b/Client/Assembly-CSharp/GoogleMobileAds/GoogleMobileAdsClientFactory.cs @@ -0,0 +1,39 @@ +using System; +using GoogleMobileAds.Api; +using GoogleMobileAds.Common; + +namespace GoogleMobileAds +{ + public class GoogleMobileAdsClientFactory + { + public static IBannerClient BuildBannerClient() + { + return new DummyClient(); + } + + public static IInterstitialClient BuildInterstitialClient() + { + return new DummyClient(); + } + + public static IRewardBasedVideoAdClient BuildRewardBasedVideoAdClient() + { + return new DummyClient(); + } + + public static IRewardedAdClient BuildRewardedAdClient() + { + return new RewardedAdDummyClient(); + } + + public static IAdLoaderClient BuildAdLoaderClient(AdLoader adLoader) + { + return new DummyClient(); + } + + public static IMobileAdsClient MobileAdsInstance() + { + return new DummyClient(); + } + } +} diff --git a/Client/Assembly-CSharp/HashRandom.cs b/Client/Assembly-CSharp/HashRandom.cs new file mode 100644 index 0000000..7d226b1 --- /dev/null +++ b/Client/Assembly-CSharp/HashRandom.cs @@ -0,0 +1,36 @@ +using System; + +public static class HashRandom +{ + private static XXHash src = new XXHash((int)DateTime.UtcNow.Ticks); + + private static int cnt = 0; + + public static uint Next() + { + return HashRandom.src.GetHash(HashRandom.cnt++); + } + + public static int FastNext(int maxInt) + { + return (int)((ulong)HashRandom.Next() % (ulong)((long)maxInt)); + } + + public static int Next(int maxInt) + { + uint num = (uint)(-1 / maxInt); + uint num2 = num * (uint)maxInt; + uint num3; + do + { + num3 = HashRandom.Next(); + } + while (num3 > num2); + return (int)(num3 / num); + } + + public static int Next(int minInt, int maxInt) + { + return HashRandom.Next(maxInt - minInt) + minInt; + } +} diff --git a/Client/Assembly-CSharp/HatBehaviour.cs b/Client/Assembly-CSharp/HatBehaviour.cs new file mode 100644 index 0000000..95d4b25 --- /dev/null +++ b/Client/Assembly-CSharp/HatBehaviour.cs @@ -0,0 +1,34 @@ +using System; +using UnityEngine; + +[CreateAssetMenu] +public class HatBehaviour : ScriptableObject, IBuyable +{ + public string ProdId + { + get + { + return this.ProductId; + } + } + + public Sprite MainImage; + + public Sprite FloorImage; + + public bool InFront; + + public bool Free; + + public int LimitedMonth; + + public int LimitedYear; + + public SkinData RelatedSkin; + + public string StoreName; + + public string ProductId; + + public int Order; +} diff --git a/Client/Assembly-CSharp/HatManager.cs b/Client/Assembly-CSharp/HatManager.cs new file mode 100644 index 0000000..4c57c44 --- /dev/null +++ b/Client/Assembly-CSharp/HatManager.cs @@ -0,0 +1,89 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using UnityEngine; + +public class HatManager : DestroyableSingleton<HatManager> +{ + public HatBehaviour NoneHat; + + public List<PetBehaviour> AllPets = new List<PetBehaviour>(); + + public List<HatBehaviour> AllHats = new List<HatBehaviour>(); + + public List<SkinData> AllSkins = new List<SkinData>(); + + internal PetBehaviour GetPetById(uint petId) + { + if ((ulong)petId >= (ulong)((long)this.AllPets.Count)) + { + return this.AllPets[0]; + } + return this.AllPets[(int)petId]; + } + + public uint GetIdFromPet(PetBehaviour pet) + { + return (uint)this.AllPets.FindIndex((PetBehaviour p) => p.idleClip == pet.idleClip); + } + + public PetBehaviour[] GetUnlockedPets() + { + return (from h in this.AllPets + where h.Free || SaveManager.GetPurchase(h.ProductId) + select h).ToArray<PetBehaviour>(); + } + + public HatBehaviour GetHatById(uint hatId) + { + if ((ulong)hatId >= (ulong)((long)this.AllHats.Count)) + { + return this.NoneHat; + } + return this.AllHats[(int)hatId]; + } + + public HatBehaviour[] GetUnlockedHats() + { + return (from h in this.AllHats + where h.LimitedMonth == 0 || SaveManager.GetPurchase(h.ProductId) + select h into o + orderby o.Order descending, o.name + select o).ToArray<HatBehaviour>(); + } + + public uint GetIdFromHat(HatBehaviour hat) + { + return (uint)this.AllHats.IndexOf(hat); + } + + public SkinData[] GetUnlockedSkins() + { + return (from o in this.AllSkins + orderby o.Order descending, o.name + select o).ToArray<SkinData>(); + } + + public uint GetIdFromSkin(SkinData skin) + { + return (uint)this.AllSkins.IndexOf(skin); + } + + internal SkinData GetSkinById(uint skinId) + { + if ((ulong)skinId >= (ulong)((long)this.AllSkins.Count)) + { + return this.AllSkins[0]; + } + return this.AllSkins[(int)skinId]; + } + + internal void SetSkin(SpriteRenderer skinRend, uint skinId) + { + SkinData skinById = this.GetSkinById(skinId); + if (skinById) + { + skinRend.sprite = skinById.IdleFrame; + } + } +} diff --git a/Client/Assembly-CSharp/HatsTab.cs b/Client/Assembly-CSharp/HatsTab.cs new file mode 100644 index 0000000..10f7b3a --- /dev/null +++ b/Client/Assembly-CSharp/HatsTab.cs @@ -0,0 +1,83 @@ +using System; +using System.Collections.Generic; +using UnityEngine; + +public class HatsTab : MonoBehaviour +{ + public ColorChip ColorTabPrefab; + + public SpriteRenderer DemoImage; + + public SpriteRenderer HatImage; + + public SpriteRenderer SkinImage; + + public SpriteRenderer PetImage; + + public FloatRange XRange = new FloatRange(1.5f, 3f); + + public float YStart = 0.8f; + + public float YOffset = 0.8f; + + public int NumPerRow = 4; + + public Scroller scroller; + + private List<ColorChip> ColorChips = new List<ColorChip>(); + + public void OnEnable() + { + PlayerControl.SetPlayerMaterialColors((int)PlayerControl.LocalPlayer.Data.ColorId, this.DemoImage); + PlayerControl.SetHatImage(SaveManager.LastHat, this.HatImage); + PlayerControl.SetSkinImage(SaveManager.LastSkin, this.SkinImage); + PlayerControl.SetPetImage(SaveManager.LastPet, (int)PlayerControl.LocalPlayer.Data.ColorId, this.PetImage); + HatBehaviour[] unlockedHats = DestroyableSingleton<HatManager>.Instance.GetUnlockedHats(); + for (int i = 0; i < unlockedHats.Length; i++) + { + HatBehaviour hat = unlockedHats[i]; + float x = this.XRange.Lerp((float)(i % this.NumPerRow) / ((float)this.NumPerRow - 1f)); + float y = this.YStart - (float)(i / this.NumPerRow) * this.YOffset; + ColorChip colorChip = UnityEngine.Object.Instantiate<ColorChip>(this.ColorTabPrefab, this.scroller.Inner); + colorChip.transform.localPosition = new Vector3(x, y, -1f); + colorChip.Button.OnClick.AddListener(delegate() + { + this.SelectHat(hat); + }); + colorChip.Inner.sprite = hat.MainImage; + this.ColorChips.Add(colorChip); + } + this.scroller.YBounds.max = -(this.YStart - (float)(unlockedHats.Length / this.NumPerRow) * this.YOffset) - 3f; + } + + public void OnDisable() + { + for (int i = 0; i < this.ColorChips.Count; i++) + { + UnityEngine.Object.Destroy(this.ColorChips[i].gameObject); + } + this.ColorChips.Clear(); + } + + public void Update() + { + PlayerControl.SetPlayerMaterialColors((int)PlayerControl.LocalPlayer.Data.ColorId, this.DemoImage); + HatBehaviour hatById = DestroyableSingleton<HatManager>.Instance.GetHatById(SaveManager.LastHat); + for (int i = 0; i < this.ColorChips.Count; i++) + { + ColorChip colorChip = this.ColorChips[i]; + colorChip.InUseForeground.SetActive(hatById.MainImage == colorChip.Inner.sprite); + } + } + + private void SelectHat(HatBehaviour hat) + { + uint idFromHat = DestroyableSingleton<HatManager>.Instance.GetIdFromHat(hat); + SaveManager.LastHat = idFromHat; + PlayerControl.SetHatImage(idFromHat, this.HatImage); + if (PlayerControl.LocalPlayer) + { + PlayerControl.LocalPlayer.RpcSetHat(idFromHat); + } + } +} diff --git a/Client/Assembly-CSharp/HorizontalGauge.cs b/Client/Assembly-CSharp/HorizontalGauge.cs new file mode 100644 index 0000000..2995903 --- /dev/null +++ b/Client/Assembly-CSharp/HorizontalGauge.cs @@ -0,0 +1,26 @@ +using System; +using UnityEngine; + +public class HorizontalGauge : MonoBehaviour +{ + public float Value = 0.5f; + + public float MaxValue = 1f; + + public float maskScale = 1f; + + public SpriteMask Mask; + + private float lastValue = float.MinValue; + + public void Update() + { + if (this.MaxValue != 0f && this.lastValue != this.Value) + { + this.lastValue = this.Value; + float num = this.lastValue / this.MaxValue * this.maskScale; + this.Mask.transform.localScale = new Vector3(num, 1f, 1f); + this.Mask.transform.localPosition = new Vector3(-this.Mask.sprite.bounds.size.x * (this.maskScale - num) / 2f, 0f, 0f); + } + } +} diff --git a/Client/Assembly-CSharp/HostGameButton.cs b/Client/Assembly-CSharp/HostGameButton.cs new file mode 100644 index 0000000..486dc8e --- /dev/null +++ b/Client/Assembly-CSharp/HostGameButton.cs @@ -0,0 +1,135 @@ +using System; +using System.Collections; +using InnerNet; +using PowerTools; +using UnityEngine; + +public class HostGameButton : MonoBehaviour, IConnectButton +{ + public AudioClip IntroMusic; + + public string targetScene; + + public SpriteRenderer FillScreen; + + public SpriteAnim connectIcon; + + public AnimationClip connectClip; + + public GameModes GameMode; + + public void Start() + { + if (DestroyableSingleton<MatchMaker>.InstanceExists) + { + DestroyableSingleton<MatchMaker>.Instance.NotConnecting(); + } + } + + public void OnClick() + { + if (this.GameMode == GameModes.FreePlay) + { + if (!NameTextBehaviour.IsValidName(SaveManager.PlayerName)) + { + SaveManager.PlayerName = "Player"; + } + } + else + { + if (NameTextBehaviour.Instance.ShakeIfInvalid()) + { + return; + } + if (StatsManager.Instance.AmBanned) + { + AmongUsClient.Instance.LastDisconnectReason = DisconnectReasons.IntentionalLeaving; + DestroyableSingleton<DisconnectPopup>.Instance.Show(); + return; + } + if (!DestroyableSingleton<MatchMaker>.Instance.Connecting(this)) + { + return; + } + } + base.StartCoroutine(this.CoStartGame()); + } + + public void StartIcon() + { + if (!this.connectIcon) + { + return; + } + this.connectIcon.Play(this.connectClip, 1f); + } + + public void StopIcon() + { + if (!this.connectIcon) + { + return; + } + this.connectIcon.Stop(); + this.connectIcon.GetComponent<SpriteRenderer>().sprite = null; + } + + private IEnumerator CoStartGame() + { + try + { + SoundManager.Instance.StopAllSound(); + AmongUsClient.Instance.GameMode = this.GameMode; + switch (this.GameMode) + { + case GameModes.LocalGame: + DestroyableSingleton<InnerNetServer>.Instance.StartAsServer(); + AmongUsClient.Instance.SetEndpoint("127.0.0.1", 22023); + AmongUsClient.Instance.MainMenuScene = "MatchMaking"; + break; + case GameModes.OnlineGame: + AmongUsClient.Instance.SetEndpoint(DestroyableSingleton<ServerManager>.Instance.OnlineNetAddress, 22023); + AmongUsClient.Instance.MainMenuScene = "MMOnline"; + break; + case GameModes.FreePlay: + DestroyableSingleton<InnerNetServer>.Instance.StartAsServer(); + AmongUsClient.Instance.SetEndpoint("127.0.0.1", 22023); + AmongUsClient.Instance.MainMenuScene = "MainMenu"; + break; + } + } + catch (Exception ex) + { + DestroyableSingleton<DisconnectPopup>.Instance.ShowCustom(ex.Message); + DestroyableSingleton<MatchMaker>.Instance.NotConnecting(); + yield break; + } + yield return new WaitForSeconds(0.1f); + if (this.FillScreen) + { + SoundManager.Instance.CrossFadeSound("MainBG", null, 0.5f, 1.5f); + this.FillScreen.gameObject.SetActive(true); + for (float time = 0f; time < 0.25f; time += Time.deltaTime) + { + this.FillScreen.color = Color.Lerp(Color.clear, Color.black, time / 0.25f); + yield return null; + } + this.FillScreen.color = Color.black; + } + AmongUsClient.Instance.OnlineScene = this.targetScene; + AmongUsClient.Instance.Connect(MatchMakerModes.HostAndClient); + yield return AmongUsClient.Instance.WaitForConnectionOrFail(); + DestroyableSingleton<MatchMaker>.Instance.NotConnecting(); + if (AmongUsClient.Instance.mode == MatchMakerModes.None && this.FillScreen) + { + SoundManager.Instance.CrossFadeSound("MainBG", this.IntroMusic, 0.5f, 1.5f); + for (float time = 0f; time < 0.25f; time += Time.deltaTime) + { + this.FillScreen.color = Color.Lerp(Color.black, Color.clear, time / 0.25f); + yield return null; + } + this.FillScreen.color = Color.clear; + } + yield break; + } +} diff --git a/Client/Assembly-CSharp/HowToPlayController.cs b/Client/Assembly-CSharp/HowToPlayController.cs new file mode 100644 index 0000000..2274478 --- /dev/null +++ b/Client/Assembly-CSharp/HowToPlayController.cs @@ -0,0 +1,67 @@ +using System; +using UnityEngine; +using UnityEngine.SceneManagement; + +public class HowToPlayController : MonoBehaviour +{ + public Transform DotParent; + + public SpriteRenderer leftButton; + + public SpriteRenderer rightButton; + + public SceneController PCMove; + + public SceneController[] Scenes; + + public int SceneNum; + + public void Start() + { + this.Scenes[2] = this.PCMove; + this.PCMove.gameObject.SetActive(false); + for (int i = 1; i < this.Scenes.Length; i++) + { + this.Scenes[i].gameObject.SetActive(false); + } + for (int j = 0; j < this.DotParent.childCount; j++) + { + this.DotParent.GetChild(j).localScale = Vector3.one; + } + this.ChangeScene(0); + } + + public void Update() + { + if (Input.GetKeyUp(KeyCode.Escape)) + { + this.Close(); + } + } + + public void NextScene() + { + this.ChangeScene(1); + } + + public void PreviousScene() + { + this.ChangeScene(-1); + } + + public void Close() + { + SceneManager.LoadScene("MainMenu"); + } + + private void ChangeScene(int del) + { + this.Scenes[this.SceneNum].gameObject.SetActive(false); + this.DotParent.GetChild(this.SceneNum).localScale = Vector3.one; + this.SceneNum = Mathf.Clamp(this.SceneNum + del, 0, this.Scenes.Length - 1); + this.Scenes[this.SceneNum].gameObject.SetActive(true); + this.DotParent.GetChild(this.SceneNum).localScale = new Vector3(1.5f, 1.5f, 1.5f); + this.leftButton.gameObject.SetActive(this.SceneNum > 0); + this.rightButton.gameObject.SetActive(this.SceneNum < this.Scenes.Length - 1); + } +} diff --git a/Client/Assembly-CSharp/HudManager.cs b/Client/Assembly-CSharp/HudManager.cs new file mode 100644 index 0000000..d3905ea --- /dev/null +++ b/Client/Assembly-CSharp/HudManager.cs @@ -0,0 +1,312 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Text; +using InnerNet; +using UnityEngine; + +public class HudManager : DestroyableSingleton<HudManager> +{ + public Coroutine ReactorFlash { get; set; } + + public Coroutine OxyFlash { get; set; } + + public MeetingHud MeetingPrefab; + + public KillButtonManager KillButton; + + public UseButtonManager UseButton; + + public ReportButtonManager ReportButton; + + public TextRenderer GameSettings; + + public GameObject TaskStuff; + + public ChatController Chat; + + public DialogueBox Dialogue; + + public TextRenderer TaskText; + + public Transform TaskCompleteOverlay; + + private float taskDirtyTimer; + + public MeshRenderer ShadowQuad; + + public SpriteRenderer FullScreen; + + public SpriteRenderer MapButton; + + public KillOverlay KillOverlay; + + public IVirtualJoystick joystick; + + public MonoBehaviour[] Joysticks; + + public DiscussBehaviour discussEmblem; + + public ShhhBehaviour shhhEmblem; + + public IntroCutscene IntroPrefab; + + public OptionsMenuBehaviour GameMenu; + + public NotificationPopper Notifier; + + public RoomTracker roomTracker; + + public AudioClip SabotageSound; + + public AudioClip TaskCompleteSound; + + public AudioClip TaskUpdateSound; + + private StringBuilder tasksString = new StringBuilder(); + + public void Start() + { + this.SetTouchType(SaveManager.TouchConfig); + } + + public void ShowTaskComplete() + { + base.StartCoroutine(this.CoTaskComplete()); + } + + private IEnumerator CoTaskComplete() + { + if (Constants.ShouldPlaySfx()) + { + SoundManager.Instance.PlaySound(this.TaskCompleteSound, false, 1f); + } + this.TaskCompleteOverlay.gameObject.SetActive(true); + yield return Effects.Slide2D(this.TaskCompleteOverlay, new Vector2(0f, -8f), Vector2.zero, 0.25f); + for (float time = 0f; time < 0.75f; time += Time.deltaTime) + { + yield return null; + } + yield return Effects.Slide2D(this.TaskCompleteOverlay, Vector2.zero, new Vector2(0f, 8f), 0.25f); + this.TaskCompleteOverlay.gameObject.SetActive(false); + yield break; + } + + public void SetJoystickSize(float size) + { + if (this.joystick != null && this.joystick is VirtualJoystick) + { + VirtualJoystick virtualJoystick = (VirtualJoystick)this.joystick; + virtualJoystick.transform.localScale = new Vector3(size, size, 1f); + AspectPosition component = virtualJoystick.GetComponent<AspectPosition>(); + float num = Mathf.Lerp(0.65f, 1.1f, FloatRange.ReverseLerp(size, 0.5f, 1.5f)); + component.DistanceFromEdge = new Vector3(num, num, -10f); + component.AdjustPosition(); + } + } + + public void SetTouchType(int type) + { + if (this.joystick != null && !(this.joystick is KeyboardJoystick)) + { + UnityEngine.Object.Destroy((this.joystick as MonoBehaviour).gameObject); + } + MonoBehaviour monoBehaviour = UnityEngine.Object.Instantiate<MonoBehaviour>(this.Joysticks[Mathf.Clamp(type + 1, 1, this.Joysticks.Length)]); + monoBehaviour.transform.SetParent(base.transform, false); + this.joystick = monoBehaviour.GetComponent<IVirtualJoystick>(); + } + + public void OpenMap() + { + this.ShowMap(delegate(MapBehaviour m) + { + m.ShowNormalMap(); + }); + } + + public void ShowMap(Action<MapBehaviour> mapAction) + { + if (!ShipStatus.Instance) + { + return; + } + if (!MapBehaviour.Instance) + { + MapBehaviour.Instance = UnityEngine.Object.Instantiate<MapBehaviour>(ShipStatus.Instance.MapPrefab, base.transform); + MapBehaviour.Instance.gameObject.SetActive(false); + } + mapAction(MapBehaviour.Instance); + } + + public void SetHudActive(bool isActive) + { + DestroyableSingleton<HudManager>.Instance.UseButton.gameObject.SetActive(isActive); + DestroyableSingleton<HudManager>.Instance.UseButton.Refresh(); + DestroyableSingleton<HudManager>.Instance.ReportButton.gameObject.SetActive(isActive); + GameData.PlayerInfo data = PlayerControl.LocalPlayer.Data; + DestroyableSingleton<HudManager>.Instance.KillButton.gameObject.SetActive(isActive && data.IsImpostor && !data.IsDead); + DestroyableSingleton<HudManager>.Instance.TaskText.transform.parent.gameObject.SetActive(isActive); + } + + public void FixedUpdate() + { + this.taskDirtyTimer += Time.fixedDeltaTime; + if (this.taskDirtyTimer > 0.25f) + { + this.taskDirtyTimer = 0f; + if (!PlayerControl.LocalPlayer) + { + this.TaskText.Text = string.Empty; + return; + } + GameData.PlayerInfo data = PlayerControl.LocalPlayer.Data; + if (data == null) + { + return; + } + bool isImpostor = data.IsImpostor; + this.tasksString.Clear(); + if (PlayerControl.LocalPlayer.myTasks.Count == 0) + { + this.tasksString.Append("None"); + } + else + { + for (int i = 0; i < PlayerControl.LocalPlayer.myTasks.Count; i++) + { + PlayerTask playerTask = PlayerControl.LocalPlayer.myTasks[i]; + if (playerTask) + { + if (playerTask.TaskType == TaskTypes.FixComms && !isImpostor) + { + this.tasksString.Clear(); + playerTask.AppendTaskText(this.tasksString); + break; + } + playerTask.AppendTaskText(this.tasksString); + } + } + this.tasksString.TrimEnd(); + } + this.TaskText.Text = this.tasksString.ToString(); + } + } + + public IEnumerator ShowEmblem(bool shhh) + { + if (shhh) + { + this.shhhEmblem.gameObject.SetActive(true); + yield return this.shhhEmblem.PlayAnimation(); + this.shhhEmblem.gameObject.SetActive(false); + } + else + { + this.discussEmblem.gameObject.SetActive(true); + yield return this.discussEmblem.PlayAnimation(); + this.discussEmblem.gameObject.SetActive(false); + } + yield break; + } + + public void StartReactorFlash() + { + if (this.ReactorFlash == null) + { + this.ReactorFlash = base.StartCoroutine(this.CoReactorFlash()); + } + } + + public void StartOxyFlash() + { + if (this.OxyFlash == null) + { + this.OxyFlash = base.StartCoroutine(this.CoReactorFlash()); + } + } + + public void ShowPopUp(string text) + { + this.Dialogue.Show(text); + } + + public void StopReactorFlash() + { + if (this.ReactorFlash != null) + { + base.StopCoroutine(this.ReactorFlash); + this.FullScreen.enabled = false; + this.ReactorFlash = null; + } + } + + public void StopOxyFlash() + { + if (this.OxyFlash != null) + { + base.StopCoroutine(this.OxyFlash); + this.FullScreen.enabled = false; + this.OxyFlash = null; + } + } + + public IEnumerator CoFadeFullScreen(Color source, Color target, float duration = 0.2f) + { + if (this.FullScreen.enabled && this.FullScreen.color == target) + { + yield break; + } + this.FullScreen.enabled = true; + for (float t = 0f; t < duration; t += Time.deltaTime) + { + this.FullScreen.color = Color.Lerp(source, target, t / duration); + yield return null; + } + this.FullScreen.color = target; + if (target.a < 0.05f) + { + this.FullScreen.enabled = false; + } + yield break; + } + + private IEnumerator CoReactorFlash() + { + WaitForSeconds wait = new WaitForSeconds(1f); + this.FullScreen.color = new Color(1f, 0f, 0f, 0.37254903f); + for (;;) + { + this.FullScreen.enabled = !this.FullScreen.enabled; + SoundManager.Instance.PlaySound(this.SabotageSound, false, 1f); + yield return wait; + } + yield break; + } + + public IEnumerator CoShowIntro(List<PlayerControl> yourTeam) + { + DestroyableSingleton<HudManager>.Instance.FullScreen.transform.localPosition = new Vector3(0f, 0f, -250f); + yield return DestroyableSingleton<HudManager>.Instance.ShowEmblem(true); + IntroCutscene introCutscene = UnityEngine.Object.Instantiate<IntroCutscene>(this.IntroPrefab, base.transform); + yield return introCutscene.CoBegin(yourTeam, PlayerControl.LocalPlayer.Data.IsImpostor); + PlayerControl.LocalPlayer.SetKillTimer(10f); + ((SabotageSystemType)ShipStatus.Instance.Systems[SystemTypes.Sabotage]).ForceSabTime(10f); + yield return this.CoFadeFullScreen(Color.black, Color.clear, 0.2f); + DestroyableSingleton<HudManager>.Instance.FullScreen.transform.localPosition = new Vector3(0f, 0f, -500f); + yield break; + } + + public void OpenMeetingRoom(PlayerControl reporter) + { + if (MeetingHud.Instance) + { + return; + } + Debug.Log("Opening meeting room: " + reporter); + ShipStatus.Instance.RepairSystem(SystemTypes.Reactor, PlayerControl.LocalPlayer, 16); + ShipStatus.Instance.RepairSystem(SystemTypes.LifeSupp, PlayerControl.LocalPlayer, 16); + MeetingHud.Instance = UnityEngine.Object.Instantiate<MeetingHud>(this.MeetingPrefab); + MeetingHud.Instance.ServerStart(reporter.PlayerId); + AmongUsClient.Instance.Spawn(MeetingHud.Instance, -2, SpawnFlags.None); + } +} diff --git a/Client/Assembly-CSharp/HudOverrideSystemType.cs b/Client/Assembly-CSharp/HudOverrideSystemType.cs new file mode 100644 index 0000000..82558cb --- /dev/null +++ b/Client/Assembly-CSharp/HudOverrideSystemType.cs @@ -0,0 +1,40 @@ +using System; +using Hazel; + +internal class HudOverrideSystemType : ISystemType, IActivatable +{ + public bool IsActive { get; private set; } + + public const byte DamageBit = 128; + + public const byte TaskMask = 127; + + public bool Detoriorate(float deltaTime) + { + if (this.IsActive && !PlayerTask.PlayerHasHudTask(PlayerControl.LocalPlayer)) + { + PlayerControl.LocalPlayer.AddSystemTask(SystemTypes.Comms); + } + return false; + } + + public void RepairDamage(PlayerControl player, byte amount) + { + if ((amount & 128) > 0) + { + this.IsActive = true; + return; + } + this.IsActive = false; + } + + public void Serialize(MessageWriter writer, bool initialState) + { + writer.Write(this.IsActive); + } + + public void Deserialize(MessageReader reader, bool initialState) + { + this.IsActive = reader.ReadBoolean(); + } +} diff --git a/Client/Assembly-CSharp/HudOverrideTask.cs b/Client/Assembly-CSharp/HudOverrideTask.cs new file mode 100644 index 0000000..eb47b87 --- /dev/null +++ b/Client/Assembly-CSharp/HudOverrideTask.cs @@ -0,0 +1,82 @@ +using System; +using System.Linq; +using System.Text; +using UnityEngine; + +public class HudOverrideTask : SabotageTask +{ + public override int TaskStep + { + get + { + if (!this.isComplete) + { + return 0; + } + return 1; + } + } + + public override bool IsComplete + { + get + { + return this.isComplete; + } + } + + private bool isComplete; + + private HudOverrideSystemType system; + + private bool even; + + public override void Initialize() + { + ShipStatus instance = ShipStatus.Instance; + this.system = (instance.Systems[SystemTypes.Comms] as HudOverrideSystemType); + base.SetupArrows(); + } + + private void FixedUpdate() + { + if (this.isComplete) + { + return; + } + if (!this.system.IsActive) + { + this.Complete(); + } + } + + public override bool ValidConsole(global::Console console) + { + return console.TaskTypes.Contains(TaskTypes.FixComms); + } + + public override void Complete() + { + this.isComplete = true; + PlayerControl.LocalPlayer.RemoveTask(this); + if (this.didContribute) + { + StatsManager instance = StatsManager.Instance; + uint sabsFixed = instance.SabsFixed; + instance.SabsFixed = sabsFixed + 1U; + } + } + + public override void AppendTaskText(StringBuilder sb) + { + this.even = !this.even; + Color color = this.even ? Color.yellow : Color.red; + sb.Append(color.ToTextColor()); + sb.Append(DestroyableSingleton<TranslationController>.Instance.GetString(TaskTypes.FixComms)); + sb.Append("[]"); + for (int i = 0; i < this.Arrows.Length; i++) + { + this.Arrows[i].image.color = color; + } + } +} diff --git a/Client/Assembly-CSharp/IActivatable.cs b/Client/Assembly-CSharp/IActivatable.cs new file mode 100644 index 0000000..fd4ecbf --- /dev/null +++ b/Client/Assembly-CSharp/IActivatable.cs @@ -0,0 +1,6 @@ +using System; + +public interface IActivatable +{ + bool IsActive { get; } +} diff --git a/Client/Assembly-CSharp/IBuyable.cs b/Client/Assembly-CSharp/IBuyable.cs new file mode 100644 index 0000000..b19fbb4 --- /dev/null +++ b/Client/Assembly-CSharp/IBuyable.cs @@ -0,0 +1,6 @@ +using System; + +public interface IBuyable +{ + string ProdId { get; } +} diff --git a/Client/Assembly-CSharp/IBytesSerializable.cs b/Client/Assembly-CSharp/IBytesSerializable.cs new file mode 100644 index 0000000..e256d7e --- /dev/null +++ b/Client/Assembly-CSharp/IBytesSerializable.cs @@ -0,0 +1,6 @@ +using System; + +public interface IBytesSerializable +{ + byte[] ToBytes(); +} diff --git a/Client/Assembly-CSharp/IConnectButton.cs b/Client/Assembly-CSharp/IConnectButton.cs new file mode 100644 index 0000000..5f2848a --- /dev/null +++ b/Client/Assembly-CSharp/IConnectButton.cs @@ -0,0 +1,8 @@ +using System; + +public interface IConnectButton +{ + void StartIcon(); + + void StopIcon(); +} diff --git a/Client/Assembly-CSharp/IDisconnectHandler.cs b/Client/Assembly-CSharp/IDisconnectHandler.cs new file mode 100644 index 0000000..c2482fe --- /dev/null +++ b/Client/Assembly-CSharp/IDisconnectHandler.cs @@ -0,0 +1,9 @@ +using System; +using InnerNet; + +public interface IDisconnectHandler +{ + void HandleDisconnect(PlayerControl pc, DisconnectReasons reason); + + void HandleDisconnect(); +} diff --git a/Client/Assembly-CSharp/IFocusHolder.cs b/Client/Assembly-CSharp/IFocusHolder.cs new file mode 100644 index 0000000..1342fa8 --- /dev/null +++ b/Client/Assembly-CSharp/IFocusHolder.cs @@ -0,0 +1,11 @@ +using System; +using UnityEngine; + +public interface IFocusHolder +{ + void GiveFocus(); + + void LoseFocus(); + + bool CheckCollision(Vector2 pt); +} diff --git a/Client/Assembly-CSharp/IGameListHandler.cs b/Client/Assembly-CSharp/IGameListHandler.cs new file mode 100644 index 0000000..4be55da --- /dev/null +++ b/Client/Assembly-CSharp/IGameListHandler.cs @@ -0,0 +1,8 @@ +using System; +using System.Collections.Generic; +using InnerNet; + +public interface IGameListHandler +{ + void HandleList(int totalGames, List<GameListing> availableGames); +} diff --git a/Client/Assembly-CSharp/ILocationActivate.cs b/Client/Assembly-CSharp/ILocationActivate.cs new file mode 100644 index 0000000..2d9bb88 --- /dev/null +++ b/Client/Assembly-CSharp/ILocationActivate.cs @@ -0,0 +1,6 @@ +using System; + +internal interface ILocationActivate +{ + void LocationUse(PlayerControl pc); +} diff --git a/Client/Assembly-CSharp/IObjectPool.cs b/Client/Assembly-CSharp/IObjectPool.cs new file mode 100644 index 0000000..312a917 --- /dev/null +++ b/Client/Assembly-CSharp/IObjectPool.cs @@ -0,0 +1,13 @@ +using System; +using UnityEngine; + +public abstract class IObjectPool : MonoBehaviour +{ + public abstract int InUse { get; } + + public abstract int NotInUse { get; } + + public abstract T Get<T>() where T : PoolableBehavior; + + public abstract void Reclaim(PoolableBehavior obj); +} diff --git a/Client/Assembly-CSharp/ISoundPlayer.cs b/Client/Assembly-CSharp/ISoundPlayer.cs new file mode 100644 index 0000000..0b5d3ca --- /dev/null +++ b/Client/Assembly-CSharp/ISoundPlayer.cs @@ -0,0 +1,11 @@ +using System; +using UnityEngine; + +public interface ISoundPlayer +{ + string Name { get; set; } + + AudioSource Player { get; set; } + + void Update(float dt); +} diff --git a/Client/Assembly-CSharp/ISystemType.cs b/Client/Assembly-CSharp/ISystemType.cs new file mode 100644 index 0000000..6e6d4fd --- /dev/null +++ b/Client/Assembly-CSharp/ISystemType.cs @@ -0,0 +1,15 @@ +using System; +using Hazel; + +// 需要同步的内容,比如门DoorsSystemType + +public interface ISystemType +{ + bool Detoriorate(float deltaTime); + + void RepairDamage(PlayerControl player, byte amount); + + void Serialize(MessageWriter writer, bool initialState); + + void Deserialize(MessageReader reader, bool initialState); +} diff --git a/Client/Assembly-CSharp/ITranslatedText.cs b/Client/Assembly-CSharp/ITranslatedText.cs new file mode 100644 index 0000000..f6f1857 --- /dev/null +++ b/Client/Assembly-CSharp/ITranslatedText.cs @@ -0,0 +1,6 @@ +using System; + +public interface ITranslatedText +{ + void ResetText(); +} diff --git a/Client/Assembly-CSharp/IUsable.cs b/Client/Assembly-CSharp/IUsable.cs new file mode 100644 index 0000000..12053be --- /dev/null +++ b/Client/Assembly-CSharp/IUsable.cs @@ -0,0 +1,14 @@ +using System; + +public interface IUsable +{ + float UsableDistance { get; } + + float PercentCool { get; } + + void SetOutline(bool on, bool mainTarget); + + float CanUse(GameData.PlayerInfo pc, out bool canUse, out bool couldUse); + + void Use(); +} diff --git a/Client/Assembly-CSharp/IVirtualJoystick.cs b/Client/Assembly-CSharp/IVirtualJoystick.cs new file mode 100644 index 0000000..fdfeef8 --- /dev/null +++ b/Client/Assembly-CSharp/IVirtualJoystick.cs @@ -0,0 +1,7 @@ +using System; +using UnityEngine; + +public interface IVirtualJoystick +{ + Vector2 Delta { get; } +} diff --git a/Client/Assembly-CSharp/ImageData.cs b/Client/Assembly-CSharp/ImageData.cs new file mode 100644 index 0000000..762189b --- /dev/null +++ b/Client/Assembly-CSharp/ImageData.cs @@ -0,0 +1,10 @@ +using System; +using UnityEngine; + +[Serializable] +public struct ImageData +{ + public ImageNames Name; + + public Sprite Sprite; +} diff --git a/Client/Assembly-CSharp/ImageNames.cs b/Client/Assembly-CSharp/ImageNames.cs new file mode 100644 index 0000000..e70e8a8 --- /dev/null +++ b/Client/Assembly-CSharp/ImageNames.cs @@ -0,0 +1,12 @@ +using System; + +public enum ImageNames +{ + LocalButton, + OnlineButton, + HowToPlayButton, + FreeplayButton, + HostHeader, + PublicHeader, + PrivateHeader +} diff --git a/Client/Assembly-CSharp/ImageTranslator.cs b/Client/Assembly-CSharp/ImageTranslator.cs new file mode 100644 index 0000000..7ea508b --- /dev/null +++ b/Client/Assembly-CSharp/ImageTranslator.cs @@ -0,0 +1,24 @@ +using System; +using UnityEngine; + +[RequireComponent(typeof(SpriteRenderer))] +public class ImageTranslator : MonoBehaviour, ITranslatedText +{ + public ImageNames TargetImage; + + public void ResetText() + { + base.GetComponent<SpriteRenderer>().sprite = DestroyableSingleton<TranslationController>.Instance.GetImage(this.TargetImage); + } + + public void Start() + { + DestroyableSingleton<TranslationController>.Instance.ActiveTexts.Add(this); + this.ResetText(); + } + + public void OnDestroy() + { + DestroyableSingleton<TranslationController>.Instance.ActiveTexts.Remove(this); + } +} diff --git a/Client/Assembly-CSharp/ImportantTextTask.cs b/Client/Assembly-CSharp/ImportantTextTask.cs new file mode 100644 index 0000000..7eb28b7 --- /dev/null +++ b/Client/Assembly-CSharp/ImportantTextTask.cs @@ -0,0 +1,41 @@ +using System; +using System.Text; + +public class ImportantTextTask : PlayerTask +{ + public override int TaskStep + { + get + { + return 0; + } + } + + public override bool IsComplete + { + get + { + return false; + } + } + + public string Text; + + public override void Initialize() + { + } + + public override bool ValidConsole(global::Console console) + { + return false; + } + + public override void Complete() + { + } + + public override void AppendTaskText(StringBuilder sb) + { + sb.AppendLine("[FF0000FF]" + this.Text + "[]"); + } +} diff --git a/Client/Assembly-CSharp/InfectedOverlay.cs b/Client/Assembly-CSharp/InfectedOverlay.cs new file mode 100644 index 0000000..53d7942 --- /dev/null +++ b/Client/Assembly-CSharp/InfectedOverlay.cs @@ -0,0 +1,51 @@ +using System; +using UnityEngine; + +public class InfectedOverlay : MonoBehaviour +{ + public bool CanUseDoors + { + get + { + return !this.SabSystem.AnyActive; + } + } + + public bool CanUseSpecial + { + get + { + return this.SabSystem.Timer <= 0f && !this.doors.IsActive && !this.SabSystem.AnyActive; + } + } + + public MapRoom[] rooms; + + private IActivatable doors; + + private SabotageSystemType SabSystem; + + public void Start() + { + for (int i = 0; i < this.rooms.Length; i++) + { + this.rooms[i].Parent = this; + } + this.SabSystem = (SabotageSystemType)ShipStatus.Instance.Systems[SystemTypes.Sabotage]; + this.doors = (IActivatable)ShipStatus.Instance.Systems[SystemTypes.Doors]; + } + + private void FixedUpdate() + { + if (this.doors == null) + { + return; + } + float specialActive = this.doors.IsActive ? 1f : this.SabSystem.PercentCool; + for (int i = 0; i < this.rooms.Length; i++) + { + this.rooms[i].SetSpecialActive(specialActive); + this.rooms[i].OOBUpdate(); + } + } +} diff --git a/Client/Assembly-CSharp/InnerNet/AlterGameTags.cs b/Client/Assembly-CSharp/InnerNet/AlterGameTags.cs new file mode 100644 index 0000000..730126b --- /dev/null +++ b/Client/Assembly-CSharp/InnerNet/AlterGameTags.cs @@ -0,0 +1,9 @@ +using System; + +namespace InnerNet +{ + public static class AlterGameTags + { + public const byte ChangePrivacy = 1; + } +} diff --git a/Client/Assembly-CSharp/InnerNet/ClientData.cs b/Client/Assembly-CSharp/InnerNet/ClientData.cs new file mode 100644 index 0000000..780d6ae --- /dev/null +++ b/Client/Assembly-CSharp/InnerNet/ClientData.cs @@ -0,0 +1,21 @@ +using System; + +namespace InnerNet +{ + [Serializable] + public class ClientData + { + public int Id; + + public bool InScene; + + public bool IsReady; + + public PlayerControl Character; + + public ClientData(int id) + { + this.Id = id; + } + } +} diff --git a/Client/Assembly-CSharp/InnerNet/DisconnectReasons.cs b/Client/Assembly-CSharp/InnerNet/DisconnectReasons.cs new file mode 100644 index 0000000..1d9c4a6 --- /dev/null +++ b/Client/Assembly-CSharp/InnerNet/DisconnectReasons.cs @@ -0,0 +1,25 @@ +using System; + +namespace InnerNet +{ + public enum DisconnectReasons + { + ExitGame, + GameFull, + GameStarted, + GameNotFound, + IncorrectVersion = 5, + Banned, + Kicked, + Custom, + Destroy = 16, + Error, + IncorrectGame, + ServerRequest, + ServerFull, + IntentionalLeaving = 208, + FocusLostBackground = 207, + FocusLost = 209, + NewConnection + } +} diff --git a/Client/Assembly-CSharp/InnerNet/GameKeywords.cs b/Client/Assembly-CSharp/InnerNet/GameKeywords.cs new file mode 100644 index 0000000..76eaabc --- /dev/null +++ b/Client/Assembly-CSharp/InnerNet/GameKeywords.cs @@ -0,0 +1,16 @@ +using System; + +namespace InnerNet +{ + [Flags] + public enum GameKeywords : uint + { + All = 0U, + AllLanguages = 31U, + English = 1U, + Spanish = 2U, + Korean = 4U, + Russian = 8U, + Portuguese = 16U + } +} diff --git a/Client/Assembly-CSharp/InnerNet/GameListing.cs b/Client/Assembly-CSharp/InnerNet/GameListing.cs new file mode 100644 index 0000000..d10ea34 --- /dev/null +++ b/Client/Assembly-CSharp/InnerNet/GameListing.cs @@ -0,0 +1,30 @@ +using System; + +namespace InnerNet +{ + [Serializable] + public struct GameListing + { + public int GameId; + + public byte PlayerCount; + + public byte ImpostorCount; + + public byte MaxPlayers; + + public int Age; + + public string HostName; + + public GameListing(int id, byte numImpostors, byte playerCount, byte maxPlayers, int age, string host) + { + this.GameId = id; + this.ImpostorCount = numImpostors; + this.PlayerCount = playerCount; + this.MaxPlayers = maxPlayers; + this.Age = age; + this.HostName = host; + } + } +} diff --git a/Client/Assembly-CSharp/InnerNet/GameStates.cs b/Client/Assembly-CSharp/InnerNet/GameStates.cs new file mode 100644 index 0000000..812ffa2 --- /dev/null +++ b/Client/Assembly-CSharp/InnerNet/GameStates.cs @@ -0,0 +1,12 @@ +using System; + +namespace InnerNet +{ + public enum GameStates : byte + { + NotStarted, + Started, + Ended, + Destroyed + } +} diff --git a/Client/Assembly-CSharp/InnerNet/InnerDiscover.cs b/Client/Assembly-CSharp/InnerNet/InnerDiscover.cs new file mode 100644 index 0000000..b596ef5 --- /dev/null +++ b/Client/Assembly-CSharp/InnerNet/InnerDiscover.cs @@ -0,0 +1,114 @@ +using System; +using System.Collections; +using System.Net.Sockets; +using Hazel.Udp; +using UnityEngine; + +namespace InnerNet +{ + public class InnerDiscover : DestroyableSingleton<InnerDiscover> + { + public event Action<BroadcastPacket> OnPacketGet; + + private UdpBroadcastListener listener; + + private UdpBroadcaster sender; + + public int Port = 47777; + + public float Interval = 1f; + + public void StartAsServer(string data) + { + bool flag = this.sender == null; + if (flag) + { + this.sender = new UdpBroadcaster(this.Port); + } + this.sender.SetData(data); + if (flag) + { + base.StartCoroutine(this.RunServer()); + } + } + + private IEnumerator RunServer() + { + while (this.sender != null) + { + this.sender.Broadcast(); + for (float timer = 0f; timer < this.Interval; timer += Time.deltaTime) + { + yield return null; + } + } + yield break; + } + + public void StopServer() + { + if (this.sender != null) + { + this.sender.Dispose(); + this.sender = null; + } + } + + public void StartAsClient() + { + if (this.listener == null) + { + try + { + this.listener = new UdpBroadcastListener(this.Port); + this.listener.StartListen(); + base.StartCoroutine(this.RunClient()); + } + catch (SocketException) + { + AmongUsClient.Instance.LastDisconnectReason = DisconnectReasons.Custom; + AmongUsClient.Instance.LastCustomDisconnect = "Couldn't start local network listener. You may need to restart Among Us."; + DestroyableSingleton<DisconnectPopup>.Instance.Show(); + } + } + } + + private IEnumerator RunClient() + { + while (this.listener != null) + { + if (!this.listener.Running) + { + this.listener.StartListen(); + } + BroadcastPacket[] packets = this.listener.GetPackets(); + for (int i = 0; i < packets.Length; i++) + { + Action<BroadcastPacket> onPacketGet = this.OnPacketGet; + if (onPacketGet != null) + { + onPacketGet(packets[i]); + } + } + yield return null; + } + yield break; + } + + public void StopClient() + { + if (this.listener != null) + { + this.listener.Dispose(); + this.listener = null; + } + } + + public override void OnDestroy() + { + this.StopServer(); + this.StopClient(); + base.OnDestroy(); + } + } +} diff --git a/Client/Assembly-CSharp/InnerNet/InnerNetClient.cs b/Client/Assembly-CSharp/InnerNet/InnerNetClient.cs new file mode 100644 index 0000000..7cff87c --- /dev/null +++ b/Client/Assembly-CSharp/InnerNet/InnerNetClient.cs @@ -0,0 +1,1726 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using System.Net; +using System.Threading; +using Assets.CoreScripts; +using Hazel; +using Hazel.Udp; +using UnityEngine; +using UnityEngine.SceneManagement; + +namespace InnerNet +{ + public abstract class InnerNetClient : MonoBehaviour + { + private bool AmConnected + { + get + { + return this.connection != null; + } + } + + public int Ping + { + get + { + if (this.connection == null) + { + return 0; + } + return (int)this.connection.AveragePingMs; + } + } + + public bool AmHost + { + get + { + return this.HostId == this.ClientId; + } + } + + public bool AmClient + { + get + { + return this.ClientId > 0; + } + } + + public bool IsGamePublic { get; private set; } + + public bool IsGameStarted + { + get + { + return this.GameState == InnerNetClient.GameStates.Started; + } + } + + public bool IsGameOver + { + get + { + return this.GameState == InnerNetClient.GameStates.Ended; + } + } + + private static readonly DisconnectReasons[] disconnectReasons = new DisconnectReasons[] + { + DisconnectReasons.Error, + DisconnectReasons.GameFull, + DisconnectReasons.GameStarted, + DisconnectReasons.GameNotFound, + DisconnectReasons.IncorrectVersion, + DisconnectReasons.Banned, + DisconnectReasons.Kicked, + DisconnectReasons.ServerFull, + DisconnectReasons.Custom + }; + + public const int NoClientId = -1; + + private string networkAddress = "127.0.0.1"; + + private int networkPort; + + private UdpClientConnection connection; + + public MatchMakerModes mode; + + public int GameId = 32; + + public int HostId; + + public int ClientId = -1; + + public List<ClientData> allClients = new List<ClientData>(); + + public DisconnectReasons LastDisconnectReason; + + public string LastCustomDisconnect; + + private readonly List<Action> PreSpawnDispatcher = new List<Action>(); + + //c 网络消息队列,网络线程写入,主线程调用 + private readonly List<Action> Dispatcher = new List<Action>(); + + public InnerNetClient.GameStates GameState; + + private List<Action> TempQueue = new List<Action>(); + + private volatile bool appPaused; + + public const int CurrentClient = -3; + + public const int InvalidClient = -2; + + internal const byte DataFlag = 1; + + internal const byte RpcFlag = 2; + + internal const byte SpawnFlag = 4; + + internal const byte DespawnFlag = 5; + + internal const byte SceneChangeFlag = 6; + + internal const byte ReadyFlag = 7; + + internal const byte ChangeSettingsFlag = 8; + + // 每次发送数据的间隔,每过0.1s发送一次 + public float MinSendInterval = 0.1f; + + private uint NetIdCnt = 1U; + + private float timer; + + public InnerNetObject[] SpawnableObjects; + + private bool InOnlineScene; + + private HashSet<uint> DestroyedObjects = new HashSet<uint>(); + + // 所有要同步的数据,包括InnerNetObject的所有派生类,场景内所有的对象的数据 + public List<InnerNetObject> allObjects = new List<InnerNetObject>(); + + private Dictionary<uint, InnerNetObject> allObjectsFast = new Dictionary<uint, InnerNetObject>(); + + private MessageWriter[] Streams; + + public enum GameStates + { + NotJoined, + Joined, + Started, + Ended + } + + public void SetEndpoint(string addr, ushort port) + { + this.networkAddress = addr; + this.networkPort = (int)port; + } + + public virtual void Start() + { + SceneManager.activeSceneChanged += delegate(Scene oldScene, Scene scene) + { + this.SendSceneChange(scene.name); + }; + this.ClientId = -1; + this.GameId = 32; + } + + private void SendOrDisconnect(MessageWriter msg) + { + try + { + this.connection.Send(msg); + } + catch + { + this.EnqueueDisconnect(DisconnectReasons.Error, "Failed to send message"); + } + } + + public ClientData GetHost() + { + List<ClientData> obj = this.allClients; + lock (obj) + { + for (int i = 0; i < this.allClients.Count; i++) + { + ClientData clientData = this.allClients[i]; + if (clientData.Id == this.HostId) + { + return clientData; + } + } + } + return null; + } + + public int GetClientIdFromCharacter(InnerNetObject character) + { + if (!character) + { + return -1; + } + List<ClientData> obj = this.allClients; + lock (obj) + { + for (int i = 0; i < this.allClients.Count; i++) + { + ClientData clientData = this.allClients[i]; + if (clientData.Character == character) + { + return clientData.Id; + } + } + } + return -1; + } + + public virtual void OnDestroy() + { + if (this.AmConnected) + { + this.DisconnectInternal(DisconnectReasons.Destroy, null); + } + } + + public IEnumerator CoConnect() + { + if (this.AmConnected) + { + yield break; + } + DestroyableSingleton<DisconnectPopup>.Instance.Close(); + this.LastDisconnectReason = DisconnectReasons.ExitGame; + this.NetIdCnt = 1U; + this.DestroyedObjects.Clear(); + if (this.Streams == null) + { + this.Streams = new MessageWriter[2]; + for (int i = 0; i < this.Streams.Length; i++) + { + this.Streams[i] = MessageWriter.Get((SendOption)i); + } + } + for (int j = 0; j < this.Streams.Length; j++) + { + MessageWriter messageWriter = this.Streams[j]; + messageWriter.Clear((SendOption)j); + messageWriter.StartMessage(5); + messageWriter.Write(this.GameId); + } + IPEndPoint remoteEndPoint = new IPEndPoint(IPAddress.Parse(this.networkAddress), this.networkPort); + this.connection = new UdpClientConnection(remoteEndPoint, IPMode.IPv4); + this.connection.KeepAliveInterval = 1500; + this.connection.DisconnectTimeout = 7500; + this.connection.ResendPingMultiplier = 2f; + this.connection.DataReceived += this.OnMessageReceived; // 注册到网络线程的消息处理函数 + this.connection.Disconnected += this.OnDisconnect; // 连接断开时的回调函数 + this.connection.ConnectAsync(this.GetConnectionData(), 5000); + + yield return this.WaitWithTimeout(() => this.connection == null || this.connection.State == ConnectionState.Connected); + + yield break; + } + + private void Connection_DataReceivedRaw(byte[] data) + { + Debug.Log("Client Got: " + string.Join(" ", from b in data + select b.ToString())); + } + + private void Connection_DataSentRaw(byte[] data, int length) + { + Debug.Log("Client Sent: " + string.Join(" ", (from b in data + select b.ToString()).ToArray<string>(), 0, length)); + } + + public void Connect(MatchMakerModes mode) + { + base.StartCoroutine(this.CoConnect(mode)); + } + + private IEnumerator CoConnect(MatchMakerModes mode) + { + if (this.mode != MatchMakerModes.None) + { + this.DisconnectInternal(DisconnectReasons.NewConnection, null); + } + this.mode = mode; + yield return this.CoConnect(); + if (!this.AmConnected) + { + yield break; + } + MatchMakerModes matchMakerModes = this.mode; + if (matchMakerModes == MatchMakerModes.Client) + { + this.JoinGame(); + yield return this.WaitWithTimeout(() => this.ClientId >= 0); + bool amConnected = this.AmConnected; + yield break; + } + if (matchMakerModes != MatchMakerModes.HostAndClient) + { + yield break; + } + this.GameId = 0; + PlayerControl.GameOptions = SaveManager.GameHostOptions; + this.HostGame(PlayerControl.GameOptions); + yield return this.WaitWithTimeout(() => this.GameId != 0); + if (!this.AmConnected) + { + yield break; + } + this.JoinGame(); + yield return this.WaitWithTimeout(() => this.ClientId >= 0); + bool amConnected2 = this.AmConnected; + yield break; + } + + public IEnumerator WaitForConnectionOrFail() + { + while (this.AmConnected) + { + switch (this.mode) + { + case MatchMakerModes.None: + goto IL_5F; + case MatchMakerModes.Client: + if (this.ClientId >= 0) + { + yield break; + } + break; + case MatchMakerModes.HostAndClient: + if (this.GameId != 0 && this.ClientId >= 0) + { + yield break; + } + break; + default: + goto IL_5F; + } + yield return null; + continue; + IL_5F: + yield break; + } + yield break; + } + + private IEnumerator WaitWithTimeout(Func<bool> success) + { + bool failed = true; + for (float timer = 0f; timer < 5f; timer += Time.deltaTime) + { + if (success()) + { + failed = false; + break; + } + if (!this.AmConnected) + { + yield break; + } + yield return null; + } + if (failed) + { + this.DisconnectInternal(DisconnectReasons.Error, null); + } + yield break; + } + + //c 执行从网络线程收到的回调Dispatcher + public void Update() + { + if (Input.GetKeyDown(KeyCode.Return) && (Input.GetKey(KeyCode.LeftAlt) || Input.GetKey(KeyCode.RightAlt))) + { + ResolutionManager.ToggleFullscreen(); + } + this.TempQueue.Clear(); + List<Action> obj = this.Dispatcher; + lock (obj) + { + this.TempQueue.AddAll(this.Dispatcher); + this.Dispatcher.Clear(); + } + for (int i = 0; i < this.TempQueue.Count; i++) + { + Action action = this.TempQueue[i]; + try + { + action(); + } + catch (Exception exception) + { + Debug.LogException(exception); + } + } + if (this.InOnlineScene) + { + this.TempQueue.Clear(); + obj = this.PreSpawnDispatcher; + lock (obj) + { + this.TempQueue.AddAll(this.PreSpawnDispatcher); + this.PreSpawnDispatcher.Clear(); + } + for (int j = 0; j < this.TempQueue.Count; j++) + { + Action action2 = this.TempQueue[j]; + try + { + action2(); + } + catch (Exception exception2) + { + Debug.LogException(exception2); + } + } + } + } + + private void OnDisconnect(object sender, DisconnectedEventArgs e) + { + if (!e.Reason.Contains("The remote sent a")) + { + this.LastCustomDisconnect = "You disconnected from the server.\r\n\r\n" + e.Reason; + this.EnqueueDisconnect(DisconnectReasons.Custom, e.Reason); + return; + } + this.EnqueueDisconnect(DisconnectReasons.Error, e.Reason); + } + + public void HandleDisconnect(DisconnectReasons reason, string stringReason = null) + { + base.StopAllCoroutines(); + DestroyableSingleton<Telemetry>.Instance.WriteDisconnect(this.LastDisconnectReason); + this.DisconnectInternal(reason, stringReason); + this.OnDisconnected(); + } + + protected void EnqueueDisconnect(DisconnectReasons reason, string stringReason = null) + { + UdpClientConnection udpClientConnection = this.connection; + List<Action> dispatcher = this.Dispatcher; + lock (dispatcher) + { + this.Dispatcher.Add(delegate + { + this.HandleDisconnect(reason, stringReason); + }); + } + } + + protected void DisconnectInternal(DisconnectReasons reason, string stringReason = null) + { + if (reason != DisconnectReasons.NewConnection && reason != DisconnectReasons.FocusLostBackground) + { + this.LastDisconnectReason = reason; + if (reason != DisconnectReasons.ExitGame && DestroyableSingleton<DisconnectPopup>.InstanceExists) + { + DestroyableSingleton<DisconnectPopup>.Instance.Show(); + } + } + if (this.mode == MatchMakerModes.HostAndClient) + { + this.GameId = 0; + } + if (this.mode == MatchMakerModes.Client || this.mode == MatchMakerModes.HostAndClient) + { + this.ClientId = -1; + } + this.mode = MatchMakerModes.None; + this.GameState = InnerNetClient.GameStates.NotJoined; + UdpClientConnection udpClientConnection = this.connection; + this.connection = null; + if (udpClientConnection != null) + { + try + { + udpClientConnection.Dispose(); + } + catch (Exception exception) + { + Debug.LogException(exception); + } + } + if (DestroyableSingleton<InnerNetServer>.InstanceExists) + { + DestroyableSingleton<InnerNetServer>.Instance.StopServer(); + } + List<Action> obj = this.Dispatcher; + lock (obj) + { + this.Dispatcher.Clear(); + } + obj = this.PreSpawnDispatcher; + lock (obj) + { + this.PreSpawnDispatcher.Clear(); + } + if (reason != DisconnectReasons.Error) + { + this.TempQueue.Clear(); + } + this.allObjects.Clear(); + this.allClients.Clear(); + this.allObjectsFast.Clear(); + } + + public void HostGame(IBytesSerializable settings) + { + this.IsGamePublic = false; + MessageWriter messageWriter = MessageWriter.Get(SendOption.Reliable); + messageWriter.StartMessage(0); + messageWriter.WriteBytesAndSize(settings.ToBytes()); + messageWriter.EndMessage(); + this.SendOrDisconnect(messageWriter); + messageWriter.Recycle(); + Debug.Log("Client requesting new game."); + } + + public void JoinGame() + { + this.ClientId = -1; + if (!this.AmConnected) + { + this.HandleDisconnect(DisconnectReasons.Error, null); + return; + } + Debug.Log("Client joining game: " + InnerNetClient.IntToGameName(this.GameId)); + MessageWriter messageWriter = MessageWriter.Get(SendOption.Reliable); + messageWriter.StartMessage(1); + messageWriter.Write(this.GameId); + messageWriter.EndMessage(); + this.SendOrDisconnect(messageWriter); + messageWriter.Recycle(); + } + + public bool CanBan() + { + return this.AmHost && !this.IsGameStarted; + } + + public bool CanKick() + { + return this.IsGameStarted || this.AmHost; + } + + public void KickPlayer(int clientId, bool ban) + { + if (!this.AmHost) + { + return; + } + MessageWriter messageWriter = MessageWriter.Get(SendOption.Reliable); + messageWriter.StartMessage(11); + messageWriter.Write(this.GameId); + messageWriter.WritePacked(clientId); + messageWriter.Write(ban); + messageWriter.EndMessage(); + this.SendOrDisconnect(messageWriter); + messageWriter.Recycle(); + } + + public MessageWriter StartEndGame() + { + MessageWriter messageWriter = MessageWriter.Get(SendOption.Reliable); + messageWriter.StartMessage(8); + messageWriter.Write(this.GameId); + return messageWriter; + } + + public void FinishEndGame(MessageWriter msg) + { + msg.EndMessage(); + this.SendOrDisconnect(msg); + msg.Recycle(); + } + + protected void SendLateRejection(int targetId, DisconnectReasons reason) + { + MessageWriter messageWriter = MessageWriter.Get(SendOption.Reliable); + messageWriter.StartMessage(4); + messageWriter.Write(this.GameId); + messageWriter.WritePacked(targetId); + messageWriter.Write((byte)reason); + messageWriter.EndMessage(); + this.SendOrDisconnect(messageWriter); + messageWriter.Recycle(); + } + + protected void SendClientReady() + { + if (!this.AmHost) + { + MessageWriter messageWriter = MessageWriter.Get(SendOption.Reliable); + messageWriter.StartMessage(5); + messageWriter.Write(this.GameId); + messageWriter.StartMessage(7); + messageWriter.WritePacked(this.ClientId); + messageWriter.EndMessage(); + messageWriter.EndMessage(); + this.SendOrDisconnect(messageWriter); + messageWriter.Recycle(); + return; + } + ClientData clientData = this.FindClientById(this.ClientId); + if (clientData == null) + { + this.HandleDisconnect(DisconnectReasons.Error, "Couldn't find self as host"); + return; + } + clientData.IsReady = true; + } + + protected void SendStartGame() + { + MessageWriter messageWriter = MessageWriter.Get(SendOption.Reliable); + messageWriter.StartMessage(2); + messageWriter.Write(this.GameId); + messageWriter.EndMessage(); + this.SendOrDisconnect(messageWriter); + messageWriter.Recycle(); + } + + public void RequestGameList(bool includePrivate, IBytesSerializable settings) + { + MessageWriter messageWriter = MessageWriter.Get(SendOption.Reliable); + messageWriter.StartMessage(9); + messageWriter.Write(includePrivate); + messageWriter.WriteBytesAndSize(settings.ToBytes()); + messageWriter.EndMessage(); + this.SendOrDisconnect(messageWriter); + messageWriter.Recycle(); + } + + public void ChangeGamePublic(bool isPublic) + { + if (this.AmHost) + { + MessageWriter messageWriter = MessageWriter.Get(SendOption.Reliable); + messageWriter.StartMessage(10); + messageWriter.Write(this.GameId); + messageWriter.Write(1); + messageWriter.Write(isPublic); + messageWriter.EndMessage(); + this.SendOrDisconnect(messageWriter); + messageWriter.Recycle(); + this.IsGamePublic = isPublic; + } + } + + //c 收到数据,在网络线程 + private void OnMessageReceived(DataReceivedEventArgs e) + { + MessageReader message = e.Message; + try + { + while (message.Position < message.Length) + { + this.HandleMessage(message.ReadMessage()); + } + } + finally + { + message.Recycle(); + } + } + + + //c 从imposter搞过来的 + //c 后来发现Tags.cs里有 + private static readonly Dictionary<byte, string> TagMap = new Dictionary<byte, string> + { + {0, "HostGame"}, + {1, "JoinGame"}, + {2, "StartGame"}, + {3, "RemoveGame"}, + {4, "RemovePlayer"}, + {5, "GameData"}, + {6, "GameDataTo"}, + {7, "JoinedGame"}, + {8, "EndGame"}, + {9, "GetGameList"}, + {10, "AlterGame"}, + {11, "KickPlayer"}, + {12, "WaitForHost"}, + {13, "Redirect"}, + {14, "ReselectServer"}, + {16, "GetGameListV2"} + }; + + + private enum TagAlias + { + HostGame = 0, // 创建 + StartGame = 2, // 开始游戏 + Disconnect = 3, // 断开 + SubMessage = 6, // + JoinGame = 7, // 加入游戏 + Gameover = 8, // 游戏结束 + } + + //c 处理收到的数据 + private void HandleMessage(MessageReader reader) + { + List<Action> obj; + switch (reader.Tag) + { + case (int)TagAlias.HostGame: + this.GameId = reader.ReadInt32(); + Debug.Log("Client hosting game: " + InnerNetClient.IntToGameName(this.GameId)); + obj = this.Dispatcher; + lock (obj) + { + this.Dispatcher.Add(delegate + { + this.OnGameCreated(InnerNetClient.IntToGameName(this.GameId)); + }); + return; + } + break; + case 1: + goto IL_2F5; + case (int)TagAlias.StartGame: + this.GameState = InnerNetClient.GameStates.Started; + obj = this.Dispatcher; + lock (obj) + { + this.Dispatcher.Add(delegate + { + this.OnStartGame(); + }); + return; + } + goto IL_675; + case (int)TagAlias.Disconnect: + { + DisconnectReasons reason3 = DisconnectReasons.ServerRequest; + if (reader.Position < reader.Length) + { + reason3 = (DisconnectReasons)reader.ReadByte(); + } + this.EnqueueDisconnect(reason3, null); + return; + } + case 4: + break; + case 5: + case (int)TagAlias.SubMessage: // 把这类消息存在队列里,主线程后续调用 + { + int num = reader.ReadInt32(); + if (this.GameId == num) + { + if (reader.Tag == 6) + { + int num2 = reader.ReadPackedInt32(); + if (this.ClientId != num2) + { + Debug.LogWarning(string.Format("Got data meant for {0}", num2)); + return; + } + } + MessageReader subReader; + if (this.InOnlineScene) + { + subReader = MessageReader.Get(reader); + obj = this.Dispatcher; + lock (obj) + { + this.Dispatcher.Add(delegate + { + this.HandleGameData(subReader, 0); // 在主线程调用 + }); + return; + } + } + Debug.Log("Stored early game data"); + subReader = MessageReader.Get(reader); + obj = this.PreSpawnDispatcher; + lock (obj) + { + this.PreSpawnDispatcher.Add(delegate + { + this.HandleGameData(subReader, 0); // 在主线程调用 + }); + return; + } + goto IL_517; + } + return; + } + case (int)TagAlias.JoinGame: + goto IL_235; + case (int)TagAlias.Gameover: + { + int num3 = reader.ReadInt32(); + if (this.GameId == num3 && this.GameState != InnerNetClient.GameStates.Ended) + { + this.GameState = InnerNetClient.GameStates.Ended; + List<ClientData> obj2 = this.allClients; + lock (obj2) + { + this.allClients.Clear(); + } + GameOverReason reason = (GameOverReason)reader.ReadByte(); + bool showAd = reader.ReadBoolean(); + obj = this.Dispatcher; + lock (obj) + { + this.Dispatcher.Add(delegate + { + this.OnGameEnd(reason, showAd); + }); + return; + } + goto IL_1DD; + } + return; + } + case 9: + goto IL_517; + case 10: + goto IL_5BC; + case 11: + goto IL_675; + case 12: + goto IL_1DD; + case 13: + { + uint address = reader.ReadUInt32(); + ushort port = reader.ReadUInt16(); + AmongUsClient.Instance.SetEndpoint(InnerNetClient.AddressToString(address), port); + obj = this.Dispatcher; + lock (obj) + { + this.Dispatcher.Add(delegate + { + Debug.Log(string.Format("Redirected to: {0}:{1}", this.networkAddress, this.networkPort)); + base.StopAllCoroutines(); + this.Connect(this.mode); + }); + return; + } + goto IL_70A; + } + default: + goto IL_70A; + } + int num4 = reader.ReadInt32(); + if (this.GameId == num4) + { + int playerIdThatLeft = reader.ReadInt32(); + int hostId = reader.ReadInt32(); + DisconnectReasons reason2 = (DisconnectReasons)reader.ReadByte(); + if (!this.AmHost) + { + this.HostId = hostId; + if (this.AmHost) + { + obj = this.Dispatcher; + lock (obj) + { + this.Dispatcher.Add(delegate + { + this.OnBecomeHost(); + }); + } + } + } + this.RemovePlayer(playerIdThatLeft, reason2); + return; + } + return; + IL_1DD: + int num5 = reader.ReadInt32(); + if (this.GameId != num5) + { + return; + } + this.ClientId = reader.ReadInt32(); + obj = this.Dispatcher; + lock (obj) + { + this.Dispatcher.Add(delegate + { + this.OnWaitForHost(InnerNetClient.IntToGameName(this.GameId)); + }); + return; + } + IL_235: + int num6 = reader.ReadInt32(); + if (this.GameId != num6 || this.GameState == InnerNetClient.GameStates.Joined) + { + return; + } + this.GameState = InnerNetClient.GameStates.Joined; + this.ClientId = reader.ReadInt32(); + ClientData myClient = this.GetOrCreateClient(this.ClientId); + this.HostId = reader.ReadInt32(); + int num7 = reader.ReadPackedInt32(); + for (int i = 0; i < num7; i++) + { + this.GetOrCreateClient(reader.ReadPackedInt32()); + } + obj = this.Dispatcher; + lock (obj) + { + this.Dispatcher.Add(delegate + { + this.OnGameJoined(InnerNetClient.IntToGameName(this.GameId), myClient); + }); + return; + } + IL_2F5: + int num8 = reader.ReadInt32(); + DisconnectReasons disconnectReasons = (DisconnectReasons)num8; + if (InnerNetClient.disconnectReasons.Contains(disconnectReasons)) + { + if (disconnectReasons == DisconnectReasons.Custom) + { + this.LastCustomDisconnect = reader.ReadString(); + } + this.GameId = -1; + this.EnqueueDisconnect(disconnectReasons, null); + return; + } + if (this.GameId == num8) + { + int num9 = reader.ReadInt32(); + bool amHost = this.AmHost; + this.HostId = reader.ReadInt32(); + ClientData client = this.GetOrCreateClient(num9); + Debug.Log(string.Format("Player {0} joined", num9)); + obj = this.Dispatcher; + lock (obj) + { + this.Dispatcher.Add(delegate + { + this.OnPlayerJoined(client); + }); + } + if (!this.AmHost || amHost) + { + return; + } + obj = this.Dispatcher; + lock (obj) + { + this.Dispatcher.Add(delegate + { + this.OnBecomeHost(); + }); + return; + } + } + this.EnqueueDisconnect(DisconnectReasons.IncorrectGame, null); + return; + IL_517: + int totalGames = reader.ReadPackedInt32(); + List<GameListing> output = new List<GameListing>(); + while (reader.Position < reader.Length) + { + output.Add(new GameListing(reader.ReadInt32(), reader.ReadByte(), reader.ReadByte(), reader.ReadByte(), reader.ReadPackedInt32(), reader.ReadString())); + } + obj = this.Dispatcher; + lock (obj) + { + this.Dispatcher.Add(delegate + { + this.OnGetGameList(totalGames, output); + }); + return; + } + IL_5BC: + int num10 = reader.ReadInt32(); + if (this.GameId != num10) + { + return; + } + byte b = reader.ReadByte(); + if (b == 1) + { + this.IsGamePublic = reader.ReadBoolean(); + string str = "Alter Public = "; + bool flag = this.IsGamePublic; + Debug.Log(str + flag.ToString()); + return; + } + Debug.Log("Alter unknown"); + return; + IL_675: + int num11 = reader.ReadInt32(); + if (this.GameId == num11 && reader.ReadPackedInt32() == this.ClientId) + { + this.EnqueueDisconnect(reader.ReadBoolean() ? DisconnectReasons.Banned : DisconnectReasons.Kicked, null); + return; + } + return; + IL_70A: + Debug.Log(string.Format("Bad tag {0} at {1}+{2}={3}: ", new object[] + { + reader.Tag, + reader.Offset, + reader.Position, + reader.Length + }) + string.Join<byte>(" ", reader.Buffer)); + } + + private static string AddressToString(uint address) + { + return string.Format("{0}.{1}.{2}.{3}", new object[] + { + (byte)address, + (byte)(address >> 8), + (byte)(address >> 16), + (byte)(address >> 24) + }); + } + + private ClientData GetOrCreateClient(int clientId) + { + List<ClientData> obj = this.allClients; + ClientData clientData; + lock (obj) + { + clientData = this.allClients.FirstOrDefault((ClientData c) => c.Id == clientId); + if (clientData == null) + { + clientData = new ClientData(clientId); + this.allClients.Add(clientData); + } + } + return clientData; + } + + private void RemovePlayer(int playerIdThatLeft, DisconnectReasons reason) + { + ClientData client = null; + List<ClientData> obj = this.allClients; + lock (obj) + { + for (int i = 0; i < this.allClients.Count; i++) + { + ClientData clientData = this.allClients[i]; + if (clientData.Id == playerIdThatLeft) + { + client = clientData; + this.allClients.RemoveAt(i); + break; + } + } + } + if (client != null) + { + List<Action> dispatcher = this.Dispatcher; + lock (dispatcher) + { + this.Dispatcher.Add(delegate + { + this.OnPlayerLeft(client, reason); + }); + } + } + } + + protected virtual void OnApplicationPause(bool pause) + { + this.appPaused = pause; + if (!pause) + { + Debug.Log("Resumed Game"); + if (this.AmHost) + { + this.RemoveUnownedObjects(); + return; + } + } + else if (this.GameState != InnerNetClient.GameStates.Ended && this.AmConnected) + { + Debug.Log("Lost focus during game"); + ThreadPool.QueueUserWorkItem(new WaitCallback(this.WaitToDisconnect)); + } + } + + private void WaitToDisconnect(object state) + { + int num = 0; + while (num < 10 && this.appPaused) + { + Thread.Sleep(1000); + num++; + } + if (this.appPaused && this.GameState != InnerNetClient.GameStates.Ended && this.AmConnected) + { + this.DisconnectInternal(DisconnectReasons.FocusLostBackground, null); + this.EnqueueDisconnect(DisconnectReasons.FocusLost, null); + } + } + + protected void SendInitialData(int clientId) + { + MessageWriter messageWriter = MessageWriter.Get(SendOption.Reliable); + messageWriter.StartMessage(6); + messageWriter.Write(this.GameId); + messageWriter.WritePacked(clientId); + List<InnerNetObject> obj = this.allObjects; + lock (obj) + { + HashSet<GameObject> hashSet = new HashSet<GameObject>(); + for (int i = 0; i < this.allObjects.Count; i++) + { + InnerNetObject innerNetObject = this.allObjects[i]; + if (innerNetObject && hashSet.Add(innerNetObject.gameObject)) + { + this.WriteSpawnMessage(innerNetObject, innerNetObject.OwnerId, innerNetObject.SpawnFlags, messageWriter); + } + } + } + messageWriter.EndMessage(); + this.SendOrDisconnect(messageWriter); + messageWriter.Recycle(); + } + + protected abstract void OnGameCreated(string gameIdString); + + protected abstract void OnGameJoined(string gameIdString, ClientData client); + + protected abstract void OnWaitForHost(string gameIdString); + + protected abstract void OnStartGame(); + + protected abstract void OnGameEnd(GameOverReason reason, bool showAd); + + protected abstract void OnBecomeHost(); + + protected abstract void OnPlayerJoined(ClientData client); + + protected abstract void OnPlayerChangedScene(ClientData client, string targetScene); + + protected abstract void OnPlayerLeft(ClientData client, DisconnectReasons reason); + + protected abstract void OnDisconnected(); + + protected abstract void OnGetGameList(int totalGames, List<GameListing> availableGames); + + protected abstract byte[] GetConnectionData(); + + protected ClientData FindClientById(int id) + { + if (id < 0) + { + return null; + } + List<ClientData> obj = this.allClients; + ClientData result; + lock (obj) + { + for (int i = 0; i < this.allClients.Count; i++) + { + ClientData clientData = this.allClients[i]; + if (clientData.Id == id) + { + return clientData; + } + } + result = null; + } + return result; + } + + public static string IntToGameName(int gameId) + { + char[] array = new char[] + { + (char)(gameId & 255), + (char)(gameId >> 8 & 255), + (char)(gameId >> 16 & 255), + (char)(gameId >> 24 & 255) + }; + if (array.Any((char c) => c < 'A' || c > 'z')) + { + return null; + } + return new string(array); + } + + public static int GameNameToInt(string gameId) + { + if (gameId.Length != 4) + { + return -1; + } + gameId = gameId.ToUpperInvariant(); + return (int)(gameId[0] | (int)gameId[1] << 8 | (int)gameId[2] << 16 | (int)gameId[3] << 24); + } + + private void FixedUpdate() + { + if (this.mode == MatchMakerModes.None || this.Streams == null) + { + this.timer = 0f; + return; + } + this.timer += Time.fixedDeltaTime; + if (this.timer < this.MinSendInterval) + { + return; + } + this.timer = 0f; + + //c 写入所有场景内包含InnerNetObject派生类的数据 + List<InnerNetObject> obj = this.allObjects; + lock (obj) + { + for (int i = 0; i < this.allObjects.Count; i++) + { + InnerNetObject innerNetObject = this.allObjects[i]; + if (innerNetObject && innerNetObject.DirtyBits != 0U && (innerNetObject.AmOwner || (innerNetObject.OwnerId == -2 && this.AmHost))) + { + MessageWriter messageWriter = this.Streams[(int)innerNetObject.sendMode]; + messageWriter.StartMessage(1); + messageWriter.WritePacked(innerNetObject.NetId); + if (innerNetObject.Serialize(messageWriter, false)) + { + messageWriter.EndMessage(); + } + else + { + messageWriter.CancelMessage(); + } + } + } + } + + for (int j = 0; j < this.Streams.Length; j++) + { + MessageWriter messageWriter2 = this.Streams[j]; + if (messageWriter2.HasBytes(7)) + { + messageWriter2.EndMessage(); + this.SendOrDisconnect(messageWriter2); + messageWriter2.Clear((SendOption)j); + messageWriter2.StartMessage(5); + messageWriter2.Write(this.GameId); + } + } + } + + public T FindObjectByNetId<T>(uint netId) where T : InnerNetObject + { + InnerNetObject innerNetObject; + if (this.allObjectsFast.TryGetValue(netId, out innerNetObject)) + { + return (T)((object)innerNetObject); + } + return default(T); + } + + public void SendRpcImmediately(uint targetNetId, byte callId, SendOption option) + { + MessageWriter messageWriter = MessageWriter.Get(option); + messageWriter.StartMessage(5); + messageWriter.Write(this.GameId); + messageWriter.StartMessage(2); + messageWriter.WritePacked(targetNetId); + messageWriter.Write(callId); + messageWriter.EndMessage(); + messageWriter.EndMessage(); + this.connection.Send(messageWriter); + messageWriter.Recycle(); + } + + public MessageWriter StartRpcImmediately(uint targetNetId, byte callId, SendOption option, int targetClientId = -1) + { + MessageWriter messageWriter = MessageWriter.Get(option); + if (targetClientId < 0) + { + messageWriter.StartMessage(5); + messageWriter.Write(this.GameId); + } + else + { + messageWriter.StartMessage(6); + messageWriter.Write(this.GameId); + messageWriter.WritePacked(targetClientId); + } + messageWriter.StartMessage(2); + messageWriter.WritePacked(targetNetId); + messageWriter.Write(callId); + return messageWriter; + } + + public void FinishRpcImmediately(MessageWriter msg) + { + msg.EndMessage(); + msg.EndMessage(); + this.SendOrDisconnect(msg); + msg.Recycle(); + } + + public void SendRpc(uint targetNetId, byte callId, SendOption option = SendOption.Reliable) + { + this.StartRpc(targetNetId, callId, option).EndMessage(); + } + + public MessageWriter StartRpc(uint targetNetId, byte callId, SendOption option = SendOption.Reliable) + { + MessageWriter messageWriter = this.Streams[(int)option]; + messageWriter.StartMessage(2); + messageWriter.WritePacked(targetNetId); + messageWriter.Write(callId); + return messageWriter; + } + + private void SendSceneChange(string sceneName) + { + this.InOnlineScene = string.Equals(sceneName, "OnlineGame"); + if (!this.AmConnected) + { + return; + } + Debug.Log("Changed To " + sceneName); + base.StartCoroutine(this.CoSendSceneChange(sceneName)); + } + + private IEnumerator CoSendSceneChange(string sceneName) + { + List<InnerNetObject> obj = this.allObjects; + lock (obj) + { + for (int i = this.allObjects.Count - 1; i > -1; i--) + { + if (!this.allObjects[i]) + { + this.allObjects.RemoveAt(i); + } + } + goto IL_BF; + } + IL_A8: + yield return null; + IL_BF: + if (this.AmConnected && this.ClientId < 0) + { + goto IL_A8; + } + if (!this.AmConnected) + { + yield break; + } + if (!this.AmHost && this.connection.State == ConnectionState.Connected) + { + MessageWriter messageWriter = MessageWriter.Get(SendOption.Reliable); + messageWriter.StartMessage(5); + messageWriter.Write(this.GameId); + messageWriter.StartMessage(6); + messageWriter.WritePacked(this.ClientId); + messageWriter.Write(sceneName); + messageWriter.EndMessage(); + messageWriter.EndMessage(); + this.SendOrDisconnect(messageWriter); + messageWriter.Recycle(); + } + ClientData client = this.FindClientById(this.ClientId); + if (client != null) + { + Debug.Log(string.Format("Self changed scene: {0} {1}", this.ClientId, sceneName)); + List<Action> dispatcher = this.Dispatcher; + lock (dispatcher) + { + this.Dispatcher.Add(delegate + { + this.OnPlayerChangedScene(client, sceneName); + }); + yield break; + } + } + Debug.Log(string.Format("Couldn't find self in clients: {0}: ", this.ClientId) + sceneName); + yield break; + } + + public void Spawn(InnerNetObject netObjParent, int ownerId = -2, SpawnFlags flags = SpawnFlags.None) + { + if (this.AmHost) + { + ownerId = ((ownerId == -3) ? this.ClientId : ownerId); + MessageWriter msg = this.Streams[1]; + this.WriteSpawnMessage(netObjParent, ownerId, flags, msg); + return; + } + if (!this.AmClient) + { + return; + } + Debug.LogError("Tried to spawn while not host:" + netObjParent); + } + + private void WriteSpawnMessage(InnerNetObject netObjParent, int ownerId, SpawnFlags flags, MessageWriter msg) + { + msg.StartMessage(4); + msg.WritePacked(netObjParent.SpawnId); + msg.WritePacked(ownerId); + msg.Write((byte)flags); + InnerNetObject[] componentsInChildren = netObjParent.GetComponentsInChildren<InnerNetObject>(); + msg.WritePacked(componentsInChildren.Length); + foreach (InnerNetObject innerNetObject in componentsInChildren) + { + innerNetObject.OwnerId = ownerId; + innerNetObject.SpawnFlags = flags; + if (innerNetObject.NetId == 0U) + { + InnerNetObject innerNetObject2 = innerNetObject; + uint netIdCnt = this.NetIdCnt; + this.NetIdCnt = netIdCnt + 1U; + innerNetObject2.NetId = netIdCnt; + this.allObjects.Add(innerNetObject); + this.allObjectsFast.Add(innerNetObject.NetId, innerNetObject); + } + msg.WritePacked(innerNetObject.NetId); + msg.StartMessage(1); + innerNetObject.Serialize(msg, true); + msg.EndMessage(); + } + msg.EndMessage(); + } + + public void Despawn(InnerNetObject objToDespawn) + { + if (objToDespawn.NetId < 1U) + { + Debug.LogError("Tried to net destroy: " + objToDespawn); + return; + } + MessageWriter messageWriter = this.Streams[1]; + messageWriter.StartMessage(5); + messageWriter.WritePacked(objToDespawn.NetId); + messageWriter.EndMessage(); + this.RemoveNetObject(objToDespawn); + } + + private bool AddNetObject(InnerNetObject obj) + { + uint num = obj.NetId + 1U; + if (num > this.NetIdCnt) + { + this.NetIdCnt = num; + } + if (!this.allObjectsFast.ContainsKey(obj.NetId)) + { + this.allObjects.Add(obj); + this.allObjectsFast.Add(obj.NetId, obj); + return true; + } + return false; + } + + public void RemoveNetObject(InnerNetObject obj) + { + int num = this.allObjects.IndexOf(obj); + if (num > -1) + { + this.allObjects.RemoveAt(num); + } + this.allObjectsFast.Remove(obj.NetId); + obj.NetId = uint.MaxValue; + } + + public void RemoveUnownedObjects() + { + HashSet<int> hashSet = new HashSet<int>(); + hashSet.Add(-2); + List<ClientData> obj = this.allClients; + lock (obj) + { + for (int i = 0; i < this.allClients.Count; i++) + { + ClientData clientData = this.allClients[i]; + if (clientData.Character) + { + hashSet.Add(clientData.Id); + } + } + } + List<InnerNetObject> obj2 = this.allObjects; + lock (obj2) + { + for (int j = this.allObjects.Count - 1; j > -1; j--) + { + InnerNetObject innerNetObject = this.allObjects[j]; + if (!innerNetObject) + { + this.allObjects.RemoveAt(j); + } + else if (!hashSet.Contains(innerNetObject.OwnerId)) + { + innerNetObject.OwnerId = this.ClientId; + UnityEngine.Object.Destroy(innerNetObject.gameObject); + } + } + } + } + + private void HandleGameData(MessageReader parentReader, int cnt = 0) + { + try + { + while (parentReader.Position < parentReader.Length) + { + this.HandleGameDataInner(parentReader.ReadMessage(), cnt); + } + } + finally + { + parentReader.Recycle(); + } + } + + //c 辅助tag别名 + private enum SubTagAlias + { + Normal = 1, // 游戏内的简单数据,比如同步角色位置、动画等 + Rpc = 2, // 远程调用Remote Procedure Call + SpawnCharacter = 4, // 生成角色 + RemoveNetObjectByNetId = 5, // 删除数据 + ChangeScene = 6, // 切换场景 + PlayerReady = 7, // 角色准备好了 + } + + //c 处理收到的数据,用来同步 + //c 这个方法是在主线程调用的 + private void HandleGameDataInner(MessageReader reader, int cnt) + { + switch (reader.Tag) + { + case (int)SubTagAlias.Normal: + { + uint num = reader.ReadPackedUInt32(); + InnerNetObject innerNetObject; + if (this.allObjectsFast.TryGetValue(num, out innerNetObject)) + { + innerNetObject.Deserialize(reader, false); + return; + } + if (!this.DestroyedObjects.Contains(num)) + { + this.DeferMessage(cnt, reader, "Stored data for " + num); + return; + } + return; + } + case (int)SubTagAlias.Rpc: + { + // 根据编号找到对应的同步数据 + uint index = reader.ReadPackedUInt32(); + InnerNetObject innerNetObject2; + if (this.allObjectsFast.TryGetValue(index, out innerNetObject2)) + { + byte callId = reader.ReadByte(); + innerNetObject2.HandleRpc(callId, reader); + return; + } + if (!this.DestroyedObjects.Contains(index)) + { + this.DeferMessage(cnt, reader, "Stored RPC for " + index); + return; + } + return; + } + case (int)SubTagAlias.SpawnCharacter: + { + uint num3 = reader.ReadPackedUInt32(); + if ((ulong)num3 >= (ulong)((long)this.SpawnableObjects.Length)) + { + Debug.LogError("Couldn't find spawnable prefab: " + num3); + return; + } + int num4 = reader.ReadPackedInt32(); + ClientData clientData = this.FindClientById(num4); + if (num4 > 0 && clientData == null) + { + this.DeferMessage(cnt, reader, "Delay spawn for unowned " + num3); + return; + } + // 创建角色对象并设置参数 + InnerNetObject innerNetObject3 = UnityEngine.Object.Instantiate<InnerNetObject>(this.SpawnableObjects[(int)num3]); + innerNetObject3.SpawnFlags = (SpawnFlags)reader.ReadByte(); + if ((innerNetObject3.SpawnFlags & SpawnFlags.IsClientCharacter) != SpawnFlags.None) + { + if (!clientData.Character) + { + clientData.InScene = true; + clientData.Character = (innerNetObject3 as PlayerControl); + } + else if (innerNetObject3) + { + Debug.LogWarning(string.Format("Double spawn character: {0} already has {1}", clientData.Id, clientData.Character.NetId)); + UnityEngine.Object.Destroy(innerNetObject3.gameObject); + return; + } + } + int num5 = reader.ReadPackedInt32(); + InnerNetObject[] componentsInChildren = innerNetObject3.GetComponentsInChildren<InnerNetObject>(); + if (num5 != componentsInChildren.Length) + { + Debug.LogError("Children didn't match for spawnable " + num3); + UnityEngine.Object.Destroy(innerNetObject3.gameObject); + return; + } + for (int i = 0; i < num5; i++) + { + InnerNetObject innerNetObject4 = componentsInChildren[i]; + innerNetObject4.NetId = reader.ReadPackedUInt32(); + innerNetObject4.OwnerId = num4; + if (this.DestroyedObjects.Contains(innerNetObject4.NetId)) + { + innerNetObject3.NetId = uint.MaxValue; + UnityEngine.Object.Destroy(innerNetObject3.gameObject); + return; + } + if (!this.AddNetObject(innerNetObject4)) + { + innerNetObject3.NetId = uint.MaxValue; + UnityEngine.Object.Destroy(innerNetObject3.gameObject); + return; + } + MessageReader messageReader = reader.ReadMessage(); + if (messageReader.Length > 0) + { + innerNetObject4.Deserialize(messageReader, true); + } + } + return; + } + case (int)SubTagAlias.RemoveNetObjectByNetId: + { + uint netId = reader.ReadPackedUInt32(); + this.DestroyedObjects.Add(netId); + InnerNetObject innerNetObject5 = this.FindObjectByNetId<InnerNetObject>(netId); + if (innerNetObject5) + { + this.RemoveNetObject(innerNetObject5); + UnityEngine.Object.Destroy(innerNetObject5.gameObject); + return; + } + return; + } + case (int)SubTagAlias.ChangeScene: + { + int id = reader.ReadPackedInt32(); + ClientData client = this.FindClientById(id); // 找到对应的玩家 + string targetScene = reader.ReadString(); + if (client != null && !string.IsNullOrWhiteSpace(targetScene)) + { + Debug.Log(string.Format("Client {0} changed scene to {1}", client.Id, targetScene)); + List<Action> dispatcher = this.Dispatcher; + lock (dispatcher) + { + this.Dispatcher.Add(delegate + { + // 切换场景 + this.OnPlayerChangedScene(client, targetScene); + }); + return; + } + } + Debug.Log(string.Format("Couldn't find client {0} to change scene to {1}", id, targetScene)); + return; + } + case (int)SubTagAlias.PlayerReady: + { + ClientData clientData2 = this.FindClientById(reader.ReadPackedInt32()); + if (clientData2 != null) + { + Debug.Log(string.Format("Client {0} ready", clientData2.Id)); + clientData2.IsReady = true; + return; + } + return; + } + } + + Debug.Log(string.Format("Bad tag {0} at {1}+{2}={3}: ", new object[] + { + reader.Tag, + reader.Offset, + reader.Position, + reader.Length + }) + string.Join<byte>(" ", reader.Buffer)); + } + + private void DeferMessage(int cnt, MessageReader reader, string logMsg) + { + if (cnt > 10) + { + Debug.Log("Giving up on: " + logMsg); + return; + } + int cnt2 = cnt; + cnt = cnt2 + 1; + Debug.Log(logMsg); + MessageReader copy = MessageReader.CopyMessageIntoParent(reader); + List<Action> preSpawnDispatcher = this.PreSpawnDispatcher; + lock (preSpawnDispatcher) + { + this.PreSpawnDispatcher.Add(delegate + { + this.HandleGameData(copy, cnt); + }); + } + } + } +} diff --git a/Client/Assembly-CSharp/InnerNet/InnerNetObject.cs b/Client/Assembly-CSharp/InnerNet/InnerNetObject.cs new file mode 100644 index 0000000..0fdcf2d --- /dev/null +++ b/Client/Assembly-CSharp/InnerNet/InnerNetObject.cs @@ -0,0 +1,74 @@ +using System; +using Hazel; +using UnityEngine; + +namespace InnerNet +{ + public abstract class InnerNetObject : MonoBehaviour, IComparable<InnerNetObject> + { + public bool AmOwner + { + get + { + return this.OwnerId == AmongUsClient.Instance.ClientId; + } + } + + public uint SpawnId; + + public uint NetId; + + public uint DirtyBits; + + public SpawnFlags SpawnFlags; + + public SendOption sendMode = SendOption.Reliable; + + public int OwnerId; + + protected bool DespawnOnDestroy = true; + + public void Despawn() + { + UnityEngine.Object.Destroy(base.gameObject); + AmongUsClient.Instance.Despawn(this); + } + + public virtual void OnDestroy() + { + if (AmongUsClient.Instance && this.NetId != 4294967295U) + { + if (this.DespawnOnDestroy && this.AmOwner) + { + AmongUsClient.Instance.Despawn(this); + return; + } + AmongUsClient.Instance.RemoveNetObject(this); + } + } + + public abstract void HandleRpc(byte callId, MessageReader reader); + + public abstract bool Serialize(MessageWriter writer, bool initialState); + + public abstract void Deserialize(MessageReader reader, bool initialState); + + public int CompareTo(InnerNetObject other) + { + if (this.NetId > other.NetId) + { + return 1; + } + if (this.NetId < other.NetId) + { + return -1; + } + return 0; + } + + protected void SetDirtyBit(uint val) + { + this.DirtyBits |= val; + } + } +} diff --git a/Client/Assembly-CSharp/InnerNet/InnerNetServer.cs b/Client/Assembly-CSharp/InnerNet/InnerNetServer.cs new file mode 100644 index 0000000..3705318 --- /dev/null +++ b/Client/Assembly-CSharp/InnerNet/InnerNetServer.cs @@ -0,0 +1,592 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Net; +using System.Threading; +using Hazel; +using Hazel.Udp; +using UnityEngine; + +namespace InnerNet +{ + public class InnerNetServer : DestroyableSingleton<InnerNetServer> + { + public const int MaxPlayers = 10; + + public bool Running; + + public const int LocalGameId = 32; + + private const int InvalidHost = -1; + + private int HostId = -1; + + public HashSet<string> ipBans = new HashSet<string>(); + + public int Port = 22023; + + [SerializeField] + private GameStates GameState; + + private NetworkConnectionListener listener; + + private List<InnerNetServer.Player> Clients = new List<InnerNetServer.Player>(); + + protected class Player + { + private static int IdCount = 1; + + public int Id; + + public Connection Connection; + + public LimboStates LimboState; + + public Player(Connection connection) + { + this.Id = Interlocked.Increment(ref InnerNetServer.Player.IdCount); + this.Connection = connection; + } + } + + public override void OnDestroy() + { + this.StopServer(); + base.OnDestroy(); + } + + public void StartAsServer() + { + if (this.listener != null) + { + this.StopServer(); + } + this.GameState = GameStates.NotStarted; + this.listener = new UdpConnectionListener(new IPEndPoint(IPAddress.Any, this.Port), IPMode.IPv4, null); + this.listener.NewConnection += this.OnServerConnect; + this.listener.Start(); + this.Running = true; + } + + public void StopServer() + { + this.HostId = -1; + this.Running = false; + this.GameState = GameStates.Destroyed; + if (this.listener != null) + { + this.listener.Close(); + this.listener.Dispose(); + this.listener = null; + } + List<InnerNetServer.Player> clients = this.Clients; + lock (clients) + { + this.Clients.Clear(); + } + } + + public static bool IsCompatibleVersion(int version) + { + return Constants.CompatVersions.Contains(version); + } + + private void OnServerConnect(NewConnectionEventArgs evt) + { + MessageReader handshakeData = evt.HandshakeData; + try + { + if (evt.HandshakeData.Length < 5) + { + InnerNetServer.SendIncorrectVersion(evt.Connection); + return; + } + if (!InnerNetServer.IsCompatibleVersion(handshakeData.ReadInt32())) + { + InnerNetServer.SendIncorrectVersion(evt.Connection); + return; + } + } + finally + { + handshakeData.Recycle(); + } + InnerNetServer.Player client = new InnerNetServer.Player(evt.Connection); + Debug.Log(string.Format("Client {0} added: {1}", client.Id, evt.Connection.EndPoint)); + UdpConnection udpConnection = (UdpConnection)evt.Connection; + udpConnection.KeepAliveInterval = 1500; + udpConnection.DisconnectTimeout = 6000; + udpConnection.ResendPingMultiplier = 1.5f; + udpConnection.DataReceived += delegate(DataReceivedEventArgs e) + { + this.OnDataReceived(client, e); + }; + udpConnection.Disconnected += delegate(object o, DisconnectedEventArgs e) + { + this.ClientDisconnect(client); + }; + } + + private static void SendIncorrectVersion(Connection connection) + { + MessageWriter messageWriter = MessageWriter.Get(SendOption.Reliable); + messageWriter.StartMessage(1); + messageWriter.Write(5); + messageWriter.EndMessage(); + connection.Send(messageWriter); + messageWriter.Recycle(); + } + + private void Connection_DataSentRaw(byte[] data, int length) + { + Debug.Log("Server Sent: " + string.Join(" ", (from b in data + select b.ToString()).ToArray<string>(), 0, length)); + } + + private void OnDataReceived(InnerNetServer.Player client, DataReceivedEventArgs evt) + { + MessageReader message = evt.Message; + if (message.Length <= 0) + { + Debug.Log("Server got 0 bytes"); + message.Recycle(); + return; + } + try + { + while (message.Position < message.Length) + { + this.HandleMessage(client, message.ReadMessage(), evt.SendOption); + } + } + catch (Exception arg) + { + Debug.Log(string.Format("{0}\r\n{1}", string.Join<byte>(" ", message.Buffer), arg)); + } + finally + { + message.Recycle(); + } + } + + private void HandleMessage(InnerNetServer.Player client, MessageReader reader, SendOption sendOption) + { + switch (reader.Tag) + { + case 0: + { + Debug.Log("Server got host game"); + MessageWriter messageWriter = MessageWriter.Get(SendOption.Reliable); + messageWriter.StartMessage(0); + messageWriter.Write(32); + messageWriter.EndMessage(); + client.Connection.Send(messageWriter); + messageWriter.Recycle(); + return; + } + case 1: + { + Debug.Log("Server got join game"); + if (reader.ReadInt32() == 32) + { + this.JoinGame(client); + return; + } + MessageWriter messageWriter2 = MessageWriter.Get(SendOption.Reliable); + messageWriter2.StartMessage(1); + messageWriter2.Write(3); + messageWriter2.EndMessage(); + client.Connection.Send(messageWriter2); + messageWriter2.Recycle(); + return; + } + case 2: + if (reader.ReadInt32() == 32) + { + this.StartGame(reader, client); + return; + } + break; + case 3: + if (reader.ReadInt32() == 32) + { + this.ClientDisconnect(client); + return; + } + break; + case 4: + case 7: + case 9: + case 10: + break; + case 5: + if (this.Clients.Contains(client)) + { + if (reader.ReadInt32() == 32) + { + MessageWriter messageWriter3 = MessageWriter.Get(sendOption); + messageWriter3.CopyFrom(reader); + this.Broadcast(messageWriter3, client); + messageWriter3.Recycle(); + return; + } + } + else if (this.GameState == GameStates.Started) + { + client.Connection.Dispose(); + return; + } + break; + case 6: + if (this.Clients.Contains(client)) + { + if (reader.ReadInt32() == 32) + { + int targetId = reader.ReadPackedInt32(); + MessageWriter messageWriter4 = MessageWriter.Get(sendOption); + messageWriter4.CopyFrom(reader); + this.SendTo(messageWriter4, targetId); + messageWriter4.Recycle(); + return; + } + } + else if (this.GameState == GameStates.Started) + { + Debug.Log("GameDataTo: Server didn't have client"); + client.Connection.Dispose(); + return; + } + break; + case 8: + if (reader.ReadInt32() == 32) + { + this.EndGame(reader, client); + return; + } + break; + case 11: + if (reader.ReadInt32() == 32) + { + this.KickPlayer(reader.ReadPackedInt32(), reader.ReadBoolean()); + } + break; + default: + return; + } + } + + private void KickPlayer(int targetId, bool ban) + { + List<InnerNetServer.Player> clients = this.Clients; + lock (clients) + { + InnerNetServer.Player player = null; + for (int i = 0; i < this.Clients.Count; i++) + { + if (this.Clients[i].Id == targetId) + { + player = this.Clients[i]; + break; + } + } + if (player != null) + { + if (ban) + { + HashSet<string> obj = this.ipBans; + lock (obj) + { + IPEndPoint endPoint = player.Connection.EndPoint; + this.ipBans.Add(endPoint.Address.ToString()); + } + } + MessageWriter messageWriter = MessageWriter.Get(SendOption.Reliable); + messageWriter.StartMessage(11); + messageWriter.Write(32); + messageWriter.WritePacked(targetId); + messageWriter.Write(ban); + messageWriter.EndMessage(); + this.Broadcast(messageWriter, null); + messageWriter.Recycle(); + } + } + } + + protected void JoinGame(InnerNetServer.Player client) + { + HashSet<string> obj = this.ipBans; + lock (obj) + { + IPEndPoint endPoint = client.Connection.EndPoint; + if (this.ipBans.Contains(endPoint.Address.ToString())) + { + MessageWriter messageWriter = MessageWriter.Get(SendOption.Reliable); + messageWriter.StartMessage(1); + messageWriter.Write(6); + messageWriter.EndMessage(); + client.Connection.Send(messageWriter); + messageWriter.Recycle(); + return; + } + } + List<InnerNetServer.Player> clients = this.Clients; + lock (clients) + { + switch (this.GameState) + { + case GameStates.NotStarted: + this.HandleNewGameJoin(client); + break; + default: + { + MessageWriter messageWriter2 = MessageWriter.Get(SendOption.Reliable); + messageWriter2.StartMessage(1); + messageWriter2.Write(2); + messageWriter2.EndMessage(); + client.Connection.Send(messageWriter2); + messageWriter2.Recycle(); + break; + } + case GameStates.Ended: + this.HandleRejoin(client); + break; + } + } + } + + private void HandleRejoin(InnerNetServer.Player client) + { + if (client.Id == this.HostId) + { + this.GameState = GameStates.NotStarted; + this.HandleNewGameJoin(client); + MessageWriter messageWriter = MessageWriter.Get(SendOption.Reliable); + for (int i = 0; i < this.Clients.Count; i++) + { + InnerNetServer.Player player = this.Clients[i]; + if (player != client) + { + try + { + this.WriteJoinedMessage(player, messageWriter, true); + player.Connection.Send(messageWriter); + } + catch + { + } + } + } + messageWriter.Recycle(); + return; + } + if (this.Clients.Count >= 9) + { + MessageWriter messageWriter2 = MessageWriter.Get(SendOption.Reliable); + messageWriter2.StartMessage(1); + messageWriter2.Write(1); + messageWriter2.EndMessage(); + client.Connection.Send(messageWriter2); + messageWriter2.Recycle(); + return; + } + this.Clients.Add(client); + client.LimboState = LimboStates.WaitingForHost; + MessageWriter messageWriter3 = MessageWriter.Get(SendOption.Reliable); + try + { + messageWriter3.StartMessage(12); + messageWriter3.Write(32); + messageWriter3.Write(client.Id); + messageWriter3.EndMessage(); + client.Connection.Send(messageWriter3); + this.BroadcastJoinMessage(client, messageWriter3); + } + catch + { + } + finally + { + messageWriter3.Recycle(); + } + } + + private void HandleNewGameJoin(InnerNetServer.Player client) + { + if (this.Clients.Count >= 10) + { + MessageWriter messageWriter = MessageWriter.Get(SendOption.Reliable); + try + { + messageWriter.StartMessage(1); + messageWriter.Write(1); + messageWriter.EndMessage(); + client.Connection.Send(messageWriter); + } + catch + { + } + finally + { + messageWriter.Recycle(); + } + return; + } + this.Clients.Add(client); + client.LimboState = LimboStates.PreSpawn; + if (this.HostId == -1) + { + this.HostId = this.Clients[0].Id; + } + if (this.HostId == client.Id) + { + client.LimboState = LimboStates.NotLimbo; + } + MessageWriter messageWriter2 = MessageWriter.Get(SendOption.Reliable); + try + { + this.WriteJoinedMessage(client, messageWriter2, true); + client.Connection.Send(messageWriter2); + this.BroadcastJoinMessage(client, messageWriter2); + } + catch + { + } + finally + { + messageWriter2.Recycle(); + } + } + + private void EndGame(MessageReader message, InnerNetServer.Player source) + { + if (source.Id == this.HostId) + { + this.GameState = GameStates.Ended; + MessageWriter messageWriter = MessageWriter.Get(SendOption.Reliable); + messageWriter.CopyFrom(message); + this.Broadcast(messageWriter, null); + messageWriter.Recycle(); + List<InnerNetServer.Player> clients = this.Clients; + lock (clients) + { + this.Clients.Clear(); + return; + } + } + Debug.LogWarning("Reset request rejected from: " + source.Id); + } + + private void StartGame(MessageReader message, InnerNetServer.Player source) + { + this.GameState = GameStates.Started; + MessageWriter messageWriter = MessageWriter.Get(SendOption.Reliable); + messageWriter.CopyFrom(message); + this.Broadcast(messageWriter, null); + messageWriter.Recycle(); + } + + private void ClientDisconnect(InnerNetServer.Player client) + { + Debug.Log("Server DC client " + client.Id); + List<InnerNetServer.Player> clients = this.Clients; + lock (clients) + { + this.Clients.Remove(client); + client.Connection.Dispose(); + if (this.Clients.Count > 0) + { + this.HostId = this.Clients[0].Id; + } + } + MessageWriter messageWriter = MessageWriter.Get(SendOption.Reliable); + messageWriter.StartMessage(4); + messageWriter.Write(32); + messageWriter.Write(client.Id); + messageWriter.Write(this.HostId); + messageWriter.Write(0); + messageWriter.EndMessage(); + this.Broadcast(messageWriter, null); + messageWriter.Recycle(); + } + + protected void SendTo(MessageWriter msg, int targetId) + { + List<InnerNetServer.Player> clients = this.Clients; + lock (clients) + { + for (int i = 0; i < this.Clients.Count; i++) + { + InnerNetServer.Player player = this.Clients[i]; + if (player.Id == targetId) + { + try + { + player.Connection.Send(msg); + break; + } + catch (Exception exception) + { + Debug.LogException(exception); + break; + } + } + } + } + } + + protected void Broadcast(MessageWriter msg, InnerNetServer.Player source) + { + List<InnerNetServer.Player> clients = this.Clients; + lock (clients) + { + for (int i = 0; i < this.Clients.Count; i++) + { + InnerNetServer.Player player = this.Clients[i]; + if (player != source) + { + try + { + player.Connection.Send(msg); + } + catch + { + } + } + } + } + } + + private void BroadcastJoinMessage(InnerNetServer.Player client, MessageWriter msg) + { + msg.Clear(SendOption.Reliable); + msg.StartMessage(1); + msg.Write(32); + msg.Write(client.Id); + msg.Write(this.HostId); + msg.EndMessage(); + this.Broadcast(msg, client); + } + + private void WriteJoinedMessage(InnerNetServer.Player client, MessageWriter msg, bool clear) + { + if (clear) + { + msg.Clear(SendOption.Reliable); + } + msg.StartMessage(7); + msg.Write(32); + msg.Write(client.Id); + msg.Write(this.HostId); + msg.WritePacked(this.Clients.Count - 1); + for (int i = 0; i < this.Clients.Count; i++) + { + InnerNetServer.Player player = this.Clients[i]; + if (player != client) + { + msg.WritePacked(player.Id); + } + } + msg.EndMessage(); + } + } +} diff --git a/Client/Assembly-CSharp/InnerNet/JoinFailureReasons.cs b/Client/Assembly-CSharp/InnerNet/JoinFailureReasons.cs new file mode 100644 index 0000000..6e5bf37 --- /dev/null +++ b/Client/Assembly-CSharp/InnerNet/JoinFailureReasons.cs @@ -0,0 +1,15 @@ +using System; + +namespace InnerNet +{ + public enum JoinFailureReasons : byte + { + TooManyPlayers = 1, + GameStarted, + GameNotFound, + HostNotReady, + IncorrectVersion, + Banned, + Kicked + } +} diff --git a/Client/Assembly-CSharp/InnerNet/LimboStates.cs b/Client/Assembly-CSharp/InnerNet/LimboStates.cs new file mode 100644 index 0000000..80446bb --- /dev/null +++ b/Client/Assembly-CSharp/InnerNet/LimboStates.cs @@ -0,0 +1,11 @@ +using System; + +namespace InnerNet +{ + public enum LimboStates + { + PreSpawn, + NotLimbo, + WaitingForHost + } +} diff --git a/Client/Assembly-CSharp/InnerNet/MatchMakerModes.cs b/Client/Assembly-CSharp/InnerNet/MatchMakerModes.cs new file mode 100644 index 0000000..64604a4 --- /dev/null +++ b/Client/Assembly-CSharp/InnerNet/MatchMakerModes.cs @@ -0,0 +1,11 @@ +using System; + +namespace InnerNet +{ + public enum MatchMakerModes + { + None, + Client, + HostAndClient + } +} diff --git a/Client/Assembly-CSharp/InnerNet/MessageExtensions.cs b/Client/Assembly-CSharp/InnerNet/MessageExtensions.cs new file mode 100644 index 0000000..9e9bd49 --- /dev/null +++ b/Client/Assembly-CSharp/InnerNet/MessageExtensions.cs @@ -0,0 +1,24 @@ +using System; +using Hazel; + +namespace InnerNet +{ + public static class MessageExtensions + { + public static void WriteNetObject(this MessageWriter self, InnerNetObject obj) + { + if (!obj) + { + self.Write(0); + return; + } + self.WritePacked(obj.NetId); + } + + public static T ReadNetObject<T>(this MessageReader self) where T : InnerNetObject + { + uint netId = self.ReadPackedUInt32(); + return AmongUsClient.Instance.FindObjectByNetId<T>(netId); + } + } +} diff --git a/Client/Assembly-CSharp/InnerNet/SpawnFlags.cs b/Client/Assembly-CSharp/InnerNet/SpawnFlags.cs new file mode 100644 index 0000000..644e4e9 --- /dev/null +++ b/Client/Assembly-CSharp/InnerNet/SpawnFlags.cs @@ -0,0 +1,11 @@ +using System; + +namespace InnerNet +{ + [Flags] + public enum SpawnFlags : byte + { + None = 0, + IsClientCharacter = 1 + } +} diff --git a/Client/Assembly-CSharp/InnerNet/Tags.cs b/Client/Assembly-CSharp/InnerNet/Tags.cs new file mode 100644 index 0000000..aa48fc3 --- /dev/null +++ b/Client/Assembly-CSharp/InnerNet/Tags.cs @@ -0,0 +1,35 @@ +using System; + +namespace InnerNet +{ + public static class Tags + { + public const byte HostGame = 0; + + public const byte JoinGame = 1; + + public const byte StartGame = 2; + + public const byte RemoveGame = 3; + + public const byte RemovePlayer = 4; + + public const byte GameData = 5; + + public const byte GameDataTo = 6; + + public const byte JoinedGame = 7; + + public const byte EndGame = 8; + + public const byte GetGameList = 9; + + public const byte AlterGame = 10; + + public const byte KickPlayer = 11; + + public const byte WaitForHost = 12; + + public const byte Redirect = 13; + } +} diff --git a/Client/Assembly-CSharp/IntRange.cs b/Client/Assembly-CSharp/IntRange.cs new file mode 100644 index 0000000..1989b3b --- /dev/null +++ b/Client/Assembly-CSharp/IntRange.cs @@ -0,0 +1,71 @@ +using System; +using UnityEngine; + +[Serializable] +public class IntRange +{ + public int min; + + public int max; + + public IntRange() + { + } + + public IntRange(int min, int max) + { + this.min = min; + this.max = max; + } + + public int Next() + { + return UnityEngine.Random.Range(this.min, this.max); + } + + public bool Contains(int value) + { + return this.min <= value && this.max >= value; + } + + public static int Next(int max) + { + return (int)(UnityEngine.Random.value * (float)max); + } + + internal static int Next(int min, int max) + { + return UnityEngine.Random.Range(min, max); + } + + internal static byte NextByte(byte max) + { + return (byte)UnityEngine.Random.Range(0, (int)max); + } + + public static void FillRandom(sbyte min, sbyte max, sbyte[] array) + { + for (int i = 0; i < array.Length; i++) + { + array[i] = (sbyte)IntRange.Next((int)min, (int)max); + } + } + + public static int RandomSign() + { + if (!BoolRange.Next(0.5f)) + { + return -1; + } + return 1; + } + + public static void FillRandomRange(sbyte[] array) + { + for (int i = 0; i < array.Length; i++) + { + array[i] = (sbyte)i; + } + array.Shuffle<sbyte>(); + } +} diff --git a/Client/Assembly-CSharp/IntroCutscene.cs b/Client/Assembly-CSharp/IntroCutscene.cs new file mode 100644 index 0000000..3271c11 --- /dev/null +++ b/Client/Assembly-CSharp/IntroCutscene.cs @@ -0,0 +1,155 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using UnityEngine; + +public class IntroCutscene : MonoBehaviour +{ + public static IntroCutscene Instance; + + public TextRenderer Title; + + public TextRenderer ImpostorText; + + public PoolablePlayer PlayerPrefab; + + public MeshRenderer BackgroundBar; + + public MeshRenderer Foreground; + + public FloatRange ForegroundRadius; + + public SpriteRenderer FrontMost; + + public AudioClip IntroStinger; + + public float BaseY = -0.25f; + + public IEnumerator CoBegin(List<PlayerControl> yourTeam, bool isImpostor) + { + SoundManager.Instance.PlaySound(this.IntroStinger, false, 1f); + if (!isImpostor) + { + this.BeginCrewmate(yourTeam); + } + else + { + this.BeginImpostor(yourTeam); + } + Color c = this.Title.Color; + Color fade = Color.black; + Color impColor = Color.white; + Vector3 titlePos = this.Title.transform.localPosition; + float timer = 0f; + while (timer < 3f) + { + timer += Time.deltaTime; + float num = Mathf.Min(1f, timer / 3f); + this.Foreground.material.SetFloat("_Rad", this.ForegroundRadius.ExpOutLerp(num * 2f)); + fade.a = Mathf.Lerp(1f, 0f, num * 3f); + this.FrontMost.color = fade; + c.a = Mathf.Clamp(FloatRange.ExpOutLerp(num, 0f, 1f), 0f, 1f); + this.Title.Color = c; + impColor.a = Mathf.Lerp(0f, 1f, (num - 0.3f) * 3f); + this.ImpostorText.Color = impColor; + titlePos.y = 2.7f - num * 0.3f; + this.Title.transform.localPosition = titlePos; + yield return null; + } + timer = 0f; + while (timer < 1f) + { + timer += Time.deltaTime; + float num2 = timer / 1f; + fade.a = Mathf.Lerp(0f, 1f, num2 * 3f); + this.FrontMost.color = fade; + yield return null; + } + UnityEngine.Object.Destroy(base.gameObject); + yield break; + } + + private void BeginCrewmate(List<PlayerControl> yourTeam) + { + Vector3 position = this.BackgroundBar.transform.position; + position.y -= 0.25f; + this.BackgroundBar.transform.position = position; + int adjustedNumImpostors = PlayerControl.GameOptions.GetAdjustedNumImpostors(GameData.Instance.PlayerCount); + if (adjustedNumImpostors == 1) + { + this.ImpostorText.Text = DestroyableSingleton<TranslationController>.Instance.GetString(StringNames.NumImpostorsS, Array.Empty<object>()); + } + else + { + this.ImpostorText.Text = DestroyableSingleton<TranslationController>.Instance.GetString(StringNames.NumImpostorsP, new object[] + { + adjustedNumImpostors + }); + } + this.BackgroundBar.material.SetColor("_Color", Palette.CrewmateBlue); + this.Title.Text = DestroyableSingleton<TranslationController>.Instance.GetString(StringNames.Crewmate, Array.Empty<object>()); + this.Title.Color = Palette.CrewmateBlue; + for (int i = 0; i < yourTeam.Count; i++) + { + PlayerControl playerControl = yourTeam[i]; + if (playerControl) + { + GameData.PlayerInfo data = playerControl.Data; + if (data != null) + { + int num = (i % 2 == 0) ? -1 : 1; + int num2 = (i + 1) / 2; + float num3 = ((i == 0) ? 1.2f : 1f) - (float)num2 * 0.12f; + float num4 = 1f - (float)num2 * 0.08f; + float num5 = (float)((i == 0) ? -8 : -1); + PoolablePlayer poolablePlayer = UnityEngine.Object.Instantiate<PoolablePlayer>(this.PlayerPrefab, base.transform); + poolablePlayer.name = data.PlayerName + "Dummy"; + poolablePlayer.SetFlipX(i % 2 == 0); + poolablePlayer.transform.localPosition = new Vector3(0.8f * (float)num * (float)num2 * num4, this.BaseY - 0.25f + (float)num2 * 0.1f, num5 + (float)num2 * 0.01f) * 1.5f; + Vector3 localScale = new Vector3(num3, num3, num3) * 1.5f; + poolablePlayer.transform.localScale = localScale; + PlayerControl.SetPlayerMaterialColors((int)data.ColorId, poolablePlayer.Body); + DestroyableSingleton<HatManager>.Instance.SetSkin(poolablePlayer.SkinSlot, data.SkinId); + PlayerControl.SetHatImage(data.HatId, poolablePlayer.HatSlot); + PlayerControl.SetPetImage(data.PetId, (int)data.ColorId, poolablePlayer.PetSlot); + poolablePlayer.NameText.gameObject.SetActive(false); + } + } + } + } + + private void BeginImpostor(List<PlayerControl> yourTeam) + { + this.ImpostorText.gameObject.SetActive(false); + this.Title.Text = DestroyableSingleton<TranslationController>.Instance.GetString(StringNames.Impostor, Array.Empty<object>()); + this.Title.Color = Palette.ImpostorRed; + for (int i = 0; i < yourTeam.Count; i++) + { + PlayerControl playerControl = yourTeam[i]; + if (playerControl) + { + GameData.PlayerInfo data = playerControl.Data; + if (data != null) + { + int num = (i % 2 == 0) ? -1 : 1; + int num2 = (i + 1) / 2; + float num3 = 1f - (float)num2 * 0.075f; + float num4 = 1f - (float)num2 * 0.035f; + float num5 = (float)((i == 0) ? -8 : -1); + PoolablePlayer poolablePlayer = UnityEngine.Object.Instantiate<PoolablePlayer>(this.PlayerPrefab, base.transform); + poolablePlayer.transform.localPosition = new Vector3((float)(num * num2) * num4, this.BaseY + (float)num2 * 0.15f, num5 + (float)num2 * 0.01f) * 1.5f; + Vector3 vector = new Vector3(num3, num3, num3) * 1.5f; + poolablePlayer.transform.localScale = vector; + poolablePlayer.SetFlipX(i % 2 == 1); + PlayerControl.SetPlayerMaterialColors((int)data.ColorId, poolablePlayer.Body); + DestroyableSingleton<HatManager>.Instance.SetSkin(poolablePlayer.SkinSlot, data.SkinId); + PlayerControl.SetHatImage(data.HatId, poolablePlayer.HatSlot); + PlayerControl.SetPetImage(data.PetId, (int)data.ColorId, poolablePlayer.PetSlot); + TextRenderer nameText = poolablePlayer.NameText; + nameText.Text = data.PlayerName; + nameText.transform.localScale = vector.Inv(); + } + } + } + } +} diff --git a/Client/Assembly-CSharp/JoinGameButton.cs b/Client/Assembly-CSharp/JoinGameButton.cs new file mode 100644 index 0000000..f9cea88 --- /dev/null +++ b/Client/Assembly-CSharp/JoinGameButton.cs @@ -0,0 +1,119 @@ +using System; +using System.Collections; +using InnerNet; +using PowerTools; +using UnityEngine; + +public class JoinGameButton : MonoBehaviour, IConnectButton +{ + public AudioClip IntroMusic; + + public TextBox GameIdText; + + public TextRenderer gameNameText; + + public float timeRecieved; + + public SpriteRenderer FillScreen; + + public SpriteAnim connectIcon; + + public AnimationClip connectClip; + + public GameModes GameMode; + + public string netAddress; + + public void OnClick() + { + if (string.IsNullOrWhiteSpace(this.netAddress)) + { + return; + } + if (NameTextBehaviour.Instance.ShakeIfInvalid()) + { + return; + } + if (StatsManager.Instance.AmBanned) + { + AmongUsClient.Instance.LastDisconnectReason = DisconnectReasons.IntentionalLeaving; + DestroyableSingleton<DisconnectPopup>.Instance.Show(); + return; + } + if (!DestroyableSingleton<MatchMaker>.Instance.Connecting(this)) + { + return; + } + AmongUsClient.Instance.GameMode = this.GameMode; + if (this.GameMode == GameModes.OnlineGame) + { + AmongUsClient.Instance.SetEndpoint(DestroyableSingleton<ServerManager>.Instance.OnlineNetAddress, 22023); + AmongUsClient.Instance.MainMenuScene = "MMOnline"; + int num = InnerNetClient.GameNameToInt(this.GameIdText.text); + if (num == -1) + { + base.StartCoroutine(Effects.Shake(this.GameIdText.transform, 0.75f, 0.25f)); + DestroyableSingleton<MatchMaker>.Instance.NotConnecting(); + return; + } + AmongUsClient.Instance.GameId = num; + } + else + { + AmongUsClient.Instance.SetEndpoint(this.netAddress, 22023); + AmongUsClient.Instance.GameId = 32; + AmongUsClient.Instance.GameMode = GameModes.LocalGame; + AmongUsClient.Instance.MainMenuScene = "MatchMaking"; + } + base.StartCoroutine(this.JoinGame()); + } + + private IEnumerator JoinGame() + { + if (this.FillScreen) + { + SoundManager.Instance.CrossFadeSound("MainBG", null, 0.5f, 1.5f); + this.FillScreen.gameObject.SetActive(true); + for (float time = 0f; time < 0.25f; time += Time.deltaTime) + { + this.FillScreen.color = Color.Lerp(Color.clear, Color.black, time / 0.25f); + yield return null; + } + this.FillScreen.color = Color.black; + } + AmongUsClient.Instance.OnlineScene = "OnlineGame"; + AmongUsClient.Instance.Connect(MatchMakerModes.Client); + yield return AmongUsClient.Instance.WaitForConnectionOrFail(); + if (AmongUsClient.Instance.mode == MatchMakerModes.None) + { + if (this.FillScreen) + { + SoundManager.Instance.CrossFadeSound("MainBG", this.IntroMusic, 0.5f, 1.5f); + for (float time = 0f; time < 0.25f; time += Time.deltaTime) + { + this.FillScreen.color = Color.Lerp(Color.black, Color.clear, time / 0.25f); + yield return null; + } + this.FillScreen.color = Color.clear; + } + DestroyableSingleton<MatchMaker>.Instance.NotConnecting(); + } + yield break; + } + + public void SetGameName(string[] gameNameParts) + { + this.gameNameText.Text = gameNameParts[0] + " (" + gameNameParts[2] + "/10)"; + } + + public void StartIcon() + { + this.connectIcon.Play(this.connectClip, 1f); + } + + public void StopIcon() + { + this.connectIcon.Stop(); + this.connectIcon.GetComponent<SpriteRenderer>().sprite = null; + } +} diff --git a/Client/Assembly-CSharp/KerningPair.cs b/Client/Assembly-CSharp/KerningPair.cs new file mode 100644 index 0000000..a264649 --- /dev/null +++ b/Client/Assembly-CSharp/KerningPair.cs @@ -0,0 +1,11 @@ +using System; + +[Serializable] +public class KerningPair +{ + public char First; + + public char Second; + + public int Pixels = 4; +} diff --git a/Client/Assembly-CSharp/KeyboardJoystick.cs b/Client/Assembly-CSharp/KeyboardJoystick.cs new file mode 100644 index 0000000..848eff3 --- /dev/null +++ b/Client/Assembly-CSharp/KeyboardJoystick.cs @@ -0,0 +1,79 @@ +using System; +using UnityEngine; + +public class KeyboardJoystick : MonoBehaviour, IVirtualJoystick +{ + public Vector2 Delta + { + get + { + return this.del; + } + } + + private Vector2 del; + + private void Update() + { + if (!PlayerControl.LocalPlayer) + { + return; + } + this.del.x = (this.del.y = 0f); + if (Input.GetKey(KeyCode.RightArrow) || Input.GetKey(KeyCode.D)) + { + this.del.x = this.del.x + 1f; + } + if (Input.GetKey(KeyCode.LeftArrow) || Input.GetKey(KeyCode.A)) + { + this.del.x = this.del.x - 1f; + } + if (Input.GetKey(KeyCode.UpArrow) || Input.GetKey(KeyCode.W)) + { + this.del.y = this.del.y + 1f; + } + if (Input.GetKey(KeyCode.DownArrow) || Input.GetKey(KeyCode.S)) + { + this.del.y = this.del.y - 1f; + } + if (Input.GetKeyDown(KeyCode.R)) + { + DestroyableSingleton<HudManager>.Instance.ReportButton.DoClick(); + } + if (Input.GetKeyDown(KeyCode.Space) || Input.GetKeyDown(KeyCode.E)) + { + DestroyableSingleton<HudManager>.Instance.UseButton.DoClick(); + } + if (Input.GetKeyDown(KeyCode.Tab)) + { + DestroyableSingleton<HudManager>.Instance.ShowMap(delegate(MapBehaviour m) + { + m.ShowNormalMap(); + }); + } + if (PlayerControl.LocalPlayer.Data.IsImpostor && Input.GetKeyDown(KeyCode.Q)) + { + DestroyableSingleton<HudManager>.Instance.KillButton.PerformKill(); + } + if (Input.GetKeyDown(KeyCode.Escape)) + { + if (Minigame.Instance) + { + Minigame.Instance.Close(); + } + else if (DestroyableSingleton<HudManager>.InstanceExists && MapBehaviour.Instance && MapBehaviour.Instance.IsOpen) + { + MapBehaviour.Instance.Close(); + } + else + { + CustomPlayerMenu customPlayerMenu = UnityEngine.Object.FindObjectOfType<CustomPlayerMenu>(); + if (customPlayerMenu) + { + customPlayerMenu.Close(true); + } + } + } + this.del.Normalize(); + } +} diff --git a/Client/Assembly-CSharp/KeypadGame.cs b/Client/Assembly-CSharp/KeypadGame.cs new file mode 100644 index 0000000..91d7a7a --- /dev/null +++ b/Client/Assembly-CSharp/KeypadGame.cs @@ -0,0 +1,135 @@ +using System; +using System.Collections; +using UnityEngine; + +public class KeypadGame : Minigame +{ + public TextRenderer TargetText; + + public TextRenderer NumberText; + + public int number; + + public string numString = string.Empty; + + private bool animating; + + public SpriteRenderer AcceptButton; + + private LifeSuppSystemType system; + + private NoOxyTask oxyTask; + + private bool done; + + public override void Begin(PlayerTask task) + { + base.Begin(task); + this.oxyTask = (NoOxyTask)task; + this.TargetText.Text = "today's code:\r\n" + this.oxyTask.targetNumber.ToString("D5"); + this.NumberText.Text = string.Empty; + this.system = (LifeSuppSystemType)ShipStatus.Instance.Systems[SystemTypes.LifeSupp]; + this.done = this.system.GetConsoleComplete(base.ConsoleId); + } + + public void ClickNumber(int i) + { + if (this.animating) + { + return; + } + if (this.done) + { + return; + } + if (this.NumberText.Text.Length >= 5) + { + base.StartCoroutine(this.BlinkAccept()); + return; + } + this.numString += i; + this.number = this.number * 10 + i; + this.NumberText.Text = this.numString; + } + + private IEnumerator BlinkAccept() + { + int num; + for (int i = 0; i < 5; i = num) + { + this.AcceptButton.color = Color.gray; + yield return null; + yield return null; + this.AcceptButton.color = Color.white; + yield return null; + yield return null; + num = i + 1; + } + yield break; + } + + public void ClearEntry() + { + if (this.animating) + { + return; + } + this.number = 0; + this.numString = string.Empty; + this.NumberText.Text = string.Empty; + } + + public void Enter() + { + if (this.animating) + { + return; + } + base.StartCoroutine(this.Animate()); + } + + private IEnumerator Animate() + { + this.animating = true; + WaitForSeconds wait = new WaitForSeconds(0.1f); + yield return wait; + this.NumberText.Text = string.Empty; + yield return wait; + if (this.oxyTask.targetNumber == this.number) + { + this.done = true; + byte amount = (byte)(base.ConsoleId | 64); + ShipStatus.Instance.RpcRepairSystem(SystemTypes.LifeSupp, (int)amount); + try + { + ((SabotageTask)this.MyTask).MarkContributed(); + } + catch + { + } + this.NumberText.Text = "OK"; + yield return wait; + this.NumberText.Text = string.Empty; + yield return wait; + this.NumberText.Text = "OK"; + yield return wait; + this.NumberText.Text = string.Empty; + yield return wait; + this.NumberText.Text = "OK"; + } + else + { + this.NumberText.Text = "Bad"; + yield return wait; + this.NumberText.Text = string.Empty; + yield return wait; + this.NumberText.Text = "Bad"; + yield return wait; + this.numString = string.Empty; + this.number = 0; + this.NumberText.Text = this.numString; + } + this.animating = false; + yield break; + } +} diff --git a/Client/Assembly-CSharp/KillAnimType.cs b/Client/Assembly-CSharp/KillAnimType.cs new file mode 100644 index 0000000..29b5198 --- /dev/null +++ b/Client/Assembly-CSharp/KillAnimType.cs @@ -0,0 +1,10 @@ +using System; + +public enum KillAnimType +{ + Stab, + Tongue, + Shoot, + Neck, + None +} diff --git a/Client/Assembly-CSharp/KillAnimation.cs b/Client/Assembly-CSharp/KillAnimation.cs new file mode 100644 index 0000000..d6e980a --- /dev/null +++ b/Client/Assembly-CSharp/KillAnimation.cs @@ -0,0 +1,52 @@ +using System; +using System.Collections; +using PowerTools; +using UnityEngine; + +public class KillAnimation : MonoBehaviour +{ + public AnimationClip BlurAnim; + + public DeadBody bodyPrefab; + + public Vector3 BodyOffset; + + public IEnumerator CoPerformKill(PlayerControl source, PlayerControl target) + { + bool isParticipant = PlayerControl.LocalPlayer == source || PlayerControl.LocalPlayer == target; + PlayerPhysics sourcePhys = source.MyPhysics; + KillAnimation.SetMovement(source, false); + KillAnimation.SetMovement(target, false); + if (isParticipant) + { + Camera.main.GetComponent<FollowerCamera>().Locked = true; + } + target.Die(DeathReason.Kill); + SpriteAnim sourceAnim = source.GetComponent<SpriteAnim>(); + yield return new WaitForAnimationFinish(sourceAnim, this.BlurAnim); + source.NetTransform.SnapTo(target.transform.position); + sourceAnim.Play(sourcePhys.IdleAnim, 1f); + KillAnimation.SetMovement(source, true); + DeadBody deadBody = UnityEngine.Object.Instantiate<DeadBody>(this.bodyPrefab); + Vector3 vector = target.transform.position + this.BodyOffset; + vector.z = vector.y / 1000f; + deadBody.transform.position = vector; + deadBody.ParentId = target.PlayerId; + target.SetPlayerMaterialColors(deadBody.GetComponent<Renderer>()); + KillAnimation.SetMovement(target, true); + if (isParticipant) + { + Camera.main.GetComponent<FollowerCamera>().Locked = false; + } + yield break; + } + + public static void SetMovement(PlayerControl source, bool canMove) + { + source.moveable = canMove; + source.MyPhysics.ResetAnim(false); + source.NetTransform.enabled = canMove; + source.MyPhysics.enabled = canMove; + source.NetTransform.Halt(); + } +} diff --git a/Client/Assembly-CSharp/KillButtonManager.cs b/Client/Assembly-CSharp/KillButtonManager.cs new file mode 100644 index 0000000..6c43b4f --- /dev/null +++ b/Client/Assembly-CSharp/KillButtonManager.cs @@ -0,0 +1,69 @@ +using System; +using UnityEngine; + +public class KillButtonManager : MonoBehaviour +{ + public PlayerControl CurrentTarget; + + public SpriteRenderer renderer; + + public TextRenderer TimerText; + + public bool isCoolingDown = true; + + public bool isActive; + + private Vector2 uv; + + public void Start() + { + this.renderer.SetCooldownNormalizedUvs(); + this.SetTarget(null); + } + + public void PerformKill() + { + if (base.isActiveAndEnabled && this.CurrentTarget && !this.isCoolingDown && !PlayerControl.LocalPlayer.Data.IsDead && PlayerControl.LocalPlayer.CanMove) + { + PlayerControl.LocalPlayer.RpcMurderPlayer(this.CurrentTarget); + this.SetTarget(null); + } + } + + public void SetTarget(PlayerControl target) + { + if (this.CurrentTarget && this.CurrentTarget != target) + { + this.CurrentTarget.GetComponent<SpriteRenderer>().material.SetFloat("_Outline", 0f); + } + this.CurrentTarget = target; + if (this.CurrentTarget) + { + SpriteRenderer component = this.CurrentTarget.GetComponent<SpriteRenderer>(); + component.material.SetFloat("_Outline", (float)(this.isActive ? 1 : 0)); + component.material.SetColor("_OutlineColor", Color.red); + this.renderer.color = Palette.EnabledColor; + this.renderer.material.SetFloat("_Desat", 0f); + return; + } + this.renderer.color = Palette.DisabledColor; + this.renderer.material.SetFloat("_Desat", 1f); + } + + public void SetCoolDown(float timer, float maxTimer) + { + float num = Mathf.Clamp(timer / maxTimer, 0f, 1f); + if (this.renderer) + { + this.renderer.material.SetFloat("_Percent", num); + } + this.isCoolingDown = (num > 0f); + if (this.isCoolingDown) + { + this.TimerText.Text = Mathf.CeilToInt(timer).ToString(); + this.TimerText.gameObject.SetActive(true); + return; + } + this.TimerText.gameObject.SetActive(false); + } +} diff --git a/Client/Assembly-CSharp/KillOverlay.cs b/Client/Assembly-CSharp/KillOverlay.cs new file mode 100644 index 0000000..9c0c226 --- /dev/null +++ b/Client/Assembly-CSharp/KillOverlay.cs @@ -0,0 +1,114 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using UnityEngine; + +public class KillOverlay : MonoBehaviour +{ + public bool IsOpen + { + get + { + return this.showAll != null || this.queue.Count > 0; + } + } + + public SpriteRenderer background; + + public GameObject flameParent; + + public OverlayKillAnimation[] KillAnims; + + public float FadeTime = 0.6f; + + public OverlayKillAnimation EmergencyOverlay; + + public OverlayKillAnimation ReportOverlay; + + private Queue<Func<IEnumerator>> queue = new Queue<Func<IEnumerator>>(); + + private Coroutine showAll; + + private Coroutine showOne; + + public IEnumerator WaitForFinish() + { + while (this.showAll != null || this.queue.Count > 0) + { + yield return null; + } + yield break; + } + + public void ShowOne(PlayerControl killer, GameData.PlayerInfo victim) + { + this.queue.Enqueue(() => this.CoShowOne(this.KillAnims.Random<OverlayKillAnimation>(), killer, victim)); + if (this.showAll == null) + { + this.showAll = base.StartCoroutine(this.ShowAll()); + } + } + + public void ShowOne(OverlayKillAnimation killAnimPrefab, PlayerControl killer, GameData.PlayerInfo victim) + { + this.queue.Enqueue(() => this.CoShowOne(killAnimPrefab, killer, victim)); + if (this.showAll == null) + { + this.showAll = base.StartCoroutine(this.ShowAll()); + } + } + + private IEnumerator ShowAll() + { + while (this.queue.Count > 0 || this.showOne != null) + { + if (this.showOne == null) + { + this.showOne = base.StartCoroutine(this.queue.Dequeue()()); + } + yield return null; + } + this.showAll = null; + yield break; + } + + private IEnumerator CoShowOne(OverlayKillAnimation killAnimPrefab, PlayerControl killer, GameData.PlayerInfo victim) + { + OverlayKillAnimation overlayKillAnimation = UnityEngine.Object.Instantiate<OverlayKillAnimation>(killAnimPrefab, base.transform); + overlayKillAnimation.Begin(killer, victim); + overlayKillAnimation.gameObject.SetActive(false); + yield return this.CoShowOne(overlayKillAnimation); + yield break; + } + + private IEnumerator CoShowOne(OverlayKillAnimation anim) + { + if (Constants.ShouldPlaySfx()) + { + SoundManager.Instance.PlaySound(anim.Stinger, false, 1f).volume = anim.StingerVolume; + } + WaitForSeconds wait = new WaitForSeconds(0.083333336f); + this.background.enabled = true; + yield return wait; + this.background.enabled = false; + this.flameParent.SetActive(true); + this.flameParent.transform.localScale = new Vector3(1f, 0.3f, 1f); + this.flameParent.transform.localEulerAngles = new Vector3(0f, 0f, 25f); + yield return wait; + this.flameParent.transform.localScale = new Vector3(1f, 0.5f, 1f); + this.flameParent.transform.localEulerAngles = new Vector3(0f, 0f, -15f); + yield return wait; + this.flameParent.transform.localScale = new Vector3(1f, 1f, 1f); + this.flameParent.transform.localEulerAngles = new Vector3(0f, 0f, 0f); + anim.gameObject.SetActive(true); + yield return anim.WaitForFinish(); + UnityEngine.Object.Destroy(anim.gameObject); + yield return new WaitForLerp(0.16666667f, delegate(float t) + { + this.flameParent.transform.localScale = new Vector3(1f, 1f - t, 1f); + }); + this.flameParent.SetActive(false); + this.showOne = null; + yield break; + } +} diff --git a/Client/Assembly-CSharp/LanguageButton.cs b/Client/Assembly-CSharp/LanguageButton.cs new file mode 100644 index 0000000..3d89dda --- /dev/null +++ b/Client/Assembly-CSharp/LanguageButton.cs @@ -0,0 +1,12 @@ +using System; +using UnityEngine; + +public class LanguageButton : MonoBehaviour +{ + public TextRenderer Title; + + public PassiveButton Button; + + [HideInInspector] + public TextAsset Language; +} diff --git a/Client/Assembly-CSharp/LanguageSetter.cs b/Client/Assembly-CSharp/LanguageSetter.cs new file mode 100644 index 0000000..e5ccac7 --- /dev/null +++ b/Client/Assembly-CSharp/LanguageSetter.cs @@ -0,0 +1,50 @@ +using System; +using UnityEngine; + +public class LanguageSetter : MonoBehaviour +{ + public LanguageButton ButtonPrefab; + + public Scroller ButtonParent; + + public float ButtonStart = 0.5f; + + public float ButtonHeight = 0.5f; + + private LanguageButton[] AllButtons; + + public void Start() + { + TextAsset[] languages = DestroyableSingleton<TranslationController>.Instance.Languages; + Vector3 vector = new Vector3(0f, this.ButtonStart, -1f); + this.AllButtons = new LanguageButton[languages.Length]; + for (int i = 0; i < languages.Length; i++) + { + LanguageButton button = UnityEngine.Object.Instantiate<LanguageButton>(this.ButtonPrefab, this.ButtonParent.Inner); + this.AllButtons[i] = button; + button.Language = languages[i]; + button.Title.Text = languages[i].name; + if ((long)i == (long)((ulong)SaveManager.LastLanguage)) + { + button.Title.Color = Color.green; + } + button.Button.OnClick.AddListener(delegate() + { + this.SetLanguage(button); + }); + button.transform.localPosition = vector; + vector.y -= this.ButtonHeight; + } + this.ButtonParent.YBounds.max = Mathf.Max(0f, -vector.y - this.ButtonStart * 2f); + } + + public void SetLanguage(LanguageButton selected) + { + for (int i = 0; i < this.AllButtons.Length; i++) + { + this.AllButtons[i].Title.Color = Color.white; + } + selected.Title.Color = Color.green; + DestroyableSingleton<TranslationController>.Instance.SetLanguage(selected.Language); + } +} diff --git a/Client/Assembly-CSharp/LanguageUnit.cs b/Client/Assembly-CSharp/LanguageUnit.cs new file mode 100644 index 0000000..62ae51e --- /dev/null +++ b/Client/Assembly-CSharp/LanguageUnit.cs @@ -0,0 +1,79 @@ +using System; +using System.Collections.Generic; +using System.IO; +using UnityEngine; + +public class LanguageUnit +{ + public bool IsEnglish; + + private Dictionary<StringNames, string> AllStrings = new Dictionary<StringNames, string>(); + + private Dictionary<ImageNames, Sprite> AllImages = new Dictionary<ImageNames, Sprite>(); + + public LanguageUnit(TextAsset data, ImageData[] images) + { + foreach (ImageData imageData in images) + { + this.AllImages.Add(imageData.Name, imageData.Sprite); + } + using (StringReader stringReader = new StringReader(data.text)) + { + for (string text = stringReader.ReadLine(); text != null; text = stringReader.ReadLine()) + { + if (text.Length != 0) + { + int num = text.IndexOf(','); + if (num < 0) + { + Debug.LogWarning("Couldn't parse: " + text); + } + else + { + string text2 = text.Substring(0, num); + StringNames key; + if (!Enum.TryParse<StringNames>(text2, out key)) + { + Debug.LogWarning("Couldn't parse: " + text2); + } + else + { + string value = LanguageUnit.UnescapeCodes(text.Substring(num + 1)); + this.AllStrings.Add(key, value); + } + } + } + } + } + } + + public static string UnescapeCodes(string src) + { + if (src.IndexOf("\\n") < 0) + { + return src; + } + return src.Replace("\\n", "\n"); + } + + public string GetString(StringNames stringId, params object[] parts) + { + string text; + if (!this.AllStrings.TryGetValue(stringId, out text)) + { + return "STRMISS"; + } + if (parts.Length != 0) + { + return string.Format(text, parts); + } + return text; + } + + public Sprite GetImage(ImageNames id) + { + Sprite result; + this.AllImages.TryGetValue(id, out result); + return result; + } +} diff --git a/Client/Assembly-CSharp/LeafBehaviour.cs b/Client/Assembly-CSharp/LeafBehaviour.cs new file mode 100644 index 0000000..58e2b0a --- /dev/null +++ b/Client/Assembly-CSharp/LeafBehaviour.cs @@ -0,0 +1,40 @@ +using System; +using UnityEngine; + +public class LeafBehaviour : MonoBehaviour +{ + public Sprite[] Images; + + public FloatRange SpinSpeed = new FloatRange(-45f, 45f); + + public Vector2Range StartVel; + + public float AccelRate = 30f; + + [HideInInspector] + public LeafMinigame Parent; + + public bool Held; + + private static RandomFill<Sprite> ImageFiller = new RandomFill<Sprite>(); + + [HideInInspector] + public Rigidbody2D body; + + public void Start() + { + LeafBehaviour.ImageFiller.Set(this.Images); + base.GetComponent<SpriteRenderer>().sprite = LeafBehaviour.ImageFiller.Get(); + this.body = base.GetComponent<Rigidbody2D>(); + this.body.angularVelocity = this.SpinSpeed.Next(); + this.body.velocity = this.StartVel.Next(); + } + + public void FixedUpdate() + { + if (!this.Held && (double)base.transform.localPosition.x < -2.5) + { + this.Parent.LeafDone(this); + } + } +} diff --git a/Client/Assembly-CSharp/LeafMinigame.cs b/Client/Assembly-CSharp/LeafMinigame.cs new file mode 100644 index 0000000..17f4d18 --- /dev/null +++ b/Client/Assembly-CSharp/LeafMinigame.cs @@ -0,0 +1,104 @@ +using System; +using PowerTools; +using UnityEngine; + +public class LeafMinigame : Minigame +{ + public LeafBehaviour LeafPrefab; + + public Vector2Range ValidArea; + + public SpriteAnim[] Arrows; + + public AnimationClip[] Inactive; + + public AnimationClip[] Active; + + public AnimationClip[] Complete; + + private Collider2D[] Leaves; + + public AudioClip[] LeaveSounds; + + public AudioClip[] SuckSounds; + + private Controller myController = new Controller(); + + public override void Begin(PlayerTask task) + { + base.Begin(task); + this.Leaves = new Collider2D[this.MyNormTask.MaxStep - this.MyNormTask.taskStep]; + for (int i = 0; i < this.Leaves.Length; i++) + { + LeafBehaviour leafBehaviour = UnityEngine.Object.Instantiate<LeafBehaviour>(this.LeafPrefab); + leafBehaviour.transform.SetParent(base.transform); + leafBehaviour.Parent = this; + Vector3 localPosition = this.ValidArea.Next(); + localPosition.z = -1f; + leafBehaviour.transform.localPosition = localPosition; + this.Leaves[i] = leafBehaviour.GetComponent<Collider2D>(); + } + } + + public void FixedUpdate() + { + this.myController.Update(); + for (int i = 0; i < this.Leaves.Length; i++) + { + Collider2D collider2D = this.Leaves[i]; + if (collider2D) + { + LeafBehaviour component = collider2D.GetComponent<LeafBehaviour>(); + switch (this.myController.CheckDrag(collider2D, false)) + { + case DragState.TouchStart: + if (Constants.ShouldPlaySfx()) + { + SoundManager.Instance.PlaySound(this.LeaveSounds.Random<AudioClip>(), false, 1f); + } + for (int j = 0; j < this.Arrows.Length; j++) + { + this.Arrows[j].Play(this.Active[j], 1f); + } + component.Held = true; + break; + case DragState.Dragging: + { + Vector2 vector = this.myController.DragPosition - component.body.position; + component.body.velocity = vector.normalized * Mathf.Min(3f, vector.magnitude * 3f); + break; + } + case DragState.Released: + component.Held = false; + for (int k = 0; k < this.Arrows.Length; k++) + { + this.Arrows[k].Play(this.Inactive[k], 1f); + this.Arrows[k].GetComponent<SpriteRenderer>().sprite = null; + } + break; + } + } + } + } + + public void LeafDone(LeafBehaviour leaf) + { + if (Constants.ShouldPlaySfx()) + { + SoundManager.Instance.PlaySound(this.SuckSounds.Random<AudioClip>(), false, 1f); + } + UnityEngine.Object.Destroy(leaf.gameObject); + if (this.MyNormTask) + { + this.MyNormTask.NextStep(); + if (this.MyNormTask.IsComplete) + { + for (int i = 0; i < this.Arrows.Length; i++) + { + this.Arrows[i].Play(this.Complete[i], 1f); + } + base.StartCoroutine(base.CoStartClose(0.75f)); + } + } + } +} diff --git a/Client/Assembly-CSharp/LetterTree.cs b/Client/Assembly-CSharp/LetterTree.cs new file mode 100644 index 0000000..b92f743 --- /dev/null +++ b/Client/Assembly-CSharp/LetterTree.cs @@ -0,0 +1,299 @@ +using System; +using System.Collections.Generic; +using System.Text; + +public class LetterTree +{ + private LetterTree.LetterNode root = new LetterTree.LetterNode('\0'); + + private enum NodeTypes : byte + { + NonTerm, + Terminal, + TerminalStrict, + TerminalExact, + TerminalUnbroken + } + + private class LetterNode + { + public char Letter; + + public LetterTree.NodeTypes Terminal; + + public LetterTree.LetterNode[] Children = new LetterTree.LetterNode[26]; + + public LetterNode(char l) + { + this.Letter = l; + } + + public LetterTree.LetterNode CreateChild(char l) + { + int num = LetterTree.LetterNode.ToIndex(l); + LetterTree.LetterNode letterNode = this.Children[num]; + if (letterNode == null) + { + letterNode = (this.Children[num] = new LetterTree.LetterNode(l)); + } + return letterNode; + } + + public LetterTree.LetterNode FindChild(char l) + { + int num = LetterTree.LetterNode.ToIndex(l); + return this.Children[num]; + } + + public static int ToIndex(char c) + { + if (c >= 'A' && c <= 'Z') + { + return (int)(c - 'A'); + } + if (c >= 'a' && c <= 'z') + { + return (int)(c - 'a'); + } + if (c == 'с') + { + return 2; + } + if (c == 'к') + { + return 10; + } + if (c == '$') + { + return 18; + } + if (c == '+') + { + return 19; + } + if (c == '0') + { + return 14; + } + if (c == '1') + { + return 8; + } + if (c == '!') + { + return 8; + } + if (c == '2') + { + return 18; + } + if (c == '3') + { + return 4; + } + if (c == '4') + { + return 0; + } + if (c == '5') + { + return 18; + } + if (c == '7') + { + return 19; + } + if (c == '8') + { + return 1; + } + if (c > 'z') + { + foreach (char c2 in c.ToString().Normalize(NormalizationForm.FormD)) + { + if (c2 <= 'z') + { + return LetterTree.LetterNode.ToIndex(c2); + } + } + } + return (int)c; + } + } + + public void Clear() + { + this.root = new LetterTree.LetterNode('\0'); + } + + public void AddWord(string word) + { + LetterTree.LetterNode letterNode = this.root; + foreach (char l in word) + { + if (!this.IsFiller(l)) + { + letterNode = letterNode.CreateChild(l); + } + } + if (letterNode.Terminal == LetterTree.NodeTypes.NonTerm) + { + letterNode.Terminal = LetterTree.NodeTypes.Terminal; + if (word[word.Length - 1] == '~') + { + letterNode.Terminal = LetterTree.NodeTypes.TerminalStrict; + } + if (word[word.Length - 1] == '^') + { + letterNode.Terminal = LetterTree.NodeTypes.TerminalExact; + } + if (word[word.Length - 1] == '`') + { + letterNode.Terminal = LetterTree.NodeTypes.TerminalUnbroken; + } + } + } + + public bool IsFiller(char l) + { + return LetterTree.LetterNode.ToIndex(l) == (int)l; + } + + public int Search(StringBuilder input, int start) + { + if (start >= input.Length || this.IsFiller(input[start])) + { + return 0; + } + bool exactStart = start == 0 || this.IsFiller(input[start - 1]); + return this.SubSearchRec(input, start, this.root, false, false, exactStart); + } + + public int Search(string inputStr, int start) + { + StringBuilder stringBuilder = new StringBuilder(inputStr); + if (start >= stringBuilder.Length || this.IsFiller(stringBuilder[start])) + { + return 0; + } + bool exactStart = start == 0 || this.IsFiller(stringBuilder[start - 1]); + return this.SubSearchRec(stringBuilder, start, this.root, false, false, exactStart); + } + + private int SubSearchRec(StringBuilder input, int start, LetterTree.LetterNode previous, bool postDupes, bool postBreak, bool exactStart) + { + if (start >= input.Length) + { + return -2; + } + char c = input[start]; + if (this.IsFiller(c)) + { + if (postDupes) + { + return -2; + } + int num = this.SubSearchRec(input, start + 1, previous, postDupes, true, exactStart); + if (num > 0) + { + return num + 1; + } + return -2; + } + else + { + if (c == previous.Letter && !postBreak) + { + int num2 = this.SubSearchRec(input, start + 1, previous, true, postBreak, exactStart); + if (num2 > 0) + { + return num2 + 1; + } + if (previous.Terminal != LetterTree.NodeTypes.NonTerm) + { + return 1; + } + } + LetterTree.LetterNode letterNode = previous.FindChild(c); + if (letterNode == null) + { + return -3; + } + int num3 = this.SubSearchRec(input, start + 1, letterNode, postDupes, postBreak, exactStart); + if (num3 > 0) + { + return num3 + 1; + } + if (letterNode.Terminal == LetterTree.NodeTypes.TerminalStrict && num3 == -2 && (exactStart || !postBreak)) + { + return 1; + } + if (letterNode.Terminal == LetterTree.NodeTypes.TerminalUnbroken && num3 == -2 && !postBreak) + { + return 1; + } + if (letterNode.Terminal == LetterTree.NodeTypes.TerminalExact && (num3 == -2 && exactStart)) + { + return 1; + } + if (letterNode.Terminal == LetterTree.NodeTypes.Terminal && num3 <= 0) + { + return 1; + } + return num3; + } + } + + public IEnumerable<string> GetWords() + { + StringBuilder b = new StringBuilder(); + foreach (LetterTree.LetterNode node in this.root.Children) + { + foreach (string text in this.GetWords(b, 0, node)) + { + yield return text; + } + IEnumerator<string> enumerator = null; + } + LetterTree.LetterNode[] array = null; + yield break; + yield break; + } + + private IEnumerable<string> GetWords(StringBuilder b, int i, LetterTree.LetterNode node) + { + if (node == null) + { + yield break; + } + int length = b.Length; + b.Length = length + 1; + b[i] = node.Letter; + if (node.Terminal == LetterTree.NodeTypes.Terminal) + { + yield return b.ToString(); + } + else if (node.Terminal == LetterTree.NodeTypes.TerminalStrict) + { + length = b.Length; + b.Length = length + 1; + b[i + 1] = '~'; + yield return b.ToString(); + length = b.Length; + b.Length = length - 1; + } + foreach (LetterTree.LetterNode node2 in node.Children) + { + foreach (string text in this.GetWords(b, i + 1, node2)) + { + yield return text; + } + IEnumerator<string> enumerator = null; + } + LetterTree.LetterNode[] array = null; + length = b.Length; + b.Length = length - 1; + yield break; + yield break; + } +} diff --git a/Client/Assembly-CSharp/LifeSuppSystemType.cs b/Client/Assembly-CSharp/LifeSuppSystemType.cs new file mode 100644 index 0000000..2e77cfc --- /dev/null +++ b/Client/Assembly-CSharp/LifeSuppSystemType.cs @@ -0,0 +1,121 @@ +using System; +using System.Collections.Generic; +using Hazel; + +public class LifeSuppSystemType : ISystemType, IActivatable +{ + public int UserCount + { + get + { + return this.CompletedConsoles.Count; + } + } + + public bool IsActive + { + get + { + return this.Countdown < 10000f; + } + } + + private const float SyncRate = 2f; + + private float timer; + + public const byte StartCountdown = 128; + + public const byte AddUserOp = 64; + + public const byte ClearCountdown = 16; + + public const float CountdownStopped = 10000f; + + public const float LifeSuppDuration = 45f; + + public const byte ConsoleIdMask = 3; + + public const byte RequiredUserCount = 2; + + public float Countdown = 10000f; + + private HashSet<int> CompletedConsoles = new HashSet<int>(); + + public bool GetConsoleComplete(int consoleId) + { + return this.CompletedConsoles.Contains(consoleId); + } + + public void RepairDamage(PlayerControl player, byte opCode) + { + int item = (int)(opCode & 3); + if (opCode == 128 && !this.IsActive) + { + this.Countdown = 45f; + this.CompletedConsoles.Clear(); + return; + } + if (opCode == 16) + { + this.Countdown = 10000f; + return; + } + if (opCode.HasAnyBit(64)) + { + this.CompletedConsoles.Add(item); + } + } + + public bool Detoriorate(float deltaTime) + { + if (this.IsActive) + { + if (DestroyableSingleton<HudManager>.Instance.OxyFlash == null) + { + PlayerControl.LocalPlayer.AddSystemTask(SystemTypes.LifeSupp); + } + this.Countdown -= deltaTime; + if (this.UserCount >= 2) + { + this.Countdown = 10000f; + return true; + } + this.timer += deltaTime; + if (this.timer > 2f) + { + this.timer = 0f; + return true; + } + } + else if (DestroyableSingleton<HudManager>.Instance.OxyFlash != null) + { + DestroyableSingleton<HudManager>.Instance.StopOxyFlash(); + } + return false; + } + + public void Serialize(MessageWriter writer, bool initialState) + { + writer.Write(this.Countdown); + writer.WritePacked(this.CompletedConsoles.Count); + foreach (int value in this.CompletedConsoles) + { + writer.WritePacked(value); + } + } + + public void Deserialize(MessageReader reader, bool initialState) + { + this.Countdown = reader.ReadSingle(); + if (reader.Position < reader.Length) + { + this.CompletedConsoles.Clear(); + int num = reader.ReadPackedInt32(); + for (int i = 0; i < num; i++) + { + this.CompletedConsoles.Add(reader.ReadPackedInt32()); + } + } + } +} diff --git a/Client/Assembly-CSharp/LightSource.cs b/Client/Assembly-CSharp/LightSource.cs new file mode 100644 index 0000000..891fcbf --- /dev/null +++ b/Client/Assembly-CSharp/LightSource.cs @@ -0,0 +1,335 @@ +using System; +using System.Collections.Generic; +using UnityEngine; + +public class LightSource : MonoBehaviour +{ + public static Dictionary<GameObject, NoShadowBehaviour> NoShadows = new Dictionary<GameObject, NoShadowBehaviour>(); + + public static Dictionary<GameObject, OneWayShadows> OneWayShadows = new Dictionary<GameObject, OneWayShadows>(); + + [HideInInspector] + private GameObject child; + + [HideInInspector] + private Vector2[] requiredDels; + + [HideInInspector] + private Mesh myMesh; + + public int MinRays = 24; + + public float LightRadius = 3f; + + public Material Material; + + [HideInInspector] + private List<LightSource.VertInfo> verts = new List<LightSource.VertInfo>(256); + + [HideInInspector] + private int vertCount; + + private RaycastHit2D[] buffer = new RaycastHit2D[25]; + + private Collider2D[] hits = new Collider2D[40]; + + private ContactFilter2D filter; + + private Vector3[] vec; + + private Vector2[] uvs; + + private int[] triangles = new int[1200]; + + public float tol = 0.05f; + + private Vector2 del; + + private Vector2 tan; + + private Vector2 side; + + private List<RaycastHit2D> lightHits = new List<RaycastHit2D>(); + + private class VertInfo + { + public float Angle; + + public Vector3 Position; + + internal void Complete(float x, float y) + { + this.Position.x = x; + this.Position.y = y; + this.Angle = LightSource.pseudoAngle(y, x); + } + + internal void Complete(Vector2 point) + { + this.Position.x = point.x; + this.Position.y = point.y; + this.Angle = LightSource.pseudoAngle(point.y, point.x); + } + } + + private class AngleComparer : IComparer<LightSource.VertInfo> + { + public static readonly LightSource.AngleComparer Instance = new LightSource.AngleComparer(); + + public int Compare(LightSource.VertInfo x, LightSource.VertInfo y) + { + if (x.Angle > y.Angle) + { + return 1; + } + if (x.Angle >= y.Angle) + { + return 0; + } + return -1; + } + } + + private class HitDepthComparer : IComparer<RaycastHit2D> + { + public static readonly LightSource.HitDepthComparer Instance = new LightSource.HitDepthComparer(); + + public int Compare(RaycastHit2D x, RaycastHit2D y) + { + if (x.fraction <= y.fraction) + { + return -1; + } + return 1; + } + } + + private void Start() + { + this.filter.useTriggers = true; + this.filter.layerMask = Constants.ShadowMask; + this.filter.useLayerMask = true; + this.requiredDels = new Vector2[this.MinRays]; + for (int i = 0; i < this.requiredDels.Length; i++) + { + this.requiredDels[i] = Vector2.left.Rotate((float)i / (float)this.requiredDels.Length * 360f); + } + this.myMesh = new Mesh(); + this.myMesh.MarkDynamic(); + this.myMesh.name = "ShadowMesh"; + GameObject gameObject = new GameObject("LightChild"); + gameObject.layer = 10; + gameObject.AddComponent<MeshFilter>().mesh = this.myMesh; + Renderer renderer = gameObject.AddComponent<MeshRenderer>(); + this.Material = new Material(this.Material); + renderer.sharedMaterial = this.Material; + this.child = gameObject; + } + + private void Update() + { + this.vertCount = 0; + Vector3 position = base.transform.position; + position.z -= 7f; + this.child.transform.position = position; + Vector2 vector = position; + this.Material.SetFloat("_LightRadius", this.LightRadius); + int num = Physics2D.OverlapCircleNonAlloc(vector, this.LightRadius, this.hits, Constants.ShadowMask); + for (int i = 0; i < num; i++) + { + Collider2D collider2D = this.hits[i]; + if (!collider2D.isTrigger) + { + EdgeCollider2D edgeCollider2D = collider2D as EdgeCollider2D; + if (edgeCollider2D) + { + Vector2[] points = edgeCollider2D.points; + for (int j = 0; j < points.Length; j++) + { + Vector2 vector2 = edgeCollider2D.transform.TransformPoint(points[j]); + this.del.x = vector2.x - vector.x; + this.del.y = vector2.y - vector.y; + this.TestBothSides(vector); + } + } + else + { + PolygonCollider2D polygonCollider2D = collider2D as PolygonCollider2D; + if (polygonCollider2D) + { + Vector2[] points2 = polygonCollider2D.points; + for (int k = 0; k < points2.Length; k++) + { + Vector2 vector3 = polygonCollider2D.transform.TransformPoint(points2[k]); + this.del.x = vector3.x - vector.x; + this.del.y = vector3.y - vector.y; + this.TestBothSides(vector); + } + } + else + { + BoxCollider2D boxCollider2D = collider2D as BoxCollider2D; + if (boxCollider2D) + { + Vector2 b = boxCollider2D.size / 2f; + Vector2 vector4 = boxCollider2D.transform.TransformPoint(boxCollider2D.offset - b) - vector; + Vector2 vector5 = boxCollider2D.transform.TransformPoint(boxCollider2D.offset + b) - vector; + this.del.x = vector4.x; + this.del.y = vector4.y; + this.TestBothSides(vector); + this.del.x = vector5.x; + this.TestBothSides(vector); + this.del.y = vector5.y; + this.TestBothSides(vector); + this.del.x = vector4.x; + this.TestBothSides(vector); + } + } + } + } + } + float d = this.LightRadius * 1.05f; + for (int l = 0; l < this.requiredDels.Length; l++) + { + Vector2 vector6 = d * this.requiredDels[l]; + this.CreateVert(vector, ref vector6); + } + this.verts.Sort(0, this.vertCount, LightSource.AngleComparer.Instance); + this.myMesh.Clear(); + if (this.vec == null || this.vec.Length < this.vertCount + 1) + { + this.vec = new Vector3[this.vertCount + 1]; + this.uvs = new Vector2[this.vec.Length]; + } + this.vec[0] = Vector3.zero; + this.uvs[0] = new Vector2(this.vec[0].x, this.vec[0].y); + for (int m = 0; m < this.vertCount; m++) + { + int num2 = m + 1; + this.vec[num2] = this.verts[m].Position; + this.uvs[num2] = new Vector2(this.vec[num2].x, this.vec[num2].y); + } + int num3 = this.vertCount * 3; + if (num3 > this.triangles.Length) + { + this.triangles = new int[num3]; + Debug.LogWarning("Resized triangles to: " + num3); + } + int num4 = 0; + for (int n = 0; n < this.triangles.Length; n += 3) + { + if (n < num3) + { + this.triangles[n] = 0; + this.triangles[n + 1] = num4 + 1; + if (n == num3 - 3) + { + this.triangles[n + 2] = 1; + } + else + { + this.triangles[n + 2] = num4 + 2; + } + num4++; + } + else + { + this.triangles[n] = 0; + this.triangles[n + 1] = 0; + this.triangles[n + 2] = 0; + } + } + this.myMesh.vertices = this.vec; + this.myMesh.uv = this.uvs; + this.myMesh.SetIndices(this.triangles, MeshTopology.Triangles, 0); + } + + private void TestBothSides(Vector2 myPos) + { + float num = LightSource.length(this.del.x, this.del.x); + this.tan.x = -this.del.y / num * this.tol; + this.tan.y = this.del.x / num * this.tol; + this.side.x = this.del.x + this.tan.x; + this.side.y = this.del.y + this.tan.y; + this.CreateVert(myPos, ref this.side); + this.side.x = this.del.x - this.tan.x; + this.side.y = this.del.y - this.tan.y; + this.CreateVert(myPos, ref this.side); + } + + private void CreateVert(Vector2 myPos, ref Vector2 del) + { + float num = this.LightRadius * 1.5f; + int num2 = Physics2D.Raycast(myPos, del, this.filter, this.buffer, num); + if (num2 > 0) + { + this.lightHits.Clear(); + RaycastHit2D raycastHit2D = default(RaycastHit2D); + Collider2D collider2D = null; + for (int i = 0; i < num2; i++) + { + RaycastHit2D raycastHit2D2 = this.buffer[i]; + Collider2D collider = raycastHit2D2.collider; + OneWayShadows oneWayShadows; + if (!LightSource.OneWayShadows.TryGetValue(collider.gameObject, out oneWayShadows) || !oneWayShadows.IsIgnored(this)) + { + this.lightHits.Add(raycastHit2D2); + if (!collider.isTrigger) + { + raycastHit2D = raycastHit2D2; + collider2D = collider; + break; + } + } + } + for (int j = 0; j < this.lightHits.Count; j++) + { + NoShadowBehaviour noShadowBehaviour; + if (LightSource.NoShadows.TryGetValue(this.lightHits[j].collider.gameObject, out noShadowBehaviour)) + { + noShadowBehaviour.didHit = true; + } + } + if (collider2D && !collider2D.isTrigger) + { + Vector2 point = raycastHit2D.point; + this.GetEmptyVert().Complete(point.x - myPos.x, point.y - myPos.y); + return; + } + } + Vector2 normalized = del.normalized; + this.GetEmptyVert().Complete(normalized.x * num, normalized.y * num); + } + + private LightSource.VertInfo GetEmptyVert() + { + if (this.vertCount < this.verts.Count) + { + List<LightSource.VertInfo> list = this.verts; + int num = this.vertCount; + this.vertCount = num + 1; + return list[num]; + } + LightSource.VertInfo vertInfo = new LightSource.VertInfo(); + this.verts.Add(vertInfo); + this.vertCount = this.verts.Count; + return vertInfo; + } + + private static float length(float x, float y) + { + return Mathf.Sqrt(x * x + y * y); + } + + public static float pseudoAngle(float dx, float dy) + { + if (dx < 0f) + { + float num = -dx; + float num2 = (dy > 0f) ? dy : (-dy); + return 2f - dy / (num + num2); + } + float num3 = (dy > 0f) ? dy : (-dy); + return dy / (dx + num3); + } +} diff --git a/Client/Assembly-CSharp/LobbyBehaviour.cs b/Client/Assembly-CSharp/LobbyBehaviour.cs new file mode 100644 index 0000000..de036b7 --- /dev/null +++ b/Client/Assembly-CSharp/LobbyBehaviour.cs @@ -0,0 +1,82 @@ +using System; +using Hazel; +using InnerNet; +using UnityEngine; + +public class LobbyBehaviour : InnerNetObject +{ + public static LobbyBehaviour Instance; + + public AudioClip SpawnSound; + + public AnimationClip SpawnInClip; + + public Vector2[] SpawnPositions; + + public AudioClip DropShipSound; + + public ShipRoom[] AllRooms; + + private float timer; + + public void Start() + { + LobbyBehaviour.Instance = this; + SoundManager.Instance.StopAllSound(); + SoundManager.Instance.PlaySound(this.DropShipSound, true, 1f).pitch = 1.2f; + Camera main = Camera.main; + if (main) + { + FollowerCamera component = main.GetComponent<FollowerCamera>(); + if (component) + { + component.shakeAmount = 0.03f; + component.shakePeriod = 400f; + } + } + } + + public void FixedUpdate() + { + this.timer += Time.deltaTime; + if (this.timer < 0.25f) + { + return; + } + this.timer = 0f; + if (PlayerControl.GameOptions != null) + { + int numPlayers = GameData.Instance ? GameData.Instance.PlayerCount : 10; + DestroyableSingleton<HudManager>.Instance.GameSettings.Text = PlayerControl.GameOptions.ToHudString(numPlayers); + DestroyableSingleton<HudManager>.Instance.GameSettings.gameObject.SetActive(true); + } + } + + public override void OnDestroy() + { + Camera main = Camera.main; + if (main) + { + FollowerCamera component = main.GetComponent<FollowerCamera>(); + if (component) + { + component.shakeAmount = 0.02f; + component.shakePeriod = 0.3f; + } + } + base.OnDestroy(); + } + + public override void HandleRpc(byte callId, MessageReader reader) + { + } + + public override bool Serialize(MessageWriter writer, bool initialState) + { + return false; + } + + public override void Deserialize(MessageReader reader, bool initialState) + { + } +} diff --git a/Client/Assembly-CSharp/MMOnlineManager.cs b/Client/Assembly-CSharp/MMOnlineManager.cs new file mode 100644 index 0000000..f65820c --- /dev/null +++ b/Client/Assembly-CSharp/MMOnlineManager.cs @@ -0,0 +1,28 @@ +using System; +using UnityEngine; + +public class MMOnlineManager : DestroyableSingleton<MMOnlineManager> +{ + public GameObject HelpMenu; + + public void Start() + { + if (this.HelpMenu) + { + if (SaveManager.ShowOnlineHelp) + { + SaveManager.ShowOnlineHelp = false; + return; + } + this.HelpMenu.gameObject.SetActive(false); + } + } + + private void Update() + { + if (Input.GetKeyUp(KeyCode.Escape)) + { + SceneChanger.ChangeScene("MainMenu"); + } + } +} diff --git a/Client/Assembly-CSharp/MainMenuManager.cs b/Client/Assembly-CSharp/MainMenuManager.cs new file mode 100644 index 0000000..c3a2054 --- /dev/null +++ b/Client/Assembly-CSharp/MainMenuManager.cs @@ -0,0 +1,66 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using UnityEngine; +using UnityEngine.Analytics; + +public class MainMenuManager : MonoBehaviour +{ + public DataCollectScreen DataPolicy; + + public AdDataCollectScreen AdsPolicy; + + public AnnouncementPopUp Announcement; + + public UnlockPopUp UnlockPop; + + private static bool SentTelemetry; + + public void Start() + { + if (!MainMenuManager.SentTelemetry && SaveManager.SendTelemetry) + { + MainMenuManager.SentTelemetry = true; + DateTime utcNow = DateTime.UtcNow; + if (SaveManager.LastStartDate != DateTime.MinValue && SaveManager.LastStartDate < utcNow) + { + TimeSpan timeSpan = utcNow - SaveManager.LastStartDate; + Analytics.CustomEvent("GameOpened", new Dictionary<string, object> + { + { + "TotalMinutes", + timeSpan.TotalMinutes + } + }); + } + SaveManager.LastStartDate = utcNow; + } + base.StartCoroutine(this.Announcement.Init()); + base.StartCoroutine(this.RunStartUp()); + } + + private IEnumerator RunStartUp() + { + yield return this.DataPolicy.Show(); + yield return this.Announcement.Show(); + yield return this.UnlockPop.Show(); + DateTime utcNow = DateTime.UtcNow; + for (int i = 0; i < DestroyableSingleton<HatManager>.Instance.AllHats.Count; i++) + { + HatBehaviour hatBehaviour = DestroyableSingleton<HatManager>.Instance.AllHats[i]; + if ((hatBehaviour.LimitedMonth == utcNow.Month || hatBehaviour.LimitedMonth == 0) && (hatBehaviour.LimitedYear == utcNow.Year || hatBehaviour.LimitedYear == 0) && !SaveManager.GetPurchase(hatBehaviour.ProductId)) + { + SaveManager.SetPurchased(hatBehaviour.ProductId); + } + } + yield break; + } + + private void Update() + { + if (Input.GetKeyUp(KeyCode.Escape)) + { + Application.Quit(); + } + } +} diff --git a/Client/Assembly-CSharp/ManualDoor.cs b/Client/Assembly-CSharp/ManualDoor.cs new file mode 100644 index 0000000..fb2ac04 --- /dev/null +++ b/Client/Assembly-CSharp/ManualDoor.cs @@ -0,0 +1,90 @@ +using System; +using System.Collections; +using Hazel; +using PowerTools; +using UnityEngine; + +public class ManualDoor : MonoBehaviour +{ + private const float ClosedDuration = 10f; + + public const float CooldownDuration = 30f; + + public bool Open; + + public BoxCollider2D myCollider; + + public SpriteAnim animator; + + public AnimationClip OpenDoorAnim; + + public AnimationClip CloseDoorAnim; + + private float size; + + private void Awake() + { + Vector2 vector = this.myCollider.size; + this.size = ((vector.x > vector.y) ? vector.y : vector.x); + } + + public virtual void SetDoorway(bool open) + { + if (this.Open == open) + { + return; + } + if (this.animator) + { + this.animator.Play(open ? this.OpenDoorAnim : this.CloseDoorAnim, 1f); + } + this.Open = open; + this.myCollider.isTrigger = open; + base.StopAllCoroutines(); + if (!open) + { + Vector2 vector = this.myCollider.size; + base.StartCoroutine(this.CoCloseDoorway(vector.x > vector.y)); + } + } + + // 自动关门 + private IEnumerator CoCloseDoorway(bool isHort) + { + Vector2 s = this.myCollider.size; + float i = 0f; + if (isHort) + { + while (i < 0.1f) + { + i += Time.deltaTime; + s.y = Mathf.Lerp(0.0001f, this.size, i / 0.1f); + this.myCollider.size = s; + yield return null; + } + } + else + { + while (i < 0.1f) + { + i += Time.deltaTime; + s.x = Mathf.Lerp(0.0001f, this.size, i / 0.1f); + this.myCollider.size = s; + yield return null; + } + } + yield break; + } + + //c 同步门的状态 + + public virtual void Serialize(MessageWriter writer) + { + writer.Write(this.Open); + } + + public virtual void Deserialize(MessageReader reader) + { + this.SetDoorway(reader.ReadBoolean()); + } +} diff --git a/Client/Assembly-CSharp/MapBehaviour.cs b/Client/Assembly-CSharp/MapBehaviour.cs new file mode 100644 index 0000000..85d6b39 --- /dev/null +++ b/Client/Assembly-CSharp/MapBehaviour.cs @@ -0,0 +1,113 @@ +using System; +using UnityEngine; + +public class MapBehaviour : MonoBehaviour +{ + public bool IsOpen + { + get + { + return base.isActiveAndEnabled; + } + } + + public bool IsOpenStopped + { + get + { + return this.IsOpen && this.countOverlay.isActiveAndEnabled; + } + } + + public static MapBehaviour Instance; + + public AlphaPulse ColorControl; + + public SpriteRenderer HerePoint; + + public MapCountOverlay countOverlay; + + public InfectedOverlay infectedOverlay; + + public MapTaskOverlay taskOverlay; + + private void Awake() + { + MapBehaviour.Instance = this; + } + + private void GenericShow() + { + base.transform.localScale = Vector3.one; + base.transform.localPosition = new Vector3(0f, 0f, -25f); + base.gameObject.SetActive(true); + } + + public void ShowInfectedMap() + { + if (this.IsOpen) + { + this.Close(); + return; + } + if (!PlayerControl.LocalPlayer.CanMove) + { + return; + } + PlayerControl.LocalPlayer.SetPlayerMaterialColors(this.HerePoint); + this.GenericShow(); + this.infectedOverlay.gameObject.SetActive(true); + this.ColorControl.SetColor(Palette.ImpostorRed); + this.taskOverlay.Hide(); + DestroyableSingleton<HudManager>.Instance.SetHudActive(false); + } + + public void ShowNormalMap() + { + if (this.IsOpen) + { + this.Close(); + return; + } + if (!PlayerControl.LocalPlayer.CanMove) + { + return; + } + PlayerControl.LocalPlayer.SetPlayerMaterialColors(this.HerePoint); + this.GenericShow(); + this.taskOverlay.Show(); + this.ColorControl.SetColor(new Color(0.05f, 0.2f, 1f, 1f)); + DestroyableSingleton<HudManager>.Instance.SetHudActive(false); + } + + public void ShowCountOverlay() + { + this.GenericShow(); + this.countOverlay.gameObject.SetActive(true); + this.taskOverlay.Hide(); + this.HerePoint.enabled = false; + DestroyableSingleton<HudManager>.Instance.SetHudActive(false); + } + + public void FixedUpdate() + { + if (!ShipStatus.Instance) + { + return; + } + Vector3 vector = PlayerControl.LocalPlayer.transform.position; + vector /= ShipStatus.Instance.MapScale; + vector.z = -1f; + this.HerePoint.transform.localPosition = vector; + } + + public void Close() + { + base.gameObject.SetActive(false); + this.countOverlay.gameObject.SetActive(false); + this.infectedOverlay.gameObject.SetActive(false); + this.taskOverlay.Hide(); + this.HerePoint.enabled = true; + DestroyableSingleton<HudManager>.Instance.SetHudActive(true); + } +} diff --git a/Client/Assembly-CSharp/MapConsole.cs b/Client/Assembly-CSharp/MapConsole.cs new file mode 100644 index 0000000..84a2e68 --- /dev/null +++ b/Client/Assembly-CSharp/MapConsole.cs @@ -0,0 +1,65 @@ +using System; +using UnityEngine; + +public class MapConsole : MonoBehaviour, IUsable +{ + public float UsableDistance + { + get + { + return this.usableDistance; + } + } + + public float PercentCool + { + get + { + return 0f; + } + } + + public float usableDistance = 1f; + + public SpriteRenderer Image; + + public void SetOutline(bool on, bool mainTarget) + { + if (this.Image) + { + this.Image.material.SetFloat("_Outline", (float)(on ? 1 : 0)); + this.Image.material.SetColor("_OutlineColor", Color.white); + this.Image.material.SetColor("_AddColor", mainTarget ? Color.white : Color.clear); + } + } + + public float CanUse(GameData.PlayerInfo pc, out bool canUse, out bool couldUse) + { + float num = float.MaxValue; + PlayerControl @object = pc.Object; + couldUse = pc.Object.CanMove; + canUse = couldUse; + if (canUse) + { + num = Vector2.Distance(@object.GetTruePosition(), base.transform.position); + canUse &= (num <= this.UsableDistance); + } + return num; + } + + public void Use() + { + bool flag; + bool flag2; + this.CanUse(PlayerControl.LocalPlayer.Data, out flag, out flag2); + if (!flag) + { + return; + } + PlayerControl.LocalPlayer.NetTransform.Halt(); + DestroyableSingleton<HudManager>.Instance.ShowMap(delegate(MapBehaviour m) + { + m.ShowCountOverlay(); + }); + } +} diff --git a/Client/Assembly-CSharp/MapCountOverlay.cs b/Client/Assembly-CSharp/MapCountOverlay.cs new file mode 100644 index 0000000..571b676 --- /dev/null +++ b/Client/Assembly-CSharp/MapCountOverlay.cs @@ -0,0 +1,90 @@ +using System; +using System.Linq; +using UnityEngine; + +public class MapCountOverlay : MonoBehaviour +{ + public AlphaPulse BackgroundColor; + + public TextRenderer SabotageText; + + public CounterArea[] CountAreas; + + private Collider2D[] buffer = new Collider2D[20]; + + private ContactFilter2D filter; + + private float timer; + + private bool isSab; + + public void Awake() + { + this.filter.useLayerMask = true; + this.filter.layerMask = Constants.PlayersOnlyMask; + this.filter.useTriggers = true; + } + + public void OnEnable() + { + this.BackgroundColor.SetColor(PlayerTask.PlayerHasHudTask(PlayerControl.LocalPlayer) ? Palette.DisabledGrey : Color.green); + this.timer = 1f; + } + + public void OnDisable() + { + for (int i = 0; i < this.CountAreas.Length; i++) + { + this.CountAreas[i].UpdateCount(0); + } + } + + public void Update() + { + this.timer += Time.deltaTime; + if (this.timer < 0.1f) + { + return; + } + this.timer = 0f; + if (!this.isSab && PlayerTask.PlayerHasHudTask(PlayerControl.LocalPlayer)) + { + this.isSab = true; + this.BackgroundColor.SetColor(Palette.DisabledGrey); + this.SabotageText.gameObject.SetActive(true); + return; + } + if (this.isSab && !PlayerTask.PlayerHasHudTask(PlayerControl.LocalPlayer)) + { + this.isSab = false; + this.BackgroundColor.SetColor(Color.green); + this.SabotageText.gameObject.SetActive(false); + } + for (int i = 0; i < this.CountAreas.Length; i++) + { + CounterArea area = this.CountAreas[i]; + if (!PlayerTask.PlayerHasHudTask(PlayerControl.LocalPlayer)) + { + int num = ShipStatus.Instance.AllRooms.First((ShipRoom r) => r.RoomId == area.RoomType).roomArea.OverlapCollider(this.filter, this.buffer); + int num2 = num; + for (int j = 0; j < num; j++) + { + Collider2D collider2D = this.buffer[j]; + if (!(collider2D.tag == "DeadBody")) + { + PlayerControl component = collider2D.GetComponent<PlayerControl>(); + if (!component || component.Data == null || component.Data.Disconnected || component.Data.IsDead) + { + num2--; + } + } + } + area.UpdateCount(num2); + } + else + { + area.UpdateCount(0); + } + } + } +} diff --git a/Client/Assembly-CSharp/MapRoom.cs b/Client/Assembly-CSharp/MapRoom.cs new file mode 100644 index 0000000..c25469c --- /dev/null +++ b/Client/Assembly-CSharp/MapRoom.cs @@ -0,0 +1,92 @@ +using System; +using UnityEngine; + +public class MapRoom : MonoBehaviour +{ + public InfectedOverlay Parent { get; set; } + + public SystemTypes room; + + public SpriteRenderer door; + + public SpriteRenderer special; + + public void Start() + { + if (this.door) + { + this.door.SetCooldownNormalizedUvs(); + } + if (this.special) + { + this.special.SetCooldownNormalizedUvs(); + } + } + + public void OOBUpdate() + { + if (this.door && ShipStatus.Instance) + { + float timer = ((DoorsSystemType)ShipStatus.Instance.Systems[SystemTypes.Doors]).GetTimer(this.room); + float value = this.Parent.CanUseDoors ? (timer / 30f) : 1f; + this.door.material.SetFloat("_Percent", value); + } + } + + internal void SetSpecialActive(float perc) + { + if (this.special) + { + this.special.material.SetFloat("_Percent", perc); + } + } + + public void SabotageReactor() + { + if (!this.Parent.CanUseSpecial) + { + return; + } + ShipStatus.Instance.RpcRepairSystem(SystemTypes.Sabotage, 3); + } + + public void SabotageComms() + { + if (!this.Parent.CanUseSpecial) + { + return; + } + ShipStatus.Instance.RpcRepairSystem(SystemTypes.Sabotage, 14); + } + + public void SabotageOxygen() + { + if (!this.Parent.CanUseSpecial) + { + return; + } + ShipStatus.Instance.RpcRepairSystem(SystemTypes.Sabotage, 8); + } + + public void SabotageLights() + { + if (!this.Parent.CanUseSpecial) + { + return; + } + ShipStatus.Instance.RpcRepairSystem(SystemTypes.Sabotage, 7); + } + + public void SabotageDoors() + { + if (!this.Parent.CanUseDoors) + { + return; + } + if (((DoorsSystemType)ShipStatus.Instance.Systems[SystemTypes.Doors]).GetTimer(this.room) > 0f) + { + return; + } + ShipStatus.Instance.RpcCloseDoorsOfType(this.room); + } +} diff --git a/Client/Assembly-CSharp/MapTaskOverlay.cs b/Client/Assembly-CSharp/MapTaskOverlay.cs new file mode 100644 index 0000000..cc70292 --- /dev/null +++ b/Client/Assembly-CSharp/MapTaskOverlay.cs @@ -0,0 +1,101 @@ +using System; +using System.Collections.Generic; +using UnityEngine; + +public class MapTaskOverlay : MonoBehaviour +{ + public ObjectPoolBehavior icons; + + private Dictionary<PlayerTask, PooledMapIcon> data = new Dictionary<PlayerTask, PooledMapIcon>(); + + public void Show() + { + base.gameObject.SetActive(true); + if (PlayerTask.PlayerHasHudTask(PlayerControl.LocalPlayer)) + { + return; + } + for (int i = 0; i < PlayerControl.LocalPlayer.myTasks.Count; i++) + { + PlayerTask playerTask = PlayerControl.LocalPlayer.myTasks[i]; + if (playerTask.HasLocation && !playerTask.IsComplete) + { + PooledMapIcon pooledMapIcon = this.icons.Get<PooledMapIcon>(); + pooledMapIcon.transform.localScale = new Vector3(pooledMapIcon.NormalSize, pooledMapIcon.NormalSize, pooledMapIcon.NormalSize); + if (PlayerTask.TaskIsEmergency(playerTask)) + { + pooledMapIcon.rend.color = Color.red; + pooledMapIcon.alphaPulse.enabled = true; + pooledMapIcon.rend.material.SetFloat("_Outline", 1f); + } + else + { + pooledMapIcon.rend.color = Color.yellow; + } + MapTaskOverlay.SetIconLocation(playerTask, pooledMapIcon); + this.data.Add(playerTask, pooledMapIcon); + } + } + } + + public void Update() + { + if (PlayerTask.PlayerHasHudTask(PlayerControl.LocalPlayer)) + { + return; + } + for (int i = 0; i < PlayerControl.LocalPlayer.myTasks.Count; i++) + { + PlayerTask playerTask = PlayerControl.LocalPlayer.myTasks[i]; + if (playerTask.HasLocation && !playerTask.IsComplete && playerTask.LocationDirty) + { + PooledMapIcon pooledMapIcon; + if (!this.data.TryGetValue(playerTask, out pooledMapIcon)) + { + pooledMapIcon = this.icons.Get<PooledMapIcon>(); + pooledMapIcon.transform.localScale = new Vector3(0.4f, 0.4f, 0.4f); + if (PlayerTask.TaskIsEmergency(playerTask)) + { + pooledMapIcon.rend.color = Color.red; + pooledMapIcon.alphaPulse.enabled = true; + pooledMapIcon.rend.material.SetFloat("_Outline", 1f); + } + else + { + pooledMapIcon.rend.color = Color.yellow; + } + this.data.Add(playerTask, pooledMapIcon); + } + MapTaskOverlay.SetIconLocation(playerTask, pooledMapIcon); + } + } + } + + private static void SetIconLocation(PlayerTask task, PooledMapIcon mapIcon) + { + if (mapIcon.lastMapTaskStep != task.TaskStep) + { + mapIcon.lastMapTaskStep = task.TaskStep; + Vector3 vector = task.Location; + vector /= ShipStatus.Instance.MapScale; + vector.z = -1f; + mapIcon.name = task.name; + mapIcon.transform.localPosition = vector; + if (task.TaskStep > 0) + { + mapIcon.alphaPulse.enabled = true; + mapIcon.rend.material.SetFloat("_Outline", 1f); + } + } + } + + public void Hide() + { + foreach (KeyValuePair<PlayerTask, PooledMapIcon> keyValuePair in this.data) + { + keyValuePair.Value.OwnerPool.Reclaim(keyValuePair.Value); + } + this.data.Clear(); + base.gameObject.SetActive(false); + } +} diff --git a/Client/Assembly-CSharp/MatchMaker.cs b/Client/Assembly-CSharp/MatchMaker.cs new file mode 100644 index 0000000..8c36a5c --- /dev/null +++ b/Client/Assembly-CSharp/MatchMaker.cs @@ -0,0 +1,41 @@ +using System; +using InnerNet; +using UnityEngine; + +public class MatchMaker : DestroyableSingleton<MatchMaker> +{ + public TextBox NameText; + + public TextBox GameIdText; + + private MonoBehaviour Connecter; + + public void Start() + { + if (this.GameIdText && AmongUsClient.Instance) + { + this.GameIdText.SetText(InnerNetClient.IntToGameName(AmongUsClient.Instance.GameId) ?? "", ""); + } + } + + public bool Connecting(MonoBehaviour button) + { + if (!this.Connecter) + { + this.Connecter = button; + ((IConnectButton)this.Connecter).StartIcon(); + return true; + } + base.StartCoroutine(Effects.Shake(this.Connecter.transform, 0.75f, 0.25f)); + return false; + } + + public void NotConnecting() + { + if (this.Connecter) + { + ((IConnectButton)this.Connecter).StopIcon(); + this.Connecter = null; + } + } +} diff --git a/Client/Assembly-CSharp/MatchMakerGameButton.cs b/Client/Assembly-CSharp/MatchMakerGameButton.cs new file mode 100644 index 0000000..64be6de --- /dev/null +++ b/Client/Assembly-CSharp/MatchMakerGameButton.cs @@ -0,0 +1,59 @@ +using System; +using System.Collections; +using InnerNet; +using PowerTools; +using UnityEngine; + +public class MatchMakerGameButton : PoolableBehavior, IConnectButton +{ + public TextRenderer NameText; + + public TextRenderer PlayerCountText; + + public TextRenderer ImpostorCountText; + + public SpriteAnim connectIcon; + + public AnimationClip connectClip; + + public GameListing myListing; + + public void OnClick() + { + if (!DestroyableSingleton<MatchMaker>.Instance.Connecting(this)) + { + return; + } + AmongUsClient.Instance.GameMode = GameModes.OnlineGame; + AmongUsClient.Instance.OnlineScene = "OnlineGame"; + AmongUsClient.Instance.GameId = this.myListing.GameId; + AmongUsClient.Instance.JoinGame(); + base.StartCoroutine(this.ConnectForFindGame()); + } + + private IEnumerator ConnectForFindGame() + { + yield return EndGameManager.WaitWithTimeout(() => AmongUsClient.Instance.ClientId >= 0 || AmongUsClient.Instance.LastDisconnectReason > DisconnectReasons.ExitGame); + DestroyableSingleton<MatchMaker>.Instance.NotConnecting(); + yield break; + } + + public void StartIcon() + { + this.connectIcon.Play(this.connectClip, 1f); + } + + public void StopIcon() + { + this.connectIcon.Stop(); + this.connectIcon.GetComponent<SpriteRenderer>().sprite = null; + } + + public void SetGame(GameListing gameListing) + { + this.myListing = gameListing; + this.NameText.Text = this.myListing.HostName; + this.ImpostorCountText.Text = this.myListing.ImpostorCount.ToString(); + this.PlayerCountText.Text = string.Format("{0}/{1}", this.myListing.PlayerCount, this.myListing.MaxPlayers); + } +} diff --git a/Client/Assembly-CSharp/MedScanMinigame.cs b/Client/Assembly-CSharp/MedScanMinigame.cs new file mode 100644 index 0000000..df940e2 --- /dev/null +++ b/Client/Assembly-CSharp/MedScanMinigame.cs @@ -0,0 +1,197 @@ +using System; +using System.Collections; +using System.Text; +using UnityEngine; + +public class MedScanMinigame : Minigame +{ + private static readonly string[] ColorNames = new string[] + { + "Red", + "Blue", + "Green", + "Pink", + "Orange", + "Yellow", + "Black", + "White", + "Purple", + "Brown", + "Cyan", + "Lime" + }; + + private static readonly string[] BloodTypes = new string[] + { + "O-", + "A-", + "B-", + "AB-", + "O+", + "A+", + "B+", + "AB+" + }; + + public TextRenderer text; + + public TextRenderer charStats; + + public HorizontalGauge gauge; + + private MedScanSystem medscan; + + public float ScanDuration = 10f; + + public float ScanTimer; + + private string completeString; + + public AudioClip ScanSound; + + public AudioClip TextSound; + + private Coroutine walking; + + private MedScanMinigame.PositionState state; + + private enum PositionState + { + None, + WalkingToPad, + WalkingToOffset + } + + public override void Begin(PlayerTask task) + { + base.Begin(task); + this.medscan = (ShipStatus.Instance.Systems[SystemTypes.MedBay] as MedScanSystem); + this.gauge.Value = 0f; + base.transform.position = new Vector3(100f, 0f, 0f); + GameData.PlayerInfo data = PlayerControl.LocalPlayer.Data; + int playerId = (int)data.PlayerId; + int colorId = (int)data.ColorId; + StringBuilder stringBuilder = new StringBuilder(); + stringBuilder.Append("ID: "); + stringBuilder.Append(MedScanMinigame.ColorNames[colorId].Substring(0, 3).ToUpperInvariant()); + stringBuilder.Append("P" + playerId); + stringBuilder.Append(new string(' ', 8)); + stringBuilder.Append("HT: 3' 6\""); + stringBuilder.Append(new string(' ', 8)); + stringBuilder.Append("WT: 92lb"); + stringBuilder.AppendLine(); + stringBuilder.Append("C: "); + stringBuilder.Append(MedScanMinigame.ColorNames[colorId].PadRight(17)); + stringBuilder.Append("BT: "); + stringBuilder.Append(MedScanMinigame.BloodTypes[playerId * 3 % MedScanMinigame.BloodTypes.Length]); + this.completeString = stringBuilder.ToString(); + this.charStats.Text = string.Empty; + ShipStatus.Instance.RpcRepairSystem(SystemTypes.MedBay, playerId | 128); + this.walking = base.StartCoroutine(this.WalkToOffset()); + } + + private IEnumerator WalkToOffset() + { + this.state = MedScanMinigame.PositionState.WalkingToOffset; + PlayerPhysics myPhysics = PlayerControl.LocalPlayer.MyPhysics; + Vector2 vector = ShipStatus.Instance.MedScanner.transform.position; + Vector2 a = Vector2.left.Rotate((float)(PlayerControl.LocalPlayer.PlayerId * 36)); + vector += a / 2f; + Camera.main.GetComponent<FollowerCamera>().Locked = false; + yield return myPhysics.WalkPlayerTo(vector, 0.001f); + yield return new WaitForSeconds(0.1f); + Camera.main.GetComponent<FollowerCamera>().Locked = true; + this.walking = null; + yield break; + } + + private IEnumerator WalkToPad() + { + this.state = MedScanMinigame.PositionState.WalkingToPad; + PlayerPhysics myPhysics = PlayerControl.LocalPlayer.MyPhysics; + Vector2 worldPos = ShipStatus.Instance.MedScanner.transform.position; + worldPos.x += 0.14f; + worldPos.y += 0.1f; + Camera.main.GetComponent<FollowerCamera>().Locked = false; + yield return myPhysics.WalkPlayerTo(worldPos, 0.001f); + yield return new WaitForSeconds(0.1f); + Camera.main.GetComponent<FollowerCamera>().Locked = true; + this.walking = null; + yield break; + } + + private void FixedUpdate() + { + if (this.MyNormTask.IsComplete) + { + return; + } + byte playerId = PlayerControl.LocalPlayer.PlayerId; + if (this.medscan.CurrentUser != playerId) + { + if (this.medscan.CurrentUser == 255) + { + this.text.Text = "Scan requested"; + return; + } + GameData.PlayerInfo playerById = GameData.Instance.GetPlayerById(this.medscan.CurrentUser); + this.text.Text = "Waiting for " + playerById.PlayerName; + return; + } + else + { + if (this.state != MedScanMinigame.PositionState.WalkingToPad) + { + if (this.walking != null) + { + base.StopCoroutine(this.walking); + } + this.walking = base.StartCoroutine(this.WalkToPad()); + return; + } + if (this.walking != null) + { + return; + } + if (this.ScanTimer == 0f) + { + PlayerControl.LocalPlayer.RpcSetScanner(true); + SoundManager.Instance.PlaySound(this.ScanSound, false, 1f); + } + this.ScanTimer += Time.fixedDeltaTime; + this.gauge.Value = this.ScanTimer / this.ScanDuration; + int num = (int)(Mathf.Min(1f, this.ScanTimer / this.ScanDuration * 1.25f) * (float)this.completeString.Length); + if (num > this.charStats.Text.Length) + { + this.charStats.Text = this.completeString.Substring(0, num); + if (this.completeString[num - 1] != ' ') + { + SoundManager.Instance.PlaySoundImmediate(this.TextSound, false, 0.7f, 0.3f); + } + } + if (this.ScanTimer >= this.ScanDuration) + { + PlayerControl.LocalPlayer.RpcSetScanner(false); + this.text.Text = "Scan complete"; + this.MyNormTask.NextStep(); + ShipStatus.Instance.RpcRepairSystem(SystemTypes.MedBay, (int)(playerId | 64)); + base.StartCoroutine(base.CoStartClose(0.75f)); + return; + } + this.text.Text = "Scan complete in: " + (int)(this.ScanDuration - this.ScanTimer); + return; + } + } + + public override void Close() + { + base.StopAllCoroutines(); + byte playerId = PlayerControl.LocalPlayer.PlayerId; + SoundManager.Instance.StopSound(this.TextSound); + SoundManager.Instance.StopSound(this.ScanSound); + PlayerControl.LocalPlayer.RpcSetScanner(false); + ShipStatus.Instance.RpcRepairSystem(SystemTypes.MedBay, (int)(playerId | 64)); + Camera.main.GetComponent<FollowerCamera>().Locked = false; + base.Close(); + } +} diff --git a/Client/Assembly-CSharp/MedScanSystem.cs b/Client/Assembly-CSharp/MedScanSystem.cs new file mode 100644 index 0000000..8a5f672 --- /dev/null +++ b/Client/Assembly-CSharp/MedScanSystem.cs @@ -0,0 +1,81 @@ +using System; +using System.Collections.Generic; +using Hazel; +using UnityEngine; + +public class MedScanSystem : ISystemType +{ + public byte CurrentUser { get; private set; } = byte.MaxValue; + + public const byte Request = 128; + + public const byte Release = 64; + + public const byte NumMask = 31; + + public const byte NoPlayer = 255; + + public List<byte> UsersList = new List<byte>(); + + public bool Detoriorate(float deltaTime) + { + if (this.UsersList.Count > 0) + { + if (this.CurrentUser != this.UsersList[0]) + { + if (this.CurrentUser != 255) + { + Debug.Log("Released scanner from: " + this.CurrentUser); + } + this.CurrentUser = this.UsersList[0]; + Debug.Log("Acquired scanner for: " + this.CurrentUser); + return true; + } + } + else if (this.CurrentUser != 255) + { + Debug.Log("Released scanner from: " + this.CurrentUser); + this.CurrentUser = byte.MaxValue; + return true; + } + return false; + } + + public void RepairDamage(PlayerControl player, byte data) + { + byte playerId = data & 31; + if ((data & 128) != 0) + { + if (!this.UsersList.Contains(playerId)) + { + Debug.Log("Added to queue: " + playerId); + this.UsersList.Add(playerId); + return; + } + } + else if ((data & 64) != 0) + { + Debug.Log("Removed from queue: " + playerId); + this.UsersList.RemoveAll((byte v) => v == playerId); + } + } + + public void Serialize(MessageWriter writer, bool initialState) + { + writer.WritePacked(this.UsersList.Count); + for (int i = 0; i < this.UsersList.Count; i++) + { + writer.Write(this.UsersList[i]); + } + } + + public void Deserialize(MessageReader reader, bool initialState) + { + this.UsersList.Clear(); + int num = reader.ReadPackedInt32(); + for (int i = 0; i < num; i++) + { + this.UsersList.Add(reader.ReadByte()); + } + } +} diff --git a/Client/Assembly-CSharp/MeetingHud.cs b/Client/Assembly-CSharp/MeetingHud.cs new file mode 100644 index 0000000..dbc22cb --- /dev/null +++ b/Client/Assembly-CSharp/MeetingHud.cs @@ -0,0 +1,734 @@ +using System; +using System.Collections; +using System.Linq; +using Assets.CoreScripts; +using Hazel; +using InnerNet; +using UnityEngine; + +public class MeetingHud : InnerNetObject, IDisconnectHandler +{ + private const float ResultsTime = 5f; + + private const float Depth = -100f; + + public static MeetingHud Instance; + + public Transform ButtonParent; + + public TextRenderer TitleText; + + public Vector3 VoteOrigin = new Vector3(-3.6f, 1.75f); + + public Vector3 VoteButtonOffsets = new Vector2(3.6f, -0.91f); + + private Vector3 CounterOrigin = new Vector2(0.5f, -0.13f); + + private Vector3 CounterOffsets = new Vector2(0.3f, 0f); + + public PlayerVoteArea SkipVoteButton; + + [HideInInspector] + private PlayerVoteArea[] playerStates; + + public PlayerVoteArea PlayerButtonPrefab; + + public SpriteRenderer PlayerVotePrefab; + + public Sprite CrackedGlass; + + public SpriteRenderer Glass; + + public PassiveButton ProceedButton; + + public ExileController ExileCutscenePrefab; + + public AudioClip VoteSound; + + public AudioClip VoteLockinSound; + + public AudioClip VoteEndingSound; + + private MeetingHud.VoteStates state; + + public SpriteRenderer SkippedVoting; + + public SpriteRenderer HostIcon; + + public Sprite KillBackground; + + private GameData.PlayerInfo exiledPlayer; + + private bool wasTie; + + public TextRenderer TimerText; + + public float discussionTimer; + + private byte reporterId; + + private bool amDead; + + private float resultsStartedAt; + + private int lastSecond = 10; + + public enum VoteStates + { + Discussion, + NotVoted, + Voted, + Results, + Proceeding + } + + private enum RpcCalls + { + Close, + VotingComplete, + CastVote, + ClearVote + } + + private void Awake() + { + if (!MeetingHud.Instance) + { + MeetingHud.Instance = this; + return; + } + if (MeetingHud.Instance != this) + { + UnityEngine.Object.Destroy(base.gameObject); + } + } + + private void Start() + { + DestroyableSingleton<HudManager>.Instance.Chat.gameObject.SetActive(true); + DestroyableSingleton<HudManager>.Instance.Chat.SetPosition(this); + DestroyableSingleton<HudManager>.Instance.StopOxyFlash(); + DestroyableSingleton<HudManager>.Instance.StopReactorFlash(); + this.SkipVoteButton.TargetPlayerId = -1; + this.SkipVoteButton.Parent = this; + Camera.main.GetComponent<FollowerCamera>().Locked = true; + if (PlayerControl.LocalPlayer.Data.IsDead) + { + this.SetForegroundForDead(); + } + AmongUsClient.Instance.DisconnectHandlers.AddUnique(this); + } + + private void SetForegroundForDead() + { + this.amDead = true; + this.SkipVoteButton.gameObject.SetActive(false); + this.Glass.sprite = this.CrackedGlass; + this.Glass.color = Color.white; + } + + public void Update() + { + this.discussionTimer += Time.deltaTime; + this.UpdateButtons(); + switch (this.state) + { + case MeetingHud.VoteStates.Discussion: + { + if (this.discussionTimer < (float)PlayerControl.GameOptions.DiscussionTime) + { + float f = (float)PlayerControl.GameOptions.DiscussionTime - this.discussionTimer; + this.TimerText.Text = string.Format("Voting Begins In: {0}s", Mathf.CeilToInt(f)); + for (int i = 0; i < this.playerStates.Length; i++) + { + this.playerStates[i].SetDisabled(); + } + this.SkipVoteButton.SetDisabled(); + return; + } + this.state = MeetingHud.VoteStates.NotVoted; + bool active = PlayerControl.GameOptions.VotingTime > 0; + this.TimerText.gameObject.SetActive(active); + for (int j = 0; j < this.playerStates.Length; j++) + { + this.playerStates[j].SetEnabled(); + } + this.SkipVoteButton.SetEnabled(); + return; + } + case MeetingHud.VoteStates.NotVoted: + case MeetingHud.VoteStates.Voted: + if (PlayerControl.GameOptions.VotingTime > 0) + { + float num = this.discussionTimer - (float)PlayerControl.GameOptions.DiscussionTime; + float f2 = Mathf.Max(0f, (float)PlayerControl.GameOptions.VotingTime - num); + this.TimerText.Text = string.Format("Voting Ends In: {0}s", Mathf.CeilToInt(f2)); + if (this.state == MeetingHud.VoteStates.NotVoted && Mathf.CeilToInt(f2) <= this.lastSecond) + { + this.lastSecond--; + base.StartCoroutine(Effects.PulseColor(this.TimerText, Color.red, Color.white, 0.25f)); + SoundManager.Instance.PlaySound(this.VoteEndingSound, false, 1f).pitch = Mathf.Lerp(1.5f, 0.8f, (float)this.lastSecond / 10f); + } + if (AmongUsClient.Instance.AmHost && num >= (float)PlayerControl.GameOptions.VotingTime) + { + this.ForceSkipAll(); + return; + } + } + break; + case MeetingHud.VoteStates.Results: + if (AmongUsClient.Instance.GameMode == GameModes.OnlineGame) + { + float num2 = this.discussionTimer - this.resultsStartedAt; + float num3 = Mathf.Max(0f, 5f - num2); + this.TimerText.Text = string.Format("Proceeding In: {0}s", Mathf.CeilToInt(num3)); + if (AmongUsClient.Instance.AmHost && num3 <= 0f) + { + this.HandleProceed(); + } + } + break; + default: + return; + } + } + + public IEnumerator CoIntro(PlayerControl reporter, GameData.PlayerInfo targetPlayer) + { + if (DestroyableSingleton<HudManager>.InstanceExists) + { + DestroyableSingleton<HudManager>.Instance.Chat.ForceClosed(); + base.transform.SetParent(DestroyableSingleton<HudManager>.Instance.transform); + base.transform.localPosition = new Vector3(0f, -10f, -100f); + DestroyableSingleton<HudManager>.Instance.SetHudActive(false); + } + OverlayKillAnimation killAnimPrefab = (targetPlayer == null) ? DestroyableSingleton<HudManager>.Instance.KillOverlay.EmergencyOverlay : DestroyableSingleton<HudManager>.Instance.KillOverlay.ReportOverlay; + DestroyableSingleton<HudManager>.Instance.KillOverlay.ShowOne(killAnimPrefab, reporter, targetPlayer); + yield return DestroyableSingleton<HudManager>.Instance.KillOverlay.WaitForFinish(); + Vector3 temp = new Vector3(0f, 0f, -50f); + for (float timer = 0f; timer < 0.25f; timer += Time.deltaTime) + { + float t = timer / 0.25f; + temp.y = Mathf.SmoothStep(-10f, 0f, t); + base.transform.localPosition = temp; + yield return null; + } + temp.y = 0f; + base.transform.localPosition = temp; + this.TitleText.Text = "Who Is The Impostor?"; + if (!PlayerControl.LocalPlayer.Data.IsDead) + { + yield return DestroyableSingleton<HudManager>.Instance.ShowEmblem(false); + } + for (int i = 0; i < this.playerStates.Length; i++) + { + base.StartCoroutine(this.playerStates[i].CoAnimateOverlay()); + } + yield break; + } + + private IEnumerator CoStartCutscene() + { + yield return DestroyableSingleton<HudManager>.Instance.CoFadeFullScreen(Color.clear, Color.black, 1f); + ExileController exileController = UnityEngine.Object.Instantiate<ExileController>(this.ExileCutscenePrefab); + exileController.transform.SetParent(DestroyableSingleton<HudManager>.Instance.transform, false); + exileController.transform.localPosition = new Vector3(0f, 0f, -60f); + exileController.Begin(this.exiledPlayer, this.wasTie); + this.DespawnOnDestroy = false; + UnityEngine.Object.Destroy(base.gameObject); + yield break; + } + + public void ServerStart(byte reporter) + { + this.reporterId = reporter; + this.PopulateButtons(reporter); + } + + public void Close() + { + GameData.PlayerInfo data = PlayerControl.LocalPlayer.Data; + DestroyableSingleton<HudManager>.Instance.Chat.SetPosition(null); + DestroyableSingleton<HudManager>.Instance.Chat.SetVisible(data.IsDead); + base.StartCoroutine(this.CoStartCutscene()); + } + + private void VotingComplete(byte[] states, GameData.PlayerInfo exiled, bool tie) + { + if (this.state == MeetingHud.VoteStates.Results) + { + return; + } + this.state = MeetingHud.VoteStates.Results; + this.resultsStartedAt = this.discussionTimer; + this.exiledPlayer = exiled; + this.wasTie = tie; + this.SkipVoteButton.gameObject.SetActive(false); + this.SkippedVoting.gameObject.SetActive(true); + AmongUsClient.Instance.DisconnectHandlers.Remove(this); + this.PopulateResults(states); + this.SetupProceedButton(); + } + + public bool Select(int suspectStateIdx) + { + if (this.discussionTimer < (float)PlayerControl.GameOptions.DiscussionTime) + { + return false; + } + if (PlayerControl.LocalPlayer.Data.IsDead) + { + return false; + } + SoundManager.Instance.PlaySound(this.VoteSound, false, 1f).volume = 0.8f; + for (int i = 0; i < this.playerStates.Length; i++) + { + PlayerVoteArea playerVoteArea = this.playerStates[i]; + if (suspectStateIdx != (int)playerVoteArea.TargetPlayerId) + { + playerVoteArea.ClearButtons(); + } + } + if (suspectStateIdx != -1) + { + this.SkipVoteButton.ClearButtons(); + } + return true; + } + + public void Confirm(sbyte suspectStateIdx) + { + if (PlayerControl.LocalPlayer.Data.IsDead) + { + return; + } + for (int i = 0; i < this.playerStates.Length; i++) + { + PlayerVoteArea playerVoteArea = this.playerStates[i]; + playerVoteArea.ClearButtons(); + playerVoteArea.voteComplete = true; + } + this.SkipVoteButton.ClearButtons(); + this.SkipVoteButton.voteComplete = true; + this.SkipVoteButton.gameObject.SetActive(false); + MeetingHud.VoteStates voteStates = this.state; + if (voteStates != MeetingHud.VoteStates.NotVoted) + { + return; + } + this.state = MeetingHud.VoteStates.Voted; + this.CmdCastVote(PlayerControl.LocalPlayer.PlayerId, suspectStateIdx); + } + + public void HandleDisconnect(PlayerControl pc, DisconnectReasons reason) + { + if (!AmongUsClient.Instance.AmHost) + { + return; + } + int num = this.playerStates.IndexOf((PlayerVoteArea pv) => pv.TargetPlayerId == (sbyte)pc.PlayerId); + PlayerVoteArea playerVoteArea = this.playerStates[num]; + playerVoteArea.isDead = true; + playerVoteArea.Overlay.gameObject.SetActive(true); + for (int i = 0; i < this.playerStates.Length; i++) + { + PlayerVoteArea playerVoteArea2 = this.playerStates[i]; + if (!playerVoteArea2.isDead && playerVoteArea2.didVote && playerVoteArea2.votedFor == (sbyte)pc.PlayerId) + { + playerVoteArea2.UnsetVote(); + base.SetDirtyBit(1U << i); + GameData.PlayerInfo playerById = GameData.Instance.GetPlayerById((byte)playerVoteArea2.TargetPlayerId); + if (playerById != null) + { + int clientIdFromCharacter = AmongUsClient.Instance.GetClientIdFromCharacter(playerById.Object); + if (clientIdFromCharacter != -1) + { + this.RpcClearVote(clientIdFromCharacter); + } + } + } + } + base.SetDirtyBit(1U << num); + this.CheckForEndVoting(); + if (this.state == MeetingHud.VoteStates.Results) + { + this.SetupProceedButton(); + } + } + + public void HandleDisconnect() + { + } + + private void ForceSkipAll() + { + for (int i = 0; i < this.playerStates.Length; i++) + { + PlayerVoteArea playerVoteArea = this.playerStates[i]; + if (!playerVoteArea.didVote) + { + playerVoteArea.didVote = true; + playerVoteArea.votedFor = -2; + base.SetDirtyBit(1U << i); + } + } + this.CheckForEndVoting(); + } + + public void CastVote(byte srcPlayerId, sbyte suspectPlayerId) + { + int num = this.playerStates.IndexOf((PlayerVoteArea pv) => pv.TargetPlayerId == (sbyte)srcPlayerId); + PlayerVoteArea playerVoteArea = this.playerStates[num]; + if (!playerVoteArea.isDead && !playerVoteArea.didVote) + { + if (PlayerControl.LocalPlayer.PlayerId == srcPlayerId || AmongUsClient.Instance.GameMode != GameModes.LocalGame) + { + SoundManager.Instance.PlaySound(this.VoteLockinSound, false, 1f); + } + playerVoteArea.SetVote(suspectPlayerId); + base.SetDirtyBit(1U << num); + this.CheckForEndVoting(); + PlayerControl.LocalPlayer.RpcSendChatNote(srcPlayerId, ChatNoteTypes.DidVote); + } + } + + public void ClearVote() + { + for (int i = 0; i < this.playerStates.Length; i++) + { + this.playerStates[i].voteComplete = false; + } + this.SkipVoteButton.voteComplete = false; + this.SkipVoteButton.gameObject.SetActive(true); + this.state = MeetingHud.VoteStates.NotVoted; + } + + private void CheckForEndVoting() + { + if (this.playerStates.All((PlayerVoteArea ps) => ps.isDead || ps.didVote)) + { + byte[] self = this.CalculateVotes(); + bool tie; + int maxIdx = self.IndexOfMax((byte p) => (int)p, out tie) - 1; + GameData.PlayerInfo exiled = GameData.Instance.AllPlayers.FirstOrDefault((GameData.PlayerInfo v) => (int)v.PlayerId == maxIdx); + byte[] states = (from ps in this.playerStates + select ps.GetState()).ToArray<byte>(); + this.RpcVotingComplete(states, exiled, tie); + } + } + + private byte[] CalculateVotes() + { + byte[] array = new byte[11]; + for (int i = 0; i < this.playerStates.Length; i++) + { + PlayerVoteArea playerVoteArea = this.playerStates[i]; + if (playerVoteArea.didVote) + { + int num = (int)(playerVoteArea.votedFor + 1); + if (num >= 0 && num < array.Length) + { + byte[] array2 = array; + int num2 = num; + array2[num2] += 1; + } + } + } + return array; + } + + public override bool Serialize(MessageWriter writer, bool initialState) + { + if (this.playerStates == null) + { + return false; + } + if (initialState) + { + for (int i = 0; i < this.playerStates.Length; i++) + { + this.playerStates[i].Serialize(writer); + } + } + else + { + writer.WritePacked(this.DirtyBits); + for (int j = 0; j < this.playerStates.Length; j++) + { + if ((this.DirtyBits & 1U << j) != 0U) + { + this.playerStates[j].Serialize(writer); + } + } + } + this.DirtyBits = 0U; + return true; + } + + public override void Deserialize(MessageReader reader, bool initialState) + { + if (initialState) + { + MeetingHud.Instance = this; + this.PopulateButtons(0); + for (int i = 0; i < this.playerStates.Length; i++) + { + PlayerVoteArea playerVoteArea = this.playerStates[i]; + playerVoteArea.Deserialize(reader); + if (playerVoteArea.didReport) + { + this.reporterId = (byte)playerVoteArea.TargetPlayerId; + } + } + return; + } + uint num = reader.ReadPackedUInt32(); + for (int j = 0; j < this.playerStates.Length; j++) + { + if ((num & 1U << j) != 0U) + { + this.playerStates[j].Deserialize(reader); + } + } + } + + public void HandleProceed() + { + if (!AmongUsClient.Instance.AmHost) + { + base.StartCoroutine(Effects.Shake(this.HostIcon.transform, 0.75f, 0.25f)); + return; + } + if (this.state != MeetingHud.VoteStates.Results) + { + return; + } + this.state = MeetingHud.VoteStates.Proceeding; + this.RpcClose(); + } + + private void SetupProceedButton() + { + if (AmongUsClient.Instance.GameMode != GameModes.OnlineGame) + { + this.TimerText.gameObject.SetActive(false); + this.ProceedButton.gameObject.SetActive(true); + this.HostIcon.gameObject.SetActive(true); + GameData.PlayerInfo host = GameData.Instance.GetHost(); + if (host != null) + { + PlayerControl.SetPlayerMaterialColors((int)host.ColorId, this.HostIcon); + return; + } + this.HostIcon.enabled = false; + } + } + + private void PopulateResults(byte[] states) + { + DestroyableSingleton<Telemetry>.Instance.WriteMeetingEnded(states, this.discussionTimer); + this.TitleText.Text = "Voting Results"; + int num = 0; + for (int i = 0; i < this.playerStates.Length; i++) + { + PlayerVoteArea playerVoteArea = this.playerStates[i]; + playerVoteArea.ClearForResults(); + int num2 = 0; + for (int j = 0; j < this.playerStates.Length; j++) + { + if (!states[j].HasAnyBit(128)) + { + GameData.PlayerInfo playerById = GameData.Instance.GetPlayerById((byte)this.playerStates[j].TargetPlayerId); + int num3 = (int)((states[j] & 15) - 1); + if (num3 == (int)playerVoteArea.TargetPlayerId) + { + SpriteRenderer spriteRenderer = UnityEngine.Object.Instantiate<SpriteRenderer>(this.PlayerVotePrefab); + PlayerControl.SetPlayerMaterialColors((int)playerById.ColorId, spriteRenderer); + spriteRenderer.transform.SetParent(playerVoteArea.transform); + spriteRenderer.transform.localPosition = this.CounterOrigin + new Vector3(this.CounterOffsets.x * (float)num2, 0f, 0f); + spriteRenderer.transform.localScale = Vector3.zero; + base.StartCoroutine(Effects.Bloop((float)num2 * 0.5f, spriteRenderer.transform, 0.5f)); + num2++; + } + else if (i == 0 && num3 == -1) + { + SpriteRenderer spriteRenderer2 = UnityEngine.Object.Instantiate<SpriteRenderer>(this.PlayerVotePrefab); + PlayerControl.SetPlayerMaterialColors((int)playerById.ColorId, spriteRenderer2); + spriteRenderer2.transform.SetParent(this.SkippedVoting.transform); + spriteRenderer2.transform.localPosition = this.CounterOrigin + new Vector3(this.CounterOffsets.x * (float)num, 0f, 0f); + spriteRenderer2.transform.localScale = Vector3.zero; + base.StartCoroutine(Effects.Bloop((float)num * 0.5f, spriteRenderer2.transform, 0.5f)); + num++; + } + } + } + } + } + + private void UpdateButtons() + { + if (PlayerControl.LocalPlayer.Data.IsDead && !this.amDead) + { + this.SetForegroundForDead(); + } + if (AmongUsClient.Instance.AmHost) + { + for (int i = 0; i < this.playerStates.Length; i++) + { + PlayerVoteArea playerVoteArea = this.playerStates[i]; + GameData.PlayerInfo playerById = GameData.Instance.GetPlayerById((byte)playerVoteArea.TargetPlayerId); + if (playerById == null) + { + playerVoteArea.SetDisabled(); + } + else + { + bool flag = playerById.Disconnected || playerById.IsDead; + if (flag != playerVoteArea.isDead) + { + playerVoteArea.SetDead(playerById.PlayerId == PlayerControl.LocalPlayer.PlayerId, this.reporterId == playerById.PlayerId, flag); + base.SetDirtyBit(1U << i); + } + } + } + } + } + + private void PopulateButtons(byte reporter) + { + this.playerStates = new PlayerVoteArea[GameData.Instance.PlayerCount]; + for (int i = 0; i < this.playerStates.Length; i++) + { + GameData.PlayerInfo playerInfo = GameData.Instance.AllPlayers[i]; + PlayerVoteArea playerVoteArea = this.playerStates[i] = this.CreateButton(playerInfo); + playerVoteArea.Parent = this; + playerVoteArea.TargetPlayerId = (sbyte)playerInfo.PlayerId; + playerVoteArea.SetDead(playerInfo.PlayerId == PlayerControl.LocalPlayer.PlayerId, reporter == playerInfo.PlayerId, playerInfo.Disconnected || playerInfo.IsDead); + } + this.SortButtons(); + } + + private void SortButtons() + { + PlayerVoteArea[] array = this.playerStates.OrderBy(delegate(PlayerVoteArea p) + { + if (!p.isDead) + { + return 0; + } + return 50; + }).ThenBy((PlayerVoteArea p) => p.TargetPlayerId).ToArray<PlayerVoteArea>(); + for (int i = 0; i < array.Length; i++) + { + int num = i % 2; + int num2 = i / 2; + array[i].transform.localPosition = this.VoteOrigin + new Vector3(this.VoteButtonOffsets.x * (float)num, this.VoteButtonOffsets.y * (float)num2, -1f); + } + } + + private PlayerVoteArea CreateButton(GameData.PlayerInfo playerInfo) + { + PlayerVoteArea playerVoteArea = UnityEngine.Object.Instantiate<PlayerVoteArea>(this.PlayerButtonPrefab, this.ButtonParent.transform); + PlayerControl.SetPlayerMaterialColors((int)playerInfo.ColorId, playerVoteArea.PlayerIcon); + playerVoteArea.NameText.Text = playerInfo.PlayerName; + bool flag = PlayerControl.LocalPlayer.Data.IsImpostor && playerInfo.IsImpostor; + playerVoteArea.NameText.Color = (flag ? Palette.ImpostorRed : Color.white); + playerVoteArea.transform.localScale = Vector3.one; + return playerVoteArea; + } + + public bool DidVote(byte playerId) + { + return this.playerStates.First((PlayerVoteArea p) => p.TargetPlayerId == (sbyte)playerId).didVote; + } + + public int GetVotesRemaining() + { + int result; + try + { + result = this.playerStates.Count((PlayerVoteArea ps) => !ps.isDead && !ps.didVote); + } + catch + { + result = 0; + } + return result; + } + + public void RpcClose() + { + if (AmongUsClient.Instance.AmClient) + { + this.Close(); + } + AmongUsClient.Instance.SendRpc(this.NetId, 0, SendOption.Reliable); + } + + public void CmdCastVote(byte playerId, sbyte suspectIdx) + { + if (AmongUsClient.Instance.AmHost) + { + this.CastVote(playerId, suspectIdx); + return; + } + MessageWriter messageWriter = AmongUsClient.Instance.StartRpcImmediately(this.NetId, 2, SendOption.Reliable, AmongUsClient.Instance.HostId); + messageWriter.Write(playerId); + messageWriter.Write(suspectIdx); + AmongUsClient.Instance.FinishRpcImmediately(messageWriter); + } + + private void RpcVotingComplete(byte[] states, GameData.PlayerInfo exiled, bool tie) + { + if (AmongUsClient.Instance.AmClient) + { + this.VotingComplete(states, exiled, tie); + } + MessageWriter messageWriter = AmongUsClient.Instance.StartRpc(this.NetId, 1, SendOption.Reliable); + messageWriter.WriteBytesAndSize(states); + messageWriter.Write((exiled != null) ? exiled.PlayerId : byte.MaxValue); + messageWriter.Write(tie); + messageWriter.EndMessage(); + } + + private void RpcClearVote(int clientId) + { + if (AmongUsClient.Instance.ClientId == clientId) + { + this.ClearVote(); + return; + } + MessageWriter msg = AmongUsClient.Instance.StartRpcImmediately(this.NetId, 3, SendOption.Reliable, clientId); + AmongUsClient.Instance.FinishRpcImmediately(msg); + } + + public override void HandleRpc(byte callId, MessageReader reader) + { + switch (callId) + { + case 0: + this.Close(); + return; + case 1: + { + byte[] states = reader.ReadBytesAndSize(); + GameData.PlayerInfo playerById = GameData.Instance.GetPlayerById(reader.ReadByte()); + bool tie = reader.ReadBoolean(); + this.VotingComplete(states, playerById, tie); + return; + } + case 2: + { + byte srcPlayerId = reader.ReadByte(); + sbyte suspectPlayerId = reader.ReadSByte(); + this.CastVote(srcPlayerId, suspectPlayerId); + return; + } + case 3: + this.ClearVote(); + return; + default: + return; + } + } +} diff --git a/Client/Assembly-CSharp/MeetingRoomManager.cs b/Client/Assembly-CSharp/MeetingRoomManager.cs new file mode 100644 index 0000000..dcb519f --- /dev/null +++ b/Client/Assembly-CSharp/MeetingRoomManager.cs @@ -0,0 +1,36 @@ +using System; +using InnerNet; + +public class MeetingRoomManager : IDisconnectHandler +{ + public static readonly MeetingRoomManager Instance = new MeetingRoomManager(); + + private PlayerControl reporter; + + private GameData.PlayerInfo target; + + public void AssignSelf(PlayerControl reporter, GameData.PlayerInfo target) + { + this.reporter = reporter; + this.target = target; + AmongUsClient.Instance.DisconnectHandlers.AddUnique(this); + } + + public void RemoveSelf() + { + AmongUsClient.Instance.DisconnectHandlers.Remove(this); + } + + public void HandleDisconnect(PlayerControl pc, DisconnectReasons reason) + { + if (AmongUsClient.Instance.AmHost) + { + this.reporter.CmdReportDeadBody(this.target); + } + } + + public void HandleDisconnect() + { + this.HandleDisconnect(null, DisconnectReasons.ExitGame); + } +} diff --git a/Client/Assembly-CSharp/MemSafeStringExtensions.cs b/Client/Assembly-CSharp/MemSafeStringExtensions.cs new file mode 100644 index 0000000..034b2bc --- /dev/null +++ b/Client/Assembly-CSharp/MemSafeStringExtensions.cs @@ -0,0 +1,37 @@ +using System; +using System.Collections.Generic; + +public static class MemSafeStringExtensions +{ + public static void SafeSplit(this SubString subString, List<SubString> output, char delim) + { + subString.Source.SafeSplit(output, delim, subString.Start, subString.Length); + } + + public static void SafeSplit(this string source, List<SubString> output, char delim) + { + source.SafeSplit(output, delim, 0, source.Length); + } + + public static void SafeSplit(this string source, List<SubString> output, char delim, int start, int length) + { + output.Clear(); + int num = start; + int num2 = start + length; + for (int i = start; i < num2; i++) + { + if (source[i] == delim) + { + if (num != i) + { + output.Add(new SubString(source, num, i - num)); + } + num = i + 1; + } + } + if (num != num2) + { + output.Add(new SubString(source, num, num2 - num)); + } + } +} diff --git a/Client/Assembly-CSharp/MeshRendererExtensions.cs b/Client/Assembly-CSharp/MeshRendererExtensions.cs new file mode 100644 index 0000000..dddc50d --- /dev/null +++ b/Client/Assembly-CSharp/MeshRendererExtensions.cs @@ -0,0 +1,23 @@ +using System; +using UnityEngine; + +public static class MeshRendererExtensions +{ + public static void SetSprite(this MeshRenderer self, Texture2D spr) + { + if (spr != null) + { + self.SetCutout(spr); + self.material.color = Color.white; + return; + } + self.SetCutout(null); + self.material.color = Color.clear; + } + + public static void SetCutout(this MeshRenderer self, Texture2D txt) + { + self.material.SetTexture("_MainTex", txt); + self.material.SetTexture("_EmissionMap", txt); + } +} diff --git a/Client/Assembly-CSharp/Minigame.cs b/Client/Assembly-CSharp/Minigame.cs new file mode 100644 index 0000000..0897e13 --- /dev/null +++ b/Client/Assembly-CSharp/Minigame.cs @@ -0,0 +1,166 @@ +using System; +using System.Collections; +using UnityEngine; + +public abstract class Minigame : MonoBehaviour +{ + public global::Console Console { get; set; } + + protected int ConsoleId + { + get + { + if (!this.Console) + { + return 0; + } + return this.Console.ConsoleId; + } + } + + public static Minigame Instance; + + public const float Depth = -50f; + + public TransitionType TransType; + + protected PlayerTask MyTask; + + protected NormalPlayerTask MyNormTask; + + protected Minigame.CloseState amClosing; + + public AudioClip OpenSound; + + public AudioClip CloseSound; + + protected enum CloseState + { + None, + Waiting, + Closing + } + + public virtual void Begin(PlayerTask task) + { + Minigame.Instance = this; + this.MyTask = task; + this.MyNormTask = (task as NormalPlayerTask); + if (PlayerControl.LocalPlayer) + { + if (MapBehaviour.Instance) + { + MapBehaviour.Instance.Close(); + } + PlayerControl.LocalPlayer.NetTransform.Halt(); + } + base.StartCoroutine(this.CoAnimateOpen()); + } + + protected IEnumerator CoStartClose(float duration = 0.75f) + { + if (this.amClosing != Minigame.CloseState.None) + { + yield break; + } + this.amClosing = Minigame.CloseState.Waiting; + yield return Effects.Wait(duration); + this.Close(); + yield break; + } + + [Obsolete("Don't use, I just don't want to reselect the close button event handlers", true)] + public void Close(bool allowMovement) + { + this.Close(); + } + + public virtual void Close() + { + if (this.amClosing != Minigame.CloseState.Closing) + { + if (this.CloseSound && Constants.ShouldPlaySfx()) + { + SoundManager.Instance.PlaySound(this.CloseSound, false, 1f); + } + this.amClosing = Minigame.CloseState.Closing; + base.StartCoroutine(this.CoDestroySelf()); + return; + } + UnityEngine.Object.Destroy(base.gameObject); + } + + protected virtual IEnumerator CoAnimateOpen() + { + if (this.OpenSound && Constants.ShouldPlaySfx()) + { + SoundManager.Instance.PlaySound(this.OpenSound, false, 1f); + } + TransitionType transType = this.TransType; + if (transType != TransitionType.SlideBottom) + { + if (transType == TransitionType.Alpha) + { + SpriteRenderer[] rends = base.GetComponentsInChildren<SpriteRenderer>(); + for (float timer = 0f; timer < 0.25f; timer += Time.deltaTime) + { + float t = timer / 0.25f; + for (int i = 0; i < rends.Length; i++) + { + rends[i].color = Color.Lerp(Palette.ClearWhite, Color.white, t); + } + yield return null; + } + for (int j = 0; j < rends.Length; j++) + { + rends[j].color = Color.white; + } + rends = null; + } + } + else + { + for (float timer = 0f; timer < 0.25f; timer += Time.deltaTime) + { + float t2 = timer / 0.25f; + base.transform.localPosition = new Vector3(0f, Mathf.SmoothStep(-8f, 0f, t2), -50f); + yield return null; + } + base.transform.localPosition = new Vector3(0f, 0f, -50f); + } + yield break; + } + + protected virtual IEnumerator CoDestroySelf() + { + TransitionType transType = this.TransType; + if (transType != TransitionType.SlideBottom) + { + if (transType == TransitionType.Alpha) + { + SpriteRenderer[] rends = base.GetComponentsInChildren<SpriteRenderer>(); + for (float timer = 0f; timer < 0.25f; timer += Time.deltaTime) + { + float t = timer / 0.25f; + for (int i = 0; i < rends.Length; i++) + { + rends[i].color = Color.Lerp(Color.white, Palette.ClearWhite, t); + } + yield return null; + } + rends = null; + } + } + else + { + for (float timer = 0f; timer < 0.25f; timer += Time.deltaTime) + { + float t2 = timer / 0.25f; + base.transform.localPosition = new Vector3(0f, Mathf.SmoothStep(0f, -8f, t2), -50f); + yield return null; + } + } + UnityEngine.Object.Destroy(base.gameObject); + yield break; + } +} diff --git a/Client/Assembly-CSharp/MonoPInvokeCallbackAttribute.cs b/Client/Assembly-CSharp/MonoPInvokeCallbackAttribute.cs new file mode 100644 index 0000000..96960fe --- /dev/null +++ b/Client/Assembly-CSharp/MonoPInvokeCallbackAttribute.cs @@ -0,0 +1,8 @@ +using System; + +public sealed class MonoPInvokeCallbackAttribute : Attribute +{ + public MonoPInvokeCallbackAttribute(Type type) + { + } +} diff --git a/Client/Assembly-CSharp/NameTextBehaviour.cs b/Client/Assembly-CSharp/NameTextBehaviour.cs new file mode 100644 index 0000000..83a3ad7 --- /dev/null +++ b/Client/Assembly-CSharp/NameTextBehaviour.cs @@ -0,0 +1,61 @@ +using System; +using UnityEngine; +using UnityEngine.Events; + +public class NameTextBehaviour : MonoBehaviour +{ + public static NameTextBehaviour Instance; + + public TextBox nameSource; + + public void Start() + { + NameTextBehaviour.Instance = this; + this.nameSource.SetText(SaveManager.PlayerName, ""); + this.nameSource.OnFocusLost.AddListener(new UnityAction(this.UpdateName)); + } + + public void UpdateName() + { + if (this.ShakeIfInvalid()) + { + return; + } + SaveManager.PlayerName = this.nameSource.text; + } + + public static bool IsValidName(string text) + { + if (text == null || text.Length == 0) + { + return false; + } + if (text.Equals("Enter Name", StringComparison.OrdinalIgnoreCase)) + { + return false; + } + if (BlockedWords.ContainsWord(text)) + { + return false; + } + bool result = false; + for (int i = 0; i < text.Length; i++) + { + if (text[i] != ' ') + { + result = true; + } + } + return result; + } + + public bool ShakeIfInvalid() + { + if (!NameTextBehaviour.IsValidName(this.nameSource.text)) + { + base.StartCoroutine(Effects.Shake(this.nameSource.transform, 0.75f, 0.25f)); + return true; + } + return false; + } +} diff --git a/Client/Assembly-CSharp/NavigationMinigame.cs b/Client/Assembly-CSharp/NavigationMinigame.cs new file mode 100644 index 0000000..6e789e2 --- /dev/null +++ b/Client/Assembly-CSharp/NavigationMinigame.cs @@ -0,0 +1,88 @@ +using System; +using System.Collections; +using UnityEngine; + +public class NavigationMinigame : Minigame +{ + public MeshRenderer TwoAxisImage; + + public SpriteRenderer CrossHairImage; + + public Collider2D hitbox; + + private Controller myController = new Controller(); + + private Vector2 crossHair; + + private Vector2 half = new Vector2(0.5f, 0.5f); + + public override void Begin(PlayerTask task) + { + base.Begin(task); + this.crossHair = UnityEngine.Random.insideUnitCircle.normalized / 2f * 0.6f; + Vector3 localPosition = new Vector3(this.crossHair.x * this.TwoAxisImage.bounds.size.x, this.crossHair.y * this.TwoAxisImage.bounds.size.y, -2f); + this.CrossHairImage.transform.localPosition = localPosition; + this.TwoAxisImage.material.SetVector("_CrossHair", this.crossHair + this.half); + } + + public void FixedUpdate() + { + if (this.MyNormTask && this.MyNormTask.IsComplete) + { + return; + } + this.myController.Update(); + DragState dragState = this.myController.CheckDrag(this.hitbox, false); + if (dragState != DragState.Dragging) + { + if (dragState != DragState.Released) + { + return; + } + if ((this.crossHair - this.half).magnitude < 0.05f) + { + base.StartCoroutine(this.CompleteGame()); + this.MyNormTask.NextStep(); + } + } + else + { + Vector2 dragPosition = this.myController.DragPosition; + Vector2 a = dragPosition - (this.TwoAxisImage.transform.position - this.TwoAxisImage.bounds.size / 2f); + this.crossHair = a.Div(this.TwoAxisImage.bounds.size); + if ((this.crossHair - this.half).magnitude < 0.45f) + { + Vector3 localPosition = dragPosition - base.transform.position; + localPosition.z = -2f; + this.CrossHairImage.transform.localPosition = localPosition; + this.TwoAxisImage.material.SetVector("_CrossHair", this.crossHair); + return; + } + } + } + + private IEnumerator CompleteGame() + { + WaitForSeconds wait = new WaitForSeconds(0.1f); + Color green = new Color(0f, 0.8f, 0f, 1f); + Color32 yellow = new Color32(byte.MaxValue, 202, 0, byte.MaxValue); + this.CrossHairImage.transform.localPosition = new Vector3(0f, 0f, -2f); + this.TwoAxisImage.material.SetVector("_CrossHair", this.half); + this.CrossHairImage.color = yellow; + this.TwoAxisImage.material.SetColor("_CrossColor", yellow); + yield return wait; + this.CrossHairImage.color = Color.white; + this.TwoAxisImage.material.SetColor("_CrossColor", Color.white); + yield return wait; + this.CrossHairImage.color = yellow; + this.TwoAxisImage.material.SetColor("_CrossColor", yellow); + yield return wait; + this.CrossHairImage.color = Color.white; + this.TwoAxisImage.material.SetColor("_CrossColor", Color.white); + yield return wait; + this.CrossHairImage.color = green; + this.TwoAxisImage.material.SetColor("_CrossColor", green); + yield return base.CoStartClose(0.75f); + yield break; + } +} diff --git a/Client/Assembly-CSharp/NoOxyTask.cs b/Client/Assembly-CSharp/NoOxyTask.cs new file mode 100644 index 0000000..47f9e88 --- /dev/null +++ b/Client/Assembly-CSharp/NoOxyTask.cs @@ -0,0 +1,106 @@ +using System; +using System.Linq; +using System.Text; +using UnityEngine; + +public class NoOxyTask : SabotageTask +{ + public override int TaskStep + { + get + { + return this.reactor.UserCount; + } + } + + public override bool IsComplete + { + get + { + return this.isComplete; + } + } + + private bool isComplete; + + private LifeSuppSystemType reactor; + + private bool even; + + public int targetNumber; + + public override void Initialize() + { + this.targetNumber = IntRange.Next(0, 99999); + ShipStatus instance = ShipStatus.Instance; + this.reactor = (LifeSuppSystemType)instance.Systems[SystemTypes.LifeSupp]; + DestroyableSingleton<HudManager>.Instance.StartOxyFlash(); + base.SetupArrows(); + } + + private void FixedUpdate() + { + if (this.isComplete) + { + return; + } + if (!this.reactor.IsActive) + { + this.Complete(); + return; + } + for (int i = 0; i < this.Arrows.Length; i++) + { + this.Arrows[i].gameObject.SetActive(!this.reactor.GetConsoleComplete(i)); + } + } + + public override bool ValidConsole(global::Console console) + { + return !this.reactor.GetConsoleComplete(console.ConsoleId) && console.TaskTypes.Contains(TaskTypes.RestoreOxy); + } + + public override void OnRemove() + { + } + + public override void Complete() + { + this.isComplete = true; + PlayerControl.LocalPlayer.RemoveTask(this); + if (this.didContribute) + { + StatsManager instance = StatsManager.Instance; + uint sabsFixed = instance.SabsFixed; + instance.SabsFixed = sabsFixed + 1U; + } + } + + public override void AppendTaskText(StringBuilder sb) + { + this.even = !this.even; + Color color = this.even ? Color.yellow : Color.red; + if (this.reactor != null) + { + sb.Append(color.ToTextColor()); + sb.Append(DestroyableSingleton<TranslationController>.Instance.GetString(TaskTypes.RestoreOxy)); + sb.Append(" "); + sb.Append(Mathf.CeilToInt(this.reactor.Countdown)); + sb.AppendLine(string.Format(" ({0}/{1})[]", this.reactor.UserCount, 2)); + } + else + { + sb.AppendLine(color.ToTextColor() + "Oxygen depleting[]"); + } + for (int i = 0; i < this.Arrows.Length; i++) + { + try + { + this.Arrows[i].image.color = color; + } + catch + { + } + } + } +} diff --git a/Client/Assembly-CSharp/NoShadowBehaviour.cs b/Client/Assembly-CSharp/NoShadowBehaviour.cs new file mode 100644 index 0000000..67023ce --- /dev/null +++ b/Client/Assembly-CSharp/NoShadowBehaviour.cs @@ -0,0 +1,55 @@ +using System; +using UnityEngine; + +public class NoShadowBehaviour : MonoBehaviour +{ + public Renderer rend; + + public bool didHit; + + public Renderer shadowChild; + + public void Start() + { + LightSource.NoShadows.Add(base.gameObject, this); + } + + public void OnDestroy() + { + LightSource.NoShadows.Remove(base.gameObject); + } + + private void LateUpdate() + { + if (!PlayerControl.LocalPlayer) + { + return; + } + GameData.PlayerInfo data = PlayerControl.LocalPlayer.Data; + if (data != null && !data.IsDead) + { + if (this.didHit) + { + this.didHit = false; + ShipStatus instance = ShipStatus.Instance; + if (instance && instance.CalculateLightRadius(data) > instance.MaxLightRadius / 3f) + { + this.SetMaskFunction(8); + return; + } + } + this.SetMaskFunction(1); + return; + } + this.SetMaskFunction(8); + } + + private void SetMaskFunction(int func) + { + this.rend.material.SetInt("_Mask", func); + if (this.shadowChild) + { + this.shadowChild.material.SetInt("_Mask", func); + } + } +} diff --git a/Client/Assembly-CSharp/NormalPlayerTask.cs b/Client/Assembly-CSharp/NormalPlayerTask.cs new file mode 100644 index 0000000..bd5133a --- /dev/null +++ b/Client/Assembly-CSharp/NormalPlayerTask.cs @@ -0,0 +1,284 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using UnityEngine; + +public class NormalPlayerTask : PlayerTask +{ + public override int TaskStep + { + get + { + return this.taskStep; + } + } + + public override bool IsComplete + { + get + { + return this.taskStep >= this.MaxStep; + } + } + + public int taskStep; + + public int MaxStep; + + public bool ShowTaskStep = true; + + public bool ShowTaskTimer; + + public NormalPlayerTask.TimerState TimerStarted; + + public float TaskTimer; + + public byte[] Data; + + public ArrowBehaviour Arrow; + + public enum TimerState + { + NotStarted, + Started, + Finished + } + + public override void Initialize() + { + if (this.Arrow && !base.Owner.AmOwner) + { + this.Arrow.gameObject.SetActive(false); + } + this.HasLocation = true; + this.LocationDirty = true; + TaskTypes taskType = this.TaskType; + switch (taskType) + { + case TaskTypes.PrimeShields: + { + this.Data = new byte[1]; + int num = 0; + for (int i = 0; i < 7; i++) + { + byte b = (byte)(1 << i); + if (BoolRange.Next(0.7f)) + { + byte[] data = this.Data; + int num2 = 0; + data[num2] |= b; + num++; + } + } + byte[] data2 = this.Data; + int num3 = 0; + data2[num3] &= 118; + return; + } + case TaskTypes.FuelEngines: + this.Data = new byte[2]; + return; + case TaskTypes.ChartCourse: + this.Data = new byte[4]; + return; + case TaskTypes.StartReactor: + this.Data = new byte[6]; + return; + case TaskTypes.SwipeCard: + case TaskTypes.ClearAsteroids: + case TaskTypes.UploadData: + case TaskTypes.EmptyChute: + case TaskTypes.EmptyGarbage: + break; + case TaskTypes.InspectSample: + this.Data = new byte[2]; + return; + case TaskTypes.AlignEngineOutput: + this.Data = new byte[2]; + this.Data[0] = AlignGame.ToByte((float)IntRange.RandomSign() * FloatRange.Next(1f, 3f)); + this.Data[1] = (byte)(IntRange.RandomSign() * IntRange.Next(25, 255)); + return; + case TaskTypes.FixWiring: + { + this.Data = new byte[this.MaxStep]; + List<global::Console> list = (from t in ShipStatus.Instance.AllConsoles + where t.TaskTypes.Contains(TaskTypes.FixWiring) + select t).ToList<global::Console>(); + List<global::Console> list2 = new List<global::Console>(list); + for (int j = 0; j < this.Data.Length; j++) + { + int index = list2.RandomIdx<global::Console>(); + this.Data[j] = (byte)list2[index].ConsoleId; + list2.RemoveAt(index); + } + Array.Sort<byte>(this.Data); + global::Console console = list.First((global::Console v) => v.ConsoleId == (int)this.Data[0]); + this.StartAt = console.Room; + break; + } + default: + if (taskType == TaskTypes.EnterIdCode) + { + this.Data = BitConverter.GetBytes(IntRange.Next(1, 99999)); + return; + } + break; + } + } + + public void NextStep() + { + this.taskStep++; + this.UpdateArrow(); + if (this.taskStep >= this.MaxStep) + { + this.taskStep = this.MaxStep; + if (PlayerControl.LocalPlayer) + { + if (DestroyableSingleton<HudManager>.InstanceExists) + { + DestroyableSingleton<HudManager>.Instance.ShowTaskComplete(); + StatsManager instance = StatsManager.Instance; + uint num = instance.TasksCompleted; + instance.TasksCompleted = num + 1U; + if (PlayerTask.AllTasksCompleted(PlayerControl.LocalPlayer)) + { + StatsManager instance2 = StatsManager.Instance; + num = instance2.CompletedAllTasks; + instance2.CompletedAllTasks = num + 1U; + } + } + PlayerControl.LocalPlayer.RpcCompleteTask(base.Id); + return; + } + } + else if (this.ShowTaskStep && Constants.ShouldPlaySfx()) + { + SoundManager.Instance.PlaySound(DestroyableSingleton<HudManager>.Instance.TaskUpdateSound, false, 1f); + } + } + + public void UpdateArrow() + { + if (!this.Arrow) + { + return; + } + if (!base.Owner.AmOwner) + { + this.Arrow.gameObject.SetActive(false); + return; + } + if (!this.IsComplete) + { + this.Arrow.gameObject.SetActive(true); + if (this.TaskType == TaskTypes.FixWiring) + { + global::Console console3 = base.FindSpecialConsole((global::Console c) => c.TaskTypes.Contains(TaskTypes.FixWiring) && c.ConsoleId == (int)this.Data[this.taskStep]); + this.Arrow.target = console3.transform.position; + this.StartAt = console3.Room; + } + else if (this.TaskType == TaskTypes.AlignEngineOutput) + { + if (AlignGame.IsSuccess(this.Data[0])) + { + this.Arrow.target = base.FindSpecialConsole((global::Console c) => c.TaskTypes.Contains(TaskTypes.AlignEngineOutput) && c.ConsoleId == 1).transform.position; + this.StartAt = SystemTypes.UpperEngine; + } + else + { + this.Arrow.target = base.FindSpecialConsole((global::Console console) => console.TaskTypes.Contains(TaskTypes.AlignEngineOutput) && console.ConsoleId == 0).transform.position; + this.StartAt = SystemTypes.LowerEngine; + } + } + else + { + global::Console console2 = base.FindObjectPos(); + this.Arrow.target = console2.transform.position; + this.StartAt = console2.Room; + } + this.LocationDirty = true; + return; + } + this.Arrow.gameObject.SetActive(false); + } + + private void FixedUpdate() + { + if (this.TimerStarted == NormalPlayerTask.TimerState.Started) + { + this.TaskTimer -= Time.fixedDeltaTime; + if (this.TaskTimer <= 0f) + { + this.TaskTimer = 0f; + this.TimerStarted = NormalPlayerTask.TimerState.Finished; + } + } + } + + public override bool ValidConsole(global::Console console) + { + if (this.TaskType == TaskTypes.FixWiring) + { + return console.TaskTypes.Contains(this.TaskType) && console.ConsoleId == (int)this.Data[this.taskStep]; + } + if (this.TaskType == TaskTypes.AlignEngineOutput) + { + return console.TaskTypes.Contains(this.TaskType) && !AlignGame.IsSuccess(this.Data[console.ConsoleId]); + } + if (this.TaskType == TaskTypes.FuelEngines) + { + return (console.TaskTypes.Contains(this.TaskType) && console.ConsoleId == (int)this.Data[1]) || console.ValidTasks.Any((TaskSet set) => this.TaskType == set.taskType && set.taskStep.Contains((int)this.Data[1])); + } + return console.TaskTypes.Any((TaskTypes tt) => tt == this.TaskType) || console.ValidTasks.Any((TaskSet set) => this.TaskType == set.taskType && set.taskStep.Contains(this.taskStep)); + } + + public override void Complete() + { + this.taskStep = this.MaxStep; + } + + public override void AppendTaskText(StringBuilder sb) + { + bool flag = this.ShouldYellowText(); + if (flag) + { + if (this.IsComplete) + { + sb.Append("[00DD00FF]"); + } + else + { + sb.Append("[FFFF00FF]"); + } + } + sb.Append(DestroyableSingleton<TranslationController>.Instance.GetString(this.StartAt)); + sb.Append(": "); + sb.Append(DestroyableSingleton<TranslationController>.Instance.GetString(this.TaskType)); + if (this.ShowTaskTimer && this.TimerStarted == NormalPlayerTask.TimerState.Started) + { + sb.Append(" ("); + sb.Append((int)this.TaskTimer); + sb.Append("s)"); + } + else if (this.ShowTaskStep) + { + sb.Append(" ("); + sb.Append(this.taskStep); + sb.Append("/"); + sb.Append(this.MaxStep); + sb.Append(")"); + } + if (flag) + { + sb.Append("[]"); + } + sb.AppendLine(); + } + + private bool ShouldYellowText() + { + return (this.TaskType == TaskTypes.FuelEngines && this.Data[1] > 0) || this.taskStep > 0 || this.TimerStarted > NormalPlayerTask.TimerState.NotStarted; + } +} diff --git a/Client/Assembly-CSharp/NotificationPopper.cs b/Client/Assembly-CSharp/NotificationPopper.cs new file mode 100644 index 0000000..8a98115 --- /dev/null +++ b/Client/Assembly-CSharp/NotificationPopper.cs @@ -0,0 +1,58 @@ +using System; +using System.Text; +using UnityEngine; + +public class NotificationPopper : MonoBehaviour +{ + public TextRenderer TextArea; + + public float zPos = -350f; + + private float alphaTimer; + + public float ShowDuration = 5f; + + public float FadeDuration = 1f; + + public Color textColor = Color.white; + + private StringBuilder builder = new StringBuilder(); + + public AudioClip NotificationSound; + + public void Update() + { + if (this.alphaTimer > 0f) + { + float num = Camera.main.orthographicSize * Camera.main.aspect; + if (!DestroyableSingleton<HudManager>.Instance.TaskText.isActiveAndEnabled) + { + float height = DestroyableSingleton<HudManager>.Instance.GameSettings.Height; + Transform transform = DestroyableSingleton<HudManager>.Instance.GameSettings.transform; + base.transform.localPosition = new Vector3(-num + 0.1f, transform.localPosition.y - height, this.zPos); + } + else + { + float height2 = DestroyableSingleton<HudManager>.Instance.TaskText.Height; + Transform parent = DestroyableSingleton<HudManager>.Instance.TaskText.transform.parent; + base.transform.localPosition = new Vector3(-num + 0.1f, parent.localPosition.y - height2 - 0.2f, this.zPos); + } + this.alphaTimer -= Time.deltaTime; + this.textColor.a = Mathf.Clamp(this.alphaTimer / this.FadeDuration, 0f, 1f); + this.TextArea.Color = this.textColor; + if (this.alphaTimer <= 0f) + { + this.builder.Clear(); + this.TextArea.Text = string.Empty; + } + } + } + + public void AddItem(string item) + { + this.builder.AppendLine(item); + this.TextArea.Text = this.builder.ToString(); + this.alphaTimer = this.ShowDuration; + SoundManager.Instance.PlaySound(this.NotificationSound, false, 1f); + } +} diff --git a/Client/Assembly-CSharp/NumberOption.cs b/Client/Assembly-CSharp/NumberOption.cs new file mode 100644 index 0000000..ebe2f94 --- /dev/null +++ b/Client/Assembly-CSharp/NumberOption.cs @@ -0,0 +1,111 @@ +using System; +using UnityEngine; + +public class NumberOption : OptionBehaviour +{ + public TextRenderer TitleText; + + public TextRenderer ValueText; + + public float Value = 1f; + + private float oldValue = float.MaxValue; + + public float Increment; + + public FloatRange ValidRange = new FloatRange(0f, 2f); + + public string FormatString = "{0:0.0}x"; + + public bool ZeroIsInfinity; + + public void OnEnable() + { + this.TitleText.Text = DestroyableSingleton<TranslationController>.Instance.GetString(this.Title, Array.Empty<object>()); + this.ValueText.Text = string.Format(this.FormatString, this.Value); + GameOptionsData gameOptions = PlayerControl.GameOptions; + StringNames title = this.Title; + switch (title) + { + case StringNames.GameNumImpostors: + this.Value = (float)gameOptions.NumImpostors; + return; + case StringNames.GameNumMeetings: + this.Value = (float)gameOptions.NumEmergencyMeetings; + return; + case StringNames.GameDiscussTime: + this.Value = (float)gameOptions.DiscussionTime; + return; + case StringNames.GameVotingTime: + this.Value = (float)gameOptions.VotingTime; + return; + case StringNames.GamePlayerSpeed: + this.Value = gameOptions.PlayerSpeedMod; + return; + case StringNames.GameCrewLight: + this.Value = gameOptions.CrewLightMod; + return; + case StringNames.GameImpostorLight: + this.Value = gameOptions.ImpostorLightMod; + return; + case StringNames.GameKillCooldown: + this.Value = gameOptions.KillCooldown; + return; + case StringNames.GameKillDistance: + break; + case StringNames.GameCommonTasks: + this.Value = (float)gameOptions.NumCommonTasks; + return; + case StringNames.GameLongTasks: + this.Value = (float)gameOptions.NumLongTasks; + return; + case StringNames.GameShortTasks: + this.Value = (float)gameOptions.NumShortTasks; + return; + default: + if (title == StringNames.GameEmergencyCooldown) + { + this.Value = (float)gameOptions.EmergencyCooldown; + return; + } + break; + } + Debug.Log("Ono, unrecognized setting: " + this.Title); + } + + private void FixedUpdate() + { + if (this.oldValue != this.Value) + { + this.oldValue = this.Value; + if (this.ZeroIsInfinity && Mathf.Abs(this.Value) < 0.0001f) + { + this.ValueText.Text = string.Format(this.FormatString, "∞"); + return; + } + this.ValueText.Text = string.Format(this.FormatString, this.Value); + } + } + + public void Increase() + { + this.Value = this.ValidRange.Clamp(this.Value + this.Increment); + this.OnValueChanged(this); + } + + public void Decrease() + { + this.Value = this.ValidRange.Clamp(this.Value - this.Increment); + this.OnValueChanged(this); + } + + public override float GetFloat() + { + return this.Value; + } + + public override int GetInt() + { + return (int)this.Value; + } +} diff --git a/Client/Assembly-CSharp/ObjectPoolBehavior.cs b/Client/Assembly-CSharp/ObjectPoolBehavior.cs new file mode 100644 index 0000000..657837b --- /dev/null +++ b/Client/Assembly-CSharp/ObjectPoolBehavior.cs @@ -0,0 +1,138 @@ +using System; +using System.Collections.Generic; +using UnityEngine; + +public class ObjectPoolBehavior : IObjectPool +{ + public override int InUse + { + get + { + return this.activeChildren.Count; + } + } + + public override int NotInUse + { + get + { + return this.inactiveChildren.Count; + } + } + + public int poolSize = 20; + + [SerializeField] + private List<PoolableBehavior> inactiveChildren = new List<PoolableBehavior>(); + + [SerializeField] + public List<PoolableBehavior> activeChildren = new List<PoolableBehavior>(); + + public PoolableBehavior Prefab; + + public bool AutoInit; + + public bool DetachOnGet; + + public virtual void Awake() + { + if (this.AutoInit) + { + this.InitPool(this.Prefab); + } + } + + public void InitPool(PoolableBehavior prefab) + { + this.AutoInit = false; + for (int i = 0; i < this.poolSize; i++) + { + this.CreateOneInactive(prefab); + } + } + + private void CreateOneInactive(PoolableBehavior prefab) + { + PoolableBehavior poolableBehavior = UnityEngine.Object.Instantiate<PoolableBehavior>(prefab); + poolableBehavior.transform.SetParent(base.transform); + poolableBehavior.gameObject.SetActive(false); + poolableBehavior.OwnerPool = this; + this.inactiveChildren.Add(poolableBehavior); + } + + public void ReclaimOldest() + { + if (this.activeChildren.Count > 0) + { + this.Reclaim(this.activeChildren[0]); + return; + } + this.InitPool(this.Prefab); + } + + public void ReclaimAll() + { + foreach (PoolableBehavior obj in this.activeChildren.ToArray()) + { + this.Reclaim(obj); + } + } + + public override T Get<T>() + { + List<PoolableBehavior> obj = this.inactiveChildren; + PoolableBehavior poolableBehavior; + lock (obj) + { + if (this.inactiveChildren.Count == 0) + { + if (this.activeChildren.Count == 0) + { + this.InitPool(this.Prefab); + } + else + { + this.CreateOneInactive(this.Prefab); + } + } + poolableBehavior = this.inactiveChildren[this.inactiveChildren.Count - 1]; + this.inactiveChildren.RemoveAt(this.inactiveChildren.Count - 1); + this.activeChildren.Add(poolableBehavior); + } + if (this.DetachOnGet) + { + poolableBehavior.transform.SetParent(null, false); + } + poolableBehavior.gameObject.SetActive(true); + poolableBehavior.Reset(); + return poolableBehavior as T; + } + + public override void Reclaim(PoolableBehavior obj) + { + if (!this) + { + DefaultPool.Instance.Reclaim(obj); + return; + } + obj.gameObject.SetActive(false); + obj.transform.SetParent(base.transform); + List<PoolableBehavior> obj2 = this.inactiveChildren; + lock (obj2) + { + if (this.activeChildren.Remove(obj)) + { + this.inactiveChildren.Add(obj); + } + else if (this.inactiveChildren.Contains(obj)) + { + Debug.Log("ObjectPoolBehavior: :| Something was reclaimed without being gotten"); + } + else + { + Debug.Log("ObjectPoolBehavior: Destroying this thing I don't own"); + UnityEngine.Object.Destroy(obj.gameObject); + } + } + } +} diff --git a/Client/Assembly-CSharp/OffsetAdjustment.cs b/Client/Assembly-CSharp/OffsetAdjustment.cs new file mode 100644 index 0000000..83e6b1c --- /dev/null +++ b/Client/Assembly-CSharp/OffsetAdjustment.cs @@ -0,0 +1,11 @@ +using System; + +[Serializable] +public class OffsetAdjustment +{ + public char Char; + + public int OffsetX; + + public int OffsetY; +} diff --git a/Client/Assembly-CSharp/OneWayShadows.cs b/Client/Assembly-CSharp/OneWayShadows.cs new file mode 100644 index 0000000..e5aff45 --- /dev/null +++ b/Client/Assembly-CSharp/OneWayShadows.cs @@ -0,0 +1,22 @@ +using System; +using UnityEngine; + +public class OneWayShadows : MonoBehaviour +{ + public Collider2D RoomCollider; + + public void Start() + { + LightSource.OneWayShadows.Add(base.gameObject, this); + } + + public void OnDestroy() + { + LightSource.OneWayShadows.Remove(base.gameObject); + } + + public bool IsIgnored(LightSource lightSource) + { + return this.RoomCollider.OverlapPoint(lightSource.transform.position); + } +} diff --git a/Client/Assembly-CSharp/OptionBehaviour.cs b/Client/Assembly-CSharp/OptionBehaviour.cs new file mode 100644 index 0000000..f17b80f --- /dev/null +++ b/Client/Assembly-CSharp/OptionBehaviour.cs @@ -0,0 +1,33 @@ +using System; +using UnityEngine; + +public abstract class OptionBehaviour : MonoBehaviour +{ + public StringNames Title; + + public Action<OptionBehaviour> OnValueChanged; + + public virtual float GetFloat() + { + throw new NotImplementedException(); + } + + public virtual int GetInt() + { + throw new NotImplementedException(); + } + + public virtual bool GetBool() + { + throw new NotImplementedException(); + } + + public void SetAsPlayer() + { + PassiveButton[] componentsInChildren = base.GetComponentsInChildren<PassiveButton>(); + for (int i = 0; i < componentsInChildren.Length; i++) + { + componentsInChildren[i].gameObject.SetActive(false); + } + } +} diff --git a/Client/Assembly-CSharp/OptionsConsole.cs b/Client/Assembly-CSharp/OptionsConsole.cs new file mode 100644 index 0000000..4d80de9 --- /dev/null +++ b/Client/Assembly-CSharp/OptionsConsole.cs @@ -0,0 +1,64 @@ +using System; +using UnityEngine; + +public class OptionsConsole : MonoBehaviour, IUsable +{ + public float UsableDistance + { + get + { + return 1f; + } + } + + public float PercentCool + { + get + { + return 0f; + } + } + + public CustomPlayerMenu MenuPrefab; + + public SpriteRenderer Outline; + + public float CanUse(GameData.PlayerInfo pc, out bool canUse, out bool couldUse) + { + float num = float.MaxValue; + PlayerControl @object = pc.Object; + couldUse = @object.CanMove; + canUse = couldUse; + if (canUse) + { + num = Vector2.Distance(@object.GetTruePosition(), base.transform.position); + canUse &= (num <= this.UsableDistance); + } + return num; + } + + public void SetOutline(bool on, bool mainTarget) + { + if (this.Outline) + { + this.Outline.material.SetFloat("_Outline", (float)(on ? 1 : 0)); + this.Outline.material.SetColor("_OutlineColor", Color.white); + this.Outline.material.SetColor("_AddColor", mainTarget ? Color.white : Color.clear); + } + } + + public void Use() + { + bool flag; + bool flag2; + this.CanUse(PlayerControl.LocalPlayer.Data, out flag, out flag2); + if (!flag) + { + return; + } + PlayerControl.LocalPlayer.NetTransform.Halt(); + CustomPlayerMenu customPlayerMenu = UnityEngine.Object.Instantiate<CustomPlayerMenu>(this.MenuPrefab); + customPlayerMenu.transform.SetParent(Camera.main.transform, false); + customPlayerMenu.transform.localPosition = new Vector3(0f, 0f, -20f); + } +} diff --git a/Client/Assembly-CSharp/OptionsMenuBehaviour.cs b/Client/Assembly-CSharp/OptionsMenuBehaviour.cs new file mode 100644 index 0000000..fffe2b4 --- /dev/null +++ b/Client/Assembly-CSharp/OptionsMenuBehaviour.cs @@ -0,0 +1,200 @@ +using System; +using UnityEngine; + +public class OptionsMenuBehaviour : MonoBehaviour, ITranslatedText +{ + public bool IsOpen + { + get + { + return base.isActiveAndEnabled; + } + } + + public SpriteRenderer Background; + + public SpriteRenderer JoystickButton; + + public SpriteRenderer TouchButton; + + public SlideBar JoystickSizeSlider; + + public FloatRange JoystickSizes = new FloatRange(0.5f, 1.5f); + + public SlideBar SoundSlider; + + public SlideBar MusicSlider; + + public ToggleButtonBehaviour SendTelemButton; + + public ToggleButtonBehaviour PersonalizedAdsButton; + + public ToggleButtonBehaviour CensorChatButton; + + public bool Toggle = true; + + public TabGroup[] Tabs; + + public void OpenTabGroup(TabGroup selected) + { + selected.Open(); + for (int i = 0; i < this.Tabs.Length; i++) + { + TabGroup tabGroup = this.Tabs[i]; + if (!(tabGroup == selected)) + { + tabGroup.Close(); + } + } + } + + private void Update() + { + if (Input.GetKeyUp(KeyCode.Escape)) + { + this.Close(); + } + } + + public void Start() + { + DestroyableSingleton<TranslationController>.Instance.ActiveTexts.Add(this); + } + + public void OnDestroy() + { + DestroyableSingleton<TranslationController>.Instance.ActiveTexts.Remove(this); + } + + public void ResetText() + { + this.JoystickButton.transform.parent.GetComponentInChildren<TextRenderer>().Text = DestroyableSingleton<TranslationController>.Instance.GetString(StringNames.SettingsMouseMode, Array.Empty<object>()); + this.TouchButton.transform.parent.GetComponentInChildren<TextRenderer>().Text = DestroyableSingleton<TranslationController>.Instance.GetString(StringNames.SettingsKeyboardMode, Array.Empty<object>()); + this.JoystickSizeSlider.gameObject.SetActive(false); + } + + public void Open() + { + this.ResetText(); + if (base.gameObject.activeSelf) + { + if (this.Toggle) + { + base.GetComponent<TransitionOpen>().Close(); + } + return; + } + this.OpenTabGroup(this.Tabs[0]); + this.UpdateButtons(); + base.gameObject.SetActive(true); + } + + public void SetControlType(int i) + { + SaveManager.TouchConfig = i; + this.UpdateButtons(); + if (DestroyableSingleton<HudManager>.InstanceExists) + { + DestroyableSingleton<HudManager>.Instance.SetTouchType(i); + } + } + + public void UpdateJoystickSize(SlideBar slider) + { + SaveManager.JoystickSize = this.JoystickSizes.Lerp(slider.Value); + if (DestroyableSingleton<HudManager>.InstanceExists) + { + DestroyableSingleton<HudManager>.Instance.SetJoystickSize(SaveManager.JoystickSize); + } + } + + public void ToggleSendTelemetry() + { + SaveManager.SendTelemetry = !SaveManager.SendTelemetry; + this.UpdateButtons(); + } + + public void ToggleSendName() + { + SaveManager.SendName = !SaveManager.SendName; + this.UpdateButtons(); + } + + public void UpdateSfxVolume(SlideBar button) + { + SaveManager.SfxVolume = button.Value; + SoundManager.Instance.ChangeSfxVolume(button.Value); + } + + public void UpdateMusicVolume(SlideBar button) + { + SaveManager.MusicVolume = button.Value; + SoundManager.Instance.ChangeMusicVolume(button.Value); + } + + public void TogglePersonalizedAd() + { + ShowAdsState showAdsState = SaveManager.ShowAdsScreen & (ShowAdsState)127; + if (showAdsState != ShowAdsState.Personalized) + { + if (showAdsState == ShowAdsState.NonPersonalized) + { + SaveManager.ShowAdsScreen = ShowAdsState.Accepted; + goto IL_30; + } + if (showAdsState == ShowAdsState.Purchased) + { + goto IL_30; + } + } + SaveManager.ShowAdsScreen = (ShowAdsState)129; + IL_30: + this.UpdateButtons(); + } + + public void ToggleCensorChat() + { + SaveManager.CensorChat = !SaveManager.CensorChat; + this.UpdateButtons(); + } + + public void UpdateButtons() + { + if (SaveManager.TouchConfig == 0) + { + this.JoystickButton.color = new Color32(0, byte.MaxValue, 42, byte.MaxValue); + this.TouchButton.color = Color.white; + this.JoystickSizeSlider.enabled = true; + this.JoystickSizeSlider.OnEnable(); + } + else + { + this.JoystickButton.color = Color.white; + this.TouchButton.color = new Color32(0, byte.MaxValue, 42, byte.MaxValue); + this.JoystickSizeSlider.enabled = false; + this.JoystickSizeSlider.OnDisable(); + } + this.JoystickSizeSlider.Value = this.JoystickSizes.ReverseLerp(SaveManager.JoystickSize); + this.SoundSlider.Value = SaveManager.SfxVolume; + this.MusicSlider.Value = SaveManager.MusicVolume; + if (this.SendTelemButton) + { + this.SendTelemButton.UpdateText(SaveManager.SendTelemetry); + } + this.CensorChatButton.UpdateText(SaveManager.CensorChat); + if (this.PersonalizedAdsButton) + { + if (SaveManager.ShowAdsScreen.HasFlag(ShowAdsState.Purchased) || SaveManager.BoughtNoAds) + { + this.PersonalizedAdsButton.transform.parent.gameObject.SetActive(false); + return; + } + this.PersonalizedAdsButton.UpdateText(!SaveManager.ShowAdsScreen.HasFlag(ShowAdsState.NonPersonalized)); + } + } + + public void Close() + { + base.gameObject.SetActive(false); + } +} diff --git a/Client/Assembly-CSharp/OverlayKillAnimation.cs b/Client/Assembly-CSharp/OverlayKillAnimation.cs new file mode 100644 index 0000000..d6f711e --- /dev/null +++ b/Client/Assembly-CSharp/OverlayKillAnimation.cs @@ -0,0 +1,150 @@ +using System; +using System.Collections; +using PowerTools; +using UnityEngine; + +public class OverlayKillAnimation : MonoBehaviour +{ + public KillAnimType KillType; + + public PoolablePlayer killerParts; + + public PoolablePlayer victimParts; + + private uint victimHat; + + public AudioClip Stinger; + + public AudioClip Sfx; + + public float StingerVolume = 0.6f; + + public void Begin(PlayerControl killer, GameData.PlayerInfo vInfo) + { + if (this.killerParts) + { + GameData.PlayerInfo kInfo = killer.Data; + PlayerControl.SetPlayerMaterialColors((int)kInfo.ColorId, this.killerParts.Body); + this.killerParts.Hands.ForEach(delegate(SpriteRenderer b) + { + PlayerControl.SetPlayerMaterialColors((int)kInfo.ColorId, b); + }); + PlayerControl.SetHatImage(kInfo.HatId, this.killerParts.HatSlot); + switch (this.KillType) + { + case KillAnimType.Stab: + case KillAnimType.Neck: + PlayerControl.SetSkinImage(kInfo.SkinId, this.killerParts.SkinSlot); + break; + case KillAnimType.Tongue: + { + SkinData skinById = DestroyableSingleton<HatManager>.Instance.GetSkinById(kInfo.SkinId); + this.killerParts.SkinSlot.GetComponent<SpriteAnim>().Play(skinById.KillTongueImpostor, 1f); + break; + } + case KillAnimType.Shoot: + { + SkinData skinById2 = DestroyableSingleton<HatManager>.Instance.GetSkinById(kInfo.SkinId); + this.killerParts.SkinSlot.GetComponent<SpriteAnim>().Play(skinById2.KillShootImpostor, 1f); + break; + } + } + if (this.killerParts.PetSlot) + { + PetBehaviour petById = DestroyableSingleton<HatManager>.Instance.GetPetById(kInfo.PetId); + if (petById && petById.scaredClip) + { + this.killerParts.PetSlot.GetComponent<SpriteAnim>().Play(petById.idleClip, 1f); + this.killerParts.PetSlot.sharedMaterial = petById.rend.sharedMaterial; + PlayerControl.SetPlayerMaterialColors((int)kInfo.ColorId, this.killerParts.PetSlot); + } + else + { + this.killerParts.PetSlot.enabled = false; + } + } + } + if (vInfo != null && this.victimParts) + { + this.victimHat = vInfo.HatId; + PlayerControl.SetPlayerMaterialColors((int)vInfo.ColorId, this.victimParts.Body); + PlayerControl.SetHatImage(vInfo.HatId, this.victimParts.HatSlot); + SkinData skinById3 = DestroyableSingleton<HatManager>.Instance.GetSkinById(vInfo.SkinId); + switch (this.KillType) + { + case KillAnimType.Stab: + this.victimParts.SkinSlot.GetComponent<SpriteAnim>().Play(skinById3.KillStabVictim, 1f); + break; + case KillAnimType.Tongue: + this.victimParts.SkinSlot.GetComponent<SpriteAnim>().Play(skinById3.KillTongueVictim, 1f); + break; + case KillAnimType.Shoot: + this.victimParts.SkinSlot.GetComponent<SpriteAnim>().Play(skinById3.KillShootVictim, 1f); + break; + case KillAnimType.Neck: + this.victimParts.SkinSlot.GetComponent<SpriteAnim>().Play(skinById3.KillNeckVictim, 1f); + break; + } + if (this.victimParts.PetSlot) + { + PetBehaviour petById2 = DestroyableSingleton<HatManager>.Instance.GetPetById(vInfo.PetId); + if (petById2 && petById2.scaredClip) + { + this.victimParts.PetSlot.GetComponent<SpriteAnim>().Play(petById2.scaredClip, 1f); + this.victimParts.PetSlot.sharedMaterial = petById2.rend.sharedMaterial; + PlayerControl.SetPlayerMaterialColors((int)vInfo.ColorId, this.victimParts.PetSlot); + return; + } + this.victimParts.PetSlot.enabled = false; + } + } + } + + public void SetHatFloor() + { + HatBehaviour hatById = DestroyableSingleton<HatManager>.Instance.GetHatById(this.victimHat); + if (!hatById) + { + return; + } + this.victimParts.HatSlot.sprite = hatById.FloorImage; + } + + public void PlayKillSound() + { + if (Constants.ShouldPlaySfx()) + { + SoundManager.Instance.PlaySound(this.Sfx, false, 1f).volume = 0.8f; + } + } + + public IEnumerator WaitForFinish() + { + SpriteAnim[] anims = base.GetComponentsInChildren<SpriteAnim>(); + if (anims.Length == 0) + { + yield return new WaitForSeconds(1f); + } + else + { + for (;;) + { + bool flag = false; + for (int i = 0; i < anims.Length; i++) + { + if (anims[i].IsPlaying(null)) + { + flag = true; + break; + } + } + if (!flag) + { + break; + } + yield return null; + } + } + yield break; + } +} diff --git a/Client/Assembly-CSharp/Palette.cs b/Client/Assembly-CSharp/Palette.cs new file mode 100644 index 0000000..044fa1a --- /dev/null +++ b/Client/Assembly-CSharp/Palette.cs @@ -0,0 +1,67 @@ +using System; +using UnityEngine; + +public static class Palette +{ + public static readonly Color DisabledGrey = new Color(0.3f, 0.3f, 0.3f, 1f); + + public static readonly Color DisabledColor = new Color(1f, 1f, 1f, 0.3f); + + public static readonly Color EnabledColor = new Color(1f, 1f, 1f, 1f); + + public static readonly Color Black = new Color(0f, 0f, 0f, 1f); + + public static readonly Color ClearWhite = new Color(1f, 1f, 1f, 0f); + + public static readonly Color HalfWhite = new Color(1f, 1f, 1f, 0.5f); + + public static readonly Color White = new Color(1f, 1f, 1f, 1f); + + public static readonly Color LightBlue = new Color(0.5f, 0.5f, 1f); + + public static readonly Color Blue = new Color(0.2f, 0.2f, 1f); + + public static readonly Color Orange = new Color(1f, 0.6f, 0.005f); + + public static readonly Color Purple = new Color(0.6f, 0.1f, 0.6f); + + public static readonly Color Brown = new Color(0.72f, 0.43f, 0.11f); + + public static readonly Color CrewmateBlue = new Color32(140, byte.MaxValue, byte.MaxValue, byte.MaxValue); + + public static readonly Color ImpostorRed = new Color32(byte.MaxValue, 25, 25, byte.MaxValue); + + public static readonly Color32[] PlayerColors = new Color32[] + { + new Color32(198, 17, 17, byte.MaxValue), + new Color32(19, 46, 210, byte.MaxValue), + new Color32(17, 128, 45, byte.MaxValue), + new Color32(238, 84, 187, byte.MaxValue), + new Color32(240, 125, 13, byte.MaxValue), + new Color32(246, 246, 87, byte.MaxValue), + new Color32(63, 71, 78, byte.MaxValue), + new Color32(215, 225, 241, byte.MaxValue), + new Color32(107, 47, 188, byte.MaxValue), + new Color32(113, 73, 30, byte.MaxValue), + new Color32(56, byte.MaxValue, 221, byte.MaxValue), + new Color32(80, 240, 57, byte.MaxValue) + }; + + public static readonly Color32[] ShadowColors = new Color32[] + { + new Color32(122, 8, 56, byte.MaxValue), + new Color32(9, 21, 142, byte.MaxValue), + new Color32(10, 77, 46, byte.MaxValue), + new Color32(172, 43, 174, byte.MaxValue), + new Color32(180, 62, 21, byte.MaxValue), + new Color32(195, 136, 34, byte.MaxValue), + new Color32(30, 31, 38, byte.MaxValue), + new Color32(132, 149, 192, byte.MaxValue), + new Color32(59, 23, 124, byte.MaxValue), + new Color32(94, 38, 21, byte.MaxValue), + new Color32(36, 169, 191, byte.MaxValue), + new Color32(21, 168, 66, byte.MaxValue) + }; + + public static readonly Color32 VisorColor = new Color32(149, 202, 220, byte.MaxValue); +} diff --git a/Client/Assembly-CSharp/ParallaxController.cs b/Client/Assembly-CSharp/ParallaxController.cs new file mode 100644 index 0000000..892453d --- /dev/null +++ b/Client/Assembly-CSharp/ParallaxController.cs @@ -0,0 +1,22 @@ +using System; +using UnityEngine; + +public class ParallaxController : MonoBehaviour +{ + public float Rate; + + private Camera cam; + + public void Start() + { + this.cam = Camera.main; + } + + private void Update() + { + Vector3 vector = base.transform.parent.position - this.cam.transform.position; + vector *= this.Rate; + vector.z = -this.Rate; + base.transform.localPosition = vector; + } +} diff --git a/Client/Assembly-CSharp/ParticleInfo.cs b/Client/Assembly-CSharp/ParticleInfo.cs new file mode 100644 index 0000000..2c5da66 --- /dev/null +++ b/Client/Assembly-CSharp/ParticleInfo.cs @@ -0,0 +1,12 @@ +using System; +using UnityEngine; + +[Serializable] +public struct ParticleInfo +{ + public Vector3 Position; + + public float Scale; + + public float Timer; +} diff --git a/Client/Assembly-CSharp/PassiveButton.cs b/Client/Assembly-CSharp/PassiveButton.cs new file mode 100644 index 0000000..f7e9337 --- /dev/null +++ b/Client/Assembly-CSharp/PassiveButton.cs @@ -0,0 +1,47 @@ +using System; +using UnityEngine; +using UnityEngine.Events; +using UnityEngine.UI; + +public class PassiveButton : MonoBehaviour +{ + public bool OnUp = true; + + public bool OnDown; + + public Button.ButtonClickedEvent OnClick = new Button.ButtonClickedEvent(); + + public AudioClip ClickSound; + + public UnityEvent OnMouseOver; + + public UnityEvent OnMouseOut; + + public Collider2D[] Colliders; + + public void Start() + { + DestroyableSingleton<PassiveButtonManager>.Instance.RegisterOne(this); + if (this.Colliders == null || this.Colliders.Length == 0) + { + this.Colliders = base.GetComponents<Collider2D>(); + } + } + + public void DoClick() + { + if (this.ClickSound) + { + SoundManager.Instance.PlaySound(this.ClickSound, false, 1f); + } + this.OnClick.Invoke(); + } + + public void OnDestroy() + { + if (DestroyableSingleton<PassiveButtonManager>.InstanceExists) + { + DestroyableSingleton<PassiveButtonManager>.Instance.RemoveOne(this); + } + } +} diff --git a/Client/Assembly-CSharp/PassiveButtonManager.cs b/Client/Assembly-CSharp/PassiveButtonManager.cs new file mode 100644 index 0000000..b45379b --- /dev/null +++ b/Client/Assembly-CSharp/PassiveButtonManager.cs @@ -0,0 +1,256 @@ +using System; +using System.Collections.Generic; +using UnityEngine; + +public class PassiveButtonManager : DestroyableSingleton<PassiveButtonManager> +{ + public List<PassiveButton> Buttons = new List<PassiveButton>(); + + private List<IFocusHolder> FocusHolders = new List<IFocusHolder>(); + + private PassiveButton currentOver; + + public Controller Controller = new Controller(); + + private PassiveButton currentDown; + + private Collider2D[] results = new Collider2D[40]; + + private class DepthComparer : IComparer<PassiveButton> + { + public static readonly PassiveButtonManager.DepthComparer Instance = new PassiveButtonManager.DepthComparer(); + + public int Compare(PassiveButton x, PassiveButton y) + { + if (x == null) + { + return 1; + } + if (y == null) + { + return -1; + } + return x.transform.position.z.CompareTo(y.transform.position.z); + } + } + + public void RegisterOne(PassiveButton button) + { + this.Buttons.Add(button); + } + + public void RemoveOne(PassiveButton passiveButton) + { + this.Buttons.Remove(passiveButton); + } + + public void RegisterOne(IFocusHolder focusHolder) + { + this.FocusHolders.Add(focusHolder); + } + + public void RemoveOne(IFocusHolder focusHolder) + { + this.FocusHolders.Remove(focusHolder); + } + + public void Update() + { + this.Controller.Update(); + for (int i = 1; i < this.Buttons.Count; i++) + { + if (PassiveButtonManager.DepthComparer.Instance.Compare(this.Buttons[i - 1], this.Buttons[i]) > 0) + { + this.Buttons.Sort(PassiveButtonManager.DepthComparer.Instance); + break; + } + } + Vector2 position = this.Controller.Touches[0].Position; + int num = Physics2D.OverlapPointNonAlloc(position, this.results); + bool flag = false; + for (int j = 0; j < this.Buttons.Count; j++) + { + PassiveButton passiveButton = this.Buttons[j]; + if (!passiveButton) + { + this.Buttons.RemoveAt(j); + j--; + } + else if (passiveButton.isActiveAndEnabled) + { + bool flag2 = false; + for (int k = 0; k < num; k++) + { + if (this.results[k].gameObject == passiveButton.gameObject) + { + flag2 = true; + break; + } + } + if (flag2) + { + flag = true; + if (passiveButton != this.currentOver) + { + if (this.currentOver) + { + this.currentOver.OnMouseOut.Invoke(); + } + this.currentOver = passiveButton; + this.currentDown = null; + this.currentOver.OnMouseOver.Invoke(); + break; + } + break; + } + } + } + if (!flag && this.currentOver) + { + this.currentOver.OnMouseOut.Invoke(); + this.currentOver = null; + this.currentDown = null; + } + if (this.Controller.AnyTouchDown) + { + if (this.currentOver) + { + this.currentDown = this.currentOver; + if (this.currentOver.OnDown) + { + this.currentOver.DoClick(); + } + } + this.HandleFocus(position); + return; + } + if (this.Controller.AnyTouchUp && this.currentDown) + { + if (this.currentDown.OnUp) + { + this.currentDown.DoClick(); + } + this.currentDown = null; + } + } + + private void CheckForDown() + { + Vector2 touch = this.GetTouch(true); + for (int i = 0; i < this.Buttons.Count; i++) + { + PassiveButton passiveButton = this.Buttons[i]; + if (!passiveButton) + { + this.Buttons.RemoveAt(i); + i--; + } + else if (passiveButton.isActiveAndEnabled) + { + for (int j = 0; j < passiveButton.Colliders.Length; j++) + { + Collider2D collider2D = passiveButton.Colliders[j]; + if (collider2D && collider2D.OverlapPoint(touch)) + { + this.currentDown = passiveButton; + if (passiveButton.OnDown) + { + passiveButton.DoClick(); + } + return; + } + } + } + } + this.HandleFocus(touch); + } + + private void HandleFocus(Vector2 pt) + { + bool flag = false; + for (int i = 0; i < this.FocusHolders.Count; i++) + { + IFocusHolder focusHolder = this.FocusHolders[i]; + if (!(focusHolder as MonoBehaviour)) + { + this.FocusHolders.RemoveAt(i); + i--; + } + else if (focusHolder.CheckCollision(pt)) + { + flag = true; + focusHolder.GiveFocus(); + for (int j = 0; j < this.FocusHolders.Count; j++) + { + if (j != i) + { + this.FocusHolders[j].LoseFocus(); + } + } + break; + } + } + if (!flag) + { + for (int k = 0; k < this.FocusHolders.Count; k++) + { + this.FocusHolders[k].LoseFocus(); + } + } + } + + private void HandleMouseOut(PassiveButton button) + { + if (this.currentOver == button) + { + button.OnMouseOut.Invoke(); + this.currentOver = null; + } + } + + private void CheckForUp() + { + if (!this.currentDown) + { + return; + } + PassiveButton passiveButton = this.currentDown; + this.currentDown = null; + if (!passiveButton.OnUp) + { + return; + } + Vector2 touch = this.GetTouch(false); + for (int i = 0; i < passiveButton.Colliders.Length; i++) + { + if (passiveButton.Colliders[i].OverlapPoint(touch)) + { + if (passiveButton.OnUp) + { + passiveButton.DoClick(); + } + return; + } + } + } + + private Vector2 GetTouch(bool downOrUp) + { + if (downOrUp) + { + if (this.Controller.Touches[0].TouchStart) + { + return this.Controller.Touches[0].Position; + } + return this.Controller.Touches[1].Position; + } + else + { + if (this.Controller.Touches[0].TouchEnd) + { + return this.Controller.Touches[0].Position; + } + return this.Controller.Touches[1].Position; + } + } +} diff --git a/Client/Assembly-CSharp/PetBehaviour.cs b/Client/Assembly-CSharp/PetBehaviour.cs new file mode 100644 index 0000000..bf94b13 --- /dev/null +++ b/Client/Assembly-CSharp/PetBehaviour.cs @@ -0,0 +1,140 @@ +using System; +using PowerTools; +using UnityEngine; + +public class PetBehaviour : MonoBehaviour, IBuyable +{ + public string ProdId + { + get + { + return this.ProductId; + } + } + + public bool Visible + { + set + { + this.rend.enabled = value; + this.shadowRend.enabled = value; + } + } + + private const float SnapDistance = 2f; + + public bool Free; + + public string ProductId; + + public string StoreName; + + public uint SteamId; + + public int ItchId; + + public string ItchUrl; + + public PlayerControl Source; + + public const float MinDistance = 0.2f; + + public const float damping = 0.7f; + + public const float Easing = 0.2f; + + public const float Speed = 5f; + + public float YOffset = -0.25f; + + public SpriteAnim animator; + + public SpriteRenderer rend; + + public SpriteRenderer shadowRend; + + public Rigidbody2D body; + + public Collider2D Collider; + + public AnimationClip idleClip; + + public AnimationClip sadClip; + + public AnimationClip scaredClip; + + public AnimationClip walkClip; + + private Vector2 GetTruePosition() + { + return base.transform.position + this.Collider.offset * 0.7f; + } + + public void FixedUpdate() + { + if (!this.Source) + { + this.body.velocity = Vector2.zero; + return; + } + this.Visible = this.Source.Visible; + Vector2 truePosition = this.Source.GetTruePosition(); + Vector2 truePosition2 = this.GetTruePosition(); + Vector2 vector = this.body.velocity; + Vector2 a = truePosition - truePosition2; + float num = 0f; + if (this.Source.CanMove) + { + num = 0.2f; + } + if (a.sqrMagnitude > num) + { + if (a.sqrMagnitude > 2f) + { + base.transform.position = truePosition; + return; + } + a *= 5f * PlayerControl.GameOptions.PlayerSpeedMod; + vector = vector * 0.8f + a * 0.2f; + } + else + { + vector *= 0.7f; + } + AnimationClip currentAnimation = this.animator.GetCurrentAnimation(); + if (vector.sqrMagnitude > 0.01f) + { + if (currentAnimation != this.walkClip) + { + this.animator.Play(this.walkClip, 1f); + } + if (vector.x < -0.01f) + { + this.rend.flipX = true; + } + else if (vector.x > 0.01f) + { + this.rend.flipX = false; + } + } + else if (currentAnimation == this.walkClip) + { + this.animator.Play(this.idleClip, 1f); + } + this.body.velocity = vector; + } + + private void LateUpdate() + { + Vector3 localPosition = base.transform.localPosition; + localPosition.z = (localPosition.y + this.YOffset) / 1000f + 0.0002f; + base.transform.localPosition = localPosition; + } + + public void SetMourning() + { + this.Source = null; + this.body.velocity = Vector2.zero; + this.animator.Play(this.sadClip, 1f); + } +} diff --git a/Client/Assembly-CSharp/PetsTab.cs b/Client/Assembly-CSharp/PetsTab.cs new file mode 100644 index 0000000..2c362c3 --- /dev/null +++ b/Client/Assembly-CSharp/PetsTab.cs @@ -0,0 +1,78 @@ +using System; +using System.Collections.Generic; +using UnityEngine; + +public class PetsTab : MonoBehaviour +{ + public ColorChip ColorTabPrefab; + + public SpriteRenderer DemoImage; + + public SpriteRenderer HatImage; + + public SpriteRenderer SkinImage; + + public SpriteRenderer PetImage; + + public FloatRange XRange = new FloatRange(1.5f, 3f); + + public float YStart = 0.8f; + + public float YOffset = 0.8f; + + public int NumPerRow = 4; + + public Scroller scroller; + + private List<ColorChip> ColorChips = new List<ColorChip>(); + + public void OnEnable() + { + PlayerControl.SetPlayerMaterialColors((int)PlayerControl.LocalPlayer.Data.ColorId, this.DemoImage); + PlayerControl.SetHatImage(SaveManager.LastHat, this.HatImage); + PlayerControl.SetSkinImage(SaveManager.LastSkin, this.SkinImage); + PlayerControl.SetPetImage(SaveManager.LastPet, (int)PlayerControl.LocalPlayer.Data.ColorId, this.PetImage); + PetBehaviour[] unlockedPets = DestroyableSingleton<HatManager>.Instance.GetUnlockedPets(); + for (int i = 0; i < unlockedPets.Length; i++) + { + PetBehaviour pet = unlockedPets[i]; + float x = this.XRange.Lerp((float)(i % this.NumPerRow) / ((float)this.NumPerRow - 1f)); + float y = this.YStart - (float)(i / this.NumPerRow) * this.YOffset; + ColorChip chip = UnityEngine.Object.Instantiate<ColorChip>(this.ColorTabPrefab, this.scroller.Inner); + chip.transform.localPosition = new Vector3(x, y, -1f); + chip.InUseForeground.SetActive(DestroyableSingleton<HatManager>.Instance.GetIdFromPet(pet) == SaveManager.LastPet); + chip.Button.OnClick.AddListener(delegate() + { + this.SelectPet(chip, pet); + }); + PlayerControl.SetPetImage(pet, (int)PlayerControl.LocalPlayer.Data.ColorId, chip.Inner); + this.ColorChips.Add(chip); + } + this.scroller.YBounds.max = -(this.YStart - (float)(unlockedPets.Length / this.NumPerRow) * this.YOffset) - 3f; + } + + public void OnDisable() + { + for (int i = 0; i < this.ColorChips.Count; i++) + { + UnityEngine.Object.Destroy(this.ColorChips[i].gameObject); + } + this.ColorChips.Clear(); + } + + private void SelectPet(ColorChip sender, PetBehaviour pet) + { + uint idFromPet = DestroyableSingleton<HatManager>.Instance.GetIdFromPet(pet); + SaveManager.LastPet = idFromPet; + PlayerControl.SetPetImage(pet, (int)PlayerControl.LocalPlayer.Data.ColorId, this.PetImage); + if (PlayerControl.LocalPlayer) + { + PlayerControl.LocalPlayer.RpcSetPet(idFromPet); + } + for (int i = 0; i < this.ColorChips.Count; i++) + { + ColorChip colorChip = this.ColorChips[i]; + colorChip.InUseForeground.SetActive(colorChip == sender); + } + } +} diff --git a/Client/Assembly-CSharp/PhysicsHelpers.cs b/Client/Assembly-CSharp/PhysicsHelpers.cs new file mode 100644 index 0000000..706073f --- /dev/null +++ b/Client/Assembly-CSharp/PhysicsHelpers.cs @@ -0,0 +1,38 @@ +using System; +using UnityEngine; + +public static class PhysicsHelpers +{ + private static RaycastHit2D[] castHits = new RaycastHit2D[20]; + + private static Vector2 temp = default(Vector2); + + private static ContactFilter2D filter = new ContactFilter2D + { + useLayerMask = true + }; + + public static bool AnythingBetween(Vector2 source, Vector2 target, int layerMask, bool useTriggers) + { + PhysicsHelpers.filter.layerMask = layerMask; + PhysicsHelpers.filter.useTriggers = useTriggers; + PhysicsHelpers.temp.x = target.x - source.x; + PhysicsHelpers.temp.y = target.y - source.y; + return Physics2D.Raycast(source, PhysicsHelpers.temp, PhysicsHelpers.filter, PhysicsHelpers.castHits, PhysicsHelpers.temp.magnitude) > 0; + } + + public static bool AnyNonTriggersBetween(Vector2 source, Vector2 dirNorm, float mag, int layerMask) + { + int num = Physics2D.RaycastNonAlloc(source, dirNorm, PhysicsHelpers.castHits, mag, layerMask); + bool result = false; + for (int i = 0; i < num; i++) + { + if (!PhysicsHelpers.castHits[i].collider.isTrigger) + { + result = true; + break; + } + } + return result; + } +} diff --git a/Client/Assembly-CSharp/PingTracker.cs b/Client/Assembly-CSharp/PingTracker.cs new file mode 100644 index 0000000..727d71c --- /dev/null +++ b/Client/Assembly-CSharp/PingTracker.cs @@ -0,0 +1,19 @@ +using System; +using UnityEngine; + +public class PingTracker : MonoBehaviour +{ + public TextRenderer text; + + private void Update() + { + if (AmongUsClient.Instance) + { + if (AmongUsClient.Instance.GameMode == GameModes.FreePlay) + { + base.gameObject.SetActive(false); + } + this.text.Text = string.Format("Ping: {0} ms", AmongUsClient.Instance.Ping); + } + } +} diff --git a/Client/Assembly-CSharp/PlayerAnimator.cs b/Client/Assembly-CSharp/PlayerAnimator.cs new file mode 100644 index 0000000..dd48ace --- /dev/null +++ b/Client/Assembly-CSharp/PlayerAnimator.cs @@ -0,0 +1,90 @@ +using System; +using System.Collections; +using PowerTools; +using UnityEngine; + +public class PlayerAnimator : MonoBehaviour +{ + public float Speed = 2.5f; + + public VirtualJoystick joystick; + + public SpriteRenderer UseButton; + + public FingerBehaviour finger; + + public AnimationClip RunAnim; + + public AnimationClip IdleAnim; + + private Vector2 velocity; + + [HideInInspector] + private SpriteAnim Animator; + + [HideInInspector] + private SpriteRenderer rend; + + public int NearbyConsoles; + + private void Start() + { + this.Animator = base.GetComponent<SpriteAnim>(); + this.rend = base.GetComponent<SpriteRenderer>(); + this.rend.material.SetColor("_BackColor", Palette.ShadowColors[0]); + this.rend.material.SetColor("_BodyColor", Palette.PlayerColors[0]); + this.rend.material.SetColor("_VisorColor", Palette.VisorColor); + } + + public void FixedUpdate() + { + base.transform.Translate(this.velocity * Time.fixedDeltaTime); + this.UseButton.enabled = (this.NearbyConsoles > 0); + } + + public void LateUpdate() + { + if (this.velocity.sqrMagnitude >= 0.1f) + { + if (this.Animator.GetCurrentAnimation() != this.RunAnim) + { + this.Animator.Play(this.RunAnim, 1f); + } + this.rend.flipX = (this.velocity.x < 0f); + return; + } + if (this.Animator.GetCurrentAnimation() == this.RunAnim) + { + this.Animator.Play(this.IdleAnim, 1f); + } + } + + public IEnumerator WalkPlayerTo(Vector2 worldPos, bool relax, float tolerance = 0.01f) + { + worldPos.y += 0.3636f; + if (!(this.joystick is DemoKeyboardStick)) + { + this.finger.ClickOn(); + } + for (;;) + { + Vector2 vector2; + Vector2 vector = vector2 = worldPos - base.transform.position; + if (vector2.sqrMagnitude <= tolerance) + { + break; + } + float d = Mathf.Clamp(vector.magnitude * 2f, 0.01f, 1f); + this.velocity = vector.normalized * this.Speed * d; + this.joystick.UpdateJoystick(this.finger, this.velocity, true); + yield return null; + } + if (relax) + { + this.finger.ClickOff(); + this.velocity = Vector2.zero; + this.joystick.UpdateJoystick(this.finger, this.velocity, false); + } + yield break; + } +} diff --git a/Client/Assembly-CSharp/PlayerControl.cs b/Client/Assembly-CSharp/PlayerControl.cs new file mode 100644 index 0000000..f0e5fbc --- /dev/null +++ b/Client/Assembly-CSharp/PlayerControl.cs @@ -0,0 +1,1470 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using Assets.CoreScripts; +using Hazel; +using InnerNet; +using PowerTools; +using UnityEngine; + +public class PlayerControl : InnerNetObject +{ + public bool CanMove + { + get + { + return this.moveable && !Minigame.Instance && (!DestroyableSingleton<HudManager>.InstanceExists || (!DestroyableSingleton<HudManager>.Instance.Chat.IsOpen && !DestroyableSingleton<HudManager>.Instance.KillOverlay.IsOpen && !DestroyableSingleton<HudManager>.Instance.GameMenu.IsOpen)) && (!MapBehaviour.Instance || !MapBehaviour.Instance.IsOpenStopped) && !MeetingHud.Instance && !CustomPlayerMenu.Instance && !ExileController.Instance && !IntroCutscene.Instance; + } + } + + public GameData.PlayerInfo Data + { + get + { + if (this._cachedData == null) + { + if (!GameData.Instance) + { + return null; + } + this._cachedData = GameData.Instance.GetPlayerById(this.PlayerId); + } + return this._cachedData; + } + } + + public bool Visible + { + get + { + return this.myRend.enabled; + } + set + { + this.myRend.enabled = value; + this.MyPhysics.Skin.Visible = value; + this.HatRenderer.enabled = value; + this.nameText.gameObject.SetActive(value); + } + } + + public byte PlayerId = byte.MaxValue; + + public float MaxReportDistance = 5f; + + public bool moveable = true; + + public bool inVent; + + public static PlayerControl LocalPlayer; + + private GameData.PlayerInfo _cachedData; + + public AudioSource FootSteps; + + public AudioClip KillSfx; + + public KillAnimation[] KillAnimations; + + [SerializeField] + private float killTimer; + + public int RemainingEmergencies; + + public TextRenderer nameText; + + public LightSource LightPrefab; + + private LightSource myLight; + + [HideInInspector] + public Collider2D Collider; + + [HideInInspector] + public PlayerPhysics MyPhysics; + + [HideInInspector] + public CustomNetworkTransform NetTransform; + + public PetBehaviour CurrentPet; + + public SpriteRenderer HatRenderer; + + private SpriteRenderer myRend; + + private Collider2D[] hitBuffer = new Collider2D[20]; + + public static GameOptionsData GameOptions = new GameOptionsData(); + + public List<PlayerTask> myTasks = new List<PlayerTask>(); + + [NonSerialized] + public uint TaskIdCount; + + public SpriteAnim[] ScannerAnims; + + public SpriteRenderer[] ScannersImages; + + public AudioClip[] VentMoveSounds; + + public AudioClip VentEnterSound; + + private IUsable closest; + + private bool isNew = true; + + public float crewStreak; + + public static List<PlayerControl> AllPlayerControls = new List<PlayerControl>(); + + private Dictionary<Collider2D, IUsable> cache = new Dictionary<Collider2D, IUsable>(PlayerControl.ColliderComparer.Instance); + + private List<IUsable> itemsInRange = new List<IUsable>(); + + private List<IUsable> newItemsInRange = new List<IUsable>(); + + private byte scannerCount; + + private int LastStartCounter; + + public class ColliderComparer : IEqualityComparer<Collider2D> + { + public static readonly PlayerControl.ColliderComparer Instance = new PlayerControl.ColliderComparer(); + + public bool Equals(Collider2D x, Collider2D y) + { + return x == y; + } + + public int GetHashCode(Collider2D obj) + { + return obj.GetInstanceID(); + } + } + + public class UsableComparer : IEqualityComparer<IUsable> + { + public static readonly PlayerControl.UsableComparer Instance = new PlayerControl.UsableComparer(); + + public bool Equals(IUsable x, IUsable y) + { + return x == y; + } + + public int GetHashCode(IUsable obj) + { + return obj.GetHashCode(); + } + } + + public enum RpcCalls : byte + { + PlayAnimation, + CompleteTask, + SyncSettings, + SetInfected, + Exiled, + CheckName, + SetName, + CheckColor, + SetColor, + SetHat, + SetSkin, + ReportDeadBody, + MurderPlayer, + SendChat, + TimesImpostor, + StartMeeting, + SetScanner, + SendChatNote, + SetPet, + SetStartCounter + } + + public void SetKillTimer(float time) + { + this.killTimer = time; + if (PlayerControl.GameOptions.KillCooldown > 0f) + { + DestroyableSingleton<HudManager>.Instance.KillButton.SetCoolDown(this.killTimer, PlayerControl.GameOptions.KillCooldown); + return; + } + DestroyableSingleton<HudManager>.Instance.KillButton.SetCoolDown(0f, PlayerControl.GameOptions.KillCooldown); + } + + private void Awake() + { + this.myRend = base.GetComponent<SpriteRenderer>(); + this.MyPhysics = base.GetComponent<PlayerPhysics>(); + this.NetTransform = base.GetComponent<CustomNetworkTransform>(); + this.Collider = base.GetComponent<Collider2D>(); + PlayerControl.AllPlayerControls.Add(this); + } + + private void Start() + { + this.RemainingEmergencies = PlayerControl.GameOptions.NumEmergencyMeetings; + if (base.AmOwner) + { + this.myLight = UnityEngine.Object.Instantiate<LightSource>(this.LightPrefab); + this.myLight.transform.SetParent(base.transform); + this.myLight.transform.localPosition = this.Collider.offset; + PlayerControl.LocalPlayer = this; + Camera.main.GetComponent<FollowerCamera>().SetTarget(this); + this.SetName(SaveManager.PlayerName); + this.SetColor(SaveManager.BodyColor); + this.CmdCheckName(SaveManager.PlayerName); + this.CmdCheckColor(SaveManager.BodyColor); + this.RpcSetPet(SaveManager.LastPet); + this.RpcSetHat(SaveManager.LastHat); + this.RpcSetSkin(SaveManager.LastSkin); + this.RpcSetTimesImpostor(StatsManager.Instance.CrewmateStreak); + } + else + { + base.StartCoroutine(this.ClientInitialize()); + } + if (this.isNew) + { + this.isNew = false; + base.StartCoroutine(this.MyPhysics.CoSpawnPlayer(LobbyBehaviour.Instance)); + } + } + + private IEnumerator ClientInitialize() + { + this.Visible = false; + while (!GameData.Instance) + { + yield return null; + } + while (this.Data == null) + { + yield return null; + } + while (string.IsNullOrEmpty(this.Data.PlayerName)) + { + yield return null; + } + this.SetName(this.Data.PlayerName); + this.SetColor(this.Data.ColorId); + this.SetHat(this.Data.HatId); + this.SetSkin(this.Data.SkinId); + this.SetPet(this.Data.PetId); + this.Visible = true; + yield break; + } + + public override void OnDestroy() + { + if (this.CurrentPet) + { + UnityEngine.Object.Destroy(this.CurrentPet.gameObject); + } + PlayerControl.AllPlayerControls.Remove(this); + base.OnDestroy(); + } + + private void FixedUpdate() + { + if (!GameData.Instance) + { + return; + } + GameData.PlayerInfo data = this.Data; + if (data == null) + { + return; + } + if (data.IsDead && PlayerControl.LocalPlayer) + { + this.Visible = PlayerControl.LocalPlayer.Data.IsDead; + } + if (base.AmOwner) + { + if (ShipStatus.Instance) + { + this.myLight.LightRadius = ShipStatus.Instance.CalculateLightRadius(data); + } + if (data.IsImpostor && this.CanMove && !data.IsDead) + { + this.SetKillTimer(Mathf.Max(0f, this.killTimer - Time.fixedDeltaTime)); + PlayerControl target = this.FindClosestTarget(); + DestroyableSingleton<HudManager>.Instance.KillButton.SetTarget(target); + } + else + { + DestroyableSingleton<HudManager>.Instance.KillButton.SetTarget(null); + } + if (this.CanMove || this.inVent) + { + this.newItemsInRange.Clear(); + bool flag = (PlayerControl.GameOptions.GhostsDoTasks || !data.IsDead) && (!AmongUsClient.Instance || !AmongUsClient.Instance.IsGameOver) && this.CanMove; + Vector2 truePosition = this.GetTruePosition(); + int num = Physics2D.OverlapCircleNonAlloc(truePosition, this.MaxReportDistance, this.hitBuffer, Constants.Usables); + IUsable usable = null; + float num2 = float.MaxValue; + bool flag2 = false; + for (int i = 0; i < num; i++) + { + Collider2D collider2D = this.hitBuffer[i]; + IUsable usable2; + if (!this.cache.TryGetValue(collider2D, out usable2)) + { + usable2 = (this.cache[collider2D] = collider2D.GetComponent<IUsable>()); + } + if (usable2 != null && (flag || this.inVent)) + { + bool flag3; + bool flag4; + float num3 = usable2.CanUse(data, out flag3, out flag4); + if (flag3 || flag4) + { + this.newItemsInRange.Add(usable2); + } + if (flag3 && num3 < num2) + { + num2 = num3; + usable = usable2; + } + } + if (flag && !data.IsDead && !flag2 && collider2D.tag == "DeadBody") + { + DeadBody component = collider2D.GetComponent<DeadBody>(); + if (!PhysicsHelpers.AnythingBetween(truePosition, component.TruePosition, Constants.ShipAndObjectsMask, false)) + { + flag2 = true; + } + } + } + for (int l = this.itemsInRange.Count - 1; l > -1; l--) + { + IUsable item = this.itemsInRange[l]; + int num4 = this.newItemsInRange.FindIndex((IUsable j) => j == item); + if (num4 == -1) + { + item.SetOutline(false, false); + this.itemsInRange.RemoveAt(l); + } + else + { + this.newItemsInRange.RemoveAt(num4); + item.SetOutline(true, usable == item); + } + } + for (int k = 0; k < this.newItemsInRange.Count; k++) + { + IUsable usable3 = this.newItemsInRange[k]; + usable3.SetOutline(true, usable == usable3); + this.itemsInRange.Add(usable3); + } + this.closest = usable; + DestroyableSingleton<HudManager>.Instance.UseButton.SetTarget(usable); + DestroyableSingleton<HudManager>.Instance.ReportButton.SetActive(flag2); + return; + } + this.closest = null; + DestroyableSingleton<HudManager>.Instance.UseButton.SetTarget(null); + DestroyableSingleton<HudManager>.Instance.ReportButton.SetActive(false); + } + } + + public void UseClosest() + { + if (this.closest != null) + { + this.closest.Use(); + } + this.closest = null; + DestroyableSingleton<HudManager>.Instance.UseButton.SetTarget(null); + } + + public void ReportClosest() + { + if (AmongUsClient.Instance.IsGameOver) + { + return; + } + if (PlayerControl.LocalPlayer.Data.IsDead) + { + return; + } + foreach (Collider2D collider2D in Physics2D.OverlapCircleAll(base.transform.position, this.MaxReportDistance, Constants.NotShipMask)) + { + if (!(collider2D.tag != "DeadBody")) + { + DeadBody component = collider2D.GetComponent<DeadBody>(); + if (component && !component.Reported) + { + component.OnClick(); + if (component.Reported) + { + break; + } + } + } + } + } + + public void PlayStepSound() + { + if (!Constants.ShouldPlaySfx()) + { + return; + } + if (DestroyableSingleton<HudManager>.InstanceExists && PlayerControl.LocalPlayer == this) + { + ShipRoom lastRoom = DestroyableSingleton<HudManager>.Instance.roomTracker.LastRoom; + if (lastRoom && lastRoom.FootStepSounds) + { + AudioClip clip = lastRoom.FootStepSounds.Random(); + this.FootSteps.clip = clip; + this.FootSteps.Play(); + } + } + } + + private void SetScanner(bool on, byte cnt) + { + if (cnt < this.scannerCount) + { + return; + } + this.scannerCount = cnt; + for (int i = 0; i < this.ScannerAnims.Length; i++) + { + SpriteAnim spriteAnim = this.ScannerAnims[i]; + if (on && !this.Data.IsDead) + { + spriteAnim.gameObject.SetActive(true); + spriteAnim.Play(null, 1f); + this.ScannersImages[i].flipX = !this.myRend.flipX; + } + else + { + if (spriteAnim.isActiveAndEnabled) + { + spriteAnim.Stop(); + } + spriteAnim.gameObject.SetActive(false); + } + } + } + + public Vector2 GetTruePosition() + { + return base.transform.position + this.Collider.offset; + } + + private PlayerControl FindClosestTarget() + { + PlayerControl result = null; + float num = GameOptionsData.KillDistances[Mathf.Clamp(PlayerControl.GameOptions.KillDistance, 0, 2)]; + if (!ShipStatus.Instance) + { + return null; + } + Vector2 truePosition = this.GetTruePosition(); + List<GameData.PlayerInfo> allPlayers = GameData.Instance.AllPlayers; + for (int i = 0; i < allPlayers.Count; i++) + { + GameData.PlayerInfo playerInfo = allPlayers[i]; + if (!playerInfo.Disconnected && playerInfo.PlayerId != this.PlayerId && !playerInfo.IsDead && !playerInfo.IsImpostor) + { + PlayerControl @object = playerInfo.Object; + if (@object) + { + Vector2 vector = @object.GetTruePosition() - truePosition; + float magnitude = vector.magnitude; + if (magnitude <= num && !PhysicsHelpers.AnyNonTriggersBetween(truePosition, vector.normalized, magnitude, Constants.ShipAndObjectsMask)) + { + result = @object; + num = magnitude; + } + } + } + } + return result; + } + + public void SetTasks(byte[] tasks) + { + base.StartCoroutine(this.CoSetTasks(tasks)); + } + + private IEnumerator CoSetTasks(byte[] tasks) + { + while (!ShipStatus.Instance) + { + yield return null; + } + if (base.AmOwner) + { + DestroyableSingleton<HudManager>.Instance.TaskStuff.SetActive(true); + StatsManager instance = StatsManager.Instance; + uint num = instance.GamesStarted; + instance.GamesStarted = num + 1U; + if (this.Data.IsImpostor) + { + StatsManager instance2 = StatsManager.Instance; + num = instance2.TimesImpostor; + instance2.TimesImpostor = num + 1U; + StatsManager.Instance.CrewmateStreak = 0U; + } + else + { + StatsManager instance3 = StatsManager.Instance; + num = instance3.TimesCrewmate; + instance3.TimesCrewmate = num + 1U; + StatsManager instance4 = StatsManager.Instance; + num = instance4.CrewmateStreak; + instance4.CrewmateStreak = num + 1U; + DestroyableSingleton<HudManager>.Instance.KillButton.gameObject.SetActive(false); + } + DestroyableSingleton<Telemetry>.Instance.StartGame(SaveManager.SendName, AmongUsClient.Instance.AmHost, GameData.Instance.PlayerCount, PlayerControl.GameOptions.NumImpostors, AmongUsClient.Instance.GameMode, StatsManager.Instance.TimesImpostor, StatsManager.Instance.GamesStarted, StatsManager.Instance.CrewmateStreak); + } + foreach (byte idx in tasks) + { + NormalPlayerTask normalPlayerTask = UnityEngine.Object.Instantiate<NormalPlayerTask>(ShipStatus.Instance.GetTaskById(idx), base.transform); + PlayerTask playerTask = normalPlayerTask; + uint num = this.TaskIdCount; + this.TaskIdCount = num + 1U; + playerTask.Id = num; + normalPlayerTask.Owner = this; + normalPlayerTask.Initialize(); + this.myTasks.Add(normalPlayerTask); + } + yield break; + } + + public void AddSystemTask(SystemTypes system) + { + PlayerTask original; + if (system <= SystemTypes.Electrical) + { + if (system != SystemTypes.Reactor) + { + if (system != SystemTypes.Electrical) + { + return; + } + original = ShipStatus.Instance.SpecialTasks[1]; + } + else + { + original = ShipStatus.Instance.SpecialTasks[0]; + } + } + else if (system != SystemTypes.LifeSupp) + { + if (system != SystemTypes.Comms) + { + return; + } + original = ShipStatus.Instance.SpecialTasks[2]; + } + else + { + original = ShipStatus.Instance.SpecialTasks[3]; + } + PlayerControl localPlayer = PlayerControl.LocalPlayer; + PlayerTask playerTask = UnityEngine.Object.Instantiate<PlayerTask>(original, localPlayer.transform); + PlayerTask playerTask2 = playerTask; + PlayerControl playerControl = localPlayer; + uint taskIdCount = playerControl.TaskIdCount; + playerControl.TaskIdCount = taskIdCount + 1U; + playerTask2.Id = (uint)((byte)taskIdCount); + playerTask.Owner = localPlayer; + playerTask.Initialize(); + localPlayer.myTasks.Add(playerTask); + } + + public void RemoveTask(PlayerTask task) + { + task.OnRemove(); + this.myTasks.Remove(task); + GameData.Instance.TutOnlyRemoveTask(this.PlayerId, task.Id); + DestroyableSingleton<HudManager>.Instance.UseButton.SetTarget(null); + UnityEngine.Object.Destroy(task.gameObject); + } + + private void ClearTasks() + { + for (int i = 0; i < this.myTasks.Count; i++) + { + PlayerTask playerTask = this.myTasks[i]; + playerTask.OnRemove(); + UnityEngine.Object.Destroy(playerTask.gameObject); + } + this.myTasks.Clear(); + } + + public void RemoveInfected() + { + GameData.PlayerInfo playerById = GameData.Instance.GetPlayerById(this.PlayerId); + if (playerById.IsImpostor) + { + playerById.Object.nameText.Color = Color.white; + playerById.IsImpostor = false; + this.myTasks.RemoveAt(0); + DestroyableSingleton<HudManager>.Instance.KillButton.gameObject.SetActive(false); + } + } + + public void Die(DeathReason reason) + { + if (!DestroyableSingleton<TutorialManager>.InstanceExists) + { + StatsManager.Instance.LastGameStarted = DateTime.MinValue; + StatsManager instance = StatsManager.Instance; + float banPoints = instance.BanPoints; + instance.BanPoints = banPoints - 1f; + } + TempData.LastDeathReason = reason; + if (this.CurrentPet) + { + this.CurrentPet.SetMourning(); + } + this.Data.IsDead = true; + base.gameObject.layer = LayerMask.NameToLayer("Ghost"); + this.nameText.GetComponent<MeshRenderer>().material.SetInt("_Mask", 0); + if (base.AmOwner) + { + DestroyableSingleton<HudManager>.Instance.Chat.SetVisible(true); + } + } + + public void Revive() + { + this.Data.IsDead = false; + base.gameObject.layer = LayerMask.NameToLayer("Players"); + this.MyPhysics.ResetAnim(true); + if (this.CurrentPet) + { + this.CurrentPet.Source = this; + } + this.nameText.GetComponent<MeshRenderer>().material.SetInt("_Mask", 4); + if (base.AmOwner) + { + DestroyableSingleton<HudManager>.Instance.KillButton.gameObject.SetActive(this.Data.IsImpostor); + DestroyableSingleton<HudManager>.Instance.Chat.ForceClosed(); + DestroyableSingleton<HudManager>.Instance.Chat.SetVisible(false); + } + } + + public void PlayAnimation(byte animType) + { + if (animType == 1) + { + ShipStatus.Instance.StartShields(); + return; + } + if (animType == 6) + { + ShipStatus.Instance.FireWeapon(); + return; + } + if (animType - 9 > 1) + { + return; + } + ShipStatus.Instance.OpenHatch(); + } + + public void CompleteTask(uint idx) + { + PlayerTask playerTask = this.myTasks.Find((PlayerTask p) => p.Id == idx); + if (playerTask) + { + GameData.Instance.CompleteTask(this, idx); + playerTask.Complete(); + DestroyableSingleton<Telemetry>.Instance.WriteCompleteTask(this.PlayerId, playerTask.TaskType); + return; + } + Debug.LogWarning(this.PlayerId + ": Server didn't have task: " + idx); + } + + public void SetInfected(byte[] infected) + { + if (!GameData.Instance) + { + Debug.Log("No game data instance."); + } + StatsManager instance = StatsManager.Instance; + float banPoints = instance.BanPoints; + instance.BanPoints = banPoints + 1f; + StatsManager.Instance.LastGameStarted = DateTime.UtcNow; + for (int i = 0; i < infected.Length; i++) + { + GameData.PlayerInfo playerById = GameData.Instance.GetPlayerById(infected[i]); + if (playerById != null) + { + playerById.IsImpostor = true; + } + else + { + Debug.LogError("Couldn't set impostor: " + infected[i]); + } + } + DestroyableSingleton<HudManager>.Instance.MapButton.gameObject.SetActive(true); + DestroyableSingleton<HudManager>.Instance.ReportButton.gameObject.SetActive(true); + PlayerControl.LocalPlayer.RemainingEmergencies = PlayerControl.GameOptions.NumEmergencyMeetings; + GameData.PlayerInfo data = PlayerControl.LocalPlayer.Data; + if (data.IsImpostor) + { + ImportantTextTask importantTextTask = new GameObject("_Player").AddComponent<ImportantTextTask>(); + importantTextTask.transform.SetParent(PlayerControl.LocalPlayer.transform, false); + importantTextTask.Text = DestroyableSingleton<TranslationController>.Instance.GetString(StringNames.ImpostorTask, Array.Empty<object>()) + "\r\n[FFFFFFFF]" + DestroyableSingleton<TranslationController>.Instance.GetString(StringNames.FakeTasks, Array.Empty<object>()); + this.myTasks.Insert(0, importantTextTask); + DestroyableSingleton<HudManager>.Instance.KillButton.gameObject.SetActive(true); + PlayerControl.LocalPlayer.SetKillTimer(10f); + for (int j = 0; j < infected.Length; j++) + { + GameData.PlayerInfo playerById2 = GameData.Instance.GetPlayerById(infected[j]); + if (playerById2 != null) + { + playerById2.Object.nameText.Color = Palette.ImpostorRed; + } + } + } + if (!DestroyableSingleton<TutorialManager>.InstanceExists) + { + List<PlayerControl> yourTeam; + if (data.IsImpostor) + { + yourTeam = (from pcd in GameData.Instance.AllPlayers + where !pcd.Disconnected + where pcd.IsImpostor + select pcd.Object).OrderBy(delegate(PlayerControl pc) + { + if (!(pc == PlayerControl.LocalPlayer)) + { + return 1; + } + return 0; + }).ToList<PlayerControl>(); + } + else + { + yourTeam = (from pcd in GameData.Instance.AllPlayers + where !pcd.Disconnected + select pcd.Object).OrderBy(delegate(PlayerControl pc) + { + if (!(pc == PlayerControl.LocalPlayer)) + { + return 1; + } + return 0; + }).ToList<PlayerControl>(); + } + base.StopAllCoroutines(); + DestroyableSingleton<HudManager>.Instance.StartCoroutine(DestroyableSingleton<HudManager>.Instance.CoShowIntro(yourTeam)); + } + } + + public void Exiled() + { + this.Die(DeathReason.Exile); + if (base.AmOwner) + { + StatsManager instance = StatsManager.Instance; + uint timesEjected = instance.TimesEjected; + instance.TimesEjected = timesEjected + 1U; + DestroyableSingleton<HudManager>.Instance.ShadowQuad.gameObject.SetActive(false); + ImportantTextTask importantTextTask = new GameObject("_Player").AddComponent<ImportantTextTask>(); + importantTextTask.transform.SetParent(base.transform, false); + if (this.Data.IsImpostor) + { + this.ClearTasks(); + importantTextTask.Text = DestroyableSingleton<TranslationController>.Instance.GetString(StringNames.GhostImpostor, Array.Empty<object>()); + } + else if (!PlayerControl.GameOptions.GhostsDoTasks) + { + this.ClearTasks(); + importantTextTask.Text = DestroyableSingleton<TranslationController>.Instance.GetString(StringNames.GhostIgnoreTasks, Array.Empty<object>()); + } + else + { + importantTextTask.Text = DestroyableSingleton<TranslationController>.Instance.GetString(StringNames.GhostDoTasks, Array.Empty<object>()); + } + this.myTasks.Insert(0, importantTextTask); + } + } + + public void CheckName(string name) + { + List<GameData.PlayerInfo> allPlayers = GameData.Instance.AllPlayers; + bool flag = allPlayers.Any((GameData.PlayerInfo i) => i.PlayerId != this.PlayerId && i.PlayerName.Equals(name, StringComparison.OrdinalIgnoreCase)); + if (flag) + { + for (int k = 1; k < 100; k++) + { + string text = name + " " + k; + flag = false; + for (int j = 0; j < allPlayers.Count; j++) + { + if (allPlayers[j].PlayerId != this.PlayerId && allPlayers[j].PlayerName.Equals(text, StringComparison.OrdinalIgnoreCase)) + { + flag = true; + break; + } + } + if (!flag) + { + name = text; + break; + } + } + } + this.RpcSetName(name); + GameData.Instance.UpdateName(this.PlayerId, name); + } + + public void SetName(string name) + { + if (GameData.Instance) + { + GameData.Instance.UpdateName(this.PlayerId, name); + } + base.gameObject.name = name; + this.nameText.Text = name; + this.nameText.GetComponent<MeshRenderer>().material.SetInt("_Mask", 4); + } + + public void CheckColor(byte bodyColor) + { + List<GameData.PlayerInfo> allPlayers = GameData.Instance.AllPlayers; + int num = 0; + while (num++ < 100 && allPlayers.Any((GameData.PlayerInfo p) => !p.Disconnected && p.PlayerId != this.PlayerId && p.ColorId == bodyColor)) + { + bodyColor = (byte)((int)(bodyColor + 1) % Palette.PlayerColors.Length); + } + this.RpcSetColor(bodyColor); + } + + public void SetHatAlpha(float a) + { + Color white = Color.white; + white.a = a; + this.HatRenderer.color = white; + } + + public void SetColor(byte bodyColor) + { + if (GameData.Instance) + { + GameData.Instance.UpdateColor(this.PlayerId, bodyColor); + } + if (this.myRend == null) + { + base.GetComponent<SpriteRenderer>(); + } + PlayerControl.SetPlayerMaterialColors((int)bodyColor, this.myRend); + if (this.CurrentPet) + { + PlayerControl.SetPlayerMaterialColors((int)bodyColor, this.CurrentPet.rend); + } + } + + public void SetSkin(uint skinId) + { + if (GameData.Instance) + { + GameData.Instance.UpdateSkin(this.PlayerId, skinId); + } + this.MyPhysics.SetSkin(skinId); + } + + public void SetHat(uint hatId) + { + if (GameData.Instance) + { + GameData.Instance.UpdateHat(this.PlayerId, hatId); + } + PlayerControl.SetHatImage(hatId, this.HatRenderer); + this.nameText.transform.localPosition = new Vector3(0f, (hatId == 0U) ? 0.7f : 1.05f, -0.5f); + } + + public void SetPet(uint petId) + { + if (this.CurrentPet) + { + UnityEngine.Object.Destroy(this.CurrentPet.gameObject); + } + this.CurrentPet = UnityEngine.Object.Instantiate<PetBehaviour>(DestroyableSingleton<HatManager>.Instance.GetPetById(petId)); + this.CurrentPet.transform.position = base.transform.position; + this.CurrentPet.Source = this; + GameData.PlayerInfo data = this.Data; + if (this.Data != null) + { + GameData.Instance.UpdatePet(this.PlayerId, petId); + this.Data.PetId = petId; + PlayerControl.SetPlayerMaterialColors((int)this.Data.ColorId, this.CurrentPet.rend); + } + } + + public static void SetPetImage(uint petId, int colorId, SpriteRenderer target) + { + if (!DestroyableSingleton<HatManager>.InstanceExists) + { + return; + } + PlayerControl.SetPetImage(DestroyableSingleton<HatManager>.Instance.GetPetById(petId), colorId, target); + } + + public static void SetPetImage(PetBehaviour pet, int colorId, SpriteRenderer target) + { + target.sprite = pet.rend.sprite; + if (target != pet.rend) + { + target.material = new Material(pet.rend.sharedMaterial); + PlayerControl.SetPlayerMaterialColors(colorId, target); + } + } + + public static void SetSkinImage(uint skinId, SpriteRenderer target) + { + if (!DestroyableSingleton<HatManager>.InstanceExists) + { + return; + } + PlayerControl.SetSkinImage(DestroyableSingleton<HatManager>.Instance.GetSkinById(skinId), target); + } + + public static void SetSkinImage(SkinData skin, SpriteRenderer target) + { + target.sprite = skin.IdleFrame; + } + + public static void SetHatImage(uint hatId, SpriteRenderer target) + { + if (!DestroyableSingleton<HatManager>.InstanceExists) + { + return; + } + PlayerControl.SetHatImage(DestroyableSingleton<HatManager>.Instance.GetHatById(hatId), target); + } + + public static void SetHatImage(HatBehaviour hat, SpriteRenderer target) + { + if (!target) + { + return; + } + if (hat) + { + target.sprite = hat.MainImage; + Vector3 localPosition = target.transform.localPosition; + localPosition.z = (hat.InFront ? -0.0001f : 0.0001f); + target.transform.localPosition = localPosition; + return; + } + string str = (!hat) ? "null" : hat.name; + Debug.LogError("Player: " + target.name + "\tHat: " + str); + } + + private void ReportDeadBody(GameData.PlayerInfo target) + { + if (AmongUsClient.Instance.IsGameOver) + { + return; + } + if (MeetingHud.Instance) + { + return; + } + if (target == null && PlayerControl.LocalPlayer.myTasks.Any(new Func<PlayerTask, bool>(PlayerTask.TaskIsEmergency))) + { + return; + } + if (this.Data.IsDead) + { + return; + } + MeetingRoomManager.Instance.AssignSelf(this, target); + if (!AmongUsClient.Instance.AmHost) + { + return; + } + if (ShipStatus.Instance.CheckTaskCompletion()) + { + return; + } + DestroyableSingleton<HudManager>.Instance.OpenMeetingRoom(this); + this.RpcStartMeeting(target); + } + + public IEnumerator CoStartMeeting(GameData.PlayerInfo target) + { + DestroyableSingleton<Telemetry>.Instance.WriteMeetingStarted(target == null); + while (!MeetingHud.Instance) + { + yield return null; + } + MeetingRoomManager.Instance.RemoveSelf(); + DeadBody[] array = UnityEngine.Object.FindObjectsOfType<DeadBody>(); + for (int i = 0; i < array.Length; i++) + { + UnityEngine.Object.Destroy(array[i].gameObject); + } + for (int j = 0; j < PlayerControl.AllPlayerControls.Count; j++) + { + PlayerControl playerControl = PlayerControl.AllPlayerControls[j]; + if (!playerControl.GetComponent<DummyBehaviour>().enabled) + { + playerControl.MyPhysics.ExitAllVents(); + playerControl.NetTransform.SnapTo(ShipStatus.Instance.GetSpawnLocation((int)playerControl.PlayerId, GameData.Instance.PlayerCount)); + } + } + if (base.AmOwner) + { + if (target != null) + { + StatsManager instance = StatsManager.Instance; + uint num = instance.BodiesReported; + instance.BodiesReported = num + 1U; + } + else + { + this.RemainingEmergencies--; + StatsManager instance2 = StatsManager.Instance; + uint num = instance2.EmergenciesCalled; + instance2.EmergenciesCalled = num + 1U; + } + } + if (MapBehaviour.Instance) + { + MapBehaviour.Instance.Close(); + } + if (Minigame.Instance) + { + Minigame.Instance.Close(); + } + KillAnimation.SetMovement(this, true); + MeetingHud.Instance.StartCoroutine(MeetingHud.Instance.CoIntro(this, target)); + yield break; + } + + public void MurderPlayer(PlayerControl target) + { + if (AmongUsClient.Instance.IsGameOver) + { + return; + } + if (!target || this.Data.IsDead || !this.Data.IsImpostor || this.Data.Disconnected) + { + Debug.LogWarning(string.Format("Bad kill from {0} to {1}", this.PlayerId, ((int)((target != null) ? new byte?(target.PlayerId) : null)) ?? -1)); + return; + } + GameData.PlayerInfo data = target.Data; + if (data != null && !data.IsDead) + { + if (base.AmOwner) + { + StatsManager instance = StatsManager.Instance; + uint num = instance.ImpostorKills; + instance.ImpostorKills = num + 1U; + if (Constants.ShouldPlaySfx()) + { + SoundManager.Instance.PlaySound(PlayerControl.LocalPlayer.KillSfx, false, 0.8f); + } + } + this.SetKillTimer(PlayerControl.GameOptions.KillCooldown); + DestroyableSingleton<Telemetry>.Instance.WriteMurder(this.PlayerId, target.PlayerId, target.transform.position); + target.gameObject.layer = LayerMask.NameToLayer("Ghost"); + if (target.AmOwner) + { + StatsManager instance2 = StatsManager.Instance; + uint num = instance2.TimesMurdered; + instance2.TimesMurdered = num + 1U; + if (Minigame.Instance) + { + Minigame.Instance.Close(); + Minigame.Instance.Close(); + } + DestroyableSingleton<HudManager>.Instance.ShadowQuad.gameObject.SetActive(false); + target.nameText.GetComponent<MeshRenderer>().material.SetInt("_Mask", 0); + DestroyableSingleton<HudManager>.Instance.KillOverlay.ShowOne(this, data); + target.RpcSetScanner(false); + ImportantTextTask importantTextTask = new GameObject("_Player").AddComponent<ImportantTextTask>(); + importantTextTask.transform.SetParent(base.transform, false); + if (!PlayerControl.GameOptions.GhostsDoTasks) + { + target.ClearTasks(); + importantTextTask.Text = DestroyableSingleton<TranslationController>.Instance.GetString(StringNames.GhostIgnoreTasks, Array.Empty<object>()); + } + else + { + importantTextTask.Text = DestroyableSingleton<TranslationController>.Instance.GetString(StringNames.GhostDoTasks, Array.Empty<object>()); + } + target.myTasks.Insert(0, importantTextTask); + } + this.MyPhysics.StartCoroutine(this.KillAnimations.Random<KillAnimation>().CoPerformKill(this, target)); + } + } + + public override bool Serialize(MessageWriter writer, bool initialState) + { + if (initialState) + { + writer.Write(this.isNew); + } + writer.Write(this.PlayerId); + return true; + } + + public override void Deserialize(MessageReader reader, bool initialState) + { + if (initialState) + { + this.isNew = reader.ReadBoolean(); + } + this.PlayerId = reader.ReadByte(); + } + + public void SetPlayerMaterialColors(Renderer rend) + { + GameData.PlayerInfo playerById = GameData.Instance.GetPlayerById(this.PlayerId); + PlayerControl.SetPlayerMaterialColors((int)((playerById != null) ? playerById.ColorId : 0), rend); + } + + public static void SetPlayerMaterialColors(int colorId, Renderer rend) + { + if (!rend) + { + return; + } + rend.material.SetColor("_BackColor", Palette.ShadowColors[colorId]); + rend.material.SetColor("_BodyColor", Palette.PlayerColors[colorId]); + rend.material.SetColor("_VisorColor", Palette.VisorColor); + } + + public void RpcSetScanner(bool value) + { + byte b = this.scannerCount + 1; + this.scannerCount = b; + byte b2 = b; + if (AmongUsClient.Instance.AmClient) + { + this.SetScanner(value, b2); + } + MessageWriter messageWriter = AmongUsClient.Instance.StartRpc(this.NetId, 16, SendOption.Reliable); + messageWriter.Write(value); + messageWriter.Write(b2); + messageWriter.EndMessage(); + } + + public void RpcPlayAnimation(byte animType) + { + if (AmongUsClient.Instance.AmClient) + { + this.PlayAnimation(animType); + } + MessageWriter messageWriter = AmongUsClient.Instance.StartRpc(this.NetId, 0, SendOption.None); + messageWriter.Write(animType); + messageWriter.EndMessage(); + } + + public void RpcSetStartCounter(int secondsLeft) + { + int lastStartCounter = this.LastStartCounter; + this.LastStartCounter = lastStartCounter + 1; + int value = lastStartCounter; + MessageWriter messageWriter = AmongUsClient.Instance.StartRpc(this.NetId, 19, SendOption.Reliable); + messageWriter.WritePacked(value); + messageWriter.Write((sbyte)secondsLeft); + messageWriter.EndMessage(); + } + + public void RpcCompleteTask(uint idx) + { + if (AmongUsClient.Instance.AmClient) + { + this.CompleteTask(idx); + } + MessageWriter messageWriter = AmongUsClient.Instance.StartRpc(this.NetId, 1, SendOption.Reliable); + messageWriter.WritePacked(idx); + messageWriter.EndMessage(); + } + + public void RpcSyncSettings(GameOptionsData gameOptions) + { + if (!AmongUsClient.Instance.AmHost || DestroyableSingleton<TutorialManager>.InstanceExists) + { + return; + } + PlayerControl.GameOptions = gameOptions; + SaveManager.GameHostOptions = gameOptions; + MessageWriter messageWriter = AmongUsClient.Instance.StartRpc(this.NetId, 2, SendOption.Reliable); + messageWriter.WriteBytesAndSize(gameOptions.ToBytes()); + messageWriter.EndMessage(); + } + + public void RpcSetInfected(GameData.PlayerInfo[] infected) + { + byte[] array = (from p in infected + select p.PlayerId).ToArray<byte>(); + if (AmongUsClient.Instance.AmClient) + { + this.SetInfected(array); + } + MessageWriter messageWriter = AmongUsClient.Instance.StartRpc(this.NetId, 3, SendOption.Reliable); + messageWriter.WriteBytesAndSize(array); + messageWriter.EndMessage(); + } + + public void CmdCheckName(string name) + { + if (AmongUsClient.Instance.AmHost) + { + this.CheckName(name); + return; + } + MessageWriter messageWriter = AmongUsClient.Instance.StartRpcImmediately(this.NetId, 5, SendOption.Reliable, AmongUsClient.Instance.HostId); + messageWriter.Write(name); + AmongUsClient.Instance.FinishRpcImmediately(messageWriter); + } + + public void RpcSetSkin(uint skinId) + { + if (AmongUsClient.Instance.AmClient) + { + this.SetSkin(skinId); + } + MessageWriter messageWriter = AmongUsClient.Instance.StartRpc(this.NetId, 10, SendOption.Reliable); + messageWriter.WritePacked(skinId); + messageWriter.EndMessage(); + } + + public void RpcSetHat(uint hatId) + { + if (AmongUsClient.Instance.AmClient) + { + this.SetHat(hatId); + } + MessageWriter messageWriter = AmongUsClient.Instance.StartRpc(this.NetId, 9, SendOption.Reliable); + messageWriter.WritePacked(hatId); + messageWriter.EndMessage(); + } + + public void RpcSetPet(uint petId) + { + if (AmongUsClient.Instance.AmClient) + { + this.SetPet(petId); + } + MessageWriter messageWriter = AmongUsClient.Instance.StartRpc(this.NetId, 18, SendOption.Reliable); + messageWriter.WritePacked(petId); + messageWriter.EndMessage(); + } + + public void RpcSetName(string name) + { + if (AmongUsClient.Instance.AmClient) + { + this.SetName(name); + } + MessageWriter messageWriter = AmongUsClient.Instance.StartRpc(this.NetId, 6, SendOption.Reliable); + messageWriter.Write(name); + messageWriter.EndMessage(); + } + + public void CmdCheckColor(byte bodyColor) + { + if (AmongUsClient.Instance.AmHost) + { + this.CheckColor(bodyColor); + return; + } + MessageWriter messageWriter = AmongUsClient.Instance.StartRpcImmediately(this.NetId, 7, SendOption.Reliable, AmongUsClient.Instance.HostId); + messageWriter.Write(bodyColor); + AmongUsClient.Instance.FinishRpcImmediately(messageWriter); + } + + public void RpcSetColor(byte bodyColor) + { + if (AmongUsClient.Instance.AmClient) + { + this.SetColor(bodyColor); + } + MessageWriter messageWriter = AmongUsClient.Instance.StartRpc(this.NetId, 8, SendOption.Reliable); + messageWriter.Write(bodyColor); + messageWriter.EndMessage(); + } + + public void RpcSetTimesImpostor(float percImpostor) + { + if (AmongUsClient.Instance.AmClient) + { + this.crewStreak = percImpostor; + } + MessageWriter messageWriter = AmongUsClient.Instance.StartRpc(this.NetId, 14, SendOption.None); + messageWriter.Write(percImpostor); + messageWriter.EndMessage(); + } + + public bool RpcSendChat(string chatText) + { + if (string.IsNullOrWhiteSpace(chatText)) + { + return false; + } + if (AmongUsClient.Instance.AmClient && DestroyableSingleton<HudManager>.Instance) + { + DestroyableSingleton<HudManager>.Instance.Chat.AddChat(this, chatText); + } + if (chatText.IndexOf("who", StringComparison.OrdinalIgnoreCase) >= 0) + { + DestroyableSingleton<Telemetry>.Instance.SendWho(); + } + MessageWriter messageWriter = AmongUsClient.Instance.StartRpc(this.NetId, 13, SendOption.Reliable); + messageWriter.Write(chatText); + messageWriter.EndMessage(); + return true; + } + + public void RpcSendChatNote(byte srcPlayerId, ChatNoteTypes noteType) + { + if (AmongUsClient.Instance.AmClient) + { + GameData.PlayerInfo playerById = GameData.Instance.GetPlayerById(srcPlayerId); + DestroyableSingleton<HudManager>.Instance.Chat.AddChatNote(playerById, noteType); + } + MessageWriter messageWriter = AmongUsClient.Instance.StartRpc(this.NetId, 17, SendOption.Reliable); + messageWriter.Write(srcPlayerId); + messageWriter.Write((byte)noteType); + messageWriter.EndMessage(); + } + + public void CmdReportDeadBody(GameData.PlayerInfo target) + { + if (AmongUsClient.Instance.AmHost) + { + this.ReportDeadBody(target); + return; + } + MessageWriter messageWriter = AmongUsClient.Instance.StartRpc(this.NetId, 11, SendOption.Reliable); + messageWriter.Write((target != null) ? target.PlayerId : byte.MaxValue); + messageWriter.EndMessage(); + } + + public void RpcStartMeeting(GameData.PlayerInfo info) + { + if (AmongUsClient.Instance.AmClient) + { + base.StartCoroutine(this.CoStartMeeting(info)); + } + MessageWriter messageWriter = AmongUsClient.Instance.StartRpcImmediately(this.NetId, 15, SendOption.Reliable, -1); + messageWriter.Write((info != null) ? info.PlayerId : byte.MaxValue); + AmongUsClient.Instance.FinishRpcImmediately(messageWriter); + } + + public void RpcMurderPlayer(PlayerControl target) + { + if (AmongUsClient.Instance.AmClient) + { + this.MurderPlayer(target); + } + MessageWriter messageWriter = AmongUsClient.Instance.StartRpcImmediately(this.NetId, 12, SendOption.Reliable, -1); + messageWriter.WriteNetObject(target); + AmongUsClient.Instance.FinishRpcImmediately(messageWriter); + } + + public override void HandleRpc(byte callId, MessageReader reader) + { + switch (callId) + { + case 0: + this.PlayAnimation(reader.ReadByte()); + return; + case 1: + this.CompleteTask(reader.ReadPackedUInt32()); + return; + case 2: + PlayerControl.GameOptions = GameOptionsData.FromBytes(reader.ReadBytesAndSize()); + return; + case 3: + this.SetInfected(reader.ReadBytesAndSize()); + return; + case 4: + this.Exiled(); + return; + case 5: + this.CheckName(reader.ReadString()); + return; + case 6: + this.SetName(reader.ReadString()); + return; + case 7: + this.CheckColor(reader.ReadByte()); + return; + case 8: + this.SetColor(reader.ReadByte()); + return; + case 9: + this.SetHat(reader.ReadPackedUInt32()); + return; + case 10: + this.SetSkin(reader.ReadPackedUInt32()); + return; + case 11: + { + GameData.PlayerInfo playerById = GameData.Instance.GetPlayerById(reader.ReadByte()); + this.ReportDeadBody(playerById); + return; + } + case 12: + { + PlayerControl target = reader.ReadNetObject<PlayerControl>(); + this.MurderPlayer(target); + return; + } + case 13: + { + string chatText = reader.ReadString(); + if (DestroyableSingleton<HudManager>.Instance) + { + DestroyableSingleton<HudManager>.Instance.Chat.AddChat(this, chatText); + return; + } + break; + } + case 14: + this.crewStreak = reader.ReadSingle(); + return; + case 15: + { + GameData.PlayerInfo playerById2 = GameData.Instance.GetPlayerById(reader.ReadByte()); + base.StartCoroutine(this.CoStartMeeting(playerById2)); + return; + } + case 16: + this.SetScanner(reader.ReadBoolean(), reader.ReadByte()); + break; + case 17: + { + GameData.PlayerInfo playerById3 = GameData.Instance.GetPlayerById(reader.ReadByte()); + DestroyableSingleton<HudManager>.Instance.Chat.AddChatNote(playerById3, (ChatNoteTypes)reader.ReadByte()); + return; + } + case 18: + this.SetPet(reader.ReadPackedUInt32()); + return; + case 19: + { + int num = reader.ReadPackedInt32(); + sbyte startCounter = reader.ReadSByte(); + if (DestroyableSingleton<GameStartManager>.InstanceExists && this.LastStartCounter < num) + { + this.LastStartCounter = num; + DestroyableSingleton<GameStartManager>.Instance.SetStartCounter(startCounter); + return; + } + break; + } + default: + return; + } + } +} diff --git a/Client/Assembly-CSharp/PlayerParticle.cs b/Client/Assembly-CSharp/PlayerParticle.cs new file mode 100644 index 0000000..41fa495 --- /dev/null +++ b/Client/Assembly-CSharp/PlayerParticle.cs @@ -0,0 +1,39 @@ +using System; +using UnityEngine; + +public class PlayerParticle : PoolableBehavior +{ + public Camera FollowCamera { get; set; } + + public SpriteRenderer myRend; + + public float maxDistance = 6f; + + public Vector2 velocity; + + public float angularVelocity; + + private Vector3 lastCamera; + + public void Update() + { + Vector3 vector = base.transform.localPosition; + float sqrMagnitude = vector.sqrMagnitude; + if (this.FollowCamera) + { + Vector3 position = this.FollowCamera.transform.position; + position.z = 0f; + vector += (position - this.lastCamera) * (1f - base.transform.localScale.x); + this.lastCamera = position; + sqrMagnitude = (vector - position).sqrMagnitude; + } + if (sqrMagnitude > this.maxDistance * this.maxDistance) + { + this.OwnerPool.Reclaim(this); + return; + } + vector += this.velocity * Time.deltaTime; + base.transform.localPosition = vector; + base.transform.Rotate(0f, 0f, Time.deltaTime * this.angularVelocity); + } +} diff --git a/Client/Assembly-CSharp/PlayerParticleInfo.cs b/Client/Assembly-CSharp/PlayerParticleInfo.cs new file mode 100644 index 0000000..620b19f --- /dev/null +++ b/Client/Assembly-CSharp/PlayerParticleInfo.cs @@ -0,0 +1,12 @@ +using System; +using UnityEngine; + +[Serializable] +public class PlayerParticleInfo +{ + public Sprite image; + + public FloatRange angularVel; + + public bool alignToVel; +} diff --git a/Client/Assembly-CSharp/PlayerParticles.cs b/Client/Assembly-CSharp/PlayerParticles.cs new file mode 100644 index 0000000..4f7cf4a --- /dev/null +++ b/Client/Assembly-CSharp/PlayerParticles.cs @@ -0,0 +1,73 @@ +using System; +using UnityEngine; + +public class PlayerParticles : MonoBehaviour +{ + public PlayerParticleInfo[] Sprites; + + public FloatRange velocity; + + public FloatRange scale; + + public ObjectPoolBehavior pool; + + public float StartRadius; + + public Camera FollowCamera; + + private RandomFill<PlayerParticleInfo> fill; + + public void Start() + { + this.fill = new RandomFill<PlayerParticleInfo>(); + this.fill.Set(this.Sprites); + int num = 0; + while (this.pool.NotInUse > 0) + { + PlayerParticle playerParticle = this.pool.Get<PlayerParticle>(); + PlayerControl.SetPlayerMaterialColors(num++, playerParticle.myRend); + this.PlacePlayer(playerParticle, true); + } + } + + public void Update() + { + while (this.pool.NotInUse > 0) + { + PlayerParticle part = this.pool.Get<PlayerParticle>(); + this.PlacePlayer(part, false); + } + } + + private void PlacePlayer(PlayerParticle part, bool initial) + { + Vector3 vector = UnityEngine.Random.insideUnitCircle; + if (!initial) + { + vector.Normalize(); + } + vector *= this.StartRadius; + float num = this.scale.Next(); + part.transform.localScale = new Vector3(num, num, num); + vector.z = -num * 0.001f; + if (this.FollowCamera) + { + Vector3 position = this.FollowCamera.transform.position; + position.z = 0f; + vector += position; + part.FollowCamera = this.FollowCamera; + } + part.transform.localPosition = vector; + PlayerParticleInfo playerParticleInfo = this.fill.Get(); + part.myRend.sprite = playerParticleInfo.image; + part.myRend.flipX = BoolRange.Next(0.5f); + Vector2 vector2 = -vector.normalized; + vector2 = vector2.Rotate(FloatRange.Next(-45f, 45f)); + part.velocity = vector2 * this.velocity.Next(); + part.angularVelocity = playerParticleInfo.angularVel.Next(); + if (playerParticleInfo.alignToVel) + { + part.transform.localEulerAngles = new Vector3(0f, 0f, Vector2.up.AngleSigned(vector2)); + } + } +} diff --git a/Client/Assembly-CSharp/PlayerPhysics.cs b/Client/Assembly-CSharp/PlayerPhysics.cs new file mode 100644 index 0000000..c35e21d --- /dev/null +++ b/Client/Assembly-CSharp/PlayerPhysics.cs @@ -0,0 +1,330 @@ +using System; +using System.Collections; +using System.Linq; +using Assets.CoreScripts; +using Hazel; +using InnerNet; +using PowerTools; +using UnityEngine; + +public class PlayerPhysics : InnerNetObject +{ + public float TrueSpeed + { + get + { + return this.Speed * PlayerControl.GameOptions.PlayerSpeedMod; + } + } + + public float TrueGhostSpeed + { + get + { + return this.GhostSpeed * PlayerControl.GameOptions.PlayerSpeedMod; + } + } + + public float Speed = 4.5f; + + public float GhostSpeed = 3f; + + [HideInInspector] + private Rigidbody2D body; + + [HideInInspector] + private SpriteAnim Animator; + + [HideInInspector] + private SpriteRenderer rend; + + [HideInInspector] + private PlayerControl myPlayer; + + public AnimationClip RunAnim; + + public AnimationClip IdleAnim; + + public AnimationClip GhostIdleAnim; + + public AnimationClip EnterVentAnim; + + public AnimationClip ExitVentAnim; + + public AnimationClip SpawnAnim; + + public SkinLayer Skin; + + private enum RpcCalls + { + EnterVent, + ExitVent + } + + public void Awake() + { + this.body = base.GetComponent<Rigidbody2D>(); + this.Animator = base.GetComponent<SpriteAnim>(); + this.rend = base.GetComponent<SpriteRenderer>(); + this.myPlayer = base.GetComponent<PlayerControl>(); + } + + private void FixedUpdate() + { + this.HandleAnimation(); + if (base.AmOwner && this.myPlayer.CanMove && GameData.Instance) + { + DestroyableSingleton<Telemetry>.Instance.WritePosition(this.myPlayer.PlayerId, base.transform.position); + GameData.PlayerInfo data = this.myPlayer.Data; + if (data == null) + { + return; + } + bool isDead = data.IsDead; + this.body.velocity = DestroyableSingleton<HudManager>.Instance.joystick.Delta * (isDead ? this.TrueGhostSpeed : this.TrueSpeed); + } + } + + private void LateUpdate() + { + Vector3 position = base.transform.position; + position.z = position.y / 1000f; + base.transform.position = position; + } + + public Vector3 Vec2ToPosition(Vector2 pos) + { + return new Vector3(pos.x, pos.y, pos.y / 1000f); + } + + public void SetSkin(uint skinId) + { + this.Skin.SetSkin(skinId); + if (this.Animator.IsPlaying(this.SpawnAnim)) + { + this.Skin.SetSpawn(this.Animator.Time); + } + } + + public void ResetAnim(bool stopCoroutines = true) + { + if (stopCoroutines) + { + this.myPlayer.StopAllCoroutines(); + base.StopAllCoroutines(); + } + base.enabled = true; + this.myPlayer.inVent = false; + this.myPlayer.Visible = true; + GameData.PlayerInfo data = this.myPlayer.Data; + if (data == null || !data.IsDead) + { + this.Skin.SetIdle(); + this.Animator.Play(this.IdleAnim, 1f); + this.myPlayer.Visible = true; + this.myPlayer.SetHatAlpha(1f); + return; + } + this.Skin.SetGhost(); + this.Animator.Play(this.GhostIdleAnim, 1f); + this.myPlayer.SetHatAlpha(0.5f); + } + + private void HandleAnimation() + { + if (this.Animator.IsPlaying(this.SpawnAnim)) + { + return; + } + if (!GameData.Instance) + { + return; + } + Vector2 velocity = this.body.velocity; + AnimationClip currentAnimation = this.Animator.GetCurrentAnimation(); + GameData.PlayerInfo data = this.myPlayer.Data; + if (data == null) + { + return; + } + if (!data.IsDead) + { + if (velocity.sqrMagnitude >= 0.05f) + { + if (currentAnimation != this.RunAnim) + { + this.Animator.Play(this.RunAnim, 1f); + this.Skin.SetRun(); + } + if (velocity.x < -0.01f) + { + this.rend.flipX = true; + } + else if (velocity.x > 0.01f) + { + this.rend.flipX = false; + } + } + else if (currentAnimation == this.RunAnim || currentAnimation == this.SpawnAnim || !currentAnimation) + { + this.Skin.SetIdle(); + this.Animator.Play(this.IdleAnim, 1f); + this.myPlayer.SetHatAlpha(1f); + } + } + else + { + this.Skin.SetGhost(); + if (currentAnimation != this.GhostIdleAnim) + { + this.Animator.Play(this.GhostIdleAnim, 1f); + this.myPlayer.SetHatAlpha(0.5f); + } + if (velocity.x < -0.01f) + { + this.rend.flipX = true; + } + else if (velocity.x > 0.01f) + { + this.rend.flipX = false; + } + } + this.Skin.Flipped = this.rend.flipX; + } + + public IEnumerator CoSpawnPlayer(LobbyBehaviour lobby) + { + if (!lobby) + { + yield break; + } + Vector3 spawnPos = this.Vec2ToPosition(lobby.SpawnPositions[(int)this.myPlayer.PlayerId % lobby.SpawnPositions.Length]); + this.myPlayer.nameText.gameObject.SetActive(false); + this.myPlayer.Collider.enabled = false; + KillAnimation.SetMovement(this.myPlayer, false); + bool amFlipped = this.myPlayer.PlayerId > 4; + this.myPlayer.GetComponent<SpriteRenderer>().flipX = amFlipped; + this.myPlayer.transform.position = spawnPos; + SoundManager.Instance.PlaySound(lobby.SpawnSound, false, 1f).volume = 0.75f; + this.Skin.SetSpawn(0f); + this.Skin.Flipped = this.rend.flipX; + yield return new WaitForAnimationFinish(this.Animator, this.SpawnAnim); + base.transform.position = spawnPos + new Vector3(amFlipped ? -0.3f : 0.3f, -0.24f); + this.ResetAnim(false); + Vector2 b = (-spawnPos).normalized; + yield return this.WalkPlayerTo(spawnPos + b, 0.01f); + this.myPlayer.Collider.enabled = true; + KillAnimation.SetMovement(this.myPlayer, true); + this.myPlayer.nameText.gameObject.SetActive(true); + yield break; + } + + public void ExitAllVents() + { + this.ResetAnim(true); + this.myPlayer.moveable = true; + Vent[] allVents = ShipStatus.Instance.AllVents; + for (int i = 0; i < allVents.Length; i++) + { + allVents[i].SetButtons(false); + } + } + + private IEnumerator CoEnterVent(int id) + { + Vent vent = ShipStatus.Instance.AllVents.First((Vent v) => v.Id == id); + this.myPlayer.moveable = false; + yield return this.WalkPlayerTo(vent.transform.position, 0.01f); + vent.EnterVent(); + this.Skin.SetEnterVent(); + yield return new WaitForAnimationFinish(this.Animator, this.EnterVentAnim); + this.Skin.SetIdle(); + this.Animator.Play(this.IdleAnim, 1f); + this.myPlayer.Visible = false; + this.myPlayer.inVent = true; + yield break; + } + + private IEnumerator CoExitVent(int id) + { + Vent vent = ShipStatus.Instance.AllVents.First((Vent v) => v.Id == id); + this.myPlayer.Visible = true; + this.myPlayer.inVent = false; + vent.ExitVent(); + this.Skin.SetExitVent(); + yield return new WaitForAnimationFinish(this.Animator, this.ExitVentAnim); + this.Skin.SetIdle(); + this.Animator.Play(this.IdleAnim, 1f); + this.myPlayer.moveable = true; + yield break; + } + + // 移动位置 + public IEnumerator WalkPlayerTo(Vector2 worldPos, float tolerance = 0.01f) + { + worldPos -= base.GetComponent<CircleCollider2D>().offset; + Rigidbody2D body = this.body; + do + { + Vector2 vector2; + Vector2 vector = vector2 = worldPos - base.transform.position; + if (vector2.sqrMagnitude <= tolerance) + { + break; + } + float d = Mathf.Clamp(vector.magnitude * 2f, 0.01f, 1f); + body.velocity = vector.normalized * this.Speed * d; + yield return null; + } + while (body.velocity.magnitude >= 0.0001f); + body.velocity = Vector2.zero; + yield break; + } + + public override bool Serialize(MessageWriter writer, bool initialState) + { + return false; + } + + public override void Deserialize(MessageReader reader, bool initialState) + { + } + + public void RpcEnterVent(int id) + { + if (AmongUsClient.Instance.AmClient) + { + base.StartCoroutine(this.CoEnterVent(id)); + } + MessageWriter messageWriter = AmongUsClient.Instance.StartRpc(this.NetId, 0, SendOption.Reliable); + messageWriter.WritePacked(id); + messageWriter.EndMessage(); + } + + public void RpcExitVent(int id) + { + if (AmongUsClient.Instance.AmClient) + { + base.StartCoroutine(this.CoExitVent(id)); + } + MessageWriter messageWriter = AmongUsClient.Instance.StartRpc(this.NetId, 1, SendOption.Reliable); + messageWriter.WritePacked(id); + messageWriter.EndMessage(); + } + + public override void HandleRpc(byte callId, MessageReader reader) + { + if (callId == 0) + { + int id = reader.ReadPackedInt32(); + base.StartCoroutine(this.CoEnterVent(id)); + return; + } + if (callId != 1) + { + return; + } + int id2 = reader.ReadPackedInt32(); + base.StartCoroutine(this.CoExitVent(id2)); + } +} diff --git a/Client/Assembly-CSharp/PlayerTab.cs b/Client/Assembly-CSharp/PlayerTab.cs new file mode 100644 index 0000000..af57c2b --- /dev/null +++ b/Client/Assembly-CSharp/PlayerTab.cs @@ -0,0 +1,100 @@ +using System; +using System.Collections.Generic; +using UnityEngine; + +public class PlayerTab : MonoBehaviour +{ + public ColorChip ColorTabPrefab; + + public SpriteRenderer DemoImage; + + public SpriteRenderer HatImage; + + public SpriteRenderer SkinImage; + + public SpriteRenderer PetImage; + + public FloatRange XRange = new FloatRange(1.5f, 3f); + + public FloatRange YRange = new FloatRange(-1f, -3f); + + private HashSet<int> AvailableColors = new HashSet<int>(); + + private List<ColorChip> ColorChips = new List<ColorChip>(); + + private const int Columns = 3; + + public void OnEnable() + { + PlayerControl.SetPlayerMaterialColors((int)PlayerControl.LocalPlayer.Data.ColorId, this.DemoImage); + PlayerControl.SetHatImage(SaveManager.LastHat, this.HatImage); + PlayerControl.SetSkinImage(SaveManager.LastSkin, this.SkinImage); + PlayerControl.SetPetImage(SaveManager.LastPet, (int)PlayerControl.LocalPlayer.Data.ColorId, this.PetImage); + float num = (float)Palette.PlayerColors.Length / 3f; + for (int i = 0; i < Palette.PlayerColors.Length; i++) + { + float x = this.XRange.Lerp((float)(i % 3) / 2f); + float y = this.YRange.Lerp(1f - (float)(i / 3) / num); + ColorChip colorChip = UnityEngine.Object.Instantiate<ColorChip>(this.ColorTabPrefab); + colorChip.transform.SetParent(base.transform); + colorChip.transform.localPosition = new Vector3(x, y, -1f); + int j = i; + colorChip.Button.OnClick.AddListener(delegate() + { + this.SelectColor(j); + }); + colorChip.Inner.color = Palette.PlayerColors[i]; + this.ColorChips.Add(colorChip); + } + } + + public void OnDisable() + { + for (int i = 0; i < this.ColorChips.Count; i++) + { + UnityEngine.Object.Destroy(this.ColorChips[i].gameObject); + } + this.ColorChips.Clear(); + } + + public void Update() + { + this.UpdateAvailableColors(); + for (int i = 0; i < this.ColorChips.Count; i++) + { + this.ColorChips[i].InUseForeground.SetActive(!this.AvailableColors.Contains(i)); + } + } + + private void SelectColor(int colorId) + { + this.UpdateAvailableColors(); + if (this.AvailableColors.Remove(colorId)) + { + SaveManager.BodyColor = (byte)colorId; + if (PlayerControl.LocalPlayer) + { + PlayerControl.LocalPlayer.CmdCheckColor((byte)colorId); + } + } + } + + public void UpdateAvailableColors() + { + PlayerControl.SetPlayerMaterialColors((int)PlayerControl.LocalPlayer.Data.ColorId, this.DemoImage); + PlayerControl.SetPetImage(SaveManager.LastPet, (int)PlayerControl.LocalPlayer.Data.ColorId, this.PetImage); + for (int i = 0; i < Palette.PlayerColors.Length; i++) + { + this.AvailableColors.Add(i); + } + if (GameData.Instance) + { + List<GameData.PlayerInfo> allPlayers = GameData.Instance.AllPlayers; + for (int j = 0; j < allPlayers.Count; j++) + { + GameData.PlayerInfo playerInfo = allPlayers[j]; + this.AvailableColors.Remove((int)playerInfo.ColorId); + } + } + } +} diff --git a/Client/Assembly-CSharp/PlayerTask.cs b/Client/Assembly-CSharp/PlayerTask.cs new file mode 100644 index 0000000..ddccafe --- /dev/null +++ b/Client/Assembly-CSharp/PlayerTask.cs @@ -0,0 +1,137 @@ +using System; +using System.Collections.Generic; +using System.Text; +using UnityEngine; + +public abstract class PlayerTask : MonoBehaviour +{ + public int Index { get; internal set; } + + public uint Id { get; internal set; } + + public PlayerControl Owner { get; internal set; } + + public abstract int TaskStep { get; } + + public abstract bool IsComplete { get; } + + public Vector2 Location + { + get + { + this.LocationDirty = false; + return this.FindObjectPos().transform.position; + } + } + + public SystemTypes StartAt; + + public TaskTypes TaskType; + + public Minigame MinigamePrefab; + + public bool HasLocation; + + public bool LocationDirty = true; + + public abstract void Initialize(); + + public virtual void OnRemove() + { + } + + public abstract bool ValidConsole(global::Console console); + + public abstract void Complete(); + + public abstract void AppendTaskText(StringBuilder sb); + + internal static bool TaskIsEmergency(PlayerTask arg) + { + return arg is NoOxyTask || arg is HudOverrideTask || arg is ReactorTask || arg is ElectricTask; + } + + protected List<global::Console> FindConsoles() + { + List<global::Console> list = new List<global::Console>(); + global::Console[] allConsoles = ShipStatus.Instance.AllConsoles; + for (int i = 0; i < allConsoles.Length; i++) + { + if (this.ValidConsole(allConsoles[i])) + { + list.Add(allConsoles[i]); + } + } + return list; + } + + public static bool PlayerHasHudTask(PlayerControl localPlayer) + { + if (!localPlayer) + { + return true; + } + for (int i = 0; i < localPlayer.myTasks.Count; i++) + { + if (localPlayer.myTasks[i] is HudOverrideTask) + { + return true; + } + } + return false; + } + + protected List<Vector2> FindObjectsPos() + { + List<Vector2> list = new List<Vector2>(); + global::Console[] allConsoles = ShipStatus.Instance.AllConsoles; + for (int i = 0; i < allConsoles.Length; i++) + { + if (this.ValidConsole(allConsoles[i])) + { + list.Add(allConsoles[i].transform.position); + } + } + return list; + } + + protected global::Console FindSpecialConsole(Func<global::Console, bool> func) + { + global::Console[] allConsoles = ShipStatus.Instance.AllConsoles; + for (int i = 0; i < allConsoles.Length; i++) + { + if (func(allConsoles[i])) + { + return allConsoles[i]; + } + } + return null; + } + + protected global::Console FindObjectPos() + { + global::Console[] allConsoles = ShipStatus.Instance.AllConsoles; + for (int i = 0; i < allConsoles.Length; i++) + { + if (this.ValidConsole(allConsoles[i])) + { + return allConsoles[i]; + } + } + Debug.LogError("Couldn't find location for task: " + base.name); + return null; + } + + protected static bool AllTasksCompleted(PlayerControl player) + { + for (int i = 0; i < player.myTasks.Count; i++) + { + PlayerTask playerTask = player.myTasks[i]; + if (playerTask is NormalPlayerTask && !playerTask.IsComplete) + { + return false; + } + } + return true; + } +} diff --git a/Client/Assembly-CSharp/PlayerVoteArea.cs b/Client/Assembly-CSharp/PlayerVoteArea.cs new file mode 100644 index 0000000..d23a2a0 --- /dev/null +++ b/Client/Assembly-CSharp/PlayerVoteArea.cs @@ -0,0 +1,211 @@ +using System; +using System.Collections; +using Hazel; +using UnityEngine; + +public class PlayerVoteArea : MonoBehaviour +{ + public MeetingHud Parent { get; set; } + + public sbyte TargetPlayerId; + + public const byte DeadBit = 128; + + public const byte VotedBit = 64; + + public const byte ReportedBit = 32; + + public const byte VoteMask = 15; + + public GameObject Buttons; + + public SpriteRenderer PlayerIcon; + + public SpriteRenderer Flag; + + public SpriteRenderer Megaphone; + + public SpriteRenderer Overlay; + + public TextRenderer NameText; + + public bool isDead; + + public bool didVote; + + public bool didReport; + + public sbyte votedFor; + + public bool voteComplete; + + public bool resultsShowing; + + public void SetDead(bool isMe, bool didReport, bool isDead) + { + this.isDead = isDead; + this.didReport = didReport; + this.Megaphone.enabled = didReport; + this.Overlay.gameObject.SetActive(false); + this.Overlay.transform.GetChild(0).gameObject.SetActive(isDead); + } + + public void SetDisabled() + { + if (this.isDead) + { + return; + } + if (this.Overlay) + { + this.Overlay.gameObject.SetActive(true); + this.Overlay.transform.GetChild(0).gameObject.SetActive(false); + return; + } + base.GetComponent<SpriteRenderer>().enabled = false; + } + + public void SetEnabled() + { + if (this.isDead) + { + return; + } + if (this.Overlay) + { + this.Overlay.gameObject.SetActive(false); + return; + } + base.GetComponent<SpriteRenderer>().enabled = true; + } + + public IEnumerator CoAnimateOverlay() + { + this.Overlay.gameObject.SetActive(this.isDead); + if (this.isDead) + { + Transform xMark = this.Overlay.transform.GetChild(0); + this.Overlay.color = Palette.ClearWhite; + xMark.localScale = Vector3.zero; + float fadeDuration = 0.5f; + for (float t = 0f; t < fadeDuration; t += Time.deltaTime) + { + this.Overlay.color = Color.Lerp(Palette.ClearWhite, Color.white, t / fadeDuration); + yield return null; + } + this.Overlay.color = Color.white; + float scaleDuration = 0.15f; + for (float t = 0f; t < scaleDuration; t += Time.deltaTime) + { + float num = Mathf.Lerp(3f, 1f, t / scaleDuration); + xMark.transform.localScale = new Vector3(num, num, num); + yield return null; + } + xMark.transform.localScale = Vector3.one; + xMark = null; + } + else if (this.didReport) + { + float scaleDuration = 1f; + for (float fadeDuration = 0f; fadeDuration < scaleDuration; fadeDuration += Time.deltaTime) + { + float num2 = fadeDuration / scaleDuration; + float num3 = PlayerVoteArea.TriangleWave(num2 * 3f) * 2f - 1f; + this.Megaphone.transform.localEulerAngles = new Vector3(0f, 0f, num3 * 30f); + num3 = Mathf.Lerp(0.7f, 1.2f, PlayerVoteArea.TriangleWave(num2 * 2f)); + this.Megaphone.transform.localScale = new Vector3(num3, num3, num3); + yield return null; + } + this.Megaphone.transform.localEulerAngles = Vector3.zero; + this.Megaphone.transform.localScale = Vector3.one; + } + yield break; + } + + private static float TriangleWave(float t) + { + t -= (float)((int)t); + if (t < 0.5f) + { + return t * 2f; + } + return 1f - (t - 0.5f) * 2f; + } + + internal void SetVote(sbyte suspectIdx) + { + this.didVote = true; + this.votedFor = suspectIdx; + this.Flag.enabled = true; + } + + public void UnsetVote() + { + this.Flag.enabled = false; + this.votedFor = 0; + this.didVote = false; + } + + public void ClearButtons() + { + this.Buttons.SetActive(false); + } + + public void ClearForResults() + { + this.resultsShowing = true; + this.Flag.enabled = false; + } + + public void VoteForMe() + { + if (!this.voteComplete) + { + this.Parent.Confirm(this.TargetPlayerId); + } + } + + public void Select() + { + if (PlayerControl.LocalPlayer.Data.IsDead) + { + return; + } + if (this.isDead) + { + return; + } + if (!this.voteComplete && this.Parent.Select((int)this.TargetPlayerId)) + { + this.Buttons.SetActive(true); + } + } + + public void Cancel() + { + this.Buttons.SetActive(false); + } + + public void Serialize(MessageWriter writer) + { + byte state = this.GetState(); + writer.Write(state); + } + + public void Deserialize(MessageReader reader) + { + byte b = reader.ReadByte(); + this.votedFor = (sbyte)((b & 15) - 1); + this.isDead = ((b & 128) > 0); + this.didVote = ((b & 64) > 0); + this.didReport = ((b & 32) > 0); + this.Flag.enabled = (this.didVote && !this.resultsShowing); + this.Overlay.gameObject.SetActive(this.isDead); + this.Megaphone.enabled = this.didReport; + } + + public byte GetState() + { + return (byte)((int)(this.votedFor + 1 & 15) | (this.isDead ? 128 : 0) | (this.didVote ? 64 : 0) | (this.didReport ? 32 : 0)); + } +} diff --git a/Client/Assembly-CSharp/PoolableBehavior.cs b/Client/Assembly-CSharp/PoolableBehavior.cs new file mode 100644 index 0000000..9f3cc11 --- /dev/null +++ b/Client/Assembly-CSharp/PoolableBehavior.cs @@ -0,0 +1,17 @@ +using System; +using UnityEngine; + +public class PoolableBehavior : MonoBehaviour +{ + [HideInInspector] + public IObjectPool OwnerPool; + + public virtual void Reset() + { + } + + public void Awake() + { + this.OwnerPool = DefaultPool.Instance; + } +} diff --git a/Client/Assembly-CSharp/PoolablePlayer.cs b/Client/Assembly-CSharp/PoolablePlayer.cs new file mode 100644 index 0000000..5b948fb --- /dev/null +++ b/Client/Assembly-CSharp/PoolablePlayer.cs @@ -0,0 +1,45 @@ +using System; +using UnityEngine; + +public class PoolablePlayer : MonoBehaviour +{ + public SpriteRenderer Body; + + public SpriteRenderer[] Hands; + + public SpriteRenderer HatSlot; + + public SpriteRenderer SkinSlot; + + public SpriteRenderer PetSlot; + + public TextRenderer NameText; + + public void SetFlipX(bool flipped) + { + this.Body.flipX = flipped; + this.SkinSlot.flipX = !flipped; + this.PetSlot.flipX = flipped; + this.HatSlot.flipX = !flipped; + if (flipped) + { + Vector3 localPosition = this.HatSlot.transform.localPosition; + localPosition.x = -localPosition.x; + this.HatSlot.transform.localPosition = localPosition; + } + } + + public void SetDeadFlipX(bool flipped) + { + this.Body.flipX = flipped; + this.PetSlot.flipX = flipped; + this.HatSlot.flipX = flipped; + if (flipped) + { + Vector3 localPosition = this.HatSlot.transform.localPosition; + localPosition.x = -localPosition.x; + localPosition.y = 0.725f; + this.HatSlot.transform.localPosition = localPosition; + } + } +} diff --git a/Client/Assembly-CSharp/PooledMapIcon.cs b/Client/Assembly-CSharp/PooledMapIcon.cs new file mode 100644 index 0000000..8e75ff3 --- /dev/null +++ b/Client/Assembly-CSharp/PooledMapIcon.cs @@ -0,0 +1,35 @@ +using System; +using UnityEngine; + +public class PooledMapIcon : PoolableBehavior +{ + public float NormalSize = 0.3f; + + public int lastMapTaskStep = -1; + + public SpriteRenderer rend; + + public AlphaPulse alphaPulse; + + public void Update() + { + if (this.alphaPulse.enabled) + { + float num = Mathf.Abs(Mathf.Cos((this.alphaPulse.Offset + Time.time) * 3.1415927f / this.alphaPulse.Duration)); + if ((double)num > 0.9) + { + num -= 0.9f; + num = this.NormalSize + num; + base.transform.localScale = new Vector3(num, num, num); + } + } + } + + public override void Reset() + { + this.lastMapTaskStep = -1; + this.alphaPulse.enabled = false; + this.rend.material.SetFloat("_Outline", 0f); + base.Reset(); + } +} diff --git a/Client/Assembly-CSharp/PowerTools/SpriteAnim.cs b/Client/Assembly-CSharp/PowerTools/SpriteAnim.cs new file mode 100644 index 0000000..863854e --- /dev/null +++ b/Client/Assembly-CSharp/PowerTools/SpriteAnim.cs @@ -0,0 +1,255 @@ +using System; +using System.Collections.Generic; +using UnityEngine; +using UnityEngine.UI; + +namespace PowerTools +{ + [RequireComponent(typeof(Animator))] + [DisallowMultipleComponent] + public class SpriteAnim : SpriteAnimEventHandler + { + public bool Playing + { + get + { + return this.IsPlaying(null); + } + } + + public bool Paused + { + get + { + return this.IsPaused(); + } + set + { + if (value) + { + this.Pause(); + return; + } + this.Resume(); + } + } + + public float Speed + { + get + { + return this.m_speed; + } + set + { + this.SetSpeed(value); + } + } + + public float Time + { + get + { + return this.GetTime(); + } + set + { + this.SetTime(value); + } + } + + public float NormalizedTime + { + get + { + return this.GetNormalisedTime(); + } + set + { + this.SetNormalizedTime(value); + } + } + + public AnimationClip Clip + { + get + { + return this.m_currAnim; + } + } + + public string ClipName + { + get + { + if (!(this.m_currAnim != null)) + { + return string.Empty; + } + return this.m_currAnim.name; + } + } + + private static readonly string STATE_NAME = "a"; + + private static readonly string CONTROLLER_PATH = "SpriteAnimController"; + + [SerializeField] + private AnimationClip m_defaultAnim; + + private static RuntimeAnimatorController m_sharedAnimatorController = null; + + private Animator m_animator; + + private AnimatorOverrideController m_controller; + + private SpriteAnimNodes m_nodes; + + private List<KeyValuePair<AnimationClip, AnimationClip>> m_clipPairList = new List<KeyValuePair<AnimationClip, AnimationClip>>(1); + + private AnimationClip m_currAnim; + + private float m_speed = 1f; + + public void Play(AnimationClip anim = null, float speed = 1f) + { + if (anim == null) + { + anim = (this.m_currAnim ? this.m_currAnim : this.m_defaultAnim); + if (anim == null) + { + return; + } + } + if (!this.m_animator.enabled) + { + this.m_animator.enabled = true; + } + if (this.m_nodes != null) + { + this.m_nodes.Reset(); + } + this.m_clipPairList[0] = new KeyValuePair<AnimationClip, AnimationClip>(this.m_clipPairList[0].Key, anim); + this.m_controller.ApplyOverrides(this.m_clipPairList); + this.m_animator.Update(0f); + this.m_animator.Play(SpriteAnim.STATE_NAME, 0, 0f); + this.m_speed = Mathf.Max(0f, speed); + this.m_animator.speed = this.m_speed; + this.m_currAnim = anim; + this.m_animator.Update(0f); + } + + public void Stop() + { + this.m_animator.enabled = false; + } + + public void Pause() + { + this.m_animator.speed = 0f; + } + + public void Resume() + { + this.m_animator.speed = this.m_speed; + } + + public AnimationClip GetCurrentAnimation() + { + return this.m_currAnim; + } + + public bool IsPlaying(AnimationClip clip = null) + { + return (clip == null || this.m_currAnim == clip) && this.m_animator.GetCurrentAnimatorStateInfo(0).normalizedTime < 1f; + } + + public bool IsPlaying(string animName) + { + return !(this.m_currAnim == null) && this.m_currAnim.name == animName && this.m_animator.GetCurrentAnimatorStateInfo(0).normalizedTime < 1f; + } + + public bool IsPaused() + { + return !(this.m_currAnim == null) && this.m_animator.speed == 0f; + } + + public void SetSpeed(float speed) + { + this.m_speed = Mathf.Max(0f, speed); + this.m_animator.speed = this.m_speed; + } + + public float GetSpeed() + { + return this.m_speed; + } + + public float GetTime() + { + if (this.m_currAnim != null) + { + return this.m_animator.GetCurrentAnimatorStateInfo(0).normalizedTime * this.m_currAnim.length; + } + return 0f; + } + + public void SetTime(float time) + { + if (this.m_currAnim == null || this.m_currAnim.length <= 0f) + { + return; + } + this.SetNormalizedTime(time / this.m_currAnim.length); + } + + public float GetNormalisedTime() + { + if (this.m_currAnim != null) + { + return this.m_animator.GetCurrentAnimatorStateInfo(0).normalizedTime; + } + return 0f; + } + + public void SetNormalizedTime(float ratio) + { + if (this.m_currAnim == null) + { + return; + } + this.m_animator.Play(SpriteAnim.STATE_NAME, 0, this.m_currAnim.isLooping ? Mathf.Repeat(ratio, 1f) : Mathf.Clamp01(ratio)); + } + + private void Awake() + { + this.m_controller = new AnimatorOverrideController(); + if (SpriteAnim.m_sharedAnimatorController == null) + { + SpriteAnim.m_sharedAnimatorController = Resources.Load<RuntimeAnimatorController>(SpriteAnim.CONTROLLER_PATH); + } + this.m_controller.runtimeAnimatorController = SpriteAnim.m_sharedAnimatorController; + this.m_animator = base.GetComponent<Animator>(); + this.m_animator.runtimeAnimatorController = this.m_controller; + this.m_controller.GetOverrides(this.m_clipPairList); + this.Play(this.m_defaultAnim, 1f); + this.m_nodes = base.GetComponent<SpriteAnimNodes>(); + } + + private void Reset() + { + if (base.GetComponent<RectTransform>() == null) + { + if (base.GetComponent<Sprite>() == null) + { + base.gameObject.AddComponent<SpriteRenderer>(); + return; + } + } + else if (base.GetComponent<Image>() == null) + { + base.gameObject.AddComponent<Image>(); + } + } + } +} diff --git a/Client/Assembly-CSharp/PowerTools/SpriteAnimEventHandler.cs b/Client/Assembly-CSharp/PowerTools/SpriteAnimEventHandler.cs new file mode 100644 index 0000000..b97b8c2 --- /dev/null +++ b/Client/Assembly-CSharp/PowerTools/SpriteAnimEventHandler.cs @@ -0,0 +1,111 @@ +using System; +using UnityEngine; + +namespace PowerTools +{ + [DisallowMultipleComponent] + public class SpriteAnimEventHandler : MonoBehaviour + { + private string m_eventWithObjectMessage; + + private object m_eventWithObjectData; + + public static class EventParser + { + public static readonly char MESSAGE_DELIMITER = '\t'; + + public static readonly string MESSAGE_NOPARAM = "_Anim"; + + public static readonly string MESSAGE_INT = "_AnimInt"; + + public static readonly string MESSAGE_FLOAT = "_AnimFloat"; + + public static readonly string MESSAGE_STRING = "_AnimString"; + + public static readonly string MESSAGE_OBJECT_FUNCNAME = "_AnimObjectFunc"; + + public static readonly string MESSAGE_OBJECT_DATA = "_AnimObjectData"; + + public static int ParseInt(ref string messageString) + { + int num = messageString.IndexOf(SpriteAnimEventHandler.EventParser.MESSAGE_DELIMITER); + int result = 0; + int.TryParse(messageString.Substring(num + 1), out result); + messageString = messageString.Substring(0, num); + return result; + } + + public static float ParseFloat(ref string messageString) + { + int num = messageString.IndexOf(SpriteAnimEventHandler.EventParser.MESSAGE_DELIMITER); + float result = 0f; + float.TryParse(messageString.Substring(num + 1), out result); + messageString = messageString.Substring(0, num); + return result; + } + + public static string ParseString(ref string messageString) + { + int num = messageString.IndexOf(SpriteAnimEventHandler.EventParser.MESSAGE_DELIMITER); + string result = messageString.Substring(num + 1); + messageString = messageString.Substring(0, num); + return result; + } + } + + private void _Anim(string function) + { + base.SendMessageUpwards(function, SendMessageOptions.DontRequireReceiver); + } + + private void _AnimInt(string messageString) + { + int num = SpriteAnimEventHandler.EventParser.ParseInt(ref messageString); + base.SendMessageUpwards(messageString, num, SendMessageOptions.DontRequireReceiver); + } + + private void _AnimFloat(string messageString) + { + float num = SpriteAnimEventHandler.EventParser.ParseFloat(ref messageString); + base.SendMessageUpwards(messageString, num, SendMessageOptions.DontRequireReceiver); + } + + private void _AnimString(string messageString) + { + string value = SpriteAnimEventHandler.EventParser.ParseString(ref messageString); + base.SendMessageUpwards(messageString, value, SendMessageOptions.DontRequireReceiver); + } + + private void _AnimObjectFunc(string funcName) + { + if (this.m_eventWithObjectData != null) + { + base.SendMessageUpwards(funcName, this.m_eventWithObjectData, SendMessageOptions.DontRequireReceiver); + this.m_eventWithObjectMessage = null; + this.m_eventWithObjectData = null; + return; + } + if (!string.IsNullOrEmpty(this.m_eventWithObjectMessage)) + { + Debug.LogError("Animation event with object parameter had no object"); + } + this.m_eventWithObjectMessage = funcName; + } + + private void _AnimObjectData(UnityEngine.Object data) + { + if (!string.IsNullOrEmpty(this.m_eventWithObjectMessage)) + { + base.SendMessageUpwards(this.m_eventWithObjectMessage, data, SendMessageOptions.DontRequireReceiver); + this.m_eventWithObjectMessage = null; + this.m_eventWithObjectData = null; + return; + } + if (this.m_eventWithObjectData != null) + { + Debug.LogError("Animation event with object parameter had no object"); + } + this.m_eventWithObjectData = data; + } + } +} diff --git a/Client/Assembly-CSharp/PowerTools/SpriteAnimNodeSync.cs b/Client/Assembly-CSharp/PowerTools/SpriteAnimNodeSync.cs new file mode 100644 index 0000000..e5fad22 --- /dev/null +++ b/Client/Assembly-CSharp/PowerTools/SpriteAnimNodeSync.cs @@ -0,0 +1,36 @@ +using System; +using UnityEngine; + +namespace PowerTools +{ + public class SpriteAnimNodeSync : MonoBehaviour + { + public int NodeId; + + public SpriteAnimNodes Parent; + + public SpriteRenderer ParentRenderer; + + public SpriteRenderer Renderer; + + public void LateUpdate() + { + if (this.Renderer && this.ParentRenderer) + { + this.Renderer.flipX = this.ParentRenderer.flipX; + } + Vector3 localPosition = base.transform.localPosition; + Vector3 localPosition2 = this.Parent.GetLocalPosition(this.NodeId, false); + localPosition.x = localPosition2.x; + localPosition.y = localPosition2.y; + base.transform.localPosition = localPosition; + float angle = this.Parent.GetAngle(this.NodeId); + if (!this.Renderer || !this.Renderer.flipX) + { + base.transform.eulerAngles = new Vector3(0f, 0f, angle); + return; + } + base.transform.eulerAngles = new Vector3(0f, 0f, -angle); + } + } +} diff --git a/Client/Assembly-CSharp/PowerTools/SpriteAnimNodes.cs b/Client/Assembly-CSharp/PowerTools/SpriteAnimNodes.cs new file mode 100644 index 0000000..2669ac1 --- /dev/null +++ b/Client/Assembly-CSharp/PowerTools/SpriteAnimNodes.cs @@ -0,0 +1,232 @@ +using System; +using UnityEngine; + +namespace PowerTools +{ + public class SpriteAnimNodes : MonoBehaviour + { + public static readonly int NUM_NODES = 10; + + [SerializeField] + [HideInInspector] + private Vector2 m_node0 = Vector2.zero; + + [SerializeField] + [HideInInspector] + private Vector2 m_node1 = Vector2.zero; + + [SerializeField] + [HideInInspector] + private Vector2 m_node2 = Vector2.zero; + + [SerializeField] + [HideInInspector] + private Vector2 m_node3 = Vector2.zero; + + [SerializeField] + [HideInInspector] + private Vector2 m_node4 = Vector2.zero; + + [SerializeField] + [HideInInspector] + private Vector2 m_node5 = Vector2.zero; + + [SerializeField] + [HideInInspector] + private Vector2 m_node6 = Vector2.zero; + + [SerializeField] + [HideInInspector] + private Vector2 m_node7 = Vector2.zero; + + [SerializeField] + [HideInInspector] + private Vector2 m_node8 = Vector2.zero; + + [SerializeField] + [HideInInspector] + private Vector2 m_node9 = Vector2.zero; + + [SerializeField] + [HideInInspector] + private float m_ang0; + + [SerializeField] + [HideInInspector] + private float m_ang1; + + [SerializeField] + [HideInInspector] + private float m_ang2; + + [SerializeField] + [HideInInspector] + private float m_ang3; + + [SerializeField] + [HideInInspector] + private float m_ang4; + + [SerializeField] + [HideInInspector] + private float m_ang5; + + [SerializeField] + [HideInInspector] + private float m_ang6; + + [SerializeField] + [HideInInspector] + private float m_ang7; + + [SerializeField] + [HideInInspector] + private float m_ang8; + + [SerializeField] + [HideInInspector] + private float m_ang9; + + private SpriteRenderer m_spriteRenderer; + + public Vector3 GetPosition(int nodeId, bool ignoredPivot = false) + { + if (this.m_spriteRenderer == null) + { + this.m_spriteRenderer = base.GetComponent<SpriteRenderer>(); + } + if (this.m_spriteRenderer == null || this.m_spriteRenderer.sprite == null) + { + return Vector2.zero; + } + Vector3 vector = this.GetLocalPosition(nodeId, ignoredPivot); + vector = base.transform.rotation * vector; + vector.Scale(base.transform.lossyScale); + return vector + base.transform.position; + } + + public Vector3 GetLocalPosition(int nodeId, bool ignoredPivot = false) + { + if (this.m_spriteRenderer == null) + { + this.m_spriteRenderer = base.GetComponent<SpriteRenderer>(); + } + if (this.m_spriteRenderer == null || this.m_spriteRenderer.sprite == null) + { + return Vector2.zero; + } + Vector3 vector = this.GetPositionRaw(nodeId); + vector.y = -vector.y; + if (ignoredPivot) + { + vector += this.m_spriteRenderer.sprite.rect.size * 0.5f - this.m_spriteRenderer.sprite.pivot; + } + vector *= 1f / this.m_spriteRenderer.sprite.pixelsPerUnit; + if (this.m_spriteRenderer.flipX) + { + vector.x = -vector.x; + } + if (this.m_spriteRenderer.flipY) + { + vector.y = -vector.y; + } + return vector; + } + + public float GetAngle(int nodeId) + { + float angleRaw = this.GetAngleRaw(nodeId); + if (this.m_spriteRenderer == null) + { + this.m_spriteRenderer = base.GetComponent<SpriteRenderer>(); + } + if (this.m_spriteRenderer == null || this.m_spriteRenderer.sprite == null) + { + return 0f; + } + return angleRaw + base.transform.eulerAngles.z; + } + + public Vector2 GetPositionRaw(int nodeId) + { + switch (nodeId) + { + case 0: + return this.m_node0; + case 1: + return this.m_node1; + case 2: + return this.m_node2; + case 3: + return this.m_node3; + case 4: + return this.m_node4; + case 5: + return this.m_node5; + case 6: + return this.m_node6; + case 7: + return this.m_node7; + case 8: + return this.m_node8; + case 9: + return this.m_node9; + default: + return Vector2.zero; + } + } + + public float GetAngleRaw(int nodeId) + { + switch (nodeId) + { + case 0: + return this.m_ang0; + case 1: + return this.m_ang1; + case 2: + return this.m_ang2; + case 3: + return this.m_ang3; + case 4: + return this.m_ang4; + case 5: + return this.m_ang5; + case 6: + return this.m_ang6; + case 7: + return this.m_ang7; + case 8: + return this.m_ang8; + case 9: + return this.m_ang9; + default: + return 0f; + } + } + + public void Reset() + { + this.m_node0 = Vector2.zero; + this.m_node1 = Vector2.zero; + this.m_node2 = Vector2.zero; + this.m_node3 = Vector2.zero; + this.m_node4 = Vector2.zero; + this.m_node5 = Vector2.zero; + this.m_node6 = Vector2.zero; + this.m_node7 = Vector2.zero; + this.m_node8 = Vector2.zero; + this.m_node9 = Vector2.zero; + this.m_ang0 = 0f; + this.m_ang1 = 0f; + this.m_ang2 = 0f; + this.m_ang3 = 0f; + this.m_ang4 = 0f; + this.m_ang5 = 0f; + this.m_ang6 = 0f; + this.m_ang7 = 0f; + this.m_ang8 = 0f; + this.m_ang9 = 0f; + } + } +} diff --git a/Client/Assembly-CSharp/PowerTools/WaitForAnimationFinish.cs b/Client/Assembly-CSharp/PowerTools/WaitForAnimationFinish.cs new file mode 100644 index 0000000..f4f083c --- /dev/null +++ b/Client/Assembly-CSharp/PowerTools/WaitForAnimationFinish.cs @@ -0,0 +1,55 @@ +using System; +using System.Collections; +using UnityEngine; + +namespace PowerTools +{ + public class WaitForAnimationFinish : IEnumerator + { + public object Current + { + get + { + return null; + } + } + + private SpriteAnim animator; + + private AnimationClip clip; + + private bool first = true; + + public WaitForAnimationFinish(SpriteAnim animator, AnimationClip clip) + { + this.animator = animator; + this.clip = clip; + this.animator.Play(this.clip, 1f); + } + + public bool MoveNext() + { + if (this.first) + { + this.first = false; + return true; + } + bool result; + try + { + result = this.animator.IsPlaying(this.clip); + } + catch + { + result = false; + } + return result; + } + + public void Reset() + { + this.first = true; + this.animator.Play(this.clip, 1f); + } + } +} diff --git a/Client/Assembly-CSharp/ProgressTracker.cs b/Client/Assembly-CSharp/ProgressTracker.cs new file mode 100644 index 0000000..60cae92 --- /dev/null +++ b/Client/Assembly-CSharp/ProgressTracker.cs @@ -0,0 +1,39 @@ +using System; +using System.Linq; +using UnityEngine; + +public class ProgressTracker : MonoBehaviour +{ + public MeshRenderer TileParent; + + private float curValue; + + public void Start() + { + this.TileParent.material.SetFloat("_Buckets", 1f); + this.TileParent.material.SetFloat("_FullBuckets", 0f); + } + + public void FixedUpdate() + { + if (PlayerTask.PlayerHasHudTask(PlayerControl.LocalPlayer)) + { + this.TileParent.enabled = false; + return; + } + if (!this.TileParent.enabled) + { + this.TileParent.enabled = true; + } + GameData instance = GameData.Instance; + if (instance && instance.TotalTasks > 0) + { + int num = DestroyableSingleton<TutorialManager>.InstanceExists ? 1 : (instance.AllPlayers.Count - PlayerControl.GameOptions.NumImpostors); + num -= instance.AllPlayers.Count((GameData.PlayerInfo p) => p.Disconnected); + float b = (float)instance.CompletedTasks / (float)instance.TotalTasks * (float)num; + this.curValue = Mathf.Lerp(this.curValue, b, Time.fixedDeltaTime * 2f); + this.TileParent.material.SetFloat("_Buckets", (float)num); + this.TileParent.material.SetFloat("_FullBuckets", this.curValue); + } + } +} diff --git a/Client/Assembly-CSharp/Properties/AssemblyInfo.cs b/Client/Assembly-CSharp/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..4480267 --- /dev/null +++ b/Client/Assembly-CSharp/Properties/AssemblyInfo.cs @@ -0,0 +1,6 @@ +using System; +using System.Diagnostics; +using System.Reflection; +using System.Runtime.CompilerServices; + +[assembly: AssemblyVersion("0.0.0.0")] diff --git a/Client/Assembly-CSharp/PurchaseButton.cs b/Client/Assembly-CSharp/PurchaseButton.cs new file mode 100644 index 0000000..56c3171 --- /dev/null +++ b/Client/Assembly-CSharp/PurchaseButton.cs @@ -0,0 +1,90 @@ +using System; +using UnityEngine; + +public class PurchaseButton : MonoBehaviour +{ + public StoreMenu Parent { get; set; } + + public SpriteRenderer PurchasedIcon; + + public TextRenderer NameText; + + public SpriteRenderer HatImage; + + public Sprite MannequinFrame; + + public SpriteRenderer Background; + + public IBuyable Product; + + public bool Purchased; + + public string Name; + + public string Price; + + public string ProductId; + + public void SetItem(IBuyable product, string productId, string name, string price, bool purchased) + { + this.Product = product; + this.Purchased = purchased; + this.Name = name; + this.Price = price; + this.ProductId = productId; + this.PurchasedIcon.enabled = this.Purchased; + if (this.Product is HatBehaviour) + { + HatBehaviour hat = (HatBehaviour)this.Product; + this.NameText.gameObject.SetActive(false); + this.HatImage.transform.parent.gameObject.SetActive(true); + PlayerControl.SetHatImage(hat, this.HatImage); + this.SetSquare(); + return; + } + if (this.Product is SkinData) + { + SkinData skin = (SkinData)this.Product; + this.NameText.gameObject.SetActive(false); + this.HatImage.transform.parent.gameObject.SetActive(true); + this.HatImage.transform.parent.GetComponent<SpriteRenderer>().sprite = this.MannequinFrame; + this.HatImage.transform.parent.localPosition = new Vector3(0f, 0f, -0.01f); + this.HatImage.transform.parent.localScale = Vector3.one * 0.3f; + this.HatImage.transform.localPosition = new Vector3(0f, 0f, -0.01f); + this.HatImage.transform.localScale = Vector3.one * 2f; + PlayerControl.SetSkinImage(skin, this.HatImage); + this.SetSquare(); + return; + } + if (this.Product is PetBehaviour) + { + PetBehaviour petBehaviour = (PetBehaviour)this.Product; + this.NameText.gameObject.SetActive(false); + this.HatImage.transform.parent.gameObject.SetActive(true); + this.HatImage.transform.parent.GetComponent<SpriteRenderer>().enabled = false; + this.HatImage.material = new Material(petBehaviour.rend.sharedMaterial); + PlayerControl.SetPetImage(petBehaviour, (int)SaveManager.BodyColor, this.HatImage); + this.SetSquare(); + return; + } + this.NameText.Text = this.Name; + } + + private void SetSquare() + { + this.Background.size = new Vector2(0.7f, 0.7f); + this.Background.GetComponent<BoxCollider2D>().size = new Vector2(0.7f, 0.7f); + this.PurchasedIcon.transform.localPosition = new Vector3(0f, 0f, -1f); + } + + internal void SetPurchased() + { + this.Purchased = true; + this.PurchasedIcon.enabled = true; + } + + public void DoPurchase() + { + this.Parent.SetProduct(this); + } +} diff --git a/Client/Assembly-CSharp/PurchaseStates.cs b/Client/Assembly-CSharp/PurchaseStates.cs new file mode 100644 index 0000000..e2ceb83 --- /dev/null +++ b/Client/Assembly-CSharp/PurchaseStates.cs @@ -0,0 +1,9 @@ +using System; + +public enum PurchaseStates +{ + NotStarted, + Started, + Success, + Fail +} diff --git a/Client/Assembly-CSharp/RadioWaveBehaviour.cs b/Client/Assembly-CSharp/RadioWaveBehaviour.cs new file mode 100644 index 0000000..c46234f --- /dev/null +++ b/Client/Assembly-CSharp/RadioWaveBehaviour.cs @@ -0,0 +1,81 @@ +using System; +using UnityEngine; + +[RequireComponent(typeof(MeshFilter))] +[RequireComponent(typeof(MeshRenderer))] +public class RadioWaveBehaviour : MonoBehaviour +{ + public int NumPoints = 128; + + public FloatRange Width; + + public FloatRange Height; + + private Mesh mesh; + + private Vector3[] vecs; + + public float TickRate = 0.1f; + + private float timer; + + public int Skip = 2; + + public float Frequency = 5f; + + private int Tick; + + public bool Random; + + [Range(0f, 1f)] + public float NoiseLevel; + + public void Start() + { + this.mesh = new Mesh(); + base.GetComponent<MeshFilter>().mesh = this.mesh; + this.mesh.MarkDynamic(); + this.vecs = new Vector3[this.NumPoints]; + int[] array = new int[this.NumPoints]; + for (int i = 0; i < this.vecs.Length; i++) + { + Vector3 vector = this.vecs[i]; + vector.x = this.Width.Lerp((float)i / (float)this.vecs.Length); + vector.y = this.Height.Next(); + this.vecs[i] = vector; + array[i] = i; + } + this.mesh.vertices = this.vecs; + this.mesh.SetIndices(array, MeshTopology.LineStrip, 0); + } + + public void Update() + { + this.timer += Time.deltaTime; + if (this.timer > this.TickRate) + { + this.timer = 0f; + this.Tick++; + for (int i = 0; i < this.vecs.Length - this.Skip; i++) + { + this.vecs[i].y = this.vecs[i + this.Skip].y; + } + if (this.Random) + { + for (int j = 1; j <= this.Skip; j++) + { + this.vecs[this.vecs.Length - j].y = this.Height.Next(); + } + } + else + { + float num = 1f - this.NoiseLevel; + for (int k = 0; k < this.Skip; k++) + { + this.vecs[this.vecs.Length - 1 - this.Skip + k].y = Mathf.Sin(((float)this.Tick + (float)k / (float)this.Skip) * this.Frequency) * this.Height.max * num + this.Height.Next() * this.NoiseLevel; + } + } + this.mesh.vertices = this.vecs; + } + } +} diff --git a/Client/Assembly-CSharp/RandomFill.cs b/Client/Assembly-CSharp/RandomFill.cs new file mode 100644 index 0000000..352eafd --- /dev/null +++ b/Client/Assembly-CSharp/RandomFill.cs @@ -0,0 +1,33 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +public class RandomFill<T> +{ + private T[] values; + + private int idx; + + public void Set(IEnumerable<T> values) + { + if (this.values == null) + { + this.values = values.ToArray<T>(); + this.values.Shuffle<T>(); + this.idx = this.values.Length - 1; + } + } + + public T Get() + { + if (this.idx < 0) + { + this.values.Shuffle<T>(); + this.idx = this.values.Length - 1; + } + T[] array = this.values; + int num = this.idx; + this.idx = num - 1; + return array[num]; + } +} diff --git a/Client/Assembly-CSharp/ReactorMinigame.cs b/Client/Assembly-CSharp/ReactorMinigame.cs new file mode 100644 index 0000000..21e1551 --- /dev/null +++ b/Client/Assembly-CSharp/ReactorMinigame.cs @@ -0,0 +1,110 @@ +using System; +using UnityEngine; + +public class ReactorMinigame : Minigame +{ + private Color bad = new Color(1f, 0.16078432f, 0f); + + private Color good = new Color(0.3019608f, 0.8862745f, 0.8352941f); + + private ReactorSystemType reactor; + + public TextRenderer statusText; + + public SpriteRenderer hand; + + private FloatRange YSweep = new FloatRange(-2.15f, 1.56f); + + public SpriteRenderer sweeper; + + public AudioClip HandSound; + + private bool isButtonDown; + + public override void Begin(PlayerTask task) + { + ShipStatus instance = ShipStatus.Instance; + if (!instance) + { + this.reactor = new ReactorSystemType(); + } + else + { + this.reactor = (instance.Systems[SystemTypes.Reactor] as ReactorSystemType); + } + this.hand.color = this.bad; + } + + public void ButtonDown() + { + if (PlayerControl.LocalPlayer.Data.IsImpostor) + { + return; + } + if (!this.reactor.IsActive) + { + return; + } + this.isButtonDown = !this.isButtonDown; + if (this.isButtonDown) + { + if (Constants.ShouldPlaySfx()) + { + SoundManager.Instance.PlaySound(this.HandSound, true, 1f); + } + ShipStatus.Instance.RpcRepairSystem(SystemTypes.Reactor, (int)((byte)(64 | base.ConsoleId))); + } + else + { + SoundManager.Instance.StopSound(this.HandSound); + ShipStatus.Instance.RpcRepairSystem(SystemTypes.Reactor, (int)((byte)(32 | base.ConsoleId))); + } + try + { + ((SabotageTask)this.MyTask).MarkContributed(); + } + catch + { + } + } + + public void FixedUpdate() + { + if (!this.reactor.IsActive) + { + if (this.amClosing == Minigame.CloseState.None) + { + this.hand.color = this.good; + this.statusText.Text = "Reactor Nominal"; + this.sweeper.enabled = false; + SoundManager.Instance.StopSound(this.HandSound); + base.StartCoroutine(base.CoStartClose(0.75f)); + return; + } + } + else + { + if (!this.isButtonDown) + { + this.statusText.Text = "Hold to stop meltdown"; + this.sweeper.enabled = false; + return; + } + this.statusText.Text = "Waiting for second user"; + Vector3 localPosition = this.sweeper.transform.localPosition; + localPosition.y = this.YSweep.Lerp(Mathf.Sin(Time.time) * 0.5f + 0.5f); + this.sweeper.transform.localPosition = localPosition; + this.sweeper.enabled = true; + } + } + + public override void Close() + { + SoundManager.Instance.StopSound(this.HandSound); + if (ShipStatus.Instance) + { + ShipStatus.Instance.RpcRepairSystem(SystemTypes.Reactor, (int)((byte)(32 | base.ConsoleId))); + } + base.Close(); + } +} diff --git a/Client/Assembly-CSharp/ReactorRoomWire.cs b/Client/Assembly-CSharp/ReactorRoomWire.cs new file mode 100644 index 0000000..6f65fb9 --- /dev/null +++ b/Client/Assembly-CSharp/ReactorRoomWire.cs @@ -0,0 +1,51 @@ +using System; +using PowerTools; +using UnityEngine; + +public class ReactorRoomWire : MonoBehaviour +{ + public global::Console myConsole; + + public SpriteAnim Image; + + public AnimationClip Normal; + + public AnimationClip MeltdownNeed; + + public AnimationClip MeltdownReady; + + private ReactorSystemType reactor; + + public void Update() + { + if (this.reactor == null) + { + ISystemType systemType; + if (!ShipStatus.Instance || !ShipStatus.Instance.Systems.TryGetValue(SystemTypes.Reactor, out systemType)) + { + return; + } + this.reactor = (ReactorSystemType)systemType; + } + if (this.reactor.IsActive) + { + if (this.reactor.GetConsoleComplete(this.myConsole.ConsoleId)) + { + if (!this.Image.IsPlaying(this.MeltdownReady)) + { + this.Image.Play(this.MeltdownReady, 1f); + return; + } + } + else if (!this.Image.IsPlaying(this.MeltdownNeed)) + { + this.Image.Play(this.MeltdownNeed, 1f); + return; + } + } + else if (!this.Image.IsPlaying(this.Normal)) + { + this.Image.Play(this.Normal, 1f); + } + } +} diff --git a/Client/Assembly-CSharp/ReactorShipRoom.cs b/Client/Assembly-CSharp/ReactorShipRoom.cs new file mode 100644 index 0000000..c1975c7 --- /dev/null +++ b/Client/Assembly-CSharp/ReactorShipRoom.cs @@ -0,0 +1,74 @@ +using System; +using PowerTools; +using UnityEngine; + +public class ReactorShipRoom : ShipRoom +{ + public Sprite normalManifolds; + + public Sprite meltdownManifolds; + + public SpriteRenderer Manifolds; + + public AnimationClip normalReactor; + + public AnimationClip meltdownReactor; + + public SpriteAnim Reactor; + + public AnimationClip normalHighFloor; + + public AnimationClip meltdownHighFloor; + + public SpriteAnim HighFloor; + + public AnimationClip normalMidFloor; + + public AnimationClip meltdownMidFloor; + + public SpriteAnim MidFloor1; + + public SpriteAnim MidFloor2; + + public AnimationClip normalLowFloor; + + public AnimationClip meltdownLowFloor; + + public SpriteAnim LowFloor; + + public AnimationClip[] normalPipes; + + public AnimationClip[] meltdownPipes; + + public SpriteAnim[] Pipes; + + public void StartMeltdown() + { + DestroyableSingleton<HudManager>.Instance.StartReactorFlash(); + this.Manifolds.sprite = this.meltdownManifolds; + this.Reactor.Play(this.meltdownReactor, 1f); + this.HighFloor.Play(this.meltdownHighFloor, 1f); + this.MidFloor1.Play(this.meltdownMidFloor, 1f); + this.MidFloor2.Play(this.meltdownMidFloor, 1f); + this.LowFloor.Play(this.meltdownLowFloor, 1f); + for (int i = 0; i < this.Pipes.Length; i++) + { + this.Pipes[i].Play(this.meltdownPipes[i], 1f); + } + } + + public void StopMeltdown() + { + DestroyableSingleton<HudManager>.Instance.StopReactorFlash(); + this.Manifolds.sprite = this.normalManifolds; + this.Reactor.Play(this.normalReactor, 1f); + this.HighFloor.Play(this.normalHighFloor, 1f); + this.MidFloor1.Play(this.normalMidFloor, 1f); + this.MidFloor2.Play(this.normalMidFloor, 1f); + this.LowFloor.Play(this.normalLowFloor, 1f); + for (int i = 0; i < this.Pipes.Length; i++) + { + this.Pipes[i].Play(this.normalPipes[i], 1f); + } + } +} diff --git a/Client/Assembly-CSharp/ReactorSystemType.cs b/Client/Assembly-CSharp/ReactorSystemType.cs new file mode 100644 index 0000000..a1e1fa0 --- /dev/null +++ b/Client/Assembly-CSharp/ReactorSystemType.cs @@ -0,0 +1,137 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using Hazel; + +public class ReactorSystemType : ISystemType, IActivatable +{ + public int UserCount + { + get + { + int num = 0; + int num2 = 0; + foreach (Tuple<byte, byte> tuple in this.UserConsolePairs) + { + int num3 = 1 << (int)tuple.Item2; + if ((num3 & num2) == 0) + { + num++; + num2 |= num3; + } + } + return num; + } + } + + public bool IsActive + { + get + { + return this.Countdown < 10000f; + } + } + + private const float SyncRate = 2f; + + private float timer; + + public const byte StartCountdown = 128; + + public const byte AddUserOp = 64; + + public const byte RemoveUserOp = 32; + + public const byte ClearCountdown = 16; + + public const float CountdownStopped = 10000f; + + public const float ReactorDuration = 30f; + + public const byte ConsoleIdMask = 3; + + public const byte RequiredUserCount = 2; + + public float Countdown = 10000f; + + private HashSet<Tuple<byte, byte>> UserConsolePairs = new HashSet<Tuple<byte, byte>>(); + + public bool GetConsoleComplete(int consoleId) + { + return this.UserConsolePairs.Any((Tuple<byte, byte> kvp) => (int)kvp.Item2 == consoleId); + } + + public void RepairDamage(PlayerControl player, byte opCode) + { + int num = (int)(opCode & 3); + if (opCode == 128 && !this.IsActive) + { + this.Countdown = 30f; + this.UserConsolePairs.Clear(); + return; + } + if (opCode == 16) + { + this.Countdown = 10000f; + return; + } + if (opCode.HasAnyBit(64)) + { + this.UserConsolePairs.Add(new Tuple<byte, byte>(player.PlayerId, (byte)num)); + if (this.UserCount >= 2) + { + this.Countdown = 10000f; + return; + } + } + else if (opCode.HasAnyBit(32)) + { + this.UserConsolePairs.Remove(new Tuple<byte, byte>(player.PlayerId, (byte)num)); + } + } + + public bool Detoriorate(float deltaTime) + { + if (this.IsActive) + { + if (DestroyableSingleton<HudManager>.Instance.ReactorFlash == null) + { + PlayerControl.LocalPlayer.AddSystemTask(SystemTypes.Reactor); + } + this.Countdown -= deltaTime; + this.timer += deltaTime; + if (this.timer > 2f) + { + this.timer = 0f; + return true; + } + } + else if (DestroyableSingleton<HudManager>.Instance.ReactorFlash != null) + { + ((ReactorShipRoom)ShipStatus.Instance.AllRooms.First((ShipRoom r) => r.RoomId == SystemTypes.Reactor)).StopMeltdown(); + } + return false; + } + + public void Serialize(MessageWriter writer, bool initialState) + { + writer.Write(this.Countdown); + writer.WritePacked(this.UserConsolePairs.Count); + foreach (Tuple<byte, byte> tuple in this.UserConsolePairs) + { + writer.Write(tuple.Item1); + writer.Write(tuple.Item2); + } + } + + public void Deserialize(MessageReader reader, bool initialState) + { + this.Countdown = reader.ReadSingle(); + this.UserConsolePairs.Clear(); + int num = reader.ReadPackedInt32(); + for (int i = 0; i < num; i++) + { + this.UserConsolePairs.Add(new Tuple<byte, byte>(reader.ReadByte(), reader.ReadByte())); + } + } +} diff --git a/Client/Assembly-CSharp/ReactorTask.cs b/Client/Assembly-CSharp/ReactorTask.cs new file mode 100644 index 0000000..43f44ba --- /dev/null +++ b/Client/Assembly-CSharp/ReactorTask.cs @@ -0,0 +1,85 @@ +using System; +using System.Linq; +using System.Text; +using UnityEngine; + +public class ReactorTask : SabotageTask +{ + public override int TaskStep + { + get + { + return this.reactor.UserCount; + } + } + + public override bool IsComplete + { + get + { + return this.isComplete; + } + } + + private bool isComplete; + + private ReactorSystemType reactor; + + private bool even; + + public override void Initialize() + { + ShipStatus instance = ShipStatus.Instance; + this.reactor = (ReactorSystemType)instance.Systems[SystemTypes.Reactor]; + ((ReactorShipRoom)instance.AllRooms.First((ShipRoom r) => r.RoomId == SystemTypes.Reactor)).StartMeltdown(); + base.SetupArrows(); + } + + private void FixedUpdate() + { + if (this.isComplete) + { + return; + } + if (!this.reactor.IsActive) + { + this.Complete(); + } + } + + public override bool ValidConsole(global::Console console) + { + return console.TaskTypes.Contains(TaskTypes.ResetReactor); + } + + public override void OnRemove() + { + } + + public override void Complete() + { + this.isComplete = true; + PlayerControl.LocalPlayer.RemoveTask(this); + if (this.didContribute) + { + StatsManager instance = StatsManager.Instance; + uint sabsFixed = instance.SabsFixed; + instance.SabsFixed = sabsFixed + 1U; + } + } + + public override void AppendTaskText(StringBuilder sb) + { + this.even = !this.even; + Color color = this.even ? Color.yellow : Color.red; + sb.Append(color.ToTextColor()); + sb.Append(DestroyableSingleton<TranslationController>.Instance.GetString(TaskTypes.ResetReactor)); + sb.Append(" "); + sb.Append((int)this.reactor.Countdown); + sb.AppendLine(string.Format(" ({0}/{1})[]", this.reactor.UserCount, 2)); + for (int i = 0; i < this.Arrows.Length; i++) + { + this.Arrows[i].image.color = color; + } + } +} diff --git a/Client/Assembly-CSharp/RefuelMinigame.cs b/Client/Assembly-CSharp/RefuelMinigame.cs new file mode 100644 index 0000000..c54401f --- /dev/null +++ b/Client/Assembly-CSharp/RefuelMinigame.cs @@ -0,0 +1,23 @@ +using System; + +public class RefuelMinigame : Minigame +{ + public RefuelStage[] Stages; + + private RefuelStage stage; + + public override void Begin(PlayerTask task) + { + base.Begin(task); + this.stage = this.Stages[(int)this.MyNormTask.Data[1]]; + this.stage.MyNormTask = this.MyNormTask; + this.stage.gameObject.SetActive(true); + this.stage.Begin(); + } + + public override void Close() + { + SoundManager.Instance.StopSound(this.stage.RefuelSound); + base.Close(); + } +} diff --git a/Client/Assembly-CSharp/RefuelStage.cs b/Client/Assembly-CSharp/RefuelStage.cs new file mode 100644 index 0000000..41b64dc --- /dev/null +++ b/Client/Assembly-CSharp/RefuelStage.cs @@ -0,0 +1,98 @@ +using System; +using UnityEngine; + +public class RefuelStage : MonoBehaviour +{ + public NormalPlayerTask MyNormTask { get; set; } + + public float RefuelDuration = 5f; + + private Color darkRed = new Color32(90, 0, 0, byte.MaxValue); + + private Color red = new Color32(byte.MaxValue, 58, 0, byte.MaxValue); + + private Color green = Color.green; + + public SpriteRenderer redLight; + + public SpriteRenderer greenLight; + + public VerticalGauge srcGauge; + + public VerticalGauge destGauge; + + public AudioClip RefuelSound; + + private float timer; + + private bool isDown; + + private bool complete; + + public void Begin() + { + this.timer = (float)this.MyNormTask.Data[0] / 255f; + } + + public void FixedUpdate() + { + if (this.complete) + { + return; + } + if (this.isDown && this.timer < 1f) + { + this.timer += Time.fixedDeltaTime / this.RefuelDuration; + this.MyNormTask.Data[0] = (byte)Mathf.Min(255f, this.timer * 255f); + if (this.timer >= 1f) + { + this.complete = true; + this.greenLight.color = this.green; + this.redLight.color = this.darkRed; + this.MyNormTask.Data[0] = 0; + byte[] data = this.MyNormTask.Data; + int num = 1; + data[num] += 1; + if (this.MyNormTask.Data[1] % 2 == 0) + { + this.MyNormTask.NextStep(); + } + this.MyNormTask.UpdateArrow(); + } + } + this.destGauge.value = this.timer; + if (this.srcGauge) + { + this.srcGauge.value = 1f - this.timer; + } + } + + public void Refuel() + { + if (this.complete) + { + base.transform.parent.GetComponent<Minigame>().Close(); + return; + } + this.isDown = !this.isDown; + this.redLight.color = (this.isDown ? this.red : this.darkRed); + if (this.isDown) + { + if (Constants.ShouldPlaySfx()) + { + SoundManager.Instance.PlayDynamicSound("Refuel", this.RefuelSound, true, new DynamicSound.GetDynamicsFunction(this.GetRefuelDynamics), true); + return; + } + } + else + { + SoundManager.Instance.StopSound(this.RefuelSound); + } + } + + private void GetRefuelDynamics(AudioSource player, float dt) + { + player.volume = 1f; + player.pitch = Mathf.Lerp(0.75f, 1.25f, this.timer); + } +} diff --git a/Client/Assembly-CSharp/ReportButtonManager.cs b/Client/Assembly-CSharp/ReportButtonManager.cs new file mode 100644 index 0000000..151b75b --- /dev/null +++ b/Client/Assembly-CSharp/ReportButtonManager.cs @@ -0,0 +1,28 @@ +using System; +using UnityEngine; + +public class ReportButtonManager : MonoBehaviour +{ + public SpriteRenderer renderer; + + public void SetActive(bool isActive) + { + if (isActive) + { + this.renderer.color = Palette.EnabledColor; + this.renderer.material.SetFloat("_Desat", 0f); + return; + } + this.renderer.color = Palette.DisabledColor; + this.renderer.material.SetFloat("_Desat", 1f); + } + + public void DoClick() + { + if (!base.isActiveAndEnabled) + { + return; + } + PlayerControl.LocalPlayer.ReportClosest(); + } +} diff --git a/Client/Assembly-CSharp/ResSetter.cs b/Client/Assembly-CSharp/ResSetter.cs new file mode 100644 index 0000000..d1632cf --- /dev/null +++ b/Client/Assembly-CSharp/ResSetter.cs @@ -0,0 +1,29 @@ +using System; +using System.IO; +using UnityEngine; + +public class ResSetter : MonoBehaviour +{ + public int Width = 1438; + + public int Height = 810; + + private int cnt; + + public void Start() + { + Screen.SetResolution(this.Width, this.Height, false); + } + + public void Update() + { + if (Input.GetKeyDown(KeyCode.S)) + { + Directory.CreateDirectory("C:\\AmongUsSS"); + string format = "C:\\AmongUsSS\\Screenshot-{0}.png"; + int num = this.cnt; + this.cnt = num + 1; + ScreenCapture.CaptureScreenshot(string.Format(format, num)); + } + } +} diff --git a/Client/Assembly-CSharp/ResolutionManager.cs b/Client/Assembly-CSharp/ResolutionManager.cs new file mode 100644 index 0000000..15a8ce7 --- /dev/null +++ b/Client/Assembly-CSharp/ResolutionManager.cs @@ -0,0 +1,44 @@ +using System; +using UnityEngine; + +public static class ResolutionManager +{ + public static event Action<float> ResolutionChanged; + + public static void SetResolution(int width, int height, bool fullscreen) + { + Action<float> resolutionChanged = ResolutionManager.ResolutionChanged; + if (resolutionChanged != null) + { + resolutionChanged((float)width / (float)height); + } + Screen.SetResolution(width, height, fullscreen); + } + + public static void ToggleFullscreen() + { + bool flag = !Screen.fullScreen; + int width; + int height; + if (flag) + { + Resolution[] resolutions = Screen.resolutions; + Resolution resolution = resolutions[0]; + for (int i = 0; i < resolutions.Length; i++) + { + if (resolution.height < resolutions[i].height) + { + resolution = resolutions[i]; + } + } + width = resolution.width; + height = resolution.height; + } + else + { + width = 711; + height = 400; + } + ResolutionManager.SetResolution(width, height, flag); + } +} diff --git a/Client/Assembly-CSharp/ResolutionSlider.cs b/Client/Assembly-CSharp/ResolutionSlider.cs new file mode 100644 index 0000000..088854a --- /dev/null +++ b/Client/Assembly-CSharp/ResolutionSlider.cs @@ -0,0 +1,73 @@ +using System; +using System.Linq; +using UnityEngine; + +public class ResolutionSlider : MonoBehaviour +{ + private int targetIdx; + + private Resolution targetResolution; + + private bool targetFullscreen; + + private Resolution[] allResolutions; + + public SlideBar slider; + + public ToggleButtonBehaviour Fullscreen; + + public ToggleButtonBehaviour VSync; + + public TextRenderer Display; + + public void OnEnable() + { + this.allResolutions = (from r in Screen.resolutions + where r.height > 480 + select r).ToArray<Resolution>(); + this.targetResolution = Screen.currentResolution; + this.targetFullscreen = Screen.fullScreen; + this.targetIdx = this.allResolutions.IndexOf((Resolution e) => e.width == this.targetResolution.width && e.height == this.targetResolution.height); + this.slider.Value = (float)this.targetIdx / ((float)this.allResolutions.Length - 1f); + this.Display.Text = string.Format("{0}x{1}", this.targetResolution.width, this.targetResolution.height); + this.Fullscreen.UpdateText(this.targetFullscreen); + this.VSync.UpdateText(QualitySettings.vSyncCount != 0); + } + + public void ToggleVSync() + { + bool flag = QualitySettings.vSyncCount != 0; + if (flag) + { + QualitySettings.vSyncCount = 0; + } + else + { + QualitySettings.vSyncCount = 1; + } + this.VSync.UpdateText(!flag); + } + + public void ToggleFullscreen() + { + this.targetFullscreen = !this.targetFullscreen; + this.Fullscreen.UpdateText(this.targetFullscreen); + } + + public void OnResChange(SlideBar slider) + { + int num = Mathf.RoundToInt((float)(this.allResolutions.Length - 1) * slider.Value); + if (num != this.targetIdx) + { + this.targetIdx = num; + this.targetResolution = this.allResolutions[num]; + this.Display.Text = string.Format("{0}x{1}", this.targetResolution.width, this.targetResolution.height); + } + slider.Value = (float)this.targetIdx / ((float)this.allResolutions.Length - 1f); + } + + public void SaveChange() + { + ResolutionManager.SetResolution(this.targetResolution.width, this.targetResolution.height, this.targetFullscreen); + } +} diff --git a/Client/Assembly-CSharp/RingBuffer.cs b/Client/Assembly-CSharp/RingBuffer.cs new file mode 100644 index 0000000..e12313e --- /dev/null +++ b/Client/Assembly-CSharp/RingBuffer.cs @@ -0,0 +1,75 @@ +using System; + +public class RingBuffer<T> +{ + public int Count { get; private set; } + + public int Capacity + { + get + { + return this.Data.Length; + } + } + + public T this[int i] + { + get + { + int num = (this.startIdx + i) % this.Data.Length; + return this.Data[num]; + } + } + + private readonly T[] Data; + + private int startIdx; + + public RingBuffer(int size) + { + this.Data = new T[size]; + } + + public T First() + { + return this.Data[this.startIdx]; + } + + public T Last() + { + int num = (this.startIdx + this.Count - 1) % this.Data.Length; + return this.Data[num]; + } + + public void Add(T item) + { + int num = (this.startIdx + this.Count) % this.Data.Length; + this.Data[num] = item; + if (this.Count < this.Data.Length) + { + int count = this.Count; + this.Count = count + 1; + return; + } + this.startIdx = (this.startIdx + 1) % this.Data.Length; + } + + public T RemoveFirst() + { + if (this.Count == 0) + { + throw new InvalidOperationException("Data is empty"); + } + T result = this.Data[this.startIdx]; + this.startIdx = (this.startIdx + 1) % this.Data.Length; + int count = this.Count; + this.Count = count - 1; + return result; + } + + public void Clear() + { + this.startIdx = 0; + this.Count = 0; + } +} diff --git a/Client/Assembly-CSharp/RoomTracker.cs b/Client/Assembly-CSharp/RoomTracker.cs new file mode 100644 index 0000000..3c24ed6 --- /dev/null +++ b/Client/Assembly-CSharp/RoomTracker.cs @@ -0,0 +1,159 @@ +using System; +using System.Collections; +using UnityEngine; + +public class RoomTracker : MonoBehaviour +{ + public TextRenderer text; + + public float SourceY = -2.5f; + + public float TargetY = -3.25f; + + private Collider2D playerCollider; + + private ContactFilter2D filter; + + private Collider2D[] buffer = new Collider2D[10]; + + public ShipRoom LastRoom; + + private Coroutine slideInRoutine; + + public void Awake() + { + this.filter = default(ContactFilter2D); + this.filter.layerMask = Constants.PlayersOnlyMask; + this.filter.useLayerMask = true; + this.filter.useTriggers = false; + } + + public void OnDisable() + { + this.LastRoom = null; + Vector3 localPosition = this.text.transform.localPosition; + localPosition.y = this.TargetY; + this.text.transform.localPosition = localPosition; + } + + public void FixedUpdate() + { + ShipRoom[] array = null; + if (LobbyBehaviour.Instance) + { + array = LobbyBehaviour.Instance.AllRooms; + } + if (ShipStatus.Instance) + { + array = ShipStatus.Instance.AllRooms; + } + if (array == null) + { + return; + } + ShipRoom shipRoom = null; + if (this.LastRoom) + { + int hitCount = this.LastRoom.roomArea.OverlapCollider(this.filter, this.buffer); + if (RoomTracker.CheckHitsForPlayer(this.buffer, hitCount)) + { + shipRoom = this.LastRoom; + } + } + if (!shipRoom) + { + foreach (ShipRoom shipRoom2 in array) + { + if (shipRoom2.roomArea) + { + int hitCount2 = shipRoom2.roomArea.OverlapCollider(this.filter, this.buffer); + if (RoomTracker.CheckHitsForPlayer(this.buffer, hitCount2)) + { + shipRoom = shipRoom2; + } + } + } + } + if (shipRoom) + { + if (this.LastRoom != shipRoom) + { + this.LastRoom = shipRoom; + if (this.slideInRoutine != null) + { + base.StopCoroutine(this.slideInRoutine); + } + if (shipRoom.RoomId != SystemTypes.Hallway) + { + this.slideInRoutine = base.StartCoroutine(this.CoSlideIn(shipRoom.RoomId)); + return; + } + this.slideInRoutine = base.StartCoroutine(this.SlideOut()); + return; + } + } + else if (this.LastRoom) + { + this.LastRoom = null; + if (this.slideInRoutine != null) + { + base.StopCoroutine(this.slideInRoutine); + } + this.slideInRoutine = base.StartCoroutine(this.SlideOut()); + } + } + + private IEnumerator CoSlideIn(SystemTypes newRoom) + { + yield return this.SlideOut(); + Vector3 tempPos = this.text.transform.localPosition; + Color tempColor = Color.white; + this.text.Text = DestroyableSingleton<TranslationController>.Instance.GetString(newRoom); + float timer = 0f; + while (timer < 0.25f) + { + timer = Mathf.Min(0.25f, timer + Time.deltaTime); + float t = timer / 0.25f; + tempPos.y = Mathf.SmoothStep(this.TargetY, this.SourceY, t); + tempColor.a = Mathf.Lerp(0f, 1f, t); + this.text.transform.localPosition = tempPos; + this.text.Color = tempColor; + yield return null; + } + yield break; + } + + private IEnumerator SlideOut() + { + Vector3 tempPos = this.text.transform.localPosition; + Color tempColor = Color.white; + float timer = FloatRange.ReverseLerp(tempPos.y, this.SourceY, this.TargetY) * 0.1f; + while (timer < 0.1f) + { + timer = Mathf.Min(0.1f, timer + Time.deltaTime); + float t = timer / 0.1f; + tempPos.y = Mathf.SmoothStep(this.SourceY, this.TargetY, t); + tempColor.a = Mathf.Lerp(1f, 0f, t); + this.text.transform.localPosition = tempPos; + this.text.Color = tempColor; + yield return null; + } + yield break; + } + + private static bool CheckHitsForPlayer(Collider2D[] buffer, int hitCount) + { + if (!PlayerControl.LocalPlayer) + { + return false; + } + for (int i = 0; i < hitCount; i++) + { + if (buffer[i].gameObject == PlayerControl.LocalPlayer.gameObject) + { + return true; + } + } + return false; + } +} diff --git a/Client/Assembly-CSharp/SabotageSystemType.cs b/Client/Assembly-CSharp/SabotageSystemType.cs new file mode 100644 index 0000000..59dd234 --- /dev/null +++ b/Client/Assembly-CSharp/SabotageSystemType.cs @@ -0,0 +1,135 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using Hazel; + +public class SabotageSystemType : ISystemType +{ + public float Timer { get; set; } + + public float PercentCool + { + get + { + return this.Timer / 30f; + } + } + + public bool AnyActive + { + get + { + return this.specials.Any((IActivatable s) => s.IsActive); + } + } + + public const float SpecialSabDelay = 30f; + + private List<IActivatable> specials; + + private bool dirty; + + private SabotageSystemType.DummySab dummy = new SabotageSystemType.DummySab(); + + public class DummySab : IActivatable + { + public bool IsActive + { + get + { + return this.timer > 0f; + } + } + + public float timer; + } + + public SabotageSystemType(IActivatable[] specials) + { + this.specials = new List<IActivatable>(specials); + this.specials.Add(this.dummy); + } + + public bool Detoriorate(float deltaTime) + { + this.dummy.timer -= deltaTime; + if (this.Timer > 0f && !this.AnyActive) + { + this.Timer -= deltaTime; + if (this.Timer <= 0f) + { + return true; + } + } + return this.dirty; + } + + public void ForceSabTime(float t) + { + this.dummy.timer = t; + } + + public void RepairDamage(PlayerControl player, byte amount) + { + this.dirty = true; + if (this.Timer > 0f) + { + return; + } + if (MeetingHud.Instance) + { + return; + } + if (AmongUsClient.Instance.AmHost) + { + if (amount <= 7) + { + if (amount != 3) + { + if (amount == 7) + { + byte b = 4; + for (int i = 0; i < 5; i++) + { + if (BoolRange.Next(0.5f)) + { + b |= (byte)(1 << i); + } + } + ShipStatus.Instance.RpcRepairSystem(SystemTypes.Electrical, (int)(b | 128)); + } + } + else + { + ShipStatus.Instance.RepairSystem(SystemTypes.Reactor, player, 128); + } + } + else if (amount != 8) + { + if (amount == 14) + { + ShipStatus.Instance.RepairSystem(SystemTypes.Comms, player, 128); + } + } + else + { + ShipStatus.Instance.RepairSystem(SystemTypes.LifeSupp, player, 128); + } + } + this.Timer = 30f; + } + + public void Serialize(MessageWriter writer, bool initialState) + { + writer.Write(this.Timer); + if (!initialState) + { + this.dirty = false; + } + } + + public void Deserialize(MessageReader reader, bool initialState) + { + this.Timer = reader.ReadSingle(); + } +} diff --git a/Client/Assembly-CSharp/SabotageTask.cs b/Client/Assembly-CSharp/SabotageTask.cs new file mode 100644 index 0000000..2f3e21a --- /dev/null +++ b/Client/Assembly-CSharp/SabotageTask.cs @@ -0,0 +1,33 @@ +using System; +using System.Collections.Generic; + +public abstract class SabotageTask : PlayerTask +{ + protected bool didContribute; + + public ArrowBehaviour[] Arrows; + + public void MarkContributed() + { + this.didContribute = true; + } + + protected void SetupArrows() + { + if (base.Owner.AmOwner) + { + List<global::Console> list = base.FindConsoles(); + for (int i = 0; i < list.Count; i++) + { + int consoleId = list[i].ConsoleId; + this.Arrows[consoleId].target = list[i].transform.position; + this.Arrows[consoleId].gameObject.SetActive(true); + } + return; + } + for (int j = 0; j < this.Arrows.Length; j++) + { + this.Arrows[j].gameObject.SetActive(false); + } + } +} diff --git a/Client/Assembly-CSharp/SampleMinigame.cs b/Client/Assembly-CSharp/SampleMinigame.cs new file mode 100644 index 0000000..fd60a67 --- /dev/null +++ b/Client/Assembly-CSharp/SampleMinigame.cs @@ -0,0 +1,382 @@ +using System; +using System.Collections; +using UnityEngine; + +public class SampleMinigame : Minigame +{ + private SampleMinigame.States State + { + get + { + return (SampleMinigame.States)this.MyNormTask.Data[0]; + } + set + { + this.MyNormTask.Data[0] = (byte)value; + } + } + + private int AnomalyId + { + get + { + return (int)this.MyNormTask.Data[1]; + } + set + { + this.MyNormTask.Data[1] = (byte)value; + } + } + + private static string[] ProcessingStrings = new string[] + { + "Take a break", + "Go grab a coffee", + "You dont need to wait", + "go do something else" + }; + + private const float PanelMoveDuration = 0.75f; + + private const byte TubeMask = 15; + + public TextRenderer UpperText; + + public TextRenderer LowerText; + + public float TimePerStep = 15f; + + public FloatRange platformY = new FloatRange(-3.5f, -0.75f); + + public FloatRange dropperX = new FloatRange(-1.25f, 1.25f); + + public SpriteRenderer CenterPanel; + + public SpriteRenderer Dropper; + + public SpriteRenderer[] Tubes; + + public SpriteRenderer[] Buttons; + + public SpriteRenderer LowerButton; + + public AudioClip ButtonSound; + + public AudioClip PanelMoveSound; + + public AudioClip FailSound; + + public AudioClip[] DropSounds; + + private RandomFill<AudioClip> dropSounds; + + public enum States : byte + { + PrepareSample, + Complete = 16, + AwaitingStart = 32, + Selection = 64, + Processing = 128 + } + + public void Awake() + { + this.dropSounds = new RandomFill<AudioClip>(); + this.dropSounds.Set(this.DropSounds); + } + + public override void Begin(PlayerTask task) + { + base.Begin(task); + SampleMinigame.States state = this.State; + if (state <= SampleMinigame.States.AwaitingStart) + { + if (state != SampleMinigame.States.PrepareSample) + { + if (state != SampleMinigame.States.AwaitingStart) + { + return; + } + this.LowerText.Text = "Press To Begin -->"; + this.SetPlatformTop(); + return; + } + else + { + base.StartCoroutine(this.BringPanelUp(true)); + } + } + else + { + if (state == SampleMinigame.States.Selection) + { + for (int i = 0; i < this.Tubes.Length; i++) + { + this.Tubes[i].color = Color.blue; + } + this.Tubes[this.AnomalyId].color = Color.red; + this.LowerText.Text = "Select Anomaly"; + this.SetPlatformTop(); + return; + } + if (state == SampleMinigame.States.Processing) + { + for (int j = 0; j < this.Tubes.Length; j++) + { + this.Tubes[j].color = Color.blue; + } + this.LowerText.Text = SampleMinigame.ProcessingStrings.Random<string>(); + this.SetPlatformBottom(); + return; + } + } + } + + private void SetPlatformBottom() + { + Vector3 localPosition = this.CenterPanel.transform.localPosition; + localPosition.y = this.platformY.min; + this.CenterPanel.transform.localPosition = localPosition; + } + + private void SetPlatformTop() + { + Vector3 localPosition = this.CenterPanel.transform.localPosition; + localPosition.y = this.platformY.max; + this.CenterPanel.transform.localPosition = localPosition; + } + + public void FixedUpdate() + { + if (this.State == SampleMinigame.States.Processing) + { + if (this.MyNormTask.TaskTimer <= 0f) + { + this.State = SampleMinigame.States.Selection; + this.LowerText.Text = "Select Anomaly"; + this.UpperText.Text = ""; + this.AnomalyId = this.Tubes.RandomIdx<SpriteRenderer>(); + this.Tubes[this.AnomalyId].color = Color.red; + this.LowerButton.color = Color.white; + base.StartCoroutine(this.BringPanelUp(false)); + return; + } + this.UpperText.Text = "ETA: " + (int)this.MyNormTask.TaskTimer; + return; + } + else + { + if (this.State == SampleMinigame.States.Selection) + { + float num = Mathf.Cos(Time.time * 1.5f) - 0.2f; + Color color = new Color(num, 1f, num, 1f); + for (int i = 0; i < this.Buttons.Length; i++) + { + this.Buttons[i].color = color; + } + return; + } + if (this.State == SampleMinigame.States.AwaitingStart) + { + float num2 = Mathf.Cos(Time.time * 1.5f) - 0.2f; + Color color2 = new Color(num2, 1f, num2, 1f); + this.LowerButton.color = color2; + } + return; + } + } + + public IEnumerator BringPanelUp(bool isBeginning) + { + if (Constants.ShouldPlaySfx()) + { + SoundManager.Instance.PlaySound(this.PanelMoveSound, false, 1f); + } + WaitForFixedUpdate wait = new WaitForFixedUpdate(); + Vector3 pos = this.CenterPanel.transform.localPosition; + for (float i = 0f; i < 0.75f; i += Time.deltaTime) + { + pos.y = this.platformY.Lerp(i / 0.75f); + this.CenterPanel.transform.localPosition = pos; + yield return wait; + } + if (isBeginning) + { + this.State = SampleMinigame.States.AwaitingStart; + this.LowerText.Text = "Press To Begin -->"; + } + pos.y = this.platformY.max; + this.CenterPanel.transform.localPosition = pos; + yield break; + } + + public IEnumerator BringPanelDown() + { + if (Constants.ShouldPlaySfx()) + { + SoundManager.Instance.PlaySound(this.PanelMoveSound, false, 1f); + } + WaitForFixedUpdate wait = new WaitForFixedUpdate(); + Vector3 pos = this.CenterPanel.transform.localPosition; + for (float i = 0f; i < 0.75f; i += Time.deltaTime) + { + pos.y = this.platformY.Lerp(1f - i / 0.75f); + this.CenterPanel.transform.localPosition = pos; + yield return wait; + } + pos.y = this.platformY.min; + this.CenterPanel.transform.localPosition = pos; + yield break; + } + + private IEnumerator DropTube(int id) + { + if (Constants.ShouldPlaySfx()) + { + SoundManager.Instance.PlaySound(this.dropSounds.Get(), false, 1f); + } + this.Tubes[id].color = Color.blue; + yield break; + } + + public void SelectTube(int tubeId) + { + if (this.State != SampleMinigame.States.Selection) + { + return; + } + this.State = SampleMinigame.States.PrepareSample; + for (int i = 0; i < this.Buttons.Length; i++) + { + this.Buttons[i].color = Color.white; + } + base.StartCoroutine(this.CoSelectTube(this.AnomalyId, tubeId)); + } + + private IEnumerator CoSelectTube(int correctTube, int selectedTube) + { + if (selectedTube != correctTube) + { + if (Constants.ShouldPlaySfx()) + { + SoundManager.Instance.PlaySound(this.FailSound, false, 1f); + } + this.UpperText.Text = "Bad Result"; + this.LowerText.Text = "Bad Result"; + for (int i = 0; i < this.Buttons.Length; i++) + { + this.Buttons[i].color = Color.red; + } + yield return new WaitForSeconds(0.25f); + for (int j = 0; j < this.Buttons.Length; j++) + { + this.Buttons[j].color = Color.white; + } + yield return new WaitForSeconds(0.25f); + for (int k = 0; k < this.Buttons.Length; k++) + { + this.Buttons[k].color = Color.red; + } + yield return new WaitForSeconds(0.25f); + for (int l = 0; l < this.Buttons.Length; l++) + { + this.Buttons[l].color = Color.white; + } + this.UpperText.Text = ""; + } + else + { + if (Constants.ShouldPlaySfx()) + { + SoundManager.Instance.PlaySound(this.ButtonSound, false, 0.6f); + } + this.UpperText.Text = "Thank you"; + this.MyNormTask.NextStep(); + if (this.MyNormTask.IsComplete) + { + this.State = SampleMinigame.States.Complete; + } + } + int num = this.MyNormTask.MaxStep - this.MyNormTask.taskStep; + if (num == 0) + { + this.LowerText.Text = "Tests Complete"; + } + else + { + this.LowerText.Text = num + " more"; + } + yield return this.BringPanelDown(); + for (int m = 0; m < this.Tubes.Length; m++) + { + this.Tubes[m].color = Color.white; + } + if (!this.MyNormTask.IsComplete) + { + yield return this.BringPanelUp(true); + } + yield break; + } + + public void NextStep() + { + if (this.State != SampleMinigame.States.AwaitingStart) + { + return; + } + this.State = SampleMinigame.States.Processing; + this.LowerButton.color = Color.white; + if (Constants.ShouldPlaySfx()) + { + SoundManager.Instance.PlaySound(this.ButtonSound, false, 1f).volume = 0.6f; + } + base.StartCoroutine(this.CoStartProcessing()); + } + + private IEnumerator CoStartProcessing() + { + this.MyNormTask.TaskTimer = this.TimePerStep; + this.MyNormTask.TimerStarted = NormalPlayerTask.TimerState.Started; + yield return this.DropLiquid(); + this.LowerText.Text = SampleMinigame.ProcessingStrings.Random<string>(); + yield return this.BringPanelDown(); + yield break; + } + + private IEnumerator DropLiquid() + { + this.LowerText.Text = "Adding Reagent"; + WaitForSeconds dropWait = new WaitForSeconds(0.25f); + WaitForFixedUpdate wait = new WaitForFixedUpdate(); + Vector3 pos = this.Dropper.transform.localPosition; + yield return dropWait; + yield return this.DropTube(0); + int num; + for (int step = -2; step < 2; step = num) + { + float start = (float)step / 2f * 1.25f; + float xTarg = (float)(step + 1) / 2f * 1.25f; + for (float i = 0f; i < 0.15f; i += Time.deltaTime) + { + pos.x = Mathf.Lerp(start, xTarg, i / 0.15f); + this.Dropper.transform.localPosition = pos; + yield return wait; + } + pos.x = xTarg; + this.Dropper.transform.localPosition = pos; + yield return dropWait; + int id = step + 3; + yield return this.DropTube(id); + num = step + 1; + } + for (float xTarg = 0f; xTarg < 0.15f; xTarg += Time.deltaTime) + { + pos.x = this.dropperX.Lerp(1f - xTarg / 0.15f); + this.Dropper.transform.localPosition = pos; + yield return wait; + } + pos.x = this.dropperX.min; + this.Dropper.transform.localPosition = pos; + yield break; + } +} diff --git a/Client/Assembly-CSharp/SaveManager.cs b/Client/Assembly-CSharp/SaveManager.cs new file mode 100644 index 0000000..8687d45 --- /dev/null +++ b/Client/Assembly-CSharp/SaveManager.cs @@ -0,0 +1,750 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.IO; +using UnityEngine; + +public static class SaveManager +{ + public static Announcement LastAnnouncement + { + get + { + SaveManager.LoadAnnouncement(); + return SaveManager.lastAnnounce; + } + set + { + SaveManager.lastAnnounce = value; + SaveManager.SaveAnnouncement(); + } + } + + public static DateTime LastStartDate + { + get + { + SaveManager.LoadSecureData2(); + return SaveManager.lastStartDate; + } + set + { + SaveManager.LoadSecureData2(); + if (SaveManager.lastStartDate < value) + { + SaveManager.lastStartDate = value; + SaveManager.SaveSecureData2(); + } + } + } + + public static int Month + { + get + { + return SaveManager.LastStartDate.Month; + } + } + + public static bool BoughtNoAds + { + get + { + SaveManager.LoadSecureData(); + return SaveManager.purchases.Contains("bought_ads"); + } + } + + public static bool CensorChat + { + get + { + SaveManager.LoadPlayerPrefs(); + return SaveManager.censorChat; + } + set + { + SaveManager.LoadPlayerPrefs(); + SaveManager.censorChat = value; + SaveManager.SavePlayerPrefs(); + } + } + + public static ShowAdsState ShowAdsScreen + { + get + { + SaveManager.LoadPlayerPrefs(); + return (ShowAdsState)SaveManager.showAdsScreen; + } + set + { + SaveManager.LoadPlayerPrefs(); + SaveManager.showAdsScreen = (byte)value; + SaveManager.SavePlayerPrefs(); + } + } + + public static bool SendDataScreen + { + get + { + SaveManager.LoadPlayerPrefs(); + return SaveManager.sendDataScreen; + } + set + { + SaveManager.LoadPlayerPrefs(); + SaveManager.sendDataScreen = value; + SaveManager.SavePlayerPrefs(); + } + } + + public static bool SendName + { + get + { + SaveManager.LoadPlayerPrefs(); + return SaveManager.sendName && SaveManager.SendTelemetry; + } + set + { + SaveManager.LoadPlayerPrefs(); + SaveManager.sendName = value; + SaveManager.SavePlayerPrefs(); + } + } + + public static bool SendTelemetry + { + get + { + SaveManager.LoadPlayerPrefs(); + return SaveManager.sendTelemetry; + } + set + { + SaveManager.LoadPlayerPrefs(); + SaveManager.sendTelemetry = value; + SaveManager.SavePlayerPrefs(); + } + } + + public static bool ShowMinPlayerWarning + { + get + { + SaveManager.LoadPlayerPrefs(); + return SaveManager.showMinPlayerWarning; + } + set + { + SaveManager.LoadPlayerPrefs(); + SaveManager.showMinPlayerWarning = value; + SaveManager.SavePlayerPrefs(); + } + } + + public static bool ShowOnlineHelp + { + get + { + SaveManager.LoadPlayerPrefs(); + return SaveManager.showOnlineHelp; + } + set + { + SaveManager.LoadPlayerPrefs(); + SaveManager.showOnlineHelp = value; + SaveManager.SavePlayerPrefs(); + } + } + + public static float SfxVolume + { + get + { + SaveManager.LoadPlayerPrefs(); + return (float)SaveManager.sfxVolume / 255f; + } + set + { + SaveManager.LoadPlayerPrefs(); + SaveManager.sfxVolume = (byte)(value * 255f); + SaveManager.SavePlayerPrefs(); + } + } + + public static float MusicVolume + { + get + { + SaveManager.LoadPlayerPrefs(); + return (float)SaveManager.musicVolume / 255f; + } + set + { + SaveManager.LoadPlayerPrefs(); + SaveManager.musicVolume = (byte)(value * 255f); + SaveManager.SavePlayerPrefs(); + } + } + + public static int TouchConfig + { + get + { + SaveManager.LoadPlayerPrefs(); + return SaveManager.touchConfig; + } + set + { + SaveManager.LoadPlayerPrefs(); + SaveManager.touchConfig = value; + SaveManager.SavePlayerPrefs(); + } + } + + public static float JoystickSize + { + get + { + SaveManager.LoadPlayerPrefs(); + return SaveManager.joyStickSize; + } + set + { + SaveManager.LoadPlayerPrefs(); + SaveManager.joyStickSize = value; + SaveManager.SavePlayerPrefs(); + } + } + + public static string PlayerName + { + get + { + SaveManager.LoadPlayerPrefs(); + return SaveManager.lastPlayerName ?? "Enter Name"; + } + set + { + SaveManager.LoadPlayerPrefs(); + SaveManager.lastPlayerName = value; + SaveManager.SavePlayerPrefs(); + } + } + + public static uint LastPet + { + get + { + SaveManager.LoadPlayerPrefs(); + return SaveManager.lastPet; + } + set + { + SaveManager.LoadPlayerPrefs(); + SaveManager.lastPet = value; + SaveManager.SavePlayerPrefs(); + } + } + + public static uint LastHat + { + get + { + SaveManager.LoadPlayerPrefs(); + return SaveManager.lastHat; + } + set + { + SaveManager.LoadPlayerPrefs(); + SaveManager.lastHat = value; + SaveManager.SavePlayerPrefs(); + } + } + + public static uint LastSkin + { + get + { + SaveManager.LoadPlayerPrefs(); + return SaveManager.lastSkin; + } + set + { + SaveManager.LoadPlayerPrefs(); + SaveManager.lastSkin = value; + SaveManager.SavePlayerPrefs(); + } + } + + public static uint LastLanguage + { + get + { + SaveManager.LoadPlayerPrefs(); + return SaveManager.lastLanguage; + } + set + { + SaveManager.LoadPlayerPrefs(); + SaveManager.lastLanguage = value; + SaveManager.SavePlayerPrefs(); + } + } + + public static byte BodyColor + { + get + { + SaveManager.LoadPlayerPrefs(); + return (byte)(SaveManager.colorConfig & 255U); + } + set + { + SaveManager.LoadPlayerPrefs(); + SaveManager.colorConfig = ((SaveManager.colorConfig & 16776960U) | (uint)(value & byte.MaxValue)); + SaveManager.SavePlayerPrefs(); + } + } + + public static GameOptionsData GameHostOptions + { + get + { + if (SaveManager.hostOptionsData == null) + { + SaveManager.hostOptionsData = SaveManager.LoadGameOptions("gameHostOptions"); + } + SaveManager.hostOptionsData.NumImpostors = Mathf.Clamp(SaveManager.hostOptionsData.NumImpostors, 1, 3); + SaveManager.hostOptionsData.KillDistance = Mathf.Clamp(SaveManager.hostOptionsData.KillDistance, 0, 2); + return SaveManager.hostOptionsData; + } + set + { + SaveManager.hostOptionsData = value; + SaveManager.SaveGameOptions(SaveManager.hostOptionsData, "gameHostOptions"); + } + } + + public static GameOptionsData GameSearchOptions + { + get + { + GameOptionsData result; + if ((result = SaveManager.searchOptionsData) == null) + { + result = (SaveManager.searchOptionsData = SaveManager.LoadGameOptions("gameSearchOptions")); + } + return result; + } + set + { + SaveManager.searchOptionsData = value; + SaveManager.SaveGameOptions(SaveManager.searchOptionsData, "gameSearchOptions"); + } + } + + private static bool loaded; + + private static bool loadedStats; + + private static bool loadedAnnounce; + + private static string lastPlayerName; + + private static byte sfxVolume = byte.MaxValue; + + private static byte musicVolume = byte.MaxValue; + + private static bool showMinPlayerWarning = true; + + private static bool showOnlineHelp = true; + + private static bool sendDataScreen = false; + + private static byte showAdsScreen = 0; + + private static bool sendName = true; + + private static bool sendTelemetry = true; + + private static bool censorChat = true; + + private static int touchConfig; + + private static float joyStickSize = 1f; + + private static uint colorConfig; + + private static uint lastPet; + + private static uint lastHat; + + private static uint lastSkin; + + private static uint lastLanguage; + + private static GameOptionsData hostOptionsData; + + private static GameOptionsData searchOptionsData; + + private static Announcement lastAnnounce; + + private static SaveManager.SecureDataFile secure2 = new SaveManager.SecureDataFile(Path.Combine(Application.persistentDataPath, "secure2")); + + private static DateTime lastStartDate = DateTime.MinValue; + + private static SaveManager.SecureDataFile purchaseFile = new SaveManager.SecureDataFile(Path.Combine(Application.persistentDataPath, "secureNew")); + + private static HashSet<string> purchases = new HashSet<string>(StringComparer.OrdinalIgnoreCase); + + private class SecureDataFile + { + public bool Loaded { get; private set; } + + private string filePath; + + public SecureDataFile(string filePath) + { + this.filePath = filePath; + } + + public BinaryReader LoadData() + { + this.Loaded = true; + Debug.Log("Loading secure: " + this.filePath); + if (File.Exists(this.filePath)) + { + byte[] array = File.ReadAllBytes(this.filePath); + for (int i = 0; i < array.Length; i++) + { + byte[] array2 = array; + int num = i; + array2[num] ^= (byte)(i % 212); + } + try + { + BinaryReader binaryReader = new BinaryReader(new MemoryStream(array)); + binaryReader.ReadString(); + return binaryReader; + } + catch + { + Debug.Log("Deleted corrupt secure file inner"); + this.Delete(); + } + } + return null; + } + + public void SaveData(params object[] items) + { + byte[] array; + using (MemoryStream memoryStream = new MemoryStream()) + { + using (BinaryWriter binaryWriter = new BinaryWriter(memoryStream)) + { + binaryWriter.Write(SystemInfo.deviceUniqueIdentifier); + foreach (object obj in items) + { + if (obj is long) + { + binaryWriter.Write((long)obj); + } + else if (obj is HashSet<string>) + { + foreach (string value in ((HashSet<string>)obj)) + { + binaryWriter.Write(value); + } + } + } + binaryWriter.Flush(); + memoryStream.Position = 0L; + array = memoryStream.ToArray(); + } + } + for (int j = 0; j < array.Length; j++) + { + byte[] array2 = array; + int num = j; + array2[num] ^= (byte)(j % 212); + } + File.WriteAllBytes(this.filePath, array); + } + + public void Delete() + { + try + { + File.Delete(this.filePath); + } + catch + { + } + } + } + + private static void SaveSecureData2() + { + SaveManager.secure2.SaveData(new object[] + { + SaveManager.lastStartDate.Ticks + }); + } + + private static void LoadSecureData2() + { + if (SaveManager.secure2.Loaded) + { + return; + } + try + { + using (BinaryReader binaryReader = SaveManager.secure2.LoadData()) + { + SaveManager.lastStartDate = new DateTime(binaryReader.ReadInt64()); + } + } + catch + { + } + } + + public static bool GetPurchase(string key) + { + SaveManager.LoadSecureData(); + return SaveManager.purchases.Contains(key); + } + + public static void SetPurchased(string key) + { + SaveManager.LoadSecureData(); + SaveManager.purchases.Add(key ?? "null"); + if (key == "bought_ads") + { + SaveManager.ShowAdsScreen = ShowAdsState.Purchased; + } + SaveManager.SaveSecureData(); + } + + private static void LoadSecureData() + { + if (SaveManager.purchaseFile.Loaded) + { + return; + } + try + { + using (BinaryReader binaryReader = SaveManager.purchaseFile.LoadData()) + { + while (binaryReader.BaseStream.Position < binaryReader.BaseStream.Length) + { + SaveManager.purchases.Add(binaryReader.ReadString()); + } + } + } + catch (NullReferenceException) + { + } + catch (Exception arg) + { + Debug.Log("Deleted corrupt secure file outer: " + arg); + SaveManager.purchaseFile.Delete(); + } + } + + private static void SaveSecureData() + { + SaveManager.purchaseFile.SaveData(new object[] + { + SaveManager.purchases + }); + } + + private static GameOptionsData LoadGameOptions(string filename) + { + string path = Path.Combine(Application.persistentDataPath, filename); + if (File.Exists(path)) + { + using (FileStream fileStream = File.OpenRead(path)) + { + using (BinaryReader binaryReader = new BinaryReader(fileStream)) + { + return GameOptionsData.Deserialize(binaryReader) ?? new GameOptionsData(); + } + } + } + return new GameOptionsData(); + } + + private static void SaveGameOptions(GameOptionsData data, string filename) + { + using (FileStream fileStream = new FileStream(Path.Combine(Application.persistentDataPath, filename), FileMode.Create, FileAccess.Write)) + { + using (BinaryWriter binaryWriter = new BinaryWriter(fileStream)) + { + data.Serialize(binaryWriter); + } + } + } + + private static void LoadAnnouncement() + { + if (SaveManager.loadedAnnounce) + { + return; + } + SaveManager.loadedAnnounce = true; + string path = Path.Combine(Application.persistentDataPath, "announcement"); + if (File.Exists(path)) + { + string[] array = File.ReadAllText(path).Split(new char[1]); + if (array.Length == 3) + { + Announcement announcement = default(Announcement); + SaveManager.TryGetUint(array, 0, out announcement.Id); + announcement.AnnounceText = array[1]; + SaveManager.TryGetInt(array, 2, out announcement.DateFetched); + SaveManager.lastAnnounce = announcement; + return; + } + SaveManager.lastAnnounce = default(Announcement); + } + } + + public static void SaveAnnouncement() + { + File.WriteAllText(Path.Combine(Application.persistentDataPath, "announcement"), string.Join("\0", new object[] + { + SaveManager.lastAnnounce.Id, + SaveManager.lastAnnounce.AnnounceText, + SaveManager.lastAnnounce.DateFetched + })); + } + + private static void LoadPlayerPrefs() + { + if (SaveManager.loaded) + { + return; + } + SaveManager.loaded = true; + string path = Path.Combine(Application.persistentDataPath, "playerPrefs"); + if (File.Exists(path)) + { + string[] array = File.ReadAllText(path).Split(new char[] + { + ',' + }); + SaveManager.lastPlayerName = array[0]; + if (array.Length > 1) + { + int.TryParse(array[1], out SaveManager.touchConfig); + } + if (array.Length <= 2 || !uint.TryParse(array[2], out SaveManager.colorConfig)) + { + SaveManager.colorConfig = (uint)((byte)(Palette.PlayerColors.RandomIdx<Color32>() << 16) | (byte)(Palette.PlayerColors.RandomIdx<Color32>() << 8) | (byte)Palette.PlayerColors.RandomIdx<Color32>()); + } + SaveManager.TryGetBool(array, 4, out SaveManager.sendName, false); + SaveManager.TryGetBool(array, 5, out SaveManager.sendTelemetry, false); + SaveManager.TryGetBool(array, 6, out SaveManager.sendDataScreen, false); + SaveManager.TryGetByte(array, 7, out SaveManager.showAdsScreen); + SaveManager.TryGetBool(array, 8, out SaveManager.showMinPlayerWarning, false); + SaveManager.TryGetBool(array, 9, out SaveManager.showOnlineHelp, false); + SaveManager.TryGetUint(array, 10, out SaveManager.lastHat); + SaveManager.TryGetByte(array, 11, out SaveManager.sfxVolume); + SaveManager.TryGetByte(array, 12, out SaveManager.musicVolume); + SaveManager.TryGetFloat(array, 13, out SaveManager.joyStickSize, 1f); + SaveManager.TryGetUint(array, 15, out SaveManager.lastSkin); + SaveManager.TryGetUint(array, 16, out SaveManager.lastPet); + SaveManager.TryGetBool(array, 17, out SaveManager.censorChat, true); + SaveManager.TryGetUint(array, 18, out SaveManager.lastLanguage); + } + } + + private static void SavePlayerPrefs() + { + SaveManager.LoadPlayerPrefs(); + File.WriteAllText(Path.Combine(Application.persistentDataPath, "playerPrefs"), string.Join(",", new object[] + { + SaveManager.lastPlayerName, + SaveManager.touchConfig, + SaveManager.colorConfig, + 1, + SaveManager.sendName, + SaveManager.sendTelemetry, + SaveManager.sendDataScreen, + SaveManager.showAdsScreen, + SaveManager.showMinPlayerWarning, + SaveManager.showOnlineHelp, + SaveManager.lastHat, + SaveManager.sfxVolume, + SaveManager.musicVolume, + SaveManager.joyStickSize.ToString(CultureInfo.InvariantCulture), + 0L, + SaveManager.lastSkin, + SaveManager.lastPet, + SaveManager.censorChat, + SaveManager.lastLanguage + })); + } + + private static void TryGetBool(string[] parts, int index, out bool value, bool @default = false) + { + value = @default; + if (parts.Length > index) + { + bool.TryParse(parts[index], out value); + } + } + + private static void TryGetByte(string[] parts, int index, out byte value) + { + value = 0; + if (parts.Length > index) + { + byte.TryParse(parts[index], out value); + } + } + + private static void TryGetFloat(string[] parts, int index, out float value, float @default = 0f) + { + value = @default; + if (parts.Length > index) + { + float.TryParse(parts[index], NumberStyles.Number, CultureInfo.InvariantCulture, out value); + } + } + + private static void TryGetInt(string[] parts, int index, out int value) + { + value = 0; + if (parts.Length > index) + { + int.TryParse(parts[index], out value); + } + } + + private static void TryGetUint(string[] parts, int index, out uint value) + { + value = 0U; + if (parts.Length > index) + { + uint.TryParse(parts[index], out value); + } + } + + private static void TryGetDateTicks(string[] parts, int index, out DateTime value) + { + value = DateTime.MinValue; + long ticks; + if (parts.Length > index && long.TryParse(parts[index], out ticks)) + { + value = new DateTime(ticks, DateTimeKind.Utc); + } + } +} diff --git a/Client/Assembly-CSharp/Scene0Controller.cs b/Client/Assembly-CSharp/Scene0Controller.cs new file mode 100644 index 0000000..abada07 --- /dev/null +++ b/Client/Assembly-CSharp/Scene0Controller.cs @@ -0,0 +1,79 @@ +using System; +using System.Collections; +using UnityEngine; + +public class Scene0Controller : SceneController +{ + public float Duration = 3f; + + public SpriteRenderer[] ExtraBoys; + + public AnimationCurve PopInCurve; + + public AnimationCurve PopOutCurve; + + public float OutDuration = 0.2f; + + public void OnEnable() + { + base.StartCoroutine(this.Run()); + } + + public void OnDisable() + { + for (int i = 0; i < this.ExtraBoys.Length; i++) + { + this.ExtraBoys[i].enabled = false; + } + } + + private IEnumerator Run() + { + int lastBoy = 0; + float start = Time.time; + for (;;) + { + float num = (Time.time - start) / this.Duration; + int num2 = Mathf.RoundToInt((Mathf.Cos(3.1415927f * num + 3.1415927f) + 1f) / 2f * (float)this.ExtraBoys.Length); + if (lastBoy < num2) + { + base.StartCoroutine(this.PopIn(this.ExtraBoys[lastBoy])); + lastBoy = num2; + } + else if (lastBoy > num2) + { + lastBoy = num2; + base.StartCoroutine(this.PopOut(this.ExtraBoys[lastBoy])); + } + yield return null; + } + yield break; + } + + private IEnumerator PopIn(SpriteRenderer boy) + { + boy.enabled = true; + for (float timer = 0f; timer < 0.2f; timer += Time.deltaTime) + { + float num = this.PopInCurve.Evaluate(timer / 0.2f); + boy.transform.localScale = new Vector3(num, num, num); + yield return null; + } + boy.transform.localScale = Vector3.one; + yield break; + } + + private IEnumerator PopOut(SpriteRenderer boy) + { + boy.enabled = true; + for (float timer = 0f; timer < this.OutDuration; timer += Time.deltaTime) + { + float num = this.PopOutCurve.Evaluate(timer / this.OutDuration); + boy.transform.localScale = new Vector3(num, num, num); + yield return null; + } + boy.transform.localScale = Vector3.one; + boy.enabled = false; + yield break; + } +} diff --git a/Client/Assembly-CSharp/Scene1Controller.cs b/Client/Assembly-CSharp/Scene1Controller.cs new file mode 100644 index 0000000..d1896ee --- /dev/null +++ b/Client/Assembly-CSharp/Scene1Controller.cs @@ -0,0 +1,94 @@ +using System; +using System.Collections; +using UnityEngine; + +public class Scene1Controller : SceneController +{ + public PlayerAnimator[] players; + + public DummyConsole[] Consoles; + + public Vector2[] WayPoints; + + public Camera backupCam; + + public void OnDrawGizmos() + { + for (int i = 0; i < this.WayPoints.Length; i++) + { + Vector2 v = this.WayPoints[i]; + Vector2 v2 = this.WayPoints[(i + 1) % this.WayPoints.Length]; + Gizmos.DrawLine(v, v2); + } + } + + public void OnEnable() + { + this.backupCam.cullingMask = 0; + base.StartCoroutine(this.RunPlayer(0)); + base.StartCoroutine(this.RunPlayer(1)); + } + + public void OnDisable() + { + this.backupCam.cullingMask = (int.MaxValue ^ LayerMask.GetMask(new string[] + { + "UI" + })); + } + + private IEnumerator RunPlayer(int idx) + { + PlayerAnimator myPlayer = this.players[idx]; + for (;;) + { + int num; + for (int i = 0; i < this.WayPoints.Length; i = num) + { + bool willInterrupt = i == 2 || i == 5; + yield return myPlayer.WalkPlayerTo(this.WayPoints[i], willInterrupt, 0.1f); + if (willInterrupt) + { + yield return this.DoUse(idx, (i == 2) ? 0 : 1); + } + num = i + 1; + } + } + yield break; + } + + private IEnumerator DoUse(int idx, int consoleid) + { + PlayerAnimator myPlayer = this.players[idx]; + yield return Scene1Controller.WaitForSeconds(0.2f); + if (idx == 0) + { + yield return myPlayer.finger.MoveTo(myPlayer.UseButton.transform.position, 0.75f); + } + else + { + yield return myPlayer.finger.MoveTo(this.Consoles[consoleid].transform.position, 0.75f); + } + yield return Scene1Controller.WaitForSeconds(0.2f); + yield return myPlayer.finger.DoClick(0.4f); + yield return Scene1Controller.WaitForSeconds(0.2f); + if (!(myPlayer.joystick is DemoKeyboardStick)) + { + yield return myPlayer.finger.MoveTo(myPlayer.joystick.transform.position, 0.75f); + } + else + { + yield return Scene1Controller.WaitForSeconds(0.75f); + } + yield break; + } + + public static IEnumerator WaitForSeconds(float duration) + { + for (float time = 0f; time < duration; time += Time.deltaTime) + { + yield return null; + } + yield break; + } +} diff --git a/Client/Assembly-CSharp/SceneChanger.cs b/Client/Assembly-CSharp/SceneChanger.cs new file mode 100644 index 0000000..0a58fa1 --- /dev/null +++ b/Client/Assembly-CSharp/SceneChanger.cs @@ -0,0 +1,27 @@ +using System; +using UnityEngine; +using UnityEngine.SceneManagement; +using UnityEngine.UI; + +public class SceneChanger : MonoBehaviour +{ + public string TargetScene; + + public Button.ButtonClickedEvent BeforeSceneChange; + + public void Click() + { + this.BeforeSceneChange.Invoke(); + SceneChanger.ChangeScene(this.TargetScene); + } + + public static void ChangeScene(string target) + { + SceneManager.LoadScene(target); + } + + public void ExitGame() + { + Application.Quit(); + } +} diff --git a/Client/Assembly-CSharp/SceneController.cs b/Client/Assembly-CSharp/SceneController.cs new file mode 100644 index 0000000..6129737 --- /dev/null +++ b/Client/Assembly-CSharp/SceneController.cs @@ -0,0 +1,6 @@ +using System; +using UnityEngine; + +public class SceneController : MonoBehaviour +{ +} diff --git a/Client/Assembly-CSharp/ScreenJoystick.cs b/Client/Assembly-CSharp/ScreenJoystick.cs new file mode 100644 index 0000000..f787ea3 --- /dev/null +++ b/Client/Assembly-CSharp/ScreenJoystick.cs @@ -0,0 +1,54 @@ +using System; +using UnityEngine; + +public class ScreenJoystick : MonoBehaviour, IVirtualJoystick +{ + public Vector2 Delta { get; private set; } + + private Collider2D[] hitBuffer = new Collider2D[20]; + + private Controller myController = new Controller(); + + private int touchId = -1; + + private void FixedUpdate() + { + this.myController.Update(); + if (this.touchId <= -1) + { + for (int i = 0; i < this.myController.Touches.Length; i++) + { + Controller.TouchState touchState = this.myController.Touches[i]; + if (touchState.TouchStart) + { + bool flag = false; + int num = Physics2D.OverlapPointNonAlloc(touchState.Position, this.hitBuffer, Constants.NotShipMask); + for (int j = 0; j < num; j++) + { + Collider2D collider2D = this.hitBuffer[j]; + if (collider2D.GetComponent<ButtonBehavior>() || collider2D.GetComponent<PassiveButton>()) + { + flag = true; + break; + } + } + if (!flag) + { + this.touchId = i; + return; + } + } + } + return; + } + Controller.TouchState touchState2 = this.myController.Touches[this.touchId]; + if (touchState2.IsDown) + { + Vector2 b = Camera.main.ViewportToWorldPoint(new Vector2(0.5f, 0.5f)); + this.Delta = (touchState2.Position - b).normalized; + return; + } + this.touchId = -1; + this.Delta = Vector2.zero; + } +} diff --git a/Client/Assembly-CSharp/Scroller.cs b/Client/Assembly-CSharp/Scroller.cs new file mode 100644 index 0000000..e38a9cb --- /dev/null +++ b/Client/Assembly-CSharp/Scroller.cs @@ -0,0 +1,85 @@ +using System; +using UnityEngine; + +public class Scroller : MonoBehaviour +{ + public bool AtTop + { + get + { + return this.Inner.localPosition.y <= this.YBounds.min + 0.25f; + } + } + + public bool AtBottom + { + get + { + return this.Inner.localPosition.y >= this.YBounds.max - 0.25f; + } + } + + public Transform Inner; + + public Collider2D HitBox; + + private Controller myController = new Controller(); + + private Vector3 origin; + + public bool allowX; + + public FloatRange XBounds = new FloatRange(-10f, 10f); + + public bool allowY; + + public FloatRange YBounds = new FloatRange(-10f, 10f); + + public float YBoundPerItem; + + public void FixedUpdate() + { + if (!this.Inner) + { + return; + } + Vector2 mouseScrollDelta = Input.mouseScrollDelta; + mouseScrollDelta.y = -mouseScrollDelta.y; + this.DoScroll(this.Inner.transform.localPosition, mouseScrollDelta); + this.myController.Update(); + DragState dragState = this.myController.CheckDrag(this.HitBox, false); + if (dragState == DragState.TouchStart) + { + this.origin = this.Inner.transform.localPosition; + return; + } + if (dragState != DragState.Dragging) + { + return; + } + Vector2 del = this.myController.DragPosition - this.myController.DragStartPosition; + this.DoScroll(this.origin, del); + } + + private void DoScroll(Vector3 origin, Vector2 del) + { + if (del.magnitude < 0.05f) + { + return; + } + if (!this.allowX) + { + del.x = 0f; + } + if (!this.allowY) + { + del.y = 0f; + } + Vector3 vector = origin + del; + vector.x = this.XBounds.Clamp(vector.x); + int childCount = this.Inner.transform.childCount; + float max = Mathf.Max(this.YBounds.min, this.YBounds.max + this.YBoundPerItem * (float)childCount); + vector.y = Mathf.Clamp(vector.y, this.YBounds.min, max); + this.Inner.transform.localPosition = vector; + } +} diff --git a/Client/Assembly-CSharp/SecurityCameraSystemType.cs b/Client/Assembly-CSharp/SecurityCameraSystemType.cs new file mode 100644 index 0000000..f7a90ce --- /dev/null +++ b/Client/Assembly-CSharp/SecurityCameraSystemType.cs @@ -0,0 +1,78 @@ +using System; +using System.Collections.Generic; +using Hazel; + +//监控器 +public class SecurityCameraSystemType : ISystemType +{ + public bool InUse + { + get + { + return this.PlayersUsing.Count > 0; + } + } + + public const byte IncrementOp = 1; + + public const byte DecrementOp = 2; + + private HashSet<byte> PlayersUsing = new HashSet<byte>(); + + public bool Detoriorate(float deltaTime) + { + return false; + } + + public void RepairDamage(PlayerControl player, byte amount) + { + if (amount == 1) + { + this.PlayersUsing.Add(player.PlayerId); + } + else + { + this.PlayersUsing.Remove(player.PlayerId); + } + this.UpdateCameras(); + } + + private void UpdateCameras() + { + for (int i = 0; i < ShipStatus.Instance.AllRooms.Length; i++) + { + ShipRoom shipRoom = ShipStatus.Instance.AllRooms[i]; + if (shipRoom.survCamera) + { + if (this.InUse) + { + shipRoom.survCamera.Image.Play(shipRoom.survCamera.OnAnim, 1f); + } + else + { + shipRoom.survCamera.Image.Play(shipRoom.survCamera.OffAnim, 1f); + } + } + } + } + + public void Serialize(MessageWriter writer, bool initialState) + { + writer.WritePacked(this.PlayersUsing.Count); + foreach (byte value in this.PlayersUsing) + { + writer.Write(value); + } + } + + public void Deserialize(MessageReader reader, bool initialState) + { + this.PlayersUsing.Clear(); + int num = reader.ReadPackedInt32(); + for (int i = 0; i < num; i++) + { + this.PlayersUsing.Add(reader.ReadByte()); + } + this.UpdateCameras(); + } +} diff --git a/Client/Assembly-CSharp/ServerInfo.cs b/Client/Assembly-CSharp/ServerInfo.cs new file mode 100644 index 0000000..f952619 --- /dev/null +++ b/Client/Assembly-CSharp/ServerInfo.cs @@ -0,0 +1,43 @@ +using System; +using System.IO; +using System.Net; + +public class ServerInfo +{ + public string Name = "Custom"; + + public string Ip = "0.0.0.0"; + + public bool Default; + + public void Serialize(BinaryWriter writer) + { + writer.Write(this.Name); + writer.Write(this.Ip); + writer.Write(this.Default); + } + + public static ServerInfo Deserialize(BinaryReader reader) + { + ServerInfo serverInfo = new ServerInfo(); + serverInfo.Name = reader.ReadString(); + serverInfo.Ip = reader.ReadString(); + IPAddress ipaddress; + if (!IPAddress.TryParse(serverInfo.Ip, out ipaddress)) + { + return null; + } + serverInfo.Default = reader.ReadBoolean(); + return serverInfo; + } + + internal static ServerInfo Deserialize(string[] parts) + { + return new ServerInfo + { + Name = parts[0], + Ip = parts[1], + Default = bool.Parse(parts[2]) + }; + } +} diff --git a/Client/Assembly-CSharp/ServerManager.cs b/Client/Assembly-CSharp/ServerManager.cs new file mode 100644 index 0000000..0b28183 --- /dev/null +++ b/Client/Assembly-CSharp/ServerManager.cs @@ -0,0 +1,59 @@ +using System; +using System.Collections; +using System.IO; +using UnityEngine; + +public class ServerManager : DestroyableSingleton<ServerManager> +{ + public string OnlineNetAddress + { + get + { + return this.LastServer.Ip; + } + } + + public const string DefaultOnlineServer = "50.116.1.42"; + + public static readonly ServerInfo DefaultServer = new ServerInfo + { + Name = "Primary", + Ip = "50.116.1.42", + Default = true + }; + + public ServerInfo[] availableServers; + + public ServerInfo LastServer = ServerManager.DefaultServer; + + private string serverInfoFile; + + private ServerManager.UpdateState state; + + private enum UpdateState + { + Connecting, + Failed, + Success + } + + public void Start() + { + this.serverInfoFile = Path.Combine(Application.persistentDataPath, "serverInfo.dat"); + this.LastServer = ServerManager.DefaultServer; + this.availableServers = new ServerInfo[] + { + this.LastServer + }; + this.state = ServerManager.UpdateState.Success; + } + + public IEnumerator WaitForServers() + { + while (this.state == ServerManager.UpdateState.Connecting) + { + yield return null; + } + yield break; + } +} diff --git a/Client/Assembly-CSharp/ServerSelectUi.cs b/Client/Assembly-CSharp/ServerSelectUi.cs new file mode 100644 index 0000000..671ff7c --- /dev/null +++ b/Client/Assembly-CSharp/ServerSelectUi.cs @@ -0,0 +1,59 @@ +using System; +using System.Collections.Generic; +using UnityEngine; + +public class ServerSelectUi : MonoBehaviour +{ + public ServerSelector ServerButtonPrefab; + + public Vector3 ScrollStartArea; + + public Scroller Slider; + + public ServerSelector CustomServer; + + private List<ServerSelector> myButtons = new List<ServerSelector>(); + + public void Start() + { + ServerInfo[] availableServers = DestroyableSingleton<ServerManager>.Instance.availableServers; + Vector3 scrollStartArea = this.ScrollStartArea; + for (int i = 0; i < availableServers.Length; i++) + { + if (!(availableServers[i].Name == "Custom")) + { + ServerSelector serverSelector = UnityEngine.Object.Instantiate<ServerSelector>(this.ServerButtonPrefab, this.Slider.Inner); + serverSelector.name = availableServers[i].Name; + this.myButtons.Add(serverSelector); + serverSelector.transform.localPosition = scrollStartArea; + serverSelector.Parent = this; + serverSelector.MyServer = availableServers[i]; + if (availableServers[i].Default) + { + serverSelector.Select(); + } + scrollStartArea.y -= 0.7f; + } + } + this.CustomServer.Parent = this; + this.myButtons.Add(this.CustomServer); + if (DestroyableSingleton<ServerManager>.Instance.LastServer.Name == "Custom") + { + this.CustomServer.Select(); + } + this.Slider.YBounds.max = this.ScrollStartArea.y; + this.Slider.YBounds.min = scrollStartArea.y; + } + + internal void SelectServer(ServerSelector selected) + { + for (int i = 0; i < this.myButtons.Count; i++) + { + ServerSelector serverSelector = this.myButtons[i]; + if (!serverSelector.MyServer.Default) + { + serverSelector.Unselect(); + } + } + } +} diff --git a/Client/Assembly-CSharp/ServerSelector.cs b/Client/Assembly-CSharp/ServerSelector.cs new file mode 100644 index 0000000..b29aa30 --- /dev/null +++ b/Client/Assembly-CSharp/ServerSelector.cs @@ -0,0 +1,53 @@ +using System; +using System.Net; +using UnityEngine; +using UnityEngine.Events; + +public class ServerSelector : MonoBehaviour +{ + public ServerSelectUi Parent { get; set; } + + public ServerInfo MyServer = new ServerInfo(); + + public TextRenderer Text; + + public ButtonRolloverHandler Background; + + public TextBox ipInput; + + public void Start() + { + if (this.ipInput) + { + this.ipInput.SetText(this.MyServer.Ip, ""); + this.ipInput.OnChange.AddListener(new UnityAction(this.OnIpChange)); + return; + } + this.Text.Text = this.MyServer.Name; + } + + private void OnIpChange() + { + IPAddress ipaddress; + if (!IPAddress.TryParse(this.ipInput.text, out ipaddress)) + { + return; + } + this.MyServer.Name = "Custom"; + this.MyServer.Ip = this.ipInput.text; + this.Select(); + } + + public void Select() + { + this.Background.OutColor = Color.green; + this.Background.DoMouseOut(); + this.Parent.SelectServer(this); + } + + internal void Unselect() + { + this.Background.OutColor = Color.white; + this.Background.DoMouseOut(); + } +} diff --git a/Client/Assembly-CSharp/SettingsMode.cs b/Client/Assembly-CSharp/SettingsMode.cs new file mode 100644 index 0000000..48c138b --- /dev/null +++ b/Client/Assembly-CSharp/SettingsMode.cs @@ -0,0 +1,7 @@ +using System; + +public enum SettingsMode +{ + Host, + Search +} diff --git a/Client/Assembly-CSharp/ShadowCamera.cs b/Client/Assembly-CSharp/ShadowCamera.cs new file mode 100644 index 0000000..468d259 --- /dev/null +++ b/Client/Assembly-CSharp/ShadowCamera.cs @@ -0,0 +1,17 @@ +using System; +using UnityEngine; + +public class ShadowCamera : MonoBehaviour +{ + public Shader Shadozer; + + public void OnEnable() + { + base.GetComponent<Camera>().SetReplacementShader(this.Shadozer, "RenderType"); + } + + public void OnDisable() + { + base.GetComponent<Camera>().ResetReplacementShader(); + } +} diff --git a/Client/Assembly-CSharp/ShhhBehaviour.cs b/Client/Assembly-CSharp/ShhhBehaviour.cs new file mode 100644 index 0000000..6164c57 --- /dev/null +++ b/Client/Assembly-CSharp/ShhhBehaviour.cs @@ -0,0 +1,135 @@ +using System; +using System.Collections; +using UnityEngine; + +public class ShhhBehaviour : MonoBehaviour +{ + public SpriteRenderer Background; + + public SpriteRenderer Body; + + public SpriteRenderer Hand; + + public SpriteRenderer TextImage; + + public float RotateSpeed = 15f; + + public Vector2Range HandTarget; + + public AnimationCurve PositionEasing; + + public FloatRange HandRotate; + + public AnimationCurve RotationEasing; + + public Vector2Range TextTarget; + + public AnimationCurve TextEasing; + + public float Duration = 0.5f; + + public float Delay = 0.1f; + + public float TextDuration = 0.5f; + + public float PulseDuration = 0.1f; + + public float PulseSize = 0.1f; + + public float HoldDuration = 2f; + + public bool Autoplay; + + public void OnEnable() + { + if (this.Autoplay) + { + Vector3 localScale = default(Vector3); + this.UpdateHand(ref localScale, 1f); + this.UpdateText(ref localScale, 1f); + localScale.Set(1f, 1f, 1f); + this.Body.transform.localScale = localScale; + this.TextImage.color = Color.white; + } + } + + public IEnumerator PlayAnimation() + { + base.StartCoroutine(this.AnimateHand()); + yield return this.AnimateText(); + yield return ShhhBehaviour.WaitWithInterrupt(this.HoldDuration); + yield break; + } + + public void Update() + { + this.Background.transform.Rotate(0f, 0f, Time.deltaTime * this.RotateSpeed); + } + + private IEnumerator AnimateText() + { + this.TextImage.color = Palette.ClearWhite; + for (float t = 0f; t < this.Delay; t += Time.deltaTime) + { + yield return null; + } + Vector3 vec = default(Vector3); + for (float t = 0f; t < this.PulseDuration; t += Time.deltaTime) + { + float num = t / this.PulseDuration; + float num2 = 1f + Mathf.Sin(3.1415927f * num) * this.PulseSize; + vec.Set(num2, num2, 1f); + this.Body.transform.localScale = vec; + this.TextImage.color = Color.Lerp(Palette.ClearWhite, Palette.White, num * 2f); + yield return null; + } + vec.Set(1f, 1f, 1f); + this.Body.transform.localScale = vec; + this.TextImage.color = Color.white; + yield break; + } + + private IEnumerator AnimateHand() + { + this.Hand.transform.localPosition = this.HandTarget.min; + Vector3 vec = default(Vector3); + for (float t = 0f; t < this.Duration; t += Time.deltaTime) + { + float p = t / this.Duration; + this.UpdateHand(ref vec, p); + yield return null; + } + this.UpdateHand(ref vec, 1f); + yield break; + } + + private void UpdateHand(ref Vector3 vec, float p) + { + this.HandTarget.LerpUnclamped(ref vec, this.PositionEasing.Evaluate(p), -1f); + this.Hand.transform.localPosition = vec; + vec.Set(0f, 0f, this.HandRotate.LerpUnclamped(this.RotationEasing.Evaluate(p))); + this.Hand.transform.eulerAngles = vec; + } + + private void UpdateText(ref Vector3 vec, float p) + { + this.TextTarget.LerpUnclamped(ref vec, p, -2f); + this.TextImage.transform.localPosition = vec; + } + + public static IEnumerator WaitWithInterrupt(float duration) + { + float timer = 0f; + while (timer < duration && !ShhhBehaviour.CheckForInterrupt()) + { + yield return null; + timer += Time.deltaTime; + } + yield break; + } + + public static bool CheckForInterrupt() + { + return Input.anyKeyDown; + } +} diff --git a/Client/Assembly-CSharp/ShieldMinigame.cs b/Client/Assembly-CSharp/ShieldMinigame.cs new file mode 100644 index 0000000..553c5fa --- /dev/null +++ b/Client/Assembly-CSharp/ShieldMinigame.cs @@ -0,0 +1,84 @@ +using System; +using UnityEngine; + +public class ShieldMinigame : Minigame +{ + public Color OnColor = Color.white; + + public Color OffColor = Color.red; + + public SpriteRenderer[] Shields; + + public SpriteRenderer Gauge; + + private byte shields; + + public AudioClip ShieldOnSound; + + public AudioClip ShieldOffSound; + + public override void Begin(PlayerTask task) + { + base.Begin(task); + this.shields = this.MyNormTask.Data[0]; + this.UpdateButtons(); + } + + public void ToggleShield(int i) + { + if (!this.MyNormTask.IsComplete) + { + byte b = (byte)(1 << i); + this.shields ^= b; + this.MyNormTask.Data[0] = this.shields; + if ((this.shields & b) != 0) + { + if (Constants.ShouldPlaySfx()) + { + SoundManager.Instance.PlaySound(this.ShieldOnSound, false, 1f); + } + } + else if (Constants.ShouldPlaySfx()) + { + SoundManager.Instance.PlaySound(this.ShieldOffSound, false, 1f); + } + if (this.shields == 127) + { + this.MyNormTask.NextStep(); + base.StartCoroutine(base.CoStartClose(0.75f)); + if (!ShipStatus.Instance.ShieldsImages[0].IsPlaying(null)) + { + ShipStatus.Instance.StartShields(); + PlayerControl.LocalPlayer.RpcPlayAnimation(1); + } + } + } + } + + public void FixedUpdate() + { + this.UpdateButtons(); + } + + private void UpdateButtons() + { + int num = 0; + for (int i = 0; i < this.Shields.Length; i++) + { + bool flag = ((int)this.shields & 1 << i) == 0; + if (!flag) + { + num++; + } + this.Shields[i].color = (flag ? this.OffColor : this.OnColor); + } + if (this.shields == 127) + { + this.Gauge.transform.Rotate(0f, 0f, Time.fixedDeltaTime * 45f); + this.Gauge.color = new Color(1f, 1f, 1f, 1f); + return; + } + float num2 = Mathf.Lerp(0.1f, 0.5f, (float)num / 6f); + this.Gauge.color = new Color(1f, num2, num2, 1f); + } +} diff --git a/Client/Assembly-CSharp/ShipRoom.cs b/Client/Assembly-CSharp/ShipRoom.cs new file mode 100644 index 0000000..8dae7a6 --- /dev/null +++ b/Client/Assembly-CSharp/ShipRoom.cs @@ -0,0 +1,15 @@ +using System; +using UnityEngine; + +public class ShipRoom : MonoBehaviour +{ + public SystemTypes RoomId; + + public SurvCamera survCamera; + + public Collider2D roomArea; + + public AudioClip AmbientSound; + + public SoundGroup FootStepSounds; +} diff --git a/Client/Assembly-CSharp/ShipStatus.cs b/Client/Assembly-CSharp/ShipStatus.cs new file mode 100644 index 0000000..81d8b4a --- /dev/null +++ b/Client/Assembly-CSharp/ShipStatus.cs @@ -0,0 +1,738 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using Assets.CoreScripts; +using Hazel; +using InnerNet; +using PowerTools; +using UnityEngine; + +//场景中的物件,包含门的开启等,在这里同步 +public class ShipStatus : InnerNetObject +{ + public ShipRoom[] AllRooms { get; private set; } + + public Vent[] AllVents { get; private set; } + + public static ShipStatus Instance; + + public Color CameraColor = Color.black; + + public float MaxLightRadius = 100f; + + public float MinLightRadius; + + public float MapScale = 4.4f; + + public Vector2 MapOffset = new Vector2(0.54f, 1.25f); + + public MapBehaviour MapPrefab; + + public Transform SpawnCenter; + + public float SpawnRadius = 1.55f; + + public AudioClip shipHum; + + public NormalPlayerTask[] CommonTasks; + + public NormalPlayerTask[] LongTasks; + + public NormalPlayerTask[] NormalTasks; + + public PlayerTask[] SpecialTasks; + + public AutoOpenDoor[] AllDoors; + + public global::Console[] AllConsoles; + + //c 场景中的门、反应堆等物件的状态 + public Dictionary<SystemTypes, ISystemType> Systems; + + public AnimationClip[] WeaponFires; + + public SpriteAnim WeaponsImage; + + public AnimationClip HatchActive; + + public SpriteAnim Hatch; + + public ParticleSystem HatchParticles; + + public AnimationClip ShieldsActive; + + public SpriteAnim[] ShieldsImages; + + public SpriteRenderer ShieldBorder; + + public Sprite ShieldBorderOn; + + public SpriteRenderer MedScanner; + + private int WeaponFireIdx; + + public float Timer; + + public float EmergencyCooldown; + + private RaycastHit2D[] volumeBuffer = new RaycastHit2D[5]; + + public class SystemTypeComparer : IEqualityComparer<SystemTypes> + { + public static readonly ShipStatus.SystemTypeComparer Instance = new ShipStatus.SystemTypeComparer(); + + public bool Equals(SystemTypes x, SystemTypes y) + { + return x == y; + } + + public int GetHashCode(SystemTypes obj) + { + return (int)obj; + } + } + + private enum RpcCalls + { + CloseDoorsOfType, + RepairSystem + } + + public ShipStatus() + { + //c 所有的systems + this.Systems = new Dictionary<SystemTypes, ISystemType>(ShipStatus.SystemTypeComparer.Instance) + { + { + SystemTypes.Electrical, + new SwitchSystem() + }, + { + SystemTypes.MedBay, + new MedScanSystem() + }, + { + SystemTypes.Reactor, + new ReactorSystemType() + }, + { + SystemTypes.LifeSupp, + new LifeSuppSystemType() + }, + { + SystemTypes.Security, + new SecurityCameraSystemType() + }, + { + SystemTypes.Comms, + new HudOverrideSystemType() + }, + { + SystemTypes.Doors, + new DoorsSystemType() + } + }; + this.Systems.Add(SystemTypes.Sabotage, new SabotageSystemType(new IActivatable[] + { + (IActivatable)this.Systems[SystemTypes.Comms], + (IActivatable)this.Systems[SystemTypes.Reactor], + (IActivatable)this.Systems[SystemTypes.LifeSupp], + (IActivatable)this.Systems[SystemTypes.Electrical] + })); + } + + private void Awake() + { + this.AllRooms = base.GetComponentsInChildren<ShipRoom>(); + this.AllConsoles = base.GetComponentsInChildren<global::Console>(); + this.AllVents = base.GetComponentsInChildren<Vent>(); + this.AssignTaskIndexes(); + ShipStatus.Instance = this; + } + + public void Start() + { + Camera.main.backgroundColor = this.CameraColor; + if (DestroyableSingleton<HudManager>.InstanceExists) + { + DestroyableSingleton<HudManager>.Instance.Chat.ForceClosed(); + DestroyableSingleton<HudManager>.Instance.Chat.SetVisible(false); + DestroyableSingleton<HudManager>.Instance.GameSettings.gameObject.SetActive(false); + } + DeconSystem componentInChildren = base.GetComponentInChildren<DeconSystem>(); + if (componentInChildren) + { + this.Systems.Add(SystemTypes.Decontamination, componentInChildren); + } + SoundManager.Instance.StopAllSound(); + AudioSource audioSource = SoundManager.Instance.PlaySound(this.shipHum, true, 1f); + if (audioSource) + { + audioSource.pitch = 0.8f; + } + if (Constants.ShouldPlaySfx()) + { + for (int i = 0; i < this.AllRooms.Length; i++) + { + ShipRoom room = this.AllRooms[i]; + if (room.AmbientSound) + { + SoundManager.Instance.PlayDynamicSound("Amb " + room.RoomId, room.AmbientSound, true, delegate(AudioSource player, float dt) + { + this.GetAmbientSoundVolume(room, player, dt); + }, false); + } + } + } + } + + public override void OnDestroy() + { + SoundManager.Instance.StopAllSound(); + base.OnDestroy(); + } + + public Vector2 GetSpawnLocation(int playerId, int numPlayer) + { + Vector2 vector = Vector2.up; + vector = vector.Rotate((float)(playerId - 1) * (360f / (float)numPlayer)); + vector *= this.SpawnRadius; + return this.SpawnCenter.position + vector + new Vector2(0f, 0.3636f); + } + + public void StartShields() + { + for (int i = 0; i < this.ShieldsImages.Length; i++) + { + this.ShieldsImages[i].Play(this.ShieldsActive, 1f); + } + this.ShieldBorder.sprite = this.ShieldBorderOn; + } + + public void FireWeapon() + { + if (!this.WeaponsImage.IsPlaying(null)) + { + this.WeaponsImage.Play(this.WeaponFires[this.WeaponFireIdx], 1f); + this.WeaponFireIdx = (this.WeaponFireIdx + 1) % 2; + } + } + + public NormalPlayerTask GetTaskById(byte idx) + { + NormalPlayerTask result; + if ((result = this.CommonTasks.FirstOrDefault((NormalPlayerTask t) => t.Index == (int)idx)) == null) + { + result = (this.LongTasks.FirstOrDefault((NormalPlayerTask t) => t.Index == (int)idx) ?? this.NormalTasks.FirstOrDefault((NormalPlayerTask t) => t.Index == (int)idx)); + } + return result; + } + + public void OpenHatch() + { + if (!this.Hatch.IsPlaying(null)) + { + this.Hatch.Play(this.HatchActive, 1f); + this.HatchParticles.Play(); + } + } + + public void CloseDoorsOfType(SystemTypes room) + { + (this.Systems[SystemTypes.Doors] as DoorsSystemType).CloseDoorsOfType(room); + base.SetDirtyBit(65536U); + } + + public void RepairSystem(SystemTypes systemType, PlayerControl player, byte amount) + { + this.Systems[systemType].RepairDamage(player, amount); + base.SetDirtyBit(1U << (int)systemType); + } + + internal void SelectInfected() + { + List<GameData.PlayerInfo> list = (from pcd in GameData.Instance.AllPlayers + where !pcd.Disconnected + select pcd into pc + where !pc.IsDead + select pc).ToList<GameData.PlayerInfo>(); + int adjustedNumImpostors = PlayerControl.GameOptions.GetAdjustedNumImpostors(GameData.Instance.PlayerCount); + list.RemoveDupes<GameData.PlayerInfo>(); + GameData.PlayerInfo[] array = new GameData.PlayerInfo[Mathf.Min(list.Count, adjustedNumImpostors)]; + for (int i = 0; i < array.Length; i++) + { + int index = HashRandom.FastNext(list.Count); + array[i] = list[index]; + list.RemoveAt(index); + } + foreach (GameData.PlayerInfo playerInfo in array) + { + DestroyableSingleton<Telemetry>.Instance.SelectInfected((int)playerInfo.ColorId, playerInfo.HatId); + } + PlayerControl.LocalPlayer.RpcSetInfected(array); + } + + private void AssignTaskIndexes() + { + int num = 0; + for (int i = 0; i < this.CommonTasks.Length; i++) + { + this.CommonTasks[i].Index = num++; + } + for (int j = 0; j < this.LongTasks.Length; j++) + { + this.LongTasks[j].Index = num++; + } + for (int k = 0; k < this.NormalTasks.Length; k++) + { + this.NormalTasks[k].Index = num++; + } + } + + public void Begin() + { + this.AssignTaskIndexes(); + GameOptionsData gameOptions = PlayerControl.GameOptions; + List<GameData.PlayerInfo> allPlayers = GameData.Instance.AllPlayers; + HashSet<TaskTypes> hashSet = new HashSet<TaskTypes>(); + List<byte> list = new List<byte>(10); + List<NormalPlayerTask> list2 = this.CommonTasks.ToList<NormalPlayerTask>(); + list2.Shuffle<NormalPlayerTask>(); + int num = 0; + this.AddTasksFromList(ref num, gameOptions.NumCommonTasks, list, hashSet, list2); + for (int i = 0; i < gameOptions.NumCommonTasks; i++) + { + if (list2.Count == 0) + { + Debug.LogWarning("Not enough common tasks"); + break; + } + int index = list2.RandomIdx<NormalPlayerTask>(); + list.Add((byte)list2[index].Index); + list2.RemoveAt(index); + } + List<NormalPlayerTask> list3 = this.LongTasks.ToList<NormalPlayerTask>(); + list3.Shuffle<NormalPlayerTask>(); + List<NormalPlayerTask> list4 = this.NormalTasks.ToList<NormalPlayerTask>(); + list4.Shuffle<NormalPlayerTask>(); + int num2 = 0; + int num3 = 0; + int count = gameOptions.NumShortTasks; + if (gameOptions.NumCommonTasks + gameOptions.NumLongTasks + gameOptions.NumShortTasks == 0) + { + count = 1; + } + byte b = 0; + while ((int)b < allPlayers.Count) + { + hashSet.Clear(); + list.RemoveRange(gameOptions.NumCommonTasks, list.Count - gameOptions.NumCommonTasks); + this.AddTasksFromList(ref num2, gameOptions.NumLongTasks, list, hashSet, list3); + this.AddTasksFromList(ref num3, count, list, hashSet, list4); + GameData.PlayerInfo playerInfo = allPlayers[(int)b]; + if (playerInfo.Object && !playerInfo.Object.GetComponent<DummyBehaviour>().enabled) + { + byte[] taskTypeIds = list.ToArray(); + GameData.Instance.RpcSetTasks(playerInfo.PlayerId, taskTypeIds); + } + b += 1; + } + base.enabled = true; + } + + private void AddTasksFromList(ref int start, int count, List<byte> tasks, HashSet<TaskTypes> usedTaskTypes, List<NormalPlayerTask> unusedTasks) + { + int num = 0; + int num2 = 0; + Func<NormalPlayerTask, bool> <>9__0; + while (num2 < count && num++ != 1000) + { + if (start >= unusedTasks.Count) + { + start = 0; + unusedTasks.Shuffle<NormalPlayerTask>(); + Func<NormalPlayerTask, bool> predicate; + if ((predicate = <>9__0) == null) + { + predicate = (<>9__0 = ((NormalPlayerTask t) => usedTaskTypes.Contains(t.TaskType))); + } + if (unusedTasks.All(predicate)) + { + Debug.Log("Not enough task types"); + usedTaskTypes.Clear(); + } + } + int num3 = start; + start = num3 + 1; + NormalPlayerTask normalPlayerTask = unusedTasks[num3]; + if (!usedTaskTypes.Add(normalPlayerTask.TaskType)) + { + num2--; + } + else + { + tasks.Add((byte)normalPlayerTask.Index); + } + num2++; + } + } + + public void FixedUpdate() + { + if (!AmongUsClient.Instance) + { + return; + } + this.Timer += Time.fixedDeltaTime; + this.EmergencyCooldown -= Time.fixedDeltaTime; + if (GameData.Instance) + { + GameData.Instance.RecomputeTaskCounts(); + } + if (AmongUsClient.Instance.AmHost) + { + this.CheckEndCriteria(); + } + if (AmongUsClient.Instance.AmClient) + { + for (int i = 0; i < SystemTypeHelpers.AllTypes.Length; i++) + { + SystemTypes systemTypes = SystemTypeHelpers.AllTypes[i]; + ISystemType systemType; + if (this.Systems.TryGetValue(systemTypes, out systemType) && systemType.Detoriorate(Time.fixedDeltaTime)) + { + base.SetDirtyBit(1U << (int)systemTypes); + } + } + } + } + + private void GetAmbientSoundVolume(ShipRoom room, AudioSource player, float dt) + { + if (!PlayerControl.LocalPlayer) + { + player.volume = 0f; + return; + } + Vector2 vector = room.transform.position; + Vector2 truePosition = PlayerControl.LocalPlayer.GetTruePosition(); + float num = Vector2.Distance(vector, truePosition); + if (num > 8f) + { + player.volume = 0f; + return; + } + Vector2 direction = truePosition - vector; + int num2 = Physics2D.RaycastNonAlloc(vector, direction, this.volumeBuffer, num, Constants.ShipOnlyMask); + float num3 = 1f - num / 8f - (float)num2 * 0.25f; + player.volume = Mathf.Lerp(player.volume, num3 * 0.7f, dt); + } + + public float CalculateLightRadius(GameData.PlayerInfo player) + { + if (player.IsDead) + { + return this.MaxLightRadius; + } + SwitchSystem switchSystem = (SwitchSystem)this.Systems[SystemTypes.Electrical]; + if (player.IsImpostor) + { + return this.MaxLightRadius * PlayerControl.GameOptions.ImpostorLightMod; + } + float t = (float)switchSystem.Value / 255f; + return Mathf.Lerp(this.MinLightRadius, this.MaxLightRadius, t) * PlayerControl.GameOptions.CrewLightMod; + } + + //c 序列化所有物件的状态 + public override bool Serialize(MessageWriter writer, bool initialState) + { + if (initialState) + { + (this.Systems[SystemTypes.Doors] as DoorsSystemType).SetDoors(this.AllDoors); + short num = 0; + while ((int)num < SystemTypeHelpers.AllTypes.Length) + { + SystemTypes key = SystemTypeHelpers.AllTypes[(int)num]; + ISystemType systemType; + if (this.Systems.TryGetValue(key, out systemType)) + { + systemType.Serialize(writer, true); + } + num += 1; + } + return true; + } + if (this.DirtyBits != 0U) + { + writer.WritePacked(this.DirtyBits); + short num2 = 0; + while ((int)num2 < SystemTypeHelpers.AllTypes.Length) + { + SystemTypes systemTypes = SystemTypeHelpers.AllTypes[(int)num2]; + ISystemType systemType2; + if (((ulong)this.DirtyBits & (ulong)(1L << (int)(systemTypes & (SystemTypes)31))) != 0UL && this.Systems.TryGetValue(systemTypes, out systemType2)) + { + systemType2.Serialize(writer, false); + } + num2 += 1; + } + this.DirtyBits = 0U; + return true; + } + return false; + } + + public override void Deserialize(MessageReader reader, bool initialState) + { + if (initialState) + { + (this.Systems[SystemTypes.Doors] as DoorsSystemType).SetDoors(this.AllDoors); + short num = 0; + while ((int)num < SystemTypeHelpers.AllTypes.Length) + { + SystemTypes key = (SystemTypes)num; + ISystemType systemType; + if (this.Systems.TryGetValue(key, out systemType)) + { + systemType.Deserialize(reader, true); + } + num += 1; + } + return; + } + uint num2 = reader.ReadPackedUInt32(); + short num3 = 0; + while ((int)num3 < SystemTypeHelpers.AllTypes.Length) + { + SystemTypes systemTypes = SystemTypeHelpers.AllTypes[(int)num3]; + ISystemType systemType2; + if (((ulong)num2 & (ulong)(1L << (int)(systemTypes & (SystemTypes)31))) != 0UL && this.Systems.TryGetValue(systemTypes, out systemType2)) + { + systemType2.Deserialize(reader, false); + } + num3 += 1; + } + } + + private void CheckEndCriteria() + { + if (!GameData.Instance) + { + return; + } + LifeSuppSystemType lifeSuppSystemType = (LifeSuppSystemType)this.Systems[SystemTypes.LifeSupp]; + if (lifeSuppSystemType.Countdown < 0f) + { + this.EndGameForSabotage(); + lifeSuppSystemType.Countdown = 10000f; + } + ReactorSystemType reactorSystemType = (ReactorSystemType)this.Systems[SystemTypes.Reactor]; + if (reactorSystemType.Countdown < 0f) + { + this.EndGameForSabotage(); + reactorSystemType.Countdown = 10000f; + } + int num = 0; + int num2 = 0; + int num3 = 0; + for (int i = 0; i < GameData.Instance.PlayerCount; i++) + { + GameData.PlayerInfo playerInfo = GameData.Instance.AllPlayers[i]; + if (!playerInfo.Disconnected) + { + if (playerInfo.IsImpostor) + { + num3++; + } + if (!playerInfo.IsDead) + { + if (playerInfo.IsImpostor) + { + num2++; + } + else + { + num++; + } + } + } + } + if (num2 <= 0 && (!DestroyableSingleton<TutorialManager>.InstanceExists || num3 > 0)) + { + if (!DestroyableSingleton<TutorialManager>.InstanceExists) + { + base.enabled = false; + ShipStatus.RpcEndGame((TempData.LastDeathReason == DeathReason.Disconnect) ? GameOverReason.ImpostorDisconnect : GameOverReason.HumansByVote, !SaveManager.BoughtNoAds); + return; + } + DestroyableSingleton<HudManager>.Instance.ShowPopUp("Normally The Crew would have just won because The Impostor is dead. For free play, we revive everyone instead."); + ShipStatus.ReviveEveryone(); + return; + } + else + { + if (num > num2) + { + if (!DestroyableSingleton<TutorialManager>.InstanceExists) + { + if (GameData.Instance.TotalTasks <= GameData.Instance.CompletedTasks) + { + base.enabled = false; + ShipStatus.RpcEndGame(GameOverReason.HumansByTask, !SaveManager.BoughtNoAds); + return; + } + } + else if (PlayerControl.LocalPlayer.myTasks.All((PlayerTask t) => t.IsComplete)) + { + DestroyableSingleton<HudManager>.Instance.ShowPopUp("Normally The Crew would have just won because the task bar is full. For free play, we issue new tasks instead."); + this.Begin(); + } + return; + } + if (!DestroyableSingleton<TutorialManager>.InstanceExists) + { + base.enabled = false; + GameOverReason endReason; + switch (TempData.LastDeathReason) + { + case DeathReason.Exile: + endReason = GameOverReason.ImpostorByVote; + break; + case DeathReason.Kill: + endReason = GameOverReason.ImpostorByKill; + break; + default: + endReason = GameOverReason.HumansDisconnect; + break; + } + ShipStatus.RpcEndGame(endReason, !SaveManager.BoughtNoAds); + return; + } + DestroyableSingleton<HudManager>.Instance.ShowPopUp("Normally The Impostor would have just won because The Crew can no longer win. For free play, we revive everyone instead."); + ShipStatus.ReviveEveryone(); + return; + } + } + + private void EndGameForSabotage() + { + if (!DestroyableSingleton<TutorialManager>.InstanceExists) + { + base.enabled = false; + ShipStatus.RpcEndGame(GameOverReason.ImpostorBySabotage, !SaveManager.BoughtNoAds); + return; + } + DestroyableSingleton<HudManager>.Instance.ShowPopUp("Normally The Impostor would have just won because of the critical sabotage. Instead we just shut it off."); + } + + public bool IsGameOverDueToDeath() + { + int num = 0; + int num2 = 0; + int num3 = 0; + for (int i = 0; i < GameData.Instance.PlayerCount; i++) + { + GameData.PlayerInfo playerInfo = GameData.Instance.AllPlayers[i]; + if (!playerInfo.Disconnected) + { + if (playerInfo.IsImpostor) + { + num3++; + } + if (!playerInfo.IsDead) + { + if (playerInfo.IsImpostor) + { + num2++; + } + else + { + num++; + } + } + } + } + return (num2 <= 0 && (!DestroyableSingleton<TutorialManager>.InstanceExists || num3 > 0)) || num <= num2; + } + + private static void RpcEndGame(GameOverReason endReason, bool showAd) + { + MessageWriter messageWriter = AmongUsClient.Instance.StartEndGame(); + messageWriter.Write((byte)endReason); + messageWriter.Write(showAd); + AmongUsClient.Instance.FinishEndGame(messageWriter); + } + + private static void ReviveEveryone() + { + for (int i = 0; i < GameData.Instance.PlayerCount; i++) + { + GameData.Instance.AllPlayers[i].Object.Revive(); + } + UnityEngine.Object.FindObjectsOfType<DeadBody>().ForEach(delegate(DeadBody b) + { + UnityEngine.Object.Destroy(b.gameObject); + }); + } + + public bool CheckTaskCompletion() + { + if (DestroyableSingleton<TutorialManager>.InstanceExists) + { + if (PlayerControl.LocalPlayer.myTasks.All((PlayerTask t) => t.IsComplete)) + { + DestroyableSingleton<HudManager>.Instance.ShowPopUp("Normally The Crew would have just won because the task bar is full. For free play, we issue new tasks instead."); + this.Begin(); + } + return false; + } + GameData.Instance.RecomputeTaskCounts(); + if (GameData.Instance.TotalTasks <= GameData.Instance.CompletedTasks) + { + base.enabled = false; + ShipStatus.RpcEndGame(GameOverReason.HumansByTask, !SaveManager.BoughtNoAds); + return true; + } + return false; + } + + public void RpcCloseDoorsOfType(SystemTypes type) + { + if (AmongUsClient.Instance.AmHost) + { + this.CloseDoorsOfType(type); + return; + } + MessageWriter messageWriter = AmongUsClient.Instance.StartRpcImmediately(this.NetId, 0, SendOption.Reliable, AmongUsClient.Instance.HostId); + messageWriter.Write((byte)type); + AmongUsClient.Instance.FinishRpcImmediately(messageWriter); + } + + public void RpcRepairSystem(SystemTypes systemType, int amount) + { + if (AmongUsClient.Instance.AmHost) + { + this.RepairSystem(systemType, PlayerControl.LocalPlayer, (byte)amount); + return; + } + MessageWriter messageWriter = AmongUsClient.Instance.StartRpcImmediately(this.NetId, 1, SendOption.Reliable, AmongUsClient.Instance.HostId); + messageWriter.Write((byte)systemType); + messageWriter.WriteNetObject(PlayerControl.LocalPlayer); + messageWriter.Write((byte)amount); + AmongUsClient.Instance.FinishRpcImmediately(messageWriter); + } + + public override void HandleRpc(byte callId, MessageReader reader) + { + if (callId == 0) + { + this.CloseDoorsOfType((SystemTypes)reader.ReadByte()); + return; + } + if (callId != 1) + { + return; + } + this.RepairSystem((SystemTypes)reader.ReadByte(), reader.ReadNetObject<PlayerControl>(), reader.ReadByte()); + } +} diff --git a/Client/Assembly-CSharp/ShowAdsState.cs b/Client/Assembly-CSharp/ShowAdsState.cs new file mode 100644 index 0000000..3515783 --- /dev/null +++ b/Client/Assembly-CSharp/ShowAdsState.cs @@ -0,0 +1,9 @@ +using System; + +public enum ShowAdsState : byte +{ + Personalized, + Accepted = 128, + NonPersonalized = 1, + Purchased = 130 +} diff --git a/Client/Assembly-CSharp/SimonSaysGame.cs b/Client/Assembly-CSharp/SimonSaysGame.cs new file mode 100644 index 0000000..a66114f --- /dev/null +++ b/Client/Assembly-CSharp/SimonSaysGame.cs @@ -0,0 +1,243 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using UnityEngine; + +public class SimonSaysGame : Minigame +{ + private int IndexCount + { + get + { + return (int)this.MyNormTask.Data[0]; + } + set + { + this.MyNormTask.Data[0] = (byte)value; + } + } + + private byte this[int idx] + { + get + { + return this.MyNormTask.Data[idx + 1]; + } + set + { + this.MyNormTask.Data[idx + 1] = value; + } + } + + private Queue<int> operations = new Queue<int>(); + + private const int FlashOp = 256; + + private const int AnimateOp = 128; + + private const int ReAnimateOp = 32; + + private const int FailOp = 64; + + private Color gray = new Color32(141, 141, 141, byte.MaxValue); + + private Color blue = new Color32(68, 168, byte.MaxValue, byte.MaxValue); + + private Color red = new Color32(byte.MaxValue, 58, 0, byte.MaxValue); + + private Color green = Color.green; + + public SpriteRenderer[] LeftSide; + + public SpriteRenderer[] Buttons; + + public SpriteRenderer[] LeftLights; + + public SpriteRenderer[] RightLights; + + private float flashTime = 0.25f; + + private float userButtonFlashTime = 0.175f; + + public AudioClip ButtonPressSound; + + public AudioClip FailSound; + + public override void Begin(PlayerTask task) + { + for (int i = 0; i < this.LeftSide.Length; i++) + { + this.LeftSide[i].color = Color.clear; + } + base.Begin(task); + if (this.IndexCount == 0) + { + this.operations.Enqueue(128); + } + else + { + this.operations.Enqueue(32); + } + base.StartCoroutine(this.CoRun()); + } + + public void HitButton(int bIdx) + { + if (this.MyNormTask.IsComplete || this.MyNormTask.taskStep >= this.IndexCount) + { + return; + } + if ((int)this[this.MyNormTask.taskStep] == bIdx) + { + this.MyNormTask.NextStep(); + this.SetLights(this.RightLights, this.MyNormTask.taskStep); + if (this.MyNormTask.IsComplete) + { + this.SetLights(this.LeftLights, this.LeftLights.Length); + for (int i = 0; i < this.Buttons.Length; i++) + { + SpriteRenderer spriteRenderer = this.Buttons[i]; + spriteRenderer.color = this.gray; + base.StartCoroutine(this.FlashButton(-1, spriteRenderer, this.flashTime)); + } + base.StartCoroutine(base.CoStartClose(0.75f)); + return; + } + this.operations.Enqueue(256 | bIdx); + if (this.MyNormTask.taskStep >= this.IndexCount) + { + this.operations.Enqueue(128); + return; + } + } + else + { + this.IndexCount = 0; + this.operations.Enqueue(64); + this.operations.Enqueue(128); + } + } + + private IEnumerator CoRun() + { + for (;;) + { + if (this.operations.Count <= 0) + { + yield return null; + } + else + { + int num = this.operations.Dequeue(); + if (num.HasAnyBit(256)) + { + int num2 = num & -257; + yield return this.FlashButton(num2, this.Buttons[num2], this.userButtonFlashTime); + } + else if (num.HasAnyBit(128)) + { + yield return this.CoAnimateNewLeftSide(); + } + else if (num.HasAnyBit(32)) + { + yield return this.CoAnimateOldLeftSide(); + } + else if (num.HasAnyBit(64)) + { + if (Constants.ShouldPlaySfx()) + { + SoundManager.Instance.PlaySound(this.FailSound, false, 1f); + } + this.SetAllColor(this.red); + yield return new WaitForSeconds(this.flashTime); + this.SetAllColor(Color.white); + yield return new WaitForSeconds(this.flashTime); + this.SetAllColor(this.red); + yield return new WaitForSeconds(this.flashTime); + this.SetAllColor(Color.white); + yield return new WaitForSeconds(this.flashTime / 2f); + } + } + } + yield break; + } + + private void AddIndex(int idxToAdd) + { + this[this.IndexCount] = (byte)idxToAdd; + int indexCount = this.IndexCount; + this.IndexCount = indexCount + 1; + } + + private IEnumerator CoAnimateNewLeftSide() + { + this.SetLights(this.RightLights, 0); + for (int i = 0; i < this.Buttons.Length; i++) + { + this.Buttons[i].color = this.gray; + } + this.AddIndex(this.Buttons.RandomIdx<SpriteRenderer>()); + yield return this.CoAnimateOldLeftSide(); + yield break; + } + + private IEnumerator CoAnimateOldLeftSide() + { + yield return new WaitForSeconds(1f); + this.SetLights(this.LeftLights, this.IndexCount); + int num2; + for (int i = 0; i < this.IndexCount; i = num2) + { + int num = (int)this[i]; + yield return this.FlashButton(num, this.LeftSide[num], this.flashTime); + yield return new WaitForSeconds(0.1f); + num2 = i + 1; + } + this.MyNormTask.taskStep = 0; + for (int j = 0; j < this.Buttons.Length; j++) + { + this.Buttons[j].color = Color.white; + } + yield break; + } + + private IEnumerator FlashButton(int id, SpriteRenderer butt, float flashTime) + { + if (id > -1 && Constants.ShouldPlaySfx()) + { + SoundManager.Instance.PlaySound(this.ButtonPressSound, false, 1f).pitch = Mathf.Lerp(0.5f, 1.5f, (float)id / 9f); + } + Color c = butt.color; + butt.color = this.blue; + yield return new WaitForSeconds(flashTime); + butt.color = c; + yield break; + } + + private void SetLights(SpriteRenderer[] lights, int num) + { + for (int i = 0; i < lights.Length; i++) + { + if (i < num) + { + lights[i].color = this.green; + } + else + { + lights[i].color = this.gray; + } + } + } + + private void SetAllColor(Color color) + { + for (int i = 0; i < this.Buttons.Length; i++) + { + this.Buttons[i].color = color; + } + for (int j = 0; j < this.RightLights.Length; j++) + { + this.RightLights[j].color = color; + } + } +} diff --git a/Client/Assembly-CSharp/SinglePopHelp.cs b/Client/Assembly-CSharp/SinglePopHelp.cs new file mode 100644 index 0000000..4a8d086 --- /dev/null +++ b/Client/Assembly-CSharp/SinglePopHelp.cs @@ -0,0 +1,6 @@ +using System; +using UnityEngine; + +public class SinglePopHelp : MonoBehaviour +{ +} diff --git a/Client/Assembly-CSharp/SkinData.cs b/Client/Assembly-CSharp/SkinData.cs new file mode 100644 index 0000000..0137d23 --- /dev/null +++ b/Client/Assembly-CSharp/SkinData.cs @@ -0,0 +1,48 @@ +using System; +using UnityEngine; + +[CreateAssetMenu] +public class SkinData : ScriptableObject, IBuyable +{ + public string ProdId + { + get + { + return this.RelatedHat.ProductId; + } + } + + public Sprite IdleFrame; + + public AnimationClip IdleAnim; + + public AnimationClip RunAnim; + + public AnimationClip EnterVentAnim; + + public AnimationClip ExitVentAnim; + + public AnimationClip KillTongueImpostor; + + public AnimationClip KillTongueVictim; + + public AnimationClip KillShootImpostor; + + public AnimationClip KillShootVictim; + + public AnimationClip KillStabVictim; + + public AnimationClip KillNeckVictim; + + public Sprite EjectFrame; + + public AnimationClip SpawnAnim; + + public bool Free; + + public HatBehaviour RelatedHat; + + public string StoreName; + + public int Order; +} diff --git a/Client/Assembly-CSharp/SkinLayer.cs b/Client/Assembly-CSharp/SkinLayer.cs new file mode 100644 index 0000000..80f0cf6 --- /dev/null +++ b/Client/Assembly-CSharp/SkinLayer.cs @@ -0,0 +1,101 @@ +using System; +using PowerTools; +using UnityEngine; + +public class SkinLayer : MonoBehaviour +{ + public bool Flipped + { + set + { + this.layer.flipX = value; + } + } + + public bool Visible + { + set + { + this.layer.enabled = value; + } + } + + public SpriteRenderer layer; + + public SpriteAnim animator; + + public SkinData skin; + + public void SetRun() + { + if (!this.skin || !this.animator) + { + this.SetGhost(); + return; + } + if (!this.animator.IsPlaying(this.skin.RunAnim)) + { + this.animator.Play(this.skin.RunAnim, 1f); + } + } + + public void SetSpawn(float time = 0f) + { + if (!this.skin || !this.animator) + { + this.SetGhost(); + return; + } + this.animator.Play(this.skin.SpawnAnim, 1f); + this.animator.Time = time; + } + + public void SetExitVent() + { + if (!this.skin || !this.animator) + { + this.SetGhost(); + return; + } + this.animator.Play(this.skin.ExitVentAnim, 1f); + } + + public void SetEnterVent() + { + if (!this.skin || !this.animator) + { + this.SetGhost(); + return; + } + this.animator.Play(this.skin.EnterVentAnim, 1f); + } + + public void SetIdle() + { + if (!this.skin || !this.animator) + { + this.SetGhost(); + return; + } + if (!this.animator.IsPlaying(this.skin.IdleAnim)) + { + this.animator.Play(this.skin.IdleAnim, 1f); + } + } + + public void SetGhost() + { + if (!this.animator) + { + return; + } + this.animator.Stop(); + this.layer.sprite = null; + } + + internal void SetSkin(uint skinId) + { + this.skin = DestroyableSingleton<HatManager>.Instance.GetSkinById(skinId); + this.SetIdle(); + } +} diff --git a/Client/Assembly-CSharp/SkinsTab.cs b/Client/Assembly-CSharp/SkinsTab.cs new file mode 100644 index 0000000..8eecb09 --- /dev/null +++ b/Client/Assembly-CSharp/SkinsTab.cs @@ -0,0 +1,83 @@ +using System; +using System.Collections.Generic; +using UnityEngine; + +public class SkinsTab : MonoBehaviour +{ + public ColorChip ColorTabPrefab; + + public SpriteRenderer DemoImage; + + public SpriteRenderer HatImage; + + public SpriteRenderer SkinImage; + + public SpriteRenderer PetImage; + + public FloatRange XRange = new FloatRange(1.5f, 3f); + + public float YStart = 0.8f; + + public float YOffset = 0.8f; + + public int NumPerRow = 4; + + public Scroller scroller; + + private List<ColorChip> ColorChips = new List<ColorChip>(); + + public void OnEnable() + { + PlayerControl.SetPlayerMaterialColors((int)PlayerControl.LocalPlayer.Data.ColorId, this.DemoImage); + PlayerControl.SetHatImage(SaveManager.LastHat, this.HatImage); + PlayerControl.SetSkinImage(SaveManager.LastSkin, this.SkinImage); + PlayerControl.SetPetImage(SaveManager.LastPet, (int)PlayerControl.LocalPlayer.Data.ColorId, this.PetImage); + SkinData[] unlockedSkins = DestroyableSingleton<HatManager>.Instance.GetUnlockedSkins(); + for (int i = 0; i < unlockedSkins.Length; i++) + { + SkinData skin = unlockedSkins[i]; + float x = this.XRange.Lerp((float)(i % this.NumPerRow) / ((float)this.NumPerRow - 1f)); + float y = this.YStart - (float)(i / this.NumPerRow) * this.YOffset; + ColorChip colorChip = UnityEngine.Object.Instantiate<ColorChip>(this.ColorTabPrefab, this.scroller.Inner); + colorChip.transform.localPosition = new Vector3(x, y, -1f); + colorChip.Button.OnClick.AddListener(delegate() + { + this.SelectHat(skin); + }); + colorChip.Inner.sprite = skin.IdleFrame; + this.ColorChips.Add(colorChip); + } + this.scroller.YBounds.max = -(this.YStart - (float)(unlockedSkins.Length / this.NumPerRow) * this.YOffset) - 3f; + } + + public void OnDisable() + { + for (int i = 0; i < this.ColorChips.Count; i++) + { + UnityEngine.Object.Destroy(this.ColorChips[i].gameObject); + } + this.ColorChips.Clear(); + } + + public void Update() + { + PlayerControl.SetPlayerMaterialColors((int)PlayerControl.LocalPlayer.Data.ColorId, this.DemoImage); + SkinData skinById = DestroyableSingleton<HatManager>.Instance.GetSkinById(SaveManager.LastSkin); + for (int i = 0; i < this.ColorChips.Count; i++) + { + ColorChip colorChip = this.ColorChips[i]; + colorChip.InUseForeground.SetActive(skinById.IdleFrame == colorChip.Inner.sprite); + } + } + + private void SelectHat(SkinData skin) + { + uint idFromSkin = DestroyableSingleton<HatManager>.Instance.GetIdFromSkin(skin); + SaveManager.LastSkin = idFromSkin; + PlayerControl.SetSkinImage(SaveManager.LastSkin, this.SkinImage); + if (PlayerControl.LocalPlayer) + { + PlayerControl.LocalPlayer.RpcSetSkin(idFromSkin); + } + } +} diff --git a/Client/Assembly-CSharp/SlideBar.cs b/Client/Assembly-CSharp/SlideBar.cs new file mode 100644 index 0000000..da36f58 --- /dev/null +++ b/Client/Assembly-CSharp/SlideBar.cs @@ -0,0 +1,78 @@ +using System; +using UnityEngine; +using UnityEngine.Events; + +public class SlideBar : MonoBehaviour +{ + public TextRenderer Title; + + public SpriteRenderer Bar; + + public Collider2D HitBox; + + public SpriteRenderer Dot; + + public FloatRange Range; + + public bool Vertical; + + public float Value; + + public UnityEvent OnValueChange; + + public void OnEnable() + { + if (this.Title) + { + this.Title.Color = Color.white; + } + this.Bar.color = Color.white; + this.Dot.color = Color.white; + } + + public void OnDisable() + { + if (this.Title) + { + this.Title.Color = Color.gray; + } + this.Bar.color = Color.gray; + this.Dot.color = Color.gray; + } + + public void Update() + { + Vector3 localPosition = this.Dot.transform.localPosition; + switch (DestroyableSingleton<PassiveButtonManager>.Instance.Controller.CheckDrag(this.HitBox, false)) + { + case DragState.Dragging: + { + Vector2 vector = DestroyableSingleton<PassiveButtonManager>.Instance.Controller.DragPosition - this.Bar.transform.position; + if (this.Vertical) + { + localPosition.y = this.Range.Clamp(vector.y); + this.Value = this.Range.ReverseLerp(localPosition.y); + } + else + { + localPosition.x = this.Range.Clamp(vector.x); + this.Value = this.Range.ReverseLerp(localPosition.x); + } + this.OnValueChange.Invoke(); + break; + } + case DragState.Released: + this.OnValueChange.Invoke(); + break; + } + if (this.Vertical) + { + localPosition.y = this.Range.Lerp(this.Value); + } + else + { + localPosition.x = this.Range.Lerp(this.Value); + } + this.Dot.transform.localPosition = localPosition; + } +} diff --git a/Client/Assembly-CSharp/SortGameObject.cs b/Client/Assembly-CSharp/SortGameObject.cs new file mode 100644 index 0000000..40a2fc8 --- /dev/null +++ b/Client/Assembly-CSharp/SortGameObject.cs @@ -0,0 +1,16 @@ +using System; +using UnityEngine; + +public class SortGameObject : MonoBehaviour +{ + public SortGameObject.ObjType MyType; + + public Collider2D Collider; + + public enum ObjType + { + Plant, + Mineral, + Animal + } +} diff --git a/Client/Assembly-CSharp/SortMinigame.cs b/Client/Assembly-CSharp/SortMinigame.cs new file mode 100644 index 0000000..829f527 --- /dev/null +++ b/Client/Assembly-CSharp/SortMinigame.cs @@ -0,0 +1,72 @@ +using System; +using UnityEngine; + +public class SortMinigame : Minigame +{ + public SortGameObject[] Objects; + + public BoxCollider2D AnimalBox; + + public BoxCollider2D PlantBox; + + public BoxCollider2D MineralBox; + + private Controller myController = new Controller(); + + public void Start() + { + this.Objects.Shuffle<SortGameObject>(); + for (int i = 0; i < this.Objects.Length; i++) + { + this.Objects[i].transform.localPosition = new Vector3(Mathf.Lerp(-2f, 2f, (float)i / ((float)this.Objects.Length - 1f)), FloatRange.Next(-1.75f, -1f), -1f); + } + } + + public void Update() + { + if (this.amClosing != Minigame.CloseState.None) + { + return; + } + this.myController.Update(); + for (int i = 0; i < this.Objects.Length; i++) + { + SortGameObject sortGameObject = this.Objects[i]; + switch (this.myController.CheckDrag(sortGameObject.Collider, false)) + { + case DragState.Dragging: + { + Vector2 dragPosition = this.myController.DragPosition; + sortGameObject.Collider.attachedRigidbody.position = dragPosition; + break; + } + case DragState.Released: + { + bool flag = true; + for (int j = 0; j < this.Objects.Length; j++) + { + SortGameObject sortGameObject2 = this.Objects[j]; + switch (sortGameObject2.MyType) + { + case SortGameObject.ObjType.Plant: + flag &= sortGameObject2.Collider.IsTouching(this.PlantBox); + break; + case SortGameObject.ObjType.Mineral: + flag &= sortGameObject2.Collider.IsTouching(this.MineralBox); + break; + case SortGameObject.ObjType.Animal: + flag &= sortGameObject2.Collider.IsTouching(this.AnimalBox); + break; + } + } + if (flag) + { + this.MyTask.Complete(); + base.StartCoroutine(base.CoStartClose(0.75f)); + } + break; + } + } + } + } +} diff --git a/Client/Assembly-CSharp/SoundGroup.cs b/Client/Assembly-CSharp/SoundGroup.cs new file mode 100644 index 0000000..b7ec876 --- /dev/null +++ b/Client/Assembly-CSharp/SoundGroup.cs @@ -0,0 +1,13 @@ +using System; +using UnityEngine; + +[CreateAssetMenu] +public class SoundGroup : ScriptableObject +{ + public AudioClip[] Clips; + + public AudioClip Random() + { + return this.Clips.Random<AudioClip>(); + } +} diff --git a/Client/Assembly-CSharp/SoundManager.cs b/Client/Assembly-CSharp/SoundManager.cs new file mode 100644 index 0000000..4d03573 --- /dev/null +++ b/Client/Assembly-CSharp/SoundManager.cs @@ -0,0 +1,239 @@ +using System; +using System.Collections.Generic; +using UnityEngine; +using UnityEngine.Audio; + +public class SoundManager : MonoBehaviour +{ + public static SoundManager Instance + { + get + { + if (!SoundManager._Instance) + { + SoundManager._Instance = (UnityEngine.Object.FindObjectOfType<SoundManager>() ?? new GameObject("SoundManager").AddComponent<SoundManager>()); + } + return SoundManager._Instance; + } + } + + private static SoundManager _Instance; + + public AudioMixerGroup musicMixer; + + public AudioMixerGroup sfxMixer; + + public static float MusicVolume = 1f; + + public static float SfxVolume = 1f; + + private Dictionary<AudioClip, AudioSource> allSources = new Dictionary<AudioClip, AudioSource>(); + + private List<ISoundPlayer> soundPlayers = new List<ISoundPlayer>(); + + public void Start() + { + if (SoundManager._Instance && SoundManager._Instance != this) + { + UnityEngine.Object.Destroy(base.gameObject); + return; + } + SoundManager._Instance = this; + this.UpdateVolume(); + UnityEngine.Object.DontDestroyOnLoad(base.gameObject); + } + + public void Update() + { + for (int i = 0; i < this.soundPlayers.Count; i++) + { + this.soundPlayers[i].Update(Time.deltaTime); + } + } + + private void UpdateVolume() + { + this.ChangeSfxVolume(SaveManager.SfxVolume); + this.ChangeMusicVolume(SaveManager.MusicVolume); + } + + public void ChangeSfxVolume(float volume) + { + if (volume <= 0f) + { + SoundManager.SfxVolume = -80f; + } + else + { + SoundManager.SfxVolume = Mathf.Log10(volume) * 20f; + } + this.musicMixer.audioMixer.SetFloat("SfxVolume", SoundManager.SfxVolume); + } + + public void ChangeMusicVolume(float volume) + { + if (volume <= 0f) + { + SoundManager.MusicVolume = -80f; + } + else + { + SoundManager.MusicVolume = Mathf.Log10(volume) * 20f; + } + this.musicMixer.audioMixer.SetFloat("MusicVolume", SoundManager.MusicVolume); + } + + public void StopSound(AudioClip clip) + { + AudioSource audioSource; + if (this.allSources.TryGetValue(clip, out audioSource)) + { + this.allSources.Remove(clip); + audioSource.Stop(); + UnityEngine.Object.Destroy(audioSource); + } + for (int i = 0; i < this.soundPlayers.Count; i++) + { + ISoundPlayer soundPlayer = this.soundPlayers[i]; + if (soundPlayer.Player.clip == clip) + { + UnityEngine.Object.Destroy(soundPlayer.Player); + this.soundPlayers.RemoveAt(i); + return; + } + } + } + + public void StopAllSound() + { + for (int i = 0; i < this.soundPlayers.Count; i++) + { + UnityEngine.Object.Destroy(this.soundPlayers[i].Player); + } + this.soundPlayers.Clear(); + foreach (KeyValuePair<AudioClip, AudioSource> keyValuePair in this.allSources) + { + AudioSource value = keyValuePair.Value; + value.volume = 0f; + value.Stop(); + UnityEngine.Object.Destroy(keyValuePair.Value); + } + this.allSources.Clear(); + } + + public void PlayDynamicSound(string name, AudioClip clip, bool loop, DynamicSound.GetDynamicsFunction volumeFunc, bool playAsSfx = false) + { + DynamicSound dynamicSound = null; + for (int i = 0; i < this.soundPlayers.Count; i++) + { + ISoundPlayer soundPlayer = this.soundPlayers[i]; + if (soundPlayer.Name == name && soundPlayer is DynamicSound) + { + dynamicSound = (DynamicSound)soundPlayer; + break; + } + } + if (dynamicSound == null) + { + dynamicSound = new DynamicSound(); + dynamicSound.Name = name; + dynamicSound.Player = base.gameObject.AddComponent<AudioSource>(); + dynamicSound.Player.outputAudioMixerGroup = ((loop && !playAsSfx) ? this.musicMixer : this.sfxMixer); + dynamicSound.Player.playOnAwake = false; + this.soundPlayers.Add(dynamicSound); + } + dynamicSound.Player.loop = loop; + dynamicSound.SetTarget(clip, volumeFunc); + } + + public void CrossFadeSound(string name, AudioClip clip, float maxVolume, float duration = 1.5f) + { + CrossFader crossFader = null; + for (int i = 0; i < this.soundPlayers.Count; i++) + { + ISoundPlayer soundPlayer = this.soundPlayers[i]; + if (soundPlayer.Name == name && soundPlayer is CrossFader) + { + crossFader = (CrossFader)soundPlayer; + break; + } + } + if (crossFader == null) + { + crossFader = new CrossFader(); + crossFader.Name = name; + crossFader.MaxVolume = maxVolume; + crossFader.Player = base.gameObject.AddComponent<AudioSource>(); + crossFader.Player.outputAudioMixerGroup = this.musicMixer; + crossFader.Player.playOnAwake = false; + crossFader.Player.loop = true; + this.soundPlayers.Add(crossFader); + } + crossFader.SetTarget(clip); + } + + public AudioSource PlaySoundImmediate(AudioClip clip, bool loop, float volume = 1f, float pitch = 1f) + { + if (clip == null) + { + Debug.LogWarning("Missing audio clip"); + return null; + } + AudioSource audioSource; + if (this.allSources.TryGetValue(clip, out audioSource)) + { + audioSource.pitch = pitch; + audioSource.loop = loop; + audioSource.Play(); + } + else + { + audioSource = base.gameObject.AddComponent<AudioSource>(); + audioSource.outputAudioMixerGroup = (loop ? this.musicMixer : this.sfxMixer); + audioSource.playOnAwake = false; + audioSource.volume = volume; + audioSource.pitch = pitch; + audioSource.loop = loop; + audioSource.clip = clip; + audioSource.Play(); + this.allSources.Add(clip, audioSource); + } + return audioSource; + } + + public bool SoundIsPlaying(AudioClip clip) + { + AudioSource audioSource; + return this.allSources.TryGetValue(clip, out audioSource) && !audioSource.isPlaying; + } + + public AudioSource PlaySound(AudioClip clip, bool loop, float volume = 1f) + { + if (clip == null) + { + Debug.LogWarning("Missing audio clip"); + return null; + } + AudioSource audioSource; + if (this.allSources.TryGetValue(clip, out audioSource)) + { + if (!audioSource.isPlaying) + { + audioSource.loop = loop; + audioSource.Play(); + } + } + else + { + audioSource = base.gameObject.AddComponent<AudioSource>(); + audioSource.outputAudioMixerGroup = (loop ? this.musicMixer : this.sfxMixer); + audioSource.playOnAwake = false; + audioSource.volume = volume; + audioSource.loop = loop; + audioSource.clip = clip; + audioSource.Play(); + this.allSources.Add(clip, audioSource); + } + return audioSource; + } +} diff --git a/Client/Assembly-CSharp/SoundStarter.cs b/Client/Assembly-CSharp/SoundStarter.cs new file mode 100644 index 0000000..0a1258e --- /dev/null +++ b/Client/Assembly-CSharp/SoundStarter.cs @@ -0,0 +1,23 @@ +using System; +using UnityEngine; + +public class SoundStarter : MonoBehaviour +{ + public string Name; + + public AudioClip SoundToPlay; + + public bool StopAll; + + [Range(0f, 1f)] + public float Volume = 1f; + + public void Awake() + { + if (this.StopAll) + { + SoundManager.Instance.StopAllSound(); + } + SoundManager.Instance.CrossFadeSound(this.Name, this.SoundToPlay, this.Volume, 1.5f); + } +} diff --git a/Client/Assembly-CSharp/SpinAnimator.cs b/Client/Assembly-CSharp/SpinAnimator.cs new file mode 100644 index 0000000..e3762f2 --- /dev/null +++ b/Client/Assembly-CSharp/SpinAnimator.cs @@ -0,0 +1,72 @@ +using System; +using System.Collections; +using UnityEngine; + +public class SpinAnimator : MonoBehaviour +{ + public float Speed = 60f; + + private SpinAnimator.States curState; + + private enum States + { + Visible, + Invisible, + Spinning, + Pulsing + } + + private void Update() + { + if (this.curState == SpinAnimator.States.Spinning) + { + base.transform.Rotate(0f, 0f, this.Speed * Time.deltaTime); + } + } + + public void Appear() + { + if (this.curState != SpinAnimator.States.Invisible) + { + return; + } + this.curState = SpinAnimator.States.Visible; + base.gameObject.SetActive(true); + base.StopAllCoroutines(); + base.StartCoroutine(Effects.ScaleIn(base.transform, 0f, 1f, 0.125f)); + } + + public void Disappear() + { + if (this.curState == SpinAnimator.States.Invisible) + { + return; + } + this.curState = SpinAnimator.States.Invisible; + base.StopAllCoroutines(); + base.StartCoroutine(this.CoDisappear()); + } + + private IEnumerator CoDisappear() + { + yield return Effects.ScaleIn(base.transform, 1f, 0f, 0.125f); + base.gameObject.SetActive(false); + yield break; + } + + public void StartPulse() + { + if (this.curState == SpinAnimator.States.Pulsing) + { + return; + } + this.curState = SpinAnimator.States.Pulsing; + SpriteRenderer component = base.GetComponent<SpriteRenderer>(); + base.StartCoroutine(Effects.CycleColors(component, Color.white, Color.green, 1f, float.MaxValue)); + } + + internal void Play() + { + this.curState = SpinAnimator.States.Spinning; + } +} diff --git a/Client/Assembly-CSharp/SpriteParticle.cs b/Client/Assembly-CSharp/SpriteParticle.cs new file mode 100644 index 0000000..8661403 --- /dev/null +++ b/Client/Assembly-CSharp/SpriteParticle.cs @@ -0,0 +1,128 @@ +using System; +using System.Collections.Generic; +using UnityEngine; + +[RequireComponent(typeof(MeshFilter))] +[RequireComponent(typeof(MeshRenderer))] +public class SpriteParticle : MonoBehaviour +{ + private const float FrameRate = 24f; + + public Sprite[] Sprites; + + public ParticleInfo[] Particles; + + public ushort[][] TriangleCache; + + private Vector3[] verts; + + private Vector2[] uvs; + + private List<int> tris = new List<int>(); + + private Mesh mesh; + + private int MaxVerts; + + private Dictionary<int, Vector2[]> VertCache = new Dictionary<int, Vector2[]>(); + + private Dictionary<int, Vector2[]> UvCache = new Dictionary<int, Vector2[]>(); + + public void OnDrawGizmos() + { + if (this.Particles == null || this.Sprites == null) + { + return; + } + if (this.Sprites.Length == 0) + { + return; + } + Sprite sprite = this.Sprites[0]; + for (int i = 0; i < this.Particles.Length; i++) + { + ParticleInfo particleInfo = this.Particles[i]; + Gizmos.DrawCube(particleInfo.Position + base.transform.position, new Vector3(sprite.bounds.size.x * particleInfo.Scale, sprite.bounds.size.y * particleInfo.Scale, sprite.bounds.size.x * particleInfo.Scale)); + } + } + + public void Start() + { + MeshFilter component = base.GetComponent<MeshFilter>(); + this.mesh = new Mesh(); + this.mesh.MarkDynamic(); + component.mesh = this.mesh; + this.TriangleCache = new ushort[this.Sprites.Length][]; + for (int i = 0; i < this.Sprites.Length; i++) + { + Sprite sprite = this.Sprites[i]; + Vector2[] vertices = sprite.vertices; + this.TriangleCache[i] = sprite.triangles; + this.VertCache[i] = vertices; + this.UvCache[i] = sprite.uv; + if (this.MaxVerts < vertices.Length) + { + this.MaxVerts = vertices.Length; + } + } + this.verts = new Vector3[this.Particles.Length * this.MaxVerts]; + this.uvs = new Vector2[this.verts.Length]; + for (int j = 0; j < this.Particles.Length; j++) + { + int num = j * this.MaxVerts; + int num2 = (int)this.Particles[j].Timer; + Sprite sprite2 = this.Sprites[num2]; + Vector2[] vertices2 = sprite2.vertices; + Vector2[] uv = sprite2.uv; + for (int k = 0; k < sprite2.vertices.Length; k++) + { + int num3 = num + k; + this.verts[num3].x = vertices2[k].x * this.Particles[j].Scale + this.Particles[j].Position.x; + this.verts[num3].y = vertices2[k].y * this.Particles[j].Scale + this.Particles[j].Position.y; + this.uvs[num3] = uv[k]; + } + ushort[] triangles = sprite2.triangles; + for (int l = 0; l < triangles.Length; l++) + { + this.tris.Add((int)triangles[l]); + } + } + this.mesh.vertices = this.verts; + this.mesh.uv = this.uvs; + this.mesh.SetTriangles(this.tris, 0); + } + + public void Update() + { + float num = Time.deltaTime * 24f; + this.tris.Clear(); + for (int i = 0; i < this.Particles.Length; i++) + { + float num2 = this.Particles[i].Timer + num; + if (num2 >= (float)this.Sprites.Length) + { + num2 %= 24f; + } + this.Particles[i].Timer = num2; + int num3 = i * this.MaxVerts; + int num4 = (int)this.Particles[i].Timer; + Vector2[] array = this.VertCache[num4]; + Vector2[] array2 = this.UvCache[num4]; + for (int j = 0; j < array.Length; j++) + { + int num5 = num3 + j; + this.verts[num5].x = array[j].x * this.Particles[i].Scale + this.Particles[i].Position.x; + this.verts[num5].y = array[j].y * this.Particles[i].Scale + this.Particles[i].Position.y; + this.uvs[num5] = array2[j]; + } + ushort[] array3 = this.TriangleCache[num4]; + for (int k = 0; k < array3.Length; k++) + { + this.tris.Add((int)array3[k] + num3); + } + } + this.mesh.vertices = this.verts; + this.mesh.uv = this.uvs; + this.mesh.SetTriangles(this.tris, 0); + } +} diff --git a/Client/Assembly-CSharp/StarGen.cs b/Client/Assembly-CSharp/StarGen.cs new file mode 100644 index 0000000..2ecd529 --- /dev/null +++ b/Client/Assembly-CSharp/StarGen.cs @@ -0,0 +1,170 @@ +using System; +using UnityEngine; + +[RequireComponent(typeof(MeshFilter))] +[RequireComponent(typeof(MeshRenderer))] +public class StarGen : MonoBehaviour +{ + private const float MaxStarRadius = 0.05f; + + public int NumStars = 500; + + public float Length = 25f; + + public float Width = 25f; + + public Vector2 Direction = new Vector2(1f, 0f); + + private Vector2 NormDir = new Vector2(1f, 0f); + + private Vector2 Tangent = new Vector2(0f, 1f); + + private float tanLen; + + public FloatRange Rates = new FloatRange(0.25f, 1f); + + [HideInInspector] + private StarGen.Stars[] stars; + + [HideInInspector] + private Vector3[] verts; + + [HideInInspector] + private Mesh mesh; + + [Serializable] + private struct Stars + { + public float Size; + + public float Rate; + + public float PositionX; + + public float PositionY; + } + + public void Start() + { + this.stars = new StarGen.Stars[this.NumStars]; + this.verts = new Vector3[this.NumStars * 4]; + Vector2[] array = new Vector2[this.NumStars * 4]; + int[] array2 = new int[this.NumStars * 6]; + this.SetDirection(this.Direction); + MeshFilter component = base.GetComponent<MeshFilter>(); + this.mesh = new Mesh(); + this.mesh.MarkDynamic(); + component.mesh = this.mesh; + Vector3 vector = default(Vector3); + Vector2 vector2 = default(Vector2); + for (int i = 0; i < this.stars.Length; i++) + { + StarGen.Stars stars = this.stars[i]; + float num = FloatRange.Next(-1f, 1f) * this.Length; + float num2 = FloatRange.Next(-1f, 1f) * this.Width; + float num3 = stars.PositionX = num * this.NormDir.x + num2 * this.Tangent.x; + float num4 = stars.PositionY = num * this.NormDir.y + num2 * this.Tangent.y; + float num5 = FloatRange.Next(0.01f, 0.05f); + stars.Size = num5; + stars.Rate = this.Rates.Next(); + this.stars[i] = stars; + int num6 = i * 4; + vector.x = num3 - num5; + vector.y = num4 + num5; + this.verts[num6] = vector; + vector.y = num4 - num5; + this.verts[num6 + 1] = vector; + vector.x = num3 + num5; + this.verts[num6 + 2] = vector; + vector.y = num4 + num5; + this.verts[num6 + 3] = vector; + vector2.x = -1f; + vector2.y = 1f; + array[num6] = vector2; + vector2.y = -1f; + array[num6 + 1] = vector2; + vector2.x = 1f; + array[num6 + 2] = vector2; + vector2.y = 1f; + array[num6 + 3] = vector2; + int num7 = i * 6; + array2[num7] = num6; + array2[num7 + 1] = num6 + 1; + array2[num7 + 2] = num6 + 2; + array2[num7 + 3] = num6 + 2; + array2[num7 + 4] = num6; + array2[num7 + 5] = num6 + 3; + } + this.mesh.vertices = this.verts; + this.mesh.uv = array; + this.mesh.SetIndices(array2, MeshTopology.Triangles, 0); + } + + private void FixedUpdate() + { + float num = -0.99f * this.Length; + Vector2 vector = this.Direction * Time.fixedDeltaTime; + for (int i = 0; i < this.stars.Length; i++) + { + StarGen.Stars stars = this.stars[i]; + float size = stars.Size; + float num2 = stars.PositionX; + float num3 = stars.PositionY; + float num4 = stars.Rate * (size / 0.05f); + num2 += num4 * vector.x; + num3 += num4 * vector.y; + if (this.OrthoDistance(num2, num3) > this.Length) + { + float num5 = FloatRange.Next(-1f, 1f) * this.Width; + num2 = num * this.NormDir.x + num5 * this.Tangent.x; + num3 = num * this.NormDir.y + num5 * this.Tangent.y; + this.stars[i].Rate = this.Rates.Next(); + } + stars.PositionX = num2; + stars.PositionY = num3; + this.stars[i] = stars; + int num6 = i * 4; + float x = num2 - size; + float x2 = num2 + size; + float y = num3 + size; + float y2 = num3 - size; + this.verts[num6].x = x; + this.verts[num6].y = y; + this.verts[num6 + 1].x = x; + this.verts[num6 + 1].y = y2; + this.verts[num6 + 2].x = x2; + this.verts[num6 + 2].y = y2; + this.verts[num6 + 3].x = x2; + this.verts[num6 + 3].y = y; + } + this.mesh.vertices = this.verts; + } + + public void SetDirection(Vector2 dir) + { + this.Direction = dir; + this.NormDir = this.Direction.normalized; + this.Tangent = new Vector2(-this.NormDir.y, this.NormDir.x); + this.tanLen = Mathf.Sqrt(this.Tangent.y * this.Tangent.y + this.Tangent.x * this.Tangent.x); + } + + public void RegenPositions() + { + if (this.stars == null) + { + return; + } + for (int i = 0; i < this.stars.Length; i++) + { + float num = FloatRange.Next(-1f, 1f) * this.Length; + float num2 = FloatRange.Next(-1f, 1f) * this.Width; + this.stars[i].PositionX = num * this.NormDir.x + num2 * this.Tangent.x; + this.stars[i].PositionY = num * this.NormDir.y + num2 * this.Tangent.y; + } + } + + private float OrthoDistance(float pointx, float pointy) + { + return (this.Tangent.y * pointx - this.Tangent.x * pointy) / this.tanLen; + } +} diff --git a/Client/Assembly-CSharp/StatsManager.cs b/Client/Assembly-CSharp/StatsManager.cs new file mode 100644 index 0000000..1b26ce2 --- /dev/null +++ b/Client/Assembly-CSharp/StatsManager.cs @@ -0,0 +1,439 @@ +using System; +using System.IO; +using UnityEngine; + +public class StatsManager +{ + public uint BodiesReported + { + get + { + this.LoadStats(); + return this.bodiesReported; + } + set + { + this.LoadStats(); + this.bodiesReported = value; + this.SaveStats(); + } + } + + public uint EmergenciesCalled + { + get + { + this.LoadStats(); + return this.emergenciesCalls; + } + set + { + this.LoadStats(); + this.emergenciesCalls = value; + this.SaveStats(); + } + } + + public uint TasksCompleted + { + get + { + this.LoadStats(); + return this.tasksCompleted; + } + set + { + this.LoadStats(); + this.tasksCompleted = value; + this.SaveStats(); + } + } + + public uint CompletedAllTasks + { + get + { + this.LoadStats(); + return this.completedAllTasks; + } + set + { + this.LoadStats(); + this.completedAllTasks = value; + this.SaveStats(); + } + } + + public uint SabsFixed + { + get + { + this.LoadStats(); + return this.sabsFixed; + } + set + { + this.LoadStats(); + this.sabsFixed = value; + this.SaveStats(); + } + } + + public uint ImpostorKills + { + get + { + this.LoadStats(); + return this.impostorKills; + } + set + { + this.LoadStats(); + this.impostorKills = value; + this.SaveStats(); + } + } + + public uint TimesMurdered + { + get + { + this.LoadStats(); + return this.timesMurdered; + } + set + { + this.LoadStats(); + this.timesMurdered = value; + this.SaveStats(); + } + } + + public uint TimesEjected + { + get + { + this.LoadStats(); + return this.timesEjected; + } + set + { + this.LoadStats(); + this.timesEjected = value; + this.SaveStats(); + } + } + + public uint CrewmateStreak + { + get + { + this.LoadStats(); + return this.crewmateStreak; + } + set + { + this.LoadStats(); + this.crewmateStreak = value; + this.SaveStats(); + } + } + + public uint TimesImpostor + { + get + { + this.LoadStats(); + return this.timesImpostor; + } + set + { + this.LoadStats(); + this.timesImpostor = value; + this.SaveStats(); + } + } + + public uint TimesCrewmate + { + get + { + this.LoadStats(); + return this.timesCrewmate; + } + set + { + this.LoadStats(); + this.timesCrewmate = value; + this.SaveStats(); + } + } + + public uint GamesStarted + { + get + { + this.LoadStats(); + return this.gamesStarted; + } + set + { + this.LoadStats(); + this.gamesStarted = value; + this.SaveStats(); + } + } + + public uint GamesFinished + { + get + { + this.LoadStats(); + return this.gamesFinished; + } + set + { + this.LoadStats(); + this.gamesFinished = value; + this.SaveStats(); + } + } + + public float BanPoints + { + get + { + this.LoadStats(); + return this.banPoints; + } + set + { + this.LoadStats(); + this.banPoints = Mathf.Max(0f, value); + this.SaveStats(); + } + } + + public DateTime LastGameStarted + { + get + { + this.LoadStats(); + return new DateTime(this.lastGameStarted); + } + set + { + this.LoadStats(); + this.lastGameStarted = value.Ticks; + this.SaveStats(); + } + } + + public float BanMinutes + { + get + { + return Mathf.Max(this.BanPoints - 2f, 0f) * 5f; + } + } + + public bool AmBanned + { + get + { + return this.BanMinutesLeft > 0; + } + } + + public int BanMinutesLeft + { + get + { + TimeSpan timeSpan = DateTime.UtcNow - this.LastGameStarted; + if (timeSpan.TotalDays > 1.0) + { + return 0; + } + return Mathf.CeilToInt(this.BanMinutes - (float)timeSpan.TotalMinutes); + } + } + + public static StatsManager Instance = new StatsManager(); + + private const byte StatsVersion = 3; + + private bool loadedStats; + + private uint bodiesReported; + + private uint emergenciesCalls; + + private uint tasksCompleted; + + private uint completedAllTasks; + + private uint sabsFixed; + + private uint impostorKills; + + private uint timesMurdered; + + private uint timesEjected; + + private uint crewmateStreak; + + private uint timesImpostor; + + private uint timesCrewmate; + + private uint gamesStarted; + + private uint gamesFinished; + + private float banPoints; + + private long lastGameStarted; + + private const int PointsUntilBanStarts = 2; + + private const int MinutesPerBanPoint = 5; + + private uint[] WinReasons = new uint[7]; + + private uint[] DrawReasons = new uint[7]; + + private uint[] LoseReasons = new uint[7]; + + public void AddDrawReason(GameOverReason reason) + { + this.LoadStats(); + this.DrawReasons[(int)reason] += 1U; + this.SaveStats(); + } + + public void AddWinReason(GameOverReason reason) + { + this.LoadStats(); + this.WinReasons[(int)reason] += 1U; + this.SaveStats(); + } + + public uint GetWinReason(GameOverReason reason) + { + this.LoadStats(); + return this.WinReasons[(int)reason]; + } + + public void AddLoseReason(GameOverReason reason) + { + this.LoadStats(); + this.LoseReasons[(int)reason] += 1U; + this.SaveStats(); + } + + public uint GetLoseReason(GameOverReason reason) + { + this.LoadStats(); + return this.LoseReasons[(int)reason]; + } + + protected virtual void LoadStats() + { + if (this.loadedStats) + { + return; + } + this.loadedStats = true; + string path = Path.Combine(Application.persistentDataPath, "playerStats2"); + if (File.Exists(path)) + { + try + { + using (BinaryReader binaryReader = new BinaryReader(File.OpenRead(path))) + { + byte b = binaryReader.ReadByte(); + this.bodiesReported = binaryReader.ReadUInt32(); + this.emergenciesCalls = binaryReader.ReadUInt32(); + this.tasksCompleted = binaryReader.ReadUInt32(); + this.completedAllTasks = binaryReader.ReadUInt32(); + this.sabsFixed = binaryReader.ReadUInt32(); + this.impostorKills = binaryReader.ReadUInt32(); + this.timesMurdered = binaryReader.ReadUInt32(); + this.timesEjected = binaryReader.ReadUInt32(); + this.crewmateStreak = binaryReader.ReadUInt32(); + this.timesImpostor = binaryReader.ReadUInt32(); + this.timesCrewmate = binaryReader.ReadUInt32(); + this.gamesStarted = binaryReader.ReadUInt32(); + this.gamesFinished = binaryReader.ReadUInt32(); + for (int i = 0; i < this.WinReasons.Length; i++) + { + this.WinReasons[i] = binaryReader.ReadUInt32(); + } + for (int j = 0; j < this.LoseReasons.Length; j++) + { + this.LoseReasons[j] = binaryReader.ReadUInt32(); + } + if (b > 1) + { + for (int k = 0; k < this.DrawReasons.Length; k++) + { + this.DrawReasons[k] = binaryReader.ReadUInt32(); + } + } + if (b > 2) + { + this.banPoints = binaryReader.ReadSingle(); + this.lastGameStarted = binaryReader.ReadInt64(); + } + } + } + catch + { + Debug.LogError("Deleting corrupted stats file"); + File.Delete(path); + } + } + } + + protected virtual void SaveStats() + { + try + { + using (BinaryWriter binaryWriter = new BinaryWriter(File.OpenWrite(Path.Combine(Application.persistentDataPath, "playerStats2")))) + { + binaryWriter.Write(3); + binaryWriter.Write(this.bodiesReported); + binaryWriter.Write(this.emergenciesCalls); + binaryWriter.Write(this.tasksCompleted); + binaryWriter.Write(this.completedAllTasks); + binaryWriter.Write(this.sabsFixed); + binaryWriter.Write(this.impostorKills); + binaryWriter.Write(this.timesMurdered); + binaryWriter.Write(this.timesEjected); + binaryWriter.Write(this.crewmateStreak); + binaryWriter.Write(this.timesImpostor); + binaryWriter.Write(this.timesCrewmate); + binaryWriter.Write(this.gamesStarted); + binaryWriter.Write(this.gamesFinished); + for (int i = 0; i < this.WinReasons.Length; i++) + { + binaryWriter.Write(this.WinReasons[i]); + } + for (int j = 0; j < this.LoseReasons.Length; j++) + { + binaryWriter.Write(this.LoseReasons[j]); + } + for (int k = 0; k < this.DrawReasons.Length; k++) + { + binaryWriter.Write(this.DrawReasons[k]); + } + binaryWriter.Write(this.banPoints); + binaryWriter.Write(this.lastGameStarted); + } + } + catch (Exception ex) + { + Debug.Log("Failed to write out stats: " + ex.Message); + } + } +} diff --git a/Client/Assembly-CSharp/StatsPopup.cs b/Client/Assembly-CSharp/StatsPopup.cs new file mode 100644 index 0000000..4ad2885 --- /dev/null +++ b/Client/Assembly-CSharp/StatsPopup.cs @@ -0,0 +1,32 @@ +using System; +using System.Text; +using UnityEngine; + +public class StatsPopup : MonoBehaviour +{ + public TextRenderer StatsText; + + private void OnEnable() + { + StringBuilder stringBuilder = new StringBuilder(); + stringBuilder.AppendLine(string.Format("Bodies Reported:\t{0}", StatsManager.Instance.BodiesReported)); + stringBuilder.AppendLine(string.Format("Emergencies Called:\t{0}", StatsManager.Instance.EmergenciesCalled)); + stringBuilder.AppendLine(string.Format("Tasks Completed:\t{0}", StatsManager.Instance.TasksCompleted)); + stringBuilder.AppendLine(string.Format("All Tasks Completed:\t{0}", StatsManager.Instance.CompletedAllTasks)); + stringBuilder.AppendLine(string.Format("Sabotages Fixed:\t{0}", StatsManager.Instance.SabsFixed)); + stringBuilder.AppendLine(string.Format("Impostor Kills: \t{0}", StatsManager.Instance.ImpostorKills)); + stringBuilder.AppendLine(string.Format("Times Murdered:\t{0}", StatsManager.Instance.TimesMurdered)); + stringBuilder.AppendLine(string.Format("Times Ejected: \t{0}", StatsManager.Instance.TimesEjected)); + stringBuilder.AppendLine(string.Format("Crewmate Streak:\t{0}", StatsManager.Instance.CrewmateStreak)); + stringBuilder.AppendLine(string.Format("Games Impostor:\t{0}", StatsManager.Instance.TimesImpostor)); + stringBuilder.AppendLine(string.Format("Games Crewmate:\t{0}", StatsManager.Instance.TimesCrewmate)); + stringBuilder.AppendLine(string.Format("Games Started: \t{0}", StatsManager.Instance.GamesStarted)); + stringBuilder.AppendLine(string.Format("Games Finished:\t{0}", StatsManager.Instance.GamesFinished)); + stringBuilder.AppendLine(string.Format("Impostor Vote Wins:\t{0}", StatsManager.Instance.GetWinReason(GameOverReason.ImpostorByVote))); + stringBuilder.AppendLine(string.Format("Impostor Kill Wins:\t{0}", StatsManager.Instance.GetWinReason(GameOverReason.ImpostorByKill))); + stringBuilder.AppendLine(string.Format("Impostor Sabotage Wins:\t{0}", StatsManager.Instance.GetWinReason(GameOverReason.ImpostorBySabotage))); + stringBuilder.AppendLine(string.Format("Crewmate Vote Wins:\t{0}", StatsManager.Instance.GetWinReason(GameOverReason.HumansByVote))); + stringBuilder.AppendLine(string.Format("Crewmate Task Wins:\t{0}", StatsManager.Instance.GetWinReason(GameOverReason.HumansByTask))); + this.StatsText.Text = stringBuilder.ToString(); + } +} diff --git a/Client/Assembly-CSharp/SteamBehaviour.cs b/Client/Assembly-CSharp/SteamBehaviour.cs new file mode 100644 index 0000000..515d641 --- /dev/null +++ b/Client/Assembly-CSharp/SteamBehaviour.cs @@ -0,0 +1,35 @@ +using System; +using System.Collections; +using PowerTools; +using UnityEngine; + +public class SteamBehaviour : MonoBehaviour +{ + public SpriteAnim anim; + + public FloatRange PlayRate = new FloatRange(0.5f, 1f); + + public void OnEnable() + { + base.StartCoroutine(this.Run()); + } + + private IEnumerator Run() + { + for (;;) + { + float time = this.PlayRate.Next(); + while (time > 0f) + { + time -= Time.deltaTime; + yield return null; + } + this.anim.Play(null, 1f); + while (this.anim.IsPlaying(null)) + { + yield return null; + } + } + yield break; + } +} diff --git a/Client/Assembly-CSharp/SteamManager.cs b/Client/Assembly-CSharp/SteamManager.cs new file mode 100644 index 0000000..ce42f18 --- /dev/null +++ b/Client/Assembly-CSharp/SteamManager.cs @@ -0,0 +1,131 @@ +using System; +using System.Text; +using Steamworks; +using UnityEngine; + +[DisallowMultipleComponent] +public class SteamManager : MonoBehaviour +{ + private static SteamManager Instance + { + get + { + if (SteamManager.s_instance == null) + { + return new GameObject("SteamManager").AddComponent<SteamManager>(); + } + return SteamManager.s_instance; + } + } + + public static bool Initialized + { + get + { + return SteamManager.Instance.m_bInitialized; + } + } + + private static SteamManager s_instance; + + private static bool s_EverInitialized; + + private bool m_bInitialized; + + private SteamAPIWarningMessageHook_t m_SteamAPIWarningMessageHook; + + private static void SteamAPIDebugTextHook(int nSeverity, StringBuilder pchDebugText) + { + Debug.LogWarning(pchDebugText); + } + + private void Awake() + { + if (SteamManager.s_instance != null) + { + UnityEngine.Object.Destroy(base.gameObject); + return; + } + SteamManager.s_instance = this; + if (SteamManager.s_EverInitialized) + { + throw new Exception("Tried to Initialize the SteamAPI twice in one session!"); + } + UnityEngine.Object.DontDestroyOnLoad(base.gameObject); + if (!Packsize.Test()) + { + Debug.LogError("[Steamworks.NET] Packsize Test returned false, the wrong version of Steamworks.NET is being run in this platform.", this); + } + if (!DllCheck.Test()) + { + Debug.LogError("[Steamworks.NET] DllCheck Test returned false, One or more of the Steamworks binaries seems to be the wrong version.", this); + } + try + { + if (SteamAPI.RestartAppIfNecessary(new AppId_t(945360U))) + { + Application.Quit(); + return; + } + } + catch (DllNotFoundException arg) + { + Debug.LogError("[Steamworks.NET] Could not load [lib]steam_api.dll/so/dylib. It's likely not in the correct location. Refer to the README for more details.\n" + arg, this); + Application.Quit(); + return; + } + this.m_bInitialized = SteamAPI.Init(); + if (!this.m_bInitialized) + { + Debug.LogError("[Steamworks.NET] SteamAPI_Init() failed. Refer to Valve's documentation or the comment above this line for more information.", this); + return; + } + SteamManager.s_EverInitialized = true; + } + + private void OnEnable() + { + if (SteamManager.s_instance == null) + { + SteamManager.s_instance = this; + } + if (!this.m_bInitialized) + { + return; + } + if (this.m_SteamAPIWarningMessageHook == null) + { + this.m_SteamAPIWarningMessageHook = new SteamAPIWarningMessageHook_t(SteamManager.SteamAPIDebugTextHook); + SteamClient.SetWarningMessageHook(this.m_SteamAPIWarningMessageHook); + } + } + + private void OnDestroy() + { + if (SteamManager.s_instance != this) + { + return; + } + SteamManager.s_instance = null; + if (!this.m_bInitialized) + { + return; + } + SteamAPI.Shutdown(); + } + + [ContextMenu("Shutdown")] + private void DoShutdown() + { + SteamAPI.Shutdown(); + } + + private void Update() + { + if (!this.m_bInitialized) + { + return; + } + SteamAPI.RunCallbacks(); + } +} diff --git a/Client/Assembly-CSharp/SteamPurchasingModule.cs b/Client/Assembly-CSharp/SteamPurchasingModule.cs new file mode 100644 index 0000000..b3d80f1 --- /dev/null +++ b/Client/Assembly-CSharp/SteamPurchasingModule.cs @@ -0,0 +1,118 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using Steamworks; +using UnityEngine; +using UnityEngine.Purchasing; +using UnityEngine.Purchasing.Extension; + +internal class SteamPurchasingModule : IPurchasingModule, IStore +{ + public const string Name = "Steam"; + + public Dictionary<string, uint> IdTranslator = new Dictionary<string, uint>(StringComparer.OrdinalIgnoreCase); + + private IStoreCallback storeCallback; + + private Callback<GameOverlayActivated_t> overlayCallback; + + private bool steamOverlayOpen; + + private StoreMenu parent; + + public SteamPurchasingModule(StoreMenu parent) + { + this.parent = parent; + } + + public void Configure(IPurchasingBinder binder) + { + binder.RegisterStore("Steam", this); + } + + public void FinishTransaction(ProductDefinition product, string transactionId) + { + } + + public void Initialize(IStoreCallback callback) + { + this.storeCallback = callback; + if (!SteamManager.Initialized || !SteamUtils.IsOverlayEnabled()) + { + this.storeCallback.OnSetupFailed(InitializationFailureReason.PurchasingUnavailable); + } + this.overlayCallback = Callback<GameOverlayActivated_t>.Create(new Callback<GameOverlayActivated_t>.DispatchDelegate(this.HandleOverlayActivate)); + } + + private void HandleOverlayActivate(GameOverlayActivated_t param) + { + this.steamOverlayOpen = (param.m_bActive > 0); + } + + public void Purchase(ProductDefinition product, string developerPayload) + { + if (!SteamUtils.IsOverlayEnabled()) + { + this.storeCallback.OnPurchaseFailed(new PurchaseFailureDescription(product.storeSpecificId, PurchaseFailureReason.PurchasingUnavailable, "Steam overlay is disabled, but required for in-game purchasing.")); + return; + } + uint value; + if (this.IdTranslator.TryGetValue(product.id, out value)) + { + AppId_t appId_t = new AppId_t(value); + SteamFriends.ActivateGameOverlayToStore(appId_t, EOverlayToStoreFlag.k_EOverlayToStoreFlag_AddToCartAndShow); + this.parent.StartCoroutine(this.WaitForDlcPurchase(product, appId_t)); + return; + } + this.storeCallback.OnPurchaseFailed(new PurchaseFailureDescription(product.storeSpecificId, PurchaseFailureReason.ProductUnavailable, "Couldn't find Product Id for " + product.id)); + } + + private IEnumerator WaitForDlcPurchase(ProductDefinition product, AppId_t appId) + { + while (!this.steamOverlayOpen) + { + SteamAPI.RunCallbacks(); + yield return null; + } + while (this.steamOverlayOpen) + { + SteamAPI.RunCallbacks(); + yield return null; + } + ulong num; + while (SteamApps.GetDlcDownloadProgress(appId, out num, out num)) + { + yield return null; + } + if (SteamApps.BIsDlcInstalled(appId)) + { + this.storeCallback.OnPurchaseSucceeded(product.id, "FakeReceipt", UnityEngine.Random.value.ToString()); + } + else + { + this.storeCallback.OnPurchaseFailed(new PurchaseFailureDescription(product.id, PurchaseFailureReason.UserCancelled, "Steam overlay closed without purchase completing")); + } + yield break; + } + + public void RetrieveProducts(ReadOnlyCollection<ProductDefinition> products) + { + if (!SteamManager.Initialized) + { + return; + } + List<ProductDescription> list = new List<ProductDescription>(products.Count); + for (int i = 0; i < products.Count; i++) + { + ProductDefinition productDefinition = products[i]; + uint value; + if (this.IdTranslator.TryGetValue(productDefinition.id, out value)) + { + bool flag = SteamApps.BIsDlcInstalled(new AppId_t(value)); + list.Add(new ProductDescription(productDefinition.id, new ProductMetadata("$2.99", null, null, "USD", 1m), flag ? "Bought" : null, null)); + } + } + this.storeCallback.OnProductsRetrieved(list); + } +} diff --git a/Client/Assembly-CSharp/StoreMenu.cs b/Client/Assembly-CSharp/StoreMenu.cs new file mode 100644 index 0000000..a67399d --- /dev/null +++ b/Client/Assembly-CSharp/StoreMenu.cs @@ -0,0 +1,409 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using PowerTools; +using UnityEngine; +using UnityEngine.Purchasing; +using UnityEngine.Purchasing.Extension; + +public class StoreMenu : MonoBehaviour, IStoreListener +{ + public PurchaseStates PurchaseState { get; private set; } + + public SpriteRenderer HatSlot; + + public SpriteRenderer SkinSlot; + + public SpriteAnim PetSlot; + + public TextRenderer ItemName; + + public SpriteRenderer PurchaseBackground; + + public TextRenderer PriceText; + + public PurchaseButton PurchasablePrefab; + + public SpriteRenderer HortLinePrefab; + + public TextRenderer LoadingText; + + public TextRenderer RestorePurchasesButton; + + public GameObject RestorePurchasesObj; + + public SpriteRenderer BannerPrefab; + + public Sprite HatBanner; + + public Sprite SkinsBanner; + + public Sprite HolidayBanner; + + public Sprite PetsBanner; + + public SpriteRenderer TopArrow; + + public SpriteRenderer BottomArrow; + + public const string BoughtAdsProductId = "bought_ads"; + + private IStoreController controller; + + private IExtensionProvider extensions; + + public Scroller Scroller; + + public Vector2 StartPositionVertical; + + public FloatRange XRange = new FloatRange(-1f, 1f); + + public int NumPerRow = 4; + + private PurchaseButton CurrentButton; + + private List<GameObject> AllObjects = new List<GameObject>(); + + private const float NormalHeight = -0.45f; + + private const float BoxHeight = -0.75f; + + public void Start() + { + this.PetSlot.gameObject.SetActive(false); + SteamPurchasingModule steamPurchasingModule = new SteamPurchasingModule(this); + foreach (PetBehaviour petBehaviour in DestroyableSingleton<HatManager>.Instance.AllPets) + { + if (petBehaviour.SteamId != 0U) + { + steamPurchasingModule.IdTranslator.Add(petBehaviour.ProdId, petBehaviour.SteamId); + } + } + ConfigurationBuilder configurationBuilder = ConfigurationBuilder.Instance(steamPurchasingModule, Array.Empty<IPurchasingModule>()); + foreach (PetBehaviour petBehaviour2 in DestroyableSingleton<HatManager>.Instance.AllPets) + { + if (!petBehaviour2.Free) + { + configurationBuilder.AddProduct(petBehaviour2.ProdId, ProductType.NonConsumable); + } + } + UnityPurchasing.Initialize(this, configurationBuilder); + this.PurchaseBackground.color = new Color(0.5f, 0.5f, 0.5f, 1f); + this.PriceText.Color = new Color(0.8f, 0.8f, 0.8f, 1f); + this.PriceText.Text = ""; + } + + public void Update() + { + this.TopArrow.enabled = !this.Scroller.AtTop; + this.BottomArrow.enabled = !this.Scroller.AtBottom; + } + + public void RestorePurchases() + { + } + + private void DestroySliderObjects() + { + for (int i = 0; i < this.AllObjects.Count; i++) + { + UnityEngine.Object.Destroy(this.AllObjects[i]); + } + this.AllObjects.Clear(); + } + + private void FinishRestoring() + { + this.ShowAllButtons(); + this.RestorePurchasesButton.Text = "Purchases Restored"; + } + + public void SetProduct(PurchaseButton button) + { + if (this.PurchaseState == PurchaseStates.Started) + { + return; + } + this.CurrentButton = button; + if (this.CurrentButton.Product is HatBehaviour) + { + HatBehaviour hatBehaviour = (HatBehaviour)this.CurrentButton.Product; + this.HatSlot.gameObject.SetActive(true); + this.SkinSlot.gameObject.SetActive(false); + this.PetSlot.gameObject.SetActive(false); + PlayerControl.SetHatImage(hatBehaviour, this.HatSlot); + this.ItemName.Text = (string.IsNullOrWhiteSpace(hatBehaviour.StoreName) ? hatBehaviour.name : hatBehaviour.StoreName); + if (hatBehaviour.RelatedSkin) + { + TextRenderer itemName = this.ItemName; + itemName.Text += " (Includes skin!)"; + this.SkinSlot.gameObject.SetActive(true); + PlayerControl.SetSkinImage(hatBehaviour.RelatedSkin, this.SkinSlot); + } + } + else if (this.CurrentButton.Product is SkinData) + { + SkinData skinData = (SkinData)this.CurrentButton.Product; + this.SkinSlot.gameObject.SetActive(true); + this.HatSlot.gameObject.SetActive(true); + this.PetSlot.gameObject.SetActive(false); + PlayerControl.SetHatImage(skinData.RelatedHat, this.HatSlot); + PlayerControl.SetSkinImage(skinData, this.SkinSlot); + this.ItemName.Text = (string.IsNullOrWhiteSpace(skinData.StoreName) ? skinData.name : skinData.StoreName); + } + else if (this.CurrentButton.Product is PetBehaviour) + { + PetBehaviour petBehaviour = (PetBehaviour)this.CurrentButton.Product; + this.SkinSlot.gameObject.SetActive(false); + this.HatSlot.gameObject.SetActive(false); + this.PetSlot.gameObject.SetActive(true); + SpriteRenderer component = this.PetSlot.GetComponent<SpriteRenderer>(); + component.material = new Material(petBehaviour.rend.sharedMaterial); + PlayerControl.SetPlayerMaterialColors((int)SaveManager.BodyColor, component); + this.PetSlot.Play(petBehaviour.idleClip, 1f); + this.ItemName.Text = (string.IsNullOrWhiteSpace(petBehaviour.StoreName) ? petBehaviour.name : petBehaviour.StoreName); + } + else + { + this.HatSlot.gameObject.SetActive(false); + this.SkinSlot.gameObject.SetActive(false); + this.PetSlot.gameObject.SetActive(false); + this.ItemName.Text = "Remove All Ads"; + } + if (button.Purchased) + { + this.PurchaseBackground.color = new Color(0.5f, 0.5f, 0.5f, 1f); + this.PriceText.Color = new Color(0.8f, 0.8f, 0.8f, 1f); + this.PriceText.Text = "Owned"; + return; + } + this.PurchaseBackground.color = Color.white; + this.PriceText.Color = Color.white; + this.PriceText.Text = button.Price; + } + + public void BuyProduct() + { + if (!this.CurrentButton || this.CurrentButton.Purchased || this.PurchaseState == PurchaseStates.Started) + { + return; + } + base.StartCoroutine(this.WaitForPurchaseAds(this.CurrentButton)); + } + + public IEnumerator WaitForPurchaseAds(PurchaseButton button) + { + this.PurchaseState = PurchaseStates.Started; + this.controller.InitiatePurchase(button.ProductId); + while (this.PurchaseState == PurchaseStates.Started) + { + yield return null; + } + if (this.PurchaseState == PurchaseStates.Success) + { + foreach (PurchaseButton purchaseButton in from p in this.AllObjects + select p.GetComponent<PurchaseButton>() into h + where h && h.ProductId == button.ProductId + select h) + { + purchaseButton.SetPurchased(); + } + } + this.SetProduct(button); + yield break; + } + + public void Close() + { + HatsTab hatsTab = UnityEngine.Object.FindObjectOfType<HatsTab>(); + if (hatsTab) + { + hatsTab.OnDisable(); + hatsTab.OnEnable(); + } + base.gameObject.SetActive(false); + } + + private void ShowAllButtons() + { + this.DestroySliderObjects(); + string text = ""; + try + { + text = "Couldn't fetch products"; + foreach (Product product in this.controller.products.all) + { + if (product != null && product.hasReceipt) + { + try + { + SaveManager.SetPurchased(product.definition.id); + } + catch + { + } + } + } + Vector3 vector = this.StartPositionVertical; + UnityEngine.Object.Destroy(this.RestorePurchasesObj); + text = "Couldn't fetch products"; + text = "Couldn't fetch pet data"; + vector.y += -0.375f; + PetBehaviour[] array = (from h in DestroyableSingleton<HatManager>.Instance.AllPets + where !h.Free + select h into p + orderby p.StoreName + select p).ToArray<PetBehaviour>(); + vector = this.InsertBanner(vector, this.PetsBanner); + Vector3 position = vector; + Product[] all; + Product[] allProducts = all; + IBuyable[] hats = array; + vector = this.InsertHatsFromList(position, allProducts, hats); + text = "Couldn't finalize menu"; + this.Scroller.YBounds.max = Mathf.Max(0f, -vector.y - 2.5f); + this.LoadingText.gameObject.SetActive(false); + } + catch (Exception ex) + { + Debug.Log(string.Concat(new object[] + { + "Exception: ", + text, + ": ", + ex + })); + this.DestroySliderObjects(); + this.LoadingText.gameObject.SetActive(true); + this.LoadingText.Text = "Loading Failed:\r\n" + text; + } + } + + private Vector3 InsertHortLine(Vector3 position) + { + position.x = 1.2f; + SpriteRenderer spriteRenderer = UnityEngine.Object.Instantiate<SpriteRenderer>(this.HortLinePrefab, this.Scroller.Inner); + spriteRenderer.transform.localPosition = position; + spriteRenderer.gameObject.SetActive(true); + position.y += -0.33749998f; + return position; + } + + private Vector3 InsertHatsFromList(Vector3 position, Product[] allProducts, IBuyable[] hats) + { + int num = 0; + for (int i = 0; i < hats.Length; i++) + { + IBuyable item = hats[i]; + Product product = allProducts.FirstOrDefault((Product p) => item.ProdId == p.definition.id); + if (product != null && product.definition != null && product.availableToPurchase) + { + int num2 = num % this.NumPerRow; + position.x = this.StartPositionVertical.x + this.XRange.Lerp((float)num2 / ((float)this.NumPerRow - 1f)); + if (num2 == 0 && num > 1) + { + position.y += -0.75f; + } + this.InsertProduct(position, product, item); + num++; + } + } + position.y += -0.75f; + return position; + } + + private void InsertProduct(Vector3 position, Product product, IBuyable item) + { + PurchaseButton purchaseButton = UnityEngine.Object.Instantiate<PurchaseButton>(this.PurchasablePrefab, this.Scroller.Inner); + this.AllObjects.Add(purchaseButton.gameObject); + purchaseButton.transform.localPosition = position; + purchaseButton.Parent = this; + PurchaseButton purchaseButton2 = purchaseButton; + string id = product.definition.id; + ProductMetadata metadata = product.metadata; + string name; + if (metadata == null) + { + name = null; + } + else + { + string localizedTitle = metadata.localizedTitle; + name = ((localizedTitle != null) ? localizedTitle.Replace("(Among Us)", "") : null); + } + ProductMetadata metadata2 = product.metadata; + purchaseButton2.SetItem(item, id, name, (metadata2 != null) ? metadata2.localizedPriceString : null, product.hasReceipt || SaveManager.GetPurchase(product.definition.id)); + } + + private Vector3 InsertBanner(Vector3 position, Sprite s) + { + position.x = this.StartPositionVertical.x; + SpriteRenderer spriteRenderer = UnityEngine.Object.Instantiate<SpriteRenderer>(this.BannerPrefab, this.Scroller.Inner); + spriteRenderer.sprite = s; + spriteRenderer.transform.localPosition = position; + position.y += -spriteRenderer.sprite.bounds.size.y; + this.AllObjects.Add(spriteRenderer.gameObject); + return position; + } + + public void OnInitialized(IStoreController controller, IExtensionProvider extensions) + { + this.controller = controller; + this.extensions = extensions; + if (this.controller == null || this.controller.products == null) + { + this.LoadingText.Text = "Product controller\r\nfailed to load"; + return; + } + this.ShowAllButtons(); + } + + public PurchaseProcessingResult ProcessPurchase(PurchaseEventArgs e) + { + this.PurchaseState = PurchaseStates.Success; + SaveManager.SetPurchased(e.purchasedProduct.definition.id); + return PurchaseProcessingResult.Complete; + } + + public void OnInitializeFailed(InitializationFailureReason error) + { + this.RestorePurchasesObj.SetActive(false); + this.LoadingText.gameObject.SetActive(true); + if (error == InitializationFailureReason.NoProductsAvailable) + { + this.LoadingText.Text = "Coming Soon!"; + return; + } + if (error == InitializationFailureReason.PurchasingUnavailable) + { + this.LoadingText.Text = "Loading Failed:\r\nSteam must be running and logged in to view products."; + return; + } + this.LoadingText.Text = "Loading Failed:\r\n" + error; + } + + public void OnPurchaseFailed(Product i, PurchaseFailureReason error) + { + if (error == PurchaseFailureReason.ProductUnavailable) + { + this.DestroySliderObjects(); + this.LoadingText.gameObject.SetActive(true); + this.LoadingText.Text = "Coming Soon!"; + } + else if (error == PurchaseFailureReason.PurchasingUnavailable) + { + this.DestroySliderObjects(); + this.LoadingText.gameObject.SetActive(true); + this.LoadingText.Text = "Steam overlay is required for in-game purchasing. You can still buy and install DLC in Steam."; + } + else + { + this.DestroySliderObjects(); + this.LoadingText.gameObject.SetActive(true); + this.LoadingText.Text = "Loading Failed:\r\n" + error; + } + Debug.LogError("Failed: " + error); + this.PurchaseState = PurchaseStates.Fail; + } +} diff --git a/Client/Assembly-CSharp/StringExtensions.cs b/Client/Assembly-CSharp/StringExtensions.cs new file mode 100644 index 0000000..dd37904 --- /dev/null +++ b/Client/Assembly-CSharp/StringExtensions.cs @@ -0,0 +1,32 @@ +using System; +using UnityEngine; + +public static class StringExtensions +{ + private static char[] buffer = new char[256]; + + public static string Lerp(string a, string b, float t) + { + int num = Mathf.Max(a.Length, b.Length); + int num2 = (int)Mathf.Lerp(0f, (float)num, t); + for (int i = 0; i < num; i++) + { + if (i < num2) + { + if (i < b.Length) + { + StringExtensions.buffer[i] = b[i]; + } + else + { + StringExtensions.buffer[i] = ' '; + } + } + else if (i < a.Length) + { + StringExtensions.buffer[i] = a[i]; + } + } + return new string(StringExtensions.buffer, 0, num); + } +} diff --git a/Client/Assembly-CSharp/StringNames.cs b/Client/Assembly-CSharp/StringNames.cs new file mode 100644 index 0000000..5c3c08b --- /dev/null +++ b/Client/Assembly-CSharp/StringNames.cs @@ -0,0 +1,168 @@ +using System; + +public enum StringNames +{ + ExitButton, + BackButton, + AvailableGamesLabel, + CreateGameButton, + FindGameButton, + EnterCode, + GhostIgnoreTasks, + GhostDoTasks, + GhostImpostor, + ImpostorTask, + FakeTasks, + TaskComplete, + ExileTextSP, + ExileTextSN, + ExileTextPP, + ExileTextPN, + NoExileSkip, + NoExileTie, + ImpostorsRemainS, + ImpostorsRemainP, + Hallway, + Storage, + Cafeteria, + Reactor, + UpperEngine, + Nav, + Admin, + Electrical, + LifeSupp, + Shields, + MedBay, + Security, + Weapons, + LowerEngine, + Comms, + Decontamination, + Launchpad, + LockerRoom, + Laboratory, + Balcony, + Office, + Greenhouse, + DivertPowerTo, + AcceptDivertedPower, + SubmitScan, + PrimeShields, + FuelEngines, + ChartCourse, + StartReactor, + SwipeCard, + ClearAsteroids, + UploadData, + DownloadData, + InspectSample, + EmptyChute, + EmptyGarbage, + AlignEngineOutput, + FixWiring, + CalibrateDistributor, + UnlockManifolds, + ResetReactor, + FixLights, + FixComms, + RestoreOxy, + CleanO2Filter, + StabilizeSteering, + AssembleArtifact, + SortSamples, + MeasureWeather, + EnterIdCode, + HowToPlayText1, + HowToPlayText2, + HowToPlayText5, + HowToPlayText6, + HowToPlayText7, + HowToPlayText81, + HowToPlayText82, + NumImpostorsS, + NumImpostorsP, + Crewmate, + Impostor, + Victory, + Defeat, + CrewmatesDisconnected, + ImpostorDisconnected, + HowToPlayText41, + HowToPlayText42, + HowToPlayText43, + HowToPlayText44, + HowToPlayTextMap, + HowToPlayTextCrew1, + HowToPlayTextCrew2, + HowToPlayTextCrew3, + HowToPlayTextCrew4, + HowToPlayTextCrew5, + HowToPlayTextCrew6, + HowToPlayTextImp1, + HowToPlayTextImp2, + HowToPlayTextImp3, + HowToPlayTextImp4, + HowToPlayTextImp5, + HowToPlayTextImp6, + HowToPlayTextImp7, + SettingsGeneral, + SettingsControls, + SettingsSound, + SettingsGraphics, + SettingsData, + SettingsCensorChat, + SettingsMusic, + SettingsSFX, + SettingsOn, + SettingsOff, + SettingsSendTelemetry, + SettingsControlMode, + SettingsTouchMode, + SettingsJoystickMode, + SettingsKeyboardMode, + SettingsFullscreen, + SettingsResolution, + SettingsApply, + SettingsPersonalizeAds, + SettingsLanguage, + SettingsJoystickSize, + SettingsMouseMode, + PlayerColor, + PlayerHat, + PlayerSkin, + PlayerPet, + GameSettings, + GameRecommendedSettings, + GameCustomSettings, + GameMapName, + GameNumImpostors, + GameNumMeetings, + GameDiscussTime, + GameVotingTime, + GamePlayerSpeed, + GameCrewLight, + GameImpostorLight, + GameKillCooldown, + GameKillDistance, + GameCommonTasks, + GameLongTasks, + GameShortTasks, + MatchMapName, + MatchLanguage, + MatchImpostors, + MatchMaxPlayers, + Cancel, + Confirm, + Limit, + RoomCode, + LeaveGame, + ReturnToGame, + LocalHelp, + OnlineHelp, + SettingsVSync, + EmergencyCount, + EmergencyNotReady, + EmergencyDuringCrisis, + EmergencyRequested, + GameEmergencyCooldown +} diff --git a/Client/Assembly-CSharp/StringOption.cs b/Client/Assembly-CSharp/StringOption.cs new file mode 100644 index 0000000..e2faa3e --- /dev/null +++ b/Client/Assembly-CSharp/StringOption.cs @@ -0,0 +1,60 @@ +using System; +using UnityEngine; + +public class StringOption : OptionBehaviour +{ + public TextRenderer TitleText; + + public TextRenderer ValueText; + + public string[] Values; + + public int Value; + + private int oldValue = -1; + + public void OnEnable() + { + this.TitleText.Text = DestroyableSingleton<TranslationController>.Instance.GetString(this.Title, Array.Empty<object>()); + this.ValueText.Text = this.Values[this.Value]; + GameOptionsData gameOptions = PlayerControl.GameOptions; + StringNames title = this.Title; + if (title == StringNames.GameMapName) + { + this.Value = (int)gameOptions.MapId; + return; + } + if (title == StringNames.GameKillDistance) + { + this.Value = gameOptions.KillDistance; + return; + } + Debug.Log("Ono, unrecognized setting: " + this.Title); + } + + private void FixedUpdate() + { + if (this.oldValue != this.Value) + { + this.oldValue = this.Value; + this.ValueText.Text = this.Values[this.Value]; + } + } + + public void Increase() + { + this.Value = Mathf.Clamp(this.Value + 1, 0, this.Values.Length - 1); + this.OnValueChanged(this); + } + + public void Decrease() + { + this.Value = Mathf.Clamp(this.Value - 1, 0, this.Values.Length - 1); + this.OnValueChanged(this); + } + + public override int GetInt() + { + return this.Value; + } +} diff --git a/Client/Assembly-CSharp/SubString.cs b/Client/Assembly-CSharp/SubString.cs new file mode 100644 index 0000000..6270112 --- /dev/null +++ b/Client/Assembly-CSharp/SubString.cs @@ -0,0 +1,77 @@ +using System; + +public struct SubString +{ + public readonly int Start; + + public readonly int Length; + + public readonly string Source; + + public SubString(string source, int start, int length) + { + this.Source = source; + this.Start = start; + this.Length = length; + } + + public override string ToString() + { + return this.Source.Substring(this.Start, this.Length); + } + + public int GetKvpValue() + { + int num = this.Start + this.Length; + for (int i = this.Start; i < num; i++) + { + if (this.Source[i] == '=') + { + i++; + return new SubString(this.Source, i, num - i).ToInt(); + } + } + throw new InvalidCastException(); + } + + public int ToInt() + { + int num = 0; + int num2 = this.Start + this.Length; + bool flag = false; + for (int i = this.Start; i < num2; i++) + { + char c = this.Source[i]; + if (c == '-') + { + flag = true; + } + else if (c >= '0' && c <= '9') + { + int num3 = (int)(c - '0'); + num = 10 * num + num3; + } + } + if (!flag) + { + return num; + } + return -num; + } + + public bool StartsWith(string v) + { + if (v.Length > this.Length) + { + return false; + } + for (int i = 0; i < v.Length; i++) + { + if (this.Source[i + this.Start] != v[i]) + { + return false; + } + } + return true; + } +} diff --git a/Client/Assembly-CSharp/SubStringReader.cs b/Client/Assembly-CSharp/SubStringReader.cs new file mode 100644 index 0000000..3d90f31 --- /dev/null +++ b/Client/Assembly-CSharp/SubStringReader.cs @@ -0,0 +1,51 @@ +using System; + +public class SubStringReader +{ + private readonly string Source; + + private int Position; + + public SubStringReader(string source) + { + this.Source = source; + } + + public SubString ReadLine() + { + int position = this.Position; + if (position >= this.Source.Length) + { + return default(SubString); + } + int num = this.Position; + int i = position; + while (i < this.Source.Length) + { + char c = this.Source[i]; + if (c == '\r') + { + num = i - 1; + this.Position = i + 1; + if (i + 1 < this.Source.Length && this.Source[i + 1] == '\n') + { + this.Position = i + 2; + break; + } + break; + } + else + { + if (c == '\n') + { + num = i - 1; + this.Position = i + 1; + break; + } + this.Position++; + i++; + } + } + return new SubString(this.Source, position, num - position); + } +} diff --git a/Client/Assembly-CSharp/SurvCamera.cs b/Client/Assembly-CSharp/SurvCamera.cs new file mode 100644 index 0000000..a5f0e1d --- /dev/null +++ b/Client/Assembly-CSharp/SurvCamera.cs @@ -0,0 +1,28 @@ +using System; +using PowerTools; +using UnityEngine; + +public class SurvCamera : MonoBehaviour +{ + public SpriteAnim Image; + + public float CamSize = 3f; + + public float CamAspect = 1f; + + public Vector3 Offset; + + public AnimationClip OnAnim; + + public AnimationClip OffAnim; + + public void Awake() + { + this.Image = base.GetComponent<SpriteAnim>(); + } + + public void SetAnimation(bool on) + { + this.Image.Play(on ? this.OnAnim : this.OffAnim, 1f); + } +} diff --git a/Client/Assembly-CSharp/SurveillanceMinigame.cs b/Client/Assembly-CSharp/SurveillanceMinigame.cs new file mode 100644 index 0000000..1fbde55 --- /dev/null +++ b/Client/Assembly-CSharp/SurveillanceMinigame.cs @@ -0,0 +1,140 @@ +using System; +using System.Collections; +using System.Linq; +using UnityEngine; + +public class SurveillanceMinigame : Minigame +{ + public Camera CameraPrefab; + + public GameObject Viewables; + + public MeshRenderer[] ViewPorts; + + public TextRenderer[] SabText; + + private ShipRoom[] FilteredRooms; + + private RenderTexture[] textures; + + public MeshRenderer FillQuad; + + public Material DefaultMaterial; + + public Material StaticMaterial; + + private bool isStatic; + + public override void Begin(PlayerTask task) + { + base.Begin(task); + this.FilteredRooms = (from i in ShipStatus.Instance.AllRooms + where i.survCamera + select i).ToArray<ShipRoom>(); + this.textures = new RenderTexture[this.FilteredRooms.Length]; + for (int j = 0; j < this.FilteredRooms.Length; j++) + { + ShipRoom shipRoom = this.FilteredRooms[j]; + Camera camera = UnityEngine.Object.Instantiate<Camera>(this.CameraPrefab); + camera.transform.SetParent(base.transform); + camera.transform.position = shipRoom.transform.position + shipRoom.survCamera.Offset; + camera.orthographicSize = shipRoom.survCamera.CamSize; + RenderTexture temporary = RenderTexture.GetTemporary((int)(256f * shipRoom.survCamera.CamAspect), 256, 16, RenderTextureFormat.ARGB32); + this.textures[j] = temporary; + camera.targetTexture = temporary; + this.ViewPorts[j].material.SetTexture("_MainTex", temporary); + } + if (!PlayerControl.LocalPlayer.Data.IsDead) + { + ShipStatus.Instance.RpcRepairSystem(SystemTypes.Security, 1); + } + } + + public void Update() + { + if (this.isStatic && !PlayerTask.PlayerHasHudTask(PlayerControl.LocalPlayer)) + { + this.isStatic = false; + for (int i = 0; i < this.ViewPorts.Length; i++) + { + this.ViewPorts[i].sharedMaterial = this.DefaultMaterial; + this.ViewPorts[i].material.SetTexture("_MainTex", this.textures[i]); + this.SabText[i].gameObject.SetActive(false); + } + return; + } + if (!this.isStatic && PlayerTask.PlayerHasHudTask(PlayerControl.LocalPlayer)) + { + this.isStatic = true; + for (int j = 0; j < this.ViewPorts.Length; j++) + { + this.ViewPorts[j].sharedMaterial = this.StaticMaterial; + this.SabText[j].gameObject.SetActive(true); + } + } + } + + protected override IEnumerator CoAnimateOpen() + { + this.Viewables.SetActive(false); + this.FillQuad.material.SetFloat("_Center", -5f); + this.FillQuad.material.SetColor("_Color2", Color.clear); + for (float timer = 0f; timer < 0.25f; timer += Time.deltaTime) + { + this.FillQuad.material.SetColor("_Color2", Color.Lerp(Color.clear, Color.black, timer / 0.25f)); + yield return null; + } + this.FillQuad.material.SetColor("_Color2", Color.black); + this.Viewables.SetActive(true); + for (float timer = 0f; timer < 0.1f; timer += Time.deltaTime) + { + this.FillQuad.material.SetFloat("_Center", Mathf.Lerp(-5f, 0f, timer / 0.1f)); + yield return null; + } + for (float timer = 0f; timer < 0.15f; timer += Time.deltaTime) + { + this.FillQuad.material.SetFloat("_Center", Mathf.Lerp(-3f, 0.4f, timer / 0.15f)); + yield return null; + } + this.FillQuad.material.SetFloat("_Center", 0.4f); + yield break; + } + + private IEnumerator CoAnimateClose() + { + for (float timer = 0f; timer < 0.1f; timer += Time.deltaTime) + { + this.FillQuad.material.SetFloat("_Center", Mathf.Lerp(0.4f, -5f, timer / 0.1f)); + yield return null; + } + this.Viewables.SetActive(false); + for (float timer = 0f; timer < 0.3f; timer += Time.deltaTime) + { + this.FillQuad.material.SetColor("_Color2", Color.Lerp(Color.black, Color.clear, timer / 0.3f)); + yield return null; + } + this.FillQuad.material.SetColor("_Color2", Color.clear); + yield break; + } + + protected override IEnumerator CoDestroySelf() + { + yield return this.CoAnimateClose(); + UnityEngine.Object.Destroy(base.gameObject); + yield break; + } + + public override void Close() + { + base.Close(); + ShipStatus.Instance.RpcRepairSystem(SystemTypes.Security, 2); + } + + public void OnDestroy() + { + for (int i = 0; i < this.textures.Length; i++) + { + this.textures[i].Release(); + } + } +} diff --git a/Client/Assembly-CSharp/SweepMinigame.cs b/Client/Assembly-CSharp/SweepMinigame.cs new file mode 100644 index 0000000..6499a3f --- /dev/null +++ b/Client/Assembly-CSharp/SweepMinigame.cs @@ -0,0 +1,123 @@ +using System; +using UnityEngine; + +public class SweepMinigame : Minigame +{ + public SpriteRenderer[] Spinners; + + public SpriteRenderer[] Shadows; + + public SpriteRenderer[] Lights; + + public HorizontalGauge[] Gauges; + + private int spinnerIdx; + + private float timer; + + public float SpinRate = 45f; + + private float initialTimer; + + public AudioClip SpinningSound; + + public AudioClip AcceptSound; + + public AudioClip RejectSound; + + public override void Begin(PlayerTask task) + { + base.Begin(task); + this.ResetGauges(); + if (Constants.ShouldPlaySfx()) + { + SoundManager.Instance.PlaySound(this.SpinningSound, true, 1f); + } + } + + public override void Close() + { + SoundManager.Instance.StopSound(this.SpinningSound); + base.Close(); + } + + public void FixedUpdate() + { + float num = Mathf.Clamp(2f - this.timer / 30f, 1f, 2f); + this.timer += Time.fixedDeltaTime * num; + if (this.spinnerIdx < this.Spinners.Length) + { + float num2 = this.CalcXPerc(); + this.Gauges[this.spinnerIdx].Value = ((num2 < 13f) ? 0.9f : 0.1f); + Quaternion localRotation = Quaternion.Euler(0f, 0f, this.timer * this.SpinRate); + this.Spinners[this.spinnerIdx].transform.localRotation = localRotation; + this.Shadows[this.spinnerIdx].transform.localRotation = localRotation; + this.Lights[this.spinnerIdx].enabled = (num2 < 13f); + } + for (int i = 0; i < this.Gauges.Length; i++) + { + HorizontalGauge horizontalGauge = this.Gauges[i]; + if (i < this.spinnerIdx) + { + horizontalGauge.Value = 0.95f; + } + if (i > this.spinnerIdx) + { + horizontalGauge.Value = 0.05f; + } + horizontalGauge.Value += (Mathf.PerlinNoise((float)i, Time.time * 51f) - 0.5f) * 0.025f; + } + } + + private float CalcXPerc() + { + int num = (int)(this.timer * this.SpinRate) % 360; + return (float)Mathf.Min(360 - num, num); + } + + public void HitButton(int i) + { + if (i != this.spinnerIdx) + { + return; + } + if (this.CalcXPerc() < 13f) + { + if (Constants.ShouldPlaySfx()) + { + SoundManager.Instance.PlaySound(this.AcceptSound, false, 1f); + } + this.Spinners[this.spinnerIdx].transform.localRotation = Quaternion.identity; + this.Shadows[this.spinnerIdx].transform.localRotation = Quaternion.identity; + this.spinnerIdx++; + this.timer = this.initialTimer; + if (this.spinnerIdx >= this.Gauges.Length) + { + this.MyNormTask.NextStep(); + base.StartCoroutine(base.CoStartClose(0.75f)); + return; + } + } + else + { + if (Constants.ShouldPlaySfx()) + { + SoundManager.Instance.PlaySound(this.RejectSound, false, 1f); + } + this.ResetGauges(); + } + } + + private void ResetGauges() + { + this.spinnerIdx = 0; + this.timer = FloatRange.Next(1f, 3f); + this.initialTimer = this.timer; + for (int i = 0; i < this.Gauges.Length; i++) + { + this.Lights[i].enabled = false; + this.Spinners[i].transform.localRotation = Quaternion.Euler(0f, 0f, this.timer * this.SpinRate); + this.Shadows[i].transform.localRotation = Quaternion.Euler(0f, 0f, this.timer * this.SpinRate); + } + } +} diff --git a/Client/Assembly-CSharp/SwitchMinigame.cs b/Client/Assembly-CSharp/SwitchMinigame.cs new file mode 100644 index 0000000..4013635 --- /dev/null +++ b/Client/Assembly-CSharp/SwitchMinigame.cs @@ -0,0 +1,97 @@ +using System; +using UnityEngine; + +public class SwitchMinigame : Minigame +{ + public Color OnColor = Color.green; + + public Color OffColor = new Color(0.1f, 0.3f, 0.1f); + + private ShipStatus ship; + + public SpriteRenderer[] switches; + + public SpriteRenderer[] lights; + + public RadioWaveBehaviour top; + + public HorizontalGauge middle; + + public FlatWaveBehaviour bottom; + + public override void Begin(PlayerTask task) + { + this.ship = UnityEngine.Object.FindObjectOfType<ShipStatus>(); + SwitchSystem switchSystem = this.ship.Systems[SystemTypes.Electrical] as SwitchSystem; + for (int i = 0; i < this.switches.Length; i++) + { + byte b = (byte)(1 << i); + int num = (int)(switchSystem.ActualSwitches & b); + this.lights[i].color = ((num == (int)(switchSystem.ExpectedSwitches & b)) ? this.OnColor : this.OffColor); + this.switches[i].flipY = (num >> i == 0); + } + } + + public void FixedUpdate() + { + if (this.amClosing != Minigame.CloseState.None) + { + return; + } + int num = 0; + SwitchSystem switchSystem = this.ship.Systems[SystemTypes.Electrical] as SwitchSystem; + for (int i = 0; i < this.switches.Length; i++) + { + byte b = (byte)(1 << i); + int num2 = (int)(switchSystem.ActualSwitches & b); + if (num2 == (int)(switchSystem.ExpectedSwitches & b)) + { + num++; + this.lights[i].color = this.OnColor; + } + else + { + this.lights[i].color = this.OffColor; + } + this.switches[i].flipY = (num2 >> i == 0); + } + float num3 = (float)num / (float)this.switches.Length; + this.bottom.Center = 0.47f * num3; + this.top.NoiseLevel = 1f - num3; + this.middle.Value = switchSystem.Level + (Mathf.PerlinNoise(0f, Time.time * 51f) - 0.5f) * 0.04f; + if (num == this.switches.Length) + { + base.StartCoroutine(base.CoStartClose(0.5f)); + } + } + + public void FlipSwitch(int switchIdx) + { + if (this.amClosing != Minigame.CloseState.None) + { + return; + } + int num = 0; + SwitchSystem switchSystem = this.ship.Systems[SystemTypes.Electrical] as SwitchSystem; + for (int i = 0; i < this.switches.Length; i++) + { + byte b = (byte)(1 << i); + if ((switchSystem.ActualSwitches & b) == (switchSystem.ExpectedSwitches & b)) + { + num++; + } + } + if (num == this.switches.Length) + { + return; + } + ShipStatus.Instance.RpcRepairSystem(SystemTypes.Electrical, (int)((byte)switchIdx)); + try + { + ((SabotageTask)this.MyTask).MarkContributed(); + } + catch + { + } + } +} diff --git a/Client/Assembly-CSharp/SwitchSystem.cs b/Client/Assembly-CSharp/SwitchSystem.cs new file mode 100644 index 0000000..0e400ad --- /dev/null +++ b/Client/Assembly-CSharp/SwitchSystem.cs @@ -0,0 +1,107 @@ +using System; +using Hazel; + +public class SwitchSystem : ISystemType, IActivatable +{ + public float Level + { + get + { + return (float)this.Value / 255f; + } + } + + public bool IsActive + { + get + { + return this.ExpectedSwitches != this.ActualSwitches; + } + } + + public const byte MaxValue = 255; + + public const int NumSwitches = 5; + + public const byte DamageSystem = 128; + + public const byte SwitchesMask = 31; + + public float DetoriorationTime = 0.03f; + + public byte Value = byte.MaxValue; + + private float timer; + + public byte ExpectedSwitches; + + public byte ActualSwitches; + + public SwitchSystem() + { + Random random = new Random(); + this.ExpectedSwitches = (byte)(random.Next() & 31); + this.ActualSwitches = this.ExpectedSwitches; + } + + public bool Detoriorate(float deltaTime) + { + this.timer += deltaTime; + if (this.timer >= this.DetoriorationTime) + { + this.timer = 0f; + if (this.ExpectedSwitches != this.ActualSwitches) + { + if (this.Value > 0) + { + this.Value = (byte)Math.Max((int)(this.Value - 3), 0); + } + if (!SwitchSystem.HasTask<ElectricTask>()) + { + PlayerControl.LocalPlayer.AddSystemTask(SystemTypes.Electrical); + } + } + else if (this.Value < 255) + { + this.Value = (byte)Math.Min((int)(this.Value + 3), 255); + } + } + return false; + } + + public void RepairDamage(PlayerControl player, byte amount) + { + if (amount.HasBit(128)) + { + this.ActualSwitches ^= (amount & 31); + return; + } + this.ActualSwitches ^= (byte)(1 << (int)amount); + } + + public void Serialize(MessageWriter writer, bool initialState) + { + writer.Write(this.ExpectedSwitches); + writer.Write(this.ActualSwitches); + writer.Write(this.Value); + } + + public void Deserialize(MessageReader reader, bool initialState) + { + this.ExpectedSwitches = reader.ReadByte(); + this.ActualSwitches = reader.ReadByte(); + this.Value = reader.ReadByte(); + } + + protected static bool HasTask<T>() + { + for (int i = PlayerControl.LocalPlayer.myTasks.Count - 1; i > 0; i--) + { + if (PlayerControl.LocalPlayer.myTasks[i] is T) + { + return true; + } + } + return false; + } +} diff --git a/Client/Assembly-CSharp/SystemConsole.cs b/Client/Assembly-CSharp/SystemConsole.cs new file mode 100644 index 0000000..e0b4c10 --- /dev/null +++ b/Client/Assembly-CSharp/SystemConsole.cs @@ -0,0 +1,77 @@ +using System; +using UnityEngine; + +public class SystemConsole : MonoBehaviour, IUsable +{ + public float UsableDistance + { + get + { + return this.usableDistance; + } + } + + public float PercentCool + { + get + { + return 0f; + } + } + + public float usableDistance = 1f; + + public bool FreeplayOnly; + + public SpriteRenderer Image; + + public Minigame MinigamePrefab; + + public void Start() + { + if (this.FreeplayOnly && !DestroyableSingleton<TutorialManager>.InstanceExists) + { + UnityEngine.Object.Destroy(base.gameObject); + } + } + + public void SetOutline(bool on, bool mainTarget) + { + if (this.Image) + { + this.Image.material.SetFloat("_Outline", (float)(on ? 1 : 0)); + this.Image.material.SetColor("_OutlineColor", Color.white); + this.Image.material.SetColor("_AddColor", mainTarget ? Color.white : Color.clear); + } + } + + public float CanUse(GameData.PlayerInfo pc, out bool canUse, out bool couldUse) + { + float num = float.MaxValue; + PlayerControl @object = pc.Object; + couldUse = (pc.Object.CanMove && (!pc.IsDead || !(this.MinigamePrefab is EmergencyMinigame))); + canUse = couldUse; + if (canUse) + { + num = Vector2.Distance(@object.GetTruePosition(), base.transform.position); + canUse &= (num <= this.UsableDistance); + } + return num; + } + + public void Use() + { + bool flag; + bool flag2; + this.CanUse(PlayerControl.LocalPlayer.Data, out flag, out flag2); + if (!flag) + { + return; + } + PlayerControl.LocalPlayer.NetTransform.Halt(); + Minigame minigame = UnityEngine.Object.Instantiate<Minigame>(this.MinigamePrefab); + minigame.transform.SetParent(Camera.main.transform, false); + minigame.transform.localPosition = new Vector3(0f, 0f, -50f); + minigame.Begin(null); + } +} diff --git a/Client/Assembly-CSharp/SystemTypeHelpers.cs b/Client/Assembly-CSharp/SystemTypeHelpers.cs new file mode 100644 index 0000000..d462322 --- /dev/null +++ b/Client/Assembly-CSharp/SystemTypeHelpers.cs @@ -0,0 +1,7 @@ +using System; +using System.Linq; + +public static class SystemTypeHelpers +{ + public static readonly SystemTypes[] AllTypes = Enum.GetValues(typeof(SystemTypes)).Cast<SystemTypes>().ToArray<SystemTypes>(); +} diff --git a/Client/Assembly-CSharp/SystemTypes.cs b/Client/Assembly-CSharp/SystemTypes.cs new file mode 100644 index 0000000..f536ac2 --- /dev/null +++ b/Client/Assembly-CSharp/SystemTypes.cs @@ -0,0 +1,30 @@ +using System; + +public enum SystemTypes : byte +{ + Hallway, + Storage, + Cafeteria, + Reactor, + UpperEngine, + Nav, + Admin, + Electrical, + LifeSupp, + Shields, + MedBay, + Security, + Weapons, + LowerEngine, + Comms, + ShipTasks, + Doors, + Sabotage, + Decontamination, + Launchpad, + LockerRoom, + Laboratory, + Balcony, + Office, + Greenhouse +} diff --git a/Client/Assembly-CSharp/TabButton.cs b/Client/Assembly-CSharp/TabButton.cs new file mode 100644 index 0000000..0d6efb5 --- /dev/null +++ b/Client/Assembly-CSharp/TabButton.cs @@ -0,0 +1,10 @@ +using System; +using UnityEngine; + +[Serializable] +public class TabButton +{ + public SpriteRenderer Button; + + public GameObject Tab; +} diff --git a/Client/Assembly-CSharp/TabGroup.cs b/Client/Assembly-CSharp/TabGroup.cs new file mode 100644 index 0000000..066e250 --- /dev/null +++ b/Client/Assembly-CSharp/TabGroup.cs @@ -0,0 +1,25 @@ +using System; +using UnityEngine; + +public class TabGroup : MonoBehaviour +{ + public SpriteRenderer Button; + + public ButtonRolloverHandler Rollover; + + public GameObject Content; + + internal void Close() + { + this.Button.color = Color.white; + this.Rollover.OutColor = Color.white; + this.Content.SetActive(false); + } + + internal void Open() + { + this.Button.color = Color.green; + this.Rollover.OutColor = Color.green; + this.Content.SetActive(true); + } +} diff --git a/Client/Assembly-CSharp/TaskAddButton.cs b/Client/Assembly-CSharp/TaskAddButton.cs new file mode 100644 index 0000000..60e54fc --- /dev/null +++ b/Client/Assembly-CSharp/TaskAddButton.cs @@ -0,0 +1,109 @@ +using System; +using UnityEngine; + +public class TaskAddButton : MonoBehaviour +{ + public TextRenderer Text; + + public SpriteRenderer Overlay; + + public Sprite CheckImage; + + public Sprite ExImage; + + public PlayerTask MyTask; + + public bool ImpostorTask; + + public void Start() + { + if (this.ImpostorTask) + { + GameData.PlayerInfo data = PlayerControl.LocalPlayer.Data; + this.Overlay.enabled = data.IsImpostor; + this.Overlay.sprite = this.CheckImage; + return; + } + PlayerTask playerTask = this.FindTaskByType(); + if (playerTask) + { + this.Overlay.enabled = true; + this.Overlay.sprite = (playerTask.IsComplete ? this.CheckImage : this.ExImage); + return; + } + this.Overlay.enabled = false; + } + + public void AddTask() + { + if (this.ImpostorTask) + { + GameData.PlayerInfo data = PlayerControl.LocalPlayer.Data; + if (data.IsImpostor) + { + PlayerControl.LocalPlayer.RemoveInfected(); + this.Overlay.enabled = false; + return; + } + PlayerControl.LocalPlayer.RpcSetInfected(new GameData.PlayerInfo[] + { + data + }); + this.Overlay.enabled = true; + return; + } + else + { + PlayerTask playerTask = this.FindTaskByType(); + if (!playerTask) + { + PlayerTask playerTask2 = UnityEngine.Object.Instantiate<PlayerTask>(this.MyTask, PlayerControl.LocalPlayer.transform); + PlayerTask playerTask3 = playerTask2; + PlayerControl localPlayer = PlayerControl.LocalPlayer; + uint taskIdCount = localPlayer.TaskIdCount; + localPlayer.TaskIdCount = taskIdCount + 1U; + playerTask3.Id = taskIdCount; + playerTask2.Owner = PlayerControl.LocalPlayer; + playerTask2.Initialize(); + PlayerControl.LocalPlayer.myTasks.Add(playerTask2); + GameData.Instance.TutOnlyAddTask(PlayerControl.LocalPlayer.PlayerId, playerTask2.Id); + this.Overlay.sprite = this.ExImage; + this.Overlay.enabled = true; + return; + } + PlayerControl.LocalPlayer.RemoveTask(playerTask); + this.Overlay.enabled = false; + return; + } + } + + private PlayerTask FindTaskByType() + { + for (int i = PlayerControl.LocalPlayer.myTasks.Count - 1; i > -1; i--) + { + PlayerTask playerTask = PlayerControl.LocalPlayer.myTasks[i]; + if (playerTask.TaskType == this.MyTask.TaskType) + { + if (playerTask.TaskType == TaskTypes.DivertPower) + { + if (((DivertPowerTask)playerTask).TargetSystem == ((DivertPowerTask)this.MyTask).TargetSystem) + { + return playerTask; + } + } + else + { + if (playerTask.TaskType != TaskTypes.UploadData) + { + return playerTask; + } + if (playerTask.StartAt == this.MyTask.StartAt) + { + return playerTask; + } + } + } + } + return null; + } +} diff --git a/Client/Assembly-CSharp/TaskAdderGame.cs b/Client/Assembly-CSharp/TaskAdderGame.cs new file mode 100644 index 0000000..b40a715 --- /dev/null +++ b/Client/Assembly-CSharp/TaskAdderGame.cs @@ -0,0 +1,168 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using UnityEngine; + +public class TaskAdderGame : Minigame +{ + public TextRenderer PathText; + + public TaskFolder RootFolderPrefab; + + public TaskAddButton TaskPrefab; + + public Transform TaskParent; + + public List<TaskFolder> Heirarchy = new List<TaskFolder>(); + + public List<Transform> ActiveItems = new List<Transform>(); + + public TaskAddButton InfectedButton; + + public float folderWidth; + + public float fileWidth; + + public float lineWidth; + + public float lineHeight; + + private TaskFolder Root; + + public override void Begin(PlayerTask t) + { + base.Begin(t); + this.Root = UnityEngine.Object.Instantiate<TaskFolder>(this.RootFolderPrefab, base.transform); + this.Root.gameObject.SetActive(false); + Dictionary<SystemTypes, TaskFolder> folders = new Dictionary<SystemTypes, TaskFolder>(); + this.PopulateRoot(this.Root, folders, ShipStatus.Instance.CommonTasks); + this.PopulateRoot(this.Root, folders, ShipStatus.Instance.LongTasks); + this.PopulateRoot(this.Root, folders, ShipStatus.Instance.NormalTasks); + this.Root.SubFolders = (from f in this.Root.SubFolders + orderby f.FolderName + select f).ToList<TaskFolder>(); + this.ShowFolder(this.Root); + } + + private void PopulateRoot(TaskFolder rootFolder, Dictionary<SystemTypes, TaskFolder> folders, NormalPlayerTask[] taskList) + { + foreach (NormalPlayerTask normalPlayerTask in taskList) + { + SystemTypes systemTypes = normalPlayerTask.StartAt; + if (normalPlayerTask is DivertPowerTask) + { + systemTypes = ((DivertPowerTask)normalPlayerTask).TargetSystem; + } + if (systemTypes == SystemTypes.LowerEngine) + { + systemTypes = SystemTypes.UpperEngine; + } + TaskFolder taskFolder; + if (!folders.TryGetValue(systemTypes, out taskFolder)) + { + taskFolder = (folders[systemTypes] = UnityEngine.Object.Instantiate<TaskFolder>(this.RootFolderPrefab, base.transform)); + taskFolder.gameObject.SetActive(false); + if (systemTypes == SystemTypes.UpperEngine) + { + taskFolder.FolderName = "Engines"; + } + else + { + taskFolder.FolderName = DestroyableSingleton<TranslationController>.Instance.GetString(systemTypes); + } + rootFolder.SubFolders.Add(taskFolder); + } + taskFolder.Children.Add(normalPlayerTask); + } + } + + public void GoToRoot() + { + this.Heirarchy.Clear(); + this.ShowFolder(this.Root); + } + + public void GoUpOne() + { + if (this.Heirarchy.Count > 1) + { + TaskFolder taskFolder = this.Heirarchy[this.Heirarchy.Count - 2]; + this.Heirarchy.RemoveAt(this.Heirarchy.Count - 1); + this.Heirarchy.RemoveAt(this.Heirarchy.Count - 1); + this.ShowFolder(taskFolder); + } + } + + public void ShowFolder(TaskFolder taskFolder) + { + StringBuilder stringBuilder = new StringBuilder(64); + this.Heirarchy.Add(taskFolder); + for (int i = 0; i < this.Heirarchy.Count; i++) + { + stringBuilder.Append(this.Heirarchy[i].FolderName); + stringBuilder.Append("\\"); + } + this.PathText.Text = stringBuilder.ToString(); + for (int j = 0; j < this.ActiveItems.Count; j++) + { + UnityEngine.Object.Destroy(this.ActiveItems[j].gameObject); + } + this.ActiveItems.Clear(); + float num = 0f; + float num2 = 0f; + for (int k = 0; k < taskFolder.SubFolders.Count; k++) + { + TaskFolder taskFolder2 = UnityEngine.Object.Instantiate<TaskFolder>(taskFolder.SubFolders[k], this.TaskParent); + taskFolder2.gameObject.SetActive(true); + taskFolder2.Parent = this; + taskFolder2.transform.localPosition = new Vector3(num, num2, 0f); + taskFolder2.transform.localScale = Vector3.one; + num += this.folderWidth; + if (num > this.lineWidth) + { + num = 0f; + num2 += this.lineHeight; + } + this.ActiveItems.Add(taskFolder2.transform); + } + List<PlayerTask> list = (from t in taskFolder.Children + orderby t.TaskType.ToString() + select t).ToList<PlayerTask>(); + for (int l = 0; l < list.Count; l++) + { + TaskAddButton taskAddButton = UnityEngine.Object.Instantiate<TaskAddButton>(this.TaskPrefab); + taskAddButton.MyTask = list[l]; + if (taskAddButton.MyTask.TaskType == TaskTypes.DivertPower) + { + SystemTypes targetSystem = ((DivertPowerTask)taskAddButton.MyTask).TargetSystem; + taskAddButton.Text.Text = DestroyableSingleton<TranslationController>.Instance.GetString(StringNames.DivertPowerTo, Array.Empty<object>()) + " " + DestroyableSingleton<TranslationController>.Instance.GetString(targetSystem); + } + else + { + taskAddButton.Text.Text = DestroyableSingleton<TranslationController>.Instance.GetString(taskAddButton.MyTask.TaskType); + } + this.AddFileAsChild(taskAddButton, ref num, ref num2); + } + if (this.Heirarchy.Count == 1) + { + TaskAddButton taskAddButton2 = UnityEngine.Object.Instantiate<TaskAddButton>(this.InfectedButton); + taskAddButton2.Text.Text = "Be_Impostor.exe"; + this.AddFileAsChild(taskAddButton2, ref num, ref num2); + } + } + + private void AddFileAsChild(TaskAddButton item, ref float xCursor, ref float yCursor) + { + item.transform.SetParent(this.TaskParent); + item.transform.localPosition = new Vector3(xCursor, yCursor, 0f); + item.transform.localScale = Vector3.one; + xCursor += this.fileWidth; + if (xCursor > this.lineWidth) + { + xCursor = 0f; + yCursor -= this.lineHeight; + } + this.ActiveItems.Add(item.transform); + } +} diff --git a/Client/Assembly-CSharp/TaskFolder.cs b/Client/Assembly-CSharp/TaskFolder.cs new file mode 100644 index 0000000..91f3f08 --- /dev/null +++ b/Client/Assembly-CSharp/TaskFolder.cs @@ -0,0 +1,31 @@ +using System; +using System.Collections.Generic; +using UnityEngine; + +public class TaskFolder : MonoBehaviour +{ + public string FolderName; + + public TextRenderer Text; + + public TaskAdderGame Parent; + + public List<TaskFolder> SubFolders = new List<TaskFolder>(); + + public List<PlayerTask> Children = new List<PlayerTask>(); + + public void Start() + { + this.Text.Text = this.FolderName; + } + + public void OnClick() + { + this.Parent.ShowFolder(this); + } + + internal List<TaskFolder> OrderBy() + { + throw new NotImplementedException(); + } +} diff --git a/Client/Assembly-CSharp/TaskPanelBehaviour.cs b/Client/Assembly-CSharp/TaskPanelBehaviour.cs new file mode 100644 index 0000000..65fb0fd --- /dev/null +++ b/Client/Assembly-CSharp/TaskPanelBehaviour.cs @@ -0,0 +1,52 @@ +using System; +using UnityEngine; + +public class TaskPanelBehaviour : MonoBehaviour +{ + public Vector3 OpenPosition; + + public Vector3 ClosedPosition; + + public SpriteRenderer background; + + public SpriteRenderer tab; + + public TextRenderer TaskText; + + public bool open; + + private float timer; + + public float Duration; + + private void Update() + { + this.background.transform.localScale = new Vector3(this.TaskText.Width + 0.2f, this.TaskText.Height + 0.2f, 1f); + Vector3 vector = this.background.sprite.bounds.extents; + vector.y = -vector.y; + vector = vector.Mul(this.background.transform.localScale); + this.background.transform.localPosition = vector; + Vector3 vector2 = this.tab.sprite.bounds.extents; + vector2 = vector2.Mul(this.tab.transform.localScale); + vector2.y = -vector2.y; + vector2.x += vector.x * 2f; + this.tab.transform.localPosition = vector2; + this.ClosedPosition.y = (this.OpenPosition.y = 0.6f); + this.ClosedPosition.x = -this.background.sprite.bounds.size.x * this.background.transform.localScale.x; + if (this.open) + { + this.timer = Mathf.Min(1f, this.timer + Time.deltaTime / this.Duration); + } + else + { + this.timer = Mathf.Max(0f, this.timer - Time.deltaTime / this.Duration); + } + Vector3 relativePos = new Vector3(Mathf.SmoothStep(this.ClosedPosition.x, this.OpenPosition.x, this.timer), Mathf.SmoothStep(this.ClosedPosition.y, this.OpenPosition.y, this.timer), this.OpenPosition.z); + base.transform.localPosition = AspectPosition.ComputePosition(AspectPosition.EdgeAlignments.LeftTop, relativePos); + } + + public void ToggleOpen() + { + this.open = !this.open; + } +} diff --git a/Client/Assembly-CSharp/TaskSet.cs b/Client/Assembly-CSharp/TaskSet.cs new file mode 100644 index 0000000..9585c7b --- /dev/null +++ b/Client/Assembly-CSharp/TaskSet.cs @@ -0,0 +1,9 @@ +using System; + +[Serializable] +public class TaskSet +{ + public TaskTypes taskType; + + public IntRange taskStep = new IntRange(0, 0); +} diff --git a/Client/Assembly-CSharp/TaskTypes.cs b/Client/Assembly-CSharp/TaskTypes.cs new file mode 100644 index 0000000..67d35db --- /dev/null +++ b/Client/Assembly-CSharp/TaskTypes.cs @@ -0,0 +1,31 @@ +using System; + +public enum TaskTypes +{ + SubmitScan, + PrimeShields, + FuelEngines, + ChartCourse, + StartReactor, + SwipeCard, + ClearAsteroids, + UploadData, + InspectSample, + EmptyChute, + EmptyGarbage, + AlignEngineOutput, + FixWiring, + CalibrateDistributor, + DivertPower, + UnlockManifolds, + ResetReactor, + FixLights, + CleanO2Filter, + FixComms, + RestoreOxy, + StabilizeSteering, + AssembleArtifact, + SortSamples, + MeasureWeather, + EnterIdCode +} diff --git a/Client/Assembly-CSharp/TaskTypesHelpers.cs b/Client/Assembly-CSharp/TaskTypesHelpers.cs new file mode 100644 index 0000000..ba8eda0 --- /dev/null +++ b/Client/Assembly-CSharp/TaskTypesHelpers.cs @@ -0,0 +1,7 @@ +using System; +using System.Linq; + +public static class TaskTypesHelpers +{ + public static readonly TaskTypes[] AllTypes = Enum.GetValues(typeof(TaskTypes)).Cast<TaskTypes>().ToArray<TaskTypes>(); +} diff --git a/Client/Assembly-CSharp/TempData.cs b/Client/Assembly-CSharp/TempData.cs new file mode 100644 index 0000000..46d333e --- /dev/null +++ b/Client/Assembly-CSharp/TempData.cs @@ -0,0 +1,74 @@ +using System; +using System.Collections.Generic; + +public static class TempData +{ + public static DeathReason LastDeathReason; + + public static GameOverReason EndReason = GameOverReason.HumansByTask; + + public static bool showAd; + + public static List<WinningPlayerData> winners = new List<WinningPlayerData> + { + new WinningPlayerData + { + Name = "WWWWWWWWWW", + ColorId = 0, + SkinId = 0U, + IsDead = true + }, + new WinningPlayerData + { + Name = "WWWWWWWWWW", + ColorId = 1, + SkinId = 1U, + IsDead = true + }, + new WinningPlayerData + { + Name = "WWWWWWWWWW", + ColorId = 2, + SkinId = 2U, + IsDead = true + }, + new WinningPlayerData + { + Name = "WWWWWWWWWW", + ColorId = 3, + SkinId = 0U + }, + new WinningPlayerData + { + Name = "WWWWWWWWWW", + ColorId = 4, + SkinId = 1U + }, + new WinningPlayerData + { + Name = "WWWWWWWWWW", + ColorId = 5, + SkinId = 2U + }, + new WinningPlayerData + { + Name = "WWWWWWWWWW", + ColorId = 6 + }, + new WinningPlayerData + { + Name = "WWWWWWWWWW", + ColorId = 7 + }, + new WinningPlayerData + { + Name = "WWWWWWWWWW", + ColorId = 8 + } + }; + + public static bool DidHumansWin(GameOverReason reason) + { + return reason == GameOverReason.HumansByTask || reason == GameOverReason.HumansByVote; + } +} diff --git a/Client/Assembly-CSharp/TextBox.cs b/Client/Assembly-CSharp/TextBox.cs new file mode 100644 index 0000000..29e98ab --- /dev/null +++ b/Client/Assembly-CSharp/TextBox.cs @@ -0,0 +1,257 @@ +using System; +using System.Collections.Generic; +using System.Text; +using UnityEngine; +using UnityEngine.UI; + +public class TextBox : MonoBehaviour, IFocusHolder +{ + public float TextHeight + { + get + { + return this.outputText.Height; + } + } + + public static readonly HashSet<char> SymbolChars = new HashSet<char> + { + '?', + '!', + ',', + '.', + '\'', + ':', + ';', + '(', + ')', + '/', + '\\', + '%', + '^', + '&', + '-', + '=' + }; + + public string text; + + private string compoText = ""; + + public int characterLimit = -1; + + [SerializeField] + private TextRenderer outputText; + + public SpriteRenderer Background; + + public MeshRenderer Pipe; + + private float pipeBlinkTimer; + + public bool ClearOnFocus; + + public bool ForceUppercase; + + public Button.ButtonClickedEvent OnEnter; + + public Button.ButtonClickedEvent OnChange; + + public Button.ButtonClickedEvent OnFocusLost; + + private TouchScreenKeyboard keyboard; + + public bool AllowSymbols; + + public bool IpMode; + + private Collider2D[] colliders; + + private bool hasFocus; + + private StringBuilder tempTxt = new StringBuilder(); + + public void Start() + { + this.colliders = base.GetComponents<Collider2D>(); + DestroyableSingleton<PassiveButtonManager>.Instance.RegisterOne(this); + if (this.Pipe) + { + this.Pipe.enabled = false; + } + } + + public void OnDestroy() + { + if (this.keyboard != null) + { + this.keyboard.active = false; + this.keyboard = null; + } + if (DestroyableSingleton<PassiveButtonManager>.InstanceExists) + { + DestroyableSingleton<PassiveButtonManager>.Instance.RemoveOne(this); + } + } + + public void Clear() + { + this.SetText(string.Empty, string.Empty); + } + + public void Update() + { + if (!this.hasFocus) + { + return; + } + string inputString = Input.inputString; + if (inputString.Length > 0 || this.compoText != Input.compositionString) + { + if (this.text == null || this.text == "Enter Name") + { + this.text = ""; + } + this.SetText(this.text + inputString, Input.compositionString); + } + if (this.Pipe && this.hasFocus) + { + this.pipeBlinkTimer += Time.deltaTime * 2f; + this.Pipe.enabled = ((int)this.pipeBlinkTimer % 2 == 0); + } + } + + public void GiveFocus() + { + Input.imeCompositionMode = IMECompositionMode.On; + if (this.hasFocus) + { + return; + } + if (this.ClearOnFocus) + { + this.text = string.Empty; + this.compoText = string.Empty; + this.outputText.Text = string.Empty; + } + this.hasFocus = true; + if (TouchScreenKeyboard.isSupported) + { + this.keyboard = TouchScreenKeyboard.Open(this.text); + } + if (this.Background) + { + this.Background.color = Color.green; + } + this.pipeBlinkTimer = 0f; + if (this.Pipe) + { + this.Pipe.transform.localPosition = this.outputText.CursorPos; + } + } + + public void LoseFocus() + { + if (!this.hasFocus) + { + return; + } + Input.imeCompositionMode = IMECompositionMode.Off; + if (this.compoText.Length > 0) + { + this.SetText(this.text + this.compoText, ""); + this.compoText = string.Empty; + } + this.hasFocus = false; + if (this.keyboard != null) + { + this.keyboard.active = false; + this.keyboard = null; + } + if (this.Background) + { + this.Background.color = Color.white; + } + if (this.Pipe) + { + this.Pipe.enabled = false; + } + this.OnFocusLost.Invoke(); + } + + public bool CheckCollision(Vector2 pt) + { + for (int i = 0; i < this.colliders.Length; i++) + { + if (this.colliders[i].OverlapPoint(pt)) + { + return true; + } + } + return false; + } + + public void SetText(string input, string inputCompo = "") + { + bool flag = false; + char c = ' '; + this.tempTxt.Clear(); + foreach (char c2 in input) + { + if (c != ' ' || c2 != ' ') + { + if (c2 == '\r' || c2 == '\n') + { + flag = true; + } + if (c2 == '\b') + { + this.tempTxt.Length = Math.Max(this.tempTxt.Length - 1, 0); + } + if (this.ForceUppercase) + { + c2 = char.ToUpperInvariant(c2); + } + if (this.IsCharAllowed(c2)) + { + this.tempTxt.Append(c2); + c = c2; + } + } + } + if (this.characterLimit > 0) + { + this.tempTxt.Length = Math.Min(this.tempTxt.Length, this.characterLimit); + } + input = this.tempTxt.ToString(); + if (!input.Equals(this.text) || !inputCompo.Equals(this.compoText)) + { + this.text = input; + this.compoText = inputCompo; + this.outputText.Text = this.text + "[FF0000FF]" + this.compoText + "[]"; + this.outputText.RefreshMesh(); + if (this.keyboard != null) + { + this.keyboard.text = this.text; + } + this.OnChange.Invoke(); + } + if (flag) + { + this.OnEnter.Invoke(); + } + if (this.Pipe) + { + this.Pipe.transform.localPosition = this.outputText.CursorPos; + } + } + + public bool IsCharAllowed(char i) + { + if (this.IpMode) + { + return (i >= '0' && i <= '9') || i == '.'; + } + return i == ' ' || (i >= 'A' && i <= 'Z') || (i >= 'a' && i <= 'z') || (i >= '0' && i <= '9') || (i >= 'À' && i <= 'ÿ') || (i >= 'Ѐ' && i <= 'џ') || (i >= 'ㄱ' && i <= 'ㆎ') || (i >= '가' && i <= '힣') || (this.AllowSymbols && TextBox.SymbolChars.Contains(i)); + } +} diff --git a/Client/Assembly-CSharp/TextController.cs b/Client/Assembly-CSharp/TextController.cs new file mode 100644 index 0000000..c98db4e --- /dev/null +++ b/Client/Assembly-CSharp/TextController.cs @@ -0,0 +1,130 @@ +using System; +using UnityEngine; + +[RequireComponent(typeof(MeshFilter))] +[RequireComponent(typeof(MeshRenderer))] +public class TextController : MonoBehaviour +{ + public float Scale = 1f; + + [Multiline] + public string Text; + + private string displaying; + + [HideInInspector] + private Texture2D texture; + + [HideInInspector] + private Texture2D colorTexture; + + private MeshRenderer rend; + + private float _scale = float.NegativeInfinity; + + public Color Color = Color.white; + + private Color lastColor; + + public Vector3 Offset; + + public bool topAligned; + + public void Update() + { + if (!this.rend) + { + this.rend = base.GetComponent<MeshRenderer>(); + } + if (string.IsNullOrEmpty(this.Text)) + { + this.rend.enabled = false; + return; + } + if (this.displaying == null || this.displaying.GetHashCode() != this.Text.GetHashCode() || this.Color != this.lastColor) + { + int num = 0; + int num2 = 0; + int num3 = 1; + for (int i = 0; i < this.Text.Length; i++) + { + if (this.Text[i] == '\n') + { + num2 = 0; + num3++; + } + else + { + num2++; + if (num2 > num) + { + num = num2; + } + } + } + if (!this.texture || !this.colorTexture) + { + if (!this.texture) + { + this.texture = new Texture2D(num, num3, TextureFormat.ARGB32, false); + this.texture.filterMode = FilterMode.Point; + this.texture.wrapMode = TextureWrapMode.Clamp; + } + if (!this.colorTexture) + { + this.colorTexture = new Texture2D(num, num3, TextureFormat.ARGB32, false); + this.colorTexture.filterMode = FilterMode.Point; + this.colorTexture.wrapMode = TextureWrapMode.Clamp; + } + } + else if (this.texture.width != num || this.texture.height != num3) + { + this.texture.Resize(num, num3, TextureFormat.ARGB32, false); + this.colorTexture.Resize(num, num3, TextureFormat.ARGB32, false); + } + Color[] array = new Color[num * num3]; + array.SetAll(this.Color); + this.colorTexture.SetPixels(array); + array.SetAll(new Color(0.125f, 0f, 0f)); + this.texture.SetPixels(array); + int num4 = 0; + int num5 = this.texture.height - 1; + Color color = this.Color; + for (int j = 0; j < this.Text.Length; j++) + { + char c = this.Text[j]; + if (c != '\r') + { + if (c == '\n') + { + num4 = 0; + num5--; + } + else + { + this.texture.SetPixel(num4, num5, new Color((float)c / 256f, 0f, 0f)); + this.colorTexture.SetPixel(num4, num5, color); + num4++; + } + } + } + this.texture.Apply(false, false); + this.colorTexture.Apply(false, false); + this.rend.enabled = true; + this.rend.material.SetTexture("_InputTex", this.texture); + this.rend.material.SetTexture("_ColorTex", this.colorTexture); + this._scale = float.NegativeInfinity; + this.displaying = this.Text; + this.lastColor = this.Color; + } + if (this._scale != this.Scale) + { + this._scale = this.Scale; + base.transform.localScale = new Vector3((float)this.texture.width, (float)this.texture.height, 1f) * this.Scale; + if (this.topAligned) + { + base.transform.localPosition = this.Offset + new Vector3((float)this.texture.width * this.Scale / 2f, (float)(-(float)this.texture.height) * this.Scale / 2f, 0f); + } + } + } +} diff --git a/Client/Assembly-CSharp/TextLink.cs b/Client/Assembly-CSharp/TextLink.cs new file mode 100644 index 0000000..6ad9e25 --- /dev/null +++ b/Client/Assembly-CSharp/TextLink.cs @@ -0,0 +1,26 @@ +using System; +using UnityEngine; + +public class TextLink : MonoBehaviour +{ + public BoxCollider2D boxCollider; + + public string targetUrl; + + public bool needed; + + public void Set(Vector2 from, Vector2 to, string target) + { + this.targetUrl = target; + Vector2 vector = to + from; + base.transform.localPosition = new Vector3(vector.x / 2f, vector.y / 2f, -1f); + vector = to - from; + vector.y = -vector.y; + this.boxCollider.size = vector; + } + + public void Click() + { + Application.OpenURL(this.targetUrl); + } +} diff --git a/Client/Assembly-CSharp/TextRenderer.cs b/Client/Assembly-CSharp/TextRenderer.cs new file mode 100644 index 0000000..e0893f1 --- /dev/null +++ b/Client/Assembly-CSharp/TextRenderer.cs @@ -0,0 +1,482 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using UnityEngine; + +[RequireComponent(typeof(MeshRenderer))] +[RequireComponent(typeof(MeshFilter))] +public class TextRenderer : MonoBehaviour +{ + public float Width { get; private set; } + + public float Height { get; private set; } + + public Vector3 CursorPos + { + get + { + return new Vector3(this.cursorLocation.x / 100f * this.scale, this.cursorLocation.y / 100f * this.scale, -0.001f); + } + } + + public TextAsset FontData; + + public float scale = 1f; + + public float TabWidth = 0.5f; + + public bool Centered; + + public bool RightAligned; + + public TextLink textLinkPrefab; + + [HideInInspector] + private Mesh mesh; + + [HideInInspector] + private MeshRenderer render; + + [Multiline] + public string Text; + + private string lastText; + + public Color Color = Color.white; + + private Color lastColor = Color.white; + + public Color OutlineColor = Color.black; + + private Color lastOutlineColor = Color.white; + + public float maxWidth = -1f; + + public bool scaleToFit; + + public bool paragraphSpacing; + + private Vector2 cursorLocation; + + public void Start() + { + this.render = base.GetComponent<MeshRenderer>(); + MeshFilter component = base.GetComponent<MeshFilter>(); + if (!component.mesh) + { + this.mesh = new Mesh(); + this.mesh.name = "Text" + base.name; + component.mesh = this.mesh; + this.render.material.SetColor("_OutlineColor", this.OutlineColor); + return; + } + this.mesh = component.mesh; + } + + [ContextMenu("Generate Mesh")] + public void GenerateMesh() + { + this.render = base.GetComponent<MeshRenderer>(); + MeshFilter component = base.GetComponent<MeshFilter>(); + if (!component.sharedMesh) + { + this.mesh = new Mesh(); + this.mesh.name = "Text" + base.name; + component.mesh = this.mesh; + } + else + { + this.mesh = component.sharedMesh; + } + this.lastText = null; + this.lastOutlineColor = this.OutlineColor; + this.Update(); + } + + private void Update() + { + if (this.lastOutlineColor != this.OutlineColor) + { + this.lastOutlineColor = this.OutlineColor; + this.render.material.SetColor("_OutlineColor", this.OutlineColor); + } + if (this.lastText != this.Text || this.lastColor != this.Color) + { + this.RefreshMesh(); + } + } + + public void RefreshMesh() + { + if (this.render == null) + { + this.Start(); + } + if (this.Text != null) + { + if (this.Text.Any((char c) => c > '✐')) + { + FontCache.Instance.SetFont(this, "Korean"); + } + } + FontData fontData = FontCache.Instance.LoadFont(this.FontData); + this.lastText = this.Text; + this.lastColor = this.Color; + float num = this.scale; + if (this.scaleToFit) + { + num = Mathf.Min(this.scale, this.maxWidth / this.GetMaxWidth(fontData, this.lastText)); + } + else if (this.maxWidth > 0f) + { + this.lastText = (this.Text = TextRenderer.WrapText(fontData, this.lastText, this.maxWidth)); + } + List<Vector3> list = new List<Vector3>(this.lastText.Length * 4); + List<Vector2> list2 = new List<Vector2>(this.lastText.Length * 4); + List<Vector4> list3 = new List<Vector4>(this.lastText.Length * 4); + List<Color> list4 = new List<Color>(this.lastText.Length * 4); + int[] array = new int[this.lastText.Length * 6]; + this.Width = 0f; + this.cursorLocation.x = (this.cursorLocation.y = 0f); + int num2 = -1; + Vector2 from = default(Vector2); + string text = null; + int lineStart = 0; + int num3 = 0; + Color item = this.Color; + int? num4 = null; + int i = 0; + while (i < this.lastText.Length) + { + int num5 = (int)this.lastText[i]; + if (num5 == 91) + { + if (num2 != 91) + { + if (this.lastText[i + 1] == '[') + { + goto IL_422; + } + num4 = new int?(0); + num2 = num5; + } + } + else + { + if (num4 == null) + { + goto IL_422; + } + if (num5 == 93) + { + if (num2 != 91) + { + int? num6 = num4; + byte r = (byte)((num6 != null) ? new int?(num6.GetValueOrDefault() >> 24 & 255) : null).Value; + int? num7 = num4; + byte g = (byte)((num7 != null) ? new int?(num7.GetValueOrDefault() >> 16 & 255) : null).Value; + int? num8 = num4; + item = new Color32(r, g, (byte)((num8 != null) ? new int?(num8.GetValueOrDefault() >> 8 & 255) : null).Value, (byte)(num4 & 255).Value); + item.a *= this.Color.a; + } + else + { + item = this.Color; + } + num4 = null; + if (text != null) + { + TextLink textLink = UnityEngine.Object.Instantiate<TextLink>(this.textLinkPrefab, base.transform); + textLink.transform.localScale = Vector3.one; + Vector3 v = list.Last<Vector3>(); + textLink.Set(from, v, text); + text = null; + } + } + else if (num5 == 104) + { + int num9 = this.lastText.IndexOf(']', i); + text = this.lastText.Substring(i, num9 - i); + from = list[list.Count - 2]; + item = new Color(0.5f, 0.5f, 1f); + num4 = null; + i = num9; + } + else + { + num4 = (num4 << 4 | this.CharToInt(num5)); + } + num2 = num5; + } + IL_81F: + i++; + continue; + IL_422: + if (num5 == 13) + { + goto IL_81F; + } + if (num5 == 10) + { + if (this.Centered) + { + this.CenterVerts(list, this.cursorLocation.x, lineStart, num); + } + else if (this.RightAligned) + { + this.RightAlignVerts(list, this.cursorLocation.x, lineStart, num); + } + bool flag = this.cursorLocation.x == 0f; + this.cursorLocation.x = 0f; + if (flag) + { + this.cursorLocation.y = this.cursorLocation.y - fontData.LineHeight / 2f; + } + else + { + this.cursorLocation.y = this.cursorLocation.y - fontData.LineHeight; + } + lineStart = list.Count; + goto IL_81F; + } + if (num5 == 9) + { + float num10 = this.cursorLocation.x / 100f; + num10 = Mathf.Ceil(num10 / this.TabWidth) * this.TabWidth; + this.cursorLocation.x = num10 * 100f; + goto IL_81F; + } + int index; + if (!fontData.charMap.TryGetValue(num5, out index)) + { + Debug.Log("Missing char :" + num5); + num5 = -1; + index = fontData.charMap[-1]; + } + Vector4 vector = fontData.bounds[index]; + Vector2 textureSize = fontData.TextureSize; + Vector3 vector2 = fontData.offsets[index]; + float kerning = fontData.GetKerning(num2, num5); + float num11 = this.cursorLocation.x + vector2.x + kerning; + float num12 = this.cursorLocation.y - vector2.y; + list.Add(new Vector3(num11, num12 - vector.w) / 100f * num); + list.Add(new Vector3(num11, num12) / 100f * num); + list.Add(new Vector3(num11 + vector.z, num12) / 100f * num); + list.Add(new Vector3(num11 + vector.z, num12 - vector.w) / 100f * num); + list4.Add(item); + list4.Add(item); + list4.Add(item); + list4.Add(item); + list2.Add(new Vector2(vector.x / textureSize.x, 1f - (vector.y + vector.w) / textureSize.y)); + list2.Add(new Vector2(vector.x / textureSize.x, 1f - vector.y / textureSize.y)); + list2.Add(new Vector2((vector.x + vector.z) / textureSize.x, 1f - vector.y / textureSize.y)); + list2.Add(new Vector2((vector.x + vector.z) / textureSize.x, 1f - (vector.y + vector.w) / textureSize.y)); + Vector4 item2 = fontData.Channels[index]; + list3.Add(item2); + list3.Add(item2); + list3.Add(item2); + list3.Add(item2); + array[num3 * 6] = num3 * 4; + array[num3 * 6 + 1] = num3 * 4 + 1; + array[num3 * 6 + 2] = num3 * 4 + 2; + array[num3 * 6 + 3] = num3 * 4; + array[num3 * 6 + 4] = num3 * 4 + 2; + array[num3 * 6 + 5] = num3 * 4 + 3; + this.cursorLocation.x = this.cursorLocation.x + (vector2.z + kerning); + float num13 = this.cursorLocation.x / 100f * num; + if (this.Width < num13) + { + this.Width = num13; + } + num2 = num5; + num3++; + goto IL_81F; + } + if (this.Centered) + { + this.CenterVerts(list, this.cursorLocation.x, lineStart, num); + this.cursorLocation.x = this.cursorLocation.x / 2f; + this.Width /= 2f; + } + else if (this.RightAligned) + { + this.RightAlignVerts(list, this.cursorLocation.x, lineStart, num); + } + this.Height = -(this.cursorLocation.y - fontData.LineHeight) / 100f * num; + this.mesh.Clear(); + if (list.Count > 0) + { + this.mesh.SetVertices(list); + this.mesh.SetColors(list4); + this.mesh.SetUVs(0, list2); + this.mesh.SetUVs(1, list3); + this.mesh.SetIndices(array, MeshTopology.Triangles, 0); + } + } + + private float GetMaxWidth(FontData data, string lastText) + { + float num = 0f; + float num2 = 0f; + int last = -1; + bool flag = false; + int num3 = 0; + int num4 = 0; + while (num4 < lastText.Length && num3++ <= 1000) + { + int num5 = (int)lastText[num4]; + if (num5 == 91) + { + flag = true; + goto IL_4D; + } + if (num5 != 93) + { + goto IL_4D; + } + flag = false; + IL_100: + num4++; + continue; + IL_4D: + if (flag || num5 == 13) + { + goto IL_100; + } + if (num5 == 10) + { + last = -1; + num2 = 0f; + goto IL_100; + } + if (num5 == 9) + { + num2 = Mathf.Ceil(num2 / 100f / 0.5f) * 0.5f * 100f; + goto IL_100; + } + int index; + if (!data.charMap.TryGetValue(num5, out index)) + { + Debug.Log("Missing char :" + num5); + num5 = -1; + index = data.charMap[-1]; + } + Vector3 vector = data.offsets[index]; + num2 += vector.z + data.GetKerning(last, num5); + if (num2 > num) + { + num = num2; + } + last = num5; + goto IL_100; + } + return num / 100f; + } + + private void RightAlignVerts(List<Vector3> verts, float baseX, int lineStart, float scale) + { + for (int i = lineStart; i < verts.Count; i++) + { + Vector3 value = verts[i]; + value.x -= baseX / 100f * scale; + verts[i] = value; + } + } + + private void CenterVerts(List<Vector3> verts, float baseX, int lineStart, float scale) + { + for (int i = lineStart; i < verts.Count; i++) + { + Vector3 value = verts[i]; + value.x -= baseX / 200f * scale; + verts[i] = value; + } + } + + private int CharToInt(int c) + { + if (c < 65) + { + return c - 48; + } + if (c < 97) + { + return 10 + (c - 65); + } + return 10 + (c - 97); + } + + public static string WrapText(FontData data, string displayTxt, float maxWidth) + { + float num = 0f; + int num2 = -1; + int last = -1; + bool flag = false; + int num3 = 0; + int num4 = 0; + while (num4 < displayTxt.Length && num3++ <= 1000) + { + int num5 = (int)displayTxt[num4]; + if (num5 == 91) + { + flag = true; + goto IL_49; + } + if (num5 != 93) + { + goto IL_49; + } + flag = false; + IL_155: + num4++; + continue; + IL_49: + if (flag || num5 == 13) + { + goto IL_155; + } + if (num5 == 10) + { + num2 = -1; + last = -1; + num = 0f; + goto IL_155; + } + if (num5 == 9) + { + num = Mathf.Ceil(num / 100f / 0.5f) * 0.5f * 100f; + goto IL_155; + } + int index; + if (!data.charMap.TryGetValue(num5, out index)) + { + Debug.Log("Missing char :" + num5); + num5 = -1; + index = data.charMap[-1]; + } + if (num5 == 32) + { + num2 = num4; + } + Vector3 vector = data.offsets[index]; + num += vector.z + data.GetKerning(last, num5); + if (num > maxWidth * 100f) + { + if (num2 != -1) + { + displayTxt = displayTxt.Substring(0, num2) + "\n" + displayTxt.Substring(num2 + 1); + num4 = num2; + } + else + { + displayTxt = displayTxt.Substring(0, num4) + "\n" + displayTxt.Substring(num4); + } + num2 = -1; + num = 0f; + } + last = num5; + goto IL_155; + } + return displayTxt; + } +} diff --git a/Client/Assembly-CSharp/TextTranslator.cs b/Client/Assembly-CSharp/TextTranslator.cs new file mode 100644 index 0000000..bb51e1b --- /dev/null +++ b/Client/Assembly-CSharp/TextTranslator.cs @@ -0,0 +1,24 @@ +using System; +using UnityEngine; + +[RequireComponent(typeof(TextRenderer))] +public class TextTranslator : MonoBehaviour, ITranslatedText +{ + public StringNames TargetText; + + public void ResetText() + { + base.GetComponent<TextRenderer>().Text = DestroyableSingleton<TranslationController>.Instance.GetString(this.TargetText, Array.Empty<object>()); + } + + public void Start() + { + DestroyableSingleton<TranslationController>.Instance.ActiveTexts.Add(this); + this.ResetText(); + } + + public void OnDestroy() + { + DestroyableSingleton<TranslationController>.Instance.ActiveTexts.Remove(this); + } +} diff --git a/Client/Assembly-CSharp/ToggleButtonBehaviour.cs b/Client/Assembly-CSharp/ToggleButtonBehaviour.cs new file mode 100644 index 0000000..4703e3e --- /dev/null +++ b/Client/Assembly-CSharp/ToggleButtonBehaviour.cs @@ -0,0 +1,42 @@ +using System; +using UnityEngine; + +public class ToggleButtonBehaviour : MonoBehaviour, ITranslatedText +{ + public StringNames BaseText; + + public TextRenderer Text; + + public SpriteRenderer Background; + + public ButtonRolloverHandler Rollover; + + private bool onState; + + public void Start() + { + DestroyableSingleton<TranslationController>.Instance.ActiveTexts.Add(this); + } + + public void OnDestroy() + { + DestroyableSingleton<TranslationController>.Instance.ActiveTexts.Remove(this); + } + + public void ResetText() + { + this.Text.Text = DestroyableSingleton<TranslationController>.Instance.GetString(this.BaseText, Array.Empty<object>()) + ": " + DestroyableSingleton<TranslationController>.Instance.GetString(this.onState ? StringNames.SettingsOn : StringNames.SettingsOff, Array.Empty<object>()); + } + + public void UpdateText(bool on) + { + this.onState = on; + Color color = on ? new Color(0f, 1f, 0.16470589f, 1f) : Color.white; + this.Background.color = color; + this.ResetText(); + if (this.Rollover) + { + this.Rollover.OutColor = color; + } + } +} diff --git a/Client/Assembly-CSharp/ToggleOption.cs b/Client/Assembly-CSharp/ToggleOption.cs new file mode 100644 index 0000000..25ffbe7 --- /dev/null +++ b/Client/Assembly-CSharp/ToggleOption.cs @@ -0,0 +1,45 @@ +using System; +using UnityEngine; + +public class ToggleOption : OptionBehaviour +{ + public TextRenderer TitleText; + + public SpriteRenderer CheckMark; + + private bool oldValue; + + public void OnEnable() + { + this.TitleText.Text = DestroyableSingleton<TranslationController>.Instance.GetString(this.Title, Array.Empty<object>()); + GameOptionsData gameOptions = PlayerControl.GameOptions; + StringNames title = this.Title; + if (title == StringNames.GameRecommendedSettings) + { + this.CheckMark.enabled = gameOptions.isDefaults; + return; + } + Debug.Log("Ono, unrecognized setting: " + this.Title); + } + + private void FixedUpdate() + { + bool @bool = this.GetBool(); + if (this.oldValue != @bool) + { + this.oldValue = @bool; + this.CheckMark.enabled = @bool; + } + } + + public void Toggle() + { + this.CheckMark.enabled = !this.CheckMark.enabled; + this.OnValueChanged(this); + } + + public override bool GetBool() + { + return this.CheckMark.enabled; + } +} diff --git a/Client/Assembly-CSharp/TowerBehaviour.cs b/Client/Assembly-CSharp/TowerBehaviour.cs new file mode 100644 index 0000000..dbf85b2 --- /dev/null +++ b/Client/Assembly-CSharp/TowerBehaviour.cs @@ -0,0 +1,43 @@ +using System; +using UnityEngine; + +public class TowerBehaviour : MonoBehaviour +{ + public float timer; + + public float frameTime = 0.2f; + + public SpriteRenderer circle; + + public SpriteRenderer middle1; + + public SpriteRenderer middle2; + + public SpriteRenderer outer1; + + public SpriteRenderer outer2; + + public void Update() + { + this.timer += Time.deltaTime; + if (this.timer < this.frameTime) + { + this.circle.color = Color.white; + this.middle1.color = (this.middle2.color = (this.outer1.color = (this.outer2.color = Color.black))); + return; + } + if (this.timer < 2f * this.frameTime) + { + this.middle1.color = (this.middle2.color = Color.white); + this.circle.color = (this.outer1.color = (this.outer2.color = Color.black)); + return; + } + if (this.timer < 3f * this.frameTime) + { + this.outer1.color = (this.outer2.color = Color.white); + this.middle1.color = (this.middle2.color = (this.circle.color = Color.black)); + return; + } + this.timer = 0f; + } +} diff --git a/Client/Assembly-CSharp/TransitionOpen.cs b/Client/Assembly-CSharp/TransitionOpen.cs new file mode 100644 index 0000000..b846e44 --- /dev/null +++ b/Client/Assembly-CSharp/TransitionOpen.cs @@ -0,0 +1,54 @@ +using System; +using System.Collections; +using UnityEngine; +using UnityEngine.UI; + +public class TransitionOpen : MonoBehaviour +{ + public float duration = 0.2f; + + public Button.ButtonClickedEvent OnClose = new Button.ButtonClickedEvent(); + + public void OnEnable() + { + base.StartCoroutine(this.AnimateOpen()); + } + + public void Close() + { + base.StartCoroutine(this.AnimateClose()); + } + + private IEnumerator AnimateClose() + { + Vector3 vec = default(Vector3); + for (float t = 0f; t < this.duration; t += Time.deltaTime) + { + float t2 = t / this.duration; + float num = Mathf.SmoothStep(1f, 0f, t2); + vec.Set(num, num, num); + base.transform.localScale = vec; + yield return null; + } + vec.Set(0f, 0f, 0f); + base.transform.localScale = vec; + this.OnClose.Invoke(); + yield break; + } + + private IEnumerator AnimateOpen() + { + Vector3 vec = default(Vector3); + for (float t = 0f; t < this.duration; t += Time.deltaTime) + { + float t2 = t / this.duration; + float num = Mathf.SmoothStep(0f, 1f, t2); + vec.Set(num, num, num); + base.transform.localScale = vec; + yield return null; + } + vec.Set(1f, 1f, 1f); + base.transform.localScale = vec; + yield break; + } +} diff --git a/Client/Assembly-CSharp/TransitionType.cs b/Client/Assembly-CSharp/TransitionType.cs new file mode 100644 index 0000000..07e5b99 --- /dev/null +++ b/Client/Assembly-CSharp/TransitionType.cs @@ -0,0 +1,7 @@ +using System; + +public enum TransitionType +{ + SlideBottom, + Alpha +} diff --git a/Client/Assembly-CSharp/TranslatedImageSet.cs b/Client/Assembly-CSharp/TranslatedImageSet.cs new file mode 100644 index 0000000..2a43583 --- /dev/null +++ b/Client/Assembly-CSharp/TranslatedImageSet.cs @@ -0,0 +1,8 @@ +using System; +using UnityEngine; + +[CreateAssetMenu] +public class TranslatedImageSet : ScriptableObject +{ + public ImageData[] Images; +} diff --git a/Client/Assembly-CSharp/TranslationController.cs b/Client/Assembly-CSharp/TranslationController.cs new file mode 100644 index 0000000..66686f7 --- /dev/null +++ b/Client/Assembly-CSharp/TranslationController.cs @@ -0,0 +1,70 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using UnityEngine; + +public class TranslationController : DestroyableSingleton<TranslationController> +{ + private static readonly StringNames[] SystemTypesToStringNames = SystemTypeHelpers.AllTypes.Select(delegate(SystemTypes t) + { + StringNames result; + Enum.TryParse<StringNames>(t.ToString(), out result); + return result; + }).ToArray<StringNames>(); + + private static readonly StringNames[] TaskTypesToStringNames = TaskTypesHelpers.AllTypes.Select(delegate(TaskTypes t) + { + StringNames result; + Enum.TryParse<StringNames>(t.ToString(), out result); + return result; + }).ToArray<StringNames>(); + + public TextAsset[] Languages; + + public TranslatedImageSet[] Images; + + public LanguageUnit CurrentLanguage; + + public List<ITranslatedText> ActiveTexts = new List<ITranslatedText>(); + + public override void Awake() + { + base.Awake(); + if (DestroyableSingleton<TranslationController>.Instance == this) + { + this.CurrentLanguage = new LanguageUnit(this.Languages[(int)SaveManager.LastLanguage], this.Images[(int)SaveManager.LastLanguage].Images); + } + } + + public void SetLanguage(TextAsset lang) + { + int num = this.Languages.IndexOf(lang); + Debug.Log("Set language to " + num); + SaveManager.LastLanguage = (uint)num; + this.CurrentLanguage = new LanguageUnit(this.Languages[num], this.Images[num].Images); + for (int i = 0; i < this.ActiveTexts.Count; i++) + { + this.ActiveTexts[i].ResetText(); + } + } + + public Sprite GetImage(ImageNames id) + { + return this.CurrentLanguage.GetImage(id); + } + + public string GetString(StringNames id, params object[] parts) + { + return this.CurrentLanguage.GetString(id, parts); + } + + public string GetString(SystemTypes room) + { + return this.GetString(TranslationController.SystemTypesToStringNames[(int)room], Array.Empty<object>()); + } + + public string GetString(TaskTypes task) + { + return this.GetString(TranslationController.TaskTypesToStringNames[(int)((byte)task)], Array.Empty<object>()); + } +} diff --git a/Client/Assembly-CSharp/TumbleBoxBehaviour.cs b/Client/Assembly-CSharp/TumbleBoxBehaviour.cs new file mode 100644 index 0000000..8d9f722 --- /dev/null +++ b/Client/Assembly-CSharp/TumbleBoxBehaviour.cs @@ -0,0 +1,24 @@ +using System; +using UnityEngine; + +public class TumbleBoxBehaviour : MonoBehaviour +{ + public FloatRange BoxHeight; + + public FloatRange shadowScale; + + public SpriteRenderer Shadow; + + public SpriteRenderer Box; + + public void FixedUpdate() + { + float z = Time.time * 15f; + float v = Mathf.Cos(Time.time * 3.1415927f / 10f) / 2f + 0.5f; + float num = this.shadowScale.Lerp(v); + this.Shadow.transform.localScale = new Vector3(num, num, num); + float y = this.BoxHeight.Lerp(v); + this.Box.transform.localPosition = new Vector3(0f, y, -0.01f); + this.Box.transform.eulerAngles = new Vector3(0f, 0f, z); + } +} diff --git a/Client/Assembly-CSharp/TuneRadioMinigame.cs b/Client/Assembly-CSharp/TuneRadioMinigame.cs new file mode 100644 index 0000000..ac2eb58 --- /dev/null +++ b/Client/Assembly-CSharp/TuneRadioMinigame.cs @@ -0,0 +1,104 @@ +using System; +using UnityEngine; + +public class TuneRadioMinigame : Minigame +{ + public RadioWaveBehaviour actualSignal; + + public DialBehaviour dial; + + public SpriteRenderer redLight; + + public SpriteRenderer greenLight; + + public float Tolerance = 0.1f; + + public float targetAngle; + + public bool finished; + + private float steadyTimer; + + public AudioClip StaticSound; + + public AudioClip RadioSound; + + public override void Begin(PlayerTask task) + { + base.Begin(task); + this.targetAngle = this.dial.DialRange.Next(); + if (Constants.ShouldPlaySfx()) + { + SoundManager.Instance.PlayDynamicSound("CommsRadio", this.RadioSound, true, new DynamicSound.GetDynamicsFunction(this.GetRadioVolume), true); + SoundManager.Instance.PlayDynamicSound("RadioStatic", this.StaticSound, true, new DynamicSound.GetDynamicsFunction(this.GetStaticVolume), true); + } + } + + private void GetRadioVolume(AudioSource player, float dt) + { + player.volume = 1f - this.actualSignal.NoiseLevel; + } + + private void GetStaticVolume(AudioSource player, float dt) + { + player.volume = this.actualSignal.NoiseLevel; + } + + public void Update() + { + if (this.finished) + { + return; + } + float f = Mathf.Abs((this.targetAngle - this.dial.Value) / this.dial.DialRange.Width) * 2f; + this.actualSignal.NoiseLevel = Mathf.Clamp(Mathf.Sqrt(f), 0f, 1f); + if (this.actualSignal.NoiseLevel <= this.Tolerance) + { + this.redLight.color = new Color(0.35f, 0f, 0f); + if (!this.dial.Engaged) + { + this.FinishGame(); + return; + } + this.steadyTimer += Time.deltaTime; + if (this.steadyTimer > 1.5f) + { + this.FinishGame(); + return; + } + } + else + { + this.redLight.color = new Color(1f, 0f, 0f); + this.steadyTimer = 0f; + } + } + + private void FinishGame() + { + this.greenLight.color = Color.green; + this.finished = true; + this.dial.enabled = false; + this.dial.SetValue(this.targetAngle); + this.actualSignal.NoiseLevel = 0f; + if (PlayerControl.LocalPlayer) + { + ShipStatus.Instance.RpcRepairSystem(SystemTypes.Comms, 0); + } + base.StartCoroutine(base.CoStartClose(0.75f)); + try + { + ((SabotageTask)this.MyTask).MarkContributed(); + } + catch + { + } + } + + public override void Close() + { + SoundManager.Instance.StopSound(this.StaticSound); + SoundManager.Instance.StopSound(this.RadioSound); + base.Close(); + } +} diff --git a/Client/Assembly-CSharp/TutorialManager.cs b/Client/Assembly-CSharp/TutorialManager.cs new file mode 100644 index 0000000..ba89235 --- /dev/null +++ b/Client/Assembly-CSharp/TutorialManager.cs @@ -0,0 +1,63 @@ +using System; +using System.Collections; +using InnerNet; +using UnityEngine; + +public class TutorialManager : DestroyableSingleton<TutorialManager> +{ + public PlayerControl PlayerPrefab; + + public Transform[] DummyLocations; + + public override void Awake() + { + base.Awake(); + StatsManager.Instance = new TutorialStatsManager(); + base.StartCoroutine(this.RunTutorial()); + } + + public override void OnDestroy() + { + StatsManager.Instance = new StatsManager(); + base.OnDestroy(); + } + + private IEnumerator RunTutorial() + { + while (!ShipStatus.Instance) + { + yield return null; + } + ShipStatus.Instance.enabled = false; + ShipStatus.Instance.Timer = 15f; + while (!PlayerControl.LocalPlayer) + { + yield return null; + } + if (DestroyableSingleton<DiscordManager>.InstanceExists) + { + DestroyableSingleton<DiscordManager>.Instance.SetHowToPlay(); + } + PlayerControl.GameOptions = new GameOptionsData + { + NumImpostors = 0, + DiscussionTime = 0 + }; + PlayerControl.LocalPlayer.RpcSetInfected(new GameData.PlayerInfo[0]); + for (int i = 0; i < this.DummyLocations.Length; i++) + { + PlayerControl playerControl = UnityEngine.Object.Instantiate<PlayerControl>(this.PlayerPrefab); + playerControl.PlayerId = (byte)GameData.Instance.GetAvailableId(); + GameData.Instance.AddPlayer(playerControl); + AmongUsClient.Instance.Spawn(playerControl, -2, SpawnFlags.None); + playerControl.transform.position = this.DummyLocations[i].position; + playerControl.GetComponent<DummyBehaviour>().enabled = true; + playerControl.NetTransform.enabled = false; + playerControl.SetName("Dummy " + (i + 1)); + playerControl.SetColor((byte)((i < (int)SaveManager.BodyColor) ? i : (i + 1))); + GameData.Instance.RpcSetTasks(playerControl.PlayerId, new byte[0]); + } + ShipStatus.Instance.Begin(); + yield break; + } +} diff --git a/Client/Assembly-CSharp/TutorialStatsManager.cs b/Client/Assembly-CSharp/TutorialStatsManager.cs new file mode 100644 index 0000000..6d473ed --- /dev/null +++ b/Client/Assembly-CSharp/TutorialStatsManager.cs @@ -0,0 +1,12 @@ +using System; + +public class TutorialStatsManager : StatsManager +{ + protected override void LoadStats() + { + } + + protected override void SaveStats() + { + } +} diff --git a/Client/Assembly-CSharp/TwitterLink.cs b/Client/Assembly-CSharp/TwitterLink.cs new file mode 100644 index 0000000..816c0fb --- /dev/null +++ b/Client/Assembly-CSharp/TwitterLink.cs @@ -0,0 +1,12 @@ +using System; +using UnityEngine; + +public class TwitterLink : MonoBehaviour +{ + public string LinkUrl = "https://www.twitter.com/InnerslothDevs"; + + public void Click() + { + Application.OpenURL(this.LinkUrl); + } +} diff --git a/Client/Assembly-CSharp/UnlockManifoldsMinigame.cs b/Client/Assembly-CSharp/UnlockManifoldsMinigame.cs new file mode 100644 index 0000000..16f6269 --- /dev/null +++ b/Client/Assembly-CSharp/UnlockManifoldsMinigame.cs @@ -0,0 +1,100 @@ +using System; +using System.Collections; +using System.Linq; +using UnityEngine; + +public class UnlockManifoldsMinigame : Minigame +{ + public SpriteRenderer[] Buttons; + + public byte SystemId; + + private int buttonCounter; + + private bool animating; + + public AudioClip PressButtonSound; + + public AudioClip FailSound; + + public override void Begin(PlayerTask task) + { + base.Begin(task); + int num = 2; + int num2 = this.Buttons.Length / num; + float[] array = FloatRange.SpreadToEdges(-1.7f, 1.7f, num2).ToArray<float>(); + float[] array2 = FloatRange.SpreadToEdges(-0.43f, 0.43f, num).ToArray<float>(); + SpriteRenderer[] array3 = this.Buttons.ToArray<SpriteRenderer>(); + array3.Shuffle<SpriteRenderer>(); + for (int i = 0; i < num2; i++) + { + for (int j = 0; j < num; j++) + { + int num3 = i + j * num2; + array3[num3].transform.localPosition = new Vector3(array[i], array2[j], 0f); + } + } + } + + public void HitButton(int idx) + { + if (this.MyNormTask.IsComplete) + { + return; + } + if (this.animating) + { + return; + } + if (Constants.ShouldPlaySfx()) + { + SoundManager.Instance.PlaySound(this.PressButtonSound, false, 1f).pitch = Mathf.Lerp(0.5f, 1.5f, (float)idx / 10f); + } + if (idx == this.buttonCounter) + { + this.Buttons[idx].color = Color.green; + this.buttonCounter++; + if (this.buttonCounter == this.Buttons.Length) + { + this.MyNormTask.NextStep(); + base.StartCoroutine(base.CoStartClose(0.75f)); + return; + } + } + else + { + this.buttonCounter = 0; + base.StartCoroutine(this.ResetAll()); + } + } + + private IEnumerator ResetAll() + { + if (Constants.ShouldPlaySfx()) + { + SoundManager.Instance.PlaySound(this.FailSound, false, 1f); + } + this.animating = true; + for (int i = 0; i < this.Buttons.Length; i++) + { + this.Buttons[i].color = Color.red; + } + yield return new WaitForSeconds(0.25f); + for (int j = 0; j < this.Buttons.Length; j++) + { + this.Buttons[j].color = Color.white; + } + yield return new WaitForSeconds(0.25f); + for (int k = 0; k < this.Buttons.Length; k++) + { + this.Buttons[k].color = Color.red; + } + yield return new WaitForSeconds(0.25f); + for (int l = 0; l < this.Buttons.Length; l++) + { + this.Buttons[l].color = Color.white; + } + this.animating = false; + yield break; + } +} diff --git a/Client/Assembly-CSharp/UnlockPopUp.cs b/Client/Assembly-CSharp/UnlockPopUp.cs new file mode 100644 index 0000000..22675fa --- /dev/null +++ b/Client/Assembly-CSharp/UnlockPopUp.cs @@ -0,0 +1,22 @@ +using System; +using System.Collections; +using UnityEngine; + +public class UnlockPopUp : MonoBehaviour +{ + public IEnumerator Show() + { + DateTime utcNow = DateTime.UtcNow; + if ((utcNow.DayOfYear < 350 && utcNow.DayOfYear > 4) || SaveManager.GetPurchase("hats_newyears2018")) + { + yield break; + } + base.gameObject.SetActive(true); + SaveManager.SetPurchased("hats_newyears2018"); + while (base.isActiveAndEnabled) + { + yield return null; + } + yield break; + } +} diff --git a/Client/Assembly-CSharp/UploadDataGame.cs b/Client/Assembly-CSharp/UploadDataGame.cs new file mode 100644 index 0000000..0f3d95c --- /dev/null +++ b/Client/Assembly-CSharp/UploadDataGame.cs @@ -0,0 +1,203 @@ +using System; +using System.Collections; +using System.Text; +using PowerTools; +using UnityEngine; + +public class UploadDataGame : Minigame +{ + public SpriteAnim LeftFolder; + + public SpriteAnim RightFolder; + + public AnimationClip FolderOpen; + + public AnimationClip FolderClose; + + public SpriteRenderer Runner; + + public HorizontalGauge Gauge; + + public TextRenderer PercentText; + + public TextRenderer EstimatedText; + + public TextRenderer SourceText; + + public TextRenderer TargetText; + + public SpriteRenderer Button; + + public Sprite DownloadImage; + + public GameObject Status; + + public GameObject Tower; + + private int count; + + private float timer; + + public const float RandomChunks = 5f; + + public const float ConstantTime = 3f; + + private bool running = true; + + public override void Begin(PlayerTask task) + { + PlayerControl.LocalPlayer.SetPlayerMaterialColors(this.Runner); + base.Begin(task); + if (this.MyNormTask.taskStep == 0) + { + this.Button.sprite = this.DownloadImage; + this.Tower.SetActive(false); + this.SourceText.Text = this.MyTask.StartAt.ToString(); + this.TargetText.Text = "My Tablet"; + return; + } + this.SourceText.Text = "My Tablet"; + this.TargetText.Text = "Headquarters"; + } + + public void Click() + { + base.StartCoroutine(this.Transition()); + } + + private IEnumerator Transition() + { + this.Button.gameObject.SetActive(false); + this.Status.SetActive(true); + float target = this.Gauge.transform.localScale.x; + for (float t = 0f; t < 0.15f; t += Time.deltaTime) + { + this.Gauge.transform.localScale = new Vector3(t / 0.15f * target, 1f, 1f); + yield return null; + } + base.StartCoroutine(this.PulseText()); + base.StartCoroutine(this.DoRun()); + base.StartCoroutine(this.DoText()); + base.StartCoroutine(this.DoPercent()); + yield break; + } + + private IEnumerator PulseText() + { + MeshRenderer rend2 = this.PercentText.GetComponent<MeshRenderer>(); + MeshRenderer rend1 = this.EstimatedText.GetComponent<MeshRenderer>(); + Color gray = new Color(0.3f, 0.3f, 0.3f, 1f); + while (this.running) + { + yield return new WaitForLerp(0.4f, delegate(float t) + { + Color value = Color.Lerp(Color.black, gray, t); + rend2.material.SetColor("_OutlineColor", value); + rend1.material.SetColor("_OutlineColor", value); + }); + yield return new WaitForLerp(0.4f, delegate(float t) + { + Color value = Color.Lerp(gray, Color.black, t); + rend2.material.SetColor("_OutlineColor", value); + rend1.material.SetColor("_OutlineColor", value); + }); + } + rend2.material.SetColor("_OutlineColor", Color.black); + rend1.material.SetColor("_OutlineColor", Color.black); + yield break; + } + + private IEnumerator DoPercent() + { + while (this.running) + { + float num = (float)this.count / 5f * 0.7f + this.timer / 3f * 0.3f; + if (num >= 1f) + { + this.running = false; + } + num = Mathf.Clamp(num, 0f, 1f); + this.Gauge.Value = num; + this.PercentText.Text = Mathf.RoundToInt(num * 100f) + "%"; + yield return null; + } + yield break; + } + + private IEnumerator DoText() + { + StringBuilder txt = new StringBuilder("Estimated Time: "); + int baselen = txt.Length; + int max = 604800; + this.count = 0; + while ((float)this.count < 5f) + { + txt.Length = baselen; + int num = IntRange.Next(max / 6, max); + int num2 = num / 86400; + if (num2 > 0) + { + txt.Append(num2 + "d "); + } + int num3 = num / 3600 % 24; + if (num3 > 0) + { + txt.Append(num3 + "hr "); + } + int num4 = num / 60 % 60; + if (num4 > 0) + { + txt.Append(num4 + "m "); + } + int num5 = num % 60; + if (num5 > 0) + { + txt.Append(num5 + "s"); + } + this.EstimatedText.Text = txt.ToString(); + max /= 4; + yield return new WaitForSeconds(FloatRange.Next(0.6f, 1.2f)); + this.count++; + } + this.timer = 0f; + while (this.timer < 3f) + { + txt.Length = baselen; + int num6 = Mathf.RoundToInt(3f - this.timer); + txt.Append(num6 + "s"); + this.EstimatedText.Text = txt.ToString(); + yield return null; + this.timer += Time.deltaTime; + } + yield break; + } + + private IEnumerator DoRun() + { + while (this.running) + { + UploadDataGame.<>c__DisplayClass25_0 CS$<>8__locals1 = new UploadDataGame.<>c__DisplayClass25_0(); + CS$<>8__locals1.<>4__this = this; + this.LeftFolder.Play(this.FolderOpen, 1f); + CS$<>8__locals1.pos = this.Runner.transform.localPosition; + yield return new WaitForLerp(1.125f, delegate(float t) + { + CS$<>8__locals1.pos.x = Mathf.Lerp(-1.25f, 0.5625f, t); + CS$<>8__locals1.<>4__this.Runner.transform.localPosition = CS$<>8__locals1.pos; + }); + this.LeftFolder.Play(this.FolderClose, 1f); + this.RightFolder.Play(this.FolderOpen, 1f); + yield return new WaitForLerp(1.375f, delegate(float t) + { + CS$<>8__locals1.pos.x = Mathf.Lerp(0.5625f, 1.25f, t); + CS$<>8__locals1.<>4__this.Runner.transform.localPosition = CS$<>8__locals1.pos; + }); + yield return new WaitForAnimationFinish(this.RightFolder, this.FolderClose); + CS$<>8__locals1 = null; + } + this.EstimatedText.Text = "Complete"; + this.MyNormTask.NextStep(); + base.StartCoroutine(base.CoStartClose(0.75f)); + yield break; + } +} diff --git a/Client/Assembly-CSharp/UploadDataTask.cs b/Client/Assembly-CSharp/UploadDataTask.cs new file mode 100644 index 0000000..8d4aafa --- /dev/null +++ b/Client/Assembly-CSharp/UploadDataTask.cs @@ -0,0 +1,34 @@ +using System; +using System.Linq; +using System.Text; + +public class UploadDataTask : NormalPlayerTask +{ + public override bool ValidConsole(global::Console console) + { + return (console.Room == this.StartAt && console.ValidTasks.Any((TaskSet set) => this.TaskType == set.taskType && set.taskStep.Contains(this.taskStep))) || (this.taskStep == 1 && console.TaskTypes.Contains(this.TaskType)); + } + + public override void AppendTaskText(StringBuilder sb) + { + if (this.taskStep > 0) + { + if (this.IsComplete) + { + sb.Append("[00DD00FF]"); + } + else + { + sb.Append("[FFFF00FF]"); + } + } + sb.Append(DestroyableSingleton<TranslationController>.Instance.GetString((this.taskStep == 0) ? this.StartAt : SystemTypes.Admin)); + sb.Append(": "); + sb.Append(DestroyableSingleton<TranslationController>.Instance.GetString((this.taskStep == 0) ? StringNames.DownloadData : StringNames.UploadData, Array.Empty<object>())); + sb.Append(" ("); + sb.Append(this.taskStep); + sb.Append("/"); + sb.Append(this.MaxStep); + sb.AppendLine(") []"); + } +} diff --git a/Client/Assembly-CSharp/UseButtonManager.cs b/Client/Assembly-CSharp/UseButtonManager.cs new file mode 100644 index 0000000..c6a7f65 --- /dev/null +++ b/Client/Assembly-CSharp/UseButtonManager.cs @@ -0,0 +1,108 @@ +using System; +using UnityEngine; + +public class UseButtonManager : MonoBehaviour +{ + private static readonly Color DisabledColor = new Color(1f, 1f, 1f, 0.3f); + + private static readonly Color EnabledColor = new Color(1f, 1f, 1f, 1f); + + public SpriteRenderer UseButton; + + public Sprite UseImage; + + public Sprite SabotageImage; + + public Sprite VentImage; + + public Sprite AdminMapImage; + + public Sprite SecurityImage; + + public Sprite OptionsImage; + + private IUsable currentTarget; + + public void SetTarget(IUsable target) + { + this.currentTarget = target; + if (target != null) + { + if (target is Vent) + { + this.UseButton.sprite = this.VentImage; + } + else if (target is MapConsole) + { + this.UseButton.sprite = this.AdminMapImage; + } + else if (target is OptionsConsole) + { + this.UseButton.sprite = this.OptionsImage; + } + else if (target is SystemConsole) + { + SystemConsole systemConsole = (SystemConsole)target; + if (systemConsole.name.StartsWith("Surv")) + { + this.UseButton.sprite = this.SecurityImage; + } + else if (systemConsole.name.StartsWith("TaskAdd")) + { + this.UseButton.sprite = this.OptionsImage; + } + else + { + this.UseButton.sprite = this.UseImage; + } + } + else + { + this.UseButton.sprite = this.UseImage; + } + this.UseButton.SetCooldownNormalizedUvs(); + this.UseButton.material.SetFloat("_Percent", target.PercentCool); + this.UseButton.color = UseButtonManager.EnabledColor; + return; + } + if (PlayerControl.LocalPlayer.Data.IsImpostor && PlayerControl.LocalPlayer.CanMove) + { + this.UseButton.sprite = this.SabotageImage; + this.UseButton.SetCooldownNormalizedUvs(); + this.UseButton.color = UseButtonManager.EnabledColor; + return; + } + this.UseButton.sprite = this.UseImage; + this.UseButton.color = UseButtonManager.DisabledColor; + } + + public void DoClick() + { + if (!base.isActiveAndEnabled) + { + return; + } + if (!PlayerControl.LocalPlayer) + { + return; + } + GameData.PlayerInfo data = PlayerControl.LocalPlayer.Data; + if (this.currentTarget != null) + { + PlayerControl.LocalPlayer.UseClosest(); + return; + } + if (data != null && data.IsImpostor) + { + DestroyableSingleton<HudManager>.Instance.ShowMap(delegate(MapBehaviour m) + { + m.ShowInfectedMap(); + }); + } + } + + internal void Refresh() + { + this.SetTarget(this.currentTarget); + } +} diff --git a/Client/Assembly-CSharp/Vector2Range.cs b/Client/Assembly-CSharp/Vector2Range.cs new file mode 100644 index 0000000..af83d56 --- /dev/null +++ b/Client/Assembly-CSharp/Vector2Range.cs @@ -0,0 +1,55 @@ +using System; +using UnityEngine; + +[Serializable] +public struct Vector2Range +{ + public float Width + { + get + { + return this.max.x - this.min.x; + } + } + + public float Height + { + get + { + return this.max.y - this.min.y; + } + } + + public Vector2 min; + + public Vector2 max; + + public Vector2Range(Vector2 min, Vector2 max) + { + this.min = min; + this.max = max; + } + + public void LerpUnclamped(ref Vector3 output, float t, float z) + { + output.Set(Mathf.LerpUnclamped(this.min.x, this.max.x, t), Mathf.LerpUnclamped(this.min.y, this.max.y, t), z); + } + + public void Lerp(ref Vector3 output, float t, float z) + { + output.Set(Mathf.Lerp(this.min.x, this.max.x, t), Mathf.Lerp(this.min.y, this.max.y, t), z); + } + + public Vector2 Next() + { + return new Vector2(UnityEngine.Random.Range(this.min.x, this.max.x), UnityEngine.Random.Range(this.min.y, this.max.y)); + } + + public static Vector2 NextEdge() + { + float f = 6.2831855f * UnityEngine.Random.value; + float x = Mathf.Cos(f); + float y = Mathf.Sin(f); + return new Vector2(x, y); + } +} diff --git a/Client/Assembly-CSharp/VendingMinigame.cs b/Client/Assembly-CSharp/VendingMinigame.cs new file mode 100644 index 0000000..19ad09b --- /dev/null +++ b/Client/Assembly-CSharp/VendingMinigame.cs @@ -0,0 +1,188 @@ +using System; +using System.Collections; +using System.Linq; +using UnityEngine; + +public class VendingMinigame : Minigame +{ + public static readonly string[] Letters = new string[] + { + "a", + "b", + "c" + }; + + public TextRenderer NumberText; + + public SpriteRenderer TargetImage; + + public string enteredCode = string.Empty; + + private bool animating; + + private bool done; + + private string targetCode; + + public SpriteRenderer AcceptButton; + + public VendingSlot[] Slots; + + public Sprite[] Drinks; + + public Sprite[] DrawnDrinks; + + public void OnEnable() + { + this.Begin(null); + } + + public override void Begin(PlayerTask task) + { + base.Begin(task); + int num = this.Drinks.RandomIdx<Sprite>(); + this.TargetImage.sprite = this.DrawnDrinks[num]; + for (int i = 0; i < this.Drinks.Length; i++) + { + Sprite sprite = this.Drinks[i]; + int num2; + while (!this.PickARandomSlot(sprite, out num2)) + { + } + this.Slots[num2].DrinkImage.enabled = true; + this.Slots[num2].DrinkImage.sprite = sprite; + if (num == i) + { + this.targetCode = VendingMinigame.SlotIdToString(num2); + } + } + this.NumberText.Text = string.Empty; + } + + private static int StringToSlotId(string code) + { + int num; + if (int.TryParse(code[0].ToString(), out num) || VendingMinigame.Letters.Any(new Func<string, bool>(code.EndsWith))) + { + return -1; + } + int num2 = VendingMinigame.Letters.IndexOf(new Predicate<string>(code.StartsWith)); + return int.Parse(code[1].ToString()) - 1 + num2 * 4; + } + + private static string SlotIdToString(int slotId) + { + int num = slotId % 4 + 1; + int num2 = slotId / 4; + return VendingMinigame.Letters[num2] + num; + } + + private bool PickARandomSlot(Sprite drink, out int slotId) + { + slotId = this.Slots.RandomIdx<VendingSlot>(); + return !this.Slots[slotId].DrinkImage.enabled; + } + + public void EnterDigit(string s) + { + if (this.animating) + { + return; + } + if (this.done) + { + return; + } + if (this.enteredCode.Length >= 2) + { + base.StartCoroutine(this.BlinkAccept()); + return; + } + this.enteredCode += s; + this.NumberText.Text = this.enteredCode; + } + + public void ClearDigits() + { + if (this.animating) + { + return; + } + this.enteredCode = string.Empty; + this.NumberText.Text = string.Empty; + } + + public void AcceptDigits() + { + if (this.animating) + { + return; + } + base.StartCoroutine(this.Animate()); + } + + private IEnumerator BlinkAccept() + { + int num; + for (int i = 0; i < 5; i = num) + { + this.AcceptButton.color = Color.gray; + yield return null; + yield return null; + this.AcceptButton.color = Color.white; + yield return null; + yield return null; + num = i + 1; + } + yield break; + } + + private IEnumerator Animate() + { + this.animating = true; + int num = VendingMinigame.StringToSlotId(this.enteredCode); + if (num >= 0 && this.Slots[num].DrinkImage.enabled) + { + yield return Effects.All(new IEnumerator[] + { + this.CoBlinkVend(), + this.Slots[num].CoBuy() + }); + if (this.targetCode == this.enteredCode) + { + this.done = true; + this.MyNormTask.NextStep(); + yield return base.CoStartClose(0.25f); + } + } + else + { + WaitForSeconds wait = new WaitForSeconds(0.1f); + this.NumberText.Text = "XXXXXXXX"; + yield return wait; + this.NumberText.Text = string.Empty; + yield return wait; + this.NumberText.Text = "XXXXXXXX"; + yield return wait; + wait = null; + } + this.enteredCode = string.Empty; + this.NumberText.Text = this.enteredCode; + this.animating = false; + yield break; + } + + private IEnumerator CoBlinkVend() + { + int num; + for (int i = 0; i < 5; i = num) + { + this.NumberText.Text = "Vending"; + yield return Effects.Wait(0.1f); + this.NumberText.Text = string.Empty; + yield return Effects.Wait(0.1f); + num = i + 1; + } + yield break; + } +} diff --git a/Client/Assembly-CSharp/VendingSlot.cs b/Client/Assembly-CSharp/VendingSlot.cs new file mode 100644 index 0000000..f2b43e6 --- /dev/null +++ b/Client/Assembly-CSharp/VendingSlot.cs @@ -0,0 +1,37 @@ +using System; +using System.Collections; +using UnityEngine; + +public class VendingSlot : MonoBehaviour +{ + public SpriteRenderer DrinkImage; + + public SpriteRenderer GlassImage; + + public IEnumerator CoBuy() + { + yield return new WaitForLerp(0.75f, delegate(float v) + { + this.GlassImage.size = new Vector2(1f, Mathf.Lerp(1.7f, 0f, v)); + this.GlassImage.transform.localPosition = new Vector3(0f, Mathf.Lerp(0f, 0.85f, v), -1f); + }); + yield return Effects.Shake(this.DrinkImage.transform, 0.75f, 0.075f); + Vector3 localPosition = this.DrinkImage.transform.localPosition; + localPosition.z = -5f; + this.DrinkImage.transform.localPosition = localPosition; + Vector3 v2 = localPosition; + v2.y = -8f - localPosition.y; + yield return Effects.All(new IEnumerator[] + { + Effects.Slide2D(this.DrinkImage.transform, localPosition, v2, 0.75f), + Effects.Rotate2D(this.DrinkImage.transform, 0f, -FloatRange.Next(-45f, 45f), 0.75f) + }); + yield return new WaitForLerp(0.75f, delegate(float v) + { + this.GlassImage.size = new Vector2(1f, Mathf.Lerp(0f, 1.7f, v)); + this.GlassImage.transform.localPosition = new Vector3(0f, Mathf.Lerp(0.85f, 0f, v), -1f); + }); + this.DrinkImage.enabled = false; + yield break; + } +} diff --git a/Client/Assembly-CSharp/Vent.cs b/Client/Assembly-CSharp/Vent.cs new file mode 100644 index 0000000..ce9c525 --- /dev/null +++ b/Client/Assembly-CSharp/Vent.cs @@ -0,0 +1,163 @@ +using System; +using PowerTools; +using UnityEngine; + +public class Vent : MonoBehaviour, IUsable +{ + public float UsableDistance + { + get + { + return 0.75f; + } + } + + public float PercentCool + { + get + { + return 0f; + } + } + + public int Id; + + public Vent Left; + + public Vent Right; + + public ButtonBehavior[] Buttons; + + public AnimationClip EnterVentAnim; + + public AnimationClip ExitVentAnim; + + private static readonly Vector3 CollOffset = new Vector3(0f, -0.3636057f, 0f); + + private SpriteRenderer myRend; + + private void Start() + { + this.SetButtons(false); + this.myRend = base.GetComponent<SpriteRenderer>(); + } + + public void SetButtons(bool enabled) + { + Vent[] array = new Vent[] + { + this.Right, + this.Left + }; + for (int i = 0; i < this.Buttons.Length; i++) + { + ButtonBehavior buttonBehavior = this.Buttons[i]; + if (enabled) + { + Vent vent = array[i]; + if (vent) + { + buttonBehavior.gameObject.SetActive(true); + Vector3 localPosition = (vent.transform.position - base.transform.position).normalized * 0.7f; + localPosition.y -= 0.08f; + localPosition.z = -10f; + buttonBehavior.transform.localPosition = localPosition; + buttonBehavior.transform.LookAt2d(vent.transform); + } + else + { + buttonBehavior.gameObject.SetActive(false); + } + } + else + { + buttonBehavior.gameObject.SetActive(false); + } + } + } + + public float CanUse(GameData.PlayerInfo pc, out bool canUse, out bool couldUse) + { + float num = float.MaxValue; + PlayerControl @object = pc.Object; + couldUse = (pc.IsImpostor && !pc.IsDead && (@object.CanMove || @object.inVent)); + canUse = couldUse; + if (canUse) + { + num = Vector2.Distance(@object.GetTruePosition(), base.transform.position); + canUse &= (num <= this.UsableDistance); + } + return num; + } + + public void SetOutline(bool on, bool mainTarget) + { + this.myRend.material.SetFloat("_Outline", (float)(on ? 1 : 0)); + this.myRend.material.SetColor("_OutlineColor", Color.red); + this.myRend.material.SetColor("_AddColor", mainTarget ? Color.red : Color.clear); + } + + public void ClickRight() + { + if (this.Right) + { + Vent.DoMove(this.Right.transform.position - Vent.CollOffset); + this.SetButtons(false); + this.Right.SetButtons(true); + } + } + + public void ClickLeft() + { + if (this.Left) + { + Vent.DoMove(this.Left.transform.position - Vent.CollOffset); + this.SetButtons(false); + this.Left.SetButtons(true); + } + } + + private static void DoMove(Vector3 pos) + { + PlayerControl.LocalPlayer.NetTransform.RpcSnapTo(pos); + if (Constants.ShouldPlaySfx()) + { + SoundManager.Instance.PlaySound(PlayerControl.LocalPlayer.VentMoveSounds.Random<AudioClip>(), false, 1f).pitch = FloatRange.Next(0.8f, 1.2f); + } + } + + public void Use() + { + bool flag; + bool flag2; + this.CanUse(PlayerControl.LocalPlayer.Data, out flag, out flag2); + if (!flag) + { + return; + } + PlayerControl localPlayer = PlayerControl.LocalPlayer; + if (Constants.ShouldPlaySfx()) + { + SoundManager.Instance.StopSound(localPlayer.VentEnterSound); + SoundManager.Instance.PlaySound(localPlayer.VentEnterSound, false, 1f).pitch = FloatRange.Next(0.8f, 1.2f); + } + if (localPlayer.inVent) + { + localPlayer.MyPhysics.RpcExitVent(this.Id); + this.SetButtons(false); + return; + } + localPlayer.MyPhysics.RpcEnterVent(this.Id); + this.SetButtons(true); + } + + internal void EnterVent() + { + base.GetComponent<SpriteAnim>().Play(this.EnterVentAnim, 1f); + } + + internal void ExitVent() + { + base.GetComponent<SpriteAnim>().Play(this.ExitVentAnim, 1f); + } +} diff --git a/Client/Assembly-CSharp/VersionShower.cs b/Client/Assembly-CSharp/VersionShower.cs new file mode 100644 index 0000000..8c87390 --- /dev/null +++ b/Client/Assembly-CSharp/VersionShower.cs @@ -0,0 +1,19 @@ +using System; +using UnityEngine; + +public class VersionShower : MonoBehaviour +{ + public TextRenderer text; + + public void Start() + { + string str = "v" + Application.version; + str += "s"; + if (!DetectTamper.Detect()) + { + str += "h"; + } + this.text.Text = str; + Screen.sleepTimeout = -1; + } +} diff --git a/Client/Assembly-CSharp/VerticalGauge.cs b/Client/Assembly-CSharp/VerticalGauge.cs new file mode 100644 index 0000000..08ebfec --- /dev/null +++ b/Client/Assembly-CSharp/VerticalGauge.cs @@ -0,0 +1,28 @@ +using System; +using UnityEngine; + +public class VerticalGauge : MonoBehaviour +{ + public float value = 0.5f; + + public float MaxValue = 1f; + + public float maskScale = 1f; + + public SpriteMask Mask; + + private float lastValue = float.MinValue; + + public void Update() + { + if (this.lastValue != this.value) + { + this.lastValue = this.value; + float num = Mathf.Clamp(this.lastValue / this.MaxValue, 0f, 1f) * this.maskScale; + Vector3 localScale = this.Mask.transform.localScale; + localScale.y = num; + this.Mask.transform.localScale = localScale; + this.Mask.transform.localPosition = new Vector3(0f, -this.Mask.sprite.bounds.size.y * (this.maskScale - num) / 2f, 0f); + } + } +} diff --git a/Client/Assembly-CSharp/VirtualJoystick.cs b/Client/Assembly-CSharp/VirtualJoystick.cs new file mode 100644 index 0000000..25aaa72 --- /dev/null +++ b/Client/Assembly-CSharp/VirtualJoystick.cs @@ -0,0 +1,59 @@ +using System; +using UnityEngine; + +public class VirtualJoystick : MonoBehaviour, IVirtualJoystick +{ + public Vector2 Delta { get; private set; } + + public float InnerRadius = 0.64f; + + public float OuterRadius = 1.28f; + + public CircleCollider2D Outer; + + public SpriteRenderer Inner; + + private Controller myController = new Controller(); + + protected virtual void FixedUpdate() + { + this.myController.Update(); + DragState dragState = this.myController.CheckDrag(this.Outer, false); + if (dragState - DragState.TouchStart <= 1) + { + float maxLength = this.OuterRadius - this.InnerRadius; + Vector2 vector = this.myController.DragPosition - base.transform.position; + float magnitude = vector.magnitude; + Vector2 a = new Vector2(Mathf.Sqrt(Mathf.Abs(vector.x)) * Mathf.Sign(vector.x), Mathf.Sqrt(Mathf.Abs(vector.y)) * Mathf.Sign(vector.y)); + this.Delta = Vector2.ClampMagnitude(a / this.OuterRadius, 1f); + this.Inner.transform.localPosition = Vector3.ClampMagnitude(vector, maxLength) + Vector3.back; + return; + } + if (dragState != DragState.Released) + { + return; + } + this.Delta = Vector2.zero; + this.Inner.transform.localPosition = Vector3.back; + } + + public virtual void UpdateJoystick(FingerBehaviour finger, Vector2 velocity, bool syncFinger) + { + Vector3 vector = this.Inner.transform.localPosition; + Vector3 vector2 = velocity.normalized * this.InnerRadius; + vector2.z = vector.z; + if (syncFinger) + { + vector = Vector3.Lerp(vector, vector2, Time.fixedDeltaTime * 5f); + this.Inner.transform.localPosition = vector; + vector = this.Inner.transform.position; + vector.z = -26f; + finger.transform.position = vector; + return; + } + if (this.Inner.gameObject != finger.gameObject) + { + this.Inner.transform.localPosition = vector2; + } + } +} diff --git a/Client/Assembly-CSharp/VoteBanSystem.cs b/Client/Assembly-CSharp/VoteBanSystem.cs new file mode 100644 index 0000000..23d030f --- /dev/null +++ b/Client/Assembly-CSharp/VoteBanSystem.cs @@ -0,0 +1,111 @@ +using System; +using System.Collections.Generic; +using Hazel; +using InnerNet; + +public class VoteBanSystem : InnerNetObject +{ + public static VoteBanSystem Instance; + + public Dictionary<int, int[]> Votes = new Dictionary<int, int[]>(); + + public enum RpcCalls + { + AddVote + } + + public void Awake() + { + VoteBanSystem.Instance = this; + } + + public void CmdAddVote(int clientId) + { + this.AddVote(AmongUsClient.Instance.ClientId, clientId); + MessageWriter messageWriter = AmongUsClient.Instance.StartRpc(this.NetId, 0, SendOption.Reliable); + messageWriter.Write(AmongUsClient.Instance.ClientId); + messageWriter.Write(clientId); + messageWriter.EndMessage(); + } + + private void AddVote(int srcClient, int clientId) + { + int[] array; + if (!this.Votes.TryGetValue(clientId, out array)) + { + array = (this.Votes[clientId] = new int[3]); + } + int num = -1; + for (int i = 0; i < array.Length; i++) + { + int num2 = array[i]; + if (num2 == srcClient) + { + break; + } + if (num2 == 0) + { + num = i; + break; + } + } + if (num != -1) + { + array[num] = srcClient; + base.SetDirtyBit(1U); + if (num == array.Length - 1) + { + AmongUsClient.Instance.KickPlayer(clientId, false); + } + } + } + + public bool HasMyVote(int clientId) + { + int[] array; + return this.Votes.TryGetValue(clientId, out array) && Array.IndexOf<int>(array, AmongUsClient.Instance.ClientId) != -1; + } + + public override void HandleRpc(byte callId, MessageReader reader) + { + if (callId == 0) + { + int srcClient = reader.ReadInt32(); + int clientId = reader.ReadInt32(); + this.AddVote(srcClient, clientId); + } + } + + public override bool Serialize(MessageWriter writer, bool initialState) + { + writer.Write((byte)this.Votes.Count); + foreach (KeyValuePair<int, int[]> keyValuePair in this.Votes) + { + writer.Write(keyValuePair.Key); + for (int i = 0; i < 3; i++) + { + writer.WritePacked(keyValuePair.Value[i]); + } + } + this.DirtyBits = 0U; + return true; + } + + public override void Deserialize(MessageReader reader, bool initialState) + { + int num = (int)reader.ReadByte(); + for (int i = 0; i < num; i++) + { + int key = reader.ReadInt32(); + int[] array; + if (!this.Votes.TryGetValue(key, out array)) + { + array = (this.Votes[key] = new int[3]); + } + for (int j = 0; j < 3; j++) + { + array[j] = reader.ReadPackedInt32(); + } + } + } +} diff --git a/Client/Assembly-CSharp/WaitForHostPopup.cs b/Client/Assembly-CSharp/WaitForHostPopup.cs new file mode 100644 index 0000000..5ccade5 --- /dev/null +++ b/Client/Assembly-CSharp/WaitForHostPopup.cs @@ -0,0 +1,27 @@ +using System; +using InnerNet; +using UnityEngine; + +public class WaitForHostPopup : DestroyableSingleton<WaitForHostPopup> +{ + public GameObject Content; + + public void Show() + { + if (AmongUsClient.Instance && AmongUsClient.Instance.ClientId > 0) + { + this.Content.SetActive(true); + } + } + + public void ExitGame() + { + AmongUsClient.Instance.ExitGame(DisconnectReasons.ExitGame); + this.Content.SetActive(false); + } + + public void Hide() + { + this.Content.SetActive(false); + } +} diff --git a/Client/Assembly-CSharp/WaitForLerp.cs b/Client/Assembly-CSharp/WaitForLerp.cs new file mode 100644 index 0000000..97c8bcd --- /dev/null +++ b/Client/Assembly-CSharp/WaitForLerp.cs @@ -0,0 +1,38 @@ +using System; +using System.Collections; +using UnityEngine; + +public class WaitForLerp : IEnumerator +{ + public object Current + { + get + { + return null; + } + } + + private float duration; + + private float timer; + + private Action<float> act; + + public WaitForLerp(float seconds, Action<float> act) + { + this.duration = seconds; + this.act = act; + } + + public bool MoveNext() + { + this.timer = Mathf.Min(this.timer + Time.deltaTime, this.duration); + this.act(this.timer / this.duration); + return this.timer < this.duration; + } + + public void Reset() + { + this.timer = 0f; + } +} diff --git a/Client/Assembly-CSharp/WeaponsMinigame.cs b/Client/Assembly-CSharp/WeaponsMinigame.cs new file mode 100644 index 0000000..c6dc8f6 --- /dev/null +++ b/Client/Assembly-CSharp/WeaponsMinigame.cs @@ -0,0 +1,149 @@ +using System; +using System.Collections; +using UnityEngine; + +public class WeaponsMinigame : Minigame +{ + public FloatRange XSpan = new FloatRange(-1.15f, 1.15f); + + public FloatRange YSpan = new FloatRange(-1.15f, 1.15f); + + public FloatRange TimeToSpawn; + + public ObjectPoolBehavior asteroidPool; + + public TextController ScoreText; + + public SpriteRenderer TargetReticle; + + public LineRenderer TargetLines; + + private Vector3 TargetCenter; + + public Collider2D BackgroundCol; + + public SpriteRenderer Background; + + public Controller myController = new Controller(); + + private float Timer; + + public AudioClip ShootSound; + + public AudioClip[] ExplodeSounds; + + public override void Begin(PlayerTask task) + { + base.Begin(task); + this.ScoreText.Text = "Destroyed: " + this.MyNormTask.taskStep; + this.TimeToSpawn.Next(); + } + + protected override IEnumerator CoAnimateOpen() + { + for (float timer = 0f; timer < 0.1f; timer += Time.deltaTime) + { + float num = timer / 0.1f; + base.transform.localScale = new Vector3(num, 0.1f, num); + yield return null; + } + for (float timer = 0.010000001f; timer < 0.1f; timer += Time.deltaTime) + { + float y = timer / 0.1f; + base.transform.localScale = new Vector3(1f, y, 1f); + yield return null; + } + base.transform.localScale = new Vector3(1f, 1f, 1f); + yield break; + } + + protected override IEnumerator CoDestroySelf() + { + for (float timer = 0.010000001f; timer < 0.1f; timer += Time.deltaTime) + { + float y = 1f - timer / 0.1f; + base.transform.localScale = new Vector3(1f, y, 1f); + yield return null; + } + for (float timer = 0f; timer < 0.1f; timer += Time.deltaTime) + { + float num = 1f - timer / 0.1f; + base.transform.localScale = new Vector3(num, 0.1f, num); + yield return null; + } + UnityEngine.Object.Destroy(base.gameObject); + yield break; + } + + public void FixedUpdate() + { + this.Background.color = Color.Lerp(Palette.ClearWhite, Color.white, Mathf.Sin(Time.time * 3f) * 0.1f + 0.79999995f); + if (this.MyNormTask && this.MyNormTask.IsComplete) + { + return; + } + this.Timer += Time.fixedDeltaTime; + if (this.Timer >= this.TimeToSpawn.Last) + { + this.Timer = 0f; + this.TimeToSpawn.Next(); + if (this.asteroidPool.InUse < this.MyNormTask.MaxStep - this.MyNormTask.TaskStep) + { + Asteroid ast = this.asteroidPool.Get<Asteroid>(); + ast.transform.localPosition = new Vector3(this.XSpan.max, this.YSpan.Next(), -1f); + ast.TargetPosition = new Vector3(this.XSpan.min, this.YSpan.Next(), -1f); + ast.GetComponent<ButtonBehavior>().OnClick.AddListener(delegate() + { + this.BreakApart(ast); + }); + } + } + this.myController.Update(); + if (this.myController.CheckDrag(this.BackgroundCol, false) == DragState.TouchStart) + { + if (Constants.ShouldPlaySfx()) + { + SoundManager.Instance.PlaySound(this.ShootSound, false, 1f); + } + Vector3 vector = this.myController.DragPosition - base.transform.position; + vector.z = -2f; + this.TargetReticle.transform.localPosition = vector; + vector.z = 0f; + this.TargetLines.SetPosition(1, vector); + if (!ShipStatus.Instance.WeaponsImage.IsPlaying(null)) + { + ShipStatus.Instance.FireWeapon(); + PlayerControl.LocalPlayer.RpcPlayAnimation(6); + } + } + } + + public void BreakApart(Asteroid ast) + { + if (Constants.ShouldPlaySfx()) + { + SoundManager.Instance.PlaySound(this.ExplodeSounds.Random<AudioClip>(), false, 1f).pitch = FloatRange.Next(0.8f, 1.2f); + } + if (!this.MyNormTask.IsComplete) + { + base.StartCoroutine(ast.CoBreakApart()); + if (this.MyNormTask) + { + this.MyNormTask.NextStep(); + this.ScoreText.Text = "Destroyed: " + this.MyNormTask.taskStep; + } + if (this.MyNormTask && this.MyNormTask.IsComplete) + { + base.StartCoroutine(base.CoStartClose(0.75f)); + foreach (PoolableBehavior poolableBehavior in this.asteroidPool.activeChildren) + { + Asteroid asteroid = (Asteroid)poolableBehavior; + if (!(asteroid == ast)) + { + base.StartCoroutine(asteroid.CoBreakApart()); + } + } + } + } + } +} diff --git a/Client/Assembly-CSharp/WeatherMinigame.cs b/Client/Assembly-CSharp/WeatherMinigame.cs new file mode 100644 index 0000000..fe02976 --- /dev/null +++ b/Client/Assembly-CSharp/WeatherMinigame.cs @@ -0,0 +1,34 @@ +using System; +using UnityEngine; + +public class WeatherMinigame : Minigame +{ + public float RefuelDuration = 5f; + + public VerticalGauge destGauge; + + private bool isDown; + + private float timer; + + public void FixedUpdate() + { + if (this.isDown && this.timer < 1f) + { + this.timer += Time.fixedDeltaTime / this.RefuelDuration; + this.MyNormTask.Data[0] = (byte)Mathf.Min(255f, this.timer * 255f); + if (this.timer >= 1f) + { + this.timer = 1f; + this.MyNormTask.NextStep(); + base.StartCoroutine(base.CoStartClose(0.75f)); + } + } + this.destGauge.value = this.timer; + } + + public void StartStopFill() + { + this.isDown = !this.isDown; + } +} diff --git a/Client/Assembly-CSharp/WinningPlayerData.cs b/Client/Assembly-CSharp/WinningPlayerData.cs new file mode 100644 index 0000000..dffd5e5 --- /dev/null +++ b/Client/Assembly-CSharp/WinningPlayerData.cs @@ -0,0 +1,36 @@ +using System; + +public class WinningPlayerData +{ + public string Name; + + public bool IsDead; + + public bool IsImpostor; + + public int ColorId; + + public uint SkinId; + + public uint HatId; + + public uint PetId; + + public bool IsYou; + + public WinningPlayerData() + { + } + + public WinningPlayerData(GameData.PlayerInfo player) + { + this.IsYou = (player.Object == PlayerControl.LocalPlayer); + this.Name = player.PlayerName; + this.IsDead = (player.IsDead || player.Disconnected); + this.IsImpostor = player.IsImpostor; + this.ColorId = (int)player.ColorId; + this.SkinId = player.SkinId; + this.PetId = player.PetId; + this.HatId = player.HatId; + } +} diff --git a/Client/Assembly-CSharp/Wire.cs b/Client/Assembly-CSharp/Wire.cs new file mode 100644 index 0000000..055bc41 --- /dev/null +++ b/Client/Assembly-CSharp/Wire.cs @@ -0,0 +1,61 @@ +using System; +using UnityEngine; + +public class Wire : MonoBehaviour +{ + public Vector2 BaseWorldPos { get; internal set; } + + private const int WireDepth = -14; + + public SpriteRenderer Liner; + + public SpriteRenderer ColorBase; + + public SpriteRenderer ColorEnd; + + public Collider2D hitbox; + + public SpriteRenderer WireTip; + + public sbyte WireId; + + public void Start() + { + this.BaseWorldPos = base.transform.position; + } + + public void ResetLine(Vector3 targetWorldPos, bool reset = false) + { + if (reset) + { + this.Liner.transform.localScale = new Vector3(0f, 0f, 0f); + this.WireTip.transform.eulerAngles = Vector3.zero; + this.WireTip.transform.position = base.transform.position; + return; + } + Vector2 vector = targetWorldPos - base.transform.position; + Vector2 normalized = vector.normalized; + Vector3 localPosition = default(Vector3); + localPosition = vector - normalized * 0.075f; + localPosition.z = -0.01f; + this.WireTip.transform.localPosition = localPosition; + float magnitude = vector.magnitude; + this.Liner.transform.localScale = new Vector3(magnitude, 1f, 1f); + this.Liner.transform.localPosition = vector / 2f; + this.WireTip.transform.LookAt2d(targetWorldPos); + this.Liner.transform.localEulerAngles = new Vector3(0f, 0f, Vector2.SignedAngle(Vector2.right, vector)); + } + + public void ConnectRight(WireNode node) + { + Vector3 position = node.transform.position; + this.ResetLine(position, false); + } + + public void SetColor(Color color) + { + this.Liner.material.SetColor("_Color", color); + this.ColorBase.color = color; + this.ColorEnd.color = color; + } +} diff --git a/Client/Assembly-CSharp/WireMinigame.cs b/Client/Assembly-CSharp/WireMinigame.cs new file mode 100644 index 0000000..27d0ecc --- /dev/null +++ b/Client/Assembly-CSharp/WireMinigame.cs @@ -0,0 +1,157 @@ +using System; +using UnityEngine; + +public class WireMinigame : Minigame +{ + private static readonly Color[] colors = new Color[] + { + Color.red, + Color.blue, + Color.yellow, + Color.magenta + }; + + public Wire[] LeftNodes; + + public WireNode[] RightNodes; + + public SpriteRenderer[] LeftLights; + + public SpriteRenderer[] RightLights; + + private Controller myController = new Controller(); + + private sbyte[] ExpectedWires = new sbyte[4]; + + private sbyte[] ActualWires = new sbyte[4]; + + public AudioClip[] WireSounds; + + private bool TaskIsForThisPanel() + { + return this.MyNormTask.taskStep < this.MyNormTask.Data.Length && !this.MyNormTask.IsComplete && (int)this.MyNormTask.Data[this.MyNormTask.taskStep] == base.ConsoleId; + } + + public override void Begin(PlayerTask task) + { + base.Begin(task); + IntRange.FillRandomRange(this.ExpectedWires); + for (int i = 0; i < this.LeftNodes.Length; i++) + { + this.ActualWires[i] = -1; + int num = (int)this.ExpectedWires[i]; + Wire wire = this.LeftNodes[i]; + wire.SetColor(WireMinigame.colors[num]); + wire.WireId = (sbyte)i; + this.RightNodes[i].SetColor(WireMinigame.colors[i]); + this.RightNodes[i].WireId = (sbyte)i; + int num2 = (int)this.ActualWires[i]; + if (num2 > -1) + { + wire.ConnectRight(this.RightNodes[num2]); + } + else + { + wire.ResetLine(Vector3.zero, true); + } + } + this.UpdateLights(); + } + + public void Update() + { + if (!this.TaskIsForThisPanel()) + { + return; + } + this.myController.Update(); + base.transform.position; + for (int i = 0; i < this.LeftNodes.Length; i++) + { + Wire wire = this.LeftNodes[i]; + DragState dragState = this.myController.CheckDrag(wire.hitbox, false); + if (dragState != DragState.Dragging) + { + if (dragState == DragState.Released) + { + if (this.ActualWires[(int)wire.WireId] == -1) + { + wire.ResetLine(wire.BaseWorldPos, true); + } + else if (Constants.ShouldPlaySfx()) + { + SoundManager.Instance.PlaySound(this.WireSounds.Random<AudioClip>(), false, 1f); + } + this.CheckTask(); + } + } + else + { + Vector2 vector = this.myController.DragPosition; + WireNode wireNode = this.CheckRightSide(vector); + if (wireNode) + { + vector = wireNode.transform.position; + this.ActualWires[(int)wire.WireId] = wireNode.WireId; + } + else + { + vector -= wire.BaseWorldPos.normalized * 0.05f; + this.ActualWires[(int)wire.WireId] = -1; + } + wire.ResetLine(vector, false); + } + } + this.UpdateLights(); + } + + private void UpdateLights() + { + for (int i = 0; i < this.ActualWires.Length; i++) + { + Color color = Color.yellow; + color *= 1f - Mathf.PerlinNoise((float)i, Time.time * 35f) * 0.3f; + color.a = 1f; + if (this.ActualWires[i] != this.ExpectedWires[i]) + { + this.RightLights[(int)this.ExpectedWires[i]].color = new Color(0.2f, 0.2f, 0.2f); + } + else + { + this.RightLights[(int)this.ExpectedWires[i]].color = color; + } + this.LeftLights[i].color = color; + } + } + + private WireNode CheckRightSide(Vector2 pos) + { + for (int i = 0; i < this.RightNodes.Length; i++) + { + WireNode wireNode = this.RightNodes[i]; + if (wireNode.hitbox.OverlapPoint(pos)) + { + return wireNode; + } + } + return null; + } + + private void CheckTask() + { + bool flag = true; + for (int i = 0; i < this.ActualWires.Length; i++) + { + if (this.ActualWires[i] != this.ExpectedWires[i]) + { + flag = false; + break; + } + } + if (flag) + { + this.MyNormTask.NextStep(); + this.Close(); + } + } +} diff --git a/Client/Assembly-CSharp/WireNode.cs b/Client/Assembly-CSharp/WireNode.cs new file mode 100644 index 0000000..04db0bc --- /dev/null +++ b/Client/Assembly-CSharp/WireNode.cs @@ -0,0 +1,19 @@ +using System; +using UnityEngine; + +public class WireNode : MonoBehaviour +{ + public Collider2D hitbox; + + public SpriteRenderer[] WireColors; + + public sbyte WireId; + + internal void SetColor(Color color) + { + for (int i = 0; i < this.WireColors.Length; i++) + { + this.WireColors[i].color = color; + } + } +} diff --git a/Client/Assembly-CSharp/XXHash.cs b/Client/Assembly-CSharp/XXHash.cs new file mode 100644 index 0000000..5845560 --- /dev/null +++ b/Client/Assembly-CSharp/XXHash.cs @@ -0,0 +1,189 @@ +using System; + +public class XXHash +{ + private uint seed; + + private const uint PRIME32_1 = 2654435761U; + + private const uint PRIME32_2 = 2246822519U; + + private const uint PRIME32_3 = 3266489917U; + + private const uint PRIME32_4 = 668265263U; + + private const uint PRIME32_5 = 374761393U; + + public XXHash(int seed) + { + this.seed = (uint)seed; + } + + public uint GetHash(byte[] buf) + { + int i = 0; + int num = buf.Length; + uint num3; + if (num >= 16) + { + int num2 = num - 16; + uint value = this.seed + 2654435761U + 2246822519U; + uint value2 = this.seed + 2246822519U; + uint value3 = this.seed; + uint value4 = this.seed - 2654435761U; + do + { + value = XXHash.CalcSubHash(value, buf, i); + i += 4; + value2 = XXHash.CalcSubHash(value2, buf, i); + i += 4; + value3 = XXHash.CalcSubHash(value3, buf, i); + i += 4; + value4 = XXHash.CalcSubHash(value4, buf, i); + i += 4; + } + while (i <= num2); + num3 = XXHash.RotateLeft(value, 1) + XXHash.RotateLeft(value2, 7) + XXHash.RotateLeft(value3, 12) + XXHash.RotateLeft(value4, 18); + } + else + { + num3 = this.seed + 374761393U; + } + num3 += (uint)num; + while (i <= num - 4) + { + num3 += BitConverter.ToUInt32(buf, i) * 3266489917U; + num3 = XXHash.RotateLeft(num3, 17) * 668265263U; + i += 4; + } + while (i < num) + { + num3 += (uint)buf[i] * 374761393U; + num3 = XXHash.RotateLeft(num3, 11) * 2654435761U; + i++; + } + num3 ^= num3 >> 15; + num3 *= 2246822519U; + num3 ^= num3 >> 13; + num3 *= 3266489917U; + return num3 ^ num3 >> 16; + } + + public uint GetHash(params uint[] buf) + { + int i = 0; + int num = buf.Length; + uint num3; + if (num >= 4) + { + int num2 = num - 4; + uint value = this.seed + 2654435761U + 2246822519U; + uint value2 = this.seed + 2246822519U; + uint value3 = this.seed; + uint value4 = this.seed - 2654435761U; + do + { + value = XXHash.CalcSubHash(value, buf[i]); + i++; + value2 = XXHash.CalcSubHash(value2, buf[i]); + i++; + value3 = XXHash.CalcSubHash(value3, buf[i]); + i++; + value4 = XXHash.CalcSubHash(value4, buf[i]); + i++; + } + while (i <= num2); + num3 = XXHash.RotateLeft(value, 1) + XXHash.RotateLeft(value2, 7) + XXHash.RotateLeft(value3, 12) + XXHash.RotateLeft(value4, 18); + } + else + { + num3 = this.seed + 374761393U; + } + num3 += (uint)(num * 4); + while (i < num) + { + num3 += buf[i] * 3266489917U; + num3 = XXHash.RotateLeft(num3, 17) * 668265263U; + i++; + } + num3 ^= num3 >> 15; + num3 *= 2246822519U; + num3 ^= num3 >> 13; + num3 *= 3266489917U; + return num3 ^ num3 >> 16; + } + + public uint GetHash(params int[] buf) + { + int i = 0; + int num = buf.Length; + uint num3; + if (num >= 4) + { + int num2 = num - 4; + uint value = this.seed + 2654435761U + 2246822519U; + uint value2 = this.seed + 2246822519U; + uint value3 = this.seed; + uint value4 = this.seed - 2654435761U; + do + { + value = XXHash.CalcSubHash(value, (uint)buf[i]); + i++; + value2 = XXHash.CalcSubHash(value2, (uint)buf[i]); + i++; + value3 = XXHash.CalcSubHash(value3, (uint)buf[i]); + i++; + value4 = XXHash.CalcSubHash(value4, (uint)buf[i]); + i++; + } + while (i <= num2); + num3 = XXHash.RotateLeft(value, 1) + XXHash.RotateLeft(value2, 7) + XXHash.RotateLeft(value3, 12) + XXHash.RotateLeft(value4, 18); + } + else + { + num3 = this.seed + 374761393U; + } + num3 += (uint)(num * 4); + while (i < num) + { + num3 += (uint)(buf[i] * -1028477379); + num3 = XXHash.RotateLeft(num3, 17) * 668265263U; + i++; + } + num3 ^= num3 >> 15; + num3 *= 2246822519U; + num3 ^= num3 >> 13; + num3 *= 3266489917U; + return num3 ^ num3 >> 16; + } + + public uint GetHash(int buf) + { + uint num = XXHash.RotateLeft(this.seed + 374761393U + 4U + (uint)(buf * -1028477379), 17) * 668265263U; + uint num2 = (num ^ num >> 15) * 2246822519U; + uint num3 = (num2 ^ num2 >> 13) * 3266489917U; + return num3 ^ num3 >> 16; + } + + private static uint CalcSubHash(uint value, byte[] buf, int index) + { + uint num = BitConverter.ToUInt32(buf, index); + value += num * 2246822519U; + value = XXHash.RotateLeft(value, 13); + value *= 2654435761U; + return value; + } + + private static uint CalcSubHash(uint value, uint read_value) + { + value += read_value * 2246822519U; + value = XXHash.RotateLeft(value, 13); + value *= 2654435761U; + return value; + } + + private static uint RotateLeft(uint value, int count) + { + return value << count | value >> 32 - count; + } +} diff --git a/Client/Assembly-CSharp/obj/Debug/Assembly-CSharp.csproj.CoreCompileInputs.cache b/Client/Assembly-CSharp/obj/Debug/Assembly-CSharp.csproj.CoreCompileInputs.cache new file mode 100644 index 0000000..2d286a7 --- /dev/null +++ b/Client/Assembly-CSharp/obj/Debug/Assembly-CSharp.csproj.CoreCompileInputs.cache @@ -0,0 +1 @@ +b8fad2e40478c2524efc69c84e4392785708d392 diff --git a/Client/Assembly-CSharp/obj/Debug/Assembly-CSharp.csprojAssemblyReference.cache b/Client/Assembly-CSharp/obj/Debug/Assembly-CSharp.csprojAssemblyReference.cache Binary files differnew file mode 100644 index 0000000..528e904 --- /dev/null +++ b/Client/Assembly-CSharp/obj/Debug/Assembly-CSharp.csprojAssemblyReference.cache |