summaryrefslogtreecommitdiff
path: root/Client/Assembly-CSharp/ShipStatus.cs
diff options
context:
space:
mode:
Diffstat (limited to 'Client/Assembly-CSharp/ShipStatus.cs')
-rw-r--r--Client/Assembly-CSharp/ShipStatus.cs738
1 files changed, 738 insertions, 0 deletions
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());
+ }
+}