# Releases
| Among Us - Version| Mod Version | Link |
|----------|-------------|-----------------|
+| 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)
| 2023.07.12s| v4.3.3| [Download](https://github.com/Eisbison/TheOtherRoles/releases/download/v4.3.3/TheOtherRoles.zip)
| 2023.03.28s| v4.3.2| [Download](https://github.com/Eisbison/TheOtherRoles/releases/download/v4.3.2/TheOtherRoles.zip)
<details>
<summary>Click to show the Changelog</summary>
+**Version 4.4.1**
+- Fixed a bug where PropHunt buttons did not work for the Hunters after watching the intro cutscene.
+
**Version 4.4.0**
- Added a new gamemode, PropHunt. Players can disguise as objects on the map
- Changed Lighter and Darker colors: L/D are no longer random, but rather assigned in alternating order.
[Goose-Goose-Duck](https://store.steampowered.com/app/1568590/Goose_Goose_Duck) - Idea for the Vulture role came from **Slushiegoose**\
[TheEpicRoles](https://github.com/LaicosVK/TheEpicRoles) - Idea for the first kill shield (partly) and the tabbed option menu (fully + some code), by **LaicosVK** **DasMonschta** **Nova**\
[Ninja](#ninja), [Thief](#thief), [Lawyer](#lawyer) / [Pursuer](#pursuer), [Deputy](#deputy), [Portalmaker](#portalmaker), [Guesser Modifier](#guesser-modifier) - Idea: [K3ndo](https://github.com/K3ndoo) ; Developed by [Gendelo](https://github.com/gendelo3) & [Mallöris](https://github.com/Mallaris) \
-[dMiner53](https://github.com/ugackMiner53/PropHunt) - Idea and core code for the Prop Hunt game mode
+[ugackMiner53](https://github.com/ugackMiner53/PropHunt) - Idea and core code for the Prop Hunt game mode
# Settings
The mod adds a few new settings to Among Us (in addition to the role settings):
#### Prop Abilities:
- Invisibility: As a disguised Prop, become invisible for x seconds.
- Speedboost: Move faster for x seconds.
+- Disguise: While near a usable object, press the button to disguise as the displayed object!
**NOTE:**
- The Report button lights up, but cannot be pressed.
- Hunters can vent
- The Kill Button and Vent Button are permanently enabled, so that you cannot use them to check if there is a prop nearby
- The Kill Button can always be pressed, but you can also miss if no Prop is nearby. The cooldown can be configured for hits and misses seperately.
+- Usable prop objects are: All task consoles as well as many objects (rocks, snowpeople, barriers, beds, tables, ...)
+- Any object on **LevelImposter** maps, that contains `liprop` in its name and has a `SpriteRenderer` (+ Sprite) will be usable as a prop too!
### Game Options
return Helpers.loadSpriteFromResources($"TheOtherRoles.Resources.IntroAnimation.intro_{index + 1000}.png", 150f, cache: false);
}
- public static void update() {
-
- if (!isPropHuntGM) {
- // Make sure the DangerMeter is not displayed in TOR HideNSeek, Classic or Guesser Game mode.
- if (GameOptionsManager.Instance.currentGameOptions.GameMode != AmongUs.GameOptions.GameModes.HideNSeek) HudManager.Instance.DangerMeter?.gameObject.SetActive(false);
- return;
- }
- if (timerRunning) timer = Math.Clamp(timer -= Time.deltaTime, 0, timer >= 0 ? timer : 0);
- else if (blackOutTimer > 0f) blackOutTimer -= Time.deltaTime;
- // Local player find prop Target:
+ public static void propTargetAndTimerDisplayUpdate() {
+
if (!PlayerControl.LocalPlayer.Data.Role.IsImpostor) currentTarget = FindClosestDisguiseObject(PlayerControl.LocalPlayer.gameObject, 1f);
if (timerText == null) {
timerText.text = Helpers.cs(timerRunning ? Color.blue : Color.red, suffix);
timerText.outlineColor = Color.white;
timerText.outlineWidth = 0.1f;
- timerText.color = timerRunning ? Color.blue : Color.red;
+ timerText.color = timerRunning ? Color.blue : Color.red;
}
}
if (HudManagerStartPatch.propDisguiseButton != null && HudManagerStartPatch.propDisguiseButton.Timer > HudManagerStartPatch.propDisguiseButton.MaxTimer) HudManagerStartPatch.propDisguiseButton.Timer = HudManagerStartPatch.propDisguiseButton.MaxTimer;
- // poolable players update.
+ }
+
+ public static void poolablePlayerUpdate() {
if (poolablesBackground == null) {
poolablesBackground = new GameObject("poolablesBackground");
poolablesBackground.AddComponent<SpriteRenderer>();
if (poolablesBackgroundSprite == null) poolablesBackgroundSprite = Helpers.loadSpriteFromResources("TheOtherRoles.Resources.poolablesBackground.jpg", 200f);
}
poolablesBackground.transform.SetParent(HudManager.Instance.transform);
- poolablesBackground.transform.localPosition = IntroCutsceneOnDestroyPatch.bottomLeft + new Vector3(-1.45f, -0.05f, 0) + Vector3.right * PlayerControl.AllPlayerControls.Count * 0.2f;
+ poolablesBackground.transform.localPosition = IntroCutsceneOnDestroyPatch.bottomLeft + new Vector3(-1.45f, -0.05f, 0) + Vector3.right * PlayerControl.AllPlayerControls.Count * 0.2f;
var backgroundSizeX = PlayerControl.AllPlayerControls.Count * 0.4f + 0.2f;
poolablesBackground.GetComponent<SpriteRenderer>().sprite = poolablesBackgroundSprite;
poolablesBackground.transform.localScale = new Vector3(poolablesBackground.transform.localScale.x * backgroundSizeX / poolablesBackground.GetComponent<SpriteRenderer>().bounds.size.x, poolablesBackground.transform.localScale.y, poolablesBackground.transform.localScale.z);
// Display Prop
poolablePlayer.cosmetics.nameText.text = Helpers.cs(Palette.CrewmateBlue, pc.Data.PlayerName); ;
if (isCurrentlyRevealed.ContainsKey(pc.PlayerId)) {
-
+
}
}
// update currently revealed:
}
}
}
+ }
- // speedboost
- foreach (var key in speedboostActive.Keys) {
- float speedboostTimer = speedboostActive[key] - Time.deltaTime;
- speedboostActive[key] = speedboostTimer;
- if (speedboostTimer < 0)
- speedboostActive.Remove(key);
- }
- // invisupdate
+ public static void invisUpdate() {
foreach (var playerId in invisPlayers.Keys) {
var pc = Helpers.playerById(playerId);
if (pc == null || pc.Data.IsDead) continue;
float timeLeft = invisPlayers[playerId] - Time.deltaTime;
invisPlayers[playerId] = timeLeft;
if (timeLeft > 0) {
- pc.GetComponent<SpriteRenderer>().color = new Color(1f, 1f, 1f, PlayerControl.LocalPlayer.Data.IsDead || PlayerControl.LocalPlayer.PlayerId == playerId ? 0.1f: 0f);
+ pc.GetComponent<SpriteRenderer>().color = new Color(1f, 1f, 1f, PlayerControl.LocalPlayer.Data.IsDead || PlayerControl.LocalPlayer.PlayerId == playerId ? 0.1f : 0f);
- }
- else {
+ } else {
pc.GetComponent<SpriteRenderer>().color = new Color(1f, 1f, 1f, 1f);
invisPlayers.Remove(playerId);
}
revealRenderer[playerId].GetComponent<SpriteRenderer>().color = pc.GetComponent<SpriteRenderer>().color;
}
}
+ }
+
+ public static void speedboostUpdate() {
+ foreach (var key in speedboostActive.Keys) {
+ float speedboostTimer = speedboostActive[key] - Time.deltaTime;
+ speedboostActive[key] = speedboostTimer;
+ if (speedboostTimer < 0)
+ speedboostActive.Remove(key);
+ }
+ }
- // Update dangerMeter
+ public static void dangerMeterUpdate() {
if (HudManager.Instance.DangerMeter.gameObject.active) {
float dist = 55f;
float dist2 = 15f;
HudManager.Instance.DangerMeter?.gameObject.SetActive(!PlayerControl.LocalPlayer.Data.IsDead && (!PlayerControl.LocalPlayer.Data.Role.IsImpostor || HudManagerStartPatch.propHuntFindButton.isEffectActive));
}
+
+ public static void update() {
+ if (!isPropHuntGM) {
+ // Make sure the DangerMeter is not displayed in TOR HideNSeek, Classic or Guesser Game mode.
+ if (GameOptionsManager.Instance.currentGameOptions.GameMode != AmongUs.GameOptions.GameModes.HideNSeek) HudManager.Instance.DangerMeter?.gameObject.SetActive(false);
+ return;
+ }
+ if (timerRunning) timer = Math.Clamp(timer -= Time.deltaTime, 0, timer >= 0 ? timer : 0);
+ else if (blackOutTimer > 0f) blackOutTimer -= Time.deltaTime;
+
+ // Local player find prop Target
+ propTargetAndTimerDisplayUpdate();
+
+ poolablePlayerUpdate();
+
+ speedboostUpdate();
+
+ invisUpdate();
+
+ dangerMeterUpdate();
+ }
+
public static void transformLayers() { // A bit of a hacky way to make sure that props as well as propable objects are not visible in the dark, while keeping collisions enabled.
PlayerControl.LocalPlayer.clearAllTasks();
foreach (Collider2D collider in Physics2D.OverlapCircleAll(PlayerControl.LocalPlayer.transform.position, 500)) {