Skip to content

Commit

Permalink
Update v4.5.2
Browse files Browse the repository at this point in the history
  • Loading branch information
gendelo3 committed Mar 8, 2024
1 parent 9d65875 commit 7b072c9
Show file tree
Hide file tree
Showing 22 changed files with 299 additions and 226 deletions.
21 changes: 17 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,15 +42,16 @@ The [Role Assignment](#role-assignment) section explains how the roles are being
# Releases
| Among Us - Version| Mod Version | Link |
|----------|-------------|-----------------|
| 2024.3.5s| v4.5.2| [Download](https://github.com/TheOtherRolesAU/TheOtherRoles/releases/download/v4.5.2/TheOtherRoles.zip)
| 2023.11.28s| v4.5.1| [Download](https://github.com/TheOtherRolesAU/TheOtherRoles/releases/download/v4.5.1/TheOtherRoles.zip)
| 2023.11.28s| v4.5.0| [Download](https://github.com/TheOtherRolesAU/TheOtherRoles/releases/download/v4.5.0/TheOtherRoles.zip)
| 2023.07.12s| v4.4.2| [Download](https://github.com/TheOtherRolesAU/TheOtherRoles/releases/download/v4.4.2/TheOtherRoles.zip)

<details>
<summary>Click to show older versions</summary>

| Among Us - Version| Mod Version | Link |
|----------|-------------|-----------------|
| 2023.11.28s| v4.5.0| [Download](https://github.com/TheOtherRolesAU/TheOtherRoles/releases/download/v4.5.0/TheOtherRoles.zip)
| 2023.07.12s| v4.4.2| [Download](https://github.com/TheOtherRolesAU/TheOtherRoles/releases/download/v4.4.2/TheOtherRoles.zip)
| 2023.07.12s| v4.4.1| [Download](https://github.com/TheOtherRolesAU/TheOtherRoles/releases/download/v4.4.1/TheOtherRoles.zip)
| 2023.07.12s| v4.4.0| [Download](https://github.com/TheOtherRolesAU/TheOtherRoles/releases/download/v4.4.0/TheOtherRoles.zip)
| 2023.07.12s| v4.3.4| [Download](https://github.com/Eisbison/TheOtherRoles/releases/download/v4.3.4/TheOtherRoles.zip)
Expand Down Expand Up @@ -131,6 +132,16 @@ The [Role Assignment](#role-assignment) section explains how the roles are being
<details>
<summary>Click to show the Changelog</summary>

**Version 4.5.2**
- Updated to Among Us version 2024.3.5s (various small / "long" features and bugfixes)
- Updated BepInEx dependency to 688
- Added a new feature: Stop the game start (With an option to allow any player to stop it)
- Added a new option (guesser mode): Sidekick is always guesser
- Fixed the Arsonist Win - death reasons for already dead players are no longer replaced
- Changed the implementation of the Detective footprints - Improved performance can be expected
- Changed the medic shield: Is now also displayed in meetings to players who can see it with brackets around the name


**Version 4.5.1**
- Fix a bug that lead to Props not being able to use the disguise button

Expand Down Expand Up @@ -853,6 +864,7 @@ Thanks to miniduikboot & GD for hosting modded servers (and so much more)

# Settings
The mod adds a few new settings to Among Us (in addition to the role settings):
- **Any Player Can Stop The Start:** If turned off, only the host can stop the game start. If on, all players can do it. Non-hosts stopping the start will send a chat message indicating who stopped it.
- **Number of Crewmates:** The number of Crewmate roles can be set inside a lobby.
- **Fill Crewmate Roles (Ignores Min/Max):** Everyone will get a role, even if the settings say there would be plain Crewmates (needs enough roles over 0%).
- **Number of Neutrals:** The number of Neutral roles can be set inside a lobby.
Expand Down Expand Up @@ -1584,7 +1596,7 @@ The Time Master won't be affected by the rewind.

## Medic
### **Team: Crewmates**
The Medic can shield (highlighted by an outline around the player) one player per game, which makes the player unkillable.\
The Medic can shield (highlighted by an outline around the player) one player per game, which makes the player unkillable.\ The shield is also shown in the meeting as brackets around the shielded player's name.
The shielded player can still be voted out and might also be an Impostor.\
If set in the options, the shielded player and/or the Medic will get a red flash on their screen if someone (Impostor, Sheriff, ...) tried to murder them.\
If the Medic dies, the shield disappears with them.\
Expand Down Expand Up @@ -2086,7 +2098,8 @@ Players can additionally have a modifier, if enabled (e.g. Medic Guesser Mini).
| Number of Neutral Guessers | -
| Number of Impostor Guessers | -
| Force Jackal Guesser | If set to "On", the first neutral role who will be Guesser is the Jackal.
| Force Thief Guesser | If set to "On", the first (or second if Force Jackal Guesser) neutral role who will be Guesser is the Thief.
| Sidekick Is Always Guesser | The converted sidekick will become a guesser | -
| Force Thief Guesser | If set to "On", the first (or second if Force Jackal Guesser) neutral role who will be Guesser is the Thief.
| Guessers Can Have A Modifier | -
| Guesser Number Of Shots | -
| Guesser Can Shoot Multiple Times Per Meeting | -
Expand Down
14 changes: 9 additions & 5 deletions TheOtherRoles/CustomOptionHolder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ public class CustomOptionHolder {
public static CustomOption modifiersCountMin;
public static CustomOption modifiersCountMax;

public static CustomOption enableCodenameHorsemode;
public static CustomOption enableCodenameDisableHorses;
public static CustomOption anyPlayerCanStopStart;
public static CustomOption enableEventMode;

public static CustomOption mafiaSpawnRate;
public static CustomOption janitorCooldown;
Expand Down Expand Up @@ -331,6 +331,7 @@ public class CustomOptionHolder {
public static CustomOption guesserGamemodeKillsThroughShield;
public static CustomOption guesserGamemodeEvilCanKillSpy;
public static CustomOption guesserGamemodeCantGuessSnitchIfTaksDone;
public static CustomOption guesserGamemodeSidekickIsAlwaysGuesser;

// Hide N Seek Gamemode
public static CustomOption hideNSeekHunterCount;
Expand Down Expand Up @@ -412,9 +413,9 @@ public static void Load() {
// Role Options
presetSelection = CustomOption.Create(0, Types.General, cs(new Color(204f / 255f, 204f / 255f, 0, 1f), "Preset"), presets, null, true);
activateRoles = CustomOption.Create(1, Types.General, cs(new Color(204f / 255f, 204f / 255f, 0, 1f), "Enable Mod Roles And Block Vanilla Roles"), true, null, true);
anyPlayerCanStopStart = CustomOption.Create(2, Types.General, cs(new Color(204f / 255f, 204f / 255f, 0, 1f), "Any Player Can Stop The Start"), false, null, false);

if (Utilities.EventUtility.canBeEnabled) enableCodenameHorsemode = CustomOption.Create(10423, Types.General, cs(Color.green, "Enable Codename Horsemode"), true, null, true);
if (Utilities.EventUtility.canBeEnabled) enableCodenameDisableHorses = CustomOption.Create(10424, Types.General, cs(Color.green, "Disable Horses"), false, enableCodenameHorsemode, false);
if (Utilities.EventUtility.canBeEnabled) enableEventMode = CustomOption.Create(10423, Types.General, cs(Color.green, "Enable Special Mode"), true, null, true);

// Using new id's for the options to not break compatibilty with older versions
crewmateRolesCountMin = CustomOption.Create(300, Types.General, cs(new Color(204f / 255f, 204f / 255f, 0, 1f), "Minimum Crewmate Roles"), 15f, 0f, 15f, 1f, null, true);
Expand All @@ -426,7 +427,7 @@ public static void Load() {
impostorRolesCountMax = CustomOption.Create(305, Types.General, cs(new Color(204f / 255f, 204f / 255f, 0, 1f), "Maximum Impostor Roles"), 15f, 0f, 15f, 1f);
modifiersCountMin = CustomOption.Create(306, Types.General, cs(new Color(204f / 255f, 204f / 255f, 0, 1f), "Minimum Modifiers"), 15f, 0f, 15f, 1f);
modifiersCountMax = CustomOption.Create(307, Types.General, cs(new Color(204f / 255f, 204f / 255f, 0, 1f), "Maximum Modifiers"), 15f, 0f, 15f, 1f);

mafiaSpawnRate = CustomOption.Create(18, Types.Impostor, cs(Janitor.color, "Mafia"), rates, null, true);
janitorCooldown = CustomOption.Create(19, Types.Impostor, "Janitor Cooldown", 30f, 10f, 60f, 2.5f, mafiaSpawnRate);

Expand Down Expand Up @@ -710,13 +711,16 @@ public static void Load() {
guesserGamemodeNeutralNumber = CustomOption.Create(2002, Types.Guesser, cs(Guesser.color, "Number of Neutral Guessers"), 15f, 1f, 15f, 1f, null, true);
guesserGamemodeImpNumber = CustomOption.Create(2003, Types.Guesser, cs(Guesser.color, "Number of Impostor Guessers"), 15f, 1f, 15f, 1f, null, true);
guesserForceJackalGuesser = CustomOption.Create(2007, Types.Guesser, "Force Jackal Guesser", false, null, true);
guesserGamemodeSidekickIsAlwaysGuesser = CustomOption.Create(2012, Types.Guesser, "Sidekick Is Always Guesser", false, null);
guesserForceThiefGuesser = CustomOption.Create(2011, Types.Guesser, "Force Thief Guesser", false, null, true);
guesserGamemodeHaveModifier = CustomOption.Create(2004, Types.Guesser, "Guessers Can Have A Modifier", true, null);
guesserGamemodeNumberOfShots = CustomOption.Create(2005, Types.Guesser, "Guesser Number Of Shots", 3f, 1f, 15f, 1f, null);
guesserGamemodeHasMultipleShotsPerMeeting = CustomOption.Create(2006, Types.Guesser, "Guesser Can Shoot Multiple Times Per Meeting", false, null);
guesserGamemodeKillsThroughShield = CustomOption.Create(2008, Types.Guesser, "Guesses Ignore The Medic Shield", true, null);
guesserGamemodeEvilCanKillSpy = CustomOption.Create(2009, Types.Guesser, "Evil Guesser Can Guess The Spy", true, null);
guesserGamemodeCantGuessSnitchIfTaksDone = CustomOption.Create(2010, Types.Guesser, "Guesser Can't Guess Snitch When Tasks Completed", true, null);
// Care: 2012 already taken!


// Hide N Seek Gamemode (3000 - 3999)
hideNSeekMap = CustomOption.Create(3020, Types.HideNSeekMain, cs(Color.yellow, "Map"), new string[] { "The Skeld", "Mira", "Polus", "Airship", "Fungle", "Submerged", "LI Map"}, null, true, onChange: () => { int map = hideNSeekMap.selection; if (map >= 3) map++; GameOptionsManager.Instance.currentNormalGameOptions.MapId = (byte)map; });
Expand Down
2 changes: 1 addition & 1 deletion TheOtherRoles/Main.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ namespace TheOtherRoles
public class TheOtherRolesPlugin : BasePlugin
{
public const string Id = "me.eisbison.theotherroles";
public const string VersionString = "4.5.1";
public const string VersionString = "4.5.2";
public static uint betaDays = 0; // amount of days for the build to be usable (0 for infinite!)

public static Version Version = Version.Parse(VersionString);
Expand Down
4 changes: 2 additions & 2 deletions TheOtherRoles/Modules/BepInExUpdater.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ namespace TheOtherRoles.Modules;

public class BepInExUpdater : MonoBehaviour
{
public const string RequiredBepInExVersion = "6.0.0-be.671+9caf61dca07043beae57b0771f6a5283aa02436b";
public const string BepInExDownloadURL = "https://builds.bepinex.dev/projects/bepinex_be/671/BepInEx-Unity.IL2CPP-win-x86-6.0.0-be.671%2B9caf61d.zip";
public const string RequiredBepInExVersion = "6.0.0-be.688+49015217f3becf052d33fa4658ac19229f5daa3a";
public const string BepInExDownloadURL = "https://builds.bepinex.dev/projects/bepinex_be/688/BepInEx-Unity.IL2CPP-win-x86-6.0.0-be.688%2B4901521.zip";
public static bool UpdateRequired => Paths.BepInExVersion.ToString() != RequiredBepInExVersion;

public void Awake()
Expand Down
56 changes: 44 additions & 12 deletions TheOtherRoles/Modules/CustomHats/CustomHatManager.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using UnityEngine;
using UnityEngine.AddressableAssets;
using System.Reflection;

namespace TheOtherRoles.Modules.CustomHats;

Expand All @@ -28,12 +30,11 @@ internal static string RepositoryUrl
internal static string CustomSkinsDirectory => Path.Combine(Path.GetDirectoryName(Application.dataPath)!, ResourcesDirectory);
internal static string HatsDirectory => CustomSkinsDirectory;

internal static readonly List<CustomHat> UnregisteredHats = new();
internal static List<CustomHat> UnregisteredHats = new();
internal static readonly Dictionary<string, HatViewData> ViewDataCache = new();
internal static readonly Dictionary<string, HatExtension> ExtensionCache = new();

private static readonly HatsLoader Loader;
private static Material cachedShader;

internal static HatExtension TestExtension { get; private set; }

Expand Down Expand Up @@ -71,8 +72,6 @@ internal static bool IsCached(this HatParent hatParent)

internal static HatData CreateHatBehaviour(CustomHat ch, bool testOnly = false)
{
if (cachedShader == null) cachedShader = DestroyableSingleton<HatManager>.Instance.PlayerMaterial;

var viewData = ViewDataCache[ch.Name] = ScriptableObject.CreateInstance<HatViewData>();
var hat = ScriptableObject.CreateInstance<HatData>();

Expand Down Expand Up @@ -101,16 +100,11 @@ internal static HatData CreateHatBehaviour(CustomHat ch, bool testOnly = false)
hat.ChipOffset = new Vector2(0f, 0.2f);
hat.Free = true;

if (ch.Adaptive && cachedShader != null)
{
viewData.AltShader = cachedShader;
}

var extend = new HatExtension
{
var extend = new HatExtension {
Author = ch.Author ?? "Unknown",
Package = ch.Package ?? "Misc.",
Condition = ch.Condition ?? "none"
Condition = ch.Condition ?? "none",
Adaptive = ch.Adaptive,
};

if (ch.FlipResource != null)
Expand Down Expand Up @@ -141,6 +135,8 @@ internal static HatData CreateHatBehaviour(CustomHat ch, bool testOnly = false)
private static Sprite CreateHatSprite(string path)
{
var texture = Helpers.loadTextureFromDisk(Path.Combine(HatsDirectory, path));
if (texture == null)
texture = Helpers.loadTextureFromResources(path);
if (texture == null) return null;
var sprite = Sprite.Create(texture,
new Rect(0, 0, texture.width, texture.height),
Expand Down Expand Up @@ -280,4 +276,40 @@ internal static List<string> GenerateDownloadList(List<CustomHat> hats)

return toDownload;
}

public static List<CustomHat> loadHorseHats() {
List<CustomHat> hatdatas = new();
Assembly assembly = Assembly.GetExecutingAssembly();
string[] resourceNames = assembly.GetManifestResourceNames();
List<string> hatFiles = new();
Dictionary<string, List<string>> hatFilesSorted = new Dictionary<string, List<string>>();
foreach (string resourceName in resourceNames) {
if (resourceName.Contains("TheOtherRoles.Resources.HorseHats.") && resourceName.Contains(".png")) {
hatFiles.Add(resourceName);
}
}

foreach (string s in hatFiles) {
string value = s.Substring(0, s.LastIndexOf("HorseSpecialHat") + 17);
if (value.Contains(".")) value.Remove(value.LastIndexOf("."));
if (!hatFilesSorted.ContainsKey(value)) hatFilesSorted.Add(value, new List<string>());
hatFilesSorted[value].Add(s);
}
int i = 0;
foreach (var item in hatFilesSorted) {
CustomHat info = new CustomHat();
info.Name = $"April Hat {i++:D2}";
info.Author = "A Fool";
info.Resource = item.Value.FirstOrDefault(x => !x.Contains("back"));
info.BackResource = item.Value.FirstOrDefault(x => x.Contains("back"));
info.Adaptive = info.Resource != null && info.Resource.Contains("adaptive");
info.FlipResource = item.Value.FirstOrDefault(x => x.Contains("flip"));
info.ClimbResource = item.Value.FirstOrDefault(x => x.Contains("climb"));
info.Package = "April Fools Hats";
if (info.Resource == null || info.Name == null) // required
continue;
hatdatas.Add(info);
}
return hatdatas;
}
}
1 change: 1 addition & 0 deletions TheOtherRoles/Modules/CustomHats/HatExtension.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,5 @@ public class HatExtension
public string Condition { get; set; }
public Sprite FlipImage { get; set; }
public Sprite BackFlipImage { get; set; }
public bool Adaptive { get; set; }
}
2 changes: 2 additions & 0 deletions TheOtherRoles/Modules/CustomHats/HatsLoader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using System.IO;
using System.Text.Json;
using BepInEx.Unity.IL2CPP.Utils;
using TheOtherRoles.Utilities;
using UnityEngine;
using UnityEngine.Networking;
using static TheOtherRoles.Modules.CustomHats.CustomHatManager;
Expand Down Expand Up @@ -51,6 +52,7 @@ private IEnumerator CoFetchHats()

UnregisteredHats.AddRange(SanitizeHats(response));
var toDownload = GenerateDownloadList(UnregisteredHats);
if (EventUtility.isEnabled) UnregisteredHats.AddRange(CustomHatManager.loadHorseHats());

TheOtherRolesPlugin.Logger.LogMessage($"I'll download {toDownload.Count} hat files");

Expand Down
20 changes: 11 additions & 9 deletions TheOtherRoles/Modules/CustomHats/Patches/HatParentPatches.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using HarmonyLib;
using PowerTools;
using TheOtherRoles;
using TheOtherRoles.Modules.CustomHats.Extensions;
using UnityEngine;

namespace TheOtherRoles.Modules.CustomHats.Patches;
Expand All @@ -24,7 +25,7 @@ private static void SetHatPrefix(HatParent __instance)
private static bool SetHatPrefix(HatParent __instance, HatData hat, int color)
{
if (SetCustomHat(__instance)) return true;
__instance.PopulateFromHatViewData();
__instance.PopulateFromViewData();
__instance.SetMaterialColor(color);
return false;
}
Expand All @@ -34,8 +35,8 @@ private static bool SetHatPrefix(HatParent __instance, HatData hat, int color)
private static bool SetHatPrefix(HatParent __instance, int color)
{
if (!__instance.IsCached()) return true;
__instance.hatDataAsset = null;
__instance.PopulateFromHatViewData();
__instance.viewAsset = null;
__instance.PopulateFromViewData();
__instance.SetMaterialColor(color);
return false;
}
Expand All @@ -45,12 +46,13 @@ private static bool SetHatPrefix(HatParent __instance, int color)
private static bool UpdateMaterialPrefix(HatParent __instance)
{
if (!__instance.TryGetCached(out var asset)) return true;
if (asset && asset.AltShader)
var extend = HatDataExtensions.GetHatExtension(__instance.Hat);
if (asset && extend != null && extend.Adaptive)
{
__instance.FrontLayer.sharedMaterial = asset.AltShader;
__instance.FrontLayer.sharedMaterial = DestroyableSingleton<HatManager>.Instance.PlayerMaterial;
if (__instance.BackLayer)
{
__instance.BackLayer.sharedMaterial = asset.AltShader;
__instance.BackLayer.sharedMaterial = DestroyableSingleton<HatManager>.Instance.PlayerMaterial;
}
}
else
Expand Down Expand Up @@ -185,8 +187,8 @@ private static bool SetIdleAnimPrefix(HatParent __instance, int colorId)
{
if (!__instance.Hat) return false;
if (!__instance.IsCached()) return true;
__instance.hatDataAsset = null;
__instance.PopulateFromHatViewData();
__instance.viewAsset = null;
__instance.PopulateFromViewData();
__instance.SetMaterialColor(colorId);
return false;
}
Expand All @@ -203,7 +205,7 @@ private static bool SetClimbAnimPrefix(HatParent __instance)
return false;
}

[HarmonyPatch(nameof(HatParent.PopulateFromHatViewData))]
[HarmonyPatch(nameof(HatParent.PopulateFromViewData))]
[HarmonyPrefix]
private static bool PopulateFromHatViewDataPrefix(HatParent __instance)
{
Expand Down
2 changes: 1 addition & 1 deletion TheOtherRoles/Modules/CustomOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ public static void switchPreset(int newPreset) {
}

public static void saveVanillaOptions() {
vanillaSettings.Value = Convert.ToBase64String(GameOptionsManager.Instance.gameOptionsFactory.ToBytes(GameManager.Instance.LogicOptions.currentGameOptions));
vanillaSettings.Value = Convert.ToBase64String(GameOptionsManager.Instance.gameOptionsFactory.ToBytes(GameManager.Instance.LogicOptions.currentGameOptions, false));
}

public static void loadVanillaOptions() {
Expand Down
Loading

0 comments on commit 7b072c9

Please sign in to comment.