mirror of
https://github.com/All-Of-Us-Mods/MiraAPI.git
synced 2026-10-19 15:51:48 +00:00
cleared all warnings
except for the todo ones, since they are supposed to be annoying
This commit is contained in:
84 files changed
+862
-595
No files matched your search
@@ -20,3 +20,18 @@ dotnet_diagnostic.S3358.severity = none
|
||||
|
||||
# IDE1006: Naming Styles
|
||||
dotnet_diagnostic.IDE1006.severity = none
|
||||
|
||||
# S3267: Use LINQ methods to simply foreach loops
|
||||
dotnet_diagnostic.S3267.severity = none
|
||||
|
||||
# S125: Sections of code should not be commented out
|
||||
dotnet_diagnostic.S125.severity = none
|
||||
|
||||
# SA1512: Single-line comments should not be followed by blank line
|
||||
dotnet_diagnostic.SA1512.severity = none
|
||||
|
||||
# S2696: Instance members should not write to "static" fields
|
||||
dotnet_diagnostic.S2696.severity = none
|
||||
|
||||
# S2245: Pseudorandom number generators (PRNGs) should not be used in security contexts
|
||||
dotnet_diagnostic.S2245.severity = none
|
||||
@@ -34,7 +34,7 @@
|
||||
<PackageReference Include="StyleCop.Analyzers" Version="1.2.0-beta.556" PrivateAssets="all" />
|
||||
<AdditionalFiles Include="$(MSBuildThisFileDirectory)\stylecop.json" Link="stylecop.json" Visible="false" />
|
||||
|
||||
<PackageReference Include="SonarAnalyzer.CSharp" Version="10.7.0.110445">
|
||||
<PackageReference Include="SonarAnalyzer.CSharp" Version="10.32.0.713">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
|
||||
</PackageReference>
|
||||
|
||||
@@ -12,6 +12,6 @@ public class GeneralModifierOptions : AbstractOptionGroup
|
||||
[ModdedToggleOption("options.generalModifier.someBooleanOption")]
|
||||
public bool SomeBooleanOption { get; set; } = true;
|
||||
|
||||
[ModdedNumberOption("options.generalModifier.numberOption", 0, 10, 1)]
|
||||
[ModdedNumberOption("options.generalModifier.numberOption", 0, 10)]
|
||||
public float NumberOption { get; set; } = 5;
|
||||
}
|
||||
@@ -5,26 +5,17 @@ namespace MiraAPI.Events.Mira;
|
||||
/// <summary>
|
||||
/// Event fired by Mira API to adjust the UI buttons at the top right of the screen.
|
||||
/// </summary>
|
||||
public class UiButtonPostResetEvent : MiraEvent
|
||||
/// <param name="topUiRow">The <see cref="GameObject"/> for the top UI row.</param>
|
||||
/// <param name="secondUiRow">The <see cref="GameObject"/> for the second UI row.</param>
|
||||
public class UiButtonPostResetEvent(GameObject topUiRow, GameObject secondUiRow) : MiraEvent
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the <see cref="GameObject"/> parent for the very top UI row.
|
||||
/// </summary>
|
||||
public GameObject MainTopUiRow { get; }
|
||||
public GameObject MainTopUiRow { get; } = topUiRow;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the <see cref="GameObject"/> parent for the second top UI row.
|
||||
/// </summary>
|
||||
public GameObject SecondTopUiRow { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="UiButtonPostResetEvent"/> class.
|
||||
/// </summary>
|
||||
/// <param name="topUiRow">The <see cref="GameObject"/> for the top UI row.</param>
|
||||
/// <param name="secondUiRow">The <see cref="GameObject"/> for the second UI row.</param>
|
||||
public UiButtonPostResetEvent(GameObject topUiRow, GameObject secondUiRow)
|
||||
{
|
||||
MainTopUiRow = topUiRow;
|
||||
SecondTopUiRow = secondUiRow;
|
||||
}
|
||||
public GameObject SecondTopUiRow { get; } = secondUiRow;
|
||||
}
|
||||
@@ -45,23 +45,13 @@ public sealed class BeforeMurderEvent(PlayerControl source, PlayerControl target
|
||||
/// </summary>
|
||||
public MeetingCheck InMeeting { get; } = inMeeting;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="BeforeMurderEvent"/> class.
|
||||
/// </summary>
|
||||
/// <param name="source">The <see cref="PlayerControl"/> that is killing the <paramref name="target"/>.</param>
|
||||
/// <param name="target">The <see cref="PlayerControl"/> that is being killed.</param>
|
||||
public BeforeMurderEvent(PlayerControl source, PlayerControl target)
|
||||
: this(source, target, MeetingCheck.Ignore)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="BeforeMurderEvent"/> class.
|
||||
/// </summary>
|
||||
/// <param name="source">The <see cref="PlayerControl"/> that is killing the <paramref name="target"/>.</param>
|
||||
/// <param name="target">The <see cref="PlayerControl"/> that is being killed.</param>
|
||||
/// <param name="inMeeting">Whether the murder is intended to be triggered in a meeting.</param>
|
||||
public BeforeMurderEvent(PlayerControl source, PlayerControl target, MeetingCheck inMeeting)
|
||||
public BeforeMurderEvent(PlayerControl source, PlayerControl target, MeetingCheck inMeeting = MeetingCheck.Ignore)
|
||||
: this(source, target, false, false, inMeeting)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
namespace MiraAPI.Events.Vanilla.Gameplay;
|
||||
|
||||
/// <summary>
|
||||
/// The event that is invoked when the end game screen is shown. Non cancelable.
|
||||
/// The event that is invoked when the end game screen is shown. Non-cancelable.
|
||||
/// </summary>
|
||||
/// <param name="manager">The <see cref="global::EndGameManager"/> instance.</param>
|
||||
public class GameEndEvent(EndGameManager manager) : MiraEvent
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
namespace MiraAPI.Events.Vanilla.Gameplay;
|
||||
|
||||
/// <summary>
|
||||
/// The event that is invoked when the intro cutscene is shown. Non cancelable.
|
||||
/// The event that is invoked when the intro cutscene is shown. Non-cancelable.
|
||||
/// </summary>
|
||||
/// <param name="introCutscene">The intro cutscene.</param>
|
||||
public class IntroBeginEvent(IntroCutscene introCutscene) : MiraEvent
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
namespace MiraAPI.Events.Vanilla.Gameplay;
|
||||
|
||||
/// <summary>
|
||||
/// The event that is invoked when the player's role is shown on the intro cutscene. Non cancelable.
|
||||
/// The event that is invoked when the player's role is shown on the intro cutscene. Non-cancelable.
|
||||
/// </summary>
|
||||
/// <param name="introCutscene">The intro cutscene.</param>
|
||||
public class IntroRoleRevealEvent(IntroCutscene introCutscene) : MiraEvent
|
||||
|
||||
@@ -13,8 +13,6 @@ public class ProcessVotesEvent(List<CustomVote> votes, NetworkedPlayerInfo? exil
|
||||
{
|
||||
private readonly List<CustomVote> _originalVotes = [.. votes];
|
||||
|
||||
private NetworkedPlayerInfo? _exiledPlayer = exiledPlayer;
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether the exiled player has been modified by the event.
|
||||
/// </summary>
|
||||
@@ -45,11 +43,12 @@ public class ProcessVotesEvent(List<CustomVote> votes, NetworkedPlayerInfo? exil
|
||||
/// </summary>
|
||||
public NetworkedPlayerInfo? ExiledPlayer
|
||||
{
|
||||
get => _exiledPlayer;
|
||||
get;
|
||||
set
|
||||
{
|
||||
_exiledPlayer = value;
|
||||
field = value;
|
||||
ExiledPlayerModified = true;
|
||||
}
|
||||
}
|
||||
= exiledPlayer;
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
namespace MiraAPI.Events.Vanilla.Player;
|
||||
|
||||
/// <summary>
|
||||
/// The event that is invoked when a player completes a task. Non cancelable.
|
||||
/// The event that is invoked when a player completes a task. Non-cancelable.
|
||||
/// </summary>
|
||||
/// <param name="player">The player who completed the task.</param>
|
||||
/// <param name="task">The task that the player completed.</param>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
namespace MiraAPI.Events.Vanilla.Player;
|
||||
|
||||
/// <summary>
|
||||
/// Event that is invoked when a player dies. Non cancelable.
|
||||
/// Event that is invoked when a player dies. Non-cancelable.
|
||||
/// </summary>
|
||||
/// <param name="player">The player who died.</param>
|
||||
/// <param name="reason">The reason the player died.</param>
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
namespace MiraAPI.Events.Vanilla.Player;
|
||||
|
||||
/// <summary>
|
||||
/// Event that is invoked when a player joins the lobby. Non cancelable.
|
||||
/// Event that is invoked when a player joins the lobby. Non-cancelable.
|
||||
/// </summary>
|
||||
/// <param name="data">The data of the player who joined.</param>
|
||||
public class PlayerJoinEvent(ClientData data) : MiraEvent
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
namespace MiraAPI.Events.Vanilla.Player;
|
||||
|
||||
/// <summary>
|
||||
/// Event that is invoked when a player leaves the game. Non cancelable.
|
||||
/// Event that is invoked when a player leaves the game. Non-cancelable.
|
||||
/// </summary>
|
||||
/// <param name="data">The data of the player who left.</param>
|
||||
/// <param name="reason">The reason why the player left.</param>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
namespace MiraAPI.Events.Vanilla.Usables;
|
||||
|
||||
/// <summary>
|
||||
/// Event for if a <see cref="PlayerControl"/> can use an <see cref="IUsable"/> from Vanilla Among Us. Will always be ran locally.
|
||||
/// Event for if a <see cref="PlayerControl"/> can use an <see cref="IUsable"/> from Vanilla Among Us. Will always be run locally.
|
||||
/// </summary>
|
||||
/// <param name="usable">The <see cref="IUsable"/>.</param>
|
||||
public class PlayerCanUseEvent(IUsable usable) : PlayerUseEvent(usable);
|
||||
@@ -1,7 +1,7 @@
|
||||
namespace MiraAPI.Events.Vanilla.Usables;
|
||||
|
||||
/// <summary>
|
||||
/// Event for <see cref="PlayerControl"/> using a <see cref="IUsable"/> from Vanilla Among Us. Will always be ran locally.
|
||||
/// Event for <see cref="PlayerControl"/> using a <see cref="IUsable"/> from Vanilla Among Us. Will always be run locally.
|
||||
/// </summary>
|
||||
/// <param name="usable">The <see cref="IUsable"/>.</param>
|
||||
public class PlayerUseEvent(IUsable usable) : MiraCancelableEvent
|
||||
|
||||
@@ -84,15 +84,11 @@ public abstract class AbstractGameMode : IOptionable
|
||||
/// <returns>Resulting body type.</returns>
|
||||
public virtual PlayerBodyTypes GetBodyType(PlayerControl player)
|
||||
{
|
||||
if (AprilFoolsMode.ShouldHorseAround())
|
||||
{
|
||||
return PlayerBodyTypes.Horse;
|
||||
}
|
||||
if (AprilFoolsMode.ShouldLongAround())
|
||||
{
|
||||
return PlayerBodyTypes.Long;
|
||||
}
|
||||
return PlayerBodyTypes.Normal;
|
||||
return AprilFoolsMode.ShouldHorseAround()
|
||||
? PlayerBodyTypes.Horse
|
||||
: (AprilFoolsMode.ShouldLongAround()
|
||||
? PlayerBodyTypes.Long
|
||||
: PlayerBodyTypes.Normal);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -185,9 +181,9 @@ public abstract class AbstractGameMode : IOptionable
|
||||
/// <summary>
|
||||
/// The IEnumerator that plays the intro cutscene for this gamemode.
|
||||
/// </summary>
|
||||
/// <param name="__instance">An instance of IntroCutscene.</param>
|
||||
/// <param name="introCutscene">An instance of IntroCutscene.</param>
|
||||
/// <returns>An IEnumerator to run the intro cutscene instead of the base game one.</returns>
|
||||
public virtual IEnumerator IntroCutscene(IntroCutscene __instance)
|
||||
public virtual IEnumerator IntroCutscene(IntroCutscene introCutscene)
|
||||
{
|
||||
yield return new WaitForEndOfFrame();
|
||||
}
|
||||
@@ -268,11 +264,15 @@ public abstract class AbstractGameMode : IOptionable
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Does the task bar appear in the gamemode.
|
||||
/// Gets a value indicating whether the task bar appears in the gamemode.
|
||||
/// </summary>
|
||||
/// <returns>True if the task bar is enabled in this mode.</returns>
|
||||
public virtual bool ShowTaskBar => true;
|
||||
|
||||
/// <summary>
|
||||
/// Updates the task panel.
|
||||
/// </summary>
|
||||
/// <param name="instance">The task panel to update.</param>
|
||||
public virtual void UpdateTaskPanel(TaskPanelBehaviour instance)
|
||||
{
|
||||
instance.background.transform.localScale = (instance.taskText.textBounds.size.x > 0f)
|
||||
@@ -296,14 +296,9 @@ public abstract class AbstractGameMode : IOptionable
|
||||
var xPos = -instance.background.sprite.bounds.size.x * instance.background.transform.localScale.x;
|
||||
instance.closedPosition = new Vector3(xPos, yPos, instance.closedPosition.z);
|
||||
instance.openPosition = new Vector3(instance.openPosition.x, yPos, instance.openPosition.z);
|
||||
if (instance.open)
|
||||
{
|
||||
instance.timer = Mathf.Min(1f, instance.timer + Time.deltaTime / instance.animationTimeSeconds);
|
||||
}
|
||||
else
|
||||
{
|
||||
instance.timer = Mathf.Max(0f, instance.timer - Time.deltaTime / instance.animationTimeSeconds);
|
||||
}
|
||||
instance.timer = instance.open
|
||||
? Mathf.Min(1f, instance.timer + Time.deltaTime / instance.animationTimeSeconds)
|
||||
: Mathf.Max(0f, instance.timer - Time.deltaTime / instance.animationTimeSeconds);
|
||||
|
||||
Vector3 relativePos = new(
|
||||
Mathf.SmoothStep(instance.closedPosition.x, instance.openPosition.x, instance.timer),
|
||||
|
||||
@@ -16,5 +16,6 @@ public class ClassicMode : AbstractGameMode
|
||||
/// <inheritdoc/>
|
||||
public override string Description => "MiraApi.Gamemode.Classic.Description";
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override LoadableAsset<Sprite>? Icon => MiraAssets.ClassicGamemodeIcon;
|
||||
}
|
||||
@@ -2,7 +2,6 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using MiraAPI.PluginLoading;
|
||||
using Reactor.Utilities;
|
||||
|
||||
namespace MiraAPI.GameModes;
|
||||
|
||||
@@ -42,14 +41,13 @@ public static class CustomGameModeManager
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!mode.HideMode)
|
||||
{
|
||||
if (mode.HideMode)
|
||||
return true;
|
||||
|
||||
IdToModeMap.Add(GetNextId(), mode);
|
||||
pluginInfo.GameModes.Add(LastId, mode);
|
||||
mode.ID = LastId;
|
||||
GameModeOption.AddOption(mode);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -135,6 +133,6 @@ public static class CustomGameModeManager
|
||||
}
|
||||
|
||||
ActiveMode = IdToModeMap[0];
|
||||
Logger<MiraApiPlugin>.Warning($"Unable to find game mode of id {id}!");
|
||||
Warning($"Unable to find game mode of id {id}!");
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Linq;
|
||||
using HarmonyLib;
|
||||
using MiraAPI.GameOptions;
|
||||
@@ -26,20 +27,23 @@ public static class GameModeOption
|
||||
get =>
|
||||
OptionBehaviour != null
|
||||
? OptionBehaviour.GetInt()
|
||||
: _lastValue;
|
||||
: LastValue;
|
||||
private set
|
||||
{
|
||||
_lastValue = value;
|
||||
LastValue = value;
|
||||
if (OptionBehaviour == null)
|
||||
return;
|
||||
OptionBehaviour.Value = value;
|
||||
OptionBehaviour.UpdateValue();
|
||||
_lastValue = value;
|
||||
LastValue = value;
|
||||
}
|
||||
}
|
||||
internal static StringOption OptionBehaviour { get; set; } = null!;
|
||||
|
||||
internal static int _lastValue;
|
||||
[SuppressMessage("Critical Code Smell", "S2223:Non-constant static fields should not be visible", Justification = "Internal behaviour that does not need property-level validation.")]
|
||||
[SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1401:Fields should be private", Justification = "Read above.")] // why so many warnings???
|
||||
internal static int LastValue;
|
||||
|
||||
internal static readonly StringNames GamemodeName = MiraLocaleManager.GetOrCreateLocaleString("Gamemode");
|
||||
internal static readonly StringNames CustomName = MiraLocaleManager.GetOrCreateLocaleString("Custom");
|
||||
internal static readonly Dictionary<uint, StringNames> Values = new()
|
||||
@@ -103,7 +107,7 @@ public static class GameModeOption
|
||||
Value = val;
|
||||
var previousMode = CustomGameModeManager.ActiveMode;
|
||||
CustomGameModeManager.GetAndSetGameMode();
|
||||
HudPatches.SetGameModeText(CustomGameModeManager.GetMode(Values.ElementAt(_lastValue).Key).ColoredName);
|
||||
HudPatches.SetGameModeText(CustomGameModeManager.GetMode(Values.ElementAt(LastValue).Key).ColoredName);
|
||||
var gm = CustomGameModeManager.ActiveMode!;
|
||||
if (gm != previousMode)
|
||||
{
|
||||
@@ -112,8 +116,7 @@ public static class GameModeOption
|
||||
GamemodeName,
|
||||
gm.ColoredName,
|
||||
new Color(0.7333f, 0.7333f, 0.7333f, 1),
|
||||
gm.TmpIcon,
|
||||
true);
|
||||
gm.TmpIcon);
|
||||
if (MenuState.Instance)
|
||||
{
|
||||
// should force reset roles for gamemodes properly
|
||||
@@ -130,10 +133,12 @@ public static class GameModeOption
|
||||
[HarmonyPrefix]
|
||||
private static bool ValueChanged(GameOptionsMenu __instance, OptionBehaviour option)
|
||||
{
|
||||
if (OptionBehaviour.Equals(option))
|
||||
{
|
||||
if (!OptionBehaviour.Equals(option))
|
||||
return true;
|
||||
|
||||
Info($"Game mode changed to {option.GetInt()}");
|
||||
RpcSyncGamemode(PlayerControl.LocalPlayer, option.GetInt());
|
||||
|
||||
if (GameSettingMenu.Instance && CustomGameModeManager.ActiveMode != null)
|
||||
{
|
||||
GameOptionsMenuPatch.ToggleGamemodeOptions(CustomGameModeManager.ActiveMode, __instance);
|
||||
@@ -141,10 +146,9 @@ public static class GameModeOption
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
[MethodRpc((uint)MiraRpc.SyncGamemodeOption)]
|
||||
[SuppressMessage("Style", "IDE0060:Remove unused parameter", Justification = "Intentionally unused because the main intent is for it to be used by dependent mods to add to a blacklist.")]
|
||||
internal static void RpcSyncGamemode(PlayerControl host, int data)
|
||||
{
|
||||
Set(data);
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using AmongUs.Data;
|
||||
using AmongUs.GameOptions;
|
||||
@@ -30,52 +32,70 @@ public class HideAndSeekMode : AbstractGameMode
|
||||
/// <inheritdoc/>
|
||||
public override string Description => "MiraApi.Gamemode.HideAndSeek.Description";
|
||||
|
||||
/// <inheritdoc/>
|
||||
// TODO: Once the Hide n Seek port is ready for release, we will remove this.
|
||||
public override bool HideMode => !MiraApiPlugin.IsDevBuild;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override Color Color { get; } = new Color32(255, 88, 90, 255);
|
||||
public override LoadableAsset<Sprite>? Icon => MiraAssets.HnSGamemodeIcon;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override LoadableAsset<Sprite> Icon => MiraAssets.HnSGamemodeIcon;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override bool ShowGameModeIntroCutscene => true;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override bool GameModeBodyTypeOverride => true;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override bool ShowNormalGameSettings => false;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override bool ShowNormalRoleSettings => false;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override float DefaultImpostorKillCooldown => 1f;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override bool ShowTaskBar => false;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override bool CanReport(DeadBody body)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override bool ShouldShowSabotageMap(MapBehaviour map)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public override bool ShowGameModeIntroCutscene => true;
|
||||
public override bool GameModeBodyTypeOverride => true;
|
||||
public override bool ShowNormalGameSettings => false;
|
||||
public override bool ShowNormalRoleSettings => false;
|
||||
public override float DefaultImpostorKillCooldown => 1f;
|
||||
|
||||
public override bool ShowTaskBar => false;
|
||||
public static int ImpostorPlayerID()
|
||||
private static int ImpostorPlayerID()
|
||||
{
|
||||
return OptionGroupSingleton<HnsImpostorOptions>.Instance.SelectedSeeker.Value;
|
||||
}
|
||||
|
||||
public static bool HasImpostorPlayerID()
|
||||
private static bool HasImpostorPlayerID()
|
||||
{
|
||||
return ImpostorPlayerID() > -1;
|
||||
}
|
||||
|
||||
public static bool ValidateImpostorPlayerID(List<NetworkedPlayerInfo> players)
|
||||
private static bool ValidateImpostorPlayerID(List<NetworkedPlayerInfo> players)
|
||||
{
|
||||
return HasImpostorPlayerID() && players.Find((NetworkedPlayerInfo p) => (int)p.PlayerId == ImpostorPlayerID()) != null;
|
||||
return HasImpostorPlayerID() && players.Find(p => p.PlayerId == ImpostorPlayerID()) != null;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override void AssignRoles(out bool runOriginal, LogicRoleSelectionNormal instance)
|
||||
{
|
||||
runOriginal = false;
|
||||
Il2CppSystem.Collections.Generic.List<ClientData> list = new();
|
||||
AmongUsClient.Instance.GetAllClients(list);
|
||||
List<NetworkedPlayerInfo> list2 = list.ToArray()
|
||||
List<NetworkedPlayerInfo> list2 = [.. list.ToArray()
|
||||
.Where(c => c.Character != null && c.Character.Data != null && !c.Character.Data.Disconnected &&
|
||||
!c.Character.Data.IsDead).OrderBy(c => c.Id).Select(c => c.Character.Data)
|
||||
.ToList();
|
||||
!c.Character.Data.IsDead).OrderBy(c => c.Id).Select(c => c.Character.Data)];
|
||||
|
||||
foreach (NetworkedPlayerInfo networkedPlayerInfo in GameData.Instance.AllPlayers)
|
||||
{
|
||||
@@ -90,7 +110,7 @@ public class HideAndSeekMode : AbstractGameMode
|
||||
AssignRolesForTeam(list2, currentGameOptions, RoleTeamTypes.Crewmate, int.MaxValue, RoleTypes.Engineer);
|
||||
}
|
||||
|
||||
public static void AssignRolesForTeam(
|
||||
private static void AssignRolesForTeam(
|
||||
List<NetworkedPlayerInfo> players,
|
||||
IGameOptions opts,
|
||||
RoleTeamTypes team,
|
||||
@@ -102,7 +122,8 @@ public class HideAndSeekMode : AbstractGameMode
|
||||
IRoleOptionsCollection roleOptions = opts.RoleOptions;
|
||||
var source = RoleManager.Instance.AllRoles.ToArray()
|
||||
.Where(role => role.TeamType == team && !RoleManager.IsGhostRole(role.Role) &&
|
||||
CustomRoleUtils.CanSpawnOnCurrentMode(role));
|
||||
CustomRoleUtils.CanSpawnOnCurrentMode(role))
|
||||
.ToList();
|
||||
var assignmentData = source.Where(x => !x.IsDead).Select(role =>
|
||||
new RoleManager.RoleAssignmentData(
|
||||
role,
|
||||
@@ -110,7 +131,7 @@ public class HideAndSeekMode : AbstractGameMode
|
||||
roleOptions.GetChancePerGame(role.Role))).ToList();
|
||||
var source2 = CustomRoleUtils.GetPossibleRoles(assignmentData, x => x.Chance == 100);
|
||||
var guaranteedRoles = source.Where(x => source2.Contains(((ushort)x.Role, 100)));
|
||||
List<RoleTypes> list = new List<RoleTypes>();
|
||||
List<RoleTypes> list = [];
|
||||
if (team == RoleTeamTypes.Crewmate)
|
||||
{
|
||||
Error($"MiraAPI.Patches.Roles.LogicRoleSelectionHnsPatch - AssignRolesForTeam: Before Guaranteed Assignment");
|
||||
@@ -171,7 +192,7 @@ public class HideAndSeekMode : AbstractGameMode
|
||||
ValidateImpostorPlayerID(players) &&
|
||||
!AmongUsClient.Instance.IsGamePublic)
|
||||
{
|
||||
NetworkedPlayerInfo networkedPlayerInfo = players.ToArray()
|
||||
NetworkedPlayerInfo networkedPlayerInfo = players
|
||||
.First(p => p.PlayerId == ImpostorPlayerID());
|
||||
players.Remove(networkedPlayerInfo);
|
||||
newImpostors.Add(networkedPlayerInfo);
|
||||
@@ -183,8 +204,8 @@ public class HideAndSeekMode : AbstractGameMode
|
||||
int num2 = 0;
|
||||
while (num2 < teamMax && players.Count > 0)
|
||||
{
|
||||
PseudoRandomList<NetworkedPlayerInfo> pseudoRandomList = new PseudoRandomList<NetworkedPlayerInfo>(AmongUsClient.Instance.GameId);
|
||||
players.Do(x => pseudoRandomList.Add(x));
|
||||
PseudoRandomList<NetworkedPlayerInfo> pseudoRandomList = new(AmongUsClient.Instance.GameId);
|
||||
players.Do(pseudoRandomList.Add);
|
||||
for (int i = 0; i < GameData.RoundsPlayedInSession; i++)
|
||||
{
|
||||
pseudoRandomList.PickRandom();
|
||||
@@ -244,7 +265,7 @@ public class HideAndSeekMode : AbstractGameMode
|
||||
}
|
||||
}
|
||||
|
||||
public static void AssignRolesFromList(List<NetworkedPlayerInfo> players, int teamMax, List<RoleTypes> roleList, ref int rolesAssigned)
|
||||
private static void AssignRolesFromList(List<NetworkedPlayerInfo> players, int teamMax, List<RoleTypes> roleList, ref int rolesAssigned)
|
||||
{
|
||||
while (roleList.Count > 0 && players.Count > 0 && rolesAssigned < teamMax)
|
||||
{
|
||||
@@ -252,62 +273,56 @@ public class HideAndSeekMode : AbstractGameMode
|
||||
RoleTypes roleType = roleList[index];
|
||||
roleList.RemoveAt(index);
|
||||
int index2 = HashRandom.FastNext(players.Count);
|
||||
players[index2].Object.RpcSetRole(roleType, false);
|
||||
players[index2].Object.RpcSetRole(roleType);
|
||||
players.RemoveAt(index2);
|
||||
rolesAssigned++;
|
||||
}
|
||||
}
|
||||
|
||||
public override IEnumerator IntroCutscene(IntroCutscene __instance)
|
||||
/// <inheritdoc/>
|
||||
public override IEnumerator IntroCutscene(IntroCutscene introCutscene)
|
||||
{
|
||||
SoundManager.Instance.PlaySound(__instance.IntroStinger, false, 1f, null);
|
||||
Logger.GlobalInstance.Info("IntroCutscene :: CoBegin() :: Game Mode: Hide and Seek (MiraAPI)", null);
|
||||
__instance.LogPlayerRoleData();
|
||||
__instance.HideAndSeekPanels.SetActive(true);
|
||||
SoundManager.Instance.PlaySound(introCutscene.IntroStinger, false);
|
||||
Logger.GlobalInstance.Info("IntroCutscene :: CoBegin() :: Game Mode: Hide and Seek (MiraAPI)");
|
||||
introCutscene.LogPlayerRoleData();
|
||||
introCutscene.HideAndSeekPanels.SetActive(true);
|
||||
if (PlayerControl.LocalPlayer.Data.Role.IsImpostor)
|
||||
{
|
||||
__instance.CrewmateRules.SetActive(false);
|
||||
__instance.ImpostorRules.SetActive(true);
|
||||
introCutscene.CrewmateRules.SetActive(false);
|
||||
introCutscene.ImpostorRules.SetActive(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
__instance.CrewmateRules.SetActive(true);
|
||||
__instance.ImpostorRules.SetActive(false);
|
||||
introCutscene.CrewmateRules.SetActive(true);
|
||||
introCutscene.ImpostorRules.SetActive(false);
|
||||
}
|
||||
|
||||
__instance.ImpostorName.gameObject.SetActive(true);
|
||||
__instance.ImpostorTitle.gameObject.SetActive(true);
|
||||
__instance.BackgroundBar.enabled = false;
|
||||
__instance.TeamTitle.gameObject.SetActive(false);
|
||||
introCutscene.ImpostorName.gameObject.SetActive(true);
|
||||
introCutscene.ImpostorTitle.gameObject.SetActive(true);
|
||||
introCutscene.BackgroundBar.enabled = false;
|
||||
introCutscene.TeamTitle.gameObject.SetActive(false);
|
||||
var impostor = PlayerControl.AllPlayerControls.ToArray().FirstOrDefault(x => x.Data.Role.IsImpostor);
|
||||
if (impostor == null)
|
||||
{
|
||||
Logger.GlobalInstance.Error("IntroCutscene :: CoBegin() :: impostor is NULL", null);
|
||||
Logger.GlobalInstance.Error("IntroCutscene :: CoBegin() :: impostor is NULL");
|
||||
}
|
||||
|
||||
GameManager.Instance.SetSpecialCosmetics(impostor);
|
||||
if (impostor != null)
|
||||
{
|
||||
__instance.ImpostorName.text = impostor.Data.PlayerName;
|
||||
}
|
||||
else
|
||||
{
|
||||
__instance.ImpostorName.text = "???";
|
||||
}
|
||||
introCutscene.ImpostorName.text = impostor != null ? impostor.Data.PlayerName : "???";
|
||||
|
||||
yield return new WaitForSecondsRealtime(0.1f);
|
||||
if (impostor != null)
|
||||
{
|
||||
__instance.ImpostorTitle.text = impostor.Data.Role.GetRoleName();
|
||||
introCutscene.ImpostorTitle.text = impostor.Data.Role.GetRoleName();
|
||||
}
|
||||
PoolablePlayer playerSlot = null;
|
||||
PoolablePlayer? playerSlot = null;
|
||||
if (impostor != null)
|
||||
{
|
||||
playerSlot = __instance.CreatePlayer(1, 1, impostor.Data, false);
|
||||
playerSlot = introCutscene.CreatePlayer(1, 1, impostor.Data, false);
|
||||
playerSlot.SetBodyType(PlayerBodyTypes.Normal);
|
||||
playerSlot.SetFlipX(false);
|
||||
playerSlot.transform.localPosition = __instance.impostorPos;
|
||||
playerSlot.transform.localScale = Vector3.one * __instance.impostorScale;
|
||||
playerSlot.transform.localPosition = introCutscene.impostorPos;
|
||||
playerSlot.transform.localScale = Vector3.one * introCutscene.impostorScale;
|
||||
}
|
||||
|
||||
yield return ShipStatus.Instance.CosmeticsCache.PopulateFromPlayers();
|
||||
@@ -317,45 +332,43 @@ public class HideAndSeekMode : AbstractGameMode
|
||||
playerSlot.gameObject.SetActive(false);
|
||||
}
|
||||
|
||||
__instance.HideAndSeekPanels.SetActive(false);
|
||||
__instance.CrewmateRules.SetActive(false);
|
||||
__instance.ImpostorRules.SetActive(false);
|
||||
introCutscene.HideAndSeekPanels.SetActive(false);
|
||||
introCutscene.CrewmateRules.SetActive(false);
|
||||
introCutscene.ImpostorRules.SetActive(false);
|
||||
HnsMusicHandler.Instance.StartMusicWithIntro();
|
||||
var hideTimer = 10f;
|
||||
|
||||
if (PlayerControl.LocalPlayer.Data.Role.IsImpostor)
|
||||
{
|
||||
__instance.HideAndSeekTimerText.gameObject.SetActive(true);
|
||||
introCutscene.HideAndSeekTimerText.gameObject.SetActive(true);
|
||||
PoolablePlayer poolablePlayer;
|
||||
AnimationClip anim;
|
||||
if (AprilFoolsMode.ShouldHorseAround())
|
||||
{
|
||||
poolablePlayer = __instance.HorseWrangleVisualSuit;
|
||||
poolablePlayer = introCutscene.HorseWrangleVisualSuit;
|
||||
poolablePlayer.gameObject.SetActive(true);
|
||||
poolablePlayer.SetBodyType(PlayerBodyTypes.Seeker);
|
||||
anim = __instance.HnSSeekerSpawnHorseAnim;
|
||||
__instance.HorseWrangleVisualPlayer.SetBodyType(PlayerBodyTypes.Normal);
|
||||
__instance.HorseWrangleVisualPlayer.UpdateFromPlayerData(
|
||||
anim = introCutscene.HnSSeekerSpawnHorseAnim;
|
||||
introCutscene.HorseWrangleVisualPlayer.SetBodyType(PlayerBodyTypes.Normal);
|
||||
introCutscene.HorseWrangleVisualPlayer.UpdateFromPlayerData(
|
||||
PlayerControl.LocalPlayer.Data,
|
||||
PlayerControl.LocalPlayer.CurrentOutfitType,
|
||||
PlayerMaterial.MaskType.None,
|
||||
false,
|
||||
null,
|
||||
false);
|
||||
}
|
||||
else if (AprilFoolsMode.ShouldLongAround())
|
||||
{
|
||||
poolablePlayer = __instance.HideAndSeekPlayerVisual;
|
||||
poolablePlayer = introCutscene.HideAndSeekPlayerVisual;
|
||||
poolablePlayer.gameObject.SetActive(true);
|
||||
poolablePlayer.SetBodyType(PlayerBodyTypes.LongSeeker);
|
||||
anim = __instance.HnSSeekerSpawnLongAnim;
|
||||
anim = introCutscene.HnSSeekerSpawnLongAnim;
|
||||
}
|
||||
else
|
||||
{
|
||||
poolablePlayer = __instance.HideAndSeekPlayerVisual;
|
||||
poolablePlayer = introCutscene.HideAndSeekPlayerVisual;
|
||||
poolablePlayer.gameObject.SetActive(true);
|
||||
poolablePlayer.SetBodyType(PlayerBodyTypes.Seeker);
|
||||
anim = __instance.HnSSeekerSpawnAnim;
|
||||
anim = introCutscene.HnSSeekerSpawnAnim;
|
||||
}
|
||||
|
||||
poolablePlayer.SetBodyCosmeticsVisible(false);
|
||||
@@ -363,16 +376,14 @@ public class HideAndSeekMode : AbstractGameMode
|
||||
PlayerControl.LocalPlayer.Data,
|
||||
PlayerControl.LocalPlayer.CurrentOutfitType,
|
||||
PlayerMaterial.MaskType.None,
|
||||
false,
|
||||
null,
|
||||
false);
|
||||
SpriteAnim component = poolablePlayer.GetComponent<SpriteAnim>();
|
||||
poolablePlayer.gameObject.SetActive(true);
|
||||
poolablePlayer.ToggleName(false);
|
||||
component.Play(anim, 1f);
|
||||
component.Play(anim);
|
||||
while (hideTimer > 0f)
|
||||
{
|
||||
__instance.HideAndSeekTimerText.text = Mathf.RoundToInt(hideTimer).ToString();
|
||||
introCutscene.HideAndSeekTimerText.text = Mathf.RoundToInt(hideTimer).ToString(CultureInfo.InvariantCulture);
|
||||
hideTimer -= Time.deltaTime;
|
||||
yield return null;
|
||||
}
|
||||
@@ -384,27 +395,29 @@ public class HideAndSeekMode : AbstractGameMode
|
||||
{
|
||||
if (impostor != null)
|
||||
{
|
||||
impostor.AnimateCustom(__instance.HnSSeekerSpawnHorseInGameAnim);
|
||||
impostor.AnimateCustom(introCutscene.HnSSeekerSpawnHorseInGameAnim);
|
||||
}
|
||||
}
|
||||
else if (AprilFoolsMode.ShouldLongAround())
|
||||
{
|
||||
if (impostor != null)
|
||||
{
|
||||
impostor.AnimateCustom(__instance.HnSSeekerSpawnLongInGameAnim);
|
||||
impostor.AnimateCustom(introCutscene.HnSSeekerSpawnLongInGameAnim);
|
||||
}
|
||||
}
|
||||
else if (impostor != null)
|
||||
{
|
||||
impostor.AnimateCustom(__instance.HnSSeekerSpawnAnim);
|
||||
impostor.AnimateCustom(introCutscene.HnSSeekerSpawnAnim);
|
||||
impostor.cosmetics.SetBodyCosmeticsVisible(false);
|
||||
}
|
||||
}
|
||||
ShipStatus.Instance.StartSFX();
|
||||
HnsMusicHandler.Instance.OnGameStart();
|
||||
HnsDangerMeter.Instance.OnGameStart();
|
||||
UnityEngine.Object.Destroy(__instance.gameObject);
|
||||
UnityEngine.Object.Destroy(introCutscene.gameObject);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override void Initialize()
|
||||
{
|
||||
deadPlayerCount = 0;
|
||||
@@ -417,9 +430,11 @@ public class HideAndSeekMode : AbstractGameMode
|
||||
HudManager.Instance.gameObject.AddComponent<HnsDangerMeter>();
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override MapOptions GetMapOptions()
|
||||
{
|
||||
MapOptions mapOptions = new MapOptions
|
||||
MapOptions mapOptions = new()
|
||||
{
|
||||
Mode = MapOptions.Modes.Normal,
|
||||
};
|
||||
@@ -433,14 +448,16 @@ public class HideAndSeekMode : AbstractGameMode
|
||||
return mapOptions;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override void CheckGameEnd(out bool runOriginal, LogicGameFlowNormal instance)
|
||||
{
|
||||
runOriginal = false;
|
||||
if (Helpers.GetAlivePlayers().Count(x => x.Data.Role.IsImpostor) == 0)
|
||||
var players = Helpers.GetAlivePlayers();
|
||||
if (!players.Any(x => x.Data.Role.IsImpostor))
|
||||
{
|
||||
instance.Manager.RpcEndGame(GameOverReason.ImpostorDisconnect, !DataManager.Player.Ads.HasPurchasedAdRemoval);
|
||||
}
|
||||
if (Helpers.GetAlivePlayers().Count(x => !x.Data.Role.IsImpostor) != 0)
|
||||
if (players.Any(x => !x.Data.Role.IsImpostor))
|
||||
{
|
||||
if (HideAndSeekHudHelper.Instance.AllTimersExpired())
|
||||
{
|
||||
@@ -451,6 +468,8 @@ public class HideAndSeekMode : AbstractGameMode
|
||||
instance.Manager.RpcEndGame(GameOverReason.HideAndSeek_ImpostorsByKills, !DataManager.Player.Ads.HasPurchasedAdRemoval);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
[SuppressMessage("Style", "IDE0046:Convert to conditional expression", Justification = "Warning cascades into forcing the entire tree to be ternary operators.")]
|
||||
public override PlayerBodyTypes GetBodyType(PlayerControl player)
|
||||
{
|
||||
if (player == null || player.Data == null || player.Data.Role == null)
|
||||
@@ -490,6 +509,8 @@ public class HideAndSeekMode : AbstractGameMode
|
||||
return PlayerBodyTypes.Normal;
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override void UpdateTaskPanel(TaskPanelBehaviour instance)
|
||||
{
|
||||
instance.background.transform.localScale = (instance.taskText.textBounds.size.x > 0f)
|
||||
@@ -513,14 +534,9 @@ public class HideAndSeekMode : AbstractGameMode
|
||||
var xPos = -instance.background.sprite.bounds.size.x * instance.background.transform.localScale.x;
|
||||
instance.closedPosition = new Vector3(xPos, yPos, instance.closedPosition.z);
|
||||
instance.openPosition = new Vector3(instance.openPosition.x, yPos, instance.openPosition.z);
|
||||
if (instance.open)
|
||||
{
|
||||
instance.timer = Mathf.Min(1f, instance.timer + Time.deltaTime / instance.animationTimeSeconds);
|
||||
}
|
||||
else
|
||||
{
|
||||
instance.timer = Mathf.Max(0f, instance.timer - Time.deltaTime / instance.animationTimeSeconds);
|
||||
}
|
||||
instance.timer = instance.open
|
||||
? Mathf.Min(1f, instance.timer + Time.deltaTime / instance.animationTimeSeconds)
|
||||
: Mathf.Max(0f, instance.timer - Time.deltaTime / instance.animationTimeSeconds);
|
||||
|
||||
Vector3 relativePos = new(
|
||||
Mathf.SmoothStep(instance.closedPosition.x, instance.openPosition.x, instance.timer),
|
||||
@@ -529,7 +545,10 @@ public class HideAndSeekMode : AbstractGameMode
|
||||
instance.transform.localPosition =
|
||||
AspectPosition.ComputePosition(AspectPosition.EdgeAlignments.LeftTop, relativePos);
|
||||
}
|
||||
|
||||
private int deadPlayerCount;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override void OnPlayerDeath(PlayerControl player, bool assignGhostRole)
|
||||
{
|
||||
base.OnPlayerDeath(player, assignGhostRole);
|
||||
|
||||
@@ -87,11 +87,11 @@ public abstract class AbstractOptionGroup<T> : AbstractOptionGroup where T : IOp
|
||||
get
|
||||
{
|
||||
var type = typeof(T);
|
||||
if (type == typeof(BaseModifier))
|
||||
if (typeof(BaseModifier).IsAssignableFrom(type))
|
||||
{
|
||||
return MenuCategory.Modifiers;
|
||||
}
|
||||
else if (type == typeof(RoleBehaviour))
|
||||
else if (typeof(RoleBehaviour).IsAssignableFrom(type))
|
||||
{
|
||||
return MenuCategory.Roles;
|
||||
}
|
||||
@@ -104,7 +104,7 @@ public abstract class AbstractOptionGroup<T> : AbstractOptionGroup where T : IOp
|
||||
/// Base class for option groups. An option group is a collection of options that are displayed together in the options menu.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The custom role that the group is for.</typeparam>
|
||||
public abstract class AbstractRoleOptionGroup<T>() : AbstractOptionGroup<T> where T : ICustomRole
|
||||
public abstract class AbstractRoleOptionGroup<T> : AbstractOptionGroup<T> where T : ICustomRole
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public override Type OptionableType => typeof(T);
|
||||
|
||||
@@ -8,6 +8,9 @@ namespace MiraAPI.GameOptions.Attributes;
|
||||
/// <summary>
|
||||
/// Attribute for creating a <see cref="ModdedEnumOption"/>.
|
||||
/// </summary>
|
||||
/// <param name="title">The title of the option.</param>
|
||||
/// <param name="enumType">The <see cref="Enum"/> type.</param>
|
||||
/// <param name="values">An option list of string values to use in place of the <see langword="enum"/> name.</param>
|
||||
[AttributeUsage(AttributeTargets.Property)]
|
||||
public class ModdedEnumOptionAttribute(string title, Type enumType, string[]? values = null)
|
||||
: ModdedOptionAttribute(title)
|
||||
|
||||
@@ -9,6 +9,13 @@ namespace MiraAPI.GameOptions.Attributes;
|
||||
/// <summary>
|
||||
/// Attribute for a <see cref="ModdedNumberOption"/>.
|
||||
/// </summary>
|
||||
/// <param name="title">The option title.</param>
|
||||
/// <param name="min">The minimum value.</param>
|
||||
/// <param name="max">The maximum value.</param>
|
||||
/// <param name="increment">The increment.</param>
|
||||
/// <param name="suffixType">The suffix type.</param>
|
||||
/// <param name="formatString">Optional format string for the option screen.</param>
|
||||
/// <param name="zeroInfinity">Flag indicating whether 0 means infinity.</param>
|
||||
[AttributeUsage(AttributeTargets.Property)]
|
||||
public class ModdedNumberOptionAttribute(
|
||||
string title,
|
||||
|
||||
@@ -46,9 +46,8 @@ public static class ModdedOptionsManager
|
||||
/// <param name="playSound">A flag that indicates if a notification sound should be played.</param>
|
||||
public static void AddSettingsChangeMessage(NotificationPopper notif, StringNames key, string value, Color textColor, TMP_SpriteAsset? sprite, bool playSound = true)
|
||||
{
|
||||
string item;
|
||||
var text = textColor.ToTextColor();
|
||||
item = sprite != null
|
||||
var item = sprite != null
|
||||
? TranslationController.Instance.GetString(
|
||||
StringNames.LobbyChangeSettingNotification,
|
||||
string.Concat(
|
||||
@@ -187,7 +186,7 @@ public static class ModdedOptionsManager
|
||||
RegisterOption(option, group, property.Name, pluginInfo);
|
||||
}
|
||||
|
||||
internal static void RegisterOption(
|
||||
private static void RegisterOption(
|
||||
IModdedOption option,
|
||||
AbstractOptionGroup group,
|
||||
string propertyName,
|
||||
|
||||
@@ -30,14 +30,14 @@ public class ModdedStringOption : ModdedOption<string>
|
||||
/// </summary>
|
||||
/// <param name="value">The option's string value.</param>
|
||||
/// <returns>The option's value in the index.</returns>
|
||||
public int GetIndex(string value, int location)
|
||||
public int GetIndex(string value)
|
||||
{
|
||||
if (Values.Contains(value))
|
||||
{
|
||||
return Values.ToList().IndexOf(value);
|
||||
return Array.IndexOf(Values, value);
|
||||
}
|
||||
Info($"Cannot find a valid index for {value} in {location}. Returning 0 instead. Values: {string.Join(", ", Values)}");
|
||||
return 0;
|
||||
Info($"Cannot find a valid index for {value}. Returning -1 instead. Values: {string.Join(", ", Values)}");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -54,10 +54,10 @@ public class ModdedStringOption : ModdedOption<string>
|
||||
|
||||
var newVals = Values.ToList();
|
||||
newVals.Insert(index, value);
|
||||
Values = newVals.ToArray();
|
||||
Values = [.. newVals];
|
||||
var newStrVals = StringNameValues.ToList();
|
||||
newStrVals.Insert(index, MiraLocaleManager.GetOrCreateLocaleString(value));
|
||||
StringNameValues = newStrVals.ToArray();
|
||||
StringNameValues = [.. newStrVals];
|
||||
}
|
||||
|
||||
if (Data != null)
|
||||
@@ -65,14 +65,14 @@ public class ModdedStringOption : ModdedOption<string>
|
||||
var data = (StringGameSetting)Data;
|
||||
data.Values = StringNameValues;
|
||||
|
||||
data.Index = GetIndex(Value, 1);
|
||||
data.Index = GetIndex(Value);
|
||||
if (OptionBehaviour != null)
|
||||
{
|
||||
var strOpt = OptionBehaviour.TryCast<StringOption>();
|
||||
if (strOpt != null)
|
||||
{
|
||||
strOpt.Values = StringNameValues;
|
||||
strOpt.Value = GetIndex(Value, 2);
|
||||
strOpt.Value = GetIndex(Value);
|
||||
Warning("StringOption is valid");
|
||||
}
|
||||
else
|
||||
@@ -108,10 +108,10 @@ public class ModdedStringOption : ModdedOption<string>
|
||||
|
||||
data.Title = StringName;
|
||||
data.Type = global::OptionTypes.String;
|
||||
StringNameValues = values.Select(MiraLocaleManager.GetOrCreateLocaleString).ToArray();
|
||||
StringNameValues = [.. values.Select(MiraLocaleManager.GetOrCreateLocaleString)];
|
||||
data.Values = StringNameValues;
|
||||
|
||||
data.Index = GetIndex(Value, 3);
|
||||
data.Index = GetIndex(Value);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
@@ -124,10 +124,10 @@ public class ModdedStringOption : ModdedOption<string>
|
||||
stringOption.SetUpFromData(Data, 20);
|
||||
stringOption.OnValueChanged = (Il2CppSystem.Action<OptionBehaviour>)ValueChanged;
|
||||
|
||||
// SetUpFromData method doesnt work correctly so we must set the values manually
|
||||
// SetUpFromData method doesn't work correctly so we must set the values manually
|
||||
stringOption.Title = StringName;
|
||||
stringOption.Values = (Data as StringGameSetting)?.Values ?? new Il2CppStructArray<StringNames>(0);
|
||||
stringOption.Value = GetIndex(Value, 4);
|
||||
stringOption.Value = GetIndex(Value);
|
||||
|
||||
OptionBehaviour = stringOption;
|
||||
ModdedOptionsManager.CreatedStringOptions.TryAdd(stringOption, this);
|
||||
@@ -162,7 +162,7 @@ public class ModdedStringOption : ModdedOption<string>
|
||||
/// <inheritdoc />
|
||||
protected override void OnValueChanged(string newValue)
|
||||
{
|
||||
HudManager.Instance.Notifier.AddSettingsChangeMessage(StringName, Data.GetValueString(GetIndex(newValue, 5)), false);
|
||||
HudManager.Instance.Notifier.AddSettingsChangeMessage(StringName, Data.GetValueString(GetIndex(newValue)), false);
|
||||
if (!OptionBehaviour)
|
||||
{
|
||||
return;
|
||||
@@ -170,7 +170,7 @@ public class ModdedStringOption : ModdedOption<string>
|
||||
|
||||
if (OptionBehaviour is StringOption opt)
|
||||
{
|
||||
opt.Value = GetIndex(newValue, 5);
|
||||
opt.Value = GetIndex(newValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.Collections;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Linq;
|
||||
using BepInEx.Unity.IL2CPP.Utils.Collections;
|
||||
using Il2CppInterop.Runtime.Attributes;
|
||||
@@ -10,44 +11,57 @@ using UnityEngine;
|
||||
|
||||
namespace MiraAPI.HnsReimplemented;
|
||||
|
||||
/// <summary>
|
||||
/// A Unity script designed to help manage the HUD during HnS mode.
|
||||
/// </summary>
|
||||
/// <param name="cppPtr">The pointer of this instance's equivalent in the Il2Cpp domain.</param>
|
||||
[RegisterInIl2Cpp]
|
||||
[SuppressMessage("Style", "IDE0051:Remove unused private members", Justification = "Unity Convention.")]
|
||||
public sealed class HideAndSeekHudHelper(nint cppPtr) : MonoBehaviour(cppPtr)
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the instance of the HnS hud helper.
|
||||
/// </summary>
|
||||
public static HideAndSeekHudHelper Instance { get; private set; }
|
||||
|
||||
public AudioClip FinalHideAlertSfx;
|
||||
private AudioClip finalHideAlertSfx;
|
||||
private AudioClip finalHideCountdownSfx;
|
||||
[SuppressMessage("Style", "IDE0052:Remove unread private members", Justification = "Ignore for now; tentative code.")]
|
||||
private AudioClip taskFinishedSound;
|
||||
|
||||
public AudioClip FinalHideCountdownSfx;
|
||||
|
||||
private AudioClip TaskFinishedSound;
|
||||
|
||||
private const int SECONDS_TO_BEEP = 10;
|
||||
|
||||
private const float SECONDS_TO_SET_DIRTY = 1f;
|
||||
|
||||
private HideAndSeekTimerBar timerBar;
|
||||
// private const int SECONDS_TO_BEEP = 10;
|
||||
// private const float SECONDS_TO_SET_DIRTY = 1f;
|
||||
|
||||
private float totalHideTime = float.MaxValue;
|
||||
|
||||
private float currentHideTime = float.MaxValue;
|
||||
|
||||
private float totalFinalHideTime = float.MaxValue;
|
||||
|
||||
private float currentFinalHideTime = float.MaxValue;
|
||||
|
||||
private float secondsSinceLastSetDirty;
|
||||
private Coroutine beepCoroutine;
|
||||
private HideAndSeekTimerBar timerBar;
|
||||
private float taskDirtyTimer;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the hide countdown timer.
|
||||
/// </summary>
|
||||
public float HideCountdown { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether the game has reached the final phase.
|
||||
/// </summary>
|
||||
public bool IsFinalCountdown => currentHideTime <= 0f;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
Instance = this;
|
||||
}
|
||||
|
||||
public bool IsFinalCountdown
|
||||
{
|
||||
get { return currentHideTime <= 0f; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks to see if the player can use the Seeker admin.
|
||||
/// </summary>
|
||||
/// <param name="player">The player to check.</param>
|
||||
/// <returns>true if the player can use the admin ability.</returns>
|
||||
public bool SeekerAdminMapEnabled(PlayerControl player)
|
||||
{
|
||||
int item = Helpers.GetAlivePlayers().Count(x => !x.Data.Role.IsImpostor);
|
||||
@@ -59,6 +73,10 @@ public sealed class HideAndSeekHudHelper(nint cppPtr) : MonoBehaviour(cppPtr)
|
||||
(GameData.Instance.PlayerCount - 1) / 3));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A event that is called when a task is completed.
|
||||
/// </summary>
|
||||
/// <param name="timeDeduction">The amount of time to deduct from the timer.</param>
|
||||
public void OnTaskComplete(float timeDeduction)
|
||||
{
|
||||
if (timerBar != null)
|
||||
@@ -69,24 +87,36 @@ public sealed class HideAndSeekHudHelper(nint cppPtr) : MonoBehaviour(cppPtr)
|
||||
AdjustEscapeTimer(timeDeduction, true);
|
||||
}
|
||||
|
||||
public float GetTotalRoundTime()
|
||||
/// <summary>
|
||||
/// Gets the match duration.
|
||||
/// </summary>
|
||||
/// <returns>The match duration in seconds.</returns>
|
||||
public static float GetTotalRoundTime()
|
||||
{
|
||||
float escapeTime = OptionGroupSingleton<HnsCrewmateOptions>.Instance.HidingTime.Value;
|
||||
float finalCountdownTime = OptionGroupSingleton<HnsFinalHideOptions>.Instance.FinalHideTime.Value;
|
||||
return escapeTime + finalCountdownTime;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the amount of total time remaining in the current round.
|
||||
/// </summary>
|
||||
/// <returns>The remaining time in seconds.</returns>
|
||||
public float GetTotalTimeRemaining()
|
||||
{
|
||||
return currentHideTime + currentFinalHideTime;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets how much time has passed since the start of the round.
|
||||
/// </summary>
|
||||
/// <returns>The elapsed time in seconds.</returns>
|
||||
public float GetRoundTimeElapsed()
|
||||
{
|
||||
return GetTotalRoundTime() - GetTotalTimeRemaining();
|
||||
}
|
||||
|
||||
public void Start()
|
||||
private void Start()
|
||||
{
|
||||
totalHideTime = OptionGroupSingleton<HnsCrewmateOptions>.Instance.HidingTime.Value;
|
||||
currentHideTime = totalHideTime;
|
||||
@@ -97,19 +127,19 @@ public sealed class HideAndSeekHudHelper(nint cppPtr) : MonoBehaviour(cppPtr)
|
||||
Object.Destroy(timerBar);
|
||||
}
|
||||
|
||||
FinalHideAlertSfx = GameManagerCreator.Instance.HideAndSeekManagerPrefab.FinalHideAlertSFX;
|
||||
FinalHideCountdownSfx = GameManagerCreator.Instance.HideAndSeekManagerPrefab.FinalHideCountdownSFX;
|
||||
TaskFinishedSound = GameManagerCreator.Instance.HideAndSeekManagerPrefab.TaskFinishedSound;
|
||||
timerBar = Object.Instantiate<HideAndSeekTimerBar>(
|
||||
finalHideAlertSfx = GameManagerCreator.Instance.HideAndSeekManagerPrefab.FinalHideAlertSFX;
|
||||
finalHideCountdownSfx = GameManagerCreator.Instance.HideAndSeekManagerPrefab.FinalHideCountdownSFX;
|
||||
taskFinishedSound = GameManagerCreator.Instance.HideAndSeekManagerPrefab.TaskFinishedSound;
|
||||
timerBar = Instantiate(
|
||||
GameManagerCreator.Instance.HideAndSeekManagerPrefab.TimerBarPrefab,
|
||||
HudManager.Instance.transform.parent);
|
||||
}
|
||||
|
||||
public void OnGameEnd()
|
||||
private void OnGameEnd()
|
||||
{
|
||||
if (timerBar != null)
|
||||
{
|
||||
Object.Destroy(timerBar.gameObject);
|
||||
Destroy(timerBar.gameObject);
|
||||
}
|
||||
|
||||
if (beepCoroutine != null)
|
||||
@@ -119,10 +149,8 @@ public sealed class HideAndSeekHudHelper(nint cppPtr) : MonoBehaviour(cppPtr)
|
||||
|
||||
beepCoroutine = null!;
|
||||
}
|
||||
private float taskDirtyTimer;
|
||||
public float HideCountdown { get; set; }
|
||||
|
||||
public void LateUpdate()
|
||||
private void LateUpdate()
|
||||
{
|
||||
if (!HudManager.InstanceExists)
|
||||
{
|
||||
@@ -178,9 +206,11 @@ public sealed class HideAndSeekHudHelper(nint cppPtr) : MonoBehaviour(cppPtr)
|
||||
HudManager.Instance.TaskPanel.SetTaskText(HudManager.Instance.tasksString.ToString());
|
||||
}
|
||||
}
|
||||
public void FixedUpdate()
|
||||
|
||||
private void FixedUpdate()
|
||||
{
|
||||
secondsSinceLastSetDirty += Time.fixedDeltaTime;
|
||||
|
||||
if (IsFinalCountdown)
|
||||
{
|
||||
AdjustFinalEscapeTimer(Time.fixedDeltaTime);
|
||||
@@ -190,11 +220,11 @@ public sealed class HideAndSeekHudHelper(nint cppPtr) : MonoBehaviour(cppPtr)
|
||||
AdjustEscapeTimer(Time.fixedDeltaTime, false);
|
||||
}
|
||||
|
||||
public void OnDestroy()
|
||||
private void OnDestroy()
|
||||
{
|
||||
if (timerBar != null)
|
||||
{
|
||||
Object.Destroy(timerBar);
|
||||
Destroy(timerBar);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -205,7 +235,7 @@ public sealed class HideAndSeekHudHelper(nint cppPtr) : MonoBehaviour(cppPtr)
|
||||
if (!playerControl.Data.Role.IsImpostor && !playerControl.Data.IsDead)
|
||||
{
|
||||
playerControl.ClearTasks();
|
||||
PlayerTask.GetOrCreateTask<ImportantTextTask>(playerControl, 0).Text =
|
||||
PlayerTask.GetOrCreateTask<ImportantTextTask>(playerControl).Text =
|
||||
DestroyableSingleton<TranslationController>.Instance.GetString(StringNames.HideActionButton);
|
||||
}
|
||||
}
|
||||
@@ -220,7 +250,7 @@ public sealed class HideAndSeekHudHelper(nint cppPtr) : MonoBehaviour(cppPtr)
|
||||
}
|
||||
|
||||
timerBar.StartFinalHide();
|
||||
SoundManager.Instance.PlaySound(FinalHideAlertSfx, false, 1f, null);
|
||||
SoundManager.Instance.PlaySound(finalHideAlertSfx, false);
|
||||
DestroyableSingleton<HudManager>.Instance.SetAlertOverlay(true);
|
||||
}
|
||||
|
||||
@@ -253,7 +283,7 @@ public sealed class HideAndSeekHudHelper(nint cppPtr) : MonoBehaviour(cppPtr)
|
||||
{
|
||||
float num = currentHideTime / 10f;
|
||||
float pitch = 1.5f - num / 2f;
|
||||
SoundManager.Instance.PlaySoundImmediate(FinalHideCountdownSfx, false, 1f, pitch, null);
|
||||
SoundManager.Instance.PlaySoundImmediate(finalHideCountdownSfx, false, 1f, pitch);
|
||||
yield return new WaitForSeconds(1f);
|
||||
}
|
||||
|
||||
@@ -262,11 +292,9 @@ public sealed class HideAndSeekHudHelper(nint cppPtr) : MonoBehaviour(cppPtr)
|
||||
{
|
||||
float num2 = currentFinalHideTime / 10f;
|
||||
float pitch2 = 1.5f - num2 / 2f;
|
||||
SoundManager.Instance.PlaySoundImmediate(FinalHideCountdownSfx, false, 1f, pitch2, null);
|
||||
SoundManager.Instance.PlaySoundImmediate(finalHideCountdownSfx, false, 1f, pitch2);
|
||||
yield return new WaitForSeconds(1f);
|
||||
}
|
||||
|
||||
yield break;
|
||||
}
|
||||
|
||||
private void AdjustFinalEscapeTimer(float timeDeduction)
|
||||
@@ -280,6 +308,10 @@ public sealed class HideAndSeekHudHelper(nint cppPtr) : MonoBehaviour(cppPtr)
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks to see if all timers have expired.
|
||||
/// </summary>
|
||||
/// <returns>true if all times have expired.</returns>
|
||||
public bool AllTimersExpired()
|
||||
{
|
||||
return currentHideTime <= 0f && currentFinalHideTime <= 0f;
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Linq;
|
||||
using MiraAPI.GameOptions;
|
||||
using MiraAPI.HnsReimplemented.Options;
|
||||
@@ -8,19 +9,22 @@ using UnityEngine;
|
||||
|
||||
namespace MiraAPI.HnsReimplemented;
|
||||
|
||||
/// <summary>
|
||||
/// A Unity script designed to mimic the base game's player danger meter during Hide and Seek.
|
||||
/// </summary>
|
||||
/// <param name="cppPtr">The pointer of this instance's equivalent in the Il2Cpp domain.</param>
|
||||
[RegisterInIl2Cpp]
|
||||
[SuppressMessage("Style", "IDE0051:Remove unused private members", Justification = "Unity Convention.")]
|
||||
public sealed class HnsDangerMeter(nint cppPtr) : MonoBehaviour(cppPtr)
|
||||
{
|
||||
public static HnsDangerMeter Instance;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
Instance = this;
|
||||
}
|
||||
/// <summary>
|
||||
/// Gets the instance of the danger meter.
|
||||
/// </summary>
|
||||
public static HnsDangerMeter Instance { get; private set; }
|
||||
|
||||
private DangerMeter dangerMeter;
|
||||
|
||||
private List<PlayerControl> impostors = [];
|
||||
private List<PlayerControl>? impostors = [];
|
||||
|
||||
private float scaryMusicDistance;
|
||||
|
||||
@@ -34,7 +38,12 @@ public sealed class HnsDangerMeter(nint cppPtr) : MonoBehaviour(cppPtr)
|
||||
|
||||
private float firstCrossfadeCountdown;
|
||||
|
||||
public void FixedUpdate()
|
||||
private void Awake()
|
||||
{
|
||||
Instance = this;
|
||||
}
|
||||
|
||||
private void FixedUpdate()
|
||||
{
|
||||
PlayerControl localPlayer = PlayerControl.LocalPlayer;
|
||||
if (impostors == null || localPlayer == null)
|
||||
@@ -50,15 +59,14 @@ public sealed class HnsDangerMeter(nint cppPtr) : MonoBehaviour(cppPtr)
|
||||
float num = float.MaxValue;
|
||||
foreach (PlayerControl playerControl in impostors)
|
||||
{
|
||||
if (!(playerControl == null))
|
||||
{
|
||||
if (playerControl == null)
|
||||
continue;
|
||||
float sqrMagnitude = (playerControl.transform.position - localPlayer.transform.position).sqrMagnitude;
|
||||
if (sqrMagnitude < scaryMusicDistance && num > sqrMagnitude)
|
||||
{
|
||||
num = sqrMagnitude;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (HideAndSeekHudHelper.Instance.HideCountdown > 0f)
|
||||
{
|
||||
@@ -71,7 +79,7 @@ public sealed class HnsDangerMeter(nint cppPtr) : MonoBehaviour(cppPtr)
|
||||
{
|
||||
firstMusicActivation = false;
|
||||
firstCrossfadeCountdown = 3f;
|
||||
HnsMusicHandler.Instance.SetMusicCrossfadeSpeed(0.6f);
|
||||
HnsMusicHandler.Instance.SetMusicCrossFadeSpeed(0.6f);
|
||||
}
|
||||
|
||||
if (firstCrossfadeCountdown > 0f)
|
||||
@@ -79,7 +87,7 @@ public sealed class HnsDangerMeter(nint cppPtr) : MonoBehaviour(cppPtr)
|
||||
firstCrossfadeCountdown -= Time.deltaTime;
|
||||
if (firstCrossfadeCountdown <= 0f)
|
||||
{
|
||||
HnsMusicHandler.Instance.SetMusicCrossfadeSpeed(5f);
|
||||
HnsMusicHandler.Instance.SetMusicCrossFadeSpeed(5f);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -115,6 +123,9 @@ public sealed class HnsDangerMeter(nint cppPtr) : MonoBehaviour(cppPtr)
|
||||
dangerMeter.SetDangerValue(dangerLevel1, dangerLevel2);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// An event that is executed when the game starts.
|
||||
/// </summary>
|
||||
public void OnGameStart()
|
||||
{
|
||||
firstMusicActivation = true;
|
||||
@@ -124,19 +135,15 @@ public sealed class HnsDangerMeter(nint cppPtr) : MonoBehaviour(cppPtr)
|
||||
dangerMeter.gameObject.SetActive(true);
|
||||
}
|
||||
|
||||
impostors = Helpers.GetAlivePlayers().Where(x => x.Data.Role.IsImpostor).ToList();
|
||||
impostors = [.. Helpers.GetAlivePlayers().Where(x => x.Data.Role.IsImpostor)];
|
||||
|
||||
var baseSpeed = OptionGroupSingleton<HnsCrewmateOptions>.Instance.PlayerSpeed.Value;
|
||||
scaryMusicDistance = 55f *
|
||||
baseSpeed;
|
||||
veryScaryMusicDistance = 15f *
|
||||
baseSpeed;
|
||||
if (scaryMusicDistance < veryScaryMusicDistance)
|
||||
{
|
||||
scaryMusicDistance = 55f * baseSpeed;
|
||||
veryScaryMusicDistance = 15f * baseSpeed;
|
||||
if (scaryMusicDistance >= veryScaryMusicDistance) return;
|
||||
float num = veryScaryMusicDistance;
|
||||
float num2 = scaryMusicDistance;
|
||||
scaryMusicDistance = num;
|
||||
veryScaryMusicDistance = num2;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using Amongus.GameModes.HideAndSeek;
|
||||
using MiraAPI.GameOptions;
|
||||
using MiraAPI.HnsReimplemented.Options;
|
||||
@@ -7,15 +8,18 @@ using UnityEngine;
|
||||
|
||||
namespace MiraAPI.HnsReimplemented;
|
||||
|
||||
/// <summary>
|
||||
/// A Unity script designed to handle the music during Hide and Seek.
|
||||
/// </summary>
|
||||
/// <param name="cppPtr">The pointer of this instance's equivalent in the Il2Cpp domain.</param>
|
||||
[RegisterInIl2Cpp]
|
||||
[SuppressMessage("Style", "IDE0051:Remove unused private members", Justification = "Unity convention.")]
|
||||
public sealed class HnsMusicHandler(nint cppPtr) : MonoBehaviour(cppPtr)
|
||||
{
|
||||
public static HnsMusicHandler Instance;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
Instance = this;
|
||||
}
|
||||
/// <summary>
|
||||
/// Gets the instance of the music handler.
|
||||
/// </summary>
|
||||
public static HnsMusicHandler Instance { get; private set; }
|
||||
|
||||
private HideAndSeekMusicCollection musicCollection;
|
||||
|
||||
@@ -41,18 +45,46 @@ public sealed class HnsMusicHandler(nint cppPtr) : MonoBehaviour(cppPtr)
|
||||
|
||||
private float musicLerpSpeed = 5f;
|
||||
|
||||
public void Start()
|
||||
private readonly Dictionary<LogicHnSMusic.HideAndSeekMusicTrack, string> musicNames = new()
|
||||
{
|
||||
{
|
||||
LogicHnSMusic.HideAndSeekMusicTrack.Normal,
|
||||
"HnS_Music_Normal"
|
||||
},
|
||||
{
|
||||
LogicHnSMusic.HideAndSeekMusicTrack.Task,
|
||||
"HnS_Music_Task"
|
||||
},
|
||||
{
|
||||
LogicHnSMusic.HideAndSeekMusicTrack.DangerLevel1,
|
||||
"HnS_Music_DangerLevel1"
|
||||
},
|
||||
{
|
||||
LogicHnSMusic.HideAndSeekMusicTrack.DangerLevel2,
|
||||
"HnS_Music_DangerLevel2"
|
||||
},
|
||||
};
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
Instance = this;
|
||||
}
|
||||
|
||||
private void Start()
|
||||
{
|
||||
musicCollection = GameManagerCreator.Instance.HideAndSeekManagerPrefab.MusicCollection;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// An event that is executed when the round starts.
|
||||
/// </summary>
|
||||
public void OnGameStart()
|
||||
{
|
||||
InitMusic();
|
||||
ResetMusic();
|
||||
}
|
||||
|
||||
public void OnDestroy()
|
||||
private void OnDestroy()
|
||||
{
|
||||
ResetMusic();
|
||||
}
|
||||
@@ -107,6 +139,9 @@ public sealed class HnsMusicHandler(nint cppPtr) : MonoBehaviour(cppPtr)
|
||||
SyncMusic();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the music with the intro.
|
||||
/// </summary>
|
||||
public void StartMusicWithIntro()
|
||||
{
|
||||
if (PlayerControl.LocalPlayer.Data.Role.IsImpostor)
|
||||
@@ -123,12 +158,16 @@ public sealed class HnsMusicHandler(nint cppPtr) : MonoBehaviour(cppPtr)
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the current task state to alter music behaviour.
|
||||
/// </summary>
|
||||
/// <param name="isDoingTask">The new value of the state.</param>
|
||||
public void SetTaskState(bool isDoingTask)
|
||||
{
|
||||
isDoingTask = isDoingTask;
|
||||
this.isDoingTask = isDoingTask;
|
||||
}
|
||||
|
||||
public void FixedUpdate()
|
||||
private void FixedUpdate()
|
||||
{
|
||||
if (normalSource == null || taskSource == null || dangerLevel1Source == null ||
|
||||
dangerLevel2Source == null)
|
||||
@@ -167,16 +206,28 @@ public sealed class HnsMusicHandler(nint cppPtr) : MonoBehaviour(cppPtr)
|
||||
lastMusicSyncTime = Time.unscaledTime;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resets the music currently playing.
|
||||
/// </summary>
|
||||
public void ResetMusic()
|
||||
{
|
||||
SetMusicValues(0f, 0f);
|
||||
}
|
||||
|
||||
public void SetMusicCrossfadeSpeed(float lerpSpeed)
|
||||
/// <summary>
|
||||
/// Sets the music crossfade speed.
|
||||
/// </summary>
|
||||
/// <param name="lerpSpeed">The new speed.</param>
|
||||
public void SetMusicCrossFadeSpeed(float lerpSpeed)
|
||||
{
|
||||
musicLerpSpeed = lerpSpeed;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the current music value based on the danger level.
|
||||
/// </summary>
|
||||
/// <param name="dangerLevel1">The first danger level.</param>
|
||||
/// <param name="dangerLevel2">The second danger level.</param>
|
||||
public void SetMusicValues(float dangerLevel1, float dangerLevel2)
|
||||
{
|
||||
if (PlayerControl.LocalPlayer != null && PlayerControl.LocalPlayer.Data.Role.IsImpostor)
|
||||
@@ -190,8 +241,8 @@ public sealed class HnsMusicHandler(nint cppPtr) : MonoBehaviour(cppPtr)
|
||||
return;
|
||||
}
|
||||
|
||||
normalVolume = (isDoingTask ? 0f : 1f);
|
||||
taskVolume = (isDoingTask ? 1f : 0f);
|
||||
normalVolume = isDoingTask ? 0f : 1f;
|
||||
taskVolume = isDoingTask ? 1f : 0f;
|
||||
dangerLevel1Volume = 0f;
|
||||
dangerLevel2Volume = 0f;
|
||||
if (dangerLevel1 > 0f)
|
||||
@@ -213,25 +264,4 @@ public sealed class HnsMusicHandler(nint cppPtr) : MonoBehaviour(cppPtr)
|
||||
dangerLevel1Volume = 1f - dangerLevel2;
|
||||
}
|
||||
}
|
||||
|
||||
private readonly Dictionary<LogicHnSMusic.HideAndSeekMusicTrack, string> musicNames =
|
||||
new Dictionary<LogicHnSMusic.HideAndSeekMusicTrack, string>
|
||||
{
|
||||
{
|
||||
LogicHnSMusic.HideAndSeekMusicTrack.Normal,
|
||||
"HnS_Music_Normal"
|
||||
},
|
||||
{
|
||||
LogicHnSMusic.HideAndSeekMusicTrack.Task,
|
||||
"HnS_Music_Task"
|
||||
},
|
||||
{
|
||||
LogicHnSMusic.HideAndSeekMusicTrack.DangerLevel1,
|
||||
"HnS_Music_DangerLevel1"
|
||||
},
|
||||
{
|
||||
LogicHnSMusic.HideAndSeekMusicTrack.DangerLevel2,
|
||||
"HnS_Music_DangerLevel2"
|
||||
},
|
||||
};
|
||||
}
|
||||
@@ -5,12 +5,17 @@ using MiraAPI.Utilities;
|
||||
|
||||
namespace MiraAPI.HnsReimplemented.Options;
|
||||
|
||||
/// <inheritdoc />
|
||||
/// <summary>
|
||||
/// Gets or sets the crewmate options for Hide and Seek.
|
||||
/// </summary>
|
||||
public class HnsCrewmateOptions : AbstractOptionGroup<HideAndSeekMode>
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public override string GroupName => "Crewmates";
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the player speed.
|
||||
/// </summary>
|
||||
public ModdedNumberOption PlayerSpeed { get; set; } = new(
|
||||
"Player Speed",
|
||||
1f,
|
||||
@@ -22,6 +27,9 @@ public class HnsCrewmateOptions : AbstractOptionGroup<HideAndSeekMode>
|
||||
MiraNumberSuffixes.Multiplier,
|
||||
"0.00");
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the hiding time.
|
||||
/// </summary>
|
||||
public ModdedNumberOption HidingTime { get; set; } = new(
|
||||
"Hiding Time",
|
||||
200,
|
||||
@@ -32,6 +40,9 @@ public class HnsCrewmateOptions : AbstractOptionGroup<HideAndSeekMode>
|
||||
"#",
|
||||
MiraNumberSuffixes.Seconds);
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the limits of a crewmate's vision.
|
||||
/// </summary>
|
||||
public ModdedNumberOption CrewmateVision { get; set; } = new(
|
||||
"Crewmate Vision",
|
||||
0.6f,
|
||||
@@ -43,33 +54,16 @@ public class HnsCrewmateOptions : AbstractOptionGroup<HideAndSeekMode>
|
||||
MiraNumberSuffixes.Multiplier,
|
||||
"0.00");
|
||||
|
||||
public ModdedNumberOption MaxVentUses { get; set; } = new(
|
||||
"Max Vent Uses",
|
||||
1,
|
||||
0,
|
||||
5,
|
||||
1,
|
||||
"#",
|
||||
"#",
|
||||
MiraNumberSuffixes.None);
|
||||
|
||||
public ModdedNumberOption MaxTimeInVent { get; set; } = new(
|
||||
"Max Time in Vent",
|
||||
3,
|
||||
1,
|
||||
10,
|
||||
1,
|
||||
"#",
|
||||
"#",
|
||||
MiraNumberSuffixes.Seconds)
|
||||
{
|
||||
Visible = () => (int)OptionGroupSingleton<HnsCrewmateOptions>.Instance.MaxVentUses.Value > 0,
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a flag that toggles flashlight vision.
|
||||
/// </summary>
|
||||
public ModdedToggleOption FlashlightMode { get; set; } = new(
|
||||
"Flashlight Mode",
|
||||
true);
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the range of a crewmate's flashlight.
|
||||
/// </summary>
|
||||
public ModdedNumberOption CrewmateFlashlightSize { get; set; } = new(
|
||||
"Crewmate Flashlight Size",
|
||||
0.35f,
|
||||
@@ -83,6 +77,38 @@ public class HnsCrewmateOptions : AbstractOptionGroup<HideAndSeekMode>
|
||||
Visible = () => OptionGroupSingleton<HnsCrewmateOptions>.Instance.FlashlightMode.Value,
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the maximum number of times a crewmate can vent.
|
||||
/// </summary>
|
||||
public ModdedNumberOption MaxVentUses { get; set; } = new(
|
||||
"Max Vent Uses",
|
||||
1,
|
||||
0,
|
||||
5,
|
||||
1,
|
||||
"#",
|
||||
"#",
|
||||
MiraNumberSuffixes.None);
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the maximum amount of time a crewmate can spend inside a vent.
|
||||
/// </summary>
|
||||
public ModdedNumberOption MaxTimeInVent { get; set; } = new(
|
||||
"Max Time in Vent",
|
||||
3,
|
||||
1,
|
||||
10,
|
||||
1,
|
||||
"#",
|
||||
"#",
|
||||
MiraNumberSuffixes.Seconds)
|
||||
{
|
||||
Visible = () => (int)OptionGroupSingleton<HnsCrewmateOptions>.Instance.MaxVentUses.Value > 0,
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the visibility of player names.
|
||||
/// </summary>
|
||||
public ModdedToggleOption ShowNames { get; set; } = new(
|
||||
"Show Names",
|
||||
false);
|
||||
|
||||
@@ -5,12 +5,17 @@ using MiraAPI.Utilities;
|
||||
|
||||
namespace MiraAPI.HnsReimplemented.Options;
|
||||
|
||||
/// <inheritdoc />
|
||||
/// <summary>
|
||||
/// Gets or sets the Final Hide options for Hide and Seek.
|
||||
/// </summary>
|
||||
public class HnsFinalHideOptions : AbstractOptionGroup<HideAndSeekMode>
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public override string GroupName => "Final Hide";
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the duration of the Final Hide phase.
|
||||
/// </summary>
|
||||
public ModdedNumberOption FinalHideTime { get; set; } = new(
|
||||
"Hiding Time",
|
||||
50,
|
||||
@@ -21,10 +26,9 @@ public class HnsFinalHideOptions : AbstractOptionGroup<HideAndSeekMode>
|
||||
"#",
|
||||
MiraNumberSuffixes.Seconds);
|
||||
|
||||
public ModdedToggleOption FinalHidePings { get; set; } = new(
|
||||
"Final Hide Pings",
|
||||
true);
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the Seeker's speed when the Final Hide phase begins.
|
||||
/// </summary>
|
||||
public ModdedNumberOption FinalHideImpostorSpeed { get; set; } = new(
|
||||
"Final Hide Impostor Speed",
|
||||
1.2f,
|
||||
@@ -36,6 +40,16 @@ public class HnsFinalHideOptions : AbstractOptionGroup<HideAndSeekMode>
|
||||
MiraNumberSuffixes.Multiplier,
|
||||
"0.00");
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets whether the Seeker sees the Final hide player pings.
|
||||
/// </summary>
|
||||
public ModdedToggleOption FinalHidePings { get; set; } = new(
|
||||
"Final Hide Pings",
|
||||
true);
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the interval between each ping.
|
||||
/// </summary>
|
||||
public ModdedNumberOption PingInterval { get; set; } = new(
|
||||
"Ping Interval",
|
||||
6,
|
||||
@@ -46,6 +60,9 @@ public class HnsFinalHideOptions : AbstractOptionGroup<HideAndSeekMode>
|
||||
"#",
|
||||
MiraNumberSuffixes.Seconds);
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets whether the Seeker can see players on an admin map.
|
||||
/// </summary>
|
||||
public ModdedToggleOption FinalHideSeekMap { get; set; } = new(
|
||||
"Final Hide Seek Map",
|
||||
true);
|
||||
|
||||
@@ -5,15 +5,23 @@ using MiraAPI.Utilities;
|
||||
|
||||
namespace MiraAPI.HnsReimplemented.Options;
|
||||
|
||||
/// <inheritdoc />
|
||||
/// <summary>
|
||||
/// Gets or sets the seeker settings on Hide and Seek.
|
||||
/// </summary>
|
||||
public class HnsImpostorOptions : AbstractOptionGroup<HideAndSeekMode>
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public override string GroupName => "Impostors";
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the player who will be the seeker.
|
||||
/// </summary>
|
||||
public ModdedPlayerOption SelectedSeeker { get; set; } = new(
|
||||
"Forced Impostor");
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the range of a seeker's vision.
|
||||
/// </summary>
|
||||
public ModdedNumberOption ImpostorVision { get; set; } = new(
|
||||
"Impostor Vision",
|
||||
0.6f,
|
||||
@@ -25,6 +33,9 @@ public class HnsImpostorOptions : AbstractOptionGroup<HideAndSeekMode>
|
||||
MiraNumberSuffixes.Multiplier,
|
||||
"0.00");
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the range of a seeker's flashlight.
|
||||
/// </summary>
|
||||
public ModdedNumberOption ImpostorFlashlightSize { get; set; } = new(
|
||||
"Impostor Flashlight Size",
|
||||
0.35f,
|
||||
|
||||
@@ -5,12 +5,17 @@ using MiraAPI.Utilities;
|
||||
|
||||
namespace MiraAPI.HnsReimplemented.Options;
|
||||
|
||||
/// <inheritdoc />
|
||||
/// <summary>
|
||||
/// Gets or sets the task options for Hide and Seek.
|
||||
/// </summary>
|
||||
public class HnsTaskOptions : AbstractOptionGroup<HideAndSeekMode>
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public override string GroupName => "Tasks";
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the umber of common tasks.
|
||||
/// </summary>
|
||||
public ModdedNumberOption CommonTasks { get; set; } = new(
|
||||
"# Common Tasks",
|
||||
1,
|
||||
@@ -21,6 +26,9 @@ public class HnsTaskOptions : AbstractOptionGroup<HideAndSeekMode>
|
||||
"#",
|
||||
MiraNumberSuffixes.None);
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the number of long tasks.
|
||||
/// </summary>
|
||||
public ModdedNumberOption LongTasks { get; set; } = new(
|
||||
"# Long Tasks",
|
||||
1,
|
||||
@@ -31,6 +39,9 @@ public class HnsTaskOptions : AbstractOptionGroup<HideAndSeekMode>
|
||||
"#",
|
||||
MiraNumberSuffixes.None);
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the number of short tasks.
|
||||
/// </summary>
|
||||
public ModdedNumberOption ShortTasks { get; set; } = new(
|
||||
"# Short Tasks",
|
||||
2,
|
||||
|
||||
@@ -9,7 +9,6 @@ using Reactor.Utilities.Attributes;
|
||||
using Reactor.Utilities.Extensions;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Events;
|
||||
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
|
||||
|
||||
namespace MiraAPI.Hud;
|
||||
|
||||
@@ -21,6 +20,8 @@ namespace MiraAPI.Hud;
|
||||
[SuppressMessage("Design", "CA1051:Do not declare visible instance fields", Justification = "Unity Convention.")]
|
||||
[SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1401:Fields should be private", Justification = "Unity Convention.")]
|
||||
[SuppressMessage("StyleCop.CSharp.NamingRules", "SA1307:Accessible fields should begin with upper-case letter", Justification = "Unity Convention.")]
|
||||
[SuppressMessage("Style", "IDE0051:Remove unused private members", Justification = "Unity convention.")]
|
||||
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member (Justification: Unity fields to mirror base game ShapeshifterMinigame; not worth documenting)
|
||||
public class CustomPlayerMenu(IntPtr il2CppPtr) : Minigame(il2CppPtr)
|
||||
{
|
||||
public ShapeshifterPanel panelPrefab;
|
||||
@@ -68,7 +69,6 @@ public class CustomPlayerMenu(IntPtr il2CppPtr) : Minigame(il2CppPtr)
|
||||
return customMenu;
|
||||
}
|
||||
|
||||
[SuppressMessage("Style", "IDE0051:Remove unused private members", Justification = "Unity convention.")]
|
||||
private void OnDisable()
|
||||
{
|
||||
ControllerManager.Instance.CloseOverlayMenu(name);
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using BepInEx.Unity.IL2CPP.Utils.Collections;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using BepInEx.Unity.IL2CPP.Utils.Collections;
|
||||
using InnerNet;
|
||||
using MiraAPI.LocalSettings;
|
||||
using MiraAPI.Modifiers.ModifierDisplay;
|
||||
@@ -9,9 +10,13 @@ using UnityEngine;
|
||||
namespace MiraAPI.Hud;
|
||||
|
||||
[RegisterInIl2Cpp]
|
||||
public sealed class MiraHudHelper(nint cppPtr) : MonoBehaviour(cppPtr)
|
||||
[SuppressMessage("Style", "IDE0051:Remove unused private members", Justification = "Unity Convention.")]
|
||||
[SuppressMessage("Critical Code Smell", "S2223:Non-constant static fields should not be visible", Justification = "Is internal code. Property-level protections are not required.")]
|
||||
[SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1401:Fields should be private", Justification = "Read above.")]
|
||||
internal sealed class MiraHudHelper(nint cppPtr) : MonoBehaviour(cppPtr)
|
||||
{
|
||||
public static MiraHudHelper Instance { get; private set; }
|
||||
|
||||
public static GameObject ModifierDisplayObject;
|
||||
public static GameObject VanillaMatchInfoButton;
|
||||
public static bool ModifierDisplayOnRight;
|
||||
@@ -25,20 +30,25 @@ public sealed class MiraHudHelper(nint cppPtr) : MonoBehaviour(cppPtr)
|
||||
public static GameObject SubmergedFloorButton;
|
||||
public static SpriteRenderer SubmergedFloorButtonRenderer;
|
||||
public static SpriteRenderer SubmergedFloorButtonRendererHover;
|
||||
public void Awake()
|
||||
|
||||
public static readonly Vector3 BelowOptionPos = new(0.435f, 1.25f, 0f);
|
||||
public static readonly Vector3 FullTopPos = new(0.435f, 0.475f, 0f);
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
Instance = this;
|
||||
}
|
||||
|
||||
public void Start()
|
||||
private void Start()
|
||||
{
|
||||
MiraApiSettings.OldButtonScaleFactor =
|
||||
LocalSettingsTabSingleton<MiraApiSettings>.Instance.TopRightButtonsFactorSlider.Value;
|
||||
StartCoroutine(MiraApiSettings.CoResizeSettingsUI().WrapToIl2Cpp());
|
||||
}
|
||||
#pragma warning disable S2325
|
||||
#pragma warning disable CA1822
|
||||
public void FixedUpdate()
|
||||
|
||||
[SuppressMessage("Performance", "CA1822:Mark members as static", Justification = "Unity script method.")]
|
||||
[SuppressMessage("Minor Code Smell", "S2325:Methods and properties that don't access instance data should be static", Justification = "Read above.")]
|
||||
private void FixedUpdate()
|
||||
{
|
||||
if (!HudManager.InstanceExists || !PlayerControl.LocalPlayer || !PlayerControl.LocalPlayer.Data)
|
||||
{
|
||||
@@ -60,11 +70,7 @@ public sealed class MiraHudHelper(nint cppPtr) : MonoBehaviour(cppPtr)
|
||||
}
|
||||
UpdateSubmergedButtons(instance);
|
||||
}
|
||||
#pragma warning restore CA1822
|
||||
#pragma warning restore S2325
|
||||
|
||||
public static Vector3 BelowOptionPos = new(0.435f, 1.25f, 0f);
|
||||
public static Vector3 FullTopPos = new(0.435f, 0.475f, 0f);
|
||||
public static void CreateUiRow(HudManager instance)
|
||||
{
|
||||
if (!UiTopRight)
|
||||
@@ -129,8 +135,9 @@ public sealed class MiraHudHelper(nint cppPtr) : MonoBehaviour(cppPtr)
|
||||
instance.Chat.chatNotifyDot = iconContainer.transform.GetChild(0).GetComponent<SpriteRenderer>();
|
||||
}
|
||||
|
||||
if (UiTopRight && UiGrid)
|
||||
{
|
||||
if (!UiTopRight || !UiGrid)
|
||||
return;
|
||||
|
||||
var isChatButtonVisible = HudManager.Instance.Chat.isActiveAndEnabled;
|
||||
instance.Chat.chatButton.gameObject.SetActive(isChatButtonVisible);
|
||||
if (VanillaMatchInfoButton)
|
||||
@@ -138,16 +145,16 @@ public sealed class MiraHudHelper(nint cppPtr) : MonoBehaviour(cppPtr)
|
||||
VanillaMatchInfoButton.SetActive(!GameSettingMenu.Instance && !Minigame.Instance);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void UpdateSubmergedButtons(HudManager instance)
|
||||
{
|
||||
if (ModCompatibility.IsSubmerged() && !SubmergedFloorButton && ExtraUiTopRight)
|
||||
{
|
||||
if (!SubmergedFloorButton && ExtraUiTopRight)
|
||||
{
|
||||
if (!ModCompatibility.IsSubmerged() || SubmergedFloorButton || !ExtraUiTopRight || SubmergedFloorButton || !ExtraUiTopRight)
|
||||
return;
|
||||
|
||||
var transform = instance.MapButton.transform.parent.Find(instance.MapButton.name + "(Clone)");
|
||||
if (transform != null)
|
||||
{
|
||||
if (transform == null)
|
||||
return;
|
||||
|
||||
SubmergedFloorButton = transform.gameObject;
|
||||
SubmergedFloorButton.transform.SetParent(ExtraUiTopRight.transform, false);
|
||||
|
||||
@@ -158,14 +165,12 @@ public sealed class MiraHudHelper(nint cppPtr) : MonoBehaviour(cppPtr)
|
||||
|
||||
MiraApiSettings.SetUpButtonPositions();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void AdjustModifierTab()
|
||||
{
|
||||
if (!ModifierDisplayObject && UiTopRight && ExtraUiTopRight && ModifierDisplayComponent.Instance)
|
||||
{
|
||||
if (ModifierDisplayObject || !UiTopRight || !ExtraUiTopRight || !ModifierDisplayComponent.Instance)
|
||||
return;
|
||||
|
||||
ModifierDisplayObject = ModifierDisplayComponent.Instance?.gameObject ?? null!;
|
||||
ModifierDisplayOnRight = !LocalSettingsTabSingleton<MiraApiSettings>.Instance.ModifiersHudLeftSide.Value;
|
||||
if (ModifierDisplayOnRight)
|
||||
@@ -179,11 +184,12 @@ public sealed class MiraHudHelper(nint cppPtr) : MonoBehaviour(cppPtr)
|
||||
}
|
||||
MiraApiSettings.SetUpButtonPositions();
|
||||
}
|
||||
}
|
||||
|
||||
public static void CreateNewUiRow(HudManager instance)
|
||||
{
|
||||
if (!ExtraUiTopRight && UiTopRight)
|
||||
{
|
||||
if (ExtraUiTopRight || !UiTopRight)
|
||||
return;
|
||||
|
||||
ExtraUiTopRight = new GameObject("ExtraUiTopRight")
|
||||
{
|
||||
layer = UiTopRight.layer,
|
||||
@@ -200,4 +206,3 @@ public sealed class MiraHudHelper(nint cppPtr) : MonoBehaviour(cppPtr)
|
||||
ExtraUiGrid.Start();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -7,6 +7,8 @@ namespace MiraAPI.LocalSettings.Attributes;
|
||||
/// <summary>
|
||||
/// Creates a <see cref="LocalToggleSetting"/> for the <see cref="ConfigEntry{T}"/>.
|
||||
/// </summary>
|
||||
/// <param name="name">The name of the setting.</param>
|
||||
/// <param name="description">The description of the setting.</param>
|
||||
[AttributeUsage(AttributeTargets.Property)]
|
||||
public class LocalToggleSettingAttribute(
|
||||
string? name = null,
|
||||
|
||||
@@ -59,9 +59,9 @@ public class LocalSettingsButton(string text, Action onClick)
|
||||
button.name = Text;
|
||||
button.OnClick = new UnityEngine.UI.Button.ButtonClickedEvent();
|
||||
rollover.OutColor = Tab!.TabAppearance.ButtonColor;
|
||||
rollover.OverColor = Tab!.TabAppearance.ButtonHoverColor;
|
||||
rollover.OverColor = Tab.TabAppearance.ButtonHoverColor;
|
||||
rollover.Target = background;
|
||||
background.color = Tab!.TabAppearance.ButtonColor;
|
||||
background.color = Tab.TabAppearance.ButtonColor;
|
||||
button.OnClick.AddListener((UnityAction)OnClick);
|
||||
|
||||
background.transform.localScale = new Vector3(1, 1.25f, 1);
|
||||
@@ -79,6 +79,9 @@ public class LocalSettingsButton(string text, Action onClick)
|
||||
return button.gameObject;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Refreshes the button.
|
||||
/// </summary>
|
||||
public void RefreshButton()
|
||||
{
|
||||
_btnText.text = Text.Translate();
|
||||
|
||||
@@ -197,7 +197,7 @@ public abstract class LocalSettingsTab(ConfigFile config)
|
||||
ref contentOrder,
|
||||
contentIndex == Buttons.Count);
|
||||
|
||||
obj!.GetComponentsInChildren<SpriteRenderer>(true).Do(x =>
|
||||
obj.GetComponentsInChildren<SpriteRenderer>(true).Do(x =>
|
||||
{
|
||||
x.maskInteraction = SpriteMaskInteraction.VisibleInsideMask;
|
||||
x.sortingOrder = 150;
|
||||
@@ -277,10 +277,8 @@ public abstract class LocalSettingsTab(ConfigFile config)
|
||||
{
|
||||
if (!tabButtonObject.Content.gameObject.activeSelf)
|
||||
{
|
||||
#pragma warning disable S125 // Sections of code should not be commented out
|
||||
// tabButtonObject.Button.color = TabColor;
|
||||
// tabButtonObject.Rollover.OutColor = TabColor;
|
||||
#pragma warning restore S125 // Sections of code should not be commented out
|
||||
}
|
||||
|
||||
tabButton.transform.localPosition = new Vector3(2.4f, 2.1f - tabOffset, 5.5f);
|
||||
|
||||
@@ -80,8 +80,8 @@ public class LocalEnumSetting(
|
||||
button.name = Name;
|
||||
button.OnClick = new UnityEngine.UI.Button.ButtonClickedEvent();
|
||||
rollover.OutColor = Tab!.TabAppearance.EnumColor;
|
||||
rollover.OverColor = Tab!.TabAppearance.EnumHoverColor;
|
||||
background.color = Tab!.TabAppearance.EnumColor;
|
||||
rollover.OverColor = Tab.TabAppearance.EnumHoverColor;
|
||||
background.color = Tab.TabAppearance.EnumColor;
|
||||
|
||||
button.OnClick.AddListener((UnityAction)(() =>
|
||||
{
|
||||
|
||||
@@ -90,8 +90,8 @@ public class LocalNumberSetting(
|
||||
button.name = Name;
|
||||
button.OnClick = new UnityEngine.UI.Button.ButtonClickedEvent();
|
||||
rollover.OutColor = Tab!.TabAppearance.NumberColor;
|
||||
rollover.OverColor = Tab!.TabAppearance.NumberHoverColor;
|
||||
background.color = Tab!.TabAppearance.NumberColor;
|
||||
rollover.OverColor = Tab.TabAppearance.NumberHoverColor;
|
||||
background.color = Tab.TabAppearance.NumberColor;
|
||||
|
||||
button.OnClick.AddListener((UnityAction)(() =>
|
||||
{
|
||||
|
||||
@@ -58,7 +58,7 @@ public abstract class LocalSettingBase<T> : ILocalSetting
|
||||
public abstract void RefreshOption();
|
||||
|
||||
/// <summary>
|
||||
/// Returns the formated string to use in the text of the setting.
|
||||
/// Returns the formatted string to use in the text of the setting.
|
||||
/// </summary>
|
||||
/// <returns>The value text.</returns>
|
||||
protected virtual string GetValueText()
|
||||
|
||||
@@ -79,8 +79,8 @@ public class LocalSliderSetting(
|
||||
newSlider.name = Name;
|
||||
newSlider.Range = new FloatRange(-1.5f, 1.5f);
|
||||
newSlider.SetValue(Mathf.InverseLerp(SliderRange.min, SliderRange.max, GetValue()));
|
||||
rollover.OutColor = Tab!.TabAppearance.SliderColor;
|
||||
rollover.OverColor = Tab!.TabAppearance.SliderHoverColor;
|
||||
rollover.OutColor = Tab.TabAppearance.SliderColor;
|
||||
rollover.OverColor = Tab.TabAppearance.SliderHoverColor;
|
||||
newSlider.Title.transform.localPosition = new Vector3(0.5f, 0, -1f);
|
||||
newSlider.Title.horizontalAlignment = DisplayValue ? HorizontalAlignmentOptions.Left : HorizontalAlignmentOptions.Center;
|
||||
newSlider.Title.text = GetValueText();
|
||||
|
||||
@@ -50,13 +50,13 @@ public class LocalToggleSetting(
|
||||
toggleObject.name = Name.Translate();
|
||||
toggleObject.Background.color = GetValue() ? Tab!.TabAppearance.ToggleActiveColor : Tab!.TabAppearance.ToggleInactiveColor;
|
||||
passiveButton.OnClick = new UnityEngine.UI.Button.ButtonClickedEvent();
|
||||
rollover.OverColor = Tab!.TabAppearance.ToggleHoverColor;
|
||||
rollover.OverColor = Tab.TabAppearance.ToggleHoverColor;
|
||||
|
||||
passiveButton.OnClick.AddListener((UnityAction)(() =>
|
||||
{
|
||||
SetValue(!GetValue());
|
||||
toggleObject.UpdateText(GetValue());
|
||||
toggleObject.Background.color = GetValue() ? Tab!.TabAppearance.ToggleActiveColor : Tab!.TabAppearance.ToggleInactiveColor;
|
||||
toggleObject.Background.color = GetValue() ? Tab.TabAppearance.ToggleActiveColor : Tab.TabAppearance.ToggleInactiveColor;
|
||||
}));
|
||||
passiveButton.OnMouseOver.AddListener((UnityAction)(() =>
|
||||
{
|
||||
@@ -68,7 +68,7 @@ public class LocalToggleSetting(
|
||||
passiveButton.OnMouseOut.AddListener((UnityAction)(() =>
|
||||
{
|
||||
toggleObject.UpdateText(GetValue());
|
||||
toggleObject.Background.color = GetValue() ? Tab!.TabAppearance.ToggleActiveColor : Tab!.TabAppearance.ToggleInactiveColor;
|
||||
toggleObject.Background.color = GetValue() ? Tab.TabAppearance.ToggleActiveColor : Tab.TabAppearance.ToggleInactiveColor;
|
||||
}));
|
||||
|
||||
Helpers.DivideSize(toggleObject.gameObject, 1.1f);
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Globalization;
|
||||
using Il2CppInterop.Runtime.Attributes;
|
||||
using Reactor.Utilities.Attributes;
|
||||
@@ -11,6 +12,7 @@ namespace MiraAPI.MeetingAbilities;
|
||||
/// A component for handling targeted meeting buttons.
|
||||
/// </summary>
|
||||
[RegisterInIl2Cpp]
|
||||
[SuppressMessage("Style", "IDE0051:Remove unused private members", Justification = "Unity convention.")]
|
||||
public class MeetingAbilityBehaviour : MonoBehaviour
|
||||
{
|
||||
/// <summary>
|
||||
@@ -24,29 +26,29 @@ public class MeetingAbilityBehaviour : MonoBehaviour
|
||||
private TargetedMeetingButton _button = null!;
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="PassiveButton"/> of this component.
|
||||
/// Gets he <see cref="PassiveButton"/> of this component.
|
||||
/// </summary>
|
||||
public PassiveButton Button;
|
||||
public PassiveButton Button { get; internal set; }
|
||||
|
||||
/// <summary>
|
||||
/// The parent <see cref="PlayerVoteArea"/>.
|
||||
/// Gets he parent <see cref="PlayerVoteArea"/>.
|
||||
/// </summary>
|
||||
public PlayerVoteArea VoteArea;
|
||||
public PlayerVoteArea VoteArea { get; internal set; }
|
||||
|
||||
/// <summary>
|
||||
/// The button's <see cref="SpriteRenderer"/> component.
|
||||
/// Gets he button's <see cref="SpriteRenderer"/> component.
|
||||
/// </summary>
|
||||
public SpriteRenderer Renderer;
|
||||
public SpriteRenderer Renderer { get; internal set; }
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="TextMeshPro"/> label used for showing the ability's cooldown.
|
||||
/// Gets he <see cref="TextMeshPro"/> label used for showing the ability's cooldown.
|
||||
/// </summary>
|
||||
public TextMeshPro CooldownText;
|
||||
public TextMeshPro CooldownText { get; internal set; }
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="TextMeshPro"/> label used for showing the ability's remaining uses.
|
||||
/// Gets the <see cref="TextMeshPro"/> label used for showing the ability's remaining uses.
|
||||
/// </summary>
|
||||
public TextMeshPro UsesText;
|
||||
public TextMeshPro UsesText { get; internal set; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes the various properties of this component.
|
||||
@@ -61,12 +63,13 @@ public class MeetingAbilityBehaviour : MonoBehaviour
|
||||
_button = button;
|
||||
Renderer = GetComponent<SpriteRenderer>();
|
||||
SetFillUp(1, 1);
|
||||
if (!TryGetComponent(out Button))
|
||||
if (!TryGetComponent<PassiveButton>(out var but))
|
||||
{
|
||||
Error($"Could not initialize MeetingButtonBehaviour for {Button.GetType().Name}, Destroying...");
|
||||
Destroy(this);
|
||||
}
|
||||
_init = true;
|
||||
Button = but;
|
||||
CooldownText = Instantiate(HudManager.Instance.KillButton.cooldownTimerText, transform);
|
||||
CooldownText.GetComponent<TextTranslatorTMP>().Destroy();
|
||||
CooldownText.transform.localPosition = new Vector3(0, 0, -10);
|
||||
@@ -112,6 +115,11 @@ public class MeetingAbilityBehaviour : MonoBehaviour
|
||||
SetFillUp(_button.Timer, _button.InitialCooldown);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the button fill up coloring based on the ratio between the time remaining and the maximum time of the button.
|
||||
/// </summary>
|
||||
/// <param name="timer">The remaining timer.</param>
|
||||
/// <param name="maxTimer">The maximum timer.</param>
|
||||
public void SetFillUp(float timer, float maxTimer)
|
||||
{
|
||||
float percentCool = Mathf.Clamp(timer / maxTimer, 0.001f, 1f);
|
||||
|
||||
@@ -73,17 +73,17 @@ public abstract class MeetingActionButton
|
||||
public int UsesSoFar { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value determining if the abiity is disabled upon being used.
|
||||
/// Gets a value indicating whether the ability is disabled upon being used.
|
||||
/// </summary>
|
||||
public virtual bool DisableUponUse => false;
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value determining if the abiity is disabled upon voting.
|
||||
/// Gets a value indicating whether the ability is disabled upon voting.
|
||||
/// </summary>
|
||||
public virtual bool DisableUponVoting => false;
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value determining if the abiity is hidden when votes wrapping up.
|
||||
/// Gets a value indicating whether the ability is hidden when votes wrapping up.
|
||||
/// </summary>
|
||||
public virtual bool HideUponWrapUp => false;
|
||||
|
||||
|
||||
@@ -15,12 +15,12 @@ public static class MeetingButtonManager
|
||||
/// <summary>
|
||||
/// Gets a list if==of all registered <see cref="TargetedMeetingButton"/>.
|
||||
/// </summary>
|
||||
public static List<TargetedMeetingButton> TargetedButtons { get; internal set; } = new();
|
||||
public static List<TargetedMeetingButton> TargetedButtons { get; internal set; } = [];
|
||||
|
||||
/// <summary>
|
||||
/// Gets a list if==of all registered <see cref="MeetingActionButton"/>.
|
||||
/// </summary>
|
||||
public static List<MeetingActionButton> UntargetedButtons { get; internal set; } = new();
|
||||
public static List<MeetingActionButton> UntargetedButtons { get; internal set; } = [];
|
||||
|
||||
internal static bool RegisterTargetedMeetingButton(Type type, MiraPluginInfo info)
|
||||
{
|
||||
@@ -29,7 +29,7 @@ public static class MeetingButtonManager
|
||||
return false;
|
||||
}
|
||||
|
||||
var button = Activator.CreateInstance(type) as TargetedMeetingButton;
|
||||
var button = (Activator.CreateInstance(type) as TargetedMeetingButton)!;
|
||||
info.InternalTargetedMeetingButtons.Add(button);
|
||||
TargetedButtons.Add(button);
|
||||
return true;
|
||||
@@ -42,14 +42,15 @@ public static class MeetingButtonManager
|
||||
return false;
|
||||
}
|
||||
|
||||
var button = Activator.CreateInstance(type) as MeetingActionButton;
|
||||
var button = (Activator.CreateInstance(type) as MeetingActionButton)!;
|
||||
info.InternalMeetingButtons.Add(button);
|
||||
UntargetedButtons.Add(button);
|
||||
return true;
|
||||
}
|
||||
|
||||
private static CenteredGridArrange? actionButtonsParent = null!;
|
||||
|
||||
/// <summary>
|
||||
/// Called on <see cref="TutorialManager.RunTutorial"/> and <see cref="IntroCutscene.CoBegin"/>/<see cref="IntroCutscene.OnDestroy"/>.
|
||||
/// </summary>
|
||||
public static void OnGameStart()
|
||||
{
|
||||
foreach (var ability in TargetedButtons.Where(x => x.UsesMode == MeetingButtonUsesMode.PerGame))
|
||||
@@ -69,7 +70,7 @@ public static class MeetingButtonManager
|
||||
public static void OnMeetingStart(MeetingHud meetingHud)
|
||||
{
|
||||
// Untargeted buttons parent.
|
||||
actionButtonsParent = new GameObject("ActionsButtonParent").AddComponent<CenteredGridArrange>();
|
||||
var actionButtonsParent = new GameObject("ActionsButtonParent").AddComponent<CenteredGridArrange>();
|
||||
actionButtonsParent.transform.SetParent(meetingHud.MeetingAbilityButton.transform.parent, meetingHud.MeetingAbilityButton.transform.parent);
|
||||
actionButtonsParent.CellSize = new Vector2(0.7f, 0.7f);
|
||||
actionButtonsParent.transform.localPosition = new Vector3(0, -2.1f, -10);
|
||||
@@ -104,7 +105,7 @@ public static class MeetingButtonManager
|
||||
btn2.transform.SetParent(meetingHud.SkipVoteButton.Buttons.transform);
|
||||
|
||||
if (ability.UsesMode == MeetingButtonUsesMode.PerMeeting) ability.UsesLeft = ability.MaxUses;
|
||||
if (ability is MultiTargetMeetingButton multiAbility) multiAbility.Targets = new();
|
||||
if (ability is MultiTargetMeetingButton multiAbility) multiAbility.Targets = [];
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
|
||||
@@ -1,7 +1,17 @@
|
||||
namespace MiraAPI.MeetingAbilities;
|
||||
|
||||
/// <summary>
|
||||
/// The use mode of the meeting button.
|
||||
/// </summary>
|
||||
public enum MeetingButtonUsesMode
|
||||
{
|
||||
/// <summary>
|
||||
/// Sets the uses to be limited per game.
|
||||
/// </summary>
|
||||
PerGame,
|
||||
PerMeeting
|
||||
|
||||
/// <summary>
|
||||
/// Sets the uses to be limited per meeting.
|
||||
/// </summary>
|
||||
PerMeeting,
|
||||
}
|
||||
@@ -7,12 +7,12 @@ using UnityEngine.UI;
|
||||
namespace MiraAPI.MeetingAbilities;
|
||||
|
||||
/// <summary>
|
||||
/// Abstract class for creating multi target meeting abilities
|
||||
/// Abstract class for creating multi target meeting abilities.
|
||||
/// </summary>
|
||||
public abstract class MultiTargetMeetingButton : TargetedMeetingButton
|
||||
{
|
||||
/// <summary>
|
||||
/// The <see cref="LoadableAsset{Sprite}"/> used for when the button is on.
|
||||
/// Gets he <see cref="LoadableAsset{Sprite}"/> used for when the button is on.
|
||||
/// </summary>
|
||||
public abstract LoadableAsset<Sprite> SpriteActive { get; }
|
||||
|
||||
@@ -24,7 +24,7 @@ public abstract class MultiTargetMeetingButton : TargetedMeetingButton
|
||||
/// <summary>
|
||||
/// Gets or sets all selected targets.
|
||||
/// </summary>
|
||||
public Dictionary<PlayerVoteArea, MeetingAbilityBehaviour> Targets { get; set; } = new();
|
||||
public Dictionary<PlayerVoteArea, MeetingAbilityBehaviour> Targets { get; set; } = [];
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void ClickHandler(MeetingAbilityBehaviour button, PlayerVoteArea playerVoteArea)
|
||||
@@ -56,7 +56,7 @@ public abstract class MultiTargetMeetingButton : TargetedMeetingButton
|
||||
Timer = Cooldown;
|
||||
UsesLeft -= 1;
|
||||
OnFinish();
|
||||
Targets = new();
|
||||
Targets = [];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -83,7 +83,7 @@ public abstract class MultiTargetMeetingButton : TargetedMeetingButton
|
||||
/// <inheritdoc />
|
||||
public override MeetingAbilityBehaviour CreateButton(PlayerVoteArea playerVoteArea)
|
||||
{
|
||||
Targets = new();
|
||||
Targets = [];
|
||||
var button = base.CreateButton(playerVoteArea);
|
||||
button.Button.OnClick = new Button.ButtonClickedEvent();
|
||||
button.Button.OnClick.AddListener(new System.Action(() => { ClickHandler(button, playerVoteArea); }));
|
||||
|
||||
@@ -17,5 +17,4 @@
|
||||
</ItemGroup>
|
||||
|
||||
<Import Project="../AmongUs.props" />
|
||||
|
||||
</Project>
|
||||
@@ -27,12 +27,6 @@ namespace MiraAPI;
|
||||
[ReactorModFlags(ModFlags.RequireOnAllClients)]
|
||||
public partial class MiraApiPlugin : BasePlugin, IMiraPlugin
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public ConfigFile GetConfigFile()
|
||||
{
|
||||
return Config;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the specified Culture for string manipulations.
|
||||
/// </summary>
|
||||
@@ -86,4 +80,10 @@ public partial class MiraApiPlugin : BasePlugin, IMiraPlugin
|
||||
ModCompatibility
|
||||
.Initialize; // Initialise AFTER the mods are loaded to ensure maximum parity (no need for the soft dependency either then)
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public ConfigFile GetConfigFile()
|
||||
{
|
||||
return Config;
|
||||
}
|
||||
}
|
||||
@@ -84,8 +84,10 @@ public class MiraApiSettings(ConfigFile config) : LocalSettingsTab(config)
|
||||
{
|
||||
var topUi = MiraHudHelper.UiTopRight;
|
||||
var extraTopUi = MiraHudHelper.ExtraUiTopRight;
|
||||
if (topUi && extraTopUi)
|
||||
{
|
||||
|
||||
if (!topUi || !extraTopUi)
|
||||
return;
|
||||
|
||||
var genericEvent = new UiButtonResetEvent();
|
||||
MiraEventManager.InvokeEvent(genericEvent);
|
||||
|
||||
@@ -94,7 +96,6 @@ public class MiraApiSettings(ConfigFile config) : LocalSettingsTab(config)
|
||||
MiraHudHelper.UiGrid.ArrangeChilds();
|
||||
MiraHudHelper.ExtraUiGrid.ArrangeChilds();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resizes the UI as a coroutine.
|
||||
|
||||
@@ -14,26 +14,44 @@ public static class ModCompatibility
|
||||
/// </summary>
|
||||
public const string SubmergedId = "Submerged";
|
||||
|
||||
/// <summary>
|
||||
/// Gets the <see cref="Version"/> of the Submerged mod.
|
||||
/// </summary>
|
||||
public static Version SubVersion { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether Submerged is loaded.
|
||||
/// </summary>
|
||||
public static bool SubLoaded { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the <see cref="BasePlugin"/> of the Submerged mod.
|
||||
/// </summary>
|
||||
public static BasePlugin SubPlugin { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the <see cref="Assembly"/> of the Submerged mod.
|
||||
/// </summary>
|
||||
public static Assembly SubAssembly { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// The map ID of Submerged.
|
||||
/// </summary>
|
||||
public const ShipStatus.MapType SubmergedMapType = (ShipStatus.MapType)6;
|
||||
|
||||
public static void Initialize()
|
||||
internal static void Initialize()
|
||||
{
|
||||
InitSubmerged();
|
||||
}
|
||||
|
||||
public static void InitSubmerged()
|
||||
internal static void InitSubmerged()
|
||||
{
|
||||
if (!IL2CPPChainloader.Instance.Plugins.TryGetValue(SubmergedId, out var plugin))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
SubPlugin = (plugin!.Instance as BasePlugin)!;
|
||||
SubPlugin = (plugin.Instance as BasePlugin)!;
|
||||
SubVersion = plugin.Metadata.Version;
|
||||
|
||||
SubAssembly = SubPlugin.GetType().Assembly;
|
||||
@@ -42,6 +60,10 @@ public static class ModCompatibility
|
||||
Message("Submerged was detected");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks to see if the current map is the Submerged map.
|
||||
/// </summary>
|
||||
/// <returns>true if the current map is Submerged.</returns>
|
||||
public static bool IsSubmerged()
|
||||
{
|
||||
return SubLoaded && ShipStatus.Instance && ShipStatus.Instance.Type == SubmergedMapType;
|
||||
|
||||
@@ -4,8 +4,8 @@ using System.Linq;
|
||||
using System.Runtime.Serialization;
|
||||
using MiraAPI.Modifiers.Types;
|
||||
using MiraAPI.PluginLoading;
|
||||
using MiraAPI.Translation;
|
||||
using MiraAPI.Roles;
|
||||
using MiraAPI.Translation;
|
||||
using MiraAPI.Utilities;
|
||||
using Reactor.Utilities.Extensions;
|
||||
using Random = System.Random;
|
||||
|
||||
@@ -50,7 +50,7 @@ public static class HudManagerFlashPatches
|
||||
hudManager.FullScreen.gameObject.SetActive(settings.EnableSabotageFlashes.Value && !hudManager.FullScreen.gameObject.activeSelf);
|
||||
if (settings.EnableSabotageBlares.Value)
|
||||
{
|
||||
SoundManager.Instance.PlaySound(ShipStatus.Instance.SabotageSound, false, 1f, null);
|
||||
SoundManager.Instance.PlaySound(ShipStatus.Instance.SabotageSound, false);
|
||||
}
|
||||
light = !light;
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
namespace MiraAPI.Patches;
|
||||
/*namespace MiraAPI.Patches;
|
||||
|
||||
/*[HarmonyPatch(typeof(DetectiveNotesMinigame), nameof(DetectiveNotesMinigame.SetImpostorPopup))]
|
||||
[HarmonyPatch(typeof(DetectiveNotesMinigame), nameof(DetectiveNotesMinigame.SetImpostorPopup))]
|
||||
public static class DetectiveNotesMinigamePatch
|
||||
{
|
||||
public static void Prefix(DetectiveNotesMinigame __instance, bool active)
|
||||
|
||||
@@ -310,16 +310,12 @@ public static class TaskAdderPatches
|
||||
switch (task.TaskType)
|
||||
{
|
||||
case TaskTypes.DivertPower:
|
||||
#pragma warning disable IDE0055 // Fix formatting
|
||||
{
|
||||
var targetSystem = task.Cast<DivertPowerTask>().TargetSystem;
|
||||
taskAddButton.Text.text = TranslationController.Instance.GetString(
|
||||
StringNames.DivertPowerTo,
|
||||
TranslationController.Instance.GetString(targetSystem));
|
||||
break;
|
||||
}
|
||||
case TaskTypes.FixWeatherNode:
|
||||
{
|
||||
var nodeId = task.Cast<WeatherNodeTask>().NodeId;
|
||||
taskAddButton.Text.text =
|
||||
TranslationController.Instance.GetString(
|
||||
@@ -327,20 +323,16 @@ public static class TaskAdderPatches
|
||||
TranslationController.Instance.GetString(
|
||||
WeatherSwitchGame.ControlNames[nodeId]);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
taskAddButton.Text.text =
|
||||
TranslationController.Instance.GetString(task.TaskType);
|
||||
break;
|
||||
}
|
||||
#pragma warning restore IDE0055 // Fix formatting
|
||||
}
|
||||
|
||||
__instance.AddFileAsChildCustom(taskAddButton, ref num, ref num2, ref num3);
|
||||
if (taskAddButton != null && taskAddButton.Button != null)
|
||||
{
|
||||
ControllerManager.Instance.AddSelectableUiElement(taskAddButton.Button, false);
|
||||
ControllerManager.Instance.AddSelectableUiElement(taskAddButton.Button);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@ internal static class ConsolePatches
|
||||
}
|
||||
|
||||
[HarmonyPrefix, HarmonyPatch(typeof(SystemConsole), nameof(SystemConsole.CanUse))]
|
||||
public static bool SystemCanUsePatch(SystemConsole __instance, [HarmonyArgument(0)] NetworkedPlayerInfo pc, [HarmonyArgument(1)] out bool canUse, [HarmonyArgument(2)] out bool couldUse)
|
||||
public static bool SystemCanUsePatch(SystemConsole __instance, [HarmonyArgument(1)] out bool canUse, [HarmonyArgument(2)] out bool couldUse)
|
||||
{
|
||||
if (AmongUsClient.Instance.GameState == InnerNetClient.GameStates.Started && ShipStatus.Instance)
|
||||
{
|
||||
@@ -55,7 +55,7 @@ internal static class ConsolePatches
|
||||
}
|
||||
|
||||
[HarmonyPrefix, HarmonyPatch(typeof(MapConsole), nameof(MapConsole.CanUse))]
|
||||
public static bool MapCanUsePatch(MapConsole __instance, [HarmonyArgument(0)] NetworkedPlayerInfo pc, [HarmonyArgument(1)] out bool canUse, [HarmonyArgument(2)] out bool couldUse)
|
||||
public static bool MapCanUsePatch(MapConsole __instance, [HarmonyArgument(1)] out bool canUse, [HarmonyArgument(2)] out bool couldUse)
|
||||
{
|
||||
if (AmongUsClient.Instance.GameState == InnerNetClient.GameStates.Started && ShipStatus.Instance)
|
||||
{
|
||||
@@ -76,36 +76,21 @@ internal static class ConsolePatches
|
||||
[HarmonyPrefix, HarmonyPatch(typeof(MapConsole), nameof(MapConsole.Use))]
|
||||
public static bool MapUsePatch(MapConsole __instance)
|
||||
{
|
||||
if (AmongUsClient.Instance.GameState == InnerNetClient.GameStates.Started && ShipStatus.Instance)
|
||||
{
|
||||
return CustomGameModeManager.ActiveMode == null ||
|
||||
return AmongUsClient.Instance.GameState != InnerNetClient.GameStates.Started || !ShipStatus.Instance || CustomGameModeManager.ActiveMode == null ||
|
||||
CustomGameModeManager.ActiveMode.CanUseMapConsole(__instance);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
[HarmonyPrefix, HarmonyPatch(typeof(SystemConsole), nameof(SystemConsole.Use))]
|
||||
public static bool SystemUsePatch(SystemConsole __instance)
|
||||
{
|
||||
if (AmongUsClient.Instance.GameState == InnerNetClient.GameStates.Started && ShipStatus.Instance)
|
||||
{
|
||||
return CustomGameModeManager.ActiveMode == null ||
|
||||
return AmongUsClient.Instance.GameState != InnerNetClient.GameStates.Started || !ShipStatus.Instance || CustomGameModeManager.ActiveMode == null ||
|
||||
CustomGameModeManager.ActiveMode.CanUseSystemConsole(__instance);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
[HarmonyPrefix, HarmonyPatch(typeof(Console), nameof(Console.Use))]
|
||||
public static bool ConsoleUsePatch(Console __instance)
|
||||
{
|
||||
if (AmongUsClient.Instance.GameState == InnerNetClient.GameStates.Started && ShipStatus.Instance)
|
||||
{
|
||||
return CustomGameModeManager.ActiveMode == null ||
|
||||
return AmongUsClient.Instance.GameState != InnerNetClient.GameStates.Started || !ShipStatus.Instance || CustomGameModeManager.ActiveMode == null ||
|
||||
CustomGameModeManager.ActiveMode.CanUseTasks(__instance);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -9,22 +9,22 @@ internal static class GameLogicPatches
|
||||
[HarmonyPrefix, HarmonyPatch(typeof(GameManager), nameof(GameManager.DidHumansWin))]
|
||||
public static bool DidHumansWin(GameOverReason reason, ref bool __result)
|
||||
{
|
||||
__result = reason == GameOverReason.CrewmatesByTask || reason == GameOverReason.CrewmatesByVote ||
|
||||
reason == GameOverReason.ImpostorDisconnect || reason == GameOverReason.HideAndSeek_CrewmatesByTimer;
|
||||
__result = reason is GameOverReason.CrewmatesByTask or GameOverReason.CrewmatesByVote or
|
||||
GameOverReason.ImpostorDisconnect or GameOverReason.HideAndSeek_CrewmatesByTimer;
|
||||
return false;
|
||||
}
|
||||
|
||||
[HarmonyPrefix, HarmonyPatch(typeof(GameManager), nameof(GameManager.DidImpostorsWin))]
|
||||
public static bool DidImpostorsWin(GameOverReason reason, ref bool __result)
|
||||
{
|
||||
__result = reason == GameOverReason.ImpostorsByKill || reason == GameOverReason.ImpostorsBySabotage ||
|
||||
reason == GameOverReason.ImpostorsByVote || reason == GameOverReason.HideAndSeek_ImpostorsByKills ||
|
||||
reason == GameOverReason.CrewmateDisconnect;
|
||||
__result = reason is GameOverReason.ImpostorsByKill or GameOverReason.ImpostorsBySabotage or
|
||||
GameOverReason.ImpostorsByVote or GameOverReason.HideAndSeek_ImpostorsByKills or
|
||||
GameOverReason.CrewmateDisconnect;
|
||||
return false;
|
||||
}
|
||||
|
||||
[HarmonyPrefix, HarmonyPatch(typeof(NormalGameManager), nameof(NormalGameManager.GetBodyType))]
|
||||
public static bool BodyTypePatch(NormalGameManager __instance, PlayerControl player, ref PlayerBodyTypes __result)
|
||||
public static bool BodyTypePatch(PlayerControl player, ref PlayerBodyTypes __result)
|
||||
{
|
||||
if (CustomGameModeManager.ActiveMode == null || !CustomGameModeManager.ActiveMode.GameModeBodyTypeOverride)
|
||||
{
|
||||
@@ -68,7 +68,7 @@ internal static class GameLogicPatches
|
||||
|
||||
[HarmonyPostfix]
|
||||
[HarmonyPatch(typeof(LogicGameFlowNormal), nameof(LogicGameFlowNormal.IsGameOverDueToDeath))]
|
||||
public static void IsGameOverDueToDeathPatch(LogicGameFlowNormal __instance, ref bool __result)
|
||||
public static void IsGameOverDueToDeathPatch(ref bool __result)
|
||||
{
|
||||
if (CustomGameModeManager.IsActiveGameMode<HideAndSeekMode>())
|
||||
{
|
||||
|
||||
@@ -23,7 +23,6 @@ internal static class HudPatches
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[HarmonyPatch(typeof(HudManager), nameof(HudManager.Start))]
|
||||
[HarmonyPostfix]
|
||||
public static void PostHudStart(HudManager __instance)
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
using MiraAPI.GameModes;
|
||||
|
||||
namespace MiraAPI.Patches.GameModes;
|
||||
|
||||
[HarmonyPatch(typeof(ProgressTracker), nameof(ProgressTracker.Start))]
|
||||
internal static class ProgressTrackerPatch
|
||||
{
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
using MiraAPI.GameModes;
|
||||
|
||||
namespace MiraAPI.Patches.GameModes;
|
||||
|
||||
[HarmonyPatch(typeof(TaskPanelBehaviour), nameof(TaskPanelBehaviour.Update))]
|
||||
internal static class TaskPanelPatch
|
||||
{
|
||||
|
||||
@@ -112,16 +112,13 @@ public static class HudManagerPatches
|
||||
}
|
||||
catch
|
||||
{
|
||||
#pragma warning disable S125 // Sections of code should not be commented out
|
||||
// Error($"Error arranging child objects in GridArrange: {e}");
|
||||
#pragma warning restore S125 // Sections of code should not be commented out
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#pragma warning disable S125 // Sections of code should not be commented out
|
||||
/*
|
||||
/// <summary>
|
||||
/// Trigger HudStart on current custom gamemode
|
||||
@@ -133,7 +130,6 @@ public static class HudManagerPatches
|
||||
CustomGameModeManager.ActiveMode?.HudStart(__instance);
|
||||
}
|
||||
*/
|
||||
#pragma warning restore S125 // Sections of code should not be commented out
|
||||
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPriority(Priority.First)]
|
||||
@@ -371,10 +367,7 @@ public static class HudManagerPatches
|
||||
}
|
||||
}
|
||||
|
||||
// suppressed warning because we want minimum allocations here
|
||||
#pragma warning disable S3267
|
||||
foreach (var entry in KeybindManager.VanillaKeybinds.Values)
|
||||
#pragma warning restore S3267
|
||||
{
|
||||
if (player.GetButtonDown(entry.Id))
|
||||
{
|
||||
|
||||
@@ -3,8 +3,8 @@ using HarmonyLib;
|
||||
using Il2CppInterop.Runtime.InteropTypes;
|
||||
using MiraAPI.Events;
|
||||
using MiraAPI.Events.Vanilla.Gameplay;
|
||||
using MiraAPI.MeetingAbilities;
|
||||
using MiraAPI.GameModes;
|
||||
using MiraAPI.MeetingAbilities;
|
||||
using MiraAPI.Roles;
|
||||
using MiraAPI.Translation;
|
||||
using MiraAPI.Utilities;
|
||||
|
||||
@@ -25,12 +25,12 @@ namespace MiraAPI.Patches.Options;
|
||||
[HarmonyPatch(typeof(GameOptionsMenu))]
|
||||
internal static class GameOptionsMenuPatch
|
||||
{
|
||||
private static List<CategoryHeaderMasked> _vanillaHeaders = new();
|
||||
private static List<OptionBehaviour> _vanillaOptions = new();
|
||||
private static List<OptionBehaviour> _mainOptions = new();
|
||||
private static System.Collections.Generic.Dictionary<AbstractGameMode, System.Collections.Generic.List<AbstractOptionGroup>> _gameModeGroups = new();
|
||||
private static System.Collections.Generic.Dictionary<AbstractGameMode, System.Collections.Generic.List<OptionBehaviour>> _gameModeOptions = new();
|
||||
private static System.Collections.Generic.Dictionary<AbstractGameMode, System.Collections.Generic.List<CategoryHeaderMasked>> _gameModeHeaders = new();
|
||||
private static readonly List<CategoryHeaderMasked> _vanillaHeaders = new();
|
||||
private static readonly List<OptionBehaviour> _vanillaOptions = new();
|
||||
private static readonly List<OptionBehaviour> _mainOptions = new();
|
||||
private static readonly System.Collections.Generic.Dictionary<AbstractGameMode, System.Collections.Generic.List<AbstractOptionGroup>> _gameModeGroups = [];
|
||||
private static readonly System.Collections.Generic.Dictionary<AbstractGameMode, System.Collections.Generic.List<OptionBehaviour>> _gameModeOptions = [];
|
||||
private static readonly System.Collections.Generic.Dictionary<AbstractGameMode, System.Collections.Generic.List<CategoryHeaderMasked>> _gameModeHeaders = [];
|
||||
private static TextMeshPro _gamemodeDescription = null!;
|
||||
private static SpriteRenderer _modIcon = null!;
|
||||
|
||||
@@ -77,7 +77,8 @@ internal static class GameOptionsMenuPatch
|
||||
return false;
|
||||
}
|
||||
|
||||
public static float AdditionalVanillaScrollNum;
|
||||
private static float additionalVanillaScrollNum;
|
||||
|
||||
internal static void ToggleGamemodeOptions(AbstractGameMode gameMode, GameOptionsMenu instance)
|
||||
{
|
||||
float num = -1.217f;
|
||||
@@ -185,7 +186,6 @@ internal static class GameOptionsMenuPatch
|
||||
instance.scrollBar.SetYBoundsMax(-num - 1.65f);
|
||||
}
|
||||
|
||||
|
||||
private static void CreateSettings(GameOptionsMenu instance, Transform container)
|
||||
{
|
||||
float num = 0.713f;
|
||||
@@ -200,21 +200,17 @@ internal static class GameOptionsMenuPatch
|
||||
gmCategory.SetHeader(GameModeOption.CustomName, 20);
|
||||
gmCategory.transform.localScale = Vector3.one * 0.63f;
|
||||
gmCategory.transform.localPosition = new Vector3(-0.903f, num, -2f);
|
||||
GameModeOption.OptionBehaviour = Object.Instantiate(
|
||||
instance.stringOptionOrigin,
|
||||
Vector3.zero,
|
||||
Quaternion.identity,
|
||||
container);
|
||||
GameModeOption.OptionBehaviour = Object.Instantiate(instance.stringOptionOrigin, container);
|
||||
num -= 0.63f;
|
||||
GameModeOption.OptionBehaviour.transform.localPosition = new Vector3(0.952f, num, -2f);
|
||||
GameModeOption.OptionBehaviour.SetClickMask(instance.ButtonClickMask);
|
||||
StringGameSetting setting = ScriptableObject.CreateInstance<StringGameSetting>();
|
||||
setting.Type = OptionTypes.MultipleChoice;
|
||||
setting.Title = GameModeOption.GamemodeName;
|
||||
setting.Index = GameModeOption._lastValue;
|
||||
setting.Index = GameModeOption.LastValue;
|
||||
setting.Values = new Il2CppStructArray<StringNames>([GameModeOption.Values[0]]);
|
||||
GameModeOption.OptionBehaviour.SetUpFromData(setting, 20);
|
||||
GameModeOption.Set(GameModeOption._lastValue);
|
||||
GameModeOption.Set(GameModeOption.LastValue);
|
||||
GameModeOption.OptionBehaviour.TitleText.fontSize = 3;
|
||||
instance.Children.Add(GameModeOption.OptionBehaviour);
|
||||
foreach (var optionBehaviour in instance.Children)
|
||||
@@ -267,81 +263,47 @@ internal static class GameOptionsMenuPatch
|
||||
_gamemodeDescription.alignment = TextAlignmentOptions.Left;
|
||||
|
||||
num -= 1.3f;
|
||||
AdditionalVanillaScrollNum = 0f;
|
||||
additionalVanillaScrollNum = 0f;
|
||||
foreach (RulesCategory rulesCategory in GameManager.Instance.GameSettingsList.AllCategories)
|
||||
{
|
||||
CategoryHeaderMasked categoryHeaderMasked = Object.Instantiate<CategoryHeaderMasked>(
|
||||
instance.categoryHeaderOrigin,
|
||||
Vector3.zero,
|
||||
Quaternion.identity,
|
||||
container);
|
||||
var categoryHeaderMasked = Object.Instantiate(instance.categoryHeaderOrigin, container);
|
||||
categoryHeaderMasked.SetHeader(rulesCategory.CategoryName, 20);
|
||||
categoryHeaderMasked.transform.localScale = Vector3.one * 0.63f;
|
||||
categoryHeaderMasked.transform.localPosition = new Vector3(-0.903f, num, -2f);
|
||||
_vanillaHeaders.Add(categoryHeaderMasked);
|
||||
num -= 0.63f;
|
||||
AdditionalVanillaScrollNum -= 0.63f;
|
||||
additionalVanillaScrollNum -= 0.63f;
|
||||
foreach (BaseGameSetting baseGameSetting in rulesCategory.AllGameSettings)
|
||||
{
|
||||
OptionBehaviour? optionBehaviour = null;
|
||||
|
||||
switch (baseGameSetting.Type)
|
||||
{
|
||||
case OptionTypes.Checkbox:
|
||||
{
|
||||
OptionBehaviour optionBehaviour = Object.Instantiate<ToggleOption>(
|
||||
instance.checkboxOrigin,
|
||||
Vector3.zero,
|
||||
Quaternion.identity,
|
||||
container);
|
||||
optionBehaviour.transform.localPosition = new Vector3(0.952f, num, -2f);
|
||||
optionBehaviour.SetClickMask(instance.ButtonClickMask);
|
||||
optionBehaviour.SetUpFromData(baseGameSetting, 20);
|
||||
_vanillaOptions.Add(optionBehaviour);
|
||||
optionBehaviour = Object.Instantiate(instance.checkboxOrigin, container);
|
||||
break;
|
||||
}
|
||||
case OptionTypes.String:
|
||||
{
|
||||
OptionBehaviour optionBehaviour = Object.Instantiate<StringOption>(
|
||||
instance.stringOptionOrigin,
|
||||
Vector3.zero,
|
||||
Quaternion.identity,
|
||||
container);
|
||||
optionBehaviour.transform.localPosition = new Vector3(0.952f, num, -2f);
|
||||
optionBehaviour.SetClickMask(instance.ButtonClickMask);
|
||||
optionBehaviour.SetUpFromData(baseGameSetting, 20);
|
||||
_vanillaOptions.Add(optionBehaviour);
|
||||
optionBehaviour = Object.Instantiate(instance.stringOptionOrigin, container);
|
||||
break;
|
||||
}
|
||||
case OptionTypes.Float:
|
||||
case OptionTypes.Int:
|
||||
{
|
||||
OptionBehaviour optionBehaviour = Object.Instantiate<NumberOption>(
|
||||
instance.numberOptionOrigin,
|
||||
Vector3.zero,
|
||||
Quaternion.identity,
|
||||
container);
|
||||
optionBehaviour.transform.localPosition = new Vector3(0.952f, num, -2f);
|
||||
optionBehaviour.SetClickMask(instance.ButtonClickMask);
|
||||
optionBehaviour.SetUpFromData(baseGameSetting, 20);
|
||||
_vanillaOptions.Add(optionBehaviour);
|
||||
optionBehaviour = Object.Instantiate(instance.numberOptionOrigin, container);
|
||||
break;
|
||||
}
|
||||
case OptionTypes.Player:
|
||||
{
|
||||
OptionBehaviour optionBehaviour = Object.Instantiate<PlayerOption>(
|
||||
instance.playerOptionOrigin,
|
||||
Vector3.zero,
|
||||
Quaternion.identity,
|
||||
container);
|
||||
optionBehaviour.transform.localPosition = new Vector3(0.952f, num, -2f);
|
||||
optionBehaviour.SetClickMask(instance.ButtonClickMask);
|
||||
optionBehaviour.SetUpFromData(baseGameSetting, 20);
|
||||
_vanillaOptions.Add(optionBehaviour);
|
||||
optionBehaviour = Object.Instantiate(instance.playerOptionOrigin, container);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!optionBehaviour)
|
||||
continue;
|
||||
|
||||
optionBehaviour!.transform.localPosition = new Vector3(0.952f, num, -2f);
|
||||
optionBehaviour.SetClickMask(instance.ButtonClickMask);
|
||||
optionBehaviour.SetUpFromData(baseGameSetting, 20);
|
||||
_vanillaOptions.Add(optionBehaviour);
|
||||
|
||||
num -= 0.45f;
|
||||
AdditionalVanillaScrollNum -= 0.45f;
|
||||
additionalVanillaScrollNum -= 0.45f;
|
||||
}
|
||||
}
|
||||
foreach (var optionBehaviour in _vanillaOptions)
|
||||
@@ -363,11 +325,11 @@ internal static class GameOptionsMenuPatch
|
||||
var filteredGroups =
|
||||
ModdedOptionsManager.GameModeOptionGroups
|
||||
.Where(x => x.Key == mode.GetType()).Select(y => y.Value).SelectMany(y => y) ?? [];
|
||||
_gameModeGroups.Add(mode, filteredGroups.ToList());
|
||||
_gameModeGroups.Add(mode, [.. filteredGroups]);
|
||||
|
||||
var optionBehaviours = new System.Collections.Generic.List<OptionBehaviour>();
|
||||
var categoryHeaders = new System.Collections.Generic.List<CategoryHeaderMasked>();
|
||||
var newNum = mode.ShowNormalGameSettings ? num : num - AdditionalVanillaScrollNum;
|
||||
var newNum = mode.ShowNormalGameSettings ? num : num - additionalVanillaScrollNum;
|
||||
foreach (var group in filteredGroups)
|
||||
{
|
||||
CreateGroup(instance, group, container, ref newNum, ref optionBehaviours, ref categoryHeaders);
|
||||
@@ -550,7 +512,7 @@ internal static class GameOptionsMenuPatch
|
||||
foreach (var option in group.Options)
|
||||
{
|
||||
if (option.OptionBehaviour != null && option.OptionBehaviour.gameObject != null)
|
||||
option.OptionBehaviour?.gameObject.SetActive(false);
|
||||
option.OptionBehaviour.gameObject.SetActive(false);
|
||||
}
|
||||
|
||||
return;
|
||||
@@ -601,7 +563,7 @@ internal static class GameOptionsMenuPatch
|
||||
|
||||
if (mode.ShowNormalGameSettings)
|
||||
{
|
||||
num += AdditionalVanillaScrollNum;
|
||||
num += additionalVanillaScrollNum;
|
||||
}
|
||||
|
||||
if (!_gameModeGroups.TryGetValue(mode, out var groups) || groups.Count == 0)
|
||||
|
||||
@@ -35,12 +35,7 @@ public static class LobbyViewPanePatches
|
||||
|
||||
private static AbstractGameMode? GetCustomGamemode()
|
||||
{
|
||||
if (!CustomGameModeManager.IsClassic() && !CustomGameModeManager.IsHideNSeek())
|
||||
{
|
||||
return CustomGameModeManager.ActiveMode;
|
||||
}
|
||||
|
||||
return null;
|
||||
return !CustomGameModeManager.IsClassic() && !CustomGameModeManager.IsHideNSeek() ? CustomGameModeManager.ActiveMode : null;
|
||||
}
|
||||
|
||||
private static IEnumerable<AbstractOptionGroup>? GetCustomGamemodeOptions()
|
||||
|
||||
@@ -7,8 +7,8 @@ using MiraAPI.GameOptions;
|
||||
using MiraAPI.Modifiers;
|
||||
using MiraAPI.PluginLoading;
|
||||
using MiraAPI.Presets;
|
||||
using MiraAPI.Translation;
|
||||
using MiraAPI.Roles;
|
||||
using MiraAPI.Translation;
|
||||
using MiraAPI.Utilities.Assets;
|
||||
using Reactor.Utilities.Attributes;
|
||||
using Reactor.Utilities.Extensions;
|
||||
|
||||
@@ -117,15 +117,15 @@ public static class RoleGuidePatches
|
||||
ControllerManager instance = ControllerManager.Instance;
|
||||
ControllerUiElementsState currentUiState = ControllerManager.Instance.CurrentUiState;
|
||||
Il2CppSystem.Collections.Generic.List<UiElement> controllerSelectable = __instance.ControllerSelectable;
|
||||
instance.SetUpSelectables(currentUiState, controllerSelectable[controllerSelectable.Count - 1], __instance.ControllerSelectable);
|
||||
instance.SetUpSelectables(currentUiState, controllerSelectable[^1], __instance.ControllerSelectable);
|
||||
ControllerManager instance2 = ControllerManager.Instance;
|
||||
Il2CppSystem.Collections.Generic.List<UiElement> controllerSelectable2 = __instance.ControllerSelectable;
|
||||
instance2.SetCurrentSelected(controllerSelectable2[controllerSelectable2.Count - 1]);
|
||||
instance2.SetCurrentSelected(controllerSelectable2[^1]);
|
||||
__instance.SetActiveTab(0);
|
||||
return false;
|
||||
}
|
||||
|
||||
private static Dictionary<RoleBehaviour, MatchInfoRolePanel> _rolePanels = [];
|
||||
private static readonly Dictionary<RoleBehaviour, MatchInfoRolePanel> _rolePanels = [];
|
||||
|
||||
public static void DisplayNormalRoleSettings(MatchInfoGuide instance, bool reset)
|
||||
{
|
||||
@@ -158,9 +158,9 @@ public static class RoleGuidePatches
|
||||
GameManager.Instance.LogicOptions.GetTaskBarMode().ToString());
|
||||
foreach (RoleBehaviour roleBehaviour in RoleManager.Instance.AllRoles)
|
||||
{
|
||||
if (roleBehaviour.Role != RoleTypes.Crewmate && roleBehaviour.Role != RoleTypes.Impostor &&
|
||||
roleBehaviour.Role is not RoleTypes.CrewmateGhost &&
|
||||
roleBehaviour.Role is not RoleTypes.ImpostorGhost)
|
||||
if (roleBehaviour.Role is not RoleTypes.Crewmate and not RoleTypes.Impostor and
|
||||
not RoleTypes.CrewmateGhost and
|
||||
not RoleTypes.ImpostorGhost)
|
||||
{
|
||||
var panel = Object.Instantiate(
|
||||
instance.MatchInfoRolePanelPrefab,
|
||||
|
||||
@@ -39,11 +39,11 @@ internal static class HowToPlayPatch
|
||||
{
|
||||
uiElement.ReceiveMouseOut();
|
||||
}
|
||||
ControllerManager.Instance.NewScene(__instance.name, __instance.closeButton, __instance.defaultButtonSelected, __instance.controllerSelectables, false);
|
||||
ControllerManager.Instance.NewScene(__instance.name, __instance.closeButton, __instance.defaultButtonSelected, __instance.controllerSelectables);
|
||||
}
|
||||
__instance.DisableAllScenes();
|
||||
__instance.roleSelectionScene.SetActive(true);
|
||||
ControllerManager.Instance.SetDefaultSelection(__instance.defaultButtonSelected, null);
|
||||
ControllerManager.Instance.SetDefaultSelection(__instance.defaultButtonSelected);
|
||||
}
|
||||
public static void OpenRolePage(HowToPlayScene instance, RoleTypes roleType)
|
||||
{
|
||||
|
||||
@@ -175,7 +175,7 @@ public static class LogicRoleSelectionHnsPatch
|
||||
RoleTypes roleType = roleList[index];
|
||||
roleList.RemoveAt(index);
|
||||
int index2 = HashRandom.FastNext(players.Count);
|
||||
players[index2].Object.RpcSetRole(roleType, false);
|
||||
players[index2].Object.RpcSetRole(roleType);
|
||||
players.RemoveAt(index2);
|
||||
rolesAssigned++;
|
||||
}
|
||||
|
||||
@@ -123,7 +123,7 @@ public static class SelectRolesPatch
|
||||
RoleTypes roleType = roleList[index];
|
||||
roleList.RemoveAt(index);
|
||||
int index2 = HashRandom.FastNext(players.Count);
|
||||
players[index2].Object.RpcSetRole(roleType, false);
|
||||
players[index2].Object.RpcSetRole(roleType);
|
||||
players.RemoveAt(index2);
|
||||
rolesAssigned++;
|
||||
}
|
||||
|
||||
@@ -31,6 +31,7 @@ public static class MinigameStubs
|
||||
[HarmonyReversePatch]
|
||||
[HarmonyPatch(typeof(Minigame), nameof(Minigame.Close), [])]
|
||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||
[SuppressMessage("Minor Code Smell", "S3878:Arrays should not be created for params parameters", Justification = "Prevents ambiguity errors.")]
|
||||
public static void Close(Minigame instance)
|
||||
{
|
||||
// nothing needed
|
||||
|
||||
@@ -15,9 +15,9 @@ public interface IMiraPlugin
|
||||
virtual bool DisplayOnOptionsMenu => true;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value for the localization id to use for anything registered under this mod.
|
||||
/// Gets the localization id to use for anything registered under this mod.
|
||||
/// </summary>
|
||||
public virtual string ParentLocaleId => GetType().Name.ToLower(CultureInfo.InvariantCulture);
|
||||
virtual string ParentLocaleId => GetType().Name.ToLower(CultureInfo.InvariantCulture);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the name to display on the options menu.
|
||||
|
||||
@@ -41,8 +41,8 @@ public sealed class MiraPluginManager
|
||||
|
||||
internal Dictionary<MiraPluginInfo, List<Type>> QueuedRoleRegistrations { get; } = [];
|
||||
internal static MiraPluginManager Instance { get; private set; } = new();
|
||||
public static ConfigFile MiraApiConfig { get; private set; } = null!;
|
||||
public static MiraPluginInfo MiraApiPluginInfo { get; private set; } = null!;
|
||||
internal static ConfigFile MiraApiConfig { get; private set; } = null!;
|
||||
internal static MiraPluginInfo MiraApiPluginInfo { get; private set; } = null!;
|
||||
|
||||
internal void Initialize(BasePlugin miraApiPlugin, IMiraPlugin apiPlugin)
|
||||
{
|
||||
@@ -222,7 +222,6 @@ public sealed class MiraPluginManager
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
if (RegisterMeetingAbility(type, info))
|
||||
{
|
||||
continue;
|
||||
|
||||
@@ -111,7 +111,6 @@ public static class PresetManager
|
||||
/// </summary>
|
||||
public static void LoadMasterPreset()
|
||||
{
|
||||
#pragma warning disable S125 // Sections of code should not be commented out
|
||||
/*foreach (var btn in plugin.InternalPresets.Select(x => x.PresetButton))
|
||||
{
|
||||
if (btn != null)
|
||||
@@ -121,7 +120,7 @@ public static class PresetManager
|
||||
}
|
||||
|
||||
plugin.InternalPresets.Clear();*/
|
||||
#pragma warning restore S125 // Sections of code should not be commented out
|
||||
|
||||
if (!Directory.Exists(PresetDirectory))
|
||||
{
|
||||
Directory.CreateDirectory(PresetDirectory);
|
||||
@@ -138,9 +137,7 @@ public static class PresetManager
|
||||
var fileName = Path.GetFileName(file);
|
||||
Info($"Loading preset file {fileName}");
|
||||
|
||||
#pragma warning disable S125 // Sections of code should not be commented out
|
||||
// var presetName = Path.GetFileNameWithoutExtension(file);
|
||||
#pragma warning restore S125 // Sections of code should not be commented out
|
||||
var presetConfig = new ConfigFile(file, false)
|
||||
{
|
||||
SaveOnConfigSet = false,
|
||||
@@ -160,9 +157,7 @@ public static class PresetManager
|
||||
|
||||
presetConfig.Save();
|
||||
|
||||
#pragma warning disable S125 // Sections of code should not be commented out
|
||||
// InternalMasterPresets.Add(new OptionPreset(presetName, plugin, presetConfig));
|
||||
#pragma warning restore S125 // Sections of code should not be commented out
|
||||
}
|
||||
MasterPresets = [.. InternalMasterPresets];
|
||||
}
|
||||
|
||||
@@ -6,25 +6,108 @@ namespace MiraAPI.Translation;
|
||||
/// </summary>
|
||||
public enum MiraLanguage
|
||||
{
|
||||
/// <summary>
|
||||
/// English.
|
||||
/// </summary>
|
||||
English,
|
||||
|
||||
/// <summary>
|
||||
/// Latam.
|
||||
/// </summary>
|
||||
Latam,
|
||||
|
||||
/// <summary>
|
||||
/// Brazilian.
|
||||
/// </summary>
|
||||
Brazilian,
|
||||
|
||||
/// <summary>
|
||||
/// Portuguese.
|
||||
/// </summary>
|
||||
Portuguese,
|
||||
|
||||
/// <summary>
|
||||
/// Korean.
|
||||
/// </summary>
|
||||
Korean,
|
||||
|
||||
/// <summary>
|
||||
/// Russian.
|
||||
/// </summary>
|
||||
Russian,
|
||||
|
||||
/// <summary>
|
||||
/// Dutch.
|
||||
/// </summary>
|
||||
Dutch,
|
||||
|
||||
/// <summary>
|
||||
/// Filipino.
|
||||
/// </summary>
|
||||
Filipino,
|
||||
|
||||
/// <summary>
|
||||
/// French.
|
||||
/// </summary>
|
||||
French,
|
||||
|
||||
/// <summary>
|
||||
/// German.
|
||||
/// </summary>
|
||||
German,
|
||||
|
||||
/// <summary>
|
||||
/// Italian.
|
||||
/// </summary>
|
||||
Italian,
|
||||
|
||||
/// <summary>
|
||||
/// Japanese.
|
||||
/// </summary>
|
||||
Japanese,
|
||||
|
||||
/// <summary>
|
||||
/// Spanish.
|
||||
/// </summary>
|
||||
Spanish,
|
||||
|
||||
/// <summary>
|
||||
/// SChinese.
|
||||
/// </summary>
|
||||
SChinese,
|
||||
|
||||
/// <summary>
|
||||
/// TChinese.
|
||||
/// </summary>
|
||||
TChinese,
|
||||
|
||||
/// <summary>
|
||||
/// Irish.
|
||||
/// </summary>
|
||||
Irish,
|
||||
|
||||
/// <summary>
|
||||
/// Polish.
|
||||
/// </summary>
|
||||
Polish,
|
||||
|
||||
/// <summary>
|
||||
/// Turkish.
|
||||
/// </summary>
|
||||
Turkish,
|
||||
|
||||
/// <summary>
|
||||
/// Swedish.
|
||||
/// </summary>
|
||||
Swedish,
|
||||
|
||||
/// <summary>
|
||||
/// Lithuanian.
|
||||
/// </summary>
|
||||
Lithuanian,
|
||||
|
||||
/// <summary>
|
||||
/// Czech.
|
||||
/// </summary>
|
||||
Czech,
|
||||
}
|
||||
@@ -5,23 +5,39 @@ using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Xml;
|
||||
using MiraAPI.Utilities;
|
||||
using MonoMod.Utils;
|
||||
using Reactor.Localization.Utilities;
|
||||
using UnityEngine;
|
||||
|
||||
namespace MiraAPI.Translation;
|
||||
|
||||
/// <summary>
|
||||
/// The locale manager to handle translations and more.
|
||||
/// </summary>
|
||||
public static class MiraLocaleManager
|
||||
{
|
||||
private const string LangDirectory = "mira_languages";
|
||||
|
||||
// Language, Xml Name, then Value
|
||||
|
||||
/// <summary>
|
||||
/// Gets the dictionary containing all loaded localization strings, organized by language and XML name.
|
||||
/// </summary>
|
||||
public static Dictionary<MiraLanguage, Dictionary<string, string>> Locale { get; } = [];
|
||||
|
||||
/// <summary>
|
||||
/// Gets the list of mod GUIDs that have been registered with the localization manager.
|
||||
/// </summary>
|
||||
public static readonly List<string> RegisteredModIds = [];
|
||||
|
||||
/// <summary>
|
||||
/// Gets a dictionary mapping registered string keys to their corresponding <see cref="StringNames"/> enum values.
|
||||
/// </summary>
|
||||
public static readonly Dictionary<string, StringNames> RegisteredStringNames = [];
|
||||
internal static readonly Dictionary<StringNames, string> StringNamesLookup = [];
|
||||
|
||||
/// <summary>
|
||||
/// Gets a dictionary mapping <see cref="MiraLanguage"/> values to their standard language codes.
|
||||
/// </summary>
|
||||
public static Dictionary<MiraLanguage, string> LangList { get; } = new()
|
||||
{
|
||||
{ MiraLanguage.English, "en_US" },
|
||||
@@ -46,6 +62,10 @@ public static class MiraLocaleManager
|
||||
{ MiraLanguage.Lithuanian, "lt_LT" }, // Custom
|
||||
{ MiraLanguage.Czech, "cs_CZ" }, // Custom
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Gets a dictionary mapping <see cref="MiraLanguage"/> values to their standard language codes.
|
||||
/// </summary>
|
||||
public static Dictionary<MiraLanguage, string> LangCultureList { get; } = new()
|
||||
{
|
||||
{ MiraLanguage.English, "en-US" },
|
||||
@@ -135,19 +155,13 @@ public static class MiraLocaleManager
|
||||
/// <returns>A <see cref="string"/> based on the key provided.</returns>
|
||||
public static string Get(MiraLanguage language, string key, string fallback = "")
|
||||
{
|
||||
if (Locale.TryGetValue(language, out var translations) &&
|
||||
translations.TryGetValue(key, out var translation))
|
||||
{
|
||||
return translation;
|
||||
}
|
||||
|
||||
if (Locale.TryGetValue(MiraLanguage.English, out var translationsEng) &&
|
||||
translationsEng.TryGetValue(key, out var translationEng))
|
||||
{
|
||||
return translationEng;
|
||||
}
|
||||
|
||||
return fallback;
|
||||
return Locale.TryGetValue(language, out var translations) &&
|
||||
translations.TryGetValue(key, out var translation)
|
||||
? translation
|
||||
: Locale.TryGetValue(MiraLanguage.English, out var translationsEng) &&
|
||||
translationsEng.TryGetValue(key, out var translationEng)
|
||||
? translationEng
|
||||
: fallback;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -202,11 +216,24 @@ public static class MiraLocaleManager
|
||||
return text;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Builds a formatted translation ID string using a mod ID, a specific ID part, and a suffix.
|
||||
/// </summary>
|
||||
/// <param name="modId">The mod GUID.</param>
|
||||
/// <param name="idPart">The core part of the ID. If it starts with '#', the character is stripped.</param>
|
||||
/// <param name="suffix">The suffix to append to the ID.</param>
|
||||
/// <returns>A formatted translation ID <see cref="string"/>.</returns>
|
||||
public static string BuildTranslationId(string modId, string idPart, string suffix)
|
||||
{
|
||||
return idPart.StartsWith('#') ? idPart[1..] : $"{modId}.{idPart}.{suffix}";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Builds a formatted translation ID string using a mod ID and a specific ID part.
|
||||
/// </summary>
|
||||
/// <param name="modId">The mod GUID.</param>
|
||||
/// <param name="idPart">The core part of the ID. If it starts with '#', the character is stripped.</param>
|
||||
/// <returns>A formatted translation ID <see cref="string"/>.</returns>
|
||||
public static string BuildTranslationId(string modId, string idPart)
|
||||
{
|
||||
return idPart.StartsWith('#') ? idPart[1..] : $"{modId}.{idPart}";
|
||||
@@ -217,6 +244,11 @@ public static class MiraLocaleManager
|
||||
return Path.Combine(Application.persistentDataPath, LangDirectory, modGuid);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves the <see cref="StringNames"/> value for a given locale string name, creating and registering a new one if it does not already exist.
|
||||
/// </summary>
|
||||
/// <param name="name">The name of the locale string.</param>
|
||||
/// <returns>The corresponding <see cref="StringNames"/> value.</returns>
|
||||
public static StringNames GetOrCreateLocaleString(string name)
|
||||
{
|
||||
if (RegisteredStringNames.TryGetValue(name, out var stringName))
|
||||
@@ -230,6 +262,9 @@ public static class MiraLocaleManager
|
||||
return newString;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Loads external locale XML files by checking predefined directories, including the plugin path, BepInEx root, game root, and registered mod directories.
|
||||
/// </summary>
|
||||
public static void LoadExternalLocale()
|
||||
{
|
||||
CheckExternalDirectory("mira.api", BepInEx.Paths.PluginPath);
|
||||
@@ -241,6 +276,11 @@ public static class MiraLocaleManager
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks a specific directory for XML language files and parses their contents into the <see cref="Locale"/> dictionary.
|
||||
/// </summary>
|
||||
/// <param name="modGuid">The mod GUID associated with the directory.</param>
|
||||
/// <param name="dir">The directory path to search for XML files.</param>
|
||||
public static void CheckExternalDirectory(string modGuid, string dir)
|
||||
{
|
||||
Directory.CreateDirectory(dir);
|
||||
@@ -262,7 +302,7 @@ public static class MiraLocaleManager
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Error($"Failed to load external translation {filePath}: {e.Message}");
|
||||
Error($"Failed to load external translation {filePath} for mod {modGuid}: {e.Message}");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -313,13 +353,20 @@ public static class MiraLocaleManager
|
||||
xmlDoc.LoadXml(xmlContent);
|
||||
XmlNodeList? stringNodes = xmlDoc.SelectNodes("/resources/string");
|
||||
|
||||
if (stringNodes != null)
|
||||
if (stringNodes == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var total = 0;
|
||||
|
||||
foreach (XmlNode node in stringNodes)
|
||||
{
|
||||
if (node.Attributes?["name"] != null)
|
||||
if (node.Attributes?["name"] == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
string name = node.Attributes["name"]!.Value;
|
||||
string value = node.InnerText;
|
||||
|
||||
@@ -344,10 +391,8 @@ public static class MiraLocaleManager
|
||||
dict[name] = value;
|
||||
total++;
|
||||
}
|
||||
}
|
||||
Info($"Loaded {language.ToDisplayString()} translation with ({total} keys)");
|
||||
}
|
||||
}
|
||||
catch (XmlException ex)
|
||||
{
|
||||
Error($"XML parsing error: {ex.Message}");
|
||||
|
||||
@@ -7,12 +7,17 @@ using Reactor.Utilities;
|
||||
|
||||
namespace MiraAPI.Translation;
|
||||
|
||||
/// <summary>
|
||||
/// Provides customized localization support, integrating MiraAPI translations into Reactor's localization system.
|
||||
/// </summary>
|
||||
public class MiraLocalizationProvider : LocalizationProvider
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public override int Priority => ReactorPriority.Normal;
|
||||
private static LocalizationProvider? _reactorProvider;
|
||||
private static bool _loadedStrings;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool TryGetText(StringNames stringName, out string? result)
|
||||
{
|
||||
if (MiraLocaleManager.StringNamesLookup.TryGetValue(stringName, out var key))
|
||||
@@ -24,6 +29,7 @@ public class MiraLocalizationProvider : LocalizationProvider
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool TryGetTextFormatted(StringNames stringName, Il2CppReferenceArray<Il2CppSystem.Object> parts, out string? result)
|
||||
{
|
||||
if (!TryGetText(stringName, out result)) return false;
|
||||
@@ -32,6 +38,7 @@ public class MiraLocalizationProvider : LocalizationProvider
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void OnLanguageChanged(SupportedLangs newLanguage)
|
||||
{
|
||||
_reactorProvider ??= LocalizationManager.Providers.First(x => x is HardCodedLocalizationProvider);
|
||||
|
||||
@@ -8,6 +8,8 @@ public static class TranslationExtensions
|
||||
/// <summary>
|
||||
/// Translates a key to the current language.
|
||||
/// </summary>
|
||||
/// <param name="key">The translation key.</param>
|
||||
/// <returns>The corresponding translation.</returns>
|
||||
public static string Translate(this string key)
|
||||
{
|
||||
return MiraLocaleManager.Get(key);
|
||||
|
||||
@@ -67,10 +67,8 @@ public static class TmpSpriteUtils
|
||||
};
|
||||
material.SetTexture(ShaderUtilities.ID_MainTex, sourceTexture);
|
||||
// TODO: Using these values, the icons will NOT clip through chat boxes. However, this breaks quite literally every other tmp text that isn't masked. Please fix this if a good solution is found.
|
||||
#pragma warning disable S125 // Sections of code should not be commented out
|
||||
/*material.SetFloat(ShaderUtilities.ID_StencilComp, 4);
|
||||
material.SetFloat(ShaderUtilities.ID_StencilID, 1);*/
|
||||
#pragma warning restore S125 // Sections of code should not be commented out
|
||||
material.SetFloat(ShaderUtilities.ID_StencilComp, 0);
|
||||
material.SetFloat(ShaderUtilities.ID_StencilID, 0);
|
||||
material.SetFloat(ShaderUtilities.ID_StencilOp, 0);
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Linq;
|
||||
using Reactor.Utilities.Attributes;
|
||||
using UnityEngine;
|
||||
@@ -11,24 +12,25 @@ namespace MiraAPI.Utilities.Components;
|
||||
/// </summary>
|
||||
/// <param name="iPtr">The <see cref="IntPtr"/> for the component.</param>
|
||||
[RegisterInIl2Cpp]
|
||||
[SuppressMessage("Style", "IDE0051:Remove unused private members", Justification = "Unity Convention.")]
|
||||
public class CenteredGridArrange(IntPtr iPtr) : MonoBehaviour(iPtr)
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the cell size, which is used for spacing.
|
||||
/// </summary>
|
||||
public Vector2 CellSize;
|
||||
public Vector2 CellSize { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the maximum amount of columns.
|
||||
/// </summary>
|
||||
public int MaxColumns = 6;
|
||||
public int MaxColumns { get; set; } = 6;
|
||||
|
||||
private List<Transform> cells;
|
||||
private static List<Transform> currentChildren = new List<Transform>();
|
||||
private static readonly List<Transform> CurrentChildren = [];
|
||||
|
||||
private void Start()
|
||||
{
|
||||
cells = new List<Transform>();
|
||||
cells = [];
|
||||
GetChildsActive();
|
||||
CheckCurrentChildren();
|
||||
}
|
||||
@@ -41,23 +43,23 @@ public class CenteredGridArrange(IntPtr iPtr) : MonoBehaviour(iPtr)
|
||||
private void CheckCurrentChildren()
|
||||
{
|
||||
GetChildsActive();
|
||||
if (cells.SequenceEqual(currentChildren))
|
||||
if (cells.SequenceEqual(CurrentChildren))
|
||||
return;
|
||||
cells.Clear();
|
||||
foreach (Transform currentChild in currentChildren)
|
||||
foreach (Transform currentChild in CurrentChildren)
|
||||
cells.Add(currentChild);
|
||||
ArrangeChilds();
|
||||
}
|
||||
|
||||
private void GetChildsActive()
|
||||
{
|
||||
currentChildren.Clear();
|
||||
CurrentChildren.Clear();
|
||||
foreach (var obj in transform)
|
||||
{
|
||||
var child = obj.TryCast<Transform>();
|
||||
if (child == null) continue;
|
||||
if (child.gameObject.activeSelf)
|
||||
currentChildren.Add(child);
|
||||
CurrentChildren.Add(child);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -62,7 +62,7 @@ public static class Extensions
|
||||
}
|
||||
if (self.CloseSound && Constants.ShouldPlaySfx())
|
||||
{
|
||||
SoundManager.Instance.PlaySound(self.CloseSound, false, 1f, null);
|
||||
SoundManager.Instance.PlaySound(self.CloseSound, false);
|
||||
}
|
||||
if (PlayerControl.LocalPlayer.Data.Role.TeamType == RoleTeamTypes.Crewmate)
|
||||
{
|
||||
@@ -222,9 +222,7 @@ public static class Extensions
|
||||
public static void DeepDestroy(this GameObject obj, bool clearGc = true)
|
||||
{
|
||||
obj.Destroy();
|
||||
#pragma warning disable S125 // Sections of code should not be commented out
|
||||
// Nuke(obj, clearGc);
|
||||
#pragma warning restore S125 // Sections of code should not be commented out
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -528,7 +526,7 @@ public static class Extensions
|
||||
/// <returns>A proper string for the <see cref="Enum"/>.</returns>
|
||||
public static string ToDisplayString(this Enum @enum)
|
||||
{
|
||||
var regex = new Regex(@"([^\^])([A-Z][a-z$])");
|
||||
var regex = new Regex(@"([^\^])([A-Z][a-z$])", default, default);
|
||||
return regex.Replace(@enum.ToString(), m => $"{m.Groups[1].Value} {m.Groups[2].Value}");
|
||||
}
|
||||
|
||||
|
||||
@@ -536,11 +536,7 @@ public static class Helpers
|
||||
/// <returns>The <see cref="RoleBehaviour"/>'s intro blurb.</returns>
|
||||
public static string GetRoleIntroBlurb(this RoleBehaviour role)
|
||||
{
|
||||
if (role is ICustomRole custom)
|
||||
{
|
||||
return custom.RoleDescription;
|
||||
}
|
||||
return role.Blurb;
|
||||
return role is ICustomRole custom ? custom.RoleDescription : role.Blurb;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -550,11 +546,7 @@ public static class Helpers
|
||||
/// <returns>The <see cref="RoleBehaviour"/>'s medium description.</returns>
|
||||
public static string GetRoleMedDescription(this RoleBehaviour role)
|
||||
{
|
||||
if (role is ICustomRole custom)
|
||||
{
|
||||
return custom.RoleDescription;
|
||||
}
|
||||
return role.BlurbMed;
|
||||
return role is ICustomRole custom ? custom.RoleDescription : role.BlurbMed;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -564,11 +556,7 @@ public static class Helpers
|
||||
/// <returns>The <see cref="RoleBehaviour"/>'s long description.</returns>
|
||||
public static string GetRoleLongDescription(this RoleBehaviour role)
|
||||
{
|
||||
if (role is ICustomRole custom)
|
||||
{
|
||||
return custom.RoleLongDescription;
|
||||
}
|
||||
return role.BlurbLong;
|
||||
return role is ICustomRole custom ? custom.RoleLongDescription : role.BlurbLong;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -4,12 +4,12 @@ using MiraAPI.Roles;
|
||||
|
||||
namespace MiraAPI.VanillaEvents;
|
||||
|
||||
public static class JudgeEvents
|
||||
internal static class JudgeEvents
|
||||
{
|
||||
public static void Initialize()
|
||||
{
|
||||
// This is required because MiraAPI isn't an IMiraPlugin (besides in the gamemodes branch)
|
||||
MiraEventManager.RegisterEventHandler<ProcessVotesEvent>(@event => ProcessVotesEventHandler(@event), -1000);
|
||||
MiraEventManager.RegisterEventHandler<ProcessVotesEvent>(ProcessVotesEventHandler, -1000);
|
||||
}
|
||||
|
||||
public static void ProcessVotesEventHandler(ProcessVotesEvent @event)
|
||||
|
||||
@@ -5,17 +5,17 @@ using MiraAPI.LocalSettings;
|
||||
|
||||
namespace MiraAPI.VanillaEvents;
|
||||
|
||||
public static class UiResetEvents
|
||||
internal static class UiResetEvents
|
||||
{
|
||||
public static void Initialize()
|
||||
{
|
||||
MiraEventManager.RegisterEventHandler<UiButtonResetEvent>(@event => ResetButtonParents(@event));
|
||||
MiraEventManager.RegisterEventHandler<UiButtonPostResetEvent>(@event => PlaceWikiButton(@event), -900);
|
||||
MiraEventManager.RegisterEventHandler<UiButtonPostResetEvent>(@event => PlaceSubmergedButton(@event), -800);
|
||||
MiraEventManager.RegisterEventHandler<UiButtonPostResetEvent>(@event => PlaceModifierUi(@event), -700);
|
||||
MiraEventManager.RegisterEventHandler<UiButtonResetEvent>(ResetButtonParents);
|
||||
MiraEventManager.RegisterEventHandler<UiButtonPostResetEvent>(PlaceWikiButton, -900);
|
||||
MiraEventManager.RegisterEventHandler<UiButtonPostResetEvent>(PlaceSubmergedButton, -800);
|
||||
MiraEventManager.RegisterEventHandler<UiButtonPostResetEvent>(PlaceModifierUi, -700);
|
||||
}
|
||||
|
||||
public static void ResetButtonParents(UiButtonResetEvent @event)
|
||||
public static void ResetButtonParents(UiButtonResetEvent _)
|
||||
{
|
||||
var wikiButton = MiraHudHelper.VanillaMatchInfoButton;
|
||||
var subButton = MiraHudHelper.SubmergedFloorButton;
|
||||
|
||||
@@ -42,6 +42,7 @@ public static class VotingUtils
|
||||
/// </summary>
|
||||
/// <param name="voteData">The player's <see cref="PlayerVoteData"/>.</param>
|
||||
/// <param name="suspectIdx">Who the player voted for.</param>
|
||||
/// <param name="byJudge">Flag that indicates that the vote was done by a Judge.</param>
|
||||
/// <param name="cancelVote">Whether you want the vote to commence or not.</param>
|
||||
private static void HandleVote(PlayerVoteData voteData, byte suspectIdx, bool byJudge, out bool cancelVote)
|
||||
{
|
||||
@@ -117,11 +118,22 @@ public static class VotingUtils
|
||||
/// <param name="suspectPlayerId">The voted player's id.</param>
|
||||
/// <param name="overruleNonce">Data that is checked by the Judge role to determine which Judge takes priority.</param>
|
||||
[MethodRpc((uint)MiraRpc.QueueOverruleVotes)]
|
||||
[SuppressMessage(
|
||||
"Style",
|
||||
"IDE0060:Remove unused parameter",
|
||||
Justification = "Required parameter: The MethodRpc system mandates an InnerNetObject (or its derived class) as the first parameter for sender context, even if unused in the method body."
|
||||
)]
|
||||
public static void RpcQueueOverruleVotes(PlayerControl source, byte srcPlayerId, byte suspectPlayerId, ushort overruleNonce)
|
||||
{
|
||||
CustomCastJudgeVote(srcPlayerId, suspectPlayerId, overruleNonce);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Casts a custom Judge vote.
|
||||
/// </summary>
|
||||
/// <param name="judgePlayerId">The Judge's player ID.</param>
|
||||
/// <param name="targetPlayerId">The unfortunate soul's player ID.</param>
|
||||
/// <param name="overruleNonce">Overruled.</param>
|
||||
public static void CustomCastJudgeVote(PlayerId judgePlayerId, PlayerId targetPlayerId, ushort overruleNonce)
|
||||
{
|
||||
var plr = GameData.Instance.GetPlayerById(judgePlayerId.Value);
|
||||
@@ -187,6 +199,11 @@ public static class VotingUtils
|
||||
CustomCastVote(srcPlayerId, suspectPlayerId);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Casts a custom vote.
|
||||
/// </summary>
|
||||
/// <param name="srcPlayerId">The casting player's ID.</param>
|
||||
/// <param name="suspectPlayerId">The voted player's ID.</param>
|
||||
public static void CustomCastVote(byte srcPlayerId, byte suspectPlayerId)
|
||||
{
|
||||
var plr = GameData.Instance.GetPlayerById(srcPlayerId);
|
||||
|
||||
Reference in new issue
Block a user