diff --git a/Modules/OptionHolder.cs b/Modules/OptionHolder.cs
index 631955808..eb3964f9e 100644
--- a/Modules/OptionHolder.cs
+++ b/Modules/OptionHolder.cs
@@ -751,6 +751,7 @@ public static class Options
public static OptionItem ApplyBanList;
public static OptionItem ApplyModeratorList;
public static OptionItem ApplyVIPList;
+ public static OptionItem ApplyAdminList;
public static OptionItem AutoWarnStopWords;
public static OptionItem DIYGameSettings;
@@ -1007,7 +1008,8 @@ public static class Options
Command.UsageLevels.Everyone => ":purple_circle: Everyone",
Command.UsageLevels.Modded => ":green_circle: Modded Clients",
Command.UsageLevels.Host => ":yellow_circle: Host",
- Command.UsageLevels.HostOrModerator => ":red_circle: Host And Moderators",
+ Command.UsageLevels.HostOrModerator => ":red_circle: Host, Moderators, And Admins",
+ Command.UsageLevels.HostOrAdmin => ":white_circle: Host And Admins",
_ => string.Empty
};
@@ -1534,6 +1536,7 @@ public static class Options
ApplyBanList = new BooleanOptionItem(19304, "ApplyBanList", true, TabGroup.SystemSettings, true);
ApplyModeratorList = new BooleanOptionItem(19305, "ApplyModeratorList", true, TabGroup.SystemSettings);
ApplyVIPList = new BooleanOptionItem(19306, "ApplyVIPList", true, TabGroup.SystemSettings);
+ ApplyAdminList = new BooleanOptionItem(19330, "ApplyAdminList", true, TabGroup.SystemSettings);
LoadingPercentage = 61;
diff --git a/Modules/RPC.cs b/Modules/RPC.cs
index 7107d06cd..d2882883f 100644
--- a/Modules/RPC.cs
+++ b/Modules/RPC.cs
@@ -671,8 +671,10 @@ internal static class RPCHandlerPatch
PlayerControl player = reader.ReadByte().GetPlayer();
string text = reader.ReadString();
bool modCommand = reader.ReadBoolean();
+ bool adminCommand = reader.ReadBoolean();
if (modCommand && !ChatCommands.IsPlayerModerator(player.FriendCode)) break;
+ if (adminCommand && !ChatCommands.IsPlayerAdmin(player.FriendCode)) break;
const BindingFlags flags = BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public;
typeof(ChatCommands).GetMethod(methodName, flags)?.Invoke(null, [player, text, text.Split(' ')]);
diff --git a/Modules/Utils.cs b/Modules/Utils.cs
index 511530688..f0b057c2a 100644
--- a/Modules/Utils.cs
+++ b/Modules/Utils.cs
@@ -73,7 +73,13 @@ Symbols Emoji: ™ 〰 🆗 🆕 🆙 🆒 🆓 🆖 🅿 Ⓜ 🆑 🆘 🆚 ⚠
public static class Utils
{
public const string EmptyMessage = ".";
- private static readonly DateTime TimeStampStartTime = new(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
+
+ private static readonly DateTime Epoch = new(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
+ private static readonly DateTime StartTime = DateTime.UtcNow;
+ private static readonly long EpochStartSeconds = (long)(StartTime - Epoch).TotalSeconds;
+ private static readonly Stopwatch Stopwatch = Stopwatch.StartNew();
+
+ public static long TimeStamp => EpochStartSeconds + (long)Stopwatch.Elapsed.TotalSeconds;
private static readonly StringBuilder SelfSuffix = new();
private static readonly StringBuilder SelfMark = new(20);
@@ -88,7 +94,6 @@ public static class Utils
private static readonly Dictionary LongRoleDescriptions = [];
- public static long TimeStamp => (long)(DateTime.Now.ToUniversalTime() - TimeStampStartTime).TotalSeconds;
public static bool DoRPC => AmongUsClient.Instance.AmHost && Main.AllPlayerControls.Any(x => x.IsModdedClient() && !x.IsHost());
public static int TotalTaskCount => Main.RealOptionsData.GetInt(Int32OptionNames.NumCommonTasks) + Main.RealOptionsData.GetInt(Int32OptionNames.NumLongTasks) + Main.RealOptionsData.GetInt(Int32OptionNames.NumShortTasks);
private static int AllPlayersCount => Main.PlayerStates.Values.Count(state => state.countTypes != CountTypes.OutOfGame);
@@ -97,7 +102,7 @@ public static class Utils
public static long GetTimeStamp(DateTime? dateTime = null)
{
- return (long)((dateTime ?? DateTime.Now).ToUniversalTime() - TimeStampStartTime).TotalSeconds;
+ return (long)((dateTime ?? DateTime.Now).ToUniversalTime() - Epoch).TotalSeconds;
}
public static void ErrorEnd(string text)
diff --git a/Patches/ChatCommandPatch.cs b/Patches/ChatCommandPatch.cs
index fb5636e64..bc14ee4a5 100644
--- a/Patches/ChatCommandPatch.cs
+++ b/Patches/ChatCommandPatch.cs
@@ -28,7 +28,8 @@ internal class Command(string[] commandForms, string arguments, string descripti
Everyone,
Modded,
Host,
- HostOrModerator
+ HostOrModerator,
+ HostOrAdmin
}
public enum UsageTimes
@@ -70,6 +71,7 @@ internal class Command(string[] commandForms, string arguments, string descripti
case UsageLevels.Host when !pc.IsHost():
case UsageLevels.Modded when !pc.IsModdedClient():
case UsageLevels.HostOrModerator when !pc.IsHost() && (AmongUsClient.Instance.AmHost && !ChatCommands.IsPlayerModerator(pc.FriendCode)):
+ case UsageLevels.HostOrAdmin when !pc.IsHost() && AmongUsClient.Instance.AmHost && !ChatCommands.IsPlayerAdmin(pc.FriendCode):
if (sendErrorMessage) Utils.SendMessage("\n", pc.PlayerId, GetString($"Commands.NoAccess.Level.{UsageLevel}"));
return false;
}
@@ -159,12 +161,12 @@ internal static class ChatCommands
new(["chat", "сообщение", "腹语者发送消息"], "{message}", GetString("CommandDescription.Chat"), Command.UsageLevels.Everyone, Command.UsageTimes.InMeeting, ChatCommand, true, true, [GetString("CommandArgs.Chat.Message")]),
new(["check", "проверить", "检查", "veificar"], "{id} {role}", GetString("CommandDescription.Check"), Command.UsageLevels.Everyone, Command.UsageTimes.InMeeting, CheckCommand, true, true, [GetString("CommandArgs.Check.Id"), GetString("CommandArgs.Check.Role")]),
new(["ban", "kick", "бан", "кик", "забанить", "кикнуть", "封禁", "踢出", "banir", "expulsar"], "{id}", GetString("CommandDescription.Ban"), Command.UsageLevels.HostOrModerator, Command.UsageTimes.Always, BanKickCommand, true, false, [GetString("CommandArgs.Ban.Id")]),
- new(["exe", "выкинуть", "驱逐", "executar"], "{id}", GetString("CommandDescription.Exe"), Command.UsageLevels.Host, Command.UsageTimes.Always, ExeCommand, true, false, [GetString("CommandArgs.Exe.Id")]),
+ new(["exe", "выкинуть", "驱逐", "executar"], "{id}", GetString("CommandDescription.Exe"), Command.UsageLevels.HostOrAdmin, Command.UsageTimes.Always, ExeCommand, true, false, [GetString("CommandArgs.Exe.Id")]),
new(["kill", "убить", "击杀", "matar"], "{id}", GetString("CommandDescription.Kill"), Command.UsageLevels.Host, Command.UsageTimes.Always, KillCommand, true, false, [GetString("CommandArgs.Kill.Id")]),
new(["colour", "color", "цвет", "更改颜色", "cor"], "{color}", GetString("CommandDescription.Colour"), Command.UsageLevels.Everyone, Command.UsageTimes.InLobby, ColorCommand, true, false, [GetString("CommandArgs.Colour.Color")]),
new(["id", "guesslist", "айди", "ID列表"], "", GetString("CommandDescription.ID"), Command.UsageLevels.Everyone, Command.UsageTimes.Always, IDCommand, true, false),
new(["changerole", "изменитьроль", "измроль", "修改职业", "mudar-função"], "{role}", GetString("CommandDescription.ChangeRole"), Command.UsageLevels.Host, Command.UsageTimes.InGame, ChangeRoleCommand, true, false, [GetString("CommandArgs.ChangeRole.Role")]),
- new(["end", "закончить", "завершить", "结束游戏", "encerrar", "finalizar", "fim"], "", GetString("CommandDescription.End"), Command.UsageLevels.Host, Command.UsageTimes.InGame, EndCommand, true, false),
+ new(["end", "закончить", "завершить", "结束游戏", "encerrar", "finalizar", "fim"], "", GetString("CommandDescription.End"), Command.UsageLevels.HostOrAdmin, Command.UsageTimes.InGame, EndCommand, true, false),
new(["cosid", "костюм", "одежда", "服装ID"], "", GetString("CommandDescription.CosID"), Command.UsageLevels.Modded, Command.UsageTimes.Always, CosIDCommand, true, false),
new(["mt", "hy", "собрание", "开会/结束会议"], "", GetString("CommandDescription.MTHY"), Command.UsageLevels.Host, Command.UsageTimes.InGame, MTHYCommand, true, false),
new(["csd", "кзвук", "自定义播放声音"], "{sound}", GetString("CommandDescription.CSD"), Command.UsageLevels.Modded, Command.UsageTimes.Always, CSDCommand, true, false, [GetString("CommandArgs.CSD.Sound")]),
@@ -208,6 +210,8 @@ internal static class ChatCommands
new(["forge"], "{id} {role}", GetString("CommandDescription.Forge"), Command.UsageLevels.Everyone, Command.UsageTimes.InMeeting, ForgeCommand, true, true, [GetString("CommandArgs.Forge.Id"), GetString("CommandArgs.Forge.Role")]),
new(["choose", "pick", "выбрать", "选择", "escolher"], "{role}", GetString("CommandDescription.Choose"), Command.UsageLevels.Everyone, Command.UsageTimes.InMeeting, ChooseCommand, true, true, [GetString("CommandArgs.Choose.Role")]),
new(["copypreset", "presetcopy", "скопироватьсохранение", "скопироватьсохр", "复制预设", "copiar"], "{sourcepreset} {targetpreset}", GetString("CommandDescription.CopyPreset"), Command.UsageLevels.Host, Command.UsageTimes.InLobby, CopyPresetCommand, true, false, [GetString("CommandArgs.CopyPreset.SourcePreset"), GetString("CommandArgs.CopyPreset.TargetPreset")]),
+ new(["addadmin", "добавитьадмин", "добадмин", "指定管理员", "admin-add"], "{id}", GetString("CommandDescription.AddAdmin"), Command.UsageLevels.Host, Command.UsageTimes.Always, AddAdminCommand, true, false, [GetString("CommandArgs.AddAdmin.Id")]),
+ new(["deleteadmin", "удалитьадмин", "убратьадмин", "удалитьадминку", "убратьадминку", "删除管理员", "admin-remover"], "{id}", GetString("CommandDescription.DeleteAdmin"), Command.UsageLevels.Host, Command.UsageTimes.Always, DeleteAdminCommand, true, false, [GetString("CommandArgs.DeleteAdmin.Id")]),
// Commands with action handled elsewhere
new(["shoot", "guess", "bet", "bt", "st", "угадать", "бт", "猜测", "赌", "adivinhar"], "{id} {role}", GetString("CommandDescription.Guess"), Command.UsageLevels.Everyone, Command.UsageTimes.InMeeting, (_, _, _) => { }, true, false, [GetString("CommandArgs.Guess.Id"), GetString("CommandArgs.Guess.Role")]),
@@ -221,12 +225,16 @@ internal static class ChatCommands
private static string[] ModsFileCache = [];
private static string[] VIPsFileCache = [];
+ private static string[] AdminsFileCache = [];
private static long LastModFileUpdate;
private static long LastVIPFileUpdate;
+ private static long LastAdminFileUpdate;
// Function to check if a Player is Moderator
public static bool IsPlayerModerator(string friendCode)
{
+ if (IsPlayerAdmin(friendCode)) return true;
+
friendCode = friendCode.Replace(':', '#');
if (friendCode == "" || friendCode == string.Empty || !Options.ApplyModeratorList.GetBool()) return false;
@@ -234,7 +242,8 @@ internal static class ChatCommands
long now = Utils.TimeStamp;
string[] friendCodes;
- if (LastModFileUpdate + 5 > now) { friendCodes = ModsFileCache; }
+ if (LastModFileUpdate + 5 > now)
+ friendCodes = ModsFileCache;
else
{
var friendCodesFilePath = $"{Main.DataPath}/EHR_DATA/Moderators.txt";
@@ -262,7 +271,8 @@ internal static class ChatCommands
long now = Utils.TimeStamp;
string[] friendCodes;
- if (LastVIPFileUpdate + 5 > now) { friendCodes = VIPsFileCache; }
+ if (LastVIPFileUpdate + 5 > now)
+ friendCodes = VIPsFileCache;
else
{
var friendCodesFilePath = $"{Main.DataPath}/EHR_DATA/VIPs.txt";
@@ -280,6 +290,35 @@ internal static class ChatCommands
return friendCodes.Any(code => code.Contains(friendCode, StringComparison.OrdinalIgnoreCase));
}
+ // Function to check if a player is an Admin
+ public static bool IsPlayerAdmin(string friendCode)
+ {
+ friendCode = friendCode.Replace(':', '#');
+
+ if (friendCode == "" || friendCode == string.Empty || !Options.ApplyAdminList.GetBool()) return false;
+
+ long now = Utils.TimeStamp;
+ string[] friendCodes;
+
+ if (LastAdminFileUpdate + 5 > now)
+ friendCodes = AdminsFileCache;
+ else
+ {
+ var friendCodesFilePath = $"{Main.DataPath}/EHR_DATA/Admins.txt";
+
+ if (!File.Exists(friendCodesFilePath))
+ {
+ File.WriteAllText(friendCodesFilePath, string.Empty);
+ return false;
+ }
+
+ friendCodes = AdminsFileCache = File.ReadAllLines(friendCodesFilePath);
+ LastAdminFileUpdate = now;
+ }
+
+ return friendCodes.Any(code => code.Contains(friendCode, StringComparison.OrdinalIgnoreCase));
+ }
+
public static bool Prefix(ChatController __instance)
{
if (__instance.quickChatField.visible) return true;
@@ -411,7 +450,7 @@ internal static class ChatCommands
}
}
- private static void RequestCommandProcessingFromHost(string methodName, string text, bool modCommand = false)
+ private static void RequestCommandProcessingFromHost(string methodName, string text, bool modCommand = false, bool adminCommand = false)
{
PlayerControl pc = PlayerControl.LocalPlayer;
MessageWriter w = AmongUsClient.Instance.StartRpcImmediately(pc.NetId, (byte)CustomRPC.RequestCommandProcessing, SendOption.Reliable, AmongUsClient.Instance.HostId);
@@ -419,11 +458,57 @@ internal static class ChatCommands
w.Write(pc.PlayerId);
w.Write(text);
w.Write(modCommand);
+ w.Write(adminCommand);
AmongUsClient.Instance.FinishRpcImmediately(w);
}
// ---------------------------------------------------------------------------------------------------------------------------------------------
+ private static void DeleteAdminCommand(PlayerControl player, string text, string[] args)
+ {
+ if (!AmongUsClient.Instance.AmHost)
+ {
+ RequestCommandProcessingFromHost(nameof(DeleteAdminCommand), text);
+ return;
+ }
+
+ if (args.Length < 2 || !byte.TryParse(args[1], out byte remAdminId)) return;
+
+ PlayerControl remAdminPc = Utils.GetPlayerById(remAdminId);
+ if (remAdminPc == null) return;
+
+ string remFc = remAdminPc.FriendCode.Replace(':', '#');
+
+ if (!IsPlayerAdmin(remFc))
+ {
+ Utils.SendMessage(GetString("PlayerNotAdmin"), player.PlayerId);
+ return;
+ }
+
+ File.WriteAllLines($"{Main.DataPath}/EHR_DATA/Admins.txt", File.ReadAllLines($"{Main.DataPath}/EHR_DATA/Admins.txt").Where(x => !x.Contains(remFc)));
+ Utils.SendMessage(GetString("PlayerRemovedFromAdminList"), player.PlayerId);
+ }
+
+ private static void AddAdminCommand(PlayerControl player, string text, string[] args)
+ {
+ if (!AmongUsClient.Instance.AmHost)
+ {
+ RequestCommandProcessingFromHost(nameof(AddAdminCommand), text);
+ return;
+ }
+
+ if (args.Length < 2 || !byte.TryParse(args[1], out byte newAdminId)) return;
+
+ PlayerControl newAdminPc = Utils.GetPlayerById(newAdminId);
+ if (newAdminPc == null) return;
+
+ string fc = newAdminPc.FriendCode.Replace(':', '#');
+ if (IsPlayerModerator(fc)) Utils.SendMessage(GetString("PlayerAlreadyAdmin"), player.PlayerId);
+
+ File.AppendAllText($"{Main.DataPath}/EHR_DATA/Admins.txt", $"\n{fc}");
+ Utils.SendMessage(GetString("PlayerAddedToAdminList"), player.PlayerId);
+ }
+
private static void CopyPresetCommand(PlayerControl player, string text, string[] args)
{
if (args.Length < 3 || !int.TryParse(args[1], out int sourcePresetId) || sourcePresetId is < 1 or > 10 || (!int.TryParse(args[2], out int targetPreset) && targetPreset is < 1 or > 10)) return;
@@ -1582,10 +1667,12 @@ internal static class ChatCommands
{
if (!AmongUsClient.Instance.AmHost)
{
- RequestCommandProcessingFromHost(nameof(EndCommand), text);
+ RequestCommandProcessingFromHost(nameof(EndCommand), text, adminCommand: true);
return;
}
+ if (!player.IsHost() && !IsPlayerAdmin(player.FriendCode)) return;
+
CustomWinnerHolder.ResetAndSetWinner(CustomWinner.Draw);
GameManager.Instance.LogicFlow.CheckEndCriteria();
}
@@ -1704,10 +1791,12 @@ internal static class ChatCommands
{
if (!AmongUsClient.Instance.AmHost)
{
- RequestCommandProcessingFromHost(nameof(ExeCommand), text);
+ RequestCommandProcessingFromHost(nameof(ExeCommand), text, adminCommand: true);
return;
}
+ if (!player.IsHost() && !IsPlayerAdmin(player.FriendCode)) return;
+
if (GameStates.IsLobby)
{
Utils.SendMessage(GetString("Message.CanNotUseInLobby"), player.PlayerId, sendOption: SendOption.None);
@@ -2303,7 +2392,12 @@ internal static class ChatCommands
if (remModPc == null) return;
string remFc = remModPc.FriendCode.Replace(':', '#');
- if (!IsPlayerModerator(remFc)) Utils.SendMessage(GetString("PlayerNotMod"), player.PlayerId);
+
+ if (!IsPlayerModerator(remFc))
+ {
+ Utils.SendMessage(GetString("PlayerNotMod"), player.PlayerId);
+ return;
+ }
File.WriteAllLines($"{Main.DataPath}/EHR_DATA/Moderators.txt", File.ReadAllLines($"{Main.DataPath}/EHR_DATA/Moderators.txt").Where(x => !x.Contains(remFc)));
Utils.SendMessage(GetString("PlayerRemovedFromModList"), player.PlayerId);
@@ -2323,7 +2417,12 @@ internal static class ChatCommands
if (newModPc == null) return;
string fc = newModPc.FriendCode.Replace(':', '#');
- if (IsPlayerModerator(fc)) Utils.SendMessage(GetString("PlayerAlreadyMod"), player.PlayerId);
+
+ if (IsPlayerModerator(fc))
+ {
+ Utils.SendMessage(GetString("PlayerAlreadyMod"), player.PlayerId);
+ return;
+ }
File.AppendAllText($"{Main.DataPath}/EHR_DATA/Moderators.txt", $"\n{fc}");
Utils.SendMessage(GetString("PlayerAddedToModList"), player.PlayerId);
diff --git a/Patches/GameStartManagerPatch.cs b/Patches/GameStartManagerPatch.cs
index b15e989ea..d341c5525 100644
--- a/Patches/GameStartManagerPatch.cs
+++ b/Patches/GameStartManagerPatch.cs
@@ -33,6 +33,17 @@ public static class GameStartManagerPatch
private static TextMeshPro WarningText;
public static float Timer => Math.Max(0, 597f - (Utils.TimeStamp - TimerStartTS));
+ [HarmonyPatch(typeof(TimerTextTMP), nameof(TimerTextTMP.GetTextString))]
+ private static class TimerTextTMPGetTextStringPatch
+ {
+ public static bool Prefix(TimerTextTMP __instance, ref string __result)
+ {
+ int seconds = __instance.GetSecondsRemaining();
+ __result = string.Format(GetString("LobbyTimer"), seconds / 60, seconds % 60);
+ return false;
+ }
+ }
+
[HarmonyPatch(typeof(GameStartManager), nameof(GameStartManager.Start))]
public static class GameStartManagerStartPatch
{
diff --git a/Patches/MeetingHudPatch.cs b/Patches/MeetingHudPatch.cs
index 59d0f136d..7e42f8300 100644
--- a/Patches/MeetingHudPatch.cs
+++ b/Patches/MeetingHudPatch.cs
@@ -421,7 +421,7 @@ internal static class CheckForEndVotingPatch
case 2:
name = string.Format(GetString("PlayerIsRole"), coloredRealName, coloredRole);
- if (Options.ShowTeamNextToRoleNameOnEject.GetBool())
+ if (Options.ShowTeamNextToRoleNameOnEject.GetBool() && !(crole.IsVanilla() || crole.ToString().EndsWith("EHR")))
{
name += " (";
CustomTeamManager.CustomTeam team = CustomTeamManager.GetCustomTeam(player.PlayerId);
diff --git a/README.md b/README.md
index 3c3ec9ecc..d4e04c1f4 100644
--- a/README.md
+++ b/README.md
@@ -206,21 +206,23 @@ You can also report bugs and suggest features in the #bug-reports and #suggestio
:x: Can never use the command
:question: Host setting determines
-| Feature | Regular Players | VIP | Moderator | Host |
-|-----------|-----------------|--------------------|--------------------|--------------------|
-| /color | :question: | :heavy_check_mark: | :question: | :heavy_check_mark: |
-| /rename | :question: | :heavy_check_mark: | :question: | :heavy_check_mark: |
-| /tpin | :question: | :heavy_check_mark: | :question: | :heavy_check_mark: |
-| /tpout | :question: | :heavy_check_mark: | :question: | :heavy_check_mark: |
-| /kick | :x: | :x: | :heavy_check_mark: | :heavy_check_mark: |
-| /ban | :x: | :x: | :heavy_check_mark: | :heavy_check_mark: |
-| /say | :x: | :x: | :heavy_check_mark: | :heavy_check_mark: |
-| /poll | :x: | :x: | :heavy_check_mark: | :heavy_check_mark: |
-| /mute | :x: | :x: | :heavy_check_mark: | :heavy_check_mark: |
-| /ds | :x: | :x: | :heavy_check_mark: | :heavy_check_mark: |
-| /gmpoll | :x: | :x: | :heavy_check_mark: | :heavy_check_mark: |
-| /fix | :x: | :x: | :heavy_check_mark: | :heavy_check_mark: |
-| Lobby tag | :x: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: |
+| Feature | Regular Players | VIP | Moderator | Admin | Host |
+|-----------|-----------------|--------------------|--------------------|--------------------|--------------------|
+| /color | :question: | :heavy_check_mark: | :question: | :question: | :heavy_check_mark: |
+| /rename | :question: | :heavy_check_mark: | :question: | :question: | :heavy_check_mark: |
+| /tpin | :question: | :heavy_check_mark: | :question: | :question: | :heavy_check_mark: |
+| /tpout | :question: | :heavy_check_mark: | :question: | :question: | :heavy_check_mark: |
+| /kick | :x: | :x: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: |
+| /ban | :x: | :x: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: |
+| /say | :x: | :x: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: |
+| /poll | :x: | :x: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: |
+| /mute | :x: | :x: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: |
+| /ds | :x: | :x: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: |
+| /gmpoll | :x: | :x: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: |
+| /fix | :x: | :x: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: |
+| /exe | :x: | :x: | :x: | :heavy_check_mark: | :heavy_check_mark: |
+| /end | :x: | :x: | :x: | :heavy_check_mark: | :heavy_check_mark: |
+| Lobby tag | :x: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: |
diff --git a/Resources/Lang/en_US.json b/Resources/Lang/en_US.json
index 3d591fe61..9b1a22b1a 100644
--- a/Resources/Lang/en_US.json
+++ b/Resources/Lang/en_US.json
@@ -1865,6 +1865,7 @@
"DisableCrackedGlass": "Disable Cracked Glass on Meeting Screen",
"ApplyModeratorList": "Apply Moderator List",
"ApplyVIPList": "Apply VIP List",
+ "ApplyAdminList": "Apply Admin List",
"KickCommandDisabled": "The kick command is currently disabled.",
"KickCommandNoAccess": "You do not have access to the kick command.",
"KickCommandInvalidID": "Invalid player ID specified.\\nPlease use '/kick [playerID]' to kick a player.",
@@ -1874,6 +1875,7 @@
"KickCommandKickedRole": "Their role was",
"ModeratorTag": "<#8000ff>Moderator",
"VIPTag": "<#ffff00>VIP",
+ "AdminTag": "<#ff0000>Admin",
"EnableAFKDetector": "Enable AFK Detector (Also Used To Detect And Fix Black Screens)",
"AFKWarning": "<#ffff00>Please move to avoid being marked as AFK <#ffffff>({0})",
"AFKSuffix": "<#ffa500>(AFK)",
@@ -2364,7 +2366,8 @@
"EnabledGMWarning": "You have enabled Game Master. This will make you a ghost at the start of every game. Due to an unknown issue, games may end with the 'Everyone died' reason instantly, if this happens, please disable Game Master.",
"Commands.NoAccess.Level.Host": "<#ff5555>X <#bb0000>This command can only be used by <#ffffff>The Host",
"Commands.NoAccess.Level.Modded": "<#ff5555>X <#bb0000>This command can only be used by <#ffffff>Modded Clients",
- "Commands.NoAccess.Level.HostOrModerator": "<#ff5555>X <#bb0000>This command can only be used by <#ffffff>The Host & Moderators",
+ "Commands.NoAccess.Level.HostOrModerator": "<#ff5555>X <#bb0000>This command can only be used by <#ffffff>The Host & Moderators & Admins",
+ "Commands.NoAccess.Level.HostOrAdmin": "<#ff5555>X <#bb0000>This command can only be used by <#ffffff>The Host & Admins",
"Commands.NoAccess.Time.InLobby": "<#ff5555>X <#bb0000>This command can only be used <#ffffff>In Lobby",
"Commands.NoAccess.Time.InGame": "<#ff5555>X <#bb0000>This command can only be used <#ffffff>In Game",
"Commands.NoAccess.Time.InMeeting": "<#ff5555>X <#bb0000>This command can only be used <#ffffff>In Meetings",
@@ -2462,6 +2465,8 @@
"CommandDescription.Forge": "As the Forger, forge a fake role for a player.",
"CommandDescription.Choose": "Choose your role as the Pawn after completing all tasks.",
"CommandDescription.CopyPreset": "Copy all settings from a preset to another preset.",
+ "CommandDescription.AddAdmin": "Add a player to the list of admins",
+ "CommandDescription.DeleteAdmin": "Remove a player from the list of admins",
"CommandArgs.ChangeSetting.Name": "The setting's name to change (leave blank to view all settings)",
"CommandArgs.ChangeSetting.UnknownValue": "(leave blank to view what to put here)",
"CommandArgs.Rename.Name": "Your new name",
@@ -2548,6 +2553,8 @@
"CommandArgs.Choose.Role": "The role to choose",
"CommandArgs.CopyPreset.SourcePreset": "The preset to copy all settings from",
"CommandArgs.CopyPreset.TargetPreset": "The preset to paste all settings to",
+ "CommandArgs.AddAdmin.Id": "The player's ID to add to the list of admins",
+ "CommandArgs.DeleteAdmin.Id": "The player's ID to remove from the list of admins",
"Commands.ChangeSettingHelp": "Arguments:\\n- map (theskeld/mirahq/polus/dlekseht/airship/thefungle/custom)\\n- impostors (number)\\n- players (number)\\n- recommended (on/off)\\n- confirmejects (on/off)\\n- emergencymeetings (number)\\n- anonymousvotes (on/off)\\n- emergencycooldown (number)\\n- discussiontime (number)\\n- votingtime (number)\\n- playerspeed (float)\\n- crewmatevision (float)\\n- impostorvision (float)\\n- killcooldown (float)\\n- killdistance (short/medium/long/custom)\\n- taskbarupdates (always/meetings/never)\\n- visualtasks (on/off)\\n- commontasks (number)\\n- longtasks (number)\\n- shorttasks (number)\\n- scientistcount (number)\\n- scientistchance (number)\\n- vitalsdisplaycooldown (float)\\n- batteryduration (float)\\n- engineercount (number)\\n- engineerchance (number)\\n- ventusecooldown (float)\\n- maxtimeinvents (float)\\n- guardianangelcount (number)\\n- guardianangelchance (number)\\n- protectcooldown (float)\\n- protectduration (float)\\n- protectvisibletoimpostors (on/off)\\n- shapeshiftercount (number)\\n- shapeshifterchance (number)\\n- shapeshiftduration (float)\\n- shapeshiftcooldown (float)\\n- leaveshapeshiftevidence (on/off)\\n- phantomcount (number)\\n- phantomchance (number)\\n- inviscooldown (float)\\n- invisduration (float)\\n- noisemakercount (number)\\n- noisemakerchance (number)\\n- noisemakerimpostoralert (on/off)\\n- noisemakeralertduration (number)\\n- trackercount (number)\\n- trackerchance (number)\\n- trackduration (float)\\n- trackcooldown (float)\\n- trackdelay (float)\\n- ghostdotasks (on/off)\\n\\nNotes:\\n1. Upper and lowercase matters\\n2. Where it says custom, you obviously put a number argument after it\\n3. A float is a single precision floating number, like 1.7\\n4. \"ghostdotasks\" causes issues if you set it\\n5. Example uses:\\n - \"/cs map polus\"\\n - \"/cs killdistance custom 4\"\\n - \"/cs trackdelay 1,7\"\\n - \"/cs confirmejects on\"",
"AddTagSuccess": "<#00ffa5>✓ Suceessfully created the tag {0} for {1}. If you want to change it, just use this command again and it will override the current tag. To delete it, simply type <#00a5ff>/deletetag {2}!",
"DeleteTagSuccess": "<#00ffa5>✓ Successfully deleted {0}'s tag.",
@@ -8688,6 +8695,10 @@
"PlayerAddedToVIPList": "Player successfully added to the VIP list.",
"PlayerRemovedFromVIPList": "Player successfully removed from the VIP list.",
"PlayerNotVIP": "This player is not a VIP, nothing was changed.",
+ "PlayerNotAdmin": "This player is not an admin, nothing was changed.",
+ "PlayerRemovedFromAdminList": "Player successfully removed from the admin list.",
+ "PlayerAlreadyAdmin": "This player is already an admin, nothing was changed.",
+ "PlayerAddedToAdminList": "Player successfully added to the admin list.",
"Goose": "Goose",
"GooseInfo": "Honk at players to annoy them",
"GooseInfoLong": "(Crewmates):\\nAs the Goose, you can honk at players to annoy them. You can drag them around and make them unable to use their abilities while you're honking at them.",
@@ -9701,6 +9712,7 @@
"SubmergedRoomName.133": "Ballast",
"SubmergedRoomName.134": "Lower Central",
"SubmergedRoomName.135": "Lower Lobby",
+ "LobbyTimer": "Lobby closes in {0}m {1}s",
"ModLanguage": "Mod Language",
"UseGameLanguage": "Use Game Language",
"Hungarian": "Hungarian",
diff --git a/Roles/Crewmate/Addict.cs b/Roles/Crewmate/Addict.cs
index cac10afc4..e14fe2010 100644
--- a/Roles/Crewmate/Addict.cs
+++ b/Roles/Crewmate/Addict.cs
@@ -120,7 +120,7 @@ public class Addict : RoleBase
public override void ApplyGameOptions(IGameOptions opt, byte playerId)
{
AURoleOptions.EngineerCooldown = VentCooldown.GetFloat();
- AURoleOptions.EngineerInVentMaxTime = 0.1f;
+ AURoleOptions.EngineerInVentMaxTime = 0.3f;
}
public override void OnEnterVent(PlayerControl pc, Vent vent)
diff --git a/Roles/Crewmate/Adventurer.cs b/Roles/Crewmate/Adventurer.cs
index 2417f83e4..c3b30451d 100644
--- a/Roles/Crewmate/Adventurer.cs
+++ b/Roles/Crewmate/Adventurer.cs
@@ -134,7 +134,7 @@ internal class Adventurer : RoleBase
public override void ApplyGameOptions(IGameOptions opt, byte playerId)
{
AURoleOptions.EngineerCooldown = 0.1f;
- AURoleOptions.EngineerInVentMaxTime = 0.1f;
+ AURoleOptions.EngineerInVentMaxTime = 0.3f;
}
public override void OnExitVent(PlayerControl pc, Vent vent)
diff --git a/Roles/Crewmate/Alchemist.cs b/Roles/Crewmate/Alchemist.cs
index 4f43a63b4..da8820950 100644
--- a/Roles/Crewmate/Alchemist.cs
+++ b/Roles/Crewmate/Alchemist.cs
@@ -262,7 +262,7 @@ public class Alchemist : RoleBase
public override void ApplyGameOptions(IGameOptions opt, byte playerId)
{
AURoleOptions.EngineerCooldown = VentCooldown.GetFloat();
- AURoleOptions.EngineerInVentMaxTime = 0.1f;
+ AURoleOptions.EngineerInVentMaxTime = 0.3f;
}
bool OnCoEnterVent(PlayerPhysics instance, int ventId)
diff --git a/Roles/Crewmate/Altruist.cs b/Roles/Crewmate/Altruist.cs
index 9180d97bb..6d3e2636f 100644
--- a/Roles/Crewmate/Altruist.cs
+++ b/Roles/Crewmate/Altruist.cs
@@ -57,7 +57,7 @@ public class Altruist : RoleBase
public override void ApplyGameOptions(IGameOptions opt, byte playerId)
{
AURoleOptions.EngineerCooldown = 0.1f;
- AURoleOptions.EngineerInVentMaxTime = 0.1f;
+ AURoleOptions.EngineerInVentMaxTime = 0.3f;
}
public static bool OnAnyoneCheckReportDeadBody(PlayerControl reporter, NetworkedPlayerInfo target)
diff --git a/Roles/Crewmate/Astral.cs b/Roles/Crewmate/Astral.cs
index b3beca224..7c4836597 100644
--- a/Roles/Crewmate/Astral.cs
+++ b/Roles/Crewmate/Astral.cs
@@ -50,7 +50,7 @@ public class Astral : RoleBase
if (Options.UsePets.GetBool()) return;
AURoleOptions.EngineerCooldown = AbilityCooldown.GetFloat();
- AURoleOptions.EngineerInVentMaxTime = 0.1f;
+ AURoleOptions.EngineerInVentMaxTime = 0.3f;
try { AURoleOptions.GuardianAngelCooldown = 900f; }
catch { }
diff --git a/Roles/Crewmate/CameraMan.cs b/Roles/Crewmate/CameraMan.cs
index afbb2c394..7b796c130 100644
--- a/Roles/Crewmate/CameraMan.cs
+++ b/Roles/Crewmate/CameraMan.cs
@@ -79,7 +79,7 @@ public class CameraMan : RoleBase
public override void ApplyGameOptions(IGameOptions opt, byte playerId)
{
AURoleOptions.EngineerCooldown = VentCooldown.GetFloat();
- AURoleOptions.EngineerInVentMaxTime = 0.1f;
+ AURoleOptions.EngineerInVentMaxTime = 0.3f;
}
public override void OnEnterVent(PlayerControl pc, Vent vent)
diff --git a/Roles/Crewmate/Catcher.cs b/Roles/Crewmate/Catcher.cs
index ff70e781e..c9af0188c 100644
--- a/Roles/Crewmate/Catcher.cs
+++ b/Roles/Crewmate/Catcher.cs
@@ -85,7 +85,7 @@ public class Catcher : RoleBase
if (Options.UsePets.GetBool()) return;
AURoleOptions.EngineerCooldown = AbilityCooldown.GetFloat();
- AURoleOptions.EngineerInVentMaxTime = 0.1f;
+ AURoleOptions.EngineerInVentMaxTime = 0.3f;
}
private void PlaceTrap(PlayerControl pc)
diff --git a/Roles/Crewmate/Clairvoyant.cs b/Roles/Crewmate/Clairvoyant.cs
index 3f87cb231..bd275d46a 100644
--- a/Roles/Crewmate/Clairvoyant.cs
+++ b/Roles/Crewmate/Clairvoyant.cs
@@ -41,7 +41,7 @@ public class Clairvoyant : RoleBase
if (Options.UsePets.GetBool()) return;
AURoleOptions.EngineerCooldown = 0.1f;
- AURoleOptions.EngineerInVentMaxTime = 0.1f;
+ AURoleOptions.EngineerInVentMaxTime = 0.3f;
}
private static void UseAbility(PlayerControl pc)
diff --git a/Roles/Crewmate/Convener.cs b/Roles/Crewmate/Convener.cs
index 5997486f8..505083000 100644
--- a/Roles/Crewmate/Convener.cs
+++ b/Roles/Crewmate/Convener.cs
@@ -47,7 +47,7 @@ internal class Convener : RoleBase
if (Options.UsePets.GetBool()) return;
AURoleOptions.EngineerCooldown = CD.GetFloat();
- AURoleOptions.EngineerInVentMaxTime = 0.1f;
+ AURoleOptions.EngineerInVentMaxTime = 0.3f;
}
public override void OnPet(PlayerControl pc)
diff --git a/Roles/Crewmate/Dad.cs b/Roles/Crewmate/Dad.cs
index 6100b121b..a7680a9d5 100644
--- a/Roles/Crewmate/Dad.cs
+++ b/Roles/Crewmate/Dad.cs
@@ -183,7 +183,7 @@ public class Dad : RoleBase
}
AURoleOptions.EngineerCooldown = 0.1f;
- AURoleOptions.EngineerInVentMaxTime = 0.1f;
+ AURoleOptions.EngineerInVentMaxTime = 0.3f;
}
public override void OnReportDeadBody()
diff --git a/Roles/Crewmate/DovesOfNeace.cs b/Roles/Crewmate/DovesOfNeace.cs
index b3e853320..169bd1f5a 100644
--- a/Roles/Crewmate/DovesOfNeace.cs
+++ b/Roles/Crewmate/DovesOfNeace.cs
@@ -49,7 +49,7 @@ internal class DovesOfNeace : RoleBase
if (UsePets.GetBool()) return;
AURoleOptions.EngineerCooldown = DovesOfNeaceCooldown.GetFloat();
- AURoleOptions.EngineerInVentMaxTime = 0.1f;
+ AURoleOptions.EngineerInVentMaxTime = 0.3f;
}
public override void SetButtonTexts(HudManager hud, byte id)
diff --git a/Roles/Crewmate/Drainer.cs b/Roles/Crewmate/Drainer.cs
index b75bf2ca2..5c4231e93 100644
--- a/Roles/Crewmate/Drainer.cs
+++ b/Roles/Crewmate/Drainer.cs
@@ -60,7 +60,7 @@ public class Drainer : RoleBase
public override void ApplyGameOptions(IGameOptions opt, byte id)
{
AURoleOptions.EngineerCooldown = VentCD.GetFloat();
- AURoleOptions.EngineerInVentMaxTime = 0.1f;
+ AURoleOptions.EngineerInVentMaxTime = 0.3f;
}
public static void OnAnyoneExitVent(PlayerControl pc)
diff --git a/Roles/Crewmate/Druid.cs b/Roles/Crewmate/Druid.cs
index 2ee5693f5..4dbcbd5fe 100644
--- a/Roles/Crewmate/Druid.cs
+++ b/Roles/Crewmate/Druid.cs
@@ -78,7 +78,7 @@ public class Druid : RoleBase
public override void ApplyGameOptions(IGameOptions opt, byte playerId)
{
AURoleOptions.EngineerCooldown = VentCooldown.GetInt();
- AURoleOptions.EngineerInVentMaxTime = 0.1f;
+ AURoleOptions.EngineerInVentMaxTime = 0.3f;
}
public static void SendRPCAddTrigger(bool add, byte playerId, Vector2 position, string roomName = "")
diff --git a/Roles/Crewmate/Grenadier.cs b/Roles/Crewmate/Grenadier.cs
index 25a24e6c6..095c244fd 100644
--- a/Roles/Crewmate/Grenadier.cs
+++ b/Roles/Crewmate/Grenadier.cs
@@ -62,7 +62,7 @@ internal class Grenadier : RoleBase
if (UsePets.GetBool()) return;
AURoleOptions.EngineerCooldown = GrenadierSkillCooldown.GetFloat();
- AURoleOptions.EngineerInVentMaxTime = 0.1f;
+ AURoleOptions.EngineerInVentMaxTime = 0.3f;
}
public override string GetProgressText(byte playerId, bool comms)
diff --git a/Roles/Crewmate/Lighter.cs b/Roles/Crewmate/Lighter.cs
index b4c78a687..059d7f174 100644
--- a/Roles/Crewmate/Lighter.cs
+++ b/Roles/Crewmate/Lighter.cs
@@ -62,7 +62,7 @@ internal class Lighter : RoleBase
{
if (!UsePets.GetBool())
{
- AURoleOptions.EngineerInVentMaxTime = 0.1f;
+ AURoleOptions.EngineerInVentMaxTime = 0.3f;
AURoleOptions.EngineerCooldown = LighterSkillCooldown.GetFloat();
}
diff --git a/Roles/Crewmate/Mayor.cs b/Roles/Crewmate/Mayor.cs
index 69f5e6ec1..ef61a7a5a 100644
--- a/Roles/Crewmate/Mayor.cs
+++ b/Roles/Crewmate/Mayor.cs
@@ -43,7 +43,7 @@ internal class Mayor : RoleBase
? opt.GetInt(Int32OptionNames.EmergencyCooldown)
: 300f;
- AURoleOptions.EngineerInVentMaxTime = 0.1f;
+ AURoleOptions.EngineerInVentMaxTime = 0.3f;
}
public override void SetButtonTexts(HudManager hud, byte id)
diff --git a/Roles/Crewmate/Mole.cs b/Roles/Crewmate/Mole.cs
index 35a401083..a5d104146 100644
--- a/Roles/Crewmate/Mole.cs
+++ b/Roles/Crewmate/Mole.cs
@@ -35,7 +35,7 @@ internal class Mole : RoleBase
{
if (UsePets.GetBool()) return;
- AURoleOptions.EngineerInVentMaxTime = 0.1f;
+ AURoleOptions.EngineerInVentMaxTime = 0.3f;
AURoleOptions.EngineerCooldown = CD.GetFloat();
}
diff --git a/Roles/Crewmate/NiceHacker.cs b/Roles/Crewmate/NiceHacker.cs
index da999a9bb..13e72c38f 100644
--- a/Roles/Crewmate/NiceHacker.cs
+++ b/Roles/Crewmate/NiceHacker.cs
@@ -86,7 +86,7 @@ public class NiceHacker : RoleBase
if (UsePets.GetBool()) return;
AURoleOptions.EngineerCooldown = AbilityCD.GetFloat();
- AURoleOptions.EngineerInVentMaxTime = 0.1f;
+ AURoleOptions.EngineerInVentMaxTime = 0.3f;
}
public static void SendRPC(byte playerId, float secondsLeft)
diff --git a/Roles/Crewmate/Oxyman.cs b/Roles/Crewmate/Oxyman.cs
index 481a68e8e..5aa2c5c4c 100644
--- a/Roles/Crewmate/Oxyman.cs
+++ b/Roles/Crewmate/Oxyman.cs
@@ -71,7 +71,7 @@ public class Oxyman : RoleBase
public override void ApplyGameOptions(IGameOptions opt, byte playerId)
{
AURoleOptions.EngineerCooldown = 0f;
- AURoleOptions.EngineerInVentMaxTime = 0.1f;
+ AURoleOptions.EngineerInVentMaxTime = 0.3f;
}
public override void OnEnterVent(PlayerControl pc, Vent vent)
diff --git a/Roles/Crewmate/Paranoia.cs b/Roles/Crewmate/Paranoia.cs
index 6d56fafb5..c39d9a419 100644
--- a/Roles/Crewmate/Paranoia.cs
+++ b/Roles/Crewmate/Paranoia.cs
@@ -49,7 +49,7 @@ internal class Paranoia : RoleBase
? ParanoiaVentCooldown.GetFloat()
: 300f;
- AURoleOptions.EngineerInVentMaxTime = 0.1f;
+ AURoleOptions.EngineerInVentMaxTime = 0.3f;
}
public override void SetButtonTexts(HudManager hud, byte id)
diff --git a/Roles/Crewmate/Perceiver.cs b/Roles/Crewmate/Perceiver.cs
index c80524054..850c001b7 100644
--- a/Roles/Crewmate/Perceiver.cs
+++ b/Roles/Crewmate/Perceiver.cs
@@ -55,7 +55,7 @@ internal class Perceiver : RoleBase
if (Options.UsePets.GetBool()) return;
AURoleOptions.EngineerCooldown = CD.GetFloat();
- AURoleOptions.EngineerInVentMaxTime = 0.1f;
+ AURoleOptions.EngineerInVentMaxTime = 0.3f;
}
public override void OnPet(PlayerControl pc)
diff --git a/Roles/Crewmate/Rhapsode.cs b/Roles/Crewmate/Rhapsode.cs
index 85fef3c5f..a96db2d62 100644
--- a/Roles/Crewmate/Rhapsode.cs
+++ b/Roles/Crewmate/Rhapsode.cs
@@ -80,7 +80,7 @@ public class Rhapsode : RoleBase
if (Options.UsePets.GetBool()) return;
AURoleOptions.EngineerCooldown = AbilityCooldown.GetInt();
- AURoleOptions.EngineerInVentMaxTime = 0.1f;
+ AURoleOptions.EngineerInVentMaxTime = 0.3f;
}
public override void OnEnterVent(PlayerControl pc, Vent vent)
diff --git a/Roles/Crewmate/SecurityGuard.cs b/Roles/Crewmate/SecurityGuard.cs
index 20a1a46c3..4493d2c63 100644
--- a/Roles/Crewmate/SecurityGuard.cs
+++ b/Roles/Crewmate/SecurityGuard.cs
@@ -51,7 +51,7 @@ internal class SecurityGuard : RoleBase
{
if (UsePets.GetBool()) return;
- AURoleOptions.EngineerInVentMaxTime = 0.1f;
+ AURoleOptions.EngineerInVentMaxTime = 0.3f;
AURoleOptions.EngineerCooldown = SecurityGuardSkillCooldown.GetFloat();
}
diff --git a/Roles/Crewmate/Sentinel.cs b/Roles/Crewmate/Sentinel.cs
index 206b72039..ad0ad9f28 100644
--- a/Roles/Crewmate/Sentinel.cs
+++ b/Roles/Crewmate/Sentinel.cs
@@ -182,7 +182,7 @@ internal class Sentinel : RoleBase
public override void ApplyGameOptions(IGameOptions opt, byte playerId)
{
AURoleOptions.EngineerCooldown = PatrolCooldown.GetFloat();
- AURoleOptions.EngineerInVentMaxTime = 0.1f;
+ AURoleOptions.EngineerInVentMaxTime = 0.3f;
}
public override void OnFixedUpdate(PlayerControl pc)
diff --git a/Roles/Crewmate/Telekinetic.cs b/Roles/Crewmate/Telekinetic.cs
index 783619e27..2870e759c 100644
--- a/Roles/Crewmate/Telekinetic.cs
+++ b/Roles/Crewmate/Telekinetic.cs
@@ -64,7 +64,7 @@ public class Telekinetic : RoleBase
public override void ApplyGameOptions(IGameOptions opt, byte playerId)
{
AURoleOptions.EngineerCooldown = 0f;
- AURoleOptions.EngineerInVentMaxTime = 0.1f;
+ AURoleOptions.EngineerInVentMaxTime = 0.3f;
}
public override void OnFixedUpdate(PlayerControl pc)
diff --git a/Roles/Crewmate/Tether.cs b/Roles/Crewmate/Tether.cs
index 1b07b8e0d..811e8d37b 100644
--- a/Roles/Crewmate/Tether.cs
+++ b/Roles/Crewmate/Tether.cs
@@ -111,7 +111,7 @@ public class Tether : RoleBase
if (UsePets.GetBool()) return;
AURoleOptions.EngineerCooldown = VentCooldown.GetFloat();
- AURoleOptions.EngineerInVentMaxTime = 0.1f;
+ AURoleOptions.EngineerInVentMaxTime = 0.3f;
}
public override bool OnVote(PlayerControl pc, PlayerControl target)
diff --git a/Roles/Crewmate/TimeMaster.cs b/Roles/Crewmate/TimeMaster.cs
index 98929638b..e746f5004 100644
--- a/Roles/Crewmate/TimeMaster.cs
+++ b/Roles/Crewmate/TimeMaster.cs
@@ -66,7 +66,7 @@ internal class TimeMaster : RoleBase
if (UsePets.GetBool()) return;
AURoleOptions.EngineerCooldown = TimeMasterSkillCooldown.GetFloat();
- AURoleOptions.EngineerInVentMaxTime = 0.1f;
+ AURoleOptions.EngineerInVentMaxTime = 0.3f;
}
public override void SetButtonTexts(HudManager hud, byte id)
diff --git a/Roles/Crewmate/Ventguard.cs b/Roles/Crewmate/Ventguard.cs
index c93d36ade..b50ea8b7f 100644
--- a/Roles/Crewmate/Ventguard.cs
+++ b/Roles/Crewmate/Ventguard.cs
@@ -57,7 +57,7 @@ internal class Ventguard : RoleBase
public override void ApplyGameOptions(IGameOptions opt, byte playerId)
{
- AURoleOptions.EngineerInVentMaxTime = 0.1f;
+ AURoleOptions.EngineerInVentMaxTime = 0.3f;
AURoleOptions.EngineerCooldown = 15f;
}
diff --git a/Roles/Crewmate/Veteran.cs b/Roles/Crewmate/Veteran.cs
index 14774f9c3..6b569cec9 100644
--- a/Roles/Crewmate/Veteran.cs
+++ b/Roles/Crewmate/Veteran.cs
@@ -54,7 +54,7 @@ internal class Veteran : RoleBase
if (UsePets.GetBool()) return;
AURoleOptions.EngineerCooldown = VeteranSkillCooldown.GetFloat();
- AURoleOptions.EngineerInVentMaxTime = 0.1f;
+ AURoleOptions.EngineerInVentMaxTime = 0.3f;
}
public override string GetProgressText(byte playerId, bool comms)
diff --git a/Roles/Neutral/Magistrate.cs b/Roles/Neutral/Magistrate.cs
index f163f5e8c..6d147e662 100644
--- a/Roles/Neutral/Magistrate.cs
+++ b/Roles/Neutral/Magistrate.cs
@@ -45,7 +45,7 @@ public class Magistrate : RoleBase
{
if (AbilityTrigger != AbilityTriggers.Vent) return;
AURoleOptions.EngineerCooldown = 0.1f;
- AURoleOptions.EngineerInVentMaxTime = 0.1f;
+ AURoleOptions.EngineerInVentMaxTime = 0.3f;
}
public override bool CanUseImpostorVentButton(PlayerControl pc)
diff --git a/Roles/Neutral/Mario.cs b/Roles/Neutral/Mario.cs
index 6f58ce813..2e7e9e05f 100644
--- a/Roles/Neutral/Mario.cs
+++ b/Roles/Neutral/Mario.cs
@@ -49,7 +49,7 @@ internal class Mario : RoleBase
public override void ApplyGameOptions(IGameOptions opt, byte playerId)
{
AURoleOptions.EngineerCooldown = MarioVentCD.GetFloat();
- AURoleOptions.EngineerInVentMaxTime = 0.1f;
+ AURoleOptions.EngineerInVentMaxTime = 0.3f;
}
public override string GetProgressText(byte playerId, bool comms)
diff --git a/Roles/Neutral/Tank.cs b/Roles/Neutral/Tank.cs
index 6cc0eaef3..f38709685 100644
--- a/Roles/Neutral/Tank.cs
+++ b/Roles/Neutral/Tank.cs
@@ -47,7 +47,7 @@ public class Tank : RoleBase
public override void ApplyGameOptions(IGameOptions opt, byte playerId)
{
AURoleOptions.EngineerCooldown = VentCooldown.GetFloat();
- AURoleOptions.EngineerInVentMaxTime = 0.1f;
+ AURoleOptions.EngineerInVentMaxTime = 0.3f;
Main.AllPlayerSpeed[playerId] = Speed.GetFloat();
}