mirror of
https://github.com/All-Of-Us-Mods/MiraAPI.git
synced 2026-10-20 01:46:15 +00:00
Merge pull request #80 from All-Of-Us-Mods/dev
## What's New - Individual game options can be reset if they are a part of a preset. - A new meeting-specific murder rpc is now available for use, checking for kills happening within and outside of a meeting. - ## What's Changed - Framerate Slider has been renamed to be more accurate - Memory usage per frame has been improved
This commit is contained in:
13 files changed
+251
-31
No files matched your search
@@ -8,7 +8,7 @@
|
|||||||
|
|
||||||
<RestorePackagesWithLockFile>true</RestorePackagesWithLockFile>
|
<RestorePackagesWithLockFile>true</RestorePackagesWithLockFile>
|
||||||
|
|
||||||
<VersionPrefix>0.3.6</VersionPrefix>
|
<VersionPrefix>0.3.7</VersionPrefix>
|
||||||
<VersionSuffix>dev</VersionSuffix>
|
<VersionSuffix>dev</VersionSuffix>
|
||||||
|
|
||||||
<Authors>All Of Us, XtraCube, Angxl</Authors>
|
<Authors>All Of Us, XtraCube, Angxl</Authors>
|
||||||
@@ -42,4 +42,4 @@
|
|||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<CodeAnalysisRuleSet>$(MSBuildThisFileDirectory)\stylecop.ruleset</CodeAnalysisRuleSet>
|
<CodeAnalysisRuleSet>$(MSBuildThisFileDirectory)\stylecop.ruleset</CodeAnalysisRuleSet>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
</Project>
|
</Project>
|
||||||
@@ -1,4 +1,6 @@
|
|||||||
namespace MiraAPI.Events.Vanilla.Gameplay;
|
using MiraAPI.Networking;
|
||||||
|
|
||||||
|
namespace MiraAPI.Events.Vanilla.Gameplay;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Event that is invoked before a player is murdered. This event is cancelable.
|
/// Event that is invoked before a player is murdered. This event is cancelable.
|
||||||
@@ -15,6 +17,24 @@ public sealed class BeforeMurderEvent : MiraCancelableEvent
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public PlayerControl Target { get; }
|
public PlayerControl Target { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets whether the murder was meant to be done in a meeting via an enum.
|
||||||
|
/// </summary>
|
||||||
|
public MeetingCheck InMeeting { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="BeforeMurderEvent"/> class.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="source">The player that is killing the target.</param>
|
||||||
|
/// <param name="target">The player that is being killed.</param>
|
||||||
|
/// <param name="inMeeting">Whether the murder is intended to be triggered in a meeting.</param>
|
||||||
|
public BeforeMurderEvent(PlayerControl source, PlayerControl target, MeetingCheck inMeeting)
|
||||||
|
{
|
||||||
|
Source = source;
|
||||||
|
Target = target;
|
||||||
|
InMeeting = inMeeting;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="BeforeMurderEvent"/> class.
|
/// Initializes a new instance of the <see cref="BeforeMurderEvent"/> class.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -24,5 +44,6 @@ public sealed class BeforeMurderEvent : MiraCancelableEvent
|
|||||||
{
|
{
|
||||||
Source = source;
|
Source = source;
|
||||||
Target = target;
|
Target = target;
|
||||||
|
InMeeting = MeetingCheck.Ignore;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
global using static Reactor.Utilities.Logger<MiraAPI.MiraApiPlugin>;
|
global using static Reactor.Utilities.Logger<MiraAPI.MiraApiPlugin>;
|
||||||
|
using System;
|
||||||
using BepInEx;
|
using BepInEx;
|
||||||
using BepInEx.Unity.IL2CPP;
|
using BepInEx.Unity.IL2CPP;
|
||||||
using HarmonyLib;
|
using HarmonyLib;
|
||||||
@@ -22,7 +23,7 @@ namespace MiraAPI;
|
|||||||
public partial class MiraApiPlugin : BasePlugin
|
public partial class MiraApiPlugin : BasePlugin
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets whether the current device is running Starlight (on mobile).
|
/// Gets a value indicating whether the current device is running Starlight (on mobile).
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static bool IsMobile => Constants.GetPlatformType() is Platforms.Android or Platforms.IPhone;
|
public static bool IsMobile => Constants.GetPlatformType() is Platforms.Android or Platforms.IPhone;
|
||||||
|
|
||||||
@@ -36,6 +37,11 @@ public partial class MiraApiPlugin : BasePlugin
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public static Color DefaultHeaderColor { get; } = new Color32(77, 77, 77, 255);
|
public static Color DefaultHeaderColor { get; } = new Color32(77, 77, 77, 255);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets a value indicating whether the current build is a development build or not. This mostly avoids confusion for users asking why the mod appears red.
|
||||||
|
/// </summary>
|
||||||
|
public static bool IsDevBuild => Version.Contains("ci", StringComparison.OrdinalIgnoreCase) || Version.Contains("dev", StringComparison.OrdinalIgnoreCase);
|
||||||
|
|
||||||
private static MiraPluginManager? PluginManager { get; set; }
|
private static MiraPluginManager? PluginManager { get; set; }
|
||||||
internal Harmony Harmony { get; } = new(Id);
|
internal Harmony Harmony { get; } = new(Id);
|
||||||
|
|
||||||
@@ -44,7 +50,7 @@ public partial class MiraApiPlugin : BasePlugin
|
|||||||
{
|
{
|
||||||
Harmony.PatchAll();
|
Harmony.PatchAll();
|
||||||
|
|
||||||
ReactorCredits.Register("Mira API", Version, true, ReactorCredits.AlwaysShow);
|
ReactorCredits.Register("Mira API", Version, IsDevBuild, ReactorCredits.AlwaysShow);
|
||||||
|
|
||||||
PluginManager = new MiraPluginManager();
|
PluginManager = new MiraPluginManager();
|
||||||
PluginManager.Initialize();
|
PluginManager.Initialize();
|
||||||
|
|||||||
@@ -79,7 +79,7 @@ public class MiraApiSettings(ConfigFile config) : LocalSettingsTab(config)
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
[LocalSliderSetting(min: 60f, max: 240f, suffixType: MiraNumberSuffixes.None, formatString: "0", displayValue: true, roundValue: true)]
|
[LocalSliderSetting(min: 60f, max: 240f, suffixType: MiraNumberSuffixes.None, formatString: "0", displayValue: true, roundValue: true)]
|
||||||
public ConfigEntry<float> SetFpsSlider { get; private set; } =
|
public ConfigEntry<float> SetFpsSlider { get; private set; } =
|
||||||
config.Bind("Visuals/UI", "Frames Per Seconds", 120f);
|
config.Bind("Visuals/UI", "Max FPS", 120f);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets whether to apply cosmetic changes to the TaskAdder.
|
/// Gets whether to apply cosmetic changes to the TaskAdder.
|
||||||
|
|||||||
@@ -32,7 +32,6 @@ public static class CustomMurderRpc
|
|||||||
/// <param name="teleportMurderer">Should the killer be snapped to the dead player.</param>
|
/// <param name="teleportMurderer">Should the killer be snapped to the dead player.</param>
|
||||||
/// <param name="showKillAnim">Should the kill animation be shown.</param>
|
/// <param name="showKillAnim">Should the kill animation be shown.</param>
|
||||||
/// <param name="playKillSound">Should the kill sound be played.</param>
|
/// <param name="playKillSound">Should the kill sound be played.</param>
|
||||||
[MethodRpc((uint)MiraRpc.CustomMurder, LocalHandling = RpcLocalHandling.Before)]
|
|
||||||
public static void RpcCustomMurder(
|
public static void RpcCustomMurder(
|
||||||
this PlayerControl source,
|
this PlayerControl source,
|
||||||
PlayerControl target,
|
PlayerControl target,
|
||||||
@@ -42,11 +41,51 @@ public static class CustomMurderRpc
|
|||||||
bool teleportMurderer = true,
|
bool teleportMurderer = true,
|
||||||
bool showKillAnim = true,
|
bool showKillAnim = true,
|
||||||
bool playKillSound = true)
|
bool playKillSound = true)
|
||||||
|
{
|
||||||
|
source.RpcCustomMurder(
|
||||||
|
target,
|
||||||
|
MeetingCheck.Ignore,
|
||||||
|
didSucceed,
|
||||||
|
resetKillTimer,
|
||||||
|
createDeadBody,
|
||||||
|
teleportMurderer,
|
||||||
|
showKillAnim,
|
||||||
|
playKillSound);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Networked Custom Murder method, which checks for meetings as well.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="source">The killer.</param>
|
||||||
|
/// <param name="target">The player to murder.</param>
|
||||||
|
/// <param name="inMeeting">Whether the murder is intended to be triggered in a meeting.</param>
|
||||||
|
/// <param name="didSucceed">Whether the murder was successful or not.</param>
|
||||||
|
/// <param name="resetKillTimer">Should the kill timer be reset.</param>
|
||||||
|
/// <param name="createDeadBody">Should a dead body be created.</param>
|
||||||
|
/// <param name="teleportMurderer">Should the killer be snapped to the dead player.</param>
|
||||||
|
/// <param name="showKillAnim">Should the kill animation be shown.</param>
|
||||||
|
/// <param name="playKillSound">Should the kill sound be played.</param>
|
||||||
|
[MethodRpc((uint)MiraRpc.CustomMurder, LocalHandling = RpcLocalHandling.Before)]
|
||||||
|
public static void RpcCustomMurder(
|
||||||
|
this PlayerControl source,
|
||||||
|
PlayerControl target,
|
||||||
|
MeetingCheck inMeeting,
|
||||||
|
bool didSucceed = true,
|
||||||
|
bool resetKillTimer = true,
|
||||||
|
bool createDeadBody = true,
|
||||||
|
bool teleportMurderer = true,
|
||||||
|
bool showKillAnim = true,
|
||||||
|
bool playKillSound = true)
|
||||||
{
|
{
|
||||||
var murderResultFlags = didSucceed ? MurderResultFlags.Succeeded : MurderResultFlags.FailedError;
|
var murderResultFlags = didSucceed ? MurderResultFlags.Succeeded : MurderResultFlags.FailedError;
|
||||||
|
|
||||||
var beforeMurderEvent = new BeforeMurderEvent(source, target);
|
var beforeMurderEvent = new BeforeMurderEvent(source, target, inMeeting);
|
||||||
MiraEventManager.InvokeEvent(beforeMurderEvent);
|
MiraEventManager.InvokeEvent(beforeMurderEvent);
|
||||||
|
var isMeetingActive = MeetingHud.Instance != null || ExileController.Instance != null;
|
||||||
|
if ((inMeeting is MeetingCheck.ForMeeting && !isMeetingActive) || (inMeeting is MeetingCheck.OutsideMeeting && isMeetingActive))
|
||||||
|
{
|
||||||
|
beforeMurderEvent.Cancel();
|
||||||
|
}
|
||||||
|
|
||||||
if (beforeMurderEvent.IsCancelled)
|
if (beforeMurderEvent.IsCancelled)
|
||||||
{
|
{
|
||||||
@@ -91,7 +130,6 @@ public static class CustomMurderRpc
|
|||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
var data = target.Data;
|
|
||||||
|
|
||||||
if (resultFlags.HasFlag(MurderResultFlags.FailedProtected) ||
|
if (resultFlags.HasFlag(MurderResultFlags.FailedProtected) ||
|
||||||
(resultFlags.HasFlag(MurderResultFlags.DecisionByHost) && target.protectedByGuardianId > -1))
|
(resultFlags.HasFlag(MurderResultFlags.DecisionByHost) && target.protectedByGuardianId > -1))
|
||||||
@@ -174,7 +212,7 @@ public static class CustomMurderRpc
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
HudManager.Instance.KillOverlay.ShowKillAnimation(source.Data, data);
|
HudManager.Instance.KillOverlay.ShowKillAnimation(source.Data, target.Data);
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
@@ -298,3 +336,24 @@ public static class CustomMurderRpc
|
|||||||
source.isKilling = false;
|
source.isKilling = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Checks for custom murders.
|
||||||
|
/// </summary>
|
||||||
|
public enum MeetingCheck
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Checks for meetings.
|
||||||
|
/// </summary>
|
||||||
|
ForMeeting,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Checks for a meeting to not be active.
|
||||||
|
/// </summary>
|
||||||
|
OutsideMeeting,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Doesn't check for a meeting at all.
|
||||||
|
/// </summary>
|
||||||
|
Ignore,
|
||||||
|
}
|
||||||
@@ -1,6 +1,5 @@
|
|||||||
using System.Collections;
|
using System.Collections;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
|
||||||
using HarmonyLib;
|
using HarmonyLib;
|
||||||
using MiraAPI.Hud;
|
using MiraAPI.Hud;
|
||||||
using MiraAPI.Keybinds;
|
using MiraAPI.Keybinds;
|
||||||
@@ -26,9 +25,9 @@ public static class HudManagerPatches
|
|||||||
public static Transform? BottomRight { get; private set; }
|
public static Transform? BottomRight { get; private set; }
|
||||||
public static Transform? Buttons { get; private set; }
|
public static Transform? Buttons { get; private set; }
|
||||||
|
|
||||||
private static Dictionary<TextMeshPro, int> vanillaKeybindIcons = new();
|
private static Dictionary<TextMeshPro, int> vanillaKeybindIcons = [];
|
||||||
|
|
||||||
internal static List<TextMeshPro> ModdedKeybindIcons = new();
|
internal static List<TextMeshPro> ModdedKeybindIcons = [];
|
||||||
|
|
||||||
public static IEnumerator CoResizeUI()
|
public static IEnumerator CoResizeUI()
|
||||||
{
|
{
|
||||||
@@ -272,31 +271,54 @@ public static class HudManagerPatches
|
|||||||
{
|
{
|
||||||
var canSeeBinds = ActiveInputManager.currentControlType == ActiveInputManager.InputType.Keyboard &&
|
var canSeeBinds = ActiveInputManager.currentControlType == ActiveInputManager.InputType.Keyboard &&
|
||||||
LocalSettingsTabSingleton<MiraApiSettings>.Instance.ShowKeybinds.Value;
|
LocalSettingsTabSingleton<MiraApiSettings>.Instance.ShowKeybinds.Value;
|
||||||
|
|
||||||
foreach (var btnIcon in vanillaKeybindIcons)
|
foreach (var btnIcon in vanillaKeybindIcons)
|
||||||
{
|
{
|
||||||
btnIcon.Key.text = KeybindUtils.GetKeycodeByActionId(btnIcon.Value).ToString();
|
btnIcon.Key.text = KeybindUtils.GetKeycodeByActionId(btnIcon.Value).ToString();
|
||||||
btnIcon.Key.transform.parent.gameObject.SetActive(canSeeBinds);
|
btnIcon.Key.transform.parent.gameObject.SetActive(canSeeBinds);
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (var btnIcon in ModdedKeybindIcons)
|
foreach (var btnIcon in ModdedKeybindIcons)
|
||||||
{
|
{
|
||||||
btnIcon.transform.parent.gameObject.SetActive(canSeeBinds);
|
btnIcon.transform.parent.gameObject.SetActive(canSeeBinds);
|
||||||
}
|
}
|
||||||
|
|
||||||
var player = ReInput.players.GetPlayer(0);
|
var player = ReInput.players.GetPlayer(0);
|
||||||
|
var keyboard = player.controllers.Keyboard;
|
||||||
foreach (var entry in KeybindManager.Keybinds)
|
foreach (var entry in KeybindManager.Keybinds)
|
||||||
{
|
{
|
||||||
var keyboard = player.controllers.Keyboard;
|
var modKeys = entry.ModifierKeys;
|
||||||
bool modifierKeysPressed = entry.ModifierKeys.All(k => keyboard.GetModifierKey(k)) ||
|
bool modifierKeysPressed;
|
||||||
entry.ModifierKeys.Length <= 0;
|
if (modKeys.Length == 0)
|
||||||
|
{
|
||||||
|
modifierKeysPressed = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
modifierKeysPressed = true;
|
||||||
|
foreach (var key in modKeys)
|
||||||
|
{
|
||||||
|
if (keyboard.GetModifierKey(key)) continue;
|
||||||
|
modifierKeysPressed = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (player.GetButtonDown(entry.Id) && modifierKeysPressed)
|
if (player.GetButtonDown(entry.Id) && modifierKeysPressed)
|
||||||
{
|
{
|
||||||
entry.Invoke();
|
entry.Invoke();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (var entry in KeybindManager.VanillaKeybinds.Values.Where(x => player.GetButtonDown(x.Id)))
|
// suppressed warning because we want minimum allocations here
|
||||||
|
#pragma warning disable S3267
|
||||||
|
foreach (var entry in KeybindManager.VanillaKeybinds.Values)
|
||||||
|
#pragma warning restore S3267
|
||||||
{
|
{
|
||||||
entry.Invoke();
|
if (player.GetButtonDown(entry.Id))
|
||||||
|
{
|
||||||
|
entry.Invoke();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,8 +1,11 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using AmongUs.GameOptions;
|
||||||
using HarmonyLib;
|
using HarmonyLib;
|
||||||
|
using Il2CppInterop.Runtime.Attributes;
|
||||||
using MiraAPI.GameOptions;
|
using MiraAPI.GameOptions;
|
||||||
using MiraAPI.Modifiers;
|
using MiraAPI.Modifiers;
|
||||||
|
using MiraAPI.Presets;
|
||||||
using MiraAPI.Utilities;
|
using MiraAPI.Utilities;
|
||||||
using MiraAPI.Utilities.Assets;
|
using MiraAPI.Utilities.Assets;
|
||||||
using Reactor.Localization.Utilities;
|
using Reactor.Localization.Utilities;
|
||||||
@@ -10,6 +13,7 @@ using Reactor.Utilities.Extensions;
|
|||||||
using TMPro;
|
using TMPro;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using UnityEngine.Events;
|
using UnityEngine.Events;
|
||||||
|
using UnityEngine.UI;
|
||||||
using Object = UnityEngine.Object;
|
using Object = UnityEngine.Object;
|
||||||
|
|
||||||
namespace MiraAPI.Patches.Options;
|
namespace MiraAPI.Patches.Options;
|
||||||
@@ -23,6 +27,7 @@ internal static class GameOptionsMenuPatch
|
|||||||
{
|
{
|
||||||
HudManager.Instance.PlayerCam.OverrideScreenShakeEnabled = false;
|
HudManager.Instance.PlayerCam.OverrideScreenShakeEnabled = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
[HarmonyPostfix]
|
[HarmonyPostfix]
|
||||||
[HarmonyPatch(nameof(GameOptionsMenu.OnDisable))]
|
[HarmonyPatch(nameof(GameOptionsMenu.OnDisable))]
|
||||||
public static void ClosePatch(GameOptionsMenu __instance)
|
public static void ClosePatch(GameOptionsMenu __instance)
|
||||||
@@ -166,7 +171,7 @@ internal static class GameOptionsMenuPatch
|
|||||||
private static void ModifiersUpdate(ref float num)
|
private static void ModifiersUpdate(ref float num)
|
||||||
{
|
{
|
||||||
var groups = GameSettingMenuPatches.SelectedMod?.InternalOptionGroups
|
var groups = GameSettingMenuPatches.SelectedMod?.InternalOptionGroups
|
||||||
.Where(x => x.ShowInModifiersMenu || x.OptionableType?.IsAssignableTo(typeof(BaseModifier))==true) ?? [];
|
.Where(x => x.ShowInModifiersMenu || x.OptionableType?.IsAssignableTo(typeof(BaseModifier)) == true) ?? [];
|
||||||
|
|
||||||
foreach (var modGroup in groups)
|
foreach (var modGroup in groups)
|
||||||
{
|
{
|
||||||
@@ -177,7 +182,7 @@ internal static class GameOptionsMenuPatch
|
|||||||
private static void ModifiersCreate(GameOptionsMenu menu)
|
private static void ModifiersCreate(GameOptionsMenu menu)
|
||||||
{
|
{
|
||||||
var groups = GameSettingMenuPatches.SelectedMod?.InternalOptionGroups
|
var groups = GameSettingMenuPatches.SelectedMod?.InternalOptionGroups
|
||||||
.Where(x => x.ShowInModifiersMenu || x.OptionableType?.IsAssignableTo(typeof(BaseModifier))==true) ?? [];
|
.Where(x => x.ShowInModifiersMenu || x.OptionableType?.IsAssignableTo(typeof(BaseModifier)) == true) ?? [];
|
||||||
foreach (var group in groups)
|
foreach (var group in groups)
|
||||||
{
|
{
|
||||||
CreateGroup(menu, group);
|
CreateGroup(menu, group);
|
||||||
@@ -270,7 +275,9 @@ internal static class GameOptionsMenuPatch
|
|||||||
categoryHeaderMasked.SetHeader(CustomStringName.CreateAndRegister(group.GroupName), 20);
|
categoryHeaderMasked.SetHeader(CustomStringName.CreateAndRegister(group.GroupName), 20);
|
||||||
categoryHeaderMasked.Background.color = group.GroupColor;
|
categoryHeaderMasked.Background.color = group.GroupColor;
|
||||||
categoryHeaderMasked.Divider.color = group.GroupColor;
|
categoryHeaderMasked.Divider.color = group.GroupColor;
|
||||||
categoryHeaderMasked.Title.color = group.GroupColor.Equals(MiraApiPlugin.DefaultHeaderColor) ? Color.white : group.GroupColor.FindAlternateColor();
|
categoryHeaderMasked.Title.color = group.GroupColor.Equals(MiraApiPlugin.DefaultHeaderColor)
|
||||||
|
? Color.white
|
||||||
|
: group.GroupColor.FindAlternateColor();
|
||||||
|
|
||||||
categoryHeaderMasked.Background.sprite = MiraAssets.CategoryHeader.LoadAsset();
|
categoryHeaderMasked.Background.sprite = MiraAssets.CategoryHeader.LoadAsset();
|
||||||
categoryHeaderMasked.Background.sprite.texture.filterMode = FilterMode.Bilinear;
|
categoryHeaderMasked.Background.sprite.texture.filterMode = FilterMode.Bilinear;
|
||||||
@@ -289,13 +296,20 @@ internal static class GameOptionsMenuPatch
|
|||||||
newText.transform.localPosition = new Vector3(2.6249f, -0.165f, 0f);
|
newText.transform.localPosition = new Vector3(2.6249f, -0.165f, 0f);
|
||||||
newText.gameObject.GetComponent<TextTranslatorTMP>().Destroy();
|
newText.gameObject.GetComponent<TextTranslatorTMP>().Destroy();
|
||||||
|
|
||||||
var options = group.Options.Select(
|
var options = group.Options.Select(opt => opt.CreateOption(
|
||||||
opt => opt.CreateOption(
|
menu.checkboxOrigin,
|
||||||
menu.checkboxOrigin,
|
menu.numberOptionOrigin,
|
||||||
menu.numberOptionOrigin,
|
menu.stringOptionOrigin,
|
||||||
menu.stringOptionOrigin,
|
menu.playerOptionOrigin,
|
||||||
menu.playerOptionOrigin,
|
menu.settingsContainer));
|
||||||
menu.settingsContainer));
|
|
||||||
|
OptionPreset? defaultPreset = null;
|
||||||
|
if (GameSettingMenuPatches.SelectedMod != null && PresetManager.DefaultPresets.TryGetValue(
|
||||||
|
GameSettingMenuPatches.SelectedMod,
|
||||||
|
out var preset))
|
||||||
|
{
|
||||||
|
defaultPreset = preset;
|
||||||
|
}
|
||||||
|
|
||||||
foreach (var newOpt in options)
|
foreach (var newOpt in options)
|
||||||
{
|
{
|
||||||
@@ -331,14 +345,79 @@ internal static class GameOptionsMenuPatch
|
|||||||
if (newOpt is ToggleOption toggle)
|
if (newOpt is ToggleOption toggle)
|
||||||
{
|
{
|
||||||
toggle.CheckMark.sprite = MiraAssets.Checkmark.LoadAsset();
|
toggle.CheckMark.sprite = MiraAssets.Checkmark.LoadAsset();
|
||||||
toggle.CheckMark.color = group.GroupColor != MiraApiPlugin.DefaultHeaderColor ? group.GroupColor : MiraAssets.AcceptedTeal;
|
toggle.CheckMark.color = group.GroupColor != MiraApiPlugin.DefaultHeaderColor
|
||||||
|
? group.GroupColor
|
||||||
|
: MiraAssets.AcceptedTeal;
|
||||||
var rend = toggle.CheckMark.transform.parent.FindChild("ActiveSprite")
|
var rend = toggle.CheckMark.transform.parent.FindChild("ActiveSprite")
|
||||||
.GetComponent<SpriteRenderer>();
|
.GetComponent<SpriteRenderer>();
|
||||||
rend.sprite = MiraAssets.CheckmarkBox.LoadAsset();
|
rend.sprite = MiraAssets.CheckmarkBox.LoadAsset();
|
||||||
rend.color = group.GroupColor != MiraApiPlugin.DefaultHeaderColor ? group.GroupColor : MiraAssets.AcceptedTeal;
|
rend.color = group.GroupColor != MiraApiPlugin.DefaultHeaderColor
|
||||||
|
? group.GroupColor
|
||||||
|
: MiraAssets.AcceptedTeal;
|
||||||
}
|
}
|
||||||
|
|
||||||
menu.Children.Add(newOpt);
|
menu.Children.Add(newOpt);
|
||||||
|
var resetBtn = new GameObject("ResetOption");
|
||||||
|
resetBtn.transform.parent = newOpt.transform;
|
||||||
|
resetBtn.transform.localScale = new(.5f, .5f, 1);
|
||||||
|
resetBtn.layer = LayerMask.NameToLayer("UI");
|
||||||
|
resetBtn.transform.localPosition = new Vector3(-3.1f, 0f, -2f);
|
||||||
|
var resetRend = resetBtn.AddComponent<SpriteRenderer>();
|
||||||
|
resetRend.sprite = MiraAssets.ResetButton.LoadAsset();
|
||||||
|
resetRend.maskInteraction = SpriteMaskInteraction.VisibleInsideMask;
|
||||||
|
resetRend.color = group.GroupColor.Equals(MiraApiPlugin.DefaultHeaderColor)
|
||||||
|
? Color.white
|
||||||
|
: group.GroupColor.FindAlternateColor();
|
||||||
|
var resetBoxCol = resetBtn.gameObject.AddComponent<BoxCollider2D>();
|
||||||
|
resetBoxCol.size = new Vector2(1f, 1f);
|
||||||
|
resetBoxCol.offset = new Vector2(0, 0);
|
||||||
|
var passiveButton = resetBtn.AddComponent<PassiveButton>();
|
||||||
|
passiveButton.OnClick = new Button.ButtonClickedEvent();
|
||||||
|
passiveButton.ClickSound = menu.BackButton.GetComponent<PassiveButton>().ClickSound;
|
||||||
|
passiveButton.OnMouseOver = new UnityEvent();
|
||||||
|
passiveButton.OnMouseOver.AddListener(
|
||||||
|
(UnityAction)(() =>
|
||||||
|
{
|
||||||
|
resetRend.color = group.GroupColor != MiraApiPlugin.DefaultHeaderColor
|
||||||
|
? group.GroupColor
|
||||||
|
: MiraAssets.AcceptedTeal;
|
||||||
|
}));
|
||||||
|
passiveButton.OnMouseOut = new UnityEvent();
|
||||||
|
passiveButton.OnMouseOut.AddListener(
|
||||||
|
(UnityAction)(() =>
|
||||||
|
{
|
||||||
|
resetRend.color = group.GroupColor.Equals(MiraApiPlugin.DefaultHeaderColor)
|
||||||
|
? Color.white
|
||||||
|
: group.GroupColor.FindAlternateColor();
|
||||||
|
}));
|
||||||
|
if (newOpt is ToggleOption toggleOpt)
|
||||||
|
{
|
||||||
|
passiveButton.OnClick.AddListener(
|
||||||
|
(UnityAction)(() =>
|
||||||
|
{
|
||||||
|
defaultPreset!.ResetOption(toggleOpt);
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
else if (newOpt is NumberOption numOpt)
|
||||||
|
{
|
||||||
|
passiveButton.OnClick.AddListener(
|
||||||
|
(UnityAction)(() =>
|
||||||
|
{
|
||||||
|
defaultPreset!.ResetOption(numOpt);
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
else if (newOpt is StringOption strOpt)
|
||||||
|
{
|
||||||
|
passiveButton.OnClick.AddListener(
|
||||||
|
(UnityAction)(() =>
|
||||||
|
{
|
||||||
|
defaultPreset!.ResetOption(strOpt);
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
if (!defaultPreset!.IsOptionInPreset(newOpt))
|
||||||
|
{
|
||||||
|
resetBtn.Destroy();
|
||||||
|
}
|
||||||
|
|
||||||
newOpt.Initialize();
|
newOpt.Initialize();
|
||||||
newOpt.gameObject.SetActive(false);
|
newOpt.gameObject.SetActive(false);
|
||||||
|
|||||||
@@ -13,6 +13,10 @@ internal static class HowToPlayPatch
|
|||||||
// yes i patched the entire method
|
// yes i patched the entire method
|
||||||
private static void Prefix(HowToPlayScene __instance)
|
private static void Prefix(HowToPlayScene __instance)
|
||||||
{
|
{
|
||||||
|
if (RoleManager.Instance.AllRoles.ToArray().All(x => !x.IsCustomRole()))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
__instance.sceneIndex = 0;
|
__instance.sceneIndex = 0;
|
||||||
__instance.category = HowToPlayScene.HowToPlayCategory.RolesSelection;
|
__instance.category = HowToPlayScene.HowToPlayCategory.RolesSelection;
|
||||||
__instance.startPage.SetActive(false);
|
__instance.startPage.SetActive(false);
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ public static class KillButtonPatches
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
PlayerControl.LocalPlayer.RpcCustomMurder(__instance.currentTarget);
|
PlayerControl.LocalPlayer.RpcCustomMurder(__instance.currentTarget, MeetingCheck.OutsideMeeting);
|
||||||
__instance.SetTarget(null);
|
__instance.SetTarget(null);
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -71,4 +71,26 @@ public class OptionPreset
|
|||||||
|
|
||||||
CustomRoleManager.SyncAllRoleSettings();
|
CustomRoleManager.SyncAllRoleSettings();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Resets the specified option with the preset provided.
|
||||||
|
/// </summary>
|
||||||
|
public void ResetOption(OptionBehaviour baseOption)
|
||||||
|
{
|
||||||
|
var selectedOpt = Plugin.InternalOptions.First(x => x.OptionBehaviour == baseOption);
|
||||||
|
selectedOpt.LoadFromPreset(PresetConfig);
|
||||||
|
/*ModdedOptionsManager.SyncAllOptions();
|
||||||
|
|
||||||
|
CustomRoleManager.SyncAllRoleSettings();*/
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets whether the specified option is included in the preset.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>>The value of whether the option is in the preset.</returns>
|
||||||
|
public bool IsOptionInPreset(OptionBehaviour baseOption)
|
||||||
|
{
|
||||||
|
var selectedOpt = Plugin.InternalOptions.First(x => x.OptionBehaviour == baseOption);
|
||||||
|
return selectedOpt.ConfigDefinition != null && PresetConfig.ContainsKey(selectedOpt.ConfigDefinition);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -19,6 +19,7 @@ public static class PresetManager
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public static string PresetDirectory { get; } = Path.GetFullPath("mira_presets", Application.persistentDataPath);
|
public static string PresetDirectory { get; } = Path.GetFullPath("mira_presets", Application.persistentDataPath);
|
||||||
|
|
||||||
|
internal static Dictionary<MiraPluginInfo, OptionPreset> DefaultPresets { get; } = [];
|
||||||
internal static List<OptionPreset> InternalMasterPresets { get; } = [];
|
internal static List<OptionPreset> InternalMasterPresets { get; } = [];
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -47,6 +48,7 @@ public static class PresetManager
|
|||||||
}
|
}
|
||||||
|
|
||||||
presetConfig.Save();
|
presetConfig.Save();
|
||||||
|
DefaultPresets.Add(plugin, new OptionPreset("Default", plugin, presetConfig));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
Binary file not shown.
|
After Width: | Height: | Size: 3.1 KiB |
@@ -90,6 +90,11 @@ public static class MiraAssets
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public static LoadableResourceAsset CheckmarkBox { get; } = new("MiraAPI.Resources.CheckMarkBox.png");
|
public static LoadableResourceAsset CheckmarkBox { get; } = new("MiraAPI.Resources.CheckMarkBox.png");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the Reset Box used in the Settings Menu.
|
||||||
|
/// </summary>
|
||||||
|
public static LoadableResourceAsset ResetButton { get; } = new("MiraAPI.Resources.ResetButton.png");
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the Checkmark used in the Settings Menu.
|
/// Gets the Checkmark used in the Settings Menu.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
Reference in new issue
Block a user