Compare commits

..
49 Commits
Author SHA1 Message Date
Ape 71461583b3 That was not a fun surpirse 2026-05-29 16:46:00 +02:00
Ape 81c20d4706 1.7.3 Part Three 2026-05-29 15:41:12 +02:00
Ape 94c0049939 1.7.3 Part Two 2026-05-29 15:28:48 +02:00
Ape 1c3224396c 1.7.3 Part One 2026-05-29 00:01:19 +02:00
Ape de4f057899 1.7.2 2026-05-14 21:59:09 +02:00
Ape 3e4d833b66 1.7.1 2026-04-12 19:07:06 +02:00
Ape 6a5fbe7300 1.7.0 2026-04-01 12:58:58 +02:00
Ape fbf9b2b6eb 3 Small fixes 2026-04-01 12:49:21 +02:00
Ape 7da659af7b 1.6.6 2026-03-30 17:42:23 +02:00
Ape 58df006f07 Yeah I still can't fix the dumb level stuff 2026-03-30 17:38:29 +02:00
Ape 0f373b8328 Super important change 2026-03-27 20:08:15 +01:00
Ape 16ed549de4 Update ExilePatch.cs 2026-03-27 20:06:29 +01:00
Ape bc2aa74046 .. Why did it do that? 2026-03-27 19:58:41 +01:00
Ape 45859032bd Merge branch 'main' of https://github.com/ApeMV/AmongUsRevamped 2026-03-27 19:57:32 +01:00
Ape 66a5eb0b09 Small fixes and optimize FixedUpdate 2026-03-27 19:55:57 +01:00
Ape 95306ba8a9 1.6.4 2026-03-22 13:30:08 +01:00
Ape 2ee17166f2 The sizes of your fixes don't matter 2026-03-22 13:09:14 +01:00
Ape 10bae07af1 The size of your fix doesn't matter 2026-03-03 20:47:17 +01:00
Ape df0a68ff19 1.6.2 2026-02-25 14:58:09 +01:00
Ape 69ecb3c7a0 Fix start detection, few more strings 2026-02-25 14:26:50 +01:00
Ape b30fa9a1e7 Finishing what was started III 2026-02-24 22:15:33 +01:00
Ape aa56c78c70 Finishing what was started II 2026-02-23 21:52:31 +01:00
Ape cd1de51a1f Finishing what was started I 2026-02-22 23:29:30 +01:00
Ape 6d0d80b736 Experimental chat in game 2026-02-22 18:37:15 +01:00
Ape 9af84609d9 New moderator system and /reload fix 2026-02-21 23:28:41 +01:00
Ape af67b4a0c4 1.6.0 2026-02-21 16:44:26 +01:00
Ape c4b6e5709f Fix role assign problems and some strings 2026-02-21 16:42:22 +01:00
Ape e53acde70a Update README for version 1.5.3 features 2026-02-18 21:30:13 +01:00
Ape f1d98c100d More translation, 2 settings, small sabo fixes 2026-02-18 21:06:23 +01:00
Ape 44f63d6042 Command, GM, NumberOption fixes + Faster loading 2026-02-17 16:50:07 +01:00
Ape 5f7ddf35e7 Number converting and translation 2026-02-15 22:06:43 +01:00
Ape 95106ddeeb Settings and settings + settings, settings 2026-02-12 23:19:07 +01:00
Ape f4c157153a Merge branch 'main' of https://github.com/ApeMV/AmongUsRevamped 2026-02-05 14:23:15 +01:00
Ape 84978edc99 Tiniest fixes ever and buttons 2026-02-05 14:23:10 +01:00
Ape 23715a848d Meow 2026-02-05 11:58:23 +01:00
Ape a7cec7787f 1.5.1 readme 2026-02-05 11:54:42 +01:00
Ape 02f7ddc63a Custom role fixes, small setting fix, winner text change 2026-02-02 20:41:26 +01:00
Ape 600234b5f2 Discodr icon 2026-02-02 15:18:40 +01:00
Ape 15d6f54982 Better options, String fix, HnS fix 2026-02-02 14:10:50 +01:00
Ape 5570d6f4ea Kick players who say start, small num fix 2026-02-01 21:14:13 +01:00
Ape e9f1c1aaf1 Lighting the stars + like so many other stuff 2026-02-01 20:19:24 +01:00
Ape a6c3220892 Starlight compatibility, small fixes 2026-02-01 15:59:29 +01:00
Ape 673386336a Dleks, Fixes, Role assigner, Sprites, Translation system 2026-01-25 20:24:09 +01:00
Ape 2ac4728f8a 1.4.0 2026-01-23 19:09:40 +01:00
Ape 88599a0680 ? ? ? ? ? ? ? ? ? ? 2026-01-23 18:44:07 +01:00
Ape 5ae6d648e3 ??????????????????????? 2026-01-23 17:39:24 +01:00
Ape 21dec84e64 I cast null reference exception 2026-01-23 00:41:37 +01:00
Ape 79425e5fb8 Update GameStartManagerPatch.cs 2026-01-22 10:27:23 +01:00
Ape 294b5df4d9 Send intercontinental missile to hackers & some other stuff 2026-01-21 22:17:29 +01:00
44 changed files with 3895 additions and 731 deletions

No files matched your search

+26 -17
View File
@@ -1,6 +1,7 @@
global using HarmonyLib;
global using System.Collections.Generic;
global using System.Linq;
global using Object = UnityEngine.Object;
using AmongUs.GameOptions;
using BepInEx;
@@ -11,6 +12,9 @@ using UnityEngine;
namespace AmongUsRevamped;
// dotnet build -c release
// dotnet build -c android
[BepInAutoPlugin]
[BepInProcess("Among Us.exe")]
public partial class Main : BasePlugin
@@ -26,19 +30,24 @@ public partial class Main : BasePlugin
public static ConfigEntry<string> Preset5 { get; private set; }
public static ConfigEntry<bool> GM { get; private set; }
public static ConfigEntry<bool> UnlockFps { get; private set; }
public static ConfigEntry<bool> ShowFps { get; private set; }
public static ConfigEntry<bool> AutoStart { get; private set; }
public static ConfigEntry<bool> DarkTheme { get; private set; }
public static ConfigEntry<bool> LobbyMusic { get; private set; }
public static ConfigEntry<bool> DisableInfoWhenDead { get; private set; }
public static NormalGameOptionsV10 NormalOptions => GameOptionsManager.Instance != null ? GameOptionsManager.Instance.currentNormalGameOptions : null;
public static HideNSeekGameOptionsV10 HideNSeekOptions => GameOptionsManager.Instance != null ? GameOptionsManager.Instance.currentHideNSeekGameOptions : null;
public static MapNames CurrentMap => (MapNames)NormalOptions.MapId;
public static bool HasArgumentException;
public static string CredentialsText;
public const string ModVersion = "v1.3.2";
public const string ModVersion = "v1.7.3";
public static float GameTimer;
public static readonly Dictionary<int, int> SayStartTimes = [];
public static PlayerControl[] AllPlayerControls
{
get
@@ -76,12 +85,13 @@ public partial class Main : BasePlugin
AutoStart = Config.Bind("Client Options", "Auto Start", false);
GM = Config.Bind("Client Options", "Game Master", false);
UnlockFps = Config.Bind("Client Options", "Unlock FPS", false);
ShowFps = Config.Bind("Client Options", "Show FPS", false);
AutoStart = Config.Bind("Client Options", "Auto Start", false);
DarkTheme = Config.Bind("Client Options", "Dark Theme", false);
LobbyMusic = Config.Bind("Client Options", "Lobby Music", false);
DisableInfoWhenDead = Config.Bind("Client Options", "Disable Task/Kill View", false);
Translator.Init();
BanManager.Init();
Harmony.PatchAll();
@@ -120,19 +130,18 @@ public partial class Main : BasePlugin
Fortegreen = 18
}
// Innersloth now censors messages with more than 5 numbers. This is the best bypass I can give
public enum BasicNumberToLetter
// Innersloth now censors messages with more than 5 numbers. Sucks to be them.
public static readonly char[] CircledDigits =
{
Zero = 0,
One = 1,
Two = 2,
Three = 3,
Four = 4,
Five = 5,
Six = 6,
Seven = 7,
Eight = 8,
Nine = 9,
Ten = 10
}
'⓪', // 0
'①', // 1
'②', // 2
'③', // 3
'④', // 4
'⑤', // 5
'⑥', // 6
'⑦', // 7
'⑧', // 8
'⑨' // 9
};
}
+17 -8
View File
@@ -1,24 +1,33 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<TargetFramework Condition="'$(Configuration)' == 'Android'">net8.0</TargetFramework>
<TargetFramework Condition="'$(Configuration)' != 'Android'">net6.0</TargetFramework>
<LangVersion>latest</LangVersion>
<DebugType>embedded</DebugType>
<VersionPrefix>1.0.0</VersionPrefix>
<VersionSuffix>dev</VersionSuffix>
<Description>The ultimate Host-Only mod without Modded Protocol</Description>
<Authors>Most Various</Authors>
<Authors>apemv</Authors>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<Configurations>Release;Android</Configurations>
<Configuration Condition="'$(Configuration)' == ''">Release</Configuration>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)' == 'Debug'">
<Configuration>Release</Configuration>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="BepInEx.Unity.IL2CPP" Version="6.0.0-be.735" Private="false" ExcludeAssets="runtime;native" />
<PackageReference Include="AmongUs.GameLibs.Steam" Version="2025.11.18" PrivateAssets="all" />
<PackageReference Include="BepInEx.Unity.IL2CPP" Version="6.0.0-be.735" ExcludeAssets="runtime;native" />
<PackageReference Include="AmongUs.GameLibs.Steam" Version="2026.3.31" PrivateAssets="all" Condition="'$(Configuration)' == 'Release'"/>
<PackageReference Include="AmongUs.GameLibs.Android" Version="2025.10.14" PrivateAssets="all" Condition="'$(Configuration)' == 'Android'"/>
<PackageReference Include="BepInEx.AutoPlugin" Version="1.1.0" PrivateAssets="all" />
<PackageReference Include="BepInEx.IL2CPP.MSBuild" Version="2.1.0-rc.1" PrivateAssets="all" ExcludeAssets="runtime" />
<EmbeddedResource Include=".\Resources\**" />
</ItemGroup>
<Target Name="Copy" AfterTargets="Build" Condition="'$(AmongUs)' != ''">
<Target Name="Copy" AfterTargets="Build" Condition="'$(AmongUs)' != '' And '$(Configuration)' != 'Android'">
<Copy SourceFiles="$(TargetPath)" DestinationFolder="$(AmongUs)/BepInEx/plugins/" UseSymboliclinksIfPossible="true" />
</Target>
</Project>
+116 -18
View File
@@ -5,38 +5,80 @@ using System.Security.Cryptography;
using System.Text;
using System.Text.RegularExpressions;
using System.Reflection;
using UnityEngine;
// https://github.com/EnhancedNetwork/TownofHost-Enhanced/blob/main/Modules/BanManager.cs
namespace AmongUsRevamped;
public static class BanManager
{
public static readonly string DataPath =
#if ANDROID
Application.persistentDataPath;
#else
".";
#endif
public static string RemoveHtmlTags(this string str) => Regex.Replace(str, "<[^>]*?>", "");
private static readonly string DenyNameListPath = "./AUR-DATA/DenyNameList.txt";
private static string BanListPath = "./AUR-DATA/BanList.txt";
private static string ModeratorListPath = "./AUR-DATA/ModeratorList.txt";
private static readonly string DenyNameListPath = $"{DataPath}/AUR-DATA/Deniednames.txt";
private static string BanListPath = $"{DataPath}/AUR-DATA/Banlist.txt";
private static string BanWordPath = $"{DataPath}/AUR-DATA/Deniedwords.txt";
private static string VipListPath = $"{DataPath}/AUR-DATA/VIP.txt";
private static string ModeratorListPath = $"{DataPath}/AUR-DATA/Moderator.txt";
private static string AdminListPath = $"{DataPath}/AUR-DATA/Admin.txt";
private static string TemplatePath = $"{DataPath}/AUR-DATA/Templates.txt";
public static Dictionary<string, string> Templates = new();
public static List<string> TempBanWhiteList = [];
public static void Init()
{
try
{
Directory.CreateDirectory("AUR-DATA");
if (!Directory.Exists($"{DataPath}/AUR-DATA")) Directory.CreateDirectory($"{DataPath}/AUR-DATA");
if (!File.Exists(DenyNameListPath))
{
Logger.Warn("Creating a new DenyNameList.txt file", "BanManager");
File.Create(DenyNameListPath).Close();
File.WriteAllText(DenyNameListPath, Translator.Get("bannameWelcome"));
}
if (!File.Exists(BanListPath))
{
Logger.Warn("Creating a new BanList.txt file", "BanManager");
Logger.Warn("Creating a new Banlist.txt file", "BanManager");
File.Create(BanListPath).Close();
File.WriteAllText(BanListPath, Translator.Get("banlistWelcome"));
}
if (!File.Exists(BanWordPath))
{
Logger.Warn("Creating a new Banlist.txt file", "BanManager");
File.Create(BanWordPath).Close();
File.WriteAllText(BanWordPath, Translator.Get("banwordWelcome"));
}
if (!File.Exists(VipListPath))
{
Logger.Warn("Creating a new VIP.txt file", "BanManager");
File.Create(VipListPath).Close();
File.WriteAllText(VipListPath, Translator.Get("vipWelcome"));
}
if (!File.Exists(ModeratorListPath))
{
Logger.Warn("Creating a new ModeratorList.txt file", "BanManager");
Logger.Warn("Creating a new Moderator.txt file", "BanManager");
File.Create(ModeratorListPath).Close();
File.WriteAllText(ModeratorListPath, Translator.Get("moderatorWelcome"));
}
if (!File.Exists(AdminListPath))
{
Logger.Warn("Creating a new Admin.txt file", "BanManager");
File.Create(AdminListPath).Close();
File.WriteAllText(AdminListPath, Translator.Get("adminWelcome"));
}
if (!File.Exists(TemplatePath))
{
Logger.Warn("Creating a new Templates.txt file", "BanManager");
File.Create(TemplatePath).Close();
File.WriteAllText(TemplatePath, Translator.Get("templateWelcome"));
}
LoadTemplates();
}
catch (Exception ex)
@@ -91,7 +133,7 @@ public static class BanManager
string friendcode = player?.FriendCode;
// Check file BanList.txt
if (Options.ApplyBanList.GetBool() && CheckBanList(friendcode, player?.GetHashedPuid()))
if (CheckBanList(friendcode, player?.GetHashedPuid()))
{
AmongUsClient.Instance.KickPlayer(player.Id, true);
Logger.Info($"{player.PlayerName} was in the BanList and has been banned", "BanListBan");
@@ -120,12 +162,14 @@ public static class BanManager
try
{
Directory.CreateDirectory("AUR-DATA");
if (!Directory.Exists($"{DataPath}/AUR-DATA")) Directory.CreateDirectory($"{DataPath}/AUR-DATA");
if (!File.Exists(BanListPath)) File.Create(BanListPath).Close();
using StreamReader sr = new(BanListPath);
string line;
while ((line = sr.ReadLine()) != null)
{
if (line.StartsWith("#")) continue;
if (line == "") continue;
if (!OnlyCheckPuid)
{
@@ -141,17 +185,71 @@ public static class BanManager
}
return false;
}
}
[HarmonyPatch(typeof(BanMenu), nameof(BanMenu.Select))]
class BanMenuSelectPatch
{
public static void Postfix(BanMenu __instance, int clientId)
public static bool IsPlayerInDenyName(ClientData client, string name)
{
ClientData recentClient = AmongUsClient.Instance.GetRecentClient(clientId);
if (recentClient == null) return;
if (name == "" || !AmongUsClient.Instance.AmHost) return false;
if (!BanManager.CheckBanList(recentClient?.FriendCode, recentClient?.GetHashedPuid()))
__instance.BanButton.GetComponent<ButtonRolloverHandler>().SetEnabledColors();
var deniedNames = File.ReadAllLines(DenyNameListPath).Where(x => !x.StartsWith("#"));
if (deniedNames.Where(code => !string.IsNullOrWhiteSpace(code)).Any(code => name.Contains(code, StringComparison.OrdinalIgnoreCase)))
{
AmongUsClient.Instance.KickPlayer(client.Id, false);
Logger.Info($" {name} was kicked because their name was in DenyNameList.txt", "Kick");
Logger.SendInGame($"{name} was kicked because their name was in DenyNameList.txt");
return true;
}
else return false;
}
public static bool IsWordBanned(PlayerControl player, string input)
{
if (input == "" || !AmongUsClient.Instance.AmHost || Utils.CheckAccessLevel(player.Data.FriendCode) > 0) return false;
var bannedWords = File.ReadAllLines(BanWordPath).Where(x => !x.StartsWith("#"));
if (bannedWords.Where(code => !string.IsNullOrWhiteSpace(code)).Any(code => input.Contains(code, StringComparison.OrdinalIgnoreCase)))
{
AmongUsClient.Instance.KickPlayer(player.Data.ClientId, false);
Logger.Info($" {player.Data.PlayerName} was kicked because they sent a banned word", "Kick");
Logger.SendInGame($"{player.Data.PlayerName} was kicked because they sent a banned word");
return true;
}
else return false;
}
[HarmonyPatch(typeof(BanMenu), nameof(BanMenu.Select))]
class BanMenuSelectPatch
{
public static void Postfix(BanMenu __instance, int clientId)
{
ClientData recentClient = AmongUsClient.Instance.GetRecentClient(clientId);
if (recentClient == null) return;
if (!BanManager.CheckBanList(recentClient?.FriendCode, recentClient?.GetHashedPuid()))
__instance.BanButton.GetComponent<ButtonRolloverHandler>().SetEnabledColors();
}
}
public static void LoadTemplates()
{
Templates.Clear();
if (!File.Exists(TemplatePath)) return;
foreach (var line in File.ReadAllLines(TemplatePath))
{
if (string.IsNullOrWhiteSpace(line)) continue;
if (line.StartsWith("#")) continue;
int splitIndex = line.IndexOf(':');
if (splitIndex == -1) continue;
string key = line[..splitIndex].Trim().ToLower();
string value = line[(splitIndex + 1)..].Trim();
if (!Templates.ContainsKey(key)) Templates.Add(key, value);
}
}
}
+483 -154
View File
@@ -4,6 +4,29 @@ using UnityEngine;
// https://github.com/tukasa0001/TownOfHost/blob/main/Modules/OptionHolder.cs
namespace AmongUsRevamped
{
public static class CL
{
public static Color32 Hex(string hex)
{
if (hex.StartsWith("#"))
hex = hex.Substring(1);
if (hex.Length == 3)
{
hex = $"{hex[0]}{hex[0]}{hex[1]}{hex[1]}{hex[2]}{hex[2]}";
}
if (hex.Length != 6)
throw new System.ArgumentException("Hex color must be 6 or 3 characters long.");
byte r = byte.Parse(hex.Substring(0, 2), System.Globalization.NumberStyles.HexNumber);
byte g = byte.Parse(hex.Substring(2, 2), System.Globalization.NumberStyles.HexNumber);
byte b = byte.Parse(hex.Substring(4, 2), System.Globalization.NumberStyles.HexNumber);
return new Color32(r, g, b, 255);
}
}
[HarmonyPatch]
public static class Options
{
@@ -15,12 +38,6 @@ namespace AmongUsRevamped
taskOptionsLoad = Task.Run(Load);
}
[HarmonyPatch(typeof(MainMenuManager), nameof(MainMenuManager.Start)), HarmonyPostfix]
public static void WaitOptionsLoad()
{
taskOptionsLoad.Wait();
}
public const int PresetId = 0;
private static readonly string[] presets =
@@ -31,12 +48,21 @@ namespace AmongUsRevamped
public static readonly string[] gameModes =
{
"None", "0 Kill Cooldown", "Shift And Seek", "Speedrun"
"Standard", "0 Kill Cooldown", "Shift And Seek", "Speedrun"
};
public static readonly string[] colorLevels =
public static readonly string[] accessLevels =
{
"Moderators", "Everyone", "Nobody"
"Everyone", "<color=yellow>VIP</color> And Above", "<color=purple>Moderator</color> And Above", "<color=red>Admin</color>", "Only You"
};
public static readonly string[] crewmateAbilities =
{
"Mayor", "Workhorse", "Jester", "Speedrunner", "None"
};
public static readonly string[] impostorAbilities =
{
"Tyrant", "Stealer", "Juggernaut", "None"
};
//System
@@ -50,10 +76,10 @@ namespace AmongUsRevamped
public static OptionItem KickInvalidFriendCodes;
public static OptionItem TempBanInvalidFriendCodes;
public static OptionItem ApplyBanList;
public static OptionItem ApplyDenyNameList;
public static OptionItem ApplyModeratorList;
public static OptionItem ModeratorCanUseCommand;
public static OptionItem AutoKickStart;
public static OptionItem AutoKickStartAsBan;
public static OptionItem AutoKickStartTimes;
public static OptionItem AutoKickStartStrength;
public static OptionItem TabGroupAutomation;
@@ -69,16 +95,64 @@ namespace AmongUsRevamped
public static OptionItem ColorCommandLevel;
public static OptionItem AllowFortegreen;
public static OptionItem NoGameEnd;
public static OptionItem TabGroupAccess;
public static OptionItem SlashColorCmd;
public static OptionItem SlashRolesAndGamemodeCmd;
public static OptionItem SlashLastGameCmd;
public static OptionItem SlashHelpAndAurCmd;
public static OptionItem SlashKickCmd;
public static OptionItem SlashBanCmd;
public static OptionItem SlashEndMeetingCmd;
public static OptionItem SlashStartAndEndGameCmd;
//Mod
//Gameplay
public static OptionItem TabGroupSabotages;
public static OptionItem DeadImpostorsCanSabotage;
public static OptionItem DisableSabotage;
public static OptionItem DisableReactor;
public static OptionItem DisableOxygen;
public static OptionItem DisableLights;
public static OptionItem DisableComms;
public static OptionItem DisableHeli;
public static OptionItem DisableMushroomMixup;
public static OptionItem DisableCloseDoor;
public static OptionItem DisableReport;
public static OptionItem TabGroupGameplayGeneral;
public static OptionItem DisableAnnoyingMeetingCalls;
public static OptionItem ChangeDecontaminationTime;
public static OptionItem DecontaminationTimeOnMiraHQ;
public static OptionItem DecontaminationDoorOpenTimeOnMiraHQ;
public static OptionItem DecontaminationTimeOnPolus;
public static OptionItem DecontaminationDoorOpenTimeOnPolus;
public static OptionItem DisableSporeTrigger;
public static OptionItem DisableDevices;
private static OptionItem DisableSkeldDevices;
public static OptionItem DisableSkeldAdmin;
public static OptionItem DisableSkeldCamera;
private static OptionItem DisableMiraHQDevices;
public static OptionItem DisableMiraHQAdmin;
public static OptionItem DisableMiraHQDoorLog;
private static OptionItem DisablePolusDevices;
public static OptionItem DisablePolusAdmin;
public static OptionItem DisablePolusCamera;
public static OptionItem DisablePolusVital;
private static OptionItem DisableAirshipDevices;
public static OptionItem DisableAirshipCockpitAdmin;
public static OptionItem DisableAirshipRecordsAdmin;
public static OptionItem DisableAirshipCamera;
public static OptionItem DisableAirshipVital;
private static OptionItem DisableFungleDevices;
public static OptionItem DisableFungleCamera;
public static OptionItem DisableFungleVital;
public static OptionItem TabGroupTasks;
public static OptionItem OverrideTaskSettings;
public static OptionItem AllPlayersSameTasks;
public static OptionItem TaskPercentNeededToWin;
public static OptionItem DisableMiraTasks;
@@ -185,6 +259,10 @@ namespace AmongUsRevamped
public static OptionItem DisableUploadData;
// Gamemode
/*
public static OptionItem TabGroupStandard;
public static OptionItem ChatBeforeFirstMeeting;
*/
public static OptionItem TabGroupHNS;
public static OptionItem NumSeekers;
@@ -193,14 +271,69 @@ namespace AmongUsRevamped
public static OptionItem TabGroupSNS;
public static OptionItem SNSSettingsOverride;
public static OptionItem SNSChatInGame;
public static OptionItem CrewAutoWinsGameAfter;
public static OptionItem CantKillTime;
public static OptionItem MisfiresToSuicide;
public static OptionItem SNSDisableSabotage;
public static OptionItem SNSDisableReactor;
public static OptionItem SNSDisableOxygen;
public static OptionItem SNSDisableLights;
public static OptionItem SNSDisableComms;
public static OptionItem SNSDisableHeli;
public static OptionItem SNSDisableMushroomMixup;
public static OptionItem SNSDisableCloseDoor;
public static OptionItem TabGroupSpeedrun;
public static OptionItem SpeedrunSettingsOverride;
public static OptionItem GameAutoEndsAfter;
public static OptionItem EngineerMode;
// Abilities
public static OptionItem TabGroupCrewmate;
public static OptionItem OverrideCrewmate;
public static OptionItem CrewmateAbility;
public static OptionItem OverrideScientist;
public static OptionItem ScientistAbility;
public static OptionItem OverrideEngineer;
public static OptionItem EngineerAbility;
public static OptionItem OverrideNoisemaker;
public static OptionItem NoisemakerAbility;
public static OptionItem OverrideTracker;
public static OptionItem TrackerAbility;
public static OptionItem OverrideDetective;
public static OptionItem DetectiveAbility;
public static OptionItem TabGroupCrewmateAbilities;
public static OptionItem ExtraVotesCrewmate;
public static OptionItem ExtraVotesPerTask;
public static OptionItem SpeedrunnerShortTasks;
public static OptionItem SpeedrunnerLongTasks;
public static OptionItem TabGroupImpostor;
public static OptionItem OverrideImpostor;
public static OptionItem ImpostorAbility;
public static OptionItem OverrideShapeshifter;
public static OptionItem ShapeshifterAbility;
public static OptionItem OverridePhantom;
public static OptionItem PhantomAbility;
public static OptionItem OverrideViper;
public static OptionItem ViperAbility;
public static OptionItem TabGroupImpostorAbilities;
public static OptionItem ExtraVotesImpostor;
public static OptionItem ExtraVotesPerKill;
public static OptionItem KillsNeededForJuggernaut;
public static bool IsLoaded = false;
@@ -212,291 +345,487 @@ namespace AmongUsRevamped
.SetColor(new Color32(204, 204, 0, 255))
.SetHeader(true);
Gamemode = StringOptionItem.Create(1, "Gamemode", gameModes, 0, TabGroup.SystemSettings, false)
Gamemode = StringOptionItem.Create(1, Translator.Get("gamemode"), gameModes, 0, TabGroup.SystemSettings, false)
.SetColor(Color.green)
.SetHeader(true);
TabGroupMain = TextOptionItem.Create(60000, "Moderation", TabGroup.SystemSettings)
TabGroupMain = TextOptionItem.Create(60000, Translator.Get("tabGroupMain"), TabGroup.SystemSettings)
.SetColor(Color.blue);
KickLowLevelPlayer = IntegerOptionItem.Create(60050, "Kick Players Under Level", new(0, 100, 1), 0, TabGroup.SystemSettings, false)
KickLowLevelPlayer = IntegerOptionItem.Create(60050, Translator.Get("kickLowLevelPlayer"), new(0, 100, 1), 0, TabGroup.SystemSettings, false)
.SetValueFormat(OptionFormat.Level);
TempBanLowLevelPlayer = BooleanOptionItem.Create(60051, "Ban Instead Of Kick", false, TabGroup.SystemSettings, false)
TempBanLowLevelPlayer = BooleanOptionItem.Create(60051, Translator.Get("tempBanLowLevelPlayer"), false, TabGroup.SystemSettings, false)
.SetParent(KickLowLevelPlayer);
KickInvalidFriendCodes = BooleanOptionItem.Create(60080, "Kick Invalid FriendCodes", true, TabGroup.SystemSettings, false);
TempBanInvalidFriendCodes = BooleanOptionItem.Create(60081, "Ban Instead Of Kick", false, TabGroup.SystemSettings, false)
KickInvalidFriendCodes = BooleanOptionItem.Create(60080, Translator.Get("kickInvalidFriendCodes"), true, TabGroup.SystemSettings, false);
TempBanInvalidFriendCodes = BooleanOptionItem.Create(60081, Translator.Get("tempBanInvalidFriendCodes"), false, TabGroup.SystemSettings, false)
.SetParent(KickInvalidFriendCodes);
ApplyBanList = BooleanOptionItem.Create(60110, "Apply BanList", true, TabGroup.SystemSettings, true);
ApplyDenyNameList = BooleanOptionItem.Create(60120, "Apply DenyName List", true, TabGroup.SystemSettings, false);
ApplyModeratorList = BooleanOptionItem.Create(60121, "Apply Moderator List", true, TabGroup.SystemSettings, false);
ModeratorCanUseCommand = BooleanOptionItem.Create(60122, "Moderators can use commands", true, TabGroup.SystemSettings, false);
AutoKickStart = BooleanOptionItem.Create(60123, Translator.Get("autoKickStart"), false, TabGroup.SystemSettings, false);
AutoKickStartAsBan = BooleanOptionItem.Create(60124, Translator.Get("autoKickStartAsBan"), false, TabGroup.SystemSettings, false)
.SetParent(AutoKickStart);
AutoKickStartTimes = IntegerOptionItem.Create(60125, Translator.Get("autoKickStartTimes"), new(1, 10, 1), 1, TabGroup.SystemSettings, false)
.SetParent(AutoKickStart)
.SetValueFormat(OptionFormat.Times);
AutoKickStartStrength = BooleanOptionItem.Create(60126, Translator.Get("autoKickStartStrength"), false, TabGroup.SystemSettings, false)
.SetParent(AutoKickStart);
TabGroupAutomation = TextOptionItem.Create(60149, "Automation", TabGroup.SystemSettings)
TabGroupAutomation = TextOptionItem.Create(60149, Translator.Get("tabGroupAutomation"), TabGroup.SystemSettings)
.SetColor(Color.yellow);
AutoSendGameInfo = BooleanOptionItem.Create(60150, "Automatically send winner info", true, TabGroup.SystemSettings, false);
AutoRejoinLobby = BooleanOptionItem.Create(60210, "Auto Rejoin Lobby", false, TabGroup.SystemSettings, false);
AutoStartTimer = IntegerOptionItem.Create(64420, "Countdown For Auto Start", new(1, 600, 1), 5, TabGroup.SystemSettings, false)
AutoSendGameInfo = BooleanOptionItem.Create(60150, Translator.Get("autoSendGameInfo"), true, TabGroup.SystemSettings, false);
AutoRejoinLobby = BooleanOptionItem.Create(60210, Translator.Get("autoRejoinLobby"), false, TabGroup.SystemSettings, false);
AutoStartTimer = IntegerOptionItem.Create(64420, Translator.Get("autoStartTimer"), new(1, 5, 1), 5, TabGroup.SystemSettings, false)
.SetValueFormat(OptionFormat.Seconds);
WaitAutoStart = IntegerOptionItem.Create(64421, "Auto Start After", new(10, 600, 10), 300, TabGroup.SystemSettings, false)
WaitAutoStart = IntegerOptionItem.Create(64421, Translator.Get("waitAutoStart"), new(10, 600, 10), 300, TabGroup.SystemSettings, false)
.SetValueFormat(OptionFormat.Seconds);
PlayerAutoStart = IntegerOptionItem.Create(64422, "Players Needed To Auto Start", new(1, 15, 1), 1, TabGroup.SystemSettings, false);
PlayerAutoStart = IntegerOptionItem.Create(64422, Translator.Get("playerAutoStart"), new(1, 15, 1), 1, TabGroup.SystemSettings, false);
TabGroupMisc = TextOptionItem.Create(60379, "Miscelleneous", TabGroup.SystemSettings)
TabGroupMisc = TextOptionItem.Create(60379, Translator.Get("tabGroupMisc"), TabGroup.SystemSettings)
.SetColor(Color.green);
StartCountdown = IntegerOptionItem.Create(60380, "Default Starting Countdown", new(1, 600, 1), 5, TabGroup.SystemSettings, false)
StartCountdown = IntegerOptionItem.Create(60380, Translator.Get("startCountdown"), new(1, 5, 1), 5, TabGroup.SystemSettings, false)
.SetValueFormat(OptionFormat.Seconds);
ColorCommandLevel = StringOptionItem.Create(60381, "Who Can use Color Commands", colorLevels, 0, TabGroup.SystemSettings, false);
AllowFortegreen = BooleanOptionItem.Create(60382, "Allow Fortegreen Color", false, TabGroup.SystemSettings, false);
NoGameEnd = BooleanOptionItem.Create(60383, "No Game End", false, TabGroup.SystemSettings, false)
AllowFortegreen = BooleanOptionItem.Create(60382, Translator.Get("allowFortegreen"), false, TabGroup.SystemSettings, false);
NoGameEnd = BooleanOptionItem.Create(60383, Translator.Get("noGameEnd"), false, TabGroup.SystemSettings, false)
.SetColor(Color.red);
// Gamemode Settings
TabGroupHNS = TextOptionItem.Create(70000, "Hide and Seek", TabGroup.GamemodeSettings)
.SetColor(Color.green);
NumSeekers = IntegerOptionItem.Create(70001, "# Seekers", new(0, 15, 1), 1, TabGroup.GamemodeSettings, false)
TabGroupAccess = TextOptionItem.Create(60400, Translator.Get("tabGroupAccess"), TabGroup.SystemSettings)
.SetColor(Color.red);
SlashColorCmd = StringOptionItem.Create(60401, Translator.Get("slashColorCmd"), accessLevels, 1, TabGroup.SystemSettings, false);
SlashRolesAndGamemodeCmd = StringOptionItem.Create(60402, Translator.Get("slashRolesAndGamemodeCmd"), accessLevels, 1, TabGroup.SystemSettings, false);
SlashLastGameCmd = StringOptionItem.Create(60403, Translator.Get("slashLastGameCmd"), accessLevels, 1, TabGroup.SystemSettings, false);
SlashHelpAndAurCmd = StringOptionItem.Create(60404, Translator.Get("slashHelpAndAurCmd"), accessLevels, 1, TabGroup.SystemSettings, false);
SlashKickCmd = StringOptionItem.Create(60405, Translator.Get("slashKickCmd"), accessLevels, 2, TabGroup.SystemSettings, false);
SlashBanCmd = StringOptionItem.Create(60406, Translator.Get("slashBanCmd"), accessLevels, 2, TabGroup.SystemSettings, false);
SlashEndMeetingCmd = StringOptionItem.Create(60407, Translator.Get("slashEndMeetingCmd"), accessLevels, 3, TabGroup.SystemSettings, false);
SlashStartAndEndGameCmd = StringOptionItem.Create(60408, Translator.Get("slashStartAndEndGameCmd"), accessLevels, 3, TabGroup.SystemSettings, false);
// Ability settings
TabGroupCrewmate = TextOptionItem.Create(100000, Translator.Get("tabGroupCrewmate"), TabGroup.AbilitySettings)
.SetColor(CL.Hex("#8cffff"));
CrewmateAbility = StringOptionItem.Create(100002, Translator.Get("crewmateAbility"), crewmateAbilities, 4, TabGroup.AbilitySettings, false)
.SetColor(CL.Hex("#8cffff"));
ScientistAbility = StringOptionItem.Create(100101, Translator.Get("scientistAbility"), crewmateAbilities, 4, TabGroup.AbilitySettings, false)
.SetColor(CL.Hex("#8cffff"));
EngineerAbility = StringOptionItem.Create(100201, Translator.Get("engineerAbility"), crewmateAbilities, 4, TabGroup.AbilitySettings, false)
.SetColor(CL.Hex("#8cffff"));
NoisemakerAbility = StringOptionItem.Create(100301, Translator.Get("noisemakerAbility"), crewmateAbilities, 4, TabGroup.AbilitySettings, false)
.SetColor(CL.Hex("#8cffff"));
TrackerAbility = StringOptionItem.Create(100401, Translator.Get("trackerAbility"), crewmateAbilities, 4, TabGroup.AbilitySettings, false)
.SetColor(CL.Hex("#8cffff"));
DetectiveAbility = StringOptionItem.Create(100501, Translator.Get("detectiveAbility"), crewmateAbilities, 4, TabGroup.AbilitySettings, false)
.SetColor(CL.Hex("#8cffff"));
TabGroupCrewmateAbilities = TextOptionItem.Create(101000, Translator.Get("tabGroupCrewmateAbilities"), TabGroup.AbilitySettings)
.SetColor(CL.Hex("#8cffff"));
ExtraVotesCrewmate = IntegerOptionItem.Create(101001, Translator.Get("extraVotesCrewmate"), new(1, 15, 1), 1, TabGroup.AbilitySettings, false)
.SetValueFormat(OptionFormat.Level);
ExtraVotesPerTask = FloatOptionItem.Create(101002, Translator.Get("extraVotesPerTask"), new(0.25f, 3f, 0.25f), 0.5f, TabGroup.AbilitySettings, false)
.SetValueFormat(OptionFormat.Level);
SpeedrunnerShortTasks = IntegerOptionItem.Create(101003, Translator.Get("speedrunnerShortTasks"), new(0, 15, 1), 1, TabGroup.AbilitySettings, false)
.SetValueFormat(OptionFormat.Level);
SpeedrunnerLongTasks = IntegerOptionItem.Create(101004, Translator.Get("speedrunnerLongTasks"), new(0, 15, 1), 1, TabGroup.AbilitySettings, false)
.SetValueFormat(OptionFormat.Level);
TabGroupImpostor = TextOptionItem.Create(102000, Translator.Get("tabGroupImpostor"), TabGroup.AbilitySettings)
.SetColor(CL.Hex("#ff1919"));
TabGroup0Kcd = TextOptionItem.Create(70025, "0 Kill Cooldown", TabGroup.GamemodeSettings)
ImpostorAbility = StringOptionItem.Create(100002, Translator.Get("impostorAbility"), impostorAbilities, 3, TabGroup.AbilitySettings, false)
.SetColor(CL.Hex("#ff1919"));
ShapeshifterAbility = StringOptionItem.Create(102101, Translator.Get("shapeshifterAbility"), impostorAbilities, 3, TabGroup.AbilitySettings, false)
.SetColor(CL.Hex("#ff1919"));
PhantomAbility = StringOptionItem.Create(102201, Translator.Get("phantomAbility"), impostorAbilities, 3, TabGroup.AbilitySettings, false)
.SetColor(CL.Hex("#ff1919"));
ViperAbility = StringOptionItem.Create(102301, Translator.Get("viperAbility"), impostorAbilities, 3, TabGroup.AbilitySettings, false)
.SetColor(CL.Hex("#ff1919"));
TabGroupImpostorAbilities = TextOptionItem.Create(103000, Translator.Get("tabGroupImpostorAbilities"), TabGroup.AbilitySettings)
.SetColor(CL.Hex("#ff1919"));
ExtraVotesImpostor = IntegerOptionItem.Create(103001, Translator.Get("extraVotesImpostor"), new(1, 15, 1), 1, TabGroup.AbilitySettings, false)
.SetValueFormat(OptionFormat.Level);
ExtraVotesPerKill = FloatOptionItem.Create(103002, Translator.Get("extraVotesPerKill"), new(0.25f, 3f, 0.25f), 0.5f, TabGroup.AbilitySettings, false)
.SetValueFormat(OptionFormat.Level);
KillsNeededForJuggernaut = IntegerOptionItem.Create(103003, Translator.Get("killsNeededForJuggernaut"), new(3, 15, 1), 7, TabGroup.AbilitySettings, false)
.SetValueFormat(OptionFormat.Level);
// Gamemode Settings
TabGroupHNS = TextOptionItem.Create(70000, Translator.Get("tabGroupHNS"), TabGroup.GamemodeSettings)
.SetColor(Color.green);
NumSeekers = IntegerOptionItem.Create(70001, Translator.Get("numSeekers"), new(1, 15, 1), 1, TabGroup.GamemodeSettings, false)
.SetValueFormat(OptionFormat.Level);
TabGroup0Kcd = TextOptionItem.Create(70025, Translator.Get("tabGroup0Kcd"), TabGroup.GamemodeSettings)
.SetColor(Color.red);
NoKcdSettingsOverride = BooleanOptionItem.Create(70026, "Auto Update Settings", true, TabGroup.GamemodeSettings, false);
NoKcdSettingsOverride = BooleanOptionItem.Create(70026, Translator.Get("noKcdSettingsOverride"), true, TabGroup.GamemodeSettings, false);
TabGroupSNS = TextOptionItem.Create(70050, "Shift and Seek", TabGroup.GamemodeSettings)
TabGroupSNS = TextOptionItem.Create(70050, Translator.Get("tabGroupSNS"), TabGroup.GamemodeSettings)
.SetColor(Color.yellow);
SNSSettingsOverride = BooleanOptionItem.Create(70051, "Auto Update Settings", true, TabGroup.GamemodeSettings, false);
CantKillTime = IntegerOptionItem.Create(70053, "After Misfiring, Can't kill for", new(0, 60, 5), 20, TabGroup.GamemodeSettings, false)
SNSSettingsOverride = BooleanOptionItem.Create(70051, Translator.Get("snsSettingsOverride"), true, TabGroup.GamemodeSettings, false);
SNSChatInGame = BooleanOptionItem.Create(70063, Translator.Get("snsChatInGame"), false, TabGroup.GamemodeSettings, false);
CantKillTime = IntegerOptionItem.Create(70053, Translator.Get("cantKillTime"), new(0, 60, 5), 20, TabGroup.GamemodeSettings, false)
.SetValueFormat(OptionFormat.Seconds);
MisfiresToSuicide = IntegerOptionItem.Create(70052, "Suicide After Amount Of Misfires", new(1, 10, 1), 2, TabGroup.GamemodeSettings, false);
CrewAutoWinsGameAfter = IntegerOptionItem.Create(70054, "Crewmates Automatically Win After", new(0, 600, 10), 300, TabGroup.GamemodeSettings, false)
MisfiresToSuicide = IntegerOptionItem.Create(70052, Translator.Get("misfiresToSuicide"), new(1, 10, 1), 2, TabGroup.GamemodeSettings, false);
CrewAutoWinsGameAfter = IntegerOptionItem.Create(70054, Translator.Get("crewAutoWinsGameAfter"), new(0, 600, 10), 300, TabGroup.GamemodeSettings, false)
.SetValueFormat(OptionFormat.Seconds);
SNSDisableSabotage = BooleanOptionItem.Create(70055, Translator.Get("snsDisableSabotage"), true, TabGroup.GamemodeSettings, false)
.SetColor(Color.red);
SNSDisableReactor = BooleanOptionItem.Create(70056, Translator.Get("snsDisableReactor"), true, TabGroup.GamemodeSettings, false)
.SetParent(SNSDisableSabotage)
.SetColor(new Color32(255, 153, 153, byte.MaxValue));
SNSDisableOxygen = BooleanOptionItem.Create(70057, Translator.Get("snsDisableOxygen"), true, TabGroup.GamemodeSettings, false)
.SetParent(SNSDisableSabotage)
.SetColor(new Color32(255, 153, 153, byte.MaxValue));
SNSDisableLights = BooleanOptionItem.Create(70058, Translator.Get("snsDisableLights"), true, TabGroup.GamemodeSettings, false)
.SetParent(SNSDisableSabotage)
.SetColor(new Color32(255, 153, 153, byte.MaxValue));
SNSDisableComms = BooleanOptionItem.Create(70059, Translator.Get("snsDisableComms"), true, TabGroup.GamemodeSettings, false)
.SetParent(SNSDisableSabotage)
.SetColor(new Color32(255, 153, 153, byte.MaxValue));
SNSDisableHeli = BooleanOptionItem.Create(70060, Translator.Get("snsDisableHeli"), true, TabGroup.GamemodeSettings, false)
.SetParent(SNSDisableSabotage)
.SetColor(new Color32(255, 153, 153, byte.MaxValue));
SNSDisableMushroomMixup = BooleanOptionItem.Create(70061, Translator.Get("snsDisableMushroomMixup"), true, TabGroup.GamemodeSettings, false)
.SetParent(SNSDisableSabotage)
.SetColor(new Color32(255, 153, 153, byte.MaxValue));
SNSDisableCloseDoor = BooleanOptionItem.Create(70062, Translator.Get("snsDisableCloseDoor"), true, TabGroup.GamemodeSettings, false)
.SetColor(Color.red);
TabGroupSpeedrun = TextOptionItem.Create(70075, "Speedrun", TabGroup.GamemodeSettings)
TabGroupSpeedrun = TextOptionItem.Create(70075, Translator.Get("tabGroupSpeedrun"), TabGroup.GamemodeSettings)
.SetColor(Color.blue);
SpeedrunSettingsOverride = BooleanOptionItem.Create(70076, "Auto Update Settings", true, TabGroup.GamemodeSettings, false);
GameAutoEndsAfter = IntegerOptionItem.Create(70077, "Game automatically ends after", new(0, 600, 10), 300, TabGroup.GamemodeSettings, false)
SpeedrunSettingsOverride = BooleanOptionItem.Create(70076, Translator.Get("speedrunSettingsOverride"), true, TabGroup.GamemodeSettings, false);
GameAutoEndsAfter = IntegerOptionItem.Create(70077, Translator.Get("gameAutoEndsAfter"), new(0, 600, 10), 300, TabGroup.GamemodeSettings, false)
.SetValueFormat(OptionFormat.Seconds);
EngineerMode = BooleanOptionItem.Create(70078, Translator.Get("engineerMode"), false, TabGroup.GamemodeSettings, false);
// Gameplay Settings
DisableSabotage = BooleanOptionItem.Create(60565, "Disable Critical Sabotages", false, TabGroup.ModSettings, false)
.SetColor(new Color32(255, 153, 153, byte.MaxValue))
.SetHeader(true);
DisableCloseDoor = BooleanOptionItem.Create(60566, "Disable Door Sabotages", false, TabGroup.ModSettings, false)
TabGroupSabotages = TextOptionItem.Create(60450, Translator.Get("tabGroupSabotages"), TabGroup.ModSettings)
.SetColor(Color.red);
DeadImpostorsCanSabotage = BooleanOptionItem.Create(60455, Translator.Get("deadImpostorsCanSabotage"), true, TabGroup.ModSettings, false)
.SetColor(Color.red);
DisableSabotage = BooleanOptionItem.Create(60456, Translator.Get("disableSabotage"), false, TabGroup.ModSettings, false)
.SetColor(Color.red);
DisableReactor = BooleanOptionItem.Create(60457, Translator.Get("disableReactor"), false, TabGroup.ModSettings, false)
.SetParent(DisableSabotage)
.SetColor(new Color32(255, 153, 153, byte.MaxValue));
DisableReport = BooleanOptionItem.Create(60520, "Disable Body Reports", false, TabGroup.ModSettings, false)
DisableOxygen = BooleanOptionItem.Create(60458, Translator.Get("disableOxygen"), false, TabGroup.ModSettings, false)
.SetParent(DisableSabotage)
.SetColor(new Color32(255, 153, 153, byte.MaxValue));
DisableLights = BooleanOptionItem.Create(60459, Translator.Get("disableLights"), false, TabGroup.ModSettings, false)
.SetParent(DisableSabotage)
.SetColor(new Color32(255, 153, 153, byte.MaxValue));
DisableComms = BooleanOptionItem.Create(60460, Translator.Get("disableComms"), false, TabGroup.ModSettings, false)
.SetParent(DisableSabotage)
.SetColor(new Color32(255, 153, 153, byte.MaxValue));
DisableHeli = BooleanOptionItem.Create(60461, Translator.Get("disableHeli"), false, TabGroup.ModSettings, false)
.SetParent(DisableSabotage)
.SetColor(new Color32(255, 153, 153, byte.MaxValue));
DisableMushroomMixup = BooleanOptionItem.Create(60462, Translator.Get("disableMushroomMixup"), false, TabGroup.ModSettings, false)
.SetParent(DisableSabotage)
.SetColor(new Color32(255, 153, 153, byte.MaxValue));
DisableCloseDoor = BooleanOptionItem.Create(60566, Translator.Get("disableCloseDoor"), false, TabGroup.ModSettings, false)
.SetColor(Color.red);
TabGroupGameplayGeneral = TextOptionItem.Create(60564, Translator.Get("tabGroupGameplayGeneral"), TabGroup.ModSettings)
.SetColor(Color.blue);
DisableAnnoyingMeetingCalls = BooleanOptionItem.Create(60565, Translator.Get("disableAnnoyingMeetingCalls"), false, TabGroup.ModSettings, false)
.SetColor(new Color32(19, 188, 233, byte.MaxValue));
ChangeDecontaminationTime = BooleanOptionItem.Create(60550, Translator.Get("changeDecontaminationTime"), false, TabGroup.ModSettings, false)
.SetColor(new Color32(19, 188, 233, byte.MaxValue));
DecontaminationTimeOnMiraHQ = FloatOptionItem.Create(60551, Translator.Get("decontaminationTimeOnMiraHQ"), new(0.5f, 10f, 0.25f), 3f, TabGroup.ModSettings, false)
.SetParent(ChangeDecontaminationTime)
.SetValueFormat(OptionFormat.Seconds)
.SetColor(new Color32(19, 188, 233, byte.MaxValue));
DecontaminationDoorOpenTimeOnMiraHQ = FloatOptionItem.Create(60552, Translator.Get("decontaminationDoorOpenTimeOnMiraHQ"), new(0.5f, 10f, 0.25f), 3f, TabGroup.ModSettings, false)
.SetParent(ChangeDecontaminationTime)
.SetValueFormat(OptionFormat.Seconds)
.SetColor(new Color32(19, 188, 233, byte.MaxValue));
DecontaminationTimeOnPolus = FloatOptionItem.Create(60553, Translator.Get("decontaminationTimeOnPolus"), new(0.5f, 10f, 0.25f), 3f, TabGroup.ModSettings, false)
.SetParent(ChangeDecontaminationTime)
.SetValueFormat(OptionFormat.Seconds)
.SetColor(new Color32(19, 188, 233, byte.MaxValue));
DecontaminationDoorOpenTimeOnPolus = FloatOptionItem.Create(60554, Translator.Get("decontaminationDoorOpenTimeOnPolus"), new(0.5f, 10f, 0.25f), 3f, TabGroup.ModSettings, false)
.SetParent(ChangeDecontaminationTime)
.SetValueFormat(OptionFormat.Seconds)
.SetColor(new Color32(19, 188, 233, byte.MaxValue));
DisableSporeTrigger = BooleanOptionItem.Create(60558, Translator.Get("disableSporeTrigger"), false, TabGroup.ModSettings, false)
.SetColor(new Color32(19, 188, 233, byte.MaxValue));
DisableDevices = BooleanOptionItem.Create(22900, Translator.Get("disableDevices"), false, TabGroup.ModSettings, false)
.SetColor(Color.red);
DisableSkeldDevices = BooleanOptionItem.Create(22905, Translator.Get("disableSkeldDevices"), false, TabGroup.ModSettings, false)
.SetParent(DisableDevices)
.SetColor(new Color32(255, 153, 153, byte.MaxValue));
DisableSkeldAdmin = BooleanOptionItem.Create(22906, Translator.Get("disableSkeldAdmin"), false, TabGroup.ModSettings, false)
.SetParent(DisableSkeldDevices)
.SetColor(new Color32(255, 153, 153, byte.MaxValue));
DisableSkeldCamera = BooleanOptionItem.Create(22907, Translator.Get("disableSkeldCamera"), false, TabGroup.ModSettings, false)
.SetParent(DisableSkeldDevices)
.SetColor(new Color32(255, 153, 153, byte.MaxValue));
DisableMiraHQDevices = BooleanOptionItem.Create(22908, Translator.Get("disableMiraHQDevices"), false, TabGroup.ModSettings, false)
.SetParent(DisableDevices)
.SetColor(new Color32(255, 153, 153, byte.MaxValue));
DisableMiraHQAdmin = BooleanOptionItem.Create(22909, Translator.Get("disableMiraHQAdmin"), false, TabGroup.ModSettings, false)
.SetParent(DisableMiraHQDevices)
.SetColor(new Color32(255, 153, 153, byte.MaxValue));
DisableMiraHQDoorLog = BooleanOptionItem.Create(22910, Translator.Get("disableMiraHQDoorLog"), false, TabGroup.ModSettings, false)
.SetParent(DisableMiraHQDevices)
.SetColor(new Color32(255, 153, 153, byte.MaxValue));
DisablePolusDevices = BooleanOptionItem.Create(22911, Translator.Get("disablePolusDevices"), false, TabGroup.ModSettings, false)
.SetParent(DisableDevices)
.SetColor(new Color32(255, 153, 153, byte.MaxValue));
DisablePolusAdmin = BooleanOptionItem.Create(22912, Translator.Get("disablePolusAdmin"), false, TabGroup.ModSettings, false)
.SetParent(DisablePolusDevices)
.SetColor(new Color32(255, 153, 153, byte.MaxValue));
DisablePolusCamera = BooleanOptionItem.Create(22913, Translator.Get("disablePolusCamera"), false, TabGroup.ModSettings, false)
.SetParent(DisablePolusDevices)
.SetColor(new Color32(255, 153, 153, byte.MaxValue));
DisablePolusVital = BooleanOptionItem.Create(22914, Translator.Get("disablePolusVital"), false, TabGroup.ModSettings, false)
.SetParent(DisablePolusDevices)
.SetColor(new Color32(255, 153, 153, byte.MaxValue));
OverrideTaskSettings = BooleanOptionItem.Create(22998, "<#ffd>Ove<#ffb>rri<#ff9>de T<#ffb>ask <#ffd>Set<#ffb>tin<#ff9>gs", false, TabGroup.ModSettings, false)
.SetColor(new Color32(239, 89, 175, byte.MaxValue))
.SetHeader(true);
DisableAirshipDevices = BooleanOptionItem.Create(22915, Translator.Get("disableAirshipDevices"), false, TabGroup.ModSettings, false)
.SetParent(DisableDevices)
.SetColor(new Color32(255, 153, 153, byte.MaxValue));
DisableAirshipCockpitAdmin = BooleanOptionItem.Create(22916, Translator.Get("disableAirshipCockpitAdmin"), false, TabGroup.ModSettings, false)
.SetParent(DisableAirshipDevices)
.SetColor(new Color32(255, 153, 153, byte.MaxValue));
DisableAirshipRecordsAdmin = BooleanOptionItem.Create(22917, Translator.Get("disableAirshipRecordsAdmin"), false, TabGroup.ModSettings, false)
.SetParent(DisableAirshipDevices)
.SetColor(new Color32(255, 153, 153, byte.MaxValue));
DisableAirshipCamera = BooleanOptionItem.Create(22918, Translator.Get("disableAirshipCamera"), false, TabGroup.ModSettings, false)
.SetParent(DisableAirshipDevices)
.SetColor(new Color32(255, 153, 153, byte.MaxValue));
DisableAirshipVital = BooleanOptionItem.Create(22919, Translator.Get("disableAirshipVital"), false, TabGroup.ModSettings, false)
.SetParent(DisableAirshipDevices)
.SetColor(new Color32(255, 153, 153, byte.MaxValue));
AllPlayersSameTasks = BooleanOptionItem.Create(22999, "Everyone has same tasks", false, TabGroup.ModSettings, false)
DisableFungleDevices = BooleanOptionItem.Create(22925, Translator.Get("disableFungleDevices"), false, TabGroup.ModSettings, false)
.SetParent(DisableDevices)
.SetColor(new Color32(255, 153, 153, byte.MaxValue));
DisableFungleCamera = BooleanOptionItem.Create(22926, Translator.Get("disableFungleCamera"), false, TabGroup.ModSettings, false)
.SetParent(DisableFungleDevices)
.SetColor(new Color32(255, 153, 153, byte.MaxValue));
DisableFungleVital = BooleanOptionItem.Create(22927, Translator.Get("disableFungleVital"), false, TabGroup.ModSettings, false)
.SetParent(DisableFungleDevices)
.SetColor(new Color32(255, 153, 153, byte.MaxValue));
TabGroupTasks = TextOptionItem.Create(22995, Translator.Get("tabGroupTasks"), TabGroup.ModSettings)
.SetColor(Color.yellow);
TaskPercentNeededToWin = IntegerOptionItem.Create(22996, Translator.Get("taskPercentNeededToWin"), new(30, 100, 5), 100, TabGroup.ModSettings, false)
.SetColor(new Color32(255, 255, 153, byte.MaxValue))
.SetParent(OverrideTaskSettings);
.SetValueFormat(OptionFormat.Percent);
AllPlayersSameTasks = BooleanOptionItem.Create(22998, Translator.Get("allPlayersSameTasks"), false, TabGroup.ModSettings, false)
.SetColor(new Color32(255, 255, 153, byte.MaxValue));
OverrideTaskSettings = BooleanOptionItem.Create(22999, Translator.Get("overrideTaskSettings"), false, TabGroup.ModSettings, false)
.SetColor(new Color32(255, 255, 153, byte.MaxValue));
DisableMiraTasks = BooleanOptionItem.Create(23000, "Disable Mira HQ Tasks", false, TabGroup.ModSettings, false)
DisableMiraTasks = BooleanOptionItem.Create(23000, Translator.Get("disableMiraTasks"), false, TabGroup.ModSettings, false)
.SetColor(new Color32(173, 216, 230, byte.MaxValue))
.SetParent(OverrideTaskSettings);
DisableBuyBeverage = BooleanOptionItem.Create(23001, "Disable Buy Beverage", false, TabGroup.ModSettings, false)
DisableBuyBeverage = BooleanOptionItem.Create(23001, Translator.Get("disableBuyBeverage"), false, TabGroup.ModSettings, false)
.SetParent(DisableMiraTasks);
DisableMeasureWeather = BooleanOptionItem.Create(23002, "Disable Measure Weather", false, TabGroup.ModSettings, false)
DisableMeasureWeather = BooleanOptionItem.Create(23002, Translator.Get("disableMeasureWeather"), false, TabGroup.ModSettings, false)
.SetParent(DisableMiraTasks);
DisableProcessData = BooleanOptionItem.Create(23003, "Disable Process Data", false, TabGroup.ModSettings, false)
DisableProcessData = BooleanOptionItem.Create(23003, Translator.Get("disableProcessData"), false, TabGroup.ModSettings, false)
.SetParent(DisableMiraTasks);
DisableRunDiagnostics = BooleanOptionItem.Create(23004, "Disable Run Diagnostics", false, TabGroup.ModSettings, false)
DisableRunDiagnostics = BooleanOptionItem.Create(23004, Translator.Get("disableRunDiagnostics"), false, TabGroup.ModSettings, false)
.SetParent(DisableMiraTasks);
DisableSortSamples = BooleanOptionItem.Create(23005, "Disable Sort Samples", false, TabGroup.ModSettings, false)
DisableSortSamples = BooleanOptionItem.Create(23005, Translator.Get("disableSortSamples"), false, TabGroup.ModSettings, false)
.SetParent(DisableMiraTasks);
DisablePolusTasks = BooleanOptionItem.Create(23100, "Disable Polus Tasks", false, TabGroup.ModSettings, false)
DisablePolusTasks = BooleanOptionItem.Create(23100, Translator.Get("disablePolusTasks"), false, TabGroup.ModSettings, false)
.SetColor(new Color32(173, 216, 230, byte.MaxValue))
.SetParent(OverrideTaskSettings);
DisableActivateWeatherNodes = BooleanOptionItem.Create(23101, "Disable Activate Weather Nodes", false, TabGroup.ModSettings, false)
DisableActivateWeatherNodes = BooleanOptionItem.Create(23101, Translator.Get("disableActivateWeatherNodes"), false, TabGroup.ModSettings, false)
.SetParent(DisablePolusTasks);
DisableAlignTelescope = BooleanOptionItem.Create(23102, "Disable Align Telescope", false, TabGroup.ModSettings, false)
DisableAlignTelescope = BooleanOptionItem.Create(23102, Translator.Get("disableAlignTelescope"), false, TabGroup.ModSettings, false)
.SetParent(DisablePolusTasks);
DisableFillCanisters = BooleanOptionItem.Create(23103, "Disable Fill Canisters", false, TabGroup.ModSettings, false)
DisableFillCanisters = BooleanOptionItem.Create(23103, Translator.Get("disableFillCanisters"), false, TabGroup.ModSettings, false)
.SetParent(DisablePolusTasks);
DisableInsertKeys = BooleanOptionItem.Create(23104, "Disable Insert Keys", false, TabGroup.ModSettings, false)
DisableInsertKeys = BooleanOptionItem.Create(23104, Translator.Get("disableInsertKeys"), false, TabGroup.ModSettings, false)
.SetParent(DisablePolusTasks);
DisableOpenWaterways = BooleanOptionItem.Create(23105, "Disable Open Waterways", false, TabGroup.ModSettings, false)
DisableOpenWaterways = BooleanOptionItem.Create(23105, Translator.Get("disableOpenWaterways"), false, TabGroup.ModSettings, false)
.SetParent(DisablePolusTasks);
DisableRebootWifi = BooleanOptionItem.Create(23106, "Disable Reboot Wifi", false, TabGroup.ModSettings, false)
DisableRebootWifi = BooleanOptionItem.Create(23106, Translator.Get("disableRebootWifi"), false, TabGroup.ModSettings, false)
.SetParent(DisablePolusTasks);
DisableRepairDrill = BooleanOptionItem.Create(23107, "Disable Repair Drill", false, TabGroup.ModSettings, false)
DisableRepairDrill = BooleanOptionItem.Create(23107, Translator.Get("disableRepairDrill"), false, TabGroup.ModSettings, false)
.SetParent(DisablePolusTasks);
DisableScanBoardingPass = BooleanOptionItem.Create(23108, "Disable Scan Boarding Pass", false, TabGroup.ModSettings, false)
DisableScanBoardingPass = BooleanOptionItem.Create(23108, Translator.Get("disableScanBoardingPass"), false, TabGroup.ModSettings, false)
.SetParent(DisablePolusTasks);
DisableAirshipTasks = BooleanOptionItem.Create(23200, "Disable Airship Tasks", false, TabGroup.ModSettings, false)
DisableAirshipTasks = BooleanOptionItem.Create(23200, Translator.Get("disableAirshipTasks"), false, TabGroup.ModSettings, false)
.SetColor(new Color32(173, 216, 230, byte.MaxValue))
.SetParent(OverrideTaskSettings);
DisableCleanToilet = BooleanOptionItem.Create(23201, "Disable Clean Toilet", false, TabGroup.ModSettings, false)
DisableCleanToilet = BooleanOptionItem.Create(23201, Translator.Get("disableCleanToilet"), false, TabGroup.ModSettings, false)
.SetParent(DisableAirshipTasks);
DisableDecontaminate = BooleanOptionItem.Create(23202, "Disable Decontaminate", false, TabGroup.ModSettings, false)
DisableDecontaminate = BooleanOptionItem.Create(23202, Translator.Get("disableDecontaminate"), false, TabGroup.ModSettings, false)
.SetParent(DisableAirshipTasks);
DisableDevelopPhotos = BooleanOptionItem.Create(23203, "Disable Develop Photos", false, TabGroup.ModSettings, false)
DisableDevelopPhotos = BooleanOptionItem.Create(23203, Translator.Get("disableDevelopPhotos"), false, TabGroup.ModSettings, false)
.SetParent(DisableAirshipTasks);
DisableDressMannequin = BooleanOptionItem.Create(23204, "Disable Dress Mannequin", false, TabGroup.ModSettings, false)
DisableDressMannequin = BooleanOptionItem.Create(23204, Translator.Get("disableDressMannequin"), false, TabGroup.ModSettings, false)
.SetParent(DisableAirshipTasks);
DisableFixShower = BooleanOptionItem.Create(23205, "Disable Fix Shower", false, TabGroup.ModSettings, false)
DisableFixShower = BooleanOptionItem.Create(23205, Translator.Get("disableFixShower"), false, TabGroup.ModSettings, false)
.SetParent(DisableAirshipTasks);
DisableMakeBurger = BooleanOptionItem.Create(23206, "Disable Make Burger", false, TabGroup.ModSettings, false)
DisableMakeBurger = BooleanOptionItem.Create(23206, Translator.Get("disableMakeBurger"), false, TabGroup.ModSettings, false)
.SetParent(DisableAirshipTasks);
DisablePickUpTowels = BooleanOptionItem.Create(23207, "Disable Pick Up Towels", false, TabGroup.ModSettings, false)
DisablePickUpTowels = BooleanOptionItem.Create(23207, Translator.Get("disablePickUpTowels"), false, TabGroup.ModSettings, false)
.SetParent(DisableAirshipTasks);
DisablePolishRuby = BooleanOptionItem.Create(23208, "Disable Polish Ruby", false, TabGroup.ModSettings, false)
DisablePolishRuby = BooleanOptionItem.Create(23208, Translator.Get("disablePolishRuby"), false, TabGroup.ModSettings, false)
.SetParent(DisableAirshipTasks);
DisablePutAwayPistols = BooleanOptionItem.Create(23209, "Disable Put Away Pistols", false, TabGroup.ModSettings, false)
DisablePutAwayPistols = BooleanOptionItem.Create(23209, Translator.Get("disablePutAwayPistols"), false, TabGroup.ModSettings, false)
.SetParent(DisableAirshipTasks);
DisablePutAwayRifles = BooleanOptionItem.Create(23210, "Disable Put Away Rifles", false, TabGroup.ModSettings, false)
DisablePutAwayRifles = BooleanOptionItem.Create(23210, Translator.Get("disablePutAwayRifles"), false, TabGroup.ModSettings, false)
.SetParent(DisableAirshipTasks);
DisableRewindTapes = BooleanOptionItem.Create(23211, "Disable Rewind Tapes", false, TabGroup.ModSettings, false)
DisableRewindTapes = BooleanOptionItem.Create(23211, Translator.Get("disableRewindTapes"), false, TabGroup.ModSettings, false)
.SetParent(DisableAirshipTasks);
DisableResetBreaker = BooleanOptionItem.Create(23212, "Disable Reset Breaker Task", false, TabGroup.ModSettings, false)
DisableResetBreaker = BooleanOptionItem.Create(23212, Translator.Get("disableResetBreaker"), false, TabGroup.ModSettings, false)
.SetParent(DisableAirshipTasks);
DisableSortRecords = BooleanOptionItem.Create(23213, "Disable Sort Records", false, TabGroup.ModSettings, false)
DisableSortRecords = BooleanOptionItem.Create(23213, Translator.Get("disableSortRecords"), false, TabGroup.ModSettings, false)
.SetParent(DisableAirshipTasks);
DisableStartFans = BooleanOptionItem.Create(23214, "Disable Start Fans", false, TabGroup.ModSettings, false)
DisableStartFans = BooleanOptionItem.Create(23214, Translator.Get("disableStartFans"), false, TabGroup.ModSettings, false)
.SetParent(DisableAirshipTasks);
DisableUnlockSafe = BooleanOptionItem.Create(23215, "Disable Unlock Safe Task", false, TabGroup.ModSettings, false)
DisableUnlockSafe = BooleanOptionItem.Create(23215, Translator.Get("disableUnlockSafe"), false, TabGroup.ModSettings, false)
.SetParent(DisableAirshipTasks);
DisableFungleTasks = BooleanOptionItem.Create(23300, "Disable Fungle Tasks", false, TabGroup.ModSettings, false)
DisableFungleTasks = BooleanOptionItem.Create(23300, Translator.Get("disableFungleTasks"), false, TabGroup.ModSettings, false)
.SetColor(new Color32(173, 216, 230, byte.MaxValue))
.SetParent(OverrideTaskSettings);
DisableBuildSandcastle = BooleanOptionItem.Create(23301, "Disable Build Sandcastle", false, TabGroup.ModSettings, false)
DisableBuildSandcastle = BooleanOptionItem.Create(23301, Translator.Get("disableBuildSandcastle"), false, TabGroup.ModSettings, false)
.SetParent(DisableFungleTasks);
DisableCatchFish = BooleanOptionItem.Create(23302, "Disable Catch Fish", false, TabGroup.ModSettings, false)
DisableCatchFish = BooleanOptionItem.Create(23302, Translator.Get("disableCatchFish"), false, TabGroup.ModSettings, false)
.SetParent(DisableFungleTasks);
DisableCollectSamples = BooleanOptionItem.Create(23303, "Disable Collect Samples", false, TabGroup.ModSettings, false)
DisableCollectSamples = BooleanOptionItem.Create(23303, Translator.Get("disableCollectSamples"), false, TabGroup.ModSettings, false)
.SetParent(DisableFungleTasks);
DisableCollectShells = BooleanOptionItem.Create(23304, "Disable Collect Shells", false, TabGroup.ModSettings, false)
DisableCollectShells = BooleanOptionItem.Create(23304, Translator.Get("disableCollectShells"), false, TabGroup.ModSettings, false)
.SetParent(DisableFungleTasks);
DisableCollectVegetables = BooleanOptionItem.Create(23305, "Disable Collect Vegetables", false, TabGroup.ModSettings, false)
DisableCollectVegetables = BooleanOptionItem.Create(23305, Translator.Get("disableCollectVegetables"), false, TabGroup.ModSettings, false)
.SetParent(DisableFungleTasks);
DisableCrankGenerator = BooleanOptionItem.Create(23306, "Disable Crank Generator", false, TabGroup.ModSettings, false)
DisableCrankGenerator = BooleanOptionItem.Create(23306, Translator.Get("disableCrankGenerator"), false, TabGroup.ModSettings, false)
.SetParent(DisableFungleTasks);
DisableExtractFuel = BooleanOptionItem.Create(23307, "Disable Extract Fuel", false, TabGroup.ModSettings, false)
DisableExtractFuel = BooleanOptionItem.Create(23307, Translator.Get("disableExtractFuel"), false, TabGroup.ModSettings, false)
.SetParent(DisableFungleTasks);
DisableFixAntenna = BooleanOptionItem.Create(23308, "Disable Fix Antenna", false, TabGroup.ModSettings, false)
DisableFixAntenna = BooleanOptionItem.Create(23308, Translator.Get("disableFixAntenna"), false, TabGroup.ModSettings, false)
.SetParent(DisableFungleTasks);
DisableHelpCritter = BooleanOptionItem.Create(23309, "Disable Help Critter", false, TabGroup.ModSettings, false)
DisableHelpCritter = BooleanOptionItem.Create(23309, Translator.Get("disableHelpCritter"), false, TabGroup.ModSettings, false)
.SetParent(DisableFungleTasks);
DisableHoistSupplies = BooleanOptionItem.Create(23310, "Disable Hoist Supplies", false, TabGroup.ModSettings, false)
DisableHoistSupplies = BooleanOptionItem.Create(23310, Translator.Get("disableHoistSupplies"), false, TabGroup.ModSettings, false)
.SetParent(DisableFungleTasks);
DisableLiftWeights = BooleanOptionItem.Create(23311, "Disable Lift Weights", false, TabGroup.ModSettings, false)
DisableLiftWeights = BooleanOptionItem.Create(23311, Translator.Get("disableLiftWeights"), false, TabGroup.ModSettings, false)
.SetParent(DisableFungleTasks);
DisableMineOres = BooleanOptionItem.Create(23312, "Disable Mine Ores", false, TabGroup.ModSettings, false)
DisableMineOres = BooleanOptionItem.Create(23312, Translator.Get("disableMineOres"), false, TabGroup.ModSettings, false)
.SetParent(DisableFungleTasks);
DisablePlayVideoGame = BooleanOptionItem.Create(23313, "Disable Play Video Game", false, TabGroup.ModSettings, false)
DisablePlayVideoGame = BooleanOptionItem.Create(23313, Translator.Get("disablePlayVideoGame"), false, TabGroup.ModSettings, false)
.SetParent(DisableFungleTasks);
DisablePolishGem = BooleanOptionItem.Create(23314, "Disable Polish Gem", false, TabGroup.ModSettings, false)
DisablePolishGem = BooleanOptionItem.Create(23314, Translator.Get("disablePolishGem"), false, TabGroup.ModSettings, false)
.SetParent(DisableFungleTasks);
DisableReplaceParts = BooleanOptionItem.Create(23315, "Disable Replace Parts", false, TabGroup.ModSettings, false)
DisableReplaceParts = BooleanOptionItem.Create(23315, Translator.Get("disableReplaceParts"), false, TabGroup.ModSettings, false)
.SetParent(DisableFungleTasks);
DisableRoastMarshmallow = BooleanOptionItem.Create(23316, "Disable Roast Marshmallow", false, TabGroup.ModSettings, false)
DisableRoastMarshmallow = BooleanOptionItem.Create(23316, Translator.Get("disableRoastMarshmallow"), false, TabGroup.ModSettings, false)
.SetParent(DisableFungleTasks);
DisableThrowFisbee = BooleanOptionItem.Create(23317, "Disable Throw Fisbee", false, TabGroup.ModSettings, false)
DisableThrowFisbee = BooleanOptionItem.Create(23317, Translator.Get("disableThrowFisbee"), false, TabGroup.ModSettings, false)
.SetParent(DisableFungleTasks);
DisableFindSignal = BooleanOptionItem.Create(23318, "Disable Find Signal", false, TabGroup.ModSettings, false)
DisableFindSignal = BooleanOptionItem.Create(23318, Translator.Get("disableFindSignal"), false, TabGroup.ModSettings, false)
.SetParent(DisableFungleTasks);
DisableMiscCommonTasks = BooleanOptionItem.Create(23400, "Disable Global Common Tasks", false, TabGroup.ModSettings, false)
DisableMiscCommonTasks = BooleanOptionItem.Create(23400, Translator.Get("disableMiscCommonTasks"), false, TabGroup.ModSettings, false)
.SetColor(new Color32(173, 216, 230, byte.MaxValue))
.SetParent(OverrideTaskSettings);
DisableEnterIdCode = BooleanOptionItem.Create(23401, "Disable Enter Id Code", false, TabGroup.ModSettings, false)
DisableEnterIdCode = BooleanOptionItem.Create(23401, Translator.Get("disableEnterIdCode"), false, TabGroup.ModSettings, false)
.SetParent(DisableMiscCommonTasks);
DisableFixWiring = BooleanOptionItem.Create(23402, "Disable Fix Wiring", false, TabGroup.ModSettings, false)
DisableFixWiring = BooleanOptionItem.Create(23402, Translator.Get("disableFixWiring"), false, TabGroup.ModSettings, false)
.SetParent(DisableMiscCommonTasks);
DisableSwipeCard = BooleanOptionItem.Create(23403, "Disable Swipe Card", false, TabGroup.ModSettings, false)
DisableSwipeCard = BooleanOptionItem.Create(23403, Translator.Get("disableSwipeCard"), false, TabGroup.ModSettings, false)
.SetParent(DisableMiscCommonTasks);
DisableMiscShortTasks = BooleanOptionItem.Create(23500, "Disable Global Short Tasks", false, TabGroup.ModSettings, false)
DisableMiscShortTasks = BooleanOptionItem.Create(23500, Translator.Get("disableMiscShortTasks"), false, TabGroup.ModSettings, false)
.SetColor(new Color32(173, 216, 230, byte.MaxValue))
.SetParent(OverrideTaskSettings);
DisableAssembleArtifact = BooleanOptionItem.Create(23501, "Disable Assemble Artifact", false, TabGroup.ModSettings, false)
DisableAssembleArtifact = BooleanOptionItem.Create(23501, Translator.Get("disableAssembleArtifact"), false, TabGroup.ModSettings, false)
.SetParent(DisableMiscShortTasks);
DisableChartCourse = BooleanOptionItem.Create(23502, "Disable Chart Course", false, TabGroup.ModSettings, false)
DisableChartCourse = BooleanOptionItem.Create(23502, Translator.Get("disableChartCourse"), false, TabGroup.ModSettings, false)
.SetParent(DisableMiscShortTasks);
DisableCleanO2Filter = BooleanOptionItem.Create(23503, "Disable Clean O2 Filter", false, TabGroup.ModSettings, false)
DisableCleanO2Filter = BooleanOptionItem.Create(23503, Translator.Get("disableCleanO2Filter"), false, TabGroup.ModSettings, false)
.SetParent(DisableMiscShortTasks);
DisableCleanVent = BooleanOptionItem.Create(23504, "Disable Clean Vent", false, TabGroup.ModSettings, false)
DisableCleanVent = BooleanOptionItem.Create(23504, Translator.Get("disableCleanVent"), false, TabGroup.ModSettings, false)
.SetParent(DisableMiscShortTasks);
DisableMonitorMushroom = BooleanOptionItem.Create(23506, "Disable Monitor Mushroom", false, TabGroup.ModSettings, false)
DisableMonitorMushroom = BooleanOptionItem.Create(23506, Translator.Get("disableMonitorMushroom"), false, TabGroup.ModSettings, false)
.SetParent(DisableMiscShortTasks);
DisableMonitorTree = BooleanOptionItem.Create(23507, "Disable Monitor Tree", false, TabGroup.ModSettings, false)
DisableMonitorTree = BooleanOptionItem.Create(23507, Translator.Get("disableMonitorTree"), false, TabGroup.ModSettings, false)
.SetParent(DisableMiscShortTasks);
DisablePrimeShields = BooleanOptionItem.Create(23508, "Disable Prime Shields", false, TabGroup.ModSettings, false)
DisablePrimeShields = BooleanOptionItem.Create(23508, Translator.Get("disablePrimeShields"), false, TabGroup.ModSettings, false)
.SetParent(DisableMiscShortTasks);
DisableRecordTemperature = BooleanOptionItem.Create(23509, "Disable Record Temperature", false, TabGroup.ModSettings, false)
DisableRecordTemperature = BooleanOptionItem.Create(23509, Translator.Get("disableRecordTemperature"), false, TabGroup.ModSettings, false)
.SetParent(DisableMiscShortTasks);
DisableStabilizeSteering = BooleanOptionItem.Create(23510, "Disable Stabilize Steering", false, TabGroup.ModSettings, false)
DisableStabilizeSteering = BooleanOptionItem.Create(23510, Translator.Get("disableStabilizeSteering"), false, TabGroup.ModSettings, false)
.SetParent(DisableMiscShortTasks);
DisableStoreArtifacts = BooleanOptionItem.Create(23511, "Disable Store Artifacts", false, TabGroup.ModSettings, false)
.SetParent(DisableMiscShortTasks);
DisableUnlockManifolds = BooleanOptionItem.Create(23512, "Disable Unlock Manifolds", false, TabGroup.ModSettings, false)
DisableStoreArtifacts = BooleanOptionItem.Create(23511, Translator.Get("disableStoreArtifacts"), false, TabGroup.ModSettings, false)
.SetParent(DisableMiscShortTasks);
DisableUnlockManifolds = BooleanOptionItem.Create(23512, Translator.Get("disableUnlockManifolds"), false, TabGroup.ModSettings, false)
.SetParent(DisableMiscShortTasks);
DisableMiscLongTasks = BooleanOptionItem.Create(23600, "Disable Global Long Tasks", false, TabGroup.ModSettings, false)
DisableMiscLongTasks = BooleanOptionItem.Create(23600, Translator.Get("disableMiscLongTasks"), false, TabGroup.ModSettings, false)
.SetColor(new Color32(173, 216, 230, byte.MaxValue))
.SetParent(OverrideTaskSettings);
DisableAlignEngineOutput = BooleanOptionItem.Create(23601, "Disable Align Engine Output", false, TabGroup.ModSettings, false)
.SetParent(DisableMiscLongTasks);
DisableClearAsteroids = BooleanOptionItem.Create(23602, "Disable Clear Asteroids", false, TabGroup.ModSettings, false)
DisableAlignEngineOutput = BooleanOptionItem.Create(23601, Translator.Get("disableAlignEngineOutput"), false, TabGroup.ModSettings, false)
.SetParent(DisableMiscLongTasks);
DisableEmptyChute = BooleanOptionItem.Create(23603, "Disable Empty Chute", false, TabGroup.ModSettings, false)
DisableClearAsteroids = BooleanOptionItem.Create(23602, Translator.Get("disableClearAsteroids"), false, TabGroup.ModSettings, false)
.SetParent(DisableMiscLongTasks);
DisableInspectSample = BooleanOptionItem.Create(23604, "Disable Inspect Sample", false, TabGroup.ModSettings, false)
DisableEmptyChute = BooleanOptionItem.Create(23603, Translator.Get("disableEmptyChute"), false, TabGroup.ModSettings, false)
.SetParent(DisableMiscLongTasks);
DisableReplaceWaterJug = BooleanOptionItem.Create(23605, "Disable Replace Water Jug", false, TabGroup.ModSettings, false)
DisableInspectSample = BooleanOptionItem.Create(23604, Translator.Get("disableInspectSample"), false, TabGroup.ModSettings, false)
.SetParent(DisableMiscLongTasks);
DisableStartReactor = BooleanOptionItem.Create(23606, "Disable Start Reactor", false, TabGroup.ModSettings, false)
DisableReplaceWaterJug = BooleanOptionItem.Create(23605, Translator.Get("disableReplaceWaterJug"), false, TabGroup.ModSettings, false)
.SetParent(DisableMiscLongTasks);
DisableWaterPlants = BooleanOptionItem.Create(23607, "Disable Water Plants", false, TabGroup.ModSettings, false)
DisableStartReactor = BooleanOptionItem.Create(23606, Translator.Get("disableStartReactor"), false, TabGroup.ModSettings, false)
.SetParent(DisableMiscLongTasks);
DisableWaterPlants = BooleanOptionItem.Create(23607, Translator.Get("disableWaterPlants"), false, TabGroup.ModSettings, false)
.SetParent(DisableMiscLongTasks);
DisableMiscMixedTasks = BooleanOptionItem.Create(23700, "Disable Global Mixed Tasks", false, TabGroup.ModSettings, false)
DisableMiscMixedTasks = BooleanOptionItem.Create(23700, Translator.Get("disableMiscMixedTasks"), false, TabGroup.ModSettings, false)
.SetColor(new Color32(173, 216, 230, byte.MaxValue))
.SetParent(OverrideTaskSettings);
DisableCalibrateDistributor = BooleanOptionItem.Create(23701, "Disable Calibrate Distributor", false, TabGroup.ModSettings, false)
DisableCalibrateDistributor = BooleanOptionItem.Create(23701, Translator.Get("disableCalibrateDistributor"), false, TabGroup.ModSettings, false)
.SetParent(DisableMiscMixedTasks);
DisableDivertPower = BooleanOptionItem.Create(23702, "Disable Divert Power", false, TabGroup.ModSettings, false)
DisableDivertPower = BooleanOptionItem.Create(23702, Translator.Get("disableDivertPower"), false, TabGroup.ModSettings, false)
.SetParent(DisableMiscMixedTasks);
DisableEmptyGarbage = BooleanOptionItem.Create(23703, "Disable Empty Garbage", false, TabGroup.ModSettings, false)
DisableEmptyGarbage = BooleanOptionItem.Create(23703, Translator.Get("disableEmptyGarbage"), false, TabGroup.ModSettings, false)
.SetParent(DisableMiscMixedTasks);
DisableFuelEngines = BooleanOptionItem.Create(23704, "Disable Fuel Engines", false, TabGroup.ModSettings, false)
DisableFuelEngines = BooleanOptionItem.Create(23704, Translator.Get("disableFuelEngines"), false, TabGroup.ModSettings, false)
.SetParent(DisableMiscMixedTasks);
DisableSubmitScan = BooleanOptionItem.Create(23705, "Disable Submit Scan", false, TabGroup.ModSettings, false)
DisableSubmitScan = BooleanOptionItem.Create(23705, Translator.Get("disableSubmitScan"), false, TabGroup.ModSettings, false)
.SetParent(DisableMiscMixedTasks);
DisableUploadData = BooleanOptionItem.Create(23706, "Disable Upload Data", false, TabGroup.ModSettings, false)
DisableUploadData = BooleanOptionItem.Create(23706, Translator.Get("disableUploadData"), false, TabGroup.ModSettings, false)
.SetParent(DisableMiscMixedTasks);
IsLoaded = true;
+351
View File
@@ -0,0 +1,351 @@
using AmongUs.GameOptions;
using Hazel;
using System;
using InnerNet;
using UnityEngine;
namespace AmongUsRevamped;
// It was a fun ride, but this won't last.
// Edit: WE ARE SO BACK
public static class AbilityManagement
{
public static bool IsMayor(PlayerControl player)
{
if (player.Data.RoleType == RoleTypes.Crewmate && Options.CrewmateAbility.GetValue() == 0 ||
player.Data.RoleType == RoleTypes.Scientist && Options.ScientistAbility.GetValue() == 0 ||
player.Data.RoleType == RoleTypes.Engineer && Options.EngineerAbility.GetValue() == 0 ||
player.Data.RoleType == RoleTypes.Noisemaker && Options.NoisemakerAbility.GetValue() == 0 ||
player.Data.RoleType == RoleTypes.Tracker && Options.TrackerAbility.GetValue() == 0 ||
player.Data.RoleType == RoleTypes.Detective && Options.DetectiveAbility.GetValue() == 0)
{
return true;
}
else return false;
}
public static bool IsWorkhorse(PlayerControl player)
{
if (player.Data.RoleType == RoleTypes.Crewmate && Options.CrewmateAbility.GetValue() == 1 ||
player.Data.RoleType == RoleTypes.Scientist && Options.ScientistAbility.GetValue() == 1 ||
player.Data.RoleType == RoleTypes.Engineer && Options.EngineerAbility.GetValue() == 1 ||
player.Data.RoleType == RoleTypes.Noisemaker && Options.NoisemakerAbility.GetValue() == 1 ||
player.Data.RoleType == RoleTypes.Tracker && Options.TrackerAbility.GetValue() == 1 ||
player.Data.RoleType == RoleTypes.Detective && Options.DetectiveAbility.GetValue() == 1)
{
return true;
}
else return false;
}
public static bool IsJester(PlayerControl player)
{
if (player.Data.RoleType == RoleTypes.Crewmate && Options.CrewmateAbility.GetValue() == 2 ||
player.Data.RoleType == RoleTypes.Scientist && Options.ScientistAbility.GetValue() == 2 ||
player.Data.RoleType == RoleTypes.Engineer && Options.EngineerAbility.GetValue() == 2 ||
player.Data.RoleType == RoleTypes.Noisemaker && Options.NoisemakerAbility.GetValue() == 2 ||
player.Data.RoleType == RoleTypes.Tracker && Options.TrackerAbility.GetValue() == 2 ||
player.Data.RoleType == RoleTypes.Detective && Options.DetectiveAbility.GetValue() == 2)
{
return true;
}
else return false;
}
public static bool IsSpeedrunner(PlayerControl player)
{
if (player.Data.RoleType == RoleTypes.Crewmate && Options.CrewmateAbility.GetValue() == 3 ||
player.Data.RoleType == RoleTypes.Scientist && Options.ScientistAbility.GetValue() == 3 ||
player.Data.RoleType == RoleTypes.Engineer && Options.EngineerAbility.GetValue() == 3 ||
player.Data.RoleType == RoleTypes.Noisemaker && Options.NoisemakerAbility.GetValue() == 3 ||
player.Data.RoleType == RoleTypes.Tracker && Options.TrackerAbility.GetValue() == 3 ||
player.Data.RoleType == RoleTypes.Detective && Options.DetectiveAbility.GetValue() == 3)
{
return true;
}
else return false;
}
public static bool IsTyrant(PlayerControl player)
{
if (player.Data.RoleType == RoleTypes.Impostor && Options.ImpostorAbility.GetValue() == 0 ||
player.Data.RoleType == RoleTypes.Shapeshifter && Options.ShapeshifterAbility.GetValue() == 0 ||
player.Data.RoleType == RoleTypes.Phantom && Options.PhantomAbility.GetValue() == 0 ||
player.Data.RoleType == RoleTypes.Viper && Options.ViperAbility.GetValue() == 0)
{
return true;
}
else return false;
}
public static bool IsStealer(PlayerControl player)
{
if (player.Data.RoleType == RoleTypes.Impostor && Options.ImpostorAbility.GetValue() == 1 ||
player.Data.RoleType == RoleTypes.Shapeshifter && Options.ShapeshifterAbility.GetValue() == 1 ||
player.Data.RoleType == RoleTypes.Phantom && Options.PhantomAbility.GetValue() == 1 ||
player.Data.RoleType == RoleTypes.Viper && Options.ViperAbility.GetValue() == 1)
{
return true;
}
else return false;
}
public static bool IsJuggernaut(PlayerControl player)
{
if (player.Data.RoleType == RoleTypes.Impostor && Options.ImpostorAbility.GetValue() == 2 ||
player.Data.RoleType == RoleTypes.Shapeshifter && Options.ShapeshifterAbility.GetValue() == 2 ||
player.Data.RoleType == RoleTypes.Phantom && Options.PhantomAbility.GetValue() == 2 ||
player.Data.RoleType == RoleTypes.Viper && Options.ViperAbility.GetValue() == 2)
{
return true;
}
else return false;
}
public static string RoleList()
{
var firstLines = new List<string>();
if (Options.CrewmateAbility.GetValue() != 4) firstLines.Add($"Crewmate: {Options.CrewmateAbility.GetString()}");
if (Options.ScientistAbility.GetValue() != 4) firstLines.Add($"Scientist: {Options.ScientistAbility.GetString()}");
if (Options.EngineerAbility.GetValue() != 4) firstLines.Add($"Engineer: {Options.EngineerAbility.GetString()}");
if (Options.NoisemakerAbility.GetValue() != 4) firstLines.Add($"Noisemaker: {Options.NoisemakerAbility.GetString()}");
if (Options.TrackerAbility.GetValue() != 4) firstLines.Add($"Tracker: {Options.TrackerAbility.GetString()}");
var secondLines = new List<string>();
if (Options.DetectiveAbility.GetValue() != 4) secondLines.Add($"Detective: {Options.DetectiveAbility.GetString()}");
if (Options.ImpostorAbility.GetValue() != 3) secondLines.Add($"Impostor: {Options.ImpostorAbility.GetString()}");
if (Options.ShapeshifterAbility.GetValue() != 3) secondLines.Add($"Shapeshifter: {Options.ShapeshifterAbility.GetString()}");
if (Options.PhantomAbility.GetValue() != 3) secondLines.Add($"Phantom: {Options.PhantomAbility.GetString()}");
if (Options.ViperAbility.GetValue() != 3) secondLines.Add($"Viper: {Options.ViperAbility.GetString()}");
string firstText = firstLines.Count > 0 ? "ABILITIES:\n\n" + string.Join("\n", firstLines) : "";
string secondText = secondLines.Count > 0 ? "\n" + string.Join("\n", secondLines) : "";
return firstText + secondText;
}
public static void SendRoleList(ChatController c, string text, bool moderator)
{
if (text.Length <= 120)
{
if (moderator) Utils.ModeratorChatCommand(text, "", false);
else Utils.ChatCommand(c, text, "", false);
return;
}
int splitIndex = text.LastIndexOf('\n', 120);
if (splitIndex <= 0) splitIndex = 120;
string first = text[..splitIndex];
string second = text[(splitIndex + 1)..];
if (moderator) Utils.ModeratorChatCommand(first, second, true);
else Utils.ChatCommand(c, first, second, true);
}
}
/*
public static class CustomRoleManagement
{
public static Dictionary<byte, string> PlayerRoles = new Dictionary<byte, string>();
private static readonly System.Random random = new System.Random();
public static string GetRole(byte playerId)
{
PlayerRoles.TryGetValue(playerId, out string role);
return role ?? "None";
}
public static void AssignRoles()
{
if (Options.Gamemode.GetValue() > 1) return;
// crewmateRoles = assigned with crewmate role base
// impostorRoles = assigned with impostor role base
List<(string roleName, int percentage)> crewmateRoles = new()
{
("Jester", Options.JesterPerc.GetInt()),
("Mayor", Options.MayorPerc.GetInt())
};
List<(string roleName, int percentage)> impostorRoles = new()
{
};
List<PlayerControl> availablePlayers = new();
foreach (var player in PlayerControl.AllPlayerControls) availablePlayers.Add(player);
availablePlayers = availablePlayers.OrderBy(x => random.Next()).ToList();
PlayerRoles.Clear();
HashSet<string> assignedRoles = new HashSet<string>();
HashSet<string> attemptedRoles = new HashSet<string>();
foreach (var player in availablePlayers)
{
bool isCrewmate = !player.Data.Role.IsImpostor;
var rolesToAssign = isCrewmate ? crewmateRoles : impostorRoles;
foreach (var (roleName, percentage) in rolesToAssign)
{
if (attemptedRoles.Contains(roleName) || percentage == 0) continue;
attemptedRoles.Add(roleName);
int randomValue = random.Next(0, 101);
Logger.Info($"{roleName}, Value: {randomValue}, Percentage: {percentage}", "StartGameCustomRole1");
if (randomValue > percentage) continue;
if (PlayerRoles.ContainsKey(player.PlayerId)) continue;
PlayerRoles[player.PlayerId] = roleName;
assignedRoles.Add(roleName);
Logger.Info($"({player.PlayerId}) {player.Data.PlayerName} -> {roleName}", "StartGameCustomRole2");
break;
}
}
}
public static string TD(string input)
{
if (string.IsNullOrEmpty(input)) return input;
var sb = new System.Text.StringBuilder(input.Length);
foreach (char c in input)
{
if (char.IsDigit(c))
sb.Append(Main.CircledDigits[c - '0']);
else
sb.Append(c);
}
return sb.ToString();
}
public static string GetActiveRoles()
{
var crewmateRoles = new List<string>();
var neutralRoles = new List<string>();
var impostorRoles = new List<string>();
var lines = new List<string>();
if (Options.MayorPerc.GetInt() > 1) crewmateRoles.Add(Translator.Get("Mayor") + TD(Options.MayorPerc.GetInt().ToString()) + "%");
if (Options.JesterPerc.GetInt() > 1) neutralRoles.Add(Translator.Get("Jester") + TD(Options.JesterPerc.GetInt().ToString()) + "%");
void AddCategory(string header, List<string> roles)
{
if (roles.Count == 0) return;
if (lines.Count > 0) lines.Add("");
lines.Add(header);
lines.AddRange(roles);
}
AddCategory("Crewmate:", crewmateRoles);
AddCategory("Neutral:", neutralRoles);
AddCategory("Impostor:", impostorRoles);
return lines.Count > 0 ? string.Join("\n", lines) : string.Empty;
}
public static bool HandlingRoleMessages = false;
private static int PendingRoleMessages = 0;
public static void SendRoleMessages(Dictionary<string, string> roleMessages)
{
if (PlayerRoles.Count == 0 || PlayerControl.LocalPlayer.Data.IsDead)
{
HandlingRoleMessages = false;
PendingRoleMessages = 0;
return;
}
HashSet<string> sentRoles = new HashSet<string>();
var players = PlayerControl.AllPlayerControls.ToArray().ToList();
float delay = 2.2f;
PendingRoleMessages = 0;
HandlingRoleMessages = true;
PlayerControl.LocalPlayer.RpcSendChat($"{Translator.Get("customRoleAnnouncement")}");
foreach (var player in players)
{
PlayerRoles.TryGetValue(player.PlayerId, out string role);
if (string.IsNullOrEmpty(role)) continue;
if (!roleMessages.ContainsKey(role)) continue;
if (sentRoles.Contains(role)) continue;
PendingRoleMessages++;
new LateTask(() =>
{
if (Utils.InGame)
{
Utils.SendPrivateMessage(player, roleMessages[role]);
}
else
{
Logger.Info("Role sending was forcefully canceled. This should not happen.", "SendRoleMessages");
}
PendingRoleMessages--;
if (PendingRoleMessages <= 0)
{
PendingRoleMessages = 0;
HandlingRoleMessages = false;
sentRoles.Clear();
}
}, delay, "SendRoleMessage");
sentRoles.Add(role);
delay += 2.2f;
}
}
public static string PlayerToCustomRole()
{
if (CustomRoleManagement.PlayerRoles.Count == 0) return string.Empty;
Dictionary<string, List<string>> roleToPlayers = new Dictionary<string, List<string>>();
foreach (var kvp in CustomRoleManagement.PlayerRoles)
{
byte playerId = kvp.Key;
string role = kvp.Value;
PlayerControl pc = null;
foreach (var p in PlayerControl.AllPlayerControls)
{
if (p.PlayerId == playerId)
{
pc = p;
break;
}
}
if (pc == null) continue;
if (!roleToPlayers.ContainsKey(role)) roleToPlayers[role] = new List<string>();
roleToPlayers[role].Add(pc.Data.PlayerName);
}
if (roleToPlayers.Count == 0) return string.Empty;
var lines = new List<string>();
foreach (var entry in roleToPlayers)
{
string players = string.Join(", ", entry.Value);
lines.Add($"{entry.Key}: {players}");
}
return string.Join("\n", lines);
}
}
*/
+204
View File
@@ -0,0 +1,204 @@
using Hazel;
using System;
using UnityEngine;
namespace AmongUsRevamped;
internal class EACR
{
public static bool PlayerControlReceiveRpc(PlayerControl pc, byte callId, MessageReader reader)
{
if (!AmongUsClient.Instance.AmHost) return false;
if (pc == null || reader == null) return false;
try
{
MessageReader sr = MessageReader.Get(reader);
var rpc = (RpcCalls)callId;
switch (rpc)
{
case RpcCalls.StartMeeting:
{
AmongUsClient.Instance.KickPlayer(pc.Data.ClientId, true);
Logger.SendInGame($"{pc.Data.PlayerName} was banned for being calling an invalid meeting (cheating)");
Logger.Info($" {pc.Data.PlayerName} was banned for being calling an invalid meeting (cheating)", "EACR");
return true;
}
}
switch (callId)
{
case 101: // Aum Chat
try
{
var firstString = sr.ReadString();
var secondString = sr.ReadString();
sr.ReadInt32();
var flag = string.IsNullOrEmpty(firstString) && string.IsNullOrEmpty(secondString);
if (!flag)
{
AmongUsClient.Instance.KickPlayer(pc.Data.ClientId, true);
Logger.SendInGame($"{pc.Data.PlayerName} was banned for AUM chat CallId (cheating)");
Logger.Info($" {pc.Data.PlayerName} was banned for AUM chat CallId (cheating)", "EACR");
return true;
}
}
catch
{
}
break;
case unchecked((byte)42069): // 85 AUM
try
{
var aumid = sr.ReadByte();
if (aumid == pc.PlayerId)
{
AmongUsClient.Instance.KickPlayer(pc.Data.ClientId, true);
Logger.SendInGame($"{pc.Data.PlayerName} was banned for AUM CallId (cheating)");
Logger.Info($" {pc.Data.PlayerName} was banned for AUM CallId (cheating)", "EACR");
return true;
}
}
catch
{
}
break;
case 119: // KN Chat
try
{
var firstString = sr.ReadString();
var secondString = sr.ReadString();
sr.ReadInt32();
var flag = string.IsNullOrEmpty(firstString) && string.IsNullOrEmpty(secondString);
if (!flag)
{
AmongUsClient.Instance.KickPlayer(pc.Data.ClientId, true);
Logger.SendInGame($"{pc.Data.PlayerName} was banned for KN chat CallId (cheating)");
Logger.Info($" {pc.Data.PlayerName} was banned for KN chat CallId (cheating)", "EACR");
return true;
}
}
catch
{
}
break;
case 250: // KN
if (sr.BytesRemaining == 0)
{
AmongUsClient.Instance.KickPlayer(pc.Data.ClientId, true);
Logger.SendInGame($"{pc.Data.PlayerName} was banned for KN CallId (cheating)");
Logger.Info($" {pc.Data.PlayerName} was banned for KN CallId (cheating)", "EACR");
return true;
}
break;
case unchecked((byte)420): // 164 Sicko
if (sr.BytesRemaining == 0)
{
AmongUsClient.Instance.KickPlayer(pc.Data.ClientId, true);
Logger.SendInGame($"{pc.Data.PlayerName} was banned for Sickomenu RPC (cheating)");
Logger.Info($" {pc.Data.PlayerName} was banned for Sickomenu RPC (cheating)", "EACR");
return true;
}
break;
}
}
catch (Exception e)
{
Logger.Exception(e, "EACR");
}
return false;
}
public static bool RpcUpdateSystemCheck(PlayerControl player, SystemTypes systemType, byte amount)
{
var Mapid = Utils.GetActiveMapId();
if (!AmongUsClient.Instance.AmHost)
{
return false;
}
if (player == null)
{
Logger.Warn("PlayerControl is null", "EACR-RpcUpdateSystemCheck");
return true;
}
if (systemType == SystemTypes.Sabotage)
{
if (!player.Data.Role.IsImpostor && !player.isNew)
{
AmongUsClient.Instance.KickPlayer(player.Data.ClientId, true);
Logger.SendInGame($"{player.Data.PlayerName} was banned for invalid sabotage (cheating)");
Logger.Info($" {player.Data.PlayerName} was banned for invalid sabotage", "EACR");
}
}
else if (systemType == SystemTypes.LifeSupp)
{
if (Mapid != 0 && Mapid != 1 && Mapid != 3) goto YesCheat;
else if (amount != 64 && amount != 65) goto YesCheat;
}
else if (systemType == SystemTypes.Comms)
{
if (amount == 0)
{
if (Mapid == 1 || Mapid == 5) goto YesCheat;
}
else if (amount == 64 || amount == 65 || amount == 32 || amount == 33 || amount == 16 || amount == 17)
{
if (!(Mapid == 1 || Mapid == 5)) goto YesCheat;
}
else goto YesCheat;
}
else if (systemType == SystemTypes.Electrical)
{
if (Mapid == 5) goto YesCheat;
if (amount >= 5)
{
goto YesCheat;
}
}
else if (systemType == SystemTypes.Laboratory)
{
if (Mapid != 2) goto YesCheat;
else if (!(amount == 64 || amount == 65 || amount == 32 || amount == 33)) goto YesCheat;
}
else if (systemType == SystemTypes.Reactor)
{
if (Mapid == 2 || Mapid == 4) goto YesCheat;
else if (!(amount == 64 || amount == 65 || amount == 32 || amount == 33)) goto YesCheat;
}
else if (systemType == SystemTypes.HeliSabotage)
{
if (Mapid != 4) goto YesCheat;
else if (!(amount == 64 || amount == 65 || amount == 16 || amount == 17 || amount == 32 || amount == 33)) goto YesCheat;
}
else if (systemType == SystemTypes.MushroomMixupSabotage)
{
goto YesCheat;
}
if (Utils.IsMeeting && MeetingHud.Instance.state != MeetingHud.VoteStates.Animating)
{
Logger.SendInGame($"{player.Data.PlayerName} might have called an invalid sabotage (cheating)");
Logger.Info($" {player.Data.PlayerName} might have called an invalid sabotage (cheating)", "EACR");
return true;
}
return false;
YesCheat:
{
AmongUsClient.Instance.KickPlayer(player.Data.ClientId, true);
Logger.SendInGame($"{player.Data.PlayerName} was banned for an invalid sabotage (cheating)");
Logger.Info($" {player.Data.PlayerName} was banned for an invalid sabotage", "EACR");
return true;
}
}
}
+54 -62
View File
@@ -27,87 +27,79 @@ public static class FixedUpdate
{
nr.SetActive(false);
}
if (!AmongUsClient.Instance.AmHost) return;
DisableDevice.FixedUpdate();
}
}
[HarmonyPatch(typeof(PlayerControl), nameof(PlayerControl.FixedUpdate))]
class FixedUpdateInGamePatch
{
public static readonly HashSet<byte> ProcessedModerators = new HashSet<byte>();
private static Dictionary<byte, string> LastColors = new();
private static float t;
private static GameObject settingsLabel;
public static void Postfix(PlayerControl __instance)
{
if (__instance == null || __instance.PlayerId == 255 || !AmongUsClient.Instance.AmHost) return;
if (Utils.IsPlayerModerator(__instance.Data.FriendCode) && !ProcessedModerators.Contains(__instance.PlayerId))
t += Time.deltaTime;
if (t < 0.2f) return;
t = 0f;
if (Utils.IsLobby)
{
__instance.SetName($"★{__instance.Data.PlayerName}★");
ProcessedModerators.Add(__instance.PlayerId);
}
GameObject g = GameObject.Find("GameSettingsLabel");
// 0Kc
if (Options.Gamemode.GetValue() == 1 && !Utils.isHideNSeek && Main.NormalOptions.KillCooldown != 0.01f)
{
Main.NormalOptions.KillCooldown = 0.01f;
if (Options.NoKcdSettingsOverride.GetBool() && g == null)
int access = Utils.CheckAccessLevel(__instance.Data.FriendCode);
string color = access switch
{
Main.NormalOptions.EmergencyCooldown = 0;
1 => "yellow",
2 => "purple",
3 => "red",
_ => "white"
};
Main.NormalOptions.TaskBarMode = 0;
if (!LastColors.TryGetValue(__instance.PlayerId, out var lastColor) || lastColor != color || !__instance.cosmetics.nameText.text.Contains($"<color={color}>"))
{
__instance.cosmetics.nameText.text = $"<color={color}>{__instance.Data.PlayerName}</color>";
LastColors[__instance.PlayerId] = color;
}
}
// SnS
if (Options.Gamemode.GetValue() == 2 && !Utils.isHideNSeek && Main.NormalOptions.KillCooldown != 2.5f)
if (settingsLabel == null) settingsLabel = GameObject.Find("GameSettingsLabel");
int gamemode = Options.Gamemode.GetValue();
switch (gamemode)
{
Main.NormalOptions.KillCooldown = 2.5f;
case 1: // 0Kc
if (Main.NormalOptions.KillCooldown != 0.01f)
Main.NormalOptions.KillCooldown = 0.01f;
if (Options.SNSSettingsOverride.GetBool() && g == null)
{
Main.NormalOptions.TaskBarMode = 0;
}
}
// Speedrun
if (Options.Gamemode.GetValue() == 3 && !Utils.isHideNSeek && g == null)
{
Main.NormalOptions.TaskBarMode = 0;
if (__instance.AllTasksCompleted() && Utils.InGame && Utils.GamePastRoleSelection && !Utils.HandlingGameEnd)
{
if (__instance == PlayerControl.LocalPlayer && Main.GM.Value) return;
Utils.CustomWinnerEndGame(__instance, 1);
NormalGameEndChecker.LastWinReason = $"★ {__instance.Data.PlayerName} Wins! (Completed tasks first)";
}
}
if (Options.Gamemode.GetValue() == 0 && Main.NormalOptions.KillCooldown <= 0.01f)
{
Main.NormalOptions.KillCooldown = 25f;
}
if (AmongUsClient.Instance.AmHost)
{
if (__instance.Data.PlayerLevel != 0 && __instance.Data.PlayerLevel < Options.KickLowLevelPlayer.GetInt() && __instance.Data.ClientId != AmongUsClient.Instance.HostId)
{
if (!Options.TempBanLowLevelPlayer.GetBool())
if (Options.NoKcdSettingsOverride.GetBool() && settingsLabel == null)
{
AmongUsClient.Instance.KickPlayer(__instance.Data.ClientId, false);
Logger.Info($" {__instance.Data.PlayerName} was kicked for being under level {Options.KickLowLevelPlayer.GetInt()}", "KickLowLevelPlayer");
Logger.SendInGame($" {__instance.Data.PlayerName} was kicked for being under level {Options.KickLowLevelPlayer.GetInt()}");
Main.NormalOptions.EmergencyCooldown = 0;
Main.NormalOptions.TaskBarMode = 0;
}
else
{
AmongUsClient.Instance.KickPlayer(__instance.Data.ClientId, true);
Logger.Info($" {__instance.Data.PlayerName} was banned for being under level {Options.KickLowLevelPlayer.GetInt()} ", "BanLowLevelPlayer");
Logger.SendInGame($" {__instance.Data.PlayerName} was banned for being under level {Options.KickLowLevelPlayer.GetInt()}");
}
}
break;
case 2: // SnS
if (Main.NormalOptions.KillCooldown != 2.5f)
Main.NormalOptions.KillCooldown = 2.5f;
if (Options.SNSSettingsOverride.GetBool() && settingsLabel == null)
Main.NormalOptions.TaskBarMode = 0;
break;
case 3: // Speedrun
if (settingsLabel == null)
Main.NormalOptions.TaskBarMode = 0;
break;
case 0: // Reset
if (Main.NormalOptions.KillCooldown <= 0.01f)
Main.NormalOptions.KillCooldown = 25f;
break;
}
if (Utils.InGame && !Utils.IsMeeting && !ExileController.Instance)
@@ -121,7 +113,7 @@ class FixedUpdateInGamePatch
Utils.ContinueEndGame((byte)GameOverReason.CrewmatesByVote);
Logger.Info($" Crewmates won because the game took longer than {Options.CrewAutoWinsGameAfter.GetInt()}s", "SNSManager");
NormalGameEndChecker.LastWinReason = $"★ Crewmates win! (Timer)\n\nImpostors:\n" + string.Join("\n", NormalGameEndChecker.imps.Select(p => p.Data.PlayerName));
NormalGameEndChecker.LastWinReason = $"Crewmates win! (Timer)\n\nImpostors:\n" + string.Join("\n", NormalGameEndChecker.imps.Select(p => p.Data.PlayerName));
}
}
// 3 = Speedrun
@@ -133,7 +125,7 @@ class FixedUpdateInGamePatch
Utils.CustomWinnerEndGame(PlayerControl.LocalPlayer, 0);
Logger.Info($" No one won because the game took longer than {Options.GameAutoEndsAfter.GetInt()}s", "SpeedrunManager");
NormalGameEndChecker.LastWinReason = $"★ No one wins! (Timer)";
NormalGameEndChecker.LastWinReason = $"No one wins! (Timer)";
}
}
}
+42
View File
@@ -0,0 +1,42 @@
using System;
using System.Linq.Expressions;
using System.Reflection;
using Il2CppInterop.Runtime;
using Il2CppInterop.Runtime.InteropTypes;
using UnityEngine;
namespace AmongUsRevamped;
// Credit: TommyXL
public static class Il2CppCastHelper
{
public static T CastFast<T>(this Il2CppObjectBase obj) where T : Il2CppObjectBase
{
if (obj is T casted) return casted;
#if ANDROID
return obj.Cast<T>();
#else
return obj.Pointer.CastFast<T>();
#endif
}
private static T CastFast<T>(this IntPtr ptr) where T : Il2CppObjectBase
{
return CastHelper<T>.Cast(ptr);
}
private static class CastHelper<T> where T : Il2CppObjectBase
{
public static readonly Func<IntPtr, T> Cast;
static CastHelper()
{
ConstructorInfo constructor = typeof(T).GetConstructor([typeof(IntPtr)]);
ParameterExpression ptr = Expression.Parameter(typeof(IntPtr));
NewExpression create = Expression.New(constructor!, ptr);
Expression<Func<IntPtr, T>> lambda = Expression.Lambda<Func<IntPtr, T>>(create, ptr);
Cast = lambda.Compile();
}
}
}
+20 -12
View File
@@ -5,14 +5,26 @@ using UnityEngine;
namespace AmongUsRevamped;
#if !ANDROID
[HarmonyPatch(typeof(ControllerManager), nameof(ControllerManager.Update))]
internal class Hotkeys
{
public static int IncrementMultiplier;
public static void Postfix()
{
if (AmongUsClient.Instance == null || PlayerControl.LocalPlayer == null) return;
bool Shift = Input.GetKey(KeyCode.LeftShift) || Input.GetKey(KeyCode.RightShift);
bool Ctrl = Input.GetKey(KeyCode.LeftControl) || Input.GetKey(KeyCode.RightControl);
bool Enter = Input.GetKeyDown(KeyCode.Return);
if ((!AmongUsClient.Instance.IsGameStarted || !Utils.IsOnlineGame) && Utils.CanMove && PlayerControl.LocalPlayer.Collider != null)
{
PlayerControl.LocalPlayer.Collider.enabled = !Ctrl;
}
if (!AmongUsClient.Instance.AmHost) return;
if (Input.GetKey(KeyCode.L) && Shift && Enter)
{
MessageWriter writer = AmongUsClient.Instance.StartEndGame();
@@ -26,27 +38,23 @@ internal class Hotkeys
{
MeetingHud.Instance.RpcClose();
}
else
{
PlayerControl.LocalPlayer.ReportDeadBody(PlayerControl.LocalPlayer.Data);
}
}
if (Shift && GameStartManager.InstanceExists && GameStartManager.Instance.startState == GameStartManager.StartingStates.Countdown && !HudManager.Instance.Chat.IsOpenOrOpening)
if (Shift && GameStartManager.InstanceExists && GameStartManager.Instance != null && GameStartManager.Instance.startState == GameStartManager.StartingStates.Countdown && !HudManager.Instance.Chat.IsOpenOrOpening)
{
GameStartManager.Instance.countDownTimer = 0;
}
if ((!AmongUsClient.Instance.IsGameStarted || !Utils.IsOnlineGame) && Utils.CanMove && PlayerControl.LocalPlayer.Collider != null)
{
PlayerControl.LocalPlayer.Collider.enabled = !Input.GetKey(KeyCode.LeftControl);
}
if (Input.GetKeyDown(KeyCode.C) && GameStartManager.Instance.startState == GameStartManager.StartingStates.Countdown && !HudManager.Instance.Chat.IsOpenOrOpening && Utils.IsLobby)
if (Input.GetKeyDown(KeyCode.C) && GameStartManager.InstanceExists && GameStartManager.Instance != null && GameStartManager.Instance.startState == GameStartManager.StartingStates.Countdown && !HudManager.Instance.Chat.IsOpenOrOpening && Utils.IsLobby)
{
Logger.Info("Resetted start countdown", "KeyCommand");
GameStartManager.Instance.ResetStartState();
Logger.SendInGame("Starting countdown canceled");
}
if (Shift) IncrementMultiplier = 5;
else if (Ctrl) IncrementMultiplier = 10;
else IncrementMultiplier = 1;
}
}
}
#endif
+2
View File
@@ -214,6 +214,8 @@ namespace AmongUsRevamped
public enum TabGroup
{
SystemSettings,
//CustomRoleSettings,
AbilitySettings,
ModSettings,
GamemodeSettings,
-2
View File
@@ -4,8 +4,6 @@ using UnityEngine;
using System;
using AmongUs.GameOptions;
using Object = UnityEngine.Object;
namespace AmongUsRevamped
{
public enum CustomRPC
+143
View File
@@ -0,0 +1,143 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using System.Text.Json;
namespace AmongUsRevamped;
public static class Translator
{
public enum SupportedLangs
{
English
}
private static readonly Dictionary<SupportedLangs, Dictionary<string, string>> _languages = new();
private static SupportedLangs _currentLang = SupportedLangs.English;
private static string LanguageFolder => $"{BanManager.DataPath}/Language";
public static void Init()
{
CheckLanguageFile(_currentLang);
LoadLanguage(_currentLang);
}
private static void CheckLanguageFile(SupportedLangs lang)
{
if (!Directory.Exists(LanguageFolder)) Directory.CreateDirectory(LanguageFolder);
string path = GetLanguagePath(lang);
var assembly = Assembly.GetExecutingAssembly();
string targetFile = $"{lang}.json";
Dictionary<string, string> embeddedDict = new();
Dictionary<string, string> diskDict = new();
foreach (var name in assembly.GetManifestResourceNames())
{
if (name.EndsWith(targetFile, StringComparison.OrdinalIgnoreCase))
{
using var stream = assembly.GetManifestResourceStream(name);
using var reader = new StreamReader(stream);
string json = reader.ReadToEnd();
embeddedDict = JsonSerializer.Deserialize<Dictionary<string, string>>(json) ?? new Dictionary<string, string>();
break;
}
}
if (File.Exists(path))
{
try
{
string json = File.ReadAllText(path);
diskDict = JsonSerializer.Deserialize<Dictionary<string, string>>(json) ?? new Dictionary<string, string>();
}
catch
{
diskDict = new Dictionary<string, string>();
}
}
bool updated = false;
foreach (var kvp in embeddedDict)
{
if (!diskDict.ContainsKey(kvp.Key))
{
diskDict[kvp.Key] = kvp.Value;
updated = true;
}
}
if (!File.Exists(path) || updated)
{
var options = new JsonSerializerOptions { WriteIndented = true };
File.WriteAllText(path, JsonSerializer.Serialize(diskDict, options));
}
}
private static void LoadLanguage(SupportedLangs lang, bool reset = false)
{
string path = GetLanguagePath(lang);
if (!File.Exists(path)) return;
try
{
string json = File.ReadAllText(path);
var dict = JsonSerializer.Deserialize<Dictionary<string, string>>(json);
if (dict != null) _languages[lang] = dict;
}
catch
{
_languages[lang] = new Dictionary<string, string>();
}
}
private static string GetLanguagePath(SupportedLangs lang)
{
return $"{LanguageFolder}/{lang}.json";
}
public static string Get(string key)
{
if (_languages.TryGetValue(_currentLang, out var dict) && dict.TryGetValue(key, out var value))
{
return SendChatPatch.ConvertNum(value);
}
return $"<MISSING:{key}>";
}
public static string Get(string key, params object[] args)
{
if (_languages.TryGetValue(_currentLang, out var dict) && dict.TryGetValue(key, out var value))
{
return SendChatPatch.ConvertNum(string.Format(value, args));
}
return $"<MISSING:{key}>";
}
public static void Reload()
{
string path = GetLanguagePath(_currentLang);
var assembly = Assembly.GetExecutingAssembly();
string targetFile = $"{_currentLang}.json";
foreach (var name in assembly.GetManifestResourceNames())
{
if (name.EndsWith(targetFile, StringComparison.OrdinalIgnoreCase))
{
using var stream = assembly.GetManifestResourceStream(name);
using var reader = new StreamReader(stream);
string json = reader.ReadToEnd();
File.WriteAllText(path, json);
break;
}
}
LoadLanguage(_currentLang);
}
}
+206 -42
View File
@@ -12,8 +12,6 @@ using System.Security.Cryptography;
using System.Text;
using AmongUs.InnerNet.GameDataMessages;
using Object = UnityEngine.Object;
namespace AmongUsRevamped;
public static class Utils
@@ -43,34 +41,30 @@ public static class Utils
public static bool GamePastRoleSelection => Main.GameTimer > 10f;
public static bool HandlingGameEnd;
public static byte CustomGameOverReason;
public static bool CanCallMeetings;
public static string ColorString(Color32 color, string str) => $"<#{color.r:x2}{color.g:x2}{color.b:x2}{color.a:x2}>{str}</color>";
public static string ColorToHex(Color32 color) => $"#{color.r:x2}{color.g:x2}{color.b:x2}{color.a:x2}";
public static byte GetActiveMapId() => GameOptionsManager.Instance.CurrentGameOptions.MapId;
public static bool IsPlayerModerator(string friendCode)
public static int CheckAccessLevel(string friendCode)
{
if (friendCode == "") return false;
if (friendCode == "") return 0;
var friendCodesFilePath = @"./AUR-DATA/ModeratorList.txt";
var friendCodes = File.ReadAllLines(friendCodesFilePath);
return friendCodes.Any(code => code.Contains(friendCode));
}
var vipFilePath = @$"{BanManager.DataPath}/AUR-DATA/VIP.txt";
var vipFriendCodes = File.ReadAllLines(vipFilePath);
public static bool IsPlayerInDenyName(ClientData client, string name)
{
if (name == "" || !AmongUsClient.Instance.AmHost || !Options.ApplyDenyNameList.GetBool()) return false;
var moderatorFilePath = @$"{BanManager.DataPath}/AUR-DATA/Moderator.txt";
var moderatorFriendCodes = File.ReadAllLines(moderatorFilePath);
var denyNameFilePath = @"./AUR-DATA/DenyNameList.txt";
var deniedNames = File.ReadAllLines(denyNameFilePath);
var adminFilePath = @$"{BanManager.DataPath}/AUR-DATA/Admin.txt";
var adminFriendCodes = File.ReadAllLines(adminFilePath);
if (deniedNames.Where(code => !string.IsNullOrWhiteSpace(code)).Any(code => name.Contains(code, StringComparison.OrdinalIgnoreCase)))
{
AmongUsClient.Instance.KickPlayer(client.Id, false);
Logger.Info($" {name} was kicked because their name was in DenyNameList.txt", "Kick");
Logger.SendInGame($" {name} was kicked because their name was in DenyNameList.txt");
return true;
}
else return false;
if (adminFriendCodes.Any(code => code.Contains(friendCode))) return 3;
if (moderatorFriendCodes.Any(code => code.Contains(friendCode))) return 2;
if (vipFriendCodes.Any(code => code.Contains(friendCode))) return 1;
return 0;
}
public static string GetTabName(TabGroup tab)
@@ -79,6 +73,12 @@ public static class Utils
{
case TabGroup.SystemSettings:
return "System Settings";
/*
case TabGroup.CustomRoleSettings:
return "Custom Roles";
*/
case TabGroup.AbilitySettings:
return "Ability Settings";
case TabGroup.ModSettings:
return "Gameplay Settings";
case TabGroup.GamemodeSettings:
@@ -148,9 +148,16 @@ public static class Utils
string name = region.Name;
// Joining games shows incorrect regions
if (!AmongUsClient.Instance.AmHost)
{
name = "";
return name;
}
if (AmongUsClient.Instance.NetworkMode != NetworkModes.OnlineGame)
{
name = "Local Game";
name = "Server: Local Game";
return name;
}
@@ -159,9 +166,9 @@ public static class Utils
// Official servers
name = name switch
{
"North America" => "NA",
"Europe" => "EU",
"Asia" => "AS",
"North America" => "Server: NA",
"Europe" => "Server: EU",
"Asia" => "Server: AS",
_ => name
};
@@ -174,11 +181,11 @@ public static class Utils
{
// Modded Servers
if (ip.Contains("au-eu"))
name = "MEU";
name = "Server: MEU";
else if (ip.Contains("au-as"))
name = "MAS";
name = "Server: MAS";
else
name = "MNA";
name = "Server: MNA";
return name;
}
@@ -201,10 +208,24 @@ public static class Utils
HandlingGameEnd = false;
OnGameJoinedPatch.AutoStartCheck = false;
Main.GameTimer = 0f;
NormalGameEndChecker.canUpdateWinnerText = true;
MurderPlayerPatch.misfireCount.Clear();
LateTask.Tasks.Clear();
FixedUpdateInGamePatch.ProcessedModerators.Clear();
MurderPlayerPatch.killCount.Clear();
LateTask.Tasks.Clear();
NormalGameEndChecker.ImpCheckComplete = false;
CreateOptionsPickerPatch.SetDleks2 = false;
CanCallMeetings = true;
//CustomRoleManagement.HandlingRoleMessages = false;
PlayerControlSetRolePatch.FirstAssign = true;
PlayerControlSetRolePatch.Jesters.Clear();
PlayerControlCompleteTaskPatch.playerTasksCompleted.Clear();
PlayerControlCompleteTaskPatch.tasksPerPlayer.Clear();
PlayerControlCompleteTaskPatch.tasksInitiated = false;
PlayerControlCompleteTaskPatch.ignoredCompletedTasks = 0;
PlayerControlCompleteTaskPatch.ignoredTasks = 0;
}
public static PlayerControl[] AllAlivePlayerControls
@@ -229,6 +250,87 @@ public static class Utils
}
}
public static bool IsActive(SystemTypes type)
{
try
{
if (Utils.IsLobby || !ShipStatus.Instance || !ShipStatus.Instance.Systems.TryGetValue(type, out ISystemType systemType)) return false;
int mapId = Main.NormalOptions.MapId;
switch (type)
{
case SystemTypes.Electrical:
{
if (mapId == 5) return false;
var switchSystem = systemType.CastFast<SwitchSystem>();
return switchSystem is { IsActive: true };
}
case SystemTypes.Reactor:
{
switch (mapId)
{
case 2:
return false;
case 4:
var heliSabotageSystem = systemType.CastFast<HeliSabotageSystem>();
return heliSabotageSystem != null && heliSabotageSystem.IsActive;
default:
var reactorSystemType = systemType.CastFast<ReactorSystemType>();
return reactorSystemType is { IsActive: true };
}
}
case SystemTypes.Laboratory:
{
if (mapId != 2) return false;
var reactorSystemType = systemType.CastFast<ReactorSystemType>();
return reactorSystemType is { IsActive: true };
}
case SystemTypes.LifeSupp:
{
if (mapId is 2 or 4 or 5) return false;
var lifeSuppSystemType = systemType.CastFast<LifeSuppSystemType>();
return lifeSuppSystemType is { IsActive: true };
}
case SystemTypes.Comms:
{
if (mapId is 1 or 5)
{
var hqHudSystemType = systemType.TryCast<HqHudSystemType>();
return hqHudSystemType != null && hqHudSystemType.IsActive;
}
var hudOverrideSystemType = systemType.CastFast<HudOverrideSystemType>();
return hudOverrideSystemType is { IsActive: true };
}
case SystemTypes.HeliSabotage:
{
if (mapId != 4) return false;
var heliSabotageSystem = systemType.CastFast<HeliSabotageSystem>();
return heliSabotageSystem != null && heliSabotageSystem.IsActive;
}
case SystemTypes.MushroomMixupSabotage:
{
if (mapId != 5) return false;
var mushroomMixupSabotageSystem = systemType.CastFast<MushroomMixupSabotageSystem>();
return mushroomMixupSabotageSystem != null && mushroomMixupSabotageSystem.IsActive;
}
default:
return false;
}
}
catch (Exception e)
{
Logger.Exception(e, "IsActive");
return false;
}
}
public static void ShowLastResult(byte playerId = byte.MaxValue)
{
if (InGame)
@@ -332,16 +434,6 @@ public static class Utils
}, 6.6f, "ModeratorChatCommand3");
}
public static string BasicIntToWord(int value)
{
if (Enum.IsDefined(typeof(Main.BasicNumberToLetter), value))
{
return ((Main.BasicNumberToLetter)value).ToString();
}
return value.ToString();
}
// 0 = no winner. 1 = solo winner. 2 = add winner.
public static void CustomWinnerEndGame(PlayerControl winner, int winnerType)
{
@@ -386,13 +478,17 @@ public static class Utils
writer.Write(gameOverReason);
AmongUsClient.Instance.FinishEndGame(writer);
HandlingGameEnd = false;
Logger.Info(" -------- GAME ENDED --------", "ManualEndGame");
Logger.Info($"{gameOverReason}", "ContinueEndGame");
}
public static void DumpLog()
{
string f = $"{Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory)}/AUR-logs/";
string t = DateTime.Now.ToString("yyyy-MM-dd_HH.mm.ss");
#if ANDROID
var f = $"{BanManager.DataPath}/AUR-Logs/{t}";
#else
string f = $"{Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory)}/AUR-logs/";
#endif
string filename = $"{f}AUR-{Main.ModVersion}-{t}.log";
if (!Directory.Exists(f)) Directory.CreateDirectory(f);
FileInfo file = new(@$"{Environment.CurrentDirectory}/BepInEx/LogOutput.log");
@@ -401,8 +497,76 @@ public static class Utils
if (PlayerControl.LocalPlayer != null)
{
HudManager.Instance.Chat.AddChat(PlayerControl.LocalPlayer, $"/Dump command activated\n\nFile: AUR-{Main.ModVersion}-{t}");
#if !ANDROID
ProcessStartInfo psi = new("Explorer.exe") { Arguments = "/e,/select," + @filename.Replace("/", "\\") };
Process.Start(psi);
#endif
}
}
private readonly static Dictionary<string, Sprite> CachedSprites = [];
public static Sprite LoadSprite(string path, float pixelsPerUnit = 1f)
{
try
{
if (CachedSprites.TryGetValue(path + pixelsPerUnit, out var sprite)) return sprite;
Texture2D texture = LoadTextureFromResources(path);
sprite = Sprite.Create(texture, new(0, 0, texture.width, texture.height), new Vector2(0.5f, 0.5f), pixelsPerUnit);
sprite.hideFlags |= HideFlags.HideAndDontSave | HideFlags.DontSaveInEditor;
return CachedSprites[path + pixelsPerUnit] = sprite;
}
catch
{
Logger.Error($"Failed to read Texture: {path}", "LoadSprite");
}
return null;
}
private static unsafe Texture2D LoadTextureFromResources(string path)
{
try
{
Texture2D texture = new(2, 2, TextureFormat.ARGB32, true);
Assembly assembly = Assembly.GetExecutingAssembly();
Stream stream = assembly.GetManifestResourceStream(path);
var length = stream.Length;
var byteTexture = new Il2CppStructArray<byte>(length);
stream.Read(new Span<byte>(IntPtr.Add(byteTexture.Pointer, IntPtr.Size * 4).ToPointer(), (int)length));
ImageConversion.LoadImage(texture, byteTexture, false);
return texture;
}
catch
{
Logger.Error($"Failed to read Texture: {path}", "LoadTextureFromResources");
}
return null;
}
public static void SetChatVisible()
{
PlayerControl.LocalPlayer.CmdReportDeadBody(null);
MeetingHud.Instance.RpcClose();
}
public static MethodBase GetStateMachineMoveNext<T>(string methodName)
{
var typeName = typeof(T).FullName;
var stateMachine = typeof(T).GetNestedTypes().FirstOrDefault(x => x.Name.Contains(methodName));
if (stateMachine == null)
{
Logger.Error($"Failed to find {methodName} state machine for {typeName}", "GetStateMachineMoveNext");
return null;
}
var moveNext = AccessTools.Method(stateMachine, "MoveNext");
if (moveNext == null)
{
Logger.Error($"Failed to find MoveNext method for {typeName}.{methodName}", "GetStateMachineMoveNext");
return null;
}
Logger.Info($"Found {methodName}.MoveNext", "GetStateMachineMoveNext");
return moveNext;
}
}
+4 -4
View File
@@ -4,6 +4,7 @@ using UnityEngine;
namespace AmongUsRevamped;
// https://github.com/Yumenopai/TownOfHost_Y
#if !ANDROID
[HarmonyPatch(typeof(HudManager), nameof(HudManager.Update))]
public static class Zoom
{
@@ -16,9 +17,7 @@ public static class Zoom
public static void Postfix()
{
bool canZoom =
(Utils.IsShip && !Utils.IsMeeting && Utils.CanMove && PlayerControl.LocalPlayer.Data.IsDead)
|| (Utils.IsLobby && Utils.CanMove);
bool canZoom = (Utils.IsShip && !Utils.IsMeeting && Utils.CanMove && PlayerControl.LocalPlayer.Data.IsDead) || (Utils.IsLobby && Utils.CanMove);
if (!canZoom)
{
@@ -100,4 +99,5 @@ public static class Flag
{
OneTimeList.Remove(type);
}
}
}
#endif
+313 -123
View File
@@ -5,7 +5,6 @@ using UnityEngine;
using UnityEngine.UI;
using TMPro;
// https://github.com/SuperNewRoles/SuperNewRoles/blob/master/SuperNewRoles/Patches/LobbyBehaviourPatch.cs
namespace AmongUsRevamped;
[HarmonyPatch(typeof(ChatController), nameof(ChatController.Update))]
@@ -14,6 +13,9 @@ internal static class ChatControllerUpdatePatch
public static void Postfix(ChatController __instance)
{
if (!__instance||!__instance.freeChatField||!__instance.freeChatField.textArea||!__instance.freeChatField.background||__instance.freeChatField.textArea.compoText == null||!__instance.freeChatField.textArea.outputText) return;
if (!__instance.quickChatField||!__instance.quickChatField.background||__instance.quickChatField.text==null) return;
if (Main.DarkTheme.Value)
{
__instance.freeChatField.background.color = new Color32(40, 40, 40, byte.MaxValue);
@@ -40,13 +42,15 @@ internal static class ChatBubbleSetNamePatch
{
public static void Postfix(ChatBubble __instance, [HarmonyArgument(2)] bool voted)
{
PlayerControl seer = PlayerControl.LocalPlayer;
if (!__instance||!__instance.playerInfo||!__instance.playerInfo.Object||!__instance.playerInfo.Object.Data||!__instance.TextArea||!__instance.Background) return;
PlayerControl target = __instance.playerInfo.Object;
if (Main.DarkTheme.Value)
{
__instance.Background.color = new(0.1f, 0.1f, 0.1f, 1f);
__instance.TextArea.color = Color.white;
if (__instance.playerInfo.Object.Data.IsDead && Utils.InGame) __instance.Background.color = new(0.1f, 0.1f, 0.1f, 0.7f);
}
}
@@ -55,21 +59,47 @@ internal static class ChatBubbleSetNamePatch
[HarmonyPatch(typeof(ChatController), nameof(ChatController.SendChat))]
internal static class SendChatPatch
{
public static string noKcdMode = "0 Kill Cooldown:\n\nImpostors have no kill cooldown, Crewmates have low tasks\nThink fast and pay attention!";
public static string SnSModeOne = "Shift and Seek:\n\nImpostors can only kill someone while shapeshifted as them\nSabotages & Meetings = Off";
public static string SnSModeTwo = $"Crew wins by tasks/surviving {Options.CrewAutoWinsGameAfter.GetInt()}s\nImp wins by killing\nOne wrong kill = Can't kill for {Options.CantKillTime.GetInt()}s\n{Utils.BasicIntToWord(Options.MisfiresToSuicide.GetInt())} wrong kills = suicide";
public static string speedrunMode = $"Speedrun:\n\nEveryone is a crewmate The 1st player to finish tasks wins the game Game auto ends after {Options.GameAutoEndsAfter.GetInt()}s";
public static string ConvertNum(string input)
{
if (string.IsNullOrEmpty(input)) return input;
int digitCount = 0;
public static string allCommandsFull = "Commands:\n/r - Current mode description\n/0kc, /sns, /sp - Specific mode description\n/l - Shows last winner info\n/kick, /ban - Bans or kicks a player by name\n/ckick, /cban - Bans or kicks a player by color";
public static string allCommandsOne = "Commands:\n/r - Current mode description\n/0kc, /sns, /sp - Specific mode description\n/l - Shows last winner info";
public static string allCommandsTwo = "/kick, /ban - Bans or kicks a player by name\n/ckick, /cban - Bans or kicks a player by color";
for (int i = 0; i < input.Length; i++)
{
if (char.IsDigit(input[i]) && ++digitCount > 5)
{
var sb = new System.Text.StringBuilder(input.Length);
foreach (char c in input)
{
if (char.IsDigit(c))
sb.Append(Main.CircledDigits[c - '0']);
else
sb.Append(c);
}
return sb.ToString();
}
}
return input;
}
public static bool Prefix(ChatController __instance)
{
string text = __instance.freeChatField.textArea.text.Trim();
string msgtext = __instance.freeChatField.textArea.text.Trim();
string text = msgtext.ToLower();
string converted = ConvertNum(msgtext);
if (!AmongUsClient.Instance.AmHost) return true;
if (text == "/reload")
{
HudManager.Instance.Chat.AddChat(PlayerControl.LocalPlayer, $"{Translator.Get("translationReloaded")}");
Translator.Reload();
__instance.freeChatField.textArea.Clear();
__instance.freeChatField.textArea.SetText(string.Empty);
return false;
}
if (text == "/dump")
{
Utils.DumpLog();
@@ -77,39 +107,99 @@ internal static class SendChatPatch
__instance.freeChatField.textArea.SetText(string.Empty);
return false;
}
if (text == "/h" || text == "/help" || text == "/cmd" || text == "/commands")
if (text == "/h" || text == "/help")
{
HudManager.Instance.Chat.AddChat(PlayerControl.LocalPlayer, $"{allCommandsFull}");
HudManager.Instance.Chat.AddChat(PlayerControl.LocalPlayer, $"{Translator.Get("allCommandsFull")}");
__instance.freeChatField.textArea.Clear();
__instance.freeChatField.textArea.SetText(string.Empty);
return false;
}
if (__instance.timeSinceLastMessage < 3f || OnGameJoinedPatch.WaitingForChat) return false;
if (text == "/s" || text == "/start")
{
GameStartManager.Instance.BeginGame();
return false;
}
if (text == "/eg" || text == "/endgame")
{
__instance.freeChatField.textArea.Clear();
__instance.freeChatField.textArea.SetText(string.Empty);
if (!Utils.InGame) return false;
MessageWriter writer = AmongUsClient.Instance.StartEndGame();
writer.Write((byte)GameOverReason.ImpostorDisconnect);
AmongUsClient.Instance.FinishEndGame(writer);
return false;
}
if (text == "/em" || text == "/endmeeting")
{
__instance.freeChatField.textArea.Clear();
__instance.freeChatField.textArea.SetText(string.Empty);
if ( !Utils.InGame || !Utils.IsMeeting) return false;
MeetingHud.Instance.RpcClose();
return false;
}
if (__instance.timeSinceLastMessage < 3f || OnGameJoinedPatch.WaitingForChat /*|| CustomRoleManagement.HandlingRoleMessages*/) return false;
if (text == "/l" || text == "/lastgame" || text == "/win" || text == "/winner")
{
if (string.IsNullOrEmpty(NormalGameEndChecker.LastWinReason) || Utils.InGame) return false;
Utils.ChatCommand(__instance, $"{NormalGameEndChecker.LastWinReason}", "", false);
return false;
}
}
if (text == "/r jester"){
Utils.ChatCommand(__instance, Translator.Get("jesterPublic"), "", false);
return false;}
if (text == "/0kc" || text == "/0kcd" || text == "/0killcooldown")
if (text == "/r mayor"){
Utils.ChatCommand(__instance, Translator.Get("mayorPublic", Options.ExtraVotesCrewmate.GetInt()), "", false);
return false;}
if (text == "/r tyrant"){
Utils.ChatCommand(__instance, Translator.Get("tyrantPublic", Options.ExtraVotesImpostor.GetInt()), "", false);
return false;}
if (text == "/r workhorse"){
Utils.ChatCommand(__instance, Translator.Get("workhorsePublic", Options.ExtraVotesPerTask.GetFloat()), "", false);
return false;}
if (text == "/r stealer"){
Utils.ChatCommand(__instance, Translator.Get("stealerPublic", Options.ExtraVotesPerKill.GetFloat()), "", false);
return false;}
if (text == "/r juggernaut"){
Utils.ChatCommand(__instance, Translator.Get("juggernautPublic", Options.KillsNeededForJuggernaut.GetInt()), "", false);
return false;}
if (text == "/r speedrunner"){
Utils.ChatCommand(__instance, Translator.Get("speedrunnerPublic"), "", false);
return false;}
if (text == "/aur" || text == "/amongusrevamped" || text == "/socials")
{
Utils.ChatCommand(__instance, $"{noKcdMode}", "", false);
Utils.ChatCommand(__instance, Translator.Get("socialsAll"), "", false);
return false;
}
if (text == "/sns" || text == "/shiftandseek" || text == "/shift&seek")
if (text == "/0kc" || text == "/0killcooldown")
{
Utils.ChatCommand(__instance, $"{SnSModeOne}", $"{SnSModeTwo}", true);
Utils.ChatCommand(__instance, Translator.Get("noKcdMode"), "", false);
return false;
}
if (text == "/sns" || text == "/shiftandseek")
{
Utils.ChatCommand(__instance, Translator.Get("SnSModeOne"), Translator.Get("SnSModeTwo", Options.CrewAutoWinsGameAfter.GetInt(), Options.CantKillTime.GetInt(), Options.MisfiresToSuicide.GetInt()), true);
return false;
}
if (text == "/sp" || text == "/sr" || text == "/speedrun")
{
Utils.ChatCommand(__instance, $"{speedrunMode}", "", false);
Utils.ChatCommand(__instance, Translator.Get("speedrunMode", Options.GameAutoEndsAfter.GetInt()), "", false);
return false;
}
@@ -118,25 +208,43 @@ internal static class SendChatPatch
switch (Options.Gamemode.GetValue())
{
case 0:
PlayerControl.LocalPlayer.RpcSendChat($"Custom roles:\nThere are no custom roles.");
__instance.timeSinceLastMessage = 0.8f;
__instance.freeChatField.textArea.Clear();
__instance.freeChatField.textArea.SetText(string.Empty);
AbilityManagement.SendRoleList(__instance, AbilityManagement.RoleList(), false);
break;
case 1:
Utils.ChatCommand(__instance, $"{noKcdMode}", "", false);
Utils.ChatCommand(__instance, Translator.Get("noKcdMode"), "", false);
break;
case 2:
Utils.ChatCommand(__instance, $"{SnSModeOne}", $"{SnSModeTwo}", true);
Utils.ChatCommand(__instance, Translator.Get("SnSModeOne"), Translator.Get("SnSModeTwo", Options.CrewAutoWinsGameAfter.GetInt(), Options.CantKillTime.GetInt(), Options.MisfiresToSuicide.GetInt()), true);
break;
case 3:
Utils.ChatCommand(__instance, $"{speedrunMode}", "", false);
Utils.ChatCommand(__instance, Translator.Get("speedrunMode", Options.GameAutoEndsAfter.GetInt()), "", false);
break;
}
__instance.timeSinceLastMessage = 0.8f;
__instance.freeChatField.textArea.Clear();
__instance.freeChatField.textArea.SetText(string.Empty);
return false;
}
if (text.StartsWith("/t "))
{
string templateName = text[3..].Trim().ToLower();
if (BanManager.Templates.TryGetValue(templateName, out string templateMessage))
{
Utils.ChatCommand(__instance, templateMessage, "", false);
}
else
{
Logger.Info($"Could not find template '{templateName}'", "TemplateManager");
HudManager.Instance.Chat.AddChat(PlayerControl.LocalPlayer, $"Template '{templateName}' not found.");
}
__instance.freeChatField.textArea.Clear();
__instance.freeChatField.textArea.SetText(string.Empty);
return false;
}
@@ -171,7 +279,10 @@ internal static class SendChatPatch
if (!isKick && !isBan && !isColorKick && !isColorBan)
{
Logger.Info($" {PlayerControl.LocalPlayer.Data.PlayerName}: {text}", "SendChat");
//__instance.freeChatField.textArea.SetText(converted);
//Utils.ChatCommand(__instance, $"{converted}", "", false);
Logger.Info($" {PlayerControl.LocalPlayer.Data.PlayerName}: {msgtext}", "SendChat");
return true;
}
@@ -214,7 +325,7 @@ internal static class SendChatPatch
[HarmonyPatch(typeof(PlayerControl), nameof(PlayerControl.HandleRpc))]
public static class RPCHandlerPatch
{
public static void Prefix(PlayerControl __instance, byte callId, MessageReader reader)
public static void Prefix(PlayerControl __instance, [HarmonyArgument(0)] byte callId, [HarmonyArgument(1)] MessageReader reader)
{
if (!AmongUsClient.Instance.AmHost) return;
@@ -225,77 +336,43 @@ public static class RPCHandlerPatch
{
case RpcCalls.SendChat:
{
string text = subReader.ReadString();
Logger.Info($" {__instance.Data.PlayerName}: {text}", "SendChat");
string msgtext = subReader.ReadString();
string text = msgtext.ToLower();
if (text == "/h" || text == "/help" || text == "/cmd" || text == "/commands")
Logger.Info($" {__instance.Data.PlayerName}: {msgtext}", "SendChat");
string[] keywords = Options.AutoKickStartStrength.GetBool() ? new[] { "start", "begin", "commence" } : new[] { "start", "begin", "commence", "s t a r t", "go" };
bool c = false;
if (Options.AutoKickStartStrength.GetBool())
{
if (!Utils.IsPlayerModerator(__instance.Data.FriendCode) || !Options.ModeratorCanUseCommand.GetBool()) return;
OnGameJoinedPatch.WaitingForChat = true;
c = keywords.Any(k => text.Contains(k));
}
else
{
c = keywords.Any(k => text == k);
}
if (c && Utils.CheckAccessLevel(__instance.Data.FriendCode) < 1 && Options.AutoKickStart.GetBool() && !Utils.InGame)
{
int clientId = __instance.Data.ClientId;
new LateTask(() =>
if (!Main.SayStartTimes.ContainsKey(clientId))
Main.SayStartTimes.Add(clientId, 0);
Main.SayStartTimes[clientId]++;
if (Main.SayStartTimes[clientId] >= Options.AutoKickStartTimes.GetInt())
{
Utils.SendPrivateMessage(__instance, $"{SendChatPatch.allCommandsOne}");
}, 2.2f, "MHP1");
new LateTask(() =>
{
Utils.SendPrivateMessage(__instance, $"{SendChatPatch.allCommandsTwo}");
}, 4.4f, "MHP2");
new LateTask(() =>
{
OnGameJoinedPatch.WaitingForChat = false;
}, 6.6f, "MHP3");
}
if (text == "/l" || text == "/lastgame" || text == "/win" || text == "/winner")
{
if (!Utils.IsPlayerModerator(__instance.Data.FriendCode) || !Options.ModeratorCanUseCommand.GetBool()) return;
if (string.IsNullOrEmpty(NormalGameEndChecker.LastWinReason) || Utils.InGame) return;
Utils.ModeratorChatCommand($"{NormalGameEndChecker.LastWinReason}", "", false);
}
if (text == "/0kc" || text == "/0kcd" || text == "/0killcooldown")
{
if (!Utils.IsPlayerModerator(__instance.Data.FriendCode) || !Options.ModeratorCanUseCommand.GetBool()) return;
Utils.ModeratorChatCommand($"{SendChatPatch.noKcdMode}", "", false);
}
if (text == "/sns" || text == "/shiftandseek" || text == "/shift&seek")
{
if (!Utils.IsPlayerModerator(__instance.Data.FriendCode) || !Options.ModeratorCanUseCommand.GetBool()) return;
Utils.ModeratorChatCommand($"{SendChatPatch.SnSModeOne}", $"{SendChatPatch.SnSModeTwo}", true);
}
if (text == "/sp" || text == "/sr" || text == "/speedrun")
{
if (!Utils.IsPlayerModerator(__instance.Data.FriendCode) || !Options.ModeratorCanUseCommand.GetBool()) return;
Utils.ModeratorChatCommand($"{SendChatPatch.speedrunMode}", "", false);
}
if (text == "/r" || text == "/roles" || text == "/gamemode" || text == "/gm")
{
if (!Utils.IsPlayerModerator(__instance.Data.FriendCode) || !Options.ModeratorCanUseCommand.GetBool()) return;
switch (Options.Gamemode.GetValue())
{
case 0:
break;
case 1:
Utils.ModeratorChatCommand($"{SendChatPatch.noKcdMode}", "", false);
break;
case 2:
Utils.ModeratorChatCommand($"{SendChatPatch.SnSModeOne}", $"{SendChatPatch.SnSModeTwo}", true);
break;
case 3:
Utils.ModeratorChatCommand($"{SendChatPatch.speedrunMode}", "", false);
break;
bool sBan = Options.AutoKickStartAsBan.GetBool();
AmongUsClient.Instance.KickPlayer(clientId, sBan);
Logger.Info($" {__instance.Data.PlayerName} was {(sBan ? "banned" : "kicked")} for saying start", "KickAnnoyingKids");
Logger.SendInGame($" {__instance.Data.PlayerName} was {(sBan ? "banned" : "kicked")} for saying start");
}
}
BanManager.IsWordBanned(__instance, text);
bool col1 = text.StartsWith("/col ") || text.StartsWith("/cor ");
bool col2 = text.StartsWith("/color ");
bool col3 = text.StartsWith("/colour ");
@@ -306,29 +383,26 @@ public static class RPCHandlerPatch
if (Utils.TryGetColorId(argCol, out byte colId))
{
if (Options.ColorCommandLevel.GetValue() == 0 && Utils.IsPlayerModerator(__instance.Data.FriendCode) || Options.ColorCommandLevel.GetValue() == 1)
if (Utils.CheckAccessLevel(__instance.Data.FriendCode) >= Options.SlashColorCmd.GetValue())
{
if (colId > 17 && !Options.AllowFortegreen.GetBool()) return;
__instance.RpcSetColor(colId);
}
}
}
else
// Banning works by name and color. Commands are separated incase someone has a color as their name
bool isKick = text.StartsWith("/kick ");
bool isBan = text.StartsWith("/ban ");
bool isColorKick = text.StartsWith("/ckick ");
bool isColorBan = text.StartsWith("/cban ");
bool banLog = isBan || isColorBan;
if (isKick || isBan || isColorKick || isColorBan)
{
if (!Utils.IsPlayerModerator(__instance.Data.FriendCode)) return;
// Banning works by name and color. Commands are seperated incase someone has a color as their name
bool isKick = text.StartsWith("/kick ");
bool isBan = text.StartsWith("/ban ");
bool isColorKick = text.StartsWith("/ckick ");
bool isColorBan = text.StartsWith("/cban ");
bool banLog = isBan || isColorBan;
if (!isKick && !isBan && !isColorKick && !isColorBan) return;
if (Utils.IsPlayerModerator(__instance.Data.FriendCode))
if (Utils.CheckAccessLevel(__instance.Data.FriendCode) >= Options.SlashKickCmd.GetValue())
{
string arg = text.Substring(isKick ? 6 : isBan ? 5 : isColorKick ? 7 : isColorBan ? 6 : 0).Trim();
@@ -336,7 +410,7 @@ public static class RPCHandlerPatch
foreach (PlayerControl p in PlayerControl.AllPlayerControls)
{
if (p.Data == null || p == PlayerControl.LocalPlayer || Utils.IsPlayerModerator(p.Data.FriendCode)) continue;
if (p.Data == null || p == PlayerControl.LocalPlayer || Utils.CheckAccessLevel(p.Data.FriendCode) >= 1) continue;
if ((isKick || isBan) && p.Data.PlayerName.Equals(arg, StringComparison.OrdinalIgnoreCase))
{
@@ -353,6 +427,7 @@ public static class RPCHandlerPatch
}
}
}
if (banLog && Utils.CheckAccessLevel(__instance.Data.FriendCode) < Options.SlashBanCmd.GetValue()) return;
if (target != null)
{
@@ -361,21 +436,136 @@ public static class RPCHandlerPatch
}
}
}
if (/*CustomRoleManagement.HandlingRoleMessages || */OnGameJoinedPatch.WaitingForChat || GameStartManagerUpdatePatch.CountingDown) return;
if (text == "/h" || text == "/help")
{
if (Utils.CheckAccessLevel(__instance.Data.FriendCode) < Options.SlashHelpAndAurCmd.GetValue()) return;
OnGameJoinedPatch.WaitingForChat = true;
new LateTask(() =>
{
Utils.SendPrivateMessage(__instance, Translator.Get("allCommandsOne"));
}, 2.2f, "MHP1");
new LateTask(() =>
{
Utils.SendPrivateMessage(__instance, Translator.Get("allCommandsTwo"));
}, 4.4f, "MHP2");
new LateTask(() =>
{
OnGameJoinedPatch.WaitingForChat = false;
}, 6.6f, "MHP3");
}
if (text == "/eg" || text == "/endgame")
{
if (Utils.CheckAccessLevel(__instance.Data.FriendCode) < Options.SlashStartAndEndGameCmd.GetValue()) return;
MessageWriter writer = AmongUsClient.Instance.StartEndGame();
writer.Write((byte)GameOverReason.ImpostorDisconnect);
AmongUsClient.Instance.FinishEndGame(writer);
}
if (text == "/em" || text == "/endmeeting")
{
if (Utils.IsMeeting)
{
if (Utils.CheckAccessLevel(__instance.Data.FriendCode) < Options.SlashEndMeetingCmd.GetValue()) return;
MeetingHud.Instance.RpcClose();
}
}
if (text == "/s" || text == "/start")
{
if (Utils.CheckAccessLevel(__instance.Data.FriendCode) < Options.SlashStartAndEndGameCmd.GetValue()) return;
GameStartManager.Instance.BeginGame();
}
if (text == "/l" || text == "/lastgame" || text == "/win" || text == "/winner")
{
if (Utils.CheckAccessLevel(__instance.Data.FriendCode) < Options.SlashLastGameCmd.GetValue()) return;
if (string.IsNullOrEmpty(NormalGameEndChecker.LastWinReason) || Utils.InGame) return;
Utils.ModeratorChatCommand($"{NormalGameEndChecker.LastWinReason}", "", false);
}
if (text == "/0kc" || text == "/0killcooldown")
{
if (Utils.CheckAccessLevel(__instance.Data.FriendCode) < Options.SlashRolesAndGamemodeCmd.GetValue()) return;
Utils.ModeratorChatCommand(Translator.Get("noKcdMode"), "", false);
}
if (text == "/sns" || text == "/shiftandseek")
{
if (Utils.CheckAccessLevel(__instance.Data.FriendCode) < Options.SlashRolesAndGamemodeCmd.GetValue()) return;
Utils.ModeratorChatCommand(Translator.Get("SnSModeOne"), Translator.Get("SnSModeTwo", Options.CrewAutoWinsGameAfter.GetInt(), Options.CantKillTime.GetInt(), Options.MisfiresToSuicide.GetInt()), true);
}
if (text == "/sp" || text == "/sr" || text == "/speedrun")
{
if (Utils.CheckAccessLevel(__instance.Data.FriendCode) < Options.SlashRolesAndGamemodeCmd.GetValue()) return;
Utils.ModeratorChatCommand(Translator.Get("speedrunMode", Options.GameAutoEndsAfter.GetInt()), "", false);
}
if (text == "/r" || text == "/roles" || text == "/gamemode" || text == "/gm")
{
if (Utils.CheckAccessLevel(__instance.Data.FriendCode) < Options.SlashRolesAndGamemodeCmd.GetValue()) return;
switch (Options.Gamemode.GetValue())
{
case 0:
AbilityManagement.SendRoleList(DestroyableSingleton<HudManager>.Instance.Chat, AbilityManagement.RoleList(), true);
break;
case 1:
Utils.ModeratorChatCommand(Translator.Get("noKcdMode"), "", false);
break;
case 2:
Utils.ModeratorChatCommand(Translator.Get("SnSModeOne"), Translator.Get("SnSModeTwo", Options.CrewAutoWinsGameAfter.GetInt(), Options.CantKillTime.GetInt(), Options.MisfiresToSuicide.GetInt()), true);
break;
case 3:
Utils.ModeratorChatCommand(Translator.Get("speedrunMode", Options.GameAutoEndsAfter.GetInt()), "", false);
break;
}
}
if (Utils.CheckAccessLevel(__instance.Data.FriendCode) < Options.SlashRolesAndGamemodeCmd.GetValue()) return;
if (text == "/r jester"){
Utils.ModeratorChatCommand(Translator.Get("jesterPublic"), "", false);}
if (text == "/r mayor"){
Utils.ModeratorChatCommand(Translator.Get("mayorPublic", Options.ExtraVotesCrewmate.GetInt()), "", false);}
if (text == "/r tyrant"){
Utils.ModeratorChatCommand(Translator.Get("tyrantPublic", Options.ExtraVotesImpostor.GetInt()), "", false);}
if (text == "/r workhorse"){
Utils.ModeratorChatCommand(Translator.Get("workhorsePublic", Options.ExtraVotesPerTask.GetFloat()), "", false);}
if (text == "/r stealer"){
Utils.ModeratorChatCommand(Translator.Get("stealerPublic", Options.ExtraVotesPerKill.GetFloat()), "", false);}
if (text == "/r juggernaut"){
Utils.ModeratorChatCommand(Translator.Get("juggernautPublic", Options.KillsNeededForJuggernaut.GetInt()), "", false);}
if (text == "/r speedrunner"){
Utils.ModeratorChatCommand(Translator.Get("speedrunnerPublic"), "", false);}
if (text.StartsWith("/t "))
{
string templateName = text[3..].Trim().ToLower();
if (BanManager.Templates.TryGetValue(templateName, out string templateMessage))
{
Utils.ModeratorChatCommand(templateMessage, "", false);
}
}
break;
}
}
}
}
[HarmonyPatch(typeof(HudManager), nameof(HudManager.Update))]
public static class HudManager_Update
{
public static void Postfix(HudManager __instance)
{
if (Main.GM.Value)
{
__instance.Chat.gameObject.SetActive(true);
__instance.MapButton.gameObject.SetActive(true);
}
}
}
+34 -19
View File
@@ -10,11 +10,11 @@ namespace AmongUsRevamped
public static class OptionsMenuBehaviourStartPatch
{
private static ClientOptionItem GM;
private static ClientOptionItem UnlockFPS;
private static ClientOptionItem ShowFPS;
private static ClientOptionItem AutoStart;
private static ClientOptionItem DarkTheme;
private static ClientOptionItem LobbyMusic;
private static ClientOptionItem DisableInfoWhenDead;
public static void Postfix(OptionsMenuBehaviour __instance)
{
@@ -22,32 +22,24 @@ namespace AmongUsRevamped
if (GM == null || GM.ToggleButton == null)
{
GM = ClientOptionItem.Create("Game Master", Main.GM, __instance, GMButtonToggle);
GM = ClientOptionItem.Create(Translator.Get("gameMaster"), Main.GM, __instance, GMButtonToggle);
static void GMButtonToggle()
{
if (Main.GM.Value)
HudManager.Instance.ShowPopUp("You will now spectate games until GM is turned off.");
}
}
if (UnlockFPS == null || UnlockFPS.ToggleButton == null)
{
UnlockFPS = ClientOptionItem.Create("Unlock FPS", Main.UnlockFps, __instance, UnlockFPSButtonToggle);
static void UnlockFPSButtonToggle()
{
Application.targetFrameRate = Main.UnlockFps.Value ? 120 : 60;
Logger.SendInGame($"FPS Set To {Application.targetFrameRate}");
HudManager.Instance.ShowPopUp(Translator.Get("gameMasterWarning"));
}
}
if (ShowFPS == null || ShowFPS.ToggleButton == null)
ShowFPS = ClientOptionItem.Create("Show FPS", Main.ShowFps, __instance);
ShowFPS = ClientOptionItem.Create(Translator.Get("showFPS"), Main.ShowFps, __instance);
if (DisableInfoWhenDead == null || DisableInfoWhenDead.ToggleButton == null)
DisableInfoWhenDead = ClientOptionItem.Create(Translator.Get("disableInfoWhenDead"), Main.DisableInfoWhenDead, __instance);
if (AutoStart == null || AutoStart.ToggleButton == null)
{
AutoStart = ClientOptionItem.Create("Auto Start", Main.AutoStart, __instance, AutoStartButtonToggle);
AutoStart = ClientOptionItem.Create(Translator.Get("autoStart"), Main.AutoStart, __instance, AutoStartButtonToggle);
static void AutoStartButtonToggle()
{
@@ -55,16 +47,16 @@ namespace AmongUsRevamped
GameStartManager.Instance.startState == GameStartManager.StartingStates.Countdown)
{
GameStartManager.Instance.ResetStartState();
Logger.SendInGame("CancelStartCountDown");
Logger.SendInGame(Translator.Get("CancelStartCountDown"));
}
}
}
if (DarkTheme == null || DarkTheme.ToggleButton == null)
DarkTheme = ClientOptionItem.Create("Enable Dark Theme", Main.DarkTheme, __instance);
DarkTheme = ClientOptionItem.Create(Translator.Get("enableDarkTheme"), Main.DarkTheme, __instance);
if (LobbyMusic == null || LobbyMusic.ToggleButton == null)
LobbyMusic = ClientOptionItem.Create("Lobby Music", Main.LobbyMusic, __instance);
LobbyMusic = ClientOptionItem.Create(Translator.Get("enableLobbyMusic"), Main.LobbyMusic, __instance);
}
}
@@ -76,4 +68,27 @@ namespace AmongUsRevamped
ClientOptionItem.CustomBackground?.gameObject.SetActive(false);
}
}
[HarmonyPatch(typeof(SplashManager), nameof(SplashManager.Update))]
internal class SplashLogoAnimatorPatch
{
public static void Prefix(SplashManager __instance)
{
__instance.sceneChanger.AllowFinishLoadingScene();
__instance.startedSceneLoad = true;
}
}
[HarmonyPatch(typeof(HudManager), nameof(HudManager.Update))]
public static class HudManager_Update
{
public static void Postfix(HudManager __instance)
{
if (Main.GM.Value && AmongUsClient.Instance.AmHost)
{
__instance.Chat.gameObject.SetActive(true);
__instance.MapButton.gameObject.SetActive(true);
}
}
}
}
+171 -50
View File
@@ -1,7 +1,9 @@
using System;
using System.Text;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using TMPro;
using UnityEngine;
using UnityEngine.SceneManagement;
//https://github.com/Gurge44/EndlessHostRoles/blob/main/Patches/CredentialsPatch.cs
namespace AmongUsRevamped
@@ -123,8 +125,12 @@ namespace AmongUsRevamped
Sb.Append(Utils.InGame ? " - " : "\r\n");
Sb.Append($"<color={color}>Ping: {ping}</color>");
AppendSeparator();
Sb.Append($"Server: {Utils.GetRegionName()}");
if (Utils.GetRegionName() != "")
{
AppendSeparator();
Sb.Append(Utils.GetRegionName());
}
if (Main.ShowFps.Value && LastFPS.Count > 0)
{
@@ -166,69 +172,184 @@ namespace AmongUsRevamped
}
}
}
}
// https://github.com/3X3CODE/MainMenuEnhanced/blob/main/MainMenuEnhanced/VisualPatch.cs
[HarmonyPatch(typeof(MainMenuManager), nameof(MainMenuManager.Start))]
public static class MainMenuManagerStartPatch
{
public static void Postfix(MainMenuManager __instance)
// https://github.com/3X3CODE/MainMenuEnhanced/blob/main/MainMenuEnhanced/VisualPatch.cs
[HarmonyPatch(typeof(MainMenuManager), nameof(MainMenuManager.Start))]
public static class MainMenuManagerStartPatch
{
if (__instance == null) return;
var bg = GameObject.Find("BackgroundTexture");
if (bg != null)
private static PassiveButton template;
private static PassiveButton discordButton;
private static PassiveButton gitHubButton;
private static Transform buttonParent;
public static void Postfix(MainMenuManager __instance)
{
bg.SetActive(false);
}
if (__instance == null) return;
if (template == null) template = __instance.quitButton;
if (template == null) return;
Transform tintTrans = __instance.transform.Find("MainUI/Tint");
var tint = tintTrans.gameObject;
if (tint != null)
{
tint.SetActive(false);
}
DisableObject("WindowShine");
DisableComponent("RightPanel");
DisableComponent("MaskedBlackScreen");
Transform playTransform = __instance.transform.Find("MainUI/AspectScaler/LeftPanel/Main Buttons/PlayButton/FontPlacer/Text_TMP");
if (playTransform != null)
{
var playbutton = playTransform.gameObject;
if (playbutton != null)
if (buttonParent == null) buttonParent = template.transform.parent;
if (discordButton == null)
{
if (playbutton.TryGetComponent<TextTranslatorTMP>(out var tmp))
discordButton = CreateButton(
__instance,
"DiscordButton",
new(2.1f, 4.05f, 1f),
new(88, 101, 242, byte.MaxValue),
new(148, 161, byte.MaxValue, byte.MaxValue),
() => Application.OpenURL("https://discord.gg/83Zhzhyhya"),
"Discord");
}
if (gitHubButton == null)
{
gitHubButton = CreateButton(
__instance,
"GitHubButton",
new(3.8f, 4.05f, 1f),
new(153, 153, 153, byte.MaxValue),
new(209, 209, 209, byte.MaxValue),
() => Application.OpenURL("https://github.com/ApeMV/AmongUsRevamped"),
"GitHub");
}
var bg = GameObject.Find("BackgroundTexture");
if (bg != null)
{
bg.SetActive(false);
}
var leftPanel = GameObject.Find("LeftPanel");
if (leftPanel != null)
{
leftPanel.gameObject.GetComponent<SpriteRenderer>().enabled = false;
}
var div = GameObject.Find("MainUI/AspectScaler/LeftPanel/Main Buttons/Divider");
if (div != null)
{
div.SetActive(false);
}
Transform tintTrans = __instance.transform.Find("MainUI/Tint");
var tint = tintTrans.gameObject;
if (tint != null)
{
tint.SetActive(false);
}
DisableObject("WindowShine");
DisableComponent("RightPanel");
DisableComponent("MaskedBlackScreen");
Transform playTransform = __instance.transform.Find("MainUI/AspectScaler/LeftPanel/Main Buttons/PlayButton/FontPlacer/Text_TMP");
if (playTransform != null)
{
var playbutton = playTransform.gameObject;
if (playbutton != null)
{
tmp.enabled = false;
}
if (playbutton.TryGetComponent<TextMeshPro>(out var text))
{
text.text = "Start";
if (playbutton.TryGetComponent<TextTranslatorTMP>(out var tmp))
{
tmp.enabled = false;
}
if (playbutton.TryGetComponent<TextMeshPro>(out var text))
{
text.text = "Start";
}
}
}
}
static void DisableObject(string name)
{
var obj = GameObject.Find(name);
if (obj != null)
static void DisableObject(string name)
{
obj.SetActive(false);
var obj = GameObject.Find(name);
if (obj != null)
{
obj.SetActive(false);
}
}
static void DisableComponent(string name)
{
var obj = GameObject.Find(name);
if (obj != null)
{
if (obj.TryGetComponent<SpriteRenderer>(out var renderer))
{
renderer.enabled = false;
}
}
}
}
static void DisableComponent(string name)
private static PassiveButton CreateButton(MainMenuManager menu, string name, Vector3 localPosition, Color32 normalColor, Color32 hoverColor, Action action, string label)
{
var obj = GameObject.Find(name);
if (obj != null)
var parent = menu.transform.Find("MainUI/AspectScaler/LeftPanel/Main Buttons");
if (parent == null) return null;
var button = Object.Instantiate(menu.quitButton, parent);
button.name = name;
button.transform.localPosition = localPosition;
button.transform.localScale = new Vector3(0.8f, 1f, 1f);
var aspect = button.GetComponent<AspectPosition>();
if (aspect != null)
{
if (obj.TryGetComponent<SpriteRenderer>(out var renderer))
{
renderer.enabled = false;
}
aspect.enabled = false;
}
button.OnClick = new();
button.OnClick.AddListener(action);
var buttonText = button.transform.Find("FontPlacer/Text_TMP").GetComponent<TMP_Text>();
Utils.DestroyTranslator(buttonText);
buttonText.text = label;
buttonText.fontSize = buttonText.fontSizeMax = buttonText.fontSizeMin = 3.5f;
buttonText.enableWordWrapping = false;
buttonText.horizontalAlignment = HorizontalAlignmentOptions.Center;
var normalSprite = button.inactiveSprites.GetComponent<SpriteRenderer>();
var hoverSprite = button.activeSprites.GetComponent<SpriteRenderer>();
normalSprite.color = normalColor;
hoverSprite.color = hoverColor;
button.gameObject.SetActive(true);
return button;
}
}
}
}
#if !ANDROID
[HarmonyPatch(typeof(ServerDropdown), nameof(ServerDropdown.FillServerOptions))]
public static class ServerDropdownPatch
{
public static bool Prefix(ServerDropdown __instance)
{
if (SceneManager.GetActiveScene().name == "FindAGame") return true;
SpriteRenderer bg = __instance.background;
bg.size = new Vector2(4, 1);
ServerManager sm = ServerManager.Instance;
TranslationController tc = TranslationController.Instance;
int totalCols = Mathf.Max(1, Mathf.CeilToInt(sm.AvailableRegions.Length / (float)5));
int rowLimit = Mathf.Min(sm.AvailableRegions.Length, 5);
for (var index = 0; index < sm.AvailableRegions.Length; index++)
{
IRegionInfo ri = sm.AvailableRegions[index];
var b = __instance.ButtonPool.Get<ServerListButton>();
b.transform.localPosition = new Vector3(((index / 5) - ((totalCols - 1) / 2f)) * 3.15f, __instance.y_posButton - (0.5f * (index % 5)), -1f);
b.Text.text = tc.GetStringWithDefault(ri.TranslateName, ri.Name, new Il2CppReferenceArray<Il2CppSystem.Object>(0));
b.Text.ForceMeshUpdate();
b.Button.OnClick.RemoveAllListeners();
b.Button.OnClick.AddListener((Action)(() => __instance.ChooseOption(ri)));
__instance.controllerSelectable.Add(b.Button);
}
float h = 1.2f + (0.5f * (rowLimit - 1));
float w = totalCols > 1 ? (3.15f * (totalCols - 1)) + bg.size.x : bg.size.x;
bg.transform.localPosition = new Vector3(0f, __instance.initialYPos - ((h - 1.2f) / 2f), 0f);
bg.size = new Vector2(w, h);
return false;
}
}
#endif
+32
View File
@@ -0,0 +1,32 @@
namespace AmongUsRevamped;
[HarmonyPatch(typeof(DeconSystem), nameof(DeconSystem.UpdateSystem))]
public static class DeconSystemUpdateSystemPatch
{
public static void Prefix(DeconSystem __instance)
{
if (!AmongUsClient.Instance.AmHost) return;
if (Options.ChangeDecontaminationTime.GetBool())
{
__instance.DoorOpenTime = Main.CurrentMap switch
{
MapNames.MiraHQ => Options.DecontaminationDoorOpenTimeOnMiraHQ.GetFloat(),
MapNames.Polus => Options.DecontaminationDoorOpenTimeOnPolus.GetFloat(),
_ => 3f
};
__instance.DeconTime = Main.CurrentMap switch
{
MapNames.MiraHQ => Options.DecontaminationTimeOnMiraHQ.GetFloat(),
MapNames.Polus => Options.DecontaminationTimeOnPolus.GetFloat(),
_ => 3f
};
}
else
{
__instance.DoorOpenTime = 3f;
__instance.DeconTime = 3f;
}
}
}
+198
View File
@@ -0,0 +1,198 @@
using System;
using Hazel;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using UnityEngine;
namespace AmongUsRevamped;
// https://github.com/ykundesu/SuperNewRoles/blob/master/SuperNewRoles/Mode/SuperHostRoles/BlockTool.cs
internal static class DisableDevice
{
public static readonly List<byte> DesyncComms = [];
private static int frame;
public static readonly Dictionary<string, Vector2> DevicePos = new()
{
["SkeldAdmin"] = new(3.48f, -8.62f),
["SkeldCamera"] = new(-13.06f, -2.45f),
["MiraHQAdmin"] = new(21.02f, 19.09f),
["MiraHQDoorLog"] = new(16.22f, 5.82f),
["PolusLeftAdmin"] = new(22.80f, -21.52f),
["PolusRightAdmin"] = new(24.66f, -21.52f),
["PolusCamera"] = new(2.96f, -12.74f),
["PolusVital"] = new(26.70f, -15.94f),
["DleksAdmin"] = new(-3.48f, -8.62f),
["DleksCamera"] = new(13.06f, -2.45f),
["AirshipCockpitAdmin"] = new(-22.32f, 0.91f),
["AirshipRecordsAdmin"] = new(19.89f, 12.60f),
["AirshipCamera"] = new(8.10f, -9.63f),
["AirshipVital"] = new(25.24f, -7.94f),
["FungleCamera"] = new(6.20f, 0.10f),
["FungleVital"] = new(-2.50f, -9.80f),
["SubmergedVital"] = new(5f, 32.54f),
["SubmergedLeftAdmin"] = new(-9.45f, 10.16f),
["SubmergedRightAdmin"] = new(-7.07f, 10.16f),
["SubmergedCamera"] = new(-3.41f, -34.56f)
};
public static bool DoDisable => Options.DisableDevices.GetBool();
public static float UsableDistance => Main.CurrentMap switch
{
MapNames.Skeld => 1.5f,
MapNames.MiraHQ => 2.2f,
MapNames.Polus => 1.4f,
MapNames.Dleks => 1.5f,
MapNames.Airship => 1.6f,
MapNames.Fungle => 1.7f,
_ => 2f
};
public static void FixedUpdate()
{
if (!AmongUsClient.Instance.AmHost || ShipStatus.Instance == null || !Utils.GamePastRoleSelection) return;
frame = frame == 5 ? 0 : ++frame;
if (frame != 0) return;
if (!DoDisable) return;
foreach (PlayerControl pc in Main.AllPlayerControls)
{
if (pc.Data.IsDead || Main.GM.Value && pc == PlayerControl.LocalPlayer) return;
try
{
var doComms = false;
Vector2 PlayerPos = pc.GetTruePosition();
if (!Utils.IsActive(SystemTypes.Comms))
{
switch (Main.NormalOptions.MapId)
{
case 0:
if (Options.DisableSkeldAdmin.GetBool()) doComms |= Vector2.Distance(PlayerPos, DevicePos["SkeldAdmin"]) <= UsableDistance;
if (Options.DisableSkeldCamera.GetBool()) doComms |= Vector2.Distance(PlayerPos, DevicePos["SkeldCamera"]) <= UsableDistance;
break;
case 1:
if (Options.DisableMiraHQAdmin.GetBool()) doComms |= Vector2.Distance(PlayerPos, DevicePos["MiraHQAdmin"]) <= UsableDistance;
if (Options.DisableMiraHQDoorLog.GetBool()) doComms |= Vector2.Distance(PlayerPos, DevicePos["MiraHQDoorLog"]) <= UsableDistance;
break;
case 2:
if (Options.DisablePolusAdmin.GetBool())
{
doComms |= Vector2.Distance(PlayerPos, DevicePos["PolusLeftAdmin"]) <= UsableDistance;
doComms |= Vector2.Distance(PlayerPos, DevicePos["PolusRightAdmin"]) <= UsableDistance;
}
if (Options.DisablePolusCamera.GetBool()) doComms |= Vector2.Distance(PlayerPos, DevicePos["PolusCamera"]) <= UsableDistance;
if (Options.DisablePolusVital.GetBool()) doComms |= Vector2.Distance(PlayerPos, DevicePos["PolusVital"]) <= UsableDistance;
break;
case 3:
if (Options.DisableSkeldAdmin.GetBool()) doComms |= Vector2.Distance(PlayerPos, DevicePos["DleksAdmin"]) <= UsableDistance;
if (Options.DisableSkeldCamera.GetBool()) doComms |= Vector2.Distance(PlayerPos, DevicePos["DleksCamera"]) <= UsableDistance;
break;
case 4:
if (Options.DisableAirshipCockpitAdmin.GetBool()) doComms |= Vector2.Distance(PlayerPos, DevicePos["AirshipCockpitAdmin"]) <= UsableDistance;
if (Options.DisableAirshipRecordsAdmin.GetBool()) doComms |= Vector2.Distance(PlayerPos, DevicePos["AirshipRecordsAdmin"]) <= UsableDistance;
if (Options.DisableAirshipCamera.GetBool()) doComms |= Vector2.Distance(PlayerPos, DevicePos["AirshipCamera"]) <= UsableDistance;
if (Options.DisableAirshipVital.GetBool()) doComms |= Vector2.Distance(PlayerPos, DevicePos["AirshipVital"]) <= UsableDistance;
break;
case 5:
if (Options.DisableFungleCamera.GetBool()) doComms |= Vector2.Distance(PlayerPos, DevicePos["FungleCamera"]) <= UsableDistance;
if (Options.DisableFungleVital.GetBool()) doComms |= Vector2.Distance(PlayerPos, DevicePos["FungleVital"]) <= UsableDistance;
break;
}
}
if (doComms && !pc.inVent)
{
if (!DesyncComms.Contains(pc.PlayerId))
{
DesyncComms.Add(pc.PlayerId);
SendDesyncRepair(pc, SystemTypes.Comms, 128);
}
}
else if (!doComms && DesyncComms.Contains(pc.PlayerId))
{
DesyncComms.Remove(pc.PlayerId);
SendDesyncRepair(pc, SystemTypes.Comms, 16);
if (Main.NormalOptions.MapId is 1 or 5) SendDesyncRepair(pc, SystemTypes.Comms, 17);
}
}
catch (Exception ex) { Logger.Exception(ex, "DisableDevice"); }
}
}
public static void SendDesyncRepair(PlayerControl target, SystemTypes systemType, byte amount)
{
if (!AmongUsClient.Instance.AmHost) return;
if (target == null || target.Data == null || target.Data.ClientId == AmongUsClient.Instance.HostId) return;
MessageWriter writer = AmongUsClient.Instance.StartRpcImmediately(
ShipStatus.Instance.NetId,
(byte)RpcCalls.UpdateSystem,
SendOption.Reliable,
target.Data.ClientId
);
writer.Write((byte)systemType);
writer.WritePacked(target.NetId);
writer.Write(amount);
AmongUsClient.Instance.FinishRpcImmediately(writer);
}
}
[HarmonyPatch(typeof(ShipStatus), nameof(ShipStatus.Start))]
public class RemoveDisableDevicesPatch
{
public static void Postfix()
{
if (!Options.DisableDevices.GetBool() || !AmongUsClient.Instance.AmHost) return;
UpdateDisableDevices();
}
public static void UpdateDisableDevices()
{
PlayerControl player = PlayerControl.LocalPlayer;
Il2CppArrayBase<MapConsole> admins = Object.FindObjectsOfType<MapConsole>(true);
Il2CppArrayBase<SystemConsole> consoles = Object.FindObjectsOfType<SystemConsole>(true);
if (admins == null || consoles == null) return;
switch (Main.NormalOptions.MapId)
{
case 3:
case 0:
if (Options.DisableSkeldAdmin.GetBool()) admins[0].gameObject.GetComponent<CircleCollider2D>().enabled = false;
if (Options.DisableSkeldCamera.GetBool()) consoles.DoIf(x => x.name == "SurvConsole", x => x.gameObject.GetComponent<PolygonCollider2D>().enabled = false);
break;
case 1:
if (Options.DisableMiraHQAdmin.GetBool()) admins[0].gameObject.GetComponent<CircleCollider2D>().enabled = false;
if (Options.DisableMiraHQDoorLog.GetBool()) consoles.DoIf(x => x.name == "SurvLogConsole", x => x.gameObject.GetComponent<BoxCollider2D>().enabled = false);
break;
case 2:
if (Options.DisablePolusAdmin.GetBool()) admins.Do(x => x.gameObject.GetComponent<BoxCollider2D>().enabled = false);
if (Options.DisablePolusCamera.GetBool()) consoles.DoIf(x => x.name == "Surv_Panel", x => x.gameObject.GetComponent<BoxCollider2D>().enabled = false);
if (Options.DisablePolusVital.GetBool()) consoles.DoIf(x => x.name == "panel_vitals", x => x.gameObject.GetComponent<BoxCollider2D>().enabled = false);
break;
case 4:
admins.Do(x =>
{
if ((Options.DisableAirshipCockpitAdmin.GetBool() && x.name == "panel_cockpit_map") ||
(Options.DisableAirshipRecordsAdmin.GetBool() && x.name == "records_admin_map"))
x.gameObject.GetComponent<BoxCollider2D>().enabled = false;
});
if (Options.DisableAirshipCamera.GetBool()) consoles.DoIf(x => x.name == "task_cams", x => x.gameObject.GetComponent<BoxCollider2D>().enabled = false);
if (Options.DisableAirshipVital.GetBool()) consoles.DoIf(x => x.name == "panel_vitals", x => x.gameObject.GetComponent<CircleCollider2D>().enabled = false);
break;
case 5:
if (Options.DisableFungleCamera.GetBool()) consoles.DoIf(x => x.name == "BinocularsSecurityConsole", x => x.gameObject.GetComponent<PolygonCollider2D>().enabled = false);
if (Options.DisableFungleVital.GetBool()) consoles.DoIf(x => x.name == "VitalsConsole", x => x.gameObject.GetComponent<BoxCollider2D>().enabled = false);
break;
}
}
}
+9 -4
View File
@@ -16,9 +16,14 @@ public class DiscordRPC
{
if (activity == null) return;
var details = $"AmongUsRevamped {Main.ModVersion}";
var details = $"Revamped {Main.ModVersion}";
activity.Details = details;
activity.Assets = new ActivityAssets
{
LargeImage = "https://i.imgur.com/ZnC1toT.png"
};
try
{
if (activity.State != "In Menus")
@@ -31,10 +36,10 @@ public class DiscordRPC
Region = Utils.GetRegionName();
}
if (Lobbycode != "" && Region != "") details = $"AmongUsRevamped - {Lobbycode} ({Region})";
if (Lobbycode != "" && Region != "") details = $"Revamped - {Lobbycode} ({Region})";
}
else
details = $"AmongUsRevamped {Main.ModVersion}";
details = $"Revamped {Main.ModVersion}";
activity.Details = details;
}
@@ -43,7 +48,7 @@ public class DiscordRPC
{
Logger.Error("Error in updating discord rpc", "DiscordPatch");
Logger.Exception(ex, "DiscordPatch");
details = $"AmongUsRevamped v{Main.ModVersion}";
details = $"Revamped v{Main.ModVersion}";
activity.Details = details;
}
}
+237
View File
@@ -0,0 +1,237 @@
using System;
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.SceneManagement;
namespace AmongUsRevamped;
class CreateOptionsPickerPatch
{
public static bool SetDleks = false;
public static bool SetDleks2;
private static bool InitiatedDleks;
private static bool isSkeldFlipped = false;
public static bool FlippedSkeld
{
get => isSkeldFlipped;
set
{
if (AmongUsClient.Instance == null || isSkeldFlipped == value) return;
AssetReference temp = AmongUsClient.Instance.ShipPrefabs[3];
AmongUsClient.Instance.ShipPrefabs[3] = AmongUsClient.Instance.ShipPrefabs[0];
AmongUsClient.Instance.ShipPrefabs[0] = temp;
isSkeldFlipped = value;
}
}
private static MapSelectButton DleksButton;
[HarmonyPatch]
public static class GameOptionsMapPickerPatch
{
[HarmonyPatch(typeof(GameOptionsMapPicker), nameof(GameOptionsMapPicker.SetupMapButtons))]
[HarmonyPostfix]
public static void Postfix_Initialize(CreateGameMapPicker __instance)
{
float delay;
if (SceneManager.GetActiveScene().name == "MainMenu" && InitiatedDleks)
{
delay = 0.2f;
}
else
{
delay = 0f;
InitiatedDleks = true;
}
if (SceneManager.GetActiveScene().name == "FindAGame") return;
new LateTask(() =>
{
int DleksPos = 3;
MapSelectButton[] AllMapButton = __instance.transform.GetComponentsInChildren<MapSelectButton>();
AllMapButton = AllMapButton.Where(x => x.gameObject.name != "DleksButton").ToArray();
if (AllMapButton != null)
{
GameObject dlekS_ehT = null;
if (!SetDleks2 || SceneManager.GetActiveScene().name != "MainMenu")
{
dlekS_ehT = UnityEngine.Object.Instantiate(AllMapButton[0].gameObject, __instance.transform);
dlekS_ehT.name = "DleksButton";
SetDleks2 = true;
}
else
{
dlekS_ehT = __instance.transform.Find("DleksButton")?.gameObject;
}
if (dlekS_ehT == null) return;
dlekS_ehT.name = "DleksButton";
dlekS_ehT.transform.position = AllMapButton[DleksPos].transform.position;
dlekS_ehT.transform.SetSiblingIndex(DleksPos + 2);
MapSelectButton dlekS_ehT_MapButton = dlekS_ehT.GetComponent<MapSelectButton>();
DleksButton = dlekS_ehT_MapButton;
foreach (var icon in dlekS_ehT_MapButton.MapIcon)
{
if (icon == null || icon.transform == null) continue;
icon.flipX = true;
}
dlekS_ehT_MapButton.Button.OnClick.RemoveAllListeners();
dlekS_ehT_MapButton.Button.OnClick.AddListener((UnityEngine.Events.UnityAction)(() =>
{
FlippedSkeld = true;
__instance.SelectMap(__instance.AllMapIcons[0]);
if (__instance.selectedButton)
{
__instance.selectedButton.Button.SelectButton(false);
}
__instance.selectedButton = dlekS_ehT_MapButton;
__instance.selectedButton.Button.SelectButton(true);
__instance.selectedMapId = 3;
if (!Utils.isHideNSeek)
Main.NormalOptions.MapId = 0;
else if (Utils.isHideNSeek)
Main.HideNSeekOptions.MapId = 0;
__instance.MapImage.sprite = Utils.LoadSprite($"AmongUsRevamped.Resources.Images.DleksBanner.png", 100f);
__instance.MapName.sprite = Utils.LoadSprite($"AmongUsRevamped.Resources.Images.DleksBanner-Wordart.png", 100f);
}));
for (int i = DleksPos; i < AllMapButton.Length; i++)
{
AllMapButton[i].transform.localPosition += new Vector3(0.625f, 0f, 0f);
}
if (DleksButton != null)
{
if (SetDleks)
{
if (__instance.selectedButton)
{
__instance.selectedButton.Button.SelectButton(false);
}
DleksButton.Button.SelectButton(true);
__instance.selectedButton = DleksButton;
__instance.selectedMapId = 3;
__instance.MapImage.sprite = Utils.LoadSprite($"AmongUsRevamped.Resources.Images.DleksBanner.png", 100f);
__instance.MapName.sprite = Utils.LoadSprite($"AmongUsRevamped.Resources.Images.DleksBanner-Wordart.png", 100f);
}
else
{
DleksButton.Button.SelectButton(false);
}
}
}
}, delay, "ApplyDleks");
}
[HarmonyPatch(typeof(GameOptionsMapPicker), nameof(GameOptionsMapPicker.FixedUpdate))]
[HarmonyPrefix]
public static bool Prefix_FixedUpdate(GameOptionsMapPicker __instance)
{
if (__instance == null) return true;
if (__instance.MapName == null) return false;
FlippedSkeld = (__instance.selectedMapId == 3);
if (DleksButton != null) SetDleks = __instance.selectedMapId == 3;
if (__instance.selectedMapId == 3)
{
if (SceneManager.GetActiveScene().name == "FindAGame")
{
__instance.SelectMap(0);
SetDleks = false;
}
return false;
}
return true;
}
}
[HarmonyPatch(typeof(CreateOptionsPicker), nameof(CreateOptionsPicker.Awake))]
class MenuMapPickerPatch
{
public static void Postfix(CreateOptionsPicker __instance)
{
Transform mapPickerTransform = __instance.transform.Find("MapPicker");
MapPickerMenu mapPickerMenu = mapPickerTransform.Find("Map Picker Menu").GetComponent<MapPickerMenu>();
MapFilterButton airhipIconInMenu = __instance.MapMenu.MapButtons[3];
MapFilterButton fungleIconInMenu = __instance.MapMenu.MapButtons[4];
MapFilterButton skeldIconInMenu = __instance.MapMenu.MapButtons[0];
MapFilterButton dleksIconInMenuCopy = UnityEngine.Object.Instantiate(airhipIconInMenu, airhipIconInMenu.transform.parent);
Transform skeldMenuButton = mapPickerMenu.transform.Find("Skeld");
Transform polusMenuButton = mapPickerMenu.transform.Find("Polus");
Transform airshipMenuButton = mapPickerMenu.transform.Find("Airship");
Transform fungleMenuButton = mapPickerMenu.transform.Find("Fungle");
Transform dleksMenuButtonCopy = UnityEngine.Object.Instantiate(airshipMenuButton, airshipMenuButton.parent);
// Set mapid for Dleks button
PassiveButton dleksButton = dleksMenuButtonCopy.GetComponent<PassiveButton>();
dleksButton.OnClick.m_PersistentCalls.m_Calls._items[0].arguments.intArgument = (int)MapNames.Dleks;
SpriteRenderer dleksImage = dleksMenuButtonCopy.Find("Image").GetComponent<SpriteRenderer>();
dleksImage.sprite = skeldMenuButton.Find("Image").GetComponent<SpriteRenderer>().sprite;
dleksIconInMenuCopy.name = "Dleks";
dleksIconInMenuCopy.transform.localPosition = new Vector3(0.8f, airhipIconInMenu.transform.localPosition.y, airhipIconInMenu.transform.localPosition.z);
dleksIconInMenuCopy.MapId = MapNames.Dleks;
dleksIconInMenuCopy.Button = dleksButton;
dleksIconInMenuCopy.ButtonCheck = dleksMenuButtonCopy.Find("selectedCheck").GetComponent<SpriteRenderer>();
dleksIconInMenuCopy.ButtonImage = dleksImage;
dleksIconInMenuCopy.ButtonOutline = dleksImage.transform.parent.GetComponent<SpriteRenderer>();
dleksIconInMenuCopy.Icon.sprite = skeldIconInMenu.Icon.sprite;
dleksMenuButtonCopy.name = "Dleks";
dleksMenuButtonCopy.position = new Vector3(dleksMenuButtonCopy.position.x, 2f * dleksMenuButtonCopy.position.y - polusMenuButton.transform.position.y, dleksMenuButtonCopy.position.z);
fungleMenuButton.position = new Vector3(fungleMenuButton.position.x, dleksMenuButtonCopy.transform.position.y - 0.6f, fungleMenuButton.position.z);
__instance.MapMenu.MapButtons = HarmonyLib.CollectionExtensions.AddItem(__instance.MapMenu.MapButtons, dleksIconInMenuCopy).ToArray();
float xPos = -1f;
for (int index = 0; index < 6; ++index)
{
__instance.MapMenu.MapButtons[index].transform.SetLocalX(xPos);
xPos += 0.34f;
}
if (__instance.mode == SettingsMode.Host)
{
mapPickerMenu.transform.localPosition = new Vector3(mapPickerMenu.transform.localPosition.x, 0.85f, mapPickerMenu.transform.localPosition.z);
mapPickerTransform.localScale = new Vector3(0.86f, 0.85f, 1f);
mapPickerTransform.transform.localPosition = new Vector3(mapPickerTransform.transform.localPosition.x + 0.05f, mapPickerTransform.transform.localPosition.y + 0.03f, mapPickerTransform.transform.localPosition.z);
}
SwapIconOrButtomsPositions(airhipIconInMenu, dleksIconInMenuCopy);
SwapIconOrButtomsPositions(fungleIconInMenu, airhipIconInMenu);
SwapIconOrButtomsPositions(airshipMenuButton, dleksMenuButtonCopy);
__instance.MapMenu.MapButtons[5].SetFlipped(true);
mapPickerMenu.transform.Find("Backdrop").localScale *= 5;
}
private static void SwapIconOrButtomsPositions(Component one, Component two)
{
Transform transform1 = one.transform;
Transform transform2 = two.transform;
Vector3 position1 = two.transform.position;
Vector3 position2 = one.transform.position;
transform1.position = position1;
transform2.position = position2;
}
}
}
+51 -17
View File
@@ -10,6 +10,7 @@ public static class EndGameManagerPatch
{
public static void Postfix(EndGameManager __instance)
{
Logger.Info(" -------- GAME ENDED --------", "EndGame");
Utils.ClearLeftoverData();
EndGameNavigation navigation = __instance.Navigation;
@@ -28,7 +29,7 @@ class NormalGameEndChecker
public static bool Prefix()
{
if (Options.NoGameEnd.GetBool() || Options.Gamemode.GetValue() == 3) return false;
if (Options.NoGameEnd.GetBool() || Options.Gamemode.GetValue() == 3 || Utils.HandlingGameEnd) return false;
var allPlayers = PlayerControl.AllPlayerControls.ToArray();
@@ -38,25 +39,58 @@ class NormalGameEndChecker
ImpCheckComplete = true;
}
if (Utils.AliveImpostors == 0)
CheckWinnerText("");
return true;
}
public static bool canUpdateWinnerText;
public static string customRoles { get; set; }
public static void CheckWinnerText(string Winner)
{
var impostorList = string.Join(", ", imps.Select(p => p.Data.PlayerName));
if (!canUpdateWinnerText) return;
if (Winner == "Jester")
{
LastWinReason = $"★ Crewmates win!\n\nImpostors:\n" + string.Join("\n", imps.Select(p => p.Data.PlayerName));
}
else if (Utils.AliveImpostors >= Utils.AliveCrewmates)
{
LastWinReason = $"★ Impostors win!\n\nImpostors:\n★" + string.Join("\n★", imps.Select(p => p.Data.PlayerName));
}
else if (GameData.Instance != null && GameData.Instance.TotalTasks > 0 && GameData.Instance.CompletedTasks >= GameData.Instance.TotalTasks)
{
LastWinReason = $"★ Crewmates win! (Tasks)\n\nImpostors:\n" + string.Join("\n", imps.Select(p => p.Data.PlayerName));
}
else if (Options.Gamemode.GetValue() < 2)
{
LastWinReason = $"★ Impostors win! (Sabotage)\n\nImpostors:\n★" + string.Join("\n★", imps.Select(p => p.Data.PlayerName));
LastWinReason = $"Jester wins! (Voted)\n\nImpostors: {impostorList}";
canUpdateWinnerText = false;
return;
}
Logger.Info(" -------- GAME ENDED --------", "EndGame");
return true;
if (Winner == "Juggernaut")
{
LastWinReason = $"Impostors win! (Juggernaut killed {Options.KillsNeededForJuggernaut.GetInt()} players)\n\nImpostor: {impostorList}";
canUpdateWinnerText = false;
return;
}
if (Winner == "Speedrunner")
{
LastWinReason = $"Crewmates win! (Speedrunner finished tasks)\n\nImpostor: {impostorList}";
canUpdateWinnerText = false;
return;
}
if (Utils.AliveImpostors == 0 || Winner == "Crewmate")
{
LastWinReason = $"Crewmates win!\n\nImpostors: {impostorList}";
canUpdateWinnerText = false;
}
else if (Utils.AliveImpostors >= Utils.AliveCrewmates || Winner == "Impostor")
{
LastWinReason = $"Impostors win!\n\nImpostor: {impostorList}";
canUpdateWinnerText = false;
}
else if (GameData.Instance != null && GameData.Instance.TotalTasks > 0 && GameData.Instance.CompletedTasks >= GameData.Instance.TotalTasks || Winner == "CrewmateTasks")
{
LastWinReason = $"Crewmates win! ({Options.TaskPercentNeededToWin.GetInt()}% Tasks)\n\nImpostors: {impostorList}";
canUpdateWinnerText = false;
}
else if (Options.Gamemode.GetValue() < 2 || Winner == "ImpostorSabotage")
{
LastWinReason = $"Impostors win! (Sabotage)\n\nImpostors: {impostorList}" + (string.IsNullOrEmpty(customRoles) ? "" : "\n\n" + customRoles);
}
}
}
+74
View File
@@ -0,0 +1,74 @@
using System.Reflection;
using Il2CppInterop.Runtime.InteropTypes;
namespace AmongUsRevamped;
[HarmonyPatch]
class ExileControllerWrapUpPatch
{
public static MethodBase TargetMethod()
{
return AccessTools.Method(typeof(ExileController), nameof(ExileController.WrapUp));
}
public static void Postfix(ExileController __instance)
{
AfterExile(__instance.initData.networkedPlayer);
}
public static void AfterExile(NetworkedPlayerInfo ejectedPlayer)
{
if (!AmongUsClient.Instance.AmHost) return;
if (ejectedPlayer == null) return;
PlayerControl pc = null;
PlayerControl exiledPlayer = ejectedPlayer.Object;
foreach (var p in PlayerControl.AllPlayerControls)
{
if (p.PlayerId == ejectedPlayer.PlayerId)
{
pc = p;
}
if (ejectedPlayer == PlayerControl.LocalPlayer.Data && !Main.DisableInfoWhenDead.Value)
{
if (p.Data.Role.IsImpostor)
{
p.cosmetics.nameText.text = $"{p.Data.PlayerName}<color=red><size=90%>({MurderPlayerPatch.killCount[p.Data.PlayerId]}†)";
}
else
{
if (!PlayerControlCompleteTaskPatch.playerTasksCompleted.ContainsKey(p))
{
PlayerControlCompleteTaskPatch.playerTasksCompleted[p] = 0;
}
p.cosmetics.nameText.text = $"{p.Data.PlayerName}<color=green><size=90%>({PlayerControlCompleteTaskPatch.playerTasksCompleted[p]}/{PlayerControlCompleteTaskPatch.tasksPerPlayer[p]})";
}
}
}
Logger.Info($" {ejectedPlayer.PlayerName} was ejected", "ExileController");
if (PlayerControlSetRolePatch.Jesters.Contains(exiledPlayer))
{
Logger.Info($"Jester {ejectedPlayer.PlayerName} wins", "ExilePatch");
Utils.CustomWinnerEndGame(exiledPlayer, 1);
NormalGameEndChecker.CheckWinnerText("Jester");
return;
}
}
[HarmonyPatch]
class AirshipExileControllerPatch
{
public static MethodBase TargetMethod()
{
return Utils.GetStateMachineMoveNext<AirshipExileController>(nameof(AirshipExileController.WrapUpAndSpawn));
}
public static void Postfix(AirshipExileController._WrapUpAndSpawn_d__11 __instance)
{
ExileControllerWrapUpPatch.AfterExile(__instance.__4__this.initData.networkedPlayer);
}
}
}
+5 -2
View File
@@ -1,8 +1,11 @@
using System;
using Il2CppSystem.Collections.Generic;
using UnityEngine;
using Object = UnityEngine.Object;
#if ANDROID
using System.Collections.Generic;
#else
using Il2CppSystem.Collections.Generic;
#endif
// https://github.com/Yumenopai/TownOfHost_Y/blob/main/Patches/GameOptionsPatch.cs
namespace AmongUsRevamped
+11 -4
View File
@@ -1,7 +1,6 @@
using System;
using TMPro;
using UnityEngine;
using Object = UnityEngine.Object;
// https://github.com/Yumenopai/TownOfHost_Y/blob/main/Patches/GameSettingMenuPatch.cs
namespace AmongUsRevamped
@@ -114,13 +113,21 @@ namespace AmongUsRevamped
switch ((TabGroup)(tabNum - 3))
{
case TabGroup.SystemSettings:
__instance.MenuDescriptionText.text = "Quality settings to improve comfort and testing";
__instance.MenuDescriptionText.text = "Quality settings to improve comfort and testing.";
break;
/*
case TabGroup.CustomRoleSettings:
__instance.MenuDescriptionText.text = "Custom Role enabling and settings.";
break;
*/
case TabGroup.AbilitySettings:
__instance.MenuDescriptionText.text = "Ability settings to enhance vanilla roles.";
break;
case TabGroup.ModSettings:
__instance.MenuDescriptionText.text = "Gameplay Settings to improve the in-game experience";
__instance.MenuDescriptionText.text = "Gameplay settings to improve the in-game experience.";
break;
case TabGroup.GamemodeSettings:
__instance.MenuDescriptionText.text = "Situational settings to apply for specific gamemodes";
__instance.MenuDescriptionText.text = "Situational settings to apply for specific gamemodes.";
break;
}
}
+57 -34
View File
@@ -9,27 +9,35 @@ public static class GameStartManagerUpdatePatch
{
public static bool CustomTimerApplied;
public static bool Autostarting;
public static bool CountingDown;
public static void Prefix(GameStartManager __instance)
{
if (!AmongUsClient.Instance.AmHost || AmongUsClient.Instance == null) return;
if (__instance == null || MeetingHud.Instance != null) return;
if (AmongUsClient.Instance == null || !AmongUsClient.Instance.AmHost) return;
if (__instance.StartButton == null || __instance.GameStartText == null) return;
__instance.MinPlayers = 1;
if (Main.AutoStart.Value && OnGameJoinedPatch.AutoStartCheck && GameStartManager.InstanceExists && GameStartManager.Instance.startState != GameStartManager.StartingStates.Countdown && GameData.Instance?.PlayerCount >= Options.PlayerAutoStart.GetInt())
if (Main.AutoStart.Value && OnGameJoinedPatch.AutoStartCheck && GameStartManager.InstanceExists && __instance.startState != GameStartManager.StartingStates.Countdown && GameData.Instance?.PlayerCount >= Options.PlayerAutoStart.GetInt())
{
GameStartManager.Instance.startState = GameStartManager.StartingStates.Countdown;
GameStartManager.Instance.countDownTimer = Options.AutoStartTimer.GetFloat();
GameStartManager.Instance?.StartButton.gameObject.SetActive(false);
__instance.startState = GameStartManager.StartingStates.Countdown;
__instance.countDownTimer = Options.AutoStartTimer.GetFloat();
__instance.StartButton.gameObject.SetActive(false);
Autostarting = true;
}
if (__instance.startState == GameStartManager.StartingStates.Countdown && !CustomTimerApplied && !Autostarting)
if (__instance.startState == GameStartManager.StartingStates.Countdown)
{
__instance.countDownTimer = Options.StartCountdown.GetInt();
CustomTimerApplied = true;
CountingDown = true;
if (!CustomTimerApplied && !Autostarting)
{
__instance.countDownTimer = Options.StartCountdown.GetInt();
CustomTimerApplied = true;
}
}
else CountingDown = false;
if (__instance.startState != GameStartManager.StartingStates.Countdown)
{
@@ -37,24 +45,38 @@ public static class GameStartManagerUpdatePatch
CustomTimerApplied = false;
}
}
public static void Postfix(GameStartManager __instance)
{
string warningMessage = "";
if (!AmongUsClient.Instance.AmHost) return;
if (__instance == null || MeetingHud.Instance != null) return;
if (AmongUsClient.Instance == null || !AmongUsClient.Instance.AmHost) return;
if (warningMessage == "")
if (__instance.StartButton == null || __instance.GameStartText == null) return;
if (GameStartManagerStartPatch.warningText != null)
{
GameStartManagerStartPatch.warningText.gameObject.SetActive(false);
}
else
{
GameStartManagerStartPatch.warningText.text = warningMessage;
GameStartManagerStartPatch.warningText.gameObject.SetActive(true);
if (warningMessage == "")
{
GameStartManagerStartPatch.warningText.gameObject.SetActive(false);
}
else
{
GameStartManagerStartPatch.warningText.text = warningMessage;
GameStartManagerStartPatch.warningText.gameObject.SetActive(true);
}
}
__instance.GameStartText.transform.localPosition = new Vector3(__instance.GameStartText.transform.localPosition.x, 2f, __instance.GameStartText.transform.localPosition.z);
GameStartManagerStartPatch.cancelButton.gameObject.SetActive(__instance.startState == GameStartManager.StartingStates.Countdown);
if (__instance.GameStartText != null)
{
__instance.GameStartText.transform.localPosition = new Vector3(__instance.GameStartText.transform.localPosition.x, 2f, __instance.GameStartText.transform.localPosition.z);
}
if (GameStartManagerStartPatch.cancelButton != null)
{
GameStartManagerStartPatch.cancelButton.gameObject.SetActive(__instance.startState == GameStartManager.StartingStates.Countdown);
}
}
}
@@ -62,40 +84,41 @@ public static class GameStartManagerUpdatePatch
public class GameStartManagerStartPatch
{
public static TextMeshPro warningText;
private static Vector3 GameStartTextlocalPosition;
public static PassiveButton cancelButton;
public static void Postfix(GameStartManager __instance)
{
if (__instance == null || !Utils.IsLobby) return;
warningText = UnityEngine.Object.Instantiate(__instance.GameStartText, __instance.transform.parent);
warningText.name = "WarningText";
warningText.transform.localPosition = new(0f, __instance.transform.localPosition.y + 3f, -1f);
warningText.transform.localPosition = new Vector3(0f, __instance.transform.localPosition.y + 3f, -1f);
warningText.gameObject.SetActive(false);
cancelButton = UnityEngine.Object.Instantiate(__instance.StartButton, __instance.transform);
cancelButton.name = "CancelButton";
var cancelLabel = cancelButton.buttonText;
cancelLabel.DestroyTranslator();
cancelLabel.text = "Cancel";
//cancelButton.transform.localScale = new(0.5f, 0.5f, 1f);
var cancelButtonInactiveRenderer = cancelButton.inactiveSprites.GetComponent<SpriteRenderer>();
cancelButtonInactiveRenderer.color = new(0.8f, 0f, 0f, 1f);
var cancelButtonActiveRenderer = cancelButton.activeSprites.GetComponent<SpriteRenderer>();
cancelButtonActiveRenderer.color = Color.red;
var cancelButtonInactiveShine = cancelButton.inactiveSprites.transform.Find("Shine");
if (cancelButtonInactiveShine)
{
cancelButtonInactiveShine.gameObject.SetActive(false);
}
cancelButton.activeTextColor = cancelButton.inactiveTextColor = Color.white;
//cancelButton.transform.localPosition = new(2f, 0.13f, 0f);
GameStartTextlocalPosition = __instance.GameStartText.transform.localPosition;
cancelButton.gameObject.SetActive(false);
cancelButton.OnClick = new();
cancelButton.OnClick.AddListener((UnityEngine.Events.UnityAction)(() =>
{
__instance.ResetStartState();
}));
cancelButton.gameObject.SetActive(false);
}
}
[HarmonyPatch(typeof(GameStartManager), nameof(GameStartManager.BeginGame))]
public class GameStartManagerBeginGamePatch
{
public static void Prefix(GameStartManager __instance)
{
if (Options.NoGameEnd.GetBool()) Logger.SendInGame(Translator.Get("noGameEndWarning"));
}
}
+67
View File
@@ -0,0 +1,67 @@
using AmongUs.GameOptions;
using Hazel;
using InnerNet;
using System;
using UnityEngine;
namespace AmongUsRevamped;
[HarmonyPatch(typeof(HudManager), nameof(HudManager.CoShowIntro))]
internal static class CoShowIntroPatch
{
public static void Postfix(IntroCutscene __instance)
{
Logger.Info(" Intro initiated", "CoShowIntro");
if (!AmongUsClient.Instance.AmHost) return;
//Utils.ModeratorChatCommand(Translator.Get("abilitiesGenericOne", Options.CrewmateAbility.GetString(), Options.ScientistAbility.GetString(), Options.EngineerAbility.GetString(), Options.NoisemakerAbility.GetString(), Options.TrackerAbility.GetString()), Translator.Get("abilitiesGenericTwo", Options.DetectiveAbility.GetString(), Options.ImpostorAbility.GetString(), Options.ShapeshifterAbility.GetString(), Options.PhantomAbility.GetString(), Options.ViperAbility.GetString()), true);
foreach (var p in PlayerControl.AllPlayerControls)
{
p.cosmetics.nameText.text = p.Data.PlayerName;
MurderPlayerPatch.killCount[p.Data.PlayerId] = 0;
MurderPlayerPatch.misfireCount[p.Data.PlayerId] = 0;
PlayerControlCompleteTaskPatch.playerTasksCompleted[p] = 0;
PlayerControlCompleteTaskPatch.tasksPerPlayer[p] = 0;
Logger.Info($" {p.Data.PlayerName} -> {p.Data.RoleType}", "RoleInfo");
}
Logger.Info($" {AbilityManagement.RoleList()}", "AbilityInfo");
if (Options.DisableAnnoyingMeetingCalls.GetBool() && !Utils.isHideNSeek)
{
Utils.CanCallMeetings = false;
_ = new LateTask(() =>
{
Utils.CanCallMeetings = true;
}, 33f, "MeetingEnabled");
}
if (Options.Gamemode.GetValue() == 2 && Options.SNSChatInGame.GetBool() /*|| Options.Gamemode.GetValue() == 0 && Options.ChatBeforeFirstMeeting.GetBool()*/)
{
_ = new LateTask(() =>
{
PlayerControl.LocalPlayer.CmdReportDeadBody(null);
if (MeetingHud.Instance != null) MeetingHud.Instance.RpcClose();
}, 9f, "SetChatVisible");
}
}
}
[HarmonyPatch(typeof(IntroCutscene), nameof(IntroCutscene.BeginCrewmate))]
class BeginCrewmatePatch
{
public static void Postfix(IntroCutscene __instance)
{
if (!AmongUsClient.Instance.AmHost) return;
if (Main.GM.Value)
{
__instance.TeamTitle.text = "Game Master";
}
}
}
+36 -10
View File
@@ -14,6 +14,8 @@ internal static class OnGameJoinedPatch
public static bool AutoStartCheck;
public static void Postfix()
{
Logger.Info(" -------- JOINED GAME --------", "OnGameJoined");
if (!AmongUsClient.Instance.AmHost) return;
WaitingForChat = false;
@@ -77,13 +79,8 @@ class OnPlayerJoinedPatch
if (AmongUsClient.Instance.AmHost)
{
BanManager.CheckBanPlayer(Client);
Utils.IsPlayerInDenyName(Client, Client.PlayerName);
if (Utils.IsPlayerModerator(Client.FriendCode) && Options.ApplyModeratorList.GetBool())
{
Logger.Info($" {Client.PlayerName} is moderator", "ModeratorCheck");
}
BanManager.IsPlayerInDenyName(Client, Client.PlayerName);
Logger.Info($" {Client.PlayerName} has access level {Utils.CheckAccessLevel(Client.FriendCode)}", "AccessCheck");
if (HasInvalidFriendCode(Client.FriendCode) && Options.KickInvalidFriendCodes.GetBool())
{
@@ -107,9 +104,38 @@ class OnPlayerJoinedPatch
[HarmonyPatch(typeof(AmongUsClient), nameof(AmongUsClient.OnPlayerLeft))]
class OnPlayerLeftPatch
{
static void Prefix([HarmonyArgument(0)] ClientData client)
static void Postfix([HarmonyArgument(0)] ClientData client)
{
if (client?.Character == null) return;
FixedUpdateInGamePatch.ProcessedModerators.Remove(client.Character.PlayerId);
if (!AmongUsClient.Instance.AmHost || !Utils.InGame) return;
{
PlayerControlCompleteTaskPatch.CalculateTaskWin();
}
}
}
[HarmonyPatch(typeof(PlayerControl), nameof(PlayerControl.SetLevel))]
public static class SetLevelPatch
{
public static List<PlayerControl> HandledLevelKicks = [];
public static void Prefix(PlayerControl __instance, uint level)
{
if (AmongUsClient.Instance.AmHost && level < Options.KickLowLevelPlayer.GetInt() - 1 && __instance.Data.ClientId != AmongUsClient.Instance.HostId)
{
if (HandledLevelKicks.Contains(__instance)) return;
if (!Options.TempBanLowLevelPlayer.GetBool())
{
AmongUsClient.Instance.KickPlayer(__instance.Data.ClientId, false);
Logger.Info($" {__instance.Data.PlayerName} was kicked for being under level {Options.KickLowLevelPlayer.GetInt()}", "KickLowLevelPlayer");
Logger.SendInGame($" {__instance.Data.PlayerName} was kicked for being under level {Options.KickLowLevelPlayer.GetInt()}");
}
else
{
AmongUsClient.Instance.KickPlayer(__instance.Data.ClientId, true);
Logger.Info($" {__instance.Data.PlayerName} was banned for being under level {Options.KickLowLevelPlayer.GetInt()} ", "BanLowLevelPlayer");
Logger.SendInGame($" {__instance.Data.PlayerName} was banned for being under level {Options.KickLowLevelPlayer.GetInt()}");
}
HandledLevelKicks.Add(__instance);
}
}
}
+31 -1
View File
@@ -1,4 +1,5 @@
using InnerNet;
using Il2CppSystem.Collections;
using InnerNet;
using System;
using UnityEngine;
@@ -25,4 +26,33 @@ internal static class LobbyBehaviourUpdatePatch
SoundManager.Instance.CrossFadeSound("MapTheme", __instance.MapTheme, 0.5f);
}
}
}
[HarmonyPatch(typeof(LobbyBehaviour), nameof(LobbyBehaviour.Start))]
public class LobbyStartPatch
{
private static GameObject LobbyPaintObject;
private static Sprite LobbyPaintSprite;
public static void Prefix()
{
LobbyPaintSprite = Utils.LoadSprite("AmongUsRevamped.Resources.Images.doger.png", 290f);
}
public static void Postfix(LobbyBehaviour __instance)
{
_ = new LateTask(() =>
{
var LeftBox = GameObject.Find("Leftbox");
if (LeftBox != null)
{
LobbyPaintObject = UnityEngine.Object.Instantiate(LeftBox, LeftBox.transform.parent);
LobbyPaintObject.name = "Lobby Paint";
LobbyPaintObject.transform.localPosition = new Vector3(0.042f, -2.59f, -10.5f);
SpriteRenderer renderer = LobbyPaintObject.GetComponent<SpriteRenderer>();
renderer.sprite = LobbyPaintSprite;
}
}, 0.25f, "Co Load Dropship Decorations");
}
}
-2
View File
@@ -2,8 +2,6 @@ using System;
using TMPro;
using UnityEngine;
using Object = UnityEngine.Object;
// https://github.com/Rabek009/MoreGamemodes/blob/master/Patches/LobbyViewSettingsPatch.cs
namespace AmongUsRevamped
{
+117
View File
@@ -0,0 +1,117 @@
using UnityEngine;
namespace AmongUsRevamped;
[HarmonyPatch(typeof(MeetingHud), nameof(MeetingHud.CheckForEndVoting))]
public static class CheckForEndVotingPatch
{
public static bool Prefix(MeetingHud __instance)
{
if (!AmongUsClient.Instance.AmHost) return true;
if (!__instance.playerStates.All(ps => ps.AmDead || ps.DidVote)) return true;
var votes = __instance.CalculateVotes();
var visualVotes = new List<MeetingHud.VoterState>();
foreach (var ps in __instance.playerStates)
{
if (ps == null) continue;
byte voterId = ps.TargetPlayerId;
byte votedFor = ps.VotedFor;
PlayerControl pc = GameData.Instance.GetPlayerById(voterId)?.Object;
if (pc == null) continue;
if (votedFor == byte.MaxValue) continue;
if (!votes.ContainsKey(votedFor)) votes[votedFor] = 0;
visualVotes.Add(new MeetingHud.VoterState { VoterId = voterId, VotedForId = votedFor });
if (!PlayerControlCompleteTaskPatch.playerTasksCompleted.ContainsKey(pc)) PlayerControlCompleteTaskPatch.playerTasksCompleted[pc] = 0;
if (!MurderPlayerPatch.killCount.ContainsKey(voterId)) MurderPlayerPatch.killCount[voterId] = 0;
int extraVotes = 0;
int extraVotesCrewmate = Options.ExtraVotesCrewmate.GetInt();
int extraVotesImpostor = Options.ExtraVotesImpostor.GetInt();
int extraVotesPerTask = (int)(Options.ExtraVotesPerTask.GetFloat()*PlayerControlCompleteTaskPatch.playerTasksCompleted[pc]+0.1f);
int extraVotesPerKill = (int)(Options.ExtraVotesPerKill.GetFloat()*MurderPlayerPatch.killCount[voterId]+0.1f);
if (!votes.TryGetValue(votedFor, out int currentVotes)) currentVotes = 0;
if (AbilityManagement.IsMayor(pc)) extraVotes += extraVotesCrewmate;
if (AbilityManagement.IsTyrant(pc)) extraVotes += extraVotesImpostor;
if (AbilityManagement.IsWorkhorse(pc)) extraVotes += extraVotesPerTask;
if (AbilityManagement.IsStealer(pc)) extraVotes += extraVotesPerKill;
for (int i = 0; i < extraVotes; i++)
{
visualVotes.Add(new MeetingHud.VoterState { VoterId = voterId, VotedForId = votedFor });
votes[votedFor]++;
}
}
var max = votes.MaxPair(out var tie);
var exiled = GameData.Instance.AllPlayers.ToArray().FirstOrDefault(p => !tie && p.PlayerId == max.Key);
var statesArray = visualVotes.ToArray();
__instance.RpcVotingComplete(statesArray, exiled, tie);
return false;
}
}
[HarmonyPatch(typeof(MeetingHud), nameof(MeetingHud.Start))]
class MeetingHudStartPatch
{
public static void Postfix(MeetingHud __instance)
{
if (!AmongUsClient.Instance.AmHost) return;
foreach (var playerState in __instance.playerStates)
{
PlayerControl player = null;
foreach (var pc in PlayerControl.AllPlayerControls)
{
if (pc.PlayerId == playerState.TargetPlayerId)
{
player = pc;
break;
}
}
if (player == null || !PlayerControl.LocalPlayer.Data.IsDead || Main.DisableInfoWhenDead.Value) continue;
var textTemplate = playerState.NameText;
var taskText = GetProgressText(player);
var taskTextMeeting = UnityEngine.Object.Instantiate(textTemplate);
taskTextMeeting.transform.SetParent(textTemplate.transform);
taskTextMeeting.transform.localPosition = new Vector3(0f, 0.18f, 0f);
taskTextMeeting.fontSize = 1.6f;
taskTextMeeting.text = taskText;
taskTextMeeting.gameObject.name = "TaskTextMeeting";
taskTextMeeting.enableWordWrapping = false;
taskTextMeeting.enabled = player.AmOwner || player.PlayerId == playerState.TargetPlayerId;
}
}
public static string GetProgressText(PlayerControl player)
{
int totalTasks = 0;
int tasksCompleted = 0;
if (player.Data.Tasks != null && !player.Data.Role.IsImpostor)
{
foreach (var task in player.Data.Tasks)
{
totalTasks++;
if (task.Complete) tasksCompleted++;
}
return $"<color=green>({tasksCompleted}/{totalTasks})</color>";
}
else
{
return $"<color=red>({MurderPlayerPatch.killCount[player.Data.PlayerId]}†)</color>";
}
}
}
+85 -20
View File
@@ -1,25 +1,44 @@
using AmongUs.GameOptions;
using UnityEngine;
namespace AmongUsRevamped;
// https://github.com/astra1dev/AUnlocker/blob/main/src/OptionsPatches.cs
[HarmonyPatch(typeof(NumberOption), nameof(NumberOption.Increase))]
public static class NumberOption_Increase
{
public static bool Prefix(NumberOption __instance)
{
if (ModGameOptionsMenu.TabIndex >= 3) return true;
#if ANDROID
float increment = __instance.Increment;
#else
float increment = Hotkeys.IncrementMultiplier * __instance.Increment;
#endif
if (Utils.isHideNSeek || !Utils.isHideNSeek && __instance.Title != StringNames.GameNumImpostors && __instance.Title != StringNames.GamePlayerSpeed)
if (Utils.IsLobby)
{
__instance.Value += __instance.Increment;
__instance.UpdateValue();
__instance.OnValueChanged.Invoke(__instance);
__instance.AdjustButtonsActiveState();
return false;
if (__instance.Value <= __instance.ValidRange.min)
{
return true;
}
if (__instance.Value + increment > __instance.ValidRange.max)
{
__instance.Value = __instance.ValidRange.max;
__instance.UpdateValue();
__instance.OnValueChanged.Invoke(__instance);
return false;
}
else
{
__instance.Value += increment;
__instance.UpdateValue();
__instance.OnValueChanged.Invoke(__instance);
return false;
}
}
else return true;
return true;
}
}
@@ -28,17 +47,36 @@ public static class NumberOption_Decrease
{
public static bool Prefix(NumberOption __instance)
{
if (ModGameOptionsMenu.TabIndex >= 3) return true;
#if ANDROID
float increment = __instance.Increment;
#else
float increment = Hotkeys.IncrementMultiplier * __instance.Increment;
#endif
if (Utils.isHideNSeek || !Utils.isHideNSeek && __instance.Title != StringNames.GameNumImpostors && __instance.Title != StringNames.GamePlayerSpeed)
if (Utils.IsLobby)
{
__instance.Value -= __instance.Increment;
__instance.UpdateValue();
__instance.OnValueChanged.Invoke(__instance);
__instance.AdjustButtonsActiveState();
return false;
if (__instance.Value >= __instance.ValidRange.max)
{
return true;
}
if (__instance.Value - increment < __instance.ValidRange.min)
{
__instance.Value = __instance.ValidRange.min;
__instance.UpdateValue();
__instance.OnValueChanged.Invoke(__instance);
return false;
}
else
{
__instance.Value -= increment;
__instance.UpdateValue();
__instance.OnValueChanged.Invoke(__instance);
return false;
}
}
else return true;
return true;
}
}
@@ -49,9 +87,36 @@ public static class NumberOption_Initialize
{
if (ModGameOptionsMenu.TabIndex >= 3) return;
if (Utils.isHideNSeek || !Utils.isHideNSeek && __instance.Title != StringNames.GameNumImpostors && __instance.Title != StringNames.GamePlayerSpeed)
if (Utils.isHideNSeek || Utils.IsLobby && !Utils.isHideNSeek && __instance.Title != StringNames.GameNumImpostors && __instance.Title != StringNames.GamePlayerSpeed)
{
__instance.ValidRange = new FloatRange(-900f, 900f);
__instance.ValidRange = new FloatRange(0f, 900f);
}
switch (__instance.Title)
{
case StringNames.GameVotingTime:
case StringNames.GameDiscussTime:
case StringNames.EscapeTime:
case StringNames.FinalEscapeTime:
__instance.Increment = 5f;
break;
case StringNames.GameKillCooldown:
__instance.Increment = 0.5f;
break;
case StringNames.GamePlayerSpeed:
case StringNames.SeekerFinalSpeed:
case StringNames.GameCrewLight:
case StringNames.GameImpostorLight:
case StringNames.CrewmateFlashlightSize:
case StringNames.ImpostorFlashlightSize:
__instance.Increment = 0.05f;
break;
default:
__instance.Increment = 1f;
break;
}
}
}
}
+81 -65
View File
@@ -1,95 +1,111 @@
using System;
using AmongUs.GameOptions;
using System;
using InnerNet;
using UnityEngine;
namespace AmongUsRevamped;
[HarmonyPatch(typeof(AmongUsClient), nameof(AmongUsClient.CoStartGame))]
internal class ApplyCustomImpostorCount
internal class CoStartGamePatch
{
public static void Postfix(AmongUsClient __instance)
{
if (!AmongUsClient.Instance.AmHost) return;
Logger.Info(" -------- GAME STARTED --------", "StartGame");
Logger.Info($" Gamemode: {Options.Gamemode.GetValue()}", "StartGame");
Logger.Info($" Players: {PlayerControl.AllPlayerControls.Count}", "StartGame");
NormalGameEndChecker.imps.Clear();
NormalGameEndChecker.LastWinReason = "";
if (Main.GM.Value)
{
if (Options.Gamemode.GetValue() == 3)
{
PlayerControl.LocalPlayer.CoSetRole(AmongUs.GameOptions.RoleTypes.CrewmateGhost, false);
}
else
{
PlayerControl.LocalPlayer.RpcSetRole(AmongUs.GameOptions.RoleTypes.CrewmateGhost, false);
}
}
}
PlayerControl.LocalPlayer.myTasks.Clear();
[HarmonyPatch(typeof(PlayerControl), nameof(PlayerControl.RpcSetRole))]
class PlayerControlSetRolePatch
{
private static int i;
public static bool FirstAssign;
private static HashSet<byte> Seekers = new();
public static HashSet<PlayerControl> Jesters = new();
private static readonly System.Random rand = new System.Random();
public static bool Prefix(PlayerControl __instance, ref RoleTypes roleType, ref bool canOverrideRole)
{
if (!FirstAssign || !AmongUsClient.Instance.AmHost) return true;
var oldRole = roleType;
canOverrideRole = false;
if (Main.GM.Value && __instance == PlayerControl.LocalPlayer)
{
roleType = RoleTypes.CrewmateGhost;
return true;
}
if (Options.Gamemode.GetValue() == 3 && !Utils.isHideNSeek)
if (Utils.isHideNSeek && i == 0)
{
int seekersCount = Options.NumSeekers.GetInt();
var candidates = new List<PlayerControl>();
foreach (var p in PlayerControl.AllPlayerControls)
{
if (p != PlayerControl.LocalPlayer)
{
p.RpcSetRole(AmongUs.GameOptions.RoleTypes.Crewmate, false);
}
if (p == PlayerControl.LocalPlayer)
{
p.CoSetRole(AmongUs.GameOptions.RoleTypes.Crewmate, false);
}
if (!Main.GM.Value || p != PlayerControl.LocalPlayer) candidates.Add(p);
}
seekersCount = Math.Min(seekersCount, candidates.Count);
for (int j = candidates.Count - 1; j > 0; j--)
{
int k = rand.Next(j + 1);
(candidates[j], candidates[k]) = (candidates[k], candidates[j]);
}
for (int j = 0; j < seekersCount; j++)
{
Seekers.Add(candidates[j].PlayerId);
}
}
if (Utils.isHideNSeek)
{
int seekersCount = Options.NumSeekers.GetInt();
int toAdd = Math.Max(0, seekersCount - 1);
var candidates = new List<PlayerControl>();
foreach (var p in PlayerControl.AllPlayerControls)
{
if (p.Data.Role.TeamType != RoleTeamTypes.Impostor && !p.Data.IsDead)
candidates.Add(p);
}
toAdd = Math.Min(toAdd, candidates.Count);
System.Random rand = new System.Random();
for (int i = candidates.Count - 1; i > 0; i--)
{
int j = rand.Next(i + 1);
(candidates[i], candidates[j]) = (candidates[j], candidates[i]);
}
// 1st RpcSetRole forces the role on that user. 2nd is needed to allow them to kill.
for (int i = 0; i < toAdd; i++)
{
var player = candidates[i];
player.RpcSetRole(AmongUs.GameOptions.RoleTypes.Impostor, false);
foreach (var p in PlayerControl.AllPlayerControls)
{
if (p.Data.Role.TeamType == RoleTeamTypes.Impostor)
{
new LateTask(() =>
{
p.RpcSetRole(AmongUs.GameOptions.RoleTypes.Impostor, false);
}, 5f, "HNS Secondary RPCSetRole");
new LateTask(() =>
{
p.RpcSetRole(AmongUs.GameOptions.RoleTypes.Impostor, false);
}, 9f, "HNS Tertiary RPCSetRole");
}
}
}
if (Seekers.Contains(__instance.PlayerId)) roleType = RoleTypes.Impostor;
else roleType = RoleTypes.Engineer;
}
if (Options.Gamemode.GetValue() == 3 && !Utils.isHideNSeek)
{
if (__instance == PlayerControl.LocalPlayer && Main.GM.Value)
{
PlayerControl.LocalPlayer.myTasks.Clear();
return true;
}
if (Options.EngineerMode.GetBool()) roleType = RoleTypes.Engineer;
else roleType = RoleTypes.Crewmate;
}
i++;
if (i >= PlayerControl.AllPlayerControls.Count)
{
Seekers.Clear();
FirstAssign = false;
i = 0;
Logger.Info("PCSRP successful", "RoleManaging");
}
if (roleType == RoleTypes.Crewmate && Options.CrewmateAbility.GetValue() == 2 ||
roleType == RoleTypes.Scientist && Options.ScientistAbility.GetValue() == 2 ||
roleType == RoleTypes.Engineer && Options.EngineerAbility.GetValue() == 2 ||
roleType == RoleTypes.Noisemaker && Options.NoisemakerAbility.GetValue() == 2 ||
roleType == RoleTypes.Tracker && Options.TrackerAbility.GetValue() == 2 ||
roleType == RoleTypes.Detective && Options.DetectiveAbility.GetValue() == 2)
{
Jesters.Add(__instance);
}
return true;
}
}
+148 -8
View File
@@ -3,7 +3,9 @@ using AmongUs.GameOptions;
using Hazel;
using InnerNet;
using System;
using TMPro;
using UnityEngine;
using UnityEngine.UI;
namespace AmongUsRevamped;
@@ -12,11 +14,21 @@ class ReportDeadBodyPatch
{
public static bool Prefix(PlayerControl __instance, [HarmonyArgument(0)] NetworkedPlayerInfo target)
{
if (!AmongUsClient.Instance.AmHost) return true;
if (!AmongUsClient.Instance.AmHost || __instance == null) return true;
if (Options.DisableReport.GetBool() && target != null || Options.Gamemode.GetValue() == 2 || Options.Gamemode.GetValue() == 3)
if (Options.DisableAnnoyingMeetingCalls.GetBool() && !Utils.CanCallMeetings /*&& !Options.ChatBeforeFirstMeeting.GetBool()*/ && target == null)
{
Logger.Info($" Stopped {__instance.Data.PlayerName} reporting the body of {target.PlayerName}", "ReportDeadBodyPatch");
Logger.Info($" {__instance.Data.PlayerName} is calling a meeting too fast, attempt blocked", "ReportDeadBodyPatch");
return false;
}
// target == null means meeting
if (Options.Gamemode.GetValue() == 2 || Options.Gamemode.GetValue() == 3)
{
if (target != null) Logger.Info($" Stopped {__instance.Data.PlayerName} reporting the body of {target.PlayerName}", "ReportDeadBodyPatch");
else Logger.Info($" Stopped {__instance.Data.PlayerName} trying to call a meeting", "ReportDeadBodyPatch");
return false;
}
else return true;
@@ -27,10 +39,46 @@ class ReportDeadBodyPatch
internal static class MurderPlayerPatch
{
public static readonly Dictionary<byte, int> misfireCount = new();
public static readonly Dictionary<byte, int> killCount = new();
public static void Postfix(PlayerControl __instance, [HarmonyArgument(0)] PlayerControl target, [HarmonyArgument(1)] MurderResultFlags resultFlags, ref bool __state)
{
if (!AmongUsClient.Instance.AmHost) return;
if (!AmongUsClient.Instance.AmHost || !resultFlags.HasFlag(MurderResultFlags.Succeeded)) return;
byte playerId = __instance.Data.PlayerId;
if (!killCount.ContainsKey(playerId))
{
killCount[playerId] = 0;
}
if (!__instance.isNew)
{
killCount[playerId]++;
Logger.Info($" {__instance.Data.PlayerName} killed {target.Data.PlayerName}", "MurderPlayer");
if ((target == PlayerControl.LocalPlayer || PlayerControl.LocalPlayer.Data.IsDead) && !Main.DisableInfoWhenDead.Value)
{
foreach (var p in PlayerControl.AllPlayerControls)
{
if (p.Data.Role.IsImpostor)
{
p.cosmetics.nameText.text = $"{p.Data.PlayerName}<color=red><size=90%>({killCount[p.Data.PlayerId]}†)";
}
else
{
p.cosmetics.nameText.text = $"{p.Data.PlayerName}<color=green><size=90%>({PlayerControlCompleteTaskPatch.playerTasksCompleted[p]}/{PlayerControlCompleteTaskPatch.tasksPerPlayer[p]})";
}
}
}
}
if (Options.Gamemode.GetValue() < 2 && AbilityManagement.IsJuggernaut(__instance) && killCount[__instance.PlayerId] >= Options.KillsNeededForJuggernaut.GetInt())
{
Logger.Info("Juggernaut win", "MurderPlayer");
Utils.ContinueEndGame((byte)GameOverReason.ImpostorsByVote);
NormalGameEndChecker.CheckWinnerText("Juggernaut");
}
//2 = Shift and Seek
if (Options.Gamemode.GetValue() == 2 && !Utils.isHideNSeek)
@@ -38,8 +86,6 @@ internal static class MurderPlayerPatch
if (!resultFlags.HasFlag(MurderResultFlags.Succeeded))
return;
byte playerId = __instance.Data.PlayerId;
if (target.Data.PlayerId == __instance.shapeshiftTargetPlayerId)
{
Logger.Info($" {__instance.Data.PlayerName} correctly killed {target.Data.PlayerName} ", "SNSKillManager");
@@ -68,8 +114,8 @@ internal static class MurderPlayerPatch
if (misfireCount[__instance.Data.PlayerId] >= Options.MisfiresToSuicide.GetFloat())
{
__instance.RpcSetRole(RoleTypes.ImpostorGhost);
Logger.Info($" {__instance.Data.PlayerName} misfired {misfireCount[playerId]} times and suicided", "SNSKillManager");
Logger.SendInGame($" {__instance.Data.PlayerName} misfired {misfireCount[playerId]} times and suicided");
Logger.Info($" {__instance.Data.PlayerName} misfired {misfireCount[playerId]} time(s) and suicided", "SNSKillManager");
Logger.SendInGame($" {__instance.Data.PlayerName} misfired {misfireCount[playerId]} time(s) and suicided");
}
}
@@ -95,3 +141,97 @@ internal static class CheckShapeshiftPatch
else return true;
}
}
[HarmonyPatch(typeof(PlayerControl), nameof(PlayerControl.CompleteTask))]
class PlayerControlCompleteTaskPatch
{
public static Dictionary<PlayerControl, int> playerTasksCompleted = new Dictionary<PlayerControl, int>();
public static Dictionary<PlayerControl, int> tasksPerPlayer = new Dictionary<PlayerControl, int>();
public static List<string> ignoredRoles = new List<string> {"Jester"};
public static int ignoredTasks;
public static int ignoredCompletedTasks;
public static bool tasksInitiated;
public static void Postfix(PlayerControl __instance, uint idx)
{
if (!AmongUsClient.Instance.AmHost) return;
foreach (var p in PlayerControl.AllPlayerControls)
{
/*
if (ignoredRoles.Contains(CustomRoleManagement.GetRole(p.PlayerId)) && !tasksInitiated)
{
ignoredTasks += p.Data.Tasks.Count;
tasksInitiated = true;
}
*/
if (!playerTasksCompleted.ContainsKey(p))
{
playerTasksCompleted[p] = 0;
}
tasksPerPlayer[p] = p.Data.Tasks.Count;
}
playerTasksCompleted[__instance]++;
/*
if (ignoredRoles.Contains(CustomRoleManagement.GetRole(__instance.PlayerId)))
{
ignoredCompletedTasks = playerTasksCompleted[__instance];
}
*/
Logger.Info($" {__instance.Data.PlayerName} completed {idx}", "TaskPatch");
if (Options.Gamemode.GetValue() < 2)
{
if (AbilityManagement.IsSpeedrunner(__instance) && !__instance.Data.IsDead && playerTasksCompleted[__instance] >= __instance.Data.Tasks.Count)
{
Logger.Info($"Speedrunner {__instance.Data.PlayerName} won", "TaskPatch");
Utils.ContinueEndGame((byte)GameOverReason.CrewmatesByVote);
NormalGameEndChecker.CheckWinnerText("Speedrunner");
}
}
if (Options.Gamemode.GetValue() != 3) CalculateTaskWin();
if (Options.Gamemode.GetValue() == 3)
{
if (!__instance.Data.IsDead && playerTasksCompleted[__instance] >= __instance.Data.Tasks.Count)
{
Utils.CustomWinnerEndGame(__instance, 1);
NormalGameEndChecker.LastWinReason = $"{__instance.Data.PlayerName} wins! (Completed tasks)";
NormalGameEndChecker.canUpdateWinnerText = false;
}
}
if (PlayerControl.LocalPlayer.Data.IsDead && !Main.DisableInfoWhenDead.Value)
{
TMP_Text nameText = __instance.cosmetics.nameText;
nameText.text = $"{__instance.Data.PlayerName}<color=green><size=90%>({playerTasksCompleted[__instance]}/{tasksPerPlayer[__instance]})</color>";
}
}
public static void CalculateTaskWin()
{
if (!Utils.GamePastRoleSelection || Utils.isHideNSeek || Options.NoGameEnd.GetBool()) return;
//Logger.Info($" Checking if {GameData.Instance.CompletedTasks} - {ignoredCompletedTasks} >= ({GameData.Instance.TotalTasks} - {ignoredTasks}) * 0.01 * {Options.TaskPercentNeededToWin.GetInt()}", "TaskPatch");
if ((GameData.Instance.CompletedTasks - ignoredCompletedTasks) >= (GameData.Instance.TotalTasks - ignoredTasks)*0.01*Options.TaskPercentNeededToWin.GetInt())
{
Utils.ContinueEndGame((byte)GameOverReason.CrewmatesByVote);
NormalGameEndChecker.CheckWinnerText("CrewmateTasks");
}
}
}
[HarmonyPatch(typeof(PlayerControl), nameof(PlayerControl.CheckSporeTrigger))]
public static class PlayerControlCheckSporeTriggerPatch
{
public static bool Prefix(PlayerControl __instance, [HarmonyArgument(0)] Mushroom mushroom)
{
if (!AmongUsClient.Instance.AmHost) return true;
if (Options.DisableSporeTrigger.GetBool()) return false;
else return true;
}
}
+57 -8
View File
@@ -4,13 +4,11 @@ using UnityEngine;
namespace AmongUsRevamped;
[HarmonyPatch(typeof(SabotageSystemType), nameof(SabotageSystemType.UpdateSystem))] // SetInitialSabotageCooldown - set sabotage cooldown in start game
[HarmonyPatch(typeof(SabotageSystemType), nameof(SabotageSystemType.UpdateSystem))]
public static class SabotageSystemTypeRepairDamagePatch
{
private static bool Prefix([HarmonyArgument(0)] PlayerControl player, [HarmonyArgument(1)] MessageReader msgReader)
{
if (!AmongUsClient.Instance.AmHost) return true;
byte amount;
{
var newReader = MessageReader.Get(msgReader);
@@ -18,12 +16,38 @@ public static class SabotageSystemTypeRepairDamagePatch
newReader.Recycle();
}
var Sabo = (SystemTypes)amount;
Logger.Info($" {player.Data.PlayerName} is trying to sabotage: {Sabo}", "SabotageCheck");
if (Options.DisableSabotage.GetBool() || Options.Gamemode.GetValue() == 2)
if (Options.Gamemode.GetValue() == 0 || Options.Gamemode.GetValue() == 1)
{
Logger.Info($" Sabotage {Sabo} by: {player.Data.PlayerName} was blocked", "SabotageCheck");
return false;
if (Sabo == SystemTypes.LifeSupp && Options.DisableOxygen.GetBool() ||
Sabo == SystemTypes.Reactor && Options.DisableReactor.GetBool() ||
Sabo == SystemTypes.Electrical && Options.DisableLights.GetBool() ||
Sabo == SystemTypes.Comms && Options.DisableComms.GetBool() ||
Sabo == SystemTypes.HeliSabotage && Options.DisableHeli.GetBool() ||
Sabo == SystemTypes.MushroomMixupSabotage && Options.DisableMushroomMixup.GetBool() ||
player.Data.IsDead && !Options.DeadImpostorsCanSabotage.GetBool())
{
Logger.Info($" Sabotage {Sabo} by: {player.Data.PlayerName} was blocked", "SabotageCheck");
return false;
}
return true;
}
if (Options.Gamemode.GetValue() == 2)
{
if (Sabo == SystemTypes.LifeSupp && Options.SNSDisableOxygen.GetBool() ||
Sabo == SystemTypes.Reactor && Options.SNSDisableReactor.GetBool() ||
Sabo == SystemTypes.Electrical && Options.SNSDisableLights.GetBool() ||
Sabo == SystemTypes.Comms && Options.SNSDisableComms.GetBool() ||
Sabo == SystemTypes.HeliSabotage && Options.SNSDisableHeli.GetBool() ||
Sabo == SystemTypes.MushroomMixupSabotage && Options.SNSDisableMushroomMixup.GetBool() ||
player.Data.IsDead && !Options.DeadImpostorsCanSabotage.GetBool())
{
Logger.Info($" Sabotage {Sabo} by: {player.Data.PlayerName} was blocked", "SnSSabotageCheck");
return false;
}
return true;
}
else return true;
}
@@ -38,11 +62,36 @@ class ShipStatusCloseDoorsPatch
Logger.Info($" Trying to close the door in: {room}", "DoorCheck");
if (Options.DisableCloseDoor.GetBool() || Options.Gamemode.GetValue() == 2)
if (Options.DisableCloseDoor.GetBool() && (Options.Gamemode.GetValue() == 0 || Options.Gamemode.GetValue() == 1) || Options.Gamemode.GetValue() == 2 && Options.SNSDisableCloseDoor.GetBool())
{
Logger.Info($" Door sabotage in: {room} was blocked", "DoorCheck");
return false;
}
else return true;
}
}
[HarmonyPatch(typeof(ShipStatus), nameof(ShipStatus.UpdateSystem), typeof(SystemTypes), typeof(PlayerControl), typeof(MessageReader))]
public static class MessageReaderUpdateSystemPatch
{
public static bool Prefix(ShipStatus __instance, [HarmonyArgument(0)] SystemTypes systemType, [HarmonyArgument(1)] PlayerControl player, [HarmonyArgument(2)] MessageReader reader)
{
if (systemType is
SystemTypes.Ventilation
or SystemTypes.Security
or SystemTypes.Decontamination
or SystemTypes.Decontamination2
or SystemTypes.Decontamination3
or SystemTypes.MedBay) return true;
if (player.Data.ClientId == AmongUsClient.Instance.HostId) return true;
var amount = MessageReader.Get(reader).ReadByte();
if (EACR.RpcUpdateSystemCheck(player, systemType, amount))
{
Logger.Info("EACR patched Sabotage RPC", "MessageReaderUpdateSystemPatch");
return false;
}
else return true;
}
}
+19 -11
View File
@@ -136,7 +136,7 @@ internal static class RpcSetTasksPatch
if (!Options.AllPlayersSameTasks.GetBool())
{
RerollTasks(ref taskTypeIds);
RerollTasks(pc, ref taskTypeIds);
return;
}
@@ -155,23 +155,26 @@ internal static class RpcSetTasksPatch
}
private static void RerollTasks(ref Il2CppStructArray<byte> taskTypeIds)
private static void RerollTasks(PlayerControl pc, ref Il2CppStructArray<byte> taskTypeIds)
{
// Default number of tasks
bool hasCommonTasks = true;
int numCommonTasks = Main.NormalOptions.NumCommonTasks;
int numLongTasks = Main.NormalOptions.NumLongTasks;
int numShortTasks = Main.NormalOptions.NumShortTasks;
if (AbilityManagement.IsSpeedrunner(pc))
{
numLongTasks = Options.SpeedrunnerLongTasks.GetInt();
numShortTasks = Options.SpeedrunnerShortTasks.GetInt();
}
if (taskTypeIds.Length == 0) hasCommonTasks = false;
switch (hasCommonTasks)
{
case false when numLongTasks == 0 && numShortTasks == 0:
numShortTasks = 1;
break;
case true when numLongTasks == Main.NormalOptions.NumLongTasks && numShortTasks == Main.NormalOptions.NumShortTasks:
return;
case false when numLongTasks == 0 && numShortTasks == 0: numShortTasks = 1; break;
case true when numLongTasks == Main.NormalOptions.NumLongTasks && numShortTasks == Main.NormalOptions.NumShortTasks: return;
}
Il2CppSystem.Collections.Generic.List<byte> TasksList = new();
@@ -180,24 +183,28 @@ internal static class RpcSetTasksPatch
Il2CppSystem.Collections.Generic.HashSet<TaskTypes> UsedTaskTypes = new();
var start0 = 0;
var start1 = 0;
var start2 = 0;
// Long tasks
Il2CppSystem.Collections.Generic.List<NormalPlayerTask> CommonTasks = new();
foreach (var task in ShipStatus.Instance.CommonTasks) CommonTasks.Add(task);
Shuffle(CommonTasks);
ShipStatus.Instance.AddTasksFromList(ref start0, numCommonTasks, TasksList, UsedTaskTypes, CommonTasks);
Il2CppSystem.Collections.Generic.List<NormalPlayerTask> LongTasks = new();
foreach (var task in ShipStatus.Instance.LongTasks) LongTasks.Add(task);
Shuffle(LongTasks);
ShipStatus.Instance.AddTasksFromList(ref start1, numLongTasks, TasksList, UsedTaskTypes, LongTasks);
// Short tasks
Il2CppSystem.Collections.Generic.List<NormalPlayerTask> ShortTasks = new();
foreach (var task in ShipStatus.Instance.ShortTasks) ShortTasks.Add(task);
Shuffle(ShortTasks);
ShipStatus.Instance.AddTasksFromList(ref start2, numShortTasks, TasksList, UsedTaskTypes, ShortTasks);
// Apply result
taskTypeIds = new Il2CppStructArray<byte>(TasksList.Count);
for (int i = 0; i < TasksList.Count; i++) taskTypeIds[i] = TasksList[i];
}
@@ -212,4 +219,5 @@ internal static class RpcSetTasksPatch
list[r] = tmp;
}
}
}
+20
View File
@@ -0,0 +1,20 @@
namespace AmongUsRevamped;
//Old Patch for Mayor
/*
[HarmonyPatch(typeof(Vent), nameof(Vent.EnterVent))]
class EnterVentPatch
{
public static void Postfix(Vent __instance, [HarmonyArgument(0)] PlayerControl pc)
{
if (!AmongUsClient.Instance.AmHost) return;
if (CustomRoleManagement.PlayerRoles.TryGetValue(pc.PlayerId, out var role) && role == "Mayor")
{
pc.CmdReportDeadBody(null);
Logger.Info($" The Mayor, {pc.Data.PlayerName}, called a meeting by venting", "EnterVent");
}
}
}
*/
+11 -3
View File
@@ -17,11 +17,9 @@ internal static class AddVotePatch
if (AmongUsClient.Instance.ClientId == srcClient)
{
AmongUsClient.Instance.KickPlayer(target.Data.ClientId, false);
Logger.Info($" Kicked {target.Data.PlayerName}, {target.Data.FriendCode}", "KickPatch");
}
return false;
return true;
}
}
@@ -48,6 +46,16 @@ internal static class BanMenuSetVisiblePatch
__instance.KickButton.gameObject.SetActive(true);
__instance.MenuButton.gameObject.SetActive(show);
return false;
}
}
[HarmonyPatch(typeof(InnerNetClient), nameof(InnerNetClient.CanBan))]
internal class InnerNetClientCanBanPatch
{
public static bool Prefix(InnerNetClient __instance, ref bool __result)
{
__result = __instance.AmHost;
return false;
}
}
+89 -31
View File
@@ -1,4 +1,4 @@
# Welcome to AmongUsRevamped!
# Welcome to Among Us Revamped!
<br>
</p>
@@ -29,54 +29,112 @@
<img src="https://github.com/astra1dev/AUnlocker/assets/90265231/14226f03-a003-4efc-b27b-6df53fb394d6" width=410 height=240>****
‎
# 🎮 Features (v1.2.1):
- <b>🔶 Client Side settings:</b>
# 🎮 Features (v1.7.3):
## <b> 🌟 Custom Abilities:</b>
- Mayor (Crewmate)
- The Mayor has a configurable amount of extra votes
- Jester (Crewmate)
- The Jester wins alone by getting ejected, can win with Crewmates
- Speedrunner (Crewmate)
- The Crewmates win if the Speedrunner completes tasks and is alive
- Workhorse (Crewmate)
- The Workhorse gains additional votes per completed task
- Tyrant (Impostor)
- The Tyrant has a configurable amount of extra votes
- Stealer (Impostor)
- The Stealer gains additional votes per kill
- Juggernaut (Impostor)
- The Impostors win if the Juggernaut gains a set amount of kills
- For the enabled ability list, type /r
- To check ability descriptions, type /r {ability}
## <b>♠️ Client Side settings:</b>
- Game Master
- Unlock FPS
- Show FPS
- Dark Theme
- Toggle Lobby Music
- <b>🔷 Technical settings:</b>
- Show/Hide Info When Dead
- Customizable strings
## <b>⚙️ Technical settings:</b>
- Kick/Ban players under a certain level
- Kick/Ban invalid FriendCodes
- Kick/Ban command using names
- Ckick/Cban command using colors
- DenyName system
- Moderator system
- Kick/Ban players who say "start"
- Denyword system
- Banlist system
- Denyname system
- Multi layer moderator system
- To add Admins, Moderators and VIP's, type the user's Friendcode in the designated files located in AUR-DATA
- Enable No Game End
- <b>🔶 Automation settings:</b>
- Auto start game and conditions for it
- Auto rejoin lobby
- Auto send winner info
- <b>🔷 Gameplay Settings:</b>
- Disable critical sabotages
- Custom starting countdown
## <b>♻️ Automation settings:</b>
- Automatically start game
- Automatically rejoin lobby
- Automatically send winner info
## <b>🔧 Gameplay Settings:</b>
- Dead impostors can sabotage
- Disable critical sabotages (invividual)
- Disable door sabotages
- Disable body reporting
- Enable/Disable any desired tasks
- Disable meeting calls first 30s
- Disable body reports
- Disable devices (per map, individual)
- Override decontamination time (per map)
- Disable spore triggers on The Fungle
- % Tasks completed for Crewmates to win
- Enable/Disable any task
- All players have same tasks
- Hide and Seek: Custom Impostor count
- <b>🔶 Custom Gamemodes:</b>
## <b>🏆 Custom Gamemodes:</b>
- 0 Kill Cooldown
- Shift and Seek
- Speedrun
- <b>🔷 Extra features:</b>
- Shift + L + Enter - Force End Game
- Shift + M + Enter - Force Call/Close Meeting
- /help command
- Specific gamemode info commands -> /0kc, /sns, /sp
- Current gamemode info command -> /r
## <b>❓ Other Improvements:</b>
- Creatable and customizable Templates
- Eht Dleks (Reverse Skeld) Map
- Ability to cancel starting countdown
- Improved main menu
- Faster startup time
- Custom anticheat system
- Zoom out in lobby or when dead
- Unlimited default Option ranges
- Logging for useful information
- <b>🎉 And this all without Modded Protocol!</b>
‎
- See player kill/task count when dead
- Higher and more accurate Option ranges
- <b>🎉 And this all works in public lobbies!</b>
### Hotkeys
| HotKey | Function | Usable Scene |
| ------------------- | ------------------------------------------- | ---------------------------------- |
| `Shift`+`L`+`Enter` | Force End Game | In Game |
| `Shift`+`M`+`Enter` | Skip meeting when active | In Game |
| `C` | Cancel game start | In Starting Countdown |
| `Shift` | Start the game immediately | In Starting Countdown |
| `Shift` | 5x Option increment | In Options Menu |
| `Ctrl` | Noclip in lobby | In Lobby |
| `Ctrl` | 10x Option increment | In Options Menu |
### Chat Commands
| Command | Function |
| ------------------------------------------- | ------------------------------------------------- |
| /h<br>/help | Show command help |
| /l<br>/win | Show winner |
| /r | Show current gamemode/roles description |
| /0kc<br>/sns</br>/sp | Show respective gamemode description |
| /ban <name> | Ban a player by name |
| /kick <name> | Kick a player by name |
| /cban <color> | Ban a player by color |
| /ckick <color> | Kick a player by color |
| /dump | Copy your LogOutput file |
| /endgame | Instantly end the game |
| /endmeeting | Instantly end an ongoing meeting |
| /aur | Sends AUR socials (GitHub, Discord) |
| /color | Sets color. Can be used to bypass color limit |
| /reload | Resets the *Language*.JSON file to default |
| /start | Starts game countdown |
‎
**Credit to these mods and their developers for their code:**
### :star: [AUnlocker](https://github.com/astra1dev/AUnlocker)
> - NumberOptionsPatch
> - Original NumberOptionsPatch
### :star: [EHR (Formerly TOHE+)](https://github.com/Gurge44/EndlessHostRoles)
> - Dark Theme
> - Task Patching
### :star: [TOH](https://github.com/tukasa0001/TownOfHost) :
> - Ban Manager
@@ -86,10 +144,10 @@
### :star: [TOHY](https://github.com/Yumenopai/TownOfHost_Y) :
> - Zoom
### :star: [MoreGamemodes](https://github.com/Rabek009/MoreGamemodes)
> - Chat Patches
> - Some Chat Patches
> - OptionItem System
---
This project is licensed under the GNU General Public License version 3.0. For more details, please refer to the [LICENSE](https://github.com/0xDrLime/TownofHost-Enhanced/blob/main/LICENSE) file.
This project is licensed under the GNU General Public License version 3.0. For more details, please refer to the [LICENSE](https://github.com/apemv/AmongUsRevamped/blob/main/LICENSE) file.
---
<b>This mod is not affiliated with Among Us or Innersloth LLC, and the content contained therein is not endorsed or otherwise sponsored by Innersloth LLC. Portions of the materials contained herein are property of Innersloth LLC. © Innersloth LLC.</b>
Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 55 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 80 KiB

+274
View File
@@ -0,0 +1,274 @@
{
"LanguageID": "0",
"gameMaster": "Game Master",
"unlockFPS": "Unlock FPS",
"showFPS": "Show FPS",
"autoStart": "Auto Start",
"enableDarkTheme": "Enable Dark Theme",
"enableLobbyMusic": "Lobby Music",
"disableInfoWhenDead": "Hide Info When Dead",
"gameMasterWarning":"You will now spectate games until Game Master is turned off.",
"cancelStartCountdown": "Start countdown canceled",
"gamemode": "Gamemode",
"tabGroupMain": "Moderation",
"kickLowLevelPlayer": "Kick Players Under Level",
"tempBanLowLevelPlayer": "Ban Instead Of Kick",
"kickInvalidFriendCodes": "Kick Invalid FriendCodes",
"tempBanInvalidFriendCodes": "Ban Instead Of Kick",
"applyBanList": "Apply BanList",
"applyDenyNameList": "Apply DenyName List",
"applyModeratorList": "Apply Moderator List",
"moderatorCanUseCommand": "Moderators can use commands",
"autoKickStart": "Kick Players Who Say Start",
"autoKickStartAsBan": "Ban Instead Of Kick",
"autoKickStartTimes": "Start messages needed to kick",
"autoKickStartStrength": "Strict detection mode",
"tabGroupAutomation": "Automation",
"autoSendGameInfo": "Automatically send winner info",
"autoRejoinLobby": "Auto Rejoin Lobby",
"autoStartTimer": "Countdown For Auto Start",
"waitAutoStart": "Auto Start After",
"playerAutoStart": "Players Needed To Auto Start",
"tabGroupMisc": "Miscelleneous",
"startCountdown": "Default Starting Countdown",
"colorCommandLevel": "Who Can use Color Commands",
"allowFortegreen": "Allow Fortegreen Color",
"noGameEnd": "No Game End",
"tabGroupAccess": "Access Levels",
"slashColorCmd": "Who Can Use /color",
"slashRolesAndGamemodeCmd": "Who Can Use /r And Templates",
"slashLastGameCmd": "Who Can Use /l",
"slashHelpAndAurCmd": "Who Can Use /help And /aur",
"slashKickCmd": "Who Can Use /kick And /ckick",
"slashBanCmd": "Who Can Use /ban And /cban",
"slashEndMeetingCmd": "Who Can Use /endmeeting",
"slashStartAndEndGameCmd": "Who Can Use /startgame And /endgame",
"tabGroupCrewmate": "Crewmate Roles",
"tabGroupNeutral": "Neutral Roles",
"tabGroupImpostor": "Impostor Roles",
"tabGroupStandard": "Standard",
"chatBeforeFirstMeeting": "Force chat 1st round to see roles (experimental)",
"tabGroupHNS": "Hide and Seek",
"numSeekers": "# Seekers",
"tabGroup0Kcd": "0 Kill Cooldown",
"noKcdSettingsOverride": "Auto Update Settings",
"tabGroupSNS": "Shift and Seek",
"snsChatInGame": "Chat during gameplay (experimental)",
"snsSettingsOverride": "Auto Update Settings",
"cantKillTime": "After Misfiring, Can't kill for",
"misfiresToSuicide": "Suicide After Amount Of Misfires",
"crewAutoWinsGameAfter": "Crewmates Automatically Win After",
"snsDisableSabotage": "Disable SnS Critical Sabotages",
"snsDisableReactor": "Disable Reactor Sabotage",
"snsDisableOxygen": "Disable O2 Sabotage",
"snsDisableLights": "Disable Lights Sabotage",
"snsDisableComms": "Disable Communications Sabotage",
"snsDisableHeli": "Disable Crash Course Sabotage",
"snsDisableMushroomMixup": "Disable Mushroom Mixup Sabotage",
"snsDisableCloseDoor": "Disable SnS Door Sabotages",
"tabGroupSpeedrun": "Speedrun",
"speedrunSettingsOverride": "Auto Update Settings",
"gameAutoEndsAfter": "Game automatically ends after",
"engineerMode": "Everyone Is Engineer",
"tabGroupSabotages": "Sabotages",
"deadImpostorsCanSabotage": "Dead Impostors Can Sabotage",
"disableSabotage": "Disable Critical Sabotages",
"disableReactor": "Disable Reactor Sabotage",
"disableOxygen": "Disable O2 Sabotage",
"disableLights": "Disable Lights Sabotage",
"disableComms": "Disable Communications Sabotage",
"disableHeli": "Disable Crash Course Sabotage",
"disableMushroomMixup": "Disable Mushroom Mixup Sabotage",
"disableCloseDoor": "Disable Door Sabotages",
"tabGroupGameplayGeneral": "General",
"disableAnnoyingMeetingCalls": "Disable Meeting Calls First 30s",
"disableReport": "Disable Body Reports",
"changeDecontaminationTime": "Override Decontamination Time (Standard Only)",
"decontaminationTimeOnMiraHQ": "Mira HQ Decon Duration",
"decontaminationDoorOpenTimeOnMiraHQ": "Mira HQ Door Open Duration",
"decontaminationTimeOnPolus": "Polus Decon Duration",
"decontaminationDoorOpenTimeOnPolus": "Polus Door Open Duration",
"disableSporeTrigger": "Disable Spores On The Fungle",
"disableDevices": "Disable Devices",
"disableSkeldDevices": "Disable Skeld Devices",
"disableSkeldAdmin": "Disable Skeld Admin",
"disableSkeldCamera": "Disable Skeld Camera",
"disableMiraHQDevices": "Disable Mira HQ Devices",
"disableMiraHQAdmin": "Disable Mira HQ Admin",
"disableMiraHQDoorLog": "Disable Mira HQ DoorLogs",
"disablePolusDevices": "Disable Polus Devices",
"disablePolusAdmin": "Disable Polus Admin",
"disablePolusCamera": "Disable Polus Camera",
"disablePolusVital": "Disable Polus Vitals",
"disableAirshipDevices": "Disable Airship Devices",
"disableAirshipCockpitAdmin": "Disable Airship Cockpit Admin",
"disableAirshipRecordsAdmin": "Disable Airship Records Admin",
"disableAirshipCamera": "Disable Airship Camera",
"disableAirshipVital": "Disable Airship Vitals",
"disableFungleDevices": "Disable Fungle Devices",
"disableFungleCamera": "Disable Fungle Camera",
"disableFungleVital": "Disable Fungle Vitals",
"tabGroupTasks": "Tasks",
"allPlayersSameTasks": "Everyone has same tasks",
"overrideTaskSettings": "Disable Tasks",
"taskPercentNeededToWin": "% Tasks completed for crewmates to win",
"disableMiraTasks": "Disable Mira HQ Tasks",
"disableBuyBeverage": "Disable Buy Beverage",
"disableMeasureWeather": "Disable Measure Weather",
"disableProcessData": "Disable Process Data",
"disableRunDiagnostics": "Disable Run Diagnostics",
"disableSortSamples": "Disable Sort Samples",
"disablePolusTasks": "Disable Polus Tasks",
"disableActivateWeatherNodes": "Disable Activate Weather Nodes",
"disableAlignTelescope": "Disable Align Telescope",
"disableFillCanisters": "Disable Fill Canisters",
"disableInsertKeys": "Disable Insert Keys",
"disableOpenWaterways": "Disable Open Waterways",
"disableRebootWifi": "Disable Reboot Wifi",
"disableRepairDrill": "Disable Repair Drill",
"disableScanBoardingPass": "Disable Scan Boarding Pass",
"disableAirshipTasks": "Disable Airship Tasks",
"disableCleanToilet": "Disable Clean Toilet",
"disableDecontaminate": "Disable Decontaminate",
"disableDevelopPhotos": "Disable Develop Photos",
"disableDressMannequin": "Disable Dress Mannequin",
"disableFixShower": "Disable Fix Shower",
"disableMakeBurger": "Disable Make Burger",
"disablePickUpTowels": "Disable Pick Up Towels",
"disablePolishRuby": "Disable Polish Ruby",
"disablePutAwayPistols": "Disable Put Away Pistols",
"disablePutAwayRifles": "Disable Put Away Rifles",
"disableRewindTapes": "Disable Rewind Tapes",
"disableResetBreaker": "Disable Reset Breakers",
"disableSortRecords": "Disable Sort Records",
"disableStartFans": "Disable Start Fans",
"disableUnlockSafe": "Disable Unlock Safe",
"disableFungleTasks": "Disable Fungle Tasks",
"disableBuildSandcastle": "Disable Build Sandcastle",
"disableCatchFish": "Disable Catch Fish",
"disableCollectSamples": "Disable Collect Samples",
"disableCollectShells": "Disable Collect Shells",
"disableCollectVegetables": "Disable Collect Vegetables",
"disableCrankGenerator": "Disable Crank Generator",
"disableExtractFuel": "Disable Extract Fuel",
"disableFixAntenna": "Disable Fix Antenna",
"disableHelpCritter": "Disable Help Critter",
"disableHoistSupplies": "Disable Hoist Supplies",
"disableLiftWeights": "Disable Lift Weights",
"disableMineOres": "Disable Mine Ores",
"disablePlayVideoGame": "Disable Play Video Game",
"disablePolishGem": "Disable Polish Gem",
"disableReplaceParts": "Disable Replace Parts",
"disableRoastMarshmallow": "Disable Roast Marshmallow",
"disableThrowFisbee": "Disable Throw Fisbee",
"disableFindSignal": "Disable Find Signal",
"disableMiscCommonTasks": "Disable Global Common Tasks",
"disableEnterIdCode": "Disable Enter Id Code",
"disableFixWiring": "Disable Fix Wiring",
"disableSwipeCard": "Disable Swipe Card",
"disableMiscShortTasks": "Disable Global Short Tasks",
"disableAssembleArtifact": "Disable Assemble Artifact",
"disableChartCourse": "Disable Chart Course",
"disableCleanO2Filter": "Disable Clean O2 Filter",
"disableCleanVent": "Disable Clean Vent",
"disableMonitorMushroom": "Disable Monitor Mushroom",
"disableMonitorTree": "Disable Monitor Tree",
"disablePrimeShields": "Disable Prime Shields",
"disableRecordTemperature": "Disable Record Temperature",
"disableStabilizeSteering": "Disable Stabilize Steering",
"disableStoreArtifacts": "Disable Store Artifacts",
"disableUnlockManifolds": "Disable Unlock Manifolds",
"disableMiscLongTasks": "Disable Global Long Tasks",
"disableAlignEngineOutput": "Disable Align Engine Output",
"disableClearAsteroids": "Disable Clear Asteroids",
"disableEmptyChute": "Disable Empty Chute",
"disableInspectSample": "Disable Inspect Sample",
"disableReplaceWaterJug": "Disable Replace Water Jug",
"disableStartReactor": "Disable Start Reactor",
"disableWaterPlants": "Disable Water Plants",
"disableMiscMixedTasks": "Disable Global Mixed Tasks",
"disableCalibrateDistributor": "Disable Calibrate Distributor",
"disableDivertPower": "Disable Divert Power",
"disableEmptyGarbage": "Disable Empty Garbage",
"disableFuelEngines": "Disable Fuel Engines",
"disableSubmitScan": "Disable Submit Scan",
"disableUploadData": "Disable Upload Data",
"noKcdMode": "0 Kill Cooldown:\n\nImpostors have no kill cooldown, Crewmates have low tasks\nThink fast and pay attention!",
"SnSModeOne": "Shift and Seek:\n\nImpostors can only kill someone while shapeshifted as them\nEmergency Meetings = Off",
"SnSModeTwo": "Crew wins by tasks/surviving {0}s\nImp wins by killing\nOne wrong kill = Can't kill for {1}s\n{2} wrong kill(s) = suicide",
"speedrunMode": "Speedrun:\n\nEveryone is a crewmate. The 1st player to finish tasks wins the game. Game auto ends after {0}s",
"allCommandsFull": "Commands:\n/r - Current mode description\n/0kc, /sns, /sp - Specific mode description\n/l - Shows last winner info\n/kick, /ban - Bans or kicks a player by name\n/ckick, /cban - Bans or kicks a player by color",
"allCommandsOne": "Commands:\n/r - Current mode description\n/0kc, /sns, /sp - Specific mode description\n/l - Shows last winner info",
"allCommandsTwo": "/kick, /ban - Bans or kicks a player by name\n/ckick, /cban - Bans or kicks a player by color",
"socialsAll": "AUR socials:\n\ng i t h u b . c o m /\nApeMV/AmongUsRevamped\n\nd i s c o r d . g g /\n83Zhzhyhya",
"translationReloaded": "Your file has successfully been reset.\nTo apply the changes, restart your game.",
"mayorPublic": "Mayor:\n\nThe Mayor is a Crewmate with {0} additional vote(s). Use them wisely.",
"tyrantPublic": "Tyrant:\n\nThe Tyrant is an Impostor with {0} additional vote(s). Use them wisely.",
"juggernautPublic": "Juggernaut:\n\nThe Impostors instantly win if the Juggernaut gains {0} kills.",
"speedrunnerPublic": "Speedrunner:\n\nThe Crewmates win if the Speedrunner completes tasks and is alive. The Speedrunner has more tasks.",
"stealerPublic": "Stealer:\n\nThe Stealer gains {0} additional vote(s) per killed player. Votes are rounded down.",
"workhorsePublic": "Workhorse:\n\nThe Workhorse gains {0} additional vote(s) per completed task. Votes are rounded down.",
"jesterPublic": "Jester:\n\nThe Jester is a Crewmate who can also win alone by getting voted.",
"customRoleAnnouncement": "Custom Roles are enabled!\n\nIf you have a Custom Role, it will show in a message below this one.",
"tabGroupCrewmateAbilities": "Crewmate Ability Settings",
"crewmateAbility": "Crewmate (Role) Ability",
"scientistAbility": "Scientist Ability",
"engineerAbility": "Engineer Ability",
"noisemakerAbility": "Noisemaker Ability",
"trackerAbility": "Tracker Ability",
"detectiveAbility": "Detective Ability",
"extraVotesCrewmate": "Extra Votes For Mayor",
"extraVotesPerTask": "Extra Votes Per Task For Workhorse",
"speedrunnerShortTasks": "Short Tasks For Speedrunner",
"speedrunnerLongTasks": "Long Tasks For Speedrunner",
"tabGroupImpostorAbilities": "Impostor Ability Settings",
"impostorAbility": "Impostor (Role) Ability",
"shapeshifterAbility": "Shapeshifter Ability",
"phantomAbility": "Phantom Ability",
"viperAbility": "Viper Ability",
"extraVotesImpostor": "Extra Votes For Tyrant",
"extraVotesPerKill": "Extra Votes Per Kill For Stealer",
"killsNeededForJuggernaut": "Kills Needed For Juggernaut",
"ability": "Ability",
"templateWelcome": "# In this file you can add Templates, which serve as easy copy-paste alternatives.\n# To create a template, write a new line with the same formatting as the test Template below.\n# Note that Templates can't be longer than 120 characters and can't contain special characters. Having so will kick you.\n\ntest: this is an example template. Type '/t test' to see it.",
"moderatorWelcome": "# In this file you can add Moderators by Friendcode.\n# If you add someone, they will gain a purple name in-game.\n# Go to 'System Settings' in-game to customize Moderator permissions. Below is a Friendcode example.\n\nfriendcode#0000",
"vipWelcome": "# In this file you can add VIP's by Friendcode.\n# If you add someone, they will gain a yellow name in-game.\n# Go to 'System Settings' in-game to customize VIP permissions. Below is a Friendcode example.\n\nfriendcode#0000\n",
"adminWelcome": "# In this file you can add Admins by Friendcode.\n# If you add someone, they will gain a red name in-game.\n# Go to 'System Settings' in-game to customize Admin permissions. Below is a Friendcode example.\n\nfriendcode#0000\n",
"banlistWelcome": "# In this file you can ban players from your lobby by Friendcode.\n# Banning someone in-game will automatically add them here as well. Below is a Friendcode example.\n\nfriendcode#0000\n",
"banwordWelcome": "# In this file you can set denied words, automatically kicking anyone in-game who sends words listed here.\n# Make sure to separate words by using new lines.",
"bannameWelcome": "# In this file you can set denied names, automatically kicking anyone in-game who uses names listed here.\n# Make sure to separate names by using new lines.",
"noGameEndWarning": "WARNING: No Game End is enabled"
}