# Releases\r
| Among Us - Version| Mod Version | Link |\r
|----------|-------------|-----------------|\r
+| 2021.4.14s| v2.6.1| [Download](https://github.com/Eisbison/TheOtherRoles/releases/download/v2.6.1/TheOtherRoles.zip)\r
| 2021.4.14s| v2.6.0| [Download](https://github.com/Eisbison/TheOtherRoles/releases/download/v2.6.0/TheOtherRoles.zip)\r
| 2021.4.14s| v2.5.1| [Download](https://github.com/Eisbison/TheOtherRoles/releases/download/v2.5.1/TheOtherRoles.zip)\r
| 2021.4.14s| v2.5.0| [Download](https://github.com/Eisbison/TheOtherRoles/releases/download/v2.5.0/TheOtherRoles.zip)\r
<details>\r
<summary>Click to show the Changelog</summary>\r
\r
+**Version 2.6.1**\r
+- Fixed a bug where the Sheriff was unable to kill the Arsonist\r
+- Fixed a bug in the role assignment system\r
+- Added the option to select the Dleks map\r
+- Improved the overlay of the Arsonist\r
+\r
**Version 2.6.0**\r
- **New Role:** [Arsonist](#arsonist)\r
- Added an Ingame Updater, to make it easier to update the Mod\r
- **Allow Skips On Emergency Meetings:** If set to false, there will not be a skip button in emergency meetings. If a player does not vote, he'll vote himself.\r
- **Hide Player Names:** Hides the names of all players that have role which is unknown to you. Team Lovers/Impostors/Jackal still see the names of their teammates. Impostors can alse see the name of the Spy and everyone can still see the age of the child.\r
- **Ghosts Can See Roles And Remaining Tasks:** If set to true, ghosts can see the role and the number of remaining tasks of each player.\r
+- **Dleks:** You are now able to select the Dleks map. \r
\r
# Custom Hats\r
## Create and submit new hat designs\r
byte targetId = 0;
if ((Sheriff.currentTarget.Data.IsImpostor && (Sheriff.currentTarget != Child.child || Child.isGrownUp())) ||
(Sheriff.spyCanDieToSheriff && Spy.spy == Sheriff.currentTarget) ||
- (Sheriff.canKillNeutrals && (Jester.jester == Sheriff.currentTarget || Jackal.jackal == Sheriff.currentTarget || Sidekick.sidekick == Sheriff.currentTarget))) {
+ (Sheriff.canKillNeutrals && (Arsonist.arsonist == Sheriff.currentTarget || Jester.jester == Sheriff.currentTarget || Jackal.jackal == Sheriff.currentTarget || Sidekick.sidekick == Sheriff.currentTarget))) {
targetId = Sheriff.currentTarget.PlayerId;
}
else {
Arsonist.douseTarget = null;
arsonistButton.Timer = Arsonist.dousedEveryoneAlive() ? 0 : arsonistButton.MaxTimer;
- int playerCounter = 0;
- Vector3 bottomLeft = new Vector3(-HudManager.Instance.UseButton.transform.localPosition.x, HudManager.Instance.UseButton.transform.localPosition.y, HudManager.Instance.UseButton.transform.localPosition.z);
- bottomLeft += new Vector3(-0.25f, -0.25f, 0);
foreach (PlayerControl p in Arsonist.dousedPlayers) {
if (Arsonist.dousedIcons.ContainsKey(p.PlayerId)) {
- Arsonist.dousedIcons[p.PlayerId].gameObject.SetActive(true);
- Arsonist.dousedIcons[p.PlayerId].transform.localPosition = bottomLeft + Vector3.right * playerCounter * 0.35f;
- playerCounter++;
+ Arsonist.dousedIcons[p.PlayerId].setSemiTransparent(false);
}
}
}
}
}
}
+ [HarmonyPatch(typeof(SaveManager), nameof(SaveManager.LoadPlayerPrefs))]
+ private static class LoadPlayerPrefsPatch { // Fix Potential issues with broken colors
+ private static bool needsPatch = false;
+ public static void Prefix([HarmonyArgument(0)] bool overrideLoad) {
+ if (!SaveManager.loaded || overrideLoad)
+ needsPatch = true;
+ }
+ public static void Postfix() {
+ if (!needsPatch) return;
+ SaveManager.colorConfig %= (uint)CustomColors.pickableColors;
+ needsPatch = false;
+ }
+ }
+ [HarmonyPatch(typeof(PlayerControl), nameof(PlayerControl.CheckColor))]
+ private static class PlayerControlCheckColorPatch {
+ private static bool isTaken(PlayerControl player, uint color) {
+ foreach (GameData.PlayerInfo p in GameData.Instance.AllPlayers)
+ if (!p.Disconnected && p.PlayerId != player.PlayerId && p.ColorId == color)
+ return true;
+ return false;
+ }
+ public static bool Prefix(PlayerControl __instance, [HarmonyArgument(0)] byte bodyColor) { // Fix incorrect color assignment
+ uint color = (uint)bodyColor;
+ if (isTaken(__instance, color) || color >= Palette.PlayerColors.Length) {
+ int num = 0;
+ while (num++ < 50 && (color >= CustomColors.pickableColors || isTaken(__instance, color))) {
+ color = (color + 1) % (uint)CustomColors.pickableColors;
+ }
+ }
+ __instance.RpcSetColor((byte)color);
+ return false;
+ }
+ }
}
}
}
sheriffSpawnRate = CustomOption.Create(100, cs(Sheriff.color, "Sheriff"), rates, null, true);
sheriffCooldown = CustomOption.Create(101, "Sheriff Cooldown", 30f, 10f, 60f, 2.5f, sheriffSpawnRate);
- sheriffCanKillNeutrals = CustomOption.Create(102, "Neutrals Can Kill The Jester", false, sheriffSpawnRate);
+ sheriffCanKillNeutrals = CustomOption.Create(102, "Sheriff Can Kill Neutrals", false, sheriffSpawnRate);
lighterSpawnRate = CustomOption.Create(110, cs(Lighter.color, "Lighter"), rates, null, true);
public static void Prefix(GameSettingMenu __instance) {
__instance.HideForOnline = new Transform[]{};
}
+
+ public static void Postfix(GameSettingMenu __instance) {
+ var mapNameTransform = __instance.AllItems.FirstOrDefault(x => x.gameObject.activeSelf && x.name.Equals("MapName", StringComparison.OrdinalIgnoreCase));
+ if (mapNameTransform == null) return;
+
+ var options = new Il2CppSystem.Collections.Generic.List<Il2CppSystem.Collections.Generic.KeyValuePair<string, int>>();
+ for (int i = 0; i < GameOptionsData.MapNames.Length; i++) {
+ var kvp = new Il2CppSystem.Collections.Generic.KeyValuePair<string, int>();
+ kvp.key = GameOptionsData.MapNames[i];
+ kvp.value = i;
+ options.Add(kvp);
+ }
+ mapNameTransform.GetComponent<KeyValueOption>().Values = options;
+ }
+ }
+
+ [HarmonyPatch(typeof(Constants), nameof(Constants.ShouldFlipSkeld))]
+ class ConstantsShouldFlipSkeldPatch {
+ public static bool Prefix(ref bool __result) {
+ if (PlayerControl.GameOptions == null) return true;
+ __result = PlayerControl.GameOptions.MapId == 3;
+ return false;
+ }
}
[HarmonyPatch]
player.Data.Tasks.Clear();
}
+ public static void setSemiTransparent(this PoolablePlayer player, bool value) {
+ float alpha = value ? 0.25f : 1f;
+ foreach (SpriteRenderer r in player.gameObject.GetComponentsInChildren<SpriteRenderer>())
+ r.color = new Color(r.color.r, r.color.g, r.color.b, alpha);
+ player.NameText.color = new Color(player.NameText.color.r, player.NameText.color.g, player.NameText.color.b, alpha);
+ }
+
public static string cs(Color c, string s) {
return string.Format("<color=#{0:X2}{1:X2}{2:X2}{3:X2}>{4}</color>", ToByte(c.r), ToByte(c.g), ToByte(c.b), ToByte(c.a), s);
}
PlayerControl.SetPetImage(data.PetId, data.ColorId, poolablePlayer.PetSlot);
poolablePlayer.NameText.text = data.PlayerName;
poolablePlayer.SetFlipX(true);
- poolablePlayer.gameObject.SetActive(false);
-
+ poolablePlayer.setSemiTransparent(true);
Arsonist.dousedIcons[player.PlayerId] = poolablePlayer;
playerCounter++;
}
public class TheOtherRolesPlugin : BasePlugin
{
public const string Id = "me.eisbison.theotherroles";
- public const string VersionString = "2.6.0";
+ public const string VersionString = "2.6.1";
public static System.Version Version = System.Version.Parse(VersionString);
public Harmony Harmony { get; } = new Harmony(Id);
}
Seer.deadBodyPositions = new List<Vector3>();
}
+
+ // Arsonist deactivate dead poolable players
+ if (Arsonist.arsonist != null && Arsonist.arsonist == PlayerControl.LocalPlayer) {
+ int visibleCounter = 0;
+ Vector3 bottomLeft = new Vector3(-HudManager.Instance.UseButton.transform.localPosition.x, HudManager.Instance.UseButton.transform.localPosition.y, HudManager.Instance.UseButton.transform.localPosition.z);
+ bottomLeft += new Vector3(-0.25f, -0.25f, 0);
+ foreach (PlayerControl p in PlayerControl.AllPlayerControls) {
+ if (!Arsonist.dousedIcons.ContainsKey(p.PlayerId)) continue;
+ if (p.Data.IsDead || p.Data.Disconnected) {
+ Arsonist.dousedIcons[p.PlayerId].gameObject.SetActive(true);
+ } else {
+ Arsonist.dousedIcons[p.PlayerId].transform.localPosition = bottomLeft + Vector3.right * visibleCounter * 0.35f;
+ visibleCounter++;
+ }
+ }
+ }
}
}
}
crewSettings.Add((byte)RoleId.Hacker, CustomOptionHolder.hackerSpawnRate.getSelection());
crewSettings.Add((byte)RoleId.Tracker, CustomOptionHolder.trackerSpawnRate.getSelection());
crewSettings.Add((byte)RoleId.Snitch, CustomOptionHolder.snitchSpawnRate.getSelection());
- crewSettings.Add((byte)RoleId.Jackal, CustomOptionHolder.jackalSpawnRate.getSelection());
if (impostors.Count > 1) // Spy is useless with less than 2 Impostors
crewSettings.Add((byte)RoleId.Spy, CustomOptionHolder.spySpawnRate.getSelection());
crewSettings.Add((byte)RoleId.SecurityGuard, CustomOptionHolder.securityGuardSpawnRate.getSelection());
}
}
} else { // Other
- for (int j = 0; j < entry.Value; j++) crewTickets.Add(entry.Key);
+ for (int j = 0; j < entry.Value; j++) neutralTickets.Add(entry.Key);
}
}
}
public static bool dousedEveryoneAlive() {
- return PlayerControl.AllPlayerControls.ToArray().All(x => { return x == Arsonist.arsonist || x.Data.IsDead || Arsonist.dousedPlayers.Any(y => y.PlayerId == x.PlayerId); });
+ return PlayerControl.AllPlayerControls.ToArray().All(x => { return x == Arsonist.arsonist || x.Data.IsDead || x.Data.Disconnected || Arsonist.dousedPlayers.Any(y => y.PlayerId == x.PlayerId); });
}
public static void clearAndReload() {
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.1</TargetFramework>
- <Version>2.6.0</Version>
+ <Version>2.6.1</Version>
<Description>TheOtherRoles</Description>
<Authors>Eisbison</Authors>
</PropertyGroup>