using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Logging;
using GameNetcodeStuff;
using HarmonyLib;
using ImpostorCompany;
using LethalSus.Patches;
using UnityEngine;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("LethalSus")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("LethalSus")]
[assembly: AssemblyCopyright("Copyright © 2024")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("b07090fa-d448-44f8-b1db-1cc22a043fac")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace ImpostorCompany
{
[BepInPlugin("Vincenzo.Impostor", "Impostor Company", "1.0.0")]
public class ImpostorCompanyModBase : BaseUnityPlugin
{
private const string modGUID = "Vincenzo.Impostor";
private const string modName = "Impostor Company";
private const string modVersion = "1.0.0";
private readonly Harmony harmony = new Harmony("Vincenzo.Impostor");
public static ImpostorCompanyModBase Instance;
internal ManualLogSource mls;
private void Awake()
{
if ((Object)(object)Instance == (Object)null)
{
Instance = this;
}
mls = Logger.CreateLogSource("Vincenzo.Impostor");
harmony.PatchAll(typeof(ImpostorCompanyModBase));
harmony.PatchAll(typeof(StartOfRoundPatch));
harmony.PatchAll(typeof(TerminalParsePlayerSentencePatch));
harmony.PatchAll(typeof(StartMatchLeverPatch));
mls.LogInfo((object)"Impostor Company Mod has loaded.");
}
}
}
namespace LethalSus.Patches
{
[HarmonyPatch(typeof(StartMatchLever))]
internal class StartMatchLeverPatch
{
private static float updateInterval = 0f;
private static bool isDeactivatedBecauseOfImpostor = false;
private static string previousDisabledHoverTip = "";
public static bool ImpostorContextCanStartShip()
{
if (!StartOfRoundPatch.impostorEnabled)
{
return true;
}
int thisClientPlayerId = StartOfRound.Instance.thisClientPlayerId;
if (StartOfRoundPatch.IsImpostor(thisClientPlayerId))
{
List<int> list = StartOfRoundPatch.AlivePlayerIds();
foreach (int item in list)
{
if (!StartOfRoundPatch.IsImpostor(item))
{
return false;
}
}
}
return true;
}
[HarmonyPatch("Update")]
[HarmonyPrefix]
public static bool UpdatePatch(StartMatchLever __instance)
{
if (updateInterval <= 0f)
{
updateInterval = 2f;
if (!__instance.triggerScript.interactable && !isDeactivatedBecauseOfImpostor)
{
return true;
}
if (__instance.leverHasBeenPulled)
{
if (!ImpostorContextCanStartShip())
{
if (!isDeactivatedBecauseOfImpostor)
{
previousDisabledHoverTip = __instance.triggerScript.disabledHoverTip;
}
__instance.triggerScript.interactable = false;
isDeactivatedBecauseOfImpostor = true;
__instance.triggerScript.disabledHoverTip = "[All innocents must be dead]";
return false;
}
__instance.triggerScript.interactable = true;
__instance.triggerScript.disabledHoverTip = previousDisabledHoverTip;
isDeactivatedBecauseOfImpostor = false;
__instance.triggerScript.hoverTip = "Start ship : [LMB]";
return true;
}
return true;
}
updateInterval -= Time.deltaTime;
return false;
}
}
[HarmonyPatch(typeof(StartOfRound))]
internal class StartOfRoundPatch
{
public static bool impostorEnabled = true;
public static bool isImpostorPicked = false;
public static List<int> impostors = new List<int>();
private static void ResetImpostors()
{
impostors = new List<int>();
isImpostorPicked = false;
}
public static void SetImpostorMode(bool status)
{
if (status != impostorEnabled)
{
impostorEnabled = status;
DisplayImpostorModeEnabledOrDisabled();
if (status)
{
DisplayImpostorStatus();
}
}
}
public static bool IsImpostor(int playerId)
{
return impostors.Contains(playerId);
}
private static IEnumerator PlayImpostorAnimation()
{
yield return (object)new WaitForSeconds(2f);
QuickMenuManager quickMenu = Object.FindObjectOfType<QuickMenuManager>();
yield return (object)new WaitUntil((Func<bool>)(() => !quickMenu.isMenuOpen));
HUDManager.Instance.DisplayTip("You are an IMPOSTOR", "You can type 'impostor' in the terminal to get more information.", true, false, "LC_Tip1");
}
private static IEnumerator PlayInnocentAnimation()
{
yield return (object)new WaitForSeconds(2f);
QuickMenuManager quickMenu = Object.FindObjectOfType<QuickMenuManager>();
yield return (object)new WaitUntil((Func<bool>)(() => !quickMenu.isMenuOpen));
HUDManager.Instance.DisplayTip("You are innocent", "Please make the quotas without worrying about any impostor.", false, false, "LC_Tip1");
}
private static IEnumerator PlayToggleModeAnimation()
{
yield return (object)new WaitForSeconds(0.1f);
QuickMenuManager quickMenu = Object.FindObjectOfType<QuickMenuManager>();
yield return (object)new WaitUntil((Func<bool>)(() => !quickMenu.isMenuOpen));
HUDManager.Instance.DisplayTip("Impostor is " + (impostorEnabled ? "ENABLED" : "DISABLED"), "Type 'imp on' or 'imp off' to toggle impostor mode", false, false, "LC_Tip1");
}
private static void DisplayImpostorStatus()
{
if (isImpostorPicked)
{
int thisClientPlayerId = StartOfRound.Instance.thisClientPlayerId;
PlayerControllerB val = StartOfRound.Instance.allPlayerScripts[thisClientPlayerId];
if (IsImpostor(thisClientPlayerId))
{
((MonoBehaviour)val).StartCoroutine(PlayImpostorAnimation());
}
else
{
((MonoBehaviour)val).StartCoroutine(PlayInnocentAnimation());
}
}
}
private static void DisplayImpostorModeEnabledOrDisabled()
{
int thisClientPlayerId = StartOfRound.Instance.thisClientPlayerId;
PlayerControllerB val = StartOfRound.Instance.allPlayerScripts[thisClientPlayerId];
((MonoBehaviour)val).StartCoroutine(PlayToggleModeAnimation());
}
public static List<string> ImpostorsNames()
{
List<string> list = new List<string>();
PlayerControllerB[] allPlayerScripts = StartOfRound.Instance.allPlayerScripts;
for (int i = 0; i < allPlayerScripts.Length; i++)
{
if (IsImpostor(i))
{
list.Add(allPlayerScripts[i].playerUsername);
}
}
return list;
}
public static List<int> ConnectedPlayerIds()
{
PlayerControllerB[] allPlayerScripts = StartOfRound.Instance.allPlayerScripts;
List<int> list = new List<int>();
for (int i = 0; i < allPlayerScripts.Length; i++)
{
if (allPlayerScripts[i].isPlayerDead || allPlayerScripts[i].isPlayerControlled)
{
list.Add(i);
}
}
return list;
}
public static List<int> AlivePlayerIds()
{
PlayerControllerB[] allPlayerScripts = StartOfRound.Instance.allPlayerScripts;
List<int> list = new List<int>();
for (int i = 0; i < allPlayerScripts.Length; i++)
{
if (!allPlayerScripts[i].isPlayerDead && allPlayerScripts[i].isPlayerControlled)
{
list.Add(i);
}
}
return list;
}
public static int PickNumberOfImpostors()
{
int num = Random.Range(0, 100);
if (num < 30)
{
return 0;
}
if (num < 90)
{
return 1;
}
return 2;
}
public static void PickImpostors(int nbImpostors)
{
List<int> list = ConnectedPlayerIds();
nbImpostors = Math.Min(nbImpostors, list.Count);
Random random = new Random(StartOfRound.Instance.randomMapSeed + 2);
impostors = new List<int>();
for (int i = 0; i < nbImpostors; i++)
{
int index = random.Next(list.Count);
impostors.Add(list[index]);
list.RemoveAt(index);
}
isImpostorPicked = true;
ImpostorCompanyModBase.Instance.mls.LogInfo((object)"Impostor(s) have been picked");
}
[HarmonyPatch("WritePlayerNotes")]
[HarmonyPostfix]
public static void WritePlayerNotesPatch()
{
if (!impostorEnabled)
{
return;
}
for (int i = 0; i < StartOfRound.Instance.gameStats.allPlayerStats.Length; i++)
{
if (IsImpostor(i))
{
StartOfRound.Instance.gameStats.allPlayerStats[i].playerNotes.Add("Impostor.");
}
}
}
[HarmonyPatch("EndOfGame")]
[HarmonyPostfix]
public static void EndOfGamePatch()
{
ResetImpostors();
}
[HarmonyPatch("OnShipLandedMiscEvents")]
[HarmonyPostfix]
public static void OnShipLandedMiscEventsPatch()
{
if (StartOfRound.Instance.currentLevel.planetHasTime)
{
int num = PickNumberOfImpostors();
PickImpostors(1);
if (impostorEnabled)
{
DisplayImpostorStatus();
}
}
}
}
[HarmonyPatch(typeof(Terminal), "ParsePlayerSentence")]
public static class TerminalParsePlayerSentencePatch
{
private static string GetImpostorMessage(bool isImpostor)
{
if (isImpostor)
{
string text = "The company has designated you as an IMPOSTOR.\n\nIf you disclose this information, you will be subject to the disciplinary process.\nYou must ensure that all the innocent players die before the ship takes off, good luck!\n\n";
if (StartOfRoundPatch.impostors.Count > 1)
{
bool flag = StartOfRoundPatch.impostors.Count > 3;
text = text + "And by the way, there " + (flag ? "are" : "is") + (StartOfRoundPatch.impostors.Count - 1) + " other impostor" + (flag ? "s" : "");
}
return text;
}
return "You are not an impostor.\n\nThe company does not know anything about impostors and will not be held accountable for any murders.\nIf you find any of your colleagues suspicious, do not hesitate to eliminate them.\n";
}
public static bool Prefix(Terminal __instance, ref TerminalNode __result)
{
string[] source = new string[4] { "impostor", "imp", "impostors", "impo" };
string[] array = __instance.screenText.text.Split(new char[1] { '\n' });
ImpostorCompanyModBase.Instance.mls.LogInfo((object)("Received terminal command: " + string.Join(" ", array)));
if (array.Length == 0)
{
return true;
}
string[] array2 = array.Last().Trim().ToLower()
.Split(new char[1] { ' ' });
if (array2.Length == 0 || !source.Contains(array2[0]))
{
return true;
}
if (array2.Length != 0 && source.Contains(array2[0]))
{
if (array2.Length > 1)
{
switch (array2[1])
{
case "1":
case "enable":
case "on":
StartOfRoundPatch.impostorEnabled = true;
__result = CreateTerminalNode("Impostor mode has been enabled.\n\n");
return false;
case "0":
case "disable":
case "off":
StartOfRoundPatch.impostorEnabled = false;
__result = CreateTerminalNode("Impostor mode has been disabled.\n\n");
return false;
case "stats":
__result = CreateTerminalNode("Probability for the number of impostors:\n 0 impostors: 30%\n 1 impostor: 60%\n 2 impostors: 10%\n");
return false;
case "help":
__result = CreateTerminalNode("Commands:\n 'impostor enable' or 'imp on' to enable the mode for you.\n\n 'impostor disable' or 'imp off' to disable the mode for you.\n\n 'impostor' or 'imp' to get information about your current role.\n\n 'impostor stats' to get information about the probability of impostors.\n\n");
return false;
default:
__result = CreateTerminalNode("Unknown impostor command. type 'imp help' to get a list of supported commands.\n\n");
return false;
}
}
if (!StartOfRoundPatch.impostorEnabled)
{
__result = CreateTerminalNode("Impostor mode is disabled.\nType 'impostor enable' or 'imp on' to enable it.\n\n");
}
else if (StartOfRoundPatch.isImpostorPicked)
{
__result = CreateTerminalNode(GetImpostorMessage(StartOfRoundPatch.IsImpostor(StartOfRound.Instance.thisClientPlayerId)) + "\n");
}
else
{
__result = CreateTerminalNode("Impostor(s) have not been picked yet.\n\n");
}
return false;
}
return true;
}
private static TerminalNode CreateTerminalNode(string message)
{
TerminalNode val = ScriptableObject.CreateInstance<TerminalNode>();
val.displayText = message;
val.clearPreviousText = true;
return val;
}
}
}