mirror of
https://github.com/All-Of-Us-Mods/MiraAPI.git
synced 2026-10-21 05:37:32 +00:00
Compare commits
6
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
834d1d878e | ||
|
|
790b37e8d3 | ||
|
|
dfa8b29710 | ||
|
|
2c0042e6a8 | ||
|
|
70f63f8b16 | ||
|
|
03a3733966 |
No files matched your search
+2
-2
@@ -2,12 +2,12 @@
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Reactor" Version="2.3.1" />
|
||||
<PackageReference Include="BepInEx.Unity.IL2CPP" Version="6.0.0-be.735" Private="false" ExcludeAssets="runtime;native" />
|
||||
<PackageReference Include="AmongUs.GameLibs.Steam" Version="2025.4.15" PrivateAssets="all" />
|
||||
<PackageReference Include="AmongUs.GameLibs.Steam" Version="2025.9.9" PrivateAssets="all" />
|
||||
|
||||
<PackageReference Include="BepInEx.AutoPlugin" Version="1.1.0" PrivateAssets="all" />
|
||||
<PackageReference Include="BepInEx.IL2CPP.MSBuild" Version="2.1.0-rc.1" PrivateAssets="all" ExcludeAssets="runtime" />
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
<Target Name="Copy" AfterTargets="Build" Condition="'$(AmongUs)' != ''">
|
||||
<Copy SourceFiles="$(TargetPath)" DestinationFolder="$(AmongUs)/BepInEx/plugins/" UseSymboliclinksIfPossible="true" />
|
||||
</Target>
|
||||
|
||||
@@ -8,7 +8,6 @@ using MiraAPI.Patches;
|
||||
using MiraAPI.Utilities;
|
||||
using MiraAPI.Utilities.Assets;
|
||||
using Reactor.Utilities;
|
||||
using Rewired;
|
||||
using TMPro;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Events;
|
||||
@@ -76,7 +75,7 @@ public abstract class CustomActionButton
|
||||
/// <summary>
|
||||
/// Gets the keybind for this button. If null, no keybind will be added.
|
||||
/// </summary>
|
||||
public virtual BaseKeybind? Keybind => null;
|
||||
public virtual MiraKeybind? Keybind => null;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the button's text outline color.
|
||||
@@ -495,8 +494,7 @@ public abstract class CustomActionButton
|
||||
{
|
||||
KeybindText.text = Keybind.CurrentKey.ToString();
|
||||
KeybindIcon?.SetActive(ActiveInputManager.currentControlType == ActiveInputManager.InputType.Keyboard &&
|
||||
LocalSettingsTabSingleton<MiraApiSettings>.Instance.ShowKeybinds.Value &&
|
||||
Keybind.CurrentKey != KeyboardKeyCode.None);
|
||||
LocalSettingsTabSingleton<MiraApiSettings>.Instance.ShowKeybinds.Value);
|
||||
}
|
||||
|
||||
if (Timer >= 0)
|
||||
|
||||
@@ -1,72 +0,0 @@
|
||||
using System;
|
||||
using Rewired;
|
||||
|
||||
namespace MiraAPI.Keybinds;
|
||||
|
||||
/// <summary>
|
||||
/// Base keybind class.
|
||||
/// </summary>
|
||||
public class BaseKeybind
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the Rewired <see cref="InputAction"/> assinged for this keybind.
|
||||
/// </summary>
|
||||
public InputAction? RewiredInputAction { get; internal set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the unique identifier for this keybind. Used in Rewired.
|
||||
/// </summary>
|
||||
public string Id { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the currently assigned keycode.
|
||||
/// </summary>
|
||||
public KeyboardKeyCode CurrentKey => KeybindUtils.GetKeycodeByKeybind(this);
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the handler of the keybind. Invoked when the keybind is activated.
|
||||
/// </summary>
|
||||
protected Action Handler { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="BaseKeybind"/> class.
|
||||
/// </summary>
|
||||
/// <param name="id">The unique identifier for this keybind.</param>
|
||||
public BaseKeybind(string id)
|
||||
{
|
||||
Id = id;
|
||||
Handler = () => { };
|
||||
}
|
||||
|
||||
public BaseKeybind()
|
||||
{
|
||||
Handler = () => { };
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Triggers the keybind, invoking its handler.
|
||||
/// </summary>
|
||||
public void Invoke()
|
||||
{
|
||||
Handler.Invoke();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds an <see cref="Action"/> that will be invoked when the keybind is used.
|
||||
/// </summary>
|
||||
/// <param name="action">The <see cref="Action"/> to add.</param>
|
||||
public void OnActivate(Action action)
|
||||
{
|
||||
Handler += action;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes an <see cref="Action"/> that would be invoked when the keybind is used.
|
||||
/// Not recommended to use - add checks in the method added in <see cref="OnActivate"/> itself rather than removing it from the keybind.
|
||||
/// </summary>
|
||||
/// <param name="action">The <see cref="Action"/> to remove.</param>
|
||||
public void RemoveOnActivate(Action action)
|
||||
{
|
||||
Handler -= action;
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Il2CppInterop.Runtime.Attributes;
|
||||
using MiraAPI.Utilities;
|
||||
using Reactor.Utilities;
|
||||
using Rewired;
|
||||
@@ -18,9 +17,6 @@ public static class KeybindManager
|
||||
/// </summary>
|
||||
public static List<MiraKeybind> Keybinds { get; } = new();
|
||||
|
||||
[HideFromIl2Cpp]
|
||||
internal static Dictionary<Type, VanillaKeybind> VanillaKeybinds { get; set; } = [];
|
||||
|
||||
internal static void RewiredInit()
|
||||
{
|
||||
try
|
||||
|
||||
@@ -18,11 +18,11 @@ public static class KeybindUtils
|
||||
/// </summary>
|
||||
/// <param name="keybind">The keybind to get the keycode from.</param>
|
||||
/// <returns>The currently assigned keycode.</returns>
|
||||
public static KeyboardKeyCode GetKeycodeByKeybind(BaseKeybind keybind)
|
||||
public static KeyboardKeyCode? GetKeycodeByKeybind(MiraKeybind keybind)
|
||||
{
|
||||
if (keybind.RewiredInputAction == null)
|
||||
{
|
||||
return KeyboardKeyCode.None;
|
||||
return null;
|
||||
}
|
||||
|
||||
return GetKeycodeByActionId(keybind.RewiredInputAction.id);
|
||||
@@ -34,29 +34,10 @@ public static class KeybindUtils
|
||||
/// <param name="actionId">The action ID.</param>
|
||||
/// <returns>The keyboard keycode.</returns>
|
||||
public static KeyboardKeyCode GetKeycodeByActionId(int actionId)
|
||||
{
|
||||
return GetActionElementMap(actionId)?.keyboardKeyCode ?? KeyboardKeyCode.None;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a <see cref="ActionElementMap"/> by id with ReInput.
|
||||
/// </summary>
|
||||
/// <param name="actionId">The action ID.</param>
|
||||
/// <returns>The keyboard keycode.</returns>
|
||||
public static ActionElementMap? GetActionElementMap(int actionId)
|
||||
{
|
||||
var player = ReInput.players.GetPlayer(0);
|
||||
return player.controllers.maps.GetFirstElementMapWithAction(ControllerType.Keyboard, actionId, false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets an <see cref="InputAction"/> by id.
|
||||
/// </summary>
|
||||
/// <param name="id">The action identifier name.</param>
|
||||
/// <returns>The keyboard keycode.</returns>
|
||||
public static InputAction? GetInputActionById(int id)
|
||||
{
|
||||
return RewiredInputManager?.userData?.GetActionById(id);
|
||||
return player.controllers.maps.GetFirstElementMapWithAction(ControllerType.Keyboard, actionId, false)?
|
||||
.keyboardKeyCode ?? KeyboardKeyCode.None;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
using System.Globalization;
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using Reactor.Utilities;
|
||||
using Rewired;
|
||||
|
||||
namespace MiraAPI.Keybinds;
|
||||
@@ -6,28 +8,48 @@ namespace MiraAPI.Keybinds;
|
||||
/// <summary>
|
||||
/// Represents a registered keybind.
|
||||
/// </summary>
|
||||
public class MiraKeybind : BaseKeybind
|
||||
public class MiraKeybind
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets name of the keybind
|
||||
/// </summary>
|
||||
public string Name { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the unique identifier for this keybind. Used in Rewired.
|
||||
/// </summary>
|
||||
public string Id { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the default keycode of this keybind.
|
||||
/// </summary>
|
||||
public KeyboardKeyCode DefaultKey { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the modifier keys assigned to this keybind.
|
||||
/// Gets a value indicating whether this keybind should be checked for conflicts with other exclusive keybinds using the same key.
|
||||
/// </summary>
|
||||
public bool Exclusive { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the modifier keys assinged to this keybind.
|
||||
/// Due to Rewired limitations, there can only be 3 modifier keys.
|
||||
/// </summary>
|
||||
public ModifierKey[] ModifierKeys { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether this keybind should be checked for conflicts with other exclusive keybinds using the same key.
|
||||
/// Gets the Rewired <see cref="InputAction"/> assinged for this keybind.
|
||||
/// </summary>
|
||||
public bool Exclusive { get; }
|
||||
public InputAction? RewiredInputAction { get; internal set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the currently assigned keycode.
|
||||
/// </summary>
|
||||
public KeyboardKeyCode CurrentKey => KeybindUtils.GetKeycodeByKeybind(this) ?? KeyboardKeyCode.None;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the handler of the keybind. Invoked when the keybind is activated.
|
||||
/// </summary>
|
||||
private Action Handler { get; set; }
|
||||
|
||||
internal string? SourcePluginName { get; set; }
|
||||
|
||||
@@ -42,12 +64,14 @@ public class MiraKeybind : BaseKeybind
|
||||
string name,
|
||||
KeyboardKeyCode? defaultKeycode,
|
||||
ModifierKey[]? modifierKeys = null,
|
||||
bool exclusive = true) : base(name.ToLower(CultureInfo.InvariantCulture).Replace(' ', '_'))
|
||||
bool exclusive = true)
|
||||
{
|
||||
Name = name;
|
||||
Id = name.ToLower(CultureInfo.InvariantCulture).Replace(' ', '_');
|
||||
DefaultKey = defaultKeycode ?? KeyboardKeyCode.None;
|
||||
ModifierKeys = modifierKeys ?? [];
|
||||
ModifierKeys = modifierKeys ?? Array.Empty<ModifierKey>();
|
||||
Exclusive = exclusive;
|
||||
Handler = () => { };
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
@@ -55,4 +79,31 @@ public class MiraKeybind : BaseKeybind
|
||||
{
|
||||
return $"{Name} ({Id})";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Triggers the keybind, invoking its handler.
|
||||
/// </summary>
|
||||
public void Invoke()
|
||||
{
|
||||
Handler.Invoke();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds an <see cref="Action"/> that will be invoked when the keybind is used.
|
||||
/// </summary>
|
||||
/// <param name="action">The <see cref="Action"/> to add.</param>
|
||||
public void OnActivate(Action action)
|
||||
{
|
||||
Handler += action;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes an <see cref="Action"/> that would be invoked when the keybind is used.
|
||||
/// Not recommended to use - add checks in the method added in <see cref="OnActivate"/> itself rather than removing it from the keybind.
|
||||
/// </summary>
|
||||
/// <param name="action">The <see cref="Action"/> to remove.</param>
|
||||
public void RemoveOnActivate(Action action)
|
||||
{
|
||||
Handler -= action;
|
||||
}
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
using Rewired;
|
||||
|
||||
namespace MiraAPI.Keybinds;
|
||||
|
||||
/// <summary>
|
||||
/// Represents a vanilla keybind.
|
||||
/// </summary>
|
||||
public class VanillaKeybind : BaseKeybind
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the <see cref="ActionButton"/> this keybind is binded to.
|
||||
/// </summary>
|
||||
public ActionButton? Button { get; internal set; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="VanillaKeybind"/> class.
|
||||
/// </summary>
|
||||
/// <param name="id">The keybind id.</param>
|
||||
public VanillaKeybind(int id)
|
||||
{
|
||||
RewiredInputAction = KeybindUtils.GetInputActionById(id);
|
||||
Id = RewiredInputAction?.name;
|
||||
}
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
namespace MiraAPI.Keybinds;
|
||||
|
||||
/// <summary>
|
||||
/// Singleton for getting a vanilla keybind by <see cref="ActionButton"/>.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">ActionButton type.</typeparam>
|
||||
public static class VanillaKeybinding<T> where T : ActionButton
|
||||
{
|
||||
private static VanillaKeybind? _instance;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the instance of the option group.
|
||||
/// </summary>
|
||||
#pragma warning disable CA1000
|
||||
public static VanillaKeybind Instance => _instance ??= KeybindManager.VanillaKeybinds[typeof(T)];
|
||||
#pragma warning restore CA1000
|
||||
}
|
||||
@@ -1,7 +1,6 @@
|
||||
using BepInEx.Configuration;
|
||||
using MiraAPI.LocalSettings;
|
||||
using MiraAPI.LocalSettings.Attributes;
|
||||
using MiraAPI.Utilities;
|
||||
using MiraAPI.Utilities.Assets;
|
||||
|
||||
namespace MiraAPI;
|
||||
@@ -27,26 +26,14 @@ public class MiraApiSettings(ConfigFile config) : LocalSettingsTab(config)
|
||||
[LocalToggleSetting]
|
||||
public ConfigEntry<bool> ModifiersHudLeftSide { get; private set; } = config.Bind("Displays", "Show Modifiers HUD on Left Side", false);
|
||||
|
||||
/// <summary>
|
||||
/// Gets whether vents and their connections appear on the map.
|
||||
/// </summary>
|
||||
[LocalToggleSetting]
|
||||
public ConfigEntry<bool> ShowVentsOnMap { get; private set; } = config.Bind("Displays", "Show Vent Layout on Map", true);
|
||||
|
||||
/// <summary>
|
||||
/// Gets whether cooldowns for buttons below 10 seconds appear with decimals.
|
||||
/// </summary>
|
||||
[LocalToggleSetting]
|
||||
public ConfigEntry<bool> PreciseCooldowns { get; private set; } = config.Bind("Buttons", "Precise Button Cooldowns Under 10s", false);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the size of ability buttons in-game.
|
||||
/// </summary>
|
||||
[LocalSliderSetting(min: 0.5f, max: 1.5f, displayValue: true, formatString: "0.00", suffixType: MiraNumberSuffixes.Multiplier)]
|
||||
public ConfigEntry<float> ButtonUiScale { get; private set; } = config.Bind("Buttons", "Button Scale Factor", 0.8f);
|
||||
|
||||
/// <summary>
|
||||
/// Gets whether to show keybinds in the control mapper.
|
||||
/// </summary>
|
||||
public ConfigEntry<bool> ShowKeybinds { get; private set; } = config.Bind("Keybinds", "Show Keybinds in Control Mapper", true);
|
||||
|
||||
/// <summary>
|
||||
/// Gets whether to apply cosmetic changes to the TaskAdder.
|
||||
/// </summary>
|
||||
[LocalToggleSetting]
|
||||
public ConfigEntry<bool> PrettyTaskAdder { get; private set; } = config.Bind("Freeplay", "Pretty Task Laptop", true);
|
||||
}
|
||||
@@ -222,7 +222,7 @@ public static class CustomMurderRpc
|
||||
|
||||
if (createDeadBody)
|
||||
{
|
||||
deadBody = Object.Instantiate(GameManager.Instance.DeadBodyPrefab);
|
||||
deadBody = Object.Instantiate(GameManager.Instance.deadBodyPrefab[0]);
|
||||
deadBody.enabled = false;
|
||||
deadBody.ParentId = target.PlayerId;
|
||||
deadBody.bodyRenderers.ToList().ForEach(target.SetPlayerMaterialColors);
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using AmongUs.GameOptions;
|
||||
using System.Text;
|
||||
using HarmonyLib;
|
||||
using MiraAPI.LocalSettings;
|
||||
using MiraAPI.Modifiers;
|
||||
using MiraAPI.Modifiers.Types;
|
||||
using MiraAPI.PluginLoading;
|
||||
using MiraAPI.Roles;
|
||||
using MiraAPI.Utilities;
|
||||
using MiraAPI.Utilities.Assets;
|
||||
using TMPro;
|
||||
using Reactor.Utilities.Extensions;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Events;
|
||||
using UnityEngine.UI;
|
||||
@@ -21,6 +21,8 @@ namespace MiraAPI.Patches.Freeplay;
|
||||
internal static class TaskAdderPatches
|
||||
{
|
||||
private static Scroller _scroller = null!;
|
||||
private static Dictionary<string, TaskFolder> folders = new();
|
||||
|
||||
[HarmonyPostfix]
|
||||
[HarmonyPatch(nameof(TaskAdderGame.Begin))]
|
||||
public static void AddRolesFolder(TaskAdderGame __instance)
|
||||
@@ -60,46 +62,80 @@ internal static class TaskAdderPatches
|
||||
__instance.RoleButton.GetComponent<PassiveButton>().ClickMask = collider;
|
||||
__instance.RootFolderPrefab.GetComponent<PassiveButton>().ClickMask = collider;
|
||||
__instance.RootFolderPrefab.gameObject.SetActive(false);
|
||||
|
||||
__instance.TaskParent = inner.transform;
|
||||
|
||||
var rolesFolder = Object.Instantiate(__instance.RootFolderPrefab, _scroller.Inner);
|
||||
rolesFolder.gameObject.SetActive(false);
|
||||
rolesFolder.FolderName = "Roles";
|
||||
rolesFolder.name = "RolesFolder";
|
||||
var crewmateFolder = __instance.Root.SubFolders.ToArray().FirstOrDefault(x => x.FolderName == "Crewmate")!;
|
||||
var impostorFolder = __instance.Root.SubFolders.ToArray().FirstOrDefault(x => x.FolderName == "Impostor")!;
|
||||
var neutralFolder = __instance.CreateFolder("Neutral", __instance.Root, 2, Color.gray);
|
||||
var modifiersFolder = __instance.CreateFolder("Modifiers", __instance.Root, 0, Color.blue);
|
||||
|
||||
var modifiersFolder = Object.Instantiate(__instance.RootFolderPrefab, _scroller.Inner);
|
||||
modifiersFolder.gameObject.SetActive(false);
|
||||
modifiersFolder.FolderName = "Modifiers";
|
||||
modifiersFolder.name = "ModifiersFolder";
|
||||
folders.Clear();
|
||||
folders.Add("Crewmate", crewmateFolder);
|
||||
folders.Add("Impostor", impostorFolder);
|
||||
folders.Add("Neutral", neutralFolder);
|
||||
folders.Add("Modifiers", modifiersFolder);
|
||||
|
||||
int folderIdx = 3;
|
||||
foreach (var plugin in MiraPluginManager.Instance.RegisteredPlugins)
|
||||
{
|
||||
if (plugin.InternalRoles.Any(x => x.Value is ICustomRole { Configuration.ShowInFreeplay: true }))
|
||||
var pluginFolders = new Dictionary<string, TaskFolder>();
|
||||
|
||||
foreach (var role in plugin.InternalRoles
|
||||
.Where(x => x.Value is ICustomRole { Configuration.ShowInFreeplay: true })
|
||||
.Select(x => x.Value))
|
||||
{
|
||||
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 customRole = role as ICustomRole;
|
||||
var folderName = customRole!.Configuration.FreeplayFolder;
|
||||
if (!folders.TryGetValue(folderName, out var teamFolder))
|
||||
{
|
||||
teamFolder = __instance.CreateFolder(folderName, __instance.Root, folderIdx++, customRole.IntroConfiguration?.IntroTeamColor ?? Color.gray);
|
||||
folders.Add(folderName, teamFolder);
|
||||
}
|
||||
|
||||
if (!pluginFolders.TryGetValue(folderName, out var pluginFolder))
|
||||
{
|
||||
pluginFolder = __instance.CreateFolder(plugin.PluginInfo.Metadata.Name, teamFolder);
|
||||
pluginFolders.Add(folderName, teamFolder);
|
||||
}
|
||||
|
||||
pluginFolder.RoleChildren.Add(role);
|
||||
}
|
||||
|
||||
if (plugin.InternalModifiers.Exists(x => x.ShowInFreeplay))
|
||||
{
|
||||
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.CreateFolder(plugin.PluginInfo.Metadata.Name, modifiersFolder)
|
||||
.gameObject.name = plugin.PluginId;
|
||||
}
|
||||
}
|
||||
|
||||
__instance.Root.SubFolders.Add(rolesFolder);
|
||||
__instance.Root.SubFolders.Add(modifiersFolder);
|
||||
// Modifier folder at the end
|
||||
__instance.Root.SubFolders.Insert(folderIdx, modifiersFolder);
|
||||
|
||||
__instance.GoToRoot();
|
||||
}
|
||||
|
||||
private static TaskFolder CreateFolder(this TaskAdderGame instance, string name, TaskFolder parent, int idx = -1, Color? color = null)
|
||||
{
|
||||
var folder = Object.Instantiate(instance.RootFolderPrefab, instance.transform);
|
||||
folder.gameObject.SetActive(false);
|
||||
folder.FolderName = name;
|
||||
folder.SetCustomColor(color ?? new Color(0.937f, 0.811f, 0.592f));
|
||||
folder.name = name + "Folder";
|
||||
if (idx == -1)
|
||||
parent.SubFolders.Add(folder);
|
||||
else if (idx > 0)
|
||||
parent.SubFolders.Insert(idx, folder);
|
||||
return folder;
|
||||
}
|
||||
|
||||
private static void SetCustomColor(this TaskFolder folder, Color color)
|
||||
{
|
||||
folder.currentFolderColor = color;
|
||||
folder.folderSpriteRenderer.color = color;
|
||||
folder.buttonRolloverHandler.OutColor = color;
|
||||
folder.buttonRolloverHandler.UnselectedColor = color;
|
||||
}
|
||||
|
||||
private static void AddFileAsChildCustom(
|
||||
this TaskAdderGame instance,
|
||||
TaskAddButton item,
|
||||
@@ -122,40 +158,46 @@ internal static class TaskAdderPatches
|
||||
instance.ActiveItems.Add(item.transform);
|
||||
}
|
||||
|
||||
private static bool IsChildOf(this TaskFolder child, TaskFolder parent) => parent.SubFolders
|
||||
.ToArray()
|
||||
.Any(x => x.FolderName == child.FolderName);
|
||||
|
||||
// yes it might be crazy patching the entire method, but i tried so many other methods and only this works :cry:
|
||||
// true -chip
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(nameof(TaskAdderGame.ShowFolder))]
|
||||
public static bool ShowPatch(TaskAdderGame __instance, TaskFolder taskFolder)
|
||||
{
|
||||
var stringBuilder = new Il2CppSystem.Text.StringBuilder(64);
|
||||
StringBuilder stringBuilder = new StringBuilder(64);
|
||||
__instance.Hierarchy.Add(taskFolder);
|
||||
for (var i = 0; i < __instance.Hierarchy.Count; i++)
|
||||
foreach (var t in __instance.Hierarchy)
|
||||
{
|
||||
stringBuilder.Append(__instance.Hierarchy.ToArray()[i].FolderName);
|
||||
stringBuilder.Append("\\");
|
||||
stringBuilder.Append(t.FolderName);
|
||||
stringBuilder.Append('\\');
|
||||
}
|
||||
|
||||
__instance.PathText.text = stringBuilder.ToString();
|
||||
for (var j = 0; j < __instance.ActiveItems.Count; j++)
|
||||
var prettyEnabled = LocalSettingsTabSingleton<MiraApiSettings>.Instance.PrettyTaskAdder.Value;
|
||||
if (prettyEnabled)
|
||||
{
|
||||
Object.Destroy(__instance.ActiveItems.ToArray()[j].gameObject);
|
||||
__instance.PathText.fontSizeMin = 3;
|
||||
__instance.PathText.fontSizeMax = 3;
|
||||
__instance.transform.FindChild("TitleText_TMP")?.gameObject.DestroyImmediate();
|
||||
}
|
||||
|
||||
__instance.ActiveItems.ToArray().Do(x => x.gameObject.Destroy());
|
||||
__instance.ActiveItems.Clear();
|
||||
var num = 0f;
|
||||
var num2 = 0f;
|
||||
var num3 = 0f;
|
||||
for (var k = 0; k < taskFolder.SubFolders.Count; k++)
|
||||
{
|
||||
var taskFolder2 = Object.Instantiate(taskFolder.SubFolders.ToArray()[k], __instance.TaskParent);
|
||||
var folderTransform = taskFolder2.transform;
|
||||
|
||||
float num = 0f;
|
||||
float num2 = 0f;
|
||||
float num3 = 0f;
|
||||
foreach (var t in taskFolder.SubFolders)
|
||||
{
|
||||
TaskFolder taskFolder2 = Object.Instantiate(t, __instance.TaskParent);
|
||||
taskFolder2.gameObject.SetActive(true);
|
||||
taskFolder2.Parent = __instance;
|
||||
|
||||
folderTransform.localPosition = new Vector3(num, num2, 0f);
|
||||
folderTransform.localScale = Vector3.one;
|
||||
num3 = Mathf.Max(num3, taskFolder2.Text.bounds.size.y + 1.3f);
|
||||
taskFolder2.transform.localPosition = new Vector3(num, num2, 0f);
|
||||
taskFolder2.transform.localScale = Vector3.one;
|
||||
num3 = Mathf.Max(num3, taskFolder2.Text.bounds.size.y + 1.1f);
|
||||
num += __instance.folderWidth;
|
||||
if (num > __instance.lineWidth)
|
||||
{
|
||||
@@ -164,242 +206,74 @@ internal static class TaskAdderPatches
|
||||
num3 = 0f;
|
||||
}
|
||||
|
||||
__instance.ActiveItems.Add(folderTransform);
|
||||
if (!taskFolder2 || !taskFolder2.Button)
|
||||
__instance.ActiveItems.Add(taskFolder2.transform);
|
||||
if (taskFolder2 != null && taskFolder2.Button != null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
ControllerManager.Instance.AddSelectableUiElement(taskFolder2.Button);
|
||||
if (!string.IsNullOrEmpty(__instance.restorePreviousSelectionByFolderName) &&
|
||||
taskFolder2.FolderName.Equals(__instance.restorePreviousSelectionByFolderName, StringComparison.Ordinal))
|
||||
{
|
||||
__instance.restorePreviousSelectionFound = taskFolder2.Button;
|
||||
ControllerManager.Instance.AddSelectableUiElement(taskFolder2.Button);
|
||||
}
|
||||
}
|
||||
|
||||
var flag = false;
|
||||
var list = taskFolder.Children.ToArray().OrderBy(t => t.TaskType).ToList();
|
||||
|
||||
for (var l = 0; l < list.Count; l++)
|
||||
var list = taskFolder.TaskChildren
|
||||
.ToArray()
|
||||
.OrderBy(x => x.TaskType)
|
||||
.ToArray();
|
||||
foreach (var task in list)
|
||||
{
|
||||
var taskAddButton = Object.Instantiate(__instance.TaskPrefab);
|
||||
taskAddButton.MyTask = list.ToArray()[l];
|
||||
switch (taskAddButton.MyTask.TaskType)
|
||||
TaskAddButton taskAddButton = Object.Instantiate(__instance.TaskPrefab);
|
||||
taskAddButton.MyTask = task;
|
||||
switch (task.TaskType)
|
||||
{
|
||||
case TaskTypes.DivertPower:
|
||||
{
|
||||
var targetSystem = taskAddButton.MyTask.Cast<DivertPowerTask>().TargetSystem;
|
||||
taskAddButton.Text.text = TranslationController.Instance.GetString(
|
||||
StringNames.DivertPowerTo,
|
||||
TranslationController.Instance.GetString(targetSystem));
|
||||
break;
|
||||
}
|
||||
{
|
||||
var targetSystem = task.Cast<DivertPowerTask>().TargetSystem;
|
||||
taskAddButton.Text.text = TranslationController.Instance.GetString(
|
||||
StringNames.DivertPowerTo,
|
||||
TranslationController.Instance.GetString(targetSystem));
|
||||
break;
|
||||
}
|
||||
case TaskTypes.FixWeatherNode:
|
||||
{
|
||||
var nodeId = taskAddButton.MyTask.Cast<WeatherNodeTask>().NodeId;
|
||||
taskAddButton.Text.text =
|
||||
TranslationController.Instance.GetString(
|
||||
StringNames.FixWeatherNode) + " " +
|
||||
TranslationController.Instance.GetString(
|
||||
WeatherSwitchGame.ControlNames[nodeId]);
|
||||
break;
|
||||
}
|
||||
{
|
||||
var nodeId = task.Cast<WeatherNodeTask>().NodeId;
|
||||
taskAddButton.Text.text =
|
||||
TranslationController.Instance.GetString(
|
||||
StringNames.FixWeatherNode) + " " +
|
||||
TranslationController.Instance.GetString(
|
||||
WeatherSwitchGame.ControlNames[nodeId]);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
taskAddButton.Text.text =
|
||||
TranslationController.Instance.GetString(taskAddButton.MyTask.TaskType);
|
||||
TranslationController.Instance.GetString(task.TaskType);
|
||||
break;
|
||||
}
|
||||
|
||||
__instance.AddFileAsChildCustom(taskAddButton, ref num, ref num2, ref num3);
|
||||
if (taskAddButton.Button == null)
|
||||
if (taskAddButton != null && taskAddButton.Button != null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
ControllerManager.Instance.AddSelectableUiElement(taskAddButton.Button);
|
||||
if (__instance.Hierarchy.Count == 1 || flag)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var component =
|
||||
ControllerManager.Instance.CurrentUiState.CurrentSelection.GetComponent<TaskFolder>();
|
||||
if (component != null)
|
||||
{
|
||||
__instance.restorePreviousSelectionByFolderName = component.FolderName;
|
||||
}
|
||||
|
||||
ControllerManager.Instance.SetDefaultSelection(taskAddButton.Button);
|
||||
flag = true;
|
||||
}
|
||||
|
||||
if (taskFolder.FolderName == "Roles")
|
||||
{
|
||||
for (var m = 0; m < RoleManager.Instance.AllRoles.Length; m++)
|
||||
{
|
||||
var roleBehaviour = RoleManager.Instance.AllRoles[m];
|
||||
if (roleBehaviour.Role == RoleTypes.ImpostorGhost || roleBehaviour.Role == RoleTypes.CrewmateGhost ||
|
||||
CustomRoleManager.CustomRoles.ContainsKey((ushort)roleBehaviour.Role))
|
||||
{
|
||||
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;
|
||||
}
|
||||
ControllerManager.Instance.AddSelectableUiElement(taskAddButton.Button, false);
|
||||
}
|
||||
}
|
||||
|
||||
if (taskFolder)
|
||||
var roleChildren = taskFolder.RoleChildren
|
||||
.ToArray()
|
||||
.Where(x => !(taskFolder.IsChildOf(__instance.Root) && x is ICustomRole))
|
||||
.ToArray();
|
||||
foreach (var role in roleChildren)
|
||||
{
|
||||
var split = taskFolder.name.Split(':');
|
||||
if (split.Length == 2)
|
||||
TaskAddButton roleAddButton = Object.Instantiate(__instance.RoleButton);
|
||||
roleAddButton.SafePositionWorld = __instance.SafePositionWorld;
|
||||
roleAddButton.Text.text = prettyEnabled ? role.NiceName : "Be_" + role.NiceName + ".exe";
|
||||
roleAddButton.Role = role;
|
||||
if (prettyEnabled)
|
||||
{
|
||||
var pluginId = split[0];
|
||||
var folderName = split[1];
|
||||
|
||||
if (MiraPluginManager.GetPluginByGuid(pluginId) is { } plugin)
|
||||
{
|
||||
if (folderName == "Roles(Clone)")
|
||||
{
|
||||
PluginRoles(__instance, plugin, ref num, ref num2, ref num3);
|
||||
}
|
||||
else if (folderName == "Modifiers(Clone)")
|
||||
{
|
||||
PluginModifiers(__instance, plugin, ref num, ref num2, ref num3);
|
||||
}
|
||||
}
|
||||
roleAddButton.Text.fontSizeMin = 1;
|
||||
roleAddButton.FileImage.sprite = role.IsImpostor
|
||||
? MiraAssets.ImpostorFile.LoadAsset()
|
||||
: MiraAssets.CrewmateFile.LoadAsset();
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var chip in __instance.ActiveItems)
|
||||
{
|
||||
chip.GetComponentInChildren<TextMeshPro>().EnableStencilMasking();
|
||||
chip.GetComponent<SpriteRenderer>().maskInteraction = SpriteMaskInteraction.VisibleInsideMask;
|
||||
}
|
||||
|
||||
if (_scroller)
|
||||
{
|
||||
_scroller.CalculateAndSetYBounds(__instance.ActiveItems.Count, 6, 4.5f, 1.65f);
|
||||
_scroller.SetYBoundsMin(0.0f);
|
||||
_scroller.ScrollToTop();
|
||||
}
|
||||
|
||||
if (__instance.Hierarchy.Count == 1)
|
||||
{
|
||||
ControllerManager.Instance.SetBackButton(__instance.BackButton);
|
||||
return false;
|
||||
}
|
||||
|
||||
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.InternalModifiers.Count; m++)
|
||||
{
|
||||
var modifier = plugin.InternalModifiers[m];
|
||||
if (!modifier.ShowInFreeplay)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var taskAddButton = Object.Instantiate(instance.RoleButton);
|
||||
taskAddButton.name = modifier.TypeId.ToString(NumberFormatInfo.InvariantInfo);
|
||||
taskAddButton.role = null;
|
||||
taskAddButton.MyTask = null;
|
||||
taskAddButton.SafePositionWorld = instance.SafePositionWorld;
|
||||
taskAddButton.Text.text = modifier.ModifierName;
|
||||
taskAddButton.Text.fontSizeMin = 1;
|
||||
taskAddButton.Text.EnableMasking();
|
||||
taskAddButton.FileImage.color = modifier.FreeplayFileColor;
|
||||
taskAddButton.RolloverHandler.OutColor = modifier.FreeplayFileColor;
|
||||
taskAddButton.Button.OnClick = new Button.ButtonClickedEvent();
|
||||
taskAddButton.Button.OnClick.AddListener((UnityEngine.Events.UnityAction)(() =>
|
||||
{
|
||||
var id = modifier.TypeId;
|
||||
if (PlayerControl.LocalPlayer.HasModifier(id))
|
||||
{
|
||||
PlayerControl.LocalPlayer.RemoveModifier(id);
|
||||
taskAddButton.Overlay.enabled = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
PlayerControl.LocalPlayer.AddModifier(id);
|
||||
taskAddButton.Overlay.enabled = true;
|
||||
}
|
||||
}));
|
||||
|
||||
if (modifier is TimedModifier timed)
|
||||
{
|
||||
taskAddButton.FileImage.sprite = MiraAssets.TimedModifierFile.LoadAsset();
|
||||
taskAddButton.Text.text += $"({timed.Duration}s)";
|
||||
}
|
||||
|
||||
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.InternalRoles.Count; m++)
|
||||
{
|
||||
var roleBehaviour = plugin.InternalRoles.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";
|
||||
taskAddButton2.Text.EnableMasking();
|
||||
|
||||
instance.AddFileAsChildCustom(taskAddButton2, ref num, ref num2, ref num3);
|
||||
taskAddButton2.Role = roleBehaviour;
|
||||
if (roleBehaviour is ICustomRole custom)
|
||||
if (role is ICustomRole custom)
|
||||
{
|
||||
if (prettyEnabled && custom.Team == ModdedRoleTeams.Custom) roleAddButton.FileImage.sprite = MiraAssets.CustomTeamFile.LoadAsset();
|
||||
var customColor = custom.IntroConfiguration?.IntroTeamColor ?? Color.gray;
|
||||
if (custom.Team is ModdedRoleTeams.Crewmate)
|
||||
{
|
||||
@@ -409,26 +283,84 @@ internal static class TaskAdderPatches
|
||||
{
|
||||
customColor = Palette.ImpostorRed;
|
||||
}
|
||||
taskAddButton2.FileImage.color = customColor;
|
||||
taskAddButton2.RolloverHandler.OutColor = customColor;
|
||||
roleAddButton.FileImage.color = customColor;
|
||||
roleAddButton.RolloverHandler.OutColor = customColor;
|
||||
}
|
||||
if (taskAddButton2.Button == null)
|
||||
__instance.AddFileAsChildCustom(roleAddButton, ref num, ref num2, ref num3);
|
||||
if (roleAddButton != null && roleAddButton.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;
|
||||
ControllerManager.Instance.AddSelectableUiElement(roleAddButton.Button);
|
||||
}
|
||||
}
|
||||
|
||||
if (folders.TryGetValue("Modifiers", out var modifiersFolder) && taskFolder.IsChildOf(modifiersFolder))
|
||||
{
|
||||
var plugin = MiraPluginManager.GetPluginByGuid(taskFolder.gameObject.name.Replace("(Clone)", string.Empty));
|
||||
if (plugin != null)
|
||||
{
|
||||
foreach (var modifier in plugin.InternalModifiers)
|
||||
{
|
||||
if (!modifier.ShowInFreeplay)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var taskAddButton = Object.Instantiate(__instance.RoleButton);
|
||||
taskAddButton.name = modifier.TypeId.ToString(NumberFormatInfo.InvariantInfo);
|
||||
taskAddButton.role = null;
|
||||
taskAddButton.MyTask = null;
|
||||
taskAddButton.SafePositionWorld = __instance.SafePositionWorld;
|
||||
taskAddButton.Text.text = modifier.ModifierName;
|
||||
taskAddButton.Text.fontSizeMin = 1;
|
||||
taskAddButton.Text.EnableMasking();
|
||||
taskAddButton.FileImage.color = modifier.FreeplayFileColor;
|
||||
taskAddButton.RolloverHandler.OutColor = modifier.FreeplayFileColor;
|
||||
if (modifier is TimedModifier timed)
|
||||
{
|
||||
taskAddButton.FileImage.sprite = MiraAssets.TimedModifierFile.LoadAsset();
|
||||
taskAddButton.Text.text += $" ({timed.Duration}s)";
|
||||
}
|
||||
else
|
||||
{
|
||||
taskAddButton.FileImage.sprite = MiraAssets.ModifierFile.LoadAsset();
|
||||
}
|
||||
|
||||
taskAddButton.Button.OnClick = new Button.ButtonClickedEvent();
|
||||
var m = modifier;
|
||||
taskAddButton.Button.OnClick.AddListener((UnityAction)(() =>
|
||||
{
|
||||
var id = m.TypeId;
|
||||
if (PlayerControl.LocalPlayer.HasModifier(id))
|
||||
{
|
||||
PlayerControl.LocalPlayer.RemoveModifier(id);
|
||||
taskAddButton.Overlay.enabled = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
PlayerControl.LocalPlayer.AddModifier(id);
|
||||
taskAddButton.Overlay.enabled = true;
|
||||
}
|
||||
}));
|
||||
|
||||
__instance.AddFileAsChildCustom(taskAddButton, ref num, ref num2, ref num3);
|
||||
|
||||
ControllerManager.Instance.AddSelectableUiElement(taskAddButton.Button);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (_scroller)
|
||||
{
|
||||
_scroller.CalculateAndSetYBounds(__instance.ActiveItems.Count, 6, 4.5f, 1.65f);
|
||||
_scroller.SetYBoundsMin(0.0f);
|
||||
_scroller.ScrollToTop();
|
||||
}
|
||||
|
||||
ControllerManager.Instance.SetBackButton(__instance.Hierarchy.Count == 1
|
||||
? __instance.BackButton
|
||||
: __instance.FolderBackButton);
|
||||
|
||||
__instance.SetPreviousControllerSelection(taskFolder.FolderName);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -99,6 +99,7 @@ public static class HudManagerPatches
|
||||
|
||||
gridArrange.Start();
|
||||
gridArrange.ArrangeChilds();
|
||||
|
||||
aspectPosition.AdjustPosition();
|
||||
|
||||
vanillaKeybindIcons = [];
|
||||
@@ -110,7 +111,6 @@ public static class HudManagerPatches
|
||||
{ __instance.ReportButton.gameObject, 7 },
|
||||
{ __instance.ImpostorVentButton.gameObject, 50 },
|
||||
{ __instance.SabotageButton.gameObject, 4 },
|
||||
{ __instance.AbilityButton.gameObject, 49 },
|
||||
};
|
||||
|
||||
foreach (var kvp in vanillaButtons)
|
||||
@@ -125,8 +125,6 @@ public static class HudManagerPatches
|
||||
}
|
||||
var icon = Helpers.CreateKeybindIcon(buttonObj, key, keybindIconPos);
|
||||
vanillaKeybindIcons.Add(icon.transform.GetChild(0).GetComponent<TextMeshPro>(), actionId);
|
||||
var comp = buttonObj.GetComponent<ActionButton>();
|
||||
KeybindManager.VanillaKeybinds[comp.GetType()].Button = comp;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -171,10 +169,11 @@ public static class HudManagerPatches
|
||||
LocalSettingsTabSingleton<MiraApiSettings>.Instance.ShowKeybinds.Value);
|
||||
}
|
||||
|
||||
var player = ReInput.players.GetPlayer(0);
|
||||
foreach (var entry in KeybindManager.Keybinds)
|
||||
{
|
||||
var player = ReInput.players.GetPlayer(0);
|
||||
var keyboard = player.controllers.Keyboard;
|
||||
|
||||
bool modifierKeysPressed = entry.ModifierKeys.All(k => keyboard.GetModifierKey(k)) ||
|
||||
entry.ModifierKeys.Length <= 0;
|
||||
if (player.GetButtonDown(entry.Id) && modifierKeysPressed)
|
||||
@@ -182,12 +181,5 @@ public static class HudManagerPatches
|
||||
entry.Invoke();
|
||||
}
|
||||
}
|
||||
foreach (var entry in KeybindManager.VanillaKeybinds.Values)
|
||||
{
|
||||
if (player.GetButtonDown(entry.Id))
|
||||
{
|
||||
entry.Invoke();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,5 @@
|
||||
using HarmonyLib;
|
||||
using MiraAPI.Keybinds;
|
||||
using MonoMod.Utils;
|
||||
using Rewired;
|
||||
|
||||
namespace MiraAPI.Patches.Keybinds;
|
||||
@@ -21,16 +20,5 @@ public static class KeybindMenuPatch
|
||||
KeybindUtils.RewiredInputManager = __instance;
|
||||
KeybindManager.RewiredInit();
|
||||
_registered = true;
|
||||
|
||||
// Set these here right after input manager initializes
|
||||
KeybindManager.VanillaKeybinds = new()
|
||||
{
|
||||
{ typeof(KillButton), new VanillaKeybind(8) },
|
||||
{ typeof(UseButton), new VanillaKeybind(6) },
|
||||
{ typeof(ReportButton), new VanillaKeybind(7) },
|
||||
{ typeof(VentButton), new VanillaKeybind(50) },
|
||||
{ typeof(SabotageButton), new VanillaKeybind(4) },
|
||||
{ typeof(AbilityButton), new VanillaKeybind(49) },
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -33,7 +33,7 @@ public static class RoleManagerPatches
|
||||
data.Role.Deinitialize(targetPlayer);
|
||||
Object.Destroy(data.Role.gameObject);
|
||||
}
|
||||
var roleBehaviour = Object.Instantiate<RoleBehaviour>(__instance.AllRoles.First(r => r.Role == roleType), data.gameObject.transform);
|
||||
var roleBehaviour = Object.Instantiate<RoleBehaviour>(__instance.AllRoles.ToArray().First(r => r.Role == roleType), data.gameObject.transform);
|
||||
roleBehaviour.Initialize(targetPlayer);
|
||||
targetPlayer.Data.Role = roleBehaviour;
|
||||
targetPlayer.Data.RoleType = roleType;
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 5.0 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 5.2 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 6.2 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 4.6 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 5.1 KiB After Width: | Height: | Size: 5.1 KiB |
@@ -32,6 +32,12 @@ public record struct CustomRoleConfiguration
|
||||
TasksCountForProgress = role.Team is ModdedRoleTeams.Crewmate;
|
||||
HideSettings = roleBehaviour?.IsDead == true;
|
||||
ShowInFreeplay = roleBehaviour?.IsDead == false;
|
||||
FreeplayFolder = role.Team switch
|
||||
{
|
||||
ModdedRoleTeams.Crewmate => "Crewmate",
|
||||
ModdedRoleTeams.Impostor => "Impostor",
|
||||
_ => "Neutral",
|
||||
};
|
||||
IntroSound = role.Team is ModdedRoleTeams.Crewmate
|
||||
? CustomRoleManager.CrewmateIntroSound
|
||||
: CustomRoleManager.ImpostorIntroSound;
|
||||
@@ -112,6 +118,11 @@ public record struct CustomRoleConfiguration
|
||||
/// </summary>
|
||||
public bool ShowInFreeplay { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a freeplay folder this role belongs to. Defaults to team folder.
|
||||
/// </summary>
|
||||
public string FreeplayFolder { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the outline color for the KillButton if <see cref="UseVanillaKillButton"/> is true.
|
||||
/// </summary>
|
||||
|
||||
@@ -35,6 +35,11 @@ public static class CustomRoleManager
|
||||
public static readonly LoadableAsset<AudioClip> ImpostorIntroSound =
|
||||
CustomRoleUtils.GetIntroSound(RoleTypes.Impostor)!;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the list of all roles from vanilla RoleManager.
|
||||
/// </summary>
|
||||
public static RoleBehaviour[] AllRoles => RoleManager.Instance.AllRoles.ToArray();
|
||||
|
||||
/// <summary>
|
||||
/// Gets the list of custom roles as RoleBehaviour objects.
|
||||
/// </summary>
|
||||
@@ -57,7 +62,10 @@ public static class CustomRoleManager
|
||||
|
||||
internal static void RegisterInRoleManager()
|
||||
{
|
||||
RoleManager.Instance.AllRoles = RoleManager.Instance.AllRoles.Concat(CustomRoles.Values).ToArray();
|
||||
foreach (var role in CustomRoles.Values)
|
||||
{
|
||||
RoleManager.Instance.AllRoles.Add(role);
|
||||
}
|
||||
|
||||
foreach (var role in CustomRoles.Values.Where(x => x.IsDead))
|
||||
{
|
||||
|
||||
@@ -4,7 +4,6 @@ using System.Linq;
|
||||
using System.Text;
|
||||
using AmongUs.GameOptions;
|
||||
using MiraAPI.Utilities.Assets;
|
||||
using Reactor.Utilities;
|
||||
using UnityEngine;
|
||||
|
||||
namespace MiraAPI.Roles;
|
||||
@@ -56,7 +55,7 @@ public static class CustomRoleUtils
|
||||
/// <returns>The intro sound.</returns>
|
||||
public static LoadableAsset<AudioClip>? GetIntroSound(RoleTypes roleType)
|
||||
{
|
||||
var role = RoleManager.Instance.AllRoles.FirstOrDefault(role => role.Role == roleType);
|
||||
var role = CustomRoleManager.AllRoles.FirstOrDefault(role => role.Role == roleType);
|
||||
if (role is ICustomRole customRole)
|
||||
{
|
||||
return customRole.Configuration.IntroSound;
|
||||
|
||||
@@ -105,6 +105,26 @@ public static class MiraAssets
|
||||
/// </summary>
|
||||
public static LoadableResourceAsset KeybindButton { get; } = new("MiraAPI.Resources.KeybindButton.png");
|
||||
|
||||
/// <summary>
|
||||
/// Gets the sprite used for crewmate role files in TaskAdderGame.
|
||||
/// </summary>
|
||||
public static LoadableResourceAsset CrewmateFile { get; } = new("MiraAPI.Resources.CrewmateFile.png");
|
||||
|
||||
/// <summary>
|
||||
/// Gets the sprite used for impostor role files in TaskAdderGame.
|
||||
/// </summary>
|
||||
public static LoadableResourceAsset ImpostorFile { get; } = new("MiraAPI.Resources.ImpostorFile.png");
|
||||
|
||||
/// <summary>
|
||||
/// Gets the sprite used for custom team role files in TaskAdderGame.
|
||||
/// </summary>
|
||||
public static LoadableResourceAsset CustomTeamFile { get; } = new("MiraAPI.Resources.CustomFile.png");
|
||||
|
||||
/// <summary>
|
||||
/// Gets the sprite used for modifier file in TaskAdderGame.
|
||||
/// </summary>
|
||||
public static LoadableResourceAsset ModifierFile { get; } = new("MiraAPI.Resources.ModifierFile.png");
|
||||
|
||||
/// <summary>
|
||||
/// Gets the sprite used for timed modifier file in TaskAdderGame.
|
||||
/// </summary>
|
||||
|
||||
Reference in new issue
Block a user