mirror of
https://github.com/All-Of-Us-Mods/MiraAPI.git
synced 2026-10-20 01:46:15 +00:00
freeplay modifiers
This commit is contained in:
1 parent
9504862bea
commit
b6dda5f970
12 files changed
+170
-53
No files matched your search
@@ -1,5 +1,4 @@
|
||||
using MiraAPI.Modifiers;
|
||||
using MiraAPI.Modifiers.Types;
|
||||
using MiraAPI.Modifiers.Types;
|
||||
|
||||
namespace MiraAPI.Example.Modifiers;
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
using Il2CppSystem;
|
||||
using MiraAPI.Example.Roles;
|
||||
using MiraAPI.Modifiers;
|
||||
using MiraAPI.Modifiers.Types;
|
||||
using UnityEngine;
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
using MiraAPI.Modifiers;
|
||||
using MiraAPI.Modifiers.Types;
|
||||
using MiraAPI.Modifiers.Types;
|
||||
|
||||
namespace MiraAPI.Example.Modifiers;
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Il2CppInterop.Runtime.InteropTypes.Arrays;
|
||||
|
||||
@@ -30,6 +30,11 @@ public abstract class BaseModifier
|
||||
/// </summary>
|
||||
public virtual bool HideOnUi => false;
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether the modifier is shown in the freeplay menu.
|
||||
/// </summary>
|
||||
public virtual bool ShowInFreeplay => false;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the HUD information for this modifier. Defaults to the modifier name. Does nothing if <see cref="HideOnUi"/> is true.
|
||||
/// </summary>
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Runtime.Serialization;
|
||||
using MiraAPI.Modifiers.Types;
|
||||
using MiraAPI.Networking;
|
||||
using MiraAPI.PluginLoading;
|
||||
using MiraAPI.Roles;
|
||||
using MiraAPI.Utilities;
|
||||
using Reactor.Networking.Rpc;
|
||||
@@ -49,7 +51,7 @@ public static class ModifierManager
|
||||
return TypeToIdModifierMap.GetValueOrDefault(type);
|
||||
}
|
||||
|
||||
internal static bool RegisterModifier(Type modifierType)
|
||||
internal static bool RegisterModifier(Type modifierType, MiraPluginInfo info)
|
||||
{
|
||||
if (!typeof(BaseModifier).IsAssignableFrom(modifierType))
|
||||
{
|
||||
@@ -58,6 +60,9 @@ public static class ModifierManager
|
||||
|
||||
IdToTypeModifierMap.Add(GetNextId(), modifierType);
|
||||
TypeToIdModifierMap.Add(modifierType, _nextId);
|
||||
var bm = (BaseModifier)FormatterServices.GetUninitializedObject(modifierType); // this probably isn't a great idea
|
||||
bm.ModifierId = _nextId;
|
||||
info.Modifiers.Add(bm);
|
||||
|
||||
if (!typeof(GameModifier).IsAssignableFrom(modifierType))
|
||||
{
|
||||
|
||||
@@ -5,6 +5,9 @@
|
||||
/// </summary>
|
||||
public abstract class GameModifier : BaseModifier
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public override bool ShowInFreeplay => true;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the chance of the modifier being assigned to a player.
|
||||
/// </summary>
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
using HarmonyLib;
|
||||
using MiraAPI.Modifiers;
|
||||
using MiraAPI.Utilities;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace MiraAPI.Patches.Roles;
|
||||
|
||||
[HarmonyPatch(typeof(TaskAddButton))]
|
||||
public static class TaskAddButtonPatches
|
||||
{
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(nameof(TaskAddButton.Start))]
|
||||
public static bool StartPrefix(TaskAddButton __instance)
|
||||
{
|
||||
if (uint.TryParse(__instance.name, out var result))
|
||||
{
|
||||
__instance.Overlay.enabled = false;
|
||||
if (PlayerControl.LocalPlayer.HasModifier(result))
|
||||
{
|
||||
__instance.Overlay.enabled = true;
|
||||
__instance.Overlay.sprite = __instance.CheckImage;
|
||||
}
|
||||
|
||||
__instance.Button.OnClick = new Button.ButtonClickedEvent();
|
||||
__instance.Button.OnClick.AddListener((UnityEngine.Events.UnityAction)(() =>
|
||||
{
|
||||
if (PlayerControl.LocalPlayer.HasModifier(result))
|
||||
{
|
||||
PlayerControl.LocalPlayer.GetModifierComponent()!.RemoveModifier(result);
|
||||
__instance.Overlay.enabled = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
PlayerControl.LocalPlayer.GetModifierComponent()!.AddModifier(ModifierManager.GetModifierType(result)!);
|
||||
__instance.Overlay.enabled = true;
|
||||
}
|
||||
}));
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -4,7 +4,6 @@ using MiraAPI.PluginLoading;
|
||||
using MiraAPI.Roles;
|
||||
using MiraAPI.Utilities.Assets;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using TMPro;
|
||||
using UnityEngine;
|
||||
@@ -18,7 +17,6 @@ namespace MiraAPI.Patches.Roles;
|
||||
[HarmonyPatch]
|
||||
public static class TaskAdderPatch
|
||||
{
|
||||
private static readonly Dictionary<string, string> ModsFolders = [];
|
||||
private static Scroller? _scroller;
|
||||
|
||||
/// <summary>
|
||||
@@ -67,25 +65,34 @@ public static class TaskAdderPatch
|
||||
rolesFolder.FolderName = "Roles";
|
||||
rolesFolder.name = "RolesFolder";
|
||||
|
||||
var modifiersFolder = Object.Instantiate(__instance.RootFolderPrefab, _scroller.Inner);
|
||||
modifiersFolder.gameObject.SetActive(false);
|
||||
modifiersFolder.FolderName = "Modifiers";
|
||||
modifiersFolder.name = "ModifiersFolder";
|
||||
|
||||
foreach (var plugin in MiraPluginManager.Instance.RegisteredPlugins())
|
||||
{
|
||||
if (plugin.CustomRoles.Count == 0)
|
||||
if (plugin.CustomRoles.Any(x => x.Value is ICustomRole { Configuration.ShowInFreeplay: true }))
|
||||
{
|
||||
continue;
|
||||
var newFolder = Object.Instantiate(__instance.RootFolderPrefab, _scroller.Inner);
|
||||
newFolder.name = plugin.PluginId+":Roles";
|
||||
newFolder.FolderName = plugin.PluginInfo.Metadata.Name;
|
||||
newFolder.gameObject.SetActive(false);
|
||||
rolesFolder.SubFolders.Add(newFolder);
|
||||
}
|
||||
|
||||
var newFolder = Object.Instantiate(__instance.RootFolderPrefab, _scroller.Inner);
|
||||
newFolder.FolderName = newFolder.name = plugin.PluginInfo.Metadata.Name;
|
||||
newFolder.gameObject.SetActive(false);
|
||||
rolesFolder.SubFolders.Add(newFolder);
|
||||
|
||||
if (!ModsFolders.ContainsKey(plugin.PluginInfo.Metadata.Name))
|
||||
if (plugin.Modifiers.Exists(x => x.ShowInFreeplay))
|
||||
{
|
||||
ModsFolders.Add(plugin.PluginInfo.Metadata.Name, plugin.PluginId);
|
||||
var newFolder = Object.Instantiate(__instance.RootFolderPrefab, _scroller.Inner);
|
||||
newFolder.name = plugin.PluginId+":Modifiers";
|
||||
newFolder.FolderName = plugin.PluginInfo.Metadata.Name;
|
||||
newFolder.gameObject.SetActive(false);
|
||||
modifiersFolder.SubFolders.Add(newFolder);
|
||||
}
|
||||
}
|
||||
|
||||
__instance.Root.SubFolders.Add(rolesFolder);
|
||||
__instance.Root.SubFolders.Add(modifiersFolder);
|
||||
|
||||
__instance.GoToRoot();
|
||||
}
|
||||
@@ -277,39 +284,21 @@ public static class TaskAdderPatch
|
||||
}
|
||||
}
|
||||
|
||||
if (ModsFolders.TryGetValue(taskFolder.FolderName, out var guid))
|
||||
var split = taskFolder.name.Split(':');
|
||||
if (split.Length == 2)
|
||||
{
|
||||
var plugin = MiraPluginManager.GetPluginByGuid(guid);
|
||||
for (var m = 0; m < plugin.CustomRoles.Count; m++)
|
||||
var pluginId = split[0];
|
||||
var folderName = split[1];
|
||||
|
||||
if (MiraPluginManager.GetPluginByGuid(pluginId) is { } plugin)
|
||||
{
|
||||
var roleBehaviour = plugin.CustomRoles.ElementAt(m).Value;
|
||||
if (roleBehaviour.Role == RoleTypes.ImpostorGhost || roleBehaviour.Role == RoleTypes.CrewmateGhost ||
|
||||
(roleBehaviour is ICustomRole customRole && !customRole.Configuration.ShowInFreeplay))
|
||||
if (folderName == "Roles(Clone)")
|
||||
{
|
||||
continue;
|
||||
PluginRoles(__instance, plugin, ref num, ref num2, ref num3);
|
||||
}
|
||||
|
||||
var taskAddButton2 = Object.Instantiate(__instance.RoleButton);
|
||||
taskAddButton2.SafePositionWorld = __instance.SafePositionWorld;
|
||||
taskAddButton2.Text.text = "Be_" + roleBehaviour.NiceName + ".exe";
|
||||
__instance.AddFileAsChildCustom(taskAddButton2, ref num, ref num2, ref num3);
|
||||
taskAddButton2.Role = roleBehaviour;
|
||||
if (taskAddButton2.Button == null)
|
||||
else if (folderName == "Modifiers(Clone)")
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
ControllerManager.Instance.AddSelectableUiElement(taskAddButton2.Button);
|
||||
switch (m)
|
||||
{
|
||||
case 0 when __instance.restorePreviousSelectionFound != null:
|
||||
ControllerManager.Instance.SetDefaultSelection(__instance.restorePreviousSelectionFound);
|
||||
__instance.restorePreviousSelectionByFolderName = string.Empty;
|
||||
__instance.restorePreviousSelectionFound = null;
|
||||
break;
|
||||
case 0:
|
||||
ControllerManager.Instance.SetDefaultSelection(taskAddButton2.Button);
|
||||
break;
|
||||
PluginModifiers(__instance, plugin, ref num, ref num2, ref num3);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -336,4 +325,78 @@ public static class TaskAdderPatch
|
||||
ControllerManager.Instance.SetBackButton(__instance.FolderBackButton);
|
||||
return false;
|
||||
}
|
||||
|
||||
private static void PluginModifiers(
|
||||
TaskAdderGame instance,
|
||||
MiraPluginInfo plugin,
|
||||
ref float num,
|
||||
ref float num2,
|
||||
ref float num3)
|
||||
{
|
||||
for (var m = 0; m < plugin.Modifiers.Count; m++)
|
||||
{
|
||||
var modifier = plugin.Modifiers[m];
|
||||
if (!modifier.ShowInFreeplay)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var taskAddButton = Object.Instantiate(instance.RoleButton);
|
||||
taskAddButton.name = modifier.ModifierId.ToString();
|
||||
taskAddButton.role = null;
|
||||
taskAddButton.MyTask = null;
|
||||
taskAddButton.SafePositionWorld = instance.SafePositionWorld;
|
||||
taskAddButton.Text.text = modifier.ModifierName;
|
||||
instance.AddFileAsChildCustom(taskAddButton, ref num, ref num2, ref num3);
|
||||
|
||||
ControllerManager.Instance.AddSelectableUiElement(taskAddButton.Button);
|
||||
switch (m)
|
||||
{
|
||||
case 0 when instance.restorePreviousSelectionFound != null:
|
||||
ControllerManager.Instance.SetDefaultSelection(instance.restorePreviousSelectionFound);
|
||||
instance.restorePreviousSelectionByFolderName = string.Empty;
|
||||
instance.restorePreviousSelectionFound = null;
|
||||
break;
|
||||
case 0:
|
||||
ControllerManager.Instance.SetDefaultSelection(taskAddButton.Button);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void PluginRoles(TaskAdderGame instance, MiraPluginInfo plugin, ref float num, ref float num2, ref float num3)
|
||||
{
|
||||
for (var m = 0; m < plugin.CustomRoles.Count; m++)
|
||||
{
|
||||
var roleBehaviour = plugin.CustomRoles.ElementAt(m).Value;
|
||||
if (roleBehaviour.Role == RoleTypes.ImpostorGhost || roleBehaviour.Role == RoleTypes.CrewmateGhost ||
|
||||
roleBehaviour is ICustomRole { Configuration.ShowInFreeplay: false })
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var taskAddButton2 = Object.Instantiate(instance.RoleButton);
|
||||
taskAddButton2.SafePositionWorld = instance.SafePositionWorld;
|
||||
taskAddButton2.Text.text = "Be_" + roleBehaviour.NiceName + ".exe";
|
||||
instance.AddFileAsChildCustom(taskAddButton2, ref num, ref num2, ref num3);
|
||||
taskAddButton2.Role = roleBehaviour;
|
||||
if (taskAddButton2.Button == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
ControllerManager.Instance.AddSelectableUiElement(taskAddButton2.Button);
|
||||
switch (m)
|
||||
{
|
||||
case 0 when instance.restorePreviousSelectionFound != null:
|
||||
ControllerManager.Instance.SetDefaultSelection(instance.restorePreviousSelectionFound);
|
||||
instance.restorePreviousSelectionByFolderName = string.Empty;
|
||||
instance.restorePreviousSelectionFound = null;
|
||||
break;
|
||||
case 0:
|
||||
ControllerManager.Instance.SetDefaultSelection(taskAddButton2.Button);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5,6 +5,7 @@ using MiraAPI.GameOptions;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using MiraAPI.Hud;
|
||||
using MiraAPI.Modifiers;
|
||||
|
||||
namespace MiraAPI.PluginLoading;
|
||||
|
||||
@@ -61,6 +62,8 @@ public class MiraPluginInfo
|
||||
|
||||
internal List<IModdedOption> Options { get; } = [];
|
||||
|
||||
internal List<BaseModifier> Modifiers { get; } = [];
|
||||
|
||||
internal Dictionary<ushort, RoleBehaviour> CustomRoles { get; } = [];
|
||||
|
||||
internal Dictionary<int, CustomGameMode> GameModes { get; } = [];
|
||||
|
||||
@@ -48,7 +48,7 @@ public sealed class MiraPluginManager
|
||||
continue;
|
||||
}
|
||||
|
||||
if (RegisterModifier(type))
|
||||
if (RegisterModifier(type, info))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@@ -91,9 +91,9 @@ public sealed class MiraPluginManager
|
||||
/// </summary>
|
||||
/// <param name="pluginId">The plugin GUID.</param>
|
||||
/// <returns>A MiraPluginInfo.</returns>
|
||||
public static MiraPluginInfo GetPluginByGuid(string pluginId)
|
||||
public static MiraPluginInfo? GetPluginByGuid(string pluginId)
|
||||
{
|
||||
return Instance._registeredPlugins.Values.First(plugin => plugin.PluginId == pluginId);
|
||||
return Instance._registeredPlugins.Values.FirstOrDefault(plugin => plugin.PluginId == pluginId);
|
||||
}
|
||||
|
||||
private static bool RegisterOptions(Type type, MiraPluginInfo pluginInfo)
|
||||
@@ -199,11 +199,11 @@ public sealed class MiraPluginManager
|
||||
}
|
||||
}
|
||||
|
||||
private static bool RegisterModifier(Type type)
|
||||
private static bool RegisterModifier(Type type, MiraPluginInfo info)
|
||||
{
|
||||
try
|
||||
{
|
||||
return ModifierManager.RegisterModifier(type);
|
||||
return ModifierManager.RegisterModifier(type, info);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
using System;
|
||||
using BepInEx.Configuration;
|
||||
using BepInEx.Configuration;
|
||||
using MiraAPI.Modifiers;
|
||||
using MiraAPI.PluginLoading;
|
||||
using MiraAPI.Utilities;
|
||||
|
||||
Reference in new issue
Block a user