finish full implementation of game modes i hope

This commit is contained in:
AlchlcDvl committed 2024-12-23 20:52:18 -05:00
1 parent b6ba8f59bd
commit edca42247d
18 files changed
+141 -38

No files matched your search

+14 -16
View File
@@ -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
/// </summary>
public uint ID { get; set; }
/// <summary>
/// Gets a value indicating whether a custom intro sequence is implemented by the game mode.
/// </summary>
public virtual bool ShowGameModeIntroCutscene => false;
/// <summary>
/// Called when Intro Cutscene is destroyed.
/// </summary>
@@ -91,18 +97,6 @@ public abstract class AbstractGameMode
runOriginal = true;
}
/// <summary>
/// Should Roles Settings be available when this gamemode is selected.
/// </summary>
/// <returns>True if Role Settings are enabled in this game mode.</returns>
public virtual bool AreRoleSettingsEnabled() => true;
/// <summary>
/// Should Game Settings be available when this gamemode is selected.
/// </summary>
/// <returns>True if Game Settings are enabled in this mode.</returns>
public virtual bool AreGameSettingsEnabled() => true;
/// <summary>
/// Custom winner selection.
/// </summary>
@@ -110,10 +104,14 @@ public abstract class AbstractGameMode
public virtual List<NetworkedPlayerInfo>? CalculateWinners() => null;
/// <summary>
/// Show gamemode in Intro Cutscene.
/// The IEnumerator that plays the intro cutscene for this gamemode.
/// </summary>
/// <returns>True if the game mode should be shown in the intro cutscene.</returns>
public virtual bool ShowGameModeIntroCutscene() => false;
/// <param name="__instance">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)
{
yield return new WaitForEndOfFrame();
}
/// <summary>
/// Can Admin be used in this gamemode.
@@ -37,6 +37,11 @@ public abstract class AbstractOptionGroup
/// </summary>
public virtual Type? AdvancedRole => null;
/// <summary>
/// Gets the role the group is associated with. This is used for the advanced role options menu.
/// </summary>
public virtual Type? AdvancedMode => null;
internal bool AllOptionsHidden { get; set; }
internal CategoryHeaderMasked? Header { get; set; }
@@ -7,13 +7,18 @@ namespace MiraAPI.GameOptions.Attributes;
/// <summary>
/// Attribute for creating an enum option.
/// </summary>
/// <param name="title">The title of the option.</param>
/// <param name="enumType">The Enum type.</param>
/// <param name="values">An option list of string values to use in place of the enum name.</param>
/// <param name="roleType">An optional role type.</param>
/// <param name="modeType">An optional game mode type.</param>
[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;
}
@@ -8,6 +8,14 @@ namespace MiraAPI.GameOptions.Attributes;
/// <summary>
/// A number option attribute for the modded options system.
/// </summary>
/// <param name="title">The title of the option.</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="zeroInfinity">Whether zero is infinity or not.</param>
/// <param name="roleType">An optional role type.</param>
/// <param name="modeType">An optional game mode type.</param>
[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);
}
/// <inheritdoc />
@@ -8,8 +8,9 @@ namespace MiraAPI.GameOptions.Attributes;
/// </summary>
/// <param name="title">The option title.</param>
/// <param name="roleType">Optional parameter to specify a role Type.</param>
/// <param name="modeType">Optional parameter to specify a game mode Type.</param>
[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)
/// </summary>
protected Type? RoleType { get; private set; } = roleType;
/// <summary>
/// Gets the game mode type of the option.
/// </summary>
protected Type? ModeType { get; private set; } = modeType;
/// <summary>
/// Sets the value of the option.
/// </summary>
@@ -9,12 +9,13 @@ namespace MiraAPI.GameOptions.Attributes;
/// </summary>
/// <param name="title">The option title.</param>
/// <param name="roleType">An optional role type.</param>
/// <param name="modeType">An optional game mode type.</param>
[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;
}
+1
View File
@@ -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<bool> Visible { get; set; }
ConfigDefinition? ConfigDefinition { get; set; }
@@ -121,6 +121,7 @@ public static class ModdedOptionsManager
option.ParentMod = pluginInfo.MiraPlugin;
option.AdvancedRole = group.AdvancedRole;
option.AdvancedMode = group.AdvancedMode;
pluginInfo.Options.Add(option);
@@ -26,7 +26,8 @@ public class ModdedEnumOption : ModdedOption<int>
/// <param name="enumType">The Enum type.</param>
/// <param name="values">An option list of string values to use in place of the enum name.</param>
/// <param name="roleType">An optional role type to specify for a specific role.</param>
public ModdedEnumOption(string title, int defaultValue, Type enumType, string[]? values = null, Type? roleType = null) : base(title, defaultValue, roleType)
/// <param name="modeType">An optional game mode type to specify for a specific mode.</param>
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<StringGameSetting>();
@@ -48,6 +48,7 @@ public class ModdedNumberOption : ModdedOption<float>
/// <param name="suffixType">The suffix type.</param>
/// <param name="zeroInfinity">Whether zero is infinity or not.</param>
/// <param name="roleType">An optional role type.</param>
/// <param name="modeType">An optional game mode type.</param>
public ModdedNumberOption(
string title,
float defaultValue,
@@ -56,7 +57,8 @@ public class ModdedNumberOption : ModdedOption<float>
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;
@@ -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<T> : IModdedOption
/// </summary>
public Type? AdvancedRole { get; set; }
/// <summary>
/// Gets or sets the advanced mode of the option.
/// </summary>
public Type? AdvancedMode { get; set; }
/// <summary>
/// Gets or sets the option behaviour of the option.
/// </summary>
@@ -103,7 +109,8 @@ public abstract class ModdedOption<T> : IModdedOption
/// <param name="title">The option title.</param>
/// <param name="defaultValue">The default value.</param>
/// <param name="roleType">The Role Type or null if it doesn't belong to a role.</param>
protected ModdedOption(string title, T defaultValue, Type? roleType)
/// <param name="modeType">The Game Mode Type or null if it doesn't belong to a mode.</param>
protected ModdedOption(string title, T defaultValue, Type? roleType, Type? modeType)
{
Id = ModdedOptionsManager.NextId;
Title = title;
@@ -116,6 +123,11 @@ public abstract class ModdedOption<T> : IModdedOption
{
AdvancedRole = roleType;
}
if (modeType is not null && modeType.IsAssignableTo(typeof(AbstractGameMode)))
{
AdvancedMode = modeType;
}
}
internal void ValueChanged(OptionBehaviour optionBehaviour)
@@ -16,7 +16,8 @@ public class ModdedToggleOption : ModdedOption<bool>
/// <param name="title">The option title.</param>
/// <param name="defaultValue">The default value.</param>
/// <param name="roleType">An optional role type.</param>
public ModdedToggleOption(string title, bool defaultValue, Type? roleType = null) : base(title, defaultValue, roleType)
/// <param name="modeType">An optional game mode type.</param>
public ModdedToggleOption(string title, bool defaultValue, Type? roleType = null, Type? modeType = null) : base(title, defaultValue, roleType, modeType)
{
Data = ScriptableObject.CreateInstance<CheckboxGameSetting>();
@@ -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;
}
}
+27
View File
@@ -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));
}
}
}
@@ -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)
{
@@ -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)
@@ -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<ICustomRole>()
.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<ICustomRole>()
.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<ICustomRole>()
.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)
{
+8 -1
View File
@@ -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
/// </summary>
MiraPluginInfo ParentMod => CustomRoleManager.FindParentMod(this);
/// <summary>
/// Gets the game mode this role is a part of.
/// </summary>
Type AssociatedGameMode => typeof(DefaultMode);
/// <summary>
/// This method runs on the PlayerControl.FixedUpdate method for ALL players with this role.
/// </summary>