# Releases
| Among Us - Version| Mod Version | Link |
|----------|-------------|-----------------|
+| 2021.12.15s| v3.3.3| [Download](https://github.com/Eisbison/TheOtherRoles/releases/download/v3.3.3/TheOtherRoles.zip)
+| 2021.12.15s| v3.3.2| [Download](https://github.com/Eisbison/TheOtherRoles/releases/download/v3.3.2/TheOtherRoles.zip)
| 2021.12.14s| v3.3.1| [Download](https://github.com/Eisbison/TheOtherRoles/releases/download/v3.3.1/TheOtherRoles.zip)
| 2021.12.14s| v3.3.0| [Download](https://github.com/Eisbison/TheOtherRoles/releases/download/v3.3.0/TheOtherRoles.zip)
| 2021.11.9.5s| v3.2.4| [Download](https://github.com/Eisbison/TheOtherRoles/releases/download/v3.2.4/TheOtherRoles.zip)
<details>
<summary>Click to show the Changelog</summary>
+**Version 3.3.3**
+- Fixed a bug where a guessed Guesser could guess
+- Fixed a bug where buttons were visible during the meeting
+- Removed Hacker vitals for Skeld & dlekS
+- Changed the Guesser option "Other Guesser Spawn Rate" to "Both Guesser Spawn Rate" (now only take effect when the chance for the first guesser was successful)
+- Changed Hacker vitals to doorlog for MIRA HQ
+
+**Version 3.3.2**
+- Fixed a bug where you can't create a lobby on Among Us 2021.12.15
+
**Version 3.3.1**
- Fixed a bug where sometimes the Evil Guesser could not guess. Thanks @tomarai
| Guesses Visible In Ghost Chat| -
| Guesses Ignore The Medic Shield| -
| Evil Guesser Can Guess The Spy| -
-| Other Guesser Spawn Rate| -
+| Both Guesser Spawn Rate| -
-----------------------
hackerVitalsButton = new CustomButton(
() => {
- if (!Minigame.Instance) {
+ if (PlayerControl.GameOptions.MapId != 1) {
if (Hacker.vitals == null) {
var e = UnityEngine.Object.FindObjectsOfType<SystemConsole>().FirstOrDefault(x => x.gameObject.name.Contains("panel_vitals"));
if (e == null || Camera.main == null) return;
Hacker.vitals.transform.SetParent(Camera.main.transform, false);
Hacker.vitals.transform.localPosition = new Vector3(0.0f, 0.0f, -50f);
Hacker.vitals.Begin(null);
+ } else {
+ if (Hacker.doorLog == null) {
+ var e = UnityEngine.Object.FindObjectsOfType<SystemConsole>().FirstOrDefault(x => x.gameObject.name.Contains("SurvLogConsole"));
+ if (e == null || Camera.main == null) return;
+ Hacker.doorLog = UnityEngine.Object.Instantiate(e.MinigamePrefab, Camera.main.transform, false);
+ }
+ Hacker.doorLog.transform.SetParent(Camera.main.transform, false);
+ Hacker.doorLog.transform.localPosition = new Vector3(0.0f, 0.0f, -50f);
+ Hacker.doorLog.Begin(null);
}
Hacker.chargesVitals--;
},
- () => { return Hacker.hacker != null && Hacker.hacker == PlayerControl.LocalPlayer && !PlayerControl.LocalPlayer.Data.IsDead;},
+ () => { return Hacker.hacker != null && Hacker.hacker == PlayerControl.LocalPlayer && !PlayerControl.LocalPlayer.Data.IsDead && PlayerControl.GameOptions.MapId != 0 && PlayerControl.GameOptions.MapId != 3; },
() => {
if (hackerVitalsChargesText != null) hackerVitalsChargesText.text = $"{Hacker.chargesVitals} / {Hacker.toolsNumber}";
+ hackerVitalsButton.actionButton.graphic.sprite = PlayerControl.GameOptions.MapId == 1 ? Hacker.getLogSprite() : Hacker.getVitalsSprite();
+ hackerVitalsButton.actionButton.OverrideText(PlayerControl.GameOptions.MapId == 1 ? "DOORLOG" : "VITALS");
return PlayerControl.LocalPlayer.CanMove && Hacker.chargesVitals > 0;
},
() => {
0f,
() => {
hackerVitalsButton.Timer = hackerVitalsButton.MaxTimer;
- if (Minigame.Instance) Hacker.vitals.ForceClose();
+ if (Minigame.Instance) {
+ if (PlayerControl.GameOptions.MapId == 1) Hacker.doorLog.ForceClose();
+ else Hacker.vitals.ForceClose();
+ }
},
false,
- "VITALS"
+ PlayerControl.GameOptions.MapId == 1 ? "DOORLOG" : "VITALS"
);
// Hacker Vitals Charges
writer.EndMessage();
RPCProcedure.sealVent(SecurityGuard.ventTarget.Id);
SecurityGuard.ventTarget = null;
+
} else if (PlayerControl.GameOptions.MapId != 1) { // Place camera if there's no vent and it's not MiraHQ
var pos = PlayerControl.LocalPlayer.transform.position;
byte[] buff = new byte[sizeof(float) * 2];
guesserShowInfoInGhostChat = CustomOption.Create(314, "Guesses Visible In Ghost Chat", true, guesserSpawnRate);
guesserKillsThroughShield = CustomOption.Create(315, "Guesses Ignore The Medic Shield", true, guesserSpawnRate);
guesserEvilCanKillSpy = CustomOption.Create(316, "Evil Guesser Can Guess The Spy", true, guesserSpawnRate);
- guesserSpawnBothRate = CustomOption.Create(317, "Other Guesser Spawn Rate", rates, guesserSpawnRate);
+ guesserSpawnBothRate = CustomOption.Create(317, "Both Guesser Spawn Rate", rates, guesserSpawnRate);
jesterSpawnRate = CustomOption.Create(60, cs(Jester.color, "Jester"), rates, null, true);
jesterCanCallEmergency = CustomOption.Create(61, "Jester can call emergency meeting", true, jesterSpawnRate);
public class TheOtherRolesPlugin : BasePlugin
{
public const string Id = "me.eisbison.theotherroles";
- public const string VersionString = "3.3.1";
+ public const string VersionString = "3.3.3";
public static System.Version Version = System.Version.Parse(VersionString);
internal static BepInEx.Logging.ManualLogSource Logger;
DnsRegionInfo region = serverManager.CurrentRegion.TryCast<DnsRegionInfo>();
if (region == null || !region.Fqdn.EndsWith("among.us")) {
var remoteEndPoint = new Il2CppSystem.Net.IPEndPoint(Il2CppSystem.Net.IPAddress.Parse(targetIp), (int)(targetPort - 3));
- __result = new Hazel.Udp.UnityUdpClientConnection(remoteEndPoint);
+ __result = new Hazel.Udp.UnityUdpClientConnection(null, remoteEndPoint);
return false;
}
return true;
int copiedIndex = i;
button.GetComponent<PassiveButton>().OnClick.RemoveAllListeners();
- button.GetComponent<PassiveButton>().OnClick.AddListener((UnityEngine.Events.UnityAction)(() => {
+ if (!PlayerControl.LocalPlayer.Data.IsDead) button.GetComponent<PassiveButton>().OnClick.AddListener((UnityEngine.Events.UnityAction)(() => {
if (selectedButton != button) {
selectedButton = button;
buttons.ForEach(x => x.GetComponent<SpriteRenderer>().color = x == selectedButton ? Color.red : Color.white);
}
// Assign Guesser (chance to be impostor based on setting)
- if (data.impostors.Count > 0 && data.maxImpostorRoles > 0 && rnd.Next(1, 101) <= CustomOptionHolder.guesserIsImpGuesserRate.getSelection() * 10) {
- data.impSettings.Add((byte)RoleId.EvilGuesser, CustomOptionHolder.guesserSpawnRate.getSelection());
- if (data.crewmates.Count > 0 && data.maxCrewmateRoles > 0) data.crewSettings.Add((byte)RoleId.NiceGuesser, CustomOptionHolder.guesserSpawnBothRate.getSelection()); // Second guesser
- } else if (data.crewmates.Count > 0 && data.maxCrewmateRoles > 0) {
- data.crewSettings.Add((byte)RoleId.NiceGuesser, CustomOptionHolder.guesserSpawnRate.getSelection());
- if (data.impostors.Count > 0 && data.maxImpostorRoles > 0) data.impSettings.Add((byte)RoleId.EvilGuesser, CustomOptionHolder.guesserSpawnBothRate.getSelection()); // Second guesser
+ bool isEvilGuesser = (rnd.Next(1, 101) <= CustomOptionHolder.guesserIsImpGuesserRate.getSelection() * 10);
+ if (CustomOptionHolder.guesserSpawnBothRate.getSelection() > 0) {
+ if (rnd.Next(1, 101) <= CustomOptionHolder.guesserSpawnRate.getSelection() * 10) {
+ if (isEvilGuesser) {
+ if (data.impostors.Count > 0 && data.maxImpostorRoles > 0) {
+ byte evilGuesser = setRoleToRandomPlayer((byte)RoleId.EvilGuesser, data.impostors);
+ data.impostors.ToList().RemoveAll(x => x.PlayerId == evilGuesser);
+ data.maxImpostorRoles--;
+ data.crewSettings.Add((byte)RoleId.NiceGuesser, CustomOptionHolder.guesserSpawnBothRate.getSelection());
+ }
+ }
+ else if (data.crewmates.Count > 0 && data.maxCrewmateRoles > 0) {
+ byte niceGuesser = setRoleToRandomPlayer((byte)RoleId.NiceGuesser, data.crewmates);
+ data.crewmates.ToList().RemoveAll(x => x.PlayerId == niceGuesser);
+ data.maxCrewmateRoles--;
+ data.impSettings.Add((byte)RoleId.EvilGuesser, CustomOptionHolder.guesserSpawnBothRate.getSelection());
+ }
+ }
+ } else {
+ if (isEvilGuesser) data.impSettings.Add((byte)RoleId.EvilGuesser, CustomOptionHolder.guesserSpawnRate.getSelection());
+ else data.crewSettings.Add((byte)RoleId.NiceGuesser, CustomOptionHolder.guesserSpawnRate.getSelection());
}
}
}
static void updateImpostorKillButton(HudManager __instance) {
- if (!PlayerControl.LocalPlayer.Data.Role.IsImpostor) return;
+ if (!PlayerControl.LocalPlayer.Data.Role.IsImpostor || MeetingHud.Instance) return;
bool enabled = true;
if (Vampire.vampire != null && Vampire.vampire == PlayerControl.LocalPlayer)
enabled = false;
public static class Hacker {
public static PlayerControl hacker;
public static Minigame vitals = null;
+ public static Minigame doorLog = null;
public static Color color = new Color32(117, 250, 76, byte.MaxValue);
public static float cooldown = 30f;
private static Sprite buttonSprite;
private static Sprite vitalsSprite;
+ private static Sprite logSprite;
private static Sprite adminSprite;
public static Sprite getButtonSprite() {
return vitalsSprite;
}
+ public static Sprite getLogSprite() {
+ if (logSprite) return logSprite;
+ logSprite = HudManager.Instance.UseButton.fastUseSettings[ImageNames.DoorLogsButton].Image;
+ return logSprite;
+ }
+
public static Sprite getAdminSprite() {
byte mapId = PlayerControl.GameOptions.MapId;
UseButtonSettings button = HudManager.Instance.UseButton.fastUseSettings[ImageNames.PolusAdminButton]; // Polus
public static void clearAndReload() {
hacker = null;
vitals = null;
+ doorLog = null;
hackerTimer = 0f;
adminSprite = null;
cooldown = CustomOptionHolder.hackerCooldown.getFloat();
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.1</TargetFramework>
- <Version>3.3.1</Version>
+ <Version>3.3.3</Version>
<Description>TheOtherRoles</Description>
<Authors>Eisbison</Authors>
</PropertyGroup>