diff --git a/README.md b/README.md index 3ed0f7fcc..4c02ef374 100644 --- a/README.md +++ b/README.md @@ -42,6 +42,8 @@ The [Role Assignment](#role-assignment) sections explains how the roles are bein # 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) @@ -125,6 +127,9 @@ The [Role Assignment](#role-assignment) sections explains how the roles are bein
Click to show the Changelog +**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. @@ -801,7 +806,7 @@ docker run -d -p 22023:22023/udp --env IMPOSTOR_AntiCheatEnabled=false --env IMP [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): @@ -2103,12 +2108,15 @@ When a Prop dies, they will either join the Hunter team or die (setting). #### 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 diff --git a/TheOtherRoles/CustomGameModes/PropHunt.cs b/TheOtherRoles/CustomGameModes/PropHunt.cs index cc5ab1f9e..bdbd39d47 100644 --- a/TheOtherRoles/CustomGameModes/PropHunt.cs +++ b/TheOtherRoles/CustomGameModes/PropHunt.cs @@ -122,17 +122,9 @@ public static Sprite getIntroSprite(int index) { 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) { @@ -157,18 +149,20 @@ public static void update() { 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(); 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().sprite = poolablesBackgroundSprite; poolablesBackground.transform.localScale = new Vector3(poolablesBackground.transform.localScale.x * backgroundSizeX / poolablesBackground.GetComponent().bounds.size.x, poolablesBackground.transform.localScale.y, poolablesBackground.transform.localScale.z); @@ -188,7 +182,7 @@ public static void update() { // Display Prop poolablePlayer.cosmetics.nameText.text = Helpers.cs(Palette.CrewmateBlue, pc.Data.PlayerName); ; if (isCurrentlyRevealed.ContainsKey(pc.PlayerId)) { - + } } // update currently revealed: @@ -219,25 +213,18 @@ public static void update() { } } } + } - // 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().color = new Color(1f, 1f, 1f, PlayerControl.LocalPlayer.Data.IsDead || PlayerControl.LocalPlayer.PlayerId == playerId ? 0.1f: 0f); + pc.GetComponent().color = new Color(1f, 1f, 1f, PlayerControl.LocalPlayer.Data.IsDead || PlayerControl.LocalPlayer.PlayerId == playerId ? 0.1f : 0f); - } - else { + } else { pc.GetComponent().color = new Color(1f, 1f, 1f, 1f); invisPlayers.Remove(playerId); } @@ -245,8 +232,18 @@ public static void update() { revealRenderer[playerId].GetComponent().color = pc.GetComponent().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; @@ -268,6 +265,28 @@ public static void update() { 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)) { diff --git a/TheOtherRoles/Helpers.cs b/TheOtherRoles/Helpers.cs index 8dfc3ab89..21a2d7536 100644 --- a/TheOtherRoles/Helpers.cs +++ b/TheOtherRoles/Helpers.cs @@ -100,6 +100,7 @@ public static AudioClip loadAudioClipFromResources(string path, string clipName int channels = 2; int sampleRate = 48000; AudioClip audioClip = AudioClip.Create(clipName, samples.Length / 2, channels, sampleRate, false); + audioClip.hideFlags |= HideFlags.HideAndDontSave | HideFlags.DontSaveInEditor; audioClip.SetData(samples, 0); return audioClip; } catch { diff --git a/TheOtherRoles/SoundEffectsManager.cs b/TheOtherRoles/SoundEffectsManager.cs index ba153bb8f..006693f42 100644 --- a/TheOtherRoles/SoundEffectsManager.cs +++ b/TheOtherRoles/SoundEffectsManager.cs @@ -42,9 +42,8 @@ public static void play(string path, float volume=0.8f, bool loop = false) { if (!TORMapOptions.enableSoundEffects) return; AudioClip clipToPlay = get(path); - // if (false) clipToPlay = get("exampleClip"); for april fools? stop(path); - if (Constants.ShouldPlaySfx()) { + if (Constants.ShouldPlaySfx() && clipToPlay != null) { AudioSource source = SoundManager.Instance.PlaySound(clipToPlay, false, volume); source.loop = loop; }