diff --git a/NewMod.sln b/NewMod.sln index e9228dc..214457f 100644 --- a/NewMod.sln +++ b/NewMod.sln @@ -8,15 +8,12 @@ Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU Release|Any CPU = Release|Any CPU - ANDROID|Any CPU = ANDROID|Any CPU EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {FC05DD49-CE3A-41F4-8452-37686FE23D0A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {FC05DD49-CE3A-41F4-8452-37686FE23D0A}.Debug|Any CPU.Build.0 = Debug|Any CPU {FC05DD49-CE3A-41F4-8452-37686FE23D0A}.Release|Any CPU.ActiveCfg = Release|Any CPU {FC05DD49-CE3A-41F4-8452-37686FE23D0A}.Release|Any CPU.Build.0 = Release|Any CPU - {FC05DD49-CE3A-41F4-8452-37686FE23D0A}.ANDROID|Any CPU.ActiveCfg = ANDROID|Any CPU - {FC05DD49-CE3A-41F4-8452-37686FE23D0A}.ANDROID|Any CPU.Build.0 = ANDROID|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/NewMod/Buttons/Revenant/DoomAwakening.cs b/NewMod/Buttons/Revenant/DoomAwakening.cs index 8e5789d..742ec01 100644 --- a/NewMod/Buttons/Revenant/DoomAwakening.cs +++ b/NewMod/Buttons/Revenant/DoomAwakening.cs @@ -155,7 +155,7 @@ public System.Collections.IEnumerator StartDoomAwakening(PlayerControl player) // Kill any nearby players foreach (var target in PlayerControl.AllPlayerControls) { - if (target == player || target.Data.IsDead || target.Data.Disconnected || target.inVent || target.Data.Role.IsImpostor) + if (target == player || target.Data.IsDead || target.Data.Disconnected || target.inVent || target.Data.Role.IsImpostor || target.Data.PlayerName == "Wraith NPC") continue; if (Vector2.Distance(player.GetTruePosition(), target.GetTruePosition()) < 1f) diff --git a/NewMod/DiscordStatus.cs b/NewMod/DiscordStatus.cs index 68d7854..a8dde5a 100644 --- a/NewMod/DiscordStatus.cs +++ b/NewMod/DiscordStatus.cs @@ -20,6 +20,12 @@ public static bool StartPrefix(DiscordManager __instance) { if (Application.platform == RuntimePlatform.Android) return true; + InitializeDiscord(__instance); + return false; + } + + private static void InitializeDiscord(DiscordManager __instance) + { const long clientId = 1405946628115791933; discord = new Discord.Discord(clientId, (ulong)CreateFlags.Default); @@ -34,8 +40,6 @@ public static bool StartPrefix(DiscordManager __instance) })); __instance.presence = discord; __instance.SetInMenus(); - - return false; } [HarmonyPrefix] diff --git a/NewMod/LocalSettings/NewModLocalSettings.cs b/NewMod/LocalSettings/NewModLocalSettings.cs index 3d52b8c..a81c383 100644 --- a/NewMod/LocalSettings/NewModLocalSettings.cs +++ b/NewMod/LocalSettings/NewModLocalSettings.cs @@ -17,14 +17,6 @@ public class NewModLocalSettings(ConfigFile config) : LocalSettingsTab(config) TabIcon = NewModAsset.NMIcon, }; - [LocalSliderSetting("Frame Rate Limit", min: 30f, max: 240f, "Lock your framerate (FPS)", displayValue: true, formatString: "0", roundValue: true)] - public ConfigEntry FrameRateLimit { get; } = config.Bind( - "Performance", - "FrameRateLimit", - 165f, - "Frames per second limit" - ); - [LocalToggleSetting("Enable Custom Cursor", "Enable the custom cursor from the birthday update")] public ConfigEntry EnableCustomCursor { get; } = config.Bind( "Features", @@ -45,11 +37,6 @@ public override void OnOptionChanged(ConfigEntryBase configEntry) { base.OnOptionChanged(configEntry); - if (configEntry == FrameRateLimit) - { - Application.targetFrameRate = (int)FrameRateLimit.Value; - } - if (configEntry == AlwaysButtonsLeft && Application.platform == RuntimePlatform.Android) { foreach (var btn in CustomButtonManager.Buttons) diff --git a/NewMod/NewMod.cs b/NewMod/NewMod.cs index 681d7f9..3aeaacf 100644 --- a/NewMod/NewMod.cs +++ b/NewMod/NewMod.cs @@ -24,7 +24,6 @@ using MiraAPI.Events; using NewMod.Patches.Compatibility; using NewMod.Buttons.Overload; -using MiraAPI.LocalSettings; namespace NewMod; @@ -36,154 +35,145 @@ namespace NewMod; [BepInProcess("Among Us.exe")] public partial class NewMod : BasePlugin, IMiraPlugin { - public const string Id = "com.callofcreator.newmod"; - public const string ModVersion = "1.2.8"; - public Harmony Harmony { get; } = new Harmony(Id); - public static BasePlugin Instance; - public static Minigame minigame; - public const string SupportedAmongUsVersion = "2025.10.14"; - public static ConfigEntry ShouldEnableBepInExConsole { get; set; } - public ConfigFile GetConfigFile() => Config; - public string OptionsTitleText => "NewMod"; - public override void Load() - { - Instance = this; - AddComponent(); - ReactorCredits.Register(ReactorCredits.AlwaysShow); - Harmony.PatchAll(); - CheckVersionCompatibility(); - NewModEventHandler.RegisterEventsLogs(); + public const string Id = "com.callofcreator.newmod"; + public const string ModVersion = "1.2.9"; + public Harmony Harmony { get; } = new Harmony(Id); + public static BasePlugin Instance; + public static Minigame minigame; + public static ConfigEntry ShouldEnableBepInExConsole { get; set; } + public ConfigFile GetConfigFile() => Config; + public string OptionsTitleText => "NewMod"; + public override void Load() + { + Instance = this; + AddComponent(); + ReactorCredits.Register(ReactorCredits.AlwaysShow); + Harmony.PatchAll(); + NewModEventHandler.RegisterEventsLogs(); - if (ModCompatibility.IsLaunchpadLoaded()) - { - Harmony.PatchAll(typeof(LaunchpadCompatibility)); - Harmony.PatchAll(typeof(LaunchpadHackTextPatch)); - } - ShouldEnableBepInExConsole = Config.Bind("NewMod", "Console", true, "Whether to enable BepInEx Console for debugging"); - if (!ShouldEnableBepInExConsole.Value) ConsoleManager.DetachConsole(); + if (ModCompatibility.IsLaunchpadLoaded()) + { + Harmony.PatchAll(typeof(LaunchpadCompatibility)); + Harmony.PatchAll(typeof(LaunchpadHackTextPatch)); + } + ShouldEnableBepInExConsole = Config.Bind("NewMod", "Console", true, "Whether to enable BepInEx Console for debugging"); + if (!ShouldEnableBepInExConsole.Value) ConsoleManager.DetachConsole(); - var bundle = NewModAsset.Bundle; - var assetNames = bundle.GetAllAssetNames(); + var bundle = NewModAsset.Bundle; + var assetNames = bundle.GetAllAssetNames(); - Instance.Log.LogMessage($"AssetBundle '{bundle.name}' contains {assetNames.Length} assets"); + Instance.Log.LogMessage($"AssetBundle '{bundle.name}' contains {assetNames.Length} assets"); - foreach (var name in assetNames) - { - Instance.Log.LogMessage($"{name}"); - } + foreach (var name in assetNames) + { + Instance.Log.LogMessage($"{name}"); + } - Instance.Log.LogMessage($"Loaded Successfully NewMod v{ModVersion} With MiraAPI Version : {MiraApiPlugin.Version}"); - } - public static void CheckVersionCompatibility() - { - if (Application.version != SupportedAmongUsVersion) - { - Instance.Log.LogError($"Detected unsupported Among Us version. Current version: {Application.version}, Supported version: {SupportedAmongUsVersion}"); - } - } + Instance.Log.LogMessage($"Loaded Successfully NewMod v{ModVersion} With MiraAPI Version : {MiraApiPlugin.Version}"); + } - [HarmonyPatch(typeof(KeyboardJoystick), nameof(KeyboardJoystick.Update))] - public class KeyboardJoystickUpdatePatch - { - public static void Postfix(KeyboardJoystick __instance) - { - InitializeKeyBinds(); - } - } - public static void InitializeKeyBinds() - { - if (Input.GetKeyDown(KeyCode.F2) && PlayerControl.LocalPlayer.Data.IsDead && OptionGroupSingleton.Instance.AllowCams) - { - var sys = Utils.FindSurveillanceConsole(); - var mainCam = Camera.main; - if (mainCam == null) return; + [HarmonyPatch(typeof(KeyboardJoystick), nameof(KeyboardJoystick.Update))] + public class KeyboardJoystickUpdatePatch + { + public static void Postfix(KeyboardJoystick __instance) + { + InitializeKeyBinds(); + } + } + public static void InitializeKeyBinds() + { + if (Input.GetKeyDown(KeyCode.F2) && PlayerControl.LocalPlayer.Data.IsDead && OptionGroupSingleton.Instance.AllowCams) + { + var sys = Utils.FindSurveillanceConsole(); + var mainCam = Camera.main; + if (mainCam == null) return; - var minigame = Object.Instantiate(sys.MinigamePrefab, mainCam.transform, false); - minigame.transform.localPosition = new Vector3(0f, 0f, -50f); - minigame.Begin(null); - } - if (Input.GetKeyDown(KeyCode.F3) && PlayerControl.LocalPlayer.Data.Role is NecromancerRole) - { - var deadBodies = Helpers.GetNearestDeadBodies(PlayerControl.LocalPlayer.GetTruePosition(), 20f, Helpers.CreateFilter(Constants.NotShipMask)); - if (deadBodies != null && deadBodies.Count > 0) - { - var randomIndex = Random.Range(0, deadBodies.Count); - var randomBodyPosition = deadBodies[randomIndex].transform.position; - PlayerControl.LocalPlayer.NetTransform.RpcSnapTo(randomBodyPosition); - } - else - { - CoroutinesHelper.CoNotify("No dead bodies nearby to teleport to."); - } - } - } + var minigame = Object.Instantiate(sys.MinigamePrefab, mainCam.transform, false); + minigame.transform.localPosition = new Vector3(0f, 0f, -50f); + minigame.Begin(null); + } + if (Input.GetKeyDown(KeyCode.F3) && PlayerControl.LocalPlayer.Data.Role is NecromancerRole) + { + var deadBodies = Helpers.GetNearestDeadBodies(PlayerControl.LocalPlayer.GetTruePosition(), 20f, Helpers.CreateFilter(Constants.NotShipMask)); + if (deadBodies != null && deadBodies.Count > 0) + { + var randomIndex = Random.Range(0, deadBodies.Count); + var randomBodyPosition = deadBodies[randomIndex].transform.position; + PlayerControl.LocalPlayer.NetTransform.RpcSnapTo(randomBodyPosition); + } + else + { + CoroutinesHelper.CoNotify("No dead bodies nearby to teleport to."); + } + } + } - [RegisterEvent] - public static void OnBeforeMurder(BeforeMurderEvent evt) - { - if (evt.Target != OverloadRole.chosenPrey) return; + [RegisterEvent] + public static void OnBeforeMurder(BeforeMurderEvent evt) + { + if (evt.Target != OverloadRole.chosenPrey) return; - //TODO: Use the newest MiraAPI roles for button mapping - if (evt.Target.Data.Role is ICustomRole customRole && Utils.RoleToButtonsMap.TryGetValue(customRole.GetType(), out var buttonsType)) - { - OverloadRole.CachedButtons = [.. CustomButtonManager.Buttons.Where(b => buttonsType.Contains(b.GetType()))]; - Instance.Log.LogMessage($"CachedButton: {buttonsType.GetType().Name}"); - } - } - [RegisterEvent] - public static void OnAfterMurder(AfterMurderEvent evt) - { - var source = evt.Source; - var target = evt.Target; - Utils.RecordOnKill(source, target); + //TODO: Use the newest MiraAPI roles for button mapping + if (evt.Target.Data.Role is ICustomRole customRole && Utils.RoleToButtonsMap.TryGetValue(customRole.GetType(), out var buttonsType)) + { + OverloadRole.CachedButtons = [.. CustomButtonManager.Buttons.Where(b => buttonsType.Contains(b.GetType()))]; + Instance.Log.LogMessage($"CachedButton: {buttonsType.GetType().Name}"); + } + } + [RegisterEvent] + public static void OnAfterMurder(AfterMurderEvent evt) + { + var source = evt.Source; + var target = evt.Target; + Utils.RecordOnKill(source, target); - if (target != OverloadRole.chosenPrey) return; + if (target != OverloadRole.chosenPrey) return; - foreach (var pc in PlayerControl.AllPlayerControls.ToArray().Where(p => p.AmOwner && p.Data.Role is OverloadRole)) - { - if (target.Data.Role is ICustomRole customRole) - { - foreach (var button in OverloadRole.CachedButtons) + foreach (var pc in PlayerControl.AllPlayerControls.ToArray().Where(p => p.AmOwner && p.Data.Role is OverloadRole)) + { + if (target.Data.Role is ICustomRole customRole) { - CustomButtonSingleton.Instance.Absorb(button); - Debug.Log($"[Overload] Successfully absorbed ability: {button.Name}"); + foreach (var button in OverloadRole.CachedButtons) + { + CustomButtonSingleton.Instance.Absorb(button); + Debug.Log($"[Overload] Successfully absorbed ability: {button.Name}"); + } } - } - else if (target.Data.Role is not ICustomRole) - { - var btn = Object.Instantiate( - HudManager.Instance.AbilityButton, - HudManager.Instance.AbilityButton.transform.parent); - btn.SetFromSettings(target.Data.Role.Ability); - var pb = btn.GetComponent(); - pb.OnClick.RemoveAllListeners(); - pb.OnClick.AddListener((UnityAction)target.Data.Role.UseAbility); - } - } - OverloadRole.CachedButtons.Clear(); - OverloadRole.AbsorbedAbilityCount++; - OverloadRole.chosenPrey = null; - Coroutines.Start(CoroutinesHelper.CoNotify($"Charge {OverloadRole.AbsorbedAbilityCount}/{OptionGroupSingleton.Instance.NeededCharge}")); + else if (target.Data.Role is not ICustomRole) + { + var btn = Object.Instantiate( + HudManager.Instance.AbilityButton, + HudManager.Instance.AbilityButton.transform.parent); + btn.SetFromSettings(target.Data.Role.Ability); + var pb = btn.GetComponent(); + pb.OnClick.RemoveAllListeners(); + pb.OnClick.AddListener((UnityAction)target.Data.Role.UseAbility); + } + } + OverloadRole.CachedButtons.Clear(); + OverloadRole.AbsorbedAbilityCount++; + OverloadRole.chosenPrey = null; + Coroutines.Start(CoroutinesHelper.CoNotify($"Charge {OverloadRole.AbsorbedAbilityCount}/{OptionGroupSingleton.Instance.NeededCharge}")); - if (OverloadRole.AbsorbedAbilityCount >= OptionGroupSingleton.Instance.NeededCharge) - { - Coroutines.Start(CoroutinesHelper.CoNotify("Objective completed: Final Ability unlocked!")); - } - else - { - Coroutines.Start(OverloadRole.CoShowMenu(1f)); - } - } + if (OverloadRole.AbsorbedAbilityCount >= OptionGroupSingleton.Instance.NeededCharge) + { + Coroutines.Start(CoroutinesHelper.CoNotify("Objective completed: Final Ability unlocked!")); + } + else + { + Coroutines.Start(OverloadRole.CoShowMenu(1f)); + } + } - [HarmonyPatch(typeof(TaskPanelBehaviour), nameof(TaskPanelBehaviour.SetTaskText))] - public static class SetTaskTextPatch - { - public static void Postfix(TaskPanelBehaviour __instance, [HarmonyArgument(0)] string str) - { - if (PlayerControl.LocalPlayer.Data.IsDead) - { - __instance.taskText.text += "\n" + (OptionGroupSingleton.Instance.AllowCams ? "Press F2 For Open Cams" : "You cannot open cams because the host has disabled this setting"); - } - } - } + [HarmonyPatch(typeof(TaskPanelBehaviour), nameof(TaskPanelBehaviour.SetTaskText))] + public static class SetTaskTextPatch + { + public static void Postfix(TaskPanelBehaviour __instance, [HarmonyArgument(0)] string str) + { + if (PlayerControl.LocalPlayer.Data.IsDead) + { + __instance.taskText.text += "\n" + (OptionGroupSingleton.Instance.AllowCams ? "Press F2 For Open Cams" : "You cannot open cams because the host has disabled this setting"); + } + } + } } diff --git a/NewMod/NewMod.csproj b/NewMod/NewMod.csproj index 16f74ed..ecceb52 100644 --- a/NewMod/NewMod.csproj +++ b/NewMod/NewMod.csproj @@ -1,28 +1,19 @@ - 1.2.8 + 1.2.9 dev NewMod is a mod for Among Us that introduces a variety of new roles, unique abilities CallofCreator net6.0 latest embedded - Debug;Release;ANDROID - - - - TRACE;PC - - - - TRACE;ANDROID_BUILD + Debug;Release; - - - + + @@ -31,4 +22,4 @@ - \ No newline at end of file + diff --git a/NewMod/Patches/Roles/Beacon/ShowMapPatch.cs b/NewMod/Patches/Roles/Beacon/ShowMapPatch.cs index e63fb2b..b8210b5 100644 --- a/NewMod/Patches/Roles/Beacon/ShowMapPatch.cs +++ b/NewMod/Patches/Roles/Beacon/ShowMapPatch.cs @@ -75,11 +75,6 @@ public static class BeaconOverlayTintKeeper static void Postfix(MapCountOverlay __instance) { if (PlayerControl.LocalPlayer.Data.Role is not BC) return; - if (Time.time >= BC.pulseUntil) - { - var effect = Camera.main.GetComponent(); - Object.Destroy(effect); ; - } var map = MapBehaviour.Instance; if (!map || !map.IsOpen) return; @@ -111,6 +106,11 @@ public static IEnumerator CoUpdateMarkers(MapBehaviour map) } yield return null; } + if (Time.time >= BC.pulseUntil) + { + Object.Destroy(Camera.main.GetComponent()); + NewMod.Instance.Log.LogError("DESTROYED EFFECT"); + } ClearMarkers(); if (map && map.IsOpen) diff --git a/NewMod/Resources/Logo.png b/NewMod/Resources/Logo.png index 7d4c6bd..b4e2940 100644 Binary files a/NewMod/Resources/Logo.png and b/NewMod/Resources/Logo.png differ diff --git a/NewMod/Roles/CrewmateRoles/Beacon.cs b/NewMod/Roles/CrewmateRoles/Beacon.cs index 7cb37ae..ec3a628 100644 --- a/NewMod/Roles/CrewmateRoles/Beacon.cs +++ b/NewMod/Roles/CrewmateRoles/Beacon.cs @@ -70,7 +70,9 @@ public override bool DidWin(GameOverReason gameOverReason) [RegisterEvent] public static void OnRoundStart(RoundStartEvent evt) { - if (PlayerControl.LocalPlayer.Data.Role is not Beacon) return; + pulseUntil = 0f; + cooldownUntil = 0f; + charges = (int)OptionGroupSingleton.Instance.MaxCharges; } [RegisterEvent] public static void OnTaskComplete(CompleteTaskEvent evt) diff --git a/NewMod/Roles/NeutralRoles/Shade.cs b/NewMod/Roles/NeutralRoles/Shade.cs index 0afc266..99361ec 100644 --- a/NewMod/Roles/NeutralRoles/Shade.cs +++ b/NewMod/Roles/NeutralRoles/Shade.cs @@ -74,7 +74,7 @@ public static void OnAfterMurder(AfterMurderEvent evt) Utils.RecordOnKill(killer, victim); - if (killer.Data.Role is not Shade shadeRole) + if (killer.Data.Role is not Shade) return; if (!ShadowZone.IsInsideAny(victim.GetTruePosition())) diff --git a/NewMod/Utilities/Utils.cs b/NewMod/Utilities/Utils.cs index 69d74d2..498b518 100644 --- a/NewMod/Utilities/Utils.cs +++ b/NewMod/Utilities/Utils.cs @@ -343,7 +343,12 @@ public static void ResetMissionSuccessCount() public static void RecordMissionFailure(PlayerControl specialAgent) { var playerId = specialAgent.PlayerId; - MissionFailureCount[playerId] = GetMissionFailureCount(playerId) + 1; + int currentFailureCount = GetMissionFailureCount(playerId); + + if (currentFailureCount >= 0) + { + MissionFailureCount[playerId] = currentFailureCount + 1; + } } /// diff --git a/README.md b/README.md index 80c3c26..18af618 100644 --- a/README.md +++ b/README.md @@ -51,6 +51,7 @@ | v1.2.6 | v16.1.0 (2025.6.10) | [Download](https://github.com/CallOfCreator/NewMod/releases/download/V1.2.6/NewMod.zip) | | v1.2.7 | v17.0.0 (2025.9.9) | [Download](https://github.com/CallOfCreator/NewMod/releases/download/V1.2.7/NewMod.zip) | | v1.2.8 | v17.0.1 (2025.10.14) & v17.1.0 (2025.11.18) | [Download](https://github.com/CallOfCreator/NewMod/releases/download/V1.2.8/NewMod.zip) | +| v1.2.9 | v17.1.0 (2025.11.18) |[Download](https://github.com/CallOfCreator/NewMod/releases/download/V1.2.9/NewMod.zip) | --- @@ -77,9 +78,10 @@ NewMod is compatible with the following mods, enabling an enhanced experience wi | Mod ame | Mod Version | GitHub Link | Status | |-------------------|-------------|------------------------------------------------------|-------------| | yanplaRoles | v0.2.1+ | [Download](https://github.com/yanpla/yanplaRoles) | ✅ Supported | -| LaunchpadReloaded | v0.3.4+ | [Download](https://github.com/All-Of-Us-Mods/LaunchpadReloaded) | ✅ Supported | -| LevelImposter | v0.20.3+ | [Download](https://github.com/DigiWorm0/LevelImposter) | ✅ Supported | -| Submerged | v2025.10.22 | [Download](https://github.com/SubmergedAmongUs/Submerged) | ✅ Supported | +| LaunchpadReloaded | v0.3.7+ | [Download](https://github.com/All-Of-Us-Mods/LaunchpadReloaded) | ✅ Supported | +| LevelImposter | v0.21.2-beta+ | [Download](https://github.com/DigiWorm0/LevelImposter) | ✅ Supported | +| Submerged | v2025.11.20+ | [Download](https://github.com/SubmergedAmongUs/Submerged) | ✅ Supported | +| Town Of Us Mira | v1.5.2+ | [Download](https://github.com/Au-Avengers/TOU-Mira) | ✅ Supported | ---