mirror of
https://github.com/ApeMV/AmongUsRevamped.git
synced 2026-10-24 06:46:56 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
02f7ddc63a | ||
|
|
600234b5f2 | ||
|
|
15d6f54982 |
No files matched your search
+1
-1
@@ -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;
|
||||
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
@@ -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 ");
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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";}}
|
||||
|
||||
Reference in new issue
Block a user