Compare commits

..
3 Commits
Author SHA1 Message Date
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
12 changed files with 195 additions and 68 deletions

No files matched your search

+1 -1
View File
@@ -39,7 +39,7 @@ public partial class Main : BasePlugin
public static HideNSeekGameOptionsV10 HideNSeekOptions => GameOptionsManager.Instance != null ? GameOptionsManager.Instance.currentHideNSeekGameOptions : null;
public static bool HasArgumentException;
public static string CredentialsText;
public const string ModVersion = "v1.5.0";
public const string ModVersion = "v1.5.1";
public static float GameTimer;
+5
View File
@@ -8,6 +8,11 @@
<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>
+68 -20
View File
@@ -14,50 +14,47 @@ public static class CustomRoleManagement
{
// crewmateRoles = assigned with crewmate role base
// impostorRoles = assigned with impostor role base
List<(string roleName, int percentage)> crewmateRoles = new List<(string, int)>
List<(string roleName, int percentage)> crewmateRoles = new()
{
("Jester", Options.JesterPerc.GetInt()),
("Mayor", Options.MayorPerc.GetInt())
};
List<(string roleName, int percentage)> impostorRoles = new List<(string, int)>
List<(string roleName, int percentage)> impostorRoles = new()
{
};
List<PlayerControl> availablePlayers = new List<PlayerControl>();
foreach (var player in PlayerControl.AllPlayerControls)
{
availablePlayers.Add(player);
}
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;
List<(string roleName, int percentage)> rolesToAssign = isCrewmate ? crewmateRoles : impostorRoles;
var rolesToAssign = isCrewmate ? crewmateRoles : impostorRoles;
foreach (var (roleName, percentage) in rolesToAssign)
{
if (assignedRoles.Contains(roleName))
continue;
if (attemptedRoles.Contains(roleName)) continue;
attemptedRoles.Add(roleName);
int randomValue = random.Next(0, 101);
Logger.Info($"{roleName}, Value: {randomValue}, Percentage: {percentage}", "StartGameCustomRole1");
if (randomValue <= percentage && !PlayerRoles.ContainsKey(player.PlayerId))
{
PlayerRoles[player.PlayerId] = roleName;
assignedRoles.Add(roleName);
Logger.Info($"({player.PlayerId}) {player.Data.PlayerName} -> {roleName}", "StartGameCustomRole2");
if (randomValue >= percentage) continue;
if (PlayerRoles.ContainsKey(player.PlayerId)) continue;
break;
}
PlayerRoles[player.PlayerId] = roleName;
assignedRoles.Add(roleName);
Logger.Info($"({player.PlayerId}) {player.Data.PlayerName} -> {roleName}", "StartGameCustomRole2");
break;
}
}
}
@@ -90,6 +87,8 @@ public static class CustomRoleManagement
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)
{
HashSet<string> sentRoles = new HashSet<string>();
@@ -97,19 +96,68 @@ public static class CustomRoleManagement
var players = PlayerControl.AllPlayerControls.ToArray().ToList();
float delay = 0f;
PendingRoleMessages = 0;
HandlingRoleMessages = false;
foreach (var player in players)
{
if (!PlayerRoles.TryGetValue(player.PlayerId, out string role)) continue;
if (!roleMessages.ContainsKey(role)) continue;
if (sentRoles.Contains(role)) continue;
PendingRoleMessages++;
new LateTask(() =>
{
Utils.SendPrivateMessage(player, roleMessages[role]);
PendingRoleMessages--;
if (PendingRoleMessages <= 0)
{
PendingRoleMessages = 0;
HandlingRoleMessages = false;
}
}, 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);
}
}
+5
View File
@@ -9,6 +9,7 @@ namespace AmongUsRevamped;
[HarmonyPatch(typeof(ControllerManager), nameof(ControllerManager.Update))]
internal class Hotkeys
{
public static int IncrementMultiplier;
public static void Postfix()
{
bool Shift = Input.GetKey(KeyCode.LeftShift) || Input.GetKey(KeyCode.RightShift);
@@ -52,6 +53,10 @@ internal class Hotkeys
GameStartManager.Instance.ResetStartState();
Logger.SendInGame("Starting countdown canceled");
}
if (Shift) IncrementMultiplier = 5;
else if (Ctrl) IncrementMultiplier = 10;
else IncrementMultiplier = 1;
}
}
#endif
+4 -4
View File
@@ -104,7 +104,7 @@ internal static class SendChatPatch
return false;
}
if (__instance.timeSinceLastMessage < 3f || OnGameJoinedPatch.WaitingForChat) return false;
if (__instance.timeSinceLastMessage < 3f || OnGameJoinedPatch.WaitingForChat || CustomRoleManagement.HandlingRoleMessages) return false;
if (text == "/l" || text == "/lastgame" || text == "/win" || text == "/winner")
{
@@ -142,7 +142,7 @@ internal static class SendChatPatch
switch (Options.Gamemode.GetValue())
{
case 0:
Utils.ChatCommand(__instance, $"ENABLED CUSTOM ROLES:\n\n{CustomRoleManagement.GetActiveRoles()}", "", false);
Utils.ChatCommand(__instance, $"Enabled Custom Roles:\n\n{CustomRoleManagement.GetActiveRoles()}", "", false);
break;
case 1:
@@ -266,7 +266,7 @@ public static class RPCHandlerPatch
{
c = keywords.Any(k => text == k);
}
if (c && !Utils.IsPlayerModerator(__instance.Data.FriendCode))
if (c && !Utils.IsPlayerModerator(__instance.Data.FriendCode) && Options.AutoKickStart.GetBool())
{
int clientId = __instance.Data.ClientId;
@@ -372,7 +372,7 @@ public static class RPCHandlerPatch
{
if (!Utils.IsPlayerModerator(__instance.Data.FriendCode)) return;
// Banning works by name and color. Commands are seperated incase someone has a color as their name
// 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 ");
+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/cxqgNyW.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;
}
}
+7 -4
View File
@@ -39,21 +39,24 @@ class NormalGameEndChecker
ImpCheckComplete = true;
}
var customRoles = CustomRoleManagement.PlayerToCustomRole();
var impostorList = string.Join(", ", imps.Select(p => p.Data.PlayerName));
if (Utils.AliveImpostors == 0)
{
LastWinReason = $"★ Crewmates win!\n\nImpostors:\n" + string.Join("\n", imps.Select(p => p.Data.PlayerName));
LastWinReason = $"Crewmates win!\n\nImpostors: {impostorList}" + (string.IsNullOrEmpty(customRoles) ? "" : "\n\n" + customRoles);
}
else if (Utils.AliveImpostors >= Utils.AliveCrewmates)
{
LastWinReason = $"★ Impostors win!\n\nImpostors:\n★" + string.Join("\n★", imps.Select(p => p.Data.PlayerName));
LastWinReason = $"Impostors win!\n\nImpostor: {impostorList}" + (string.IsNullOrEmpty(customRoles) ? "" : "\n\n" + customRoles);
}
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));
LastWinReason = $"Crewmates win! (Tasks)\n\nImpostors: {impostorList}" + (string.IsNullOrEmpty(customRoles) ? "" : "\n\n" + customRoles);
}
else if (Options.Gamemode.GetValue() < 2)
{
LastWinReason = $"★ Impostors win! (Sabotage)\n\nImpostors:\n★" + string.Join("\n★", imps.Select(p => p.Data.PlayerName));
LastWinReason = $"Impostors win! (Sabotage)\n\nImpostors: {impostorList}" + (string.IsNullOrEmpty(customRoles) ? "" : "\n\n" + customRoles);
}
return true;
}
+35
View File
@@ -0,0 +1,35 @@
namespace AmongUsRevamped;
class ExileControllerWrapUpPatch
{
[HarmonyPatch(typeof(ExileController), nameof(ExileController.WrapUp))]
class ExileControllerPatch
{
public static void Postfix(ExileController __instance)
{
if (!AmongUsClient.Instance.AmHost) return;
var ejectedPlayer = __instance.initData?.networkedPlayer;
if (ejectedPlayer == null) return;
PlayerControl pc = null;
foreach (var p in PlayerControl.AllPlayerControls)
{
if (p.PlayerId == ejectedPlayer.PlayerId)
{
pc = p;
break;
}
}
Logger.Info($" {ejectedPlayer.PlayerName} was ejected", "ExileController");
if (!CustomRoleManagement.PlayerRoles.TryGetValue(ejectedPlayer.PlayerId, out var role)) return;
if (role == "Jester")
{
Utils.CustomWinnerEndGame(pc, 1);
}
}
}
}
+11 -1
View File
@@ -10,7 +10,7 @@ internal static class CoShowIntroPatch
{
public static void Postfix(IntroCutscene __instance)
{
Logger.Info("Intro initiated", "d");
Logger.Info("Intro initiated", "CoShowIntro");
if (!AmongUsClient.Instance.AmHost) return;
@@ -24,5 +24,15 @@ internal static class CoShowIntroPatch
{ "Jester", $"{String.Jester}"},
{ "Mayor", $"{String.Mayor}"}
});
if (!Utils.isHideNSeek) return;
foreach (var p in PlayerControl.AllPlayerControls)
{
if (p.Data.Role.TeamType == RoleTeamTypes.Impostor)
{
p.RpcSetRole(AmongUs.GameOptions.RoleTypes.Impostor, false);
}
}
}
}
+49 -16
View File
@@ -1,25 +1,32 @@
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;
float increment = Hotkeys.IncrementMultiplier * __instance.Increment;
if (Utils.isHideNSeek || Utils.IsLobby && !Utils.isHideNSeek && __instance.Title != StringNames.GameNumImpostors && __instance.Title != StringNames.GamePlayerSpeed)
{
__instance.Value += __instance.Increment;
__instance.UpdateValue();
__instance.OnValueChanged.Invoke(__instance);
__instance.AdjustButtonsActiveState();
return false;
if (__instance.Value + increment > __instance.ValidRange.max)
{
return true;
}
else
{
__instance.Value += increment;
__instance.UpdateValue();
__instance.OnValueChanged.Invoke(__instance);
return false;
}
}
else return true;
return true;
}
}
@@ -28,17 +35,23 @@ public static class NumberOption_Decrease
{
public static bool Prefix(NumberOption __instance)
{
if (ModGameOptionsMenu.TabIndex >= 3) return true;
float increment = Hotkeys.IncrementMultiplier * __instance.Increment;
if (Utils.isHideNSeek || Utils.IsLobby && !Utils.isHideNSeek && __instance.Title != StringNames.GameNumImpostors && __instance.Title != StringNames.GamePlayerSpeed)
{
__instance.Value -= __instance.Increment;
__instance.UpdateValue();
__instance.OnValueChanged.Invoke(__instance);
__instance.AdjustButtonsActiveState();
return false;
if (__instance.Value - increment < __instance.ValidRange.min)
{
return true;
}
else
{
__instance.Value -= increment;
__instance.UpdateValue();
__instance.OnValueChanged.Invoke(__instance);
return false;
}
}
else return true;
return true;
}
}
@@ -51,7 +64,27 @@ public static class NumberOption_Initialize
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:
__instance.Increment = 5f;
break;
case StringNames.GameKillCooldown:
__instance.Increment = 0.5f;
break;
case StringNames.GamePlayerSpeed:
case StringNames.GameCrewLight:
case StringNames.GameImpostorLight:
__instance.Increment = 0.05f;
break;
default:
__instance.Increment = 1f;
break;
}
}
}
-17
View File
@@ -67,28 +67,11 @@ internal class CoStartGamePatch
(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");
}
}
}
}
}
+1 -1
View File
@@ -18,7 +18,7 @@ public static class String
return $"Shift and Seek:\n\nImpostors can only kill someone while shapeshifted as them\nSabotages & Meetings = Off";}}
public static string SnSModeTwo{get{
return $"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";}}
return $"Crew wins by tasks/surviving {Options.CrewAutoWinsGameAfter.GetInt()}s\n" + "Imp wins by killing\n" + (Options.MisfiresToSuicide.GetInt() == 1 ? "" : $"One wrong kill = Can't kill for {Options.CantKillTime.GetInt()}s\n") + $"{Utils.BasicIntToWord(Options.MisfiresToSuicide.GetInt())} wrong kill{(Options.MisfiresToSuicide.GetInt() == 1 ? "" : "s")} = suicide";}}
public static string speedrunMode{get{
return $"Speedrun:\n\nEveryone is a crewmate. The 1st player to finish tasks wins the game. Game auto ends after {Options.GameAutoEndsAfter.GetInt()}s";}}