From edca42247d96cce24e6d56680889edc3a353a1a1 Mon Sep 17 00:00:00 2001
From: AlchlcDvl <56699741+AlchlcDvl@users.noreply.github.com>
Date: Mon, 23 Dec 2024 20:52:18 -0500
Subject: [PATCH] finish full implementation of game modes i hope
---
MiraAPI/GameModes/AbstractGameMode.cs | 30 +++++++++----------
MiraAPI/GameOptions/AbstractOptionGroup.cs | 5 ++++
.../Attributes/ModdedEnumOptionAttribute.cs | 11 +++++--
.../Attributes/ModdedNumberOptionAttribute.cs | 15 ++++++++--
.../Attributes/ModdedOptionAttribute.cs | 8 ++++-
.../Attributes/ModdedToggleOptionAttribute.cs | 5 ++--
MiraAPI/GameOptions/IModdedOption.cs | 1 +
MiraAPI/GameOptions/ModdedOptionsManager.cs | 1 +
.../OptionTypes/ModdedEnumOption.cs | 3 +-
.../OptionTypes/ModdedNumberOption.cs | 4 ++-
.../GameOptions/OptionTypes/ModdedOption.cs | 14 ++++++++-
.../OptionTypes/ModdedToggleOption.cs | 3 +-
.../Patches/GameModes/IntroCutscenePatch.cs | 20 +++++++++++++
MiraAPI/Patches/GameModes/WinnersPatch.cs | 27 +++++++++++++++++
.../Patches/Options/GameOptionsMenuPatch.cs | 6 ++--
.../Patches/Options/LobbyViewPanePatches.cs | 2 +-
.../Patches/Options/RoleSettingMenuPatches.cs | 15 ++++++----
MiraAPI/Roles/ICustomRole.cs | 9 +++++-
18 files changed, 141 insertions(+), 38 deletions(-)
create mode 100644 MiraAPI/Patches/GameModes/IntroCutscenePatch.cs
create mode 100644 MiraAPI/Patches/GameModes/WinnersPatch.cs
diff --git a/MiraAPI/GameModes/AbstractGameMode.cs b/MiraAPI/GameModes/AbstractGameMode.cs
index 0f820c8..b7acea3 100644
--- a/MiraAPI/GameModes/AbstractGameMode.cs
+++ b/MiraAPI/GameModes/AbstractGameMode.cs
@@ -1,4 +1,5 @@
-using System.Collections.Generic;
+using System.Collections;
+using System.Collections.Generic;
using UnityEngine;
namespace MiraAPI.GameModes;
@@ -28,6 +29,11 @@ public abstract class AbstractGameMode
///
public uint ID { get; set; }
+ ///
+ /// Gets a value indicating whether a custom intro sequence is implemented by the game mode.
+ ///
+ public virtual bool ShowGameModeIntroCutscene => false;
+
///
/// Called when Intro Cutscene is destroyed.
///
@@ -91,18 +97,6 @@ public abstract class AbstractGameMode
runOriginal = true;
}
- ///
- /// Should Roles Settings be available when this gamemode is selected.
- ///
- /// True if Role Settings are enabled in this game mode.
- public virtual bool AreRoleSettingsEnabled() => true;
-
- ///
- /// Should Game Settings be available when this gamemode is selected.
- ///
- /// True if Game Settings are enabled in this mode.
- public virtual bool AreGameSettingsEnabled() => true;
-
///
/// Custom winner selection.
///
@@ -110,10 +104,14 @@ public abstract class AbstractGameMode
public virtual List? CalculateWinners() => null;
///
- /// Show gamemode in Intro Cutscene.
+ /// The IEnumerator that plays the intro cutscene for this gamemode.
///
- /// True if the game mode should be shown in the intro cutscene.
- public virtual bool ShowGameModeIntroCutscene() => false;
+ /// An instance of IntroCutscene.
+ /// An IEnumerator to run the intro cutscene instead of the base game one.
+ public virtual IEnumerator IntroCutscene(IntroCutscene __instance)
+ {
+ yield return new WaitForEndOfFrame();
+ }
///
/// Can Admin be used in this gamemode.
diff --git a/MiraAPI/GameOptions/AbstractOptionGroup.cs b/MiraAPI/GameOptions/AbstractOptionGroup.cs
index 418f25b..9cbdc95 100644
--- a/MiraAPI/GameOptions/AbstractOptionGroup.cs
+++ b/MiraAPI/GameOptions/AbstractOptionGroup.cs
@@ -37,6 +37,11 @@ public abstract class AbstractOptionGroup
///
public virtual Type? AdvancedRole => null;
+ ///
+ /// Gets the role the group is associated with. This is used for the advanced role options menu.
+ ///
+ public virtual Type? AdvancedMode => null;
+
internal bool AllOptionsHidden { get; set; }
internal CategoryHeaderMasked? Header { get; set; }
diff --git a/MiraAPI/GameOptions/Attributes/ModdedEnumOptionAttribute.cs b/MiraAPI/GameOptions/Attributes/ModdedEnumOptionAttribute.cs
index 2944520..5bb8433 100644
--- a/MiraAPI/GameOptions/Attributes/ModdedEnumOptionAttribute.cs
+++ b/MiraAPI/GameOptions/Attributes/ModdedEnumOptionAttribute.cs
@@ -7,13 +7,18 @@ namespace MiraAPI.GameOptions.Attributes;
///
/// Attribute for creating an enum option.
///
+/// The title of the option.
+/// The Enum type.
+/// An option list of string values to use in place of the enum name.
+/// An optional role type.
+/// An optional game mode type.
[AttributeUsage(AttributeTargets.Property)]
-public class ModdedEnumOptionAttribute(string title, Type enumType, string[]? values = null, Type? roleType = null)
- : ModdedOptionAttribute(title, roleType)
+public class ModdedEnumOptionAttribute(string title, Type enumType, string[]? values = null, Type? roleType = null, Type? modeType = null)
+ : ModdedOptionAttribute(title, roleType, modeType)
{
internal override IModdedOption CreateOption(object? value, PropertyInfo property)
{
- var opt = new ModdedEnumOption(Title, (int)(value ?? 0), enumType, values, RoleType);
+ var opt = new ModdedEnumOption(Title, (int)(value ?? 0), enumType, values, RoleType, ModeType);
return opt;
}
diff --git a/MiraAPI/GameOptions/Attributes/ModdedNumberOptionAttribute.cs b/MiraAPI/GameOptions/Attributes/ModdedNumberOptionAttribute.cs
index 2bd4438..50db882 100644
--- a/MiraAPI/GameOptions/Attributes/ModdedNumberOptionAttribute.cs
+++ b/MiraAPI/GameOptions/Attributes/ModdedNumberOptionAttribute.cs
@@ -8,6 +8,14 @@ namespace MiraAPI.GameOptions.Attributes;
///
/// A number option attribute for the modded options system.
///
+/// The title of the option.
+/// The minimum value.
+/// The maximum value.
+/// The increment.
+/// The suffix type.
+/// Whether zero is infinity or not.
+/// An optional role type.
+/// An optional game mode type.
[AttributeUsage(AttributeTargets.Property)]
public class ModdedNumberOptionAttribute(
string title,
@@ -16,12 +24,13 @@ public class ModdedNumberOptionAttribute(
float increment = 1,
MiraNumberSuffixes suffixType = MiraNumberSuffixes.None,
bool zeroInfinity = false,
- Type? roleType = null)
- : ModdedOptionAttribute(title, roleType)
+ Type? roleType = null,
+ Type? modeType = null)
+ : ModdedOptionAttribute(title, roleType, modeType)
{
internal override IModdedOption CreateOption(object? value, PropertyInfo property)
{
- return new ModdedNumberOption(Title, (float)(value ?? min+increment), min, max, increment, suffixType, zeroInfinity, RoleType);
+ return new ModdedNumberOption(Title, (float)(value ?? min+increment), min, max, increment, suffixType, zeroInfinity, RoleType, ModeType);
}
///
diff --git a/MiraAPI/GameOptions/Attributes/ModdedOptionAttribute.cs b/MiraAPI/GameOptions/Attributes/ModdedOptionAttribute.cs
index 702d75e..bb9dab5 100644
--- a/MiraAPI/GameOptions/Attributes/ModdedOptionAttribute.cs
+++ b/MiraAPI/GameOptions/Attributes/ModdedOptionAttribute.cs
@@ -8,8 +8,9 @@ namespace MiraAPI.GameOptions.Attributes;
///
/// The option title.
/// Optional parameter to specify a role Type.
+/// Optional parameter to specify a game mode Type.
[AttributeUsage(AttributeTargets.Property)]
-public abstract class ModdedOptionAttribute(string title, Type? roleType = null) : Attribute
+public abstract class ModdedOptionAttribute(string title, Type? roleType = null, Type? modeType = null) : Attribute
{
internal IModdedOption? HolderOption { get; set; }
@@ -23,6 +24,11 @@ public abstract class ModdedOptionAttribute(string title, Type? roleType = null)
///
protected Type? RoleType { get; private set; } = roleType;
+ ///
+ /// Gets the game mode type of the option.
+ ///
+ protected Type? ModeType { get; private set; } = modeType;
+
///
/// Sets the value of the option.
///
diff --git a/MiraAPI/GameOptions/Attributes/ModdedToggleOptionAttribute.cs b/MiraAPI/GameOptions/Attributes/ModdedToggleOptionAttribute.cs
index c389292..5adfe77 100644
--- a/MiraAPI/GameOptions/Attributes/ModdedToggleOptionAttribute.cs
+++ b/MiraAPI/GameOptions/Attributes/ModdedToggleOptionAttribute.cs
@@ -9,12 +9,13 @@ namespace MiraAPI.GameOptions.Attributes;
///
/// The option title.
/// An optional role type.
+/// An optional game mode type.
[AttributeUsage(AttributeTargets.Property)]
-public class ModdedToggleOptionAttribute(string title, Type? roleType = null) : ModdedOptionAttribute(title, roleType)
+public class ModdedToggleOptionAttribute(string title, Type? roleType = null, Type? modeType = null) : ModdedOptionAttribute(title, roleType, modeType)
{
internal override IModdedOption CreateOption(object? value, PropertyInfo property)
{
- var toggleOpt = new ModdedToggleOption(Title, (bool)(value ?? false), RoleType);
+ var toggleOpt = new ModdedToggleOption(Title, (bool)(value ?? false), RoleType, ModeType);
return toggleOpt;
}
diff --git a/MiraAPI/GameOptions/IModdedOption.cs b/MiraAPI/GameOptions/IModdedOption.cs
index 1aee3c4..b2c542e 100644
--- a/MiraAPI/GameOptions/IModdedOption.cs
+++ b/MiraAPI/GameOptions/IModdedOption.cs
@@ -14,6 +14,7 @@ public interface IModdedOption
IMiraPlugin? ParentMod { get; set; }
BaseGameSetting Data { get; }
Type? AdvancedRole { get; set; }
+ Type? AdvancedMode { get; set; }
OptionBehaviour? OptionBehaviour { get; }
Func Visible { get; set; }
ConfigDefinition? ConfigDefinition { get; set; }
diff --git a/MiraAPI/GameOptions/ModdedOptionsManager.cs b/MiraAPI/GameOptions/ModdedOptionsManager.cs
index 3f30019..1913d07 100644
--- a/MiraAPI/GameOptions/ModdedOptionsManager.cs
+++ b/MiraAPI/GameOptions/ModdedOptionsManager.cs
@@ -121,6 +121,7 @@ public static class ModdedOptionsManager
option.ParentMod = pluginInfo.MiraPlugin;
option.AdvancedRole = group.AdvancedRole;
+ option.AdvancedMode = group.AdvancedMode;
pluginInfo.Options.Add(option);
diff --git a/MiraAPI/GameOptions/OptionTypes/ModdedEnumOption.cs b/MiraAPI/GameOptions/OptionTypes/ModdedEnumOption.cs
index 0d236a0..74c1860 100644
--- a/MiraAPI/GameOptions/OptionTypes/ModdedEnumOption.cs
+++ b/MiraAPI/GameOptions/OptionTypes/ModdedEnumOption.cs
@@ -26,7 +26,8 @@ public class ModdedEnumOption : ModdedOption
/// The Enum type.
/// An option list of string values to use in place of the enum name.
/// An optional role type to specify for a specific role.
- public ModdedEnumOption(string title, int defaultValue, Type enumType, string[]? values = null, Type? roleType = null) : base(title, defaultValue, roleType)
+ /// An optional game mode type to specify for a specific mode.
+ public ModdedEnumOption(string title, int defaultValue, Type enumType, string[]? values = null, Type? roleType = null, Type? modeType = null) : base(title, defaultValue, roleType, modeType)
{
Values = values ?? Enum.GetNames(enumType);
Data = ScriptableObject.CreateInstance();
diff --git a/MiraAPI/GameOptions/OptionTypes/ModdedNumberOption.cs b/MiraAPI/GameOptions/OptionTypes/ModdedNumberOption.cs
index e86d88d..3256654 100644
--- a/MiraAPI/GameOptions/OptionTypes/ModdedNumberOption.cs
+++ b/MiraAPI/GameOptions/OptionTypes/ModdedNumberOption.cs
@@ -48,6 +48,7 @@ public class ModdedNumberOption : ModdedOption
/// The suffix type.
/// Whether zero is infinity or not.
/// An optional role type.
+ /// An optional game mode type.
public ModdedNumberOption(
string title,
float defaultValue,
@@ -56,7 +57,8 @@ public class ModdedNumberOption : ModdedOption
float increment,
MiraNumberSuffixes suffixType,
bool zeroInfinity = false,
- Type? roleType = null) : base(title, defaultValue, roleType)
+ Type? roleType = null,
+ Type? modeType = null) : base(title, defaultValue, roleType, modeType)
{
Min = min;
Max = max;
diff --git a/MiraAPI/GameOptions/OptionTypes/ModdedOption.cs b/MiraAPI/GameOptions/OptionTypes/ModdedOption.cs
index d811f1d..3719353 100644
--- a/MiraAPI/GameOptions/OptionTypes/ModdedOption.cs
+++ b/MiraAPI/GameOptions/OptionTypes/ModdedOption.cs
@@ -1,4 +1,5 @@
using BepInEx.Configuration;
+using MiraAPI.GameModes;
using MiraAPI.Networking;
using MiraAPI.PluginLoading;
using MiraAPI.Roles;
@@ -77,6 +78,11 @@ public abstract class ModdedOption : IModdedOption
///
public Type? AdvancedRole { get; set; }
+ ///
+ /// Gets or sets the advanced mode of the option.
+ ///
+ public Type? AdvancedMode { get; set; }
+
///
/// Gets or sets the option behaviour of the option.
///
@@ -103,7 +109,8 @@ public abstract class ModdedOption : IModdedOption
/// The option title.
/// The default value.
/// The Role Type or null if it doesn't belong to a role.
- protected ModdedOption(string title, T defaultValue, Type? roleType)
+ /// The Game Mode Type or null if it doesn't belong to a mode.
+ protected ModdedOption(string title, T defaultValue, Type? roleType, Type? modeType)
{
Id = ModdedOptionsManager.NextId;
Title = title;
@@ -116,6 +123,11 @@ public abstract class ModdedOption : IModdedOption
{
AdvancedRole = roleType;
}
+
+ if (modeType is not null && modeType.IsAssignableTo(typeof(AbstractGameMode)))
+ {
+ AdvancedMode = modeType;
+ }
}
internal void ValueChanged(OptionBehaviour optionBehaviour)
diff --git a/MiraAPI/GameOptions/OptionTypes/ModdedToggleOption.cs b/MiraAPI/GameOptions/OptionTypes/ModdedToggleOption.cs
index 12f8f5f..79e8281 100644
--- a/MiraAPI/GameOptions/OptionTypes/ModdedToggleOption.cs
+++ b/MiraAPI/GameOptions/OptionTypes/ModdedToggleOption.cs
@@ -16,7 +16,8 @@ public class ModdedToggleOption : ModdedOption
/// The option title.
/// The default value.
/// An optional role type.
- public ModdedToggleOption(string title, bool defaultValue, Type? roleType = null) : base(title, defaultValue, roleType)
+ /// An optional game mode type.
+ public ModdedToggleOption(string title, bool defaultValue, Type? roleType = null, Type? modeType = null) : base(title, defaultValue, roleType, modeType)
{
Data = ScriptableObject.CreateInstance();
diff --git a/MiraAPI/Patches/GameModes/IntroCutscenePatch.cs b/MiraAPI/Patches/GameModes/IntroCutscenePatch.cs
new file mode 100644
index 0000000..5701014
--- /dev/null
+++ b/MiraAPI/Patches/GameModes/IntroCutscenePatch.cs
@@ -0,0 +1,20 @@
+using BepInEx.Unity.IL2CPP.Utils.Collections;
+using HarmonyLib;
+using MiraAPI.GameModes;
+
+namespace MiraAPI.Patches.GameModes;
+
+[HarmonyPatch(typeof(IntroCutscene), nameof(IntroCutscene.CoBegin))]
+internal static class IntroCutscenePatch
+{
+ public static bool Prefix(IntroCutscene __instance, ref Il2CppSystem.Collections.IEnumerator __result)
+ {
+ if (CustomGameModeManager.ActiveMode?.ShowGameModeIntroCutscene == true)
+ {
+ __result = CustomGameModeManager.ActiveMode.IntroCutscene(__instance).WrapToIl2Cpp();
+ return false;
+ }
+
+ return true;
+ }
+}
diff --git a/MiraAPI/Patches/GameModes/WinnersPatch.cs b/MiraAPI/Patches/GameModes/WinnersPatch.cs
new file mode 100644
index 0000000..01f9859
--- /dev/null
+++ b/MiraAPI/Patches/GameModes/WinnersPatch.cs
@@ -0,0 +1,27 @@
+using HarmonyLib;
+using MiraAPI.GameModes;
+
+namespace MiraAPI.Patches.GameModes;
+
+[HarmonyPatch(typeof(AmongUsClient), nameof(AmongUsClient.OnGameEnd))]
+internal static class WinnersPatch
+{
+ [HarmonyPostfix]
+ public static void ShowWinningScreen()
+ {
+ if (CustomGameModeManager.ActiveMode is null or DefaultMode)
+ return;
+
+ var winners = CustomGameModeManager.ActiveMode.CalculateWinners();
+
+ if (winners is null)
+ return;
+
+ EndGameResult.CachedWinners.Clear();
+
+ foreach (var data in winners)
+ {
+ EndGameResult.CachedWinners.Add(new(data));
+ }
+ }
+}
diff --git a/MiraAPI/Patches/Options/GameOptionsMenuPatch.cs b/MiraAPI/Patches/Options/GameOptionsMenuPatch.cs
index 92cd925..7e75ede 100644
--- a/MiraAPI/Patches/Options/GameOptionsMenuPatch.cs
+++ b/MiraAPI/Patches/Options/GameOptionsMenuPatch.cs
@@ -1,4 +1,5 @@
using HarmonyLib;
+using MiraAPI.GameModes;
using MiraAPI.Utilities;
using MiraAPI.Utilities.Assets;
using Reactor.Localization.Utilities;
@@ -32,7 +33,7 @@ public static class GameOptionsMenuPatch
var num = 2.1f;
var filteredGroups =
GameSettingMenuPatches.SelectedMod?.OptionGroups.Where(
- x => x.AdvancedRole is null) ?? [];
+ x => x.AdvancedRole is null && (x.AdvancedMode is null || x.AdvancedMode == CustomGameModeManager.ActiveMode?.GetType())) ?? [];
foreach (var group in filteredGroups)
{
@@ -99,7 +100,8 @@ public static class GameOptionsMenuPatch
__instance.MapPicker.gameObject.SetActive(false);
- var filteredGroups = GameSettingMenuPatches.SelectedMod?.OptionGroups.Where(x => x.AdvancedRole is null) ?? [];
+ var filteredGroups = GameSettingMenuPatches.SelectedMod?.OptionGroups.Where(x => x.AdvancedRole is null && (x.AdvancedMode is null || x.AdvancedMode ==
+ CustomGameModeManager.ActiveMode?.GetType())) ?? [];
foreach (var group in filteredGroups)
{
diff --git a/MiraAPI/Patches/Options/LobbyViewPanePatches.cs b/MiraAPI/Patches/Options/LobbyViewPanePatches.cs
index 0649873..e00d1cd 100644
--- a/MiraAPI/Patches/Options/LobbyViewPanePatches.cs
+++ b/MiraAPI/Patches/Options/LobbyViewPanePatches.cs
@@ -280,7 +280,7 @@ public static class LobbyViewPanePatches
viewSettingsInfoPanelRoleVariant.transform.localPosition = new Vector3(num2, num, -2f);
var advancedRoleOptions = SelectedMod.Options
- .Where(x => x.AdvancedRole == customRole.GetType())
+ .Where(x => x.AdvancedRole == customRole.GetType() && (x.AdvancedMode is null || x.AdvancedMode == customRole.AssociatedGameMode))
.ToList();
if (!flag && advancedRoleOptions.Count > 0)
diff --git a/MiraAPI/Patches/Options/RoleSettingMenuPatches.cs b/MiraAPI/Patches/Options/RoleSettingMenuPatches.cs
index 4461423..17bce70 100644
--- a/MiraAPI/Patches/Options/RoleSettingMenuPatches.cs
+++ b/MiraAPI/Patches/Options/RoleSettingMenuPatches.cs
@@ -1,5 +1,6 @@
using HarmonyLib;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
+using MiraAPI.GameModes;
using MiraAPI.Networking;
using MiraAPI.Roles;
using MiraAPI.Utilities;
@@ -18,7 +19,7 @@ using Object = UnityEngine.Object;
namespace MiraAPI.Patches.Options;
[HarmonyPatch(typeof(RolesSettingsMenu))]
-public static class RoleSettingMenuPatches
+internal static class RoleSettingMenuPatches
{
[HarmonyPrefix]
[HarmonyPatch(nameof(RolesSettingsMenu.SetQuotaTab))]
@@ -56,7 +57,8 @@ public static class RoleSettingMenuPatches
var crewRoles = GameSettingMenuPatches.SelectedMod?.CustomRoles.Values
.OfType()
- .Where(role => role is { Team: ModdedRoleTeams.Crewmate, Configuration.HideSettings: false })
+ .Where(role => role is { Team: ModdedRoleTeams.Crewmate, Configuration.HideSettings: false } && (role.AssociatedGameMode is null || role.AssociatedGameMode ==
+ CustomGameModeManager.ActiveMode?.GetType()))
.ToList() ?? [];
if (crewRoles is { Count: > 0 })
@@ -82,7 +84,8 @@ public static class RoleSettingMenuPatches
var impRoles = GameSettingMenuPatches.SelectedMod?.CustomRoles.Values
.OfType()
- .Where(role => role is { Team: ModdedRoleTeams.Impostor, Configuration.HideSettings: false })
+ .Where(role => role is { Team: ModdedRoleTeams.Impostor, Configuration.HideSettings: false } && (role.AssociatedGameMode is null || role.AssociatedGameMode ==
+ CustomGameModeManager.ActiveMode?.GetType()))
.ToList() ?? [];
if (impRoles is { Count: > 0 })
@@ -109,7 +112,8 @@ public static class RoleSettingMenuPatches
var neutRoles = GameSettingMenuPatches.SelectedMod?.CustomRoles.Values
.OfType()
- .Where(role => role is { Team: ModdedRoleTeams.Neutral, Configuration.HideSettings: false })
+ .Where(role => role is { Team: ModdedRoleTeams.Neutral, Configuration.HideSettings: false } && (role.AssociatedGameMode is null || role.AssociatedGameMode ==
+ CustomGameModeManager.ActiveMode?.GetType()))
.ToList() ?? [];
if (neutRoles is { Count: > 0 })
@@ -208,7 +212,8 @@ public static class RoleSettingMenuPatches
var num = -0.872f;
- var filteredOptions = GameSettingMenuPatches.SelectedMod?.Options.Where(x => x.AdvancedRole == role.GetType()) ?? [];
+ var filteredOptions = GameSettingMenuPatches.SelectedMod?.Options?.Where(x => x.AdvancedRole == role.GetType() && (x.AdvancedMode is null || x.AdvancedMode ==
+ CustomGameModeManager.ActiveMode?.GetType())) ?? [];
foreach (var option in filteredOptions)
{
diff --git a/MiraAPI/Roles/ICustomRole.cs b/MiraAPI/Roles/ICustomRole.cs
index ba318b2..eae4d30 100644
--- a/MiraAPI/Roles/ICustomRole.cs
+++ b/MiraAPI/Roles/ICustomRole.cs
@@ -1,9 +1,11 @@
using BepInEx.Configuration;
+using MiraAPI.GameModes;
using MiraAPI.Modifiers;
using MiraAPI.PluginLoading;
using MiraAPI.Utilities;
-using System.Text;
using Reactor.Utilities;
+using System;
+using System.Text;
using UnityEngine;
namespace MiraAPI.Roles;
@@ -48,6 +50,11 @@ public interface ICustomRole
///
MiraPluginInfo ParentMod => CustomRoleManager.FindParentMod(this);
+ ///
+ /// Gets the game mode this role is a part of.
+ ///
+ Type AssociatedGameMode => typeof(DefaultMode);
+
///
/// This method runs on the PlayerControl.FixedUpdate method for ALL players with this role.
///